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