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 IsClosed(const TopoDS_Wire& aWire)
60 TopExp::Vertices(aWire, V1, V2);
61 return (V1.IsSame(V2));
64 static Standard_Boolean IsLinear(const TopoDS_Edge& anEdge,
67 Standard_Real fpar, lpar;
68 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
69 if (aCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
70 aCurve = ((Handle(Geom_TrimmedCurve)&) aCurve)->BasisCurve();
73 if (aCurve->IsKind(STANDARD_TYPE(Geom_Line)))
75 aLine = ((Handle(Geom_Line)&) aCurve)->Lin();
78 else if (aCurve->IsKind(STANDARD_TYPE(Geom_BezierCurve)))
80 Handle(Geom_BezierCurve) theBezier = (Handle(Geom_BezierCurve)&) aCurve;
81 if (theBezier->NbPoles() == 2)
83 Pnt1 = theBezier->Pole(1);
84 Pnt2 = theBezier->Pole(2);
85 aLine = gce_MakeLin(Pnt1, Pnt2);
89 else if (aCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
91 Handle(Geom_BSplineCurve) theBSpline = (Handle(Geom_BSplineCurve)&) aCurve;
92 if (theBSpline->NbPoles() == 2)
94 Pnt1 = theBSpline->Pole(1);
95 Pnt2 = theBSpline->Pole(2);
96 aLine = gce_MakeLin(Pnt1, Pnt2);
101 return Standard_False;
104 static GeomAbs_CurveType TypeOfEdge(const TopoDS_Edge& anEdge)
107 if (IsLinear(anEdge, aLin))
110 BRepAdaptor_Curve BAcurve(anEdge);
111 return BAcurve.GetType();
114 static gp_Vec TangentOfEdge(const TopoDS_Shape& aShape,
115 const Standard_Boolean OnFirst)
117 TopoDS_Edge anEdge = TopoDS::Edge(aShape);
118 TopAbs_Orientation anOr = anEdge.Orientation();
120 Standard_Real fpar, lpar;
121 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
122 Standard_Real thePar;
124 thePar = (anOr == TopAbs_FORWARD)? fpar : lpar;
126 thePar = (anOr == TopAbs_FORWARD)? lpar : fpar;
130 aCurve->D1(thePar, thePoint, theTangent);
131 if (anOr == TopAbs_REVERSED)
132 theTangent.Reverse();
138 static Standard_Boolean IsValidEdge(const TopoDS_Edge& theEdge,
139 const TopoDS_Face& theFace)
141 TopoDS_Vertex V1, V2;
142 TopExp::Vertices(theEdge, V1, V2);
144 Standard_Real Tol = Precision::Confusion();
147 TopExp_Explorer Explo(theFace, TopAbs_EDGE);
148 for (; Explo.More(); Explo.Next())
150 const TopoDS_Shape& anEdge = Explo.Current();
151 BRepExtrema_DistShapeShape DistMini(theEdge, anEdge);
152 if (DistMini.Value() <= Tol)
154 for (i = 1; i <= DistMini.NbSolution(); i++)
156 BRepExtrema_SupportType theType = DistMini.SupportTypeShape2(i);
157 if (theType == BRepExtrema_IsOnEdge)
158 return Standard_False;
159 //theType is "IsVertex"
160 TopoDS_Shape aVertex = DistMini.SupportOnShape2(i);
161 if (!(aVertex.IsSame(V1) || aVertex.IsSame(V2)))
162 return Standard_False;
167 return Standard_True;
171 //=======================================================================
172 //function : BRepOffsetAPI_MiddlePath
173 //purpose : Constructor
174 //=======================================================================
176 BRepOffsetAPI_MiddlePath::BRepOffsetAPI_MiddlePath(const TopoDS_Shape& aShape,
177 const TopoDS_Wire& StartWire)
179 myInitialShape = aShape;
180 myStartWire = StartWire;
181 myClosedSection = myStartWire.Closed();
184 //=======================================================================
185 //function : BRepOffsetAPI_MiddlePath
186 //purpose : Constructor
187 //=======================================================================
189 BRepOffsetAPI_MiddlePath::BRepOffsetAPI_MiddlePath(const TopoDS_Shape& aShape,
190 const TopoDS_Edge& StartEdge)
192 myInitialShape = aShape;
194 BRepLib_MakeWire MW(StartEdge);
196 //BB.Add(myStartWire, StartEdge);
198 TopTools_IndexedDataMapOfShapeListOfShape EFmap;
199 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
200 TopExp::MapShapesAndAncestors(myInitialShape, TopAbs_EDGE, TopAbs_FACE, EFmap);
201 TopExp::MapShapesAndAncestors(myInitialShape, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
203 //Standard_Boolean Start = Standard_True;
206 //TopExp::Vertices(CurEdge, V1, V2);
209 // if (VEmap(CurVertex).Extent() == 2) //end: two free edges
213 // if (VEmap(CurVertex).Extent() == 2) //end: two free edges
216 // Start = Standard_False;
220 TopoDS_Vertex StartVertex, CurVertex, V1, V2;
221 TopExp::Vertices(StartEdge, StartVertex, CurVertex);
222 TopoDS_Edge CurEdge = StartEdge;
224 for (i = 1; i <= 2; i++)
228 const TopTools_ListOfShape& LE = VEmap.FindFromKey(CurVertex);
229 if (LE.Extent() == 2) //end: two free edges or one closed free edge
231 TopTools_ListIteratorOfListOfShape itl(LE);
233 for (; itl.More(); itl.Next())
235 anEdge = TopoDS::Edge(itl.Value());
236 if (anEdge.IsSame(CurEdge))
238 if (EFmap.FindFromKey(anEdge).Extent() == 1) //another free edge found
241 //BB.Add(myStartWire, anEdge);
243 TopExp::Vertices(anEdge, V1, V2);
244 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
246 if (CurVertex.IsSame(StartVertex))
249 if (CurVertex.IsSame(StartVertex))
251 CurVertex = StartVertex;
255 myStartWire = MW.Wire();
256 myClosedSection = myStartWire.Closed();
260 //=======================================================================
261 //function : BRepOffsetAPI_MiddlePath
262 //purpose : Constructor
263 //=======================================================================
265 BRepOffsetAPI_MiddlePath::BRepOffsetAPI_MiddlePath(const TopoDS_Shape& aShape,
266 const TopoDS_Shape& StartShape,
267 const TopoDS_Shape& EndShape)
269 ShapeUpgrade_UnifySameDomain Unifier(aShape);
271 myInitialShape = Unifier.Shape();
273 TopoDS_Wire aStartWire, anEndWire;
274 if (StartShape.ShapeType() == TopAbs_FACE)
276 const TopoDS_Face& StartFace = TopoDS::Face(StartShape);
277 aStartWire = BRepTools::OuterWire(StartFace);
280 aStartWire = TopoDS::Wire(StartShape);
282 if (EndShape.ShapeType() == TopAbs_FACE)
284 const TopoDS_Face& EndFace = TopoDS::Face(EndShape);
285 anEndWire = BRepTools::OuterWire(EndFace);
288 anEndWire = TopoDS::Wire(EndShape);
290 BRepLib_MakeWire MWstart;
291 //TopTools_MapOfShape MapEdges;
292 BRepTools_WireExplorer wexp(aStartWire);
293 for (; wexp.More(); wexp.Next())
295 TopoDS_Shape anEdge = wexp.Current();
296 TopoDS_Shape NewEdge = Unifier.Generated(anEdge);
297 if (!NewEdge.IsNull())
298 MWstart.Add(TopoDS::Edge(NewEdge));
300 myStartWire = MWstart.Wire();
302 BRepLib_MakeWire MWend;
304 for (wexp.Init(anEndWire); wexp.More(); wexp.Next())
306 TopoDS_Shape anEdge = wexp.Current();
307 TopoDS_Shape NewEdge = Unifier.Generated(anEdge);
308 if (!NewEdge.IsNull())
309 MWend.Add(TopoDS::Edge(NewEdge));
311 myEndWire = MWend.Wire();
313 myClosedSection = myStartWire.Closed();
314 myClosedRing = myStartWire.IsSame(myEndWire);
317 //=======================================================================
320 //=======================================================================
322 void BRepOffsetAPI_MiddlePath::Build()
324 TopTools_ListIteratorOfListOfShape itl;
326 TopTools_SequenceOfShape StartVertices;
327 TopTools_MapOfShape EndVertices;
328 TopTools_MapOfShape EndEdges;
329 BRepOffsetAPI_SequenceOfSequenceOfShape SectionsEdges;
331 BRepTools_WireExplorer wexp(myStartWire);
332 TopTools_SequenceOfShape EdgeSeq;
333 for (; wexp.More(); wexp.Next())
335 StartVertices.Append(wexp.CurrentVertex());
336 EdgeSeq.Append(wexp.Current());
338 if (!myClosedSection)
339 StartVertices.Append(wexp.CurrentVertex());
340 SectionsEdges.Append(EdgeSeq);
342 for (wexp.Init(myEndWire); wexp.More(); wexp.Next())
344 EndVertices.Add(wexp.CurrentVertex());
345 EndEdges.Add(wexp.Current());
347 if (!myClosedSection)
348 EndVertices.Add(wexp.CurrentVertex());
351 TopoDS_Iterator itw(myStartWire);
352 for (; itw.More(); itw.Next())
353 myStartWireEdges.Add(itw.Value());
354 for (itw.Initialize(myEndWire); itw.More(); itw.Next())
355 myEndWireEdges.Add(itw.Value());
357 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
358 TopTools_IndexedDataMapOfShapeListOfShape EFmap;
359 TopExp::MapShapesAndAncestors(myInitialShape, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
360 TopExp::MapShapesAndAncestors(myInitialShape, TopAbs_EDGE, TopAbs_FACE, EFmap);
362 TopTools_MapOfShape CurVertices;
364 Standard_Integer i, j, k;
366 TopoDS_Vertex V1, V2, NextVertex;
367 //Initialization of <myPaths>
368 for (i = 1; i <= StartVertices.Length(); i++)
370 TopTools_SequenceOfShape Edges;
371 const TopTools_ListOfShape& LE = VEmap.FindFromKey(StartVertices(i));
372 for (itl.Initialize(LE); itl.More(); itl.Next())
374 anEdge = TopoDS::Edge(itl.Value());
375 if (!myStartWireEdges.Contains(anEdge))
377 TopExp::Vertices(anEdge, V1, V2, Standard_True);
378 if (V1.IsSame(StartVertices(i)))
385 Edges.Append(anEdge);
389 myPaths.Append(Edges);
392 //Filling of "myPaths"
393 TopTools_ListOfShape NextVertices;
396 for (i = 1; i <= myPaths.Length(); i++)
398 const TopoDS_Shape& theShape = myPaths(i).Last();
400 TopoDS_Vertex theVertex;
401 if (theShape.ShapeType() == TopAbs_EDGE)
403 theEdge = TopoDS::Edge(theShape);
404 theVertex = TopExp::LastVertex(theEdge, Standard_True);
406 else //last segment of path was punctual
408 theEdge = TopoDS::Edge(myPaths(i)(myPaths(i).Length()-1));
409 theVertex = TopoDS::Vertex(theShape);
412 if (EndVertices.Contains(theVertex))
414 const TopTools_ListOfShape& LE = VEmap.FindFromKey(theVertex);
415 TopTools_MapOfShape NextEdgeCandidates;
416 for (itl.Initialize(LE); itl.More(); itl.Next())
418 anEdge = TopoDS::Edge(itl.Value());
419 if (anEdge.IsSame(theEdge))
421 TopExp::Vertices(anEdge, V1, V2, Standard_True);
422 if (V1.IsSame(theVertex))
429 if (!CurVertices.Contains(NextVertex))
430 NextEdgeCandidates.Add(anEdge);
432 if (!NextEdgeCandidates.IsEmpty())
434 if (NextEdgeCandidates.Extent() > 1)
435 myPaths(i).Append(theVertex); //punctual segment of path
438 TopTools_MapIteratorOfMapOfShape mapit(NextEdgeCandidates);
439 anEdge = TopoDS::Edge(mapit.Key());
440 myPaths(i).Append(anEdge);
441 NextVertex = TopExp::LastVertex(anEdge, Standard_True);
442 NextVertices.Append(NextVertex);
446 if (NextVertices.IsEmpty())
448 for (itl.Initialize(NextVertices); itl.More(); itl.Next())
449 CurVertices.Add(itl.Value());
450 NextVertices.Clear();
455 TopoDS_Compound aCompound, aCmp1;
457 BB.MakeCompound(aCompound);
458 BB.MakeCompound(aCmp1);
459 for (i = 1; i <= myPaths.Length(); i++)
461 TopoDS_Compound aCmp;
462 BB.MakeCompound(aCmp);
463 for (j = 1; j <= myPaths(i).Length(); j++)
464 BB.Add(aCmp, myPaths(i)(j));
467 BB.Add(aCompound, aCmp1);
476 //Building of set of sections
477 Standard_Integer NbE = EdgeSeq.Length();
478 Standard_Integer NbPaths = myPaths.Length();
479 Standard_Integer NbVer = myPaths.Length();
485 for (j = 1; j <= EdgeSeq.Length(); j++)
486 EdgeSeq(j).Nullify();
488 Standard_Boolean ToInsertVertex = Standard_False;
490 for (j = 2; j <= NbVer; j++)
492 if (!EdgeSeq(j-1).IsNull())
495 //for the end of initial shape
496 if (myPaths(j-1).Length() < i)
498 TopoDS_Edge aE1 = TopoDS::Edge(myPaths(j-1)(i-1));
499 TopoDS_Shape LastVer = TopExp::LastVertex(aE1, Standard_True);
500 myPaths(j-1).Append(LastVer);
502 if (myPaths((j<=NbPaths)? j : 1).Length() < i)
504 TopoDS_Edge aE2 = TopoDS::Edge(myPaths((j<=NbPaths)? j : 1)(i-1));
505 TopoDS_Shape LastVer = TopExp::LastVertex(aE2, Standard_True);
506 myPaths((j<=NbPaths)? j : 1).Append(LastVer);
508 //////////////////////////////
512 if (myPaths(j-1)(i).ShapeType() == TopAbs_EDGE)
514 TopoDS_Edge aE1 = TopoDS::Edge(myPaths(j-1)(i));
515 TopoDS_Shape fver = TopExp::FirstVertex(aE1, Standard_True);
516 myPaths(j-1).InsertBefore(i, fver);
518 if (myPaths((j<=NbPaths)? j : 1)(i).ShapeType() == TopAbs_EDGE)
520 TopoDS_Edge aE2 = TopoDS::Edge(myPaths((j<=NbPaths)? j : 1)(i));
521 TopoDS_Shape fver = TopExp::FirstVertex(aE2, Standard_True);
522 myPaths((j<=NbPaths)? j : 1).InsertBefore(i, fver);
524 ToInsertVertex = Standard_False;
528 if (myPaths(j-1)(i).ShapeType() == TopAbs_EDGE)
529 E1 = TopoDS::Edge(myPaths(j-1)(i));
530 if (myPaths((j<=NbPaths)? j : 1)(i).ShapeType() == TopAbs_EDGE)
531 E2 = TopoDS::Edge(myPaths((j<=NbPaths)? j : 1)(i));
532 TopoDS_Edge E12 = TopoDS::Edge(SectionsEdges(i)(j-1));
534 //TopoDS_Vertex PrevVertex = TopoDS::Vertex(VerSeq(j-1));
535 //TopoDS_Vertex CurVertex = TopoDS::Vertex(VerSeq(j));
536 TopoDS_Vertex PrevVertex = (E1.IsNull())? TopoDS::Vertex(myPaths(j-1)(i))
537 : TopExp::LastVertex(E1, Standard_True);
538 TopoDS_Vertex CurVertex = (E2.IsNull())? TopoDS::Vertex(myPaths((j<=NbPaths)? j : 1)(i))
539 : TopExp::LastVertex(E2, Standard_True);
541 TopoDS_Edge ProperEdge;
542 const TopTools_ListOfShape& LE = VEmap.FindFromKey(PrevVertex);
544 Standard_Integer LenList = LE.Extent();
546 for (itl.Initialize(LE); itl.More(); itl.Next())
548 anEdge = TopoDS::Edge(itl.Value());
549 TopExp::Vertices(anEdge, V1, V2);
550 if ((V1.IsSame(PrevVertex) && V2.IsSame(CurVertex) ||
551 V1.IsSame(CurVertex) && V2.IsSame(PrevVertex)) &&
559 if ((myPaths(j-1)(i)).ShapeType() == TopAbs_VERTEX &&
560 (myPaths((j<=NbPaths)? j : 1)(i)).ShapeType() == TopAbs_VERTEX)
562 EdgeSeq(j-1) = ProperEdge;
566 TopoDS_Vertex PrevPrevVer = (E1.IsNull())? PrevVertex
567 : TopExp::FirstVertex(E1, Standard_True);
568 TopoDS_Vertex PrevCurVer = (E2.IsNull())? CurVertex
569 : TopExp::FirstVertex(E2, Standard_True);
570 if (ProperEdge.IsNull()) //no connection between these two vertices
572 //Find the face on which E1, E2 and E12 lie
573 //ToInsertVertex = Standard_False;
574 const TopoDS_Shape& EE1 = (E1.IsNull())?
575 myPaths(j-1)(i-1) : E1;
576 const TopoDS_Shape& EE2 = (E2.IsNull())?
577 myPaths((j<=NbPaths)? j : 1)(i-1) : E2;
578 const TopTools_ListOfShape& LF = EFmap.FindFromKey(EE1);
580 for (itl.Initialize(LF); itl.More(); itl.Next())
582 const TopoDS_Shape& aFace = itl.Value();
583 TopExp_Explorer Explo(aFace, TopAbs_EDGE);
584 for (; Explo.More(); Explo.Next())
586 if (EE2.IsSame(Explo.Current()))
588 const TopTools_ListOfShape& LFsec = EFmap.FindFromKey(E12);
589 TopTools_ListIteratorOfListOfShape itlsec(LFsec);
590 for (; itlsec.More(); itlsec.Next())
591 if (aFace.IsSame(itlsec.Value()))
593 theFace = TopoDS::Face(aFace);
596 if (!theFace.IsNull())
600 if (!theFace.IsNull())
603 TopTools_ListOfShape ListOneFace;
604 ListOneFace.Append(theFace);
606 if (E1.IsNull() || E2.IsNull())
609 E1 = TopoDS::Edge(myPaths(j-1)(i-1));
611 E2 = TopoDS::Edge(myPaths((j<=NbPaths)? j : 1)(i-1));
612 Standard_Real fpar1, lpar1, fpar2, lpar2;
613 Standard_Real FirstPar1, LastPar1, FirstPar2, LastPar2;
614 Handle(Geom2d_Curve) PCurve1 = BRep_Tool::CurveOnSurface(E1, theFace, fpar1, lpar1);
615 Handle(Geom2d_Curve) PCurve2 = BRep_Tool::CurveOnSurface(E2, theFace, fpar2, lpar2);
616 if (E1.Orientation() == TopAbs_FORWARD)
617 { FirstPar1 = fpar1; LastPar1 = lpar1; }
619 { FirstPar1 = lpar1; LastPar1 = fpar1; }
620 if (E2.Orientation() == TopAbs_FORWARD)
621 { FirstPar2 = fpar2; LastPar2 = lpar2; }
623 { FirstPar2 = lpar2; LastPar2 = fpar2; }
624 gp_Pnt2d FirstPnt2d = PCurve1->Value(LastPar1);
625 gp_Pnt2d LastPnt2d = PCurve2->Value(LastPar2);
626 Handle(Geom_Surface) theSurf = BRep_Tool::Surface(theFace);
627 Handle(Geom2d_Line) theLine = GCE2d_MakeLine(FirstPnt2d, LastPnt2d);
628 Standard_Real len_ne = FirstPnt2d.Distance(LastPnt2d);
629 TopoDS_Edge NewEdge = BRepLib_MakeEdge(theLine, theSurf,
630 PrevVertex, CurVertex,
632 BRepLib::BuildCurve3d(NewEdge);
633 EdgeSeq(j-1) = NewEdge;
634 EFmap.Add(NewEdge, ListOneFace);
639 Standard_Real fpar1, lpar1, fpar2, lpar2;
640 Standard_Real FirstPar1, LastPar1, FirstPar2, LastPar2;
641 Handle(Geom2d_Curve) PCurve1 = BRep_Tool::CurveOnSurface(E1, theFace, fpar1, lpar1);
642 Handle(Geom2d_Curve) PCurve2 = BRep_Tool::CurveOnSurface(E2, theFace, fpar2, lpar2);
643 if (E1.Orientation() == TopAbs_FORWARD)
644 { FirstPar1 = fpar1; LastPar1 = lpar1; }
646 { FirstPar1 = lpar1; LastPar1 = fpar1; }
647 if (E2.Orientation() == TopAbs_FORWARD)
648 { FirstPar2 = fpar2; LastPar2 = lpar2; }
650 { FirstPar2 = lpar2; LastPar2 = fpar2; }
651 gp_Pnt2d FirstPnt2d = PCurve1->Value(LastPar1);
652 gp_Pnt2d LastPnt2d = PCurve2->Value(LastPar2);
653 Handle(Geom_Surface) theSurf = BRep_Tool::Surface(theFace);
654 Handle(Geom2d_Line) theLine = GCE2d_MakeLine(FirstPnt2d, LastPnt2d);
655 Standard_Real len_ne = FirstPnt2d.Distance(LastPnt2d);
656 TopoDS_Edge NewEdge = BRepLib_MakeEdge(theLine, theSurf,
657 PrevVertex, CurVertex,
659 BRepLib::BuildCurve3d(NewEdge);
660 gp_Pnt2d PrevFirstPnt2d = PCurve1->Value(FirstPar1);
661 gp_Pnt2d PrevLastPnt2d = PCurve2->Value(FirstPar2);
662 Handle(Geom2d_Line) Line1 = GCE2d_MakeLine(PrevFirstPnt2d, LastPnt2d);
663 Handle(Geom2d_Line) Line2 = GCE2d_MakeLine(FirstPnt2d, PrevLastPnt2d);
664 Standard_Real len_ne1 = PrevFirstPnt2d.Distance(LastPnt2d);
665 TopoDS_Edge NewEdge1 = BRepLib_MakeEdge(Line1, theSurf,
666 PrevPrevVer, CurVertex,
668 BRepLib::BuildCurve3d(NewEdge1);
669 Standard_Real len_ne2 = FirstPnt2d.Distance(PrevLastPnt2d);
670 TopoDS_Edge NewEdge2 = BRepLib_MakeEdge(Line2, theSurf,
671 PrevVertex, PrevCurVer,
673 BRepLib::BuildCurve3d(NewEdge2);
674 Standard_Boolean good_ne = IsValidEdge(NewEdge, theFace);
675 Standard_Boolean good_ne1 = IsValidEdge(NewEdge1, theFace);
676 Standard_Boolean good_ne2 = IsValidEdge(NewEdge2, theFace);
678 GeomAbs_CurveType type_E1 = TypeOfEdge(E1);
679 GeomAbs_CurveType type_E2 = TypeOfEdge(E2);
681 Standard_Integer ChooseEdge = 0;
683 if (!good_ne || type_E1 != type_E2)
685 if (type_E1 == type_E2) //!good_ne
692 else //types are different
694 if (type_E1 == GeomAbs_Line)
696 else if (type_E2 == GeomAbs_Line)
698 else //to be developed later...
705 EdgeSeq(j-1) = NewEdge;
706 EFmap.Add(NewEdge, ListOneFace);
708 else if (ChooseEdge == 1)
710 EdgeSeq(j-1) = NewEdge1;
711 EFmap.Add(NewEdge1, ListOneFace);
712 for (k = 1; k < j-1; k++)
713 EdgeSeq(k).Nullify();
714 for (k = 1; k <= j-1; k++)
716 TopoDS_Edge aLastEdge = TopoDS::Edge(myPaths(k)(i));
717 TopoDS_Shape VertexAsEdge = TopExp::FirstVertex(aLastEdge, Standard_True);
718 myPaths(k).InsertBefore(i, VertexAsEdge);
720 j = 1; //start from beginning
722 else if (ChooseEdge == 2)
724 EdgeSeq(j-1) = NewEdge2;
725 EFmap.Add(NewEdge2, ListOneFace);
726 ToInsertVertex = Standard_True;
728 } //else //E1 is edge
729 } //if (ProperEdge.IsNull())
730 else //connecting edge exists
735 myPaths(j-1).InsertBefore(i, PrevPrevVer);
736 myPaths((j<=NbPaths)? j : 1).InsertBefore(i, PrevCurVer);
741 EdgeSeq(j-1) = ProperEdge;
743 } //for (j = 2; j <= NbVer; j++)
744 SectionsEdges.Append(EdgeSeq);
746 //check for exit from for(;;)
747 Standard_Integer NbEndEdges = 0;
748 for (j = 1; j <= EdgeSeq.Length(); j++)
749 if (EndEdges.Contains(EdgeSeq(j)))
751 if (NbEndEdges == NbE)
758 //final phase: building of middle path
759 Standard_Integer NbSecFaces = SectionsEdges.Length();
760 TopTools_Array1OfShape SecFaces(1, NbSecFaces);
761 for (i = 1; i <= NbSecFaces; i++)
764 for (j = 1; j <= NbE; j++)
766 anEdge = TopoDS::Edge(SectionsEdges(i)(j));
769 if (!myClosedSection)
771 TopExp::Vertices(MW.Wire(), V1, V2);
772 anEdge = BRepLib_MakeEdge(V2, V1);
775 TopoDS_Wire aWire = MW.Wire();
776 BRepLib_MakeFace MF(aWire, Standard_True); //Only plane
778 SecFaces(i) = MF.Face();
783 TColgp_Array1OfPnt Centers(1, NbSecFaces);
784 for (i = 1; i <= NbSecFaces; i++)
786 GProp_GProps Properties;
787 if (SecFaces(i).ShapeType() == TopAbs_FACE)
788 BRepGProp::SurfaceProperties(SecFaces(i), Properties);
790 BRepGProp::LinearProperties(SecFaces(i), Properties);
792 Centers(i) = Properties.CentreOfMass();
795 TopTools_Array1OfShape MidEdges(1, NbSecFaces-1);
796 Standard_Real LinTol = 1.e-5;
797 Standard_Real AngTol = 1.e-7;
799 for (i = 1; i < NbSecFaces; i++)
801 GeomAbs_CurveType TypeOfMidEdge = GeomAbs_OtherCurve;
802 for (j = 1; j <= myPaths.Length(); j++)
804 const TopoDS_Shape& aShape = myPaths(j)(i);
805 if (aShape.ShapeType() == TopAbs_VERTEX)
807 TypeOfMidEdge = GeomAbs_OtherCurve;
810 anEdge = TopoDS::Edge(aShape);
811 GeomAbs_CurveType aType = TypeOfEdge(anEdge);
813 TypeOfMidEdge = aType;
816 if (aType != TypeOfMidEdge)
818 TypeOfMidEdge = GeomAbs_OtherCurve;
823 if (TypeOfMidEdge == GeomAbs_Line)
824 MidEdges(i) = BRepLib_MakeEdge(Centers(i), Centers(i+1));
825 else if (TypeOfMidEdge == GeomAbs_Circle)
828 gp_Dir theDir1, theDir2;
829 Standard_Real theAngle;
831 Standard_Boolean SimilarArcs = Standard_True;
832 for (j = 1; j <= myPaths.Length(); j++)
834 anEdge = TopoDS::Edge(myPaths(j)(i));
835 Standard_Real fpar, lpar;
836 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
837 if (aCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
838 aCurve = ((Handle(Geom_TrimmedCurve)&) aCurve)->BasisCurve();
839 Pnt1 = aCurve->Value(fpar);
840 Pnt2 = aCurve->Value(lpar);
841 Handle(Geom_Circle) aCircle = Handle(Geom_Circle)::DownCast(aCurve);
842 gp_Circ aCirc = aCircle->Circ();
845 theAxis = aCirc.Axis();
846 theDir1 = gp_Vec(aCirc.Location(), Pnt1);
847 theDir2 = gp_Vec(aCirc.Location(), Pnt2);
848 theAngle = lpar - fpar;
849 Standard_Real theParam = (anEdge.Orientation() == TopAbs_FORWARD)?
851 aCurve->D1(theParam, Pnt1, theTangent);
852 if (anEdge.Orientation() == TopAbs_REVERSED)
853 theTangent.Reverse();
857 gp_Ax1 anAxis = aCirc.Axis();
859 if (!aLin.Contains(theAxis.Location(), LinTol) ||
860 !anAxis.IsParallel(theAxis, AngTol))
862 SimilarArcs = Standard_False;
865 gp_Dir aDir1 = gp_Vec(aCirc.Location(), Pnt1);
866 gp_Dir aDir2 = gp_Vec(aCirc.Location(), Pnt2);
867 if (!(aDir1.IsEqual(theDir1, AngTol) && aDir2.IsEqual(theDir2, AngTol) ||
868 aDir1.IsEqual(theDir2, AngTol) && aDir2.IsEqual(theDir1, AngTol)))
870 SimilarArcs = Standard_False;
877 gp_XYZ AxisLoc = theAxis.Location().XYZ();
878 gp_XYZ AxisDir = theAxis.Direction().XYZ();
879 Standard_Real Parameter = (Centers(i).XYZ() - AxisLoc) * AxisDir;
880 gp_Pnt theCenterOfCirc(AxisLoc + Parameter*AxisDir);
882 gp_Vec Vec1(theCenterOfCirc, Centers(i));
883 gp_Vec Vec2(theCenterOfCirc, Centers(i+1));
885 gp_Dir VecProd = Vec1 ^ Vec2;
886 if (theAxis.Direction() * VecProd < 0.)
890 Standard_Real anAngle = Vec1.AngleWithRef(Vec2, theAxis.Direction());
893 if (Abs(anAngle - theAngle) > AngTol)
895 gp_Ax2 theAx2(theCenterOfCirc, theAxis.Direction(), Vec1);
896 Handle(Geom_Circle) theCircle = GC_MakeCircle(theAx2, Vec1.Magnitude());
898 theCircle->D1( 0., Pnt1, aTangent );
899 if (aTangent * theTangent < 0.)
902 theAx2 = gp_Ax2(theCenterOfCirc, theAxis.Direction(), Vec1);
903 theCircle = GC_MakeCircle(theAx2, Vec1.Magnitude());
905 MidEdges(i) = BRepLib_MakeEdge(theCircle, 0., theAngle);
911 for (i = 1; i < NbSecFaces; i++)
913 if (MidEdges(i).IsNull())
915 for (j = i+1; j < NbSecFaces; j++)
917 if (!MidEdges(j).IsNull())
920 //from i to j-1 all edges are null
921 Handle(TColgp_HArray1OfPnt) thePoints = new TColgp_HArray1OfPnt(1, j-i+1);
922 TColgp_Array1OfVec theTangents(1, j-i+1);
923 Handle(TColStd_HArray1OfBoolean) theFlags = new TColStd_HArray1OfBoolean(1, j-i+1);
924 for (k = i; k <= j; k++)
925 thePoints->SetValue(k-i+1, Centers(k));
926 for (k = i; k <= j; k++)
928 TColgp_SequenceOfPnt PntSeq;
929 for (Standard_Integer indp = 1; indp <= myPaths.Length(); indp++)
934 if (myPaths(indp)(k).ShapeType() == TopAbs_VERTEX)
936 aTangent = TangentOfEdge(myPaths(indp)(k), Standard_True); //at begin
940 if (myPaths(indp)(k-1).ShapeType() == TopAbs_VERTEX)
942 aTangent = TangentOfEdge(myPaths(indp)(k-1), Standard_False); //at end
946 if (myPaths(indp)(k-1).ShapeType() == TopAbs_VERTEX ||
947 myPaths(indp)(k).ShapeType() == TopAbs_VERTEX)
949 gp_Vec Tangent1 = TangentOfEdge(myPaths(indp)(k-1), Standard_False); //at end
950 gp_Vec Tangent2 = TangentOfEdge(myPaths(indp)(k), Standard_True); //at begin
951 aTangent = Tangent1 + Tangent2;
953 aTangent.Normalize();
954 gp_Pnt aPnt(aTangent.XYZ());
957 TColgp_Array1OfPnt PntArray(1, PntSeq.Length());
958 for (Standard_Integer ip = 1; ip <= PntSeq.Length(); ip++)
959 PntArray(ip) = PntSeq(ip);
962 Standard_Real xgap, ygap, zgap;
963 GeomLib::Inertia(PntArray, theBary, xdir, ydir, xgap, ygap, zgap);
964 gp_Vec theTangent(theBary.XYZ());
965 theTangents(k-i+1) = theTangent;
967 theFlags->Init(Standard_True);
969 GeomAPI_Interpolate Interpol(thePoints, Standard_False, LinTol);
970 Interpol.Load(theTangents, theFlags);
972 if (!Interpol.IsDone())
974 cout<<endl<<"Interpolation failed"<<endl;
976 Handle(Geom_Curve) InterCurve = Interpol.Curve();
977 MidEdges(i) = BRepLib_MakeEdge(InterCurve);
982 BRepLib_MakeWire MakeFinalWire;
983 for (i = 1; i < NbSecFaces; i++)
984 if (!MidEdges(i).IsNull())
985 MakeFinalWire.Add(TopoDS::Edge(MidEdges(i)));
987 TopoDS_Wire FinalWire = MakeFinalWire.Wire();
988 myShape = MakeFinalWire.Wire();
992 TopoDS_Compound aCompound, aCmp1, aCmp2;
994 BB.MakeCompound(aCompound);
995 BB.MakeCompound(aCmp1);
996 BB.MakeCompound(aCmp2);
997 for (i = 1; i <= myPaths.Length(); i++)
999 TopoDS_Compound aCmp;
1000 BB.MakeCompound(aCmp);
1001 for (j = 1; j <= myPaths(i).Length(); j++)
1002 BB.Add(aCmp, myPaths(i)(j));
1003 BB.Add(aCmp1, aCmp);
1005 for (i = 1; i <= SectionsEdges.Length(); i++)
1009 for (j = 1; j <= SectionsEdges(i).Length(); j++)
1010 BB.Add(aWire, SectionsEdges(i)(j));
1011 BB.Add(aCmp2, aWire);
1013 BB.Add(aCompound, aCmp1);
1014 BB.Add(aCompound, aCmp2);
1015 BB.Add(aCompound, FinalWire);
1017 myShape = aCompound;