0025656: Specification of semantic of Closed flag of an edge
[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(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f));
308   if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) {
309     B.MakeEdge(Edge3,Iso,Precision::Confusion());
310   }
311   else {
312     B.MakeEdge(Edge3);
313     B.Degenerated(Edge3, Standard_True);
314   }
315   V1f.Orientation(TopAbs_FORWARD);
316   B.Add(Edge3,V1f);
317   V2f.Orientation(TopAbs_REVERSED);
318   B.Add(Edge3,V2f);
319   B.Range(Edge3,f2,l2);
320
321   if (Closed) {
322     Edge4 = Edge3;
323   }
324   else {
325     Iso = Surf->UIso(l1);
326     Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l));
327     if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) {
328       B.MakeEdge(Edge4,Iso,Precision::Confusion());
329     }
330     else {
331       B.MakeEdge(Edge4);
332       B.Degenerated(Edge4, Standard_True);
333     }
334     V1l.Orientation(TopAbs_FORWARD);
335     B.Add(Edge4,V1l);
336     V2l.Orientation(TopAbs_REVERSED);
337     B.Add(Edge4,V2l);
338     B.Range(Edge4,f2,l2);
339   }
340
341   // make the wire
342
343   TopoDS_Wire W;
344   B.MakeWire(W);
345
346   Edge3.Reverse();
347   B.Add(W,Edge1);
348   B.Add(W,Edge4);
349   B.Add(W,Edge2.Reversed());
350   B.Add(W,Edge3);
351   W.Closed (Standard_True);
352
353   B.Add(Face,W);
354
355   // set the pcurves
356
357   Standard_Real T = Precision::Confusion();
358
359   if ( Edge1.Orientation() == TopAbs_REVERSED ) {
360     B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),Face,T);
361     B.Range(Edge1,Face,-l1,-f1);
362   }
363   else {
364     B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),Face,T);
365     B.Range(Edge1,Face,f1,l1);
366   }
367
368   if ( Edge2.Orientation() == TopAbs_REVERSED ) {
369     B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),Face,T);
370     B.Range(Edge2,Face,-l1,-f1);
371   }
372   else {
373     B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),Face,T);
374     B.Range(Edge2,Face,f1,l1);
375   }
376
377   if ( Closed) {
378     B.UpdateEdge(Edge3,
379                  new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
380                  new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
381   }
382   else {
383     B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
384     B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
385   }
386
387   // Set the non parameter flag;
388   B.SameParameter(Edge1,Standard_False);
389   B.SameParameter(Edge2,Standard_False);
390   B.SameParameter(Edge3,Standard_False);
391   B.SameParameter(Edge4,Standard_False);
392   B.SameRange(Edge1,Standard_False);
393   B.SameRange(Edge2,Standard_False);
394   B.SameRange(Edge3,Standard_False);
395   B.SameRange(Edge4,Standard_False);
396   
397   BRepLib::SameParameter(Face);
398
399   if ( SameLoc) Face.Move(L);
400   return Face;
401 }
402
403
404 //=======================================================================
405 //function : Shell
406 //purpose  : 
407 //=======================================================================
408
409 TopoDS_Shell BRepFill::Shell(const TopoDS_Wire& Wire1, 
410                              const TopoDS_Wire& Wire2 )
411 {
412   TopoDS_Shell Shell;
413   TopoDS_Face  Face;
414   TopoDS_Shape S1, S2;
415   TopoDS_Edge  Edge1, Edge2, Edge3, Edge4, Couture;
416
417   BRep_Builder B;
418 // Class BRep_Tool without fields and without Constructor :
419 //  BRep_Tool BT;
420   B.MakeShell(Shell);
421
422   TopExp_Explorer ex1;
423   TopExp_Explorer ex2;
424
425   Standard_Boolean Closed = Wire1.Closed() && Wire2.Closed();
426   
427   Standard_Boolean thefirst = Standard_True;
428
429   ex1.Init(Wire1,TopAbs_EDGE);
430   ex2.Init(Wire2,TopAbs_EDGE);
431
432   while ( ex1.More() && ex2.More() ) { 
433
434     Edge1 = TopoDS::Edge(ex1.Current());
435     Edge2 = TopoDS::Edge(ex2.Current());
436
437     Standard_Boolean Periodic =
438       BRep_Tool::IsClosed(Edge1) && BRep_Tool::IsClosed(Edge2);
439     
440     ex1.Next();
441     ex2.Next();
442     
443     TopLoc_Location L,L1,L2;
444     Standard_Real f1,l1,f2,l2,Tol;
445     
446     Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,L1,f1,l1);
447     Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,L2,f2,l2);
448     
449     // compute the location
450     Standard_Boolean SameLoc = Standard_False;
451     if (L1 == L2) {
452       L = L1;
453       L1 = L2 = TopLoc_Location();
454       SameLoc = Standard_True;
455     }
456
457     // transform and trim the curves
458
459     TopoDS_Vertex V1f,V1l,V2f,V2l;
460     
461
462     if (Abs(f1 - C1->FirstParameter()) > Precision::PConfusion() ||
463         Abs(l1 - C1->LastParameter())  > Precision::PConfusion()   ) {
464       C1 = new Geom_TrimmedCurve(C1,f1,l1);
465     }
466     else {
467       C1 = Handle(Geom_Curve)::DownCast(C1->Copy());
468     }
469     if ( !SameLoc) {
470       C1->Transform(L1.Transformation());
471     }
472     if (Edge1.Orientation() == TopAbs_REVERSED) {
473       TopExp::Vertices(Edge1,V1l,V1f);
474       C1->Reverse();
475     }
476     else
477       TopExp::Vertices(Edge1,V1f,V1l);
478     
479     if (Abs(f2 - C2->FirstParameter()) > Precision::PConfusion() ||
480         Abs(l2 - C2->LastParameter())  > Precision::PConfusion()   ) {
481       C2 = new Geom_TrimmedCurve(C2,f2,l2);
482     }
483     else {
484       C2 = Handle(Geom_Curve)::DownCast(C2->Copy());
485     }
486     if ( !SameLoc) {
487       C2->Transform(L2.Transformation());
488     }
489     if (Edge2.Orientation() == TopAbs_REVERSED) {
490       TopExp::Vertices(Edge2,V2l,V2f);
491         C2->Reverse();
492       }
493     else
494       TopExp::Vertices(Edge2,V2f,V2l);
495     
496     GeomFill_Generator Generator;
497     Generator.AddCurve( C1);
498     Generator.AddCurve( C2);
499     Generator.Perform( Precision::PConfusion());
500     
501     Handle(Geom_Surface) Surf = Generator.Surface();
502     Handle(Geom_Curve) Iso;
503     
504     B.MakeFace(Face,Surf,Precision::Confusion());
505     
506     // make the missing edges
507     Surf->Bounds(f1,l1,f2,l2);
508         
509     if ( thefirst) {
510       Iso = Surf->UIso(f1);
511 //      Tol = Max(BT.Tolerance(V1f), BT.Tolerance(V2f));
512       Tol = Max(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f));
513       if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) {
514         B.MakeEdge(Edge3,Iso,Precision::Confusion());
515       }
516       else {
517         B.MakeEdge(Edge3);
518         B.Degenerated(Edge3, Standard_True);
519       }
520       V1f.Orientation(TopAbs_FORWARD);
521       B.Add(Edge3,V1f);
522       V2f.Orientation(TopAbs_REVERSED);
523       B.Add(Edge3,V2f);
524       B.Range(Edge3,f2,l2);
525       if ( Closed) {
526         Couture = Edge3;
527       }
528       Edge3.Reverse();
529       thefirst = Standard_False;
530     }
531     else {
532       Edge3 = Edge4;
533       Edge3.Reverse();
534     }
535     
536     if ( Closed && !ex1.More() && !ex2.More() ) {
537       Edge4 = Couture;
538     }
539     else {
540       Iso = Surf->UIso(l1);
541 //      Tol = Max(BT.Tolerance(V1l), BT.Tolerance(V2l));
542       Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l));
543       if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) {
544         B.MakeEdge(Edge4,Iso,Precision::Confusion());
545       }
546       else {
547         B.MakeEdge(Edge4);
548         B.Degenerated(Edge4, Standard_True);
549       }
550       V1l.Orientation(TopAbs_FORWARD);
551       B.Add(Edge4,V1l);
552       V2l.Orientation(TopAbs_REVERSED);
553       B.Add(Edge4,V2l);
554       B.Range(Edge4,f2,l2);
555     }
556
557     // make the wire
558     
559     TopoDS_Wire W;
560     B.MakeWire(W);
561     
562     B.Add(W,Edge1);
563     B.Add(W,Edge4);
564     B.Add(W,Edge2.Reversed());
565     B.Add(W,Edge3);
566     W.Closed (Standard_True);
567     
568     B.Add(Face,W);
569     
570     if ( SameLoc) Face.Move( L);
571
572     B.Add(Shell,Face);
573
574     // set the pcurves
575     
576     Standard_Real T = Precision::Confusion();
577
578     if ( Edge1.Orientation() == TopAbs_REVERSED ) {
579       B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),
580                    Face,T);
581       B.Range(Edge1,Face,-l1,-f1);
582     }
583     else {
584       B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
585                    Face,T);
586       B.Range(Edge1,Face,f1,l1);
587     }
588     
589     if ( Edge2.Orientation() == TopAbs_REVERSED ) {
590       B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),
591                    Face,T);
592       B.Range(Edge2,Face,-l1,-f1);
593     }
594     else {
595       B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),
596                    Face,T);
597       B.Range(Edge2,Face,f1,l1);
598     }
599
600     if ( Periodic) {
601       B.UpdateEdge(Edge3,
602                    new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
603                    new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),
604                    Face,T);
605     }
606     else {
607       B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
608       B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
609     }
610     
611     // Set the non parameter flag;
612     B.SameParameter(Edge1,Standard_False);
613     B.SameParameter(Edge2,Standard_False);
614     B.SameParameter(Edge3,Standard_False);
615     B.SameParameter(Edge4,Standard_False);
616     B.SameRange(Edge1,Standard_False);
617     B.SameRange(Edge2,Standard_False);
618     B.SameRange(Edge3,Standard_False);
619     B.SameRange(Edge4,Standard_False);
620   }
621   
622   Shell.Closed (BRep_Tool::IsClosed (Shell));
623   BRepLib::SameParameter(Shell);
624   return Shell;
625 }
626
627 //=======================================================================
628 //function : Axe
629 //purpose  : 
630 //=======================================================================
631
632 void BRepFill::Axe (const TopoDS_Shape&       Spine,
633                     const TopoDS_Wire&        Profile,
634                           gp_Ax3&             AxeProf,
635                           Standard_Boolean&   ProfOnSpine,
636                     const Standard_Real       Tol)
637 {  
638   gp_Pnt Loc,Loc1,Loc2;
639   gp_Vec Tang,Tang1,Tang2,Normal;
640
641   Handle(Geom_Surface) S;
642   TopLoc_Location      L;
643   
644   TopoDS_Face aFace;
645
646   // normal to the Spine.
647   if (Spine.ShapeType() == TopAbs_FACE) {
648     aFace = TopoDS::Face(Spine);
649     S = BRep_Tool::Surface(TopoDS::Face(Spine), L);  
650     if ( !S->IsKind(STANDARD_TYPE(Geom_Plane))) {
651       BRepLib_FindSurface FS(TopoDS::Face(Spine), -1, Standard_True);
652       if ( FS.Found()) {
653         S = FS.Surface();
654         L = FS.Location();
655       }
656       else {
657         Standard_NoSuchObject::Raise 
658           ("BRepFill_Evolved : The Face is not planar");
659       }
660     }
661   }
662   else if (Spine.ShapeType() == TopAbs_WIRE) {  
663     aFace = BRepLib_MakeFace(TopoDS::Wire(Spine),Standard_True);
664     S = BRep_Tool::Surface(aFace, L);
665   }
666   
667   if (S.IsNull()) Standard_DomainError::Raise("BRepFill_Evolved::Axe");
668     
669   if (!L.IsIdentity())
670     S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
671   
672   Normal = Handle(Geom_Plane)::DownCast(S)->Pln().Axis().Direction();
673
674   // Find vertex of the profile closest to the spine.
675   Standard_Real     DistMin = Precision::Infinite();
676   Standard_Real     Dist;
677 //  Standard_Real     Tol2 = Tol*Tol;
678   Standard_Real     Tol2 = 1.e-10;
679   TopExp_Explorer   PE, SE;
680   BRepExtrema_ExtPC BE;   
681   Standard_Real     Par =0.,f,l;        
682 //  Standard_Real     D1,D2;
683   gp_Pnt            P1,P2;
684
685   // First check if there is contact Vertex Vertex.
686   Standard_Boolean IsOnVertex = Standard_False;
687   SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
688 //  modified by NIZHNY-EAP Wed Feb 23 12:31:52 2000 ___BEGIN___
689 //  for (;SE.More() && !IsOnVertex ; SE.Next()) {
690   for (;SE.More(); SE.Next()) {
691     P1 = BRep_Tool::Pnt(TopoDS::Vertex(SE.Current()));
692
693     PE.Init(Profile,TopAbs_VERTEX);
694     for ( ; PE.More(); PE.Next()) {
695       P2 = BRep_Tool::Pnt(TopoDS::Vertex(PE.Current()));
696       Standard_Real DistP1P2 = P1.SquareDistance(P2);
697       IsOnVertex = (DistP1P2 <= Tol2);
698       if (IsOnVertex) break;
699     }
700     // otherwise SE.Next() is done and VonF is wrong
701     if (IsOnVertex) break;
702 //  modified by NIZHNY-EAP Wed Jan 26 09:08:36 2000 ___END___
703   }
704
705   if (IsOnVertex) {
706     // try to find on which edge which shared this vertex,
707     // the profile must be considered.
708     // E1, E2 : those two edges.
709     TopTools_IndexedDataMapOfShapeListOfShape Map;
710     TopExp::MapShapesAndAncestors(aFace.Oriented(TopAbs_FORWARD),
711                                   TopAbs_VERTEX, 
712                                   TopAbs_EDGE,
713                                   Map);
714
715     const TopoDS_Vertex&        VonF = TopoDS::Vertex(SE.Current());
716     const TopTools_ListOfShape& List = Map.FindFromKey(VonF);
717     const TopoDS_Edge&          E1   = TopoDS::Edge(List.First());
718     const TopoDS_Edge&          E2   = TopoDS::Edge(List. Last());
719
720     Handle(Geom_Curve) CE1 = BRep_Tool::Curve(E1,L,f,l);
721     Standard_Real Par1 = BRep_Tool::Parameter(VonF,E1,aFace);
722     CE1->D1(Par1,Loc1,Tang1);
723     if (!L.IsIdentity()) {
724       Tang1.Transform(L.Transformation());
725       Loc1.Transform(L.Transformation());
726     }
727     if (E1.Orientation() == TopAbs_REVERSED) Tang1.Reverse();
728
729     Handle(Geom_Curve) CE2 = BRep_Tool::Curve(E2,L,f,l);
730     Standard_Real Par2 = BRep_Tool::Parameter(VonF,E2,aFace);
731     CE2->D1(Par2,Loc2,Tang2);
732     if (!L.IsIdentity()) {
733       Tang2.Transform(L.Transformation());
734       Loc2.Transform(L.Transformation());
735     }
736     if (E2.Orientation() == TopAbs_REVERSED) Tang2.Reverse();
737
738 //  modified by NIZHNY-EAP Wed Feb  2 15:38:41 2000 ___BEGIN___
739     Tang1.Normalize();
740     Tang2.Normalize();
741     Standard_Real sca1=0., sca2=0.;
742     TopoDS_Vertex V1, V2;
743     TopoDS_Edge E;
744     for (PE.Init(Profile,TopAbs_EDGE); PE.More(); PE.Next()) {
745       E = TopoDS::Edge(PE.Current());
746       TopExp::Vertices(E, V1, V2);
747       P1 = BRep_Tool::Pnt(V1);
748       P2 = BRep_Tool::Pnt(V2);
749       gp_Vec vec(P1,P2);
750       sca1 += Abs(Tang1.Dot(vec));
751       sca2 += Abs(Tang2.Dot(vec));
752     } 
753 //  modified by NIZHNY-EAP Wed Feb  2 15:38:44 2000 ___END___
754
755     if ( Abs(sca1) < Abs(sca2)) {
756       Loc  = Loc1;
757       Tang = Tang1;
758     }
759     else {
760       Loc  = Loc2;
761       Tang = Tang2;
762     }
763     DistMin = 0.;
764   }
765   else {
766     SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
767     for ( ; SE.More(); SE.Next()) {
768       const TopoDS_Edge& E = TopoDS::Edge(SE.Current());
769       BE.Initialize(E);
770       for (PE.Init(Profile,TopAbs_VERTEX) ; PE.More(); PE.Next()) {
771         Dist = Precision::Infinite();
772         const TopoDS_Vertex&  V = TopoDS::Vertex(PE.Current());
773         BE.Perform(V);
774         if (BE.IsDone()) {
775           // extrema.
776           for (Standard_Integer i = 1; i <= BE.NbExt(); i++) {
777             if (BE.IsMin(i)) { 
778               Dist = sqrt (BE.SquareDistance(i));
779               Par  = BE.Parameter(i);
780               break;
781             }
782           }
783         }
784         // save minimum.
785         if (Dist < DistMin) {
786           DistMin = Dist;
787           BRepAdaptor_Curve BAC(E);
788           BAC.D1 (Par,Loc,Tang);
789           if (E.Orientation() == TopAbs_REVERSED) Tang.Reverse();
790         }
791       }
792     }
793   }
794
795   ProfOnSpine = (DistMin < Tol);
796   //Construction AxeProf;
797   gp_Ax3 A3 (Loc,Normal,Tang);
798   AxeProf = A3;
799   
800 }
801
802 //=======================================================================
803 //function : SearchOrigin
804 //purpose  : Cut and orientate a closed wire. 
805 //=======================================================================
806
807 void BRepFill::SearchOrigin(TopoDS_Wire & W,
808                             const gp_Pnt& P,
809                             const gp_Vec& Dir,
810                             const Standard_Real Tol)
811 {
812   if (!W.Closed()) 
813     Standard_NoSuchObject::
814       Raise("BRepFill::SearchOrigin : the wire must be closed");
815
816
817   Standard_Boolean NewVertex = Standard_False;
818   Standard_Real theparam = 1.e101, angle;
819   TopoDS_Vertex V ;
820   TopoDS_Edge E, Eref, E1 , E2;
821   BRep_Builder B;
822 // Class BRep_Tool without fields and without Constructor :
823 //  BRep_Tool BT;
824
825   W.Orientation(TopAbs_FORWARD); //to avoid composing the orientations
826
827   // Calculate the distance
828   B.MakeVertex(V, P, Tol);  
829   BRepExtrema_DistShapeShape DSS(V, W);
830   if (DSS.IsDone()) {
831     Standard_Integer isol = 1;
832     Standard_Real dss = P.Distance(DSS.PointOnShape2(isol));
833     for (Standard_Integer iss=2; iss<=DSS.NbSolution(); iss++) 
834       if (dss > P.Distance(DSS.PointOnShape2(iss))) {
835         dss = P.Distance(DSS.PointOnShape2(iss));
836         isol = iss;
837       }
838     TopoDS_Shape supp = DSS.SupportOnShape2(isol);
839     if (DSS.SupportTypeShape2(isol)==BRepExtrema_IsVertex) {
840       V = TopoDS::Vertex(supp);
841     }
842     else {
843       TopoDS_Vertex Vf, Vl;
844       Standard_Real d, dist;
845       E = TopoDS::Edge(supp);
846       TopExp::Vertices(E, Vf, Vl);
847 //      dist = P.Distance(BT.Pnt(Vf));
848       dist = P.Distance(BRep_Tool::Pnt(Vf));
849       if (dist < Tol) {
850         V = Vl;
851       }
852 //      d = P.Distance(BT.Pnt(Vl));
853       d = P.Distance(BRep_Tool::Pnt(Vl));
854       if ((d<Tol) && (d<dist)) {
855         V = Vf;
856         dist = d;
857       }
858       NewVertex = (dist > Tol);
859       if (NewVertex) {
860         DSS.ParOnEdgeS2(isol, theparam);
861       }
862     }
863   } 
864 #ifdef OCCT_DEBUG
865   else {
866     cout << "BRepFill::SearchOrigine : Echec Distance" << endl;
867   }
868 #endif
869
870   Standard_Integer ii, rangdeb=0, NbEdges=0;
871   Standard_Boolean forward;
872   BRepTools_WireExplorer exp;
873
874   // Calculate the number of edges
875   for(exp.Init(W); exp.More(); exp.Next()) NbEdges++;
876   if (NewVertex) {
877     NbEdges++;
878     Eref = E;
879   }
880
881   // Construct the Table and calculate rangdeb
882   TopTools_Array1OfShape Edges(1, NbEdges);
883   for(exp.Init(W), ii=1; exp.More(); exp.Next(), ii++) {
884     E = exp.Current();
885     if (NewVertex && E.IsSame(Eref)) {
886       TopoDS_Edge E1, E2;
887       CutEdge(E, theparam, E1, E2, exp.CurrentVertex());
888       Edges(ii) = E1;
889       ii++;
890       Edges(ii) = E2;
891       rangdeb = ii;
892     }
893     else {
894       Edges(ii) = E;
895     }
896     if (!NewVertex && V.IsSame(exp.CurrentVertex())) {
897       rangdeb = ii;
898     }
899   }
900   if (rangdeb == 0) rangdeb = NbEdges;
901
902   // Calculate the direction of parsing
903   E = TopoDS::Edge(Edges(rangdeb));
904   if (!NewVertex) {
905 //    theparam = BT.Parameter(V, E);
906     theparam = BRep_Tool::Parameter(V, E);
907   }
908   BRepAdaptor_Curve AC(E);
909   gp_Pnt Pe;
910   gp_Vec Ve;
911   AC.D1(theparam, Pe, Ve);
912   if (E.Orientation()==TopAbs_REVERSED) {
913     Ve *= -1;
914   }
915   angle = Ve.Angle(Dir);
916   if (angle > M_PI) angle = 2*M_PI - angle;
917   forward = (angle <= M_PI/2);
918
919   // Reconstruction
920   MakeWire( Edges, rangdeb, forward, W);
921   W.Closed(Standard_True);
922 }
923
924
925
926 //=======================================================================
927 //function : ComputeACR
928 //purpose  : 
929 //=======================================================================
930
931 void BRepFill::ComputeACR(const TopoDS_Wire& wire,
932                           TColStd_Array1OfReal& ACR)
933 {
934   // calculate the reduced curvilinear abscisses and the length of the wire
935   BRepTools_WireExplorer anExp;
936   Standard_Integer nbEdges=0, i;
937
938   // cumulated lengths
939   ACR.Init(0);
940   for(anExp.Init(wire); anExp.More(); anExp.Next()) {
941     nbEdges++;
942     TopoDS_Edge Ecur = TopoDS::Edge(anExp.Current());
943     ACR(nbEdges) = ACR(nbEdges-1);
944     if (!BRep_Tool::Degenerated(Ecur)) {
945       BRepAdaptor_Curve anEcur(Ecur);
946       ACR(nbEdges) += GCPnts_AbscissaPoint::Length(anEcur);
947     }
948   }
949
950   // total length of the wire
951   ACR(0) = ACR(nbEdges);
952
953   // reduced curvilinear abscisses 
954   if (ACR(0)>Precision::Confusion()) {
955     for (i=1; i<=nbEdges; i++) {
956       ACR(i) /= ACR(0);
957     }
958   }
959   else {
960     // punctual wire 
961     ACR(nbEdges) = 1;
962   }
963
964 }
965
966 //=======================================================================
967 //function : InsertACR
968 //purpose  : 
969 //=======================================================================
970
971 TopoDS_Wire BRepFill::InsertACR(const TopoDS_Wire& wire,
972                                 const TColStd_Array1OfReal& ACRcuts,
973                                 const Standard_Real prec)
974 {
975   // calculate ACR of the wire to be cut
976   BRepTools_WireExplorer anExp;
977   Standard_Integer nbEdges=0;
978   for(anExp.Init(wire); anExp.More(); anExp.Next()) {
979     nbEdges++;
980   }
981   TColStd_Array1OfReal ACRwire(0,nbEdges);
982   ComputeACR(wire, ACRwire);
983
984   Standard_Integer i, j, nmax=ACRcuts.Length();
985   TColStd_Array1OfReal paradec(1,nmax);
986   BRepLib_MakeWire MW;
987
988   Standard_Real t0,t1=0;
989   nbEdges=0;
990
991   // processing edge by edge
992   for(anExp.Init(wire); anExp.More(); anExp.Next()) {
993     nbEdges++;
994     t0 = t1;
995     t1 = ACRwire(nbEdges);
996
997     // parameters of cut on this edge
998     Standard_Integer ndec=0;
999     for (i=1; i<=ACRcuts.Length(); i++ ) {
1000       if (t0+prec<ACRcuts(i) && ACRcuts(i)<t1-prec) {
1001         ndec++;
1002         paradec(ndec) = ACRcuts(i);
1003       }
1004     }
1005
1006     TopoDS_Edge E = anExp.Current();
1007     TopoDS_Vertex V = anExp.CurrentVertex();
1008
1009     if (ndec==0 || BRep_Tool::Degenerated(E)) {
1010       // copy the edge
1011       MW.Add(E);
1012     }
1013     else {
1014       // it is necessary to cut the edge
1015       // following the direction of parsing of the wire
1016       Standard_Boolean SO = (V.IsSame(TopExp::FirstVertex(E)));
1017       TopTools_SequenceOfShape SE;
1018       SE.Clear();
1019       TColStd_SequenceOfReal SR;
1020       SR.Clear();
1021       // the wire is always FORWARD
1022       // it is necesary to modify the parameter of cut6 if the edge is REVERSED
1023       if (E.Orientation() == TopAbs_FORWARD) {
1024         for (j=1; j<=ndec; j++) SR.Append(paradec(j));
1025       }
1026       else {
1027         for (j=1; j<=ndec; j++) SR.Append(t0+t1-paradec(ndec+1-j));
1028       }
1029       TrimEdge(E,SR,t0,t1,SO,SE);
1030       for (j=1; j<=SE.Length(); j++) {
1031         MW.Add(TopoDS::Edge(SE.Value(j)));
1032       }
1033     }
1034   }
1035
1036   // result
1037   TopAbs_Orientation Orien = wire.Orientation();
1038   TopoDS_Shape aLocalShape = MW.Wire();
1039   aLocalShape.Orientation(Orien);
1040   TopoDS_Wire wres = TopoDS::Wire(aLocalShape);
1041 //  TopoDS_Wire wres = TopoDS::Wire(MW.Wire().Oriented(Orien));
1042   return wres;
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
1087