0024428: Implementation of LGPL license
[occt.git] / src / BRepFill / BRepFill.cxx
CommitLineData
b311480e 1// Created on: 1994-03-03
2// Created by: Joelle CHAUVET
3// Copyright (c) 1994-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
973c2be1 8// This library is free software; you can redistribute it and / or modify it
9// under the terms of the GNU Lesser General Public 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
b311480e 16
7fd59977 17// Modified: Mon Jan 12 10:50:10 1998
0d969553
Y
18// automatic management of origin and orientation
19// with method Organize
7fd59977 20// Modified: Mon Feb 23 09:28:46 1998
0d969553
Y
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
7fd59977 25// Modified: Thu Apr 30 15:24:17 1998
0d969553
Y
26// separation closed / open sections + debug
27// Organize becomes ComputeOrigin and SearchOrigin
7fd59977 28// Modified: Tue Jul 21 16:48:35 1998
0d969553 29// limited case for Pnext of a twist (BUC60281)
7fd59977 30// Modified: Thu Jul 23 11:38:36 1998
0d969553 31// calculate the angle of rotation in SearchOrigin
7fd59977 32// Modified: Fri Jul 31 15:14:19 1998
7fd59977 33// IntersectOnWire + MapVLV
34// Modified: Mon Oct 12 09:42:33 1998
0d969553 35// number of edges in EdgesFromVertex (CTS21570)
7fd59977 36
37#include <BRepFill.ixx>
38
39#include <BRepLib.hxx>
40#include <BRepLib_FindSurface.hxx>
41#include <BRepLib_MakeFace.hxx>
42#include <BRepLib_MakeEdge.hxx>
43#include <BRepLib_MakeVertex.hxx>
44#include <BRepLib_MakeWire.hxx>
45#include <BRepExtrema_ExtPC.hxx>
46#include <BRepExtrema_DistShapeShape.hxx>
47#include <BRep_Tool.hxx>
48#include <BRepTools_WireExplorer.hxx>
49
50#include <TopoDS_Face.hxx>
51#include <TopoDS_Wire.hxx>
52#include <TopoDS_Vertex.hxx>
53#include <BRep_Builder.hxx>
54#include <TopLoc_Location.hxx>
55#include <TopExp_Explorer.hxx>
56#include <gp_Vec.hxx>
57#include <gp_Lin.hxx>
58#include <gp_Pln.hxx>
59#include <gp_Pnt2d.hxx>
60#include <gp_Dir.hxx>
61#include <gp_Dir2d.hxx>
62#include <gp_Circ.hxx>
63#include <gp_Elips.hxx>
64#include <Geom_Curve.hxx>
65#include <Geom_TrimmedCurve.hxx>
66#include <Geom_Surface.hxx>
67#include <Geom_Plane.hxx>
68#include <Geom2d_Line.hxx>
69#include <GeomFill_Generator.hxx>
70#include <GeomAdaptor_Curve.hxx>
71#include <BRepLProp.hxx>
72#include <BRepGProp.hxx>
73#include <GProp_GProps.hxx>
74#include <GProp_PrincipalProps.hxx>
75#include <GCPnts_AbscissaPoint.hxx>
76#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
77#include <TopTools_DataMapOfShapeListOfShape.hxx>
78#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
79#include <TopTools_ListIteratorOfListOfShape.hxx>
80#include <TopTools_ListOfShape.hxx>
81#include <TopTools_Array1OfShape.hxx>
82#include <TopTools_SequenceOfShape.hxx>
83#include <TopTools_HSequenceOfShape.hxx>
84#include <BRepAdaptor_Curve.hxx>
85#include <TopTools_IndexedMapOfShape.hxx>
86
87#include <BRep_Tool.hxx>
88#include <TopoDS.hxx>
89#include <TopExp.hxx>
90#include <Precision.hxx>
91
92#include <TColStd_Array1OfInteger.hxx>
93#include <Standard_NoSuchObject.hxx>
94
95
96static void MakeWire(const TopTools_Array1OfShape& Edges,
97 const Standard_Integer rangdeb,
98 const Standard_Boolean forward,
99 TopoDS_Wire& newwire)
100{
101 BRep_Builder BW;
102 Standard_Integer rang, nbEdges = Edges.Length();
103 BW.MakeWire(newwire);
104 if (forward) {
105 for (rang=rangdeb;rang<=nbEdges;rang++) {
106 BW.Add(newwire,TopoDS::Edge(Edges(rang)));
107 }
108 for (rang=1;rang<rangdeb;rang++) {
109 BW.Add(newwire,TopoDS::Edge(Edges(rang)));
110 }
111 }
112
113 else {
114 TopoDS_Edge E;
115 for (rang=rangdeb;rang>=1;rang--) {
116 E = TopoDS::Edge(Edges(rang));
117 BW.Add(newwire,E.Reversed());
118 }
119 for (rang=nbEdges;rang>rangdeb;rang--) {
120 E = TopoDS::Edge(Edges(rang));
121 BW.Add(newwire, E.Reversed());
122 }
123 }
124 newwire.Orientation(TopAbs_FORWARD);
125}
126
127static 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
150static 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) {
0d969553 168 // from first to last
7fd59977 169 m0 = first;
170 V0 = Vf;
171 for (j=1; j<=ndec; j++) {
0d969553 172 // piece of edge
7fd59977 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) {
0d969553 180 // last piece
7fd59977 181 TopoDS_Edge LastE = BRepLib_MakeEdge(C,V0,Vl,m0,last);
182 LastE.Orientation(CurrentOrient);
183 S.Append(LastE);
184 }
185 }
186 }
187 else {
0d969553 188 // from last to first
7fd59977 189 m1 = last;
190 V1 = Vl;
191 for (j=ndec; j>=1; j--) {
0d969553 192 // piece of edge
7fd59977 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) {
0d969553 200 // last piece
7fd59977 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
215TopoDS_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
0d969553 244 // create a new Handle
7fd59977 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 }
0d969553 252 // eventually the curve is concerned
7fd59977 253 if ( !SameLoc) {
254 C1->Transform(L1.Transformation());
255 }
0d969553 256 // it is set in the proper direction and its vertices are taken
7fd59977 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
0d969553 265 // a new Handle is created
7fd59977 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 }
0d969553 273 // eventually the curve is concerned
7fd59977 274 if ( !SameLoc) {
275 C2->Transform(L2.Transformation());
276 }
0d969553 277 // it is set in the proper direction and its vertices are taken
7fd59977 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
0d969553 286 // Are they closed edges?
7fd59977 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(BT.Tolerance(V1f), BT.Tolerance(V2f));
307 Tol = Max(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f));
308 if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) {
309 B.MakeEdge(Edge3,Iso,Precision::Confusion());
310 }
311 else {
312 B.MakeEdge(Edge3);
313 B.Degenerated(Edge3, Standard_True);
314 }
315 V1f.Orientation(TopAbs_FORWARD);
316 B.Add(Edge3,V1f);
317 V2f.Orientation(TopAbs_REVERSED);
318 B.Add(Edge3,V2f);
319 B.Range(Edge3,f2,l2);
320
321 if (Closed) {
322 Edge4 = Edge3;
323 }
324 else {
325 Iso = Surf->UIso(l1);
326// Tol = Max(BT.Tolerance(V1l), BT.Tolerance(V2l));
327 Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l));
328 if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) {
329 B.MakeEdge(Edge4,Iso,Precision::Confusion());
330 }
331 else {
332 B.MakeEdge(Edge4);
333 B.Degenerated(Edge4, Standard_True);
334 }
335 V1l.Orientation(TopAbs_FORWARD);
336 B.Add(Edge4,V1l);
337 V2l.Orientation(TopAbs_REVERSED);
338 B.Add(Edge4,V2l);
339 B.Range(Edge4,f2,l2);
340 }
341
342 // make the wire
343
344 TopoDS_Wire W;
345 B.MakeWire(W);
346
347 Edge3.Reverse();
348 B.Add(W,Edge1);
349 B.Add(W,Edge4);
350 B.Add(W,Edge2.Reversed());
351 B.Add(W,Edge3);
352
353 B.Add(Face,W);
354
355 // set the pcurves
356
357 Standard_Real T = Precision::Confusion();
358
359 if ( Edge1.Orientation() == TopAbs_REVERSED ) {
360 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),Face,T);
361 B.Range(Edge1,Face,-l1,-f1);
362 }
363 else {
364 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),Face,T);
365 B.Range(Edge1,Face,f1,l1);
366 }
367
368 if ( Edge2.Orientation() == TopAbs_REVERSED ) {
369 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),Face,T);
370 B.Range(Edge2,Face,-l1,-f1);
371 }
372 else {
373 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),Face,T);
374 B.Range(Edge2,Face,f1,l1);
375 }
376
377 if ( Closed) {
378 B.UpdateEdge(Edge3,
379 new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
380 new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
381 }
382 else {
383 B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
384 B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
385 }
386
387 // Set the non parameter flag;
388 B.SameParameter(Edge1,Standard_False);
389 B.SameParameter(Edge2,Standard_False);
390 B.SameParameter(Edge3,Standard_False);
391 B.SameParameter(Edge4,Standard_False);
392 B.SameRange(Edge1,Standard_False);
393 B.SameRange(Edge2,Standard_False);
394 B.SameRange(Edge3,Standard_False);
395 B.SameRange(Edge4,Standard_False);
396
397 BRepLib::SameParameter(Face);
398
399 if ( SameLoc) Face.Move(L);
400 return Face;
401}
402
403
404//=======================================================================
405//function : Shell
406//purpose :
407//=======================================================================
408
409TopoDS_Shell BRepFill::Shell(const TopoDS_Wire& Wire1,
410 const TopoDS_Wire& Wire2 )
411{
412 TopoDS_Shell Shell;
413 TopoDS_Face Face;
414 TopoDS_Shape S1, S2;
415 TopoDS_Edge Edge1, Edge2, Edge3, Edge4, Couture;
416
417 BRep_Builder B;
418// Class BRep_Tool without fields and without Constructor :
419// BRep_Tool BT;
420 B.MakeShell(Shell);
421
422 TopExp_Explorer ex1;
423 TopExp_Explorer ex2;
424
425 Standard_Boolean Closed = Wire1.Closed() && Wire2.Closed();
426
427 Standard_Boolean thefirst = Standard_True;
428
429 ex1.Init(Wire1,TopAbs_EDGE);
430 ex2.Init(Wire2,TopAbs_EDGE);
431
432 while ( ex1.More() && ex2.More() ) {
433
434 Edge1 = TopoDS::Edge(ex1.Current());
435 Edge2 = TopoDS::Edge(ex2.Current());
436
437 Standard_Boolean Periodic = Edge1.Closed() && Edge2.Closed();
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
566 B.Add(Face,W);
567
568 if ( SameLoc) Face.Move( L);
569
570 B.Add(Shell,Face);
571
572 // set the pcurves
573
574 Standard_Real T = Precision::Confusion();
575
576 if ( Edge1.Orientation() == TopAbs_REVERSED ) {
577 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),
578 Face,T);
579 B.Range(Edge1,Face,-l1,-f1);
580 }
581 else {
582 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
583 Face,T);
584 B.Range(Edge1,Face,f1,l1);
585 }
586
587 if ( Edge2.Orientation() == TopAbs_REVERSED ) {
588 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),
589 Face,T);
590 B.Range(Edge2,Face,-l1,-f1);
591 }
592 else {
593 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),
594 Face,T);
595 B.Range(Edge2,Face,f1,l1);
596 }
597
598 if ( Periodic) {
599 B.UpdateEdge(Edge3,
600 new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
601 new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),
602 Face,T);
603 }
604 else {
605 B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
606 B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
607 }
608
609 // Set the non parameter flag;
610 B.SameParameter(Edge1,Standard_False);
611 B.SameParameter(Edge2,Standard_False);
612 B.SameParameter(Edge3,Standard_False);
613 B.SameParameter(Edge4,Standard_False);
614 B.SameRange(Edge1,Standard_False);
615 B.SameRange(Edge2,Standard_False);
616 B.SameRange(Edge3,Standard_False);
617 B.SameRange(Edge4,Standard_False);
618 }
619
620 BRepLib::SameParameter(Shell);
621 return Shell;
622}
623
624//=======================================================================
625//function : Axe
626//purpose :
627//=======================================================================
628
629void BRepFill::Axe (const TopoDS_Shape& Spine,
630 const TopoDS_Wire& Profile,
631 gp_Ax3& AxeProf,
632 Standard_Boolean& ProfOnSpine,
633 const Standard_Real Tol)
634{
635 gp_Pnt Loc,Loc1,Loc2;
636 gp_Vec Tang,Tang1,Tang2,Normal;
637
638 Handle(Geom_Surface) S;
639 TopLoc_Location L;
640
641 TopoDS_Face aFace;
642
0d969553 643 // normal to the Spine.
7fd59977 644 if (Spine.ShapeType() == TopAbs_FACE) {
645 aFace = TopoDS::Face(Spine);
646 S = BRep_Tool::Surface(TopoDS::Face(Spine), L);
647 if ( !S->IsKind(STANDARD_TYPE(Geom_Plane))) {
648 BRepLib_FindSurface FS(TopoDS::Face(Spine), -1, Standard_True);
649 if ( FS.Found()) {
650 S = FS.Surface();
651 L = FS.Location();
652 }
653 else {
654 Standard_NoSuchObject::Raise
655 ("BRepFill_Evolved : The Face is not planar");
656 }
657 }
658 }
659 else if (Spine.ShapeType() == TopAbs_WIRE) {
660 aFace = BRepLib_MakeFace(TopoDS::Wire(Spine),Standard_True);
661 S = BRep_Tool::Surface(aFace, L);
662 }
663
664 if (S.IsNull()) Standard_DomainError::Raise("BRepFill_Evolved::Axe");
665
666 if (!L.IsIdentity())
667 S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
668
669 Normal = Handle(Geom_Plane)::DownCast(S)->Pln().Axis().Direction();
670
0d969553 671 // Find vertex of the profile closest to the spine.
7fd59977 672 Standard_Real DistMin = Precision::Infinite();
673 Standard_Real Dist;
674// Standard_Real Tol2 = Tol*Tol;
675 Standard_Real Tol2 = 1.e-10;
676 TopExp_Explorer PE, SE;
677 BRepExtrema_ExtPC BE;
678 Standard_Real Par =0.,f,l;
679// Standard_Real D1,D2;
680 gp_Pnt P1,P2;
681
0d969553 682 // First check if there is contact Vertex Vertex.
7fd59977 683 Standard_Boolean IsOnVertex = Standard_False;
684 SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
685// modified by NIZHNY-EAP Wed Feb 23 12:31:52 2000 ___BEGIN___
686// for (;SE.More() && !IsOnVertex ; SE.Next()) {
687 for (;SE.More(); SE.Next()) {
688 P1 = BRep_Tool::Pnt(TopoDS::Vertex(SE.Current()));
689
690 PE.Init(Profile,TopAbs_VERTEX);
691 for ( ; PE.More(); PE.Next()) {
692 P2 = BRep_Tool::Pnt(TopoDS::Vertex(PE.Current()));
693 Standard_Real DistP1P2 = P1.SquareDistance(P2);
694 IsOnVertex = (DistP1P2 <= Tol2);
695 if (IsOnVertex) break;
696 }
697 // otherwise SE.Next() is done and VonF is wrong
698 if (IsOnVertex) break;
699// modified by NIZHNY-EAP Wed Jan 26 09:08:36 2000 ___END___
700 }
701
702 if (IsOnVertex) {
703 // try to find on which edge which shared this vertex,
704 // the profile must be considered.
705 // E1, E2 : those two edges.
706 TopTools_IndexedDataMapOfShapeListOfShape Map;
707 TopExp::MapShapesAndAncestors(aFace.Oriented(TopAbs_FORWARD),
708 TopAbs_VERTEX,
709 TopAbs_EDGE,
710 Map);
711
712 const TopoDS_Vertex& VonF = TopoDS::Vertex(SE.Current());
713 const TopTools_ListOfShape& List = Map.FindFromKey(VonF);
714 const TopoDS_Edge& E1 = TopoDS::Edge(List.First());
715 const TopoDS_Edge& E2 = TopoDS::Edge(List. Last());
716
717 Handle(Geom_Curve) CE1 = BRep_Tool::Curve(E1,L,f,l);
718 Standard_Real Par1 = BRep_Tool::Parameter(VonF,E1,aFace);
719 CE1->D1(Par1,Loc1,Tang1);
720 if (!L.IsIdentity()) {
721 Tang1.Transform(L.Transformation());
722 Loc1.Transform(L.Transformation());
723 }
724 if (E1.Orientation() == TopAbs_REVERSED) Tang1.Reverse();
725
726 Handle(Geom_Curve) CE2 = BRep_Tool::Curve(E2,L,f,l);
727 Standard_Real Par2 = BRep_Tool::Parameter(VonF,E2,aFace);
728 CE2->D1(Par2,Loc2,Tang2);
729 if (!L.IsIdentity()) {
730 Tang2.Transform(L.Transformation());
731 Loc2.Transform(L.Transformation());
732 }
733 if (E2.Orientation() == TopAbs_REVERSED) Tang2.Reverse();
734
735// modified by NIZHNY-EAP Wed Feb 2 15:38:41 2000 ___BEGIN___
736 Tang1.Normalize();
737 Tang2.Normalize();
738 Standard_Real sca1=0., sca2=0.;
739 TopoDS_Vertex V1, V2;
740 TopoDS_Edge E;
741 for (PE.Init(Profile,TopAbs_EDGE); PE.More(); PE.Next()) {
742 E = TopoDS::Edge(PE.Current());
743 TopExp::Vertices(E, V1, V2);
744 P1 = BRep_Tool::Pnt(V1);
745 P2 = BRep_Tool::Pnt(V2);
746 gp_Vec vec(P1,P2);
747 sca1 += Abs(Tang1.Dot(vec));
748 sca2 += Abs(Tang2.Dot(vec));
749 }
750// modified by NIZHNY-EAP Wed Feb 2 15:38:44 2000 ___END___
751
752 if ( Abs(sca1) < Abs(sca2)) {
753 Loc = Loc1;
754 Tang = Tang1;
755 }
756 else {
757 Loc = Loc2;
758 Tang = Tang2;
759 }
760 DistMin = 0.;
761 }
762 else {
763 SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
764 for ( ; SE.More(); SE.Next()) {
765 const TopoDS_Edge& E = TopoDS::Edge(SE.Current());
766 BE.Initialize(E);
767 for (PE.Init(Profile,TopAbs_VERTEX) ; PE.More(); PE.Next()) {
768 Dist = Precision::Infinite();
769 const TopoDS_Vertex& V = TopoDS::Vertex(PE.Current());
770 BE.Perform(V);
771 if (BE.IsDone()) {
772 // extrema.
773 for (Standard_Integer i = 1; i <= BE.NbExt(); i++) {
774 if (BE.IsMin(i)) {
775 Dist = sqrt (BE.SquareDistance(i));
776 Par = BE.Parameter(i);
777 break;
778 }
779 }
780 }
0d969553 781 // save minimum.
7fd59977 782 if (Dist < DistMin) {
783 DistMin = Dist;
784 BRepAdaptor_Curve BAC(E);
785 BAC.D1 (Par,Loc,Tang);
786 if (E.Orientation() == TopAbs_REVERSED) Tang.Reverse();
787 }
788 }
789 }
790 }
791
792 ProfOnSpine = (DistMin < Tol);
793 //Construction AxeProf;
794 gp_Ax3 A3 (Loc,Normal,Tang);
795 AxeProf = A3;
796
797}
798
799//=======================================================================
800//function : SearchOrigin
0d969553 801//purpose : Cut and orientate a closed wire.
7fd59977 802//=======================================================================
803
804void BRepFill::SearchOrigin(TopoDS_Wire & W,
805 const gp_Pnt& P,
806 const gp_Vec& Dir,
807 const Standard_Real Tol)
808{
809 if (!W.Closed())
810 Standard_NoSuchObject::
811 Raise("BRepFill::SearchOrigin : the wire must be closed");
812
813
814 Standard_Boolean NewVertex = Standard_False;
815 Standard_Real theparam = 1.e101, angle;
816 TopoDS_Vertex V ;
817 TopoDS_Edge E, Eref, E1 , E2;
818 BRep_Builder B;
819// Class BRep_Tool without fields and without Constructor :
820// BRep_Tool BT;
821
0d969553 822 W.Orientation(TopAbs_FORWARD); //to avoid composing the orientations
7fd59977 823
0d969553 824 // Calculate the distance
7fd59977 825 B.MakeVertex(V, P, Tol);
826 BRepExtrema_DistShapeShape DSS(V, W);
827 if (DSS.IsDone()) {
828 Standard_Integer isol = 1;
829 Standard_Real dss = P.Distance(DSS.PointOnShape2(isol));
830 for (Standard_Integer iss=2; iss<=DSS.NbSolution(); iss++)
831 if (dss > P.Distance(DSS.PointOnShape2(iss))) {
832 dss = P.Distance(DSS.PointOnShape2(iss));
833 isol = iss;
834 }
835 TopoDS_Shape supp = DSS.SupportOnShape2(isol);
836 if (DSS.SupportTypeShape2(isol)==BRepExtrema_IsVertex) {
837 V = TopoDS::Vertex(supp);
838 }
839 else {
840 TopoDS_Vertex Vf, Vl;
841 Standard_Real d, dist;
842 E = TopoDS::Edge(supp);
843 TopExp::Vertices(E, Vf, Vl);
844// dist = P.Distance(BT.Pnt(Vf));
845 dist = P.Distance(BRep_Tool::Pnt(Vf));
846 if (dist < Tol) {
847 V = Vl;
848 }
849// d = P.Distance(BT.Pnt(Vl));
850 d = P.Distance(BRep_Tool::Pnt(Vl));
851 if ((d<Tol) && (d<dist)) {
852 V = Vf;
853 dist = d;
854 }
855 NewVertex = (dist > Tol);
856 if (NewVertex) {
857 DSS.ParOnEdgeS2(isol, theparam);
858 }
859 }
860 }
861#if DEB
862 else {
863 cout << "BRepFill::SearchOrigine : Echec Distance" << endl;
864 }
865#endif
866
867 Standard_Integer ii, rangdeb=0, NbEdges=0;
868 Standard_Boolean forward;
869 BRepTools_WireExplorer exp;
870
0d969553 871 // Calculate the number of edges
7fd59977 872 for(exp.Init(W); exp.More(); exp.Next()) NbEdges++;
873 if (NewVertex) {
874 NbEdges++;
875 Eref = E;
876 }
877
0d969553 878 // Construct the Table and calculate rangdeb
7fd59977 879 TopTools_Array1OfShape Edges(1, NbEdges);
880 for(exp.Init(W), ii=1; exp.More(); exp.Next(), ii++) {
881 E = exp.Current();
882 if (NewVertex && E.IsSame(Eref)) {
883 TopoDS_Edge E1, E2;
884 CutEdge(E, theparam, E1, E2, exp.CurrentVertex());
885 Edges(ii) = E1;
886 ii++;
887 Edges(ii) = E2;
888 rangdeb = ii;
889 }
890 else {
891 Edges(ii) = E;
892 }
893 if (!NewVertex && V.IsSame(exp.CurrentVertex())) {
894 rangdeb = ii;
895 }
896 }
897 if (rangdeb == 0) rangdeb = NbEdges;
898
0d969553 899 // Calculate the direction of parsing
7fd59977 900 E = TopoDS::Edge(Edges(rangdeb));
901 if (!NewVertex) {
902// theparam = BT.Parameter(V, E);
903 theparam = BRep_Tool::Parameter(V, E);
904 }
905 BRepAdaptor_Curve AC(E);
906 gp_Pnt Pe;
907 gp_Vec Ve;
908 AC.D1(theparam, Pe, Ve);
909 if (E.Orientation()==TopAbs_REVERSED) {
910 Ve *= -1;
911 }
912 angle = Ve.Angle(Dir);
c6541a0c
D
913 if (angle > M_PI) angle = 2*M_PI - angle;
914 forward = (angle <= M_PI/2);
7fd59977 915
916 // Reconstruction
917 MakeWire( Edges, rangdeb, forward, W);
918 W.Closed(Standard_True);
919}
920
921
922
923//=======================================================================
924//function : ComputeACR
925//purpose :
926//=======================================================================
927
928void BRepFill::ComputeACR(const TopoDS_Wire& wire,
929 TColStd_Array1OfReal& ACR)
930{
0d969553 931 // calculate the reduced curvilinear abscisses and the length of the wire
7fd59977 932 BRepTools_WireExplorer anExp;
933 Standard_Integer nbEdges=0, i;
934
0d969553 935 // cumulated lengths
7fd59977 936 ACR.Init(0);
937 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
938 nbEdges++;
939 TopoDS_Edge Ecur = TopoDS::Edge(anExp.Current());
940 ACR(nbEdges) = ACR(nbEdges-1);
941 if (!BRep_Tool::Degenerated(Ecur)) {
942 BRepAdaptor_Curve anEcur(Ecur);
943 ACR(nbEdges) += GCPnts_AbscissaPoint::Length(anEcur);
944 }
945 }
946
0d969553 947 // total length of the wire
7fd59977 948 ACR(0) = ACR(nbEdges);
949
0d969553 950 // reduced curvilinear abscisses
7fd59977 951 if (ACR(0)>Precision::Confusion()) {
952 for (i=1; i<=nbEdges; i++) {
953 ACR(i) /= ACR(0);
954 }
955 }
956 else {
0d969553 957 // punctual wire
7fd59977 958 ACR(nbEdges) = 1;
959 }
960
961}
962
963//=======================================================================
964//function : InsertACR
965//purpose :
966//=======================================================================
967
968TopoDS_Wire BRepFill::InsertACR(const TopoDS_Wire& wire,
969 const TColStd_Array1OfReal& ACRcuts,
970 const Standard_Real prec)
971{
0d969553 972 // calculate ACR of the wire to be cut
7fd59977 973 BRepTools_WireExplorer anExp;
974 Standard_Integer nbEdges=0;
975 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
976 nbEdges++;
977 }
978 TColStd_Array1OfReal ACRwire(0,nbEdges);
979 ComputeACR(wire, ACRwire);
980
981 Standard_Integer i, j, nmax=ACRcuts.Length();
982 TColStd_Array1OfReal paradec(1,nmax);
983 BRepLib_MakeWire MW;
984
985 Standard_Real t0,t1=0;
986 nbEdges=0;
987
0d969553 988 // processing edge by edge
7fd59977 989 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
990 nbEdges++;
991 t0 = t1;
992 t1 = ACRwire(nbEdges);
993
0d969553 994 // parameters of cut on this edge
7fd59977 995 Standard_Integer ndec=0;
996 for (i=1; i<=ACRcuts.Length(); i++ ) {
997 if (t0+prec<ACRcuts(i) && ACRcuts(i)<t1-prec) {
998 ndec++;
999 paradec(ndec) = ACRcuts(i);
1000 }
1001 }
1002
1003 TopoDS_Edge E = anExp.Current();
1004 TopoDS_Vertex V = anExp.CurrentVertex();
1005
1006 if (ndec==0 || BRep_Tool::Degenerated(E)) {
0d969553 1007 // copy the edge
7fd59977 1008 MW.Add(E);
1009 }
1010 else {
0d969553
Y
1011 // it is necessary to cut the edge
1012 // following the direction of parsing of the wire
7fd59977 1013 Standard_Boolean SO = (V.IsSame(TopExp::FirstVertex(E)));
1014 TopTools_SequenceOfShape SE;
1015 SE.Clear();
1016 TColStd_SequenceOfReal SR;
1017 SR.Clear();
0d969553
Y
1018 // the wire is always FORWARD
1019 // it is necesary to modify the parameter of cut6 if the edge is REVERSED
7fd59977 1020 if (E.Orientation() == TopAbs_FORWARD) {
1021 for (j=1; j<=ndec; j++) SR.Append(paradec(j));
1022 }
1023 else {
1024 for (j=1; j<=ndec; j++) SR.Append(t0+t1-paradec(ndec+1-j));
1025 }
1026 TrimEdge(E,SR,t0,t1,SO,SE);
1027 for (j=1; j<=SE.Length(); j++) {
1028 MW.Add(TopoDS::Edge(SE.Value(j)));
1029 }
1030 }
1031 }
1032
0d969553 1033 // result
7fd59977 1034 TopAbs_Orientation Orien = wire.Orientation();
1035 TopoDS_Shape aLocalShape = MW.Wire();
1036 aLocalShape.Orientation(Orien);
1037 TopoDS_Wire wres = TopoDS::Wire(aLocalShape);
1038// TopoDS_Wire wres = TopoDS::Wire(MW.Wire().Oriented(Orien));
1039 return wres;
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
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084