1 // File: BRepFill_CompatibleWires.cxx
2 // Created: Thu Jul 2 16:47:25 1998
3 // Author: Joelle CHAUVET
7 #include <BRepFill_CompatibleWires.ixx>
9 #include <BRepAdaptor_Curve.hxx>
11 #include <BRepFill.hxx>
12 #include <BRepLib.hxx>
13 #include <BRepLib_FindSurface.hxx>
14 #include <BRepLib_MakeWire.hxx>
15 #include <BRepLib_MakeEdge.hxx>
16 #include <BRepCheck_Wire.hxx>
17 #include <BRepExtrema_DistShapeShape.hxx>
18 #include <Bnd_Box.hxx>
19 #include <BRepBndLib.hxx>
20 #include <BRep_Builder.hxx>
21 #include <BRep_Tool.hxx>
22 #include <BRepTools_WireExplorer.hxx>
23 #include <BRepLProp.hxx>
24 #include <BRepGProp.hxx>
25 #include <GProp_GProps.hxx>
26 #include <GProp_PrincipalProps.hxx>
27 #include <Geom_Surface.hxx>
28 #include <Geom_Plane.hxx>
29 #include <Precision.hxx>
32 #include <TopExp_Explorer.hxx>
34 #include <TopoDS_Wire.hxx>
35 #include <TopTools_ListIteratorOfListOfShape.hxx>
36 #include <TopTools_DataMapOfShapeListOfShape.hxx>
37 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
38 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
39 #include <TopTools_HSequenceOfShape.hxx>
40 #include <TopTools_SequenceOfShape.hxx>
41 #include <TopTools_ListOfShape.hxx>
47 #include <gp_Circ.hxx>
48 #include <gp_Elips.hxx>
49 #include <TColgp_HArray1OfVec.hxx>
50 #include <TColgp_HArray1OfPnt.hxx>
52 #include <TColStd_Array1OfInteger.hxx>
53 #include <TColStd_Array1OfReal.hxx>
54 #include <TColStd_SequenceOfReal.hxx>
57 static void EdgesFromVertex (const TopoDS_Wire& W,
58 const TopoDS_Vertex& V,
62 TopTools_IndexedDataMapOfShapeListOfShape Map;
63 TopExp::MapShapesAndAncestors(W,TopAbs_VERTEX,TopAbs_EDGE,Map);
65 const TopTools_ListOfShape& List = Map.FindFromKey(V);
66 TopoDS_Edge e1 = TopoDS::Edge(List.First());
67 TopoDS_Edge e2 = TopoDS::Edge(List. Last());
69 BRepTools_WireExplorer anExp;
70 Standard_Integer I1=0, I2=0, NE=0;
72 for(anExp.Init(W); anExp.More(); anExp.Next()) {
74 const TopoDS_Edge& ECur = anExp.Current();
75 if (e1.IsSame(ECur)) {
78 if (e2.IsSame(ECur)) {
84 // numeros consecutifs
95 // numeros non consecutifs sur un wire ferme
108 static void SeqOfVertices (const TopoDS_Wire& W,
109 TopTools_SequenceOfShape& S)
112 Standard_Integer jj, cpt = 0;
114 for (PE.Init(W,TopAbs_VERTEX); PE.More(); PE.Next()) {
116 Standard_Boolean trouve=Standard_False;
117 for (jj=1;jj<=S.Length() && (!trouve);jj++) {
118 if (S.Value(jj).IsSame(PE.Current())) trouve = Standard_True;
120 if (!trouve) S.Append(PE.Current());
125 static Standard_Boolean PlaneOfWire (const TopoDS_Wire& W, gp_Pln& P)
127 Standard_Boolean isplane = Standard_True;
128 BRepLib_FindSurface findPlanarSurf;
129 Handle(Geom_Surface) S;
133 BRepGProp::LinearProperties(W,GP);
134 gp_Pnt Bary = GP.CentreOfMass();
136 // blindage pour les cas particuliers : 1 seule edge cercle ou ellipse
137 // sur un wire ferme !
138 Standard_Integer nbEdges = 0;
139 BRepTools_WireExplorer anExp;
141 Standard_Boolean wClosed = W.Closed();
143 // on regarde quand meme si les vertex sont les memes.
144 TopoDS_Vertex V1, V2;
145 TopExp::Vertices(W,V1,V2);
146 if ( V1.IsSame(V2)) wClosed = Standard_True;
148 TopoDS_Edge Edge = TopoDS::Edge(anExp.Current());
149 Standard_Real first, last;
151 Handle(Geom_Curve) curv;
152 curv = BRep_Tool::Curve(Edge, loc, first, last);
154 Handle(Geom_Curve)::DownCast(curv->Transformed(loc.Transformation()));
156 GeomAdaptor_Curve AdC;
158 for(; anExp.More(); anExp.Next()) {
161 if ( nbEdges==1 && AdC.GetType() == GeomAbs_Circle ) {
162 Bary = AdC.Circle().Location();
164 if ( nbEdges==1 && AdC.GetType() == GeomAbs_Ellipse ) {
165 Bary = AdC.Ellipse().Location();
169 findPlanarSurf.Init(W, -1, Standard_True);
170 if ( findPlanarSurf.Found()) {
171 S = findPlanarSurf.Surface();
172 L = findPlanarSurf.Location();
173 if (!L.IsIdentity()) S = Handle(Geom_Surface)::
174 DownCast(S->Transformed(L.Transformation()));
175 P = (Handle(Geom_Plane)::DownCast(S))->Pln();
180 GProp_PrincipalProps Pp = GP.PrincipalProperties();
182 Standard_Real R1, R2, R3,Tol = Precision::Confusion();
183 Pp.RadiusOfGyration(R1,R2,R3);
184 Standard_Real RMax = Max(Max(R1,R2),R3);
185 if ( ( Abs(RMax-R1)<Tol && Abs(RMax-R2)<Tol )
186 || ( Abs(RMax-R1)<Tol && Abs(RMax-R3)<Tol )
187 || ( Abs(RMax-R2)<Tol && Abs(RMax-R3)<Tol ) )
188 isplane = Standard_False;
190 if (R1>=R2 && R1>=R3) {
191 Vec = Pp.FirstAxisOfInertia();
193 else if (R2>=R1 && R2>=R3) {
194 Vec = Pp.SecondAxisOfInertia();
196 else if (R3>=R1 && R3>=R2) {
197 Vec = Pp.ThirdAxisOfInertia();
200 if (R3<=R2 && R3<=R1) {
201 Vec = Pp.ThirdAxisOfInertia();
203 else if (R2<=R1 && R2<=R3) {
204 Vec = Pp.SecondAxisOfInertia();
206 else if (R1<=R2 && R1<=R3) {
207 Vec = Pp.FirstAxisOfInertia();
210 gp_Ax3 repere(Bary,NDir,XDir);
211 Geom_Plane GPlan(repere);
221 static void WireContinuity (const TopoDS_Wire& W,
222 GeomAbs_Shape& contW)
226 Standard_Boolean IsDegenerated = Standard_False;
228 BRepTools_WireExplorer anExp;
229 Standard_Integer nbEdges=0;
230 Handle(TopTools_HSequenceOfShape) Edges = new TopTools_HSequenceOfShape();
231 for(anExp.Init(W); anExp.More(); anExp.Next()) {
233 Edges->Append(anExp.Current());
234 if (BRep_Tool::Degenerated(anExp.Current())) IsDegenerated = Standard_True;
237 if (!IsDegenerated) {
239 Standard_Boolean testconti = Standard_True;
241 for (Standard_Integer j=1;j<=nbEdges;j++) {
243 TopoDS_Edge Edge1, Edge2;
246 Edge1 = TopoDS::Edge (Edges->Value(nbEdges));
247 Edge2 = TopoDS::Edge (Edges->Value(1));
250 Edge1 = TopoDS::Edge (Edges->Value(j));
251 Edge2 = TopoDS::Edge (Edges->Value(j+1));
254 TopoDS_Vertex V1,V2,Vbid;
255 TopExp::Vertices(Edge1,Vbid,V1,Standard_True);
256 TopExp::Vertices(Edge2,V2,Vbid,Standard_True);
257 Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1);
258 Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2);
259 BRepAdaptor_Curve Curve1(Edge1);
260 BRepAdaptor_Curve Curve2(Edge2);
261 Standard_Real Eps = BRep_Tool::Tolerance(V2) + BRep_Tool::Tolerance(V1);
264 testconti = Curve1.Value(U1).IsEqual(Curve2.Value(U2), Eps);
267 cont = BRepLProp::Continuity(Curve1,Curve2,U1,U2,
268 Eps, Precision::Angular());
269 if (cont <= contW) contW = cont;
276 static void TrimEdge (const TopoDS_Edge& CurrentEdge,
277 const TColStd_SequenceOfReal& CutValues,
278 const Standard_Real t0, const Standard_Real t1,
279 const Standard_Boolean SeqOrder,
280 TopTools_SequenceOfShape& S)
284 Standard_Integer j, ndec=CutValues.Length();
285 Standard_Real first,last,m0,m1;
286 Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
288 TopoDS_Vertex Vf,Vl,Vbid,V0,V1;
289 TopAbs_Orientation CurrentOrient = CurrentEdge.Orientation();
290 TopExp::Vertices(CurrentEdge,Vf,Vl);
294 // de first vers last
297 for (j=1; j<=ndec; j++) {
299 m1 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
300 TopoDS_Edge CutE = BRepLib_MakeEdge(C,V0,Vbid,m0,m1);
301 CutE.Orientation(CurrentOrient);
304 V0 = TopExp::LastVertex(CutE);
307 TopoDS_Edge LastE = BRepLib_MakeEdge(C,V0,Vl,m0,last);
308 LastE.Orientation(CurrentOrient);
314 // de last vers first
317 for (j=ndec; j>=1; j--) {
319 m0 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
320 TopoDS_Edge CutE = BRepLib_MakeEdge(C,Vbid,V1,m0,m1);
321 CutE.Orientation(CurrentOrient);
324 V1 = TopExp::FirstVertex(CutE);
327 TopoDS_Edge LastE = BRepLib_MakeEdge(C,Vf,V1,first,m1);
328 LastE.Orientation(CurrentOrient);
337 static Standard_Boolean SearchRoot (const TopoDS_Vertex& V,
338 const TopTools_DataMapOfShapeListOfShape& Map,
339 TopoDS_Vertex& VRoot)
341 Standard_Boolean trouve = Standard_False;
343 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape it;
344 for (it.Initialize(Map); it.More(); it.Next()) {
345 const TopTools_ListOfShape & List = it.Value();
346 TopTools_ListIteratorOfListOfShape itL;
347 Standard_Boolean ilyest = Standard_False;
348 for (itL.Initialize(List); itL.More(); itL.Next()) {
349 TopoDS_Vertex Vcur = TopoDS::Vertex(itL.Value());
350 if (Vcur.IsSame(V)) {
351 ilyest = Standard_True;
356 trouve = Standard_True;
357 VRoot = TopoDS::Vertex(it.Key());
364 static Standard_Boolean SearchVertex (const TopTools_ListOfShape& List,
365 const TopoDS_Wire& W,
368 Standard_Boolean trouve = Standard_False;
370 TopTools_SequenceOfShape SeqV;
371 SeqOfVertices(W,SeqV);
372 for (Standard_Integer ii=1;ii<=SeqV.Length();ii++) {
373 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
374 TopTools_ListIteratorOfListOfShape itL;
375 Standard_Boolean ilyest = Standard_False;
376 for (itL.Initialize(List); itL.More(); itL.Next()) {
377 TopoDS_Vertex Vcur = TopoDS::Vertex(itL.Value());
378 if (Vcur.IsSame(Vi)) {
379 ilyest = Standard_True;
384 trouve = Standard_True;
393 static Standard_Boolean EdgeIntersectOnWire (const gp_Pnt& P1,
395 Standard_Real percent,
396 const TopTools_DataMapOfShapeListOfShape& Map,
397 const TopoDS_Wire& W,
402 BRepTools_WireExplorer anExp;
404 // construction de l'edge d'intersection
405 Standard_Boolean NewVertex = Standard_False;
406 gp_Lin droite(P1,gp_Dir(gp_Vec(P1,P2)));
407 // ATTENTION : en toute rigueur, il faudrait construire une demi-droite
408 // mais il y a un bug dans BRepExtrema_DistShapeShape
409 // on se contente de 100 * la distance entre P1 et P2
410 // en esperant que ce soit suffisant jusqu'a ce que le bug
412 // Standard_Real dernierparam = Precision::Infinite();
413 // ATTENTION : le retour !!
414 // 100 c'est mieux que 10 mais quelquefois c'est trop !
415 // finalement, rien ne vaut une bonne boite d'encombrement
416 // Standard_Real dernierparam = 100 * P1.Distance(P2);
418 BRepBndLib::Add(W,B);
419 Standard_Real x1,x2,y1,y2,z1,z2;
420 B.Get(x1,y1,z1,x2,y2,z2);
421 gp_Pnt BP1(x1,y1,z1), BP2(x2,y2,z2);
422 Standard_Real diag = BP1.Distance(BP2);
423 Standard_Real dernierparam = diag;
424 BRepLib_MakeEdge ME(droite,0.,dernierparam);
425 TopoDS_Edge ECur = BRepLib_MakeEdge(droite,0.,P1.Distance(P2));
427 // calcul de l'intersection par BRepExtrema (point de distance mini)
428 BRepExtrema_DistShapeShape DSS(ME.Edge(),W);
430 // on choisit la solution la plus proche de P2
431 Standard_Integer isol = 1;
432 Standard_Real dss = P2.Distance(DSS.PointOnShape2(isol));
433 for (Standard_Integer iss=2; iss<=DSS.NbSolution(); iss++) {
434 if (dss>P2.Distance(DSS.PointOnShape2(iss))) {
435 dss = P2.Distance(DSS.PointOnShape2(iss));
442 DSS.PointOnShape2(isol);
443 // la solution est-elle un nouveau vertex ?
444 NewVertex = (DSS.SupportTypeShape2(isol) != BRepExtrema_IsVertex);
446 TopoDS_Shape aLocalShape = DSS.SupportOnShape2(isol);
447 TopoDS_Edge E = TopoDS::Edge(aLocalShape);
448 // TopoDS_Edge E = TopoDS::Edge(DSS.SupportOnShape2(isol));
449 Standard_Real tol = Precision::PConfusion();
450 Standard_Real first,last,param;
451 BRep_Tool::Range(E,first,last);
452 tol = Max(tol,percent*Abs(last-first));
453 DSS.ParOnEdgeS2(isol,param);
454 if (Abs(first-param)<tol) {
455 NewVertex = Standard_False;
456 Vsol = TopExp::FirstVertex(E);
458 else if (Abs(last-param)<tol) {
459 NewVertex = Standard_False;
460 Vsol = TopExp::LastVertex(E);
465 if (SearchRoot(Vsol,Map,VRoot)) NewVertex = Standard_True;
469 TopoDS_Shape aLocalShape = DSS.SupportOnShape2(isol);
470 Vsol = TopoDS::Vertex(aLocalShape);
471 // Vsol = TopoDS::Vertex(DSS.SupportOnShape2(isol));
474 // il faut decouper l'edge
476 TopoDS_Shape aLocalShape = DSS.SupportOnShape2(isol);
477 TopoDS_Edge E = TopoDS::Edge(aLocalShape);
478 // TopoDS_Edge E = TopoDS::Edge(DSS.SupportOnShape2(isol));
482 Precision::PConfusion();
483 Standard_Real first,last,param;
484 DSS.ParOnEdgeS2(isol,param);
485 BRep_Tool::Range(E,first,last);
487 for (anExp.Init(W); anExp.More(); anExp.Next()) {
488 if (E.IsSame(anExp.Current())) {
490 = (anExp.CurrentVertex().IsSame(TopExp::FirstVertex(E)));
491 TopTools_SequenceOfShape SE;
493 TColStd_SequenceOfReal SR;
496 TrimEdge(E,SR,first,last,SO,SE);
497 TopoDS_Vertex VV1,VV2;
498 TopExp::Vertices(TopoDS::Edge(SE.Value(1)),VV1,VV2);
499 if (TopExp::FirstVertex(E).IsSame(VV1)
500 || TopExp::LastVertex(E).IsSame(VV1)) {
503 if (TopExp::FirstVertex(E).IsSame(VV2)
504 || TopExp::LastVertex(E).IsSame(VV2)) {
507 for (Standard_Integer k=1; k<=SE.Length(); k++) {
508 MW.Add(TopoDS::Edge(SE.Value(k)));
512 MW.Add(anExp.Current());
529 static void Transform (const Standard_Boolean WithRotation,
538 Pnew = P.Translated (Pos1,Pos2);
539 gp_Vec axe1 = Ax1, axe2 = Ax2;
540 if (!axe1.IsParallel(axe2,1.e-4)) {
541 gp_Vec Vtrans(Pos1,Pos2),Vsign;
542 Standard_Real alpha,beta,sign=1;
543 alpha = Vtrans.Dot(axe1);
544 beta = Vtrans.Dot(axe2);
545 if (alpha<-1.e-7) axe1 *=-1;
546 if (beta<1.e-7) axe2 *=-1;
547 alpha = Vtrans.Dot(axe1);
548 beta = Vtrans.Dot(axe2);
549 gp_Vec norm2 = axe1 ^ axe2;
550 Vsign.SetLinearForm(Vtrans.Dot(axe1),axe2,-Vtrans.Dot(axe2),axe1);
551 alpha = Vsign.Dot(axe1);
552 beta = Vsign.Dot(axe2);
553 Standard_Boolean pasnul = (Abs(alpha)>1.e-4 && Abs(beta)>1.e-4);
554 if ( alpha*beta>0.0 && pasnul ) sign=-1;
555 gp_Ax1 Norm(Pos2,norm2);
556 Standard_Real ang = axe1.AngleWithRef(axe2,norm2);
558 if (ang>PI/2) ang = ang - PI;
559 if (ang<-PI/2) ang = ang + PI;
562 Pnew = Pnew.Rotated (Norm,ang);
566 static void BuildConnectedEdges(const TopoDS_Wire& aWire,
567 const TopoDS_Edge& StartEdge,
568 const TopoDS_Vertex& StartVertex,
569 TopTools_ListOfShape& ConnectedEdges)
571 TopTools_IndexedDataMapOfShapeListOfShape MapVE;
572 TopExp::MapShapesAndAncestors(aWire, TopAbs_VERTEX, TopAbs_EDGE, MapVE);
573 TopoDS_Edge CurEdge = StartEdge;
574 TopoDS_Vertex CurVertex = StartVertex;
575 TopoDS_Vertex Origin, V1, V2;
576 TopExp::Vertices(StartEdge, V1, V2);
577 Origin = (V1.IsSame(StartVertex))? V2 : V1;
581 TopTools_ListIteratorOfListOfShape itE( MapVE.FindFromKey(CurVertex) );
582 for (; itE.More(); itE.Next())
584 TopoDS_Edge anEdge = TopoDS::Edge(itE.Value());
585 if (!anEdge.IsSame(CurEdge))
587 ConnectedEdges.Append(anEdge);
588 TopExp::Vertices(anEdge, V1, V2);
589 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
594 if (CurVertex.IsSame(Origin))
599 //=======================================================================
600 //function : BRepFill_CompatibleWires
602 //=======================================================================
604 BRepFill_CompatibleWires::BRepFill_CompatibleWires()
605 :myIsDone(Standard_False)
610 //=======================================================================
611 //function : BRepFill_CompatibleWires
613 //=======================================================================
615 BRepFill_CompatibleWires::BRepFill_CompatibleWires(const TopTools_SequenceOfShape& Sections)
621 //=======================================================================
624 //=======================================================================
626 void BRepFill_CompatibleWires::Init(const TopTools_SequenceOfShape& Sections)
631 myIsDone = Standard_False;
637 //=======================================================================
638 //function : SetPercent
640 //=======================================================================
642 void BRepFill_CompatibleWires::SetPercent(const Standard_Real Percent)
644 if (0.<Percent && Percent<1.) myPercent = Percent;
649 //=======================================================================
652 //=======================================================================
654 Standard_Boolean BRepFill_CompatibleWires::IsDone() const
660 //=======================================================================
663 //=======================================================================
665 const TopTools_SequenceOfShape& BRepFill_CompatibleWires::Shape() const
671 //=======================================================================
672 //function : GeneratedShapes
674 //=======================================================================
676 const TopTools_ListOfShape& BRepFill_CompatibleWires::GeneratedShapes
677 (const TopoDS_Edge& SubSection) const
680 if (myMap.IsBound(SubSection)) {
681 return myMap(SubSection);
684 static TopTools_ListOfShape Empty;
690 //=======================================================================
693 //=======================================================================
695 void BRepFill_CompatibleWires::Perform (const Standard_Boolean WithRotation)
697 // compute origin and orientation on wires to avoid twisted results
698 // and update wires to have same number of edges
700 // determination de report:
701 // si le nombre d'elements est identique et si les wires ont des discontinuites
702 // en tangence, on n'effectue pas le report par abscisse curviligne, ni
703 Standard_Integer nbSects = myWork.Length(), i;
704 BRepTools_WireExplorer anExp;
705 Standard_Integer nbmax=0, nbmin=0;
706 TColStd_Array1OfInteger nbEdges(1,nbSects);
707 Standard_Boolean report;
708 GeomAbs_Shape contS=GeomAbs_CN;
710 for (i=1; i<=nbSects; i++) {
711 TopoDS_Shape aLocalShape = myWork(i).Oriented(TopAbs_FORWARD);
712 myWork(i) = TopoDS::Wire(aLocalShape);
713 // myWork(i) = TopoDS::Wire(myWork(i).Oriented(TopAbs_FORWARD));
714 TopoDS_Wire W = TopoDS::Wire(myWork(i));
715 WireContinuity(W,cont);
716 if (cont<contS) contS=cont;
718 for(anExp.Init(W); anExp.More(); anExp.Next() ) nbEdges(i)++;
719 if (i==1) nbmin = nbEdges(i);
720 if (nbmax<nbEdges(i)) nbmax = nbEdges(i);
721 if (nbmin>nbEdges(i)) nbmin = nbEdges(i);
723 // si on n'a pas le meme nombre d'elements ou si tous les wires sont au moins
724 // C1, on effectue le report par abscisse curviligne des decoupes sinon, on se
725 // fait un report vertex / Vertex
726 report = (nbmax != nbmin || contS >= GeomAbs_C1 );
728 // initialisation de la map
729 Standard_Integer nbE = 0;
730 TopTools_ListOfShape Empty;
731 for (i=1; i<=nbSects; i++) {
732 TopoDS_Wire W = TopoDS::Wire(myWork(i));
733 for(anExp.Init(W); anExp.More(); anExp.Next() ) {
734 TopoDS_Edge E = TopoDS::Edge(anExp.Current());
741 // sections ouvertes / sections fermees
742 // initialisation de myDegen1, myDegen2
743 Standard_Integer ideb=1, ifin=myWork.Length();
744 // on regarde si le premier wire est ponctuel
745 myDegen1 = Standard_True;
746 for(anExp.Init(TopoDS::Wire(myWork(ideb))); anExp.More(); anExp.Next()) {
747 myDegen1 = myDegen1 && (BRep_Tool::Degenerated(anExp.Current()));
749 if (myDegen1) ideb++;
750 // on regarde si le dernier wire est ponctuel
751 myDegen2 = Standard_True;
752 for(anExp.Init(TopoDS::Wire(myWork(ifin))); anExp.More(); anExp.Next()) {
753 myDegen2 = myDegen2 && (BRep_Tool::Degenerated(anExp.Current()));
755 if (myDegen2) ifin--;
757 Standard_Boolean wClosed, allClosed = Standard_True, allOpen = Standard_True;
758 for (i=ideb; i<=ifin; i++) {
759 wClosed = myWork(i).Closed();
761 // on regarde quand meme si les vertex sont les memes.
762 TopoDS_Vertex V1, V2;
763 TopExp::Vertices(TopoDS::Wire(myWork(i)),V1,V2);
764 if ( V1.IsSame(V2)) wClosed = Standard_True;
766 allClosed = (allClosed && wClosed);
767 allOpen = (allOpen && !wClosed);
771 // Toutes les sections sont fermees
773 // same number of elements
774 SameNumberByPolarMethod(WithRotation);
778 ComputeOrigin(Standard_False);
780 myIsDone = Standard_True;
783 // Toutes les sections sont ouvertes
786 // same number of elements
788 SameNumberByACR(report);
790 myIsDone = Standard_True;
793 // Il y a des sections ouvertes et des sections fermees :
795 Standard_DomainError::Raise("Sections must be all closed or all open");
803 //=======================================================================
804 //function : Generated
806 //=======================================================================
808 const TopTools_DataMapOfShapeListOfShape& BRepFill_CompatibleWires::Generated() const
814 //=======================================================================
815 //function : SameNumberByPolarMethod
817 //=======================================================================
819 void BRepFill_CompatibleWires::
820 SameNumberByPolarMethod(const Standard_Boolean WithRotation)
824 Standard_Integer NbSects=myWork.Length();
825 BRepTools_WireExplorer anExp;
826 TopoDS_Vertex V1, V2;
828 Standard_Boolean allClosed = Standard_True;
829 Standard_Integer i,ii,ideb=1,ifin=NbSects;
830 for (i=1; i<=NbSects; i++) {
831 Handle(BRepCheck_Wire) Checker = new BRepCheck_Wire(TopoDS::Wire(myWork(i)));
832 allClosed = (allClosed && (Checker->Closed() == BRepCheck_NoError));
833 //allClosed = (allClosed && myWork(i).Closed());
836 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SameNumberByPolarMethod : the wires must be closed");
838 // Nombre max de decoupes possibles
839 Standard_Integer NbMaxV = 0;
840 for (i=1; i<=NbSects; i++) {
841 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
846 // sections ponctuelles, sections bouclantes ?
847 if (myDegen1) ideb++;
848 if (myDegen2) ifin--;
849 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
850 && (myWork(ideb).IsSame(myWork(ifin)));
852 // construction des tableaux de plans des wires
854 Handle(TColgp_HArray1OfPnt) Pos
855 = new (TColgp_HArray1OfPnt) (1,NbSects);
856 Handle(TColgp_HArray1OfVec) Axe
857 = new (TColgp_HArray1OfVec) (1,NbSects);
858 for (i=ideb;i<=ifin;i++) {
859 if (PlaneOfWire(TopoDS::Wire(myWork(i)),P)) {
860 Pos->SetValue(i,P.Location());
861 Axe->SetValue(i,gp_Vec(P.Axis().Direction()));
864 TopTools_SequenceOfShape SeqV;
866 SeqOfVertices(TopoDS::Wire(myWork(1)),SeqV);
867 Pos->SetValue(1,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
868 Axe->SetValue(1,Axe->Value(ideb));
871 SeqOfVertices(TopoDS::Wire(myWork(NbSects)),SeqV);
872 Pos->SetValue(NbSects,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
873 Axe->SetValue(NbSects,Axe->Value(ifin));
876 // construction de RMap, map des reports du wire i vers le wire i-1
877 TopTools_DataMapOfShapeListOfShape RMap;
881 for (i=ifin; i>ideb; i--) {
883 const TopoDS_Wire& wire1 = TopoDS::Wire(myWork(i));
885 // sequence des vertex du premier wire
886 SeqOfVertices(wire1,SeqV);
887 if (SeqV.Length()>NbMaxV)
888 Standard_NoSuchObject::Raise("BRepFill::SameNumberByPolarMethod failed");
890 // extremite du premier wire
891 V1 = TopoDS::Vertex(SeqV.Value(1));
894 const TopoDS_Wire& wire2 =
896 TopoDS::Wire(myWork(i-1));
897 // boucle sur les vertex de wire1
898 for (ii=1;ii<=SeqV.Length();ii++) {
900 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
902 // init de RMap pour Vi
903 TopTools_ListOfShape Init;
907 // il faut chercher l'intersection Vi - wire2
908 gp_Pnt Pi = BRep_Tool::Pnt(Vi);
910 // on ramene Pi dans le plan courant
912 Transform(WithRotation,Pi,
913 Pos->Value(i),Axe->Value(i),
914 Pos->Value(i-1),Axe->Value(i-1),Pnew);
916 // calcul de l'intersection
917 TopoDS_Shape Support;
918 Standard_Boolean NewVertex;
921 if (Pnew.Distance(Pos->Value(i-1))>Precision::Confusion()) {
922 Standard_Real percent = myPercent;
923 NewVertex = EdgeIntersectOnWire(Pos->Value(i-1),Pnew,percent,
924 RMap,TopoDS::Wire(myWork(i-1)),
926 if (NewVertex) myWork(i-1) = newwire;
927 RMap(Vi).Append(Vsol);
933 // initialisation de MapVLV, map des correspondances vertex - liste de vertex
934 TopTools_DataMapOfShapeListOfShape MapVLV;
935 SeqOfVertices(TopoDS::Wire(myWork(ideb)),SeqV);
936 Standard_Integer SizeMap = SeqV.Length();
938 for (ii=1;ii<=SizeMap;ii++) {
939 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
940 TopTools_ListOfShape Init;
943 MapVLV.Bind(Vi,Init);
944 Standard_Integer NbV = 1;
947 Standard_Boolean tantque = SearchRoot(V0,RMap,V1);
949 MapVLV(Vi).Append(V1);
951 // test sur NbV necessaire pour les sections bouclantes
952 if (V1.IsSame(Vi) || NbV >= myWork.Length()) {
953 tantque = Standard_False;
957 tantque = SearchRoot(V0,RMap,V1);
963 for (i=ideb; i<ifin; i++) {
965 const TopoDS_Wire& wire1 = TopoDS::Wire(myWork(i));
967 // sequence des vertex du premier wire
968 SeqOfVertices(wire1,SeqV);
969 if ( SeqV.Length()>NbMaxV || SeqV.Length()>SizeMap )
970 Standard_NoSuchObject::Raise("BRepFill::SameNumberByPolarMethod failed");
972 // extremite du premier wire
973 V1 = TopoDS::Vertex(SeqV.Value(1));
976 const TopoDS_Wire& wire2 = TopoDS::Wire(myWork(i+1));
978 // boucle sur les vertex de wire1
979 for (ii=1;ii<=SeqV.Length();ii++) {
981 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
984 Standard_Boolean intersect = Standard_True;
985 if (SearchRoot(Vi,MapVLV,VRoot)) {
986 const TopTools_ListOfShape& LVi = MapVLV(VRoot);
989 intersect = (!SearchVertex(LVi,wire2,VonW));
993 // il faut chercher l'intersection Vi - wire2
994 gp_Pnt Pi = BRep_Tool::Pnt(Vi);
996 // on ramene Pi dans le plan courant
998 Transform(WithRotation,Pi,
999 Pos->Value(i),Axe->Value(i),
1000 Pos->Value(i+1),Axe->Value(i+1),Pnew);
1002 // calcul de l'intersection
1003 TopoDS_Shape Support;
1004 Standard_Boolean NewVertex;
1006 TopoDS_Wire newwire;
1007 if (Pnew.Distance(Pos->Value(i+1))>Precision::Confusion()) {
1008 Standard_Real percent = myPercent;
1009 NewVertex = EdgeIntersectOnWire(Pos->Value(i+1),Pnew,percent,
1010 MapVLV,TopoDS::Wire(myWork(i+1)),
1012 MapVLV(VRoot).Append(Vsol);
1013 if (NewVertex) myWork(i+1) = newwire;
1020 // mise en ordre des wires en suivant MapVLV
1021 TopoDS_Wire wire = TopoDS::Wire(myWork(ideb));
1023 // sauf le dernier si les sections sont bouclantes
1024 Standard_Integer ibout = ifin;
1025 if (vClosed) ibout--;
1027 for ( i=ideb+1; i<=ibout; i++) {
1029 BRepLib_MakeWire MW;
1032 TopoDS_Edge ECur = anExp.Current();
1033 TopoDS_Vertex VF,VL;
1034 TopExp::Vertices(ECur,VF,VL,Standard_True);
1035 Standard_Real U1 = BRep_Tool::Parameter(VF,ECur);
1036 Standard_Real U2 = BRep_Tool::Parameter(VL,ECur);
1037 BRepAdaptor_Curve Curve(ECur);
1038 gp_Pnt PPs = Curve.Value(0.1*(U1+9*U2));
1039 TopTools_ListIteratorOfListOfShape itF(MapVLV(VF)),itL(MapVLV(VL));
1040 Standard_Integer rang = ideb;
1046 TopoDS_Vertex V1 = TopoDS::Vertex(itF.Value()), V2 = TopoDS::Vertex(itL.Value());
1048 Standard_Real scalmax=0.;
1049 TopoDS_Iterator itW( myWork(i) );
1051 for(; itW.More(); itW.Next())
1053 TopoDS_Edge E = TopoDS::Edge(itW.Value());
1054 TopoDS_Vertex VVF,VVL;
1055 TopExp::Vertices(E,VVF,VVL,Standard_True);
1057 // tri des edges candidates
1058 Standard_Real scal1,scal2;
1059 if ( (V1.IsSame(VVF)&&V2.IsSame(VVL)) || (V2.IsSame(VVF)&&V1.IsSame(VVL)) ) {
1060 Standard_Real U1 = BRep_Tool::Parameter(VVF,E);
1061 Standard_Real U2 = BRep_Tool::Parameter(VVL,E);
1062 BRepAdaptor_Curve Curve(E);
1063 gp_Pnt PP1 = Curve.Value(0.1*(U1+9*U2));
1064 gp_Pnt PP2 = Curve.Value(0.1*(9*U1+U2));
1066 for (rang=i;rang>ideb;rang--) {
1067 Transform(WithRotation, PP1,
1068 Pos->Value(rang), Axe->Value(rang),
1069 Pos->Value(rang-1), Axe->Value(rang-1), PP1);
1070 Transform(WithRotation, PP2,
1071 Pos->Value(rang), Axe->Value(rang),
1072 Pos->Value(rang-1), Axe->Value(rang-1), PP2);
1074 gp_Vec Ns(Pos->Value(ideb),PPs);
1075 Ns = Ns.Normalized();
1076 gp_Vec N1(Pos->Value(ideb),PP1);
1077 N1 = N1.Normalized();
1078 gp_Vec N2(Pos->Value(ideb),PP2);
1079 N2 = N2.Normalized();
1081 if (scal1>scalmax) {
1086 if (scal2>scalmax) {
1088 TopoDS_Shape aLocalShape = E.Reversed();
1089 Esol = TopoDS::Edge(aLocalShape);
1092 } //end of for(; itW.More(); itW.Next())
1095 TopTools_ListOfShape ConnectedEdges;
1096 BuildConnectedEdges( TopoDS::Wire(myWork(i)), Esol, V2, ConnectedEdges );
1098 TopTools_ListIteratorOfListOfShape itCE(ConnectedEdges);
1099 for(; anExp.More(), itCE.More(); anExp.Next(), itCE.Next())
1101 ECur = anExp.Current();
1102 TopExp::Vertices(ECur,VF,VL,Standard_True);
1103 U1 = BRep_Tool::Parameter(VF,ECur);
1104 U2 = BRep_Tool::Parameter(VL,ECur);
1105 Curve.Initialize(ECur);
1106 PPs = Curve.Value(0.1*(U1+9*U2));
1108 TopoDS_Edge E = TopoDS::Edge(itCE.Value());
1109 TopoDS_Vertex VVF,VVL;
1110 TopExp::Vertices(E,VVF,VVL,Standard_True);
1112 // tri des edges candidates
1113 Standard_Real scal1,scal2;
1114 U1 = BRep_Tool::Parameter(VVF,E);
1115 U2 = BRep_Tool::Parameter(VVL,E);
1116 Curve.Initialize(E);
1117 gp_Pnt PP1 = Curve.Value(0.1*(U1+9*U2));
1118 gp_Pnt PP2 = Curve.Value(0.1*(9*U1+U2));
1120 for (rang=i;rang>ideb;rang--) {
1121 Transform(WithRotation, PP1,
1122 Pos->Value(rang), Axe->Value(rang),
1123 Pos->Value(rang-1), Axe->Value(rang-1), PP1);
1124 Transform(WithRotation, PP2,
1125 Pos->Value(rang), Axe->Value(rang),
1126 Pos->Value(rang-1), Axe->Value(rang-1), PP2);
1128 gp_Vec Ns(Pos->Value(ideb),PPs);
1129 Ns = Ns.Normalized();
1130 gp_Vec N1(Pos->Value(ideb),PP1);
1131 N1 = N1.Normalized();
1132 gp_Vec N2(Pos->Value(ideb),PP2);
1133 N2 = N2.Normalized();
1140 myWork(i) = MW.Wire();
1143 // sections bouclantes ?
1144 if (vClosed) myWork(myWork.Length()) = myWork(1);
1146 // verification du nombre d'edges pour debug
1147 Standard_Integer nbmax=0, nbmin=0;
1148 for ( i=ideb; i<=ifin; i++) {
1149 Standard_Integer nbEdges=0;
1150 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1153 if (i==ideb) nbmin = nbEdges;
1154 if (nbmax<nbEdges) nbmax = nbEdges;
1155 if (nbmin>nbEdges) nbmin = nbEdges;
1158 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SameNumberByPolarMethod failed");
1163 //=======================================================================
1164 //function : SameNumberByACR
1166 //=======================================================================
1168 void BRepFill_CompatibleWires::SameNumberByACR(const Standard_Boolean report)
1170 // find the dimension
1171 Standard_Integer ideb=1, ifin=myWork.Length();
1172 BRepTools_WireExplorer anExp;
1174 // sections ponctuelles, sections bouclantes ?
1175 if (myDegen1) ideb++;
1176 if (myDegen2) ifin--;
1177 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
1178 && (myWork(ideb).IsSame(myWork(ifin)));
1180 Standard_Integer nbSects = myWork.Length(), i;
1181 Standard_Integer nbmax=0, nbmin=0;
1182 TColStd_Array1OfInteger nbEdges(1,nbSects);
1183 for (i=1; i<=nbSects; i++) {
1185 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1188 if (i==1) nbmin = nbEdges(i);
1189 if (nbmax<nbEdges(i)) nbmax = nbEdges(i);
1190 if (nbmin>nbEdges(i)) nbmin = nbEdges(i);
1196 if (report || nbmin<nbmax) {
1197 // insertion des decoupes
1198 Standard_Integer nbdec=(nbmax-1)*nbSects+1;
1199 Standard_Real tol = 0.01;
1200 TColStd_Array1OfReal dec(1,nbdec);
1203 // calcul du tableau des decoupes
1204 Standard_Integer j,k,l;
1205 for (i=1; i<=nbSects; i++) {
1207 const TopoDS_Wire& wire1 = TopoDS::Wire(myWork(i));
1208 Standard_Integer nbE = 0;
1209 for(anExp.Init(wire1); anExp.More(); anExp.Next()) {
1212 // longueur et ACR du wire
1213 TColStd_Array1OfReal ACR(0,nbE);
1215 BRepFill::ComputeACR(wire1, ACR);
1216 // insertion des ACR du wire dans le tableau des decoupes
1217 for (j=1; j<ACR.Length()-1; j++) {
1219 while (dec(k)<ACR(j)) {
1223 if (dec(k-1)+tol<ACR(j)&& ACR(j)+tol<dec(k)) {
1224 for (l=nbdec-1;l>=k;l--) {
1232 // tableau effectif des decoupes
1239 TColStd_Array1OfReal dec2(1,nbdec);
1240 for (k=1;k<=nbdec;k++) {
1244 // insertion des decoupes dans chaque wire
1245 for (i=1; i<=nbSects; i++) {
1246 const TopoDS_Wire& oldwire = TopoDS::Wire(myWork(i));
1247 TopoDS_Wire newwire = BRepFill::InsertACR(oldwire, dec2, tol);
1248 BRepTools_WireExplorer anExp1,anExp2;
1249 anExp1.Init(oldwire);
1250 anExp2.Init(newwire);
1251 for (;anExp1.More();anExp1.Next()) {
1252 const TopoDS_Edge& Ecur = anExp1.Current();
1253 if (!Ecur.IsSame(TopoDS::Edge(anExp2.Current()))) {
1254 TopTools_ListOfShape LE;
1257 const TopoDS_Vertex& V1 = anExp1.CurrentVertex();
1258 TopoDS_Vertex VF,VR;
1259 TopExp::Vertices(Ecur,VF,VR,Standard_True);
1260 if (V1.IsSame(VF)) P1 = BRep_Tool::Pnt(VR);
1261 if (V1.IsSame(VR)) P1 = BRep_Tool::Pnt(VF);
1262 TopoDS_Vertex V2 = anExp2.CurrentVertex();
1263 TopExp::Vertices(TopoDS::Edge(anExp2.Current()),
1264 VF,VR,Standard_True);
1265 if (V2.IsSame(VF)) P2 = BRep_Tool::Pnt(VR);
1266 if (V2.IsSame(VR)) P2 = BRep_Tool::Pnt(VF);
1267 while (P1.Distance(P2)>1.e-3) {
1268 LE.Append(anExp2.Current());
1270 V2 = anExp2.CurrentVertex();
1271 TopExp::Vertices(TopoDS::Edge(anExp2.Current()),
1272 VF,VR,Standard_True);
1273 if (V2.IsSame(VF)) P2 = BRep_Tool::Pnt(VR);
1274 if (V2.IsSame(VR)) P2 = BRep_Tool::Pnt(VF);
1275 if (P1.Distance(P2)<=1.e-3) {
1276 LE.Append(anExp2.Current());
1281 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itmap;
1282 //TopTools_ListIteratorOfListOfShape itlist;
1283 TopoDS_Edge Ancestor;
1284 Standard_Integer nbedge, nblist=0;
1285 Standard_Boolean found = Standard_False;
1287 for (itmap.Initialize(myMap);itmap.More()&&(!found);itmap.Next()) {
1289 TopTools_ListIteratorOfListOfShape itlist(itmap.Value());
1291 while (itlist.More()&&(!found)) {
1293 TopoDS_Edge ECur = TopoDS::Edge(itlist.Value());
1295 if (Ecur.IsSame(ECur)) {
1296 Ancestor = TopoDS::Edge(itmap.Key());
1297 found = Standard_True;
1298 myMap(Ancestor).InsertBefore(LE,itlist);
1299 myMap(Ancestor).Remove(itlist);
1301 if (itlist.More()) itlist.Next();
1312 myWork(i) = newwire;
1318 // sections bouclantes ?
1319 if (vClosed) myWork(myWork.Length()) = myWork(1);
1321 // verification du nombre d'edges pour debug
1323 for (i=ideb; i<=ifin; i++) {
1325 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1328 if (i==ideb) nbmin = nbEdges(i);
1329 if (nbmax<nbEdges(i)) nbmax = nbEdges(i);
1330 if (nbmin>nbEdges(i)) nbmin = nbEdges(i);
1333 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SameNumberByACR failed");
1336 //=======================================================================
1337 //function : ComputeOrigin
1339 //=======================================================================
1341 void BRepFill_CompatibleWires::ComputeOrigin(const Standard_Boolean polar )
1343 // reorganize the wires respecting orientation and origin
1345 TopoDS_Vertex Vdeb, Vfin;
1346 gp_Pnt Pdeb, Psuiv, PPs;
1348 BRepTools_WireExplorer anExp;
1350 Standard_Boolean wClosed, allClosed = Standard_True;
1352 Standard_Integer NbSects = myWork.Length();
1353 Standard_Integer i, ideb=1,ifin=NbSects;
1355 // sections ponctuelles, sections bouclantes
1356 if (myDegen1) ideb++;
1357 if (myDegen2) ifin--;
1358 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
1359 && (myWork(ideb).IsSame(myWork(ifin)));
1362 for (i=ideb; i<=ifin; i++) {
1363 wClosed = myWork(i).Closed();
1365 // on regarde quand meme si les vertex sont les memes.
1366 TopoDS_Vertex V1, V2;
1367 TopExp::Vertices(TopoDS::Wire(myWork(i)),V1,V2);
1368 if ( V1.IsSame(V2)) wClosed = Standard_True;
1370 allClosed = (allClosed && wClosed);
1373 for (i=ideb; i<=ifin; i++) {
1374 allClosed = (allClosed && myWork(i).Closed());
1378 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::ComputeOrigin : the wires must be closed");
1381 // Nombre max de decoupes possibles
1382 Standard_Integer NbMaxV = 0;
1383 for (i=1; i<=NbSects; i++) {
1384 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1389 // construction des tableaux de plans des wires
1391 Handle(TColgp_HArray1OfPnt) Pos
1392 = new (TColgp_HArray1OfPnt) (1,NbSects);
1393 Handle(TColgp_HArray1OfVec) Axe
1394 = new (TColgp_HArray1OfVec) (1,NbSects);
1395 for (i=ideb;i<=ifin;i++) {
1396 if (PlaneOfWire(TopoDS::Wire(myWork(i)),P)) {
1397 Pos->SetValue(i,P.Location());
1398 Axe->SetValue(i,gp_Vec(P.Axis().Direction()));
1401 TopTools_SequenceOfShape SeqV;
1403 SeqOfVertices(TopoDS::Wire(myWork(1)),SeqV);
1404 Pos->SetValue(1,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
1405 Axe->SetValue(1,Axe->Value(ideb));
1408 SeqOfVertices(TopoDS::Wire(myWork(NbSects)),SeqV);
1409 Pos->SetValue(NbSects,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
1410 Axe->SetValue(NbSects,Axe->Value(ifin));
1414 //Consider that all wires have same number of edges (polar==Standard_False)
1415 TopTools_SequenceOfShape PrevSeq;
1416 Standard_Integer theLength = 0;
1417 const TopoDS_Wire& wire = TopoDS::Wire( myWork(ideb) );
1418 for (anExp.Init(wire); anExp.More(); anExp.Next())
1420 PrevSeq.Append(anExp.CurrentVertex());
1424 for (i = ideb+1; i <= ifin; i++)
1426 const TopoDS_Wire& wire = TopoDS::Wire(myWork(i));
1427 TopoDS_Wire newwire;
1429 BB.MakeWire(newwire);
1431 TopTools_SequenceOfShape SeqVertices, SeqEdges;
1432 for (anExp.Init(wire); anExp.More(); anExp.Next())
1434 SeqVertices.Append( anExp.CurrentVertex() );
1435 SeqEdges.Append( anExp.Current() );
1438 Standard_Real MinSumDist = Precision::Infinite();
1439 Standard_Integer jmin, j, k, n;
1440 Standard_Boolean forward;
1441 if (i == myWork.Length() && myDegen2)
1443 // derniere section ponctuelle
1445 forward = Standard_True;
1448 for (j = 1; j <= theLength; j++)
1451 Standard_Real SumDist = 0.;
1452 for (k = j, n = 1; k <= theLength; k++, n++)
1454 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1455 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1456 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1457 gp_Pnt P = BRep_Tool::Pnt(V);
1458 SumDist += Pprev.Distance(P);
1460 for (k = 1; k < j; k++, n++)
1462 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1463 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1464 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1465 gp_Pnt P = BRep_Tool::Pnt(V);
1466 SumDist += Pprev.Distance(P);
1468 if (SumDist < MinSumDist)
1470 MinSumDist = SumDist;
1472 forward = Standard_True;
1477 for (k = j, n = 1; k >= 1; k--, n++)
1479 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1480 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1481 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1482 gp_Pnt P = BRep_Tool::Pnt(V);
1483 SumDist += Pprev.Distance(P);
1485 for (k = theLength; k > j; k--, n++)
1487 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1488 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1489 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1490 gp_Pnt P = BRep_Tool::Pnt(V);
1491 SumDist += Pprev.Distance(P);
1493 if (SumDist < MinSumDist)
1495 MinSumDist = SumDist;
1497 forward = Standard_False;
1504 for (j = jmin; j <= theLength; j++)
1506 BB.Add( newwire, TopoDS::Edge(SeqEdges(j)) );
1507 PrevSeq.Append( SeqVertices(j) );
1509 for (j = 1; j < jmin; j++)
1511 BB.Add( newwire, TopoDS::Edge(SeqEdges(j)) );
1512 PrevSeq.Append( SeqVertices(j) );
1517 for (j = jmin-1; j >= 1; j--)
1519 TopoDS_Shape aLocalShape = SeqEdges(j).Reversed();
1520 BB.Add( newwire, TopoDS::Edge(aLocalShape) );
1521 //PrevSeq.Append( SeqVertices(j) );
1523 for (j = theLength; j >= jmin; j--)
1525 TopoDS_Shape aLocalShape = SeqEdges(j).Reversed();
1526 BB.Add( newwire, TopoDS::Edge(aLocalShape) );
1527 //PrevSeq.Append( SeqVertices(j) );
1529 for (j = jmin; j >= 1; j--)
1530 PrevSeq.Append( SeqVertices(j) );
1531 for (j = theLength; j > jmin; j--)
1532 PrevSeq.Append( SeqVertices(j) );
1535 newwire.Closed( Standard_True );
1536 newwire.Orientation( TopAbs_FORWARD );
1537 myWork(i) = newwire;
1541 for ( i=ideb; i<=myWork.Length(); i++) {
1543 const TopoDS_Wire& wire = TopoDS::Wire(myWork(i));
1545 Standard_Integer nbEdges=0;
1546 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next())
1548 TopExp::Vertices(wire,Vdeb,Vfin);
1549 Standard_Boolean wClosed = wire.Closed();
1551 // on regarde quand meme si les vertex sont les memes.
1552 if ( Vdeb.IsSame(Vfin)) wClosed = Standard_True;
1556 TopoDS_Vertex Vsuiv, VF, VR;
1557 TopoDS_Wire newwire;
1559 BW.MakeWire(newwire);
1562 const TopoDS_Edge Ecur = TopoDS::Edge(anExp.Current());
1563 TopExp::Vertices(Ecur,VF,VR);
1564 if (Vdeb.IsSame(VF)) Vsuiv=VR;
1565 else if (Vdeb.IsSame(VR)) Vsuiv=VF;
1567 // par defaut on prend l'origine sur cette arete
1568 if (VR.IsSame(TopoDS::Vertex(anExp.CurrentVertex()))) {
1577 Pdeb=BRep_Tool::Pnt(Vdeb);
1578 Psuiv=BRep_Tool::Pnt(Vsuiv);
1579 Standard_Real U1 = BRep_Tool::Parameter(Vdeb,Ecur);
1580 Standard_Real U2 = BRep_Tool::Parameter(Vsuiv,Ecur);
1581 BRepAdaptor_Curve Curve(Ecur);
1582 PPs = Curve.Value(0.25*(U1+3*U2));
1583 myWork(ideb) = wire;
1586 // on ramene Pdeb, Psuiv et PPs dans le plan courant
1587 gp_Pnt Pnew,Pnext,PPn;
1588 Transform(Standard_True,Pdeb,Pos->Value(i-1),Axe->Value(i-1),
1589 Pos->Value(i),Axe->Value(i),Pnew);
1590 Transform(Standard_True,Psuiv,Pos->Value(i-1),Axe->Value(i-1),
1591 Pos->Value(i),Axe->Value(i),Pnext);
1592 Transform(Standard_True,PPs,Pos->Value(i-1),Axe->Value(i-1),
1593 Pos->Value(i),Axe->Value(i),PPn);
1595 Standard_Real distmini,dist;
1596 Standard_Integer rang=0,rangdeb=0;
1597 TopoDS_Vertex Vmini;
1599 SeqOfVertices(wire,SeqV);
1600 if (SeqV.Length()>NbMaxV)
1601 Standard_NoSuchObject::Raise("BRepFill::ComputeOrigin failed");
1603 // choix du vertex le plus proche comme origine
1604 distmini = Precision::Infinite();
1605 for (Standard_Integer ii=1;ii<=SeqV.Length();ii++) {
1606 P1 = BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(ii)));
1607 dist = P1.Distance(Pnew);
1608 if (dist<distmini) {
1610 Vmini = TopoDS::Vertex(SeqV.Value(ii));
1613 if (!Vmini.IsNull()) Pmini = BRep_Tool::Pnt(Vmini);
1617 // recherche du vertex correspondant a la projection conique
1618 Standard_Real angmin, angV, eta = Precision::Angular();
1619 TopoDS_Vertex Vopti;
1621 distmini = Precision::Infinite();
1622 gp_Dir dir0(gp_Vec(Pnew,P.Location()));
1623 for (Standard_Integer ii=1;ii<=SeqV.Length();ii++) {
1624 P1 = BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(ii)));
1625 dist = Pnew.Distance(P1);
1626 if (dist<Precision::Confusion()) {
1630 gp_Dir dir1(gp_Vec(Pnew,P1));
1631 angV = dir1.Angle(dir0);
1633 if (angV>PI/2) angV = PI - angV;
1634 if (angmin>angV+eta) {
1637 Vopti = TopoDS::Vertex(SeqV.Value(ii));
1639 else if (Abs(angmin-angV)<eta) {
1640 if (dist<distmini) {
1643 Vopti = TopoDS::Vertex(SeqV.Value(ii));
1648 if (!Vopti.IsNull()) Popti = BRep_Tool::Pnt(Vopti);
1653 distmini = Precision::Infinite();
1654 for (anExp.Init(wire); anExp.More(); anExp.Next()) {
1655 TopoDS_Edge Ecur = anExp.Current();
1656 TopoDS_Vertex Vcur = anExp.CurrentVertex();
1657 TopExp::Vertices(Ecur,VF,VR);
1658 if (VF.IsSame(Vmini)) {
1659 P1 = BRep_Tool::Pnt(VR);
1660 dist = P1.Distance(Pnext);
1661 if (dist<=distmini) {
1666 if (VR.IsSame(Vmini)) {
1667 P1 = BRep_Tool::Pnt(VF);
1668 dist = P1.Distance(Pnext);
1669 if (dist<distmini) {
1676 // choix du sens de parcours en fonction de Pnext
1677 Standard_Boolean parcours = Standard_False;
1678 if (i==myWork.Length() && myDegen2) {
1679 // derniere section ponctuelle
1681 parcours = Standard_True;
1685 gp_Pnt Pbout = Pnext;
1687 TopoDS_Vertex V1,V2;
1688 EdgesFromVertex(wire,Vmini,E1,E2);
1690 TopExp::Vertices(E1,V1,V2,Standard_True);
1692 Standard_Real U1=0, U2=0;
1694 Standard_Real U1, U2;
1696 if (Vmini.IsSame(V1)) {
1697 P1 = BRep_Tool::Pnt(V2);
1698 U1 = 0.25*(BRep_Tool::Parameter(V1,E1)+3*BRep_Tool::Parameter(V2,E1));
1700 if (Vmini.IsSame(V2)) {
1701 P1 = BRep_Tool::Pnt(V1);
1702 U1 = 0.25*(3*BRep_Tool::Parameter(V1,E1)+BRep_Tool::Parameter(V2,E1));
1705 TopExp::Vertices(E2,V1,V2,Standard_True);
1706 if (Vmini.IsSame(V1)) {
1707 P2 = BRep_Tool::Pnt(V2);
1708 U2 = 0.25*(BRep_Tool::Parameter(V1,E2)+3*BRep_Tool::Parameter(V2,E2));
1710 if (Vmini.IsSame(V2)) {
1711 P2 = BRep_Tool::Pnt(V1);
1712 U2 = 0.25*(3*BRep_Tool::Parameter(V1,E2)+BRep_Tool::Parameter(V2,E2));
1715 if (Abs(Pbout.Distance(P1)-Pbout.Distance(P2))<Precision::Confusion()) {
1716 // cas limite ; on se decale un peu
1718 BRepAdaptor_Curve Curve1(E1);
1719 P1 = Curve1.Value(U1);
1720 BRepAdaptor_Curve Curve2(E2);
1721 P2 = Curve2.Value(U2);
1724 // calcul de rangdeb
1726 if (Pbout.Distance(P1)<Pbout.Distance(P2)){
1727 // P1 est plus proche; parcours = False
1728 parcours = Standard_False;
1730 for (anExp.Init(wire); anExp.More(); anExp.Next()) {
1732 TopoDS_Edge Ecur = anExp.Current();
1733 if (E1.IsSame(Ecur)) {
1737 BRepAdaptor_Curve Curve(E1);
1738 PPs = Curve.Value(U1);
1741 // P2 est plus proche; parcours = True
1742 parcours = Standard_True;
1744 for (anExp.Init(wire); anExp.More(); anExp.Next()) {
1746 TopoDS_Edge Ecur = anExp.Current();
1747 if (E2.IsSame(Ecur)) {
1751 BRepAdaptor_Curve Curve(E2);
1752 PPs = Curve.Value(U2);
1756 // reconstruction du wire a partir de rangdeb
1757 TopTools_SequenceOfShape SeqEdges;
1759 for (anExp.Init(TopoDS::Wire(wire)); anExp.More(); anExp.Next()) {
1760 SeqEdges.Append(anExp.Current());
1763 for (rang=rangdeb;rang<=nbEdges;rang++) {
1764 BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang)));
1766 for (rang=1;rang<rangdeb;rang++) {
1767 BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang)));
1771 for (rang=rangdeb;rang>=1;rang--) {
1772 TopoDS_Shape aLocalShape = SeqEdges.Value(rang).Reversed();
1773 BW.Add(newwire,TopoDS::Edge(aLocalShape));
1774 // BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang).Reversed()));
1776 for (rang=nbEdges;rang>rangdeb;rang--) {
1777 TopoDS_Shape aLocalShape = SeqEdges.Value(rang).Reversed();
1778 BW.Add(newwire,TopoDS::Edge(aLocalShape));
1779 // BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang).Reversed()));
1783 myWork(i) = newwire.Oriented(TopAbs_FORWARD);
1785 // on passe au wire suivant
1786 if (!Vmini.IsNull()) Pdeb=BRep_Tool::Pnt(Vmini);
1787 if (!Vsuiv.IsNull()) Psuiv=BRep_Tool::Pnt(Vsuiv);
1792 // sections bouclantes ?
1793 if (vClosed) myWork(myWork.Length()) = myWork(1);
1796 //=======================================================================
1797 //function : SearchOrigin
1799 //=======================================================================
1801 void BRepFill_CompatibleWires::SearchOrigin()
1803 // reorganize the open wires respecting orientation and origin
1807 TopoDS_Vertex Vdeb, Vfin;
1808 gp_Pnt Pdeb, Pfin;//,Psuiv;
1810 BRepTools_WireExplorer anExp;
1812 Standard_Boolean allOpen = Standard_True;
1813 Standard_Integer ideb=1, ifin=myWork.Length();
1814 if (myDegen1) ideb++;
1815 if (myDegen2) ifin--;
1816 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
1817 && (myWork(ideb).IsSame(myWork(ifin)));
1819 // for (Standard_Integer i=ideb; i<=ifin; i++) {
1821 for (i=ideb; i<=ifin; i++) {
1822 allOpen = (allOpen && !myWork(i).Closed());
1825 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SearchOrigin : the wires must be open");
1829 TopoDS_Wire wire1 = TopoDS::Wire(myWork(ideb));
1830 wire1.Orientation(TopAbs_FORWARD);
1831 TopExp::Vertices(wire1,Vdeb,Vfin);
1832 Pdeb = BRep_Tool::Pnt(Vdeb);
1833 Pfin = BRep_Tool::Pnt(Vfin);
1834 Standard_Boolean isline0 = (!PlaneOfWire(wire1,P0)), isline;
1835 myWork(ideb) = wire1;
1838 TopoDS_Edge E0 = anExp.Current(), E;
1840 for ( i=ideb+1; i<=ifin; i++) {
1842 TopoDS_Wire wire = TopoDS::Wire(myWork(i));
1843 wire.Orientation(TopAbs_FORWARD);
1845 TopTools_SequenceOfShape SeqEdges;
1847 Standard_Integer nbEdges=0;
1848 //OCC86 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
1849 for(anExp.Init(wire), E = anExp.Current(); anExp.More(); anExp.Next()) {
1850 SeqEdges.Append(anExp.Current());
1853 TopExp::Vertices(wire,Vdeb,Vfin);
1854 isline = (!PlaneOfWire(wire,P));
1856 TopoDS_Vertex Vmini;
1857 TopoDS_Wire newwire;
1859 BW.MakeWire(newwire);
1860 Standard_Boolean parcours = Standard_True;
1862 if (isline0 || isline) {
1864 // cas particulier des segments de droite
1865 gp_Pnt P1 = BRep_Tool::Pnt(Vdeb),
1866 P2 = BRep_Tool::Pnt(Vfin);
1867 Standard_Real dist1, dist2;
1868 dist1 = Pdeb.Distance(P1)+Pfin.Distance(P2);
1869 dist2 = Pdeb.Distance(P2)+Pfin.Distance(P1);
1870 parcours = (dist2>=dist1);
1875 gp_Pnt P1 = BRep_Tool::Pnt(Vdeb), P1o = Pdeb,
1876 P2 = BRep_Tool::Pnt(Vfin), P2o = Pfin;
1877 /* // on ramene Pdeb dans le plan courant
1878 gp_Pnt Pnew = Pdeb.Translated (P0.Location(),P.Location());
1879 gp_Ax1 A0 = P0.Axis();
1880 gp_Ax1 A1 = P.Axis();
1882 if (!A0.IsParallel(A1,1.e-4)) {
1883 gp_Vec vec1(A0.Direction()), vec2(A1.Direction()),
1885 gp_Ax1 Norm(P.Location(),norm);
1886 Standard_Real ang = vec1.AngleWithRef(vec2,norm);
1891 if (Abs(ang-PI/2.0)<Precision::Angular()) {
1893 gp_Vec Vtrans(P0.Location(),P.Location()),Vsign;
1894 Standard_Real alpha,beta,sign=1;
1895 Vsign.SetLinearForm(Vtrans.Dot(vec1),vec2,-Vtrans.Dot(vec2),vec1);
1896 alpha = Vsign.Dot(vec1);
1897 beta = Vsign.Dot(vec2);
1898 Standard_Boolean pasnul = (Abs(alpha)>1.e-4 && Abs(beta)>1.e-4);
1899 if ( alpha*beta>0.0 && pasnul ) sign=-1;
1902 Pnew = Pnew.Rotated (Norm,ang);
1904 // choix entre Vdeb et Vfin
1905 Standard_Real dist = Pnew.Distance(P1);
1906 parcours = (dist<Pnew.Distance(P2));
1908 if(P1.IsEqual(P2,Precision::Confusion()) || P1o.IsEqual(P2o,Precision::Confusion())){
1909 BRepAdaptor_Curve Curve0(E0), Curve(E);
1910 Curve0.D0(Curve0.FirstParameter() + Precision::Confusion(), P2o);
1911 Curve.D0(Curve.FirstParameter() + Precision::Confusion(), P2);
1913 gp_Vec VDebFin0(P1o,P2o), VDebFin(P1,P2);
1914 Standard_Real AStraight = VDebFin0.Angle(VDebFin);
1915 parcours = (AStraight < PI/2.0? Standard_True: Standard_False);
1918 // reconstruction du wire
1919 Standard_Integer rang;
1921 for (rang=1;rang<=nbEdges;rang++) {
1922 TopoDS_Shape alocalshape = SeqEdges.Value(rang);
1923 BW.Add(newwire,TopoDS::Edge(alocalshape));
1924 // BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang)));
1928 for (rang=nbEdges;rang>=1;rang--) {
1929 TopoDS_Shape alocalshape = SeqEdges.Value(rang).Reversed();
1930 BW.Add(newwire,TopoDS::Edge(alocalshape));
1931 // BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang).Reversed()));
1935 // orientation du wire
1936 newwire.Oriented(TopAbs_FORWARD);
1937 myWork(i) = newwire;
1939 // on passe au wire suivant
1941 Pdeb = BRep_Tool::Pnt(Vdeb);
1942 Pfin = BRep_Tool::Pnt(Vfin);
1945 Pfin = BRep_Tool::Pnt(Vdeb);
1946 Pdeb = BRep_Tool::Pnt(Vfin);
1954 // sections bouclantes ?
1955 if (vClosed) myWork(myWork.Length()) = myWork(1);