0024002: Overall code and build procedure refactoring -- automatic
[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//
d5f74e42 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
973c2be1 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
42cf5bc1 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>
7fd59977 44#include <BRepLib.hxx>
45#include <BRepLib_FindSurface.hxx>
7fd59977 46#include <BRepLib_MakeEdge.hxx>
42cf5bc1 47#include <BRepLib_MakeFace.hxx>
7fd59977 48#include <BRepLib_MakeVertex.hxx>
49#include <BRepLib_MakeWire.hxx>
42cf5bc1 50#include <BRepLProp.hxx>
7fd59977 51#include <BRepTools_WireExplorer.hxx>
42cf5bc1 52#include <GCPnts_AbscissaPoint.hxx>
53#include <Geom2d_Line.hxx>
7fd59977 54#include <Geom_Curve.hxx>
7fd59977 55#include <Geom_Plane.hxx>
42cf5bc1 56#include <Geom_Surface.hxx>
57#include <Geom_TrimmedCurve.hxx>
7fd59977 58#include <GeomAdaptor_Curve.hxx>
42cf5bc1 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>
7fd59977 70#include <GProp_GProps.hxx>
71#include <GProp_PrincipalProps.hxx>
42cf5bc1 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>
7fd59977 86#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
42cf5bc1 87#include <TopTools_DataMapOfShapeListOfShape.hxx>
88#include <TopTools_HSequenceOfShape.hxx>
89#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
90#include <TopTools_IndexedMapOfShape.hxx>
7fd59977 91#include <TopTools_ListIteratorOfListOfShape.hxx>
92#include <TopTools_ListOfShape.hxx>
7fd59977 93#include <TopTools_SequenceOfShape.hxx>
7fd59977 94
95static 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);
ab860031 124 newwire.Closed (Standard_True);
7fd59977 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);
7fd59977 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);
7fd59977 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);
ab860031 350 W.Closed (Standard_True);
7fd59977 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
408TopoDS_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
da72a17c 436 Standard_Boolean Periodic =
437 BRep_Tool::IsClosed(Edge1) && BRep_Tool::IsClosed(Edge2);
7fd59977 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);
ab860031 565 W.Closed (Standard_True);
7fd59977 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
ab860031 621 Shell.Closed (BRep_Tool::IsClosed (Shell));
7fd59977 622 BRepLib::SameParameter(Shell);
623 return Shell;
624}
625
626//=======================================================================
627//function : Axe
628//purpose :
629//=======================================================================
630
631void 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
0d969553 645 // normal to the Spine.
7fd59977 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 Standard_NoSuchObject::Raise
657 ("BRepFill_Evolved : The Face is not planar");
658 }
659 }
660 }
661 else if (Spine.ShapeType() == TopAbs_WIRE) {
662 aFace = BRepLib_MakeFace(TopoDS::Wire(Spine),Standard_True);
663 S = BRep_Tool::Surface(aFace, L);
664 }
665
666 if (S.IsNull()) Standard_DomainError::Raise("BRepFill_Evolved::Axe");
667
668 if (!L.IsIdentity())
669 S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
670
671 Normal = Handle(Geom_Plane)::DownCast(S)->Pln().Axis().Direction();
672
0d969553 673 // Find vertex of the profile closest to the spine.
7fd59977 674 Standard_Real DistMin = Precision::Infinite();
675 Standard_Real Dist;
676// Standard_Real Tol2 = Tol*Tol;
677 Standard_Real Tol2 = 1.e-10;
678 TopExp_Explorer PE, SE;
679 BRepExtrema_ExtPC BE;
680 Standard_Real Par =0.,f,l;
681// Standard_Real D1,D2;
682 gp_Pnt P1,P2;
683
0d969553 684 // First check if there is contact Vertex Vertex.
7fd59977 685 Standard_Boolean IsOnVertex = Standard_False;
686 SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_VERTEX);
687// modified by NIZHNY-EAP Wed Feb 23 12:31:52 2000 ___BEGIN___
688// for (;SE.More() && !IsOnVertex ; SE.Next()) {
689 for (;SE.More(); SE.Next()) {
690 P1 = BRep_Tool::Pnt(TopoDS::Vertex(SE.Current()));
691
692 PE.Init(Profile,TopAbs_VERTEX);
693 for ( ; PE.More(); PE.Next()) {
694 P2 = BRep_Tool::Pnt(TopoDS::Vertex(PE.Current()));
695 Standard_Real DistP1P2 = P1.SquareDistance(P2);
696 IsOnVertex = (DistP1P2 <= Tol2);
697 if (IsOnVertex) break;
698 }
699 // otherwise SE.Next() is done and VonF is wrong
700 if (IsOnVertex) break;
701// modified by NIZHNY-EAP Wed Jan 26 09:08:36 2000 ___END___
702 }
703
704 if (IsOnVertex) {
705 // try to find on which edge which shared this vertex,
706 // the profile must be considered.
707 // E1, E2 : those two edges.
708 TopTools_IndexedDataMapOfShapeListOfShape Map;
709 TopExp::MapShapesAndAncestors(aFace.Oriented(TopAbs_FORWARD),
710 TopAbs_VERTEX,
711 TopAbs_EDGE,
712 Map);
713
714 const TopoDS_Vertex& VonF = TopoDS::Vertex(SE.Current());
715 const TopTools_ListOfShape& List = Map.FindFromKey(VonF);
716 const TopoDS_Edge& E1 = TopoDS::Edge(List.First());
717 const TopoDS_Edge& E2 = TopoDS::Edge(List. Last());
718
719 Handle(Geom_Curve) CE1 = BRep_Tool::Curve(E1,L,f,l);
720 Standard_Real Par1 = BRep_Tool::Parameter(VonF,E1,aFace);
721 CE1->D1(Par1,Loc1,Tang1);
722 if (!L.IsIdentity()) {
723 Tang1.Transform(L.Transformation());
724 Loc1.Transform(L.Transformation());
725 }
726 if (E1.Orientation() == TopAbs_REVERSED) Tang1.Reverse();
727
728 Handle(Geom_Curve) CE2 = BRep_Tool::Curve(E2,L,f,l);
729 Standard_Real Par2 = BRep_Tool::Parameter(VonF,E2,aFace);
730 CE2->D1(Par2,Loc2,Tang2);
731 if (!L.IsIdentity()) {
732 Tang2.Transform(L.Transformation());
733 Loc2.Transform(L.Transformation());
734 }
735 if (E2.Orientation() == TopAbs_REVERSED) Tang2.Reverse();
736
737// modified by NIZHNY-EAP Wed Feb 2 15:38:41 2000 ___BEGIN___
738 Tang1.Normalize();
739 Tang2.Normalize();
740 Standard_Real sca1=0., sca2=0.;
741 TopoDS_Vertex V1, V2;
742 TopoDS_Edge E;
743 for (PE.Init(Profile,TopAbs_EDGE); PE.More(); PE.Next()) {
744 E = TopoDS::Edge(PE.Current());
745 TopExp::Vertices(E, V1, V2);
746 P1 = BRep_Tool::Pnt(V1);
747 P2 = BRep_Tool::Pnt(V2);
748 gp_Vec vec(P1,P2);
749 sca1 += Abs(Tang1.Dot(vec));
750 sca2 += Abs(Tang2.Dot(vec));
751 }
752// modified by NIZHNY-EAP Wed Feb 2 15:38:44 2000 ___END___
753
754 if ( Abs(sca1) < Abs(sca2)) {
755 Loc = Loc1;
756 Tang = Tang1;
757 }
758 else {
759 Loc = Loc2;
760 Tang = Tang2;
761 }
762 DistMin = 0.;
763 }
764 else {
765 SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
766 for ( ; SE.More(); SE.Next()) {
767 const TopoDS_Edge& E = TopoDS::Edge(SE.Current());
768 BE.Initialize(E);
769 for (PE.Init(Profile,TopAbs_VERTEX) ; PE.More(); PE.Next()) {
770 Dist = Precision::Infinite();
771 const TopoDS_Vertex& V = TopoDS::Vertex(PE.Current());
772 BE.Perform(V);
773 if (BE.IsDone()) {
774 // extrema.
775 for (Standard_Integer i = 1; i <= BE.NbExt(); i++) {
776 if (BE.IsMin(i)) {
777 Dist = sqrt (BE.SquareDistance(i));
778 Par = BE.Parameter(i);
779 break;
780 }
781 }
782 }
0d969553 783 // save minimum.
7fd59977 784 if (Dist < DistMin) {
785 DistMin = Dist;
786 BRepAdaptor_Curve BAC(E);
787 BAC.D1 (Par,Loc,Tang);
788 if (E.Orientation() == TopAbs_REVERSED) Tang.Reverse();
789 }
790 }
791 }
792 }
793
794 ProfOnSpine = (DistMin < Tol);
795 //Construction AxeProf;
796 gp_Ax3 A3 (Loc,Normal,Tang);
797 AxeProf = A3;
798
799}
800
801//=======================================================================
802//function : SearchOrigin
0d969553 803//purpose : Cut and orientate a closed wire.
7fd59977 804//=======================================================================
805
806void BRepFill::SearchOrigin(TopoDS_Wire & W,
807 const gp_Pnt& P,
808 const gp_Vec& Dir,
809 const Standard_Real Tol)
810{
811 if (!W.Closed())
812 Standard_NoSuchObject::
813 Raise("BRepFill::SearchOrigin : the wire must be closed");
814
815
816 Standard_Boolean NewVertex = Standard_False;
817 Standard_Real theparam = 1.e101, angle;
818 TopoDS_Vertex V ;
819 TopoDS_Edge E, Eref, E1 , E2;
820 BRep_Builder B;
821// Class BRep_Tool without fields and without Constructor :
822// BRep_Tool BT;
823
0d969553 824 W.Orientation(TopAbs_FORWARD); //to avoid composing the orientations
7fd59977 825
0d969553 826 // Calculate the distance
7fd59977 827 B.MakeVertex(V, P, Tol);
828 BRepExtrema_DistShapeShape DSS(V, W);
829 if (DSS.IsDone()) {
830 Standard_Integer isol = 1;
831 Standard_Real dss = P.Distance(DSS.PointOnShape2(isol));
832 for (Standard_Integer iss=2; iss<=DSS.NbSolution(); iss++)
833 if (dss > P.Distance(DSS.PointOnShape2(iss))) {
834 dss = P.Distance(DSS.PointOnShape2(iss));
835 isol = iss;
836 }
837 TopoDS_Shape supp = DSS.SupportOnShape2(isol);
838 if (DSS.SupportTypeShape2(isol)==BRepExtrema_IsVertex) {
839 V = TopoDS::Vertex(supp);
840 }
841 else {
842 TopoDS_Vertex Vf, Vl;
843 Standard_Real d, dist;
844 E = TopoDS::Edge(supp);
845 TopExp::Vertices(E, Vf, Vl);
846// dist = P.Distance(BT.Pnt(Vf));
847 dist = P.Distance(BRep_Tool::Pnt(Vf));
848 if (dist < Tol) {
849 V = Vl;
850 }
851// d = P.Distance(BT.Pnt(Vl));
852 d = P.Distance(BRep_Tool::Pnt(Vl));
853 if ((d<Tol) && (d<dist)) {
854 V = Vf;
855 dist = d;
856 }
857 NewVertex = (dist > Tol);
858 if (NewVertex) {
859 DSS.ParOnEdgeS2(isol, theparam);
860 }
861 }
862 }
0797d9d3 863#ifdef OCCT_DEBUG
7fd59977 864 else {
865 cout << "BRepFill::SearchOrigine : Echec Distance" << endl;
866 }
867#endif
868
869 Standard_Integer ii, rangdeb=0, NbEdges=0;
870 Standard_Boolean forward;
871 BRepTools_WireExplorer exp;
872
0d969553 873 // Calculate the number of edges
7fd59977 874 for(exp.Init(W); exp.More(); exp.Next()) NbEdges++;
875 if (NewVertex) {
876 NbEdges++;
877 Eref = E;
878 }
879
0d969553 880 // Construct the Table and calculate rangdeb
7fd59977 881 TopTools_Array1OfShape Edges(1, NbEdges);
882 for(exp.Init(W), ii=1; exp.More(); exp.Next(), ii++) {
883 E = exp.Current();
884 if (NewVertex && E.IsSame(Eref)) {
885 TopoDS_Edge E1, E2;
886 CutEdge(E, theparam, E1, E2, exp.CurrentVertex());
887 Edges(ii) = E1;
888 ii++;
889 Edges(ii) = E2;
890 rangdeb = ii;
891 }
892 else {
893 Edges(ii) = E;
894 }
895 if (!NewVertex && V.IsSame(exp.CurrentVertex())) {
896 rangdeb = ii;
897 }
898 }
899 if (rangdeb == 0) rangdeb = NbEdges;
900
0d969553 901 // Calculate the direction of parsing
7fd59977 902 E = TopoDS::Edge(Edges(rangdeb));
903 if (!NewVertex) {
904// theparam = BT.Parameter(V, E);
905 theparam = BRep_Tool::Parameter(V, E);
906 }
907 BRepAdaptor_Curve AC(E);
908 gp_Pnt Pe;
909 gp_Vec Ve;
910 AC.D1(theparam, Pe, Ve);
911 if (E.Orientation()==TopAbs_REVERSED) {
912 Ve *= -1;
913 }
914 angle = Ve.Angle(Dir);
c6541a0c
D
915 if (angle > M_PI) angle = 2*M_PI - angle;
916 forward = (angle <= M_PI/2);
7fd59977 917
918 // Reconstruction
919 MakeWire( Edges, rangdeb, forward, W);
920 W.Closed(Standard_True);
921}
922
923
924
925//=======================================================================
926//function : ComputeACR
927//purpose :
928//=======================================================================
929
930void BRepFill::ComputeACR(const TopoDS_Wire& wire,
931 TColStd_Array1OfReal& ACR)
932{
0d969553 933 // calculate the reduced curvilinear abscisses and the length of the wire
7fd59977 934 BRepTools_WireExplorer anExp;
935 Standard_Integer nbEdges=0, i;
936
0d969553 937 // cumulated lengths
7fd59977 938 ACR.Init(0);
939 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
940 nbEdges++;
941 TopoDS_Edge Ecur = TopoDS::Edge(anExp.Current());
942 ACR(nbEdges) = ACR(nbEdges-1);
943 if (!BRep_Tool::Degenerated(Ecur)) {
944 BRepAdaptor_Curve anEcur(Ecur);
945 ACR(nbEdges) += GCPnts_AbscissaPoint::Length(anEcur);
946 }
947 }
948
0d969553 949 // total length of the wire
7fd59977 950 ACR(0) = ACR(nbEdges);
951
0d969553 952 // reduced curvilinear abscisses
7fd59977 953 if (ACR(0)>Precision::Confusion()) {
954 for (i=1; i<=nbEdges; i++) {
955 ACR(i) /= ACR(0);
956 }
957 }
958 else {
0d969553 959 // punctual wire
7fd59977 960 ACR(nbEdges) = 1;
961 }
962
963}
964
965//=======================================================================
966//function : InsertACR
967//purpose :
968//=======================================================================
969
970TopoDS_Wire BRepFill::InsertACR(const TopoDS_Wire& wire,
971 const TColStd_Array1OfReal& ACRcuts,
972 const Standard_Real prec)
973{
0d969553 974 // calculate ACR of the wire to be cut
7fd59977 975 BRepTools_WireExplorer anExp;
976 Standard_Integer nbEdges=0;
977 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
978 nbEdges++;
979 }
980 TColStd_Array1OfReal ACRwire(0,nbEdges);
981 ComputeACR(wire, ACRwire);
982
983 Standard_Integer i, j, nmax=ACRcuts.Length();
984 TColStd_Array1OfReal paradec(1,nmax);
985 BRepLib_MakeWire MW;
986
987 Standard_Real t0,t1=0;
988 nbEdges=0;
989
0d969553 990 // processing edge by edge
7fd59977 991 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
992 nbEdges++;
993 t0 = t1;
994 t1 = ACRwire(nbEdges);
995
0d969553 996 // parameters of cut on this edge
7fd59977 997 Standard_Integer ndec=0;
998 for (i=1; i<=ACRcuts.Length(); i++ ) {
999 if (t0+prec<ACRcuts(i) && ACRcuts(i)<t1-prec) {
1000 ndec++;
1001 paradec(ndec) = ACRcuts(i);
1002 }
1003 }
1004
1005 TopoDS_Edge E = anExp.Current();
1006 TopoDS_Vertex V = anExp.CurrentVertex();
1007
1008 if (ndec==0 || BRep_Tool::Degenerated(E)) {
0d969553 1009 // copy the edge
7fd59977 1010 MW.Add(E);
1011 }
1012 else {
0d969553
Y
1013 // it is necessary to cut the edge
1014 // following the direction of parsing of the wire
7fd59977 1015 Standard_Boolean SO = (V.IsSame(TopExp::FirstVertex(E)));
1016 TopTools_SequenceOfShape SE;
1017 SE.Clear();
1018 TColStd_SequenceOfReal SR;
1019 SR.Clear();
0d969553
Y
1020 // the wire is always FORWARD
1021 // it is necesary to modify the parameter of cut6 if the edge is REVERSED
7fd59977 1022 if (E.Orientation() == TopAbs_FORWARD) {
1023 for (j=1; j<=ndec; j++) SR.Append(paradec(j));
1024 }
1025 else {
1026 for (j=1; j<=ndec; j++) SR.Append(t0+t1-paradec(ndec+1-j));
1027 }
1028 TrimEdge(E,SR,t0,t1,SO,SE);
1029 for (j=1; j<=SE.Length(); j++) {
1030 MW.Add(TopoDS::Edge(SE.Value(j)));
1031 }
1032 }
1033 }
1034
0d969553 1035 // result
7fd59977 1036 TopAbs_Orientation Orien = wire.Orientation();
1037 TopoDS_Shape aLocalShape = MW.Wire();
1038 aLocalShape.Orientation(Orien);
1039 TopoDS_Wire wres = TopoDS::Wire(aLocalShape);
1040// TopoDS_Wire wres = TopoDS::Wire(MW.Wire().Oriented(Orien));
1041 return wres;
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