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