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.
17 #include <BRepFill_CompatibleWires.ixx>
19 #include <BRepAdaptor_Curve.hxx>
21 #include <BRepFill.hxx>
22 #include <BRepLib.hxx>
23 #include <BRepLib_FindSurface.hxx>
24 #include <BRepLib_MakeWire.hxx>
25 #include <BRepLib_MakeEdge.hxx>
26 #include <BRepCheck_Wire.hxx>
27 #include <BRepExtrema_DistShapeShape.hxx>
28 #include <Bnd_Box.hxx>
29 #include <BRepBndLib.hxx>
30 #include <BRep_Builder.hxx>
31 #include <BRep_Tool.hxx>
32 #include <BRepTools_WireExplorer.hxx>
33 #include <BRepLProp.hxx>
34 #include <BRepGProp.hxx>
35 #include <GProp_GProps.hxx>
36 #include <GProp_PrincipalProps.hxx>
37 #include <Geom_Surface.hxx>
38 #include <Geom_Plane.hxx>
39 #include <Precision.hxx>
42 #include <TopExp_Explorer.hxx>
44 #include <TopoDS_Wire.hxx>
45 #include <TopTools_ListIteratorOfListOfShape.hxx>
46 #include <TopTools_DataMapOfShapeListOfShape.hxx>
47 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
48 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
49 #include <TopTools_HSequenceOfShape.hxx>
50 #include <TopTools_SequenceOfShape.hxx>
51 #include <TopTools_ListOfShape.hxx>
57 #include <gp_Circ.hxx>
58 #include <gp_Elips.hxx>
59 #include <TColgp_HArray1OfVec.hxx>
60 #include <TColgp_HArray1OfPnt.hxx>
62 #include <TColStd_Array1OfInteger.hxx>
63 #include <TColStd_Array1OfReal.hxx>
64 #include <TColStd_SequenceOfReal.hxx>
67 static void EdgesFromVertex (const TopoDS_Wire& W,
68 const TopoDS_Vertex& V,
72 TopTools_IndexedDataMapOfShapeListOfShape Map;
73 TopExp::MapShapesAndAncestors(W,TopAbs_VERTEX,TopAbs_EDGE,Map);
75 const TopTools_ListOfShape& List = Map.FindFromKey(V);
76 TopoDS_Edge e1 = TopoDS::Edge(List.First());
77 TopoDS_Edge e2 = TopoDS::Edge(List. Last());
79 BRepTools_WireExplorer anExp;
80 Standard_Integer I1=0, I2=0, NE=0;
82 for(anExp.Init(W); anExp.More(); anExp.Next()) {
84 const TopoDS_Edge& ECur = anExp.Current();
85 if (e1.IsSame(ECur)) {
88 if (e2.IsSame(ECur)) {
94 // consecutive numbers
105 // non consecutive numbers on a closed wire
118 static void SeqOfVertices (const TopoDS_Wire& W,
119 TopTools_SequenceOfShape& S)
122 Standard_Integer jj, cpt = 0;
124 for (PE.Init(W,TopAbs_VERTEX); PE.More(); PE.Next()) {
126 Standard_Boolean trouve=Standard_False;
127 for (jj=1;jj<=S.Length() && (!trouve);jj++) {
128 if (S.Value(jj).IsSame(PE.Current())) trouve = Standard_True;
130 if (!trouve) S.Append(PE.Current());
135 static Standard_Boolean PlaneOfWire (const TopoDS_Wire& W, gp_Pln& P)
137 Standard_Boolean isplane = Standard_True;
138 BRepLib_FindSurface findPlanarSurf;
139 Handle(Geom_Surface) S;
143 BRepGProp::LinearProperties(W,GP);
144 gp_Pnt Bary = GP.CentreOfMass();
146 // shielding for particular cases : only one edge circle or ellipse
147 // on a closed wire !
148 Standard_Integer nbEdges = 0;
149 BRepTools_WireExplorer anExp;
151 Standard_Boolean wClosed = W.Closed();
153 // it is checked if the vertices are the same.
154 TopoDS_Vertex V1, V2;
155 TopExp::Vertices(W,V1,V2);
156 if ( V1.IsSame(V2)) wClosed = Standard_True;
158 TopoDS_Edge Edge = TopoDS::Edge(anExp.Current());
159 Standard_Real first, last;
160 Handle(Geom_Curve) curv = BRep_Tool::Curve(Edge, first, last);
162 GeomAdaptor_Curve AdC;
164 for(; anExp.More(); anExp.Next()) {
167 if ( nbEdges==1 && AdC.GetType() == GeomAbs_Circle ) {
168 Bary = AdC.Circle().Location();
170 if ( nbEdges==1 && AdC.GetType() == GeomAbs_Ellipse ) {
171 Bary = AdC.Ellipse().Location();
175 findPlanarSurf.Init(W, -1, Standard_True);
176 if ( findPlanarSurf.Found()) {
177 S = findPlanarSurf.Surface();
178 L = findPlanarSurf.Location();
179 if (!L.IsIdentity()) S = Handle(Geom_Surface)::
180 DownCast(S->Transformed(L.Transformation()));
181 P = (Handle(Geom_Plane)::DownCast(S))->Pln();
186 GProp_PrincipalProps Pp = GP.PrincipalProperties();
188 Standard_Real R1, R2, R3,Tol = Precision::Confusion();
189 Pp.RadiusOfGyration(R1,R2,R3);
190 Standard_Real RMax = Max(Max(R1,R2),R3);
191 if ( ( Abs(RMax-R1)<Tol && Abs(RMax-R2)<Tol )
192 || ( Abs(RMax-R1)<Tol && Abs(RMax-R3)<Tol )
193 || ( Abs(RMax-R2)<Tol && Abs(RMax-R3)<Tol ) )
194 isplane = Standard_False;
196 if (R1>=R2 && R1>=R3) {
197 Vec = Pp.FirstAxisOfInertia();
199 else if (R2>=R1 && R2>=R3) {
200 Vec = Pp.SecondAxisOfInertia();
202 else if (R3>=R1 && R3>=R2) {
203 Vec = Pp.ThirdAxisOfInertia();
206 if (R3<=R2 && R3<=R1) {
207 Vec = Pp.ThirdAxisOfInertia();
209 else if (R2<=R1 && R2<=R3) {
210 Vec = Pp.SecondAxisOfInertia();
212 else if (R1<=R2 && R1<=R3) {
213 Vec = Pp.FirstAxisOfInertia();
216 gp_Ax3 repere(Bary,NDir,XDir);
217 Geom_Plane GPlan(repere);
227 static void WireContinuity (const TopoDS_Wire& W,
228 GeomAbs_Shape& contW)
232 Standard_Boolean IsDegenerated = Standard_False;
234 BRepTools_WireExplorer anExp;
235 Standard_Integer nbEdges=0;
236 Handle(TopTools_HSequenceOfShape) Edges = new TopTools_HSequenceOfShape();
237 for(anExp.Init(W); anExp.More(); anExp.Next()) {
239 Edges->Append(anExp.Current());
240 if (BRep_Tool::Degenerated(anExp.Current())) IsDegenerated = Standard_True;
243 if (!IsDegenerated) {
245 Standard_Boolean testconti = Standard_True;
247 for (Standard_Integer j=1;j<=nbEdges;j++) {
249 TopoDS_Edge Edge1, Edge2;
252 Edge1 = TopoDS::Edge (Edges->Value(nbEdges));
253 Edge2 = TopoDS::Edge (Edges->Value(1));
256 Edge1 = TopoDS::Edge (Edges->Value(j));
257 Edge2 = TopoDS::Edge (Edges->Value(j+1));
260 TopoDS_Vertex V1,V2,Vbid;
261 TopExp::Vertices(Edge1,Vbid,V1,Standard_True);
262 TopExp::Vertices(Edge2,V2,Vbid,Standard_True);
263 Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1);
264 Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2);
265 BRepAdaptor_Curve Curve1(Edge1);
266 BRepAdaptor_Curve Curve2(Edge2);
267 Standard_Real Eps = BRep_Tool::Tolerance(V2) + BRep_Tool::Tolerance(V1);
270 testconti = Curve1.Value(U1).IsEqual(Curve2.Value(U2), Eps);
273 cont = BRepLProp::Continuity(Curve1,Curve2,U1,U2,
274 Eps, Precision::Angular());
275 if (cont <= contW) contW = cont;
282 static void TrimEdge (const TopoDS_Edge& CurrentEdge,
283 const TColStd_SequenceOfReal& CutValues,
284 const Standard_Real t0, const Standard_Real t1,
285 const Standard_Boolean SeqOrder,
286 TopTools_SequenceOfShape& S)
290 Standard_Integer j, ndec=CutValues.Length();
291 Standard_Real first,last,m0,m1;
292 Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
294 TopoDS_Vertex Vf,Vl,Vbid,V0,V1;
295 TopAbs_Orientation CurrentOrient = CurrentEdge.Orientation();
296 TopExp::Vertices(CurrentEdge,Vf,Vl);
300 // from first to last
303 for (j=1; j<=ndec; j++) {
305 m1 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
306 TopoDS_Edge CutE = BRepLib_MakeEdge(C,V0,Vbid,m0,m1);
307 CutE.Orientation(CurrentOrient);
310 V0 = TopExp::LastVertex(CutE);
313 TopoDS_Edge LastE = BRepLib_MakeEdge(C,V0,Vl,m0,last);
314 LastE.Orientation(CurrentOrient);
320 // from last to first
323 for (j=ndec; j>=1; j--) {
325 m0 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
326 TopoDS_Edge CutE = BRepLib_MakeEdge(C,Vbid,V1,m0,m1);
327 CutE.Orientation(CurrentOrient);
330 V1 = TopExp::FirstVertex(CutE);
333 TopoDS_Edge LastE = BRepLib_MakeEdge(C,Vf,V1,first,m1);
334 LastE.Orientation(CurrentOrient);
343 static Standard_Boolean SearchRoot (const TopoDS_Vertex& V,
344 const TopTools_DataMapOfShapeListOfShape& Map,
345 TopoDS_Vertex& VRoot)
347 Standard_Boolean trouve = Standard_False;
349 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape it;
350 for (it.Initialize(Map); it.More(); it.Next()) {
351 const TopTools_ListOfShape & List = it.Value();
352 TopTools_ListIteratorOfListOfShape itL;
353 Standard_Boolean ilyest = Standard_False;
354 for (itL.Initialize(List); itL.More(); itL.Next()) {
355 TopoDS_Vertex Vcur = TopoDS::Vertex(itL.Value());
356 if (Vcur.IsSame(V)) {
357 ilyest = Standard_True;
362 trouve = Standard_True;
363 VRoot = TopoDS::Vertex(it.Key());
370 static Standard_Boolean SearchVertex (const TopTools_ListOfShape& List,
371 const TopoDS_Wire& W,
374 Standard_Boolean trouve = Standard_False;
376 TopTools_SequenceOfShape SeqV;
377 SeqOfVertices(W,SeqV);
378 for (Standard_Integer ii=1;ii<=SeqV.Length();ii++) {
379 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
380 TopTools_ListIteratorOfListOfShape itL;
381 Standard_Boolean ilyest = Standard_False;
382 for (itL.Initialize(List); itL.More(); itL.Next()) {
383 TopoDS_Vertex Vcur = TopoDS::Vertex(itL.Value());
384 if (Vcur.IsSame(Vi)) {
385 ilyest = Standard_True;
390 trouve = Standard_True;
399 static Standard_Boolean EdgeIntersectOnWire (const gp_Pnt& P1,
401 Standard_Real percent,
402 const TopTools_DataMapOfShapeListOfShape& Map,
403 const TopoDS_Wire& W,
408 BRepTools_WireExplorer anExp;
410 // construction of the edge of intersection
411 Standard_Boolean NewVertex = Standard_False;
412 gp_Lin droite(P1,gp_Dir(gp_Vec(P1,P2)));
413 // ATTENTION : it is required to construct a half-straight
414 // but there is a bug in BRepExtrema_DistShapeShape
415 // it is enough to take 100 * distance between P1 and P2
416 // hoping that it is enough until the bug is corrected
417 // Standard_Real dernierparam = Precision::Infinite();
418 // ATTENTION : return !!
419 // 100 is better than 10 but it is too much !
420 // finally, nothing is better than a blocking box
421 // Standard_Real dernierparam = 100 * P1.Distance(P2);
423 BRepBndLib::Add(W,B);
424 Standard_Real x1,x2,y1,y2,z1,z2;
425 B.Get(x1,y1,z1,x2,y2,z2);
426 gp_Pnt BP1(x1,y1,z1), BP2(x2,y2,z2);
427 Standard_Real diag = BP1.Distance(BP2);
428 Standard_Real dernierparam = diag;
429 BRepLib_MakeEdge ME(droite,0.,dernierparam);
430 TopoDS_Edge ECur = BRepLib_MakeEdge(droite,0.,P1.Distance(P2));
432 // calculate the intersection by BRepExtrema (point of min distance)
433 BRepExtrema_DistShapeShape DSS(ME.Edge(),W);
435 // choose the solution closest to P2
436 Standard_Integer isol = 1;
437 Standard_Real dss = P2.Distance(DSS.PointOnShape2(isol));
438 for (Standard_Integer iss=2; iss<=DSS.NbSolution(); iss++) {
439 if (dss>P2.Distance(DSS.PointOnShape2(iss))) {
440 dss = P2.Distance(DSS.PointOnShape2(iss));
447 DSS.PointOnShape2(isol);
448 // is the solution a new vertex ?
449 NewVertex = (DSS.SupportTypeShape2(isol) != BRepExtrema_IsVertex);
451 TopoDS_Shape aLocalShape = DSS.SupportOnShape2(isol);
452 TopoDS_Edge E = TopoDS::Edge(aLocalShape);
453 // TopoDS_Edge E = TopoDS::Edge(DSS.SupportOnShape2(isol));
454 Standard_Real tol = Precision::PConfusion();
455 Standard_Real first,last,param;
456 BRep_Tool::Range(E,first,last);
457 tol = Max(tol,percent*Abs(last-first));
458 DSS.ParOnEdgeS2(isol,param);
459 if (Abs(first-param)<tol) {
460 NewVertex = Standard_False;
461 Vsol = TopExp::FirstVertex(E);
463 else if (Abs(last-param)<tol) {
464 NewVertex = Standard_False;
465 Vsol = TopExp::LastVertex(E);
470 if (SearchRoot(Vsol,Map,VRoot)) NewVertex = Standard_True;
474 TopoDS_Shape aLocalShape = DSS.SupportOnShape2(isol);
475 Vsol = TopoDS::Vertex(aLocalShape);
476 // Vsol = TopoDS::Vertex(DSS.SupportOnShape2(isol));
479 // it is required to cut the edge
481 TopoDS_Shape aLocalShape = DSS.SupportOnShape2(isol);
482 TopoDS_Edge E = TopoDS::Edge(aLocalShape);
483 // TopoDS_Edge E = TopoDS::Edge(DSS.SupportOnShape2(isol));
484 Standard_Real first,last,param;
485 DSS.ParOnEdgeS2(isol,param);
486 BRep_Tool::Range(E,first,last);
488 for (anExp.Init(W); anExp.More(); anExp.Next()) {
489 if (E.IsSame(anExp.Current())) {
491 = (anExp.CurrentVertex().IsSame(TopExp::FirstVertex(E)));
492 TopTools_SequenceOfShape SE;
494 TColStd_SequenceOfReal SR;
497 TrimEdge(E,SR,first,last,SO,SE);
498 TopoDS_Vertex VV1,VV2;
499 TopExp::Vertices(TopoDS::Edge(SE.Value(1)),VV1,VV2);
500 if (TopExp::FirstVertex(E).IsSame(VV1)
501 || TopExp::LastVertex(E).IsSame(VV1)) {
504 if (TopExp::FirstVertex(E).IsSame(VV2)
505 || TopExp::LastVertex(E).IsSame(VV2)) {
508 for (Standard_Integer k=1; k<=SE.Length(); k++) {
509 MW.Add(TopoDS::Edge(SE.Value(k)));
513 MW.Add(anExp.Current());
530 static void Transform (const Standard_Boolean WithRotation,
539 Pnew = P.Translated (Pos1,Pos2);
540 gp_Vec axe1 = Ax1, axe2 = Ax2;
541 if (!axe1.IsParallel(axe2,1.e-4)) {
542 gp_Vec Vtrans(Pos1,Pos2),Vsign;
543 Standard_Real alpha,beta,sign=1;
544 alpha = Vtrans.Dot(axe1);
545 beta = Vtrans.Dot(axe2);
546 if (alpha<-1.e-7) axe1 *=-1;
547 if (beta<1.e-7) axe2 *=-1;
548 alpha = Vtrans.Dot(axe1);
549 beta = Vtrans.Dot(axe2);
550 gp_Vec norm2 = axe1 ^ axe2;
551 Vsign.SetLinearForm(Vtrans.Dot(axe1),axe2,-Vtrans.Dot(axe2),axe1);
552 alpha = Vsign.Dot(axe1);
553 beta = Vsign.Dot(axe2);
554 Standard_Boolean pasnul = (Abs(alpha)>1.e-4 && Abs(beta)>1.e-4);
555 if ( alpha*beta>0.0 && pasnul ) sign=-1;
556 gp_Ax1 Norm(Pos2,norm2);
557 Standard_Real ang = axe1.AngleWithRef(axe2,norm2);
559 if (ang>M_PI/2) ang = ang - M_PI;
560 if (ang<-M_PI/2) ang = ang + M_PI;
563 Pnew = Pnew.Rotated (Norm,ang);
567 static void BuildConnectedEdges(const TopoDS_Wire& aWire,
568 const TopoDS_Edge& StartEdge,
569 const TopoDS_Vertex& StartVertex,
570 TopTools_ListOfShape& ConnectedEdges)
572 TopTools_IndexedDataMapOfShapeListOfShape MapVE;
573 TopExp::MapShapesAndAncestors(aWire, TopAbs_VERTEX, TopAbs_EDGE, MapVE);
574 TopoDS_Edge CurEdge = StartEdge;
575 TopoDS_Vertex CurVertex = StartVertex;
576 TopoDS_Vertex Origin, V1, V2;
577 TopExp::Vertices(StartEdge, V1, V2);
578 Origin = (V1.IsSame(StartVertex))? V2 : V1;
582 TopTools_ListIteratorOfListOfShape itE( MapVE.FindFromKey(CurVertex) );
583 for (; itE.More(); itE.Next())
585 TopoDS_Edge anEdge = TopoDS::Edge(itE.Value());
586 if (!anEdge.IsSame(CurEdge))
588 ConnectedEdges.Append(anEdge);
589 TopExp::Vertices(anEdge, V1, V2);
590 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
595 if (CurVertex.IsSame(Origin))
600 //=======================================================================
601 //function : BRepFill_CompatibleWires
603 //=======================================================================
605 BRepFill_CompatibleWires::BRepFill_CompatibleWires()
606 :myIsDone(Standard_False)
611 //=======================================================================
612 //function : BRepFill_CompatibleWires
614 //=======================================================================
616 BRepFill_CompatibleWires::BRepFill_CompatibleWires(const TopTools_SequenceOfShape& Sections)
622 //=======================================================================
625 //=======================================================================
627 void BRepFill_CompatibleWires::Init(const TopTools_SequenceOfShape& Sections)
632 myIsDone = Standard_False;
638 //=======================================================================
639 //function : SetPercent
641 //=======================================================================
643 void BRepFill_CompatibleWires::SetPercent(const Standard_Real Percent)
645 if (0.<Percent && Percent<1.) myPercent = Percent;
650 //=======================================================================
653 //=======================================================================
655 Standard_Boolean BRepFill_CompatibleWires::IsDone() const
661 //=======================================================================
664 //=======================================================================
666 const TopTools_SequenceOfShape& BRepFill_CompatibleWires::Shape() const
672 //=======================================================================
673 //function : GeneratedShapes
675 //=======================================================================
677 const TopTools_ListOfShape& BRepFill_CompatibleWires::GeneratedShapes
678 (const TopoDS_Edge& SubSection) const
681 if (myMap.IsBound(SubSection)) {
682 return myMap(SubSection);
685 static TopTools_ListOfShape Empty;
691 //=======================================================================
694 //=======================================================================
696 void BRepFill_CompatibleWires::Perform (const Standard_Boolean WithRotation)
698 // compute origin and orientation on wires to avoid twisted results
699 // and update wires to have same number of edges
701 // determination of report:
702 // if the number of elements is the same and if the wires have discontinuities
703 // by tangency, the report is not carried out by curvilinear abscissa
704 Standard_Integer nbSects = myWork.Length(), i;
705 BRepTools_WireExplorer anExp;
706 Standard_Integer nbmax=0, nbmin=0;
707 TColStd_Array1OfInteger nbEdges(1,nbSects);
708 Standard_Boolean report;
709 GeomAbs_Shape contS=GeomAbs_CN;
711 for (i=1; i<=nbSects; i++) {
712 TopoDS_Shape aLocalShape = myWork(i).Oriented(TopAbs_FORWARD);
713 myWork(i) = TopoDS::Wire(aLocalShape);
714 // myWork(i) = TopoDS::Wire(myWork(i).Oriented(TopAbs_FORWARD));
715 TopoDS_Wire W = TopoDS::Wire(myWork(i));
716 WireContinuity(W,cont);
717 if (cont<contS) contS=cont;
719 for(anExp.Init(W); anExp.More(); anExp.Next() ) nbEdges(i)++;
720 if (i==1) nbmin = nbEdges(i);
721 if (nbmax<nbEdges(i)) nbmax = nbEdges(i);
722 if (nbmin>nbEdges(i)) nbmin = nbEdges(i);
724 // if the number of elements is not the same or if all wires are at least
725 // C1, the report is carried out by curvilinear abscissa of cuts, otherwise
726 // a report vertex / Vertex is done
727 report = (nbmax != nbmin || contS >= GeomAbs_C1 );
729 // initialization of the map
730 Standard_Integer nbE = 0;
731 TopTools_ListOfShape Empty;
732 for (i=1; i<=nbSects; i++) {
733 TopoDS_Wire W = TopoDS::Wire(myWork(i));
734 for(anExp.Init(W); anExp.More(); anExp.Next() ) {
735 TopoDS_Edge E = TopoDS::Edge(anExp.Current());
742 // open/closed sections
743 // initialisation of myDegen1, myDegen2
744 Standard_Integer ideb=1, ifin=myWork.Length();
745 // check if the first wire is punctual
746 myDegen1 = Standard_True;
747 for(anExp.Init(TopoDS::Wire(myWork(ideb))); anExp.More(); anExp.Next()) {
748 myDegen1 = myDegen1 && (BRep_Tool::Degenerated(anExp.Current()));
750 if (myDegen1) ideb++;
751 // check if the last wire is punctual
752 myDegen2 = Standard_True;
753 for(anExp.Init(TopoDS::Wire(myWork(ifin))); anExp.More(); anExp.Next()) {
754 myDegen2 = myDegen2 && (BRep_Tool::Degenerated(anExp.Current()));
756 if (myDegen2) ifin--;
758 Standard_Boolean wClosed, allClosed = Standard_True, allOpen = Standard_True;
759 for (i=ideb; i<=ifin; i++) {
760 wClosed = myWork(i).Closed();
762 // check if the vertices are the same.
763 TopoDS_Vertex V1, V2;
764 TopExp::Vertices(TopoDS::Wire(myWork(i)),V1,V2);
765 if ( V1.IsSame(V2)) wClosed = Standard_True;
767 allClosed = (allClosed && wClosed);
768 allOpen = (allOpen && !wClosed);
772 // All sections are closed
774 // same number of elements
775 SameNumberByPolarMethod(WithRotation);
779 ComputeOrigin(Standard_False);
781 myIsDone = Standard_True;
784 // All sections are open
787 // same number of elements
789 SameNumberByACR(report);
791 myIsDone = Standard_True;
794 // There are open and closed sections :
796 Standard_DomainError::Raise("Sections must be all closed or all open");
804 //=======================================================================
805 //function : Generated
807 //=======================================================================
809 const TopTools_DataMapOfShapeListOfShape& BRepFill_CompatibleWires::Generated() const
815 //=======================================================================
816 //function : SameNumberByPolarMethod
818 //=======================================================================
820 void BRepFill_CompatibleWires::
821 SameNumberByPolarMethod(const Standard_Boolean WithRotation)
825 Standard_Integer NbSects=myWork.Length();
826 BRepTools_WireExplorer anExp;
827 TopoDS_Vertex V1, V2;
829 Standard_Boolean allClosed = Standard_True;
830 Standard_Integer i,ii,ideb=1,ifin=NbSects;
831 for (i=1; i<=NbSects; i++) {
832 Handle(BRepCheck_Wire) Checker = new BRepCheck_Wire(TopoDS::Wire(myWork(i)));
833 allClosed = (allClosed && (Checker->Closed() == BRepCheck_NoError));
834 //allClosed = (allClosed && myWork(i).Closed());
837 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SameNumberByPolarMethod : the wires must be closed");
839 // sections ponctuelles, sections bouclantes ?
840 if (myDegen1) ideb++;
841 if (myDegen2) ifin--;
842 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
843 && (myWork(ideb).IsSame(myWork(ifin)));
845 //Removing degenerated edges
846 for (i = ideb; i <= ifin; i++)
848 Standard_Boolean hasDegEdge = Standard_False;
849 TopoDS_Iterator anItw(myWork(i));
850 for (; anItw.More(); anItw.Next())
852 const TopoDS_Edge& anEdge = TopoDS::Edge(anItw.Value());
853 if (BRep_Tool::Degenerated(anEdge))
855 hasDegEdge = Standard_True;
861 TopoDS_Wire aNewWire;
862 BRep_Builder aBBuilder;
863 aBBuilder.MakeWire(aNewWire);
864 for (anItw.Initialize(myWork(i)); anItw.More(); anItw.Next())
866 const TopoDS_Edge& anEdge = TopoDS::Edge(anItw.Value());
867 if (!BRep_Tool::Degenerated(anEdge))
868 aBBuilder.Add(aNewWire, anEdge);
870 myWork(i) = aNewWire;
874 // Nombre max de decoupes possibles
875 Standard_Integer NbMaxV = 0;
876 for (i=1; i<=NbSects; i++) {
877 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
882 // construction of tables of planes of wires
884 Handle(TColgp_HArray1OfPnt) Pos
885 = new (TColgp_HArray1OfPnt) (1,NbSects);
886 Handle(TColgp_HArray1OfVec) Axe
887 = new (TColgp_HArray1OfVec) (1,NbSects);
888 for (i=ideb;i<=ifin;i++) {
889 if (PlaneOfWire(TopoDS::Wire(myWork(i)),P)) {
890 Pos->SetValue(i,P.Location());
891 Axe->SetValue(i,gp_Vec(P.Axis().Direction()));
894 TopTools_SequenceOfShape SeqV;
896 SeqOfVertices(TopoDS::Wire(myWork(1)),SeqV);
897 Pos->SetValue(1,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
898 Axe->SetValue(1,Axe->Value(ideb));
901 SeqOfVertices(TopoDS::Wire(myWork(NbSects)),SeqV);
902 Pos->SetValue(NbSects,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
903 Axe->SetValue(NbSects,Axe->Value(ifin));
906 // construction of RMap, map of reports of wire i to wire i-1
907 TopTools_DataMapOfShapeListOfShape RMap;
911 for (i=ifin; i>ideb; i--) {
913 const TopoDS_Wire& wire1 = TopoDS::Wire(myWork(i));
915 // sequence of vertices of the first wire
916 SeqOfVertices(wire1,SeqV);
917 if (SeqV.Length()>NbMaxV)
918 Standard_NoSuchObject::Raise("BRepFill::SameNumberByPolarMethod failed");
920 // extremity of the first wire
921 V1 = TopoDS::Vertex(SeqV.Value(1));
922 // loop on vertices of wire1
923 for (ii=1;ii<=SeqV.Length();ii++) {
925 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
927 // init of RMap for Vi
928 TopTools_ListOfShape Init;
932 // it is required to find intersection Vi - wire2
933 gp_Pnt Pi = BRep_Tool::Pnt(Vi);
935 // return Pi in the current plane
937 Transform(WithRotation,Pi,
938 Pos->Value(i),Axe->Value(i),
939 Pos->Value(i-1),Axe->Value(i-1),Pnew);
941 // calculate the intersection
942 TopoDS_Shape Support;
943 Standard_Boolean NewVertex;
946 if (Pnew.Distance(Pos->Value(i-1))>Precision::Confusion()) {
947 Standard_Real percent = myPercent;
948 NewVertex = EdgeIntersectOnWire(Pos->Value(i-1),Pnew,percent,
949 RMap,TopoDS::Wire(myWork(i-1)),
951 if (NewVertex) myWork(i-1) = newwire;
952 RMap(Vi).Append(Vsol);
958 // initialisation of MapVLV, map of correspondences vertex - list of vertices
959 TopTools_DataMapOfShapeListOfShape MapVLV;
960 SeqOfVertices(TopoDS::Wire(myWork(ideb)),SeqV);
961 Standard_Integer SizeMap = SeqV.Length();
963 for (ii=1;ii<=SizeMap;ii++) {
964 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
965 TopTools_ListOfShape Init;
968 MapVLV.Bind(Vi,Init);
969 Standard_Integer NbV = 1;
972 Standard_Boolean tantque = SearchRoot(V0,RMap,V1);
974 MapVLV(Vi).Append(V1);
976 // test on NbV required for looping sections
977 if (V1.IsSame(Vi) || NbV >= myWork.Length()) {
978 tantque = Standard_False;
982 tantque = SearchRoot(V0,RMap,V1);
988 for (i=ideb; i<ifin; i++) {
990 const TopoDS_Wire& wire1 = TopoDS::Wire(myWork(i));
992 // sequence of vertices of the first wire
993 SeqOfVertices(wire1,SeqV);
994 if ( SeqV.Length()>NbMaxV || SeqV.Length()>SizeMap )
995 Standard_NoSuchObject::Raise("BRepFill::SameNumberByPolarMethod failed");
997 // extremity of the first wire
998 V1 = TopoDS::Vertex(SeqV.Value(1));
1001 const TopoDS_Wire& wire2 = TopoDS::Wire(myWork(i+1));
1003 // loop on vertices of wire1
1004 for (ii=1;ii<=SeqV.Length();ii++) {
1006 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
1007 TopoDS_Vertex VRoot;
1009 Standard_Boolean intersect = Standard_True;
1010 if (SearchRoot(Vi,MapVLV,VRoot)) {
1011 const TopTools_ListOfShape& LVi = MapVLV(VRoot);
1014 intersect = (!SearchVertex(LVi,wire2,VonW));
1018 // it is necessary to find intersection Vi - wire2
1019 gp_Pnt Pi = BRep_Tool::Pnt(Vi);
1021 // return Pi in the current plane
1023 Transform(WithRotation,Pi,
1024 Pos->Value(i),Axe->Value(i),
1025 Pos->Value(i+1),Axe->Value(i+1),Pnew);
1027 // calculate the intersection
1028 TopoDS_Shape Support;
1029 Standard_Boolean NewVertex;
1031 TopoDS_Wire newwire;
1032 if (Pnew.Distance(Pos->Value(i+1))>Precision::Confusion()) {
1033 Standard_Real percent = myPercent;
1034 NewVertex = EdgeIntersectOnWire(Pos->Value(i+1),Pnew,percent,
1035 MapVLV,TopoDS::Wire(myWork(i+1)),
1037 MapVLV(VRoot).Append(Vsol);
1038 if (NewVertex) myWork(i+1) = newwire;
1045 // regularize wires following MapVLV
1046 TopoDS_Wire wire = TopoDS::Wire(myWork(ideb));
1048 // except for the last if the sections loop
1049 Standard_Integer ibout = ifin;
1050 if (vClosed) ibout--;
1052 for ( i=ideb+1; i<=ibout; i++) {
1054 BRepLib_MakeWire MW;
1057 TopoDS_Edge ECur = anExp.Current();
1058 TopoDS_Vertex VF,VL;
1059 TopExp::Vertices(ECur,VF,VL,Standard_True);
1060 Standard_Real U1 = BRep_Tool::Parameter(VF,ECur);
1061 Standard_Real U2 = BRep_Tool::Parameter(VL,ECur);
1062 BRepAdaptor_Curve Curve(ECur);
1063 gp_Pnt PPs = Curve.Value(0.1*(U1+9*U2));
1064 TopTools_ListIteratorOfListOfShape itF(MapVLV(VF)),itL(MapVLV(VL));
1065 Standard_Integer rang = ideb;
1071 TopoDS_Vertex V1 = TopoDS::Vertex(itF.Value()), V2 = TopoDS::Vertex(itL.Value());
1073 Standard_Real scalmax=0.;
1074 TopoDS_Iterator itW( myWork(i) );
1076 for(; itW.More(); itW.Next())
1078 TopoDS_Edge E = TopoDS::Edge(itW.Value());
1079 TopoDS_Vertex VVF,VVL;
1080 TopExp::Vertices(E,VVF,VVL,Standard_True);
1082 // parse candidate edges
1083 Standard_Real scal1,scal2;
1084 if ( (V1.IsSame(VVF)&&V2.IsSame(VVL)) || (V2.IsSame(VVF)&&V1.IsSame(VVL)) ) {
1085 Standard_Real U1 = BRep_Tool::Parameter(VVF,E);
1086 Standard_Real U2 = BRep_Tool::Parameter(VVL,E);
1087 BRepAdaptor_Curve Curve(E);
1088 gp_Pnt PP1 = Curve.Value(0.1*(U1+9*U2));
1089 gp_Pnt PP2 = Curve.Value(0.1*(9*U1+U2));
1091 for (rang=i;rang>ideb;rang--) {
1092 Transform(WithRotation, PP1,
1093 Pos->Value(rang), Axe->Value(rang),
1094 Pos->Value(rang-1), Axe->Value(rang-1), PP1);
1095 Transform(WithRotation, PP2,
1096 Pos->Value(rang), Axe->Value(rang),
1097 Pos->Value(rang-1), Axe->Value(rang-1), PP2);
1099 gp_Vec Ns(Pos->Value(ideb),PPs);
1100 Ns = Ns.Normalized();
1101 gp_Vec N1(Pos->Value(ideb),PP1);
1102 N1 = N1.Normalized();
1103 gp_Vec N2(Pos->Value(ideb),PP2);
1104 N2 = N2.Normalized();
1106 if (scal1>scalmax) {
1111 if (scal2>scalmax) {
1113 TopoDS_Shape aLocalShape = E.Reversed();
1114 Esol = TopoDS::Edge(aLocalShape);
1117 } //end of for(; itW.More(); itW.Next())
1120 TopTools_ListOfShape ConnectedEdges;
1121 BuildConnectedEdges( TopoDS::Wire(myWork(i)), Esol, V2, ConnectedEdges );
1123 TopTools_ListIteratorOfListOfShape itCE(ConnectedEdges);
1124 for(; anExp.More(), itCE.More(); anExp.Next(), itCE.Next())
1126 ECur = anExp.Current();
1127 TopExp::Vertices(ECur,VF,VL,Standard_True);
1128 U1 = BRep_Tool::Parameter(VF,ECur);
1129 U2 = BRep_Tool::Parameter(VL,ECur);
1130 Curve.Initialize(ECur);
1131 PPs = Curve.Value(0.1*(U1+9*U2));
1133 TopoDS_Edge E = TopoDS::Edge(itCE.Value());
1134 TopoDS_Vertex VVF,VVL;
1135 TopExp::Vertices(E,VVF,VVL,Standard_True);
1137 // parse candidate edges
1138 Standard_Real scal1,scal2;
1139 U1 = BRep_Tool::Parameter(VVF,E);
1140 U2 = BRep_Tool::Parameter(VVL,E);
1141 Curve.Initialize(E);
1142 gp_Pnt PP1 = Curve.Value(0.1*(U1+9*U2));
1143 gp_Pnt PP2 = Curve.Value(0.1*(9*U1+U2));
1145 for (rang=i;rang>ideb;rang--) {
1146 Transform(WithRotation, PP1,
1147 Pos->Value(rang), Axe->Value(rang),
1148 Pos->Value(rang-1), Axe->Value(rang-1), PP1);
1149 Transform(WithRotation, PP2,
1150 Pos->Value(rang), Axe->Value(rang),
1151 Pos->Value(rang-1), Axe->Value(rang-1), PP2);
1153 gp_Vec Ns(Pos->Value(ideb),PPs);
1154 Ns = Ns.Normalized();
1155 gp_Vec N1(Pos->Value(ideb),PP1);
1156 N1 = N1.Normalized();
1157 gp_Vec N2(Pos->Value(ideb),PP2);
1158 N2 = N2.Normalized();
1165 myWork(i) = MW.Wire();
1168 // blocking sections?
1169 if (vClosed) myWork(myWork.Length()) = myWork(1);
1171 // check the number of edges for debug
1172 Standard_Integer nbmax=0, nbmin=0;
1173 for ( i=ideb; i<=ifin; i++) {
1174 Standard_Integer nbEdges=0;
1175 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1178 if (i==ideb) nbmin = nbEdges;
1179 if (nbmax<nbEdges) nbmax = nbEdges;
1180 if (nbmin>nbEdges) nbmin = nbEdges;
1183 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SameNumberByPolarMethod failed");
1188 //=======================================================================
1189 //function : SameNumberByACR
1191 //=======================================================================
1193 void BRepFill_CompatibleWires::SameNumberByACR(const Standard_Boolean report)
1195 // find the dimension
1196 Standard_Integer ideb=1, ifin=myWork.Length();
1197 BRepTools_WireExplorer anExp;
1199 // point sections, blocking sections?
1200 if (myDegen1) ideb++;
1201 if (myDegen2) ifin--;
1202 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
1203 && (myWork(ideb).IsSame(myWork(ifin)));
1205 Standard_Integer nbSects = myWork.Length(), i;
1206 Standard_Integer nbmax=0, nbmin=0;
1207 TColStd_Array1OfInteger nbEdges(1,nbSects);
1208 for (i=1; i<=nbSects; i++) {
1210 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1213 if (i==1) nbmin = nbEdges(i);
1214 if (nbmax<nbEdges(i)) nbmax = nbEdges(i);
1215 if (nbmin>nbEdges(i)) nbmin = nbEdges(i);
1221 if (report || nbmin<nbmax) {
1222 // insertion of cuts
1223 Standard_Integer nbdec=(nbmax-1)*nbSects+1;
1224 Standard_Real tol = 0.01;
1225 TColStd_Array1OfReal dec(1,nbdec);
1228 // calculate the table of cuts
1229 Standard_Integer j,k,l;
1230 for (i=1; i<=nbSects; i++) {
1232 const TopoDS_Wire& wire1 = TopoDS::Wire(myWork(i));
1233 Standard_Integer nbE = 0;
1234 for(anExp.Init(wire1); anExp.More(); anExp.Next()) {
1237 // length and ACR of the wire
1238 TColStd_Array1OfReal ACR(0,nbE);
1240 BRepFill::ComputeACR(wire1, ACR);
1241 // insertion of ACR of the wire in the table of cuts
1242 for (j=1; j<ACR.Length()-1; j++) {
1244 while (dec(k)<ACR(j)) {
1248 if (dec(k-1)+tol<ACR(j)&& ACR(j)+tol<dec(k)) {
1249 for (l=nbdec-1;l>=k;l--) {
1264 TColStd_Array1OfReal dec2(1,nbdec);
1265 for (k=1;k<=nbdec;k++) {
1269 // insertion of cuts in each wire
1270 for (i=1; i<=nbSects; i++) {
1271 const TopoDS_Wire& oldwire = TopoDS::Wire(myWork(i));
1272 TopoDS_Wire newwire = BRepFill::InsertACR(oldwire, dec2, tol);
1273 BRepTools_WireExplorer anExp1,anExp2;
1274 anExp1.Init(oldwire);
1275 anExp2.Init(newwire);
1276 for (;anExp1.More();anExp1.Next()) {
1277 const TopoDS_Edge& Ecur = anExp1.Current();
1278 if (!Ecur.IsSame(TopoDS::Edge(anExp2.Current()))) {
1279 TopTools_ListOfShape LE;
1282 const TopoDS_Vertex& V1 = anExp1.CurrentVertex();
1283 TopoDS_Vertex VF,VR;
1284 TopExp::Vertices(Ecur,VF,VR,Standard_True);
1285 if (V1.IsSame(VF)) P1 = BRep_Tool::Pnt(VR);
1286 if (V1.IsSame(VR)) P1 = BRep_Tool::Pnt(VF);
1287 TopoDS_Vertex V2 = anExp2.CurrentVertex();
1288 TopExp::Vertices(TopoDS::Edge(anExp2.Current()),
1289 VF,VR,Standard_True);
1290 if (V2.IsSame(VF)) P2 = BRep_Tool::Pnt(VR);
1291 if (V2.IsSame(VR)) P2 = BRep_Tool::Pnt(VF);
1292 while (P1.Distance(P2)>1.e-3) {
1293 LE.Append(anExp2.Current());
1295 V2 = anExp2.CurrentVertex();
1296 TopExp::Vertices(TopoDS::Edge(anExp2.Current()),
1297 VF,VR,Standard_True);
1298 if (V2.IsSame(VF)) P2 = BRep_Tool::Pnt(VR);
1299 if (V2.IsSame(VR)) P2 = BRep_Tool::Pnt(VF);
1300 if (P1.Distance(P2)<=1.e-3) {
1301 LE.Append(anExp2.Current());
1306 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itmap;
1307 //TopTools_ListIteratorOfListOfShape itlist;
1308 TopoDS_Edge Ancestor;
1309 Standard_Integer nbedge, nblist=0;
1310 Standard_Boolean found = Standard_False;
1312 for (itmap.Initialize(myMap);itmap.More()&&(!found);itmap.Next()) {
1314 TopTools_ListIteratorOfListOfShape itlist(itmap.Value());
1316 while (itlist.More()&&(!found)) {
1318 TopoDS_Edge ECur = TopoDS::Edge(itlist.Value());
1320 if (Ecur.IsSame(ECur)) {
1321 Ancestor = TopoDS::Edge(itmap.Key());
1322 found = Standard_True;
1323 myMap(Ancestor).InsertBefore(LE,itlist);
1324 myMap(Ancestor).Remove(itlist);
1326 if (itlist.More()) itlist.Next();
1337 myWork(i) = newwire;
1343 // blocking sections ?
1344 if (vClosed) myWork(myWork.Length()) = myWork(1);
1346 // check the number of edges for debug
1348 for (i=ideb; i<=ifin; i++) {
1350 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1353 if (i==ideb) nbmin = nbEdges(i);
1354 if (nbmax<nbEdges(i)) nbmax = nbEdges(i);
1355 if (nbmin>nbEdges(i)) nbmin = nbEdges(i);
1358 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SameNumberByACR failed");
1361 //=======================================================================
1362 //function : ComputeOrigin
1364 //=======================================================================
1366 void BRepFill_CompatibleWires::ComputeOrigin(const Standard_Boolean /*polar*/ )
1368 // reorganize the wires respecting orientation and origin
1370 TopoDS_Vertex Vdeb, Vfin;
1371 gp_Pnt Pdeb, Psuiv, PPs;
1373 BRepTools_WireExplorer anExp;
1375 Standard_Boolean wClosed, allClosed = Standard_True;
1377 Standard_Integer NbSects = myWork.Length();
1378 Standard_Integer i, ideb=1,ifin=NbSects;
1380 // point sections, blocking sections
1381 if (myDegen1) ideb++;
1382 if (myDegen2) ifin--;
1383 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
1384 && (myWork(ideb).IsSame(myWork(ifin)));
1387 for (i=ideb; i<=ifin; i++) {
1388 wClosed = myWork(i).Closed();
1390 // check if the vertices are the same.
1391 TopoDS_Vertex V1, V2;
1392 TopExp::Vertices(TopoDS::Wire(myWork(i)),V1,V2);
1393 if ( V1.IsSame(V2)) wClosed = Standard_True;
1395 allClosed = (allClosed && wClosed);
1398 for (i=ideb; i<=ifin; i++) {
1399 allClosed = (allClosed && myWork(i).Closed());
1403 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::ComputeOrigin : the wires must be closed");
1406 // Max number of possible cuts
1407 Standard_Integer NbMaxV = 0;
1408 for (i=1; i<=NbSects; i++) {
1409 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1414 // construction of tables of planes of wires
1416 Handle(TColgp_HArray1OfPnt) Pos
1417 = new (TColgp_HArray1OfPnt) (1,NbSects);
1418 Handle(TColgp_HArray1OfVec) Axe
1419 = new (TColgp_HArray1OfVec) (1,NbSects);
1420 for (i=ideb;i<=ifin;i++) {
1421 if (PlaneOfWire(TopoDS::Wire(myWork(i)),P)) {
1422 Pos->SetValue(i,P.Location());
1423 Axe->SetValue(i,gp_Vec(P.Axis().Direction()));
1426 TopTools_SequenceOfShape SeqV;
1428 SeqOfVertices(TopoDS::Wire(myWork(1)),SeqV);
1429 Pos->SetValue(1,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
1430 Axe->SetValue(1,Axe->Value(ideb));
1433 SeqOfVertices(TopoDS::Wire(myWork(NbSects)),SeqV);
1434 Pos->SetValue(NbSects,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
1435 Axe->SetValue(NbSects,Axe->Value(ifin));
1439 //Consider that all wires have same number of edges (polar==Standard_False)
1440 TopTools_SequenceOfShape PrevSeq;
1441 TopTools_SequenceOfShape PrevEseq;
1442 Standard_Integer theLength = 0;
1443 const TopoDS_Wire& wire = TopoDS::Wire( myWork(ideb) );
1444 for (anExp.Init(wire); anExp.More(); anExp.Next())
1446 PrevSeq.Append(anExp.CurrentVertex());
1447 PrevEseq.Append(anExp.Current());
1451 Standard_Integer nbs, NbSamples = 0;
1455 PlaneOfWire(TopoDS::Wire(myWork(ideb)), FirstPlane);
1456 gp_Pnt FirstBary = FirstPlane.Location();
1457 gp_Vec NormalOfFirstPlane = FirstPlane.Axis().Direction();
1458 for (i = ideb+1; i <= ifin; i++)
1460 const TopoDS_Wire& wire = TopoDS::Wire(myWork(i));
1462 //Compute offset vector as current bary center projected on first plane
1463 //to first bary center
1465 PlaneOfWire(wire, CurPlane);
1466 gp_Pnt CurBary = CurPlane.Location();
1467 gp_Vec aVec(FirstBary, CurBary);
1468 gp_Vec anOffsetProj = (aVec * NormalOfFirstPlane) * NormalOfFirstPlane;
1469 CurBary.Translate(-anOffsetProj); //projected current bary center
1470 gp_Vec Offset(CurBary, FirstBary);
1472 TopoDS_Wire newwire;
1474 BB.MakeWire(newwire);
1476 TopTools_SequenceOfShape SeqVertices, SeqEdges;
1477 for (anExp.Init(wire); anExp.More(); anExp.Next())
1479 SeqVertices.Append( anExp.CurrentVertex() );
1480 SeqEdges.Append( anExp.Current() );
1483 Standard_Real MinSumDist = Precision::Infinite();
1484 Standard_Integer jmin = 1, j, k, n;
1485 Standard_Boolean forward = Standard_False;
1486 if (i == myWork.Length() && myDegen2)
1488 // last point section
1490 forward = Standard_True;
1493 for (j = 1; j <= theLength; j++)
1496 Standard_Real SumDist = 0.;
1497 for (k = j, n = 1; k <= theLength; k++, n++)
1499 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1500 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1501 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1502 gp_Pnt P = BRep_Tool::Pnt(V).XYZ() + Offset.XYZ();
1503 SumDist += Pprev.Distance(P);
1506 const TopoDS_Edge& PrevEdge = TopoDS::Edge(PrevEseq(n));
1507 const TopoDS_Edge& CurEdge = TopoDS::Edge(SeqEdges(k));
1508 BRepAdaptor_Curve PrevEcurve(PrevEdge);
1509 BRepAdaptor_Curve Ecurve(CurEdge);
1510 Standard_Real SampleOnPrev = (PrevEcurve.LastParameter()-PrevEcurve.FirstParameter())/NbSamples;
1511 Standard_Real SampleOnCur = (Ecurve.LastParameter()-Ecurve.FirstParameter())/NbSamples;
1512 for (nbs = 1; nbs <= NbSamples-1; nbs++)
1514 Standard_Real ParOnPrev = (PrevEdge.Orientation() == TopAbs_FORWARD)?
1515 (PrevEcurve.FirstParameter() + nbs*SampleOnPrev) :
1516 (PrevEcurve.FirstParameter() + (NbSamples-nbs)*SampleOnPrev);
1517 Standard_Real ParOnCur = (CurEdge.Orientation() == TopAbs_FORWARD)?
1518 (Ecurve.FirstParameter() + nbs*SampleOnCur) :
1519 (Ecurve.FirstParameter() + (NbSamples-nbs)*SampleOnCur);
1520 gp_Pnt PonPrev = PrevEcurve.Value(ParOnPrev);
1521 gp_Pnt PonCur = Ecurve.Value(ParOnCur).XYZ() + Offset.XYZ();
1522 SumDist += PonPrev.Distance(PonCur);
1526 for (k = 1; k < j; k++, n++)
1528 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1529 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1530 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1531 gp_Pnt P = BRep_Tool::Pnt(V).XYZ() + Offset.XYZ();
1532 SumDist += Pprev.Distance(P);
1535 const TopoDS_Edge& PrevEdge = TopoDS::Edge(PrevEseq(n));
1536 const TopoDS_Edge& CurEdge = TopoDS::Edge(SeqEdges(k));
1537 BRepAdaptor_Curve PrevEcurve(PrevEdge);
1538 BRepAdaptor_Curve Ecurve(CurEdge);
1539 Standard_Real SampleOnPrev = (PrevEcurve.LastParameter()-PrevEcurve.FirstParameter())/NbSamples;
1540 Standard_Real SampleOnCur = (Ecurve.LastParameter()-Ecurve.FirstParameter())/NbSamples;
1541 for (nbs = 1; nbs <= NbSamples-1; nbs++)
1543 Standard_Real ParOnPrev = (PrevEdge.Orientation() == TopAbs_FORWARD)?
1544 (PrevEcurve.FirstParameter() + nbs*SampleOnPrev) :
1545 (PrevEcurve.FirstParameter() + (NbSamples-nbs)*SampleOnPrev);
1546 Standard_Real ParOnCur = (CurEdge.Orientation() == TopAbs_FORWARD)?
1547 (Ecurve.FirstParameter() + nbs*SampleOnCur) :
1548 (Ecurve.FirstParameter() + (NbSamples-nbs)*SampleOnCur);
1549 gp_Pnt PonPrev = PrevEcurve.Value(ParOnPrev);
1550 gp_Pnt PonCur = Ecurve.Value(ParOnCur).XYZ() + Offset.XYZ();
1551 SumDist += PonPrev.Distance(PonCur);
1555 if (SumDist < MinSumDist)
1557 MinSumDist = SumDist;
1559 forward = Standard_True;
1564 for (k = j, n = 1; k >= 1; k--, n++)
1566 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1567 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1568 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1569 gp_Pnt P = BRep_Tool::Pnt(V).XYZ() + Offset.XYZ();
1570 SumDist += Pprev.Distance(P);
1573 Standard_Integer k_cur = k-1;
1576 const TopoDS_Edge& PrevEdge = TopoDS::Edge(PrevEseq(n));
1577 const TopoDS_Edge& CurEdge = TopoDS::Edge(SeqEdges(k_cur));
1578 BRepAdaptor_Curve PrevEcurve(PrevEdge);
1579 BRepAdaptor_Curve Ecurve(CurEdge);
1580 Standard_Real SampleOnPrev = (PrevEcurve.LastParameter()-PrevEcurve.FirstParameter())/NbSamples;
1581 Standard_Real SampleOnCur = (Ecurve.LastParameter()-Ecurve.FirstParameter())/NbSamples;
1582 for (nbs = 1; nbs <= NbSamples-1; nbs++)
1584 Standard_Real ParOnPrev = (PrevEdge.Orientation() == TopAbs_FORWARD)?
1585 (PrevEcurve.FirstParameter() + nbs*SampleOnPrev) :
1586 (PrevEcurve.FirstParameter() + (NbSamples-nbs)*SampleOnPrev);
1587 Standard_Real ParOnCur = (CurEdge.Orientation() == TopAbs_FORWARD)?
1588 (Ecurve.FirstParameter() + (NbSamples-nbs)*SampleOnCur) :
1589 (Ecurve.FirstParameter() + nbs*SampleOnCur);
1590 gp_Pnt PonPrev = PrevEcurve.Value(ParOnPrev);
1591 gp_Pnt PonCur = Ecurve.Value(ParOnCur).XYZ() + Offset.XYZ();
1592 SumDist += PonPrev.Distance(PonCur);
1596 for (k = theLength; k > j; k--, n++)
1598 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1599 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1600 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1601 gp_Pnt P = BRep_Tool::Pnt(V).XYZ() + Offset.XYZ();
1602 SumDist += Pprev.Distance(P);
1605 const TopoDS_Edge& PrevEdge = TopoDS::Edge(PrevEseq(n));
1606 const TopoDS_Edge& CurEdge = TopoDS::Edge(SeqEdges(k-1));
1607 BRepAdaptor_Curve PrevEcurve(PrevEdge);
1608 BRepAdaptor_Curve Ecurve(CurEdge);
1609 Standard_Real SampleOnPrev = (PrevEcurve.LastParameter()-PrevEcurve.FirstParameter())/NbSamples;
1610 Standard_Real SampleOnCur = (Ecurve.LastParameter()-Ecurve.FirstParameter())/NbSamples;
1611 for (nbs = 1; nbs <= NbSamples-1; nbs++)
1613 Standard_Real ParOnPrev = (PrevEdge.Orientation() == TopAbs_FORWARD)?
1614 (PrevEcurve.FirstParameter() + nbs*SampleOnPrev) :
1615 (PrevEcurve.FirstParameter() + (NbSamples-nbs)*SampleOnPrev);
1616 Standard_Real ParOnCur = (CurEdge.Orientation() == TopAbs_FORWARD)?
1617 (Ecurve.FirstParameter() + (NbSamples-nbs)*SampleOnCur) :
1618 (Ecurve.FirstParameter() + nbs*SampleOnCur);
1619 gp_Pnt PonPrev = PrevEcurve.Value(ParOnPrev);
1620 gp_Pnt PonCur = Ecurve.Value(ParOnCur).XYZ() + Offset.XYZ();
1621 SumDist += PonPrev.Distance(PonCur);
1625 if (SumDist < MinSumDist)
1627 MinSumDist = SumDist;
1629 forward = Standard_False;
1637 for (j = jmin; j <= theLength; j++)
1639 BB.Add( newwire, TopoDS::Edge(SeqEdges(j)) );
1640 PrevSeq.Append( SeqVertices(j) );
1641 PrevEseq.Append( SeqEdges(j) );
1643 for (j = 1; j < jmin; j++)
1645 BB.Add( newwire, TopoDS::Edge(SeqEdges(j)) );
1646 PrevSeq.Append( SeqVertices(j) );
1647 PrevEseq.Append( SeqEdges(j) );
1652 for (j = jmin-1; j >= 1; j--)
1654 TopoDS_Shape aLocalShape = SeqEdges(j).Reversed();
1655 BB.Add( newwire, TopoDS::Edge(aLocalShape) );
1656 //PrevSeq.Append( SeqVertices(j) );
1657 PrevEseq.Append( SeqEdges(j).Reversed() );
1659 for (j = theLength; j >= jmin; j--)
1661 TopoDS_Shape aLocalShape = SeqEdges(j).Reversed();
1662 BB.Add( newwire, TopoDS::Edge(aLocalShape) );
1663 //PrevSeq.Append( SeqVertices(j) );
1664 PrevEseq.Append( SeqEdges(j).Reversed() );
1666 for (j = jmin; j >= 1; j--)
1667 PrevSeq.Append( SeqVertices(j) );
1668 for (j = theLength; j > jmin; j--)
1669 PrevSeq.Append( SeqVertices(j) );
1672 newwire.Closed( Standard_True );
1673 newwire.Orientation( TopAbs_FORWARD );
1674 myWork(i) = newwire;
1678 for ( i=ideb; i<=myWork.Length(); i++) {
1680 const TopoDS_Wire& wire = TopoDS::Wire(myWork(i));
1682 Standard_Integer nbEdges=0;
1683 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next())
1685 TopExp::Vertices(wire,Vdeb,Vfin);
1686 Standard_Boolean wClosed = wire.Closed();
1688 // on regarde quand meme si les vertex sont les memes.
1689 if ( Vdeb.IsSame(Vfin)) wClosed = Standard_True;
1693 TopoDS_Vertex Vsuiv, VF, VR;
1694 TopoDS_Wire newwire;
1696 BW.MakeWire(newwire);
1699 const TopoDS_Edge Ecur = TopoDS::Edge(anExp.Current());
1700 TopExp::Vertices(Ecur,VF,VR);
1701 if (Vdeb.IsSame(VF)) Vsuiv=VR;
1702 else if (Vdeb.IsSame(VR)) Vsuiv=VF;
1704 // par defaut on prend l'origine sur cette arete
1705 if (VR.IsSame(TopoDS::Vertex(anExp.CurrentVertex()))) {
1714 Pdeb=BRep_Tool::Pnt(Vdeb);
1715 Psuiv=BRep_Tool::Pnt(Vsuiv);
1716 Standard_Real U1 = BRep_Tool::Parameter(Vdeb,Ecur);
1717 Standard_Real U2 = BRep_Tool::Parameter(Vsuiv,Ecur);
1718 BRepAdaptor_Curve Curve(Ecur);
1719 PPs = Curve.Value(0.25*(U1+3*U2));
1720 myWork(ideb) = wire;
1723 // on ramene Pdeb, Psuiv et PPs dans le plan courant
1724 gp_Pnt Pnew,Pnext,PPn;
1725 Transform(Standard_True,Pdeb,Pos->Value(i-1),Axe->Value(i-1),
1726 Pos->Value(i),Axe->Value(i),Pnew);
1727 Transform(Standard_True,Psuiv,Pos->Value(i-1),Axe->Value(i-1),
1728 Pos->Value(i),Axe->Value(i),Pnext);
1729 Transform(Standard_True,PPs,Pos->Value(i-1),Axe->Value(i-1),
1730 Pos->Value(i),Axe->Value(i),PPn);
1732 Standard_Real distmini,dist;
1733 Standard_Integer rang=0,rangdeb=0;
1734 TopoDS_Vertex Vmini;
1736 SeqOfVertices(wire,SeqV);
1737 if (SeqV.Length()>NbMaxV)
1738 Standard_NoSuchObject::Raise("BRepFill::ComputeOrigin failed");
1740 // choix du vertex le plus proche comme origine
1741 distmini = Precision::Infinite();
1742 for (Standard_Integer ii=1;ii<=SeqV.Length();ii++) {
1743 P1 = BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(ii)));
1744 dist = P1.Distance(Pnew);
1745 if (dist<distmini) {
1747 Vmini = TopoDS::Vertex(SeqV.Value(ii));
1750 if (!Vmini.IsNull()) Pmini = BRep_Tool::Pnt(Vmini);
1754 // recherche du vertex correspondant a la projection conique
1755 Standard_Real angmin, angV, eta = Precision::Angular();
1756 TopoDS_Vertex Vopti;
1758 distmini = Precision::Infinite();
1759 gp_Dir dir0(gp_Vec(Pnew,P.Location()));
1760 for (Standard_Integer ii=1;ii<=SeqV.Length();ii++) {
1761 P1 = BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(ii)));
1762 dist = Pnew.Distance(P1);
1763 if (dist<Precision::Confusion()) {
1767 gp_Dir dir1(gp_Vec(Pnew,P1));
1768 angV = dir1.Angle(dir0);
1770 if (angV>M_PI/2) angV = M_PI - angV;
1771 if (angmin>angV+eta) {
1774 Vopti = TopoDS::Vertex(SeqV.Value(ii));
1776 else if (Abs(angmin-angV)<eta) {
1777 if (dist<distmini) {
1780 Vopti = TopoDS::Vertex(SeqV.Value(ii));
1785 if (!Vopti.IsNull()) Popti = BRep_Tool::Pnt(Vopti);
1790 distmini = Precision::Infinite();
1791 for (anExp.Init(wire); anExp.More(); anExp.Next()) {
1792 TopoDS_Edge Ecur = anExp.Current();
1793 TopoDS_Vertex Vcur = anExp.CurrentVertex();
1794 TopExp::Vertices(Ecur,VF,VR);
1795 if (VF.IsSame(Vmini)) {
1796 P1 = BRep_Tool::Pnt(VR);
1797 dist = P1.Distance(Pnext);
1798 if (dist<=distmini) {
1803 if (VR.IsSame(Vmini)) {
1804 P1 = BRep_Tool::Pnt(VF);
1805 dist = P1.Distance(Pnext);
1806 if (dist<distmini) {
1813 // choix du sens de parcours en fonction de Pnext
1814 Standard_Boolean parcours = Standard_False;
1815 if (i==myWork.Length() && myDegen2) {
1816 // derniere section ponctuelle
1818 parcours = Standard_True;
1822 gp_Pnt Pbout = Pnext;
1824 TopoDS_Vertex V1,V2;
1825 EdgesFromVertex(wire,Vmini,E1,E2);
1827 TopExp::Vertices(E1,V1,V2,Standard_True);
1829 Standard_Real U1=0, U2=0;
1831 Standard_Real U1, U2;
1833 if (Vmini.IsSame(V1)) {
1834 P1 = BRep_Tool::Pnt(V2);
1835 U1 = 0.25*(BRep_Tool::Parameter(V1,E1)+3*BRep_Tool::Parameter(V2,E1));
1837 if (Vmini.IsSame(V2)) {
1838 P1 = BRep_Tool::Pnt(V1);
1839 U1 = 0.25*(3*BRep_Tool::Parameter(V1,E1)+BRep_Tool::Parameter(V2,E1));
1842 TopExp::Vertices(E2,V1,V2,Standard_True);
1843 if (Vmini.IsSame(V1)) {
1844 P2 = BRep_Tool::Pnt(V2);
1845 U2 = 0.25*(BRep_Tool::Parameter(V1,E2)+3*BRep_Tool::Parameter(V2,E2));
1847 if (Vmini.IsSame(V2)) {
1848 P2 = BRep_Tool::Pnt(V1);
1849 U2 = 0.25*(3*BRep_Tool::Parameter(V1,E2)+BRep_Tool::Parameter(V2,E2));
1852 if (Abs(Pbout.Distance(P1)-Pbout.Distance(P2))<Precision::Confusion()) {
1853 // cas limite ; on se decale un peu
1855 BRepAdaptor_Curve Curve1(E1);
1856 P1 = Curve1.Value(U1);
1857 BRepAdaptor_Curve Curve2(E2);
1858 P2 = Curve2.Value(U2);
1861 // calcul de rangdeb
1863 if (Pbout.Distance(P1)<Pbout.Distance(P2)){
1864 // P1 est plus proche; parcours = False
1865 parcours = Standard_False;
1867 for (anExp.Init(wire); anExp.More(); anExp.Next()) {
1869 TopoDS_Edge Ecur = anExp.Current();
1870 if (E1.IsSame(Ecur)) {
1874 BRepAdaptor_Curve Curve(E1);
1875 PPs = Curve.Value(U1);
1878 // P2 est plus proche; parcours = True
1879 parcours = Standard_True;
1881 for (anExp.Init(wire); anExp.More(); anExp.Next()) {
1883 TopoDS_Edge Ecur = anExp.Current();
1884 if (E2.IsSame(Ecur)) {
1888 BRepAdaptor_Curve Curve(E2);
1889 PPs = Curve.Value(U2);
1893 // reconstruction du wire a partir de rangdeb
1894 TopTools_SequenceOfShape SeqEdges;
1896 for (anExp.Init(TopoDS::Wire(wire)); anExp.More(); anExp.Next()) {
1897 SeqEdges.Append(anExp.Current());
1900 for (rang=rangdeb;rang<=nbEdges;rang++) {
1901 BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang)));
1903 for (rang=1;rang<rangdeb;rang++) {
1904 BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang)));
1908 for (rang=rangdeb;rang>=1;rang--) {
1909 TopoDS_Shape aLocalShape = SeqEdges.Value(rang).Reversed();
1910 BW.Add(newwire,TopoDS::Edge(aLocalShape));
1911 // BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang).Reversed()));
1913 for (rang=nbEdges;rang>rangdeb;rang--) {
1914 TopoDS_Shape aLocalShape = SeqEdges.Value(rang).Reversed();
1915 BW.Add(newwire,TopoDS::Edge(aLocalShape));
1916 // BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang).Reversed()));
1920 myWork(i) = newwire.Oriented(TopAbs_FORWARD);
1922 // on passe au wire suivant
1923 if (!Vmini.IsNull()) Pdeb=BRep_Tool::Pnt(Vmini);
1924 if (!Vsuiv.IsNull()) Psuiv=BRep_Tool::Pnt(Vsuiv);
1929 // blocking sections ?
1930 if (vClosed) myWork(myWork.Length()) = myWork(1);
1933 //=======================================================================
1934 //function : SearchOrigin
1936 //=======================================================================
1938 void BRepFill_CompatibleWires::SearchOrigin()
1940 // reorganize the open wires respecting orientation and origin
1944 TopoDS_Vertex Vdeb, Vfin;
1945 gp_Pnt Pdeb, Pfin;//,Psuiv;
1947 BRepTools_WireExplorer anExp;
1949 Standard_Boolean allOpen = Standard_True;
1950 Standard_Integer ideb=1, ifin=myWork.Length();
1951 if (myDegen1) ideb++;
1952 if (myDegen2) ifin--;
1953 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
1954 && (myWork(ideb).IsSame(myWork(ifin)));
1956 // for (Standard_Integer i=ideb; i<=ifin; i++) {
1958 for (i=ideb; i<=ifin; i++) {
1959 allOpen = (allOpen && !myWork(i).Closed());
1962 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SearchOrigin : the wires must be open");
1966 TopoDS_Wire wire1 = TopoDS::Wire(myWork(ideb));
1967 wire1.Orientation(TopAbs_FORWARD);
1968 TopExp::Vertices(wire1,Vdeb,Vfin);
1969 Pdeb = BRep_Tool::Pnt(Vdeb);
1970 Pfin = BRep_Tool::Pnt(Vfin);
1971 Standard_Boolean isline0 = (!PlaneOfWire(wire1,P0)), isline;
1972 myWork(ideb) = wire1;
1975 TopoDS_Edge E0 = anExp.Current(), E;
1977 for ( i=ideb+1; i<=ifin; i++) {
1979 TopoDS_Wire wire = TopoDS::Wire(myWork(i));
1980 wire.Orientation(TopAbs_FORWARD);
1982 TopTools_SequenceOfShape SeqEdges;
1984 Standard_Integer nbEdges=0;
1985 //OCC86 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
1986 for(anExp.Init(wire), E = anExp.Current(); anExp.More(); anExp.Next()) {
1987 SeqEdges.Append(anExp.Current());
1990 TopExp::Vertices(wire,Vdeb,Vfin);
1991 isline = (!PlaneOfWire(wire,P));
1993 TopoDS_Vertex Vmini;
1994 TopoDS_Wire newwire;
1996 BW.MakeWire(newwire);
1997 Standard_Boolean parcours = Standard_True;
1999 if (isline0 || isline) {
2001 // particular case of straight segments
2002 gp_Pnt P1 = BRep_Tool::Pnt(Vdeb),
2003 P2 = BRep_Tool::Pnt(Vfin);
2004 Standard_Real dist1, dist2;
2005 dist1 = Pdeb.Distance(P1)+Pfin.Distance(P2);
2006 dist2 = Pdeb.Distance(P2)+Pfin.Distance(P1);
2007 parcours = (dist2>=dist1);
2012 gp_Pnt P1 = BRep_Tool::Pnt(Vdeb), P1o = Pdeb,
2013 P2 = BRep_Tool::Pnt(Vfin), P2o = Pfin;
2014 /* // return Pdeb in the current plane
2015 gp_Pnt Pnew = Pdeb.Translated (P0.Location(),P.Location());
2016 gp_Ax1 A0 = P0.Axis();
2017 gp_Ax1 A1 = P.Axis();
2019 if (!A0.IsParallel(A1,1.e-4)) {
2020 gp_Vec vec1(A0.Direction()), vec2(A1.Direction()),
2022 gp_Ax1 Norm(P.Location(),norm);
2023 Standard_Real ang = vec1.AngleWithRef(vec2,norm);
2026 if (ang < -M_PI/2.0)
2028 if (Abs(ang-M_PI/2.0)<Precision::Angular()) {
2030 gp_Vec Vtrans(P0.Location(),P.Location()),Vsign;
2031 Standard_Real alpha,beta,sign=1;
2032 Vsign.SetLinearForm(Vtrans.Dot(vec1),vec2,-Vtrans.Dot(vec2),vec1);
2033 alpha = Vsign.Dot(vec1);
2034 beta = Vsign.Dot(vec2);
2035 Standard_Boolean pasnul = (Abs(alpha)>1.e-4 && Abs(beta)>1.e-4);
2036 if ( alpha*beta>0.0 && pasnul ) sign=-1;
2039 Pnew = Pnew.Rotated (Norm,ang);
2041 // choix entre Vdeb et Vfin
2042 Standard_Real dist = Pnew.Distance(P1);
2043 parcours = (dist<Pnew.Distance(P2));
2045 if(P1.IsEqual(P2,Precision::Confusion()) || P1o.IsEqual(P2o,Precision::Confusion())){
2046 BRepAdaptor_Curve Curve0(E0), Curve(E);
2047 Curve0.D0(Curve0.FirstParameter() + Precision::Confusion(), P2o);
2048 Curve.D0(Curve.FirstParameter() + Precision::Confusion(), P2);
2050 gp_Vec VDebFin0(P1o,P2o), VDebFin(P1,P2);
2051 Standard_Real AStraight = VDebFin0.Angle(VDebFin);
2052 parcours = (AStraight < M_PI/2.0? Standard_True: Standard_False);
2055 // reconstruction of the wire
2056 Standard_Integer rang;
2058 for (rang=1;rang<=nbEdges;rang++) {
2059 TopoDS_Shape alocalshape = SeqEdges.Value(rang);
2060 BW.Add(newwire,TopoDS::Edge(alocalshape));
2061 // BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang)));
2065 for (rang=nbEdges;rang>=1;rang--) {
2066 TopoDS_Shape alocalshape = SeqEdges.Value(rang).Reversed();
2067 BW.Add(newwire,TopoDS::Edge(alocalshape));
2068 // BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang).Reversed()));
2072 // orientation of the wire
2073 newwire.Oriented(TopAbs_FORWARD);
2074 myWork(i) = newwire;
2076 // passe to the next wire
2078 Pdeb = BRep_Tool::Pnt(Vdeb);
2079 Pfin = BRep_Tool::Pnt(Vfin);
2082 Pfin = BRep_Tool::Pnt(Vdeb);
2083 Pdeb = BRep_Tool::Pnt(Vfin);
2091 // blocking sections ?
2092 if (vClosed) myWork(myWork.Length()) = myWork(1);