b311480e |
1 | // Created on: 2000-12-08 |
2 | // Created by: Michael SAZONOV |
3 | // Copyright (c) 2000-2012 OPEN CASCADE SAS |
4 | // |
5 | // The content of this file is subject to the Open CASCADE Technology Public |
6 | // License Version 6.5 (the "License"). You may not use the content of this file |
7 | // except in compliance with the License. Please obtain a copy of the License |
8 | // at http://www.opencascade.org and read it completely before using this file. |
9 | // |
10 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
11 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
12 | // |
13 | // The Original Code and all software distributed under the License is |
14 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
15 | // Initial Developer hereby disclaims all such warranties, including without |
16 | // limitation, any warranties of merchantability, fitness for a particular |
17 | // purpose or non-infringement. Please see the License for the specific terms |
18 | // and conditions governing the rights and limitations under the License. |
7fd59977 |
19 | |
20 | #include <QANewModTopOpe_Glue.ixx> |
21 | #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx> |
22 | #include <TopoDS_Iterator.hxx> |
23 | #include <TopExp_Explorer.hxx> |
24 | #include <BRep_Builder.hxx> |
25 | #include <TopoDS.hxx> |
26 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
27 | |
28 | static TopoDS_Shape RemoveCompounds(const TopoDS_Shape& TheS) |
29 | { |
30 | |
31 | if(TheS.IsNull()) return TheS; |
32 | |
33 | TopAbs_ShapeEnum aType = TheS.ShapeType(); |
34 | |
35 | if(aType != TopAbs_COMPOUND) return TheS; |
36 | |
37 | TopTools_MapOfShape aMap; |
38 | TopoDS_Shape aResult; |
39 | |
40 | BRep_Builder aBld; |
41 | aBld.MakeCompound(TopoDS::Compound(aResult)); |
42 | Standard_Integer n = 0; |
43 | TopExp_Explorer anExp; |
44 | |
45 | anExp.Init(TheS, TopAbs_COMPSOLID); |
46 | for(; anExp.More(); anExp.Next()) { |
47 | n++; |
48 | if(aMap.Add(anExp.Current())) aBld.Add(aResult, anExp.Current()); |
49 | } |
50 | |
51 | anExp.Init(TheS, TopAbs_SOLID, TopAbs_COMPSOLID); |
52 | for(; anExp.More(); anExp.Next()) { |
53 | n++; |
54 | if(aMap.Add(anExp.Current())) aBld.Add(aResult, anExp.Current()); |
55 | } |
56 | |
57 | anExp.Init(TheS, TopAbs_SHELL, TopAbs_SOLID); |
58 | for(; anExp.More(); anExp.Next()) { |
59 | n++; |
60 | if(aMap.Add(anExp.Current())) aBld.Add(aResult, anExp.Current()); |
61 | } |
62 | |
63 | anExp.Init(TheS, TopAbs_FACE, TopAbs_SHELL); |
64 | for(; anExp.More(); anExp.Next()) { |
65 | n++; |
66 | if(aMap.Add(anExp.Current())) aBld.Add(aResult, anExp.Current()); |
67 | } |
68 | |
69 | anExp.Init(TheS, TopAbs_WIRE, TopAbs_FACE); |
70 | for(; anExp.More(); anExp.Next()) { |
71 | n++; |
72 | if(aMap.Add(anExp.Current())) aBld.Add(aResult, anExp.Current()); |
73 | } |
74 | |
75 | anExp.Init(TheS, TopAbs_EDGE, TopAbs_WIRE); |
76 | for(; anExp.More(); anExp.Next()) { |
77 | n++; |
78 | if(aMap.Add(anExp.Current())) aBld.Add(aResult, anExp.Current()); |
79 | } |
80 | |
81 | if(n == 1) { |
82 | TopoDS_Iterator anIter(aResult); |
83 | aResult = anIter.Value(); |
84 | } |
85 | |
86 | if(n == 0) aResult.Nullify(); |
87 | |
88 | return aResult; |
89 | } |
90 | |
91 | |
92 | //======================================================================= |
93 | //function : QANewModTopOpe_Glue |
94 | //purpose : |
95 | //======================================================================= |
96 | QANewModTopOpe_Glue::QANewModTopOpe_Glue(const TopoDS_Shape& theS1, |
97 | const TopoDS_Shape& theS2, |
98 | const Standard_Boolean theAllowCutting, |
99 | const Standard_Boolean thePerformNow) |
4e57c75e |
100 | : BRepAlgoAPI_BooleanOperation (theS1,theS2, BOPAlgo_FUSE), |
eafb234b |
101 | myCompleted (Standard_False), |
102 | myAllowCutting (theAllowCutting) |
7fd59977 |
103 | { |
104 | NotDone(); |
105 | myGenerated.Clear(); |
106 | myMapModif.Clear(); |
107 | myMapGener.Clear(); |
108 | if (thePerformNow) |
109 | Build(); |
110 | } |
111 | |
112 | //======================================================================= |
113 | //function : Build |
114 | //purpose : |
115 | //======================================================================= |
116 | |
117 | void QANewModTopOpe_Glue::Build() |
118 | { |
119 | if (myCompleted) return; |
120 | |
121 | TopAbs_ShapeEnum aType1, aType2; |
122 | aType1 = myS1.ShapeType(); |
123 | aType2 = myS2.ShapeType(); |
124 | |
125 | TopoDS_Shape aCopyS1 = myS1; |
126 | TopoDS_Shape aCopyS2 = myS2; |
127 | TopoDS_Shape aResult; |
128 | |
129 | if(aType2 == TopAbs_VERTEX) { |
130 | |
131 | PerformVertex(); |
132 | |
133 | myCompleted = Standard_True; |
134 | return; |
135 | |
136 | } else if (aType1 == TopAbs_VERTEX) { |
137 | |
138 | myS2 = aCopyS1; |
139 | myS1 = aCopyS2; |
140 | |
141 | PerformVertex(); |
142 | |
143 | myCompleted = Standard_True; |
144 | myS1 = aCopyS1; |
145 | myS2 = aCopyS2; |
146 | return; |
147 | } |
148 | |
149 | Standard_Boolean aContains1 = Standard_False; |
150 | Standard_Boolean aContains2 = Standard_False; |
151 | |
152 | TopExp_Explorer anExp(myS1, TopAbs_FACE); |
153 | aContains1 = anExp.More(); |
154 | anExp.Init(myS2, TopAbs_FACE); |
155 | aContains2 = anExp.More(); |
156 | |
157 | if(aContains1 && aContains2) { |
158 | |
159 | if(myS1.ShapeType() == TopAbs_FACE) { |
160 | BRep_Builder aBld; |
161 | TopoDS_Shape aCmp; |
162 | aBld.MakeCompound(TopoDS::Compound(aCmp)); |
163 | aBld.Add(aCmp, myS1); |
164 | myS1 = aCmp; |
165 | } |
166 | if(myS2.ShapeType() == TopAbs_FACE) { |
167 | BRep_Builder aBld; |
168 | TopoDS_Shape aCmp; |
169 | aBld.MakeCompound(TopoDS::Compound(aCmp)); |
170 | aBld.Add(aCmp, myS2); |
171 | myS2 = aCmp; |
172 | } |
173 | |
174 | mySubst.Clear(); |
175 | PerformSDFaces(); |
176 | |
177 | if(!myShape.IsNull()) { |
178 | |
179 | TopoDS_Iterator anIter(myShape); |
180 | if(anIter.More()) { |
181 | myS1 = anIter.Value(); |
182 | anIter.Next(); |
183 | myS2 = anIter.Value(); |
184 | } |
185 | |
186 | aResult = myShape; |
187 | myShape.Nullify(); |
188 | |
189 | } |
190 | |
191 | mySubst.Clear(); |
192 | PerformShell(); |
193 | |
194 | if(!myShape.IsNull()) { |
195 | |
196 | TopoDS_Iterator anIter(myShape); |
197 | if(anIter.More()) { |
198 | myS1 = anIter.Value(); |
199 | anIter.Next(); |
200 | myS2 = anIter.Value(); |
201 | } |
202 | |
203 | aResult = myShape; |
204 | myShape.Nullify(); |
205 | |
206 | } |
207 | |
208 | } |
209 | |
210 | if(aContains1 || aContains2) { |
211 | BRep_Builder aBld; |
212 | TopoDS_Shape aS1, aS2; |
213 | TopoDS_Shape aCpS1 = myS1, aCpS2 = myS2; |
214 | aBld.MakeCompound(TopoDS::Compound(aS1)); |
215 | aBld.MakeCompound(TopoDS::Compound(aS2)); |
216 | |
217 | anExp.Init(myS1, TopAbs_WIRE, TopAbs_FACE); |
218 | for(; anExp.More(); anExp.Next()) { |
219 | aBld.Add(aS1, anExp.Current()); |
220 | } |
221 | |
222 | anExp.Init(myS1, TopAbs_EDGE, TopAbs_WIRE); |
223 | for(; anExp.More(); anExp.Next()) { |
224 | aBld.Add(aS1, anExp.Current()); |
225 | } |
226 | |
227 | anExp.Init(myS2, TopAbs_WIRE, TopAbs_FACE); |
228 | for(; anExp.More(); anExp.Next()) { |
229 | aBld.Add(aS2, anExp.Current()); |
230 | } |
231 | |
232 | anExp.Init(myS2, TopAbs_EDGE, TopAbs_WIRE); |
233 | for(; anExp.More(); anExp.Next()) { |
234 | aBld.Add(aS2, anExp.Current()); |
235 | } |
236 | |
237 | TopoDS_Iterator anIt1(aS1); |
238 | TopoDS_Iterator anIt2(aS2); |
239 | |
240 | Standard_Boolean aShellWire = Standard_False; |
241 | |
242 | if(anIt1.More() && anIt2.More()) { |
243 | aShellWire = Standard_True; |
244 | myS1 = aS1; |
245 | myS2 = aS2; |
246 | mySubst.Clear(); |
247 | |
248 | PerformWires(); |
249 | |
250 | myS1 = aCpS1; |
251 | myS2 = aCpS2; |
252 | |
253 | if(!myShape.IsNull()) { |
254 | aS2 = myShape; |
255 | aS1.Nullify(); |
256 | aBld.MakeCompound(TopoDS::Compound(aS1)); |
257 | } |
258 | else { |
259 | for(; anIt1.More(); anIt1.Next()) aBld.Add(aS2, anIt1.Value()); |
260 | aS1.Nullify(); |
261 | aBld.MakeCompound(TopoDS::Compound(aS1)); |
262 | } |
263 | } |
264 | else if(anIt1.More()) { |
265 | aShellWire = Standard_True; |
266 | aS2 = aS1; |
267 | aS1.Nullify(); |
268 | aBld.MakeCompound(TopoDS::Compound(aS1)); |
269 | } |
270 | else if(anIt2.More()) { |
271 | aShellWire = Standard_True; |
272 | } |
273 | |
274 | if(aShellWire) { |
275 | |
276 | if(aContains1) { |
277 | |
278 | anExp.Init(myS1, TopAbs_COMPSOLID); |
279 | for(; anExp.More(); anExp.Next()) { |
280 | aBld.Add(aS1, anExp.Current()); |
281 | } |
282 | |
283 | anExp.Init(myS1, TopAbs_SOLID, TopAbs_COMPSOLID); |
284 | for(; anExp.More(); anExp.Next()) { |
285 | aBld.Add(aS1, anExp.Current()); |
286 | } |
287 | |
288 | anExp.Init(myS1, TopAbs_SHELL, TopAbs_SOLID); |
289 | for(; anExp.More(); anExp.Next()) { |
290 | aBld.Add(aS1, anExp.Current()); |
291 | } |
292 | |
293 | anExp.Init(myS1, TopAbs_FACE, TopAbs_SHELL); |
294 | for(; anExp.More(); anExp.Next()) { |
295 | aBld.Add(aS1, anExp.Current()); |
296 | } |
297 | |
298 | } |
299 | |
300 | if(aContains2) { |
301 | |
302 | anExp.Init(myS2, TopAbs_COMPSOLID); |
303 | for(; anExp.More(); anExp.Next()) { |
304 | aBld.Add(aS1, anExp.Current()); |
305 | } |
306 | |
307 | anExp.Init(myS2, TopAbs_SOLID, TopAbs_COMPSOLID); |
308 | for(; anExp.More(); anExp.Next()) { |
309 | aBld.Add(aS1, anExp.Current()); |
310 | } |
311 | |
312 | anExp.Init(myS2, TopAbs_SHELL, TopAbs_SOLID); |
313 | for(; anExp.More(); anExp.Next()) { |
314 | aBld.Add(aS1, anExp.Current()); |
315 | } |
316 | |
317 | anExp.Init(myS2, TopAbs_FACE, TopAbs_SHELL); |
318 | for(; anExp.More(); anExp.Next()) { |
319 | aBld.Add(aS1, anExp.Current()); |
320 | } |
321 | |
322 | } |
323 | |
324 | myS1 = aS1; |
325 | myS2 = aS2; |
326 | |
327 | mySubst.Clear(); |
328 | PerformShellWire(); |
329 | |
330 | if(!myShape.IsNull()) { |
331 | aResult = myShape; |
332 | } |
333 | |
334 | } |
335 | |
336 | } |
337 | |
338 | if(!aContains1 && !aContains2) { |
339 | |
340 | mySubst.Clear(); |
341 | PerformWires(); |
342 | |
343 | if(!myShape.IsNull()) { |
344 | aResult = myShape; |
345 | } |
346 | |
347 | } |
348 | |
349 | myS1 = aCopyS1; |
350 | myS2 = aCopyS2; |
351 | myShape = RemoveCompounds(aResult); |
352 | if(myShape.IsNull()) NotDone(); |
353 | myCompleted = Standard_True; |
354 | } |
355 | |
356 | //======================================================================= |
357 | //function : Generated |
358 | //purpose : |
359 | //======================================================================= |
360 | |
361 | const TopTools_ListOfShape& |
362 | QANewModTopOpe_Glue::Generated (const TopoDS_Shape& theS) |
363 | { |
364 | if (IsDone() && (myMapGener.IsBound(theS) || myMapModif.IsBound(theS))) { |
365 | TopTools_ListIteratorOfListOfShape anItl; |
366 | if(myMapGener.IsBound(theS)) anItl.Initialize(myMapGener(theS)); |
367 | TopTools_ListIteratorOfListOfShape anItl1; |
368 | myGenerated.Clear(); |
369 | Standard_Boolean aNonEmpty = Standard_False; |
370 | TopTools_ListOfShape aL1, aL; |
371 | |
372 | for(; anItl.More(); anItl.Next()) aL.Append(anItl.Value()); |
373 | |
374 | TopTools_MapOfShape aMapModif; |
375 | anItl.Initialize(Modified(theS)); |
376 | for(; anItl.More(); anItl.Next()) aMapModif.Add(anItl.Value()); |
377 | myGenerated.Clear(); |
378 | |
379 | anItl.Initialize(myMapModif(theS)); |
380 | for(; anItl.More(); anItl.Next()) { |
381 | if(!aMapModif.Contains(anItl.Value())) { |
382 | aL.Append(anItl.Value()); |
383 | } |
384 | } |
385 | |
386 | do |
387 | { |
388 | |
389 | aNonEmpty = Standard_False; |
390 | anItl.Initialize(aL); |
391 | |
392 | for(; anItl.More(); anItl.Next()) { |
393 | |
394 | if(myMapGener.IsBound(anItl.Value())) { |
395 | aNonEmpty = Standard_True; |
396 | anItl1.Initialize(myMapGener(anItl.Value())); |
397 | for(; anItl1.More(); anItl1.Next()) { |
398 | if(!anItl.Value().IsSame(anItl1.Value())) aL1.Append(anItl1.Value()); |
399 | } |
400 | } |
401 | else { |
402 | if(myMapModif.IsBound(anItl.Value())) { |
403 | aNonEmpty = Standard_True; |
404 | anItl1.Initialize(myMapModif(anItl.Value())); |
405 | for(; anItl1.More(); anItl1.Next()) { |
406 | if(!anItl.Value().IsSame(anItl1.Value())) aL1.Append(anItl1.Value()); |
407 | } |
408 | } |
409 | else { |
410 | if(!aMapModif.Contains(anItl.Value())) myGenerated.Append(anItl.Value()); |
411 | } |
412 | } |
413 | |
414 | } |
415 | |
416 | if(!aL1.IsEmpty()) { |
417 | aL.Clear(); |
418 | aL.Append(aL1); |
419 | aL1.Clear(); |
420 | } |
421 | else aNonEmpty = Standard_False; |
422 | |
423 | } |
424 | while (aNonEmpty); |
425 | |
426 | return myGenerated; |
427 | |
428 | } |
429 | |
430 | |
431 | myGenerated.Clear(); |
432 | return myGenerated; |
433 | } |
434 | |
435 | //======================================================================= |
436 | //function : Modified |
437 | //purpose : |
438 | //======================================================================= |
439 | |
440 | const TopTools_ListOfShape& |
441 | QANewModTopOpe_Glue::Modified (const TopoDS_Shape& theS) |
442 | { |
443 | if (IsDone() && myMapModif.IsBound(theS)) { |
444 | TopTools_ListIteratorOfListOfShape anItl(myMapModif(theS)); |
445 | TopTools_ListIteratorOfListOfShape anItl1; |
446 | myGenerated.Clear(); |
447 | Standard_Boolean aNonEmpty = Standard_False; |
448 | TopTools_ListOfShape aL1, aL; |
449 | for(; anItl.More(); anItl.Next()) aL.Append(anItl.Value()); |
450 | |
451 | myGenerated.Clear(); |
452 | |
453 | do |
454 | { |
455 | |
456 | aNonEmpty = Standard_False; |
457 | anItl.Initialize(aL); |
458 | |
459 | for(; anItl.More(); anItl.Next()) { |
460 | if(myMapModif.IsBound(anItl.Value())) { |
461 | aNonEmpty = Standard_True; |
462 | anItl1.Initialize(myMapModif(anItl.Value())); |
463 | for(; anItl1.More(); anItl1.Next()) { |
464 | if(!anItl.Value().IsSame(anItl1.Value())) aL1.Append(anItl1.Value()); |
465 | } |
466 | } |
467 | else { |
468 | myGenerated.Append(anItl.Value()); |
469 | } |
470 | } |
471 | |
472 | if(!aL1.IsEmpty()) { |
473 | aL.Clear(); |
474 | aL.Append(aL1); |
475 | aL1.Clear(); |
476 | } |
477 | else aNonEmpty = Standard_False; |
478 | |
479 | } |
480 | while (aNonEmpty); |
481 | |
482 | return myGenerated; |
483 | |
484 | } |
485 | |
486 | myGenerated.Clear(); |
487 | return myGenerated; |
488 | } |
489 | |
490 | //======================================================================= |
491 | //function : IsDeleted |
492 | //purpose : |
493 | //======================================================================= |
494 | |
495 | Standard_Boolean |
496 | QANewModTopOpe_Glue::IsDeleted (const TopoDS_Shape& theS) |
497 | { |
498 | if (IsDone() && myMapModif.IsBound(theS)) { |
499 | const TopTools_ListOfShape &aList = myMapModif.Find(theS); |
500 | |
501 | if (aList.IsEmpty()) |
502 | return Standard_True; |
503 | |
504 | TopTools_ListIteratorOfListOfShape anIter(aList); |
505 | |
506 | for (; anIter.More(); anIter.Next()) { |
507 | const TopoDS_Shape &aSplit = anIter.Value(); |
508 | |
509 | if (!IsDeleted(aSplit)) |
510 | return Standard_False; |
511 | } |
512 | |
513 | return Standard_True; |
514 | } |
515 | |
516 | return Standard_False; |
517 | } |
518 | //======================================================================= |
519 | //function : HasGenerated |
520 | //purpose : |
521 | //======================================================================= |
522 | |
523 | Standard_Boolean |
524 | QANewModTopOpe_Glue::HasGenerated () const |
525 | { |
526 | if (IsDone() && myMapGener.Extent() > 0) |
527 | return Standard_True; |
528 | return Standard_False; |
529 | } |
530 | //======================================================================= |
531 | //function : HasModified |
532 | //purpose : |
533 | //======================================================================= |
534 | |
535 | Standard_Boolean |
536 | QANewModTopOpe_Glue::HasModified () const |
537 | { |
538 | |
539 | if (IsDone() && myMapModif.Extent() > 0) { |
540 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape anIter(myMapModif); |
541 | for(; anIter.More(); anIter.Next()) { |
542 | if(anIter.Value().Extent() > 0) return Standard_True; |
543 | } |
544 | } |
545 | return Standard_False; |
546 | } |
547 | //======================================================================= |
548 | //function : HasDeleted |
549 | //purpose : |
550 | //======================================================================= |
551 | |
552 | Standard_Boolean |
553 | QANewModTopOpe_Glue::HasDeleted () const |
554 | { |
555 | if (IsDone() && myMapModif.Extent() > 0) { |
556 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape anIter(myMapModif); |
557 | for(; anIter.More(); anIter.Next()) { |
558 | if(anIter.Value().Extent() == 0) return Standard_True; |
559 | } |
560 | } |
561 | return Standard_False; |
562 | } |