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