0024002: Overall code and build procedure refactoring -- automatic
[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 <BRep_Builder.hxx>
38 #include <BRep_Tool.hxx>
39 #include <BRepAdaptor_Curve.hxx>
40 #include <BRepExtrema_DistShapeShape.hxx>
41 #include <BRepExtrema_ExtPC.hxx>
42 #include <BRepFill.hxx>
43 #include <BRepGProp.hxx>
44 #include <BRepLib.hxx>
45 #include <BRepLib_FindSurface.hxx>
46 #include <BRepLib_MakeEdge.hxx>
47 #include <BRepLib_MakeFace.hxx>
48 #include <BRepLib_MakeVertex.hxx>
49 #include <BRepLib_MakeWire.hxx>
50 #include <BRepLProp.hxx>
51 #include <BRepTools_WireExplorer.hxx>
52 #include <GCPnts_AbscissaPoint.hxx>
53 #include <Geom2d_Line.hxx>
54 #include <Geom_Curve.hxx>
55 #include <Geom_Plane.hxx>
56 #include <Geom_Surface.hxx>
57 #include <Geom_TrimmedCurve.hxx>
58 #include <GeomAdaptor_Curve.hxx>
59 #include <GeomFill_Generator.hxx>
60 #include <gp_Ax3.hxx>
61 #include <gp_Circ.hxx>
62 #include <gp_Dir.hxx>
63 #include <gp_Dir2d.hxx>
64 #include <gp_Elips.hxx>
65 #include <gp_Lin.hxx>
66 #include <gp_Pln.hxx>
67 #include <gp_Pnt.hxx>
68 #include <gp_Pnt2d.hxx>
69 #include <gp_Vec.hxx>
70 #include <GProp_GProps.hxx>
71 #include <GProp_PrincipalProps.hxx>
72 #include <Precision.hxx>
73 #include <Standard_NoSuchObject.hxx>
74 #include <TColStd_Array1OfInteger.hxx>
75 #include <TopExp.hxx>
76 #include <TopExp_Explorer.hxx>
77 #include <TopLoc_Location.hxx>
78 #include <TopoDS.hxx>
79 #include <TopoDS_Edge.hxx>
80 #include <TopoDS_Face.hxx>
81 #include <TopoDS_Shape.hxx>
82 #include <TopoDS_Shell.hxx>
83 #include <TopoDS_Vertex.hxx>
84 #include <TopoDS_Wire.hxx>
85 #include <TopTools_Array1OfShape.hxx>
86 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
87 #include <TopTools_DataMapOfShapeListOfShape.hxx>
88 #include <TopTools_HSequenceOfShape.hxx>
89 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
90 #include <TopTools_IndexedMapOfShape.hxx>
91 #include <TopTools_ListIteratorOfListOfShape.hxx>
92 #include <TopTools_ListOfShape.hxx>
93 #include <TopTools_SequenceOfShape.hxx>
94
95 static void MakeWire(const TopTools_Array1OfShape& Edges,
96                      const Standard_Integer rangdeb,
97                      const Standard_Boolean forward,
98                      TopoDS_Wire& newwire)
99 {
100   BRep_Builder BW;
101   Standard_Integer rang, nbEdges = Edges.Length();
102   BW.MakeWire(newwire);
103   if (forward) {
104     for (rang=rangdeb;rang<=nbEdges;rang++) {
105       BW.Add(newwire,TopoDS::Edge(Edges(rang)));
106     }
107     for (rang=1;rang<rangdeb;rang++) {
108       BW.Add(newwire,TopoDS::Edge(Edges(rang)));
109     }
110   }
111
112   else {
113     TopoDS_Edge E;
114     for (rang=rangdeb;rang>=1;rang--) {
115       E = TopoDS::Edge(Edges(rang));
116       BW.Add(newwire,E.Reversed());
117     }
118     for (rang=nbEdges;rang>rangdeb;rang--) {
119       E = TopoDS::Edge(Edges(rang));
120       BW.Add(newwire, E.Reversed());
121     }
122   }
123   newwire.Orientation(TopAbs_FORWARD);
124   newwire.Closed (Standard_True);
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(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f));
307   if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) {
308     B.MakeEdge(Edge3,Iso,Precision::Confusion());
309   }
310   else {
311     B.MakeEdge(Edge3);
312     B.Degenerated(Edge3, Standard_True);
313   }
314   V1f.Orientation(TopAbs_FORWARD);
315   B.Add(Edge3,V1f);
316   V2f.Orientation(TopAbs_REVERSED);
317   B.Add(Edge3,V2f);
318   B.Range(Edge3,f2,l2);
319
320   if (Closed) {
321     Edge4 = Edge3;
322   }
323   else {
324     Iso = Surf->UIso(l1);
325     Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l));
326     if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) {
327       B.MakeEdge(Edge4,Iso,Precision::Confusion());
328     }
329     else {
330       B.MakeEdge(Edge4);
331       B.Degenerated(Edge4, Standard_True);
332     }
333     V1l.Orientation(TopAbs_FORWARD);
334     B.Add(Edge4,V1l);
335     V2l.Orientation(TopAbs_REVERSED);
336     B.Add(Edge4,V2l);
337     B.Range(Edge4,f2,l2);
338   }
339
340   // make the wire
341
342   TopoDS_Wire W;
343   B.MakeWire(W);
344
345   Edge3.Reverse();
346   B.Add(W,Edge1);
347   B.Add(W,Edge4);
348   B.Add(W,Edge2.Reversed());
349   B.Add(W,Edge3);
350   W.Closed (Standard_True);
351
352   B.Add(Face,W);
353
354   // set the pcurves
355
356   Standard_Real T = Precision::Confusion();
357
358   if ( Edge1.Orientation() == TopAbs_REVERSED ) {
359     B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),Face,T);
360     B.Range(Edge1,Face,-l1,-f1);
361   }
362   else {
363     B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),Face,T);
364     B.Range(Edge1,Face,f1,l1);
365   }
366
367   if ( Edge2.Orientation() == TopAbs_REVERSED ) {
368     B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),Face,T);
369     B.Range(Edge2,Face,-l1,-f1);
370   }
371   else {
372     B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),Face,T);
373     B.Range(Edge2,Face,f1,l1);
374   }
375
376   if ( Closed) {
377     B.UpdateEdge(Edge3,
378                  new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
379                  new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
380   }
381   else {
382     B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
383     B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
384   }
385
386   // Set the non parameter flag;
387   B.SameParameter(Edge1,Standard_False);
388   B.SameParameter(Edge2,Standard_False);
389   B.SameParameter(Edge3,Standard_False);
390   B.SameParameter(Edge4,Standard_False);
391   B.SameRange(Edge1,Standard_False);
392   B.SameRange(Edge2,Standard_False);
393   B.SameRange(Edge3,Standard_False);
394   B.SameRange(Edge4,Standard_False);
395   
396   BRepLib::SameParameter(Face);
397
398   if ( SameLoc) Face.Move(L);
399   return Face;
400 }
401
402
403 //=======================================================================
404 //function : Shell
405 //purpose  : 
406 //=======================================================================
407
408 TopoDS_Shell BRepFill::Shell(const TopoDS_Wire& Wire1, 
409                              const TopoDS_Wire& Wire2 )
410 {
411   TopoDS_Shell Shell;
412   TopoDS_Face  Face;
413   TopoDS_Shape S1, S2;
414   TopoDS_Edge  Edge1, Edge2, Edge3, Edge4, Couture;
415
416   BRep_Builder B;
417 // Class BRep_Tool without fields and without Constructor :
418 //  BRep_Tool BT;
419   B.MakeShell(Shell);
420
421   TopExp_Explorer ex1;
422   TopExp_Explorer ex2;
423
424   Standard_Boolean Closed = Wire1.Closed() && Wire2.Closed();
425   
426   Standard_Boolean thefirst = Standard_True;
427
428   ex1.Init(Wire1,TopAbs_EDGE);
429   ex2.Init(Wire2,TopAbs_EDGE);
430
431   while ( ex1.More() && ex2.More() ) { 
432
433     Edge1 = TopoDS::Edge(ex1.Current());
434     Edge2 = TopoDS::Edge(ex2.Current());
435
436     Standard_Boolean Periodic =
437       BRep_Tool::IsClosed(Edge1) && BRep_Tool::IsClosed(Edge2);
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     W.Closed (Standard_True);
566     
567     B.Add(Face,W);
568     
569     if ( SameLoc) Face.Move( L);
570
571     B.Add(Shell,Face);
572
573     // set the pcurves
574     
575     Standard_Real T = Precision::Confusion();
576
577     if ( Edge1.Orientation() == TopAbs_REVERSED ) {
578       B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),
579                    Face,T);
580       B.Range(Edge1,Face,-l1,-f1);
581     }
582     else {
583       B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
584                    Face,T);
585       B.Range(Edge1,Face,f1,l1);
586     }
587     
588     if ( Edge2.Orientation() == TopAbs_REVERSED ) {
589       B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),
590                    Face,T);
591       B.Range(Edge2,Face,-l1,-f1);
592     }
593     else {
594       B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),
595                    Face,T);
596       B.Range(Edge2,Face,f1,l1);
597     }
598
599     if ( Periodic) {
600       B.UpdateEdge(Edge3,
601                    new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
602                    new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),
603                    Face,T);
604     }
605     else {
606       B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
607       B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
608     }
609     
610     // Set the non parameter flag;
611     B.SameParameter(Edge1,Standard_False);
612     B.SameParameter(Edge2,Standard_False);
613     B.SameParameter(Edge3,Standard_False);
614     B.SameParameter(Edge4,Standard_False);
615     B.SameRange(Edge1,Standard_False);
616     B.SameRange(Edge2,Standard_False);
617     B.SameRange(Edge3,Standard_False);
618     B.SameRange(Edge4,Standard_False);
619   }
620   
621   Shell.Closed (BRep_Tool::IsClosed (Shell));
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 #ifdef OCCT_DEBUG
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