0024428: Implementation of LGPL license
[occt.git] / src / BOPAlgo / BOPAlgo_BuilderFace.cxx
CommitLineData
4e57c75e 1// Created by: Peter KURNEV
973c2be1 2// Copyright (c) 2010-2014 OPEN CASCADE SAS
4e57c75e 3// Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4// Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5// EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6//
973c2be1 7// This file is part of Open CASCADE Technology software library.
4e57c75e 8//
973c2be1 9// This library is free software; you can redistribute it and / or modify it
10// under the terms of the GNU Lesser General Public version 2.1 as published
11// by the Free Software Foundation, with special exception defined in the file
12// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13// distribution for complete text of the license and disclaimer of any warranty.
4e57c75e 14//
973c2be1 15// Alternatively, this file may be used under the terms of Open CASCADE
16// commercial license or contractual agreement.
4e57c75e 17
18#include <BOPAlgo_BuilderFace.ixx>
19
20#include <gp_Pnt2d.hxx>
21#include <gp_Pln.hxx>
22#include <gp_Vec.hxx>
23#include <gp_Dir.hxx>
24#include <gp_Pnt.hxx>
25
26#include <Geom_Surface.hxx>
27
28#include <TopAbs.hxx>
29#include <TopLoc_Location.hxx>
30
31#include <TopoDS_Iterator.hxx>
32#include <TopoDS_Face.hxx>
33#include <TopoDS_Shape.hxx>
34#include <TopoDS_Wire.hxx>
35#include <TopoDS_Edge.hxx>
36#include <TopoDS_Vertex.hxx>
37
38#include <BRep_Builder.hxx>
39#include <BRep_Tool.hxx>
40#include <BRepTools.hxx>
41
42#include <TopExp.hxx>
43#include <TopExp_Explorer.hxx>
44
45#include <IntTools_FClass2d.hxx>
46#include <BOPInt_Context.hxx>
47
48//
49#include <BOPTools_AlgoTools.hxx>
50#include <BOPTools_AlgoTools2D.hxx>
51#include <BOPAlgo_WireEdgeSet.hxx>
52//
53#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
54#include <BOPTools.hxx>
55#include <BOPCol_ListOfShape.hxx>
56#include <BOPAlgo_WireSplitter.hxx>
57#include <BOPCol_DataMapOfShapeShape.hxx>
58#include <BOPCol_DataMapOfShapeListOfShape.hxx>
59#include <BOPCol_MapOfShape.hxx>
60
61
62static
63 Standard_Boolean IsGrowthWire(const TopoDS_Shape& ,
64 const BOPCol_IndexedMapOfShape& );
65
66static
67 Standard_Boolean IsInside(const TopoDS_Shape& ,
68 const TopoDS_Shape& ,
69 Handle(BOPInt_Context)& );
70static
71 void MakeInternalWires(const BOPCol_MapOfShape& ,
72 BOPCol_ListOfShape& );
73
74//=======================================================================
75//function :
76//purpose :
77//=======================================================================
78 BOPAlgo_BuilderFace::BOPAlgo_BuilderFace()
79:
80 BOPAlgo_BuilderArea()
81{
acccace3 82 myOrientation=TopAbs_EXTERNAL;
4e57c75e 83}
84//=======================================================================
85//function :
86//purpose :
87//=======================================================================
88 BOPAlgo_BuilderFace::BOPAlgo_BuilderFace(const Handle(NCollection_BaseAllocator)& theAllocator)
89:
90 BOPAlgo_BuilderArea(theAllocator)
acccace3 91{
92 myOrientation=TopAbs_EXTERNAL;
4e57c75e 93}
94//=======================================================================
95//function : ~
96//purpose :
97//=======================================================================
98 BOPAlgo_BuilderFace::~BOPAlgo_BuilderFace()
99{
100}
101//=======================================================================
102//function : SetFace
103//purpose :
104//=======================================================================
105 void BOPAlgo_BuilderFace::SetFace(const TopoDS_Face& theFace)
106{
acccace3 107 myOrientation=theFace.Orientation();
4e57c75e 108 myFace=theFace;
acccace3 109 myFace.Orientation(TopAbs_FORWARD);
110}
111//=======================================================================
112//function : Orientation
113//purpose :
114//=======================================================================
115TopAbs_Orientation BOPAlgo_BuilderFace::Orientation()const
116{
117 return myOrientation;
4e57c75e 118}
119//=======================================================================
120//function : Face
121//purpose :
122//=======================================================================
123 const TopoDS_Face& BOPAlgo_BuilderFace::Face()const
124{
125 return myFace;
126}
127//=======================================================================
128//function : CheckData
129//purpose :
130//=======================================================================
131 void BOPAlgo_BuilderFace::CheckData()
132{
133 myErrorStatus=0;
134 //
135 if (myContext.IsNull()) {
136 //myErrorStatus=11;// Null Context
137 //return;
138 myContext = new BOPInt_Context;
139 }
140 //
141 if (myFace.IsNull()) {
142 myErrorStatus=12;// Null face generix
143 return;
144 }
145}
146//=======================================================================
147//function : Perform
148//purpose :
149//=======================================================================
150 void BOPAlgo_BuilderFace::Perform()
151{
152 myErrorStatus=0;
153 //
154 CheckData();
155 if (myErrorStatus) {
156 return;
157 }
158 //
159 PerformShapesToAvoid();
160 if (myErrorStatus) {
161 return;
162 }
163 //
164 PerformLoops();
165 if (myErrorStatus) {
166 return;
167 }
168 //
169 PerformAreas();
170 if (myErrorStatus) {
171 return;
172 }
173 //
174 PerformInternalShapes();
175 if (myErrorStatus) {
176 return;
177 }
178}
179//=======================================================================
180//function :PerformShapesToAvoid
181//purpose :
182//=======================================================================
183 void BOPAlgo_BuilderFace::PerformShapesToAvoid()
184{
185 Standard_Boolean bFound;
186 Standard_Integer i, iCnt, aNbV, aNbE;
187 BOPCol_IndexedDataMapOfShapeListOfShape aMVE;
188 BOPCol_ListIteratorOfListOfShape aIt;
189 //
190 myShapesToAvoid.Clear();
191 //
192 iCnt=0;
302f96fb 193 for(;;) {
4e57c75e 194 ++iCnt;
195 bFound=Standard_False;
196 //
197 // 1. MEF
198 aMVE.Clear();
199 aIt.Initialize (myShapes);
200 for (; aIt.More(); aIt.Next()) {
201 const TopoDS_Shape& aE=aIt.Value();
202 if (!myShapesToAvoid.Contains(aE)) {
203 BOPTools::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
204 }
205 //else {
206 //int a=0;
207 //}
208 }
209 aNbV=aMVE.Extent();
210 //
211 // 2. myEdgesToAvoid
212 for (i=1; i<=aNbV; ++i) {
213 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aMVE.FindKey(i)));
214 //
215 BOPCol_ListOfShape& aLE=aMVE.ChangeFromKey(aV);
216 aNbE=aLE.Extent();
217 if (!aNbE) {
218 continue;
219 }
220 //
221 const TopoDS_Edge& aE1=(*(TopoDS_Edge *)(&aLE.First()));
222 if (aNbE==1) {
223 if (BRep_Tool::Degenerated(aE1)) {
224 continue;
225 }
226 if (aV.Orientation()==TopAbs_INTERNAL) {
227 continue;
228 }
229 bFound=Standard_True;
230 myShapesToAvoid.Add(aE1);
231 }
232 else if (aNbE==2) {
233 const TopoDS_Edge& aE2=(*(TopoDS_Edge *)(&aLE.Last()));
234 if (aE2.IsSame(aE1)) {
235 TopoDS_Vertex aV1x, aV2x;
236 //
237 TopExp::Vertices(aE1, aV1x, aV2x);
238 if (aV1x.IsSame(aV2x)) {
239 continue;
240 }
241 bFound=Standard_True;
242 myShapesToAvoid.Add(aE1);
243 myShapesToAvoid.Add(aE2);
244 }
245 }
246 }// for (i=1; i<=aNbE; ++i) {
247 //
248 if (!bFound) {
249 break;
250 }
251 //
252 }//while (1)
253 //printf(" EdgesToAvoid=%d, iCnt=%d\n", EdgesToAvoid.Extent(), iCnt);
254}
255//=======================================================================
256//function : PerformLoops
257//purpose :
258//=======================================================================
259 void BOPAlgo_BuilderFace::PerformLoops()
260{
261 myErrorStatus=0;
262 //
263 Standard_Boolean bFlag;
264 Standard_Integer iErr, aNbEA;
265 BOPCol_ListIteratorOfListOfShape aIt;
266 BOPCol_MapIteratorOfMapOfOrientedShape aItM;
267 BOPCol_IndexedDataMapOfShapeListOfShape aVEMap;
268 BOPCol_MapOfOrientedShape aMAdded;
269 TopoDS_Iterator aItW;
270 BRep_Builder aBB;
271 BOPAlgo_WireEdgeSet aWES(myAllocator);
272 BOPAlgo_WireSplitter aWSp(myAllocator);
273 //
274 // 1.
275 myLoops.Clear();
276 aWES.SetFace(myFace);
277 //
278 aIt.Initialize(myShapes);
279 for (; aIt.More(); aIt.Next()) {
280 const TopoDS_Shape& aE=aIt.Value();
281 if (!myShapesToAvoid.Contains(aE)) {
282 aWES.AddStartElement(aE);
283 }
284 }
285 //
286 aWSp.SetWES(aWES);
287 aWSp.Perform();
288 iErr=aWSp.ErrorStatus();
289 if (iErr) {
290 return;
291 }
292 //
293 const BOPCol_ListOfShape& aLW=aWES.Shapes();
294 aIt.Initialize (aLW);
295 for (; aIt.More(); aIt.Next()) {
296 const TopoDS_Shape& aW=aIt.Value();
297 myLoops.Append(aW);
298 }
299 // Post Treatment
300 BOPCol_MapOfOrientedShape aMEP;
301 //
302 // a. collect all edges that are in loops
303 aIt.Initialize (myLoops);
304 for (; aIt.More(); aIt.Next()) {
305 const TopoDS_Shape& aW=aIt.Value();
306 aItW.Initialize(aW);
307 for (; aItW.More(); aItW.Next()) {
308 const TopoDS_Shape& aE=aItW.Value();
309 aMEP.Add(aE);
310 }
311 }
312 //
313 // b. collect all edges that are to avoid
314 aItM.Initialize(myShapesToAvoid);
315 for (; aItM.More(); aItM.Next()) {
316 const TopoDS_Shape& aE=aItM.Key();
317 aMEP.Add(aE);
318 }
319 //
320 // c. add all edges that are not processed to myShapesToAvoid
321 aIt.Initialize (myShapes);
322 for (; aIt.More(); aIt.Next()) {
323 const TopoDS_Shape& aE=aIt.Value();
324 if (!aMEP.Contains(aE)) {
325 myShapesToAvoid.Add(aE);
326 }
327 }
328 //
329 // 2. Internal Wires
330 myLoopsInternal.Clear();
331 //
332 aNbEA=myShapesToAvoid.Extent();
333 aItM.Initialize(myShapesToAvoid);
334 for (; aItM.More(); aItM.Next()) {
335 const TopoDS_Shape& aEE=aItM.Key();
336 BOPTools::MapShapesAndAncestors(aEE, TopAbs_VERTEX, TopAbs_EDGE, aVEMap);
337 }
338 //
339 bFlag=Standard_True;
340 aItM.Initialize(myShapesToAvoid);
341 for (; aItM.More()&&bFlag; aItM.Next()) {
342 const TopoDS_Shape& aEE=aItM.Key();
343 if (!aMAdded.Add(aEE)) {
344 continue;
345 }
346 //
347 // make new wire
348 TopoDS_Wire aW;
349 aBB.MakeWire(aW);
350 aBB.Add(aW, aEE);
351 //
352 aItW.Initialize(aW);
353 for (; aItW.More()&&bFlag; aItW.Next()) {
354 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aItW.Value()));
355 //
356 TopoDS_Iterator aItE(aE);
357 for (; aItE.More()&&bFlag; aItE.Next()) {
358 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&aItE.Value()));
359 const BOPCol_ListOfShape& aLE=aVEMap.FindFromKey(aV);
360 aIt.Initialize(aLE);
361 for (; aIt.More()&&bFlag; aIt.Next()) {
362 const TopoDS_Shape& aEx=aIt.Value();
363 if (aMAdded.Add(aEx)) {
364 aBB.Add(aW, aEx);
365 if(aMAdded.Extent()==aNbEA) {
366 bFlag=!bFlag;
367 }
368 }
369 }//for (; aIt.More(); aIt.Next()) {
370 }//for (; aItE.More(); aItE.Next()) {
371 }//for (; aItW.More(); aItW.Next()) {
372 myLoopsInternal.Append(aW);
373 }//for (; aItM.More(); aItM.Next()) {
374}
375//=======================================================================
376//function : PerformAreas
377//purpose :
378//=======================================================================
379 void BOPAlgo_BuilderFace::PerformAreas()
380{
381 myErrorStatus=0;
382 //
383 Standard_Boolean bIsGrowth, bIsHole;
384 Standard_Real aTol;
385 TopoDS_Shape anInfinitePointShape;
386 //
387 BOPCol_ListOfShape aNewFaces, aHoleWires;
388 BOPCol_DataMapOfShapeShape aInOutMap;
389 BOPCol_DataMapOfShapeListOfShape aMSH;
390 BOPCol_IndexedMapOfShape aMHE;
391
392 BOPCol_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
393 BOPCol_ListIteratorOfListOfShape aIt1, aIt2;
394 BRep_Builder aBB;
395 Handle(Geom_Surface) aS;
396 TopLoc_Location aLoc;
397 //
398 aTol=BRep_Tool::Tolerance(myFace);
399 aS=BRep_Tool::Surface(myFace, aLoc);
400 //
401 myAreas.Clear();
402 //
403 // Draft faces [aNewFaces]
404 aIt1.Initialize(myLoops);
405 for ( ; aIt1.More(); aIt1.Next()) {
406 const TopoDS_Shape& aWire=aIt1.Value();
407 //
408 bIsGrowth=IsGrowthWire(aWire, aMHE);
409 if (bIsGrowth) {
410 // make a growth face from a wire
411 TopoDS_Face aFace;
412 aBB.MakeFace(aFace, aS, aLoc, aTol);
413 aBB.Add (aFace, aWire);
414 //
415 aNewFaces.Append (aFace);
416 }
417 else{
418 // check if a wire is a hole
419 //XX
420 TopoDS_Face aFace;
421 aBB.MakeFace(aFace, aS, aLoc, aTol);
422 aBB.Add (aFace, aWire);
423 //
424 IntTools_FClass2d& aClsf=myContext->FClass2d(aFace);
425 aClsf.Init(aFace, aTol);
426 //
427 bIsHole=aClsf.IsHole();
428 //
429 //bIsHole=BOPTools_AlgoTools::IsHole(aWire, myFace);
430 //XX
431 if (bIsHole) {
432 aHoleWires.Append(aWire);
433 BOPTools::MapShapes(aWire, TopAbs_EDGE, aMHE);
434 }
435 else {
436 // make a growth face from a wire
437 TopoDS_Face aFace;
438 aBB.MakeFace(aFace, aS, aLoc, aTol);
439 aBB.Add (aFace, aWire);
440 //
441 aNewFaces.Append (aFace);
442 }
443 }
444 }
445 //
446 // 2. Find outer growth shell that is most close to each hole shell
447 aIt2.Initialize(aHoleWires);
448 for (; aIt2.More(); aIt2.Next()) {
449 const TopoDS_Shape& aHole = aIt2.Value();
450 //
451 aIt1.Initialize(aNewFaces);
452 for ( ; aIt1.More(); aIt1.Next()) {
453 const TopoDS_Shape& aF=aIt1.Value();
454 //
455 if (!IsInside(aHole, aF, myContext)){
456 continue;
457 }
458 //
459 if ( aInOutMap.IsBound (aHole)){
460 const TopoDS_Shape& aF2=aInOutMap(aHole);
461 if (IsInside(aF, aF2, myContext)) {
462 aInOutMap.UnBind(aHole);
463 aInOutMap.Bind (aHole, aF);
464 }
465 }
466 else{
467 aInOutMap.Bind (aHole, aF);
468 }
469 }
470 //
471 // Add aHole to a map Face/ListOfHoles [aMSH]
472 if (aInOutMap.IsBound(aHole)){
473 const TopoDS_Shape& aF=aInOutMap(aHole);
474 if (aMSH.IsBound(aF)) {
475 BOPCol_ListOfShape& aLH=aMSH.ChangeFind(aF);
476 aLH.Append(aHole);
477 }
478 else {
479 BOPCol_ListOfShape aLH;
480 aLH.Append(aHole);
481 aMSH.Bind(aF, aLH);
482 }
483 }
484 }// for (; aIt2.More(); aIt2.Next())
485 //
486 // 3. Add aHoles to Faces
487 aItMSH.Initialize(aMSH);
488 for (; aItMSH.More(); aItMSH.Next()) {
489 TopoDS_Face aF=(*(TopoDS_Face *)(&aItMSH.Key()));
490 //
491 const BOPCol_ListOfShape& aLH=aItMSH.Value();
492 aIt2.Initialize(aLH);
493 for (; aIt2.More(); aIt2.Next()) {
494 const TopoDS_Shape& aHole = aIt2.Value();
495 aBB.Add (aF, aHole);
496 }
497 //
498 // update classifier
499 aTol=BRep_Tool::Tolerance(aF);
500 IntTools_FClass2d& aClsf=myContext->FClass2d(aF);
501 aClsf.Init(aF, aTol);
502 }
503 //
504 // These aNewFaces are draft faces that
505 // do not contain any internal shapes
506 //
507 aIt1.Initialize(aNewFaces);
508 for ( ; aIt1.More(); aIt1.Next()) {
509 const TopoDS_Shape& aF=aIt1.Value();
510 myAreas.Append(aF);
511 }
512}
513//=======================================================================
514//function : PerformInternalShapes
515//purpose :
516//=======================================================================
517 void BOPAlgo_BuilderFace::PerformInternalShapes()
518{
519 myErrorStatus=0;
520 //
521 Standard_Integer aNbWI=myLoopsInternal.Extent();
522 if (!aNbWI) {// nothing to do
523 return;
524 }
525 //
526 //Standard_Real aTol;
527 BRep_Builder aBB;
528 BOPCol_ListIteratorOfListOfShape aIt1, aIt2;
529 TopoDS_Iterator aIt;
530 BOPCol_MapOfShape aME, aMEP;
531 BOPCol_MapIteratorOfMapOfShape aItME;
532 BOPCol_IndexedDataMapOfShapeListOfShape aMVE;
533 BOPCol_ListOfShape aLSI;
534 //
535 // 1. All internal edges
536 aIt1.Initialize(myLoopsInternal);
537 for (; aIt1.More(); aIt1.Next()) {
538 const TopoDS_Shape& aWire=aIt1.Value();
539 aIt.Initialize(aWire);
540 for (; aIt.More(); aIt.Next()) {
541 const TopoDS_Shape& aE=aIt.Value();
542 aME.Add(aE);
543 }
544 }
545 aNbWI=aME.Extent();
546 //
547 // 2 Process faces
548 aIt2.Initialize(myAreas);
549 for ( ; aIt2.More(); aIt2.Next()) {
550 TopoDS_Face& aF=(*(TopoDS_Face *)(&aIt2.Value()));
551 //
552 aMVE.Clear();
553 BOPTools::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
554 //
555 // 2.1 Separate faces to process aMEP
556 aMEP.Clear();
557 aItME.Initialize(aME);
558 for (; aItME.More(); aItME.Next()) {
559 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aItME.Key()));
560 if (IsInside(aE, aF, myContext)) {
561 aMEP.Add(aE);
562 }
563 }
564 //
565 // 2.2 Make Internal Wires
566 aLSI.Clear();
567 MakeInternalWires(aMEP, aLSI);
568 //
569 // 2.3 Add them to aF
570 aIt1.Initialize(aLSI);
571 for (; aIt1.More(); aIt1.Next()) {
572 const TopoDS_Shape& aSI=aIt1.Value();
573 aBB.Add (aF, aSI);
574 }
575 //
576 // 2.4 Remove faces aMFP from aMF
577 aItME.Initialize(aMEP);
578 for (; aItME.More(); aItME.Next()) {
579 const TopoDS_Shape& aE=aItME.Key();
580 aME.Remove(aE);
581 }
582 //
583 aNbWI=aME.Extent();
584 if (!aNbWI) {
585 break;
586 }
587 } //for ( ; aIt2.More(); aIt2.Next()) {
588}
589//=======================================================================
590//function : MakeInternalWires
591//purpose :
592//=======================================================================
593void MakeInternalWires(const BOPCol_MapOfShape& theME,
594 BOPCol_ListOfShape& theWires)
595{
596 BOPCol_MapIteratorOfMapOfShape aItM;
597 BOPCol_MapOfShape aAddedMap;
598 BOPCol_ListIteratorOfListOfShape aItE;
599 BOPCol_IndexedDataMapOfShapeListOfShape aMVE;
600 BRep_Builder aBB;
601 //
602 aItM.Initialize(theME);
603 for (; aItM.More(); aItM.Next()) {
604 const TopoDS_Shape& aE=aItM.Key();
605 BOPTools::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
606 }
607 //
608 aItM.Initialize(theME);
609 for (; aItM.More(); aItM.Next()) {
610 TopoDS_Shape aEE=aItM.Key();
611 if (!aAddedMap.Add(aEE)) {
612 continue;
613 }
614 //
615 // make a new shell
616 TopoDS_Wire aW;
617 aBB.MakeWire(aW);
618 aEE.Orientation(TopAbs_INTERNAL);
619 aBB.Add(aW, aEE);
620 //
621 TopoDS_Iterator aItAdded (aW);
622 for (; aItAdded.More(); aItAdded.Next()) {
623 const TopoDS_Shape& aE =aItAdded.Value();
624 //
625 TopExp_Explorer aExp(aE, TopAbs_VERTEX);
626 for (; aExp.More(); aExp.Next()) {
627 const TopoDS_Shape& aV =aExp.Current();
628 const BOPCol_ListOfShape& aLE=aMVE.FindFromKey(aV);
629 aItE.Initialize(aLE);
630 for (; aItE.More(); aItE.Next()) {
631 TopoDS_Shape aEL=aItE.Value();
632 if (aAddedMap.Add(aEL)){
633 aEL.Orientation(TopAbs_INTERNAL);
634 aBB.Add(aW, aEL);
635 }
636 }
637 }
638 }
639 theWires.Append(aW);
640 }
641}
642//=======================================================================
643//function : IsInside
644//purpose :
645//=======================================================================
646Standard_Boolean IsInside(const TopoDS_Shape& theHole,
647 const TopoDS_Shape& theF2,
648 Handle(BOPInt_Context)& theContext)
649{
650 Standard_Boolean bRet;
651 Standard_Real aT, aU, aV;
652
653 TopAbs_State aState;
654 TopExp_Explorer aExp;
655 BOPCol_IndexedMapOfShape aME2;
656 gp_Pnt2d aP2D;
657 //
658 bRet=Standard_False;
659 aState=TopAbs_UNKNOWN;
660 const TopoDS_Face& aF2=(*(TopoDS_Face *)(&theF2));
661 //
662 BOPTools::MapShapes(aF2, TopAbs_EDGE, aME2);//AA
663 //
664 aExp.Init(theHole, TopAbs_EDGE);
665 if (aExp.More()) {
666 const TopoDS_Edge& aE =(*(TopoDS_Edge *)(&aExp.Current()));
667 if (aME2.Contains(aE)) {
668 return bRet;
669 }
670 if (!BRep_Tool::Degenerated(aE)) {
671 //
672 aT=BOPTools_AlgoTools2D::IntermediatePoint(aE);
673 BOPTools_AlgoTools2D::PointOnSurface(aE, aF2, aT, aU, aV);
674 aP2D.SetCoord(aU, aV);
675 //
676 IntTools_FClass2d& aClsf=theContext->FClass2d(aF2);
677 aState=aClsf.Perform(aP2D);
678 bRet=(aState==TopAbs_IN);
679 }
680 }
681 //
682 return bRet;
683}
684
685//=======================================================================
686//function : IsGrowthWire
687//purpose :
688//=======================================================================
689Standard_Boolean IsGrowthWire(const TopoDS_Shape& theWire,
690 const BOPCol_IndexedMapOfShape& theMHE)
691{
692 Standard_Boolean bRet;
693 TopoDS_Iterator aIt;
694 //
695 bRet=Standard_False;
696 if (theMHE.Extent()) {
697 aIt.Initialize(theWire);
698 for(; aIt.More(); aIt.Next()) {
699 const TopoDS_Shape& aE=aIt.Value();
700 if (theMHE.Contains(aE)) {
701 return !bRet;
702 }
703 }
704 }
705 return bRet;
706}
707
708//BRepTools::Write(aFF, "ff");
709//
710// ErrorStatus :
711// 11 - Null Context
712// 12 - Null face generix