1 // File: BRepOffsetAPI_MiddlePath.cxx
2 // Created: 06.08.12 16:53:16
4 // Copyright: Open CASCADE 2012
6 #include <BRepOffsetAPI_MiddlePath.ixx>
7 #include <BRepOffsetAPI_MiddlePath.hxx>
9 #include <ShapeUpgrade_UnifySameDomain.hxx>
12 #include <Geom_Curve.hxx>
13 #include <Geom_TrimmedCurve.hxx>
14 #include <Geom_Line.hxx>
15 #include <Geom_BezierCurve.hxx>
16 #include <Geom_BSplineCurve.hxx>
17 #include <BRep_Tool.hxx>
18 #include <gce_MakeLin.hxx>
20 #include <BRepLib_MakeWire.hxx>
22 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
23 #include <TopTools_MapIteratorOfMapOfShape.hxx>
25 #include <TopTools_ListIteratorOfListOfShape.hxx>
27 #include <BRepTools.hxx>
28 #include <TopTools_SequenceOfShape.hxx>
29 #include <BRepTools_WireExplorer.hxx>
30 #include <TopoDS_Iterator.hxx>
31 #include <BRep_Builder.hxx>
32 #include <Precision.hxx>
33 #include <TopExp_Explorer.hxx>
34 #include <BRepExtrema_DistShapeShape.hxx>
35 #include <Geom2d_Curve.hxx>
36 #include <Geom2d_Line.hxx>
37 #include <GCE2d_MakeLine.hxx>
38 #include <BRepLib_MakeEdge.hxx>
39 #include <BRepLib.hxx>
40 #include <GeomAbs_CurveType.hxx>
41 #include <BRepAdaptor_Curve.hxx>
42 #include <TopTools_Array1OfShape.hxx>
43 #include <BRepLib_MakeFace.hxx>
44 #include <TColgp_Array1OfPnt.hxx>
45 #include <TColgp_HArray1OfPnt.hxx>
46 #include <TColgp_Array1OfVec.hxx>
47 #include <TColStd_HArray1OfBoolean.hxx>
48 #include <GProp_GProps.hxx>
49 #include <BRepGProp.hxx>
50 #include <Geom_Circle.hxx>
51 #include <gp_Circ.hxx>
52 #include <GC_MakeCircle.hxx>
53 #include <TColgp_SequenceOfPnt.hxx>
54 #include <GeomLib.hxx>
55 #include <GeomAPI_Interpolate.hxx>
57 static Standard_Boolean IsLinear(const TopoDS_Edge& anEdge,
60 Standard_Real fpar, lpar;
61 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
62 if (aCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
63 aCurve = ((Handle(Geom_TrimmedCurve)&) aCurve)->BasisCurve();
66 if (aCurve->IsKind(STANDARD_TYPE(Geom_Line)))
68 aLine = ((Handle(Geom_Line)&) aCurve)->Lin();
71 else if (aCurve->IsKind(STANDARD_TYPE(Geom_BezierCurve)))
73 Handle(Geom_BezierCurve) theBezier = (Handle(Geom_BezierCurve)&) aCurve;
74 if (theBezier->NbPoles() == 2)
76 Pnt1 = theBezier->Pole(1);
77 Pnt2 = theBezier->Pole(2);
78 aLine = gce_MakeLin(Pnt1, Pnt2);
82 else if (aCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
84 Handle(Geom_BSplineCurve) theBSpline = (Handle(Geom_BSplineCurve)&) aCurve;
85 if (theBSpline->NbPoles() == 2)
87 Pnt1 = theBSpline->Pole(1);
88 Pnt2 = theBSpline->Pole(2);
89 aLine = gce_MakeLin(Pnt1, Pnt2);
94 return Standard_False;
97 static GeomAbs_CurveType TypeOfEdge(const TopoDS_Edge& anEdge)
100 if (IsLinear(anEdge, aLin))
103 BRepAdaptor_Curve BAcurve(anEdge);
104 return BAcurve.GetType();
107 static gp_Vec TangentOfEdge(const TopoDS_Shape& aShape,
108 const Standard_Boolean OnFirst)
110 TopoDS_Edge anEdge = TopoDS::Edge(aShape);
111 TopAbs_Orientation anOr = anEdge.Orientation();
113 Standard_Real fpar, lpar;
114 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
115 Standard_Real thePar;
117 thePar = (anOr == TopAbs_FORWARD)? fpar : lpar;
119 thePar = (anOr == TopAbs_FORWARD)? lpar : fpar;
123 aCurve->D1(thePar, thePoint, theTangent);
124 if (anOr == TopAbs_REVERSED)
125 theTangent.Reverse();
131 static Standard_Boolean IsValidEdge(const TopoDS_Edge& theEdge,
132 const TopoDS_Face& theFace)
134 TopoDS_Vertex V1, V2;
135 TopExp::Vertices(theEdge, V1, V2);
137 Standard_Real Tol = Precision::Confusion();
140 TopExp_Explorer Explo(theFace, TopAbs_EDGE);
141 for (; Explo.More(); Explo.Next())
143 const TopoDS_Shape& anEdge = Explo.Current();
144 BRepExtrema_DistShapeShape DistMini(theEdge, anEdge);
145 if (DistMini.Value() <= Tol)
147 for (i = 1; i <= DistMini.NbSolution(); i++)
149 BRepExtrema_SupportType theType = DistMini.SupportTypeShape2(i);
150 if (theType == BRepExtrema_IsOnEdge)
151 return Standard_False;
152 //theType is "IsVertex"
153 TopoDS_Shape aVertex = DistMini.SupportOnShape2(i);
154 if (!(aVertex.IsSame(V1) || aVertex.IsSame(V2)))
155 return Standard_False;
160 return Standard_True;
164 //=======================================================================
165 //function : BRepOffsetAPI_MiddlePath
166 //purpose : Constructor
167 //=======================================================================
169 BRepOffsetAPI_MiddlePath::BRepOffsetAPI_MiddlePath(const TopoDS_Shape& aShape,
170 const TopoDS_Wire& StartWire)
172 myInitialShape = aShape;
173 myStartWire = StartWire;
174 myClosedSection = myStartWire.Closed();
177 //=======================================================================
178 //function : BRepOffsetAPI_MiddlePath
179 //purpose : Constructor
180 //=======================================================================
182 BRepOffsetAPI_MiddlePath::BRepOffsetAPI_MiddlePath(const TopoDS_Shape& aShape,
183 const TopoDS_Edge& StartEdge)
185 myInitialShape = aShape;
187 BRepLib_MakeWire MW(StartEdge);
189 //BB.Add(myStartWire, StartEdge);
191 TopTools_IndexedDataMapOfShapeListOfShape EFmap;
192 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
193 TopExp::MapShapesAndAncestors(myInitialShape, TopAbs_EDGE, TopAbs_FACE, EFmap);
194 TopExp::MapShapesAndAncestors(myInitialShape, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
196 //Standard_Boolean Start = Standard_True;
199 //TopExp::Vertices(CurEdge, V1, V2);
202 // if (VEmap(CurVertex).Extent() == 2) //end: two free edges
206 // if (VEmap(CurVertex).Extent() == 2) //end: two free edges
209 // Start = Standard_False;
213 TopoDS_Vertex StartVertex, CurVertex, V1, V2;
214 TopExp::Vertices(StartEdge, StartVertex, CurVertex);
215 TopoDS_Edge CurEdge = StartEdge;
217 for (i = 1; i <= 2; i++)
221 const TopTools_ListOfShape& LE = VEmap.FindFromKey(CurVertex);
222 if (LE.Extent() == 2) //end: two free edges or one closed free edge
224 TopTools_ListIteratorOfListOfShape itl(LE);
226 for (; itl.More(); itl.Next())
228 anEdge = TopoDS::Edge(itl.Value());
229 if (anEdge.IsSame(CurEdge))
231 if (EFmap.FindFromKey(anEdge).Extent() == 1) //another free edge found
234 //BB.Add(myStartWire, anEdge);
236 TopExp::Vertices(anEdge, V1, V2);
237 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
239 if (CurVertex.IsSame(StartVertex))
242 if (CurVertex.IsSame(StartVertex))
244 CurVertex = StartVertex;
248 myStartWire = MW.Wire();
249 myClosedSection = myStartWire.Closed();
253 //=======================================================================
254 //function : BRepOffsetAPI_MiddlePath
255 //purpose : Constructor
256 //=======================================================================
258 BRepOffsetAPI_MiddlePath::BRepOffsetAPI_MiddlePath(const TopoDS_Shape& aShape,
259 const TopoDS_Shape& StartShape,
260 const TopoDS_Shape& EndShape)
262 ShapeUpgrade_UnifySameDomain Unifier(aShape);
264 myInitialShape = Unifier.Shape();
266 TopoDS_Wire aStartWire, anEndWire;
267 if (StartShape.ShapeType() == TopAbs_FACE)
269 const TopoDS_Face& StartFace = TopoDS::Face(StartShape);
270 aStartWire = BRepTools::OuterWire(StartFace);
273 aStartWire = TopoDS::Wire(StartShape);
275 if (EndShape.ShapeType() == TopAbs_FACE)
277 const TopoDS_Face& EndFace = TopoDS::Face(EndShape);
278 anEndWire = BRepTools::OuterWire(EndFace);
281 anEndWire = TopoDS::Wire(EndShape);
283 BRepLib_MakeWire MWstart;
284 //TopTools_MapOfShape MapEdges;
285 BRepTools_WireExplorer wexp(aStartWire);
286 for (; wexp.More(); wexp.Next())
288 TopoDS_Shape anEdge = wexp.Current();
289 TopoDS_Shape NewEdge = Unifier.Generated(anEdge);
290 if (!NewEdge.IsNull())
291 MWstart.Add(TopoDS::Edge(NewEdge));
293 myStartWire = MWstart.Wire();
295 BRepLib_MakeWire MWend;
297 for (wexp.Init(anEndWire); wexp.More(); wexp.Next())
299 TopoDS_Shape anEdge = wexp.Current();
300 TopoDS_Shape NewEdge = Unifier.Generated(anEdge);
301 if (!NewEdge.IsNull())
302 MWend.Add(TopoDS::Edge(NewEdge));
304 myEndWire = MWend.Wire();
306 myClosedSection = myStartWire.Closed();
307 myClosedRing = myStartWire.IsSame(myEndWire);
310 //=======================================================================
313 //=======================================================================
315 void BRepOffsetAPI_MiddlePath::Build()
317 TopTools_ListIteratorOfListOfShape itl;
319 TopTools_SequenceOfShape StartVertices;
320 TopTools_MapOfShape EndVertices;
321 TopTools_MapOfShape EndEdges;
322 BRepOffsetAPI_SequenceOfSequenceOfShape SectionsEdges;
324 BRepTools_WireExplorer wexp(myStartWire);
325 TopTools_SequenceOfShape EdgeSeq;
326 for (; wexp.More(); wexp.Next())
328 StartVertices.Append(wexp.CurrentVertex());
329 EdgeSeq.Append(wexp.Current());
331 if (!myClosedSection)
332 StartVertices.Append(wexp.CurrentVertex());
333 SectionsEdges.Append(EdgeSeq);
335 for (wexp.Init(myEndWire); wexp.More(); wexp.Next())
337 EndVertices.Add(wexp.CurrentVertex());
338 EndEdges.Add(wexp.Current());
340 if (!myClosedSection)
341 EndVertices.Add(wexp.CurrentVertex());
344 TopoDS_Iterator itw(myStartWire);
345 for (; itw.More(); itw.Next())
346 myStartWireEdges.Add(itw.Value());
347 for (itw.Initialize(myEndWire); itw.More(); itw.Next())
348 myEndWireEdges.Add(itw.Value());
350 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
351 TopTools_IndexedDataMapOfShapeListOfShape EFmap;
352 TopExp::MapShapesAndAncestors(myInitialShape, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
353 TopExp::MapShapesAndAncestors(myInitialShape, TopAbs_EDGE, TopAbs_FACE, EFmap);
355 TopTools_MapOfShape CurVertices;
357 Standard_Integer i, j, k;
359 TopoDS_Vertex V1, V2, NextVertex;
360 //Initialization of <myPaths>
361 for (i = 1; i <= StartVertices.Length(); i++)
363 TopTools_SequenceOfShape Edges;
364 const TopTools_ListOfShape& LE = VEmap.FindFromKey(StartVertices(i));
365 for (itl.Initialize(LE); itl.More(); itl.Next())
367 anEdge = TopoDS::Edge(itl.Value());
368 if (!myStartWireEdges.Contains(anEdge))
370 TopExp::Vertices(anEdge, V1, V2, Standard_True);
371 if (V1.IsSame(StartVertices(i)))
378 Edges.Append(anEdge);
382 myPaths.Append(Edges);
385 //Filling of "myPaths"
386 TopTools_ListOfShape NextVertices;
389 for (i = 1; i <= myPaths.Length(); i++)
391 const TopoDS_Shape& theShape = myPaths(i).Last();
393 TopoDS_Vertex theVertex;
394 if (theShape.ShapeType() == TopAbs_EDGE)
396 theEdge = TopoDS::Edge(theShape);
397 theVertex = TopExp::LastVertex(theEdge, Standard_True);
399 else //last segment of path was punctual
401 theEdge = TopoDS::Edge(myPaths(i)(myPaths(i).Length()-1));
402 theVertex = TopoDS::Vertex(theShape);
405 if (EndVertices.Contains(theVertex))
407 const TopTools_ListOfShape& LE = VEmap.FindFromKey(theVertex);
408 TopTools_MapOfShape NextEdgeCandidates;
409 for (itl.Initialize(LE); itl.More(); itl.Next())
411 anEdge = TopoDS::Edge(itl.Value());
412 if (anEdge.IsSame(theEdge))
414 TopExp::Vertices(anEdge, V1, V2, Standard_True);
415 if (V1.IsSame(theVertex))
422 if (!CurVertices.Contains(NextVertex))
423 NextEdgeCandidates.Add(anEdge);
425 if (!NextEdgeCandidates.IsEmpty())
427 if (NextEdgeCandidates.Extent() > 1)
428 myPaths(i).Append(theVertex); //punctual segment of path
431 TopTools_MapIteratorOfMapOfShape mapit(NextEdgeCandidates);
432 anEdge = TopoDS::Edge(mapit.Key());
433 myPaths(i).Append(anEdge);
434 NextVertex = TopExp::LastVertex(anEdge, Standard_True);
435 NextVertices.Append(NextVertex);
439 if (NextVertices.IsEmpty())
441 for (itl.Initialize(NextVertices); itl.More(); itl.Next())
442 CurVertices.Add(itl.Value());
443 NextVertices.Clear();
448 TopoDS_Compound aCompound, aCmp1;
450 BB.MakeCompound(aCompound);
451 BB.MakeCompound(aCmp1);
452 for (i = 1; i <= myPaths.Length(); i++)
454 TopoDS_Compound aCmp;
455 BB.MakeCompound(aCmp);
456 for (j = 1; j <= myPaths(i).Length(); j++)
457 BB.Add(aCmp, myPaths(i)(j));
460 BB.Add(aCompound, aCmp1);
469 //Building of set of sections
470 Standard_Integer NbE = EdgeSeq.Length();
471 Standard_Integer NbPaths = myPaths.Length();
472 Standard_Integer NbVer = myPaths.Length();
478 for (j = 1; j <= EdgeSeq.Length(); j++)
479 EdgeSeq(j).Nullify();
481 Standard_Boolean ToInsertVertex = Standard_False;
483 for (j = 2; j <= NbVer; j++)
485 if (!EdgeSeq(j-1).IsNull())
488 //for the end of initial shape
489 if (myPaths(j-1).Length() < i)
491 TopoDS_Edge aE1 = TopoDS::Edge(myPaths(j-1)(i-1));
492 TopoDS_Shape LastVer = TopExp::LastVertex(aE1, Standard_True);
493 myPaths(j-1).Append(LastVer);
495 if (myPaths((j<=NbPaths)? j : 1).Length() < i)
497 TopoDS_Edge aE2 = TopoDS::Edge(myPaths((j<=NbPaths)? j : 1)(i-1));
498 TopoDS_Shape LastVer = TopExp::LastVertex(aE2, Standard_True);
499 myPaths((j<=NbPaths)? j : 1).Append(LastVer);
501 //////////////////////////////
505 if (myPaths(j-1)(i).ShapeType() == TopAbs_EDGE)
507 TopoDS_Edge aE1 = TopoDS::Edge(myPaths(j-1)(i));
508 TopoDS_Shape fver = TopExp::FirstVertex(aE1, Standard_True);
509 myPaths(j-1).InsertBefore(i, fver);
511 if (myPaths((j<=NbPaths)? j : 1)(i).ShapeType() == TopAbs_EDGE)
513 TopoDS_Edge aE2 = TopoDS::Edge(myPaths((j<=NbPaths)? j : 1)(i));
514 TopoDS_Shape fver = TopExp::FirstVertex(aE2, Standard_True);
515 myPaths((j<=NbPaths)? j : 1).InsertBefore(i, fver);
517 ToInsertVertex = Standard_False;
521 if (myPaths(j-1)(i).ShapeType() == TopAbs_EDGE)
522 E1 = TopoDS::Edge(myPaths(j-1)(i));
523 if (myPaths((j<=NbPaths)? j : 1)(i).ShapeType() == TopAbs_EDGE)
524 E2 = TopoDS::Edge(myPaths((j<=NbPaths)? j : 1)(i));
525 TopoDS_Edge E12 = TopoDS::Edge(SectionsEdges(i)(j-1));
527 TopoDS_Vertex PrevVertex = (E1.IsNull())? TopoDS::Vertex(myPaths(j-1)(i))
528 : TopExp::LastVertex(E1, Standard_True);
529 TopoDS_Vertex CurVertex = (E2.IsNull())? TopoDS::Vertex(myPaths((j<=NbPaths)? j : 1)(i))
530 : TopExp::LastVertex(E2, Standard_True);
532 TopoDS_Edge ProperEdge;
533 const TopTools_ListOfShape& LE = VEmap.FindFromKey(PrevVertex);
535 for (itl.Initialize(LE); itl.More(); itl.Next())
537 anEdge = TopoDS::Edge(itl.Value());
538 TopExp::Vertices(anEdge, V1, V2);
539 if ((V1.IsSame(PrevVertex) && V2.IsSame(CurVertex) ||
540 V1.IsSame(CurVertex) && V2.IsSame(PrevVertex)) &&
548 if ((myPaths(j-1)(i)).ShapeType() == TopAbs_VERTEX &&
549 (myPaths((j<=NbPaths)? j : 1)(i)).ShapeType() == TopAbs_VERTEX)
551 EdgeSeq(j-1) = ProperEdge;
555 TopoDS_Vertex PrevPrevVer = (E1.IsNull())? PrevVertex
556 : TopExp::FirstVertex(E1, Standard_True);
557 TopoDS_Vertex PrevCurVer = (E2.IsNull())? CurVertex
558 : TopExp::FirstVertex(E2, Standard_True);
559 if (ProperEdge.IsNull()) //no connection between these two vertices
561 //Find the face on which E1, E2 and E12 lie
562 //ToInsertVertex = Standard_False;
563 const TopoDS_Shape& EE1 = (E1.IsNull())?
564 myPaths(j-1)(i-1) : E1;
565 const TopoDS_Shape& EE2 = (E2.IsNull())?
566 myPaths((j<=NbPaths)? j : 1)(i-1) : E2;
567 const TopTools_ListOfShape& LF = EFmap.FindFromKey(EE1);
569 for (itl.Initialize(LF); itl.More(); itl.Next())
571 const TopoDS_Shape& aFace = itl.Value();
572 TopExp_Explorer Explo(aFace, TopAbs_EDGE);
573 for (; Explo.More(); Explo.Next())
575 if (EE2.IsSame(Explo.Current()))
577 const TopTools_ListOfShape& LFsec = EFmap.FindFromKey(E12);
578 TopTools_ListIteratorOfListOfShape itlsec(LFsec);
579 for (; itlsec.More(); itlsec.Next())
580 if (aFace.IsSame(itlsec.Value()))
582 theFace = TopoDS::Face(aFace);
585 if (!theFace.IsNull())
589 if (!theFace.IsNull())
592 TopTools_ListOfShape ListOneFace;
593 ListOneFace.Append(theFace);
595 if (E1.IsNull() || E2.IsNull())
598 E1 = TopoDS::Edge(myPaths(j-1)(i-1));
600 E2 = TopoDS::Edge(myPaths((j<=NbPaths)? j : 1)(i-1));
601 Standard_Real fpar1, lpar1, fpar2, lpar2;
602 Standard_Real FirstPar1, LastPar1, FirstPar2, LastPar2;
603 Handle(Geom2d_Curve) PCurve1 = BRep_Tool::CurveOnSurface(E1, theFace, fpar1, lpar1);
604 Handle(Geom2d_Curve) PCurve2 = BRep_Tool::CurveOnSurface(E2, theFace, fpar2, lpar2);
605 if (E1.Orientation() == TopAbs_FORWARD)
606 { FirstPar1 = fpar1; LastPar1 = lpar1; }
608 { FirstPar1 = lpar1; LastPar1 = fpar1; }
609 if (E2.Orientation() == TopAbs_FORWARD)
610 { FirstPar2 = fpar2; LastPar2 = lpar2; }
612 { FirstPar2 = lpar2; LastPar2 = fpar2; }
613 gp_Pnt2d FirstPnt2d = PCurve1->Value(LastPar1);
614 gp_Pnt2d LastPnt2d = PCurve2->Value(LastPar2);
615 Handle(Geom_Surface) theSurf = BRep_Tool::Surface(theFace);
616 Handle(Geom2d_Line) theLine = GCE2d_MakeLine(FirstPnt2d, LastPnt2d);
617 Standard_Real len_ne = FirstPnt2d.Distance(LastPnt2d);
618 TopoDS_Edge NewEdge = BRepLib_MakeEdge(theLine, theSurf,
619 PrevVertex, CurVertex,
621 BRepLib::BuildCurve3d(NewEdge);
622 EdgeSeq(j-1) = NewEdge;
623 EFmap.Add(NewEdge, ListOneFace);
628 Standard_Real fpar1, lpar1, fpar2, lpar2;
629 Standard_Real FirstPar1, LastPar1, FirstPar2, LastPar2;
630 Handle(Geom2d_Curve) PCurve1 = BRep_Tool::CurveOnSurface(E1, theFace, fpar1, lpar1);
631 Handle(Geom2d_Curve) PCurve2 = BRep_Tool::CurveOnSurface(E2, theFace, fpar2, lpar2);
632 if (E1.Orientation() == TopAbs_FORWARD)
633 { FirstPar1 = fpar1; LastPar1 = lpar1; }
635 { FirstPar1 = lpar1; LastPar1 = fpar1; }
636 if (E2.Orientation() == TopAbs_FORWARD)
637 { FirstPar2 = fpar2; LastPar2 = lpar2; }
639 { FirstPar2 = lpar2; LastPar2 = fpar2; }
640 gp_Pnt2d FirstPnt2d = PCurve1->Value(LastPar1);
641 gp_Pnt2d LastPnt2d = PCurve2->Value(LastPar2);
642 Handle(Geom_Surface) theSurf = BRep_Tool::Surface(theFace);
643 Handle(Geom2d_Line) theLine = GCE2d_MakeLine(FirstPnt2d, LastPnt2d);
644 Standard_Real len_ne = FirstPnt2d.Distance(LastPnt2d);
645 TopoDS_Edge NewEdge = BRepLib_MakeEdge(theLine, theSurf,
646 PrevVertex, CurVertex,
648 BRepLib::BuildCurve3d(NewEdge);
649 gp_Pnt2d PrevFirstPnt2d = PCurve1->Value(FirstPar1);
650 gp_Pnt2d PrevLastPnt2d = PCurve2->Value(FirstPar2);
651 Handle(Geom2d_Line) Line1 = GCE2d_MakeLine(PrevFirstPnt2d, LastPnt2d);
652 Handle(Geom2d_Line) Line2 = GCE2d_MakeLine(FirstPnt2d, PrevLastPnt2d);
653 Standard_Real len_ne1 = PrevFirstPnt2d.Distance(LastPnt2d);
654 TopoDS_Edge NewEdge1 = BRepLib_MakeEdge(Line1, theSurf,
655 PrevPrevVer, CurVertex,
657 BRepLib::BuildCurve3d(NewEdge1);
658 Standard_Real len_ne2 = FirstPnt2d.Distance(PrevLastPnt2d);
659 TopoDS_Edge NewEdge2 = BRepLib_MakeEdge(Line2, theSurf,
660 PrevVertex, PrevCurVer,
662 BRepLib::BuildCurve3d(NewEdge2);
663 Standard_Boolean good_ne = IsValidEdge(NewEdge, theFace);
664 Standard_Boolean good_ne1 = IsValidEdge(NewEdge1, theFace);
666 GeomAbs_CurveType type_E1 = TypeOfEdge(E1);
667 GeomAbs_CurveType type_E2 = TypeOfEdge(E2);
669 Standard_Integer ChooseEdge = 0;
671 if (!good_ne || type_E1 != type_E2)
673 if (type_E1 == type_E2) //!good_ne
680 else //types are different
682 if (type_E1 == GeomAbs_Line)
684 else if (type_E2 == GeomAbs_Line)
686 else //to be developed later...
693 EdgeSeq(j-1) = NewEdge;
694 EFmap.Add(NewEdge, ListOneFace);
696 else if (ChooseEdge == 1)
698 EdgeSeq(j-1) = NewEdge1;
699 EFmap.Add(NewEdge1, ListOneFace);
700 for (k = 1; k < j-1; k++)
701 EdgeSeq(k).Nullify();
702 for (k = 1; k <= j-1; k++)
704 TopoDS_Edge aLastEdge = TopoDS::Edge(myPaths(k)(i));
705 TopoDS_Shape VertexAsEdge = TopExp::FirstVertex(aLastEdge, Standard_True);
706 myPaths(k).InsertBefore(i, VertexAsEdge);
708 j = 1; //start from beginning
710 else if (ChooseEdge == 2)
712 EdgeSeq(j-1) = NewEdge2;
713 EFmap.Add(NewEdge2, ListOneFace);
714 ToInsertVertex = Standard_True;
716 } //else //E1 is edge
717 } //if (ProperEdge.IsNull())
718 else //connecting edge exists
723 myPaths(j-1).InsertBefore(i, PrevPrevVer);
724 myPaths((j<=NbPaths)? j : 1).InsertBefore(i, PrevCurVer);
729 EdgeSeq(j-1) = ProperEdge;
731 } //for (j = 2; j <= NbVer; j++)
732 SectionsEdges.Append(EdgeSeq);
734 //check for exit from for(;;)
735 Standard_Integer NbEndEdges = 0;
736 for (j = 1; j <= EdgeSeq.Length(); j++)
737 if (EndEdges.Contains(EdgeSeq(j)))
739 if (NbEndEdges == NbE)
746 //final phase: building of middle path
747 Standard_Integer NbSecFaces = SectionsEdges.Length();
748 TopTools_Array1OfShape SecFaces(1, NbSecFaces);
749 for (i = 1; i <= NbSecFaces; i++)
752 for (j = 1; j <= NbE; j++)
754 anEdge = TopoDS::Edge(SectionsEdges(i)(j));
757 if (!myClosedSection)
759 TopExp::Vertices(MW.Wire(), V1, V2);
760 anEdge = BRepLib_MakeEdge(V2, V1);
763 TopoDS_Wire aWire = MW.Wire();
764 BRepLib_MakeFace MF(aWire, Standard_True); //Only plane
766 SecFaces(i) = MF.Face();
771 TColgp_Array1OfPnt Centers(1, NbSecFaces);
772 for (i = 1; i <= NbSecFaces; i++)
774 GProp_GProps Properties;
775 if (SecFaces(i).ShapeType() == TopAbs_FACE)
776 BRepGProp::SurfaceProperties(SecFaces(i), Properties);
778 BRepGProp::LinearProperties(SecFaces(i), Properties);
780 Centers(i) = Properties.CentreOfMass();
783 TopTools_Array1OfShape MidEdges(1, NbSecFaces-1);
784 Standard_Real LinTol = 1.e-5;
785 Standard_Real AngTol = 1.e-7;
787 for (i = 1; i < NbSecFaces; i++)
789 GeomAbs_CurveType TypeOfMidEdge = GeomAbs_OtherCurve;
790 for (j = 1; j <= myPaths.Length(); j++)
792 const TopoDS_Shape& aShape = myPaths(j)(i);
793 if (aShape.ShapeType() == TopAbs_VERTEX)
795 TypeOfMidEdge = GeomAbs_OtherCurve;
798 anEdge = TopoDS::Edge(aShape);
799 GeomAbs_CurveType aType = TypeOfEdge(anEdge);
801 TypeOfMidEdge = aType;
804 if (aType != TypeOfMidEdge)
806 TypeOfMidEdge = GeomAbs_OtherCurve;
811 if (TypeOfMidEdge == GeomAbs_Line)
812 MidEdges(i) = BRepLib_MakeEdge(Centers(i), Centers(i+1));
813 else if (TypeOfMidEdge == GeomAbs_Circle)
816 gp_Dir theDir1, theDir2;
817 Standard_Real theAngle = 0.;
819 Standard_Boolean SimilarArcs = Standard_True;
820 for (j = 1; j <= myPaths.Length(); j++)
822 anEdge = TopoDS::Edge(myPaths(j)(i));
823 Standard_Real fpar, lpar;
824 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
825 if (aCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
826 aCurve = ((Handle(Geom_TrimmedCurve)&) aCurve)->BasisCurve();
827 Pnt1 = aCurve->Value(fpar);
828 Pnt2 = aCurve->Value(lpar);
829 Handle(Geom_Circle) aCircle = Handle(Geom_Circle)::DownCast(aCurve);
830 gp_Circ aCirc = aCircle->Circ();
833 theAxis = aCirc.Axis();
834 theDir1 = gp_Vec(aCirc.Location(), Pnt1);
835 theDir2 = gp_Vec(aCirc.Location(), Pnt2);
836 theAngle = lpar - fpar;
837 Standard_Real theParam = (anEdge.Orientation() == TopAbs_FORWARD)?
839 aCurve->D1(theParam, Pnt1, theTangent);
840 if (anEdge.Orientation() == TopAbs_REVERSED)
841 theTangent.Reverse();
845 gp_Ax1 anAxis = aCirc.Axis();
847 if (!aLin.Contains(theAxis.Location(), LinTol) ||
848 !anAxis.IsParallel(theAxis, AngTol))
850 SimilarArcs = Standard_False;
853 gp_Dir aDir1 = gp_Vec(aCirc.Location(), Pnt1);
854 gp_Dir aDir2 = gp_Vec(aCirc.Location(), Pnt2);
855 if (!(aDir1.IsEqual(theDir1, AngTol) && aDir2.IsEqual(theDir2, AngTol) ||
856 aDir1.IsEqual(theDir2, AngTol) && aDir2.IsEqual(theDir1, AngTol)))
858 SimilarArcs = Standard_False;
865 gp_XYZ AxisLoc = theAxis.Location().XYZ();
866 gp_XYZ AxisDir = theAxis.Direction().XYZ();
867 Standard_Real Parameter = (Centers(i).XYZ() - AxisLoc) * AxisDir;
868 gp_Pnt theCenterOfCirc(AxisLoc + Parameter*AxisDir);
870 gp_Vec Vec1(theCenterOfCirc, Centers(i));
871 gp_Vec Vec2(theCenterOfCirc, Centers(i+1));
873 gp_Dir VecProd = Vec1 ^ Vec2;
874 if (theAxis.Direction() * VecProd < 0.)
878 Standard_Real anAngle = Vec1.AngleWithRef(Vec2, theAxis.Direction());
881 if (Abs(anAngle - theAngle) > AngTol)
883 gp_Ax2 theAx2(theCenterOfCirc, theAxis.Direction(), Vec1);
884 Handle(Geom_Circle) theCircle = GC_MakeCircle(theAx2, Vec1.Magnitude());
886 theCircle->D1( 0., Pnt1, aTangent );
887 if (aTangent * theTangent < 0.)
890 theAx2 = gp_Ax2(theCenterOfCirc, theAxis.Direction(), Vec1);
891 theCircle = GC_MakeCircle(theAx2, Vec1.Magnitude());
893 BRepLib_MakeEdge aME (theCircle, 0., theAngle);
896 MidEdges(i) = aME.IsDone() ?
904 for (i = 1; i < NbSecFaces; i++)
906 if (MidEdges(i).IsNull())
908 for (j = i+1; j < NbSecFaces; j++)
910 if (!MidEdges(j).IsNull())
913 //from i to j-1 all edges are null
914 Handle(TColgp_HArray1OfPnt) thePoints = new TColgp_HArray1OfPnt(1, j-i+1);
915 TColgp_Array1OfVec theTangents(1, j-i+1);
916 Handle(TColStd_HArray1OfBoolean) theFlags = new TColStd_HArray1OfBoolean(1, j-i+1);
917 for (k = i; k <= j; k++)
918 thePoints->SetValue(k-i+1, Centers(k));
919 for (k = i; k <= j; k++)
921 TColgp_SequenceOfPnt PntSeq;
922 for (Standard_Integer indp = 1; indp <= myPaths.Length(); indp++)
927 if (myPaths(indp)(k).ShapeType() == TopAbs_VERTEX)
929 aTangent = TangentOfEdge(myPaths(indp)(k), Standard_True); //at begin
933 if (myPaths(indp)(k-1).ShapeType() == TopAbs_VERTEX)
935 aTangent = TangentOfEdge(myPaths(indp)(k-1), Standard_False); //at end
939 if (myPaths(indp)(k-1).ShapeType() == TopAbs_VERTEX ||
940 myPaths(indp)(k).ShapeType() == TopAbs_VERTEX)
942 gp_Vec Tangent1 = TangentOfEdge(myPaths(indp)(k-1), Standard_False); //at end
943 gp_Vec Tangent2 = TangentOfEdge(myPaths(indp)(k), Standard_True); //at begin
944 aTangent = Tangent1 + Tangent2;
946 aTangent.Normalize();
947 gp_Pnt aPnt(aTangent.XYZ());
950 TColgp_Array1OfPnt PntArray(1, PntSeq.Length());
951 for (Standard_Integer ip = 1; ip <= PntSeq.Length(); ip++)
952 PntArray(ip) = PntSeq(ip);
955 Standard_Real xgap, ygap, zgap;
956 GeomLib::Inertia(PntArray, theBary, xdir, ydir, xgap, ygap, zgap);
957 gp_Vec theTangent(theBary.XYZ());
958 theTangents(k-i+1) = theTangent;
960 theFlags->Init(Standard_True);
962 GeomAPI_Interpolate Interpol(thePoints, Standard_False, LinTol);
963 Interpol.Load(theTangents, theFlags);
965 if (!Interpol.IsDone())
967 cout<<endl<<"Interpolation failed"<<endl;
969 Handle(Geom_Curve) InterCurve = Interpol.Curve();
970 MidEdges(i) = BRepLib_MakeEdge(InterCurve);
975 BRepLib_MakeWire MakeFinalWire;
976 for (i = 1; i < NbSecFaces; i++)
977 if (!MidEdges(i).IsNull())
978 MakeFinalWire.Add(TopoDS::Edge(MidEdges(i)));
980 TopoDS_Wire FinalWire = MakeFinalWire.Wire();
981 myShape = MakeFinalWire.Wire();
985 TopoDS_Compound aCompound, aCmp1, aCmp2;
987 BB.MakeCompound(aCompound);
988 BB.MakeCompound(aCmp1);
989 BB.MakeCompound(aCmp2);
990 for (i = 1; i <= myPaths.Length(); i++)
992 TopoDS_Compound aCmp;
993 BB.MakeCompound(aCmp);
994 for (j = 1; j <= myPaths(i).Length(); j++)
995 BB.Add(aCmp, myPaths(i)(j));
998 for (i = 1; i <= SectionsEdges.Length(); i++)
1002 for (j = 1; j <= SectionsEdges(i).Length(); j++)
1003 BB.Add(aWire, SectionsEdges(i)(j));
1004 BB.Add(aCmp2, aWire);
1006 BB.Add(aCompound, aCmp1);
1007 BB.Add(aCompound, aCmp2);
1008 BB.Add(aCompound, FinalWire);
1010 myShape = aCompound;