a489c111db56377311531cd1741090dc77bdf40c
[occt.git] / src / BRepFill / BRepFill_CompatibleWires.cxx
1 // File:        BRepFill_CompatibleWires.cxx
2 // Created:     Thu Jul  2 16:47:25 1998
3 // Author:      Joelle CHAUVET
4 //              <jct@sgi64>
5
6
7 #include <BRepFill_CompatibleWires.ixx>
8
9 #include <BRepAdaptor_Curve.hxx>
10
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 <BRepExtrema_DistShapeShape.hxx>
17 #include <Bnd_Box.hxx>
18 #include <BRepBndLib.hxx>
19 #include <BRep_Builder.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepTools_WireExplorer.hxx>
22 #include <BRepLProp.hxx>
23 #include <BRepGProp.hxx>
24 #include <GProp_GProps.hxx>
25 #include <GProp_PrincipalProps.hxx>
26 #include <Geom_Surface.hxx>
27 #include <Geom_Plane.hxx>
28 #include <Precision.hxx>
29 #include <TopAbs.hxx> 
30 #include <TopExp.hxx>
31 #include <TopExp_Explorer.hxx>
32 #include <TopoDS.hxx>
33 #include <TopoDS_Wire.hxx>
34 #include <TopTools_ListIteratorOfListOfShape.hxx>
35 #include <TopTools_DataMapOfShapeListOfShape.hxx>
36 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
37 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
38 #include <TopTools_HSequenceOfShape.hxx>
39 #include <TopTools_SequenceOfShape.hxx>
40 #include <TopTools_ListOfShape.hxx>    
41
42 #include <gp.hxx>
43 #include <gp_Vec.hxx>
44 #include <gp_Ax2.hxx>
45 #include <gp_Pln.hxx>
46 #include <gp_Circ.hxx>
47 #include <gp_Elips.hxx>
48 #include <TColgp_HArray1OfVec.hxx>
49 #include <TColgp_HArray1OfPnt.hxx>
50
51 #include <TColStd_Array1OfInteger.hxx>
52 #include <TColStd_Array1OfReal.hxx>
53 #include <TColStd_SequenceOfReal.hxx>
54
55
56 static void EdgesFromVertex (const TopoDS_Wire&   W,
57                              const TopoDS_Vertex& V, 
58                              TopoDS_Edge& E1, 
59                              TopoDS_Edge& E2)
60 {
61   TopTools_IndexedDataMapOfShapeListOfShape Map;
62   TopExp::MapShapesAndAncestors(W,TopAbs_VERTEX,TopAbs_EDGE,Map);
63
64   const TopTools_ListOfShape& List = Map.FindFromKey(V);
65   TopoDS_Edge          e1   = TopoDS::Edge(List.First());
66   TopoDS_Edge          e2   = TopoDS::Edge(List. Last());
67
68   BRepTools_WireExplorer anExp;
69   Standard_Integer I1=0, I2=0, NE=0;
70
71   for(anExp.Init(W); anExp.More(); anExp.Next()) {
72     NE++;
73     const TopoDS_Edge& ECur = anExp.Current();
74     if (e1.IsSame(ECur)) {
75       I1 = NE;
76     }
77     if (e2.IsSame(ECur)) {
78       I2 = NE;
79     }
80   }
81
82   if (Abs(I2-I1)==1) {
83     // numeros consecutifs
84     if (I2==I1+1) {
85       E1 = e1;
86       E2 = e2;
87     }
88     else {
89       E1 = e2;
90       E2 = e1;
91     }
92   }
93   else {
94     // numeros non consecutifs sur un wire ferme
95     if (I1==1&&I2==NE) {
96       E1 = e2;
97       E2 = e1;
98     }
99     else {
100       E1 = e1;
101       E2 = e2;
102     }
103   }
104 }
105                                       
106
107 static void SeqOfVertices (const TopoDS_Wire&   W,
108                            TopTools_SequenceOfShape& S)
109 {
110   S.Clear();
111   Standard_Integer jj, cpt = 0;
112   TopExp_Explorer PE;
113   for (PE.Init(W,TopAbs_VERTEX); PE.More(); PE.Next()) {
114     cpt++;
115     Standard_Boolean trouve=Standard_False;
116     for (jj=1;jj<=S.Length() && (!trouve);jj++) {
117       if (S.Value(jj).IsSame(PE.Current())) trouve = Standard_True; 
118       }
119       if (!trouve) S.Append(PE.Current());
120     }
121 }
122                                       
123
124 static Standard_Boolean PlaneOfWire (const TopoDS_Wire& W, gp_Pln& P)
125 {
126   Standard_Boolean isplane = Standard_True;
127   BRepLib_FindSurface findPlanarSurf;
128   Handle(Geom_Surface) S;
129   TopLoc_Location      L;
130   
131   GProp_GProps GP;
132   BRepGProp::LinearProperties(W,GP);
133   gp_Pnt Bary = GP.CentreOfMass();
134
135 // blindage pour les cas particuliers : 1 seule edge cercle ou ellipse
136 // sur un wire ferme !
137   Standard_Integer nbEdges = 0;
138   BRepTools_WireExplorer anExp;
139   anExp.Init(W);
140   Standard_Boolean wClosed = W.Closed();
141   if (!wClosed) {
142     // on regarde quand meme si les vertex sont les memes.
143     TopoDS_Vertex V1, V2;
144     TopExp::Vertices(W,V1,V2);
145     if ( V1.IsSame(V2)) wClosed = Standard_True;
146   }
147   TopoDS_Edge Edge = TopoDS::Edge(anExp.Current());
148   Standard_Real first, last;
149   TopLoc_Location loc;
150   Handle(Geom_Curve) curv;
151   curv = BRep_Tool::Curve(Edge, loc, first, last);
152   curv = 
153       Handle(Geom_Curve)::DownCast(curv->Transformed(loc.Transformation()));
154   if (wClosed) {
155     GeomAdaptor_Curve AdC;
156     AdC.Load(curv);
157     for(; anExp.More(); anExp.Next()) {
158       nbEdges ++;
159     }
160     if ( nbEdges==1 && AdC.GetType() == GeomAbs_Circle ) {
161       Bary = AdC.Circle().Location();
162     }
163     if ( nbEdges==1 && AdC.GetType() == GeomAbs_Ellipse ) {
164       Bary = AdC.Ellipse().Location();
165     }
166   }
167
168   findPlanarSurf.Init(W, -1, Standard_True);
169   if ( findPlanarSurf.Found()) {
170     S = findPlanarSurf.Surface();
171     L = findPlanarSurf.Location();
172     if (!L.IsIdentity()) S = Handle(Geom_Surface)::
173       DownCast(S->Transformed(L.Transformation()));
174     P = (Handle(Geom_Plane)::DownCast(S))->Pln();
175     P.SetLocation(Bary);
176   }
177   else {
178     // wire non plan !
179     GProp_PrincipalProps Pp  = GP.PrincipalProperties();
180     gp_Vec Vec;
181     Standard_Real R1, R2, R3,Tol = Precision::Confusion();
182     Pp.RadiusOfGyration(R1,R2,R3);
183     Standard_Real RMax = Max(Max(R1,R2),R3);
184     if ( ( Abs(RMax-R1)<Tol && Abs(RMax-R2)<Tol )
185         || ( Abs(RMax-R1)<Tol && Abs(RMax-R3)<Tol ) 
186         || ( Abs(RMax-R2)<Tol && Abs(RMax-R3)<Tol ) )
187       isplane = Standard_False;
188     else {
189       if (R1>=R2 && R1>=R3) {
190         Vec = Pp.FirstAxisOfInertia();
191       }
192       else if (R2>=R1 && R2>=R3) {
193         Vec = Pp.SecondAxisOfInertia();
194       }
195       else if (R3>=R1 && R3>=R2) {
196         Vec = Pp.ThirdAxisOfInertia();
197       }
198       gp_Dir NDir(Vec);
199       if (R3<=R2 && R3<=R1) {
200         Vec = Pp.ThirdAxisOfInertia();
201       }
202       else if (R2<=R1 && R2<=R3) {
203         Vec = Pp.SecondAxisOfInertia();
204       }
205       else if (R1<=R2 && R1<=R3) {
206         Vec = Pp.FirstAxisOfInertia();
207       }
208       gp_Dir XDir(Vec);
209       gp_Ax3 repere(Bary,NDir,XDir);
210       Geom_Plane GPlan(repere);
211       P = GPlan.Pln();
212     }
213   }
214
215   return isplane;
216
217 }
218                                       
219
220 static void WireContinuity (const TopoDS_Wire& W,
221                             GeomAbs_Shape& contW)
222 {
223   contW = GeomAbs_CN;
224   GeomAbs_Shape cont;
225   Standard_Boolean IsDegenerated = Standard_False;
226
227   BRepTools_WireExplorer anExp;
228   Standard_Integer nbEdges=0;
229   Handle(TopTools_HSequenceOfShape) Edges = new TopTools_HSequenceOfShape();
230   for(anExp.Init(W); anExp.More(); anExp.Next()) {
231     nbEdges++;
232     Edges->Append(anExp.Current());
233     if (BRep_Tool::Degenerated(anExp.Current())) IsDegenerated = Standard_True;
234   }
235   
236   if (!IsDegenerated) {
237
238     Standard_Boolean testconti = Standard_True;
239
240     for (Standard_Integer j=1;j<=nbEdges;j++) {
241       
242       TopoDS_Edge Edge1, Edge2;
243       
244       if (j == nbEdges) {
245         Edge1 = TopoDS::Edge (Edges->Value(nbEdges));
246         Edge2 = TopoDS::Edge (Edges->Value(1));
247       }
248       else {
249         Edge1 = TopoDS::Edge (Edges->Value(j));
250         Edge2 = TopoDS::Edge (Edges->Value(j+1));
251       } 
252       
253       TopoDS_Vertex V1,V2,Vbid;
254       TopExp::Vertices(Edge1,Vbid,V1,Standard_True);
255       TopExp::Vertices(Edge2,V2,Vbid,Standard_True);
256       Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1);
257       Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2);
258       BRepAdaptor_Curve Curve1(Edge1);
259       BRepAdaptor_Curve Curve2(Edge2);
260       Standard_Real Eps = BRep_Tool::Tolerance(V2) + BRep_Tool::Tolerance(V1);
261       
262       if(j == nbEdges) 
263         testconti = Curve1.Value(U1).IsEqual(Curve2.Value(U2), Eps);
264       
265       if(testconti) {
266         cont = BRepLProp::Continuity(Curve1,Curve2,U1,U2,
267                                      Eps, Precision::Angular()); 
268         if (cont <= contW) contW = cont;
269       }
270     }
271   }
272   
273 }
274
275 static void TrimEdge (const TopoDS_Edge&              CurrentEdge,
276                       const TColStd_SequenceOfReal&   CutValues,
277                       const Standard_Real   t0, const Standard_Real   t1,
278                       const Standard_Boolean          SeqOrder,
279                       TopTools_SequenceOfShape& S)
280
281 {
282   S.Clear();
283   Standard_Integer j, ndec=CutValues.Length();
284   Standard_Real first,last,m0,m1;
285   Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
286
287   TopoDS_Vertex Vf,Vl,Vbid,V0,V1;
288   TopAbs_Orientation CurrentOrient = CurrentEdge.Orientation();
289   TopExp::Vertices(CurrentEdge,Vf,Vl);
290   Vbid.Nullify();
291
292   if (SeqOrder) {
293     // de first vers last
294     m0 = first;
295     V0 = Vf;
296     for (j=1; j<=ndec; j++) {
297       // morceau d'edge  
298       m1 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
299       TopoDS_Edge CutE = BRepLib_MakeEdge(C,V0,Vbid,m0,m1);
300       CutE.Orientation(CurrentOrient);
301       S.Append(CutE);
302       m0 = m1;
303       V0 = TopExp::LastVertex(CutE);
304       if (j==ndec) {
305         // dernier morceau
306         TopoDS_Edge LastE = BRepLib_MakeEdge(C,V0,Vl,m0,last);
307         LastE.Orientation(CurrentOrient);
308         S.Append(LastE);
309       }
310     }
311   }
312   else {
313     // de last vers first
314     m1 = last;
315     V1 = Vl;
316     for (j=ndec; j>=1; j--) {
317       // morceau d'edge  
318       m0 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
319       TopoDS_Edge CutE = BRepLib_MakeEdge(C,Vbid,V1,m0,m1);
320       CutE.Orientation(CurrentOrient);
321       S.Append(CutE);
322       m1 = m0;
323       V1 = TopExp::FirstVertex(CutE);
324       if (j==1) {
325         // dernier morceau
326         TopoDS_Edge LastE = BRepLib_MakeEdge(C,Vf,V1,first,m1);
327         LastE.Orientation(CurrentOrient);
328         S.Append(LastE);
329       }
330     }
331   }
332 }
333
334
335
336 static Standard_Boolean SearchRoot (const TopoDS_Vertex& V,
337                                     const TopTools_DataMapOfShapeListOfShape& Map,
338                                     TopoDS_Vertex& VRoot)
339 {
340   Standard_Boolean trouve = Standard_False;
341   VRoot.Nullify();
342   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape it;
343   for (it.Initialize(Map); it.More(); it.Next()) {
344     const TopTools_ListOfShape & List = it.Value();
345     TopTools_ListIteratorOfListOfShape itL;
346     Standard_Boolean ilyest = Standard_False;
347     for (itL.Initialize(List); itL.More(); itL.Next()) {
348       TopoDS_Vertex Vcur = TopoDS::Vertex(itL.Value());
349       if (Vcur.IsSame(V)) {
350         ilyest = Standard_True;
351       }
352       if (ilyest) break;
353     }
354     if (ilyest) {
355       trouve = Standard_True;
356       VRoot = TopoDS::Vertex(it.Key());
357     }
358     if (trouve) break;
359   }
360   return trouve;
361 }
362
363 static Standard_Boolean SearchVertex (const TopTools_ListOfShape& List,
364                                       const TopoDS_Wire&   W,
365                                       TopoDS_Vertex& VonW)
366 {
367   Standard_Boolean trouve = Standard_False;
368   VonW.Nullify();
369   TopTools_SequenceOfShape SeqV;
370   SeqOfVertices(W,SeqV);
371   for (Standard_Integer ii=1;ii<=SeqV.Length();ii++) {
372     TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
373     TopTools_ListIteratorOfListOfShape itL;
374     Standard_Boolean ilyest = Standard_False;
375     for (itL.Initialize(List); itL.More(); itL.Next()) {
376       TopoDS_Vertex Vcur = TopoDS::Vertex(itL.Value());
377       if (Vcur.IsSame(Vi)) {
378         ilyest = Standard_True;
379       }
380       if (ilyest) break;
381     }
382     if (ilyest) {
383       trouve = Standard_True;
384       VonW = Vi;
385     }
386     if (trouve) break;
387   }
388   return trouve;
389 }
390
391
392 static Standard_Boolean EdgeIntersectOnWire (const gp_Pnt& P1,
393                                              const gp_Pnt& P2,
394                                              Standard_Real percent,
395                                              const TopTools_DataMapOfShapeListOfShape& Map,
396                                              const TopoDS_Wire&   W,
397                                              TopoDS_Vertex& Vsol,
398                                              TopoDS_Wire&   newW)
399 {
400
401   BRepTools_WireExplorer anExp;
402
403   // construction de l'edge d'intersection
404   Standard_Boolean NewVertex = Standard_False;
405   gp_Lin droite(P1,gp_Dir(gp_Vec(P1,P2)));
406   // ATTENTION : en toute rigueur, il faudrait construire une demi-droite
407   //             mais il y a un bug dans BRepExtrema_DistShapeShape
408   //             on se contente de 100 * la distance entre P1 et P2
409   //             en esperant que ce soit suffisant jusqu'a ce que le bug
410   //             soit corrige
411   //  Standard_Real dernierparam = Precision::Infinite();
412   // ATTENTION : le retour !!
413   //             100 c'est mieux que 10 mais quelquefois c'est trop !
414   //             finalement, rien ne vaut une bonne boite d'encombrement
415   //  Standard_Real dernierparam = 100 * P1.Distance(P2);
416   Bnd_Box B;
417   BRepBndLib::Add(W,B);
418   Standard_Real x1,x2,y1,y2,z1,z2;
419   B.Get(x1,y1,z1,x2,y2,z2);
420   gp_Pnt BP1(x1,y1,z1), BP2(x2,y2,z2);
421   Standard_Real diag = BP1.Distance(BP2);
422   Standard_Real dernierparam = diag;
423   BRepLib_MakeEdge ME(droite,0.,dernierparam);
424   TopoDS_Edge ECur = BRepLib_MakeEdge(droite,0.,P1.Distance(P2));
425
426   // calcul de l'intersection par BRepExtrema (point de distance mini)
427   BRepExtrema_DistShapeShape DSS(ME.Edge(),W);
428   if (DSS.IsDone()) {
429     // on choisit la solution la plus proche de P2
430     Standard_Integer isol = 1;
431     Standard_Real dss = P2.Distance(DSS.PointOnShape2(isol));
432     for (Standard_Integer iss=2; iss<=DSS.NbSolution(); iss++) {
433       if (dss>P2.Distance(DSS.PointOnShape2(iss))) {
434         dss = P2.Distance(DSS.PointOnShape2(iss));
435         isol = iss;
436       }
437     }
438 #ifdef DEB
439     gp_Pnt Psol = 
440 #endif
441       DSS.PointOnShape2(isol);
442     // la solution est-elle un nouveau vertex ?
443     NewVertex = (DSS.SupportTypeShape2(isol) != BRepExtrema_IsVertex);
444     if (NewVertex) {
445       TopoDS_Shape aLocalShape = DSS.SupportOnShape2(isol);
446       TopoDS_Edge E = TopoDS::Edge(aLocalShape);
447 //      TopoDS_Edge E = TopoDS::Edge(DSS.SupportOnShape2(isol));
448       Standard_Real tol = Precision::PConfusion();
449       Standard_Real first,last,param;
450       BRep_Tool::Range(E,first,last);
451       tol = Max(tol,percent*Abs(last-first));
452       DSS.ParOnEdgeS2(isol,param);
453       if (Abs(first-param)<tol) {
454         NewVertex = Standard_False;
455         Vsol = TopExp::FirstVertex(E);
456       }
457       else if (Abs(last-param)<tol) {
458         NewVertex = Standard_False;
459         Vsol = TopExp::LastVertex(E);
460       }
461       // verif
462       if (!NewVertex) {
463         TopoDS_Vertex VRoot;
464         if (SearchRoot(Vsol,Map,VRoot)) NewVertex = Standard_True;
465       }
466     }
467     else {
468       TopoDS_Shape aLocalShape = DSS.SupportOnShape2(isol);
469       Vsol = TopoDS::Vertex(aLocalShape);
470 //      Vsol = TopoDS::Vertex(DSS.SupportOnShape2(isol));
471     }
472
473     // il faut decouper l'edge
474     if (NewVertex) {
475       TopoDS_Shape aLocalShape = DSS.SupportOnShape2(isol);
476       TopoDS_Edge E = TopoDS::Edge(aLocalShape);
477 //      TopoDS_Edge E = TopoDS::Edge(DSS.SupportOnShape2(isol));
478 #ifdef DEB
479       Standard_Real tol = 
480 #endif
481         Precision::PConfusion();
482       Standard_Real first,last,param;
483       DSS.ParOnEdgeS2(isol,param);
484       BRep_Tool::Range(E,first,last);
485       BRepLib_MakeWire MW;
486       for (anExp.Init(W); anExp.More(); anExp.Next()) {
487         if (E.IsSame(anExp.Current())) {
488           Standard_Boolean SO 
489             = (anExp.CurrentVertex().IsSame(TopExp::FirstVertex(E)));
490           TopTools_SequenceOfShape SE;
491           SE.Clear();
492           TColStd_SequenceOfReal SR;
493           SR.Clear();
494           SR.Append(param);
495           TrimEdge(E,SR,first,last,SO,SE);
496           TopoDS_Vertex VV1,VV2;
497           TopExp::Vertices(TopoDS::Edge(SE.Value(1)),VV1,VV2);
498           if (TopExp::FirstVertex(E).IsSame(VV1)
499               || TopExp::LastVertex(E).IsSame(VV1)) {
500             Vsol = VV2;
501           }
502           if (TopExp::FirstVertex(E).IsSame(VV2)
503               || TopExp::LastVertex(E).IsSame(VV2)) {
504             Vsol = VV1;
505           }
506           for (Standard_Integer k=1; k<=SE.Length(); k++) {
507             MW.Add(TopoDS::Edge(SE.Value(k)));
508           }
509         }
510         else {
511           MW.Add(anExp.Current());
512         }
513       }
514       newW = MW.Wire();
515     }
516     else {
517       newW = W;
518     }
519     
520     
521   }
522
523   return NewVertex;
524
525 }
526
527
528 static void Transform (const Standard_Boolean WithRotation,
529                        const gp_Pnt& P,
530                        const gp_Pnt& Pos1,
531                        const gp_Vec& Ax1,
532                        const gp_Pnt& Pos2,
533                        const gp_Vec& Ax2,
534                        gp_Pnt& Pnew)
535 {
536
537   Pnew = P.Translated (Pos1,Pos2);
538   gp_Vec axe1 = Ax1, axe2 = Ax2; 
539   if (!axe1.IsParallel(axe2,1.e-4)) {
540     gp_Vec Vtrans(Pos1,Pos2),Vsign;
541     Standard_Real alpha,beta,sign=1;
542     alpha = Vtrans.Dot(axe1);
543     beta = Vtrans.Dot(axe2);
544     if (alpha<-1.e-7) axe1 *=-1;
545     if (beta<1.e-7) axe2 *=-1;
546     alpha = Vtrans.Dot(axe1);
547     beta = Vtrans.Dot(axe2);
548     gp_Vec norm2 = axe1 ^ axe2;
549     Vsign.SetLinearForm(Vtrans.Dot(axe1),axe2,-Vtrans.Dot(axe2),axe1);
550     alpha = Vsign.Dot(axe1);
551     beta = Vsign.Dot(axe2);
552     Standard_Boolean pasnul = (Abs(alpha)>1.e-4 && Abs(beta)>1.e-4);
553     if ( alpha*beta>0.0 && pasnul ) sign=-1;
554     gp_Ax1 Norm(Pos2,norm2);
555     Standard_Real ang = axe1.AngleWithRef(axe2,norm2);
556     if (!WithRotation) {
557       if (ang>PI/2) ang = ang - PI;
558       if (ang<-PI/2) ang = ang + PI;
559     }
560     ang *= sign;
561     Pnew = Pnew.Rotated (Norm,ang);
562   }
563 }
564
565 static void BuildConnectedEdges(const TopoDS_Wire& aWire,
566                                 const TopoDS_Edge& StartEdge,
567                                 const TopoDS_Vertex& StartVertex,
568                                 TopTools_ListOfShape& ConnectedEdges)
569 {
570   TopTools_IndexedDataMapOfShapeListOfShape MapVE;
571   TopExp::MapShapesAndAncestors(aWire, TopAbs_VERTEX, TopAbs_EDGE, MapVE);
572   TopoDS_Edge CurEdge = StartEdge;
573   TopoDS_Vertex CurVertex = StartVertex;
574   TopoDS_Vertex Origin, V1, V2;
575   TopExp::Vertices(StartEdge, V1, V2);
576   Origin = (V1.IsSame(StartVertex))? V2 : V1;
577
578   for (;;)
579     {
580       TopTools_ListIteratorOfListOfShape itE( MapVE.FindFromKey(CurVertex) );
581       for (; itE.More(); itE.Next())
582         {
583           TopoDS_Edge anEdge = TopoDS::Edge(itE.Value());
584           if (!anEdge.IsSame(CurEdge))
585             {
586               ConnectedEdges.Append(anEdge);
587               TopExp::Vertices(anEdge, V1, V2);
588               CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
589               CurEdge = anEdge;
590               break;
591             }
592         }
593       if (CurVertex.IsSame(Origin))
594         break;
595     }
596 }
597                                       
598 //=======================================================================
599 //function : BRepFill_CompatibleWires
600 //purpose  : 
601 //=======================================================================
602
603 BRepFill_CompatibleWires::BRepFill_CompatibleWires() 
604 :myIsDone(Standard_False)
605 {
606 }
607
608
609 //=======================================================================
610 //function : BRepFill_CompatibleWires
611 //purpose  : 
612 //=======================================================================
613
614 BRepFill_CompatibleWires::BRepFill_CompatibleWires(const TopTools_SequenceOfShape& Sections)
615 {
616   Init(Sections);
617 }
618
619
620 //=======================================================================
621 //function : Init
622 //purpose  : 
623 //=======================================================================
624
625 void BRepFill_CompatibleWires::Init(const TopTools_SequenceOfShape& Sections)
626 {
627   myInit = Sections;
628   myWork = Sections;
629   myPercent = 0.01;
630   myIsDone = Standard_False;
631   myMap.Clear();
632
633 }
634
635
636 //=======================================================================
637 //function : SetPercent
638 //purpose  : 
639 //=======================================================================
640
641 void BRepFill_CompatibleWires::SetPercent(const Standard_Real Percent)
642 {
643   if (0.<Percent && Percent<1.) myPercent = Percent;
644
645 }
646
647
648 //=======================================================================
649 //function : IsDone
650 //purpose  : 
651 //=======================================================================
652
653 Standard_Boolean BRepFill_CompatibleWires::IsDone() const 
654 {
655   return myIsDone;
656 }
657
658
659 //=======================================================================
660 //function : Shape
661 //purpose  : 
662 //=======================================================================
663
664 const TopTools_SequenceOfShape& BRepFill_CompatibleWires::Shape() const 
665 {
666   return myWork;
667 }
668
669
670 //=======================================================================
671 //function : GeneratedShapes
672 //purpose  : 
673 //=======================================================================
674
675 const TopTools_ListOfShape& BRepFill_CompatibleWires::GeneratedShapes
676 (const TopoDS_Edge& SubSection) const
677 {  
678
679   if (myMap.IsBound(SubSection)) {
680     return myMap(SubSection);
681   }
682   else {
683     static TopTools_ListOfShape Empty;
684     return Empty;
685   }
686 }
687
688
689 //=======================================================================
690 //function : Perform
691 //purpose  : 
692 //=======================================================================
693
694 void BRepFill_CompatibleWires::Perform (const Standard_Boolean WithRotation)
695 {
696   // compute origin and orientation on wires to avoid twisted results
697   // and update wires to have same number of edges
698
699   // determination de report:
700   // si le nombre d'elements est identique  et si les wires ont des discontinuites
701   // en tangence, on n'effectue pas le report par abscisse curviligne, ni
702   Standard_Integer nbSects = myWork.Length(), i;
703   BRepTools_WireExplorer anExp;
704   Standard_Integer nbmax=0, nbmin=0;
705   TColStd_Array1OfInteger nbEdges(1,nbSects);
706   Standard_Boolean report;
707   GeomAbs_Shape contS=GeomAbs_CN;
708   GeomAbs_Shape cont;
709   for (i=1; i<=nbSects; i++) {
710     TopoDS_Shape aLocalShape = myWork(i).Oriented(TopAbs_FORWARD);
711     myWork(i) = TopoDS::Wire(aLocalShape);
712 //    myWork(i) = TopoDS::Wire(myWork(i).Oriented(TopAbs_FORWARD));
713     TopoDS_Wire W = TopoDS::Wire(myWork(i));
714     WireContinuity(W,cont);
715     if (cont<contS) contS=cont;
716     nbEdges(i) = 0;
717     for(anExp.Init(W); anExp.More(); anExp.Next() ) nbEdges(i)++;
718     if (i==1) nbmin = nbEdges(i);
719     if (nbmax<nbEdges(i)) nbmax = nbEdges(i);
720     if (nbmin>nbEdges(i)) nbmin = nbEdges(i);
721   } 
722   // si on n'a pas le meme nombre d'elements ou si tous les wires sont au moins
723   // C1, on effectue le report par abscisse curviligne des decoupes sinon, on se
724   // fait un report vertex / Vertex
725   report = (nbmax != nbmin || contS >= GeomAbs_C1 );
726   
727   // initialisation de la map
728   Standard_Integer nbE = 0;
729   TopTools_ListOfShape Empty;
730   for (i=1; i<=nbSects; i++) {
731     TopoDS_Wire W = TopoDS::Wire(myWork(i));
732     for(anExp.Init(W); anExp.More(); anExp.Next() ) {
733       TopoDS_Edge E = TopoDS::Edge(anExp.Current());
734       myMap.Bind(E,Empty);
735       myMap(E).Append(E);
736       nbE++;
737     }
738   } 
739   
740   // sections ouvertes / sections fermees
741   // initialisation de myDegen1, myDegen2
742   Standard_Integer ideb=1, ifin=myWork.Length();
743   // on regarde si le premier wire est ponctuel
744   myDegen1 = Standard_True;
745   for(anExp.Init(TopoDS::Wire(myWork(ideb))); anExp.More(); anExp.Next()) {
746     myDegen1 = myDegen1 && (BRep_Tool::Degenerated(anExp.Current()));
747   }
748   if (myDegen1) ideb++;
749   // on regarde si le dernier wire est ponctuel
750   myDegen2 = Standard_True;
751   for(anExp.Init(TopoDS::Wire(myWork(ifin))); anExp.More(); anExp.Next()) {
752     myDegen2 = myDegen2 && (BRep_Tool::Degenerated(anExp.Current()));
753   }
754   if (myDegen2) ifin--;
755   
756   Standard_Boolean wClosed, allClosed = Standard_True, allOpen = Standard_True;
757   for (i=ideb; i<=ifin; i++) {
758     wClosed = myWork(i).Closed();
759     if (!wClosed) {
760       // on regarde quand meme si les vertex sont les memes.
761       TopoDS_Vertex V1, V2;
762       TopExp::Vertices(TopoDS::Wire(myWork(i)),V1,V2);
763       if ( V1.IsSame(V2)) wClosed = Standard_True;
764     }
765     allClosed = (allClosed && wClosed);
766     allOpen = (allOpen && !wClosed);
767   }
768   
769   if (allClosed) {
770     // Toutes les sections sont fermees 
771     if (report) {
772       // same number of elements  
773       SameNumberByPolarMethod(WithRotation);
774     }
775     else {
776       // origine
777       ComputeOrigin(Standard_False);
778     }
779     myIsDone = Standard_True;
780   }
781   else if (allOpen) {
782     // Toutes les sections sont ouvertes
783     // origine
784     SearchOrigin();
785     // same number of elements
786     if (report) {
787       SameNumberByACR(report);
788     }
789     myIsDone = Standard_True;
790   }
791   else {
792     // Il y a des sections ouvertes et des sections fermees :
793     // on ne traite pas
794     Standard_DomainError::Raise("Sections must be all closed or all open");
795   }
796   
797 }
798
799
800
801
802 //=======================================================================
803 //function : Generated
804 //purpose  : 
805 //=======================================================================
806
807 const TopTools_DataMapOfShapeListOfShape&  BRepFill_CompatibleWires::Generated() const 
808 {
809   return myMap;
810 }
811
812
813 //=======================================================================
814 //function : SameNumberByPolarMethod
815 //purpose  : 
816 //=======================================================================
817
818 void BRepFill_CompatibleWires::
819               SameNumberByPolarMethod(const Standard_Boolean WithRotation)
820 {
821
822   // initialisation 
823   Standard_Integer NbSects=myWork.Length();
824   BRepTools_WireExplorer anExp;
825   TopoDS_Vertex V1, V2;
826   
827   Standard_Boolean allClosed = Standard_True;
828   Standard_Integer i,ii,ideb=1,ifin=NbSects;
829   for (i=1; i<=NbSects; i++) {
830     allClosed = (allClosed && myWork(i).Closed());
831   }
832   if (!allClosed)
833     Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SameNumberByPolarMethod : the wires must be closed");
834   
835   // Nombre max de decoupes possibles
836   Standard_Integer NbMaxV = 0;
837   for (i=1; i<=NbSects; i++) {
838     for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
839       NbMaxV++;
840     }
841   }
842   
843   // sections ponctuelles, sections bouclantes ?
844   if (myDegen1) ideb++;
845   if (myDegen2) ifin--;
846   Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
847                                 && (myWork(ideb).IsSame(myWork(ifin)));
848   
849   // construction des tableaux de plans des wires 
850   gp_Pln P;
851   Handle(TColgp_HArray1OfPnt) Pos
852     = new (TColgp_HArray1OfPnt) (1,NbSects);
853   Handle(TColgp_HArray1OfVec) Axe
854     = new (TColgp_HArray1OfVec) (1,NbSects);
855   for (i=ideb;i<=ifin;i++) {
856     if (PlaneOfWire(TopoDS::Wire(myWork(i)),P)) {
857       Pos->SetValue(i,P.Location());
858       Axe->SetValue(i,gp_Vec(P.Axis().Direction()));
859     }
860   }
861   TopTools_SequenceOfShape SeqV;
862   if (myDegen1) {
863     SeqOfVertices(TopoDS::Wire(myWork(1)),SeqV);
864     Pos->SetValue(1,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
865     Axe->SetValue(1,Axe->Value(ideb));
866   }
867   if (myDegen2) {
868     SeqOfVertices(TopoDS::Wire(myWork(NbSects)),SeqV);
869     Pos->SetValue(NbSects,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
870     Axe->SetValue(NbSects,Axe->Value(ifin));
871   }
872   
873   // construction de RMap, map des reports du wire i vers le wire i-1
874   TopTools_DataMapOfShapeListOfShape RMap;
875   RMap.Clear();
876   
877   // boucle sur i
878   for (i=ifin; i>ideb; i--) {
879     
880     const TopoDS_Wire& wire1 = TopoDS::Wire(myWork(i));
881     
882     // sequence des vertex du premier wire
883     SeqOfVertices(wire1,SeqV);
884     if (SeqV.Length()>NbMaxV) 
885       Standard_NoSuchObject::Raise("BRepFill::SameNumberByPolarMethod failed");
886     
887     // extremite du premier wire
888     V1 = TopoDS::Vertex(SeqV.Value(1)); 
889     // wire precedent
890 #ifdef DEB
891     const TopoDS_Wire& wire2 = 
892 #endif
893       TopoDS::Wire(myWork(i-1));
894     // boucle sur les vertex de wire1
895     for (ii=1;ii<=SeqV.Length();ii++) {
896       
897       TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
898       
899       // init de RMap pour Vi
900       TopTools_ListOfShape Init;
901       Init.Clear();
902       RMap.Bind(Vi,Init);
903       
904       // il faut chercher l'intersection Vi - wire2
905       gp_Pnt Pi = BRep_Tool::Pnt(Vi);
906       
907       // on ramene Pi dans le plan courant
908       gp_Pnt Pnew;
909       Transform(WithRotation,Pi,
910                 Pos->Value(i),Axe->Value(i), 
911                 Pos->Value(i-1),Axe->Value(i-1),Pnew);
912       
913       // calcul de l'intersection
914       TopoDS_Shape Support;
915       Standard_Boolean NewVertex;
916       TopoDS_Vertex Vsol;
917       TopoDS_Wire newwire;
918       if (Pnew.Distance(Pos->Value(i-1))>Precision::Confusion()) {
919         Standard_Real percent = myPercent;
920         NewVertex = EdgeIntersectOnWire(Pos->Value(i-1),Pnew,percent,
921                                     RMap,TopoDS::Wire(myWork(i-1)),
922                                     Vsol,newwire);
923         if (NewVertex) myWork(i-1) = newwire;
924         RMap(Vi).Append(Vsol);
925       }
926       
927     } // boucle sur ii
928   }   // boucle sur i
929   
930   // initialisation de MapVLV, map des correspondances vertex - liste de vertex
931   TopTools_DataMapOfShapeListOfShape MapVLV;
932   SeqOfVertices(TopoDS::Wire(myWork(ideb)),SeqV);
933   Standard_Integer SizeMap = SeqV.Length();
934   MapVLV.Clear();
935   for (ii=1;ii<=SizeMap;ii++) {
936     TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
937     TopTools_ListOfShape Init;
938     Init.Clear();
939     Init.Append(Vi);
940     MapVLV.Bind(Vi,Init);
941     Standard_Integer NbV = 1;
942     TopoDS_Vertex V0,V1;
943     V0 = Vi;
944     Standard_Boolean tantque = SearchRoot(V0,RMap,V1);
945     while (tantque) {
946       MapVLV(Vi).Append(V1);
947       NbV++;
948       // test sur NbV necessaire pour les sections bouclantes
949       if (V1.IsSame(Vi) || NbV >= myWork.Length()) {
950         tantque = Standard_False;
951       }
952       else {
953         V0 = V1;
954         tantque = SearchRoot(V0,RMap,V1);
955       }
956     }
957   }
958   
959   // boucle sur i
960   for (i=ideb; i<ifin; i++) {
961     
962     const TopoDS_Wire& wire1 = TopoDS::Wire(myWork(i));
963     
964     // sequence des vertex du premier wire
965     SeqOfVertices(wire1,SeqV);
966     if ( SeqV.Length()>NbMaxV || SeqV.Length()>SizeMap ) 
967       Standard_NoSuchObject::Raise("BRepFill::SameNumberByPolarMethod failed");
968     
969     // extremite du premier wire
970     V1 = TopoDS::Vertex(SeqV.Value(1));
971
972     // wire suivant
973     const TopoDS_Wire& wire2 = TopoDS::Wire(myWork(i+1));
974     
975     // boucle sur les vertex de wire1
976     for (ii=1;ii<=SeqV.Length();ii++) {
977       
978       TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
979       TopoDS_Vertex VRoot;
980       VRoot.Nullify();
981       Standard_Boolean intersect = Standard_True;
982       if (SearchRoot(Vi,MapVLV,VRoot)) {
983         const TopTools_ListOfShape& LVi = MapVLV(VRoot);
984         TopoDS_Vertex VonW;
985         VonW.Nullify();
986         intersect = (!SearchVertex(LVi,wire2,VonW));
987       }
988       
989       if (intersect) {
990         // il faut chercher l'intersection Vi - wire2
991         gp_Pnt Pi = BRep_Tool::Pnt(Vi);
992         
993         // on ramene Pi dans le plan courant
994         gp_Pnt Pnew;
995         Transform(WithRotation,Pi,
996                   Pos->Value(i),Axe->Value(i), 
997                   Pos->Value(i+1),Axe->Value(i+1),Pnew);
998         
999         // calcul de l'intersection
1000         TopoDS_Shape Support;
1001         Standard_Boolean NewVertex;
1002         TopoDS_Vertex Vsol;
1003         TopoDS_Wire newwire;
1004         if (Pnew.Distance(Pos->Value(i+1))>Precision::Confusion()) {
1005           Standard_Real percent = myPercent;
1006           NewVertex = EdgeIntersectOnWire(Pos->Value(i+1),Pnew,percent,
1007                                       MapVLV,TopoDS::Wire(myWork(i+1)),
1008                                       Vsol,newwire);
1009           MapVLV(VRoot).Append(Vsol);
1010           if (NewVertex) myWork(i+1) = newwire;
1011         }
1012         
1013       }
1014     } // boucle sur ii
1015   }   // boucle sur i
1016   
1017   // mise en ordre des wires en suivant MapVLV
1018   TopoDS_Wire wire = TopoDS::Wire(myWork(ideb));
1019
1020   // sauf le dernier si les sections sont bouclantes
1021   Standard_Integer ibout = ifin;
1022   if (vClosed) ibout--;
1023
1024   for ( i=ideb+1; i<=ibout; i++) {
1025
1026     BRepLib_MakeWire MW;
1027
1028     anExp.Init(wire);
1029     TopoDS_Edge ECur = anExp.Current();
1030     TopoDS_Vertex VF,VL;
1031     TopExp::Vertices(ECur,VF,VL,Standard_True);
1032     Standard_Real U1 = BRep_Tool::Parameter(VF,ECur);
1033     Standard_Real U2 = BRep_Tool::Parameter(VL,ECur);
1034     BRepAdaptor_Curve Curve(ECur);
1035     gp_Pnt PPs = Curve.Value(0.1*(U1+9*U2));
1036     TopTools_ListIteratorOfListOfShape itF(MapVLV(VF)),itL(MapVLV(VL));
1037     Standard_Integer rang = ideb;
1038     while (rang < i) {
1039       itF.Next();
1040       itL.Next();
1041       rang++;
1042     }
1043     TopoDS_Vertex V1 = TopoDS::Vertex(itF.Value()), V2 = TopoDS::Vertex(itL.Value());
1044     TopoDS_Edge Esol;
1045     Standard_Real scalmax=0.;
1046     TopoDS_Iterator itW( myWork(i) );
1047     
1048     for(; itW.More(); itW.Next())
1049       {
1050         TopoDS_Edge E = TopoDS::Edge(itW.Value());
1051         TopoDS_Vertex VVF,VVL;
1052         TopExp::Vertices(E,VVF,VVL,Standard_True);
1053         
1054         // tri des edges candidates
1055         Standard_Real scal1,scal2;
1056         if ( (V1.IsSame(VVF)&&V2.IsSame(VVL)) || (V2.IsSame(VVF)&&V1.IsSame(VVL)) ) {
1057           Standard_Real U1 = BRep_Tool::Parameter(VVF,E);
1058           Standard_Real U2 = BRep_Tool::Parameter(VVL,E);
1059           BRepAdaptor_Curve Curve(E);
1060           gp_Pnt PP1 = Curve.Value(0.1*(U1+9*U2));
1061           gp_Pnt PP2 = Curve.Value(0.1*(9*U1+U2));
1062   
1063           for (rang=i;rang>ideb;rang--) {
1064             Transform(WithRotation, PP1,
1065                       Pos->Value(rang), Axe->Value(rang),
1066                       Pos->Value(rang-1), Axe->Value(rang-1), PP1);
1067             Transform(WithRotation, PP2,
1068                       Pos->Value(rang), Axe->Value(rang),
1069                       Pos->Value(rang-1), Axe->Value(rang-1), PP2);
1070           }
1071           gp_Vec Ns(Pos->Value(ideb),PPs);
1072           Ns = Ns.Normalized();
1073           gp_Vec N1(Pos->Value(ideb),PP1);
1074           N1 = N1.Normalized();
1075           gp_Vec N2(Pos->Value(ideb),PP2);
1076           N2 = N2.Normalized();
1077           scal1 = N1.Dot(Ns);
1078           if (scal1>scalmax) {
1079             scalmax = scal1;
1080             Esol = E;
1081           }
1082           scal2 = N2.Dot(Ns);
1083           if (scal2>scalmax) {
1084             scalmax = scal2;
1085             TopoDS_Shape aLocalShape = E.Reversed();
1086             Esol = TopoDS::Edge(aLocalShape);
1087           }
1088         }
1089       } //end of for(; itW.More(); itW.Next())
1090     MW.Add(Esol);
1091
1092     TopTools_ListOfShape ConnectedEdges;
1093     BuildConnectedEdges( TopoDS::Wire(myWork(i)), Esol, V2, ConnectedEdges );
1094
1095     TopTools_ListIteratorOfListOfShape itCE(ConnectedEdges);
1096     for(; anExp.More(), itCE.More(); anExp.Next(), itCE.Next())
1097       {
1098         ECur = anExp.Current();
1099         TopExp::Vertices(ECur,VF,VL,Standard_True);
1100         U1 = BRep_Tool::Parameter(VF,ECur);
1101         U2 = BRep_Tool::Parameter(VL,ECur);
1102         Curve.Initialize(ECur);
1103         PPs = Curve.Value(0.1*(U1+9*U2));
1104         
1105         TopoDS_Edge E = TopoDS::Edge(itCE.Value());
1106         TopoDS_Vertex VVF,VVL;
1107         TopExp::Vertices(E,VVF,VVL,Standard_True);
1108
1109         // tri des edges candidates
1110         Standard_Real scal1,scal2;
1111         U1 = BRep_Tool::Parameter(VVF,E);
1112         U2 = BRep_Tool::Parameter(VVL,E);
1113         Curve.Initialize(E);
1114         gp_Pnt PP1 = Curve.Value(0.1*(U1+9*U2));
1115         gp_Pnt PP2 = Curve.Value(0.1*(9*U1+U2));
1116         
1117         for (rang=i;rang>ideb;rang--) {
1118           Transform(WithRotation, PP1,
1119                     Pos->Value(rang), Axe->Value(rang),
1120                     Pos->Value(rang-1), Axe->Value(rang-1), PP1);
1121           Transform(WithRotation, PP2,
1122                     Pos->Value(rang), Axe->Value(rang),
1123                     Pos->Value(rang-1), Axe->Value(rang-1), PP2);
1124         }
1125         gp_Vec Ns(Pos->Value(ideb),PPs);
1126         Ns = Ns.Normalized();
1127         gp_Vec N1(Pos->Value(ideb),PP1);
1128         N1 = N1.Normalized();
1129         gp_Vec N2(Pos->Value(ideb),PP2);
1130         N2 = N2.Normalized();
1131         scal1 = N1.Dot(Ns);
1132         scal2 = N2.Dot(Ns);
1133         if (scal2>scal1)
1134           E.Reverse();
1135         MW.Add(E);
1136       }
1137     myWork(i) = MW.Wire();
1138   }
1139   
1140   // sections bouclantes ?
1141   if (vClosed) myWork(myWork.Length()) = myWork(1);
1142
1143   // verification du nombre d'edges pour debug
1144   Standard_Integer nbmax=0, nbmin=0;
1145   for ( i=ideb; i<=ifin; i++) {
1146     Standard_Integer nbEdges=0;
1147     for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1148       nbEdges++;
1149     }
1150     if (i==ideb) nbmin = nbEdges;
1151     if (nbmax<nbEdges) nbmax = nbEdges;
1152     if (nbmin>nbEdges) nbmin = nbEdges;
1153   }
1154   if (nbmin!=nbmax) {
1155     Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SameNumberByPolarMethod failed");
1156   }
1157
1158 }
1159
1160 //=======================================================================
1161 //function : SameNumberByACR
1162 //purpose  : 
1163 //=======================================================================
1164
1165 void BRepFill_CompatibleWires::SameNumberByACR(const  Standard_Boolean  report)
1166 {
1167   // find the dimension
1168   Standard_Integer ideb=1, ifin=myWork.Length();
1169   BRepTools_WireExplorer anExp;
1170
1171   // sections ponctuelles, sections bouclantes ?
1172   if (myDegen1) ideb++;
1173   if (myDegen2) ifin--;
1174   Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
1175                                 && (myWork(ideb).IsSame(myWork(ifin)));
1176
1177   Standard_Integer nbSects = myWork.Length(), i;
1178   Standard_Integer nbmax=0, nbmin=0;
1179   TColStd_Array1OfInteger nbEdges(1,nbSects);
1180   for (i=1; i<=nbSects; i++) {
1181     nbEdges(i) = 0;
1182     for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1183       nbEdges(i)++;
1184     }
1185     if (i==1) nbmin = nbEdges(i);
1186     if (nbmax<nbEdges(i)) nbmax = nbEdges(i);
1187     if (nbmin>nbEdges(i)) nbmin = nbEdges(i);
1188   }
1189
1190   if (nbmax>1) {
1191     // plusieurs edges
1192
1193     if (report || nbmin<nbmax) {
1194       // insertion des decoupes
1195       Standard_Integer nbdec=(nbmax-1)*nbSects+1;
1196       Standard_Real tol = 0.01;
1197       TColStd_Array1OfReal dec(1,nbdec);
1198       dec.Init(0);
1199       dec(2)=1;
1200       // calcul du tableau des decoupes
1201       Standard_Integer j,k,l;
1202       for (i=1; i<=nbSects; i++) {
1203         // wire courant
1204         const TopoDS_Wire& wire1 = TopoDS::Wire(myWork(i));
1205         Standard_Integer nbE = 0;
1206         for(anExp.Init(wire1); anExp.More(); anExp.Next()) {
1207           nbE++;
1208         }
1209         // longueur et ACR du wire 
1210         TColStd_Array1OfReal ACR(0,nbE);
1211         ACR.Init(0);
1212         BRepFill::ComputeACR(wire1, ACR);
1213         // insertion des ACR du wire dans le tableau des decoupes
1214         for (j=1; j<ACR.Length()-1; j++) {
1215           k=1;
1216           while (dec(k)<ACR(j)) {
1217             k++;
1218             if (k>nbdec) break;
1219           }
1220           if (dec(k-1)+tol<ACR(j)&& ACR(j)+tol<dec(k)) {
1221             for (l=nbdec-1;l>=k;l--) {
1222               dec(l+1)=dec(l);
1223             }
1224             dec(k) = ACR(j);
1225           }
1226         }
1227       }
1228       
1229       // tableau effectif des decoupes
1230       k=1;
1231       while (dec(k)<1) {
1232         k++;
1233         if (k>nbdec) break;
1234       }
1235       nbdec = k-1;
1236       TColStd_Array1OfReal dec2(1,nbdec);
1237       for (k=1;k<=nbdec;k++) {
1238         dec2(k) = dec(k);
1239       }
1240       
1241       // insertion des decoupes dans chaque wire
1242       for (i=1; i<=nbSects; i++) {
1243         const TopoDS_Wire& oldwire = TopoDS::Wire(myWork(i));
1244         TopoDS_Wire newwire = BRepFill::InsertACR(oldwire, dec2, tol);
1245         BRepTools_WireExplorer anExp1,anExp2;
1246         anExp1.Init(oldwire);
1247         anExp2.Init(newwire);
1248         for (;anExp1.More();anExp1.Next()) {
1249           const TopoDS_Edge& Ecur = anExp1.Current();
1250           if (!Ecur.IsSame(TopoDS::Edge(anExp2.Current()))) {
1251             TopTools_ListOfShape LE;
1252             LE.Clear();
1253             gp_Pnt P1,P2;
1254             const TopoDS_Vertex& V1 = anExp1.CurrentVertex();
1255             TopoDS_Vertex VF,VR;
1256             TopExp::Vertices(Ecur,VF,VR,Standard_True);
1257             if (V1.IsSame(VF)) P1 = BRep_Tool::Pnt(VR);
1258             if (V1.IsSame(VR)) P1 = BRep_Tool::Pnt(VF);
1259             TopoDS_Vertex V2 = anExp2.CurrentVertex();
1260             TopExp::Vertices(TopoDS::Edge(anExp2.Current()),
1261                              VF,VR,Standard_True);
1262             if (V2.IsSame(VF)) P2 = BRep_Tool::Pnt(VR);
1263             if (V2.IsSame(VR)) P2 = BRep_Tool::Pnt(VF);
1264             while (P1.Distance(P2)>1.e-3) {
1265               LE.Append(anExp2.Current());
1266               anExp2.Next();
1267               V2 = anExp2.CurrentVertex();
1268               TopExp::Vertices(TopoDS::Edge(anExp2.Current()),
1269                                VF,VR,Standard_True);
1270               if (V2.IsSame(VF)) P2 = BRep_Tool::Pnt(VR);
1271               if (V2.IsSame(VR)) P2 = BRep_Tool::Pnt(VF);
1272               if (P1.Distance(P2)<=1.e-3) {
1273                 LE.Append(anExp2.Current());
1274                 anExp2.Next();
1275               }
1276             }
1277
1278             TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itmap;
1279             //TopTools_ListIteratorOfListOfShape itlist;
1280             TopoDS_Edge Ancestor;
1281             Standard_Integer nbedge, nblist=0;
1282             Standard_Boolean found = Standard_False;
1283
1284             for (itmap.Initialize(myMap);itmap.More()&&(!found);itmap.Next()) {
1285               nblist++;
1286               TopTools_ListIteratorOfListOfShape itlist(itmap.Value());
1287               nbedge = 0;
1288               while (itlist.More()&&(!found)) {
1289                 nbedge++;
1290                 TopoDS_Edge ECur = TopoDS::Edge(itlist.Value());
1291                     
1292                 if (Ecur.IsSame(ECur)) {
1293                   Ancestor = TopoDS::Edge(itmap.Key());
1294                   found = Standard_True;
1295                   myMap(Ancestor).InsertBefore(LE,itlist);
1296                   myMap(Ancestor).Remove(itlist);
1297                 }
1298                 if (itlist.More()) itlist.Next();
1299               }
1300               
1301             }
1302
1303           }
1304           else {
1305             anExp2.Next();
1306           }
1307           
1308         }
1309         myWork(i) = newwire;
1310       }
1311       
1312     }
1313   }
1314   
1315   // sections bouclantes ?
1316   if (vClosed) myWork(myWork.Length()) = myWork(1);
1317
1318   // verification du nombre d'edges pour debug
1319   nbmax = 0;
1320   for (i=ideb; i<=ifin; i++) {
1321     nbEdges(i) = 0;
1322     for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1323       nbEdges(i)++;
1324     }
1325     if (i==ideb) nbmin = nbEdges(i);
1326     if (nbmax<nbEdges(i)) nbmax = nbEdges(i);
1327     if (nbmin>nbEdges(i)) nbmin = nbEdges(i);
1328   }
1329   if (nbmax!=nbmin) 
1330     Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SameNumberByACR failed");
1331 }
1332
1333 //=======================================================================
1334 //function : ComputeOrigin
1335 //purpose  : 
1336 //=======================================================================
1337
1338 void BRepFill_CompatibleWires::ComputeOrigin(const  Standard_Boolean polar )
1339 {
1340   // reorganize the wires respecting orientation and origin
1341   
1342   TopoDS_Vertex Vdeb, Vfin;
1343   gp_Pnt Pdeb, Psuiv, PPs;
1344
1345   BRepTools_WireExplorer anExp;
1346
1347   Standard_Boolean wClosed, allClosed = Standard_True;
1348
1349   Standard_Integer NbSects = myWork.Length();
1350   Standard_Integer i, ideb=1,ifin=NbSects;
1351
1352   // sections ponctuelles, sections bouclantes
1353   if (myDegen1) ideb++;
1354   if (myDegen2) ifin--;
1355   Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
1356                                 && (myWork(ideb).IsSame(myWork(ifin)));
1357   
1358   
1359   for (i=ideb; i<=ifin; i++) {
1360     wClosed = myWork(i).Closed();
1361     if (!wClosed) {
1362       // on regarde quand meme si les vertex sont les memes.
1363       TopoDS_Vertex V1, V2;
1364       TopExp::Vertices(TopoDS::Wire(myWork(i)),V1,V2);
1365       if ( V1.IsSame(V2)) wClosed = Standard_True;
1366     }
1367     allClosed = (allClosed && wClosed);
1368   }
1369 /*
1370   for (i=ideb; i<=ifin; i++) {
1371     allClosed = (allClosed && myWork(i).Closed());
1372   }
1373 */
1374   if (!allClosed) 
1375     Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::ComputeOrigin : the wires must be closed");
1376
1377 /*  
1378   // Nombre max de decoupes possibles
1379   Standard_Integer NbMaxV = 0;
1380   for (i=1; i<=NbSects; i++) {
1381     for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1382       NbMaxV++;
1383     }
1384   }
1385   
1386   // construction des tableaux de plans des wires 
1387   gp_Pln P;  
1388   Handle(TColgp_HArray1OfPnt) Pos
1389     = new (TColgp_HArray1OfPnt) (1,NbSects);
1390   Handle(TColgp_HArray1OfVec) Axe
1391     = new (TColgp_HArray1OfVec) (1,NbSects);
1392   for (i=ideb;i<=ifin;i++) {
1393     if (PlaneOfWire(TopoDS::Wire(myWork(i)),P)) {
1394       Pos->SetValue(i,P.Location());
1395       Axe->SetValue(i,gp_Vec(P.Axis().Direction()));
1396     }
1397   }
1398   TopTools_SequenceOfShape SeqV;
1399   if (myDegen1) {
1400     SeqOfVertices(TopoDS::Wire(myWork(1)),SeqV);
1401     Pos->SetValue(1,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
1402     Axe->SetValue(1,Axe->Value(ideb));
1403   }
1404   if (myDegen2) {
1405     SeqOfVertices(TopoDS::Wire(myWork(NbSects)),SeqV);
1406     Pos->SetValue(NbSects,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
1407     Axe->SetValue(NbSects,Axe->Value(ifin));
1408   }
1409 */
1410
1411   //Consider that all wires have same number of edges (polar==Standard_False)
1412   TopTools_SequenceOfShape PrevSeq;
1413   Standard_Integer theLength = 0;
1414   const TopoDS_Wire& wire = TopoDS::Wire( myWork(ideb) );
1415   for (anExp.Init(wire); anExp.More(); anExp.Next())
1416     {
1417       PrevSeq.Append(anExp.CurrentVertex());
1418       theLength++;
1419     }
1420
1421   for (i = ideb+1; i <= ifin; i++)
1422     {
1423       const TopoDS_Wire& wire = TopoDS::Wire(myWork(i));
1424       TopoDS_Wire newwire;
1425       BRep_Builder BB;
1426       BB.MakeWire(newwire);
1427       
1428       TopTools_SequenceOfShape SeqVertices, SeqEdges;
1429       for (anExp.Init(wire); anExp.More(); anExp.Next())
1430         {
1431           SeqVertices.Append( anExp.CurrentVertex() );
1432           SeqEdges.Append( anExp.Current() );
1433         }
1434       
1435       Standard_Real MinSumDist = Precision::Infinite();
1436       Standard_Integer jmin, j, k, n;
1437       Standard_Boolean forward;
1438       if (i == myWork.Length() && myDegen2)
1439         {
1440           // derniere section ponctuelle
1441           jmin = 1;
1442           forward = Standard_True;
1443         }
1444       else
1445         for (j = 1; j <= theLength; j++)
1446           {
1447             //Forward
1448             Standard_Real SumDist = 0.;
1449             for (k = j, n = 1; k <= theLength; k++, n++)
1450               {
1451                 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1452                 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1453                 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1454                 gp_Pnt P = BRep_Tool::Pnt(V);
1455                 SumDist += Pprev.Distance(P);
1456               }
1457             for (k = 1; k < j; k++, n++)
1458               {
1459                 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1460                 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1461                 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1462                 gp_Pnt P = BRep_Tool::Pnt(V);
1463                 SumDist += Pprev.Distance(P);
1464               }
1465             if (SumDist < MinSumDist)
1466               {
1467                 MinSumDist = SumDist;
1468                 jmin = j;
1469                 forward = Standard_True;
1470               }
1471             
1472             //Backward
1473             SumDist = 0.;
1474             for (k = j, n = 1; k >= 1; k--, n++)
1475               {
1476                 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1477                 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1478                 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1479                 gp_Pnt P = BRep_Tool::Pnt(V);
1480                 SumDist += Pprev.Distance(P);
1481               }
1482             for (k = theLength; k > j; k--, n++)
1483               {
1484                 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1485                 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1486                 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1487                 gp_Pnt P = BRep_Tool::Pnt(V);
1488                 SumDist += Pprev.Distance(P);
1489               }
1490             if (SumDist < MinSumDist)
1491               {
1492                 MinSumDist = SumDist;
1493                 jmin = j;
1494                 forward = Standard_False;
1495               }
1496           }
1497       
1498       PrevSeq.Clear();
1499       if (forward)
1500         {
1501           for (j = jmin; j <= theLength; j++)
1502             {
1503               BB.Add( newwire, TopoDS::Edge(SeqEdges(j)) );
1504               PrevSeq.Append( SeqVertices(j) );
1505             }
1506           for (j = 1; j < jmin; j++)
1507             {
1508               BB.Add( newwire, TopoDS::Edge(SeqEdges(j)) );
1509               PrevSeq.Append( SeqVertices(j) );
1510             }
1511         }
1512       else
1513         {
1514           for (j = jmin-1; j >= 1; j--)
1515             {
1516               TopoDS_Shape aLocalShape = SeqEdges(j).Reversed();
1517               BB.Add( newwire, TopoDS::Edge(aLocalShape) );
1518               //PrevSeq.Append( SeqVertices(j) );
1519             }
1520           for (j = theLength; j >= jmin; j--)
1521             {
1522               TopoDS_Shape aLocalShape = SeqEdges(j).Reversed();
1523               BB.Add( newwire, TopoDS::Edge(aLocalShape) );
1524               //PrevSeq.Append( SeqVertices(j) );
1525             }
1526           for (j = jmin; j >= 1; j--)
1527             PrevSeq.Append( SeqVertices(j) );
1528           for (j = theLength; j > jmin; j--)
1529             PrevSeq.Append( SeqVertices(j) );
1530         }
1531       
1532       newwire.Closed( Standard_True );
1533       newwire.Orientation( TopAbs_FORWARD );
1534       myWork(i) = newwire;
1535     }
1536
1537 /*  
1538   for ( i=ideb; i<=myWork.Length(); i++) {
1539     
1540     const TopoDS_Wire& wire = TopoDS::Wire(myWork(i));
1541     
1542     Standard_Integer nbEdges=0;
1543     for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next())
1544       nbEdges++;
1545     TopExp::Vertices(wire,Vdeb,Vfin);
1546     Standard_Boolean wClosed = wire.Closed();
1547     if (!wClosed) {
1548       // on regarde quand meme si les vertex sont les memes.
1549       if ( Vdeb.IsSame(Vfin)) wClosed = Standard_True;
1550     }
1551     
1552     
1553     TopoDS_Vertex Vsuiv, VF, VR;
1554     TopoDS_Wire newwire;
1555     BRep_Builder BW;
1556     BW.MakeWire(newwire);
1557     if (i==ideb) {
1558       anExp.Init(wire);
1559       const TopoDS_Edge Ecur = TopoDS::Edge(anExp.Current());
1560       TopExp::Vertices(Ecur,VF,VR);
1561       if (Vdeb.IsSame(VF)) Vsuiv=VR;
1562       else if (Vdeb.IsSame(VR)) Vsuiv=VF;
1563       else {
1564         // par defaut on prend l'origine sur cette arete
1565         if (VR.IsSame(TopoDS::Vertex(anExp.CurrentVertex()))) {
1566           Vdeb = VR;
1567           Vsuiv = VF;
1568         }
1569         else {
1570           Vdeb = VF;
1571           Vsuiv = VR;
1572         }
1573       }
1574       Pdeb=BRep_Tool::Pnt(Vdeb);
1575       Psuiv=BRep_Tool::Pnt(Vsuiv);
1576       Standard_Real U1 = BRep_Tool::Parameter(Vdeb,Ecur);
1577       Standard_Real U2 = BRep_Tool::Parameter(Vsuiv,Ecur);
1578       BRepAdaptor_Curve Curve(Ecur);
1579       PPs = Curve.Value(0.25*(U1+3*U2));
1580       myWork(ideb) = wire;
1581     }
1582     else {
1583       // on ramene Pdeb, Psuiv et PPs dans le plan courant
1584       gp_Pnt Pnew,Pnext,PPn; 
1585       Transform(Standard_True,Pdeb,Pos->Value(i-1),Axe->Value(i-1), 
1586                               Pos->Value(i),Axe->Value(i),Pnew);
1587       Transform(Standard_True,Psuiv,Pos->Value(i-1),Axe->Value(i-1), 
1588                               Pos->Value(i),Axe->Value(i),Pnext);
1589       Transform(Standard_True,PPs,Pos->Value(i-1),Axe->Value(i-1), 
1590                               Pos->Value(i),Axe->Value(i),PPn);
1591       
1592       Standard_Real distmini,dist;
1593       Standard_Integer rang=0,rangdeb=0;
1594       TopoDS_Vertex Vmini;
1595       gp_Pnt Pmini,P1,P2;
1596       SeqOfVertices(wire,SeqV);
1597       if (SeqV.Length()>NbMaxV) 
1598         Standard_NoSuchObject::Raise("BRepFill::ComputeOrigin failed");
1599       if (!polar) {
1600         // choix du vertex le plus proche comme origine
1601         distmini = Precision::Infinite();
1602         for (Standard_Integer ii=1;ii<=SeqV.Length();ii++) {
1603           P1 = BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(ii)));
1604           dist = P1.Distance(Pnew);
1605           if (dist<distmini) {
1606             distmini = dist;
1607             Vmini = TopoDS::Vertex(SeqV.Value(ii));
1608           }
1609         }
1610         if (!Vmini.IsNull()) Pmini = BRep_Tool::Pnt(Vmini);
1611       }
1612       else {
1613         
1614         // recherche du vertex correspondant a la projection conique
1615         Standard_Real angmin, angV, eta = Precision::Angular();
1616         TopoDS_Vertex Vopti;
1617         angmin = PI/2;
1618         distmini = Precision::Infinite();
1619         gp_Dir dir0(gp_Vec(Pnew,P.Location()));
1620         for (Standard_Integer ii=1;ii<=SeqV.Length();ii++) {
1621           P1 = BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(ii)));
1622           dist = Pnew.Distance(P1);
1623           if (dist<Precision::Confusion()) {
1624             angV = 0.0;
1625           }
1626           else {
1627             gp_Dir dir1(gp_Vec(Pnew,P1));
1628             angV = dir1.Angle(dir0);
1629           }
1630           if (angV>PI/2) angV = PI - angV;
1631           if (angmin>angV+eta) {
1632             distmini = dist;
1633             angmin = angV;
1634             Vopti = TopoDS::Vertex(SeqV.Value(ii));
1635           }
1636           else if (Abs(angmin-angV)<eta) {
1637             if (dist<distmini) {
1638               distmini = dist;
1639               angmin = angV;
1640               Vopti = TopoDS::Vertex(SeqV.Value(ii));
1641             }
1642           }
1643         }
1644         gp_Pnt Popti;
1645         if (!Vopti.IsNull()) Popti = BRep_Tool::Pnt(Vopti);
1646         Vmini = Vopti;
1647         
1648       }
1649
1650       distmini = Precision::Infinite();
1651       for (anExp.Init(wire); anExp.More(); anExp.Next()) {
1652         TopoDS_Edge Ecur = anExp.Current();
1653         TopoDS_Vertex Vcur = anExp.CurrentVertex();
1654         TopExp::Vertices(Ecur,VF,VR);
1655         if (VF.IsSame(Vmini)) {
1656           P1 = BRep_Tool::Pnt(VR);
1657           dist = P1.Distance(Pnext);
1658           if (dist<=distmini) {
1659             distmini = dist;
1660             Vsuiv = VR;
1661           }
1662         }
1663         if (VR.IsSame(Vmini)) {
1664           P1 = BRep_Tool::Pnt(VF);
1665           dist = P1.Distance(Pnext);
1666           if (dist<distmini) {
1667             distmini = dist;
1668             Vsuiv = VF;
1669           }
1670         }
1671       }
1672       
1673       // choix du sens de parcours en fonction de Pnext
1674       Standard_Boolean parcours = Standard_False;
1675       if (i==myWork.Length() && myDegen2) {
1676         // derniere section ponctuelle
1677         rangdeb = 1;
1678         parcours = Standard_True;
1679       }
1680       else {
1681         // cas general
1682         gp_Pnt Pbout = Pnext;
1683         TopoDS_Edge E1,E2;
1684         TopoDS_Vertex V1,V2;
1685         EdgesFromVertex(wire,Vmini,E1,E2);
1686         
1687         TopExp::Vertices(E1,V1,V2,Standard_True);
1688 #ifndef DEB
1689         Standard_Real U1=0, U2=0;
1690 #else
1691         Standard_Real U1, U2;
1692 #endif
1693         if (Vmini.IsSame(V1)) { 
1694           P1 = BRep_Tool::Pnt(V2);
1695           U1 = 0.25*(BRep_Tool::Parameter(V1,E1)+3*BRep_Tool::Parameter(V2,E1));
1696         }
1697         if (Vmini.IsSame(V2)) {
1698           P1 = BRep_Tool::Pnt(V1);
1699           U1 = 0.25*(3*BRep_Tool::Parameter(V1,E1)+BRep_Tool::Parameter(V2,E1));
1700         }
1701         
1702         TopExp::Vertices(E2,V1,V2,Standard_True);
1703         if (Vmini.IsSame(V1)) { 
1704           P2 = BRep_Tool::Pnt(V2);
1705           U2 = 0.25*(BRep_Tool::Parameter(V1,E2)+3*BRep_Tool::Parameter(V2,E2));
1706         }
1707         if (Vmini.IsSame(V2)) {
1708           P2 = BRep_Tool::Pnt(V1);
1709           U2 = 0.25*(3*BRep_Tool::Parameter(V1,E2)+BRep_Tool::Parameter(V2,E2));
1710         }
1711         
1712         if (Abs(Pbout.Distance(P1)-Pbout.Distance(P2))<Precision::Confusion()) {
1713           // cas limite ; on se decale un peu
1714           Pbout = PPn;
1715           BRepAdaptor_Curve Curve1(E1);
1716           P1 = Curve1.Value(U1);
1717           BRepAdaptor_Curve Curve2(E2);
1718           P2 = Curve2.Value(U2);
1719         }
1720         
1721         // calcul de rangdeb
1722         rangdeb = 0;
1723         if (Pbout.Distance(P1)<Pbout.Distance(P2)){
1724           // P1 est plus proche; parcours = False
1725           parcours = Standard_False;
1726           rang = 0;
1727           for (anExp.Init(wire); anExp.More(); anExp.Next()) {
1728             rang++;
1729             TopoDS_Edge Ecur = anExp.Current();
1730             if (E1.IsSame(Ecur)) {
1731               rangdeb = rang;
1732             }
1733           }
1734           BRepAdaptor_Curve Curve(E1);
1735           PPs = Curve.Value(U1);
1736         }
1737         else {
1738           // P2 est plus proche; parcours = True
1739           parcours = Standard_True;
1740           rang = 0;
1741           for (anExp.Init(wire); anExp.More(); anExp.Next()) {
1742             rang++;
1743             TopoDS_Edge Ecur = anExp.Current();
1744             if (E2.IsSame(Ecur)) {
1745               rangdeb = rang;
1746             }
1747           }
1748           BRepAdaptor_Curve Curve(E2);
1749           PPs = Curve.Value(U2);
1750         }
1751       }
1752
1753       // reconstruction du wire a partir de rangdeb
1754       TopTools_SequenceOfShape SeqEdges;
1755       SeqEdges.Clear();
1756       for (anExp.Init(TopoDS::Wire(wire)); anExp.More(); anExp.Next()) {
1757         SeqEdges.Append(anExp.Current());
1758       }
1759       if (parcours) {
1760         for (rang=rangdeb;rang<=nbEdges;rang++) {
1761           BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang)));
1762         }
1763         for (rang=1;rang<rangdeb;rang++) {
1764           BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang)));
1765         }
1766       }
1767       else {
1768         for (rang=rangdeb;rang>=1;rang--) {
1769           TopoDS_Shape aLocalShape = SeqEdges.Value(rang).Reversed();
1770           BW.Add(newwire,TopoDS::Edge(aLocalShape));
1771 //        BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang).Reversed()));
1772         }
1773         for (rang=nbEdges;rang>rangdeb;rang--) {
1774           TopoDS_Shape aLocalShape = SeqEdges.Value(rang).Reversed();
1775           BW.Add(newwire,TopoDS::Edge(aLocalShape));
1776 //        BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang).Reversed()));
1777         }
1778       }
1779       
1780       myWork(i) = newwire.Oriented(TopAbs_FORWARD);
1781       
1782       // on passe au wire suivant
1783       if (!Vmini.IsNull()) Pdeb=BRep_Tool::Pnt(Vmini);
1784       if (!Vsuiv.IsNull()) Psuiv=BRep_Tool::Pnt(Vsuiv);
1785     }
1786   }
1787 */
1788   
1789   // sections bouclantes ?
1790   if (vClosed) myWork(myWork.Length()) = myWork(1);
1791 }
1792
1793 //=======================================================================
1794 //function : SearchOrigin
1795 //purpose  : 
1796 //=======================================================================
1797
1798 void BRepFill_CompatibleWires::SearchOrigin()
1799 {
1800   // reorganize the open wires respecting orientation and origin
1801   
1802   gp_Pln P0,P;  
1803
1804   TopoDS_Vertex Vdeb, Vfin;
1805   gp_Pnt Pdeb,  Pfin;//,Psuiv;
1806
1807   BRepTools_WireExplorer anExp;
1808
1809   Standard_Boolean allOpen = Standard_True;
1810   Standard_Integer ideb=1, ifin=myWork.Length();
1811   if (myDegen1) ideb++;
1812   if (myDegen2) ifin--;
1813   Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
1814                                 && (myWork(ideb).IsSame(myWork(ifin)));
1815   
1816 //  for (Standard_Integer i=ideb; i<=ifin; i++) {
1817   Standard_Integer i;
1818   for  (i=ideb; i<=ifin; i++) {
1819     allOpen = (allOpen && !myWork(i).Closed());
1820   }
1821   if (!allOpen)
1822     Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SearchOrigin : the wires must be open");
1823
1824   // init
1825
1826   TopoDS_Wire wire1 = TopoDS::Wire(myWork(ideb));
1827   wire1.Orientation(TopAbs_FORWARD);
1828   TopExp::Vertices(wire1,Vdeb,Vfin);
1829   Pdeb = BRep_Tool::Pnt(Vdeb);
1830   Pfin = BRep_Tool::Pnt(Vfin);
1831   Standard_Boolean isline0 = (!PlaneOfWire(wire1,P0)), isline;
1832   myWork(ideb) = wire1;
1833   //OCC86
1834   anExp.Init(wire1);
1835   TopoDS_Edge E0 = anExp.Current(), E;
1836
1837   for ( i=ideb+1; i<=ifin; i++) {
1838
1839     TopoDS_Wire wire = TopoDS::Wire(myWork(i));
1840     wire.Orientation(TopAbs_FORWARD);
1841
1842     TopTools_SequenceOfShape SeqEdges;
1843     SeqEdges.Clear();
1844     Standard_Integer nbEdges=0;
1845     //OCC86  for(anExp.Init(wire); anExp.More(); anExp.Next()) {
1846     for(anExp.Init(wire), E = anExp.Current(); anExp.More(); anExp.Next()) {
1847       SeqEdges.Append(anExp.Current());
1848       nbEdges++;
1849     }
1850     TopExp::Vertices(wire,Vdeb,Vfin);
1851     isline = (!PlaneOfWire(wire,P));
1852
1853     TopoDS_Vertex Vmini;
1854     TopoDS_Wire newwire;
1855     BRep_Builder BW;
1856     BW.MakeWire(newwire);
1857     Standard_Boolean parcours = Standard_True;
1858
1859     if (isline0 || isline) {
1860       
1861       // cas particulier des segments de droite
1862       gp_Pnt P1 = BRep_Tool::Pnt(Vdeb),
1863              P2 = BRep_Tool::Pnt(Vfin);
1864       Standard_Real dist1, dist2;
1865       dist1 = Pdeb.Distance(P1)+Pfin.Distance(P2);
1866       dist2 = Pdeb.Distance(P2)+Pfin.Distance(P1);
1867       parcours = (dist2>=dist1);
1868     }
1869     
1870     else {
1871       //OCC86
1872       gp_Pnt P1 = BRep_Tool::Pnt(Vdeb), P1o = Pdeb,
1873              P2 = BRep_Tool::Pnt(Vfin), P2o = Pfin;
1874 /*    // on ramene Pdeb dans le plan courant
1875       gp_Pnt Pnew = Pdeb.Translated (P0.Location(),P.Location());
1876       gp_Ax1 A0 = P0.Axis();
1877       gp_Ax1 A1 = P.Axis();
1878       
1879       if (!A0.IsParallel(A1,1.e-4)) {
1880         gp_Vec vec1(A0.Direction()), vec2(A1.Direction()), 
1881         norm = vec1 ^ vec2;
1882         gp_Ax1 Norm(P.Location(),norm);
1883         Standard_Real ang = vec1.AngleWithRef(vec2,norm);
1884         if (ang > PI/2.0)
1885           ang = PI - ang;
1886         if (ang < -PI/2.0)
1887           ang = -PI - ang;
1888         if (Abs(ang-PI/2.0)<Precision::Angular()) {
1889           // cas d'ambiguite
1890           gp_Vec Vtrans(P0.Location(),P.Location()),Vsign;
1891           Standard_Real alpha,beta,sign=1;
1892           Vsign.SetLinearForm(Vtrans.Dot(vec1),vec2,-Vtrans.Dot(vec2),vec1);
1893           alpha = Vsign.Dot(vec1);
1894           beta = Vsign.Dot(vec2);
1895           Standard_Boolean pasnul = (Abs(alpha)>1.e-4 && Abs(beta)>1.e-4);
1896           if ( alpha*beta>0.0 && pasnul ) sign=-1;
1897           ang *= sign;
1898         }
1899         Pnew = Pnew.Rotated (Norm,ang);
1900       }
1901       // choix entre Vdeb et Vfin
1902       Standard_Real dist = Pnew.Distance(P1);
1903       parcours = (dist<Pnew.Distance(P2));
1904 */      
1905       if(P1.IsEqual(P2,Precision::Confusion()) || P1o.IsEqual(P2o,Precision::Confusion())){
1906         BRepAdaptor_Curve Curve0(E0), Curve(E);
1907         Curve0.D0(Curve0.FirstParameter() + Precision::Confusion(), P2o);
1908         Curve.D0(Curve.FirstParameter() + Precision::Confusion(), P2);
1909       };
1910       gp_Vec VDebFin0(P1o,P2o), VDebFin(P1,P2);
1911       Standard_Real AStraight = VDebFin0.Angle(VDebFin);
1912       parcours = (AStraight < PI/2.0? Standard_True: Standard_False);
1913     }
1914     
1915     // reconstruction du wire
1916     Standard_Integer rang;
1917     if (parcours) {
1918       for (rang=1;rang<=nbEdges;rang++) {
1919         TopoDS_Shape alocalshape = SeqEdges.Value(rang);
1920         BW.Add(newwire,TopoDS::Edge(alocalshape));
1921 //      BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang)));
1922       }
1923     }
1924     else {
1925       for (rang=nbEdges;rang>=1;rang--) {
1926         TopoDS_Shape alocalshape = SeqEdges.Value(rang).Reversed();
1927         BW.Add(newwire,TopoDS::Edge(alocalshape));
1928 //      BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang).Reversed()));
1929       }
1930     }
1931
1932     // orientation du wire
1933     newwire.Oriented(TopAbs_FORWARD);
1934     myWork(i) = newwire;
1935
1936     // on passe au wire suivant
1937     if (parcours) {
1938       Pdeb = BRep_Tool::Pnt(Vdeb);
1939       Pfin = BRep_Tool::Pnt(Vfin);
1940     }
1941     else {
1942       Pfin = BRep_Tool::Pnt(Vdeb);
1943       Pdeb = BRep_Tool::Pnt(Vfin);
1944     }
1945     P0 = P;
1946     isline0 = isline;
1947     //OCC86
1948     E0 = E;
1949   }
1950   
1951   // sections bouclantes ?
1952   if (vClosed) myWork(myWork.Length()) = myWork(1);
1953 }
1954
1955
1956
1957
1958
1959
1960
1961