0025266: Debug statements in the source are getting flushed on to the console
[occt.git] / src / LocOpe / LocOpe_SplitShape.cxx
CommitLineData
b311480e 1// Created on: 1995-06-27
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1995-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.
7fd59977 16
17#include <LocOpe_SplitShape.ixx>
c1e18dd8 18#include <TopTools_IndexedMapOfShape.hxx>
7fd59977 19#include <TopTools_ListOfShape.hxx>
20#include <TopTools_ListIteratorOfListOfShape.hxx>
21#include <TopTools_MapOfShape.hxx>
253881cf 22#include <TopTools_MapOfOrientedShape.hxx>
7fd59977 23#include <TopTools_DataMapOfShapeListOfShape.hxx>
24#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
ed60a55e 25#include <TopTools_DataMapOfShapeInteger.hxx>
26#include <TopTools_DataMapOfShapeShape.hxx>
27#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
7fd59977 28#include <TopTools_MapIteratorOfMapOfShape.hxx>
253881cf 29#include <TopTools_MapIteratorOfMapOfOrientedShape.hxx>
7fd59977 30#include <TopoDS_Iterator.hxx>
31#include <TopExp_Explorer.hxx>
32#include <BRep_Builder.hxx>
33#include <TopoDS_Vertex.hxx>
34#include <BRepLib_MakeFace.hxx>
ed60a55e 35#include <BRepLib_MakeWire.hxx>
7fd59977 36#include <BRep_Tool.hxx>
37#include <BRepTools.hxx>
ed60a55e 38#include <BRepTools_WireExplorer.hxx>
7fd59977 39#include <BRep_Builder.hxx>
40
41#include <BRepClass_FaceExplorer.hxx>
42#include <BRepTopAdaptor_FClass2d.hxx>
43#include <BRepAdaptor_Surface.hxx>
44
45#include <Geom2d_Curve.hxx>
46#include <gp_Pnt2d.hxx>
47#include <gp_Vec2d.hxx>
48#include <gp_Dir2d.hxx>
49#include <TopoDS.hxx>
50#include <TopExp.hxx>
51#include <Precision.hxx>
52#include <BRepTools.hxx>
53#include <LocOpe.hxx>
54#include <Standard_ErrorHandler.hxx>
55
56static Standard_Boolean IsInside(const TopoDS_Face&,
57 const TopoDS_Wire&,
58 const TopoDS_Wire&);
59
60static Standard_Boolean IsInside(const TopoDS_Face&,
61 const TopoDS_Wire&);
62
c1e18dd8 63static void GetDirection(const TopoDS_Edge&,
64 const TopoDS_Face&,
65 Standard_Real&,
66 gp_Pnt2d&,
67 gp_Vec2d&);
68
7fd59977 69static void ChoixUV(const TopoDS_Edge&,
70 const TopoDS_Face&,
c1e18dd8 71 const TopTools_IndexedMapOfShape&,
72 TopoDS_Edge&,
7fd59977 73 gp_Pnt2d&,
74 gp_Vec2d&,
75 const Standard_Real tol);
76
ed60a55e 77static TopoDS_Shape ChooseDirection(const TopoDS_Shape&,
78 const TopoDS_Vertex&,
79 const TopoDS_Face&,
80 const TopTools_ListOfShape&);
81
7fd59977 82inline Standard_Boolean SameUV(const gp_Pnt2d& P1, const gp_Pnt2d& P2,
83 const BRepAdaptor_Surface& theBAS)//const Standard_Real tol)
84{
85 // Standard_Real tol = Precision::Confusion();
86 // return P1.SquareDistance(P2) < 10*tol;
87 //gka
88 Standard_Boolean isSame = Standard_True;
89 if(theBAS.IsUPeriodic())
90 isSame = (fabs(P1.X() - P2.X()) < theBAS.UPeriod() *0.5);
91 if(theBAS.IsVPeriodic())
92 isSame = (isSame && (fabs(P1.Y() - P2.Y()) < theBAS.VPeriod() *0.5));
93 return isSame;
94 //return P1.SquareDistance(P2) < tol * tol; //IFV
95}
96
97
98
99//=======================================================================
100//function : Init
101//purpose :
102//=======================================================================
103
104void LocOpe_SplitShape::Init(const TopoDS_Shape& S)
105{
106 myDone = Standard_False;
107 myShape = S;
108 myDblE.Clear();
109 myMap.Clear();
110 Put(myShape);
111}
112
113
114//=======================================================================
115//function : CanSplit
116//purpose :
117//=======================================================================
118
119Standard_Boolean LocOpe_SplitShape::CanSplit(const TopoDS_Edge& E) const
120{
121 if (myDone) {
122 return Standard_False;
123 }
124 if (myMap.IsEmpty()) {
125 return Standard_False;
126 }
127
128 if (!myMap.IsBound(E)) {
129 return Standard_False;
130 }
131
132 // On verifie que l`edge n`appartient pas a un wire deja reconstruit
133 TopExp_Explorer exp;
134 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myMap);
135 for (; itm.More(); itm.Next()) {
136 if (itm.Key().ShapeType() == TopAbs_WIRE && !itm.Value().IsEmpty()) {
137 for (exp.Init(itm.Key(),TopAbs_EDGE); exp.More(); exp.Next()) {
138 if (exp.Current().IsSame(E)) {
139 return Standard_False;
140 }
141 }
142 }
143 }
144 return Standard_True;
145}
146
147
148//=======================================================================
149//function : Add
150//purpose :
151//=======================================================================
152
153void LocOpe_SplitShape::Add(const TopoDS_Vertex& V,
154 const Standard_Real P,
155 const TopoDS_Edge& E)
156{
157 if (!CanSplit(E)) {
158 Standard_ConstructionError::Raise();
159 }
160
161 BRep_Builder B;
162 TopTools_ListOfShape& le = myMap(E);
163 if (le.IsEmpty()) {
164 le.Append(E);
165 }
166 TopTools_ListIteratorOfListOfShape itl(le);
167 Standard_Real f,l;
168
169 for (; itl.More(); itl.Next()) {
170 const TopoDS_Edge& edg = TopoDS::Edge(itl.Value());
171 BRep_Tool::Range(edg,f,l);
172 if (P>f && P <l) {
173 break;
174 }
175 }
176 if (!itl.More()) {
177 Standard_ConstructionError::Raise();
178 }
179 TopoDS_Edge edg = TopoDS::Edge(itl.Value());
180 le.Remove(itl);
181 if (V.Orientation() == TopAbs_FORWARD ||
182 V.Orientation() == TopAbs_REVERSED) {
183
184 TopoDS_Shape aLocalShape = edg.EmptyCopied();
185 TopoDS_Edge E1 = TopoDS::Edge(aLocalShape);
186 aLocalShape = edg.EmptyCopied();
187 TopoDS_Edge E2 = TopoDS::Edge(aLocalShape);
188 // TopoDS_Edge E1 = TopoDS::Edge(edg.EmptyCopied());
189 // TopoDS_Edge E2 = TopoDS::Edge(edg.EmptyCopied());
190 E1.Orientation(TopAbs_FORWARD);
191 E2.Orientation(TopAbs_FORWARD);
192 TopoDS_Vertex newVtx = V;
193 newVtx.Orientation(TopAbs_REVERSED);
194 B.Add(E1,newVtx);
195 B.UpdateVertex(newVtx,P,E1,BRep_Tool::Tolerance(V));
196 newVtx.Orientation(TopAbs_FORWARD);
197 B.Add(E2,newVtx);
198 B.UpdateVertex(newVtx,P,E2,BRep_Tool::Tolerance(V));
199 edg.Orientation(TopAbs_FORWARD);
200 TopExp_Explorer exp;
201 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
202 // for (TopExp_Explorer exp(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
203 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
204 f = BRep_Tool::Parameter(vtx,edg);
205 if (f < P) {
206 B.Add(E1,vtx);
207 B.UpdateVertex(vtx,f,E1,BRep_Tool::Tolerance(vtx));
208 }
209 else {
210 B.Add(E2,vtx);
211 B.UpdateVertex(vtx,f,E2,BRep_Tool::Tolerance(vtx));
212 }
213 }
214 le.Append(E1);
215 le.Append(E2);
216 }
217 else {
218 TopoDS_Shape aLocalShape = edg.EmptyCopied();
219 TopoDS_Edge E1 = TopoDS::Edge(aLocalShape);
220 // TopoDS_Edge E1 = TopoDS::Edge(edg.EmptyCopied());
221 TopExp_Explorer exp;
222 for (exp.Init(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
223 // for (TopExp_Explorer exp(edg,TopAbs_VERTEX); exp.More(); exp.Next()) {
224 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current());
225 f = BRep_Tool::Parameter(vtx,edg);
226 B.Add(E1,vtx);
227 B.UpdateVertex(vtx,f,E1,BRep_Tool::Tolerance(vtx));
228 }
229 B.Add(E1,V);
230 B.UpdateVertex(V,P,E1,BRep_Tool::Tolerance(V));
231 le.Append(E1);
232 }
233}
234
ed60a55e 235//=======================================================================
236//function : Add
237//purpose : adds the list of wires on the face <F>
238//=======================================================================
239
240void LocOpe_SplitShape::Add(const TopTools_ListOfShape& Lwires,
241 const TopoDS_Face& F)
242{
243
244 if (myDone) {
245 Standard_ConstructionError::Raise();
246 }
247
248 TopTools_ListOfShape& lf = myMap(F);
249 if (lf.IsEmpty()) {
250 Rebuild(F);
251 }
252
253 // On cherche la face descendante de F qui continent le wire
254 lf = myMap(F);
255 TopTools_ListIteratorOfListOfShape itl(lf);
256 TopoDS_Vertex Vfirst,Vlast;
257
258 BRepTools::Update(F);
259
260 for (; itl.More(); itl.Next())
261 {
262 const TopoDS_Face& fac = TopoDS::Face(itl.Value());
263 Standard_Boolean AllWiresInside = Standard_True;
264 TopTools_ListIteratorOfListOfShape itwires(Lwires);
265 for (; itwires.More(); itwires.Next())
266 {
267 const TopoDS_Wire& aWire = TopoDS::Wire(itwires.Value());
268 if (!IsInside(fac, aWire))
269 {
270 AllWiresInside = Standard_False;
271 break;
272 }
273 }
274 if (AllWiresInside)
275 break;
276 }
277 if (!itl.More()) {
278 Standard_ConstructionError::Raise();
279 }
280
281 TopoDS_Face FaceRef = TopoDS::Face(itl.Value());
282 FaceRef.Orientation(TopAbs_FORWARD);
283 lf.Remove(itl);
284
285 TopTools_ListOfShape NewWires;
286
287 TopTools_DataMapOfShapeInteger SectionsTimes;
288 for (itl.Initialize(Lwires); itl.More(); itl.Next())
289 SectionsTimes.Bind(itl.Value(), 2);
290
291 TopTools_ListOfShape BreakVertices;
292 TopTools_ListOfShape BreakOnWires;
293
294 TopTools_DataMapOfShapeShape VerWireMap;
295 Standard_Integer i;
296 TopExp_Explorer ExploF, ExploW;
297 for (itl.Initialize(Lwires); itl.More(); itl.Next())
298 {
299 const TopoDS_Wire& aSection = TopoDS::Wire(itl.Value());
300 TopoDS_Vertex Ver [2];
301 TopExp::Vertices(aSection, Ver[0], Ver[1]);
302 for (i = 0; i < 2; i++)
303 {
304 if (VerWireMap.IsBound(Ver[i]))
305 continue;
306 for (ExploF.Init(FaceRef, TopAbs_WIRE); ExploF.More(); ExploF.Next())
307 {
308 const TopoDS_Shape& aWire = ExploF.Current();
309 TopoDS_Shape aVer;
310 for (ExploW.Init(aWire, TopAbs_VERTEX); ExploW.More(); ExploW.Next())
311 {
312 aVer = ExploW.Current();
313 if (aVer.IsSame(Ver[i]))
314 break;
315 }
316 if (aVer.IsSame(Ver[i]))
317 {
318 VerWireMap.Bind(aVer, aWire);
319 break;
320 }
321 }
322 }
323 }
324
325 TopTools_DataMapOfShapeListOfShape VerSecMap;
326 for (itl.Initialize(Lwires); itl.More(); itl.Next())
327 {
328 const TopoDS_Wire& aWire = TopoDS::Wire(itl.Value());
329 TopoDS_Vertex V1, V2;
330 TopExp::Vertices(aWire, V1, V2);
331 TopTools_ListOfShape LW1, LW2;
332 if (!VerSecMap.IsBound(V1))
333 VerSecMap.Bind(V1, LW1);
334 VerSecMap(V1).Append(aWire);
335 if (!VerSecMap.IsBound(V2))
336 VerSecMap.Bind(V2, LW2);
337 VerSecMap(V2).Append(aWire);
338 }
339
340 //TopTools_IndexedDataMapOfShapeShape InnerTouchingWiresOnVertex;
341
342 TopoDS_Wire outerW = BRepTools::OuterWire(FaceRef);
343 TopoDS_Wire CurWire = outerW;
344 BRepLib_MakeWire *MW;
345 MW = new BRepLib_MakeWire();
346 BRepTools_WireExplorer wexp(CurWire, FaceRef);
347 for (;;)
348 {
349 TopoDS_Vertex theStartVertex = wexp.CurrentVertex(), CurVertex;
350 TopoDS_Edge CurEdge = wexp.Current();
351 TopoDS_Edge LastEdge = CurEdge;
352 MW->Add(CurEdge);
353 TopoDS_Wire aSectionWire;
354 TopoDS_Vertex aBreakVertex;
355 wexp.Next();
356 if (!wexp.More())
357 wexp.Init(CurWire, FaceRef);
358 for (;;)
359 {
360 if (MW->Wire().Closed())
361 break;
362 CurVertex = wexp.CurrentVertex();
363 if (VerSecMap.IsBound(CurVertex))
364 {
365 TopoDS_Shape aLocalWire = ChooseDirection(LastEdge, CurVertex, FaceRef, VerSecMap(CurVertex));
366 aSectionWire = TopoDS::Wire(aLocalWire);
367 break;
368 }
369 CurEdge = wexp.Current();
370 MW->Add(CurEdge);
371 LastEdge = CurEdge;
372 wexp.Next();
373 if (!wexp.More())
374 wexp.Init(CurWire, FaceRef);
375 }
376 if (MW->Wire().Closed())
377 {
378 NewWires.Append(MW->Wire());
379 theStartVertex = TopoDS::Vertex(BreakVertices.First());
380 BreakVertices.RemoveFirst();
381 CurWire = TopoDS::Wire(BreakOnWires.First());
382 BreakOnWires.RemoveFirst();
383 wexp.Init(CurWire, FaceRef);
384 while (!wexp.CurrentVertex().IsSame(theStartVertex))
385 wexp.Next();
386 MW = new BRepLib_MakeWire();
387 continue;
388 }
389 aBreakVertex = CurVertex;
390 BreakVertices.Append(aBreakVertex);
391 BreakOnWires.Append(CurWire);
392 for (;;)
393 {
394 MW->Add(aSectionWire);
395 (SectionsTimes(aSectionWire))--;
396 if (SectionsTimes(aSectionWire) == 0)
397 SectionsTimes.UnBind(aSectionWire);
398 if (MW->Wire().Closed())
399 {
400 NewWires.Append(MW->Wire());
401 if (SectionsTimes.IsEmpty())
402 break;
403 theStartVertex = TopoDS::Vertex(BreakVertices.First());
404 BreakVertices.RemoveFirst();
405 CurWire = TopoDS::Wire(BreakOnWires.First());
406 BreakOnWires.RemoveFirst();
407 wexp.Init(CurWire, FaceRef);
408 while (!wexp.CurrentVertex().IsSame(theStartVertex))
409 wexp.Next();
410 MW = new BRepLib_MakeWire();
411 break;
412 }
413 else
414 {
415 TopoDS_Vertex V1, V2, aStartVertex;
416 TopExp::Vertices(aSectionWire, V1, V2);
417 aStartVertex = (V1.IsSame(aBreakVertex))? V2 : V1;
418 CurWire = TopoDS::Wire(VerWireMap(aStartVertex));
419
420 wexp.Init(CurWire, FaceRef);
421 while (!wexp.CurrentVertex().IsSame(aStartVertex))
422 wexp.Next();
423
424 const TopTools_ListOfShape& Lsections = VerSecMap(aStartVertex);
425 if (Lsections.Extent() == 1)
426 break;
427
428 //else: choose the way
429 TopoDS_Wire NextSectionWire =
430 TopoDS::Wire((aSectionWire.IsSame(Lsections.First()))? Lsections.Last() : Lsections.First());
431
432 Standard_Integer Times = 0;
433 TopTools_DataMapIteratorOfDataMapOfShapeShape itVW(VerWireMap);
434 for (; itVW.More(); itVW.Next())
435 if (itVW.Value().IsSame(CurWire))
436 Times++;
437 if (Times == 1) //it is inner touching wire
438 {
439 //InnerTouchingWiresOnVertex.Bind(aWire, aStartVertex);
440 }
441 else
442 {
443 //we have to choose the direction
444 TopoDS_Edge aStartEdge = wexp.Current();
445 TopTools_ListOfShape Ldirs;
446 Ldirs.Append(aStartEdge);
447 Ldirs.Append(NextSectionWire);
448 TopoDS_Shape theDirection = ChooseDirection(aSectionWire, aStartVertex, FaceRef, Ldirs);
449 if (theDirection.IsSame(aStartEdge))
450 break;
451 }
452 aSectionWire = NextSectionWire;
453 aBreakVertex = aStartVertex;
454 } //end of else (MW is not closed)
455 } //end of for (;;) (loop on section wires)
456 if (SectionsTimes.IsEmpty())
457 break;
458 } //end of global for (;;)
459
460 TopTools_ListOfShape NewFaces;
461 BRep_Builder BB;
462 for (itl.Initialize(NewWires); itl.More(); itl.Next())
463 {
464 TopoDS_Shape aLocalFace = FaceRef.EmptyCopied();
465 TopoDS_Face aNewFace = TopoDS::Face(aLocalFace);
466 aNewFace.Orientation(TopAbs_FORWARD);
467 BB.Add(aNewFace, itl.Value());
468 NewFaces.Append(aNewFace);
469 }
470
471 //Inserting holes
472 TopTools_ListOfShape Holes;
473 for (ExploF.Init(FaceRef, TopAbs_WIRE); ExploF.More(); ExploF.Next())
474 {
475 const TopoDS_Shape& aWire = ExploF.Current();
476 ExploW.Init(aWire, TopAbs_EDGE);
477 TopoDS_Shape anEdge = ExploW.Current();
478 Standard_Boolean found = Standard_False;
479 for (itl.Initialize(NewWires); itl.More(); itl.Next())
480 {
481 const TopoDS_Shape& aNewWire = itl.Value();
482 for (ExploW.Init(aNewWire, TopAbs_EDGE); ExploW.More(); ExploW.Next())
483 {
484 if (anEdge.IsSame(ExploW.Current()))
485 {
486 found = Standard_True;
487 break;
488 }
489 }
490 if (found)
491 break;
492 }
493 if (!found)
494 Holes.Append(aWire);
495 }
496 TopTools_ListIteratorOfListOfShape itlNewF;
497 for (itl.Initialize(Holes); itl.More(); itl.Next())
498 {
499 const TopoDS_Wire& aHole = TopoDS::Wire(itl.Value());
500 for (itlNewF.Initialize(NewFaces); itlNewF.More(); itlNewF.Next())
501 {
502 TopoDS_Face& aNewFace = TopoDS::Face(itlNewF.Value());
503 if (IsInside(aNewFace, aHole))
504 {
505 BB.Add(aNewFace, aHole);
506 break;
507 }
508 }
509 }
510
511 //Update "myMap"
512 lf.Append(NewFaces);
513
514 //Update of descendants of wires
515 for (ExploF.Init(F, TopAbs_WIRE); ExploF.More(); ExploF.Next())
516 {
517 TopTools_ListOfShape& ls = myMap(ExploF.Current());
518 ls.Clear();
519 }
520 ///////////////////
521
522 // JAG 10.11.95 Codage des regularites
523 for (itl.Initialize(Lwires); itl.More(); itl.Next())
524 for (ExploW.Init(itl.Value(), TopAbs_EDGE); ExploW.More(); ExploW.Next())
525 {
526 const TopoDS_Edge& edg = TopoDS::Edge(ExploW.Current());
527 if (!BRep_Tool::HasContinuity(edg,F,F)) {
528 BB.Continuity(edg,F,F,GeomAbs_CN);
529 }
530 }
531}
7fd59977 532
533
534//=======================================================================
535//function : Add
536//purpose :
537//=======================================================================
538
539void LocOpe_SplitShape::Add(const TopoDS_Wire& W,
540 const TopoDS_Face& F)
541{
542
543 if (myDone) {
544 Standard_ConstructionError::Raise();
545 }
546
547
548 TopExp_Explorer exp;
549 TopTools_ListOfShape& lf = myMap(F);
550 if (lf.IsEmpty()) {
551 Rebuild(F);
552 }
553 try {
554 OCC_CATCH_SIGNALS
555 if (!LocOpe::Closed(W,F)) {
556 AddOpenWire(W,F);
557 }
558 else {
559 AddClosedWire(W,F);
560 }
561 } catch (Standard_Failure ) {
63c629aa 562#ifdef LOCOPE_DEB
7fd59977 563 cout << "Warning: SpliShape internal problem detected, some faces may be lost. Check input edges/wires" <<endl;
564#endif
565 return;
566 }
567 // JAG 10.11.95 Codage des regularites
568 BRep_Builder B;
569 for (exp.Init(W,TopAbs_EDGE); exp.More(); exp.Next()) {
570 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
571 if (!BRep_Tool::HasContinuity(edg,F,F)) {
572 B.Continuity(edg,F,F,GeomAbs_CN);
573 }
574 }
575}
576
577
578
579//=======================================================================
580//function : AddClosedWire
581//purpose :
582//=======================================================================
583
584void LocOpe_SplitShape::AddClosedWire(const TopoDS_Wire& W,
585 const TopoDS_Face& F)
586{
587 TopExp_Explorer exp;
588
589 // On cherche la face descendante de F qui continent le wire
590 TopTools_ListOfShape& lf = myMap(F);
591 TopTools_ListIteratorOfListOfShape itl(lf);
592 TopoDS_Wire outerW;
593 for (; itl.More(); itl.Next()) {
594 const TopoDS_Face& fac = TopoDS::Face(itl.Value());
595 /*
596 outerW = BRepTools::OuterWire(fac);
597 if (IsInside(F,W,outerW)) {
598 break;
599 }
600 */
601 if (IsInside(fac,W)) {
602 break;
603 }
604
605 }
606 if (!itl.More()) {
607 Standard_ConstructionError::Raise();
608 }
609
610 BRep_Builder B;
611
612 TopAbs_Orientation orWire = W.Orientation();
613 TopoDS_Shape aLocalFace = F.EmptyCopied();
614 TopoDS_Face newFace = TopoDS::Face(aLocalFace);
615 // TopoDS_Face newFace = TopoDS::Face(F.EmptyCopied());
616 newFace.Orientation(TopAbs_FORWARD);
617 B.Add(newFace,W);
618 // GProp_GProps GP;
619 // BRepGProp::SurfaceProperties (newFace,GP);
620 // if (GP.Mass() < 0) {
621 BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion());
622 if (classif.PerformInfinitePoint() == TopAbs_IN) {
623 //le wire donne defini un trou
624 aLocalFace = F.EmptyCopied();
625 newFace = TopoDS::Face(aLocalFace);
626 // newFace = TopoDS::Face(F.EmptyCopied());
627 newFace.Orientation(TopAbs_FORWARD);
628 orWire = TopAbs::Reverse(orWire);
629 B.Add(newFace,W.Oriented(orWire));
630 }
631
632 TopoDS_Face FaceRef = TopoDS::Face(itl.Value());
633 FaceRef.Orientation(TopAbs_FORWARD);
634 lf.Remove(itl);
635
636 aLocalFace = FaceRef.EmptyCopied();
637 TopoDS_Face newRef = TopoDS::Face(aLocalFace);
638 // TopoDS_Face newRef = TopoDS::Face(FaceRef.EmptyCopied());
639 newRef.Orientation(TopAbs_FORWARD);
640
641 // On suppose que les edges du wire ont des courbes 2d.
642 // Comme on ne change pas de surface de base, pas besoin d`UpdateEdge.
643
644 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
645 exp.More(); exp.Next()) {
646 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
647 if (IsInside(F,wir,W)) {
648 B.Add(newFace,wir);
649 }
650 else {
651 B.Add(newRef,wir);
652 }
653 }
654 B.Add(newRef,W.Oriented(TopAbs::Reverse(orWire)));
655 lf.Append(newRef);
656 lf.Append(newFace);
657
658}
659
660
661//=======================================================================
662//function : AddOpenWire
663//purpose :
664//=======================================================================
665
666void LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W,
667 const TopoDS_Face& F)
668{
669 // On cherche la face descendante de F qui continent le wire
670 TopTools_ListOfShape& lf = myMap(F);
671 TopTools_ListIteratorOfListOfShape itl(lf);
672 TopoDS_Vertex Vfirst,Vlast;
673
674 BRepTools::Update(F);
675
7fd59977 676 Standard_Real tolf, toll, tol1;
677
678 TopoDS_Shape aLocalShape = W.Oriented(TopAbs_FORWARD);
679 TopExp::Vertices(TopoDS::Wire(aLocalShape),Vfirst,Vlast);
7fd59977 680
681 tolf = BRep_Tool::Tolerance(Vfirst);
682 toll = BRep_Tool::Tolerance(Vlast);
683 tol1 = Max(tolf, toll);
684
685
253881cf 686 TopExp_Explorer exp,exp2;
7fd59977 687
688 TopoDS_Wire wfirst,wlast;
689 for (; itl.More(); itl.Next()) {
253881cf 690 TopoDS_Face fac = TopoDS::Face(itl.Value());
7fd59977 691 if (!IsInside(fac,W)) {
692 continue;
693 }
253881cf 694
695 fac.Orientation(TopAbs_FORWARD);
7fd59977 696 Standard_Boolean ffound = Standard_False;
697 Standard_Boolean lfound = Standard_False;
698 for (exp.Init(fac,TopAbs_WIRE); exp.More(); exp.Next()) {
699 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
700 for (exp2.Init(wir,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
701 if (!ffound && exp2.Current().IsSame(Vfirst)) {
702 ffound = Standard_True;
703 wfirst = wir;
704 }
705 else if (!lfound && exp2.Current().IsSame(Vlast)) {
706 lfound = Standard_True;
707 wlast = wir;
708 }
709 if (ffound && lfound) {
710 break;
711 }
712 }
713 if (exp2.More()) {
714 break;
715 }
716 }
717 if (exp.More()) {
718 break;
719 }
720 }
721 if (!itl.More()) {
722 Standard_ConstructionError::Raise();
723 }
724
725 TopoDS_Face FaceRef = TopoDS::Face(itl.Value());
726 FaceRef.Orientation(TopAbs_FORWARD);
727 lf.Remove(itl);
728 BRep_Builder B;
729
730 BRepAdaptor_Surface BAS(FaceRef, Standard_False);
731
732 Standard_Boolean IsPeriodic = BAS.IsUPeriodic() || BAS.IsVPeriodic();
733
734 tol1 = Max(BAS.UResolution(tol1), BAS.VResolution(tol1));
735
736 if (wfirst.IsSame(wlast)) {
737 // on cree 2 faces en remplacement de itl.Value()
738 // Essai JAG
253881cf 739 TopTools_ListOfShape WiresFirst;
7fd59977 740 for (exp.Init(wfirst,TopAbs_EDGE); exp.More(); exp.Next()) {
741 if (BRep_Tool::IsClosed(TopoDS::Edge(exp.Current()),FaceRef)) {
742 myDblE.Add(exp.Current());
743 }
253881cf 744 WiresFirst.Append(exp.Current());
7fd59977 745 }
746
747 TopAbs_Orientation orient;
748 TopoDS_Wire newW1,newW2;
749 B.MakeWire(newW1);
750 newW1.Orientation(TopAbs_FORWARD);
751 B.MakeWire(newW2);
752 newW2.Orientation(TopAbs_FORWARD);
753
253881cf 754 Standard_Integer nbE = 0;
7fd59977 755 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
756 exp.More(); exp.Next()) {
757 nbE++;
758 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
253881cf 759 orient = edg.Orientation();
760 WiresFirst.Append(edg);
761 WiresFirst.Append(edg.Oriented(TopAbs::Reverse(orient)));
762 myDblE.Add(edg);
763 }
764
c1e18dd8 765 TopTools_IndexedMapOfShape PossE;
253881cf 766 TopTools_MapOfOrientedShape MapE;
7fd59977 767 TopoDS_Vertex vdeb,vfin;
768 Standard_Integer nbPoss;
769
770 // On recherche l`edge contenant Vlast
771 TopoDS_Edge LastEdge;
772 gp_Pnt2d pfirst,plast;
773 gp_Vec2d dlast;
774 Handle(Geom2d_Curve) C2d;
775 Standard_Real f,l;
776
777 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
778 exp.More(); exp.Next()) {
779 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
780 for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
781 if (exp2.Current().IsSame(Vfirst)) {
782 break;
783 }
784 }
785 if (exp2.More()) {
786 LastEdge = edg;
787 LastEdge.Orientation(edg.Orientation());
788 break;
789 }
790 }
791
792 TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
793 C2d = BRep_Tool::CurveOnSurface(LastEdge, TopoDS::Face(aLocalFace), f, l);
253881cf 794
7fd59977 795 if (LastEdge.Orientation() == TopAbs_FORWARD) {
796 pfirst = C2d->Value(f);
797 }
798 else {
799 pfirst = C2d->Value(l);
800 }
801
802 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
803 exp.More(); exp.Next()) {
804 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
805 if( nbE>1 && edg.IsSame(LastEdge) )
806 continue;
807 for (exp2.Init(edg,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
808 if (exp2.Current().IsSame(Vlast)) {
809 break;
810 }
811 }
812 if (exp2.More()) {
813 LastEdge = edg;
814 LastEdge.Orientation(edg.Orientation());
815 break;
816 }
817 }
818 aLocalFace = FaceRef.Oriented(wfirst.Orientation());
819 C2d = BRep_Tool::CurveOnSurface(LastEdge, TopoDS::Face(aLocalFace), f, l);
7c104885 820 Standard_Real dpar = (l - f)*0.01;
253881cf 821
7fd59977 822 if (LastEdge.Orientation() == TopAbs_FORWARD) {
823 C2d->D1(l,plast,dlast);
7c104885 824 if (dlast.Magnitude() < gp::Resolution())
825 {
826 gp_Pnt2d PrevPnt = C2d->Value(l - dpar);
827 dlast.SetXY(plast.XY() - PrevPnt.XY());
828 }
7fd59977 829 }
830 else {
7fd59977 831 C2d->D1(f,plast,dlast);
7c104885 832 if (dlast.Magnitude() < gp::Resolution())
833 {
834 gp_Pnt2d NextPnt = C2d->Value(f + dpar);
835 dlast.SetXY(NextPnt.XY() - plast.XY());
836 }
7fd59977 837 dlast.Reverse();
838 }
839
840 Standard_Boolean cond;
841
842 if(IsPeriodic) {
843
844 cond = !(Vfirst.IsSame(Vlast) && SameUV(pfirst,plast,BAS));
845 }
846 else {
847 cond = !(Vfirst.IsSame(Vlast));
848 }
253881cf 849
850 while (cond) {
7fd59977 851 PossE.Clear();
852
253881cf 853 // On enchaine par la fin
854 TopTools_ListIteratorOfListOfShape lexp(WiresFirst);
855 for (; lexp.More(); lexp.Next()) {
856 const TopoDS_Edge& edg = TopoDS::Edge(lexp.Value());
7fd59977 857
858 orient = edg.Orientation();
859 TopExp::Vertices(edg,vdeb,vfin);
860 if (orient == TopAbs_FORWARD && Vlast.IsSame(vdeb)) {
861 PossE.Add(edg.Oriented(orient));
862 }
863 else if (orient == TopAbs_REVERSED && Vlast.IsSame(vfin)) {
864 PossE.Add(edg.Oriented(orient));
865 }
866 }
867 nbPoss = PossE.Extent();
253881cf 868 if (nbPoss == 0)
869 {
870 break;
871 }
872
c1e18dd8 873 TopoDS_Edge aNextEdge;
7fd59977 874 if (nbPoss == 1) {
c1e18dd8 875 aNextEdge = TopoDS::Edge (PossE.FindKey (1));
7fd59977 876 TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
c1e18dd8 877 C2d = BRep_Tool::CurveOnSurface(aNextEdge,
7fd59977 878 TopoDS::Face(aLocalFace), f, l);
7c104885 879 Standard_Real dpar = (l - f)*0.01;
253881cf 880
c1e18dd8 881 if (aNextEdge.Orientation() == TopAbs_FORWARD) {
7fd59977 882 C2d->D1(l,plast,dlast);
7c104885 883 if (dlast.Magnitude() < gp::Resolution())
884 {
885 gp_Pnt2d PrevPnt = C2d->Value(l - dpar);
886 dlast.SetXY(plast.XY() - PrevPnt.XY());
887 }
7fd59977 888 }
889 else {
7fd59977 890 C2d->D1(f,plast,dlast);
7c104885 891 if (dlast.Magnitude() < gp::Resolution())
892 {
893 gp_Pnt2d NextPnt = C2d->Value(f + dpar);
894 dlast.SetXY(NextPnt.XY() - plast.XY());
895 }
7fd59977 896 dlast.Reverse();
897 }
898 }
899 else if (nbPoss > 1) {
900 // Faire choix en U,V...
901 TopoDS_Shape aLocalFace = FaceRef.Oriented(wfirst.Orientation());
902
7fd59977 903 ChoixUV(LastEdge, TopoDS::Face(aLocalFace), PossE,
c1e18dd8 904 aNextEdge, plast, dlast, toll);
7fd59977 905 }
906
907 if (nbPoss >= 1) {
c1e18dd8 908 if (aNextEdge.IsNull())
909 {
910 // loop is not closed. Split is not possible
911 Standard_ConstructionError::Raise("Split is not possible: split loop is not closed");
912 }
913
914 if (MapE.Contains(aNextEdge))
253881cf 915 break;
c1e18dd8 916 B.Add(newW1, aNextEdge);
917 MapE.Add(aNextEdge);
918 LastEdge = aNextEdge;
253881cf 919
7fd59977 920 if (LastEdge.Orientation() == TopAbs_FORWARD) {
921 Vlast = TopExp::LastVertex(LastEdge);
922 }
923 else {
924 Vlast = TopExp::FirstVertex(LastEdge);
925 }
926
927 toll = BRep_Tool::Tolerance(Vlast);
928 tol1 = Max(tolf, toll);
929
930 }
931 //MODIFICATION PIERRE SMEYERS : si pas de possibilite, on sort avec erreur
932 else{
933 cout<<"erreur Spliter : pas de chainage du wire"<<endl;
253881cf 934 Standard_ConstructionError::Raise();
7fd59977 935 }
936 //fin MODIF.
937
938 tol1 = Max(BAS.UResolution(tol1), BAS.VResolution(tol1));
939
7fd59977 940 }
941
253881cf 942 TopTools_ListIteratorOfListOfShape lexp(WiresFirst);
943 for (; lexp.More(); lexp.Next()) {
944 const TopoDS_Edge& edg = TopoDS::Edge(lexp.Value());
7fd59977 945 if (!MapE.Contains(edg)) {
946 B.Add(newW2,edg);
947 MapE.Add(edg);
948 }
253881cf 949 }
950
7fd59977 951 TopoDS_Face newF1,newF2;
952 aLocalFace = FaceRef.EmptyCopied();
953 newF1 = TopoDS::Face(aLocalFace);
954 newF1.Orientation(TopAbs_FORWARD);
955 aLocalFace = FaceRef.EmptyCopied();
956 newF2 = TopoDS::Face(aLocalFace);
7fd59977 957 newF2.Orientation(TopAbs_FORWARD);
958
959 // modifs JAG 97.05.28
1d47d8d0 960
7fd59977 961 TopAbs_Orientation orfila=TopAbs_FORWARD;
1d47d8d0 962
7fd59977 963 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
964 exp.More(); exp.Next()) {
965 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
966 if (wir.IsSame(wfirst)) {
967 orfila = exp.Current().Orientation();
968 break;
969 }
970 }
971
c1e18dd8 972 //newW1.Oriented(orfila);
973 //newW2.Oriented(orfila);
7c104885 974
253881cf 975 B.Add(newF1,newW1);
c1e18dd8 976 //BRepTools::Write(newF1, "k:/queries/WrongBOP/NewF1.brep");
253881cf 977 B.Add(newF2,newW2);
c1e18dd8 978 //BRepTools::Write(newF2, "k:/queries/WrongBOP/NewF2.brep");
7fd59977 979
980 for (exp.ReInit(); exp.More(); exp.Next()) {
981 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
982 if (!wir.IsSame(wfirst)) {
7fd59977 983 if (IsInside(newF1, wir)) {
984 B.Add(newF1,wir);
985 }
986 else if (IsInside(newF2, wir)) {
987 B.Add(newF2,wir);
988 }
989 else {
990 // Ce wire est ni dans newF2 ni dans newF1
991 // Peut etre faut il construire une troisieme face
992 cout << "WARNING: LocOpe_SPlitShape : Ce wire est ni dans newF2 ni dans newF1" << endl;
993 }
994 }
995 }
996 lf.Append(newF1);
997 lf.Append(newF2);
998
999 // Mise a jour des descendants des wires
1000 for (exp.Init(F,TopAbs_WIRE); exp.More(); exp.Next()) {
1001 TopTools_ListOfShape& ls = myMap(exp.Current());
1002 itl.Initialize(ls);
1003 for (; itl.More(); itl.Next()) {
1004 if (itl.Value().IsSame(wfirst)) {
1005 break;
1006 }
1007 }
1008 if (itl.More()) { // on a trouve le wire
1009 ls.Remove(itl);
1010 ls.Append(newW1);
1011 ls.Append(newW2);
1012 }
1013 }
1014 }
1015 else {
1016 // on ne cree qu`une seule face
1017 TopoDS_Wire outerW = BRepTools::OuterWire(FaceRef);
1018 TopoDS_Wire newWire;
1019 TopoDS_Face newFace;
1020 B.MakeWire(newWire);
1021 newWire.Orientation(TopAbs_FORWARD);
1022 TopAbs_Orientation orient,orRelat;
1023
1024 if (wfirst.Orientation() == wlast.Orientation()) {
1025 orRelat = TopAbs_FORWARD;
1026 }
1027 else {
1028 orRelat = TopAbs_REVERSED;
1029 }
1030
1031 if (wlast.IsSame(outerW)) {
1032 wlast = wfirst;
1033 wfirst = outerW;
1034 }
1035
1036 // Edges de wfirst
1037 for (exp.Init(wfirst.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1038 exp.More(); exp.Next()) {
1039 B.Add(newWire,TopoDS::Edge(exp.Current()));
1040 }
1041
1042 // Edges de wlast
1043 for (exp.Init(wlast.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1044 exp.More(); exp.Next()) {
1045 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
1046 orient = TopAbs::Compose(edg.Orientation(),orRelat);
1047 B.Add(newWire,edg.Oriented(orient));
1048 }
1049
1050
1051 // Edges du wire ajoute, et dans les 2 sens
1052 for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
1053 exp.More(); exp.Next()) {
1054 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
1055 orient = edg.Orientation();
1056 B.Add(newWire,edg.Oriented(orient));
1057 B.Add(newWire,edg.Oriented(TopAbs::Reverse(orient)));
1058 myDblE.Add(edg.Oriented(orient));
1059 }
1060
1061 // on refait une face
1062
1063 TopoDS_Shape aLocalFace = FaceRef.EmptyCopied();
1064 newFace = TopoDS::Face(aLocalFace);
1065 // newFace = TopoDS::Face(FaceRef.EmptyCopied());
1066 FaceRef.Orientation(TopAbs_FORWARD);
1067 for (exp.Init(FaceRef.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
1068 exp.More(); exp.Next()) {
1069 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
1070 if (wir.IsSame(wfirst)) {
1071 B.Add(newFace,newWire.Oriented(wir.Orientation()));
1072 }
1073 else if (!wir.IsSame(wlast)) {
1074 B.Add(newFace,wir);
1075 }
1076 }
1077 lf.Append(newFace);
1078
1079 // Mise a jour des descendants des wires
1080 for (exp.Init(F,TopAbs_WIRE); exp.More(); exp.Next()) {
1081 TopTools_ListOfShape& ls = myMap(exp.Current());
1082 itl.Initialize(ls);
1083 Standard_Boolean touch = Standard_False;
1084 while (itl.More()) {
1085 if (itl.Value().IsSame(wfirst) || itl.Value().IsSame(wlast)) {
1086 ls.Remove(itl);
1087 touch = Standard_True;
1088 }
1089 else {
1090 itl.Next();
1091 }
1092 }
1093 if (touch) {
1094 ls.Append(newWire);
1095 }
1096
1097 }
1098 }
1099}
1100
1101
1102//=======================================================================
1103//function : LeftOf
1104//purpose :
1105//=======================================================================
1106
1107const TopTools_ListOfShape& LocOpe_SplitShape::LeftOf(const TopoDS_Wire& W,
1108 const TopoDS_Face& F)
1109{
1110 if (myShape.IsNull()) {
1111 Standard_NoSuchObject::Raise();
1112 }
1113
1114 TopExp_Explorer exp,expw,expf;
1115 exp.Init(myShape,TopAbs_FACE);
1116 for (; exp.More(); exp.Next()) {
1117 if (exp.Current().IsSame(F)) {
1118 break;
1119 }
1120 }
1121 if (!exp.More()) {
1122 Standard_NoSuchObject::Raise();
1123 }
1124 myLeft.Clear();
1125
1126 const TopoDS_Face& theFace = TopoDS::Face(exp.Current());
1127 TopAbs_Orientation orFace = theFace.Orientation();
1128 TopTools_ListIteratorOfListOfShape itl,itl2;
1129
1130 for (expw.Init(W,TopAbs_EDGE); expw.More(); expw.Next()) {
1131 const TopoDS_Edge& edg = TopoDS::Edge(expw.Current());
1132 for (itl.Initialize(myMap(theFace)); itl.More(); itl.Next()) {
1133 TopoDS_Face fac = TopoDS::Face(itl.Value());
1134 fac.Orientation(orFace);
1135 for (expf.Init(fac,TopAbs_EDGE); expf.More(); expf.Next()) {
1136 const TopoDS_Edge& edgbis = TopoDS::Edge(expf.Current());
1137 if (edgbis.IsSame(edg) &&
1138 edgbis.Orientation() == edg.Orientation()) {
1139 for (itl2.Initialize(myLeft); itl2.More(); itl2.Next()) {
1140 if (itl2.Value().IsSame(fac)) {
1141 break;
1142 }
1143 }
1144 if (!itl2.More()) { // la face n`est pas deja presente
1145 myLeft.Append(fac);
1146 }
1147 break;
1148 }
1149 }
1150 if (expf.More()) { // face found
1151 break;
1152 }
1153 }
1154 }
1155 return myLeft;
1156}
1157
1158
1159//=======================================================================
1160//function : DescendantShapes
1161//purpose :
1162//=======================================================================
1163
1164const TopTools_ListOfShape& LocOpe_SplitShape::DescendantShapes
1165(const TopoDS_Shape& S)
1166{
1167 if (!myDone) {
1168 Rebuild(myShape);
1169 myDone = Standard_True;
1170 }
63c629aa 1171#ifdef LOCOPE_DEB
7fd59977 1172 if (!myDblE.IsEmpty()) {
1173 cout << "Le shape comporte des faces invalides" << endl;
1174 }
1175#endif
1176 return myMap(S);
1177}
1178
1179
1180
1181//=======================================================================
1182//function : Put
1183//purpose :
1184//=======================================================================
1185
1186void LocOpe_SplitShape::Put(const TopoDS_Shape& S)
1187{
1188 if (!myMap.IsBound(S)) {
1189 TopTools_ListOfShape thelist;
1190 myMap.Bind(S, thelist);
1191 if (S.ShapeType() != TopAbs_VERTEX) {
1192 for(TopoDS_Iterator theIterator(S);theIterator.More();
1193 theIterator.Next()) {
1194 Put(theIterator.Value());
1195 }
1196 }
1197 else {
1198 myMap(S).Append(S);
1199 }
1200 }
1201}
1202
1203
1204//=======================================================================
1205//function : Rebuild
1206//purpose :
1207//=======================================================================
1208
1209Standard_Boolean LocOpe_SplitShape::Rebuild(const TopoDS_Shape& S)
1210
1211{
1212
1213 TopTools_ListIteratorOfListOfShape itr(myMap(S));
1214 if (itr.More()) {
1215 if (itr.Value().IsSame(S)) {
1216 return Standard_False;
1217 }
1218 return Standard_True;
1219 }
1220 Standard_Boolean rebuild = Standard_False;
1221 TopoDS_Iterator it;
1222 for(it.Initialize(S); it.More(); it.Next()) {
1223 rebuild = Rebuild(it.Value()) || rebuild;
1224 }
1225
1226 if (rebuild) {
1227 BRep_Builder B;
1228 TopoDS_Shape result = S.EmptyCopied();
1229 TopAbs_Orientation orient;
1230 for(it.Initialize(S); it.More(); it.Next()) {
1231 orient = it.Value().Orientation();
1232 for (itr.Initialize(myMap(it.Value())); itr.More(); itr.Next()) {
1233 B.Add(result,itr.Value().Oriented(orient));
1234 }
1235 }
ab860031 1236 result.Closed (BRep_Tool::IsClosed(result));
7fd59977 1237 myMap(S).Append(result);
1238 }
1239 else {
1240 myMap(S).Append(S);
1241 }
1242 return rebuild;
1243}
1244
1245
1246
1247//=======================================================================
1248//function : IsInside
1249//purpose :
1250//=======================================================================
1251
1252static Standard_Boolean IsInside(const TopoDS_Face& F,
1253 const TopoDS_Wire& W1,
1254 const TopoDS_Wire& W2)
1255{
1256 // Attention, c`est tres boeuf !!!!
1257 BRep_Builder B;
1258 TopoDS_Shape aLocalShape = F.EmptyCopied();
1259 TopoDS_Face newFace = TopoDS::Face(aLocalShape);
1260 // TopoDS_Face newFace = TopoDS::Face(F.EmptyCopied());
6e6cd5d9 1261
1262 //TopAbs_Orientation orWire = W2.Orientation();
1263
7fd59977 1264 newFace.Orientation(TopAbs_FORWARD);
1265 B.Add(newFace,W2);
1266 // GProp_GProps GP;
1267 // BRepGProp::SurfaceProperties(newFace,GP);
1268 // if (GP.Mass() < 0) {
1269 BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion());
1270 Standard_Boolean Reversed = Standard_False;
1271 if (classif.PerformInfinitePoint() == TopAbs_IN) {
1272 //le wire donne defini un trou
1273 // newFace = TopoDS::Face(F.EmptyCopied());
1274 // newFace.Orientation(TopAbs_FORWARD);
1275 // orWire = TopAbs::Reverse(orWire);
1276 // B.Add(newFace,W2.Oriented(orWire));
1277 Reversed = Standard_True;
1278 }
1279
1280 // Standard_Real U,V;
1281 TopExp_Explorer exp(W1,TopAbs_EDGE);
1282 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
1283 TopExp_Explorer exp2(edg,TopAbs_VERTEX);
1284 const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current());
1285 Standard_Real prm = BRep_Tool::Parameter(vtx,edg);
1286 Standard_Real f,l;
1287 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
1288 if(C2d.IsNull()) {
63c629aa 1289#ifdef LOCOPE_DEB
7fd59977 1290 cout << "Edge is not on surface" <<endl;
1291#endif
1292 return Standard_False;
1293 }
1294 gp_Pnt2d pt2d(C2d->Value(prm));
1295 // BRepClass_FaceClassifier classif(newFace,pt2d,Precision::PConfusion());
1296 // return (classif.State() == TopAbs_IN);
1297 if (!Reversed) {
1298 return (classif.Perform(pt2d) == TopAbs_IN);
1299 }
1300 else {
1301 return (classif.Perform(pt2d) == TopAbs_OUT);
1302 }
1303}
1304
1305
1306//=======================================================================
1307//function : IsInside
1308//purpose :
1309//=======================================================================
1310
1311static Standard_Boolean IsInside(const TopoDS_Face& F,
1312 const TopoDS_Wire& W)
1313{
1314 // Attention, c`est tres boeuf !!!!
1315 TopExp_Explorer exp(W,TopAbs_EDGE);
1316 for( ; exp.More(); exp.Next()) {
1317 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
1318 // TopExp_Explorer exp2(edg,TopAbs_VERTEX);
1319 // const TopoDS_Vertex& vtx = TopoDS::Vertex(exp2.Current());
1320 // Standard_Real prm = BRep_Tool::Parameter(vtx,edg);
1321 Standard_Real f,l,prm;
1322 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
1323 if (!Precision::IsNegativeInfinite(f) &&
1324 !Precision::IsPositiveInfinite(l)) {
1325 prm = (f+l)/2.;
1326 }
1327 else {
1328 if (Precision::IsNegativeInfinite(f) &&
1329 Precision::IsPositiveInfinite(l)){
1330 prm = 0.;
1331 }
1332 else if (Precision::IsNegativeInfinite(f)) {
1333 prm = l-1.;
1334 }
1335 else {
1336 prm = f+1.;
1337 }
1338 }
1339
1340 gp_Pnt2d pt2d(C2d->Value(prm));
1341 // BRepClass_FaceClassifier classif(F,pt2d,Precision::PConfusion());
1342 // return (classif.State() != TopAbs_OUT);
1343 BRepTopAdaptor_FClass2d classif(F,Precision::PConfusion());
ed60a55e 1344 TopAbs_State stat = classif.Perform(pt2d);
7fd59977 1345 // return (classif.Perform(pt2d) != TopAbs_OUT);
1346 if(stat == TopAbs_OUT) return Standard_False;
1347
1348 if(stat == TopAbs_ON) {
1349 Standard_Integer nbPnt =10;
1350 Standard_Integer nbOut =0,nbIn =0,nbOn=0;
1351 Standard_Integer j =1;
1352 for( ; j<= nbPnt ; j++)
1353 {
1354 //check neighbouring point
1355 //prm = .66 * prm + .34 * l;
1356 prm = f + (l-f)/nbPnt*(j-1);
1357 pt2d = C2d->Value(prm);
1358 stat = classif.Perform(pt2d);
1359 if(stat == TopAbs_OUT )
1360 nbOut++;
1361 else if(stat == TopAbs_IN)
1362 nbIn++;
1363 else
1364 nbOn++;
1365 }
1366 if(nbOut > nbIn + nbOn)
1367 return Standard_False;
1368 }
1369 }
1370 return Standard_True;
1371}
1372
c1e18dd8 1373//=======================================================================
1374//function : GetDirection
1375//purpose :
1376//=======================================================================
1377static void GetDirection(const TopoDS_Edge& theEdge,
1378 const TopoDS_Face& theFace,
1379 Standard_Real& theTol,
1380 gp_Pnt2d& thePnt,
1381 gp_Vec2d& theDir)
1382{
1383 Standard_Real aFirst, aLast;
1384 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface (theEdge, theFace, aFirst, aLast);
1385
1386 TopAbs_Orientation anOr = theEdge.Orientation();
1387 TopoDS_Vertex aVtx;
1388 if (anOr == TopAbs_FORWARD)
1389 {
1390 aVtx = TopExp::FirstVertex (theEdge);
1391 aC2d->D0 (aFirst, thePnt);
1392 }
1393 else
1394 {
1395 aVtx = TopExp::LastVertex (theEdge);
1396 aC2d->D0 (aLast, thePnt);
1397 }
1398
1399 BRepAdaptor_Surface aSurf (theFace, Standard_False);
1400 theTol = BRep_Tool::Tolerance (aVtx);
1401 Standard_Real aTol = Max (aSurf.UResolution (theTol), aSurf.VResolution (theTol));
1402 aTol = Min (aTol, (aLast - aFirst)*0.1);
1403
1404 gp_Pnt2d aP2d;
1405
1406 if (anOr == TopAbs_FORWARD)
1407 {
1408 aFirst += aTol;
1409 aC2d->D0 (aFirst, aP2d);
1410 }
1411 else
1412 {
1413 aLast -= aTol;
1414 aC2d->D0 (aLast, aP2d);
1415 }
1416 theDir = gp_Vec2d (thePnt, aP2d);
1417}
7fd59977 1418
1419//=======================================================================
1420//function : ChoixUV
1421//purpose :
1422//=======================================================================
1423
1424static void ChoixUV(const TopoDS_Edge& Last,
1425 const TopoDS_Face& F,
c1e18dd8 1426 const TopTools_IndexedMapOfShape& Poss,
1427 TopoDS_Edge& theResEdge,
7fd59977 1428 gp_Pnt2d& plst,
1429 gp_Vec2d& dlst,
1430 const Standard_Real toll)
1431{
1432
1433 Standard_Real f,l;
7fd59977 1434 gp_Pnt2d p2d;
1435 gp_Vec2d v2d;
c3297e82 1436 gp_Pnt aPCur, aPlst;
7fd59977 1437
1438 BRepAdaptor_Surface surf(F,Standard_False); // no restriction
c3297e82 1439 surf.D0 (plst.X(), plst.Y(), aPlst);
7fd59977 1440
1441 Standard_Real tol;
1442
7fd59977 1443 gp_Dir2d ref2d(dlst);
1444
1445 Handle(Geom2d_Curve) C2d;
7c104885 1446 Standard_Real dpar;
7fd59977 1447
1448 Standard_Integer index = 0, imin=0;
c6541a0c 1449 Standard_Real angmax = -M_PI, dist, ang;
7fd59977 1450
1451
c1e18dd8 1452 for (index = 1; index <= Poss.Extent(); index++) {
1453 TopoDS_Edge anEdge = TopoDS::Edge (Poss.FindKey (index));
1454 GetDirection (anEdge, F, tol, p2d, v2d);
7fd59977 1455
c3297e82 1456 surf.D0 (p2d.X(), p2d.Y(), aPCur);
7fd59977 1457
7fd59977 1458 tol = Max(toll, tol); tol *= tol;
1459
c3297e82 1460 dist = aPCur.SquareDistance(aPlst);
7fd59977 1461
c1e18dd8 1462 if (!Last.IsSame(anEdge)) {
7fd59977 1463 ang = ref2d.Angle(gp_Dir2d(v2d));
1464 }
1465 else {
c6541a0c 1466 ang = -M_PI;
7fd59977 1467 }
1468
7fd59977 1469 if ((dist < tol) && (ang > angmax)) {
1470 imin = index;
7fd59977 1471 angmax = ang;
1472 }
1473 }
1474
c1e18dd8 1475 if (imin)
1476 {
1477 theResEdge = TopoDS::Edge (Poss.FindKey (imin));
1478 C2d = BRep_Tool::CurveOnSurface (theResEdge, F, f, l);
1479 dpar = (l - f)*0.01;
1480 if (theResEdge.Orientation() == TopAbs_FORWARD)
1481 {
1482 C2d->D1 (l, plst, dlst);
1483 if (dlst.Magnitude() < gp::Resolution())
1484 {
1485 gp_Pnt2d PrevPnt = C2d->Value(l - dpar);
1486 dlst.SetXY(plst.XY() - PrevPnt.XY());
7fd59977 1487 }
c1e18dd8 1488 }
1489 else
1490 {
1491 C2d->D1 (f, plst, dlst);
1492 if (dlst.Magnitude() < gp::Resolution())
1493 {
1494 gp_Pnt2d NextPnt = C2d->Value(f + dpar);
1495 dlst.SetXY(NextPnt.XY() - plst.XY());
7fd59977 1496 }
c1e18dd8 1497 dlst.Reverse();
7fd59977 1498 }
7fd59977 1499 }
1500
1501}
ed60a55e 1502
1503//=======================================================================
1504//function : ChooseDirection
1505//purpose :
1506//=======================================================================
1507
1508static TopoDS_Shape ChooseDirection(const TopoDS_Shape& RefDir,
1509 const TopoDS_Vertex& RefVertex,
1510 const TopoDS_Face& theFace,
1511 const TopTools_ListOfShape& Ldirs)
1512{
1513 TopExp_Explorer Explo(RefDir, TopAbs_EDGE);
1514 TopoDS_Edge RefEdge;
1515 TopoDS_Vertex V1, V2;
1d47d8d0 1516 TopAbs_Orientation anOr = TopAbs_FORWARD;
ed60a55e 1517 for (; Explo.More(); Explo.Next())
1518 {
1519 RefEdge = TopoDS::Edge(Explo.Current());
1520 TopExp::Vertices(RefEdge, V1, V2);
1521 if (V1.IsSame(RefVertex))
1522 {
1523 anOr = TopAbs_REVERSED;
1524 break;
1525 }
1526 else if (V2.IsSame(RefVertex))
1527 {
1528 anOr = TopAbs_FORWARD;
1529 break;
1530 }
1531 }
1532
1533 Standard_Real RefFirst, RefLast;
1534 Handle(Geom2d_Curve) RefCurve = BRep_Tool::CurveOnSurface(RefEdge, theFace, RefFirst, RefLast);
1535 gp_Pnt2d RefPnt;
1536 gp_Vec2d RefVec;
1537
1538 //Standard_Real RefPar = (RefEdge.Orientation() == TopAbs_FORWARD)? RefLast : RefFirst;
1539 Standard_Real RefPar = (anOr == TopAbs_FORWARD)? RefLast : RefFirst;
1540 RefCurve->D1(RefPar, RefPnt, RefVec);
1541 if (anOr == TopAbs_FORWARD)
1542 RefVec.Reverse();
1543
1544 Handle(Geom2d_Curve) aCurve;
1545 Standard_Real aFirst, aLast, aPar;
1546 gp_Vec2d aVec;
1547 Standard_Real MinAngle = RealLast(), anAngle;
1548 TopoDS_Shape TargetDir;
1549 TopTools_ListIteratorOfListOfShape itl(Ldirs);
1550 for (; itl.More(); itl.Next())
1551 {
1552 const TopoDS_Shape& aShape = itl.Value();
1553 TopoDS_Edge anEdge;
1554 for (Explo.Init(aShape, TopAbs_EDGE); Explo.More(); Explo.Next())
1555 {
1556 anEdge = TopoDS::Edge(Explo.Current());
1557 TopExp::Vertices(anEdge, V1, V2);
1558 if (V1.IsSame(RefVertex))
1559 {
1560 anOr = TopAbs_FORWARD;
1561 break;
1562 }
1563 else if (V2.IsSame(RefVertex))
1564 {
1565 anOr = TopAbs_REVERSED;
1566 break;
1567 }
1568 }
1569 aCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, aFirst, aLast);
1570 aPar = (anOr == TopAbs_FORWARD)? aFirst : aLast;
1571 aCurve->D1(aPar, RefPnt, aVec);
1572 if (anOr == TopAbs_REVERSED)
1573 aVec.Reverse();
1574 anAngle = aVec.Angle(RefVec);
1575 if (anAngle < 0.)
1576 anAngle += 2.*M_PI;
1577
1578 if (anAngle < MinAngle)
1579 {
1580 MinAngle = anAngle;
1581 TargetDir = aShape;
1582 }
1583 }
1584
1585 return TargetDir;
1586}