b311480e |
1 | // Created on: 1995-04-25 |
2 | // Created by: Jacques GOUSSARD |
3 | // Copyright (c) 1995-1999 Matra Datavision |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
5 | // |
6 | // The content of this file is subject to the Open CASCADE Technology Public |
7 | // License Version 6.5 (the "License"). You may not use the content of this file |
8 | // except in compliance with the License. Please obtain a copy of the License |
9 | // at http://www.opencascade.org and read it completely before using this file. |
10 | // |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
13 | // |
14 | // The Original Code and all software distributed under the License is |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
16 | // Initial Developer hereby disclaims all such warranties, including without |
17 | // limitation, any warranties of merchantability, fitness for a particular |
18 | // purpose or non-infringement. Please see the License for the specific terms |
19 | // and conditions governing the rights and limitations under the License. |
20 | |
7fd59977 |
21 | |
22 | |
23 | #include <LocOpe_Builder.ixx> |
24 | |
25 | #include <LocOpe_DataMapOfShapePnt.hxx> |
26 | #include <LocOpe_DataMapIteratorOfDataMapOfShapePnt.hxx> |
27 | #include <LocOpe.hxx> |
28 | |
29 | |
30 | //#include <TopOpeBRepDS_HDataStructure.hxx> |
31 | //#include <TopOpeBRepDS_DataStructure.hxx> |
32 | #include <BRepAlgo_Tool.hxx> |
33 | #include <BRep_Tool.hxx> |
34 | #include <BRep_Builder.hxx> |
35 | #include <TColStd_MapOfInteger.hxx> |
36 | |
37 | #include <TopTools_ListOfShape.hxx> |
38 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
39 | #include <TopTools_MapOfShape.hxx> |
40 | #include <TopTools_MapIteratorOfMapOfShape.hxx> |
41 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
42 | |
43 | #include <TColStd_Array1OfInteger.hxx> |
44 | |
45 | #include <TopoDS.hxx> |
46 | #include <TopoDS_Compound.hxx> |
47 | #include <TopExp.hxx> |
48 | #include <Precision.hxx> |
49 | #include <Geom_Surface.hxx> |
50 | #include <Geom_Plane.hxx> |
51 | #include <Geom_RectangularTrimmedSurface.hxx> |
52 | #include <gp_Pln.hxx> |
53 | #include <BRepAlgo.hxx> |
54 | #include <Standard_ErrorHandler.hxx> |
55 | #include <BRepAlgo_Tool.hxx> |
56 | #include <BRep_Builder.hxx> |
57 | #include <BooleanOperations_ShapesDataStructure.hxx> |
58 | #include <BOPTools_DSFiller.hxx> |
59 | #include <BOPTools_PDSFiller.hxx> |
60 | #include <BOP_Builder.hxx> |
61 | #include <BOP_PBuilder.hxx> |
62 | #include <BOPTools_InterferencePool.hxx> |
63 | #include <BOPTools_CArray1OfSSInterference.hxx> |
64 | #include <BOPTools_SSInterference.hxx> |
65 | #include <BOPTools_ListOfPaveBlock.hxx> |
66 | #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx> |
67 | #include <BOPTools_PaveBlock.hxx> |
68 | #include <BOPTools_SequenceOfCurves.hxx> |
69 | #include <BOPTools_Curve.hxx> |
70 | #include <TopExp_Explorer.hxx> |
71 | #include <TopoDS_Face.hxx> |
72 | #include <stdio.h> |
73 | |
74 | //#define DRAW |
75 | #ifdef DRAW |
76 | #include <TestTopOpe.hxx> |
77 | #include <DBRep.hxx> |
78 | #endif |
79 | |
80 | void RemoveFaces(const TopoDS_Shape& theComp, const BOPTools_PDSFiller& theDSFiller, |
81 | TopTools_MapOfShape& theMap) |
82 | { |
83 | const BooleanOperations_ShapesDataStructure& aDS = theDSFiller->DS(); |
84 | const BOPTools_InterferencePool& anInterfPool = theDSFiller->InterfPool(); |
85 | BOPTools_InterferencePool* pInterfPool = (BOPTools_InterferencePool*) &anInterfPool; |
86 | BOPTools_CArray1OfSSInterference& aFFs = pInterfPool->SSInterferences(); |
87 | |
88 | TopTools_MapOfShape aCompMap; |
89 | TopExp_Explorer anExp(theComp, TopAbs_EDGE); |
90 | for(; anExp.More(); anExp.Next()) { |
91 | aCompMap.Add(anExp.Current()); |
92 | } |
93 | |
94 | Standard_Integer aNbFFs=aFFs.Extent(), i, j, aNbS, aNbCurves, nSect; |
95 | |
96 | for (i=1; i<=aNbFFs; ++i) { |
97 | BOPTools_SSInterference& aFFi=aFFs(i); |
98 | // |
99 | // |
100 | // Old Section Edges |
101 | const BOPTools_ListOfPaveBlock& aSectList=aFFi.PaveBlocks(); |
102 | aNbS=aSectList.Extent(); |
103 | BOPTools_ListIteratorOfListOfPaveBlock anIt(aSectList); |
104 | for (; anIt.More();anIt.Next()) { |
105 | const BOPTools_PaveBlock& aPB=anIt.Value(); |
106 | nSect=aPB.Edge(); |
107 | const TopoDS_Shape& aS=aDS.GetShape(nSect); |
108 | |
109 | const TopoDS_Edge& aE = TopoDS::Edge(aS); |
110 | |
111 | if(!aCompMap.Contains(aE)) continue; |
112 | |
113 | Standard_Integer nF1 = aFFi.Index1(); |
114 | Standard_Integer nF2 = aFFi.Index2(); |
115 | |
116 | const TopoDS_Shape& aF1 = aDS.Shape(nF1); |
117 | const TopoDS_Shape& aF2 = aDS.Shape(nF2); |
118 | |
119 | if(theMap.Contains(aF1)) theMap.Remove(aF1); |
120 | if(theMap.Contains(aF2)) theMap.Remove(aF2); |
121 | |
122 | |
123 | } |
124 | // |
125 | // New Section Edges |
126 | BOPTools_SequenceOfCurves& aBCurves=aFFi.Curves(); |
127 | aNbCurves=aBCurves.Length(); |
128 | for (j=1; j<=aNbCurves; j++) { |
129 | BOPTools_Curve& aBC=aBCurves(j); |
130 | const BOPTools_ListOfPaveBlock& aSectEdges=aBC.NewPaveBlocks(); |
131 | aNbS=aSectEdges.Extent(); |
132 | |
133 | BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSectEdges); |
134 | for (; aPBIt.More(); aPBIt.Next()) { |
135 | BOPTools_PaveBlock& aPB=aPBIt.Value(); |
136 | nSect=aPB.Edge(); |
137 | const TopoDS_Shape& aS=aDS.GetShape(nSect); |
138 | const TopoDS_Edge& aE = TopoDS::Edge(aS); |
139 | |
140 | if(!aCompMap.Contains(aE)) continue; |
141 | |
142 | Standard_Integer nF1 = aFFi.Index1(); |
143 | Standard_Integer nF2 = aFFi.Index2(); |
144 | |
145 | const TopoDS_Shape& aF1 = aDS.Shape(nF1); |
146 | const TopoDS_Shape& aF2 = aDS.Shape(nF2); |
147 | |
148 | if(theMap.Contains(aF1)) theMap.Remove(aF1); |
149 | if(theMap.Contains(aF2)) theMap.Remove(aF2); |
150 | |
151 | } |
152 | } |
153 | } |
154 | |
155 | } |
156 | |
157 | inline Standard_Boolean Egal(const gp_Pnt& P1, const gp_Pnt& P2) |
158 | { |
159 | |
160 | return ((P1.X() == P2.X()) && |
161 | (P1.Y() == P2.Y()) && |
162 | (P1.Z() == P2.Z())); |
163 | |
164 | } |
165 | |
166 | |
167 | //======================================================================= |
168 | //function : LocOpe_Builder |
169 | //purpose : |
170 | //======================================================================= |
171 | |
172 | LocOpe_Builder::LocOpe_Builder() : |
173 | myDone(Standard_False), myPdone(Standard_False),myPerfdone(Standard_False), |
174 | myInvDone(Standard_False) |
175 | { |
176 | |
177 | } |
178 | |
179 | |
180 | //======================================================================= |
181 | //function : LocOpe_Builder |
182 | //purpose : |
183 | //======================================================================= |
184 | |
185 | LocOpe_Builder::LocOpe_Builder(const TopoDS_Shape& S) : |
186 | myDone(Standard_False), myShape(S), myTool(S), |
187 | myPdone(Standard_False), myPerfdone(Standard_False), |
188 | myInvDone(Standard_False) |
189 | { |
190 | |
191 | if (S.IsNull()) { |
192 | Standard_ConstructionError::Raise(); |
193 | } |
194 | } |
195 | |
196 | |
197 | //======================================================================= |
198 | //function : LocOpe_Builder |
199 | //purpose : |
200 | //======================================================================= |
201 | |
202 | LocOpe_Builder::LocOpe_Builder(const TopoDS_Shape& S, |
203 | const TopoDS_Shape& T) : |
204 | myDone(Standard_False), myShape(S), myTool(T), |
205 | myPdone(Standard_False), myPerfdone(Standard_False), |
206 | myInvDone(Standard_False) |
207 | { |
208 | |
209 | if (S.IsNull()|| T.IsNull()) { |
210 | Standard_ConstructionError::Raise(); |
211 | } |
212 | } |
213 | |
214 | |
215 | //======================================================================= |
216 | //function : Init |
217 | //purpose : |
218 | //======================================================================= |
219 | |
220 | void LocOpe_Builder::Init(const TopoDS_Shape& S) |
221 | { |
222 | if (S.IsNull()) { |
223 | Standard_ConstructionError::Raise(); |
224 | } |
225 | |
226 | myDone = Standard_False; |
227 | myPdone = Standard_False; |
228 | myPerfdone = Standard_False; |
229 | myInvDone = Standard_False; |
230 | myShape = S; |
231 | myTool = S; |
232 | myParts.Clear(); |
233 | myRemoved.Clear(); |
234 | myResult.Nullify(); |
235 | } |
236 | |
237 | //======================================================================= |
238 | //function : Init |
239 | //purpose : |
240 | //======================================================================= |
241 | |
242 | void LocOpe_Builder::Init(const TopoDS_Shape& S, |
243 | const TopoDS_Shape& T) |
244 | { |
245 | if (S.IsNull() || T.IsNull()) { |
246 | Standard_ConstructionError::Raise(); |
247 | } |
248 | |
249 | myDone = Standard_False; |
250 | myPdone = Standard_False; |
251 | myPerfdone = Standard_False; |
252 | myInvDone = Standard_False; |
253 | myShape = S; |
254 | myTool = T; |
255 | myParts.Clear(); |
256 | myRemoved.Clear(); |
257 | myResult.Nullify(); |
258 | } |
259 | |
260 | |
261 | //======================================================================= |
262 | //function : Perform |
263 | //purpose : |
264 | //======================================================================= |
265 | |
266 | void LocOpe_Builder::Perform (const TopoDS_Shape& Tool, |
267 | const TopTools_ListOfShape& L, |
268 | const Standard_Boolean Fuse) |
269 | { |
270 | |
271 | if (Tool.IsNull() || myShape.IsSame(Tool)) { |
272 | Standard_ConstructionError::Raise(); |
273 | } |
274 | myTool = Tool; |
275 | TopTools_ListOfShape LTool; |
276 | TopExp_Explorer exp; |
277 | for (exp.Init(myTool,TopAbs_FACE); exp.More(); exp.Next()) { |
278 | // for (TopExp_Explorer exp(myTool,TopAbs_FACE); exp.More(); exp.Next()) { |
279 | LTool.Append(exp.Current()); |
280 | } |
281 | Perform(L,LTool,Fuse); |
282 | } |
283 | |
284 | |
285 | //======================================================================= |
286 | //function : Perform |
287 | //purpose : |
288 | //======================================================================= |
289 | |
290 | void LocOpe_Builder::Perform (const TopTools_ListOfShape& LShape, |
291 | const TopTools_ListOfShape& LTool, |
292 | const Standard_Boolean Fuse) |
293 | { |
294 | |
295 | |
296 | myPerfdone = Standard_False; |
297 | myInvDone = Standard_False; |
298 | |
299 | myDone = Standard_False; |
300 | myPdone = Standard_False; |
301 | |
302 | myFuse = Fuse; |
303 | TopAbs_State St2 = (myFuse) ? TopAbs_OUT : TopAbs_IN; |
304 | |
305 | |
306 | TopTools_MapOfShape mapUsedShape,mapUsedTool,mapShape, |
307 | mapTool,mapAdded, NewEdges; |
308 | TopTools_IndexedDataMapOfShapeListOfShape EFMap; |
309 | TopTools_ListIteratorOfListOfShape its(LShape),itt(LTool); |
310 | TopTools_MapIteratorOfMapOfShape itm,itm2; |
311 | TopTools_ListOfShape newFS,newFT; |
312 | BRep_Builder B; |
313 | |
314 | Standard_Boolean found; |
315 | |
316 | TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,EFMap); |
317 | if (!myTool.IsSame(myShape)) { |
318 | TopExp::MapShapesAndAncestors(myTool,TopAbs_EDGE,TopAbs_FACE,EFMap); |
319 | } |
320 | |
321 | // on veut l`orientation relative correcte des faces dans le shape |
322 | // for (TopExp_Explorer it(myShape.Oriented(TopAbs_FORWARD),TopAbs_FACE); |
323 | TopExp_Explorer it(myShape.Oriented(TopAbs_FORWARD),TopAbs_FACE); |
324 | for ( ; it.More(); it.Next()) { |
325 | mapShape.Add(it.Current()); |
326 | } |
327 | |
328 | for (it.Init(myTool.Oriented(TopAbs_FORWARD),TopAbs_FACE); |
329 | it.More(); |
330 | it.Next()) { |
331 | mapTool.Add(it.Current()); |
332 | } |
333 | |
334 | if (!LShape.IsEmpty()) { |
335 | |
336 | // on verifie que les faces de LShape appartiennent a myShape |
337 | while (its.More()) { |
338 | Standard_Boolean found = Standard_False; |
339 | for (itm.Initialize(mapShape);itm.More(); itm.Next()) { |
340 | if (itm.Key().IsSame(its.Value())) { |
341 | found = Standard_True; |
342 | break; |
343 | } |
344 | } |
345 | if (!found) { |
346 | return; |
347 | } |
348 | |
349 | TopAbs_Orientation orient = itm.Key().Orientation(); |
350 | TopoDS_Face theF = TopoDS::Face(its.Value()); |
351 | theF.Orientation(orient); |
352 | if (mapAdded.Add(theF)) { |
353 | newFS.Append(theF); |
354 | } |
355 | its.Next(); |
356 | } |
357 | } |
358 | else { |
359 | for (it.Init(myShape.Oriented(TopAbs_FORWARD),TopAbs_FACE); |
360 | it.More(); |
361 | it.Next()) { |
362 | if (mapAdded.Add(it.Current())) { |
363 | newFS.Append(it.Current()); |
364 | } |
365 | } |
366 | } |
367 | |
368 | |
369 | if (!LTool.IsEmpty()) { |
370 | // on verifie que les faces de LTool appartiennent a myTool |
371 | while (itt.More()) { |
372 | found = Standard_False; |
373 | for (itm.Initialize(mapTool);itm.More(); itm.Next()) { |
374 | if (itm.Key().IsSame(itt.Value())) { |
375 | found = Standard_True; |
376 | break; |
377 | } |
378 | } |
379 | if (!found) { |
380 | return; |
381 | } |
382 | |
383 | TopAbs_Orientation orient = itm.Key().Orientation(); |
384 | TopoDS_Face theF = TopoDS::Face(itt.Value()); |
385 | theF.Orientation(orient); |
386 | if (mapAdded.Add(theF)) { |
387 | newFT.Append(theF); |
388 | } |
389 | itt.Next(); |
390 | } |
391 | } |
392 | else { |
393 | for (it.Init(myTool.Oriented(TopAbs_FORWARD),TopAbs_FACE); |
394 | it.More(); |
395 | it.Next()) { |
396 | if (mapAdded.Add(it.Current())) { |
397 | newFT.Append(it.Current()); |
398 | } |
399 | } |
400 | } |
401 | |
402 | #ifdef DRAW |
403 | Standard_Integer ii = 0; |
404 | char namep[10]; |
405 | for (its.Initialize(newFS); its.More(); its.Next()) { |
406 | ii++; |
407 | sprintf(namep,"F_%d",ii); |
408 | DBRep::Set(namep,its.Value()); |
409 | } |
410 | ii = 0; |
411 | for (itt.Initialize(newFT); itt.More(); itt.Next()) { |
412 | ii++; |
413 | sprintf(namep,"T_%d",ii); |
414 | DBRep::Set(namep,itt.Value()); |
415 | } |
416 | #endif |
417 | #ifdef DRAW |
418 | DBRep::Set("myShape", myShape); |
419 | DBRep::Set("myTool", myTool); |
420 | #endif |
421 | |
422 | myShapeMap.Clear(); |
423 | myToolMap.Clear(); //-------------- |
424 | |
425 | #ifdef DRAW |
426 | ii = 0; |
427 | #endif |
428 | do { |
429 | #ifdef DRAW |
430 | ii++; |
431 | #endif |
432 | TopoDS_Compound CoFS, CoFT, CoTool, CoShape; |
433 | B.MakeCompound(CoFS); |
434 | B.MakeCompound(CoFT); |
435 | B.MakeCompound(CoTool); |
436 | B.MakeCompound(CoShape); |
437 | for (its.Initialize(newFS); its.More(); its.Next()) { |
438 | myShapeMap.Add(its.Value()); |
439 | B.Add(CoFS, its.Value()); |
440 | } |
441 | #ifdef DRAW |
442 | sprintf(namep,"CoFS_%d",ii); |
443 | DBRep::Set(namep, CoFS); |
444 | #endif |
445 | |
446 | for (itt.Initialize(newFT); itt.More(); itt.Next()) { |
447 | myToolMap.Add(itt.Value()); |
448 | B.Add(CoFT, itt.Value()); |
449 | } |
450 | #ifdef DRAW |
451 | sprintf(namep,"CoFT_%d",ii); |
452 | DBRep::Set(namep, CoFT); |
453 | #endif |
454 | |
455 | for (itm2.Initialize(mapUsedTool); itm2.More(); itm2.Next()) { |
456 | myToolMap.Add(itm2.Key()); |
457 | B.Add(CoTool, itm2.Key()); |
458 | } |
459 | #ifdef DRAW |
460 | sprintf(namep,"CoTool_%d",ii); |
461 | DBRep::Set(namep, CoTool); |
462 | #endif |
463 | |
464 | for (itm.Initialize(mapUsedShape); itm.More(); itm.Next()) { |
465 | myShapeMap.Add(itm.Key()); |
466 | B.Add(CoShape, itm.Key()); |
467 | } |
468 | #ifdef DRAW |
469 | sprintf(namep,"CoShape_%d",ii); |
470 | DBRep::Set(namep, CoShape); |
471 | #endif |
472 | |
473 | //--------------------------------------------------------------- |
474 | myAlgo.Init(); |
475 | if (St2 != TopAbs_OUT) { |
476 | myAlgo.Load(myShape, myTool); |
477 | } |
478 | else { |
479 | myAlgo.Load(myTool, myShape); |
480 | } |
481 | |
482 | TopoDS_Compound aCoShape, aCoTool; |
483 | B.MakeCompound(aCoShape); |
484 | B.MakeCompound(aCoTool); |
485 | |
486 | TopTools_MapIteratorOfMapOfShape anIt1(myShapeMap), anIt2(myToolMap); |
487 | |
488 | for(; anIt1.More(); anIt1.Next()) { |
489 | B.Add(aCoShape, anIt1.Key()); |
490 | } |
491 | |
492 | for(; anIt2.More(); anIt2.Next()) { |
493 | B.Add(aCoTool, anIt2.Key()); |
494 | } |
495 | |
496 | if (St2 != TopAbs_OUT) myAlgo.Intersect(aCoShape, aCoTool); |
497 | else myAlgo.Intersect(aCoTool, aCoShape); |
498 | |
499 | //------------------------------------------------------------------- |
500 | |
501 | for (its.Initialize(newFS); its.More(); its.Next()) { |
502 | mapUsedShape.Add(its.Value()); |
503 | } |
504 | for (itt.Initialize(newFT); itt.More(); itt.Next()) { |
505 | mapUsedTool.Add(itt.Value()); |
506 | } |
507 | |
508 | newFS.Clear(); |
509 | newFT.Clear(); |
510 | |
511 | const BOPTools_PDSFiller& aFiller = myAlgo.DSFiller(); |
512 | const BooleanOperations_ShapesDataStructure& aDS = aFiller->DS(); |
513 | const BOPTools_InterferencePool& anIntrf = aFiller->InterfPool(); |
514 | //Checks if the set of faces is complete |
515 | for (Standard_Integer i=1; i<=EFMap.Extent(); i++) { |
516 | const TopoDS_Edge& Ed = TopoDS::Edge(EFMap.FindKey(i)); |
517 | |
518 | Standard_Integer index = aDS.ShapeIndex(Ed, 1); |
519 | if(index <= 0) index = aDS.ShapeIndex(Ed, 2); |
520 | if(index > 0 ) { |
521 | |
522 | if(!anIntrf.HasInterference(index)) continue; |
523 | |
524 | const TopTools_ListOfShape& Lf = EFMap.FindFromIndex(i); |
525 | Standard_Boolean InShape = Standard_False; |
526 | for (its.Initialize(Lf); its.More(); its.Next()) { |
527 | if (mapUsedShape.Contains(its.Value())) { |
528 | InShape = Standard_True; |
529 | break; |
530 | } |
531 | else if (mapUsedTool.Contains(its.Value())) { |
532 | InShape = Standard_False; |
533 | break; |
534 | } |
535 | } |
536 | if (!its.More()) { |
537 | Standard_ConstructionError::Raise(); |
538 | } |
539 | |
540 | for (its.Initialize(Lf); its.More(); its.Next()) { |
541 | if (InShape) { |
542 | if (!mapUsedShape.Contains(its.Value())) { |
543 | for (itm.Initialize(mapShape);itm.More(); itm.Next()) { |
544 | if (itm.Key().IsSame(its.Value())) { |
545 | break; |
546 | } |
547 | } |
548 | TopAbs_Orientation orient = itm.Key().Orientation(); |
549 | TopoDS_Face newF = TopoDS::Face(its.Value()); |
550 | newF.Orientation(orient); |
551 | if (mapAdded.Add(newF)) { |
552 | newFS.Append(newF); |
553 | } |
554 | } |
555 | } |
556 | else { |
557 | if (!mapUsedTool.Contains(its.Value())) { |
558 | for (itm.Initialize(mapTool);itm.More(); itm.Next()) { |
559 | if (itm.Key().IsSame(its.Value())) { |
560 | break; |
561 | } |
562 | } |
563 | TopAbs_Orientation orient = itm.Key().Orientation(); |
564 | TopoDS_Face newF = TopoDS::Face(its.Value()); |
565 | newF.Orientation(orient); |
566 | if (mapAdded.Add(newF)) { |
567 | newFT.Append(newF); |
568 | } |
569 | } |
570 | } |
571 | } |
572 | } |
573 | } |
574 | } while (!(newFS.IsEmpty() && newFT.IsEmpty())); |
575 | |
576 | |
577 | //----------------------------------------- |
578 | myAlgo.ToCompleteIntersection(); |
579 | //----------------------------------------- |
580 | |
581 | |
582 | myPerfdone = Standard_True; |
583 | |
584 | } |
585 | |
586 | |
587 | //======================================================================= |
588 | //function : BuildPartsOfTool |
589 | //purpose : |
590 | //======================================================================= |
591 | |
592 | void LocOpe_Builder::BuildPartsOfTool () |
593 | { |
594 | if (!myPerfdone) { |
595 | StdFail_NotDone::Raise(); |
596 | } |
597 | |
598 | myPdone = Standard_False; |
599 | myParts.Clear(); |
600 | myRemoved.Clear(); |
601 | |
602 | TopAbs_State St2 = (myFuse) ? TopAbs_OUT : TopAbs_IN; |
603 | |
604 | TopoDS_Shape SS; |
605 | static Standard_Boolean OK; |
606 | OK = Standard_True; |
607 | |
608 | try { |
609 | OCC_CATCH_SIGNALS |
610 | if (St2 != TopAbs_OUT) { |
611 | SS = myAlgo.Merge(TopAbs_IN, St2); |
612 | } |
613 | else { |
614 | SS = myAlgo.Merge(St2, TopAbs_IN); |
615 | } |
616 | } |
617 | catch (Standard_Failure){ |
618 | OK = Standard_False; |
619 | } |
620 | |
621 | |
622 | //-------------------------------------------- |
623 | #ifdef DRAW |
624 | DBRep::Set("SS", SS); |
625 | #endif |
626 | //------------------------------------------------------------ |
627 | TopTools_MapOfShape DummyMap; |
628 | if (!SS.IsNull()) SS = BRepAlgo_Tool::Deboucle3D(SS, DummyMap); |
629 | if (SS.IsNull()) OK = Standard_False; |
630 | |
631 | // Est-ce que le shape est valide ? |
632 | TopExp_Explorer ex; |
633 | if (OK) { |
634 | ex.Init(SS, TopAbs_FACE); |
635 | OK = ex.More(); |
636 | if (OK) { |
637 | if (!BRepAlgo::IsTopologicallyValid(SS)) { |
638 | OK = Standard_False; |
639 | #ifdef DRAW |
640 | cout <<"LocOpe_Builder::BuildPartsOfTool: Shape non valide, on intersecte tout."<< endl; |
641 | #endif |
642 | } |
643 | } |
644 | else { |
645 | #ifdef DRAW |
646 | cout <<"LocOpe_Builder: Pas de faces dans le resultat, on intersecte tout."<< endl; |
647 | #endif |
648 | } |
649 | } |
650 | |
651 | |
652 | if (!OK) { |
653 | myAlgo.Init(); |
654 | if (St2 != TopAbs_OUT) { |
655 | myAlgo.Load(myShape, myTool); |
656 | myAlgo.Intersect(); |
657 | SS = myAlgo.Merge(TopAbs_IN, St2); |
658 | } |
659 | else { |
660 | myAlgo.Load(myTool, myShape); |
661 | myAlgo.Intersect(); |
662 | SS = myAlgo.Merge(St2, TopAbs_IN); |
663 | } |
664 | } |
665 | |
666 | TopExp_Explorer exp; |
667 | for (exp.Init(SS,TopAbs_SHELL); |
668 | exp.More(); exp.Next()) { |
669 | TopoDS_Shape S1 = exp.Current(); |
670 | if (!S1.IsNull()) S1 = BRepAlgo_Tool::Deboucle3D(S1, DummyMap); |
671 | if (!S1.IsNull()) myParts.Append(S1); |
672 | } |
673 | |
674 | myPdone = Standard_True; |
675 | } |
676 | |
677 | |
678 | //======================================================================= |
679 | //function : PartsOfTool |
680 | //purpose : |
681 | //======================================================================= |
682 | |
683 | const TopTools_ListOfShape& LocOpe_Builder::PartsOfTool () const |
684 | { |
685 | if (!myPdone) { |
686 | StdFail_NotDone::Raise(); |
687 | } |
688 | return myParts; |
689 | } |
690 | |
691 | |
692 | //======================================================================= |
693 | //function : RemovePart |
694 | //purpose : |
695 | //======================================================================= |
696 | |
697 | void LocOpe_Builder::RemovePart (const TopoDS_Shape& S) |
698 | { |
699 | if (!myPdone) { |
700 | StdFail_NotDone::Raise(); |
701 | } |
702 | |
703 | TopTools_ListIteratorOfListOfShape its(myParts); |
704 | for (;its.More(); its.Next()) { |
705 | if (S.IsSame(its.Value())) { |
706 | break; |
707 | } |
708 | } |
709 | if (!its.More()) { // S ne peut etre enlever |
710 | #ifdef DRAW |
711 | cout << "Invalid Shape" << endl; |
712 | #endif |
713 | } |
714 | else { |
715 | for (its.Initialize(myRemoved); its.More(); its.Next()) { |
716 | if (S.IsSame(its.Value())) { |
717 | break; |
718 | } |
719 | } |
720 | if (its.More()) { // S deja enleve |
721 | #ifdef DRAW |
722 | cout << "S has already been removed" << endl; |
723 | #endif |
724 | } |
725 | else { |
726 | myRemoved.Append(S); |
727 | } |
728 | } |
729 | } |
730 | |
731 | |
732 | |
733 | //======================================================================= |
734 | //function : ActivatePart |
735 | //purpose : |
736 | //======================================================================= |
737 | |
738 | void LocOpe_Builder::ActivatePart (const TopoDS_Shape& S) |
739 | { |
740 | if (!myPdone) { |
741 | StdFail_NotDone::Raise(); |
742 | } |
743 | TopTools_ListIteratorOfListOfShape its(myRemoved); |
744 | for (;its.More(); its.Next()) { |
745 | if (S.IsSame(its.Value())) { |
746 | break; |
747 | } |
748 | } |
749 | if (!its.More()) { // S ne peut etre re-active |
750 | #ifdef DRAW |
751 | cout << "Invalid Shape" << endl; |
752 | #endif |
753 | } |
754 | else { |
755 | myRemoved.Remove(its); |
756 | } |
757 | } |
758 | |
759 | |
760 | //======================================================================= |
761 | //function : PerformResult |
762 | //purpose : |
763 | //======================================================================= |
764 | |
765 | void LocOpe_Builder::PerformResult() |
766 | { |
767 | if (!myPerfdone) { |
768 | StdFail_NotDone::Raise(); |
769 | } |
770 | |
771 | |
772 | InvalidateParts(); |
773 | |
774 | TopTools_MapOfShape DummyMap; |
775 | Standard_Boolean OK = Standard_True; |
776 | TopAbs_State St1; |
777 | |
778 | if (!myShape.IsSame(myTool)) { |
779 | St1 = TopAbs_OUT; |
780 | TopAbs_State St2 = (myFuse) ? TopAbs_OUT : TopAbs_IN; |
781 | |
782 | if (St2 != TopAbs_OUT) myResult = myAlgo.Merge(St1, St2); |
783 | else myResult = myAlgo.Merge(St2, St1); |
784 | |
785 | #ifdef DRAW |
786 | DBRep::Set("res1", myResult); |
787 | #endif |
788 | if (!myResult.IsNull()) |
789 | myResult = BRepAlgo_Tool::Deboucle3D(myResult, DummyMap); |
790 | #ifdef DRAW |
791 | DBRep::Set("res2", myResult); |
792 | #endif |
793 | |
794 | if (myResult.IsNull()) OK = Standard_False; |
795 | |
796 | if (OK) { |
797 | if (!BRepAlgo::IsTopologicallyValid(myResult)) { |
798 | OK = Standard_False; |
799 | #ifdef DRAW |
800 | cout <<"LocOpe_Builder::PerformResult: Shape non valide, on intersecte tout."<< endl; |
801 | #endif |
802 | } |
803 | } |
804 | /* |
805 | if (!OK) { |
806 | myShapeMap.Clear(); |
807 | myAlgo.Init(); |
808 | TopExp_Explorer anExp(myShape, TopAbs_FACE); |
809 | for(; anExp.More(); anExp.Next()) { |
810 | myShapeMap.Add(anExp.Current()); |
811 | } |
812 | if (St2 != TopAbs_OUT) { |
813 | myAlgo.Load(myShape, myTool); |
814 | myAlgo.Intersect(); |
815 | InvalidateParts(); |
816 | myResult = myAlgo.Merge(St1, St2); |
817 | } |
818 | else { |
819 | myAlgo.Load(myTool, myShape); |
820 | myAlgo.Intersect(); |
821 | InvalidateParts(); |
822 | myResult = myAlgo.Merge(St2, St1); |
823 | } |
824 | #ifdef DRAW |
825 | DBRep::Set("res3", myResult); |
826 | #endif |
827 | if (!myResult.IsNull()) myResult = BRepAlgo_Tool::Deboucle3D(myResult, DummyMap); |
828 | #ifdef DRAW |
829 | DBRep::Set("res4", myResult); |
830 | #endif |
831 | } |
832 | */ |
833 | } |
834 | else { |
835 | St1 = (myFuse) ? TopAbs_OUT : TopAbs_IN; |
836 | myResult = myAlgo.Merge(St1); // debouclage |
837 | #ifdef DRAW |
838 | DBRep::Set("res5", myResult); |
839 | #endif |
840 | if (!myResult.IsNull()) myResult = BRepAlgo_Tool::Deboucle3D(myResult, DummyMap); |
841 | #ifdef DRAW |
842 | DBRep::Set("res6", myResult); |
843 | #endif |
844 | } |
845 | |
846 | |
847 | #ifdef DRAW |
848 | DBRep::Set("myRes", myResult); |
849 | #endif |
850 | |
851 | |
852 | myEdges.Clear(); |
853 | myTgtEdges.Clear(); |
854 | TopExp_Explorer ex, ex1; |
855 | |
856 | if (myResult.IsNull() || !OK) { |
857 | myDone = Standard_False; |
858 | } |
859 | else { |
860 | |
861 | TopTools_ListIteratorOfListOfShape is(myAlgo.GetSectionEdgeSet()); |
862 | while (is.More()) { |
863 | for (ex.Init(is.Value(), TopAbs_EDGE); ex.More(); ex.Next()) { |
864 | const TopoDS_Edge& E = TopoDS::Edge(ex.Current()); |
865 | ex1.Init(myResult, TopAbs_EDGE); |
866 | for(; ex1.More(); ex1.Next()) { |
867 | if(E.IsSame(ex1.Current())) break; |
868 | } |
869 | if(ex1.More()) { |
870 | myEdges.Append(E); |
871 | } |
872 | } |
873 | is.Next(); |
874 | } |
875 | |
876 | TopTools_IndexedDataMapOfShapeListOfShape ma; |
877 | TopTools_ListIteratorOfListOfShape its3; |
878 | |
879 | TopExp::MapShapesAndAncestors(myResult, TopAbs_EDGE, TopAbs_FACE, ma); |
880 | its3.Initialize(myEdges); |
881 | for(; its3.More(); its3.Next()) { |
882 | const TopoDS_Edge& edg = TopoDS::Edge(its3.Value()); |
883 | const TopTools_ListOfShape& L0 = ma.FindFromKey(its3.Value()); |
884 | const TopoDS_Face& F1 = TopoDS::Face(L0.First()); |
885 | const TopoDS_Face& F2 = TopoDS::Face(L0.Last()); |
886 | if(!F1.IsSame(F2)) { |
887 | if(LocOpe::TgtFaces(edg, F1, F2)) { |
888 | myTgtEdges.Append(its3.Value()); |
889 | } |
890 | } |
891 | } |
892 | myDone = Standard_True; |
893 | } |
894 | |
895 | if (!myInvDone) { |
896 | myDone = Standard_False; |
897 | } |
898 | |
899 | } |
900 | |
901 | |
902 | |
903 | //======================================================================= |
904 | //function : InvalidateParts |
905 | //purpose : |
906 | //======================================================================= |
907 | |
908 | void LocOpe_Builder::InvalidateParts () |
909 | { |
910 | |
911 | myInvDone = Standard_True; |
912 | const TopTools_ListOfShape& L = myAlgo.GetSectionEdgeSet(); |
913 | TopTools_ListOfShape *pL = (TopTools_ListOfShape*)&L; |
914 | |
915 | TopTools_ListIteratorOfListOfShape its; |
916 | |
917 | #ifdef DRAW |
918 | char namep[12]; |
919 | Standard_Integer ii = 0; |
920 | for (its.Initialize(L); its.More(); its.Next()) { |
921 | ii++; |
922 | sprintf(namep,"CO_%d",ii); |
923 | DBRep::Set(namep, its.Value()); |
924 | } |
925 | |
926 | ii = 0; |
927 | for (its.Initialize(myParts);its.More(); its.Next()) { |
928 | ii++; |
929 | sprintf(namep,"thePart_%d",ii); |
930 | DBRep::Set(namep,its.Value()); |
931 | } |
932 | #endif |
933 | |
934 | |
935 | if (myRemoved.IsEmpty() && myParts.IsEmpty()) { |
936 | return; |
937 | } |
938 | |
939 | Standard_Integer NbFaces = myShapeMap.Extent(); |
940 | |
941 | TopExp_Explorer exp, exp1; |
942 | |
943 | its.Initialize(*pL); |
944 | while (its.More()) { |
945 | TopoDS_Compound C = TopoDS::Compound(its.Value()); |
946 | Standard_Boolean Finish = Standard_False; |
947 | |
948 | for (exp.Init(C,TopAbs_VERTEX); !Finish && exp.More(); exp.Next()) { |
949 | gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(exp.Current())); |
950 | TopTools_ListIteratorOfListOfShape its2(myRemoved); |
951 | |
952 | for (; !Finish && its2.More(); its2.Next()) { |
953 | for (exp1.Init(its2.Value(),TopAbs_VERTEX); exp1.More(); exp1.Next()) { |
954 | gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(exp1.Current())); |
955 | if (Egal(P1, P2)) { |
956 | // le compound est a enlever. |
957 | Finish = Standard_True; |
958 | break; |
959 | } |
960 | } |
961 | } |
962 | } |
963 | |
964 | Standard_Boolean ToSuppress = Standard_True; |
965 | |
966 | for (exp.Init(C,TopAbs_VERTEX); ToSuppress && exp.More(); exp.Next()) { |
967 | gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(exp.Current())); |
968 | // its2 iterateur sur myRemoved = morceaux outils enleves |
969 | // its3 iteratuer sur myParts = tous les morceaux outil |
970 | TopTools_ListIteratorOfListOfShape its3(myParts); |
971 | |
972 | for (;ToSuppress && its3.More(); its3.Next()) { |
973 | |
974 | Standard_Integer myKeep = Standard_True; |
975 | TopTools_ListIteratorOfListOfShape its2(myRemoved); |
976 | for (; its2.More(); its2.Next()) { |
977 | if (its3.Value() == its2.Value()) myKeep = Standard_False; |
978 | } |
979 | if (!myKeep) continue; |
980 | |
981 | for (exp1.Init(its3.Value(),TopAbs_VERTEX); exp1.More(); exp1.Next()) { |
982 | gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(exp1.Current())); |
983 | if (Egal(P1, P2)) { |
984 | // le compound est a garder. |
985 | ToSuppress = Standard_False; |
986 | break; |
987 | } |
988 | } |
989 | } |
990 | } |
991 | |
992 | if (Finish || ToSuppress) { |
993 | myAlgo.SuppressEdgeSet(); |
994 | pL->Remove(its); |
995 | RemoveFaces(C, myAlgo.DSFiller(), myShapeMap); |
996 | } |
997 | |
998 | #ifdef DRAW |
999 | if (!Finish && ToSuppress) { |
1000 | cout << "LocOpe_Builder::InvalidateParts : suppress intersection line" << endl; |
1001 | } |
1002 | #endif |
1003 | |
1004 | if (Finish && !ToSuppress) { |
1005 | #ifdef DRAW |
1006 | cout << "LocOpe_Builder::InvalidateParts : intersection line conflict" << endl; |
1007 | #endif |
1008 | myInvDone = Standard_False; |
1009 | } |
1010 | |
1011 | if (Finish || ToSuppress) continue; |
1012 | its.Next(); |
1013 | } |
1014 | |
1015 | if(NbFaces > myShapeMap.Extent()) { |
1016 | |
1017 | TopAbs_State St2 = (myFuse) ? TopAbs_OUT : TopAbs_IN; |
1018 | BRep_Builder B; |
1019 | |
1020 | TopoDS_Compound aCoShape, aCoTool; |
1021 | B.MakeCompound(aCoShape); |
1022 | B.MakeCompound(aCoTool); |
1023 | |
1024 | TopTools_MapIteratorOfMapOfShape anIt1(myShapeMap), anIt2(myToolMap); |
1025 | |
1026 | for(; anIt1.More(); anIt1.Next()) { |
1027 | B.Add(aCoShape, anIt1.Key()); |
1028 | } |
1029 | |
1030 | for(; anIt2.More(); anIt2.Next()) { |
1031 | B.Add(aCoTool, anIt2.Key()); |
1032 | } |
1033 | |
1034 | #ifdef DRAW |
1035 | DBRep::Set("aCoShape", aCoShape); |
1036 | #endif |
1037 | myAlgo.Init(); |
1038 | if (St2 != TopAbs_OUT) { |
1039 | myAlgo.Load(myShape, myTool); |
1040 | } |
1041 | else { |
1042 | myAlgo.Load(myTool, myShape); |
1043 | } |
1044 | |
1045 | if (St2 != TopAbs_OUT) myAlgo.Intersect(aCoShape, aCoTool); |
1046 | else myAlgo.Intersect(aCoTool, aCoShape); |
1047 | |
1048 | myAlgo.ToCompleteIntersection(); |
1049 | |
1050 | } |
1051 | } |
1052 | |
1053 | |