0030895: Coding Rules - specify std namespace explicitly for std::cout and streams
[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         throw Standard_NoSuchObject("BRepFill_Evolved : The Face is not planar");
657       }
658     }
659   }
660   else if (Spine.ShapeType() == TopAbs_WIRE) {  
661     aFace = BRepLib_MakeFace(TopoDS::Wire(Spine),Standard_True);
662     S = BRep_Tool::Surface(aFace, L);
663   }
664   
665   if (S.IsNull()) throw Standard_DomainError("BRepFill_Evolved::Axe");
666     
667   if (!L.IsIdentity())
668     S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
669   
670   Normal = Handle(Geom_Plane)::DownCast(S)->Pln().Axis().Direction();
671
672   // Find vertex of the profile closest to the spine.
673   Standard_Real     DistMin = Precision::Infinite();
674   Standard_Real     Dist;
675 //  Standard_Real     Tol2 = Tol*Tol;
676   Standard_Real     Tol2 = 1.e-10;
677   TopExp_Explorer   PE, SE;
678   BRepExtrema_ExtPC BE;   
679   Standard_Real     Par =0.,f,l;        
680 //  Standard_Real     D1,D2;
681   gp_Pnt            P1,P2;
682
683   // First check if there is contact Vertex Vertex.
684   Standard_Boolean IsOnVertex = Standard_False;
685   SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
686 //  modified by NIZHNY-EAP Wed Feb 23 12:31:52 2000 ___BEGIN___
687 //  for (;SE.More() && !IsOnVertex ; SE.Next()) {
688   for (;SE.More(); SE.Next()) {
689     P1 = BRep_Tool::Pnt(TopoDS::Vertex(SE.Current()));
690
691     PE.Init(Profile,TopAbs_VERTEX);
692     for ( ; PE.More(); PE.Next()) {
693       P2 = BRep_Tool::Pnt(TopoDS::Vertex(PE.Current()));
694       Standard_Real DistP1P2 = P1.SquareDistance(P2);
695       IsOnVertex = (DistP1P2 <= Tol2);
696       if (IsOnVertex) break;
697     }
698     // otherwise SE.Next() is done and VonF is wrong
699     if (IsOnVertex) break;
700 //  modified by NIZHNY-EAP Wed Jan 26 09:08:36 2000 ___END___
701   }
702
703   if (IsOnVertex) {
704     // try to find on which edge which shared this vertex,
705     // the profile must be considered.
706     // E1, E2 : those two edges.
707     TopTools_IndexedDataMapOfShapeListOfShape Map;
708     TopExp::MapShapesAndAncestors(aFace.Oriented(TopAbs_FORWARD),
709                                   TopAbs_VERTEX, 
710                                   TopAbs_EDGE,
711                                   Map);
712
713     const TopoDS_Vertex&        VonF = TopoDS::Vertex(SE.Current());
714     const TopTools_ListOfShape& List = Map.FindFromKey(VonF);
715     const TopoDS_Edge&          E1   = TopoDS::Edge(List.First());
716     const TopoDS_Edge&          E2   = TopoDS::Edge(List. Last());
717
718     Handle(Geom_Curve) CE1 = BRep_Tool::Curve(E1,L,f,l);
719     Standard_Real Par1 = BRep_Tool::Parameter(VonF,E1,aFace);
720     CE1->D1(Par1,Loc1,Tang1);
721     if (!L.IsIdentity()) {
722       Tang1.Transform(L.Transformation());
723       Loc1.Transform(L.Transformation());
724     }
725     if (E1.Orientation() == TopAbs_REVERSED) Tang1.Reverse();
726
727     Handle(Geom_Curve) CE2 = BRep_Tool::Curve(E2,L,f,l);
728     Standard_Real Par2 = BRep_Tool::Parameter(VonF,E2,aFace);
729     CE2->D1(Par2,Loc2,Tang2);
730     if (!L.IsIdentity()) {
731       Tang2.Transform(L.Transformation());
732       Loc2.Transform(L.Transformation());
733     }
734     if (E2.Orientation() == TopAbs_REVERSED) Tang2.Reverse();
735
736 //  modified by NIZHNY-EAP Wed Feb  2 15:38:41 2000 ___BEGIN___
737     Tang1.Normalize();
738     Tang2.Normalize();
739     Standard_Real sca1=0., sca2=0.;
740     TopoDS_Vertex V1, V2;
741     TopoDS_Edge E;
742     for (PE.Init(Profile,TopAbs_EDGE); PE.More(); PE.Next()) {
743       E = TopoDS::Edge(PE.Current());
744       TopExp::Vertices(E, V1, V2);
745       P1 = BRep_Tool::Pnt(V1);
746       P2 = BRep_Tool::Pnt(V2);
747       gp_Vec vec(P1,P2);
748       sca1 += Abs(Tang1.Dot(vec));
749       sca2 += Abs(Tang2.Dot(vec));
750     } 
751 //  modified by NIZHNY-EAP Wed Feb  2 15:38:44 2000 ___END___
752
753     if ( Abs(sca1) < Abs(sca2)) {
754       Loc  = Loc1;
755       Tang = Tang1;
756     }
757     else {
758       Loc  = Loc2;
759       Tang = Tang2;
760     }
761     DistMin = 0.;
762   }
763   else {
764     SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
765     for ( ; SE.More(); SE.Next()) {
766       const TopoDS_Edge& E = TopoDS::Edge(SE.Current());
767       BE.Initialize(E);
768       for (PE.Init(Profile,TopAbs_VERTEX) ; PE.More(); PE.Next()) {
769         Dist = Precision::Infinite();
770         const TopoDS_Vertex&  V = TopoDS::Vertex(PE.Current());
771         BE.Perform(V);
772         if (BE.IsDone()) {
773           // extrema.
774           for (Standard_Integer i = 1; i <= BE.NbExt(); i++) {
775             if (BE.IsMin(i)) { 
776               Dist = sqrt (BE.SquareDistance(i));
777               Par  = BE.Parameter(i);
778               break;
779             }
780           }
781         }
782         // save minimum.
783         if (Dist < DistMin) {
784           DistMin = Dist;
785           BRepAdaptor_Curve BAC(E);
786           BAC.D1 (Par,Loc,Tang);
787           if (E.Orientation() == TopAbs_REVERSED) Tang.Reverse();
788         }
789       }
790     }
791   }
792
793   ProfOnSpine = (DistMin < Tol);
794   //Construction AxeProf;
795   gp_Ax3 A3 (Loc,Normal,Tang);
796   AxeProf = A3;
797   
798 }
799
800 //=======================================================================
801 //function : SearchOrigin
802 //purpose  : Cut and orientate a closed wire. 
803 //=======================================================================
804
805 void BRepFill::SearchOrigin(TopoDS_Wire & W,
806                             const gp_Pnt& P,
807                             const gp_Vec& Dir,
808                             const Standard_Real Tol)
809 {
810   if (!W.Closed()) 
811     Standard_NoSuchObject::
812       Raise("BRepFill::SearchOrigin : the wire must be closed");
813
814
815   Standard_Boolean NewVertex = Standard_False;
816   Standard_Real theparam = 1.e101, angle;
817   TopoDS_Vertex V ;
818   TopoDS_Edge E, Eref;
819   BRep_Builder B;
820 // Class BRep_Tool without fields and without Constructor :
821 //  BRep_Tool BT;
822
823   W.Orientation(TopAbs_FORWARD); //to avoid composing the orientations
824
825   // Calculate the distance
826   B.MakeVertex(V, P, Tol);  
827   BRepExtrema_DistShapeShape DSS(V, W);
828   if (DSS.IsDone()) {
829     Standard_Integer isol = 1;
830     Standard_Real dss = P.Distance(DSS.PointOnShape2(isol));
831     for (Standard_Integer iss=2; iss<=DSS.NbSolution(); iss++) 
832       if (dss > P.Distance(DSS.PointOnShape2(iss))) {
833         dss = P.Distance(DSS.PointOnShape2(iss));
834         isol = iss;
835       }
836     TopoDS_Shape supp = DSS.SupportOnShape2(isol);
837     if (DSS.SupportTypeShape2(isol)==BRepExtrema_IsVertex) {
838       V = TopoDS::Vertex(supp);
839     }
840     else {
841       TopoDS_Vertex Vf, Vl;
842       Standard_Real d, dist;
843       E = TopoDS::Edge(supp);
844       TopExp::Vertices(E, Vf, Vl);
845 //      dist = P.Distance(BT.Pnt(Vf));
846       dist = P.Distance(BRep_Tool::Pnt(Vf));
847       if (dist < Tol) {
848         V = Vl;
849       }
850 //      d = P.Distance(BT.Pnt(Vl));
851       d = P.Distance(BRep_Tool::Pnt(Vl));
852       if ((d<Tol) && (d<dist)) {
853         V = Vf;
854         dist = d;
855       }
856       NewVertex = (dist > Tol);
857       if (NewVertex) {
858         DSS.ParOnEdgeS2(isol, theparam);
859       }
860     }
861   } 
862 #ifdef OCCT_DEBUG
863   else {
864     std::cout << "BRepFill::SearchOrigine : Echec Distance" << std::endl;
865   }
866 #endif
867
868   Standard_Integer ii, rangdeb=0, NbEdges=0;
869   Standard_Boolean forward;
870   BRepTools_WireExplorer exp;
871
872   // Calculate the number of edges
873   for(exp.Init(W); exp.More(); exp.Next()) NbEdges++;
874   if (NewVertex) {
875     NbEdges++;
876     Eref = E;
877   }
878
879   // Construct the Table and calculate rangdeb
880   TopTools_Array1OfShape Edges(1, NbEdges);
881   for(exp.Init(W), ii=1; exp.More(); exp.Next(), ii++) {
882     E = exp.Current();
883     if (NewVertex && E.IsSame(Eref)) {
884       TopoDS_Edge E1, E2;
885       CutEdge(E, theparam, E1, E2, exp.CurrentVertex());
886       Edges(ii) = E1;
887       ii++;
888       Edges(ii) = E2;
889       rangdeb = ii;
890     }
891     else {
892       Edges(ii) = E;
893     }
894     if (!NewVertex && V.IsSame(exp.CurrentVertex())) {
895       rangdeb = ii;
896     }
897   }
898   if (rangdeb == 0) rangdeb = NbEdges;
899
900   // Calculate the direction of parsing
901   E = TopoDS::Edge(Edges(rangdeb));
902   if (!NewVertex) {
903 //    theparam = BT.Parameter(V, E);
904     theparam = BRep_Tool::Parameter(V, E);
905   }
906   BRepAdaptor_Curve AC(E);
907   gp_Pnt Pe;
908   gp_Vec Ve;
909   AC.D1(theparam, Pe, Ve);
910   if (E.Orientation()==TopAbs_REVERSED) {
911     Ve *= -1;
912   }
913   angle = Ve.Angle(Dir);
914   if (angle > M_PI) angle = 2*M_PI - angle;
915   forward = (angle <= M_PI/2);
916
917   // Reconstruction
918   MakeWire( Edges, rangdeb, forward, W);
919   W.Closed(Standard_True);
920 }
921
922
923
924 //=======================================================================
925 //function : ComputeACR
926 //purpose  : 
927 //=======================================================================
928
929 void BRepFill::ComputeACR(const TopoDS_Wire& wire,
930                           TColStd_Array1OfReal& ACR)
931 {
932   // calculate the reduced curvilinear abscisses and the length of the wire
933   BRepTools_WireExplorer anExp;
934   Standard_Integer nbEdges=0, i;
935
936   // cumulated lengths
937   ACR.Init(0);
938   for(anExp.Init(wire); anExp.More(); anExp.Next()) {
939     nbEdges++;
940     TopoDS_Edge Ecur = TopoDS::Edge(anExp.Current());
941     ACR(nbEdges) = ACR(nbEdges-1);
942     if (!BRep_Tool::Degenerated(Ecur)) {
943       BRepAdaptor_Curve anEcur(Ecur);
944       ACR(nbEdges) += GCPnts_AbscissaPoint::Length(anEcur);
945     }
946   }
947
948   // total length of the wire
949   ACR(0) = ACR(nbEdges);
950
951   // reduced curvilinear abscisses 
952   if (ACR(0)>Precision::Confusion()) {
953     for (i=1; i<=nbEdges; i++) {
954       ACR(i) /= ACR(0);
955     }
956   }
957   else {
958     // punctual wire 
959     ACR(nbEdges) = 1;
960   }
961
962 }
963
964 //=======================================================================
965 //function : InsertACR
966 //purpose  : 
967 //=======================================================================
968
969 TopoDS_Wire BRepFill::InsertACR(const TopoDS_Wire& wire,
970                                 const TColStd_Array1OfReal& ACRcuts,
971                                 const Standard_Real prec)
972 {
973   // calculate ACR of the wire to be cut
974   BRepTools_WireExplorer anExp;
975   Standard_Integer nbEdges=0;
976   for(anExp.Init(wire); anExp.More(); anExp.Next()) {
977     nbEdges++;
978   }
979   TColStd_Array1OfReal ACRwire(0,nbEdges);
980   ComputeACR(wire, ACRwire);
981
982   Standard_Integer i, j, nmax=ACRcuts.Length();
983   TColStd_Array1OfReal paradec(1,nmax);
984   BRepLib_MakeWire MW;
985
986   Standard_Real t0,t1=0;
987   nbEdges=0;
988
989   // processing edge by edge
990   for(anExp.Init(wire); anExp.More(); anExp.Next()) {
991     nbEdges++;
992     t0 = t1;
993     t1 = ACRwire(nbEdges);
994
995     // parameters of cut on this edge
996     Standard_Integer ndec=0;
997     for (i=1; i<=ACRcuts.Length(); i++ ) {
998       if (t0+prec<ACRcuts(i) && ACRcuts(i)<t1-prec) {
999         ndec++;
1000         paradec(ndec) = ACRcuts(i);
1001       }
1002     }
1003
1004     TopoDS_Edge E = anExp.Current();
1005     TopoDS_Vertex V = anExp.CurrentVertex();
1006
1007     if (ndec==0 || BRep_Tool::Degenerated(E)) {
1008       // copy the edge
1009       MW.Add(E);
1010     }
1011     else {
1012       // it is necessary to cut the edge
1013       // following the direction of parsing of the wire
1014       Standard_Boolean SO = (V.IsSame(TopExp::FirstVertex(E)));
1015       TopTools_SequenceOfShape SE;
1016       SE.Clear();
1017       TColStd_SequenceOfReal SR;
1018       SR.Clear();
1019       // the wire is always FORWARD
1020       // it is necesary to modify the parameter of cut6 if the edge is REVERSED
1021       if (E.Orientation() == TopAbs_FORWARD) {
1022         for (j=1; j<=ndec; j++) SR.Append(paradec(j));
1023       }
1024       else {
1025         for (j=1; j<=ndec; j++) SR.Append(t0+t1-paradec(ndec+1-j));
1026       }
1027       TrimEdge(E,SR,t0,t1,SO,SE);
1028       for (j=1; j<=SE.Length(); j++) {
1029         MW.Add(TopoDS::Edge(SE.Value(j)));
1030       }
1031     }
1032   }
1033
1034   // result
1035   TopAbs_Orientation Orien = wire.Orientation();
1036   TopoDS_Shape aLocalShape = MW.Wire();
1037   aLocalShape.Orientation(Orien);
1038   TopoDS_Wire wres = TopoDS::Wire(aLocalShape);
1039 //  TopoDS_Wire wres = TopoDS::Wire(MW.Wire().Oriented(Orien));
1040   return wres;
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
1085