1 // Created on: 1998-07-02
2 // Created by: Joelle CHAUVET
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Bnd_Box.hxx>
19 #include <BRep_Builder.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepAdaptor_Curve.hxx>
22 #include <BRepBndLib.hxx>
23 #include <BRepCheck_Wire.hxx>
24 #include <BRepExtrema_DistShapeShape.hxx>
25 #include <BRepFill.hxx>
26 #include <BRepFill_CompatibleWires.hxx>
27 #include <BRepGProp.hxx>
28 #include <BRepLib.hxx>
29 #include <BRepLib_FindSurface.hxx>
30 #include <BRepLib_MakeEdge.hxx>
31 #include <BRepLib_MakeWire.hxx>
32 #include <BRepLProp.hxx>
33 #include <BRepTools_WireExplorer.hxx>
34 #include <Geom_Plane.hxx>
35 #include <Geom_Surface.hxx>
38 #include <gp_Circ.hxx>
39 #include <gp_Elips.hxx>
42 #include <GProp_GProps.hxx>
43 #include <GProp_PrincipalProps.hxx>
44 #include <Precision.hxx>
45 #include <Standard_ConstructionError.hxx>
46 #include <Standard_NoSuchObject.hxx>
47 #include <TColgp_HArray1OfPnt.hxx>
48 #include <TColgp_HArray1OfVec.hxx>
49 #include <TColStd_Array1OfInteger.hxx>
50 #include <TColStd_Array1OfReal.hxx>
51 #include <TColStd_MapOfInteger.hxx>
52 #include <TColStd_SequenceOfReal.hxx>
55 #include <TopExp_Explorer.hxx>
57 #include <TopoDS_Edge.hxx>
58 #include <TopoDS_Wire.hxx>
59 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
60 #include <TopTools_DataMapOfShapeListOfShape.hxx>
61 #include <TopTools_DataMapOfShapeSequenceOfShape.hxx>
62 #include <TopTools_HSequenceOfShape.hxx>
63 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
64 #include <TopTools_ListIteratorOfListOfShape.hxx>
65 #include <TopTools_ListOfShape.hxx>
66 #include <TopTools_SequenceOfShape.hxx>
69 static void EdgesFromVertex (const TopoDS_Wire& W,
70 const TopoDS_Vertex& V,
74 TopTools_IndexedDataMapOfShapeListOfShape Map;
75 TopExp::MapShapesAndAncestors(W,TopAbs_VERTEX,TopAbs_EDGE,Map);
77 const TopTools_ListOfShape& List = Map.FindFromKey(V);
78 TopoDS_Edge e1 = TopoDS::Edge(List.First());
79 TopoDS_Edge e2 = TopoDS::Edge(List. Last());
81 BRepTools_WireExplorer anExp;
82 Standard_Integer I1=0, I2=0, NE=0;
84 for(anExp.Init(W); anExp.More(); anExp.Next()) {
86 const TopoDS_Edge& ECur = anExp.Current();
87 if (e1.IsSame(ECur)) {
90 if (e2.IsSame(ECur)) {
96 // consecutive numbers
107 // non consecutive numbers on a closed wire
121 //=======================================================================
122 //function : AddNewEdge
123 //purpose : for <theEdge> find all newest edges
124 // in <theEdgeNewEdges> recursively
125 //=======================================================================
127 static void AddNewEdge(const TopoDS_Shape& theEdge,
128 const TopTools_DataMapOfShapeSequenceOfShape& theEdgeNewEdges,
129 TopTools_ListOfShape& ListNewEdges)
131 if (theEdgeNewEdges.IsBound(theEdge))
133 const TopTools_SequenceOfShape& NewEdges = theEdgeNewEdges(theEdge);
134 for (Standard_Integer i = 1; i <= NewEdges.Length(); i++)
136 TopoDS_Shape anEdge = NewEdges(i);
137 AddNewEdge(anEdge, theEdgeNewEdges, ListNewEdges);
141 ListNewEdges.Append(theEdge);
144 static void SeqOfVertices (const TopoDS_Wire& W,
145 TopTools_SequenceOfShape& S)
148 Standard_Integer jj, cpt = 0;
150 for (PE.Init(W,TopAbs_VERTEX); PE.More(); PE.Next()) {
152 Standard_Boolean trouve=Standard_False;
153 for (jj=1;jj<=S.Length() && (!trouve);jj++) {
154 if (S.Value(jj).IsSame(PE.Current())) trouve = Standard_True;
156 if (!trouve) S.Append(PE.Current());
161 static Standard_Boolean PlaneOfWire (const TopoDS_Wire& W, gp_Pln& P)
163 Standard_Boolean isplane = Standard_True;
164 BRepLib_FindSurface findPlanarSurf;
165 Handle(Geom_Surface) S;
170 Standard_Boolean isBaryDefined = Standard_False;
172 // shielding for particular cases : only one edge circle or ellipse
173 // on a closed wire !
175 Standard_Boolean wClosed = W.Closed();
178 // it is checked if the vertices are the same.
179 TopoDS_Vertex V1, V2;
180 TopExp::Vertices(W,V1,V2);
181 if ( V1.IsSame(V2)) wClosed = Standard_True;
186 Standard_Integer nbEdges = 0;
187 TopoDS_Iterator anIter;
188 anIter.Initialize(W);
189 for(; anIter.More(); anIter.Next())
194 GeomAdaptor_Curve AdC;
195 Standard_Real first, last;
196 anIter.Initialize(W);
197 AdC.Load(BRep_Tool::Curve(TopoDS::Edge(anIter.Value()), first, last));
199 if (AdC.GetType() == GeomAbs_Circle)
201 Bary = AdC.Circle().Location();
202 isBaryDefined = Standard_True;
205 if (AdC.GetType() == GeomAbs_Ellipse)
207 Bary = AdC.Ellipse().Location();
208 isBaryDefined = Standard_True;
215 BRepGProp::LinearProperties(W,GP);
216 Bary = GP.CentreOfMass();
219 findPlanarSurf.Init(W, -1, Standard_True);
220 if ( findPlanarSurf.Found())
222 S = findPlanarSurf.Surface();
223 L = findPlanarSurf.Location();
224 if (!L.IsIdentity()) S = Handle(Geom_Surface)::
225 DownCast(S->Transformed(L.Transformation()));
226 P = (Handle(Geom_Plane)::DownCast(S))->Pln();
232 GProp_PrincipalProps Pp = GP.PrincipalProperties();
234 Standard_Real R1, R2, R3,Tol = Precision::Confusion();
235 Pp.RadiusOfGyration(R1,R2,R3);
236 Standard_Real RMax = Max(Max(R1,R2),R3);
237 if ( ( Abs(RMax-R1)<Tol && Abs(RMax-R2)<Tol )
238 || ( Abs(RMax-R1)<Tol && Abs(RMax-R3)<Tol )
239 || ( Abs(RMax-R2)<Tol && Abs(RMax-R3)<Tol ) )
240 isplane = Standard_False;
243 if (R1>=R2 && R1>=R3)
245 Vec = Pp.FirstAxisOfInertia();
247 else if (R2>=R1 && R2>=R3)
249 Vec = Pp.SecondAxisOfInertia();
251 else if (R3>=R1 && R3>=R2)
253 Vec = Pp.ThirdAxisOfInertia();
256 if (R3<=R2 && R3<=R1)
258 Vec = Pp.ThirdAxisOfInertia();
260 else if (R2<=R1 && R2<=R3)
262 Vec = Pp.SecondAxisOfInertia();
264 else if (R1<=R2 && R1<=R3)
266 Vec = Pp.FirstAxisOfInertia();
269 gp_Ax3 repere(Bary,NDir,XDir);
270 Geom_Plane GPlan(repere);
280 static void WireContinuity (const TopoDS_Wire& W,
281 GeomAbs_Shape& contW)
285 Standard_Boolean IsDegenerated = Standard_False;
287 BRepTools_WireExplorer anExp;
288 Standard_Integer nbEdges=0;
289 Handle(TopTools_HSequenceOfShape) Edges = new TopTools_HSequenceOfShape();
290 for(anExp.Init(W); anExp.More(); anExp.Next()) {
292 Edges->Append(anExp.Current());
293 if (BRep_Tool::Degenerated(anExp.Current())) IsDegenerated = Standard_True;
296 if (!IsDegenerated) {
298 Standard_Boolean testconti = Standard_True;
300 for (Standard_Integer j=1;j<=nbEdges;j++) {
302 TopoDS_Edge Edge1, Edge2;
305 Edge1 = TopoDS::Edge (Edges->Value(nbEdges));
306 Edge2 = TopoDS::Edge (Edges->Value(1));
309 Edge1 = TopoDS::Edge (Edges->Value(j));
310 Edge2 = TopoDS::Edge (Edges->Value(j+1));
313 TopoDS_Vertex V1,V2,Vbid;
314 TopExp::Vertices(Edge1,Vbid,V1,Standard_True);
315 TopExp::Vertices(Edge2,V2,Vbid,Standard_True);
316 Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1);
317 Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2);
318 BRepAdaptor_Curve Curve1(Edge1);
319 BRepAdaptor_Curve Curve2(Edge2);
320 Standard_Real Eps = BRep_Tool::Tolerance(V2) + BRep_Tool::Tolerance(V1);
323 testconti = Curve1.Value(U1).IsEqual(Curve2.Value(U2), Eps);
326 cont = BRepLProp::Continuity(Curve1,Curve2,U1,U2,
327 Eps, Precision::Angular());
328 if (cont <= contW) contW = cont;
335 static void TrimEdge (const TopoDS_Edge& CurrentEdge,
336 const TColStd_SequenceOfReal& CutValues,
337 const Standard_Real t0, const Standard_Real t1,
338 const Standard_Boolean SeqOrder,
339 TopTools_SequenceOfShape& S)
343 Standard_Integer j, ndec=CutValues.Length();
344 Standard_Real first,last,m0,m1;
345 Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
347 TopoDS_Vertex Vf,Vl,Vbid,V0,V1;
348 TopAbs_Orientation CurrentOrient = CurrentEdge.Orientation();
349 TopExp::Vertices(CurrentEdge,Vf,Vl);
353 // from first to last
356 for (j=1; j<=ndec; j++) {
358 m1 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
359 TopoDS_Edge CutE = BRepLib_MakeEdge(C,V0,Vbid,m0,m1);
360 CutE.Orientation(CurrentOrient);
363 V0 = TopExp::LastVertex(CutE);
366 TopoDS_Edge LastE = BRepLib_MakeEdge(C,V0,Vl,m0,last);
367 LastE.Orientation(CurrentOrient);
373 // from last to first
376 for (j=ndec; j>=1; j--) {
378 m0 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
379 TopoDS_Edge CutE = BRepLib_MakeEdge(C,Vbid,V1,m0,m1);
380 CutE.Orientation(CurrentOrient);
383 V1 = TopExp::FirstVertex(CutE);
386 TopoDS_Edge LastE = BRepLib_MakeEdge(C,Vf,V1,first,m1);
387 LastE.Orientation(CurrentOrient);
396 static Standard_Boolean SearchRoot (const TopoDS_Vertex& V,
397 const TopTools_DataMapOfShapeListOfShape& Map,
398 TopoDS_Vertex& VRoot)
400 Standard_Boolean trouve = Standard_False;
402 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape it;
403 for (it.Initialize(Map); it.More(); it.Next()) {
404 const TopTools_ListOfShape & List = it.Value();
405 TopTools_ListIteratorOfListOfShape itL;
406 Standard_Boolean ilyest = Standard_False;
407 for (itL.Initialize(List); itL.More(); itL.Next()) {
408 TopoDS_Vertex Vcur = TopoDS::Vertex(itL.Value());
409 if (Vcur.IsSame(V)) {
410 ilyest = Standard_True;
415 trouve = Standard_True;
416 VRoot = TopoDS::Vertex(it.Key());
423 static Standard_Boolean SearchVertex (const TopTools_ListOfShape& List,
424 const TopoDS_Wire& W,
427 Standard_Boolean trouve = Standard_False;
429 TopTools_SequenceOfShape SeqV;
430 SeqOfVertices(W,SeqV);
431 for (Standard_Integer ii=1;ii<=SeqV.Length();ii++) {
432 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
433 TopTools_ListIteratorOfListOfShape itL;
434 Standard_Boolean ilyest = Standard_False;
435 for (itL.Initialize(List); itL.More(); itL.Next()) {
436 TopoDS_Vertex Vcur = TopoDS::Vertex(itL.Value());
437 if (Vcur.IsSame(Vi)) {
438 ilyest = Standard_True;
443 trouve = Standard_True;
452 static Standard_Boolean EdgeIntersectOnWire (const gp_Pnt& P1,
454 Standard_Real percent,
455 const TopTools_DataMapOfShapeListOfShape& Map,
456 const TopoDS_Wire& W,
459 TopTools_DataMapOfShapeSequenceOfShape& theEdgeNewEdges)
462 BRepTools_WireExplorer anExp;
464 // construction of the edge of intersection
465 Standard_Boolean NewVertex = Standard_False;
466 gp_Lin droite(P1,gp_Dir(gp_Vec(P1,P2)));
467 // ATTENTION : it is required to construct a half-straight
468 // but there is a bug in BRepExtrema_DistShapeShape
469 // it is enough to take 100 * distance between P1 and P2
470 // hoping that it is enough until the bug is corrected
471 // Standard_Real dernierparam = Precision::Infinite();
472 // ATTENTION : return !!
473 // 100 is better than 10 but it is too much !
474 // finally, nothing is better than a blocking box
475 // Standard_Real dernierparam = 100 * P1.Distance(P2);
477 BRepBndLib::Add(W,B);
478 Standard_Real x1,x2,y1,y2,z1,z2;
479 B.Get(x1,y1,z1,x2,y2,z2);
480 gp_Pnt BP1(x1,y1,z1), BP2(x2,y2,z2);
481 Standard_Real diag = BP1.Distance(BP2);
482 Standard_Real dernierparam = diag;
483 BRepLib_MakeEdge ME(droite,0.,dernierparam);
484 TopoDS_Edge ECur = BRepLib_MakeEdge(droite,0.,P1.Distance(P2));
486 // calculate the intersection by BRepExtrema (point of min distance)
487 BRepExtrema_DistShapeShape DSS(ME.Edge(),W);
489 // choose the solution closest to P2
490 Standard_Integer isol = 1;
491 gp_Pnt Psol = DSS.PointOnShape2(isol);
492 Standard_Real dss = P2.Distance(Psol);
493 for (Standard_Integer iss=2; iss<=DSS.NbSolution(); iss++) {
494 gp_Pnt Pss = DSS.PointOnShape2(iss);
495 Standard_Real aDist = P2.Distance(Pss);
505 // is the solution a new vertex ?
506 NewVertex = (DSS.SupportTypeShape2(isol) != BRepExtrema_IsVertex);
508 TopoDS_Edge E = TopoDS::Edge(DSS.SupportOnShape2(isol));
509 Standard_Real tol = Precision::PConfusion();
510 Standard_Real first,last,param;
511 BRep_Tool::Range(E,first,last);
512 tol = Max(tol,percent*Abs(last-first));
513 DSS.ParOnEdgeS2(isol,param);
514 if (Abs(first-param)<tol) {
515 NewVertex = Standard_False;
516 Vsol = TopExp::FirstVertex(E);
518 else if (Abs(last-param)<tol) {
519 NewVertex = Standard_False;
520 Vsol = TopExp::LastVertex(E);
525 if (SearchRoot(Vsol,Map,VRoot)) NewVertex = Standard_True;
529 TopoDS_Shape aLocalShape = DSS.SupportOnShape2(isol);
530 Vsol = TopoDS::Vertex(aLocalShape);
531 // Vsol = TopoDS::Vertex(DSS.SupportOnShape2(isol));
534 // it is required to cut the edge
536 TopoDS_Shape aLocalShape = DSS.SupportOnShape2(isol);
537 TopoDS_Edge E = TopoDS::Edge(aLocalShape);
538 // TopoDS_Edge E = TopoDS::Edge(DSS.SupportOnShape2(isol));
539 TopTools_SequenceOfShape EmptySeq;
540 theEdgeNewEdges.Bind(E, EmptySeq);
541 Standard_Real first,last,param;
542 DSS.ParOnEdgeS2(isol,param);
543 BRep_Tool::Range(E,first,last);
545 for (anExp.Init(W); anExp.More(); anExp.Next()) {
546 if (E.IsSame(anExp.Current())) {
548 = (anExp.CurrentVertex().IsSame(TopExp::FirstVertex(E)));
549 TopTools_SequenceOfShape SE;
551 TColStd_SequenceOfReal SR;
554 TrimEdge(E,SR,first,last,SO,SE);
555 theEdgeNewEdges(E) = SE;
556 TopoDS_Vertex VV1,VV2;
557 TopExp::Vertices(TopoDS::Edge(SE.Value(1)),VV1,VV2);
558 if (TopExp::FirstVertex(E).IsSame(VV1)
559 || TopExp::LastVertex(E).IsSame(VV1)) {
562 if (TopExp::FirstVertex(E).IsSame(VV2)
563 || TopExp::LastVertex(E).IsSame(VV2)) {
566 for (Standard_Integer k=1; k<=SE.Length(); k++) {
567 MW.Add(TopoDS::Edge(SE.Value(k)));
571 MW.Add(anExp.Current());
588 static void Transform (const Standard_Boolean WithRotation,
597 Pnew = P.Translated (Pos1,Pos2);
598 gp_Vec axe1 = Ax1, axe2 = Ax2;
599 if (!axe1.IsParallel(axe2,1.e-4)) {
600 gp_Vec Vtrans(Pos1,Pos2),Vsign;
601 Standard_Real alpha,beta,sign=1;
602 alpha = Vtrans.Dot(axe1);
603 beta = Vtrans.Dot(axe2);
604 if (alpha<-1.e-7) axe1 *=-1;
605 if (beta<1.e-7) axe2 *=-1;
606 alpha = Vtrans.Dot(axe1);
607 beta = Vtrans.Dot(axe2);
608 gp_Vec norm2 = axe1 ^ axe2;
609 Vsign.SetLinearForm(Vtrans.Dot(axe1),axe2,-Vtrans.Dot(axe2),axe1);
610 alpha = Vsign.Dot(axe1);
611 beta = Vsign.Dot(axe2);
612 Standard_Boolean pasnul = (Abs(alpha)>1.e-4 && Abs(beta)>1.e-4);
613 if ( alpha*beta>0.0 && pasnul ) sign=-1;
614 gp_Ax1 Norm(Pos2,norm2);
615 Standard_Real ang = axe1.AngleWithRef(axe2,norm2);
617 if (ang>M_PI/2) ang = ang - M_PI;
618 if (ang<-M_PI/2) ang = ang + M_PI;
621 Pnew = Pnew.Rotated (Norm,ang);
625 static void BuildConnectedEdges(const TopoDS_Wire& aWire,
626 const TopoDS_Edge& StartEdge,
627 const TopoDS_Vertex& StartVertex,
628 TopTools_ListOfShape& ConnectedEdges)
630 TopTools_IndexedDataMapOfShapeListOfShape MapVE;
631 TopExp::MapShapesAndAncestors(aWire, TopAbs_VERTEX, TopAbs_EDGE, MapVE);
632 TopoDS_Edge CurEdge = StartEdge;
633 TopoDS_Vertex CurVertex = StartVertex;
634 TopoDS_Vertex Origin, V1, V2;
635 TopExp::Vertices(StartEdge, V1, V2);
636 Origin = (V1.IsSame(StartVertex))? V2 : V1;
640 TopTools_ListIteratorOfListOfShape itE( MapVE.FindFromKey(CurVertex) );
641 for (; itE.More(); itE.Next())
643 TopoDS_Edge anEdge = TopoDS::Edge(itE.Value());
644 if (!anEdge.IsSame(CurEdge))
646 ConnectedEdges.Append(anEdge);
647 TopExp::Vertices(anEdge, V1, V2);
648 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
653 if (CurVertex.IsSame(Origin))
658 //=======================================================================
659 //function : BRepFill_CompatibleWires
661 //=======================================================================
663 BRepFill_CompatibleWires::BRepFill_CompatibleWires()
664 :myIsDone(Standard_False)
669 //=======================================================================
670 //function : BRepFill_CompatibleWires
672 //=======================================================================
674 BRepFill_CompatibleWires::BRepFill_CompatibleWires(const TopTools_SequenceOfShape& Sections)
680 //=======================================================================
683 //=======================================================================
685 void BRepFill_CompatibleWires::Init(const TopTools_SequenceOfShape& Sections)
690 myIsDone = Standard_False;
696 //=======================================================================
697 //function : SetPercent
699 //=======================================================================
701 void BRepFill_CompatibleWires::SetPercent(const Standard_Real Percent)
703 if (0.<Percent && Percent<1.) myPercent = Percent;
708 //=======================================================================
711 //=======================================================================
713 Standard_Boolean BRepFill_CompatibleWires::IsDone() const
719 //=======================================================================
722 //=======================================================================
724 const TopTools_SequenceOfShape& BRepFill_CompatibleWires::Shape() const
730 //=======================================================================
731 //function : GeneratedShapes
733 //=======================================================================
735 const TopTools_ListOfShape& BRepFill_CompatibleWires::GeneratedShapes
736 (const TopoDS_Edge& SubSection) const
739 if (myMap.IsBound(SubSection)) {
740 return myMap(SubSection);
743 static TopTools_ListOfShape Empty;
749 //=======================================================================
752 //=======================================================================
754 void BRepFill_CompatibleWires::Perform (const Standard_Boolean WithRotation)
756 // compute origin and orientation on wires to avoid twisted results
757 // and update wires to have same number of edges
759 // determination of report:
760 // if the number of elements is the same and if the wires have discontinuities
761 // by tangency, the report is not carried out by curvilinear abscissa
762 Standard_Integer nbSects = myWork.Length(), i;
763 BRepTools_WireExplorer anExp;
764 Standard_Integer nbmax=0, nbmin=0;
765 TColStd_Array1OfInteger nbEdges(1,nbSects);
766 Standard_Boolean report;
767 GeomAbs_Shape contS=GeomAbs_CN;
769 for (i=1; i<=nbSects; i++) {
770 TopoDS_Shape aLocalShape = myWork(i).Oriented(TopAbs_FORWARD);
771 myWork(i) = TopoDS::Wire(aLocalShape);
772 // myWork(i) = TopoDS::Wire(myWork(i).Oriented(TopAbs_FORWARD));
773 TopoDS_Wire W = TopoDS::Wire(myWork(i));
774 WireContinuity(W,cont);
775 if (cont<contS) contS=cont;
777 for(anExp.Init(W); anExp.More(); anExp.Next() ) nbEdges(i)++;
778 if (i==1) nbmin = nbEdges(i);
779 if (nbmax<nbEdges(i)) nbmax = nbEdges(i);
780 if (nbmin>nbEdges(i)) nbmin = nbEdges(i);
782 // if the number of elements is not the same or if all wires are at least
783 // C1, the report is carried out by curvilinear abscissa of cuts, otherwise
784 // a report vertex / Vertex is done
785 report = (nbmax != nbmin || contS >= GeomAbs_C1 );
787 // initialization of the map
788 Standard_Integer nbE = 0;
789 TopTools_ListOfShape Empty;
790 for (i=1; i<=nbSects; i++) {
791 TopoDS_Wire W = TopoDS::Wire(myWork(i));
792 for(anExp.Init(W); anExp.More(); anExp.Next() ) {
793 TopoDS_Edge E = TopoDS::Edge(anExp.Current());
800 // open/closed sections
801 // initialisation of myDegen1, myDegen2
802 Standard_Integer ideb=1, ifin=myWork.Length();
803 // check if the first wire is punctual
804 myDegen1 = Standard_True;
805 for(anExp.Init(TopoDS::Wire(myWork(ideb))); anExp.More(); anExp.Next()) {
806 myDegen1 = myDegen1 && (BRep_Tool::Degenerated(anExp.Current()));
808 if (myDegen1) ideb++;
809 // check if the last wire is punctual
810 myDegen2 = Standard_True;
811 for(anExp.Init(TopoDS::Wire(myWork(ifin))); anExp.More(); anExp.Next()) {
812 myDegen2 = myDegen2 && (BRep_Tool::Degenerated(anExp.Current()));
814 if (myDegen2) ifin--;
816 Standard_Boolean wClosed, allClosed = Standard_True, allOpen = Standard_True;
817 for (i=ideb; i<=ifin; i++) {
818 wClosed = myWork(i).Closed();
820 // check if the vertices are the same.
821 TopoDS_Vertex V1, V2;
822 TopExp::Vertices(TopoDS::Wire(myWork(i)),V1,V2);
823 if ( V1.IsSame(V2)) wClosed = Standard_True;
825 allClosed = (allClosed && wClosed);
826 allOpen = (allOpen && !wClosed);
830 // All sections are closed
832 // same number of elements
833 SameNumberByPolarMethod(WithRotation);
837 ComputeOrigin(Standard_False);
839 myIsDone = Standard_True;
842 // All sections are open
845 // same number of elements
847 SameNumberByACR(report);
849 myIsDone = Standard_True;
852 // There are open and closed sections :
854 Standard_DomainError::Raise("Sections must be all closed or all open");
862 //=======================================================================
863 //function : Generated
865 //=======================================================================
867 const TopTools_DataMapOfShapeListOfShape& BRepFill_CompatibleWires::Generated() const
873 //=======================================================================
874 //function : SameNumberByPolarMethod
876 //=======================================================================
878 void BRepFill_CompatibleWires::
879 SameNumberByPolarMethod(const Standard_Boolean WithRotation)
883 Standard_Integer NbSects=myWork.Length();
884 BRepTools_WireExplorer anExp;
885 TopTools_DataMapOfShapeSequenceOfShape EdgeNewEdges;
887 Standard_Boolean allClosed = Standard_True;
888 Standard_Integer i,ii,ideb=1,ifin=NbSects;
890 for (i=1; i<=NbSects; i++) {
891 Handle(BRepCheck_Wire) Checker = new BRepCheck_Wire(TopoDS::Wire(myWork(i)));
892 allClosed = (allClosed && (Checker->Closed() == BRepCheck_NoError));
893 //allClosed = (allClosed && myWork(i).Closed());
896 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SameNumberByPolarMethod : the wires must be closed");
898 // sections ponctuelles, sections bouclantes ?
899 if (myDegen1) ideb++;
900 if (myDegen2) ifin--;
901 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
902 && (myWork(ideb).IsSame(myWork(ifin)));
904 //Removing degenerated edges
905 for (i = ideb; i <= ifin; i++)
907 Standard_Boolean hasDegEdge = Standard_False;
908 TopoDS_Iterator anItw(myWork(i));
909 for (; anItw.More(); anItw.Next())
911 const TopoDS_Edge& anEdge = TopoDS::Edge(anItw.Value());
912 if (BRep_Tool::Degenerated(anEdge))
914 hasDegEdge = Standard_True;
920 TopoDS_Wire aNewWire;
921 BRep_Builder aBBuilder;
922 aBBuilder.MakeWire(aNewWire);
923 for (anItw.Initialize(myWork(i)); anItw.More(); anItw.Next())
925 const TopoDS_Edge& anEdge = TopoDS::Edge(anItw.Value());
926 if (!BRep_Tool::Degenerated(anEdge))
927 aBBuilder.Add(aNewWire, anEdge);
929 myWork(i) = aNewWire;
933 // Nombre max de decoupes possibles
934 Standard_Integer NbMaxV = 0;
935 for (i=1; i<=NbSects; i++) {
936 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
941 // construction of tables of planes of wires
943 Handle(TColgp_HArray1OfPnt) Pos
944 = new (TColgp_HArray1OfPnt) (1,NbSects);
945 Handle(TColgp_HArray1OfVec) Axe
946 = new (TColgp_HArray1OfVec) (1,NbSects);
947 for (i=ideb;i<=ifin;i++) {
948 if (PlaneOfWire(TopoDS::Wire(myWork(i)),P)) {
949 Pos->SetValue(i,P.Location());
950 Axe->SetValue(i,gp_Vec(P.Axis().Direction()));
953 TopTools_SequenceOfShape SeqV;
955 SeqOfVertices(TopoDS::Wire(myWork(1)),SeqV);
956 Pos->SetValue(1,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
957 Axe->SetValue(1,Axe->Value(ideb));
960 SeqOfVertices(TopoDS::Wire(myWork(NbSects)),SeqV);
961 Pos->SetValue(NbSects,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
962 Axe->SetValue(NbSects,Axe->Value(ifin));
965 // construction of RMap, map of reports of wire i to wire i-1
966 TopTools_DataMapOfShapeListOfShape RMap;
970 for (i=ifin; i>ideb; i--) {
972 const TopoDS_Wire& wire1 = TopoDS::Wire(myWork(i));
974 // sequence of vertices of the first wire
975 SeqOfVertices(wire1,SeqV);
976 if (SeqV.Length()>NbMaxV)
977 Standard_NoSuchObject::Raise("BRepFill::SameNumberByPolarMethod failed");
979 // loop on vertices of wire1
980 for (ii=1;ii<=SeqV.Length();ii++) {
982 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
984 // init of RMap for Vi
985 TopTools_ListOfShape Init;
989 // it is required to find intersection Vi - wire2
990 gp_Pnt Pi = BRep_Tool::Pnt(Vi);
992 // return Pi in the current plane
994 Transform(WithRotation,Pi,
995 Pos->Value(i),Axe->Value(i),
996 Pos->Value(i-1),Axe->Value(i-1),Pnew);
998 // calculate the intersection
999 TopoDS_Shape Support;
1000 Standard_Boolean NewVertex;
1002 TopoDS_Wire newwire;
1003 if (Pnew.Distance(Pos->Value(i-1))>Precision::Confusion()) {
1004 Standard_Real percent = myPercent;
1005 NewVertex = EdgeIntersectOnWire(Pos->Value(i-1),Pnew,percent,
1006 RMap,TopoDS::Wire(myWork(i-1)),
1007 Vsol,newwire,EdgeNewEdges);
1008 if (NewVertex) myWork(i-1) = newwire;
1009 RMap(Vi).Append(Vsol);
1015 // initialisation of MapVLV, map of correspondences vertex - list of vertices
1016 TopTools_DataMapOfShapeListOfShape MapVLV;
1017 SeqOfVertices(TopoDS::Wire(myWork(ideb)),SeqV);
1018 Standard_Integer SizeMap = SeqV.Length();
1020 for (ii=1;ii<=SizeMap;ii++) {
1021 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
1022 TopTools_ListOfShape Init;
1025 MapVLV.Bind(Vi,Init);
1026 Standard_Integer NbV = 1;
1027 TopoDS_Vertex V0,V1;
1029 Standard_Boolean tantque = SearchRoot(V0,RMap,V1);
1031 MapVLV(Vi).Append(V1);
1033 // test on NbV required for looping sections
1034 if (V1.IsSame(Vi) || NbV >= myWork.Length()) {
1035 tantque = Standard_False;
1039 tantque = SearchRoot(V0,RMap,V1);
1045 for (i=ideb; i<ifin; i++) {
1047 const TopoDS_Wire& wire1 = TopoDS::Wire(myWork(i));
1049 // sequence of vertices of the first wire
1050 SeqOfVertices(wire1,SeqV);
1051 if ( SeqV.Length()>NbMaxV || SeqV.Length()>SizeMap )
1052 Standard_NoSuchObject::Raise("BRepFill::SameNumberByPolarMethod failed");
1056 const TopoDS_Wire& wire2 = TopoDS::Wire(myWork(i+1));
1058 // loop on vertices of wire1
1059 for (ii=1;ii<=SeqV.Length();ii++) {
1061 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
1062 TopoDS_Vertex VRoot;
1064 Standard_Boolean intersect = Standard_True;
1065 if (SearchRoot(Vi,MapVLV,VRoot)) {
1066 const TopTools_ListOfShape& LVi = MapVLV(VRoot);
1069 intersect = (!SearchVertex(LVi,wire2,VonW));
1073 // it is necessary to find intersection Vi - wire2
1074 gp_Pnt Pi = BRep_Tool::Pnt(Vi);
1076 // return Pi in the current plane
1078 Transform(WithRotation,Pi,
1079 Pos->Value(i),Axe->Value(i),
1080 Pos->Value(i+1),Axe->Value(i+1),Pnew);
1082 // calculate the intersection
1083 TopoDS_Shape Support;
1084 Standard_Boolean NewVertex;
1086 TopoDS_Wire newwire;
1087 if (Pnew.Distance(Pos->Value(i+1))>Precision::Confusion()) {
1088 Standard_Real percent = myPercent;
1089 NewVertex = EdgeIntersectOnWire(Pos->Value(i+1),Pnew,percent,
1090 MapVLV,TopoDS::Wire(myWork(i+1)),
1091 Vsol,newwire,EdgeNewEdges);
1092 MapVLV(VRoot).Append(Vsol);
1093 if (NewVertex) myWork(i+1) = newwire;
1100 // regularize wires following MapVLV
1101 TopoDS_Wire wire = TopoDS::Wire(myWork(ideb));
1103 // except for the last if the sections loop
1104 Standard_Integer ibout = ifin;
1105 if (vClosed) ibout--;
1107 for ( i=ideb+1; i<=ibout; i++) {
1109 BRepLib_MakeWire MW;
1112 TopoDS_Edge ECur = anExp.Current();
1113 TopoDS_Vertex VF,VL;
1114 TopExp::Vertices(ECur,VF,VL,Standard_True);
1115 Standard_Real U1 = BRep_Tool::Parameter(VF,ECur);
1116 Standard_Real U2 = BRep_Tool::Parameter(VL,ECur);
1117 BRepAdaptor_Curve Curve(ECur);
1118 gp_Pnt PPs = Curve.Value(0.1*(U1+9*U2));
1119 TopTools_ListIteratorOfListOfShape itF(MapVLV(VF)),itL(MapVLV(VL));
1120 Standard_Integer rang = ideb;
1126 TopoDS_Vertex V1 = TopoDS::Vertex(itF.Value()), V2 = TopoDS::Vertex(itL.Value());
1128 Standard_Real scalmax=0.;
1129 TopoDS_Iterator itW( myWork(i) );
1131 for(; itW.More(); itW.Next())
1133 TopoDS_Edge E = TopoDS::Edge(itW.Value());
1134 TopoDS_Vertex VVF,VVL;
1135 TopExp::Vertices(E,VVF,VVL,Standard_True);
1137 // parse candidate edges
1138 Standard_Real scal1,scal2;
1139 if ( (V1.IsSame(VVF)&&V2.IsSame(VVL)) || (V2.IsSame(VVF)&&V1.IsSame(VVL)) ) {
1140 Standard_Real U1param = BRep_Tool::Parameter(VVF,E);
1141 Standard_Real U2param = BRep_Tool::Parameter(VVL,E);
1142 BRepAdaptor_Curve CurveE(E);
1143 gp_Pnt PP1 = CurveE.Value(0.1*(U1param +9* U2param));
1144 gp_Pnt PP2 = CurveE.Value(0.1*(9* U1param + U2param));
1146 for (rang=i;rang>ideb;rang--) {
1147 Transform(WithRotation, PP1,
1148 Pos->Value(rang), Axe->Value(rang),
1149 Pos->Value(rang-1), Axe->Value(rang-1), PP1);
1150 Transform(WithRotation, PP2,
1151 Pos->Value(rang), Axe->Value(rang),
1152 Pos->Value(rang-1), Axe->Value(rang-1), PP2);
1154 gp_Vec Ns(Pos->Value(ideb),PPs);
1155 Ns = Ns.Normalized();
1156 gp_Vec N1(Pos->Value(ideb),PP1);
1157 N1 = N1.Normalized();
1158 gp_Vec N2(Pos->Value(ideb),PP2);
1159 N2 = N2.Normalized();
1161 if (scal1>scalmax) {
1166 if (scal2>scalmax) {
1168 TopoDS_Shape aLocalShape = E.Reversed();
1169 Esol = TopoDS::Edge(aLocalShape);
1172 } //end of for(; itW.More(); itW.Next())
1174 Standard_ConstructionError::Raise("BRepFill :: profiles are inconsistent");
1177 TopTools_ListOfShape ConnectedEdges;
1178 BuildConnectedEdges( TopoDS::Wire(myWork(i)), Esol, V2, ConnectedEdges );
1180 TopTools_ListIteratorOfListOfShape itCE(ConnectedEdges);
1181 for(; anExp.More(), itCE.More(); anExp.Next(), itCE.Next())
1183 ECur = anExp.Current();
1184 TopExp::Vertices(ECur,VF,VL,Standard_True);
1185 U1 = BRep_Tool::Parameter(VF,ECur);
1186 U2 = BRep_Tool::Parameter(VL,ECur);
1187 Curve.Initialize(ECur);
1188 PPs = Curve.Value(0.1*(U1+9*U2));
1190 TopoDS_Edge E = TopoDS::Edge(itCE.Value());
1191 TopoDS_Vertex VVF,VVL;
1192 TopExp::Vertices(E,VVF,VVL,Standard_True);
1194 // parse candidate edges
1195 Standard_Real scal1,scal2;
1196 U1 = BRep_Tool::Parameter(VVF,E);
1197 U2 = BRep_Tool::Parameter(VVL,E);
1198 Curve.Initialize(E);
1199 gp_Pnt PP1 = Curve.Value(0.1*(U1+9*U2));
1200 gp_Pnt PP2 = Curve.Value(0.1*(9*U1+U2));
1202 for (rang=i;rang>ideb;rang--) {
1203 Transform(WithRotation, PP1,
1204 Pos->Value(rang), Axe->Value(rang),
1205 Pos->Value(rang-1), Axe->Value(rang-1), PP1);
1206 Transform(WithRotation, PP2,
1207 Pos->Value(rang), Axe->Value(rang),
1208 Pos->Value(rang-1), Axe->Value(rang-1), PP2);
1210 gp_Vec Ns(Pos->Value(ideb),PPs);
1211 Ns = Ns.Normalized();
1212 gp_Vec N1(Pos->Value(ideb),PP1);
1213 N1 = N1.Normalized();
1214 gp_Vec N2(Pos->Value(ideb),PP2);
1215 N2 = N2.Normalized();
1222 myWork(i) = MW.Wire();
1225 // blocking sections?
1226 if (vClosed) myWork(myWork.Length()) = myWork(1);
1228 // check the number of edges for debug
1229 Standard_Integer nbmax=0, nbmin=0;
1230 for ( i=ideb; i<=ifin; i++) {
1231 Standard_Integer nbEdges=0;
1232 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1235 if (i==ideb) nbmin = nbEdges;
1236 if (nbmax<nbEdges) nbmax = nbEdges;
1237 if (nbmin>nbEdges) nbmin = nbEdges;
1240 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SameNumberByPolarMethod failed");
1244 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itmap(myMap);
1245 for (; itmap.More(); itmap.Next())
1247 TopoDS_Shape anEdge = itmap.Key();
1248 TopTools_ListOfShape ListOfNewEdges;
1250 //for each edge of <myMap> find all newest edges
1251 //in <EdgeNewEdges> recursively
1252 AddNewEdge(anEdge, EdgeNewEdges, ListOfNewEdges);
1254 myMap(anEdge) = ListOfNewEdges;
1258 //=======================================================================
1259 //function : SameNumberByACR
1261 //=======================================================================
1263 void BRepFill_CompatibleWires::SameNumberByACR(const Standard_Boolean report)
1265 // find the dimension
1266 Standard_Integer ideb=1, ifin=myWork.Length();
1267 BRepTools_WireExplorer anExp;
1269 // point sections, blocking sections?
1270 if (myDegen1) ideb++;
1271 if (myDegen2) ifin--;
1272 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
1273 && (myWork(ideb).IsSame(myWork(ifin)));
1275 Standard_Integer nbSects = myWork.Length(), i;
1276 Standard_Integer nbmax=0, nbmin=0;
1277 TColStd_Array1OfInteger nbEdges(1,nbSects);
1278 for (i=1; i<=nbSects; i++) {
1280 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1283 if (i==1) nbmin = nbEdges(i);
1284 if (nbmax<nbEdges(i)) nbmax = nbEdges(i);
1285 if (nbmin>nbEdges(i)) nbmin = nbEdges(i);
1291 if (report || nbmin<nbmax) {
1292 // insertion of cuts
1293 Standard_Integer nbdec=(nbmax-1)*nbSects+1;
1294 TColStd_Array1OfReal dec(1,nbdec);
1298 TColStd_Array1OfReal WireLen(1, nbSects);
1300 // calculate the table of cuts
1301 Standard_Integer j,k,l;
1302 for (i=1; i<=nbSects; i++) {
1304 const TopoDS_Wire& wire1 = TopoDS::Wire(myWork(i));
1305 Standard_Integer nbE = 0;
1306 for(anExp.Init(wire1); anExp.More(); anExp.Next()) {
1309 // length and ACR of the wire
1310 TColStd_Array1OfReal ACR(0,nbE);
1312 BRepFill::ComputeACR(wire1, ACR);
1313 WireLen(i) = ACR(0);
1314 // insertion of ACR of the wire in the table of cuts
1315 for (j=1; j<ACR.Length()-1; j++) {
1317 while (dec(k)<ACR(j)) {
1321 if (dec(k-1)<ACR(j)&& ACR(j)<dec(k)) {
1322 for (l=nbdec-1;l>=k;l--) {
1337 TColStd_Array1OfReal dec2(1,nbdec);
1338 for (k=1;k<=nbdec;k++) {
1342 //Check of cuts: are all the new edges long enouph or not
1343 TColStd_MapOfInteger CutsToRemove;
1344 for (k = 1; k <= nbdec; k++)
1346 Standard_Real Knot1 = dec2(k);
1347 Standard_Real Knot2 = (k == nbdec)? 1. : dec2(k+1);
1348 Standard_Real AllLengthsNull = Standard_True;
1349 for (i = 1; i <= nbSects; i++)
1351 Standard_Real EdgeLen = (Knot2 - Knot1) * WireLen(i);
1352 if (EdgeLen > Precision::Confusion())
1354 AllLengthsNull = Standard_False;
1359 CutsToRemove.Add(k);
1361 Standard_Integer NewNbDec = nbdec - CutsToRemove.Extent();
1362 TColStd_Array1OfReal dec3(1, NewNbDec);
1364 for (k = 1; k <= nbdec; k++)
1365 if (!CutsToRemove.Contains(k))
1366 dec3(i++) = dec2(k);
1369 // insertion of cuts in each wire
1370 for (i=1; i<=nbSects; i++) {
1371 const TopoDS_Wire& oldwire = TopoDS::Wire(myWork(i));
1372 Standard_Real tol = Precision::Confusion() / WireLen(i);
1373 TopoDS_Wire newwire = BRepFill::InsertACR(oldwire, dec3, tol);
1374 BRepTools_WireExplorer anExp1,anExp2;
1375 anExp1.Init(oldwire);
1376 anExp2.Init(newwire);
1377 for (;anExp1.More();anExp1.Next()) {
1378 const TopoDS_Edge& Ecur = anExp1.Current();
1379 if (!Ecur.IsSame(TopoDS::Edge(anExp2.Current()))) {
1380 TopTools_ListOfShape LE;
1383 const TopoDS_Vertex& V1 = anExp1.CurrentVertex();
1384 TopoDS_Vertex VF,VR;
1385 TopExp::Vertices(Ecur,VF,VR,Standard_True);
1386 if (V1.IsSame(VF)) P1 = BRep_Tool::Pnt(VR);
1387 if (V1.IsSame(VR)) P1 = BRep_Tool::Pnt(VF);
1388 TopoDS_Vertex V2 = anExp2.CurrentVertex();
1389 TopExp::Vertices(TopoDS::Edge(anExp2.Current()),
1390 VF,VR,Standard_True);
1391 if (V2.IsSame(VF)) P2 = BRep_Tool::Pnt(VR);
1392 if (V2.IsSame(VR)) P2 = BRep_Tool::Pnt(VF);
1393 while (P1.Distance(P2)>1.e-3) {
1394 LE.Append(anExp2.Current());
1396 V2 = anExp2.CurrentVertex();
1397 TopExp::Vertices(TopoDS::Edge(anExp2.Current()),
1398 VF,VR,Standard_True);
1399 if (V2.IsSame(VF)) P2 = BRep_Tool::Pnt(VR);
1400 if (V2.IsSame(VR)) P2 = BRep_Tool::Pnt(VF);
1401 if (P1.Distance(P2)<=1.e-3) {
1402 LE.Append(anExp2.Current());
1407 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itmap;
1408 //TopTools_ListIteratorOfListOfShape itlist;
1409 TopoDS_Edge Ancestor;
1410 Standard_Integer nbedge, nblist=0;
1411 Standard_Boolean found = Standard_False;
1413 for (itmap.Initialize(myMap);itmap.More()&&(!found);itmap.Next()) {
1415 TopTools_ListIteratorOfListOfShape itlist(itmap.Value());
1417 while (itlist.More()&&(!found)) {
1419 TopoDS_Edge ECur = TopoDS::Edge(itlist.Value());
1421 if (Ecur.IsSame(ECur)) {
1422 Ancestor = TopoDS::Edge(itmap.Key());
1423 found = Standard_True;
1424 myMap(Ancestor).InsertBefore(LE,itlist);
1425 myMap(Ancestor).Remove(itlist);
1427 if (itlist.More()) itlist.Next();
1438 myWork(i) = newwire;
1444 // blocking sections ?
1445 if (vClosed) myWork(myWork.Length()) = myWork(1);
1447 // check the number of edges for debug
1449 for (i=ideb; i<=ifin; i++) {
1451 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1454 if (i==ideb) nbmin = nbEdges(i);
1455 if (nbmax<nbEdges(i)) nbmax = nbEdges(i);
1456 if (nbmin>nbEdges(i)) nbmin = nbEdges(i);
1459 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SameNumberByACR failed");
1462 //=======================================================================
1463 //function : ComputeOrigin
1465 //=======================================================================
1467 void BRepFill_CompatibleWires::ComputeOrigin(const Standard_Boolean /*polar*/ )
1469 // reorganize the wires respecting orientation and origin
1471 TopoDS_Vertex Vdeb, Vfin;
1472 gp_Pnt Pdeb, Psuiv, PPs;
1474 BRepTools_WireExplorer anExp;
1476 Standard_Boolean wClosed, allClosed = Standard_True;
1478 Standard_Integer NbSects = myWork.Length();
1479 Standard_Integer i, ideb=1,ifin=NbSects;
1481 // point sections, blocking sections
1482 if (myDegen1) ideb++;
1483 if (myDegen2) ifin--;
1484 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
1485 && (myWork(ideb).IsSame(myWork(ifin)));
1488 for (i=ideb; i<=ifin; i++) {
1489 wClosed = myWork(i).Closed();
1491 // check if the vertices are the same.
1492 TopoDS_Vertex V1, V2;
1493 TopExp::Vertices(TopoDS::Wire(myWork(i)),V1,V2);
1494 if ( V1.IsSame(V2)) wClosed = Standard_True;
1496 allClosed = (allClosed && wClosed);
1499 for (i=ideb; i<=ifin; i++) {
1500 allClosed = (allClosed && myWork(i).Closed());
1504 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::ComputeOrigin : the wires must be closed");
1507 // Max number of possible cuts
1508 Standard_Integer NbMaxV = 0;
1509 for (i=1; i<=NbSects; i++) {
1510 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1515 // construction of tables of planes of wires
1517 Handle(TColgp_HArray1OfPnt) Pos
1518 = new (TColgp_HArray1OfPnt) (1,NbSects);
1519 Handle(TColgp_HArray1OfVec) Axe
1520 = new (TColgp_HArray1OfVec) (1,NbSects);
1521 for (i=ideb;i<=ifin;i++) {
1522 if (PlaneOfWire(TopoDS::Wire(myWork(i)),P)) {
1523 Pos->SetValue(i,P.Location());
1524 Axe->SetValue(i,gp_Vec(P.Axis().Direction()));
1527 TopTools_SequenceOfShape SeqV;
1529 SeqOfVertices(TopoDS::Wire(myWork(1)),SeqV);
1530 Pos->SetValue(1,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
1531 Axe->SetValue(1,Axe->Value(ideb));
1534 SeqOfVertices(TopoDS::Wire(myWork(NbSects)),SeqV);
1535 Pos->SetValue(NbSects,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
1536 Axe->SetValue(NbSects,Axe->Value(ifin));
1540 //Consider that all wires have same number of edges (polar==Standard_False)
1541 TopTools_SequenceOfShape PrevSeq;
1542 TopTools_SequenceOfShape PrevEseq;
1543 Standard_Integer theLength = 0;
1544 const TopoDS_Wire& wire = TopoDS::Wire( myWork(ideb) );
1545 for (anExp.Init(wire); anExp.More(); anExp.Next())
1547 PrevSeq.Append(anExp.CurrentVertex());
1548 PrevEseq.Append(anExp.Current());
1552 Standard_Integer nbs, NbSamples = 0;
1556 PlaneOfWire(TopoDS::Wire(myWork(ideb)), FirstPlane);
1557 gp_Pnt FirstBary = FirstPlane.Location();
1558 gp_Vec NormalOfFirstPlane = FirstPlane.Axis().Direction();
1559 for (i = ideb+1; i <= ifin; i++)
1561 const TopoDS_Wire& aWire = TopoDS::Wire(myWork(i));
1563 //Compute offset vector as current bary center projected on first plane
1564 //to first bary center
1566 PlaneOfWire(aWire, CurPlane);
1567 gp_Pnt CurBary = CurPlane.Location();
1568 gp_Vec aVec(FirstBary, CurBary);
1569 gp_Vec anOffsetProj = (aVec * NormalOfFirstPlane) * NormalOfFirstPlane;
1570 CurBary.Translate(-anOffsetProj); //projected current bary center
1571 gp_Vec Offset(CurBary, FirstBary);
1573 TopoDS_Wire newwire;
1575 BB.MakeWire(newwire);
1577 TopTools_SequenceOfShape SeqVertices, SeqEdges;
1578 for (anExp.Init(aWire); anExp.More(); anExp.Next())
1580 SeqVertices.Append( anExp.CurrentVertex() );
1581 SeqEdges.Append( anExp.Current() );
1584 Standard_Real MinSumDist = Precision::Infinite();
1585 Standard_Integer jmin = 1, j, k, n;
1586 Standard_Boolean forward = Standard_False;
1587 if (i == myWork.Length() && myDegen2)
1589 // last point section
1591 forward = Standard_True;
1594 for (j = 1; j <= theLength; j++)
1597 Standard_Real SumDist = 0.;
1598 for (k = j, n = 1; k <= theLength; k++, n++)
1600 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1601 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1602 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1603 gp_Pnt P = BRep_Tool::Pnt(V).XYZ() + Offset.XYZ();
1604 SumDist += Pprev.Distance(P);
1607 const TopoDS_Edge& PrevEdge = TopoDS::Edge(PrevEseq(n));
1608 const TopoDS_Edge& CurEdge = TopoDS::Edge(SeqEdges(k));
1609 BRepAdaptor_Curve PrevEcurve(PrevEdge);
1610 BRepAdaptor_Curve Ecurve(CurEdge);
1611 Standard_Real SampleOnPrev = (PrevEcurve.LastParameter()-PrevEcurve.FirstParameter())/NbSamples;
1612 Standard_Real SampleOnCur = (Ecurve.LastParameter()-Ecurve.FirstParameter())/NbSamples;
1613 for (nbs = 1; nbs <= NbSamples-1; nbs++)
1615 Standard_Real ParOnPrev = (PrevEdge.Orientation() == TopAbs_FORWARD)?
1616 (PrevEcurve.FirstParameter() + nbs*SampleOnPrev) :
1617 (PrevEcurve.FirstParameter() + (NbSamples-nbs)*SampleOnPrev);
1618 Standard_Real ParOnCur = (CurEdge.Orientation() == TopAbs_FORWARD)?
1619 (Ecurve.FirstParameter() + nbs*SampleOnCur) :
1620 (Ecurve.FirstParameter() + (NbSamples-nbs)*SampleOnCur);
1621 gp_Pnt PonPrev = PrevEcurve.Value(ParOnPrev);
1622 gp_Pnt PonCur = Ecurve.Value(ParOnCur).XYZ() + Offset.XYZ();
1623 SumDist += PonPrev.Distance(PonCur);
1627 for (k = 1; k < j; k++, n++)
1629 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1630 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1631 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1632 gp_Pnt P = BRep_Tool::Pnt(V).XYZ() + Offset.XYZ();
1633 SumDist += Pprev.Distance(P);
1636 const TopoDS_Edge& PrevEdge = TopoDS::Edge(PrevEseq(n));
1637 const TopoDS_Edge& CurEdge = TopoDS::Edge(SeqEdges(k));
1638 BRepAdaptor_Curve PrevEcurve(PrevEdge);
1639 BRepAdaptor_Curve Ecurve(CurEdge);
1640 Standard_Real SampleOnPrev = (PrevEcurve.LastParameter()-PrevEcurve.FirstParameter())/NbSamples;
1641 Standard_Real SampleOnCur = (Ecurve.LastParameter()-Ecurve.FirstParameter())/NbSamples;
1642 for (nbs = 1; nbs <= NbSamples-1; nbs++)
1644 Standard_Real ParOnPrev = (PrevEdge.Orientation() == TopAbs_FORWARD)?
1645 (PrevEcurve.FirstParameter() + nbs*SampleOnPrev) :
1646 (PrevEcurve.FirstParameter() + (NbSamples-nbs)*SampleOnPrev);
1647 Standard_Real ParOnCur = (CurEdge.Orientation() == TopAbs_FORWARD)?
1648 (Ecurve.FirstParameter() + nbs*SampleOnCur) :
1649 (Ecurve.FirstParameter() + (NbSamples-nbs)*SampleOnCur);
1650 gp_Pnt PonPrev = PrevEcurve.Value(ParOnPrev);
1651 gp_Pnt PonCur = Ecurve.Value(ParOnCur).XYZ() + Offset.XYZ();
1652 SumDist += PonPrev.Distance(PonCur);
1656 if (SumDist < MinSumDist)
1658 MinSumDist = SumDist;
1660 forward = Standard_True;
1665 for (k = j, n = 1; k >= 1; k--, n++)
1667 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1668 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1669 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1670 gp_Pnt P = BRep_Tool::Pnt(V).XYZ() + Offset.XYZ();
1671 SumDist += Pprev.Distance(P);
1674 Standard_Integer k_cur = k-1;
1677 const TopoDS_Edge& PrevEdge = TopoDS::Edge(PrevEseq(n));
1678 const TopoDS_Edge& CurEdge = TopoDS::Edge(SeqEdges(k_cur));
1679 BRepAdaptor_Curve PrevEcurve(PrevEdge);
1680 BRepAdaptor_Curve Ecurve(CurEdge);
1681 Standard_Real SampleOnPrev = (PrevEcurve.LastParameter()-PrevEcurve.FirstParameter())/NbSamples;
1682 Standard_Real SampleOnCur = (Ecurve.LastParameter()-Ecurve.FirstParameter())/NbSamples;
1683 for (nbs = 1; nbs <= NbSamples-1; nbs++)
1685 Standard_Real ParOnPrev = (PrevEdge.Orientation() == TopAbs_FORWARD)?
1686 (PrevEcurve.FirstParameter() + nbs*SampleOnPrev) :
1687 (PrevEcurve.FirstParameter() + (NbSamples-nbs)*SampleOnPrev);
1688 Standard_Real ParOnCur = (CurEdge.Orientation() == TopAbs_FORWARD)?
1689 (Ecurve.FirstParameter() + (NbSamples-nbs)*SampleOnCur) :
1690 (Ecurve.FirstParameter() + nbs*SampleOnCur);
1691 gp_Pnt PonPrev = PrevEcurve.Value(ParOnPrev);
1692 gp_Pnt PonCur = Ecurve.Value(ParOnCur).XYZ() + Offset.XYZ();
1693 SumDist += PonPrev.Distance(PonCur);
1697 for (k = theLength; k > j; k--, n++)
1699 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1700 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1701 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1702 gp_Pnt P = BRep_Tool::Pnt(V).XYZ() + Offset.XYZ();
1703 SumDist += Pprev.Distance(P);
1706 const TopoDS_Edge& PrevEdge = TopoDS::Edge(PrevEseq(n));
1707 const TopoDS_Edge& CurEdge = TopoDS::Edge(SeqEdges(k-1));
1708 BRepAdaptor_Curve PrevEcurve(PrevEdge);
1709 BRepAdaptor_Curve Ecurve(CurEdge);
1710 Standard_Real SampleOnPrev = (PrevEcurve.LastParameter()-PrevEcurve.FirstParameter())/NbSamples;
1711 Standard_Real SampleOnCur = (Ecurve.LastParameter()-Ecurve.FirstParameter())/NbSamples;
1712 for (nbs = 1; nbs <= NbSamples-1; nbs++)
1714 Standard_Real ParOnPrev = (PrevEdge.Orientation() == TopAbs_FORWARD)?
1715 (PrevEcurve.FirstParameter() + nbs*SampleOnPrev) :
1716 (PrevEcurve.FirstParameter() + (NbSamples-nbs)*SampleOnPrev);
1717 Standard_Real ParOnCur = (CurEdge.Orientation() == TopAbs_FORWARD)?
1718 (Ecurve.FirstParameter() + (NbSamples-nbs)*SampleOnCur) :
1719 (Ecurve.FirstParameter() + nbs*SampleOnCur);
1720 gp_Pnt PonPrev = PrevEcurve.Value(ParOnPrev);
1721 gp_Pnt PonCur = Ecurve.Value(ParOnCur).XYZ() + Offset.XYZ();
1722 SumDist += PonPrev.Distance(PonCur);
1726 if (SumDist < MinSumDist)
1728 MinSumDist = SumDist;
1730 forward = Standard_False;
1738 for (j = jmin; j <= theLength; j++)
1740 BB.Add( newwire, TopoDS::Edge(SeqEdges(j)) );
1741 PrevSeq.Append( SeqVertices(j) );
1742 PrevEseq.Append( SeqEdges(j) );
1744 for (j = 1; j < jmin; j++)
1746 BB.Add( newwire, TopoDS::Edge(SeqEdges(j)) );
1747 PrevSeq.Append( SeqVertices(j) );
1748 PrevEseq.Append( SeqEdges(j) );
1753 for (j = jmin-1; j >= 1; j--)
1755 TopoDS_Shape aLocalShape = SeqEdges(j).Reversed();
1756 BB.Add( newwire, TopoDS::Edge(aLocalShape) );
1757 //PrevSeq.Append( SeqVertices(j) );
1758 PrevEseq.Append( SeqEdges(j).Reversed() );
1760 for (j = theLength; j >= jmin; j--)
1762 TopoDS_Shape aLocalShape = SeqEdges(j).Reversed();
1763 BB.Add( newwire, TopoDS::Edge(aLocalShape) );
1764 //PrevSeq.Append( SeqVertices(j) );
1765 PrevEseq.Append( SeqEdges(j).Reversed() );
1767 for (j = jmin; j >= 1; j--)
1768 PrevSeq.Append( SeqVertices(j) );
1769 for (j = theLength; j > jmin; j--)
1770 PrevSeq.Append( SeqVertices(j) );
1773 newwire.Closed( Standard_True );
1774 newwire.Orientation( TopAbs_FORWARD );
1775 myWork(i) = newwire;
1777 #ifdef OCCT_DEBUG_EFV
1779 for ( i=ideb; i<=myWork.Length(); i++) {
1781 const TopoDS_Wire& wire = TopoDS::Wire(myWork(i));
1783 Standard_Integer nbEdges=0;
1784 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next())
1786 TopExp::Vertices(wire,Vdeb,Vfin);
1787 Standard_Boolean wClosed = wire.Closed();
1789 // on regarde quand meme si les vertex sont les memes.
1790 if ( Vdeb.IsSame(Vfin)) wClosed = Standard_True;
1794 TopoDS_Vertex Vsuiv, VF, VR;
1795 TopoDS_Wire newwire;
1797 BW.MakeWire(newwire);
1800 const TopoDS_Edge Ecur = TopoDS::Edge(anExp.Current());
1801 TopExp::Vertices(Ecur,VF,VR);
1802 if (Vdeb.IsSame(VF)) Vsuiv=VR;
1803 else if (Vdeb.IsSame(VR)) Vsuiv=VF;
1805 // par defaut on prend l'origine sur cette arete
1806 if (VR.IsSame(TopoDS::Vertex(anExp.CurrentVertex()))) {
1815 Pdeb=BRep_Tool::Pnt(Vdeb);
1816 Psuiv=BRep_Tool::Pnt(Vsuiv);
1817 Standard_Real U1 = BRep_Tool::Parameter(Vdeb,Ecur);
1818 Standard_Real U2 = BRep_Tool::Parameter(Vsuiv,Ecur);
1819 BRepAdaptor_Curve Curve(Ecur);
1820 PPs = Curve.Value(0.25*(U1+3*U2));
1821 myWork(ideb) = wire;
1824 // on ramene Pdeb, Psuiv et PPs dans le plan courant
1825 gp_Pnt Pnew,Pnext,PPn;
1826 Transform(Standard_True,Pdeb,Pos->Value(i-1),Axe->Value(i-1),
1827 Pos->Value(i),Axe->Value(i),Pnew);
1828 Transform(Standard_True,Psuiv,Pos->Value(i-1),Axe->Value(i-1),
1829 Pos->Value(i),Axe->Value(i),Pnext);
1830 Transform(Standard_True,PPs,Pos->Value(i-1),Axe->Value(i-1),
1831 Pos->Value(i),Axe->Value(i),PPn);
1833 Standard_Real distmini,dist;
1834 Standard_Integer rang=0,rangdeb=0;
1835 TopoDS_Vertex Vmini;
1837 SeqOfVertices(wire,SeqV);
1838 if (SeqV.Length()>NbMaxV)
1839 Standard_NoSuchObject::Raise("BRepFill::ComputeOrigin failed");
1841 // choix du vertex le plus proche comme origine
1842 distmini = Precision::Infinite();
1843 for (Standard_Integer ii=1;ii<=SeqV.Length();ii++) {
1844 P1 = BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(ii)));
1845 dist = P1.Distance(Pnew);
1846 if (dist<distmini) {
1848 Vmini = TopoDS::Vertex(SeqV.Value(ii));
1851 if (!Vmini.IsNull()) Pmini = BRep_Tool::Pnt(Vmini);
1855 // recherche du vertex correspondant a la projection conique
1856 Standard_Real angmin, angV, eta = Precision::Angular();
1857 TopoDS_Vertex Vopti;
1859 distmini = Precision::Infinite();
1860 gp_Dir dir0(gp_Vec(Pnew,P.Location()));
1861 for (Standard_Integer ii=1;ii<=SeqV.Length();ii++) {
1862 P1 = BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(ii)));
1863 dist = Pnew.Distance(P1);
1864 if (dist<Precision::Confusion()) {
1868 gp_Dir dir1(gp_Vec(Pnew,P1));
1869 angV = dir1.Angle(dir0);
1871 if (angV>M_PI/2) angV = M_PI - angV;
1872 if (angmin>angV+eta) {
1875 Vopti = TopoDS::Vertex(SeqV.Value(ii));
1877 else if (Abs(angmin-angV)<eta) {
1878 if (dist<distmini) {
1881 Vopti = TopoDS::Vertex(SeqV.Value(ii));
1886 if (!Vopti.IsNull()) Popti = BRep_Tool::Pnt(Vopti);
1891 distmini = Precision::Infinite();
1892 for (anExp.Init(wire); anExp.More(); anExp.Next()) {
1893 TopoDS_Edge Ecur = anExp.Current();
1894 TopoDS_Vertex Vcur = anExp.CurrentVertex();
1895 TopExp::Vertices(Ecur,VF,VR);
1896 if (VF.IsSame(Vmini)) {
1897 P1 = BRep_Tool::Pnt(VR);
1898 dist = P1.Distance(Pnext);
1899 if (dist<=distmini) {
1904 if (VR.IsSame(Vmini)) {
1905 P1 = BRep_Tool::Pnt(VF);
1906 dist = P1.Distance(Pnext);
1907 if (dist<distmini) {
1914 // choix du sens de parcours en fonction de Pnext
1915 Standard_Boolean parcours = Standard_False;
1916 if (i==myWork.Length() && myDegen2) {
1917 // derniere section ponctuelle
1919 parcours = Standard_True;
1923 gp_Pnt Pbout = Pnext;
1925 TopoDS_Vertex V1,V2;
1926 EdgesFromVertex(wire,Vmini,E1,E2);
1928 TopExp::Vertices(E1,V1,V2,Standard_True);
1930 Standard_Real U1=0, U2=0;
1932 Standard_Real U1, U2;
1934 if (Vmini.IsSame(V1)) {
1935 P1 = BRep_Tool::Pnt(V2);
1936 U1 = 0.25*(BRep_Tool::Parameter(V1,E1)+3*BRep_Tool::Parameter(V2,E1));
1938 if (Vmini.IsSame(V2)) {
1939 P1 = BRep_Tool::Pnt(V1);
1940 U1 = 0.25*(3*BRep_Tool::Parameter(V1,E1)+BRep_Tool::Parameter(V2,E1));
1943 TopExp::Vertices(E2,V1,V2,Standard_True);
1944 if (Vmini.IsSame(V1)) {
1945 P2 = BRep_Tool::Pnt(V2);
1946 U2 = 0.25*(BRep_Tool::Parameter(V1,E2)+3*BRep_Tool::Parameter(V2,E2));
1948 if (Vmini.IsSame(V2)) {
1949 P2 = BRep_Tool::Pnt(V1);
1950 U2 = 0.25*(3*BRep_Tool::Parameter(V1,E2)+BRep_Tool::Parameter(V2,E2));
1953 if (Abs(Pbout.Distance(P1)-Pbout.Distance(P2))<Precision::Confusion()) {
1954 // cas limite ; on se decale un peu
1956 BRepAdaptor_Curve Curve1(E1);
1957 P1 = Curve1.Value(U1);
1958 BRepAdaptor_Curve Curve2(E2);
1959 P2 = Curve2.Value(U2);
1962 // calcul de rangdeb
1964 if (Pbout.Distance(P1)<Pbout.Distance(P2)){
1965 // P1 est plus proche; parcours = False
1966 parcours = Standard_False;
1968 for (anExp.Init(wire); anExp.More(); anExp.Next()) {
1970 TopoDS_Edge Ecur = anExp.Current();
1971 if (E1.IsSame(Ecur)) {
1975 BRepAdaptor_Curve Curve(E1);
1976 PPs = Curve.Value(U1);
1979 // P2 est plus proche; parcours = True
1980 parcours = Standard_True;
1982 for (anExp.Init(wire); anExp.More(); anExp.Next()) {
1984 TopoDS_Edge Ecur = anExp.Current();
1985 if (E2.IsSame(Ecur)) {
1989 BRepAdaptor_Curve Curve(E2);
1990 PPs = Curve.Value(U2);
1994 // reconstruction du wire a partir de rangdeb
1995 TopTools_SequenceOfShape SeqEdges;
1997 for (anExp.Init(TopoDS::Wire(wire)); anExp.More(); anExp.Next()) {
1998 SeqEdges.Append(anExp.Current());
2001 for (rang=rangdeb;rang<=nbEdges;rang++) {
2002 BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang)));
2004 for (rang=1;rang<rangdeb;rang++) {
2005 BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang)));
2009 for (rang=rangdeb;rang>=1;rang--) {
2010 TopoDS_Shape aLocalShape = SeqEdges.Value(rang).Reversed();
2011 BW.Add(newwire,TopoDS::Edge(aLocalShape));
2012 // BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang).Reversed()));
2014 for (rang=nbEdges;rang>rangdeb;rang--) {
2015 TopoDS_Shape aLocalShape = SeqEdges.Value(rang).Reversed();
2016 BW.Add(newwire,TopoDS::Edge(aLocalShape));
2017 // BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang).Reversed()));
2021 myWork(i) = newwire.Oriented(TopAbs_FORWARD);
2023 // on passe au wire suivant
2024 if (!Vmini.IsNull()) Pdeb=BRep_Tool::Pnt(Vmini);
2025 if (!Vsuiv.IsNull()) Psuiv=BRep_Tool::Pnt(Vsuiv);
2030 // blocking sections ?
2031 if (vClosed) myWork(myWork.Length()) = myWork(1);
2034 //=======================================================================
2035 //function : SearchOrigin
2037 //=======================================================================
2039 void BRepFill_CompatibleWires::SearchOrigin()
2041 // reorganize the open wires respecting orientation and origin
2045 TopoDS_Vertex Vdeb, Vfin;
2046 gp_Pnt Pdeb, Pfin;//,Psuiv;
2048 BRepTools_WireExplorer anExp;
2050 Standard_Boolean allOpen = Standard_True;
2051 Standard_Integer ideb=1, ifin=myWork.Length();
2052 if (myDegen1) ideb++;
2053 if (myDegen2) ifin--;
2054 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
2055 && (myWork(ideb).IsSame(myWork(ifin)));
2057 // for (Standard_Integer i=ideb; i<=ifin; i++) {
2059 for (i=ideb; i<=ifin; i++) {
2060 allOpen = (allOpen && !myWork(i).Closed());
2063 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SearchOrigin : the wires must be open");
2067 TopoDS_Wire wire1 = TopoDS::Wire(myWork(ideb));
2068 wire1.Orientation(TopAbs_FORWARD);
2069 TopExp::Vertices(wire1,Vdeb,Vfin);
2070 Pdeb = BRep_Tool::Pnt(Vdeb);
2071 Pfin = BRep_Tool::Pnt(Vfin);
2072 Standard_Boolean isline0 = (!PlaneOfWire(wire1,P0)), isline;
2073 myWork(ideb) = wire1;
2076 TopoDS_Edge E0 = anExp.Current(), E;
2078 for ( i=ideb+1; i<=ifin; i++) {
2080 TopoDS_Wire wire = TopoDS::Wire(myWork(i));
2081 wire.Orientation(TopAbs_FORWARD);
2083 TopTools_SequenceOfShape SeqEdges;
2085 Standard_Integer nbEdges=0;
2086 //OCC86 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
2087 for(anExp.Init(wire), E = anExp.Current(); anExp.More(); anExp.Next()) {
2088 SeqEdges.Append(anExp.Current());
2091 TopExp::Vertices(wire,Vdeb,Vfin);
2092 isline = (!PlaneOfWire(wire,P));
2094 TopoDS_Vertex Vmini;
2095 TopoDS_Wire newwire;
2097 BW.MakeWire(newwire);
2098 Standard_Boolean parcours = Standard_True;
2100 if (isline0 || isline) {
2102 // particular case of straight segments
2103 gp_Pnt P1 = BRep_Tool::Pnt(Vdeb),
2104 P2 = BRep_Tool::Pnt(Vfin);
2105 Standard_Real dist1, dist2;
2106 dist1 = Pdeb.Distance(P1)+Pfin.Distance(P2);
2107 dist2 = Pdeb.Distance(P2)+Pfin.Distance(P1);
2108 parcours = (dist2>=dist1);
2113 gp_Pnt P1 = BRep_Tool::Pnt(Vdeb), P1o = Pdeb,
2114 P2 = BRep_Tool::Pnt(Vfin), P2o = Pfin;
2115 /* // return Pdeb in the current plane
2116 gp_Pnt Pnew = Pdeb.Translated (P0.Location(),P.Location());
2117 gp_Ax1 A0 = P0.Axis();
2118 gp_Ax1 A1 = P.Axis();
2120 if (!A0.IsParallel(A1,1.e-4)) {
2121 gp_Vec vec1(A0.Direction()), vec2(A1.Direction()),
2123 gp_Ax1 Norm(P.Location(),norm);
2124 Standard_Real ang = vec1.AngleWithRef(vec2,norm);
2127 if (ang < -M_PI/2.0)
2129 if (Abs(ang-M_PI/2.0)<Precision::Angular()) {
2131 gp_Vec Vtrans(P0.Location(),P.Location()),Vsign;
2132 Standard_Real alpha,beta,sign=1;
2133 Vsign.SetLinearForm(Vtrans.Dot(vec1),vec2,-Vtrans.Dot(vec2),vec1);
2134 alpha = Vsign.Dot(vec1);
2135 beta = Vsign.Dot(vec2);
2136 Standard_Boolean pasnul = (Abs(alpha)>1.e-4 && Abs(beta)>1.e-4);
2137 if ( alpha*beta>0.0 && pasnul ) sign=-1;
2140 Pnew = Pnew.Rotated (Norm,ang);
2142 // choix entre Vdeb et Vfin
2143 Standard_Real dist = Pnew.Distance(P1);
2144 parcours = (dist<Pnew.Distance(P2));
2146 if(P1.IsEqual(P2,Precision::Confusion()) || P1o.IsEqual(P2o,Precision::Confusion())){
2147 BRepAdaptor_Curve Curve0(E0), Curve(E);
2148 Curve0.D0(Curve0.FirstParameter() + Precision::Confusion(), P2o);
2149 Curve.D0(Curve.FirstParameter() + Precision::Confusion(), P2);
2151 gp_Vec VDebFin0(P1o,P2o), VDebFin(P1,P2);
2152 Standard_Real AStraight = VDebFin0.Angle(VDebFin);
2153 parcours = (AStraight < M_PI/2.0? Standard_True: Standard_False);
2156 // reconstruction of the wire
2157 Standard_Integer rang;
2159 for (rang=1;rang<=nbEdges;rang++) {
2160 TopoDS_Shape alocalshape = SeqEdges.Value(rang);
2161 BW.Add(newwire,TopoDS::Edge(alocalshape));
2162 // BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang)));
2166 for (rang=nbEdges;rang>=1;rang--) {
2167 TopoDS_Shape alocalshape = SeqEdges.Value(rang).Reversed();
2168 BW.Add(newwire,TopoDS::Edge(alocalshape));
2169 // BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang).Reversed()));
2173 // orientation of the wire
2174 newwire.Oriented(TopAbs_FORWARD);
2175 myWork(i) = newwire;
2177 // passe to the next wire
2179 Pdeb = BRep_Tool::Pnt(Vdeb);
2180 Pfin = BRep_Tool::Pnt(Vfin);
2183 Pfin = BRep_Tool::Pnt(Vdeb);
2184 Pdeb = BRep_Tool::Pnt(Vfin);
2192 // blocking sections ?
2193 if (vClosed) myWork(myWork.Length()) = myWork(1);