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