0023953: Avoid unjustified use of $CASROOT and exporting to GIF in tests
[occt.git] / src / BRepFill / BRepFill_OffsetWire.cxx
CommitLineData
b311480e 1// Created on: 1995-04-20
2// Created by: Bruno DUMORTIER
3// Copyright (c) 1995-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22// Modified by skv - Fri Jul 8 11:21:38 2005 OCC9145
23
24#include <stdio.h>
25
26#include <BRepFill_OffsetWire.ixx>
27
28#include <BRepAdaptor_Curve.hxx>
29#include <BRepAdaptor_Surface.hxx>
30
31#include <BRepFill_DataMapOfNodeShape.hxx>
32#include <BRepFill_DataMapOfShapeSequenceOfPnt.hxx>
33#include <BRepFill_DataMapOfShapeSequenceOfReal.hxx>
34#include <BRepFill_DataMapOfOrientedShapeListOfShape.hxx>
7fd59977 35#include <BRepFill_TrimEdgeTool.hxx>
36#include <BRepLib.hxx>
37#include <BRepLib_MakeVertex.hxx>
38#include <BRepLib_MakeFace.hxx>
39#include <BRepLib_MakeWire.hxx>
40#include <BRepLib_MakeEdge.hxx>
41#include <BRepTools.hxx>
42#include <BRep_Builder.hxx>
43#include <BRep_Tool.hxx>
44#include <BRep_TEdge.hxx>
45#include <BRep_CurveRepresentation.hxx>
46#include <BRep_GCurve.hxx>
47#include <BRepTools_WireExplorer.hxx>
48#include <BRepMAT2d_Explorer.hxx>
49#include <Geom2dAdaptor_Curve.hxx>
50#include <Geom2dAdaptor_HCurve.hxx>
51#include <Adaptor3d_OffsetCurve.hxx>
52#include <Adaptor3d_Curve.hxx>
53#include <Geom_Surface.hxx>
54#include <Geom_Plane.hxx>
55#include <Geom2d_Curve.hxx>
56#include <Geom2d_Circle.hxx>
57#include <Geom2d_Line.hxx>
58#include <Geom2d_TrimmedCurve.hxx>
59#include <Geom2d_OffsetCurve.hxx>
60#include <GeomAPI.hxx>
61#include <Geom_TrimmedCurve.hxx>
62#include <Geom_Circle.hxx>
63#include <Geom_OffsetCurve.hxx>
64#include <MAT_Arc.hxx>
65#include <MAT_Node.hxx>
66#include <MAT_Graph.hxx>
67#include <MAT2d_CutCurve.hxx>
68#include <Precision.hxx>
69#include <Standard_NotImplemented.hxx>
70#include <TColgp_SequenceOfPnt.hxx>
71#include <TColStd_SequenceOfReal.hxx>
72#include <TopAbs.hxx>
73#include <TopExp.hxx>
74#include <TopExp_Explorer.hxx>
75#include <TopoDS.hxx>
76#include <TopoDS_Wire.hxx>
77#include <TopoDS_Compound.hxx>
78#include <TopoDS_Iterator.hxx>
79#include <TopTools_MapOfShape.hxx>
80#include <TopTools_MapIteratorOfMapOfShape.hxx>
81#include <TopTools_ListIteratorOfListOfShape.hxx>
82#include <TopTools_DataMapOfShapeListOfShape.hxx>
83#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
84#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
85#include <TopTools_SequenceOfShape.hxx>
86#include <TopTools_ListOfShape.hxx>
87#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
88#include <TopTools_DataMapOfShapeSequenceOfShape.hxx>
89
90#include <gp.hxx>
91#include <gp_Vec.hxx>
92#include <gp_Ax2.hxx>
93#include <gp_Pln.hxx>
94#include <gp_Dir2d.hxx>
95
96#include <BRep_TVertex.hxx>
97#include <TopTools_IndexedMapOfShape.hxx>
98#include <Geom2d_BSplineCurve.hxx>
99#include <TColgp_Array1OfPnt2d.hxx>
100#include <TColStd_Array1OfReal.hxx>
101#include <TColStd_Array1OfInteger.hxx>
102#include <BRepTools_Substitution.hxx>
103#include <BRepLib_MakeVertex.hxx>
104#include <Geom2dLProp_CLProps2d.hxx>
105#include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
106#include <Standard_ErrorHandler.hxx>
107
108#ifdef DRAW
109#include <Draw.hxx>
110#include <DrawTrSurf.hxx>
111#include <DrawTrSurf_Curve2d.hxx>
112#include <DBRep.hxx>
113#endif
114
115#ifdef DEB
116static Standard_Boolean AffichGeom = Standard_False;
117static Standard_Boolean Affich2d = Standard_False;
118static Standard_Boolean AffichEdge = Standard_False;
119static Standard_Integer NbTRIMEDGES = 0;
120static Standard_Integer NbOFFSET = 0;
121static Standard_Integer NbEDGES = 0;
122static Standard_Integer NbBISSEC = 0;
123#ifndef WNT
124static char tname[100];
125static Standard_CString name = tname ;
126#endif
127#endif
128
129// Modified by Sergey KHROMOV - Thu Nov 16 17:24:39 2000 Begin
130
131static void QuasiFleche(const Adaptor3d_Curve& C,
132 const Standard_Real Deflection2,
133 const Standard_Real Udeb,
134 const gp_Pnt& Pdeb,
135 const gp_Vec& Vdeb,
136 const Standard_Real Ufin,
137 const gp_Pnt& Pfin,
138 const gp_Vec& Vfin,
139 const Standard_Integer Nbmin,
140 const Standard_Real Eps,
141 TColStd_SequenceOfReal& Parameters,
142 TColgp_SequenceOfPnt& Points);
143
144static Standard_Boolean PerformCurve (TColStd_SequenceOfReal& Parameters,
145 TColgp_SequenceOfPnt& Points,
146 const Adaptor3d_Curve& C,
147 const Standard_Real Deflection,
148 const Standard_Real U1,
149 const Standard_Real U2,
150 const Standard_Real EPSILON,
151 const Standard_Integer Nbmin);
152
153static void CheckBadEdges(const TopoDS_Face& Spine, const Standard_Real Offset,
154 const BRepMAT2d_BisectingLocus& Locus,
155 const BRepMAT2d_LinkTopoBilo& Link,
156 TopTools_ListOfShape& BadEdges);
157
158static Standard_Integer CutEdge (const TopoDS_Edge& E,
159 const TopoDS_Face& F,
160 Standard_Integer ForceCut,
161 TopTools_ListOfShape& Cuts);
162
163
164static void CutCurve (const Handle(Geom2d_TrimmedCurve)& C,
165 const Standard_Integer nbParts,
166 TColGeom2d_SequenceOfCurve& theCurves);
167// Modified by Sergey KHROMOV - Thu Nov 16 17:24:47 2000 End
168
169
170static void EdgeVertices (const TopoDS_Edge& E,
171 TopoDS_Vertex& V1,
172 TopoDS_Vertex& V2)
173{
174 if (E.Orientation() == TopAbs_REVERSED) {
175 TopExp::Vertices(E,V2,V1);
176 }
177 else {
178 TopExp::Vertices(E,V1,V2);
179 }
180}
181
182static void UpdateDetromp (TopTools_ListOfShape& Detromp1,
183 TopTools_ListOfShape& Detromp2,
184 const TopTools_SequenceOfShape& Vertices,
185 const TColgp_SequenceOfPnt& Params,
186 const Bisector_Bisec& Bisec,
187 const Standard_Boolean SOnE,
188 const Standard_Boolean EOnE,
189 const BRepFill_TrimEdgeTool& Trim);
190
191static Standard_Boolean VertexFromNode
192(const Handle(MAT_Node)& aNode,
193 const Standard_Real Offset,
194 gp_Pnt2d& PN,
195 BRepFill_DataMapOfNodeShape& MapNodeVertex,
196 TopoDS_Vertex& VN);
197
198static void StoreInMap (const TopoDS_Shape& V1,
199 const TopoDS_Shape& V2,
200 TopTools_IndexedDataMapOfShapeShape& MapVV);
201
202static void TrimEdge (const TopoDS_Edge& CurrentEdge,
203 const TopTools_ListOfShape& D,
204 TopTools_SequenceOfShape& Sv,
205 TColStd_SequenceOfReal& MapverPar,
206 TopTools_SequenceOfShape& S,
207 TopTools_IndexedDataMapOfShapeShape& MapVV);
208
209static Standard_Boolean DoubleOrNotInside (const TopTools_ListOfShape& EC,
210 const TopoDS_Vertex& V);
211
212static Standard_Boolean IsSmallClosedEdge(const TopoDS_Edge& anEdge,
213 const TopoDS_Vertex& aVertex);
214
215static void MakeCircle
216(const TopoDS_Edge& E,
217 const TopoDS_Vertex& V,
218 const TopoDS_Face& F,
219 const Standard_Real Offset,
86b3805f 220 BRepFill_IndexedDataMapOfOrientedShapeListOfShape& Map,
7fd59977 221 const Handle(Geom_Plane)& RefPlane);
222
223static void MakeOffset
224(const TopoDS_Edge& E,
225 const TopoDS_Face& F,
226 const Standard_Real Offset,
86b3805f 227 BRepFill_IndexedDataMapOfOrientedShapeListOfShape& Map,
7fd59977 228 const Handle(Geom_Plane)& RefPlane);
229
230//=======================================================================
231//function : KPartCircle
232//purpose :
233//=======================================================================
234
235static Standard_Boolean KPartCircle
236(const TopoDS_Face& mySpine,
237 const Standard_Real myOffset,
238 const Standard_Real Alt,
239 TopoDS_Shape& myShape,
86b3805f 240 BRepFill_IndexedDataMapOfOrientedShapeListOfShape& myMap,
7fd59977 241 Standard_Boolean& myIsDone)
242{
0d969553 243 // The only contour which is a closed circle
7fd59977 244 TopExp_Explorer exp(mySpine,TopAbs_EDGE);
245 Standard_Integer NbEdges = 0;
246 TopoDS_Edge E;
247
248 for (; exp.More(); exp.Next()) {
249 NbEdges++;
250 E = TopoDS::Edge(exp.Current());
251 if (NbEdges > 1) return Standard_False;
252 }
253 TopoDS_Vertex V1,V2;
254 TopExp::Vertices(E,V1,V2);
255 if (!V1.IsSame(V2)) return Standard_False;
256
257 Standard_Real f,l;
258 TopLoc_Location L;
259 Handle(Geom_Curve) C = BRep_Tool::Curve(E,L,f,l);
260
261 if (C->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
262 Handle(Geom_TrimmedCurve) Ct = Handle(Geom_TrimmedCurve)::DownCast(C);
263 C = Ct->BasisCurve();
264 }
265
266 if (!C->IsKind(STANDARD_TYPE(Geom_Circle))) return Standard_False;
267 Handle(Geom_Circle) CE = Handle(Geom_Circle)::DownCast(C);
268 Standard_Real anOffset = myOffset;
269 if (E.Orientation() == TopAbs_REVERSED) anOffset *= -1;
270
271 if (anOffset < 0. || Abs(anOffset) < CE->Radius()) {
272 Handle(Geom_Circle) OC = new Geom_Circle (CE->Position(),CE->Radius() - anOffset);
273 myShape = BRepLib_MakeEdge(OC,f,l);
274
275 myShape.Orientation(E.Orientation());
276 myShape.Location(L);
277 if (Alt != 0.) {
278 BRepAdaptor_Surface S(mySpine,0);
279 gp_Ax1 Nor = S.Plane().Axis();
280 gp_Trsf T;
281 gp_Vec Trans(Nor.Direction());
282 Trans = Alt*Trans;
283 T.SetTranslation(Trans);
284 myShape.Move(TopLoc_Location(T));
285 }
286
287 TopTools_ListOfShape LL;
288 LL.Append(myShape);
86b3805f 289 myMap.Add(E,LL);
7fd59977 290 }
291 myIsDone = Standard_True;
292 return Standard_True;
293}
294
295//=======================================================================
296//function : BRepFill_OffsetWire
297//purpose :
298//=======================================================================
299
300BRepFill_OffsetWire::BRepFill_OffsetWire()
301:myIsDone(Standard_False)
302{
303}
304
305
306//=======================================================================
307//function : BRepFill_OffsetWire
308//purpose :
309//=======================================================================
310
311BRepFill_OffsetWire::BRepFill_OffsetWire(const TopoDS_Face& Spine,
312 const GeomAbs_JoinType Join )
313{
314 Init(Spine,Join);
315}
316
317
318//=======================================================================
319//function : Init
320//purpose :
321//=======================================================================
322
323void BRepFill_OffsetWire::Init(const TopoDS_Face& Spine,
324 const GeomAbs_JoinType Join )
325{
326 Standard_NotImplemented_Raise_if(Join > GeomAbs_Arc,
327 "Only GeomAbs_Arc is implemented");
328
329 myIsDone = Standard_False;
330 TopoDS_Shape aLocalShape = Spine.Oriented(TopAbs_FORWARD);
331 mySpine = TopoDS::Face(aLocalShape);
332// mySpine = TopoDS::Face(Spine.Oriented(TopAbs_FORWARD));
333 myJoinType = Join;
334
335 myMap.Clear();
336 myMapSpine.Clear();
337 //------------------------------------------------------------------
0d969553 338 // cut the spine for bissectors.
7fd59977 339 //------------------------------------------------------------------
340// Modified by Sergey KHROMOV - Tue Nov 26 17:39:03 2002 Begin
341 static BRepMAT2d_Explorer Exp;
342
343 Exp.Perform(mySpine);
344
345// TopoDS_Face anOldSpine = mySpine;
346
347 mySpine = TopoDS::Face(Exp.ModifiedShape(mySpine));
348 PrepareSpine ();
349
350// Modified by Sergey KHROMOV - Tue Nov 26 17:39:03 2002 End
351 TopoDS_Shape aShape;
86b3805f 352 BRepFill_IndexedDataMapOfOrientedShapeListOfShape aMap;
7fd59977 353 Standard_Boolean Done;
354 if (KPartCircle(myWorkSpine,1.,0.,aShape,aMap,Done)) return;
355
356
357 //-----------------------------------------------------
0d969553
Y
358 // Calculate the map of bissectors to the left.
359 // and Links Topology -> base elements of the map.
7fd59977 360 //-----------------------------------------------------
361
362// Modified by Sergey KHROMOV - Tue Nov 26 17:39:03 2002 Begin
363// static BRepMAT2d_Explorer Exp;
364// Modified by Sergey KHROMOV - Tue Nov 26 17:39:03 2002 End
365 Exp.Perform(myWorkSpine);
366 myBilo.Compute(Exp,1,MAT_Left);
367 myLink.Perform(Exp,myBilo);
368}
369
370
371//=======================================================================
372//function : IsDone
373//purpose :
374//=======================================================================
375
376Standard_Boolean BRepFill_OffsetWire::IsDone() const
377{
378 return myIsDone;
379}
380
381
382//=======================================================================
383//function : Spine
384//purpose :
385//=======================================================================
386
387const TopoDS_Face& BRepFill_OffsetWire::Spine() const
388{
389 return mySpine;
390}
391
392
393//=======================================================================
394//function : Shape
395//purpose :
396//=======================================================================
397
398const TopoDS_Shape& BRepFill_OffsetWire::Shape() const
399{
400 return myShape;
401}
402
403
404//=======================================================================
405//function : GeneratedShapes
406//purpose :
407//=======================================================================
408
409const TopTools_ListOfShape& BRepFill_OffsetWire::GeneratedShapes
410(const TopoDS_Shape& SpineShape)
411{
412 if (!myCallGen) {
413 if (!myMapSpine.IsEmpty()) {
0d969553 414 // myMapSpine can be empty if passed by PerformWithBilo.
7fd59977 415 TopTools_DataMapIteratorOfDataMapOfShapeShape it(myMapSpine);
416 for (; it.More(); it.Next()) {
86b3805f
J
417 if (myMap.Contains(it.Key())) {
418 if (!myMap.Contains(it.Value())) {
7fd59977 419 TopTools_ListOfShape L;
86b3805f 420 myMap.Add(it.Value(),L);
7fd59977 421 }
422 if ( !it.Value().IsSame(it.Key())) {
86b3805f
J
423 myMap.ChangeFromKey(it.Value()).Append(myMap.ChangeFromKey(it.Key()));
424 //myMap.UnBind(it.Key());
425 TopoDS_Shape LastShape = myMap.FindKey(myMap.Extent());
426 TopTools_ListOfShape LastList;
427 LastList.Append(myMap(myMap.Extent()));
428 myMap.RemoveLast();
429 if (myMap.FindIndex(it.Key()) != 0)
430 myMap.Substitute(myMap.FindIndex(it.Key()), LastShape, LastList);
7fd59977 431 }
432 }
86b3805f
J
433 if (myMap.Contains(it.Key().Reversed())) {
434 if (!myMap.Contains(it.Value().Reversed())) {
7fd59977 435 TopTools_ListOfShape L;
86b3805f 436 myMap.Add(it.Value().Reversed(),L);
7fd59977 437 }
438 if ( !it.Value().IsSame(it.Key())) {
86b3805f
J
439 myMap.ChangeFromKey(it.Value().Reversed()).Append(myMap.ChangeFromKey(it.Key().Reversed()));
440 //myMap.UnBind(it.Key().Reversed());
441 TopoDS_Shape LastShape = myMap.FindKey(myMap.Extent());
442 TopTools_ListOfShape LastList;
443 LastList.Append(myMap(myMap.Extent()));
444 myMap.RemoveLast();
445 if (myMap.FindIndex(it.Key().Reversed()) != 0)
446 myMap.Substitute(myMap.FindIndex(it.Key().Reversed()), LastShape, LastList);
7fd59977 447 }
448 }
449 }
450 }
451 myCallGen = Standard_True;
452 }
453
86b3805f
J
454 if (myMap.Contains(SpineShape)) {
455 return myMap.FindFromKey(SpineShape);
7fd59977 456 }
457 else {
458 static TopTools_ListOfShape Empty;
459 return Empty;
460 }
461}
462
463
464//=======================================================================
465//function : JoinType
466//purpose :
467//=======================================================================
468
469GeomAbs_JoinType BRepFill_OffsetWire::JoinType() const
470{
471 return myJoinType;
472}
473
474//=======================================================================
475//function : Perform
476//purpose :
477//=======================================================================
478
479void BRepFill_OffsetWire::Perform (const Standard_Real Offset,
480 const Standard_Real Alt)
481{
482// Modified by skv - Fri Jul 8 11:21:38 2005 OCC9145 Begin
483 try {
484 OCC_CATCH_SIGNALS
485 myCallGen = Standard_False;
486 if (KPartCircle(mySpine,Offset,Alt,myShape,myMap,myIsDone)) return;
487
488 TopoDS_Face oldWorkSpain = myWorkSpine;
489
490 TopTools_ListOfShape BadEdges;
491 CheckBadEdges(myWorkSpine,Offset,myBilo,myLink,BadEdges);
492
493 if(!BadEdges.IsEmpty()) {
494 // Modification of myWorkSpine;
495 //cout << "Modification of myWorkSpine : " << BadEdges.Extent() << endl;
496 BRepTools_Substitution aSubst;
497 TopTools_ListIteratorOfListOfShape it(BadEdges);
498 TopTools_ListOfShape aL;
499 Standard_Real aDefl = .01 * Abs(Offset);
500 TColStd_SequenceOfReal Parameters;
501 TColgp_SequenceOfPnt Points;
502
503 for(; it.More(); it.Next()) {
504 aL.Clear();
505 Parameters.Clear();
506 Points.Clear();
507 const TopoDS_Shape& anE = it.Value();
508 TopoDS_Vertex Vf, Vl;
509 TopExp::Vertices(TopoDS::Edge(anE), Vf, Vl);
510
511 Standard_Real f, l;
512 Handle(Geom_Curve) G3d = BRep_Tool::Curve(TopoDS::Edge(anE),f,l);
513 GeomAdaptor_Curve AC(G3d,f,l);
514
515 Standard_Boolean dummy = PerformCurve(Parameters, Points,
516 AC, aDefl, f, l, Precision::Confusion(),
517 2);
518
519 Standard_Integer NPnts = Points.Length();
520 if(NPnts > 2) {
521 //cout << NPnts << " points " << endl;
522 TopoDS_Vertex FV = Vf;
523 TopoDS_Vertex LV;
524 TopoDS_Edge newE;
525 Standard_Integer np;
526 for(np = 2; np < NPnts; np++) {
527 gp_Pnt LP = Points(np);
528 LV = BRepLib_MakeVertex(LP);
529 newE = BRepLib_MakeEdge(FV, LV);
530 aL.Append(newE);
531 FV = LV;
532 }
533 LV = Vl;
534 newE = BRepLib_MakeEdge(FV, LV);
535 aL.Append(newE);
536 }
537 else {
538 //cout << " 2 points " << endl;
539 TopoDS_Edge newE = BRepLib_MakeEdge(Vf, Vl);
540 aL.Append(newE);
541 }
542 //Update myMapSpine
543 if (myMapSpine.IsBound( anE ))
544 {
545 TopTools_ListIteratorOfListOfShape newit( aL );
546 for (; newit.More(); newit.Next())
547 {
548 TopoDS_Edge NewEdge = TopoDS::Edge( newit.Value() );
549 myMapSpine.Bind( NewEdge, myMapSpine(anE) );
550 TopoDS_Vertex NewV1, NewV2;
551 EdgeVertices( NewEdge, NewV1, NewV2 );
552 if (!myMapSpine.IsBound(NewV1)) myMapSpine.Bind( NewV1, myMapSpine(anE) );
553 if (!myMapSpine.IsBound(NewV2)) myMapSpine.Bind( NewV2, myMapSpine(anE) );
554 }
555 myMapSpine.UnBind( anE );
556 }
557 ///////////////////
558 aSubst.Substitute(anE, aL);
559 }
560
561 TopTools_DataMapOfShapeListOfShape wwmap;
562 TopoDS_Iterator itws( myWorkSpine );
563 for (; itws.More(); itws.Next())
564 {
565 TopoDS_Shape aWire = itws.Value();
566 aSubst.Build( aWire );
567 if (aSubst.IsCopied(aWire))
568 {
569 TopoDS_Wire NewWire = TopoDS::Wire( aSubst.Copy(aWire).First() );
570 NewWire.Closed( aWire.Closed() );
571 TopTools_ListOfShape Lw;
572 Lw.Append( NewWire );
573 wwmap.Bind( aWire, Lw );
574 }
575 }
576 aSubst.Clear();
577 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itmap( wwmap );
578 for (; itmap.More(); itmap.Next())
579 aSubst.Substitute( itmap.Key(), itmap.Value() );
580 aSubst.Build(myWorkSpine);
581 if(aSubst.IsCopied(myWorkSpine)) {
582 myWorkSpine = TopoDS::Face(aSubst.Copy(myWorkSpine).First());
583 //sprintf(name,"WS1");
584 //DBRep::Set(name,myWorkSpine);
585
586 BRepMAT2d_Explorer newExp;
587 newExp.Perform(myWorkSpine);
588 BRepMAT2d_BisectingLocus newBilo;
589 BRepMAT2d_LinkTopoBilo newLink;
590 newBilo.Compute(newExp,1,MAT_Left);
591 newLink.Perform(newExp,newBilo);
592 PerformWithBiLo(myWorkSpine,Offset,newBilo,newLink,myJoinType,Alt);
593
594 myWorkSpine = oldWorkSpain;
595 }
596 else {
597 PerformWithBiLo(myWorkSpine,Offset,myBilo,myLink,myJoinType,Alt);
598 }
599
600 }
601 else {
602 PerformWithBiLo(myWorkSpine,Offset,myBilo,myLink,myJoinType,Alt);
603 }
604
605 } catch (Standard_Failure) {
606 myShape.Nullify();
607 myIsDone = Standard_False;
608
609 return;
610 }
611// Modified by skv - Fri Jul 8 11:21:38 2005 OCC9145 End
612// Modified by Sergey KHROMOV - Thu Mar 14 10:48:15 2002 Begin
613 TopExp_Explorer anExp(myShape, TopAbs_WIRE);
614
615 for (; anExp.More(); anExp.Next()) {
616 const TopoDS_Shape &aWire = anExp.Current();
617
618 if (!aWire.Closed()) {
619 myShape.Nullify();
620 myIsDone = Standard_False;
621 Standard_ConstructionError::Raise("Offset wire is not closed.");
622 }
623 }
624// Modified by Sergey KHROMOV - Thu Mar 14 10:48:16 2002 End
625}
626
627//=======================================================================
628//function : Compute
629//purpose :
630//=======================================================================
631
632void Compute (const TopoDS_Face& Spine,
633 TopoDS_Shape& aShape,
86b3805f 634 BRepFill_IndexedDataMapOfOrientedShapeListOfShape& Map,
7fd59977 635 const Standard_Real Alt)
636{
637 BRep_Builder B;
638 B.MakeCompound(TopoDS::Compound(aShape));
639 Standard_Real ALT = Alt;
640 if ( Spine.Orientation() == TopAbs_REVERSED) ALT = -Alt;
641 gp_Trsf T;
642 T.SetTranslation(gp_Vec(0.,0.,ALT));
643 TopLoc_Location L(T);
644
645 for ( TopExp_Explorer exp(Spine,TopAbs_WIRE); exp.More(); exp.Next()) {
646 const TopoDS_Wire& CurW = TopoDS::Wire(exp.Current());
647 TopoDS_Shape aLocalShape = CurW.Moved(L);
648 TopoDS_Wire NewW = TopoDS::Wire(aLocalShape);
649// TopoDS_Wire NewW = TopoDS::Wire(CurW.Moved(L));
650 B.Add(aShape,NewW);
0d969553 651 // update Map.
7fd59977 652 TopoDS_Iterator it1( CurW);
653 TopoDS_Iterator it2( NewW);
654 for ( ; it1.More(); it1.Next(), it2.Next()) {
655 TopTools_ListOfShape List;
656 List.Append(it2.Value());
86b3805f 657 Map.Add(it1.Value(), List);
7fd59977 658 }
659 }
660}
661
662//=======================================================================
663//function : PerformWithBiLo
664//purpose :
665//=======================================================================
666
667void BRepFill_OffsetWire::PerformWithBiLo
668(const TopoDS_Face& Spine,
669 const Standard_Real Offset,
670 const BRepMAT2d_BisectingLocus& Locus,
671 BRepMAT2d_LinkTopoBilo& Link,
672 const GeomAbs_JoinType Join,
673 const Standard_Real Alt)
674{
675 Standard_NotImplemented_Raise_if (Join > GeomAbs_Arc,
676 "Only GeomAbs_Arc is implemented");
677
678 myIsDone = Standard_False;
679 TopoDS_Shape aLocalShape = Spine.Oriented(TopAbs_FORWARD);
680 myWorkSpine = TopoDS::Face(aLocalShape);
681// myWorkSpine = TopoDS::Face(Spine.Oriented(TopAbs_FORWARD));
682 myJoinType = Join;
683 myOffset = Offset ;
684 myShape.Nullify();
685
686
687 if (mySpine.IsNull()) {
688 TopoDS_Shape aLocalShape = Spine.Oriented(TopAbs_FORWARD);
689 mySpine = TopoDS::Face(aLocalShape);
690// mySpine = TopoDS::Face(Spine.Oriented(TopAbs_FORWARD));
691}
692 myMap.Clear();
693
7fd59977 694 if ( Abs(myOffset) < Precision::Confusion()) {
695 Compute(mySpine,myShape,myMap,Alt);
696 myIsDone = Standard_True;
697 return;
698 }
699
0d969553
Y
700 //********************************
701 // Calculate for a non null offset
702 //********************************
7fd59977 703 if (KPartCircle(mySpine,Offset,Alt,myShape,myMap,myIsDone)) return;
704
705 BRep_Builder myBuilder;
706 myBuilder.MakeCompound(TopoDS::Compound(myShape));
707
708 //---------------------------------------------------------------------
0d969553
Y
709 // MapNodeVertex : associate to each node of the map (key1) and to
710 // each element of the profile (key2) a vertex (item).
711 // MapBis : all edges or vertices (item) generated by
712 // a bisectrice on a face or an edge (key) of revolution tubes.
713 // MapVerPar : Map of parameters of vertices on parallel edges
714 // the list contained in MapVerPar (E) corresponds to
715 // parameters on E of vertices contained in MapBis(E);
7fd59977 716 //---------------------------------------------------------------------
717
718
719 BRepFill_DataMapOfNodeShape MapNodeVertex;
720 TopTools_DataMapOfShapeSequenceOfShape MapBis;
721 BRepFill_DataMapOfShapeSequenceOfReal MapVerPar;
722
723 TopTools_DataMapOfShapeShape EmptyMap;
724 TopTools_SequenceOfShape EmptySeq;
725 TopTools_ListOfShape EmptyList;
726 TColStd_SequenceOfReal EmptySeqOfReal;
727
728 Standard_Real ALT = Alt;
729 Handle(Geom_Plane) RefPlane =
730 Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(myWorkSpine));
731 if ( myWorkSpine.Orientation() == TopAbs_REVERSED) ALT = -Alt;
732 RefPlane = Handle(Geom_Plane)::DownCast
733 (RefPlane->Translated( ALT * gp_Vec(RefPlane->Axis().Direction() )));
734
735 //---------------------------------------------------------------
0d969553 736 // Construction of Circles and OffsetCurves
7fd59977 737 //---------------------------------------------------------------
738
739 for (Standard_Integer ic = 1; ic <= Locus.NumberOfContours(); ic++) {
740 TopoDS_Shape PEE = Link.GeneratingShape(Locus.BasicElt(ic,Locus.NumberOfElts(ic)));
741 TopoDS_Shape& PE = PEE ;
742 for (Standard_Integer ie = 1; ie <= Locus.NumberOfElts(ic); ie++) {
743 const TopoDS_Shape& SE = Link.GeneratingShape(Locus.BasicElt(ic,ie));
744 if (SE.ShapeType() == TopAbs_VERTEX) {
745 MakeCircle (TopoDS::Edge(PE),TopoDS::Vertex(SE),
746 myWorkSpine,myOffset,myMap,RefPlane);
747 }
748 else {
749 MakeOffset (TopoDS::Edge(SE),myWorkSpine,myOffset,myMap,RefPlane);
750 PE = SE;
751 }
752 }
753 }
754
755
756#ifdef DEB
757 if (AffichEdge) {
0d969553 758 cout << " End Construction of geometric primitives "<<endl;
7fd59977 759 }
760#endif
761
762
763 //---------------------------------------------------
0d969553 764 // Construction of offset vertices.
7fd59977 765 //---------------------------------------------------
766 BRepFill_DataMapOfOrientedShapeListOfShape Detromp;
767 Handle(MAT_Arc) CurrentArc;
768 Handle(Geom2d_Curve) Bis, PCurve1, PCurve2 ;
769 Handle(Geom_Curve) CBis;
770 Standard_Boolean Reverse;
771 TopoDS_Edge CurrentEdge;
772 TopoDS_Shape S [2];
773 TopoDS_Edge E [2];
774 TopLoc_Location L;
86b3805f 775 Standard_Integer j, k;
7fd59977 776
777 for (Standard_Integer i = 1; i <= Locus.Graph()->NumberOfArcs(); i++) {
778
779 CurrentArc = Locus.Graph()->Arc(i);
780 Bisector_Bisec Bisec = Locus.GeomBis(CurrentArc,Reverse);
781
782#ifdef DRAW
783 if ( AffichGeom) {
784 sprintf(name,"BISSEC_%d",NbBISSEC++);
785 DrawTrSurf::Set(name,Bisec.Value());
786 }
787#endif
788
0d969553
Y
789 //-------------------------------------------------------------------
790 // Return elements of the spine corresponding to separate basicElts.
791 //-------------------------------------------------------------------
7fd59977 792 S [0] = Link.GeneratingShape(CurrentArc->FirstElement());
793 S [1] = Link.GeneratingShape(CurrentArc->SecondElement());
794
795 TopTools_SequenceOfShape Vertices;
796 TColgp_SequenceOfPnt Params;
797
798 TopTools_DataMapOfShapeSequenceOfShape MapSeqVer;
799 BRepFill_DataMapOfShapeSequenceOfPnt MapSeqPar;
800
801 //-----------------------------------------------------------
0d969553
Y
802 // Return parallel edges on each face.
803 // If no offset generated => move to the next bissectrice.
7fd59977 804 //--------------------------------------------------------------
86b3805f
J
805 if (myMap.Contains(S[0]) && myMap.Contains(S[1])) {
806 E [0] = TopoDS::Edge(myMap.FindFromKey(S[0]).First());
807 E [1] = TopoDS::Edge(myMap.FindFromKey(S[1]).First());
7fd59977 808 }
809 else continue;
810
811 //-----------------------------------------------------------
0d969553
Y
812 // Construction of vertices corresponding to the node of the map.
813 // if they are on the offset.
7fd59977 814 //-----------------------------------------------------------
815 TopoDS_Vertex VS,VE;
816 Handle(MAT_Node) Node1, Node2;
817
818 if (Reverse) {
819 Node1 = CurrentArc->SecondNode();
820 Node2 = CurrentArc->FirstNode();
821 }
822 else {
823 Node1 = CurrentArc->FirstNode();
824 Node2 = CurrentArc->SecondNode();
825 }
826
827 Standard_Boolean StartOnEdge = 0, EndOnEdge = 0;
828
829 if (!Node1->Infinite()) {
830 gp_Pnt2d aLocalPnt2d = Locus.GeomElt(Node1);
831 StartOnEdge = VertexFromNode(Node1, myOffset, aLocalPnt2d ,MapNodeVertex,VS);
832// StartOnEdge = VertexFromNode(Node1, myOffset, Locus.GeomElt(Node1),
833// MapNodeVertex,VS);
834 }
835 if (!Node2->Infinite()) {
836 gp_Pnt2d aLocalPnt2d = Locus.GeomElt(Node2) ;
837 EndOnEdge = VertexFromNode(Node2, myOffset, aLocalPnt2d ,MapNodeVertex,VE);
838// EndOnEdge = VertexFromNode(Node2, myOffset, Locus.GeomElt(Node2),
839// MapNodeVertex,VE);
840 }
841
842 //---------------------------------------------
0d969553 843 // Construction of geometries.
7fd59977 844 //---------------------------------------------
845 BRepFill_TrimEdgeTool Trim (Bisec,
846 Locus.GeomElt(CurrentArc->FirstElement()),
847 Locus.GeomElt(CurrentArc->SecondElement()),
848 myOffset);
849
850 //-----------------------------------------------------------
0d969553 851 // Construction of vertices on edges parallel to the spine.
7fd59977 852 //-----------------------------------------------------------
853
854 Trim.IntersectWith(E [0], E [1], Params);
855
856 for (Standard_Integer s = 1; s <= Params.Length(); s++) {
857 TopoDS_Vertex VC;
858 myBuilder.MakeVertex (VC);
859 gp_Pnt2d P2 = Bisec.Value()->Value(Params.Value(s).X());
860 gp_Pnt PVC(P2.X(),P2.Y(),0.);
861
862 myBuilder.UpdateVertex(VC,PVC,Precision::Confusion());
863 Vertices.Append(VC);
864 }
865 if (StartOnEdge) {
866 Standard_Boolean Start = 1;
867 Trim.AddOrConfuse(Start, E[0], E[1], Params);
868 if (Params.Length() == Vertices.Length())
869 Vertices.SetValue(1,VS);
870
871 else
0d969553 872 // the point was not found by IntersectWith
7fd59977 873 Vertices.Prepend(VS);
874 }
875 if (EndOnEdge) {
876 Standard_Boolean Start = 0;
877 Trim.AddOrConfuse(Start, E[0], E[1], Params);
878 if (Params.Length() == Vertices.Length())
879 Vertices.SetValue(Params.Length(),VE);
880
881 else
0d969553 882 // the point was not found by IntersectWith
7fd59977 883 Vertices.Append(VE);
884 }
885
886 //------------------------------------------------------------
0d969553
Y
887 // Update Detromp.
888 // Detromp allows to remove vertices on the offset
889 // corresponding to tangency zones
890 // Detromp ranks the vertices that limit
891 // the parts of the bissectrices located between the spine and the
892 // offset.
7fd59977 893 //------------------------------------------------------------
894 if (!Detromp.IsBound(S[0])) Detromp.Bind(S[0],EmptyList);
895 if (!Detromp.IsBound(S[1])) Detromp.Bind(S[1],EmptyList);
896
897
898 UpdateDetromp (Detromp(S[0]), Detromp(S[1]), Vertices, Params,
899 Bisec, StartOnEdge, EndOnEdge, Trim);
900 //----------------------------------------------
0d969553
Y
901 // Storage of vertices on parallel edges.
902 // fill MapBis and MapVerPar.
7fd59977 903 //----------------------------------------------
904 if (!Vertices.IsEmpty()) {
905 for (k = 0; k <= 1; k++) {
906 if (!MapBis.IsBound(E[k])) {
907 MapBis .Bind(E[k],EmptySeq);
908 MapVerPar.Bind(E[k],EmptySeqOfReal);
909 }
910 for (Standard_Integer ii = 1; ii <= Vertices.Length(); ii++) {
911 MapBis (E[k]).Append(Vertices.Value(ii));
912 if (k == 0) MapVerPar (E[k]).Append(Params.Value(ii).Y());
913 else MapVerPar (E[k]).Append(Params.Value(ii).Z());
914 }
915 }
916 }
917 else {
918 //------------------------------------------------------------
0d969553
Y
919 // FOR COMPLETE CIRCLES. the parallel line can be contained
920 // in the zone without intersection with the border
921 // no intersection
922 // if myoffset is < distance of nodes the parallel can be valid.
7fd59977 923 //-------------------------------------------------------------
924 for (k = 0; k <= 1; k++) {
925 if (!MapBis.IsBound(E[k])) {
926 if (Node1->Distance() > myOffset && Node2->Distance() > myOffset) {
927 MapBis .Bind(E[k],EmptySeq);
928 MapVerPar.Bind(E[k],EmptySeqOfReal);
929 }
930 }
931 }
932 }
933 }
934
935#ifdef DEB
936 if (AffichEdge) {
0d969553 937 cout << " End Construction of vertices on offsets"<<endl;
7fd59977 938 }
939#endif
940
941 //----------------------------------
0d969553 942 // Construction of parallel edges.
7fd59977 943 //----------------------------------
944 TopTools_IndexedDataMapOfShapeShape MapVV;
945
946 TopoDS_Shape CurrentSpine;
947
86b3805f 948 //BRepFill_DataMapIteratorOfDataMapOfOrientedShapeListOfShape ite1;
7fd59977 949
86b3805f
J
950 for (j = 1; j <= myMap.Extent(); j++) {
951 CurrentSpine = myMap.FindKey(j);
952 CurrentEdge = TopoDS::Edge(myMap(j).First());
7fd59977 953
86b3805f 954 myMap(j).Clear();
7fd59977 955 if (MapBis.IsBound(CurrentEdge)) {
956 TopTools_SequenceOfShape S;
957 if (!MapBis(CurrentEdge).IsEmpty()) {
958 TrimEdge (CurrentEdge,
959 Detromp (CurrentSpine),
960 MapBis (CurrentEdge) ,
961 MapVerPar(CurrentEdge) ,
962 S, MapVV);
963 for ( k = 1; k <= S.Length(); k++) {
86b3805f 964 myMap(j).Append(S.Value(k));
7fd59977 965 }
966 }
967 else {
968 //-----------------
0d969553 969 // Complete circles
7fd59977 970 //-----------------
86b3805f 971 myMap(j).Append(CurrentEdge);
7fd59977 972 }
973 }
974 }
975
976 Standard_Integer ind;
977 for (ind = 1; ind <= MapVV.Extent(); ind++)
978 {
979 TopoDS_Vertex OldV = TopoDS::Vertex(MapVV.FindKey(ind));
980 TopoDS_Vertex NewV = TopoDS::Vertex(MapVV(ind));
981 gp_Pnt P1 = BRep_Tool::Pnt(OldV);
982 gp_Pnt P2 = BRep_Tool::Pnt(NewV);
983 myBuilder.UpdateVertex(NewV, P1.Distance(P2));
984 TopTools_ListOfShape LV;
985 LV.Append( NewV.Oriented(TopAbs_FORWARD) );
986 BRepTools_Substitution aSubst;
987 aSubst.Substitute( OldV, LV );
86b3805f 988 for (j = 1; j <= myMap.Extent(); j++)
7fd59977 989 {
86b3805f 990 TopTools_ListIteratorOfListOfShape itl(myMap(j));
7fd59977 991 for (; itl.More(); itl.Next())
992 {
993 aSubst.Build(itl.Value());
994 if (aSubst.IsCopied(itl.Value()))
995 {
996 const TopTools_ListOfShape& listSh = aSubst.Copy(itl.Value());
86b3805f 997 TopAbs_Orientation SaveOr = itl.Value().Orientation();
7fd59977 998 itl.Value() = listSh.First();
86b3805f 999 itl.Value().Orientation(SaveOr);
7fd59977 1000 }
1001 }
1002 }
1003 }
1004
1005 //----------------------------------
0d969553 1006 // Construction of offset wires.
7fd59977 1007 //----------------------------------
1008 MakeWires ();
1009
0d969553 1010 // Update vertices ( Constructed in the plane Z = 0) !!!
7fd59977 1011 TopTools_MapOfShape MapVertex;
1012 for ( TopExp_Explorer exp(myShape,TopAbs_VERTEX); exp.More(); exp.Next()) {
1013 TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
1014 if ( MapVertex.Add(V)) {
1015 gp_Pnt P = BRep_Tool::Pnt(V);
1016 P = RefPlane->Value(P.X(),P.Y());
1017 myBuilder.UpdateVertex(V,P, Precision::Confusion());
1018 }
1019 }
1020
0d969553 1021 // Construction of curves 3d.
7fd59977 1022 BRepLib::BuildCurves3d(myShape);
1023 MapVertex.Clear();
1024 TopExp_Explorer Explo( myShape, TopAbs_EDGE );
1025 for (; Explo.More(); Explo.Next())
1026 {
1027 TopoDS_Edge E = TopoDS::Edge( Explo.Current() );
1028 TopoDS_Vertex V1, V2;
1029 TopExp::Vertices( E, V1, V2 );
1030 Handle(BRep_TVertex)& TV1 = *((Handle(BRep_TVertex)*) &(V1).TShape());
1031 Handle(BRep_TVertex)& TV2 = *((Handle(BRep_TVertex)*) &(V2).TShape());
1032
1033 TopLoc_Location loc;
1034 Standard_Real f, l;
1035 Handle( Geom_Curve ) theCurve = BRep_Tool::Curve( E, loc, f, l );
1036 theCurve = Handle( Geom_Curve )::DownCast( theCurve->Copy() );
1037 theCurve->Transform( loc.Transformation() );
1038 gp_Pnt f3d = theCurve->Value( f );
1039 gp_Pnt l3d = theCurve->Value( l );
1040
1041 Standard_Real dist1, dist2;
1042 dist1 = f3d.Distance( TV1->Pnt() );
1043 dist2 = l3d.Distance( TV2->Pnt() );
1044 if (! MapVertex.Contains( V1 ))
1045 {
1046 TV1->Pnt( f3d );
1047 MapVertex.Add( V1 );
1048 }
1049 else
1050 TV1->UpdateTolerance( 1.5*dist1 );
1051 if (! MapVertex.Contains( V2 ))
1052 {
1053 TV2->Pnt( l3d );
1054 MapVertex.Add( V2 );
1055 }
1056 else
1057 TV2->UpdateTolerance( 1.5*dist2 );
1058 }
1059
1060 FixHoles();
1061
1062 myIsDone = Standard_True;
1063}
1064
1065
1066//=======================================================================
1067//function : Generated
1068//purpose :
1069//=======================================================================
1070
86b3805f 1071BRepFill_IndexedDataMapOfOrientedShapeListOfShape&
7fd59977 1072BRepFill_OffsetWire::Generated()
1073{
1074 return myMap;
1075}
1076
1077
1078//=======================================================================
1079//function : PrepareSpine
1080//purpose :
1081//=======================================================================
1082
1083void BRepFill_OffsetWire::PrepareSpine()
1084{
1085 BRep_Builder B;
1086 TopTools_ListOfShape Cuts;
1087 TopTools_ListIteratorOfListOfShape IteCuts;
1088 TopoDS_Vertex V1,V2;
1089
1090 myWorkSpine.Nullify();
1091 myMapSpine.Clear();
1092
1093 TopLoc_Location L;
1094 const Handle(Geom_Surface)& S = BRep_Tool::Surface (mySpine,L);
1095 Standard_Real TolF = BRep_Tool::Tolerance(mySpine);
1096 B.MakeFace(myWorkSpine,S,L,TolF);
1097
1098 for (TopoDS_Iterator IteF(mySpine) ; IteF.More(); IteF.Next()) {
1099
1100 TopoDS_Wire NW;
1101 B.MakeWire (NW);
1102
1103// Modified by Sergey KHROMOV - Thu Nov 16 17:29:55 2000 Begin
1104 Standard_Integer ForcedCut = 0;
1105 Standard_Integer nbResEdges = -1;
1106 TopTools_IndexedMapOfShape EdgeMap;
1107
1108 TopExp::MapShapes(IteF.Value(), TopAbs_EDGE, EdgeMap);
1109 Standard_Integer nbEdges = EdgeMap.Extent();
1110
1111 if (nbEdges == 1)
1112 ForcedCut = 2;
1113// Modified by Sergey KHROMOV - Thu Nov 16 17:29:48 2000 End
1114
1115 for (TopoDS_Iterator IteW(IteF.Value()); IteW.More(); IteW.Next()) {
1116
1117 const TopoDS_Edge& E = TopoDS::Edge(IteW.Value());
1118 EdgeVertices(E,V1,V2);
1119 myMapSpine.Bind(V1,V1);
1120 myMapSpine.Bind(V2,V2);
1121 Cuts.Clear();
1122
0d969553 1123 // Cut
7fd59977 1124 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
1125// Modified by Sergey KHROMOV - Thu Nov 16 17:29:29 2000 Begin
1126 if (nbEdges == 2 && nbResEdges == 0)
1127 ForcedCut = 1;
1128// Modified by Sergey KHROMOV - Thu Nov 16 17:29:33 2000 End
1129 nbResEdges = CutEdge (TopoDS::Edge(aLocalShape), mySpine, ForcedCut, Cuts);
1130
1131 if (Cuts.IsEmpty()) {
1132 B.Add(NW,E);
1133 myMapSpine.Bind(E,E);
1134 }
1135 else {
1136 for (IteCuts.Initialize(Cuts); IteCuts.More(); IteCuts.Next()) {
1137 TopoDS_Edge NE = TopoDS::Edge(IteCuts.Value());
1138 NE.Orientation(E.Orientation());
1139 B.Add(NW,NE);
1140 myMapSpine.Bind(NE,E);
1141 EdgeVertices(NE,V1,V2);
1142 if (!myMapSpine.IsBound(V1)) myMapSpine.Bind(V1,E);
1143 if (!myMapSpine.IsBound(V2)) myMapSpine.Bind(V2,E);
1144 }
1145 }
1146 }
1147// Modified by Sergey KHROMOV - Thu Mar 7 09:17:41 2002 Begin
1148 TopoDS_Vertex aV1;
1149 TopoDS_Vertex aV2;
1150
1151 TopExp::Vertices(NW, aV1, aV2);
1152
1153 NW.Closed(aV1.IsSame(aV2));
1154// Modified by Sergey KHROMOV - Thu Mar 7 09:17:43 2002 End
1155 B.Add(myWorkSpine, NW);
1156 }
1157
1158#ifdef DRAW
1159 if ( AffichEdge) {
1160 sprintf(name,"WS");
1161 DBRep::Set(name,myWorkSpine);
1162 }
1163#endif
1164
1165}
1166
1167//=======================================================================
1168//function : MakeWires
1169//purpose :
1170//=======================================================================
1171
1172void BRepFill_OffsetWire::MakeWires()
1173{
1174 //--------------------------------------------------------
0d969553 1175 // creation of a single list of created parallel edges.
7fd59977 1176 //--------------------------------------------------------
1177 TopTools_SequenceOfShape TheEdges;
1178 TopTools_ListOfShape TheWires;
1179 TopTools_ListIteratorOfListOfShape itl;
86b3805f
J
1180 //BRepFill_DataMapIteratorOfDataMapOfOrientedShapeListOfShape ite;
1181 TopTools_IndexedDataMapOfShapeListOfShape MVE;
1182 //TopTools_DataMapIteratorOfDataMapOfShapeListOfShape MVEit;
7fd59977 1183 TopoDS_Vertex V1,V2,VF,CV;
86b3805f 1184 Standard_Integer i;
7fd59977 1185
86b3805f
J
1186 for (i = 1; i <= myMap.Extent(); i++) {
1187 for (itl.Initialize(myMap(i)); itl.More(); itl.Next()) {
7fd59977 1188 const TopoDS_Edge& E = TopoDS::Edge(itl.Value());
1189 TopExp::Vertices (E,V1,V2);
1190 if (V1.IsSame(V2) && IsSmallClosedEdge(E, V1))
1191 continue; //remove small closed edges
86b3805f 1192 if (!MVE.Contains(V1)) {
7fd59977 1193 TopTools_ListOfShape empty;
86b3805f 1194 MVE.Add(V1,empty);
7fd59977 1195 }
86b3805f
J
1196 MVE.ChangeFromKey(V1).Append(E);
1197 if (!MVE.Contains(V2)) {
7fd59977 1198 TopTools_ListOfShape empty;
86b3805f 1199 MVE.Add(V2,empty);
7fd59977 1200 }
86b3805f 1201 MVE.ChangeFromKey(V2).Append(E);
7fd59977 1202 }
1203 }
1204
1205 //--------------------------------------
0d969553 1206 // Creation of parallel wires.
7fd59977 1207 //--------------------------------------
1208 BRep_Builder B;
1209
1210// Standard_Integer NbEdges;
1211// Standard_Boolean NewWire = Standard_True;
1212// Standard_Boolean AddEdge = Standard_False;
1213
1214 TopoDS_Wire NW;
1215 Standard_Boolean End;
1216 TopoDS_Edge CE;
1217
1218 while (!MVE.IsEmpty()) {
1219 B.MakeWire(NW);
1220
86b3805f
J
1221 //MVEit.Initialize(MVE);
1222 for (i = 1; i <= MVE.Extent(); i++)
1223 if(MVE(i).Extent() == 1)
1224 break;
7fd59977 1225
86b3805f
J
1226 //if(!MVEit.More()) MVEit.Initialize(MVE);
1227 if (i > MVE.Extent())
1228 i = 1;
7fd59977 1229
86b3805f
J
1230 CV = VF = TopoDS::Vertex(MVE.FindKey(i));
1231 CE = TopoDS::Edge(MVE(i).First());
7fd59977 1232 End = Standard_False;
86b3805f 1233 MVE.ChangeFromKey(CV).RemoveFirst();
7fd59977 1234
1235// Modified by Sergey KHROMOV - Thu Mar 14 11:29:59 2002 Begin
1236 Standard_Boolean isClosed = Standard_False;
1237// Modified by Sergey KHROMOV - Thu Mar 14 11:30:00 2002 End
1238
1239 while(!End) {
1240 //-------------------------------
0d969553 1241 // Construction of a wire.
7fd59977 1242 //-------------------------------
1243 TopExp::Vertices(CE,V1,V2);
1244 if (!CV.IsSame(V1)) CV = V1; else CV = V2;
1245
1246 B.Add (NW,CE);
1247
86b3805f 1248 if (VF.IsSame(CV) || !MVE.Contains(CV)) {
7fd59977 1249// Modified by Sergey KHROMOV - Thu Mar 14 11:30:14 2002 Begin
1250 isClosed = VF.IsSame(CV);
1251// Modified by Sergey KHROMOV - Thu Mar 14 11:30:15 2002 End
1252 End = Standard_True;
86b3805f
J
1253 //MVE.UnBind(VF);
1254 TopoDS_Shape LastShape = MVE.FindKey(MVE.Extent());
1255 TopTools_ListOfShape LastList;
1256 LastList.Append(MVE(MVE.Extent()));
1257 MVE.RemoveLast();
1258 if (MVE.FindIndex(VF) != 0)
1259 MVE.Substitute(MVE.FindIndex(VF), LastShape, LastList);
7fd59977 1260 }
1261
1262 if (!End) {
86b3805f 1263 if (MVE.FindFromKey(CV).Extent() > 2) {
0d969553 1264 //cout <<"vertex on more that 2 edges in a face."<<endl;
7fd59977 1265 }
86b3805f 1266 for ( itl.Initialize(MVE.FindFromKey(CV)); itl.More(); itl.Next()) {
7fd59977 1267 if (itl.Value().IsSame(CE)) {
86b3805f 1268 MVE.ChangeFromKey(CV).Remove(itl);
7fd59977 1269 break;
1270 }
1271 }
86b3805f
J
1272 if (!MVE.FindFromKey(CV).IsEmpty()) {
1273 CE = TopoDS::Edge(MVE.FindFromKey(CV).First());
1274 MVE.ChangeFromKey(CV).RemoveFirst();
7fd59977 1275 }
86b3805f
J
1276 if (MVE.FindFromKey(CV).IsEmpty())
1277 {
1278 //MVE.UnBind(CV);
1279 TopoDS_Shape LastShape = MVE.FindKey(MVE.Extent());
1280 TopTools_ListOfShape LastList;
1281 LastList.Append(MVE(MVE.Extent()));
1282 MVE.RemoveLast();
1283 if (MVE.FindIndex(CV) != 0)
1284 MVE.Substitute(MVE.FindIndex(CV), LastShape, LastList);
1285 }
7fd59977 1286 }
1287 }
1288// Modified by Sergey KHROMOV - Thu Mar 14 11:29:31 2002 Begin
1289// NW.Closed(Standard_True);
1290 NW.Closed(isClosed);
1291// Modified by Sergey KHROMOV - Thu Mar 14 11:29:37 2002 End
1292 TheWires.Append(NW);
1293 }
1294
0d969553
Y
1295 // update myShape :
1296 // -- if only one wire : myShape is a Wire
1297 // -- if several wires : myShape is a Compound.
7fd59977 1298 if ( TheWires.Extent() == 1) {
1299 myShape = TheWires.First();
1300 }
1301 else {
1302 TopoDS_Compound R;
1303 B.MakeCompound(R);
1304 TopTools_ListIteratorOfListOfShape it(TheWires);
1305 for ( ; it.More(); it.Next()) {
1306 B.Add(R, it.Value());
1307 }
1308 myShape = R;
1309 }
1310
1311}
1312
1313//=======================================================================
1314//function : FixHoles
1315//purpose :
1316//=======================================================================
1317
1318void BRepFill_OffsetWire::FixHoles()
1319{
1320 TopTools_SequenceOfShape ClosedWires, UnclosedWires, IsolatedWires;
1321
1322 Standard_Real MaxTol = 0.;
1323 Standard_Integer i;
1324 BRep_Builder BB;
1325
1326 TopExp_Explorer Explo( mySpine, TopAbs_VERTEX );
1327 for (; Explo.More(); Explo.Next())
1328 {
1329 const TopoDS_Vertex& aVertex = TopoDS::Vertex( Explo.Current() );
1330 Standard_Real Tol = BRep_Tool::Tolerance(aVertex);
1331 if (Tol > MaxTol)
1332 MaxTol = Tol;
1333 }
1334 MaxTol *= 100.;
1335
1336 Explo.Init( myShape, TopAbs_WIRE );
1337 for (; Explo.More(); Explo.Next())
1338 {
1339 TopoDS_Shape aWire = Explo.Current();
1340 // Remove duplicated edges
1341 TopTools_DataMapOfShapeListOfShape EEmap;
1342 TopoDS_Iterator it( aWire );
1343 for (; it.More(); it.Next())
1344 {
1345 const TopoDS_Shape& anEdge = it.Value();
1346 if (! EEmap.IsBound( anEdge ))
1347 {
1348 TopTools_ListOfShape LE;
1349 EEmap.Bind( anEdge, LE );
1350 }
1351 else
1352 EEmap(anEdge).Append( anEdge );
1353 }
1354 aWire.Free( Standard_True );
1355 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape mapit( EEmap );
1356 for (; mapit.More(); mapit.Next())
1357 {
1358 const TopTools_ListOfShape& LE = mapit.Value();
1359 TopTools_ListIteratorOfListOfShape itl( LE );
1360 for (; itl.More(); itl.Next())
1361 BB.Remove( aWire, itl.Value() );
1362 }
1363 // Sorting
1364 if (aWire.Closed())
1365 ClosedWires.Append( aWire );
1366 else
1367 UnclosedWires.Append( aWire );
1368 }
1369
1370 while (!UnclosedWires.IsEmpty())
1371 {
1372 TopoDS_Wire& Base = TopoDS::Wire( UnclosedWires(1) );
1373 TopoDS_Vertex Vf, Vl;
1374 TopExp::Vertices( Base, Vf, Vl );
1375 gp_Pnt Pf, Pl;
1376 Pf = BRep_Tool::Pnt(Vf);
1377 Pl = BRep_Tool::Pnt(Vl);
1378 Standard_Real DistF = RealLast(), DistL = RealLast();
1379 Standard_Integer IndexF, IndexL;
1380 Standard_Boolean IsFirstF, IsFirstL;
1381 for (Standard_Integer i = 2; i <= UnclosedWires.Length(); i++)
1382 {
1383 TopoDS_Wire aWire = TopoDS::Wire( UnclosedWires(i) );
1384 TopoDS_Vertex V1, V2;
1385 TopExp::Vertices( aWire, V1, V2 );
1386 gp_Pnt P1, P2;
1387 P1 = BRep_Tool::Pnt(V1);
1388 P2 = BRep_Tool::Pnt(V2);
1389 Standard_Real dist = Pf.Distance( P1 );
1390 if (dist < DistF)
1391 {
1392 DistF = dist;
1393 IndexF = i;
1394 IsFirstF = Standard_True;
1395 }
1396 dist = Pf.Distance( P2 );
1397 if (dist < DistF)
1398 {
1399 DistF = dist;
1400 IndexF = i;
1401 IsFirstF = Standard_False;
1402 }
1403 dist = Pl.Distance( P1 );
1404 if (dist < DistL)
1405 {
1406 DistL = dist;
1407 IndexL = i;
1408 IsFirstL = Standard_True;
1409 }
1410 dist = Pl.Distance( P2 );
1411 if (dist < DistL)
1412 {
1413 DistL = dist;
1414 IndexL = i;
1415 IsFirstL = Standard_False;
1416 }
1417 }
1418 TopoDS_Wire theWire;
1419 TopoDS_Edge theEdge;
1420 TopoDS_Vertex theVertex;
1421 Standard_Real CommonTol;
1422 Standard_Boolean TryToClose = Standard_True;
1423 if (DistF <= MaxTol && DistL <= MaxTol && IndexF == IndexL && IsFirstF == IsFirstL)
1424 {
1425 if (DistF < DistL)
1426 {
1427 DistL = RealLast();
1428 IndexL++;
1429 }
1430 else
1431 {
1432 DistF = RealLast();
1433 IndexF++;
1434 }
1435 TryToClose = Standard_False;
1436 }
1437 if (DistF <= MaxTol)
1438 {
1439 theWire = TopoDS::Wire( UnclosedWires(IndexF) );
1440 TopoDS_Vertex V1, V2;
1441 TopExp::Vertices( theWire, V1, V2 );
1442 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
1443 TopExp::MapShapesAndAncestors( theWire, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
1444 theEdge = (IsFirstF)? TopoDS::Edge(VEmap.FindFromKey( V1 ).First()) :
1445 TopoDS::Edge(VEmap.FindFromKey( V2 ).First());
1446 TopoDS_Iterator it( theWire );
1447 for (; it.More(); it.Next())
1448 {
1449 TopoDS_Edge anEdge = TopoDS::Edge( it.Value() );
1450 if (IsFirstF) anEdge.Reverse();
1451 if (!anEdge.IsSame( theEdge ))
1452 BB.Add( Base, anEdge );
1453 }
1454 theVertex = (IsFirstF)? V1 : V2;
1455 CommonTol = Max( BRep_Tool::Tolerance(Vf), BRep_Tool::Tolerance(theVertex) );
1456 if (DistF <= CommonTol)
1457 {
1458 theEdge.Free( Standard_True );
1459 Vf.Orientation( theVertex.Orientation() );
1460 BB.Remove( theEdge, theVertex );
1461 BB.Add( theEdge, Vf );
1462 BB.UpdateVertex( Vf, CommonTol );
1463 if (IsFirstF) theEdge.Reverse();
1464 BB.Add( Base, theEdge );
1465 }
1466 else
1467 {
1468 if (IsFirstF) theEdge.Reverse();
1469 BB.Add( Base, theEdge );
1470 // Creating new edge from theVertex to Vf
1471 TopoDS_Edge NewEdge = BRepLib_MakeEdge( theVertex, Vf );
1472 BB.Add( Base, NewEdge );
1473 }
1474 }
1475 if (DistL <= MaxTol && IndexL != IndexF)
1476 {
1477 theWire = TopoDS::Wire( UnclosedWires(IndexL) );
1478 TopoDS_Vertex V1, V2;
1479 TopExp::Vertices( theWire, V1, V2 );
1480 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
1481 TopExp::MapShapesAndAncestors( theWire, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
1482 theEdge = (IsFirstL)? TopoDS::Edge(VEmap.FindFromKey( V1 ).First()) :
1483 TopoDS::Edge(VEmap.FindFromKey( V2 ).First());
1484 TopoDS_Iterator it( theWire );
1485 for (; it.More(); it.Next())
1486 {
1487 TopoDS_Edge anEdge = TopoDS::Edge( it.Value() );
1488 if (!IsFirstL) anEdge.Reverse();
1489 if (!anEdge.IsSame( theEdge ))
1490 BB.Add( Base, anEdge );
1491 }
1492 theVertex = (IsFirstL)? V1 : V2;
1493 CommonTol = Max( BRep_Tool::Tolerance(Vl), BRep_Tool::Tolerance(theVertex) );
1494 if (DistL <= CommonTol)
1495 {
1496 theEdge.Free( Standard_True );
1497 Vl.Orientation( theVertex.Orientation() );
1498 BB.Remove( theEdge, theVertex );
1499 BB.Add( theEdge, Vl );
1500 BB.UpdateVertex( Vl, CommonTol );
1501 if (!IsFirstL) theEdge.Reverse();
1502 BB.Add( Base, theEdge );
1503 }
1504 else
1505 {
1506 if (!IsFirstL) theEdge.Reverse();
1507 BB.Add( Base, theEdge );
1508 // Creating new edge from Vl to theVertex
1509 TopoDS_Edge NewEdge = BRepLib_MakeEdge( Vl, theVertex );
1510 BB.Add( Base, NewEdge );
1511 }
1512 }
1513 // Check if it is possible to close resulting wire
1514 if (TryToClose)
1515 {
1516 TopExp::Vertices( Base, Vf, Vl );
1517 CommonTol = Max( BRep_Tool::Tolerance(Vf), BRep_Tool::Tolerance(Vl) );
1518 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
1519 TopExp::MapShapesAndAncestors( Base, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
1520 TopoDS_Edge Efirst, Elast;
1521 Efirst = TopoDS::Edge(VEmap.FindFromKey( Vf ).First());
1522 Elast = TopoDS::Edge(VEmap.FindFromKey( Vl ).First());
1523 Pf = BRep_Tool::Pnt(Vf);
1524 Pl = BRep_Tool::Pnt(Vl);
1525 Standard_Real Dist = Pf.Distance(Pl);
1526 if (Dist <= CommonTol)
1527 {
1528 Elast.Free( Standard_True );
1529 Vf.Orientation( Vl.Orientation() );
1530 BB.Remove( Elast, Vl );
1531 BB.Add( Elast, Vf );
1532 BB.UpdateVertex( Vf, CommonTol );
1533 Base.Closed( Standard_True );
1534 }
1535 else if (Dist <= MaxTol)
1536 {
1537 // Creating new edge from Vl to Vf
1538 TopoDS_Edge NewEdge = BRepLib_MakeEdge( Vf, Vl );
1539 BB.Add( Base, NewEdge );
1540 Base.Closed( Standard_True );
1541 }
1542 }
1543 // Updating sequences ClosedWires and UnclosedWires
1544 if (DistF <= MaxTol)
1545 UnclosedWires.Remove( IndexF );
1546 if (DistL <= MaxTol && IndexL != IndexF)
1547 {
1548 if (DistF <= MaxTol && IndexL > IndexF)
1549 IndexL--;
1550 UnclosedWires.Remove( IndexL );
1551 }
1552 if (Base.Closed())
1553 {
1554 ClosedWires.Append( Base );
1555 UnclosedWires.Remove( 1 );
1556 }
1557 else if (DistF > MaxTol && DistL > MaxTol)
1558 {
1559 IsolatedWires.Append( Base );
1560 UnclosedWires.Remove( 1 );
1561 }
1562 }
1563
1564 // Updating myShape
1565 if (ClosedWires.Length() + IsolatedWires.Length() == 1)
1566 {
1567 if (!ClosedWires.IsEmpty())
1568 myShape = ClosedWires.First();
1569 else
1570 myShape = IsolatedWires.First();
1571 }
1572 else
1573 {
1574 TopoDS_Compound R;
1575 BB.MakeCompound( R );
1576 for (i = 1; i <= ClosedWires.Length(); i++)
1577 BB.Add( R, ClosedWires(i) );
1578 for (i = 1; i <= IsolatedWires.Length(); i++)
1579 BB.Add( R, IsolatedWires(i) );
1580 myShape = R;
1581 }
1582}
1583
1584//=======================================================================
1585//function : CutEdge
0d969553
Y
1586//purpose : Cut edge at the extrema of curvatures and points of inflexion.
1587// So, closed circles are cut in two.
1588// If <Cuts> is empty, the edge is not modified.
1589// The first and the last vertex of the initial edge
1590// belong to the first and the last parts respectively.
7fd59977 1591//=======================================================================
1592Standard_Integer CutEdge (const TopoDS_Edge& E,
1593 const TopoDS_Face& F,
1594 Standard_Integer ForceCut,
1595 TopTools_ListOfShape& Cuts)
1596{
1597 Cuts.Clear();
1598 MAT2d_CutCurve Cuter;
1599 TColGeom2d_SequenceOfCurve theCurves;
1600 Standard_Real f,l;
1601 Handle(Geom2d_Curve) C2d;
1602 Handle(Geom2d_TrimmedCurve) CT2d;
1603// Modified by Sergey KHROMOV - Wed Mar 6 17:36:25 2002 Begin
1604 Standard_Real aTol = BRep_Tool::Tolerance(E);
1605 Handle(Geom_Curve) aC;
1606// Modified by Sergey KHROMOV - Wed Mar 6 17:36:25 2002 End
1607
1608 TopoDS_Vertex V1,V2,VF,VL;
1609 TopExp::Vertices (E,V1,V2);
1610 BRep_Builder B;
1611
1612 C2d = BRep_Tool::CurveOnSurface (E,F,f,l);
1613// Modified by Sergey KHROMOV - Wed Mar 6 17:36:54 2002 Begin
1614 aC = BRep_Tool::Curve(E,f,l);
1615// Modified by Sergey KHROMOV - Wed Mar 6 17:36:54 2002 End
1616 CT2d = new Geom2d_TrimmedCurve(C2d,f,l);
1617 //if (E.Orientation() == TopAbs_REVERSED) CT2d->Reverse();
1618
1619 if (CT2d->BasisCurve()->IsKind(STANDARD_TYPE(Geom2d_Circle)) &&
c6541a0c 1620 ( Abs(f-l) >= M_PI) ) {
7fd59977 1621 return 0;
7fd59977 1622 }
1623
1624 //-------------------------
0d969553 1625 // Cut curve.
7fd59977 1626 //-------------------------
1627 Cuter.Perform(CT2d);
1628
1629// Modified by Sergey KHROMOV - Thu Nov 16 17:28:29 2000 Begin
1630 if (ForceCut == 0) {
1631 if (Cuter.UnModified()) {
1632 //-----------------------------
0d969553 1633 // edge not modified => return.
7fd59977 1634 //-----------------------------
1635 return 0;
1636 } else {
1637 for (Standard_Integer k = 1; k <= Cuter.NbCurves(); k++)
1638 theCurves.Append(Cuter.Value(k));
1639 }
1640 } else if (ForceCut == 1) {
1641 if (Cuter.UnModified()) {
1642 CutCurve (CT2d, 2, theCurves);
1643 } else {
1644 for (Standard_Integer k = 1; k <= Cuter.NbCurves(); k++)
1645 theCurves.Append(Cuter.Value(k));
1646 }
1647 } else if (ForceCut == 2) {
1648 if (Cuter.UnModified()) {
1649 CutCurve (CT2d, 3, theCurves);
1650 } else {
1651 if (Cuter.NbCurves() == 2) {
1652 Handle(Geom2d_TrimmedCurve)CC = Cuter.Value(1);
1653
1654 if (CC->LastParameter() > (l+f)/2.) {
1655 CutCurve (CC, 2, theCurves);
1656 theCurves.Append(Cuter.Value(2));
1657 } else {
1658 theCurves.Append(CC);
1659 CutCurve (Cuter.Value(2), 2, theCurves);
1660 }
1661 } else {
1662 for (Standard_Integer k = 1; k <= Cuter.NbCurves(); k++)
1663 theCurves.Append(Cuter.Value(k));
1664 }
1665 }
1666 }
1667// Modified by Sergey KHROMOV - Thu Nov 16 17:28:37 2000 End
1668
1669 //--------------------------------------
0d969553 1670 // Creation of cut edges.
7fd59977 1671 //--------------------------------------
1672 VF = V1;
1673
1674 for (Standard_Integer k = 1; k <= theCurves.Length(); k++) {
1675
1676 Handle(Geom2d_TrimmedCurve)CC = Handle(Geom2d_TrimmedCurve)::DownCast(theCurves.Value(k));
1677
1678 if (k == theCurves.Length()) {VL = V2;}
1679 else {
1680// Modified by Sergey KHROMOV - Wed Mar 6 17:38:02 2002 Begin
1681 gp_Pnt P = aC->Value(CC->LastParameter());
1682
1683 VL = BRepLib_MakeVertex(P);
1684 B.UpdateVertex(VL, aTol);
1685// Modified by Sergey KHROMOV - Wed Mar 6 17:38:05 2002 End
1686 }
1687 TopoDS_Shape aLocalShape = E.EmptyCopied();
1688 TopoDS_Edge NE = TopoDS::Edge(aLocalShape);
1689// TopoDS_Edge NE = TopoDS::Edge(E.EmptyCopied());
1690 NE.Orientation(TopAbs_FORWARD);
1691 B.Add (NE,VF.Oriented(TopAbs_FORWARD));
1692 B.Add (NE,VL.Oriented(TopAbs_REVERSED));
1693 B.Range(NE,CC->FirstParameter(),CC->LastParameter());
1694 Cuts.Append(NE.Oriented(E.Orientation()));
1695 VF = VL;
1696 }
1697
1698 return theCurves.Length();
1699}
1700
1701// Modified by Sergey KHROMOV - Thu Nov 16 17:27:56 2000 Begin
1702//=======================================================================
1703//function : CutCurve
1704//purpose :
1705//=======================================================================
1706
1707void CutCurve (const Handle(Geom2d_TrimmedCurve)& C,
1708 const Standard_Integer nbParts,
1709 TColGeom2d_SequenceOfCurve& theCurves)
1710{
1711 Handle(Geom2d_TrimmedCurve) TrimC;
1712 Standard_Real UF,UL,UC;
1713 Standard_Real Step;
1714 gp_Pnt2d PF,PL,PC;
1715 Standard_Real PTol = Precision::PConfusion()*10;
1716 Standard_Real Tol = Precision::Confusion()*10;
1717 Standard_Boolean YaCut = Standard_False;
1718
1719 UF = C->FirstParameter();
1720 UL = C->LastParameter ();
1721 PF = C->Value(UF);
1722 PL = C->Value(UL);
1723
1724 Step = (UL - UF)/nbParts;
1725
1726 for (Standard_Integer i = 1; i < nbParts; i++) {
1727
1728 UC = UF + i*Step;
1729 PC = C->Value(UC);
1730
1731 if (UC - UF > PTol && PC.Distance(PF) > Tol) {
1732 if ( UL - UC < PTol || PL.Distance(PC) < Tol)
1733 continue;
1734
1735 TrimC = new Geom2d_TrimmedCurve(C,UF,UC);
1736 theCurves.Append(TrimC);
1737 UF = UC;
1738 PF = PC;
1739 YaCut = Standard_True;
1740 }
1741 }
1742 if (YaCut) {
1743 TrimC = new Geom2d_TrimmedCurve(C,UF,UL);
1744 theCurves.Append(TrimC);
1745 } else
1746 theCurves.Append(C);
1747}
1748// Modified by Sergey KHROMOV - Thu Nov 16 17:28:13 2000 End
1749
1750//=======================================================================
1751//function : MakeCircle
1752//purpose :
1753//=======================================================================
1754
1755void MakeCircle (const TopoDS_Edge& E,
1756 const TopoDS_Vertex& V,
1757 const TopoDS_Face& F,
1758 const Standard_Real Offset,
86b3805f 1759 BRepFill_IndexedDataMapOfOrientedShapeListOfShape& Map,
7fd59977 1760 const Handle(Geom_Plane)& RefPlane)
1761{
0d969553 1762 // evaluate the Axis of the Circle.
7fd59977 1763 Standard_Real f,l;
1764 Handle(Geom2d_Curve) GC = BRep_Tool::CurveOnSurface(E,F,f,l);
1765 gp_Vec2d DX;
1766 gp_Pnt2d P;
1767
1768 if (E.Orientation() == TopAbs_FORWARD) {
1769 GC->D1(l,P,DX);
1770 DX.Reverse();
1771 }
1772 else GC->D1(f,P,DX);
1773
1774 gp_Ax2d Axis(P,gp_Dir2d(DX));
1775 Handle(Geom2d_Circle) Circ
1776 = new Geom2d_Circle(Axis, Abs(Offset), Offset < 0.);
1777
1778 // Bind the edges in my Map.
1779 TopoDS_Edge OE = BRepLib_MakeEdge(Circ, RefPlane);
1780 TopTools_ListOfShape LL;
1781
1782 LL.Append(OE);
86b3805f 1783 Map.Add(V,LL);
7fd59977 1784
1785#ifdef DRAW
1786 if ( AffichGeom && !OE.IsNull()) {
1787 sprintf(name,"OFFSET_%d",++NbOFFSET);
1788 DBRep::Set(name,OE);
1789 }
1790#endif
1791}
1792
1793//=======================================================================
1794//function : MakeOffset
1795//purpose :
1796//=======================================================================
1797
1798void MakeOffset (const TopoDS_Edge& E,
1799 const TopoDS_Face& F,
1800 const Standard_Real Offset,
86b3805f 1801 BRepFill_IndexedDataMapOfOrientedShapeListOfShape& Map,
7fd59977 1802 const Handle(Geom_Plane)& RefPlane)
1803{
1804 Standard_Real f,l;
1805 Standard_Real anOffset = Offset;
1806
1807 if (E.Orientation() == TopAbs_REVERSED) anOffset *= -1;
1808
1809 Handle(Geom2d_Curve) G2d = BRep_Tool::CurveOnSurface(E,F,f,l);
1810 Handle(Geom2d_Curve) G2dOC;
1811
1812 Geom2dAdaptor_Curve AC(G2d,f,l);
1813 if ( AC.GetType() == GeomAbs_Circle) {
0d969553
Y
1814 // if the offset is greater otr equal to the radius and the side of the
1815 // concavity of the circle => edge null.
7fd59977 1816 gp_Circ2d C1(AC.Circle());
7fd59977 1817 gp_Ax22d axes( C1.Axis());
1818 gp_Dir2d Xd = axes.XDirection();
1819 gp_Dir2d Yd = axes.YDirection();
1820 Standard_Real Crossed = Xd.X()*Yd.Y()-Xd.Y()*Yd.X();
1821 Standard_Real Signe = ( Crossed > 0.) ? 1. : -1.;
1822
1823 if (anOffset*Signe < AC.Circle().Radius()) {
0d969553 1824
7fd59977 1825 Handle(Geom2dAdaptor_HCurve) AHC =
1826 new Geom2dAdaptor_HCurve(G2d);
1827 Adaptor3d_OffsetCurve Off(AHC,-anOffset);
1828 Handle(Geom2d_Circle) CC = new Geom2d_Circle(Off.Circle());
1829
c6541a0c 1830 Standard_Real Delta = 2*M_PI - l + f;
7fd59977 1831 f -= 0.2*Delta; l += 0.2*Delta;
1832
1833 G2dOC = new Geom2d_TrimmedCurve(CC,f,l);
1834 }
1835 }
1836 else if (AC.GetType() == GeomAbs_Line) {
1837 Handle(Geom2dAdaptor_HCurve) AHC =
1838 new Geom2dAdaptor_HCurve(G2d);
1839 Adaptor3d_OffsetCurve Off(AHC,anOffset);
1840 Handle(Geom2d_Line) CC = new Geom2d_Line(Off.Line());
1841 Standard_Real Delta = (l - f);
1842 f -= Delta; l += Delta;
1843 G2dOC = new Geom2d_TrimmedCurve(CC,f,l);
1844 }
1845 else {
1846
1847 anOffset = -anOffset;
1848 Handle(Geom2d_TrimmedCurve) G2dT = new Geom2d_TrimmedCurve(G2d,f,l);
1849 G2dOC = new Geom2d_OffsetCurve( G2dT, anOffset);
1850
1851 }
1852
1853 // Bind the edges in my Map.
1854 if (!G2dOC.IsNull()) {
1855 TopoDS_Edge OE = BRepLib_MakeEdge(G2dOC, RefPlane);
1856 OE.Orientation(E.Orientation());
1857 TopTools_ListOfShape LL;
1858 LL.Append(OE);
86b3805f 1859 Map.Add(E,LL);
7fd59977 1860
1861#ifdef DRAW
1862 if (AffichGeom && !OE.IsNull()) {
1863 sprintf(name,"OFFSET_%d",++NbOFFSET);
1864 DBRep::Set(name,OE);
1865 Standard_Real ii = 0;
1866 }
1867#endif
1868
1869 }
1870}
1871
1872//=======================================================================
1873//function : UpdateDetromp
0d969553
Y
1874//purpose : For each interval on bissectrice defined by parameters
1875// test if the medium point is at a distance > offset
1876// in this case vertices corresponding to the extremities of the interval
1877// are ranked in the proofing.
1878// => If the same vertex appears in the proofing, the
1879// border of the zone of proximity is tangent to the offset .
7fd59977 1880//=======================================================================
1881
1882void UpdateDetromp (TopTools_ListOfShape& Detromp1,
1883 TopTools_ListOfShape& Detromp2,
1884 const TopTools_SequenceOfShape& Vertices,
1885 const TColgp_SequenceOfPnt& Params,
1886 const Bisector_Bisec& Bisec,
1887 const Standard_Boolean SOnE,
1888 const Standard_Boolean EOnE,
1889 const BRepFill_TrimEdgeTool& Trim)
1890{
1891 Standard_Integer ii = 1;
1892 Standard_Real U1,U2;
1893 TopoDS_Vertex V1,V2;
1894
1895 Handle(Geom2d_Curve) Bis = Bisec.Value();
1896
1897 U1 = Bis->FirstParameter();
1898
1899 if (SOnE) {
0d969553 1900 // the first point of the bissectrice is on the offset
7fd59977 1901 V1 = TopoDS::Vertex(Vertices.Value(ii));
1902 ii++;
1903 }
1904
1905 while (ii <= Vertices.Length()) {
1906 U2 = Params.Value(ii).X();
1907 V2 = TopoDS::Vertex(Vertices.Value(ii));
1908
1909 gp_Pnt2d P = Bis->Value((U2 + U1)*0.5);
1910 if (!Trim.IsInside(P)) {
1911 if (!V1.IsNull()) {
1912 Detromp1.Append(V1);
1913 Detromp2.Append(V1);
1914 }
1915 Detromp1.Append(V2);
1916 Detromp2.Append(V2);
1917 }
1918 U1 = U2;
1919 V1 = V2;
1920 ii ++;
1921 }
1922
0d969553 1923 // test medium point between the last parameter and the end of the bissectrice.
7fd59977 1924 U2 = Bis->LastParameter();
1925 if (!EOnE) {
1926 if (!Precision::IsInfinite(U2)) {
1927 gp_Pnt2d P = Bis->Value((U2 + U1)*0.5);
1928 if (!Trim.IsInside(P)) {
1929 if (!V1.IsNull()) {
1930 Detromp1.Append(V1);
1931 Detromp2.Append(V1);
1932 }
1933 }
1934 }
1935 else {
1936 if (!V1.IsNull()) {
1937 Detromp1.Append(V1);
1938 Detromp2.Append(V1);
1939 }
1940 }
1941 }
1942}
1943
1944//=======================================================================
1945//function : VertexFromNode
1946//purpose :
1947//=======================================================================
1948
1949Standard_Boolean VertexFromNode (const Handle(MAT_Node)& aNode,
1950 const Standard_Real Offset,
1951 gp_Pnt2d& PN,
1952 BRepFill_DataMapOfNodeShape& MapNodeVertex,
1953 TopoDS_Vertex& VN)
1954{
1955 Standard_Boolean Status;
1956 Standard_Real Tol = Precision::Confusion();
1957 BRep_Builder B;
1958
1959 if (!aNode->Infinite() && Abs(aNode->Distance()-Offset) < Tol) {
1960 //------------------------------------------------
0d969553 1961 // the Node gives a vertex on the offset
7fd59977 1962 //------------------------------------------------
1963 if (MapNodeVertex.IsBound(aNode)) {
1964 VN = TopoDS::Vertex(MapNodeVertex(aNode));
1965 }
1966 else {
1967 gp_Pnt P(PN.X(),PN.Y(),0.);
1968 B.MakeVertex (VN);
1969 B.UpdateVertex(VN,P, Precision::Confusion());
1970 MapNodeVertex.Bind(aNode,VN);
1971 }
1972 Status = Standard_True;
1973 }
1974 else Status = Standard_False;
1975
1976 return Status;
1977}
1978
1979
1980//=======================================================================
1981//function : StoreInMap
1982//purpose :
1983//=======================================================================
1984
1985void StoreInMap (const TopoDS_Shape& V1,
1986 const TopoDS_Shape& V2,
1987 TopTools_IndexedDataMapOfShapeShape& MapVV)
1988{
1989 TopoDS_Shape OldV = V1, NewV = V2;
1990 Standard_Integer i;
1991
1992 if (MapVV.Contains(V2))
1993 NewV = MapVV.FindFromKey(V2);
1994
1995 if (MapVV.Contains(V1))
1996 MapVV.ChangeFromKey(V1) = NewV;
1997
1998 for (i = 1; i <= MapVV.Extent(); i++)
1999 if (MapVV(i).IsSame(V1))
2000 MapVV(i) = NewV;
2001
2002 MapVV.Add(V1, NewV);
2003}
2004
2005//=======================================================================
2006//function : TrimEdge
2007//purpose :
2008//=======================================================================
2009
2010void TrimEdge (const TopoDS_Edge& E,
2011 const TopTools_ListOfShape& Detromp,
2012 TopTools_SequenceOfShape& TheVer,
2013 TColStd_SequenceOfReal& ThePar,
2014 TopTools_SequenceOfShape& S,
2015 TopTools_IndexedDataMapOfShapeShape& MapVV)
2016{
2017 Standard_Boolean Change = Standard_True;
2018 BRep_Builder TheBuilder;
2019 S.Clear();
2020
2021 //-----------------------------------------------------------
0d969553 2022 // Parse two sequences depending on the parameter on the edge.
7fd59977 2023 //-----------------------------------------------------------
2024 while (Change) {
2025 Change = Standard_False;
2026 for (Standard_Integer i = 1; i < ThePar.Length(); i++) {
2027 if (ThePar.Value(i) > ThePar.Value(i+1)) {
2028 ThePar.Exchange(i,i+1);
2029 TheVer.Exchange(i,i+1);
2030 Change = Standard_True;
2031 }
2032 }
2033 }
2034
2035 //----------------------------------------------------------
0d969553 2036 // If a vertex is not in the proofing, it is eliminated.
7fd59977 2037 //----------------------------------------------------------
2038 if (!BRep_Tool::Degenerated(E)) {
2039 for (Standard_Integer k = 1; k <= TheVer.Length(); k ++) {
2040 if ( DoubleOrNotInside (Detromp,
2041 TopoDS::Vertex(TheVer.Value(k)))) {
2042 TheVer.Remove(k);
2043 ThePar.Remove(k);
2044 k--;
2045 }
2046 }
2047 }
2048
2049 //----------------------------------------------------------
0d969553
Y
2050 // If a vertex_double appears twice in the proofing
2051 // the vertex is removed.
2052 // otherwise preserve only one of its representations.
7fd59977 2053 //----------------------------------------------------------
2054 if (!BRep_Tool::Degenerated(E)) {
2055 for (Standard_Integer k = 1; k < TheVer.Length(); k ++) {
2056 if (TheVer.Value(k).IsSame(TheVer.Value(k+1)) ||
2057 Abs(ThePar.Value(k)-ThePar.Value(k+1)) <= Precision::PConfusion()) {
2058
2059 if(k+1 == TheVer.Length()) {
2060 StoreInMap(TheVer(k), TheVer(k+1), MapVV);
2061 TheVer.Remove(k);
2062 ThePar.Remove(k);
2063 }
2064 else {
2065 StoreInMap(TheVer(k+1), TheVer(k), MapVV);
2066 TheVer.Remove(k+1);
2067 ThePar.Remove(k+1);
2068 }
2069 /*
2070 if ( DoubleOrNotInside (Detromp,
2071 TopoDS::Vertex(TheVer.Value(k)))) {
2072 TheVer.Remove(k);
2073 ThePar.Remove(k);
2074 k--;
2075 }
2076 */
2077 k--;
2078 }
2079 }
2080 }
2081 //-----------------------------------------------------------
0d969553
Y
2082 // Creation of edges.
2083 // the number of vertices should be even. The created edges
2084 // go from a vertex with uneven index i to vertex i+1;
7fd59977 2085 //-----------------------------------------------------------
2086 for (Standard_Integer k = 1; k < TheVer.Length(); k = k+2) {
2087 TopoDS_Shape aLocalShape = E.EmptyCopied();
2088 TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
2089// TopoDS_Edge NewEdge = TopoDS::Edge(E.EmptyCopied());
2090
2091 if (NewEdge.Orientation() == TopAbs_REVERSED) {
2092 TheBuilder.Add (NewEdge,TheVer.Value(k) .Oriented(TopAbs_REVERSED));
2093 TheBuilder.Add (NewEdge,TheVer.Value(k+1).Oriented(TopAbs_FORWARD));
2094 }
2095 else {
2096 TheBuilder.Add (NewEdge,TheVer.Value(k) .Oriented(TopAbs_FORWARD));
2097 TheBuilder.Add (NewEdge,TheVer.Value(k+1).Oriented(TopAbs_REVERSED));
2098 }
2099
2100
2101 TheBuilder.Range(NewEdge,ThePar.Value(k),ThePar.Value(k+1));
2102
2103#ifdef DRAW
2104 if ( AffichEdge) {
2105 sprintf(name,"TRIMEDGE_%d",NbTRIMEDGES);
2106 DBRep::Set(name,NewEdge);
2107 }
2108 if (Affich2d) {
2109 TopLoc_Location L;
2110 Standard_Real f,l;
2111 Handle(Geom_Surface) Surf;
2112 Handle(Geom2d_Curve) C;
2113 BRep_Tool::CurveOnSurface(NewEdge,C,Surf,L,f,l);
2114 sprintf(name,"OFFSET2d_%d",NbTRIMEDGES++);
2115 Handle(Geom2d_TrimmedCurve) C2d = new Geom2d_TrimmedCurve(C,f,l);
2116 Handle(DrawTrSurf_Curve2d) dr =
2117 new DrawTrSurf_Curve2d(C2d,Standard_False);
2118 dr->SetColor(Draw_bleu);
2119 Draw::Set(name,dr);
2120 }
2121#endif
2122
2123 S.Append(NewEdge);
2124 }
2125}
2126
2127//=======================================================================
2128//function : DoubleOrNotInside
0d969553 2129//purpose : return True if V appears twice in LV or is not inside.
7fd59977 2130//=======================================================================
2131
2132Standard_Boolean DoubleOrNotInside (const TopTools_ListOfShape& LV,
2133 const TopoDS_Vertex& V)
2134{
2135 Standard_Boolean Vu = Standard_False;
2136 TopTools_ListIteratorOfListOfShape it(LV);
2137
2138 for ( ; it.More(); it.Next()) {
2139 if (V.IsSame(it.Value())) {
2140 if (Vu) return Standard_True;
2141 else Vu = Standard_True;
2142 }
2143 }
2144 if (Vu) return Standard_False;
2145 else return Standard_True;
2146}
2147
2148Standard_Boolean IsSmallClosedEdge(const TopoDS_Edge& anEdge,
2149 const TopoDS_Vertex& aVertex)
2150{
2151 gp_Pnt PV = BRep_Tool::Pnt(aVertex);
2152 gp_Pnt2d PV2d, Pfirst, Plast, Pmid;
2153 PV2d.SetCoord( PV.X(), PV.Y() );
2154
2155 Handle(Geom2d_Curve) PCurve;
2156 Handle( BRep_CurveRepresentation ) CurveRep =
2157 ((Handle(BRep_TEdge)::DownCast(anEdge.TShape()))->Curves()).First();
2158 PCurve = CurveRep->PCurve();
2159
2160 Standard_Real fpar = (Handle(BRep_GCurve)::DownCast(CurveRep))->First();
2161 Standard_Real lpar = (Handle(BRep_GCurve)::DownCast(CurveRep))->Last();
2162 Pfirst = PCurve->Value(fpar);
2163 Plast = PCurve->Value(lpar);
2164 Pmid = PCurve->Value((fpar + lpar)*0.5);
2165
2166 Standard_Real theTol = BRep_Tool::Tolerance(aVertex);
2167 theTol *= 1.5;
2168
2169 Standard_Real dist1 = Pfirst.Distance(PV2d);
2170 Standard_Real dist2 = Plast.Distance(PV2d);
2171 Standard_Real dist3 = Pmid.Distance(PV2d);
2172
2173 if (dist1 <= theTol && dist2 <= theTol && dist3 <= theTol)
2174 return Standard_True;
2175
2176 return Standard_False;
2177}
2178
2179static void CheckBadEdges(const TopoDS_Face& Spine, const Standard_Real Offset,
2180 const BRepMAT2d_BisectingLocus& Locus,
2181 const BRepMAT2d_LinkTopoBilo& Link,
2182 TopTools_ListOfShape& BadEdges)
2183{
2184
2185 TopoDS_Face F = TopoDS::Face(Spine.Oriented(TopAbs_FORWARD));
2186 Standard_Real eps = Precision::Confusion();
2187 Standard_Real LimCurv = 1./Offset;
2188
2189 TopTools_MapOfShape aMap;
2190
2191 for (Standard_Integer ic = 1; ic <= Locus.NumberOfContours(); ic++) {
2192 for (Standard_Integer ie = 1; ie <= Locus.NumberOfElts(ic); ie++) {
2193 const TopoDS_Shape& SE = Link.GeneratingShape(Locus.BasicElt(ic,ie));
2194 if (SE.ShapeType() == TopAbs_EDGE) {
2195
2196 if (aMap.Contains(SE)) {
2197 //cout << "Edge is treated second time" << endl;
2198 continue;
2199 }
2200
2201 TopoDS_Edge E = TopoDS::Edge(SE);
2202
2203 Standard_Real f,l;
2204
2205 Handle(Geom2d_Curve) G2d = BRep_Tool::CurveOnSurface(E,F,f,l);
2206
2207 Geom2dAdaptor_Curve AC(G2d,f,l);
2208 GeomAbs_CurveType aCType = AC.GetType();
2209
2210 if(aCType != GeomAbs_Line && aCType != GeomAbs_Circle) {
2211
2212 Standard_Boolean reverse = Standard_False;
2213 if (E.Orientation() == TopAbs_FORWARD) reverse = Standard_True;
2214
2215 gp_Pnt2d P, Pc;
2216 gp_Dir2d N;
2217
2218 Geom2dLProp_CLProps2d aCLProps(G2d, 2, eps);
2219
2220 aCLProps.SetParameter(f);
2221 if(!aCLProps.IsTangentDefined()) {
2222 BadEdges.Append(SE);
2223 aMap.Add(SE);
2224 continue;
2225 }
2226
2227 P = aCLProps.Value();
2228 Standard_Real Crv = aCLProps.Curvature();
2229
2230 if(Crv >= eps) {
2231 aCLProps.Tangent(N);
2232 Standard_Real x = N.Y(), y = -N.X();
2233 N.SetCoord(x, y);
2234 if (reverse) N.Reverse();
2235 aCLProps.CentreOfCurvature(Pc);
2236 gp_Vec2d Dir( P, Pc );
2237 if (N.Dot(Dir) > 0.) {
2238 if (LimCurv <= Crv + eps) {
2239 BadEdges.Append(SE);
2240 aMap.Add(SE);
2241 continue;
2242 }
2243 }
2244 }
2245
2246 aCLProps.SetParameter(l);
2247 if(!aCLProps.IsTangentDefined()) {
2248 BadEdges.Append(SE);
2249 aMap.Add(SE);
2250 continue;
2251 }
2252
2253 P = aCLProps.Value();
2254 Crv = aCLProps.Curvature();
2255
2256 if(Crv >= eps) {
2257 aCLProps.Tangent(N);
2258 Standard_Real x = N.Y(), y = -N.X();
2259 N.SetCoord(x, y);
2260 if (reverse) N.Reverse();
2261 aCLProps.CentreOfCurvature(Pc);
2262 gp_Vec2d Dir( P, Pc );
2263 if (N.Dot(Dir) > 0.) {
2264 if (LimCurv <= Crv + eps) {
2265 BadEdges.Append(SE);
2266 aMap.Add(SE);
2267 continue;
2268 }
2269 }
2270 }
2271 }
2272 }
2273 }
2274 }
2275}
2276
2277
2278//=======================================================================
2279//function : PerformCurve
2280//purpose :
2281//=======================================================================
2282
2283static Standard_Boolean PerformCurve (TColStd_SequenceOfReal& Parameters,
2284 TColgp_SequenceOfPnt& Points,
2285 const Adaptor3d_Curve& C,
2286 const Standard_Real Deflection,
2287 const Standard_Real U1,
2288 const Standard_Real U2,
2289 const Standard_Real EPSILON,
2290 const Standard_Integer Nbmin)
2291{
2292 Standard_Real UU1 = Min(U1, U2);
2293 Standard_Real UU2 = Max(U1, U2);
2294
2295 gp_Pnt Pdeb, Pfin;
2296 gp_Vec Ddeb,Dfin;
2297 C.D1(UU1,Pdeb,Ddeb);
2298 Parameters.Append(UU1);
2299 Points.Append(Pdeb);
2300
2301 C.D1(UU2,Pfin,Dfin);
2302 QuasiFleche(C,Deflection*Deflection,
2303 UU1,Pdeb,
2304 Ddeb,
2305 UU2,Pfin,
2306 Dfin,
2307 Nbmin,
2308 EPSILON*EPSILON,
2309 Parameters,Points);
2310 return Standard_True;
2311}
2312//=======================================================================
2313//function : QuasiFleche
2314//purpose :
2315//=======================================================================
2316
2317static void QuasiFleche(const Adaptor3d_Curve& C,
2318 const Standard_Real Deflection2,
2319 const Standard_Real Udeb,
2320 const gp_Pnt& Pdeb,
2321 const gp_Vec& Vdeb,
2322 const Standard_Real Ufin,
2323 const gp_Pnt& Pfin,
2324 const gp_Vec& Vfin,
2325 const Standard_Integer Nbmin,
2326 const Standard_Real Eps,
2327 TColStd_SequenceOfReal& Parameters,
2328 TColgp_SequenceOfPnt& Points)
2329{
2330 Standard_Integer Ptslength = Points.Length();
2331 Standard_Real Udelta = Ufin-Udeb;
2332 gp_Pnt Pdelta;
2333 gp_Vec Vdelta;
2334 if (Nbmin > 2) {
2335 Udelta /=(Nbmin-1);
2336 C.D1(Udeb+Udelta,Pdelta,Vdelta);
2337 }
2338 else {
2339 Pdelta = Pfin;
2340 Vdelta = Vfin;
2341 }
2342
2343
2344 Standard_Real Norme = gp_Vec(Pdeb,Pdelta).SquareMagnitude();
2345 Standard_Real theFleche=0;
2346 Standard_Boolean flecheok = Standard_False;
2347 if (Norme > Eps) {
0d969553 2348 // Evaluation of the arrow by interpolation. See IntWalk_IWalking_5.gxx
7fd59977 2349 Standard_Real N1 = Vdeb.SquareMagnitude();
2350 Standard_Real N2 = Vdelta.SquareMagnitude();
2351 if (N1 > Eps && N2 > Eps) {
2352 Standard_Real Normediff =
2353 (Vdeb.Normalized().XYZ()-Vdelta.Normalized().XYZ()).SquareModulus();
2354 if (Normediff > Eps) {
2355 theFleche = Normediff*Norme/64.;
2356 flecheok = Standard_True;
2357 }
2358 }
2359 }
2360 if (!flecheok) {
2361 gp_Pnt Pmid((Pdeb.XYZ()+Pdelta.XYZ())/2.);
2362 gp_Pnt Pverif(C.Value(Udeb+Udelta/2.));
2363 theFleche = Pmid.SquareDistance(Pverif);
2364 }
2365
2366 if (theFleche < Deflection2) {
2367 Parameters.Append(Udeb+Udelta);
2368 Points.Append(Pdelta);
2369 }
2370 else {
2371 QuasiFleche(C,Deflection2,Udeb,Pdeb,
2372 Vdeb,
2373 Udeb+Udelta,Pdelta,
2374 Vdelta,
2375 3,
2376 Eps,
2377 Parameters,Points);
2378
2379 }
2380
2381 if (Nbmin > 2) {
2382 QuasiFleche(C,Deflection2,Udeb+Udelta,Pdelta,
2383 Vdelta,
2384 Ufin,Pfin,
2385 Vfin,
2386 Nbmin-(Points.Length()-Ptslength),
2387 Eps,
2388 Parameters,Points);
2389 }
2390}
2391