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