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 | |
62 | static |
63 | Standard_Boolean IsGrowthWire(const TopoDS_Shape& , |
64 | const BOPCol_IndexedMapOfShape& ); |
65 | |
66 | static |
67 | Standard_Boolean IsInside(const TopoDS_Shape& , |
68 | const TopoDS_Shape& , |
69 | Handle(BOPInt_Context)& ); |
70 | static |
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 | //======================================================================= |
115 | TopAbs_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 | //======================================================================= |
593 | void 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 | //======================================================================= |
646 | Standard_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 | //======================================================================= |
689 | Standard_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 |