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 
MakeWire(const TopTools_Array1OfShape & Edges,const Standard_Integer rangdeb,const Standard_Boolean forward,TopoDS_Wire & newwire)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 
CutEdge(const TopoDS_Edge & CurrentEdge,const Standard_Real & Param,TopoDS_Edge & E1,TopoDS_Edge & E2,const TopoDS_Vertex & VRef)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 
TrimEdge(const TopoDS_Edge & CurrentEdge,const TColStd_SequenceOfReal & CutValues,const Standard_Real t0,const Standard_Real t1,const Standard_Boolean SeqOrder,TopTools_SequenceOfShape & S)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 
Face(const TopoDS_Edge & Edge1,const TopoDS_Edge & Edge2)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 
Shell(const TopoDS_Wire & Wire1,const TopoDS_Wire & Wire2)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 
Axe(const TopoDS_Shape & Spine,const TopoDS_Wire & Profile,gp_Ax3 & AxeProf,Standard_Boolean & ProfOnSpine,const Standard_Real Tol)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 
SearchOrigin(TopoDS_Wire & W,const gp_Pnt & P,const gp_Vec & Dir,const Standard_Real Tol)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 
ComputeACR(const TopoDS_Wire & wire,TColStd_Array1OfReal & ACR)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 
InsertACR(const TopoDS_Wire & wire,const TColStd_Array1OfReal & ACRcuts,const Standard_Real prec)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 necessary 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 
1086