0022792: Globally defined symbol PI conflicts with VTK definition (Intel compiler)
[occt.git] / src / LocOpe / LocOpe_SplitShape.cxx
CommitLineData
7fd59977 1// File: LocOpe_SplitShape.cxx
2// Created: Tue Jun 27 16:37:40 1995
3// Author: Jacques GOUSSARD
4// <jag@bravox>
5
6
7#include <LocOpe_SplitShape.ixx>
8
9#include <TopTools_ListOfShape.hxx>
10#include <TopTools_ListIteratorOfListOfShape.hxx>
11#include <TopTools_MapOfShape.hxx>
12#include <TopTools_DataMapOfShapeListOfShape.hxx>
13#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
14#include <TopTools_MapIteratorOfMapOfShape.hxx>
15#include <TopoDS_Iterator.hxx>
16#include <TopExp_Explorer.hxx>
17#include <BRep_Builder.hxx>
18#include <TopoDS_Vertex.hxx>
19#include <BRepLib_MakeFace.hxx>
20#include <BRep_Tool.hxx>
21#include <BRepTools.hxx>
22#include <BRep_Builder.hxx>
23
24#include <BRepClass_FaceExplorer.hxx>
25#include <BRepTopAdaptor_FClass2d.hxx>
26#include <BRepAdaptor_Surface.hxx>
27
28#include <Geom2d_Curve.hxx>
29#include <gp_Pnt2d.hxx>
30#include <gp_Vec2d.hxx>
31#include <gp_Dir2d.hxx>
32#include <TopoDS.hxx>
33#include <TopExp.hxx>
34#include <Precision.hxx>
35#include <BRepTools.hxx>
36#include <LocOpe.hxx>
37#include <Standard_ErrorHandler.hxx>
38
39static Standard_Boolean IsInside(const TopoDS_Face&,
40 const TopoDS_Wire&,
41 const TopoDS_Wire&);
42
43static Standard_Boolean IsInside(const TopoDS_Face&,
44 const TopoDS_Wire&);
45
46static void ChoixUV(const TopoDS_Edge&,
47 const TopoDS_Face&,
48 const TopTools_MapOfShape&,
49 TopTools_MapIteratorOfMapOfShape&,
50 gp_Pnt2d&,
51 gp_Vec2d&,
52 const Standard_Real tol);
53
54inline Standard_Boolean SameUV(const gp_Pnt2d& P1, const gp_Pnt2d& P2,
55 const BRepAdaptor_Surface& theBAS)//const Standard_Real tol)
56{
57 // Standard_Real tol = Precision::Confusion();
58 // return P1.SquareDistance(P2) < 10*tol;
59 //gka
60 Standard_Boolean isSame = Standard_True;
61 if(theBAS.IsUPeriodic())
62 isSame = (fabs(P1.X() - P2.X()) < theBAS.UPeriod() *0.5);
63 if(theBAS.IsVPeriodic())
64 isSame = (isSame && (fabs(P1.Y() - P2.Y()) < theBAS.VPeriod() *0.5));
65 return isSame;
66 //return P1.SquareDistance(P2) < tol * tol; //IFV
67}
68
69
70
71//=======================================================================
72//function : Init
73//purpose :
74//=======================================================================
75
76void LocOpe_SplitShape::Init(const TopoDS_Shape& S)
77{
78 myDone = Standard_False;
79 myShape = S;
80 myDblE.Clear();
81 myMap.Clear();
82 Put(myShape);
83}
84
85
86//=======================================================================
87//function : CanSplit
88//purpose :
89//=======================================================================
90
91Standard_Boolean LocOpe_SplitShape::CanSplit(const TopoDS_Edge& E) const
92{
93 if (myDone) {
94 return Standard_False;
95 }
96 if (myMap.IsEmpty()) {
97 return Standard_False;
98 }
99
100 if (!myMap.IsBound(E)) {
101 return Standard_False;
102 }
103
104 // On verifie que l`edge n`appartient pas a un wire deja reconstruit
105 TopExp_Explorer exp;
106 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myMap);
107 for (; itm.More(); itm.Next()) {
108 if (itm.Key().ShapeType() == TopAbs_WIRE && !itm.Value().IsEmpty()) {
109 for (exp.Init(itm.Key(),TopAbs_EDGE); exp.More(); exp.Next()) {
110 if (exp.Current().IsSame(E)) {
111 return Standard_False;
112 }
113 }
114 }
115 }
116 return Standard_True;
117}
118
119
120//=======================================================================
121//function : Add
122//purpose :
123//=======================================================================
124
125void LocOpe_SplitShape::Add(const TopoDS_Vertex& V,
126 const Standard_Real P,
127 const TopoDS_Edge& E)
128{
129 if (!CanSplit(E)) {
130 Standard_ConstructionError::Raise();
131 }
132
133 BRep_Builder B;
134 TopTools_ListOfShape& le = myMap(E);
135 if (le.IsEmpty()) {
136 le.Append(E);
137 }
138 TopTools_ListIteratorOfListOfShape itl(le);
139 Standard_Real f,l;
140
141 for (; itl.More(); itl.Next()) {
142 const TopoDS_Edge& edg = TopoDS::Edge(itl.Value());
143 BRep_Tool::Range(edg,f,l);
144 if (P>f && P <l) {
145 break;
146 }
147 }
148 if (!itl.More()) {
149 Standard_ConstructionError::Raise();
150 }
151 TopoDS_Edge edg = TopoDS::Edge(itl.Value());
152 le.Remove(itl);
153 if (V.Orientation() == TopAbs_FORWARD ||
154 V.Orientation() == TopAbs_REVERSED) {
155
156 TopoDS_Shape aLocalShape = edg.EmptyCopied();
157 TopoDS_Edge E1 = TopoDS::Edge(aLocalShape);
158 aLocalShape = edg.EmptyCopied();
159 TopoDS_Edge E2 = TopoDS::Edge(aLocalShape);
160 // TopoDS_Edge E1 = TopoDS::Edge(edg.EmptyCopied());
161 // TopoDS_Edge E2 = TopoDS::Edge(edg.EmptyCopied());
162 E1.Orientation(TopAbs_FORWARD);
163 E2.Orientation(TopAbs_FORWARD);
164 TopoDS_Vertex newVtx = V;
165 newVtx.Orientation(TopAbs_REVERSED);
166 B.Add(E1,newVtx);
167 B.UpdateVertex(newVtx,P,E1,BRep_Tool::Tolerance(V));
168 newVtx.Orientation(TopAbs_FORWARD);
169 B.Add(E2,newVtx);
170 B.UpdateVertex(newVtx,P,E2,BRep_Tool::Tolerance(V));
171 edg.Orientation(TopAbs_FORWARD);
172 TopExp_Explorer exp;
173 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
174 // for (TopExp_Explorer exp(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
175 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
176 f = BRep_Tool::Parameter(vtx,edg);
177 if (f < P) {
178 B.Add(E1,vtx);
179 B.UpdateVertex(vtx,f,E1,BRep_Tool::Tolerance(vtx));
180 }
181 else {
182 B.Add(E2,vtx);
183 B.UpdateVertex(vtx,f,E2,BRep_Tool::Tolerance(vtx));
184 }
185 }
186 le.Append(E1);
187 le.Append(E2);
188 }
189 else {
190 TopoDS_Shape aLocalShape = edg.EmptyCopied();
191 TopoDS_Edge E1 = TopoDS::Edge(aLocalShape);
192 // TopoDS_Edge E1 = TopoDS::Edge(edg.EmptyCopied());
193 TopExp_Explorer exp;
194 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
195 // for (TopExp_Explorer exp(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
196 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
197 f = BRep_Tool::Parameter(vtx,edg);
198 B.Add(E1,vtx);
199 B.UpdateVertex(vtx,f,E1,BRep_Tool::Tolerance(vtx));
200 }
201 B.Add(E1,V);
202 B.UpdateVertex(V,P,E1,BRep_Tool::Tolerance(V));
203 le.Append(E1);
204 }
205}
206
207
208
209//=======================================================================
210//function : Add
211//purpose :
212//=======================================================================
213
214void LocOpe_SplitShape::Add(const TopoDS_Wire& W,
215 const TopoDS_Face& F)
216{
217
218 if (myDone) {
219 Standard_ConstructionError::Raise();
220 }
221
222
223 TopExp_Explorer exp;
224 TopTools_ListOfShape& lf = myMap(F);
225 if (lf.IsEmpty()) {
226 Rebuild(F);
227 }
228 try {
229 OCC_CATCH_SIGNALS
230 if (!LocOpe::Closed(W,F)) {
231 AddOpenWire(W,F);
232 }
233 else {
234 AddClosedWire(W,F);
235 }
236 } catch (Standard_Failure ) {
237#ifdef DEB
238 cout << "Warning: SpliShape internal problem detected, some faces may be lost. Check input edges/wires" <<endl;
239#endif
240 return;
241 }
242 // JAG 10.11.95 Codage des regularites
243 BRep_Builder B;
244 for (exp.Init(W,TopAbs_EDGE); exp.More(); exp.Next()) {
245 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
246 if (!BRep_Tool::HasContinuity(edg,F,F)) {
247 B.Continuity(edg,F,F,GeomAbs_CN);
248 }
249 }
250}
251
252
253
254//=======================================================================
255//function : AddClosedWire
256//purpose :
257//=======================================================================
258
259void LocOpe_SplitShape::AddClosedWire(const TopoDS_Wire& W,
260 const TopoDS_Face& F)
261{
262 TopExp_Explorer exp;
263
264 // On cherche la face descendante de F qui continent le wire
265 TopTools_ListOfShape& lf = myMap(F);
266 TopTools_ListIteratorOfListOfShape itl(lf);
267 TopoDS_Wire outerW;
268 for (; itl.More(); itl.Next()) {
269 const TopoDS_Face& fac = TopoDS::Face(itl.Value());
270 /*
271 outerW = BRepTools::OuterWire(fac);
272 if (IsInside(F,W,outerW)) {
273 break;
274 }
275 */
276 if (IsInside(fac,W)) {
277 break;
278 }
279
280 }
281 if (!itl.More()) {
282 Standard_ConstructionError::Raise();
283 }
284
285 BRep_Builder B;
286
287 TopAbs_Orientation orWire = W.Orientation();
288 TopoDS_Shape aLocalFace = F.EmptyCopied();
289 TopoDS_Face newFace = TopoDS::Face(aLocalFace);
290 // TopoDS_Face newFace = TopoDS::Face(F.EmptyCopied());
291 newFace.Orientation(TopAbs_FORWARD);
292 B.Add(newFace,W);
293 // GProp_GProps GP;
294 // BRepGProp::SurfaceProperties (newFace,GP);
295 // if (GP.Mass() < 0) {
296 BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion());
297 if (classif.PerformInfinitePoint() == TopAbs_IN) {
298 //le wire donne defini un trou
299 aLocalFace = F.EmptyCopied();
300 newFace = TopoDS::Face(aLocalFace);
301 // newFace = TopoDS::Face(F.EmptyCopied());
302 newFace.Orientation(TopAbs_FORWARD);
303 orWire = TopAbs::Reverse(orWire);
304 B.Add(newFace,W.Oriented(orWire));
305 }
306
307 TopoDS_Face FaceRef = TopoDS::Face(itl.Value());
308 FaceRef.Orientation(TopAbs_FORWARD);
309 lf.Remove(itl);
310
311 aLocalFace = FaceRef.EmptyCopied();
312 TopoDS_Face newRef = TopoDS::Face(aLocalFace);
313 // TopoDS_Face newRef = TopoDS::Face(FaceRef.EmptyCopied());
314 newRef.Orientation(TopAbs_FORWARD);
315
316 // On suppose que les edges du wire ont des courbes 2d.
317 // Comme on ne change pas de surface de base, pas besoin d`UpdateEdge.
318
319 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
320 exp.More(); exp.Next()) {
321 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
322 if (IsInside(F,wir,W)) {
323 B.Add(newFace,wir);
324 }
325 else {
326 B.Add(newRef,wir);
327 }
328 }
329 B.Add(newRef,W.Oriented(TopAbs::Reverse(orWire)));
330 lf.Append(newRef);
331 lf.Append(newFace);
332
333}
334
335
336//=======================================================================
337//function : AddOpenWire
338//purpose :
339//=======================================================================
340
341void LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W,
342 const TopoDS_Face& F)
343{
344 // On cherche la face descendante de F qui continent le wire
345 TopTools_ListOfShape& lf = myMap(F);
346 TopTools_ListIteratorOfListOfShape itl(lf);
347 TopoDS_Vertex Vfirst,Vlast;
348
349 BRepTools::Update(F);
350
351 // TopExp::Vertices(W,Vfirst,Vlast);
352
353 Standard_Real tolf, toll, tol1;
354
355 TopoDS_Shape aLocalShape = W.Oriented(TopAbs_FORWARD);
356 TopExp::Vertices(TopoDS::Wire(aLocalShape),Vfirst,Vlast);
357 // TopExp::Vertices(TopoDS::Wire(W.Oriented(TopAbs_FORWARD)),Vfirst,Vlast);
358
359 tolf = BRep_Tool::Tolerance(Vfirst);
360 toll = BRep_Tool::Tolerance(Vlast);
361 tol1 = Max(tolf, toll);
362
363
364 TopExp_Explorer exp,exp2;
365
366 TopoDS_Wire wfirst,wlast;
367 for (; itl.More(); itl.Next()) {
368 const TopoDS_Face& fac = TopoDS::Face(itl.Value());
369 if (!IsInside(fac,W)) {
370 continue;
371 }
372
373 Standard_Boolean ffound = Standard_False;
374 Standard_Boolean lfound = Standard_False;
375 for (exp.Init(fac,TopAbs_WIRE); exp.More(); exp.Next()) {
376 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
377 for (exp2.Init(wir,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
378 if (!ffound && exp2.Current().IsSame(Vfirst)) {
379 ffound = Standard_True;
380 wfirst = wir;
381 }
382 else if (!lfound && exp2.Current().IsSame(Vlast)) {
383 lfound = Standard_True;
384 wlast = wir;
385 }
386 if (ffound && lfound) {
387 break;
388 }
389 }
390 if (exp2.More()) {
391 break;
392 }
393 }
394 if (exp.More()) {
395 break;
396 }
397 }
398 if (!itl.More()) {
399 Standard_ConstructionError::Raise();
400 }
401
402 TopoDS_Face FaceRef = TopoDS::Face(itl.Value());
403 FaceRef.Orientation(TopAbs_FORWARD);
404 lf.Remove(itl);
405 BRep_Builder B;
406
407 BRepAdaptor_Surface BAS(FaceRef, Standard_False);
408
409 Standard_Boolean IsPeriodic = BAS.IsUPeriodic() || BAS.IsVPeriodic();
410
411 tol1 = Max(BAS.UResolution(tol1), BAS.VResolution(tol1));
412
413 if (wfirst.IsSame(wlast)) {
414 // on cree 2 faces en remplacement de itl.Value()
415 // Essai JAG
416
417 for (exp.Init(wfirst,TopAbs_EDGE); exp.More(); exp.Next()) {
418 if (BRep_Tool::IsClosed(TopoDS::Edge(exp.Current()),FaceRef)) {
419 myDblE.Add(exp.Current());
420 }
421 }
422
423 TopAbs_Orientation orient;
424 TopoDS_Wire newW1,newW2;
425 B.MakeWire(newW1);
426 newW1.Orientation(TopAbs_FORWARD);
427 B.MakeWire(newW2);
428 newW2.Orientation(TopAbs_FORWARD);
429
430 Standard_Integer nbE = 0;
431 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
432 exp.More(); exp.Next()) {
433 nbE++;
434 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
435 orient = edg.Orientation();
436 B.Add(newW1,edg);
437 B.Add(newW2,edg.Oriented(TopAbs::Reverse(orient)));
438 }
439
440 TopTools_MapOfShape MapE, PossE;
441 TopTools_MapIteratorOfMapOfShape itm;
442 TopoDS_Vertex vdeb,vfin;
443 Standard_Integer nbPoss;
444
445 // On recherche l`edge contenant Vlast
446 TopoDS_Edge LastEdge;
447 gp_Pnt2d pfirst,plast;
448 gp_Vec2d dlast;
449 Handle(Geom2d_Curve) C2d;
450 Standard_Real f,l;
451
452 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
453 exp.More(); exp.Next()) {
454 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
455 for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
456 if (exp2.Current().IsSame(Vfirst)) {
457 break;
458 }
459 }
460 if (exp2.More()) {
461 LastEdge = edg;
462 LastEdge.Orientation(edg.Orientation());
463 break;
464 }
465 }
466
467 TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
468 C2d = BRep_Tool::CurveOnSurface(LastEdge, TopoDS::Face(aLocalFace), f, l);
469 // C2d = BRep_Tool::CurveOnSurface
470 // (LastEdge,
471 // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
472 // f,l);
473 if (LastEdge.Orientation() == TopAbs_FORWARD) {
474 pfirst = C2d->Value(f);
475 }
476 else {
477 pfirst = C2d->Value(l);
478 }
479
480 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
481 exp.More(); exp.Next()) {
482 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
483 if( nbE>1 && edg.IsSame(LastEdge) )
484 continue;
485 for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
486 if (exp2.Current().IsSame(Vlast)) {
487 break;
488 }
489 }
490 if (exp2.More()) {
491 LastEdge = edg;
492 LastEdge.Orientation(edg.Orientation());
493 break;
494 }
495 }
496 aLocalFace = FaceRef.Oriented(wfirst.Orientation());
497 C2d = BRep_Tool::CurveOnSurface(LastEdge, TopoDS::Face(aLocalFace), f, l);
498 // C2d = BRep_Tool::CurveOnSurface
499 // (LastEdge,
500 // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
501 // f,l);
502 if (LastEdge.Orientation() == TopAbs_FORWARD) {
503 C2d->D1(l,plast,dlast);
504 // plast = C2d->Value(l);
505 }
506 else {
507 // plast = C2d->Value(f);
508 C2d->D1(f,plast,dlast);
509 dlast.Reverse();
510 }
511
512 Standard_Boolean cond;
513
514 if(IsPeriodic) {
515
516 cond = !(Vfirst.IsSame(Vlast) && SameUV(pfirst,plast,BAS));
517 }
518 else {
519 cond = !(Vfirst.IsSame(Vlast));
520 }
521
522 while (cond) {
523 PossE.Clear();
524
525 // On enchaine par la fin
526 for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
527 exp.More(); exp.Next()) {
528 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
529 if (MapE.Contains(edg) && !myDblE.Contains(edg)) {
530 continue;
531 }
532
533 orient = edg.Orientation();
534 TopExp::Vertices(edg,vdeb,vfin);
535 if (orient == TopAbs_FORWARD && Vlast.IsSame(vdeb)) {
536 PossE.Add(edg.Oriented(orient));
537 }
538 else if (orient == TopAbs_REVERSED && Vlast.IsSame(vfin)) {
539 PossE.Add(edg.Oriented(orient));
540 }
541 }
542 nbPoss = PossE.Extent();
543 if (nbPoss == 1) {
544 itm.Initialize(PossE);
545 TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
546 C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(itm.Key()),
547 TopoDS::Face(aLocalFace), f, l);
548 // C2d = BRep_Tool::CurveOnSurface
549 // (TopoDS::Edge(itm.Key()),
550 // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
551 // f,l);
552 if (itm.Key().Orientation() == TopAbs_FORWARD) {
553 // plast = C2d->Value(l);
554 C2d->D1(l,plast,dlast);
555 }
556 else {
557 // plast = C2d->Value(f);
558 C2d->D1(f,plast,dlast);
559 dlast.Reverse();
560 }
561 }
562 else if (nbPoss > 1) {
563 // Faire choix en U,V...
564 TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
565
566 toll = Max(BAS.UResolution(toll), BAS.VResolution(toll));
567
568 ChoixUV(LastEdge, TopoDS::Face(aLocalFace), PossE,
569 itm, plast, dlast, toll);
570 // ChoixUV(LastEdge,
571 // TopoDS::Face(FaceRef.Oriented(wfirst.Orientation())),
572 // PossE,
573 // itm,
574 // plast,
575 // dlast, toll);
576
577 }
578
579 if (nbPoss >= 1) {
580 B.Add(newW1,itm.Key());
581 if (MapE.Contains(itm.Key())) {
582 myDblE.Remove(itm.Key());
583 }
584 else {
585 MapE.Add(itm.Key());
586 }
587 LastEdge = TopoDS::Edge(itm.Key());
588 if (LastEdge.Orientation() == TopAbs_FORWARD) {
589 Vlast = TopExp::LastVertex(LastEdge);
590 }
591 else {
592 Vlast = TopExp::FirstVertex(LastEdge);
593 }
594
595 toll = BRep_Tool::Tolerance(Vlast);
596 tol1 = Max(tolf, toll);
597
598 }
599 //MODIFICATION PIERRE SMEYERS : si pas de possibilite, on sort avec erreur
600 else{
601 cout<<"erreur Spliter : pas de chainage du wire"<<endl;
602 Standard_ConstructionError::Raise();
603 }
604 //fin MODIF.
605
606 tol1 = Max(BAS.UResolution(tol1), BAS.VResolution(tol1));
607
608 if(IsPeriodic) {
609 cond = !(Vfirst.IsSame(Vlast) && SameUV(pfirst,plast,BAS));
610 }
611 else {
612 cond = !(Vfirst.IsSame(Vlast));
613 }
614
615 }
616
617 for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
618 exp.More(); exp.Next()) {
619 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
620 if (!MapE.Contains(edg)) {
621 B.Add(newW2,edg);
622 MapE.Add(edg);
623 }
624 else if (myDblE.Contains(edg)) {
625 for (itm.Initialize(MapE); itm.More(); itm.Next()) {
626 const TopoDS_Edge& edg2 = TopoDS::Edge(itm.Key());
627 if (edg.IsSame(edg2) && edg.Orientation() != edg2.Orientation()) {
628 B.Add(newW2,edg);
629 myDblE.Remove(edg);
630 }
631 }
632 }
633 }
634
635 TopoDS_Face newF1,newF2;
636 aLocalFace = FaceRef.EmptyCopied();
637 newF1 = TopoDS::Face(aLocalFace);
638 newF1.Orientation(TopAbs_FORWARD);
639 aLocalFace = FaceRef.EmptyCopied();
640 newF2 = TopoDS::Face(aLocalFace);
641 // newF2 = TopoDS::Face(FaceRef.EmptyCopied());
642 newF2.Orientation(TopAbs_FORWARD);
643
644 // modifs JAG 97.05.28
645#ifdef DEB
646 TopAbs_Orientation orfila;
647#else
648 TopAbs_Orientation orfila=TopAbs_FORWARD;
649#endif
650 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
651 exp.More(); exp.Next()) {
652 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
653 if (wir.IsSame(wfirst)) {
654 orfila = exp.Current().Orientation();
655 break;
656 }
657 }
658
659 B.Add(newF1,newW1.Oriented(orfila));
660 B.Add(newF2,newW2.Oriented(orfila));
661 // Standard_Boolean exch = Standard_False;
662 BRepTopAdaptor_FClass2d classif(newF1,Precision::PConfusion());
663 if (classif.PerformInfinitePoint() == TopAbs_OUT) {
664 BRepTopAdaptor_FClass2d classi(newF2,Precision::PConfusion());
665 if (classi.PerformInfinitePoint() == TopAbs_IN) {
666 TopoDS_Face tempF = newF2;
667 newF2 = newF1;
668 newF1 = tempF;
669 }
670 }
671
672 for (exp.ReInit(); exp.More(); exp.Next()) {
673 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
674 if (!wir.IsSame(wfirst)) {
675 // if (IsInside(F,wir,newW1) || IsInside(F,newW1,wir)) {
676 if (IsInside(newF1, wir)) {
677 B.Add(newF1,wir);
678 }
679 else if (IsInside(newF2, wir)) {
680 B.Add(newF2,wir);
681 }
682 else {
683 // Ce wire est ni dans newF2 ni dans newF1
684 // Peut etre faut il construire une troisieme face
685 cout << "WARNING: LocOpe_SPlitShape : Ce wire est ni dans newF2 ni dans newF1" << endl;
686 }
687 }
688 }
689 lf.Append(newF1);
690 lf.Append(newF2);
691
692 // Mise a jour des descendants des wires
693 for (exp.Init(F,TopAbs_WIRE); exp.More(); exp.Next()) {
694 TopTools_ListOfShape& ls = myMap(exp.Current());
695 itl.Initialize(ls);
696 for (; itl.More(); itl.Next()) {
697 if (itl.Value().IsSame(wfirst)) {
698 break;
699 }
700 }
701 if (itl.More()) { // on a trouve le wire
702 ls.Remove(itl);
703 ls.Append(newW1);
704 ls.Append(newW2);
705 }
706 }
707 }
708 else {
709 // on ne cree qu`une seule face
710 TopoDS_Wire outerW = BRepTools::OuterWire(FaceRef);
711 TopoDS_Wire newWire;
712 TopoDS_Face newFace;
713 B.MakeWire(newWire);
714 newWire.Orientation(TopAbs_FORWARD);
715 TopAbs_Orientation orient,orRelat;
716
717 if (wfirst.Orientation() == wlast.Orientation()) {
718 orRelat = TopAbs_FORWARD;
719 }
720 else {
721 orRelat = TopAbs_REVERSED;
722 }
723
724 if (wlast.IsSame(outerW)) {
725 wlast = wfirst;
726 wfirst = outerW;
727 }
728
729 // Edges de wfirst
730 for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
731 exp.More(); exp.Next()) {
732 B.Add(newWire,TopoDS::Edge(exp.Current()));
733 }
734
735 // Edges de wlast
736 for (exp.Init(wlast.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
737 exp.More(); exp.Next()) {
738 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
739 orient = TopAbs::Compose(edg.Orientation(),orRelat);
740 B.Add(newWire,edg.Oriented(orient));
741 }
742
743
744 // Edges du wire ajoute, et dans les 2 sens
745 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
746 exp.More(); exp.Next()) {
747 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
748 orient = edg.Orientation();
749 B.Add(newWire,edg.Oriented(orient));
750 B.Add(newWire,edg.Oriented(TopAbs::Reverse(orient)));
751 myDblE.Add(edg.Oriented(orient));
752 }
753
754 // on refait une face
755
756 TopoDS_Shape aLocalFace = FaceRef.EmptyCopied();
757 newFace = TopoDS::Face(aLocalFace);
758 // newFace = TopoDS::Face(FaceRef.EmptyCopied());
759 FaceRef.Orientation(TopAbs_FORWARD);
760 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
761 exp.More(); exp.Next()) {
762 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
763 if (wir.IsSame(wfirst)) {
764 B.Add(newFace,newWire.Oriented(wir.Orientation()));
765 }
766 else if (!wir.IsSame(wlast)) {
767 B.Add(newFace,wir);
768 }
769 }
770 lf.Append(newFace);
771
772 // Mise a jour des descendants des wires
773 for (exp.Init(F,TopAbs_WIRE); exp.More(); exp.Next()) {
774 TopTools_ListOfShape& ls = myMap(exp.Current());
775 itl.Initialize(ls);
776 Standard_Boolean touch = Standard_False;
777 while (itl.More()) {
778 if (itl.Value().IsSame(wfirst) || itl.Value().IsSame(wlast)) {
779 ls.Remove(itl);
780 touch = Standard_True;
781 }
782 else {
783 itl.Next();
784 }
785 }
786 if (touch) {
787 ls.Append(newWire);
788 }
789
790 }
791 }
792}
793
794
795//=======================================================================
796//function : LeftOf
797//purpose :
798//=======================================================================
799
800const TopTools_ListOfShape& LocOpe_SplitShape::LeftOf(const TopoDS_Wire& W,
801 const TopoDS_Face& F)
802{
803 if (myShape.IsNull()) {
804 Standard_NoSuchObject::Raise();
805 }
806
807 TopExp_Explorer exp,expw,expf;
808 exp.Init(myShape,TopAbs_FACE);
809 for (; exp.More(); exp.Next()) {
810 if (exp.Current().IsSame(F)) {
811 break;
812 }
813 }
814 if (!exp.More()) {
815 Standard_NoSuchObject::Raise();
816 }
817 myLeft.Clear();
818
819 const TopoDS_Face& theFace = TopoDS::Face(exp.Current());
820 TopAbs_Orientation orFace = theFace.Orientation();
821 TopTools_ListIteratorOfListOfShape itl,itl2;
822
823 for (expw.Init(W,TopAbs_EDGE); expw.More(); expw.Next()) {
824 const TopoDS_Edge& edg = TopoDS::Edge(expw.Current());
825 for (itl.Initialize(myMap(theFace)); itl.More(); itl.Next()) {
826 TopoDS_Face fac = TopoDS::Face(itl.Value());
827 fac.Orientation(orFace);
828 for (expf.Init(fac,TopAbs_EDGE); expf.More(); expf.Next()) {
829 const TopoDS_Edge& edgbis = TopoDS::Edge(expf.Current());
830 if (edgbis.IsSame(edg) &&
831 edgbis.Orientation() == edg.Orientation()) {
832 for (itl2.Initialize(myLeft); itl2.More(); itl2.Next()) {
833 if (itl2.Value().IsSame(fac)) {
834 break;
835 }
836 }
837 if (!itl2.More()) { // la face n`est pas deja presente
838 myLeft.Append(fac);
839 }
840 break;
841 }
842 }
843 if (expf.More()) { // face found
844 break;
845 }
846 }
847 }
848 return myLeft;
849}
850
851
852//=======================================================================
853//function : DescendantShapes
854//purpose :
855//=======================================================================
856
857const TopTools_ListOfShape& LocOpe_SplitShape::DescendantShapes
858(const TopoDS_Shape& S)
859{
860 if (!myDone) {
861 Rebuild(myShape);
862 myDone = Standard_True;
863 }
864#ifdef DEB
865 if (!myDblE.IsEmpty()) {
866 cout << "Le shape comporte des faces invalides" << endl;
867 }
868#endif
869 return myMap(S);
870}
871
872
873
874//=======================================================================
875//function : Put
876//purpose :
877//=======================================================================
878
879void LocOpe_SplitShape::Put(const TopoDS_Shape& S)
880{
881 if (!myMap.IsBound(S)) {
882 TopTools_ListOfShape thelist;
883 myMap.Bind(S, thelist);
884 if (S.ShapeType() != TopAbs_VERTEX) {
885 for(TopoDS_Iterator theIterator(S);theIterator.More();
886 theIterator.Next()) {
887 Put(theIterator.Value());
888 }
889 }
890 else {
891 myMap(S).Append(S);
892 }
893 }
894}
895
896
897//=======================================================================
898//function : Rebuild
899//purpose :
900//=======================================================================
901
902Standard_Boolean LocOpe_SplitShape::Rebuild(const TopoDS_Shape& S)
903
904{
905
906 TopTools_ListIteratorOfListOfShape itr(myMap(S));
907 if (itr.More()) {
908 if (itr.Value().IsSame(S)) {
909 return Standard_False;
910 }
911 return Standard_True;
912 }
913 Standard_Boolean rebuild = Standard_False;
914 TopoDS_Iterator it;
915 for(it.Initialize(S); it.More(); it.Next()) {
916 rebuild = Rebuild(it.Value()) || rebuild;
917 }
918
919 if (rebuild) {
920 BRep_Builder B;
921 TopoDS_Shape result = S.EmptyCopied();
922 TopAbs_Orientation orient;
923 for(it.Initialize(S); it.More(); it.Next()) {
924 orient = it.Value().Orientation();
925 for (itr.Initialize(myMap(it.Value())); itr.More(); itr.Next()) {
926 B.Add(result,itr.Value().Oriented(orient));
927 }
928 }
929 myMap(S).Append(result);
930 }
931 else {
932 myMap(S).Append(S);
933 }
934 return rebuild;
935}
936
937
938
939//=======================================================================
940//function : IsInside
941//purpose :
942//=======================================================================
943
944static Standard_Boolean IsInside(const TopoDS_Face& F,
945 const TopoDS_Wire& W1,
946 const TopoDS_Wire& W2)
947{
948 // Attention, c`est tres boeuf !!!!
949 BRep_Builder B;
950 TopoDS_Shape aLocalShape = F.EmptyCopied();
951 TopoDS_Face newFace = TopoDS::Face(aLocalShape);
952 // TopoDS_Face newFace = TopoDS::Face(F.EmptyCopied());
953#ifdef DEB
954 TopAbs_Orientation orWire =
955#endif
956 W2.Orientation();
957 newFace.Orientation(TopAbs_FORWARD);
958 B.Add(newFace,W2);
959 // GProp_GProps GP;
960 // BRepGProp::SurfaceProperties(newFace,GP);
961 // if (GP.Mass() < 0) {
962 BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion());
963 Standard_Boolean Reversed = Standard_False;
964 if (classif.PerformInfinitePoint() == TopAbs_IN) {
965 //le wire donne defini un trou
966 // newFace = TopoDS::Face(F.EmptyCopied());
967 // newFace.Orientation(TopAbs_FORWARD);
968 // orWire = TopAbs::Reverse(orWire);
969 // B.Add(newFace,W2.Oriented(orWire));
970 Reversed = Standard_True;
971 }
972
973 // Standard_Real U,V;
974 TopExp_Explorer exp(W1,TopAbs_EDGE);
975 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
976 TopExp_Explorer exp2(edg,TopAbs_VERTEX);
977 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current());
978 Standard_Real prm = BRep_Tool::Parameter(vtx,edg);
979 Standard_Real f,l;
980 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
981 if(C2d.IsNull()) {
982#ifdef DEB
983 cout << "Edge is not on surface" <<endl;
984#endif
985 return Standard_False;
986 }
987 gp_Pnt2d pt2d(C2d->Value(prm));
988 // BRepClass_FaceClassifier classif(newFace,pt2d,Precision::PConfusion());
989 // return (classif.State() == TopAbs_IN);
990 if (!Reversed) {
991 return (classif.Perform(pt2d) == TopAbs_IN);
992 }
993 else {
994 return (classif.Perform(pt2d) == TopAbs_OUT);
995 }
996}
997
998
999//=======================================================================
1000//function : IsInside
1001//purpose :
1002//=======================================================================
1003
1004static Standard_Boolean IsInside(const TopoDS_Face& F,
1005 const TopoDS_Wire& W)
1006{
1007 // Attention, c`est tres boeuf !!!!
1008 TopExp_Explorer exp(W,TopAbs_EDGE);
1009 for( ; exp.More(); exp.Next()) {
1010 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
1011 // TopExp_Explorer exp2(edg,TopAbs_VERTEX);
1012 // const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current());
1013 // Standard_Real prm = BRep_Tool::Parameter(vtx,edg);
1014 Standard_Real f,l,prm;
1015 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
1016 if (!Precision::IsNegativeInfinite(f) &&
1017 !Precision::IsPositiveInfinite(l)) {
1018 prm = (f+l)/2.;
1019 }
1020 else {
1021 if (Precision::IsNegativeInfinite(f) &&
1022 Precision::IsPositiveInfinite(l)){
1023 prm = 0.;
1024 }
1025 else if (Precision::IsNegativeInfinite(f)) {
1026 prm = l-1.;
1027 }
1028 else {
1029 prm = f+1.;
1030 }
1031 }
1032
1033 gp_Pnt2d pt2d(C2d->Value(prm));
1034 // BRepClass_FaceClassifier classif(F,pt2d,Precision::PConfusion());
1035 // return (classif.State() != TopAbs_OUT);
1036 BRepTopAdaptor_FClass2d classif(F,Precision::PConfusion());
1037 Standard_Boolean stat = classif.Perform(pt2d);
1038 // return (classif.Perform(pt2d) != TopAbs_OUT);
1039 if(stat == TopAbs_OUT) return Standard_False;
1040
1041 if(stat == TopAbs_ON) {
1042 Standard_Integer nbPnt =10;
1043 Standard_Integer nbOut =0,nbIn =0,nbOn=0;
1044 Standard_Integer j =1;
1045 for( ; j<= nbPnt ; j++)
1046 {
1047 //check neighbouring point
1048 //prm = .66 * prm + .34 * l;
1049 prm = f + (l-f)/nbPnt*(j-1);
1050 pt2d = C2d->Value(prm);
1051 stat = classif.Perform(pt2d);
1052 if(stat == TopAbs_OUT )
1053 nbOut++;
1054 else if(stat == TopAbs_IN)
1055 nbIn++;
1056 else
1057 nbOn++;
1058 }
1059 if(nbOut > nbIn + nbOn)
1060 return Standard_False;
1061 }
1062 }
1063 return Standard_True;
1064}
1065
1066
1067//=======================================================================
1068//function : ChoixUV
1069//purpose :
1070//=======================================================================
1071
1072static void ChoixUV(const TopoDS_Edge& Last,
1073 const TopoDS_Face& F,
1074 const TopTools_MapOfShape& Poss,
1075 TopTools_MapIteratorOfMapOfShape& It,
1076 gp_Pnt2d& plst,
1077 gp_Vec2d& dlst,
1078 const Standard_Real toll)
1079{
1080
1081 Standard_Real f,l;
1082 // gp_Pnt2d p2d,psav;
1083 gp_Pnt2d p2d;
1084 gp_Vec2d v2d;
1085
1086 BRepAdaptor_Surface surf(F,Standard_False); // no restriction
1087 // Standard_Real tol = Precision::PConfusion() //BRep_Tool::Tolerance(Last));
1088
1089 Standard_Real tol;
1090
1091 TopoDS_Vertex vtx;
1092
1093 gp_Dir2d ref2d(dlst);
1094
1095 Handle(Geom2d_Curve) C2d;
1096
1097 Standard_Integer index = 0, imin=0;
c6541a0c 1098 Standard_Real angmax = -M_PI, dist, ang;
7fd59977 1099
1100
1101 for (It.Initialize(Poss); It.More(); It.Next()) {
1102 index++;
1103 C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(It.Key()),F,f,l);
1104 if (It.Key().Orientation() == TopAbs_FORWARD) {
1105 // p2d = C2d->Value(f);
1106 C2d->D1(f,p2d,v2d);
1107 vtx = TopExp::FirstVertex(TopoDS::Edge(It.Key()));
1108 }
1109 else {
1110 // p2d = C2d->Value(l);
1111 C2d->D1(l,p2d,v2d);
1112 v2d.Reverse();
1113 vtx = TopExp::LastVertex(TopoDS::Edge(It.Key()));
1114 }
1115
1116 if (surf.IsUPeriodic())
1117 if ((fabs(p2d.Y() - plst.Y()) <= toll) ||
1118 ((surf.IsVPeriodic()) &&
1119 (fabs(fabs(p2d.Y() - plst.Y()) - surf.VPeriod()) <= toll)))
1120 if (fabs(p2d.X() - plst.X() - surf.UPeriod()) <= toll)
1121 p2d.SetX(p2d.X() - surf.UPeriod());
1122 else if (fabs(plst.X() - p2d.X() - surf.UPeriod()) <= toll)
1123 p2d.SetX(p2d.X() + surf.UPeriod());
1124
1125 if (surf.IsVPeriodic())
1126 if (fabs(p2d.X() - plst.X()) <= toll)
1127 if (fabs(p2d.Y() - plst.Y() - surf.VPeriod()) <= toll)
1128 p2d.SetY(p2d.Y() - surf.VPeriod());
1129 else if (fabs(plst.Y() - p2d.Y() - surf.VPeriod()) <= toll)
1130 p2d.SetY(p2d.Y() + surf.VPeriod());
1131
1132 tol = BRep_Tool::Tolerance(vtx);
1133 tol = Max(surf.UResolution(tol), surf.VResolution(tol));
1134 tol = Max(toll, tol); tol *= tol;
1135
1136 dist = p2d.SquareDistance(plst);
1137
1138 if (!Last.IsSame(It.Key())) {
1139 ang = ref2d.Angle(gp_Dir2d(v2d));
1140 }
1141 else {
c6541a0c 1142 ang = -M_PI;
7fd59977 1143 }
1144
1145 //if ((dist < dmin - tol) ||
1146 //(dist <= dmin+tol && ang > angmax)) {
1147 if ((dist < tol) && (ang > angmax)) {
1148 imin = index;
1149 // dmin = dist;
1150 angmax = ang;
1151 }
1152 }
1153
1154 for (index = 1, It.Initialize(Poss); It.More(); It.Next()) {
1155 if (index == imin) {
1156 C2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(It.Key()),F,f,l);
1157 if (It.Key().Orientation() == TopAbs_FORWARD) {
1158 // plst = C2d->Value(l);
1159 C2d->D1(l,plst,dlst);
1160 }
1161 else {
1162 // plst = C2d->Value(f);
1163 C2d->D1(f,plst,dlst);
1164 dlst.Reverse();
1165 }
1166 break;
1167 }
1168 index++;
1169 }
1170
1171}