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