b311480e |
1 | // Created on: 2001-10-29 |
2 | // Created by: Peter KURNEV |
3 | // Copyright (c) 2001-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. |
19 | |
7fd59977 |
20 | |
21 | #include <BOP_ShellShell.ixx> |
22 | |
23 | |
24 | #include <TopoDS.hxx> |
25 | #include <TopoDS_Shape.hxx> |
26 | #include <TopoDS_Face.hxx> |
27 | #include <TopoDS_Edge.hxx> |
28 | #include <TopoDS_Shell.hxx> |
29 | #include <TopoDS_Compound.hxx> |
30 | |
31 | #include <BRep_Tool.hxx> |
32 | #include <BRep_Builder.hxx> |
33 | |
34 | #include <TopAbs_Orientation.hxx> |
35 | #include <TopExp_Explorer.hxx> |
36 | #include <TopExp.hxx> |
37 | |
38 | #include <TopTools_ListOfShape.hxx> |
39 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
40 | |
41 | #include <TopTools_IndexedMapOfShape.hxx> |
42 | |
43 | #include <TColStd_IndexedMapOfInteger.hxx> |
44 | |
45 | #include <BOPTColStd_Dump.hxx> |
46 | |
47 | #include <BooleanOperations_ShapesDataStructure.hxx> |
48 | #include <BooleanOperations_StateOfShape.hxx> |
49 | |
50 | #include <BOPTools_PaveFiller.hxx> |
51 | #include <BOPTools_InterferencePool.hxx> |
52 | #include <BOPTools_CArray1OfSSInterference.hxx> |
53 | #include <BOPTools_CArray1OfInterferenceLine.hxx> |
54 | #include <BOPTools_InterferenceLine.hxx> |
55 | |
56 | #include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx> |
57 | #include <BOPTools_SSInterference.hxx> |
58 | |
59 | #include <BOP_WireEdgeSet.hxx> |
60 | #include <BOP_SDFWESFiller.hxx> |
61 | #include <BOP_FaceBuilder.hxx> |
62 | #include <BOP_Draw.hxx> |
63 | #include <BOP_CorrectTolerances.hxx> |
64 | #include <BOP_BuilderTools.hxx> |
65 | #include <BOP_Refiner.hxx> |
66 | #include <Standard_Failure.hxx> |
67 | #include <Standard_ErrorHandler.hxx> |
852a895c |
68 | #include <TopTools_DataMapOfShapeInteger.hxx> |
7fd59977 |
69 | |
70 | |
71 | |
72 | //======================================================================= |
73 | // function: BOP_ShellShell::BOP_ShellShell |
74 | // purpose: |
75 | //======================================================================= |
b311480e |
76 | BOP_ShellShell::BOP_ShellShell() |
7fd59977 |
77 | { |
78 | } |
79 | |
80 | //======================================================================= |
81 | // function: Destroy |
82 | // purpose: |
83 | //======================================================================= |
852a895c |
84 | void BOP_ShellShell::Destroy() { |
85 | } |
7fd59977 |
86 | |
87 | //======================================================================= |
88 | // function: DoWithFiller |
89 | // purpose: |
90 | //======================================================================= |
852a895c |
91 | void BOP_ShellShell::DoWithFiller(const BOPTools_DSFiller& aDSFiller) |
7fd59977 |
92 | { |
93 | myErrorStatus=0; |
94 | myIsDone=Standard_False; |
95 | // |
96 | myResultMap.Clear(); |
97 | myModifiedMap.Clear(); |
98 | // |
99 | myDSFiller=(BOPTools_DSFiller*) &aDSFiller; |
100 | // |
101 | try { |
102 | OCC_CATCH_SIGNALS |
103 | |
7fd59977 |
104 | if(!myDSFiller->IsDone()) { |
105 | myErrorStatus = 1; |
106 | BOPTColStd_Dump::PrintMessage("DSFiller is invalid: Can not build result\n"); |
107 | return; |
108 | } |
852a895c |
109 | // |
7fd59977 |
110 | Standard_Boolean bIsNewFiller; |
111 | bIsNewFiller=aDSFiller.IsNewFiller(); |
112 | |
113 | if (bIsNewFiller) { |
114 | Prepare(); |
115 | aDSFiller.SetNewFiller(!bIsNewFiller); |
116 | } |
117 | // |
118 | DoNewFaces(); |
119 | // |
120 | BuildResult(); |
121 | // |
122 | // Treat of internals |
123 | CollectInternals(); |
124 | BOP_Refiner aRefiner; |
125 | aRefiner.SetShape(myResult); |
126 | aRefiner.SetInternals(myInternals); |
127 | aRefiner.Do(); |
128 | // |
129 | BOP_CorrectTolerances::CorrectTolerances(myResult, 0.01); |
130 | // |
131 | FillModified(); |
132 | myIsDone=Standard_True; |
133 | } |
134 | catch ( Standard_Failure ) { |
135 | myErrorStatus = 1; |
136 | BOPTColStd_Dump::PrintMessage("Can not build result\n"); |
137 | } |
138 | } |
139 | |
140 | //================================================================================= |
141 | // function: BuildResult |
142 | // purpose: |
143 | //================================================================================= |
852a895c |
144 | void BOP_ShellShell::BuildResult() |
7fd59977 |
145 | { |
146 | const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS(); |
147 | |
148 | Standard_Integer i, j, aNb, iRank, aNbFaces; |
149 | BooleanOperations_StateOfShape aState, aStateToCompare; |
150 | BRep_Builder aBB; |
151 | TopoDS_Compound aFCompound, aRes; |
152 | // |
153 | Standard_Boolean bHasInterference; |
154 | BOPTools_InterferencePool* pInterfPool= |
155 | (BOPTools_InterferencePool*) &myDSFiller->InterfPool(); |
156 | BOPTools_CArray1OfInterferenceLine* pTable= |
157 | (BOPTools_CArray1OfInterferenceLine*) &pInterfPool->InterferenceTable(); |
158 | // |
159 | aBB.MakeCompound(aRes); |
160 | // |
161 | // 1. Make aCompound containing all faces for thr Result |
162 | aBB.MakeCompound(aFCompound); |
163 | // |
164 | // 1.1. Old Faces with right 3D-state |
165 | aNb=aDS.NumberOfSourceShapes(); |
166 | for (i=1; i<=aNb; i++) { |
167 | const TopoDS_Shape& aS=aDS.Shape(i); |
168 | if (aS.ShapeType()==TopAbs_FACE){ |
169 | // |
170 | BOPTools_InterferenceLine& anInterfLine=pTable->ChangeValue(i); |
171 | bHasInterference=anInterfLine.HasInterference(); |
172 | if (bHasInterference) { |
173 | continue; |
174 | } |
175 | // |
176 | aState=aDS.GetState(i); |
177 | if (aState==BooleanOperations_IN || |
178 | aState==BooleanOperations_OUT) { |
179 | iRank=aDS.Rank(i); |
180 | aStateToCompare=BOP_BuilderTools::StateToCompare(iRank, myOperation); |
181 | if (aState==aStateToCompare) { |
182 | aBB.Add(aFCompound, aS); |
183 | } |
184 | } |
185 | } |
186 | } |
187 | // |
188 | // 1.2. aListOfNewFaces |
189 | TopTools_ListIteratorOfListOfShape anIt(myNewFaces); |
190 | for(; anIt.More(); anIt.Next()) { |
191 | aBB.Add(aFCompound, anIt.Value()); |
192 | } |
193 | // |
194 | // 2. |
195 | TopTools_IndexedDataMapOfShapeListOfShape aEFMap; |
196 | TopTools_IndexedMapOfShape aProcessedEdges; |
197 | |
198 | TopExp::MapShapesAndAncestors(aFCompound, TopAbs_EDGE, TopAbs_FACE, aEFMap); |
199 | aNb=aEFMap.Extent(); |
200 | for (i=1; i<=aNb; i++) { |
201 | const TopoDS_Shape& aE=aEFMap.FindKey(i); |
202 | TopTools_IndexedMapOfShape aFaces; |
203 | Path (aE, aEFMap, aFaces, aProcessedEdges); |
204 | |
205 | TopoDS_Shell aShell, aShellNew; |
206 | aBB.MakeShell(aShell); |
207 | |
208 | aNbFaces=aFaces.Extent(); |
209 | if (aNbFaces) { |
210 | for (j=1; j<=aNbFaces; j++) { |
211 | const TopoDS_Shape& aF=aFaces(j); |
212 | aBB.Add(aShell, aF); |
213 | } |
214 | |
215 | OrientFacesOnShell(aShell, aShellNew); |
216 | |
217 | aBB.Add(aRes, aShellNew); |
218 | } |
219 | } |
220 | myResult=aRes; |
221 | } |
222 | //======================================================================= |
223 | // function: DoNewFaces |
224 | // purpose: |
225 | //======================================================================= |
226 | void BOP_ShellShell::DoNewFaces() |
227 | { |
228 | const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS(); |
229 | BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&myDSFiller->InterfPool(); |
230 | BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences(); |
231 | // |
232 | // vars |
233 | Standard_Boolean bIsTouchCase, bIsTouch; |
852a895c |
234 | Standard_Integer i, aNb, j, aNbj, iFF, nF1, iRank, nF2; |
7fd59977 |
235 | TopTools_ListOfShape aListOfNewFaces; |
236 | TopTools_IndexedMapOfShape anEMap; |
237 | TopAbs_Orientation anOriF1; |
238 | // |
239 | // DoMap |
240 | BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger aFFMap; |
241 | BOP_BuilderTools::DoMap(aFFs, aFFMap); |
242 | // |
243 | aNb=aFFMap.Extent(); |
244 | // |
245 | for (i=1; i<=aNb; i++) { |
246 | // |
247 | // a. Prepare info about the Face nF1 and create WES for nF1 |
248 | nF1=aFFMap.FindKey(i); |
249 | const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(nF1)); |
250 | |
251 | anOriF1=aF1.Orientation(); |
252 | iRank=aDS.Rank(nF1); |
253 | |
254 | myFace=aF1; |
255 | myFace.Orientation(TopAbs_FORWARD); |
256 | BOP_WireEdgeSet aWES (myFace); |
257 | |
258 | const TColStd_IndexedMapOfInteger& aFFIndicesMap=aFFMap.FindFromIndex(i); |
259 | aNbj=aFFIndicesMap.Extent(); |
260 | // |
261 | // b. The Switch: Same Domain Faces or Non-Same Domain Faces |
262 | bIsTouchCase=Standard_False; |
263 | for (j=1; j<=aNbj; j++) { |
264 | iFF=aFFIndicesMap(j); |
265 | BOPTools_SSInterference& aFF=aFFs(iFF); |
266 | bIsTouchCase=aFF.IsTangentFaces(); |
267 | if (bIsTouchCase) { |
268 | break; |
269 | } |
270 | } |
271 | // |
272 | // c. Filling the WES for nF1 |
273 | if (bIsTouchCase) { |
274 | // 1. Add Split Parts having states in accordance with operation |
275 | AddSplitPartsINOUT (nF1, aWES); |
276 | // 2. Add Section Edges to the WES |
277 | for (j=1; j<=aNbj; j++) { |
278 | iFF=aFFIndicesMap(j); |
279 | BOPTools_SSInterference& aFF=aFFs(iFF); |
280 | bIsTouch=aFF.IsTangentFaces(); |
281 | if (!bIsTouch) { |
282 | AddSectionPartsSh(nF1, iFF, aWES); |
283 | } |
284 | } |
285 | // 3. Add IN2D, ON2D Parts to the WES |
852a895c |
286 | // |
287 | //modified by NIZNHY-PKV Fri Sep 14 10:00:44 2012f |
288 | BOP_WireEdgeSet aWES1 (myFace); |
289 | // |
290 | for (j=1; j<=aNbj; j++) { |
291 | iFF=aFFIndicesMap(j); |
292 | BOPTools_SSInterference& aFF=aFFs(iFF); |
293 | bIsTouch=aFF.IsTangentFaces(); |
294 | if (bIsTouch) { |
295 | nF2=aFF.OppositeIndex(nF1); |
296 | AddINON2DPartsSh(nF1, iFF, aWES1); |
297 | } |
298 | } |
299 | // |
300 | if (iRank==2 || (iRank==1 && myOperation==BOP_CUT)) { |
301 | // #0023431 |
302 | // Refine WES to remove duplicated edges: |
303 | // - for the faces of the Object: Cut operation |
304 | // - for the faces of the Tool: all operations |
305 | // |
306 | // The duplications caused by the separated treatment |
307 | // the faces of an argument for the cases when: |
308 | // -these faces contain shared edges and |
309 | // -they are same domain faces with the faces of the other argument. |
310 | TopTools_DataMapOfShapeInteger aDMSI; |
311 | |
312 | //-- |
313 | aWES1.InitStartElements(); |
314 | for (; aWES1.MoreStartElements(); aWES1.NextStartElement()) { |
315 | const TopoDS_Edge& aE=*((TopoDS_Edge*)&aWES1.StartElement()); |
316 | if (!aDMSI.IsBound(aE)) { |
317 | Standard_Integer iCnt=1; |
318 | // |
319 | aDMSI.Bind(aE, iCnt); |
320 | } |
321 | else { |
322 | Standard_Integer& iCnt=aDMSI.ChangeFind(aE); |
323 | ++iCnt; |
324 | } |
325 | } |
326 | // |
327 | aWES1.InitStartElements(); |
328 | for (; aWES1.MoreStartElements(); aWES1.NextStartElement()) { |
329 | const TopoDS_Shape& aE=aWES1.StartElement(); |
330 | const Standard_Integer& iCnt=aDMSI.Find(aE); |
331 | if (iCnt==1) { |
332 | aWES.AddStartElement(aE); |
333 | } |
334 | } |
335 | } |
336 | else { |
337 | aWES1.InitStartElements(); |
338 | for (; aWES1.MoreStartElements(); aWES1.NextStartElement()) { |
339 | const TopoDS_Shape& aE=aWES1.StartElement(); |
340 | aWES.AddStartElement(aE); |
341 | } |
342 | } |
343 | //-- |
344 | /* |
7fd59977 |
345 | for (j=1; j<=aNbj; j++) { |
346 | iFF=aFFIndicesMap(j); |
347 | BOPTools_SSInterference& aFF=aFFs(iFF); |
348 | bIsTouch=aFF.IsTangentFaces(); |
349 | if (bIsTouch) { |
350 | Standard_Integer nF2; |
351 | nF2=aFF.OppositeIndex(nF1); |
352 | AddINON2DPartsSh(nF1, iFF, aWES); |
353 | } |
354 | } |
852a895c |
355 | */ |
356 | //modified by NIZNHY-PKV Fri Sep 14 10:00:48 2012t |
7fd59977 |
357 | // 4. Add EF parts (E (from F2) on F1 ), |
358 | // where F2 is non-same-domain face to F1 |
359 | anEMap.Clear(); |
360 | // |
361 | // anEMap will contain all Split parts that has already in aWES |
362 | const TopTools_ListOfShape& aLE=aWES.StartElements(); |
363 | |
364 | Standard_Integer aNbEdges1 = aLE.Extent(); |
365 | |
366 | TopTools_ListIteratorOfListOfShape anIt; |
367 | anIt.Initialize (aLE); |
368 | for (; anIt.More(); anIt.Next()) { |
369 | TopoDS_Shape& anE=anIt.Value(); |
370 | anEMap.Add(anE); |
371 | } |
372 | // |
373 | // IFV's workaround for occ13538: |
374 | // It is necessary to avoid building SD faces twice in case if SD faces of object and tool |
375 | // fully coincide and face of object has adjacent faces along all boundaries. |
376 | // For such cases WES for second SD faces are built from EE edges. |
377 | // The sence of workarond is to find such situation by checking of number of EF edges. |
378 | // If number of EF edges == 0, it means that SD faces fully coincide. |
379 | Standard_Integer aNbEF; |
380 | for (j=1; j<=aNbj; j++) { |
381 | iFF=aFFIndicesMap(j); |
382 | BOPTools_SSInterference& aFF=aFFs(iFF); |
383 | bIsTouch=aFF.IsTangentFaces(); |
384 | if (!bIsTouch) { |
385 | AddPartsEFNonSDSh (nF1, iFF, anEMap, aWES); |
386 | } |
387 | } |
388 | // |
389 | aNbEF = aWES.StartElements().Extent() - aNbEdges1; |
390 | // |
391 | if((aNbEdges1 > 0) && (aNbEF > 0)) { |
392 | for (j=1; j<=aNbj; j++) { |
393 | iFF=aFFIndicesMap(j); |
394 | BOPTools_SSInterference& aFF=aFFs(iFF); |
395 | bIsTouch=aFF.IsTangentFaces(); |
396 | if (!bIsTouch) { |
397 | AddPartsEENonSDSh (nF1, iFF, anEMap, aWES); |
398 | } |
399 | } |
400 | } |
401 | // IFV's workaround for occ13538 - end |
402 | // |
403 | }// end of if (bIsTouchCase) |
404 | else { |
405 | // 1. Add Split Parts having states in accordance with operation |
406 | AddSplitPartsINOUT (nF1, aWES); |
407 | // 2. Add Split Parts with state ON |
408 | AddSplitPartsONSh (nF1, aWES); |
409 | // 3. Add Section Edges to the WES |
410 | for (j=1; j<=aNbj; j++) { |
411 | iFF=aFFIndicesMap(j); |
412 | AddSectionPartsSh(nF1, iFF, aWES); |
413 | } |
414 | // 4. Add EF parts (E (from F2) on F1 ) |
415 | anEMap.Clear(); |
416 | for (j=1; j<=aNbj; j++) { |
417 | iFF=aFFIndicesMap(j); |
418 | AddPartsEFSh(nF1, iFF, anEMap, aWES); |
419 | } |
420 | }// end of (bIsTouchCase)'s else |
421 | // |
7fd59977 |
422 | // |
423 | // d. Build new Faces from myFace |
424 | BOP_FaceBuilder aFB; |
425 | aFB.SetTreatment(0); // 0-Do Internal Edges |
426 | aFB.SetTreatSDScales(1); |
427 | aFB.Do(aWES); |
428 | |
429 | const TopTools_ListOfShape& aLF=aFB.NewFaces(); |
430 | // |
431 | // e. Do Internal Vertices |
432 | // |
433 | DoInternalVertices(nF1, aLF); |
434 | // |
435 | // f. Orient new faces |
436 | TopTools_ListOfShape aLFx; |
437 | TopTools_ListIteratorOfListOfShape anIt; |
438 | anIt.Initialize(aLF); |
439 | for (; anIt.More(); anIt.Next()) { |
440 | TopoDS_Shape& aFx=anIt.Value(); |
441 | aFx.Orientation(anOriF1); |
442 | aListOfNewFaces.Append(aFx); |
443 | aLFx.Append(aFx); |
444 | } |
445 | // |
446 | // Fill "Modified" |
447 | FillModified(aF1, aLFx); |
448 | // |
449 | }// for (i=1; i<=aNb; i++) |
450 | // |
852a895c |
451 | |
7fd59977 |
452 | myNewFaces.Clear(); |
453 | myNewFaces.Append(aListOfNewFaces); |
454 | } |
852a895c |
455 | /* DEB |
456 | { |
457 | TopoDS_Compound aCx; |
458 | BRep_Builder aBB; |
459 | // |
460 | aBB.MakeCompound(aCx); |
461 | aBB.Add(aCx, myFace); |
462 | // |
463 | aWES.InitStartElements(); |
464 | for (; aWES.MoreStartElements(); aWES.NextStartElement()) { |
465 | const TopoDS_Shape& aE = aWES.StartElement(); |
466 | aBB.Add(aCx, aE); |
467 | } |
468 | int a=0; |
469 | } |
470 | |
471 | */ |