0022792: Globally defined symbol PI conflicts with VTK definition (Intel compiler)
[occt.git] / src / BRepFill / BRepFill.cxx
1 // File:        BRepFill.cxx
2 // Created:     Thu Mar  3 11:18:14 1994
3 // Author:      Bruno DUMORTIER
4 //              <dub@fuegox>
5 // Modified:    Mon Jan 12 10:50:10 1998
6 // Author:      Joelle CHAUVET
7 //              <jct@sgi64>
8 //              automatic management of origin and orientation
9 //              with method Organize
10 // Modified:    Mon Feb 23 09:28:46 1998
11 // Author:      Joelle CHAUVET
12 //              <jct@sgi64>
13 //              method Organize with option of projection for closed wires
14 //              new method SameNumber with option to report cuts
15 //              + utilities ComputeACR and InsertACR
16 //              + processing of the case of last point section 
17 // Modified:    Thu Apr 30 15:24:17 1998
18 // Author:      Joelle CHAUVET
19 //              <jct@sgi64>
20 //              separation closed / open sections + debug 
21 //              Organize becomes ComputeOrigin and SearchOrigin 
22 // Modified:    Tue Jul 21 16:48:35 1998
23 // Author:      Joelle CHAUVET
24 //              <jct@sgi64>
25 //              limited case for Pnext of a twist (BUC60281) 
26 // Modified:    Thu Jul 23 11:38:36 1998
27 // Author:      Joelle CHAUVET
28 //              <jct@sgi64>
29 //              calculate the angle of rotation in SearchOrigin 
30 // Modified:    Fri Jul 31 15:14:19 1998
31 // Author:      Joelle CHAUVET
32 //              <jct@sgi64>
33 //              IntersectOnWire + MapVLV
34 // Modified:    Mon Oct 12 09:42:33 1998
35 // Author:      Joelle CHAUVET
36 //              <jct@sgi64>
37 //              number of edges in EdgesFromVertex (CTS21570) 
38
39 #include <BRepFill.ixx>
40
41 #include <BRepLib.hxx>
42 #include <BRepLib_FindSurface.hxx>
43 #include <BRepLib_MakeFace.hxx>
44 #include <BRepLib_MakeEdge.hxx>
45 #include <BRepLib_MakeVertex.hxx>
46 #include <BRepLib_MakeWire.hxx>
47 #include <BRepExtrema_ExtPC.hxx>
48 #include <BRepExtrema_DistShapeShape.hxx>
49 #include <BRep_Tool.hxx>
50 #include <BRepTools_WireExplorer.hxx>
51
52 #include <TopoDS_Face.hxx>
53 #include <TopoDS_Wire.hxx>
54 #include <TopoDS_Vertex.hxx>
55 #include <BRep_Builder.hxx>
56 #include <TopLoc_Location.hxx>
57 #include <TopExp_Explorer.hxx>
58 #include <gp_Vec.hxx>
59 #include <gp_Lin.hxx>
60 #include <gp_Pln.hxx>
61 #include <gp_Pnt2d.hxx>
62 #include <gp_Dir.hxx>
63 #include <gp_Dir2d.hxx>
64 #include <gp_Circ.hxx>
65 #include <gp_Elips.hxx>
66 #include <Geom_Curve.hxx>
67 #include <Geom_TrimmedCurve.hxx>
68 #include <Geom_Surface.hxx>
69 #include <Geom_Plane.hxx>
70 #include <Geom2d_Line.hxx>
71 #include <GeomFill_Generator.hxx>
72 #include <GeomAdaptor_Curve.hxx>
73 #include <BRepLProp.hxx>
74 #include <BRepGProp.hxx>
75 #include <GProp_GProps.hxx>
76 #include <GProp_PrincipalProps.hxx>
77 #include <GCPnts_AbscissaPoint.hxx>
78 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
79 #include <TopTools_DataMapOfShapeListOfShape.hxx>
80 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
81 #include <TopTools_ListIteratorOfListOfShape.hxx>
82 #include <TopTools_ListOfShape.hxx>
83 #include <TopTools_Array1OfShape.hxx>
84 #include <TopTools_SequenceOfShape.hxx>
85 #include <TopTools_HSequenceOfShape.hxx>
86 #include <BRepAdaptor_Curve.hxx>
87 #include <TopTools_IndexedMapOfShape.hxx>
88
89 #include <BRep_Tool.hxx>
90 #include <TopoDS.hxx>
91 #include <TopExp.hxx>
92 #include <Precision.hxx>
93
94 #include <TColStd_Array1OfInteger.hxx>
95 #include <Standard_NoSuchObject.hxx>
96
97
98 static void MakeWire(const TopTools_Array1OfShape& Edges,
99                      const Standard_Integer rangdeb,
100                      const Standard_Boolean forward,
101                      TopoDS_Wire& newwire)
102 {
103   BRep_Builder BW;
104   Standard_Integer rang, nbEdges = Edges.Length();
105   BW.MakeWire(newwire);
106   if (forward) {
107     for (rang=rangdeb;rang<=nbEdges;rang++) {
108       BW.Add(newwire,TopoDS::Edge(Edges(rang)));
109     }
110     for (rang=1;rang<rangdeb;rang++) {
111       BW.Add(newwire,TopoDS::Edge(Edges(rang)));
112     }
113   }
114
115   else {
116     TopoDS_Edge E;
117     for (rang=rangdeb;rang>=1;rang--) {
118       E = TopoDS::Edge(Edges(rang));
119       BW.Add(newwire,E.Reversed());
120     }
121     for (rang=nbEdges;rang>rangdeb;rang--) {
122       E = TopoDS::Edge(Edges(rang));
123       BW.Add(newwire, E.Reversed());
124     }
125   }
126   newwire.Orientation(TopAbs_FORWARD);
127 }
128
129 static void CutEdge(const TopoDS_Edge&    CurrentEdge,
130                     const Standard_Real&  Param,
131                     TopoDS_Edge& E1,
132                     TopoDS_Edge& E2,
133                     const TopoDS_Vertex& VRef)
134 {
135   BRep_Builder B; 
136   Standard_Real first,last;
137   Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
138   TopoDS_Vertex Vf, Vl, Vi;
139   B.MakeVertex(Vi, C->Value(Param), Precision::Confusion());
140   TopExp::Vertices(CurrentEdge, Vf, Vl);
141   if (VRef.IsSame(Vf)) {
142     E1 = BRepLib_MakeEdge(C,Vf,Vi, first,Param);
143     E2 = BRepLib_MakeEdge(C,Vi,Vl, Param,last);
144   }
145   else {
146     E2 = BRepLib_MakeEdge(C,Vf,Vi, first,Param);
147     E1 = BRepLib_MakeEdge(C,Vi,Vl, Param,last);    
148   }   
149 }
150
151
152 static void TrimEdge (const TopoDS_Edge&              CurrentEdge,
153                       const TColStd_SequenceOfReal&   CutValues,
154                       const Standard_Real   t0, const Standard_Real   t1,
155                       const Standard_Boolean          SeqOrder,
156                       TopTools_SequenceOfShape& S)
157
158 {
159   S.Clear();
160   Standard_Integer j, ndec=CutValues.Length();
161   Standard_Real first,last,m0,m1;
162   Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
163
164   TopoDS_Vertex Vf,Vl,Vbid,V0,V1;
165   TopAbs_Orientation CurrentOrient = CurrentEdge.Orientation();
166   TopExp::Vertices(CurrentEdge,Vf,Vl);
167   Vbid.Nullify();
168
169   if (SeqOrder) {
170     // from first to last
171     m0 = first;
172     V0 = Vf;
173     for (j=1; j<=ndec; j++) {
174       // piece of edge  
175       m1 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
176       TopoDS_Edge CutE = BRepLib_MakeEdge(C,V0,Vbid,m0,m1);
177       CutE.Orientation(CurrentOrient);
178       S.Append(CutE);
179       m0 = m1;
180       V0 = TopExp::LastVertex(CutE);
181       if (j==ndec) {
182         // last piece
183         TopoDS_Edge LastE = BRepLib_MakeEdge(C,V0,Vl,m0,last);
184         LastE.Orientation(CurrentOrient);
185         S.Append(LastE);
186       }
187     }
188   }
189   else {
190     // from last to first
191     m1 = last;
192     V1 = Vl;
193     for (j=ndec; j>=1; j--) {
194       // piece of edge  
195       m0 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
196       TopoDS_Edge CutE = BRepLib_MakeEdge(C,Vbid,V1,m0,m1);
197       CutE.Orientation(CurrentOrient);
198       S.Append(CutE);
199       m1 = m0;
200       V1 = TopExp::FirstVertex(CutE);
201       if (j==1) {
202         // last piece
203         TopoDS_Edge LastE = BRepLib_MakeEdge(C,Vf,V1,first,m1);
204         LastE.Orientation(CurrentOrient);
205         S.Append(LastE);
206       }
207     }
208   }
209 }
210
211
212 //=======================================================================
213 //function : Face
214 //purpose  : 
215 //=======================================================================
216
217 TopoDS_Face BRepFill::Face(const TopoDS_Edge& Edge1, 
218                            const TopoDS_Edge& Edge2 )
219 {
220   TopoDS_Face Face;
221
222   BRep_Builder B;
223 // Class BRep_Tool without fields and without Constructor :
224 //  BRep_Tool BT;
225
226   TopLoc_Location L,L1,L2;
227   Standard_Real f1,f2,l1,l2, Tol;
228
229 //  Handle(Geom_Curve) C1 = BT.Curve(Edge1,L1,f1,l1);
230   Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,L1,f1,l1);
231 //  Handle(Geom_Curve) C2 = BT.Curve(Edge2,L2,f2,l2);
232   Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,L2,f2,l2);
233
234   // compute the location
235   Standard_Boolean SameLoc = Standard_False;
236   if (L1 == L2) {
237     L = L1;
238     L1 = L2 = TopLoc_Location();
239     SameLoc = Standard_True;
240   }
241
242   // transform and trim the curves
243
244   TopoDS_Vertex V1f,V1l,V2f,V2l;
245   
246   // create a new Handle
247   if (Abs(f1 - C1->FirstParameter()) > Precision::PConfusion() ||
248       Abs(l1 - C1->LastParameter())  > Precision::PConfusion()   ) {
249     C1 = new Geom_TrimmedCurve(C1,f1,l1);
250   }
251   else {
252     C1 = Handle(Geom_Curve)::DownCast(C1->Copy());
253   }
254   // eventually the curve is concerned
255   if ( !SameLoc) {
256     C1->Transform(L1.Transformation());
257   }
258   // it is set in the proper direction and its vertices are taken
259   if (Edge1.Orientation() == TopAbs_REVERSED) {
260     TopExp::Vertices(Edge1,V1l,V1f);
261     C1->Reverse();
262   }
263   else {
264     TopExp::Vertices(Edge1,V1f,V1l);
265   }
266
267   // a new Handle is created
268   if (Abs(f2 - C2->FirstParameter()) > Precision::PConfusion() ||
269       Abs(l2 - C2->LastParameter())  > Precision::PConfusion()   ) {
270     C2 = new Geom_TrimmedCurve(C2,f2,l2);
271   }
272   else {
273     C2 = Handle(Geom_Curve)::DownCast(C2->Copy());
274   }
275   // eventually the curve is concerned
276   if ( !SameLoc) {
277     C2->Transform(L2.Transformation());
278   }
279   // it is set in the proper direction and its vertices are taken
280   if (Edge2.Orientation() == TopAbs_REVERSED) {
281     TopExp::Vertices(Edge2,V2l,V2f);
282     C2->Reverse();
283   }
284   else {
285     TopExp::Vertices(Edge2,V2f,V2l);
286   }
287
288   // Are they closed edges?
289   Standard_Boolean Closed = V1f.IsSame(V1l) && V2f.IsSame(V2l);
290
291
292   GeomFill_Generator Generator;
293   Generator.AddCurve( C1);
294   Generator.AddCurve( C2);
295   Generator.Perform( Precision::PConfusion());
296
297   Handle(Geom_Surface) Surf = Generator.Surface();
298   Handle(Geom_Curve) Iso;
299
300   B.MakeFace(Face,Surf,Precision::Confusion());
301
302   // make the missing edges
303   Surf->Bounds(f1,l1,f2,l2);
304
305   TopoDS_Edge Edge3, Edge4;
306
307   Iso = Surf->UIso(f1);
308 //  Tol = Max(BT.Tolerance(V1f), BT.Tolerance(V2f));
309   Tol = Max(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f));
310   if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) {
311     B.MakeEdge(Edge3,Iso,Precision::Confusion());
312   }
313   else {
314     B.MakeEdge(Edge3);
315     B.Degenerated(Edge3, Standard_True);
316   }
317   V1f.Orientation(TopAbs_FORWARD);
318   B.Add(Edge3,V1f);
319   V2f.Orientation(TopAbs_REVERSED);
320   B.Add(Edge3,V2f);
321   B.Range(Edge3,f2,l2);
322
323   if (Closed) {
324     Edge4 = Edge3;
325   }
326   else {
327     Iso = Surf->UIso(l1);
328 //    Tol = Max(BT.Tolerance(V1l), BT.Tolerance(V2l));
329     Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l));
330     if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) {
331       B.MakeEdge(Edge4,Iso,Precision::Confusion());
332     }
333     else {
334       B.MakeEdge(Edge4);
335       B.Degenerated(Edge4, Standard_True);
336     }
337     V1l.Orientation(TopAbs_FORWARD);
338     B.Add(Edge4,V1l);
339     V2l.Orientation(TopAbs_REVERSED);
340     B.Add(Edge4,V2l);
341     B.Range(Edge4,f2,l2);
342   }
343
344   // make the wire
345
346   TopoDS_Wire W;
347   B.MakeWire(W);
348
349   Edge3.Reverse();
350   B.Add(W,Edge1);
351   B.Add(W,Edge4);
352   B.Add(W,Edge2.Reversed());
353   B.Add(W,Edge3);
354
355   B.Add(Face,W);
356
357   // set the pcurves
358
359   Standard_Real T = Precision::Confusion();
360
361   if ( Edge1.Orientation() == TopAbs_REVERSED ) {
362     B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),Face,T);
363     B.Range(Edge1,Face,-l1,-f1);
364   }
365   else {
366     B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),Face,T);
367     B.Range(Edge1,Face,f1,l1);
368   }
369
370   if ( Edge2.Orientation() == TopAbs_REVERSED ) {
371     B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),Face,T);
372     B.Range(Edge2,Face,-l1,-f1);
373   }
374   else {
375     B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),Face,T);
376     B.Range(Edge2,Face,f1,l1);
377   }
378
379   if ( Closed) {
380     B.UpdateEdge(Edge3,
381                  new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
382                  new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
383   }
384   else {
385     B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
386     B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
387   }
388
389   // Set the non parameter flag;
390   B.SameParameter(Edge1,Standard_False);
391   B.SameParameter(Edge2,Standard_False);
392   B.SameParameter(Edge3,Standard_False);
393   B.SameParameter(Edge4,Standard_False);
394   B.SameRange(Edge1,Standard_False);
395   B.SameRange(Edge2,Standard_False);
396   B.SameRange(Edge3,Standard_False);
397   B.SameRange(Edge4,Standard_False);
398   
399   BRepLib::SameParameter(Face);
400
401   if ( SameLoc) Face.Move(L);
402   return Face;
403 }
404
405
406 //=======================================================================
407 //function : Shell
408 //purpose  : 
409 //=======================================================================
410
411 TopoDS_Shell BRepFill::Shell(const TopoDS_Wire& Wire1, 
412                              const TopoDS_Wire& Wire2 )
413 {
414   TopoDS_Shell Shell;
415   TopoDS_Face  Face;
416   TopoDS_Shape S1, S2;
417   TopoDS_Edge  Edge1, Edge2, Edge3, Edge4, Couture;
418
419   BRep_Builder B;
420 // Class BRep_Tool without fields and without Constructor :
421 //  BRep_Tool BT;
422   B.MakeShell(Shell);
423
424   TopExp_Explorer ex1;
425   TopExp_Explorer ex2;
426
427   Standard_Boolean Closed = Wire1.Closed() && Wire2.Closed();
428   
429   Standard_Boolean thefirst = Standard_True;
430
431   ex1.Init(Wire1,TopAbs_EDGE);
432   ex2.Init(Wire2,TopAbs_EDGE);
433
434   while ( ex1.More() && ex2.More() ) { 
435
436     Edge1 = TopoDS::Edge(ex1.Current());
437     Edge2 = TopoDS::Edge(ex2.Current());
438
439     Standard_Boolean Periodic = Edge1.Closed() && Edge2.Closed();
440     
441     ex1.Next();
442     ex2.Next();
443     
444     TopLoc_Location L,L1,L2;
445     Standard_Real f1,l1,f2,l2,Tol;
446     
447     Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,L1,f1,l1);
448     Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,L2,f2,l2);
449     
450     // compute the location
451     Standard_Boolean SameLoc = Standard_False;
452     if (L1 == L2) {
453       L = L1;
454       L1 = L2 = TopLoc_Location();
455       SameLoc = Standard_True;
456     }
457
458     // transform and trim the curves
459
460     TopoDS_Vertex V1f,V1l,V2f,V2l;
461     
462
463     if (Abs(f1 - C1->FirstParameter()) > Precision::PConfusion() ||
464         Abs(l1 - C1->LastParameter())  > Precision::PConfusion()   ) {
465       C1 = new Geom_TrimmedCurve(C1,f1,l1);
466     }
467     else {
468       C1 = Handle(Geom_Curve)::DownCast(C1->Copy());
469     }
470     if ( !SameLoc) {
471       C1->Transform(L1.Transformation());
472     }
473     if (Edge1.Orientation() == TopAbs_REVERSED) {
474       TopExp::Vertices(Edge1,V1l,V1f);
475       C1->Reverse();
476     }
477     else
478       TopExp::Vertices(Edge1,V1f,V1l);
479     
480     if (Abs(f2 - C2->FirstParameter()) > Precision::PConfusion() ||
481         Abs(l2 - C2->LastParameter())  > Precision::PConfusion()   ) {
482       C2 = new Geom_TrimmedCurve(C2,f2,l2);
483     }
484     else {
485       C2 = Handle(Geom_Curve)::DownCast(C2->Copy());
486     }
487     if ( !SameLoc) {
488       C2->Transform(L2.Transformation());
489     }
490     if (Edge2.Orientation() == TopAbs_REVERSED) {
491       TopExp::Vertices(Edge2,V2l,V2f);
492         C2->Reverse();
493       }
494     else
495       TopExp::Vertices(Edge2,V2f,V2l);
496     
497     GeomFill_Generator Generator;
498     Generator.AddCurve( C1);
499     Generator.AddCurve( C2);
500     Generator.Perform( Precision::PConfusion());
501     
502     Handle(Geom_Surface) Surf = Generator.Surface();
503     Handle(Geom_Curve) Iso;
504     
505     B.MakeFace(Face,Surf,Precision::Confusion());
506     
507     // make the missing edges
508     Surf->Bounds(f1,l1,f2,l2);
509         
510     if ( thefirst) {
511       Iso = Surf->UIso(f1);
512 //      Tol = Max(BT.Tolerance(V1f), BT.Tolerance(V2f));
513       Tol = Max(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f));
514       if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) {
515         B.MakeEdge(Edge3,Iso,Precision::Confusion());
516       }
517       else {
518         B.MakeEdge(Edge3);
519         B.Degenerated(Edge3, Standard_True);
520       }
521       V1f.Orientation(TopAbs_FORWARD);
522       B.Add(Edge3,V1f);
523       V2f.Orientation(TopAbs_REVERSED);
524       B.Add(Edge3,V2f);
525       B.Range(Edge3,f2,l2);
526       if ( Closed) {
527         Couture = Edge3;
528       }
529       Edge3.Reverse();
530       thefirst = Standard_False;
531     }
532     else {
533       Edge3 = Edge4;
534       Edge3.Reverse();
535     }
536     
537     if ( Closed && !ex1.More() && !ex2.More() ) {
538       Edge4 = Couture;
539     }
540     else {
541       Iso = Surf->UIso(l1);
542 //      Tol = Max(BT.Tolerance(V1l), BT.Tolerance(V2l));
543       Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l));
544       if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) {
545         B.MakeEdge(Edge4,Iso,Precision::Confusion());
546       }
547       else {
548         B.MakeEdge(Edge4);
549         B.Degenerated(Edge4, Standard_True);
550       }
551       V1l.Orientation(TopAbs_FORWARD);
552       B.Add(Edge4,V1l);
553       V2l.Orientation(TopAbs_REVERSED);
554       B.Add(Edge4,V2l);
555       B.Range(Edge4,f2,l2);
556     }
557
558     // make the wire
559     
560     TopoDS_Wire W;
561     B.MakeWire(W);
562     
563     B.Add(W,Edge1);
564     B.Add(W,Edge4);
565     B.Add(W,Edge2.Reversed());
566     B.Add(W,Edge3);
567     
568     B.Add(Face,W);
569     
570     if ( SameLoc) Face.Move( L);
571
572     B.Add(Shell,Face);
573
574     // set the pcurves
575     
576     Standard_Real T = Precision::Confusion();
577
578     if ( Edge1.Orientation() == TopAbs_REVERSED ) {
579       B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),
580                    Face,T);
581       B.Range(Edge1,Face,-l1,-f1);
582     }
583     else {
584       B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
585                    Face,T);
586       B.Range(Edge1,Face,f1,l1);
587     }
588     
589     if ( Edge2.Orientation() == TopAbs_REVERSED ) {
590       B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),
591                    Face,T);
592       B.Range(Edge2,Face,-l1,-f1);
593     }
594     else {
595       B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),
596                    Face,T);
597       B.Range(Edge2,Face,f1,l1);
598     }
599
600     if ( Periodic) {
601       B.UpdateEdge(Edge3,
602                    new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
603                    new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),
604                    Face,T);
605     }
606     else {
607       B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
608       B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
609     }
610     
611     // Set the non parameter flag;
612     B.SameParameter(Edge1,Standard_False);
613     B.SameParameter(Edge2,Standard_False);
614     B.SameParameter(Edge3,Standard_False);
615     B.SameParameter(Edge4,Standard_False);
616     B.SameRange(Edge1,Standard_False);
617     B.SameRange(Edge2,Standard_False);
618     B.SameRange(Edge3,Standard_False);
619     B.SameRange(Edge4,Standard_False);
620   }
621   
622   BRepLib::SameParameter(Shell);
623   return Shell;
624 }
625
626 //=======================================================================
627 //function : Axe
628 //purpose  : 
629 //=======================================================================
630
631 void BRepFill::Axe (const TopoDS_Shape&       Spine,
632                     const TopoDS_Wire&        Profile,
633                           gp_Ax3&             AxeProf,
634                           Standard_Boolean&   ProfOnSpine,
635                     const Standard_Real       Tol)
636 {  
637   gp_Pnt Loc,Loc1,Loc2;
638   gp_Vec Tang,Tang1,Tang2,Normal;
639
640   Handle(Geom_Surface) S;
641   TopLoc_Location      L;
642   
643   TopoDS_Face aFace;
644
645   // normal to the Spine.
646   if (Spine.ShapeType() == TopAbs_FACE) {
647     aFace = TopoDS::Face(Spine);
648     S = BRep_Tool::Surface(TopoDS::Face(Spine), L);  
649     if ( !S->IsKind(STANDARD_TYPE(Geom_Plane))) {
650       BRepLib_FindSurface FS(TopoDS::Face(Spine), -1, Standard_True);
651       if ( FS.Found()) {
652         S = FS.Surface();
653         L = FS.Location();
654       }
655       else {
656         Standard_NoSuchObject::Raise 
657           ("BRepFill_Evolved : The Face is not planar");
658       }
659     }
660   }
661   else if (Spine.ShapeType() == TopAbs_WIRE) {  
662     aFace = BRepLib_MakeFace(TopoDS::Wire(Spine),Standard_True);
663     S = BRep_Tool::Surface(aFace, L);
664   }
665   
666   if (S.IsNull()) Standard_DomainError::Raise("BRepFill_Evolved::Axe");
667     
668   if (!L.IsIdentity())
669     S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
670   
671   Normal = Handle(Geom_Plane)::DownCast(S)->Pln().Axis().Direction();
672
673   // Find vertex of the profile closest to the spine.
674   Standard_Real     DistMin = Precision::Infinite();
675   Standard_Real     Dist;
676 //  Standard_Real     Tol2 = Tol*Tol;
677   Standard_Real     Tol2 = 1.e-10;
678   TopExp_Explorer   PE, SE;
679   BRepExtrema_ExtPC BE;   
680   Standard_Real     Par =0.,f,l;        
681 //  Standard_Real     D1,D2;
682   gp_Pnt            P1,P2;
683
684   // First check if there is contact Vertex Vertex.
685   Standard_Boolean IsOnVertex = Standard_False;
686   SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
687 //  modified by NIZHNY-EAP Wed Feb 23 12:31:52 2000 ___BEGIN___
688 //  for (;SE.More() && !IsOnVertex ; SE.Next()) {
689   for (;SE.More(); SE.Next()) {
690     P1 = BRep_Tool::Pnt(TopoDS::Vertex(SE.Current()));
691
692     PE.Init(Profile,TopAbs_VERTEX);
693     for ( ; PE.More(); PE.Next()) {
694       P2 = BRep_Tool::Pnt(TopoDS::Vertex(PE.Current()));
695       Standard_Real DistP1P2 = P1.SquareDistance(P2);
696       IsOnVertex = (DistP1P2 <= Tol2);
697       if (IsOnVertex) break;
698     }
699     // otherwise SE.Next() is done and VonF is wrong
700     if (IsOnVertex) break;
701 //  modified by NIZHNY-EAP Wed Jan 26 09:08:36 2000 ___END___
702   }
703
704   if (IsOnVertex) {
705     // try to find on which edge which shared this vertex,
706     // the profile must be considered.
707     // E1, E2 : those two edges.
708     TopTools_IndexedDataMapOfShapeListOfShape Map;
709     TopExp::MapShapesAndAncestors(aFace.Oriented(TopAbs_FORWARD),
710                                   TopAbs_VERTEX, 
711                                   TopAbs_EDGE,
712                                   Map);
713
714     const TopoDS_Vertex&        VonF = TopoDS::Vertex(SE.Current());
715     const TopTools_ListOfShape& List = Map.FindFromKey(VonF);
716     const TopoDS_Edge&          E1   = TopoDS::Edge(List.First());
717     const TopoDS_Edge&          E2   = TopoDS::Edge(List. Last());
718
719     Handle(Geom_Curve) CE1 = BRep_Tool::Curve(E1,L,f,l);
720     Standard_Real Par1 = BRep_Tool::Parameter(VonF,E1,aFace);
721     CE1->D1(Par1,Loc1,Tang1);
722     if (!L.IsIdentity()) {
723       Tang1.Transform(L.Transformation());
724       Loc1.Transform(L.Transformation());
725     }
726     if (E1.Orientation() == TopAbs_REVERSED) Tang1.Reverse();
727
728     Handle(Geom_Curve) CE2 = BRep_Tool::Curve(E2,L,f,l);
729     Standard_Real Par2 = BRep_Tool::Parameter(VonF,E2,aFace);
730     CE2->D1(Par2,Loc2,Tang2);
731     if (!L.IsIdentity()) {
732       Tang2.Transform(L.Transformation());
733       Loc2.Transform(L.Transformation());
734     }
735     if (E2.Orientation() == TopAbs_REVERSED) Tang2.Reverse();
736
737 //  modified by NIZHNY-EAP Wed Feb  2 15:38:41 2000 ___BEGIN___
738     Tang1.Normalize();
739     Tang2.Normalize();
740     Standard_Real sca1=0., sca2=0.;
741     TopoDS_Vertex V1, V2;
742     TopoDS_Edge E;
743     for (PE.Init(Profile,TopAbs_EDGE); PE.More(); PE.Next()) {
744       E = TopoDS::Edge(PE.Current());
745       TopExp::Vertices(E, V1, V2);
746       P1 = BRep_Tool::Pnt(V1);
747       P2 = BRep_Tool::Pnt(V2);
748       gp_Vec vec(P1,P2);
749       sca1 += Abs(Tang1.Dot(vec));
750       sca2 += Abs(Tang2.Dot(vec));
751     } 
752 //  modified by NIZHNY-EAP Wed Feb  2 15:38:44 2000 ___END___
753
754     if ( Abs(sca1) < Abs(sca2)) {
755       Loc  = Loc1;
756       Tang = Tang1;
757     }
758     else {
759       Loc  = Loc2;
760       Tang = Tang2;
761     }
762     DistMin = 0.;
763   }
764   else {
765     SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
766     for ( ; SE.More(); SE.Next()) {
767       const TopoDS_Edge& E = TopoDS::Edge(SE.Current());
768       BE.Initialize(E);
769       for (PE.Init(Profile,TopAbs_VERTEX) ; PE.More(); PE.Next()) {
770         Dist = Precision::Infinite();
771         const TopoDS_Vertex&  V = TopoDS::Vertex(PE.Current());
772         BE.Perform(V);
773         if (BE.IsDone()) {
774           // extrema.
775           for (Standard_Integer i = 1; i <= BE.NbExt(); i++) {
776             if (BE.IsMin(i)) { 
777               Dist = sqrt (BE.SquareDistance(i));
778               Par  = BE.Parameter(i);
779               break;
780             }
781           }
782         }
783         // save minimum.
784         if (Dist < DistMin) {
785           DistMin = Dist;
786           BRepAdaptor_Curve BAC(E);
787           BAC.D1 (Par,Loc,Tang);
788           if (E.Orientation() == TopAbs_REVERSED) Tang.Reverse();
789         }
790       }
791     }
792   }
793
794   ProfOnSpine = (DistMin < Tol);
795   //Construction AxeProf;
796   gp_Ax3 A3 (Loc,Normal,Tang);
797   AxeProf = A3;
798   
799 }
800
801 //=======================================================================
802 //function : SearchOrigin
803 //purpose  : Cut and orientate a closed wire. 
804 //=======================================================================
805
806 void BRepFill::SearchOrigin(TopoDS_Wire & W,
807                             const gp_Pnt& P,
808                             const gp_Vec& Dir,
809                             const Standard_Real Tol)
810 {
811   if (!W.Closed()) 
812     Standard_NoSuchObject::
813       Raise("BRepFill::SearchOrigin : the wire must be closed");
814
815
816   Standard_Boolean NewVertex = Standard_False;
817   Standard_Real theparam = 1.e101, angle;
818   TopoDS_Vertex V ;
819   TopoDS_Edge E, Eref, E1 , E2;
820   BRep_Builder B;
821 // Class BRep_Tool without fields and without Constructor :
822 //  BRep_Tool BT;
823
824   W.Orientation(TopAbs_FORWARD); //to avoid composing the orientations
825
826   // Calculate the distance
827   B.MakeVertex(V, P, Tol);  
828   BRepExtrema_DistShapeShape DSS(V, W);
829   if (DSS.IsDone()) {
830     Standard_Integer isol = 1;
831     Standard_Real dss = P.Distance(DSS.PointOnShape2(isol));
832     for (Standard_Integer iss=2; iss<=DSS.NbSolution(); iss++) 
833       if (dss > P.Distance(DSS.PointOnShape2(iss))) {
834         dss = P.Distance(DSS.PointOnShape2(iss));
835         isol = iss;
836       }
837     TopoDS_Shape supp = DSS.SupportOnShape2(isol);
838     if (DSS.SupportTypeShape2(isol)==BRepExtrema_IsVertex) {
839       V = TopoDS::Vertex(supp);
840     }
841     else {
842       TopoDS_Vertex Vf, Vl;
843       Standard_Real d, dist;
844       E = TopoDS::Edge(supp);
845       TopExp::Vertices(E, Vf, Vl);
846 //      dist = P.Distance(BT.Pnt(Vf));
847       dist = P.Distance(BRep_Tool::Pnt(Vf));
848       if (dist < Tol) {
849         V = Vl;
850       }
851 //      d = P.Distance(BT.Pnt(Vl));
852       d = P.Distance(BRep_Tool::Pnt(Vl));
853       if ((d<Tol) && (d<dist)) {
854         V = Vf;
855         dist = d;
856       }
857       NewVertex = (dist > Tol);
858       if (NewVertex) {
859         DSS.ParOnEdgeS2(isol, theparam);
860       }
861     }
862   } 
863 #if DEB
864   else {
865     cout << "BRepFill::SearchOrigine : Echec Distance" << endl;
866   }
867 #endif
868
869   Standard_Integer ii, rangdeb=0, NbEdges=0;
870   Standard_Boolean forward;
871   BRepTools_WireExplorer exp;
872
873   // Calculate the number of edges
874   for(exp.Init(W); exp.More(); exp.Next()) NbEdges++;
875   if (NewVertex) {
876     NbEdges++;
877     Eref = E;
878   }
879
880   // Construct the Table and calculate rangdeb
881   TopTools_Array1OfShape Edges(1, NbEdges);
882   for(exp.Init(W), ii=1; exp.More(); exp.Next(), ii++) {
883     E = exp.Current();
884     if (NewVertex && E.IsSame(Eref)) {
885       TopoDS_Edge E1, E2;
886       CutEdge(E, theparam, E1, E2, exp.CurrentVertex());
887       Edges(ii) = E1;
888       ii++;
889       Edges(ii) = E2;
890       rangdeb = ii;
891     }
892     else {
893       Edges(ii) = E;
894     }
895     if (!NewVertex && V.IsSame(exp.CurrentVertex())) {
896       rangdeb = ii;
897     }
898   }
899   if (rangdeb == 0) rangdeb = NbEdges;
900
901   // Calculate the direction of parsing
902   E = TopoDS::Edge(Edges(rangdeb));
903   if (!NewVertex) {
904 //    theparam = BT.Parameter(V, E);
905     theparam = BRep_Tool::Parameter(V, E);
906   }
907   BRepAdaptor_Curve AC(E);
908   gp_Pnt Pe;
909   gp_Vec Ve;
910   AC.D1(theparam, Pe, Ve);
911   if (E.Orientation()==TopAbs_REVERSED) {
912     Ve *= -1;
913   }
914   angle = Ve.Angle(Dir);
915   if (angle > M_PI) angle = 2*M_PI - angle;
916   forward = (angle <= M_PI/2);
917
918   // Reconstruction
919   MakeWire( Edges, rangdeb, forward, W);
920   W.Closed(Standard_True);
921 }
922
923
924
925 //=======================================================================
926 //function : ComputeACR
927 //purpose  : 
928 //=======================================================================
929
930 void BRepFill::ComputeACR(const TopoDS_Wire& wire,
931                           TColStd_Array1OfReal& ACR)
932 {
933   // calculate the reduced curvilinear abscisses and the length of the wire
934   BRepTools_WireExplorer anExp;
935   Standard_Integer nbEdges=0, i;
936
937   // cumulated lengths
938   ACR.Init(0);
939   for(anExp.Init(wire); anExp.More(); anExp.Next()) {
940     nbEdges++;
941     TopoDS_Edge Ecur = TopoDS::Edge(anExp.Current());
942     ACR(nbEdges) = ACR(nbEdges-1);
943     if (!BRep_Tool::Degenerated(Ecur)) {
944       BRepAdaptor_Curve anEcur(Ecur);
945       ACR(nbEdges) += GCPnts_AbscissaPoint::Length(anEcur);
946     }
947   }
948
949   // total length of the wire
950   ACR(0) = ACR(nbEdges);
951
952   // reduced curvilinear abscisses 
953   if (ACR(0)>Precision::Confusion()) {
954     for (i=1; i<=nbEdges; i++) {
955       ACR(i) /= ACR(0);
956     }
957   }
958   else {
959     // punctual wire 
960     ACR(nbEdges) = 1;
961   }
962
963 }
964
965 //=======================================================================
966 //function : InsertACR
967 //purpose  : 
968 //=======================================================================
969
970 TopoDS_Wire BRepFill::InsertACR(const TopoDS_Wire& wire,
971                                 const TColStd_Array1OfReal& ACRcuts,
972                                 const Standard_Real prec)
973 {
974   // calculate ACR of the wire to be cut
975   BRepTools_WireExplorer anExp;
976   Standard_Integer nbEdges=0;
977   for(anExp.Init(wire); anExp.More(); anExp.Next()) {
978     nbEdges++;
979   }
980   TColStd_Array1OfReal ACRwire(0,nbEdges);
981   ComputeACR(wire, ACRwire);
982
983   Standard_Integer i, j, nmax=ACRcuts.Length();
984   TColStd_Array1OfReal paradec(1,nmax);
985   BRepLib_MakeWire MW;
986
987   Standard_Real t0,t1=0;
988   nbEdges=0;
989
990   // processing edge by edge
991   for(anExp.Init(wire); anExp.More(); anExp.Next()) {
992     nbEdges++;
993     t0 = t1;
994     t1 = ACRwire(nbEdges);
995
996     // parameters of cut on this edge
997     Standard_Integer ndec=0;
998     for (i=1; i<=ACRcuts.Length(); i++ ) {
999       if (t0+prec<ACRcuts(i) && ACRcuts(i)<t1-prec) {
1000         ndec++;
1001         paradec(ndec) = ACRcuts(i);
1002       }
1003     }
1004
1005     TopoDS_Edge E = anExp.Current();
1006     TopoDS_Vertex V = anExp.CurrentVertex();
1007
1008     if (ndec==0 || BRep_Tool::Degenerated(E)) {
1009       // copy the edge
1010       MW.Add(E);
1011     }
1012     else {
1013       // it is necessary to cut the edge
1014       // following the direction of parsing of the wire
1015       Standard_Boolean SO = (V.IsSame(TopExp::FirstVertex(E)));
1016       TopTools_SequenceOfShape SE;
1017       SE.Clear();
1018       TColStd_SequenceOfReal SR;
1019       SR.Clear();
1020       // the wire is always FORWARD
1021       // it is necesary to modify the parameter of cut6 if the edge is REVERSED
1022       if (E.Orientation() == TopAbs_FORWARD) {
1023         for (j=1; j<=ndec; j++) SR.Append(paradec(j));
1024       }
1025       else {
1026         for (j=1; j<=ndec; j++) SR.Append(t0+t1-paradec(ndec+1-j));
1027       }
1028       TrimEdge(E,SR,t0,t1,SO,SE);
1029       for (j=1; j<=SE.Length(); j++) {
1030         MW.Add(TopoDS::Edge(SE.Value(j)));
1031       }
1032     }
1033   }
1034
1035   // result
1036   TopAbs_Orientation Orien = wire.Orientation();
1037   TopoDS_Shape aLocalShape = MW.Wire();
1038   aLocalShape.Orientation(Orien);
1039   TopoDS_Wire wres = TopoDS::Wire(aLocalShape);
1040 //  TopoDS_Wire wres = TopoDS::Wire(MW.Wire().Oriented(Orien));
1041   return wres;
1042 }
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086