Integration of OCCT 6.5.0 from SVN
[occt.git] / src / BRepFill / BRepFill.cxx
CommitLineData
7fd59977 1// File: BRepFill.cxx
2// Created: Thu Mar 3 11:18:14 1994
3// Author: Bruno DUMORTIER
4// <dub@fuegox>
5// Modified: Mon Jan 12 10:50:10 1998
6// Author: Joelle CHAUVET
7// <jct@sgi64>
8// gestion automatique de l'origine et de l'orientation
9// avec la methode Organize
10// Modified: Mon Feb 23 09:28:46 1998
11// Author: Joelle CHAUVET
12// <jct@sgi64>
13// methode Organize avec option de projection pour les wires fermes
14// nouvelle methode SameNumber avec option de report des decoupes
15// + utilitaires ComputeACR et InsertACR
16// + traitement du cas derniere section ponctuelle
17// Modified: Thu Apr 30 15:24:17 1998
18// Author: Joelle CHAUVET
19// <jct@sgi64>
20// separation sections fermees / sections ouvertes + debug
21// Organize devient ComputeOrigin et SearchOrigin
22// Modified: Tue Jul 21 16:48:35 1998
23// Author: Joelle CHAUVET
24// <jct@sgi64>
25// cas limite pour Pnext d'ou vrillage (BUC60281)
26// Modified: Thu Jul 23 11:38:36 1998
27// Author: Joelle CHAUVET
28// <jct@sgi64>
29// calcul de l'angle de la rotation dans SearchOrigin
30// Modified: Fri Jul 31 15:14:19 1998
31// Author: Joelle CHAUVET
32// <jct@sgi64>
33// IntersectOnWire + MapVLV
34// Modified: Mon Oct 12 09:42:33 1998
35// Author: Joelle CHAUVET
36// <jct@sgi64>
37// numero des aretes dans EdgesFromVertex (CTS21570)
38
39#include <BRepFill.ixx>
40
41#include <BRepLib.hxx>
42#include <BRepLib_FindSurface.hxx>
43#include <BRepLib_MakeFace.hxx>
44#include <BRepLib_MakeEdge.hxx>
45#include <BRepLib_MakeVertex.hxx>
46#include <BRepLib_MakeWire.hxx>
47#include <BRepExtrema_ExtPC.hxx>
48#include <BRepExtrema_DistShapeShape.hxx>
49#include <BRep_Tool.hxx>
50#include <BRepTools_WireExplorer.hxx>
51
52#include <TopoDS_Face.hxx>
53#include <TopoDS_Wire.hxx>
54#include <TopoDS_Vertex.hxx>
55#include <BRep_Builder.hxx>
56#include <TopLoc_Location.hxx>
57#include <TopExp_Explorer.hxx>
58#include <gp_Vec.hxx>
59#include <gp_Lin.hxx>
60#include <gp_Pln.hxx>
61#include <gp_Pnt2d.hxx>
62#include <gp_Dir.hxx>
63#include <gp_Dir2d.hxx>
64#include <gp_Circ.hxx>
65#include <gp_Elips.hxx>
66#include <Geom_Curve.hxx>
67#include <Geom_TrimmedCurve.hxx>
68#include <Geom_Surface.hxx>
69#include <Geom_Plane.hxx>
70#include <Geom2d_Line.hxx>
71#include <GeomFill_Generator.hxx>
72#include <GeomAdaptor_Curve.hxx>
73#include <BRepLProp.hxx>
74#include <BRepGProp.hxx>
75#include <GProp_GProps.hxx>
76#include <GProp_PrincipalProps.hxx>
77#include <GCPnts_AbscissaPoint.hxx>
78#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
79#include <TopTools_DataMapOfShapeListOfShape.hxx>
80#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
81#include <TopTools_ListIteratorOfListOfShape.hxx>
82#include <TopTools_ListOfShape.hxx>
83#include <TopTools_Array1OfShape.hxx>
84#include <TopTools_SequenceOfShape.hxx>
85#include <TopTools_HSequenceOfShape.hxx>
86#include <BRepAdaptor_Curve.hxx>
87#include <TopTools_IndexedMapOfShape.hxx>
88
89#include <BRep_Tool.hxx>
90#include <TopoDS.hxx>
91#include <TopExp.hxx>
92#include <Precision.hxx>
93
94#include <TColStd_Array1OfInteger.hxx>
95#include <Standard_NoSuchObject.hxx>
96
97
98static void MakeWire(const TopTools_Array1OfShape& Edges,
99 const Standard_Integer rangdeb,
100 const Standard_Boolean forward,
101 TopoDS_Wire& newwire)
102{
103 BRep_Builder BW;
104 Standard_Integer rang, nbEdges = Edges.Length();
105 BW.MakeWire(newwire);
106 if (forward) {
107 for (rang=rangdeb;rang<=nbEdges;rang++) {
108 BW.Add(newwire,TopoDS::Edge(Edges(rang)));
109 }
110 for (rang=1;rang<rangdeb;rang++) {
111 BW.Add(newwire,TopoDS::Edge(Edges(rang)));
112 }
113 }
114
115 else {
116 TopoDS_Edge E;
117 for (rang=rangdeb;rang>=1;rang--) {
118 E = TopoDS::Edge(Edges(rang));
119 BW.Add(newwire,E.Reversed());
120 }
121 for (rang=nbEdges;rang>rangdeb;rang--) {
122 E = TopoDS::Edge(Edges(rang));
123 BW.Add(newwire, E.Reversed());
124 }
125 }
126 newwire.Orientation(TopAbs_FORWARD);
127}
128
129static void CutEdge(const TopoDS_Edge& CurrentEdge,
130 const Standard_Real& Param,
131 TopoDS_Edge& E1,
132 TopoDS_Edge& E2,
133 const TopoDS_Vertex& VRef)
134{
135 BRep_Builder B;
136 Standard_Real first,last;
137 Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
138 TopoDS_Vertex Vf, Vl, Vi;
139 B.MakeVertex(Vi, C->Value(Param), Precision::Confusion());
140 TopExp::Vertices(CurrentEdge, Vf, Vl);
141 if (VRef.IsSame(Vf)) {
142 E1 = BRepLib_MakeEdge(C,Vf,Vi, first,Param);
143 E2 = BRepLib_MakeEdge(C,Vi,Vl, Param,last);
144 }
145 else {
146 E2 = BRepLib_MakeEdge(C,Vf,Vi, first,Param);
147 E1 = BRepLib_MakeEdge(C,Vi,Vl, Param,last);
148 }
149}
150
151
152static void TrimEdge (const TopoDS_Edge& CurrentEdge,
153 const TColStd_SequenceOfReal& CutValues,
154 const Standard_Real t0, const Standard_Real t1,
155 const Standard_Boolean SeqOrder,
156 TopTools_SequenceOfShape& S)
157
158{
159 S.Clear();
160 Standard_Integer j, ndec=CutValues.Length();
161 Standard_Real first,last,m0,m1;
162 Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
163
164 TopoDS_Vertex Vf,Vl,Vbid,V0,V1;
165 TopAbs_Orientation CurrentOrient = CurrentEdge.Orientation();
166 TopExp::Vertices(CurrentEdge,Vf,Vl);
167 Vbid.Nullify();
168
169 if (SeqOrder) {
170 // de first vers last
171 m0 = first;
172 V0 = Vf;
173 for (j=1; j<=ndec; j++) {
174 // morceau d'edge
175 m1 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
176 TopoDS_Edge CutE = BRepLib_MakeEdge(C,V0,Vbid,m0,m1);
177 CutE.Orientation(CurrentOrient);
178 S.Append(CutE);
179 m0 = m1;
180 V0 = TopExp::LastVertex(CutE);
181 if (j==ndec) {
182 // dernier morceau
183 TopoDS_Edge LastE = BRepLib_MakeEdge(C,V0,Vl,m0,last);
184 LastE.Orientation(CurrentOrient);
185 S.Append(LastE);
186 }
187 }
188 }
189 else {
190 // de last vers first
191 m1 = last;
192 V1 = Vl;
193 for (j=ndec; j>=1; j--) {
194 // morceau d'edge
195 m0 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
196 TopoDS_Edge CutE = BRepLib_MakeEdge(C,Vbid,V1,m0,m1);
197 CutE.Orientation(CurrentOrient);
198 S.Append(CutE);
199 m1 = m0;
200 V1 = TopExp::FirstVertex(CutE);
201 if (j==1) {
202 // dernier morceau
203 TopoDS_Edge LastE = BRepLib_MakeEdge(C,Vf,V1,first,m1);
204 LastE.Orientation(CurrentOrient);
205 S.Append(LastE);
206 }
207 }
208 }
209}
210
211
212//=======================================================================
213//function : Face
214//purpose :
215//=======================================================================
216
217TopoDS_Face BRepFill::Face(const TopoDS_Edge& Edge1,
218 const TopoDS_Edge& Edge2 )
219{
220 TopoDS_Face Face;
221
222 BRep_Builder B;
223// Class BRep_Tool without fields and without Constructor :
224// BRep_Tool BT;
225
226 TopLoc_Location L,L1,L2;
227 Standard_Real f1,f2,l1,l2, Tol;
228
229// Handle(Geom_Curve) C1 = BT.Curve(Edge1,L1,f1,l1);
230 Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,L1,f1,l1);
231// Handle(Geom_Curve) C2 = BT.Curve(Edge2,L2,f2,l2);
232 Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,L2,f2,l2);
233
234 // compute the location
235 Standard_Boolean SameLoc = Standard_False;
236 if (L1 == L2) {
237 L = L1;
238 L1 = L2 = TopLoc_Location();
239 SameLoc = Standard_True;
240 }
241
242 // transform and trim the curves
243
244 TopoDS_Vertex V1f,V1l,V2f,V2l;
245
246 // on cree un new Handle
247 if (Abs(f1 - C1->FirstParameter()) > Precision::PConfusion() ||
248 Abs(l1 - C1->LastParameter()) > Precision::PConfusion() ) {
249 C1 = new Geom_TrimmedCurve(C1,f1,l1);
250 }
251 else {
252 C1 = Handle(Geom_Curve)::DownCast(C1->Copy());
253 }
254 // eventuellement on bouge la courbe
255 if ( !SameLoc) {
256 C1->Transform(L1.Transformation());
257 }
258 // on la met dans le bon sens et on prend ses vertex
259 if (Edge1.Orientation() == TopAbs_REVERSED) {
260 TopExp::Vertices(Edge1,V1l,V1f);
261 C1->Reverse();
262 }
263 else {
264 TopExp::Vertices(Edge1,V1f,V1l);
265 }
266
267 // on cree un new Handle
268 if (Abs(f2 - C2->FirstParameter()) > Precision::PConfusion() ||
269 Abs(l2 - C2->LastParameter()) > Precision::PConfusion() ) {
270 C2 = new Geom_TrimmedCurve(C2,f2,l2);
271 }
272 else {
273 C2 = Handle(Geom_Curve)::DownCast(C2->Copy());
274 }
275 // eventuellement on bouge la courbe
276 if ( !SameLoc) {
277 C2->Transform(L2.Transformation());
278 }
279 // on la met dans le bon sens et on prend ses vertex
280 if (Edge2.Orientation() == TopAbs_REVERSED) {
281 TopExp::Vertices(Edge2,V2l,V2f);
282 C2->Reverse();
283 }
284 else {
285 TopExp::Vertices(Edge2,V2f,V2l);
286 }
287
288 // Sont-ce des edges fermes
289 Standard_Boolean Closed = V1f.IsSame(V1l) && V2f.IsSame(V2l);
290
291
292 GeomFill_Generator Generator;
293 Generator.AddCurve( C1);
294 Generator.AddCurve( C2);
295 Generator.Perform( Precision::PConfusion());
296
297 Handle(Geom_Surface) Surf = Generator.Surface();
298 Handle(Geom_Curve) Iso;
299
300 B.MakeFace(Face,Surf,Precision::Confusion());
301
302 // make the missing edges
303 Surf->Bounds(f1,l1,f2,l2);
304
305 TopoDS_Edge Edge3, Edge4;
306
307 Iso = Surf->UIso(f1);
308// Tol = Max(BT.Tolerance(V1f), BT.Tolerance(V2f));
309 Tol = Max(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f));
310 if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) {
311 B.MakeEdge(Edge3,Iso,Precision::Confusion());
312 }
313 else {
314 B.MakeEdge(Edge3);
315 B.Degenerated(Edge3, Standard_True);
316 }
317 V1f.Orientation(TopAbs_FORWARD);
318 B.Add(Edge3,V1f);
319 V2f.Orientation(TopAbs_REVERSED);
320 B.Add(Edge3,V2f);
321 B.Range(Edge3,f2,l2);
322
323 if (Closed) {
324 Edge4 = Edge3;
325 }
326 else {
327 Iso = Surf->UIso(l1);
328// Tol = Max(BT.Tolerance(V1l), BT.Tolerance(V2l));
329 Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l));
330 if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) {
331 B.MakeEdge(Edge4,Iso,Precision::Confusion());
332 }
333 else {
334 B.MakeEdge(Edge4);
335 B.Degenerated(Edge4, Standard_True);
336 }
337 V1l.Orientation(TopAbs_FORWARD);
338 B.Add(Edge4,V1l);
339 V2l.Orientation(TopAbs_REVERSED);
340 B.Add(Edge4,V2l);
341 B.Range(Edge4,f2,l2);
342 }
343
344 // make the wire
345
346 TopoDS_Wire W;
347 B.MakeWire(W);
348
349 Edge3.Reverse();
350 B.Add(W,Edge1);
351 B.Add(W,Edge4);
352 B.Add(W,Edge2.Reversed());
353 B.Add(W,Edge3);
354
355 B.Add(Face,W);
356
357 // set the pcurves
358
359 Standard_Real T = Precision::Confusion();
360
361 if ( Edge1.Orientation() == TopAbs_REVERSED ) {
362 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),Face,T);
363 B.Range(Edge1,Face,-l1,-f1);
364 }
365 else {
366 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),Face,T);
367 B.Range(Edge1,Face,f1,l1);
368 }
369
370 if ( Edge2.Orientation() == TopAbs_REVERSED ) {
371 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),Face,T);
372 B.Range(Edge2,Face,-l1,-f1);
373 }
374 else {
375 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),Face,T);
376 B.Range(Edge2,Face,f1,l1);
377 }
378
379 if ( Closed) {
380 B.UpdateEdge(Edge3,
381 new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
382 new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
383 }
384 else {
385 B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
386 B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
387 }
388
389 // Set the non parameter flag;
390 B.SameParameter(Edge1,Standard_False);
391 B.SameParameter(Edge2,Standard_False);
392 B.SameParameter(Edge3,Standard_False);
393 B.SameParameter(Edge4,Standard_False);
394 B.SameRange(Edge1,Standard_False);
395 B.SameRange(Edge2,Standard_False);
396 B.SameRange(Edge3,Standard_False);
397 B.SameRange(Edge4,Standard_False);
398
399 BRepLib::SameParameter(Face);
400
401 if ( SameLoc) Face.Move(L);
402 return Face;
403}
404
405
406//=======================================================================
407//function : Shell
408//purpose :
409//=======================================================================
410
411TopoDS_Shell BRepFill::Shell(const TopoDS_Wire& Wire1,
412 const TopoDS_Wire& Wire2 )
413{
414 TopoDS_Shell Shell;
415 TopoDS_Face Face;
416 TopoDS_Shape S1, S2;
417 TopoDS_Edge Edge1, Edge2, Edge3, Edge4, Couture;
418
419 BRep_Builder B;
420// Class BRep_Tool without fields and without Constructor :
421// BRep_Tool BT;
422 B.MakeShell(Shell);
423
424 TopExp_Explorer ex1;
425 TopExp_Explorer ex2;
426
427 Standard_Boolean Closed = Wire1.Closed() && Wire2.Closed();
428
429 Standard_Boolean thefirst = Standard_True;
430
431 ex1.Init(Wire1,TopAbs_EDGE);
432 ex2.Init(Wire2,TopAbs_EDGE);
433
434 while ( ex1.More() && ex2.More() ) {
435
436 Edge1 = TopoDS::Edge(ex1.Current());
437 Edge2 = TopoDS::Edge(ex2.Current());
438
439 Standard_Boolean Periodic = Edge1.Closed() && Edge2.Closed();
440
441 ex1.Next();
442 ex2.Next();
443
444 TopLoc_Location L,L1,L2;
445 Standard_Real f1,l1,f2,l2,Tol;
446
447 Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,L1,f1,l1);
448 Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,L2,f2,l2);
449
450 // compute the location
451 Standard_Boolean SameLoc = Standard_False;
452 if (L1 == L2) {
453 L = L1;
454 L1 = L2 = TopLoc_Location();
455 SameLoc = Standard_True;
456 }
457
458 // transform and trim the curves
459
460 TopoDS_Vertex V1f,V1l,V2f,V2l;
461
462
463 if (Abs(f1 - C1->FirstParameter()) > Precision::PConfusion() ||
464 Abs(l1 - C1->LastParameter()) > Precision::PConfusion() ) {
465 C1 = new Geom_TrimmedCurve(C1,f1,l1);
466 }
467 else {
468 C1 = Handle(Geom_Curve)::DownCast(C1->Copy());
469 }
470 if ( !SameLoc) {
471 C1->Transform(L1.Transformation());
472 }
473 if (Edge1.Orientation() == TopAbs_REVERSED) {
474 TopExp::Vertices(Edge1,V1l,V1f);
475 C1->Reverse();
476 }
477 else
478 TopExp::Vertices(Edge1,V1f,V1l);
479
480 if (Abs(f2 - C2->FirstParameter()) > Precision::PConfusion() ||
481 Abs(l2 - C2->LastParameter()) > Precision::PConfusion() ) {
482 C2 = new Geom_TrimmedCurve(C2,f2,l2);
483 }
484 else {
485 C2 = Handle(Geom_Curve)::DownCast(C2->Copy());
486 }
487 if ( !SameLoc) {
488 C2->Transform(L2.Transformation());
489 }
490 if (Edge2.Orientation() == TopAbs_REVERSED) {
491 TopExp::Vertices(Edge2,V2l,V2f);
492 C2->Reverse();
493 }
494 else
495 TopExp::Vertices(Edge2,V2f,V2l);
496
497 GeomFill_Generator Generator;
498 Generator.AddCurve( C1);
499 Generator.AddCurve( C2);
500 Generator.Perform( Precision::PConfusion());
501
502 Handle(Geom_Surface) Surf = Generator.Surface();
503 Handle(Geom_Curve) Iso;
504
505 B.MakeFace(Face,Surf,Precision::Confusion());
506
507 // make the missing edges
508 Surf->Bounds(f1,l1,f2,l2);
509
510 if ( thefirst) {
511 Iso = Surf->UIso(f1);
512// Tol = Max(BT.Tolerance(V1f), BT.Tolerance(V2f));
513 Tol = Max(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f));
514 if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) {
515 B.MakeEdge(Edge3,Iso,Precision::Confusion());
516 }
517 else {
518 B.MakeEdge(Edge3);
519 B.Degenerated(Edge3, Standard_True);
520 }
521 V1f.Orientation(TopAbs_FORWARD);
522 B.Add(Edge3,V1f);
523 V2f.Orientation(TopAbs_REVERSED);
524 B.Add(Edge3,V2f);
525 B.Range(Edge3,f2,l2);
526 if ( Closed) {
527 Couture = Edge3;
528 }
529 Edge3.Reverse();
530 thefirst = Standard_False;
531 }
532 else {
533 Edge3 = Edge4;
534 Edge3.Reverse();
535 }
536
537 if ( Closed && !ex1.More() && !ex2.More() ) {
538 Edge4 = Couture;
539 }
540 else {
541 Iso = Surf->UIso(l1);
542// Tol = Max(BT.Tolerance(V1l), BT.Tolerance(V2l));
543 Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l));
544 if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) {
545 B.MakeEdge(Edge4,Iso,Precision::Confusion());
546 }
547 else {
548 B.MakeEdge(Edge4);
549 B.Degenerated(Edge4, Standard_True);
550 }
551 V1l.Orientation(TopAbs_FORWARD);
552 B.Add(Edge4,V1l);
553 V2l.Orientation(TopAbs_REVERSED);
554 B.Add(Edge4,V2l);
555 B.Range(Edge4,f2,l2);
556 }
557
558 // make the wire
559
560 TopoDS_Wire W;
561 B.MakeWire(W);
562
563 B.Add(W,Edge1);
564 B.Add(W,Edge4);
565 B.Add(W,Edge2.Reversed());
566 B.Add(W,Edge3);
567
568 B.Add(Face,W);
569
570 if ( SameLoc) Face.Move( L);
571
572 B.Add(Shell,Face);
573
574 // set the pcurves
575
576 Standard_Real T = Precision::Confusion();
577
578 if ( Edge1.Orientation() == TopAbs_REVERSED ) {
579 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),
580 Face,T);
581 B.Range(Edge1,Face,-l1,-f1);
582 }
583 else {
584 B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
585 Face,T);
586 B.Range(Edge1,Face,f1,l1);
587 }
588
589 if ( Edge2.Orientation() == TopAbs_REVERSED ) {
590 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),
591 Face,T);
592 B.Range(Edge2,Face,-l1,-f1);
593 }
594 else {
595 B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),
596 Face,T);
597 B.Range(Edge2,Face,f1,l1);
598 }
599
600 if ( Periodic) {
601 B.UpdateEdge(Edge3,
602 new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
603 new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),
604 Face,T);
605 }
606 else {
607 B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T);
608 B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T);
609 }
610
611 // Set the non parameter flag;
612 B.SameParameter(Edge1,Standard_False);
613 B.SameParameter(Edge2,Standard_False);
614 B.SameParameter(Edge3,Standard_False);
615 B.SameParameter(Edge4,Standard_False);
616 B.SameRange(Edge1,Standard_False);
617 B.SameRange(Edge2,Standard_False);
618 B.SameRange(Edge3,Standard_False);
619 B.SameRange(Edge4,Standard_False);
620 }
621
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
645 // normale au 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 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
673 // Recherche du vertex du profil le plus proche du spine.
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
684 // On cherche d'abord si il y a contact Vertex Vertex.
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 }
783 // sauvegarde minimum.
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
803//purpose : Decoupe et oriente un wire ferme.
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
824 W.Orientation(TopAbs_FORWARD); //pour ne pas composer les orientations
825
826 // Calcul la distance
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 }
863#if DEB
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
873 // Calcul le nombre d'edges
874 for(exp.Init(W); exp.More(); exp.Next()) NbEdges++;
875 if (NewVertex) {
876 NbEdges++;
877 Eref = E;
878 }
879
880 // Construit la Table et calcul rangdeb
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
901 // Calcul du sens de parcourt
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);
915 if (angle > PI) angle = 2*PI - angle;
916 forward = (angle <= PI/2);
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{
933 // calcul des abscisses curvilignes reduites et de la longueur du wire
934 BRepTools_WireExplorer anExp;
935 Standard_Integer nbEdges=0, i;
936
937 // longueurs cumulees
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
949 // longueur totale du wire
950 ACR(0) = ACR(nbEdges);
951
952 // abscisses curvilignes reduites
953 if (ACR(0)>Precision::Confusion()) {
954 for (i=1; i<=nbEdges; i++) {
955 ACR(i) /= ACR(0);
956 }
957 }
958 else {
959 // wire ponctuel
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{
974 // calcul des ACR du wire a decouper
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
990 // traitement edge par edge
991 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
992 nbEdges++;
993 t0 = t1;
994 t1 = ACRwire(nbEdges);
995
996 // parametres de decoupe sur cette edge
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)) {
1009 // on copie l'edge
1010 MW.Add(E);
1011 }
1012 else {
1013 // il faut couper l'edge
1014 // en respectant le sens de parcours du wire
1015 Standard_Boolean SO = (V.IsSame(TopExp::FirstVertex(E)));
1016 TopTools_SequenceOfShape SE;
1017 SE.Clear();
1018 TColStd_SequenceOfReal SR;
1019 SR.Clear();
1020 // le wire est toujours FORWARD
1021 // il faut modifier le parametre de decoupe si l'edge est REVERSED
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
1035 // resultat
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