0025266: Debug statements in the source are getting flushed on to the console
[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   newwire.Closed (Standard_True);
126 }
127
128 static void CutEdge(const TopoDS_Edge&    CurrentEdge,
129                     const Standard_Real&  Param,
130                     TopoDS_Edge& E1,
131                     TopoDS_Edge& E2,
132                     const TopoDS_Vertex& VRef)
133 {
134   BRep_Builder B; 
135   Standard_Real first,last;
136   Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
137   TopoDS_Vertex Vf, Vl, Vi;
138   B.MakeVertex(Vi, C->Value(Param), Precision::Confusion());
139   TopExp::Vertices(CurrentEdge, Vf, Vl);
140   if (VRef.IsSame(Vf)) {
141     E1 = BRepLib_MakeEdge(C,Vf,Vi, first,Param);
142     E2 = BRepLib_MakeEdge(C,Vi,Vl, Param,last);
143   }
144   else {
145     E2 = BRepLib_MakeEdge(C,Vf,Vi, first,Param);
146     E1 = BRepLib_MakeEdge(C,Vi,Vl, Param,last);    
147   }   
148 }
149
150
151 static void TrimEdge (const TopoDS_Edge&              CurrentEdge,
152                       const TColStd_SequenceOfReal&   CutValues,
153                       const Standard_Real   t0, const Standard_Real   t1,
154                       const Standard_Boolean          SeqOrder,
155                       TopTools_SequenceOfShape& S)
156
157 {
158   S.Clear();
159   Standard_Integer j, ndec=CutValues.Length();
160   Standard_Real first,last,m0,m1;
161   Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
162
163   TopoDS_Vertex Vf,Vl,Vbid,V0,V1;
164   TopAbs_Orientation CurrentOrient = CurrentEdge.Orientation();
165   TopExp::Vertices(CurrentEdge,Vf,Vl);
166   Vbid.Nullify();
167
168   if (SeqOrder) {
169     // from first to last
170     m0 = first;
171     V0 = Vf;
172     for (j=1; j<=ndec; j++) {
173       // piece of edge  
174       m1 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
175       TopoDS_Edge CutE = BRepLib_MakeEdge(C,V0,Vbid,m0,m1);
176       CutE.Orientation(CurrentOrient);
177       S.Append(CutE);
178       m0 = m1;
179       V0 = TopExp::LastVertex(CutE);
180       if (j==ndec) {
181         // last piece
182         TopoDS_Edge LastE = BRepLib_MakeEdge(C,V0,Vl,m0,last);
183         LastE.Orientation(CurrentOrient);
184         S.Append(LastE);
185       }
186     }
187   }
188   else {
189     // from last to first
190     m1 = last;
191     V1 = Vl;
192     for (j=ndec; j>=1; j--) {
193       // piece of edge  
194       m0 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
195       TopoDS_Edge CutE = BRepLib_MakeEdge(C,Vbid,V1,m0,m1);
196       CutE.Orientation(CurrentOrient);
197       S.Append(CutE);
198       m1 = m0;
199       V1 = TopExp::FirstVertex(CutE);
200       if (j==1) {
201         // last piece
202         TopoDS_Edge LastE = BRepLib_MakeEdge(C,Vf,V1,first,m1);
203         LastE.Orientation(CurrentOrient);
204         S.Append(LastE);
205       }
206     }
207   }
208 }
209
210
211 //=======================================================================
212 //function : Face
213 //purpose  : 
214 //=======================================================================
215
216 TopoDS_Face BRepFill::Face(const TopoDS_Edge& Edge1, 
217                            const TopoDS_Edge& Edge2 )
218 {
219   TopoDS_Face Face;
220
221   BRep_Builder B;
222 // Class BRep_Tool without fields and without Constructor :
223 //  BRep_Tool BT;
224
225   TopLoc_Location L,L1,L2;
226   Standard_Real f1,f2,l1,l2, Tol;
227
228 //  Handle(Geom_Curve) C1 = BT.Curve(Edge1,L1,f1,l1);
229   Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,L1,f1,l1);
230 //  Handle(Geom_Curve) C2 = BT.Curve(Edge2,L2,f2,l2);
231   Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,L2,f2,l2);
232
233   // compute the location
234   Standard_Boolean SameLoc = Standard_False;
235   if (L1 == L2) {
236     L = L1;
237     L1 = L2 = TopLoc_Location();
238     SameLoc = Standard_True;
239   }
240
241   // transform and trim the curves
242
243   TopoDS_Vertex V1f,V1l,V2f,V2l;
244   
245   // create a new Handle
246   if (Abs(f1 - C1->FirstParameter()) > Precision::PConfusion() ||
247       Abs(l1 - C1->LastParameter())  > Precision::PConfusion()   ) {
248     C1 = new Geom_TrimmedCurve(C1,f1,l1);
249   }
250   else {
251     C1 = Handle(Geom_Curve)::DownCast(C1->Copy());
252   }
253   // eventually the curve is concerned
254   if ( !SameLoc) {
255     C1->Transform(L1.Transformation());
256   }
257   // it is set in the proper direction and its vertices are taken
258   if (Edge1.Orientation() == TopAbs_REVERSED) {
259     TopExp::Vertices(Edge1,V1l,V1f);
260     C1->Reverse();
261   }
262   else {
263     TopExp::Vertices(Edge1,V1f,V1l);
264   }
265
266   // a new Handle is created
267   if (Abs(f2 - C2->FirstParameter()) > Precision::PConfusion() ||
268       Abs(l2 - C2->LastParameter())  > Precision::PConfusion()   ) {
269     C2 = new Geom_TrimmedCurve(C2,f2,l2);
270   }
271   else {
272     C2 = Handle(Geom_Curve)::DownCast(C2->Copy());
273   }
274   // eventually the curve is concerned
275   if ( !SameLoc) {
276     C2->Transform(L2.Transformation());
277   }
278   // it is set in the proper direction and its vertices are taken
279   if (Edge2.Orientation() == TopAbs_REVERSED) {
280     TopExp::Vertices(Edge2,V2l,V2f);
281     C2->Reverse();
282   }
283   else {
284     TopExp::Vertices(Edge2,V2f,V2l);
285   }
286
287   // Are they closed edges?
288   Standard_Boolean Closed = V1f.IsSame(V1l) && V2f.IsSame(V2l);
289
290
291   GeomFill_Generator Generator;
292   Generator.AddCurve( C1);
293   Generator.AddCurve( C2);
294   Generator.Perform( Precision::PConfusion());
295
296   Handle(Geom_Surface) Surf = Generator.Surface();
297   Handle(Geom_Curve) Iso;
298
299   B.MakeFace(Face,Surf,Precision::Confusion());
300
301   // make the missing edges
302   Surf->Bounds(f1,l1,f2,l2);
303
304   TopoDS_Edge Edge3, Edge4;
305
306   Iso = Surf->UIso(f1);
307 //  Tol = Max(BT.Tolerance(V1f), BT.Tolerance(V2f));
308   Tol = Max(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f));
309   if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) {
310     B.MakeEdge(Edge3,Iso,Precision::Confusion());
311   }
312   else {
313     B.MakeEdge(Edge3);
314     B.Degenerated(Edge3, Standard_True);
315   }
316   V1f.Orientation(TopAbs_FORWARD);
317   B.Add(Edge3,V1f);
318   V2f.Orientation(TopAbs_REVERSED);
319   B.Add(Edge3,V2f);
320   B.Range(Edge3,f2,l2);
321
322   if (Closed) {
323     Edge4 = Edge3;
324   }
325   else {
326     Iso = Surf->UIso(l1);
327 //    Tol = Max(BT.Tolerance(V1l), BT.Tolerance(V2l));
328     Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l));
329     if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) {
330       B.MakeEdge(Edge4,Iso,Precision::Confusion());
331     }
332     else {
333       B.MakeEdge(Edge4);
334       B.Degenerated(Edge4, Standard_True);
335     }
336     V1l.Orientation(TopAbs_FORWARD);
337     B.Add(Edge4,V1l);
338     V2l.Orientation(TopAbs_REVERSED);
339     B.Add(Edge4,V2l);
340     B.Range(Edge4,f2,l2);
341   }
342
343   // make the wire
344
345   TopoDS_Wire W;
346   B.MakeWire(W);
347
348   Edge3.Reverse();
349   B.Add(W,Edge1);
350   B.Add(W,Edge4);
351   B.Add(W,Edge2.Reversed());
352   B.Add(W,Edge3);
353   W.Closed (Standard_True);
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     W.Closed (Standard_True);
568     
569     B.Add(Face,W);
570     
571     if ( SameLoc) Face.Move( L);
572
573     B.Add(Shell,Face);
574
575     // set the pcurves
576     
577     Standard_Real T = Precision::Confusion();
578
579     if ( Edge1.Orientation() == TopAbs_REVERSED ) {
580       B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),
581                    Face,T);
582       B.Range(Edge1,Face,-l1,-f1);
583     }
584     else {
585       B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
586                    Face,T);
587       B.Range(Edge1,Face,f1,l1);
588     }
589     
590     if ( Edge2.Orientation() == TopAbs_REVERSED ) {
591       B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),
592                    Face,T);
593       B.Range(Edge2,Face,-l1,-f1);
594     }
595     else {
596       B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),
597                    Face,T);
598       B.Range(Edge2,Face,f1,l1);
599     }
600
601     if ( Periodic) {
602       B.UpdateEdge(Edge3,
603                    new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
604                    new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),
605                    Face,T);
606     }
607     else {
608       B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
609       B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
610     }
611     
612     // Set the non parameter flag;
613     B.SameParameter(Edge1,Standard_False);
614     B.SameParameter(Edge2,Standard_False);
615     B.SameParameter(Edge3,Standard_False);
616     B.SameParameter(Edge4,Standard_False);
617     B.SameRange(Edge1,Standard_False);
618     B.SameRange(Edge2,Standard_False);
619     B.SameRange(Edge3,Standard_False);
620     B.SameRange(Edge4,Standard_False);
621   }
622   
623   Shell.Closed (BRep_Tool::IsClosed (Shell));
624   BRepLib::SameParameter(Shell);
625   return Shell;
626 }
627
628 //=======================================================================
629 //function : Axe
630 //purpose  : 
631 //=======================================================================
632
633 void BRepFill::Axe (const TopoDS_Shape&       Spine,
634                     const TopoDS_Wire&        Profile,
635                           gp_Ax3&             AxeProf,
636                           Standard_Boolean&   ProfOnSpine,
637                     const Standard_Real       Tol)
638 {  
639   gp_Pnt Loc,Loc1,Loc2;
640   gp_Vec Tang,Tang1,Tang2,Normal;
641
642   Handle(Geom_Surface) S;
643   TopLoc_Location      L;
644   
645   TopoDS_Face aFace;
646
647   // normal to the Spine.
648   if (Spine.ShapeType() == TopAbs_FACE) {
649     aFace = TopoDS::Face(Spine);
650     S = BRep_Tool::Surface(TopoDS::Face(Spine), L);  
651     if ( !S->IsKind(STANDARD_TYPE(Geom_Plane))) {
652       BRepLib_FindSurface FS(TopoDS::Face(Spine), -1, Standard_True);
653       if ( FS.Found()) {
654         S = FS.Surface();
655         L = FS.Location();
656       }
657       else {
658         Standard_NoSuchObject::Raise 
659           ("BRepFill_Evolved : The Face is not planar");
660       }
661     }
662   }
663   else if (Spine.ShapeType() == TopAbs_WIRE) {  
664     aFace = BRepLib_MakeFace(TopoDS::Wire(Spine),Standard_True);
665     S = BRep_Tool::Surface(aFace, L);
666   }
667   
668   if (S.IsNull()) Standard_DomainError::Raise("BRepFill_Evolved::Axe");
669     
670   if (!L.IsIdentity())
671     S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
672   
673   Normal = Handle(Geom_Plane)::DownCast(S)->Pln().Axis().Direction();
674
675   // Find vertex of the profile closest to the spine.
676   Standard_Real     DistMin = Precision::Infinite();
677   Standard_Real     Dist;
678 //  Standard_Real     Tol2 = Tol*Tol;
679   Standard_Real     Tol2 = 1.e-10;
680   TopExp_Explorer   PE, SE;
681   BRepExtrema_ExtPC BE;   
682   Standard_Real     Par =0.,f,l;        
683 //  Standard_Real     D1,D2;
684   gp_Pnt            P1,P2;
685
686   // First check if there is contact Vertex Vertex.
687   Standard_Boolean IsOnVertex = Standard_False;
688   SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
689 //  modified by NIZHNY-EAP Wed Feb 23 12:31:52 2000 ___BEGIN___
690 //  for (;SE.More() && !IsOnVertex ; SE.Next()) {
691   for (;SE.More(); SE.Next()) {
692     P1 = BRep_Tool::Pnt(TopoDS::Vertex(SE.Current()));
693
694     PE.Init(Profile,TopAbs_VERTEX);
695     for ( ; PE.More(); PE.Next()) {
696       P2 = BRep_Tool::Pnt(TopoDS::Vertex(PE.Current()));
697       Standard_Real DistP1P2 = P1.SquareDistance(P2);
698       IsOnVertex = (DistP1P2 <= Tol2);
699       if (IsOnVertex) break;
700     }
701     // otherwise SE.Next() is done and VonF is wrong
702     if (IsOnVertex) break;
703 //  modified by NIZHNY-EAP Wed Jan 26 09:08:36 2000 ___END___
704   }
705
706   if (IsOnVertex) {
707     // try to find on which edge which shared this vertex,
708     // the profile must be considered.
709     // E1, E2 : those two edges.
710     TopTools_IndexedDataMapOfShapeListOfShape Map;
711     TopExp::MapShapesAndAncestors(aFace.Oriented(TopAbs_FORWARD),
712                                   TopAbs_VERTEX, 
713                                   TopAbs_EDGE,
714                                   Map);
715
716     const TopoDS_Vertex&        VonF = TopoDS::Vertex(SE.Current());
717     const TopTools_ListOfShape& List = Map.FindFromKey(VonF);
718     const TopoDS_Edge&          E1   = TopoDS::Edge(List.First());
719     const TopoDS_Edge&          E2   = TopoDS::Edge(List. Last());
720
721     Handle(Geom_Curve) CE1 = BRep_Tool::Curve(E1,L,f,l);
722     Standard_Real Par1 = BRep_Tool::Parameter(VonF,E1,aFace);
723     CE1->D1(Par1,Loc1,Tang1);
724     if (!L.IsIdentity()) {
725       Tang1.Transform(L.Transformation());
726       Loc1.Transform(L.Transformation());
727     }
728     if (E1.Orientation() == TopAbs_REVERSED) Tang1.Reverse();
729
730     Handle(Geom_Curve) CE2 = BRep_Tool::Curve(E2,L,f,l);
731     Standard_Real Par2 = BRep_Tool::Parameter(VonF,E2,aFace);
732     CE2->D1(Par2,Loc2,Tang2);
733     if (!L.IsIdentity()) {
734       Tang2.Transform(L.Transformation());
735       Loc2.Transform(L.Transformation());
736     }
737     if (E2.Orientation() == TopAbs_REVERSED) Tang2.Reverse();
738
739 //  modified by NIZHNY-EAP Wed Feb  2 15:38:41 2000 ___BEGIN___
740     Tang1.Normalize();
741     Tang2.Normalize();
742     Standard_Real sca1=0., sca2=0.;
743     TopoDS_Vertex V1, V2;
744     TopoDS_Edge E;
745     for (PE.Init(Profile,TopAbs_EDGE); PE.More(); PE.Next()) {
746       E = TopoDS::Edge(PE.Current());
747       TopExp::Vertices(E, V1, V2);
748       P1 = BRep_Tool::Pnt(V1);
749       P2 = BRep_Tool::Pnt(V2);
750       gp_Vec vec(P1,P2);
751       sca1 += Abs(Tang1.Dot(vec));
752       sca2 += Abs(Tang2.Dot(vec));
753     } 
754 //  modified by NIZHNY-EAP Wed Feb  2 15:38:44 2000 ___END___
755
756     if ( Abs(sca1) < Abs(sca2)) {
757       Loc  = Loc1;
758       Tang = Tang1;
759     }
760     else {
761       Loc  = Loc2;
762       Tang = Tang2;
763     }
764     DistMin = 0.;
765   }
766   else {
767     SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
768     for ( ; SE.More(); SE.Next()) {
769       const TopoDS_Edge& E = TopoDS::Edge(SE.Current());
770       BE.Initialize(E);
771       for (PE.Init(Profile,TopAbs_VERTEX) ; PE.More(); PE.Next()) {
772         Dist = Precision::Infinite();
773         const TopoDS_Vertex&  V = TopoDS::Vertex(PE.Current());
774         BE.Perform(V);
775         if (BE.IsDone()) {
776           // extrema.
777           for (Standard_Integer i = 1; i <= BE.NbExt(); i++) {
778             if (BE.IsMin(i)) { 
779               Dist = sqrt (BE.SquareDistance(i));
780               Par  = BE.Parameter(i);
781               break;
782             }
783           }
784         }
785         // save minimum.
786         if (Dist < DistMin) {
787           DistMin = Dist;
788           BRepAdaptor_Curve BAC(E);
789           BAC.D1 (Par,Loc,Tang);
790           if (E.Orientation() == TopAbs_REVERSED) Tang.Reverse();
791         }
792       }
793     }
794   }
795
796   ProfOnSpine = (DistMin < Tol);
797   //Construction AxeProf;
798   gp_Ax3 A3 (Loc,Normal,Tang);
799   AxeProf = A3;
800   
801 }
802
803 //=======================================================================
804 //function : SearchOrigin
805 //purpose  : Cut and orientate a closed wire. 
806 //=======================================================================
807
808 void BRepFill::SearchOrigin(TopoDS_Wire & W,
809                             const gp_Pnt& P,
810                             const gp_Vec& Dir,
811                             const Standard_Real Tol)
812 {
813   if (!W.Closed()) 
814     Standard_NoSuchObject::
815       Raise("BRepFill::SearchOrigin : the wire must be closed");
816
817
818   Standard_Boolean NewVertex = Standard_False;
819   Standard_Real theparam = 1.e101, angle;
820   TopoDS_Vertex V ;
821   TopoDS_Edge E, Eref, E1 , E2;
822   BRep_Builder B;
823 // Class BRep_Tool without fields and without Constructor :
824 //  BRep_Tool BT;
825
826   W.Orientation(TopAbs_FORWARD); //to avoid composing the orientations
827
828   // Calculate the distance
829   B.MakeVertex(V, P, Tol);  
830   BRepExtrema_DistShapeShape DSS(V, W);
831   if (DSS.IsDone()) {
832     Standard_Integer isol = 1;
833     Standard_Real dss = P.Distance(DSS.PointOnShape2(isol));
834     for (Standard_Integer iss=2; iss<=DSS.NbSolution(); iss++) 
835       if (dss > P.Distance(DSS.PointOnShape2(iss))) {
836         dss = P.Distance(DSS.PointOnShape2(iss));
837         isol = iss;
838       }
839     TopoDS_Shape supp = DSS.SupportOnShape2(isol);
840     if (DSS.SupportTypeShape2(isol)==BRepExtrema_IsVertex) {
841       V = TopoDS::Vertex(supp);
842     }
843     else {
844       TopoDS_Vertex Vf, Vl;
845       Standard_Real d, dist;
846       E = TopoDS::Edge(supp);
847       TopExp::Vertices(E, Vf, Vl);
848 //      dist = P.Distance(BT.Pnt(Vf));
849       dist = P.Distance(BRep_Tool::Pnt(Vf));
850       if (dist < Tol) {
851         V = Vl;
852       }
853 //      d = P.Distance(BT.Pnt(Vl));
854       d = P.Distance(BRep_Tool::Pnt(Vl));
855       if ((d<Tol) && (d<dist)) {
856         V = Vf;
857         dist = d;
858       }
859       NewVertex = (dist > Tol);
860       if (NewVertex) {
861         DSS.ParOnEdgeS2(isol, theparam);
862       }
863     }
864   } 
865 #if BREPFILL_DEB
866   else {
867     cout << "BRepFill::SearchOrigine : Echec Distance" << endl;
868   }
869 #endif
870
871   Standard_Integer ii, rangdeb=0, NbEdges=0;
872   Standard_Boolean forward;
873   BRepTools_WireExplorer exp;
874
875   // Calculate the number of edges
876   for(exp.Init(W); exp.More(); exp.Next()) NbEdges++;
877   if (NewVertex) {
878     NbEdges++;
879     Eref = E;
880   }
881
882   // Construct the Table and calculate rangdeb
883   TopTools_Array1OfShape Edges(1, NbEdges);
884   for(exp.Init(W), ii=1; exp.More(); exp.Next(), ii++) {
885     E = exp.Current();
886     if (NewVertex && E.IsSame(Eref)) {
887       TopoDS_Edge E1, E2;
888       CutEdge(E, theparam, E1, E2, exp.CurrentVertex());
889       Edges(ii) = E1;
890       ii++;
891       Edges(ii) = E2;
892       rangdeb = ii;
893     }
894     else {
895       Edges(ii) = E;
896     }
897     if (!NewVertex && V.IsSame(exp.CurrentVertex())) {
898       rangdeb = ii;
899     }
900   }
901   if (rangdeb == 0) rangdeb = NbEdges;
902
903   // Calculate the direction of parsing
904   E = TopoDS::Edge(Edges(rangdeb));
905   if (!NewVertex) {
906 //    theparam = BT.Parameter(V, E);
907     theparam = BRep_Tool::Parameter(V, E);
908   }
909   BRepAdaptor_Curve AC(E);
910   gp_Pnt Pe;
911   gp_Vec Ve;
912   AC.D1(theparam, Pe, Ve);
913   if (E.Orientation()==TopAbs_REVERSED) {
914     Ve *= -1;
915   }
916   angle = Ve.Angle(Dir);
917   if (angle > M_PI) angle = 2*M_PI - angle;
918   forward = (angle <= M_PI/2);
919
920   // Reconstruction
921   MakeWire( Edges, rangdeb, forward, W);
922   W.Closed(Standard_True);
923 }
924
925
926
927 //=======================================================================
928 //function : ComputeACR
929 //purpose  : 
930 //=======================================================================
931
932 void BRepFill::ComputeACR(const TopoDS_Wire& wire,
933                           TColStd_Array1OfReal& ACR)
934 {
935   // calculate the reduced curvilinear abscisses and the length of the wire
936   BRepTools_WireExplorer anExp;
937   Standard_Integer nbEdges=0, i;
938
939   // cumulated lengths
940   ACR.Init(0);
941   for(anExp.Init(wire); anExp.More(); anExp.Next()) {
942     nbEdges++;
943     TopoDS_Edge Ecur = TopoDS::Edge(anExp.Current());
944     ACR(nbEdges) = ACR(nbEdges-1);
945     if (!BRep_Tool::Degenerated(Ecur)) {
946       BRepAdaptor_Curve anEcur(Ecur);
947       ACR(nbEdges) += GCPnts_AbscissaPoint::Length(anEcur);
948     }
949   }
950
951   // total length of the wire
952   ACR(0) = ACR(nbEdges);
953
954   // reduced curvilinear abscisses 
955   if (ACR(0)>Precision::Confusion()) {
956     for (i=1; i<=nbEdges; i++) {
957       ACR(i) /= ACR(0);
958     }
959   }
960   else {
961     // punctual wire 
962     ACR(nbEdges) = 1;
963   }
964
965 }
966
967 //=======================================================================
968 //function : InsertACR
969 //purpose  : 
970 //=======================================================================
971
972 TopoDS_Wire BRepFill::InsertACR(const TopoDS_Wire& wire,
973                                 const TColStd_Array1OfReal& ACRcuts,
974                                 const Standard_Real prec)
975 {
976   // calculate ACR of the wire to be cut
977   BRepTools_WireExplorer anExp;
978   Standard_Integer nbEdges=0;
979   for(anExp.Init(wire); anExp.More(); anExp.Next()) {
980     nbEdges++;
981   }
982   TColStd_Array1OfReal ACRwire(0,nbEdges);
983   ComputeACR(wire, ACRwire);
984
985   Standard_Integer i, j, nmax=ACRcuts.Length();
986   TColStd_Array1OfReal paradec(1,nmax);
987   BRepLib_MakeWire MW;
988
989   Standard_Real t0,t1=0;
990   nbEdges=0;
991
992   // processing edge by edge
993   for(anExp.Init(wire); anExp.More(); anExp.Next()) {
994     nbEdges++;
995     t0 = t1;
996     t1 = ACRwire(nbEdges);
997
998     // parameters of cut on this edge
999     Standard_Integer ndec=0;
1000     for (i=1; i<=ACRcuts.Length(); i++ ) {
1001       if (t0+prec<ACRcuts(i) && ACRcuts(i)<t1-prec) {
1002         ndec++;
1003         paradec(ndec) = ACRcuts(i);
1004       }
1005     }
1006
1007     TopoDS_Edge E = anExp.Current();
1008     TopoDS_Vertex V = anExp.CurrentVertex();
1009
1010     if (ndec==0 || BRep_Tool::Degenerated(E)) {
1011       // copy the edge
1012       MW.Add(E);
1013     }
1014     else {
1015       // it is necessary to cut the edge
1016       // following the direction of parsing of the wire
1017       Standard_Boolean SO = (V.IsSame(TopExp::FirstVertex(E)));
1018       TopTools_SequenceOfShape SE;
1019       SE.Clear();
1020       TColStd_SequenceOfReal SR;
1021       SR.Clear();
1022       // the wire is always FORWARD
1023       // it is necesary to modify the parameter of cut6 if the edge is REVERSED
1024       if (E.Orientation() == TopAbs_FORWARD) {
1025         for (j=1; j<=ndec; j++) SR.Append(paradec(j));
1026       }
1027       else {
1028         for (j=1; j<=ndec; j++) SR.Append(t0+t1-paradec(ndec+1-j));
1029       }
1030       TrimEdge(E,SR,t0,t1,SO,SE);
1031       for (j=1; j<=SE.Length(); j++) {
1032         MW.Add(TopoDS::Edge(SE.Value(j)));
1033       }
1034     }
1035   }
1036
1037   // result
1038   TopAbs_Orientation Orien = wire.Orientation();
1039   TopoDS_Shape aLocalShape = MW.Wire();
1040   aLocalShape.Orientation(Orien);
1041   TopoDS_Wire wres = TopoDS::Wire(aLocalShape);
1042 //  TopoDS_Wire wres = TopoDS::Wire(MW.Wire().Oriented(Orien));
1043   return wres;
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
1087
1088