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 | // |
d5f74e42 |
9 | // This library is free software; you can redistribute it and/or modify it under |
10 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
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. |
465d1fba |
17 | // |
4e57c75e |
18 | #include <BOPAlgo_Builder.hxx> |
a0a3f6ac |
19 | // |
92ae0f2f |
20 | #include <Precision.hxx> |
21 | // |
db8e4b9a |
22 | #include <Bnd_Box.hxx> |
4e57c75e |
23 | #include <TopAbs_State.hxx> |
a0a3f6ac |
24 | // |
4e57c75e |
25 | #include <TopoDS.hxx> |
26 | #include <TopoDS_Iterator.hxx> |
27 | #include <TopoDS_Solid.hxx> |
28 | #include <TopoDS_Shape.hxx> |
29 | #include <TopoDS_Face.hxx> |
744511c8 |
30 | #include <TopoDS_Edge.hxx> |
4e57c75e |
31 | #include <TopoDS_Solid.hxx> |
32 | #include <TopoDS_Iterator.hxx> |
33 | #include <TopoDS_Shell.hxx> |
34 | #include <TopoDS_Compound.hxx> |
a0a3f6ac |
35 | // |
4e57c75e |
36 | #include <TopExp.hxx> |
37 | #include <TopExp_Explorer.hxx> |
a0a3f6ac |
38 | // |
4e57c75e |
39 | #include <BRep_Builder.hxx> |
b7cd7c2b |
40 | // |
41 | #include <BOPAlgo_Tools.hxx> |
42 | #include <BOPAlgo_BuilderSolid.hxx> |
4e57c75e |
43 | // |
1e143abb |
44 | #include <IntTools_Context.hxx> |
4e57c75e |
45 | // |
46 | #include <BOPDS_DS.hxx> |
47 | #include <BOPDS_ShapeInfo.hxx> |
48 | // |
4e57c75e |
49 | #include <BOPTools_AlgoTools.hxx> |
4e57c75e |
50 | #include <BOPTools_MapOfSet.hxx> |
51 | #include <BOPTools_Set.hxx> |
1155d05a |
52 | #include <BOPTools_Parallel.hxx> |
4e57c75e |
53 | // |
977ad983 |
54 | #include <BOPAlgo_Tools.hxx> |
4691b61a |
55 | #include <NCollection_Array1.hxx> |
86218548 |
56 | #include <NCollection_IncAllocator.hxx> |
1155d05a |
57 | #include <NCollection_Vector.hxx> |
58 | |
59 | #include <TopTools_IndexedMapOfShape.hxx> |
60 | #include <TopTools_MapOfShape.hxx> |
61 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
62 | #include <TopTools_IndexedDataMapOfShapeShape.hxx> |
63 | #include <TopTools_ListOfShape.hxx> |
744511c8 |
64 | |
0644bfa4 |
65 | #include <algorithm> |
744511c8 |
66 | |
4e57c75e |
67 | static |
68 | void OwnInternalShapes(const TopoDS_Shape& , |
1155d05a |
69 | TopTools_IndexedMapOfShape& ); |
4e57c75e |
70 | |
98b37659 |
71 | |
4e57c75e |
72 | //======================================================================= |
73 | //function : FillImagesSolids |
74 | //purpose : |
75 | //======================================================================= |
744511c8 |
76 | void BOPAlgo_Builder::FillImagesSolids() |
4e57c75e |
77 | { |
744511c8 |
78 | Standard_Boolean bHasSolids; |
79 | Standard_Integer i, aNbS; |
80 | // |
744511c8 |
81 | bHasSolids=Standard_False; |
82 | aNbS=myDS->NbSourceShapes(); |
83 | for (i=0; i<aNbS; ++i) { |
84 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); |
85 | if (aSI.ShapeType()==TopAbs_SOLID) { |
86 | bHasSolids=!bHasSolids; |
87 | break; |
88 | } |
89 | } |
90 | // |
91 | if (!bHasSolids) { |
92 | return; |
93 | } |
488e5b9d |
94 | // |
95 | Handle(NCollection_BaseAllocator) aAlr; |
744511c8 |
96 | // |
488e5b9d |
97 | aAlr=NCollection_BaseAllocator::CommonBaseAllocator(); |
4e57c75e |
98 | // |
1155d05a |
99 | TopTools_DataMapOfShapeListOfShape theInParts(100, aAlr); |
100 | TopTools_DataMapOfShapeShape theDraftSolids(100, aAlr); |
744511c8 |
101 | // |
30ecd5f8 |
102 | FillIn3DParts(theInParts, theDraftSolids, aAlr); |
744511c8 |
103 | BuildSplitSolids(theInParts, theDraftSolids, aAlr); |
4e57c75e |
104 | FillInternalShapes(); |
105 | // |
106 | theInParts.Clear(); |
107 | theDraftSolids.Clear(); |
4e57c75e |
108 | } |
109 | //======================================================================= |
110 | //function : FillIn3DParts |
111 | //purpose : |
112 | //======================================================================= |
a0a3f6ac |
113 | void BOPAlgo_Builder::FillIn3DParts |
1155d05a |
114 | (TopTools_DataMapOfShapeListOfShape& theInParts, |
115 | TopTools_DataMapOfShapeShape& theDraftSolids, |
116 | const Handle(NCollection_BaseAllocator)& ) |
4e57c75e |
117 | { |
b7cd7c2b |
118 | Handle(NCollection_BaseAllocator) anAlloc = new NCollection_IncAllocator; |
119 | |
120 | // Find all faces that are IN solids |
121 | |
122 | // Store boxes of the shapes into a map |
1155d05a |
123 | TopTools_DataMapOfShapeBox aShapeBoxMap(1, anAlloc); |
b7cd7c2b |
124 | |
125 | // Fence map |
1155d05a |
126 | TopTools_MapOfShape aMFence(1, anAlloc); |
b7cd7c2b |
127 | |
128 | // Get all faces |
1155d05a |
129 | TopTools_ListOfShape aLFaces(anAlloc); |
b7cd7c2b |
130 | |
131 | Standard_Integer i, aNbS = myDS->NbSourceShapes(); |
132 | for (i = 0; i < aNbS; ++i) |
133 | { |
134 | const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); |
135 | if (aSI.ShapeType() != TopAbs_FACE) |
744511c8 |
136 | continue; |
b7cd7c2b |
137 | |
138 | const TopoDS_Shape& aS = aSI.Shape(); |
1155d05a |
139 | const TopTools_ListOfShape* pLSIm = myImages.Seek(aS); |
b7cd7c2b |
140 | |
141 | if (pLSIm) |
142 | { |
1155d05a |
143 | TopTools_ListIteratorOfListOfShape aItLSIm(*pLSIm); |
b7cd7c2b |
144 | for (; aItLSIm.More(); aItLSIm.Next()) |
145 | { |
146 | const TopoDS_Shape& aSIm = aItLSIm.Value(); |
147 | if (aMFence.Add(aSIm)) |
148 | aLFaces.Append(aSIm); |
4e57c75e |
149 | } |
744511c8 |
150 | } |
b7cd7c2b |
151 | else |
152 | { |
153 | aLFaces.Append(aS); |
154 | aShapeBoxMap.Bind(aS, aSI.Box()); |
4e57c75e |
155 | } |
30ecd5f8 |
156 | } |
b7cd7c2b |
157 | |
158 | BRep_Builder aBB; |
159 | |
160 | // Get all solids |
1155d05a |
161 | TopTools_ListOfShape aLSolids(anAlloc); |
b7cd7c2b |
162 | // Keep INTERNAL faces of the solids |
1155d05a |
163 | TopTools_DataMapOfShapeListOfShape aSolidsIF(1, anAlloc); |
b7cd7c2b |
164 | // Draft solids |
1155d05a |
165 | TopTools_IndexedDataMapOfShapeShape aDraftSolid(1, anAlloc); |
b7cd7c2b |
166 | |
167 | for (i = 0; i < aNbS; ++i) |
168 | { |
169 | BOPDS_ShapeInfo& aSI = myDS->ChangeShapeInfo(i); |
170 | if (aSI.ShapeType() != TopAbs_SOLID) |
744511c8 |
171 | continue; |
b7cd7c2b |
172 | |
173 | const TopoDS_Shape& aS = aSI.Shape(); |
174 | const TopoDS_Solid& aSolid = (*(TopoDS_Solid*)(&aS)); |
4e57c75e |
175 | // |
b7cd7c2b |
176 | // Bounding box for the solid aS |
98b37659 |
177 | Bnd_Box& aBoxS = aSI.ChangeBox(); |
178 | if (aBoxS.IsVoid()) |
179 | myDS->BuildBndBoxSolid(i, aBoxS, myCheckInverted); |
b7cd7c2b |
180 | |
181 | // Build Draft Solid |
1155d05a |
182 | TopTools_ListOfShape aLIF; |
b7cd7c2b |
183 | TopoDS_Solid aSD; |
0090ae85 |
184 | aBB.MakeSolid(aSD); |
744511c8 |
185 | BuildDraftSolid(aSolid, aSD, aLIF); |
b7cd7c2b |
186 | |
187 | aLSolids.Append(aSD); |
188 | aSolidsIF.Bind(aSD, aLIF); |
189 | aShapeBoxMap.Bind(aSD, aBoxS); |
190 | aDraftSolid.Add(aS, aSD); |
191 | } |
192 | |
193 | // Perform classification of the faces |
1155d05a |
194 | TopTools_IndexedDataMapOfShapeListOfShape anInParts; |
b7cd7c2b |
195 | |
196 | BOPAlgo_Tools::ClassifyFaces(aLFaces, aLSolids, myRunParallel, |
197 | myContext, anInParts, aShapeBoxMap, aSolidsIF); |
198 | |
199 | // Analyze the results of classification |
200 | Standard_Integer aNbSol = aDraftSolid.Extent(); |
201 | for (i = 1; i <= aNbSol; ++i) |
202 | { |
203 | const TopoDS_Solid& aSolid = TopoDS::Solid(aDraftSolid.FindKey(i)); |
204 | const TopoDS_Solid& aSDraft = TopoDS::Solid(aDraftSolid(i)); |
1155d05a |
205 | const TopTools_ListOfShape& aLInFaces = anInParts.FindFromKey(aSDraft); |
206 | const TopTools_ListOfShape& aLInternal = aSolidsIF.Find(aSDraft); |
b7cd7c2b |
207 | |
208 | Standard_Integer aNbIN = aLInFaces.Extent(); |
209 | |
210 | if (!aNbIN) |
211 | { |
212 | Standard_Boolean bHasImage = Standard_False; |
213 | // Check if the shells of the solid have image |
214 | for (TopoDS_Iterator it(aSolid); it.More() && !bHasImage; it.Next()) |
215 | bHasImage = myImages.IsBound(it.Value()); |
216 | |
217 | if (!bHasImage) |
218 | // no need to split the solid |
219 | continue; |
4e57c75e |
220 | } |
b7cd7c2b |
221 | |
222 | theDraftSolids.Bind(aSolid, aSDraft); |
223 | |
224 | Standard_Integer aNbInt = aLInternal.Extent(); |
225 | if (aNbInt || aNbIN) |
226 | { |
227 | // Combine the lists |
1155d05a |
228 | TopTools_ListOfShape *pLIN = theInParts.Bound(aSolid, TopTools_ListOfShape()); |
b7cd7c2b |
229 | |
1155d05a |
230 | TopTools_ListIteratorOfListOfShape aItLS(aLInFaces); |
b7cd7c2b |
231 | for (; aItLS.More(); aItLS.Next()) |
232 | pLIN->Append(aItLS.Value()); |
233 | |
234 | aItLS.Initialize(aLInternal); |
235 | for (; aItLS.More(); aItLS.Next()) |
236 | pLIN->Append(aItLS.Value()); |
4e57c75e |
237 | } |
0090ae85 |
238 | } |
4e57c75e |
239 | } |
240 | //======================================================================= |
241 | //function : BuildDraftSolid |
242 | //purpose : |
243 | //======================================================================= |
744511c8 |
244 | void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid, |
a0a3f6ac |
245 | TopoDS_Shape& theDraftSolid, |
1155d05a |
246 | TopTools_ListOfShape& theLIF) |
4e57c75e |
247 | { |
4e57c75e |
248 | Standard_Boolean bToReverse; |
249 | Standard_Integer iFlag; |
250 | TopAbs_Orientation aOrF, aOrSh, aOrSd; |
251 | TopoDS_Iterator aIt1, aIt2; |
252 | TopoDS_Shell aShD; |
81a55a69 |
253 | TopoDS_Shape aFx; |
4e57c75e |
254 | BRep_Builder aBB; |
1155d05a |
255 | TopTools_ListIteratorOfListOfShape aItS; |
4e57c75e |
256 | // |
257 | aOrSd=theSolid.Orientation(); |
258 | theDraftSolid.Orientation(aOrSd); |
259 | // |
260 | aIt1.Initialize(theSolid); |
261 | for (; aIt1.More(); aIt1.Next()) { |
262 | const TopoDS_Shape& aSh=aIt1.Value(); |
263 | if(aSh.ShapeType()!=TopAbs_SHELL) { |
264 | continue; // mb internal edges,vertices |
265 | } |
266 | // |
267 | aOrSh=aSh.Orientation(); |
268 | aBB.MakeShell(aShD); |
269 | aShD.Orientation(aOrSh); |
270 | iFlag=0; |
271 | // |
272 | aIt2.Initialize(aSh); |
273 | for (; aIt2.More(); aIt2.Next()) { |
274 | const TopoDS_Shape& aF=aIt2.Value(); |
275 | aOrF=aF.Orientation(); |
276 | // |
277 | if (myImages.IsBound(aF)) { |
1155d05a |
278 | const TopTools_ListOfShape& aLSp=myImages.Find(aF); |
4e57c75e |
279 | aItS.Initialize(aLSp); |
280 | for (; aItS.More(); aItS.Next()) { |
281 | aFx=aItS.Value(); |
282 | // |
283 | if (myShapesSD.IsBound(aFx)) { |
4e57c75e |
284 | // |
285 | if (aOrF==TopAbs_INTERNAL) { |
81a55a69 |
286 | aFx.Orientation(aOrF); |
287 | theLIF.Append(aFx); |
4e57c75e |
288 | } |
289 | else { |
1e143abb |
290 | bToReverse=BOPTools_AlgoTools::IsSplitToReverse |
81a55a69 |
291 | (aFx, aF, myContext); |
4e57c75e |
292 | if (bToReverse) { |
81a55a69 |
293 | aFx.Reverse(); |
4e57c75e |
294 | } |
295 | // |
296 | iFlag=1; |
81a55a69 |
297 | aBB.Add(aShD, aFx); |
4e57c75e |
298 | } |
299 | }//if (myShapesSD.IsBound(aFx)) { |
300 | else { |
301 | aFx.Orientation(aOrF); |
302 | if (aOrF==TopAbs_INTERNAL) { |
303 | theLIF.Append(aFx); |
304 | } |
305 | else{ |
306 | iFlag=1; |
307 | aBB.Add(aShD, aFx); |
308 | } |
309 | } |
310 | } |
311 | } // if (myImages.IsBound(aF)) { |
312 | // |
313 | else { |
314 | if (aOrF==TopAbs_INTERNAL) { |
315 | theLIF.Append(aF); |
316 | } |
317 | else{ |
318 | iFlag=1; |
319 | aBB.Add(aShD, aF); |
320 | } |
321 | } |
322 | } //for (; aIt2.More(); aIt2.Next()) { |
323 | // |
324 | if (iFlag) { |
ab860031 |
325 | aShD.Closed (BRep_Tool::IsClosed (aShD)); |
4e57c75e |
326 | aBB.Add(theDraftSolid, aShD); |
327 | } |
328 | } //for (; aIt1.More(); aIt1.Next()) { |
329 | } |
b7cd7c2b |
330 | |
331 | //======================================================================= |
332 | // Vector of Solid Builders |
1155d05a |
333 | typedef NCollection_Vector<BOPAlgo_BuilderSolid> BOPAlgo_VectorOfBuilderSolid; |
b7cd7c2b |
334 | // Functors to split solids |
1155d05a |
335 | typedef BOPTools_Functor<BOPAlgo_BuilderSolid, |
b7cd7c2b |
336 | BOPAlgo_VectorOfBuilderSolid> BOPAlgo_BuilderSolidFunctor; |
337 | // |
1155d05a |
338 | typedef BOPTools_Cnt<BOPAlgo_BuilderSolidFunctor, |
b7cd7c2b |
339 | BOPAlgo_VectorOfBuilderSolid> BOPAlgo_BuilderSolidCnt; |
340 | //======================================================================= |
341 | |
4e57c75e |
342 | //======================================================================= |
343 | //function : BuildSplitSolids |
344 | //purpose : |
345 | //======================================================================= |
a0a3f6ac |
346 | void BOPAlgo_Builder::BuildSplitSolids |
1155d05a |
347 | (TopTools_DataMapOfShapeListOfShape& theInParts, |
348 | TopTools_DataMapOfShapeShape& theDraftSolids, |
349 | const Handle(NCollection_BaseAllocator)& ) |
4e57c75e |
350 | { |
4e57c75e |
351 | Standard_Boolean bFlagSD; |
96a95605 |
352 | Standard_Integer i, aNbS; |
4e57c75e |
353 | TopExp_Explorer aExp; |
1155d05a |
354 | TopTools_ListIteratorOfListOfShape aIt; |
4e57c75e |
355 | // |
488e5b9d |
356 | Handle(NCollection_BaseAllocator) aAlr0; |
357 | aAlr0=NCollection_BaseAllocator::CommonBaseAllocator(); |
744511c8 |
358 | // |
1155d05a |
359 | TopTools_ListOfShape aSFS(aAlr0), aLSEmpty(aAlr0); |
360 | TopTools_MapOfShape aMFence(100, aAlr0); |
744511c8 |
361 | BOPTools_MapOfSet aMST(100, aAlr0); |
30ecd5f8 |
362 | BOPAlgo_VectorOfBuilderSolid aVBS; |
4e57c75e |
363 | // |
b7cd7c2b |
364 | // 0. Find same domain solids for non-interfered solids |
4e57c75e |
365 | aNbS=myDS->NbSourceShapes(); |
366 | for (i=0; i<aNbS; ++i) { |
367 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); |
368 | // |
369 | if (aSI.ShapeType()!=TopAbs_SOLID) { |
370 | continue; |
371 | } |
372 | // |
373 | const TopoDS_Shape& aS=aSI.Shape(); |
374 | if (!aMFence.Add(aS)) { |
375 | continue; |
376 | } |
377 | if(theDraftSolids.IsBound(aS)) { |
378 | continue; |
379 | } |
380 | // |
381 | BOPTools_Set aST; |
382 | // |
383 | aST.Add(aS, TopAbs_FACE); |
384 | aMST.Add(aST); |
385 | // |
386 | } //for (i=1; i<=aNbS; ++i) |
387 | // |
98b37659 |
388 | // Build temporary map of solids images to avoid rebuilding |
389 | // of the solids without internal faces |
1155d05a |
390 | TopTools_IndexedDataMapOfShapeListOfShape aSolidsIm; |
98b37659 |
391 | // 1. Build solids for interfered source solids |
392 | for (i = 0; i < aNbS; ++i) { |
393 | const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); |
394 | if (aSI.ShapeType() != TopAbs_SOLID) |
4e57c75e |
395 | continue; |
98b37659 |
396 | |
397 | const TopoDS_Shape& aS = aSI.Shape(); |
30ecd5f8 |
398 | const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS)); |
98b37659 |
399 | if (!theDraftSolids.IsBound(aS)) |
400 | continue; |
401 | |
402 | const TopoDS_Shape& aSD = theDraftSolids.Find(aS); |
1155d05a |
403 | const TopTools_ListOfShape* pLFIN = theInParts.Seek(aS); |
b7cd7c2b |
404 | if (!pLFIN || pLFIN->IsEmpty()) |
98b37659 |
405 | { |
1155d05a |
406 | aSolidsIm(aSolidsIm.Add(aS, TopTools_ListOfShape())).Append(aSD); |
4e57c75e |
407 | continue; |
408 | } |
98b37659 |
409 | |
410 | aSFS.Clear(); |
4e57c75e |
411 | // |
412 | // 1.1 Fill Shell Faces Set |
4e57c75e |
413 | aExp.Init(aSD, TopAbs_FACE); |
414 | for (; aExp.More(); aExp.Next()) { |
98b37659 |
415 | const TopoDS_Shape& aF = aExp.Current(); |
4e57c75e |
416 | aSFS.Append(aF); |
417 | } |
418 | // |
98b37659 |
419 | // 1.2 Fill internal faces |
420 | aIt.Initialize(*pLFIN); |
4e57c75e |
421 | for (; aIt.More(); aIt.Next()) { |
98b37659 |
422 | TopoDS_Shape aF = aIt.Value(); |
4e57c75e |
423 | // |
424 | aF.Orientation(TopAbs_FORWARD); |
425 | aSFS.Append(aF); |
426 | aF.Orientation(TopAbs_REVERSED); |
427 | aSFS.Append(aF); |
428 | } |
429 | // |
98b37659 |
430 | // 1.3 Build new solids |
1155d05a |
431 | BOPAlgo_BuilderSolid& aBS=aVBS.Appended(); |
30ecd5f8 |
432 | aBS.SetSolid(aSolid); |
433 | aBS.SetShapes(aSFS); |
465d1fba |
434 | aBS.SetRunParallel(myRunParallel); |
36f4947b |
435 | aBS.SetProgressIndicator(myProgressIndicator); |
30ecd5f8 |
436 | }//for (i=0; i<aNbS; ++i) { |
437 | // |
438 | Standard_Integer k, aNbBS; |
439 | // |
1155d05a |
440 | aNbBS=aVBS.Length(); |
30ecd5f8 |
441 | // |
442 | //=================================================== |
443 | BOPAlgo_BuilderSolidCnt::Perform(myRunParallel, aVBS); |
444 | //=================================================== |
445 | // |
98b37659 |
446 | for (k = 0; k < aNbBS; ++k) |
447 | { |
448 | BOPAlgo_BuilderSolid& aBS = aVBS(k); |
449 | aSolidsIm.Add(aBS.Solid(), aBS.Areas()); |
450 | } |
451 | // |
452 | // Add new solids to images map |
453 | aNbBS = aSolidsIm.Extent(); |
454 | for (k = 1; k <= aNbBS; ++k) |
455 | { |
456 | const TopoDS_Shape& aS = aSolidsIm.FindKey(k); |
1155d05a |
457 | const TopTools_ListOfShape& aLSR = aSolidsIm(k); |
4e57c75e |
458 | // |
4e57c75e |
459 | if (!myImages.IsBound(aS)) { |
1155d05a |
460 | TopTools_ListOfShape* pLSx = myImages.Bound(aS, TopTools_ListOfShape()); |
4e57c75e |
461 | // |
462 | aIt.Initialize(aLSR); |
463 | for (; aIt.More(); aIt.Next()) { |
464 | BOPTools_Set aST; |
465 | // |
466 | const TopoDS_Shape& aSR=aIt.Value(); |
467 | aST.Add(aSR, TopAbs_FACE); |
468 | // |
469 | bFlagSD=aMST.Contains(aST); |
470 | // |
471 | const BOPTools_Set& aSTx=aMST.Added(aST); |
472 | const TopoDS_Shape& aSx=aSTx.Shape(); |
b18a83d4 |
473 | pLSx->Append(aSx); |
474 | // |
1155d05a |
475 | TopTools_ListOfShape* pLOr = myOrigins.ChangeSeek(aSx); |
b18a83d4 |
476 | if (!pLOr) { |
1155d05a |
477 | pLOr = myOrigins.Bound(aSx, TopTools_ListOfShape()); |
b18a83d4 |
478 | } |
479 | pLOr->Append(aS); |
4e57c75e |
480 | // |
481 | if (bFlagSD) { |
482 | myShapesSD.Bind(aSR, aSx); |
483 | } |
484 | } |
485 | } |
30ecd5f8 |
486 | } |
4e57c75e |
487 | } |
4e57c75e |
488 | //======================================================================= |
489 | //function :FillInternalShapes |
490 | //purpose : |
491 | //======================================================================= |
744511c8 |
492 | void BOPAlgo_Builder::FillInternalShapes() |
4e57c75e |
493 | { |
96a95605 |
494 | Standard_Integer i, j, aNbS, aNbSI, aNbSx; |
4e57c75e |
495 | TopAbs_ShapeEnum aType; |
496 | TopAbs_State aState; |
497 | TopoDS_Iterator aItS; |
498 | BRep_Builder aBB; |
1155d05a |
499 | TopTools_ListIteratorOfListOfShape aIt, aIt1; |
4e57c75e |
500 | // |
488e5b9d |
501 | Handle(NCollection_BaseAllocator) aAllocator; |
4e57c75e |
502 | //-----------------------------------------------------scope f |
488e5b9d |
503 | aAllocator=NCollection_BaseAllocator::CommonBaseAllocator(); |
4e57c75e |
504 | // |
1155d05a |
505 | TopTools_IndexedDataMapOfShapeListOfShape aMSx(100, aAllocator); |
506 | TopTools_IndexedMapOfShape aMx(100, aAllocator); |
507 | TopTools_IndexedMapOfShape aMSI(100, aAllocator); |
508 | TopTools_MapOfShape aMFence(100, aAllocator); |
509 | TopTools_MapOfShape aMSOr(100, aAllocator); |
510 | TopTools_ListOfShape aLSd(aAllocator); |
511 | TopTools_ListOfShape aLArgs(aAllocator); |
512 | TopTools_ListOfShape aLSC(aAllocator); |
513 | TopTools_ListOfShape aLSI(aAllocator); |
4e57c75e |
514 | // |
515 | // 1. Shapes to process |
516 | // |
517 | // 1.1 Shapes from pure arguments aMSI |
518 | // 1.1.1 vertex, edge, wire |
519 | // |
1155d05a |
520 | const TopTools_ListOfShape& aArguments=myDS->Arguments(); |
8620e18d |
521 | aIt.Initialize(aArguments); |
4e57c75e |
522 | for (; aIt.More(); aIt.Next()) { |
523 | const TopoDS_Shape& aS=aIt.Value(); |
977ad983 |
524 | BOPAlgo_Tools::TreatCompound(aS, aMFence, aLSC); |
c884a268 |
525 | } |
526 | aIt.Initialize(aLSC); |
527 | for (; aIt.More(); aIt.Next()) { |
528 | const TopoDS_Shape& aS=aIt.Value(); |
4e57c75e |
529 | aType=aS.ShapeType(); |
530 | if (aType==TopAbs_WIRE) { |
531 | aItS.Initialize(aS); |
532 | for(; aItS.More(); aItS.Next()) { |
533 | const TopoDS_Shape& aE=aItS.Value(); |
534 | if (aMFence.Add(aE)) { |
535 | aLArgs.Append(aE); |
536 | } |
537 | } |
538 | } |
539 | else if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE){ |
540 | aLArgs.Append(aS); |
541 | } |
542 | } |
543 | aMFence.Clear(); |
544 | // |
545 | aIt.Initialize(aLArgs); |
546 | for (; aIt.More(); aIt.Next()) { |
547 | const TopoDS_Shape& aS=aIt.Value(); |
548 | aType=aS.ShapeType(); |
a0a3f6ac |
549 | if (aType==TopAbs_VERTEX || |
550 | aType==TopAbs_EDGE || |
551 | aType==TopAbs_WIRE) { |
4e57c75e |
552 | if (aMFence.Add(aS)) { |
553 | if (myImages.IsBound(aS)) { |
1155d05a |
554 | const TopTools_ListOfShape &aLSp=myImages.Find(aS); |
4e57c75e |
555 | aIt1.Initialize(aLSp); |
556 | for (; aIt1.More(); aIt1.Next()) { |
557 | const TopoDS_Shape& aSp=aIt1.Value(); |
558 | aMSI.Add(aSp); |
559 | } |
560 | } |
561 | else { |
562 | aMSI.Add(aS); |
563 | } |
564 | } |
565 | } |
566 | } |
567 | |
568 | aNbSI=aMSI.Extent(); |
569 | // |
570 | // 2. Internal vertices, edges from source solids |
571 | aMFence.Clear(); |
572 | aLSd.Clear(); |
573 | // |
574 | aNbS=myDS->NbSourceShapes(); |
575 | for (i=0; i<aNbS; ++i) { |
576 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); |
577 | // |
578 | if (aSI.ShapeType()!=TopAbs_SOLID) { |
579 | continue; |
580 | } |
581 | // |
36f4947b |
582 | UserBreak(); |
583 | // |
4e57c75e |
584 | const TopoDS_Shape& aS=aSI.Shape(); |
585 | // |
586 | aMx.Clear(); |
587 | OwnInternalShapes(aS, aMx); |
588 | // |
589 | aNbSx=aMx.Extent(); |
590 | for (j=1; j<=aNbSx; ++j) { |
591 | const TopoDS_Shape& aSi=aMx(j); |
592 | if (myImages.IsBound(aSi)) { |
1155d05a |
593 | const TopTools_ListOfShape &aLSp=myImages.Find(aSi); |
4e57c75e |
594 | aIt1.Initialize(aLSp); |
595 | for (; aIt1.More(); aIt1.Next()) { |
596 | const TopoDS_Shape& aSp=aIt1.Value(); |
597 | aMSI.Add(aSp); |
598 | } |
599 | } |
600 | else { |
601 | aMSI.Add(aSi); |
602 | } |
603 | } |
604 | // |
605 | // build aux map from splits of solids |
606 | if (myImages.IsBound(aS)) { |
1155d05a |
607 | const TopTools_ListOfShape &aLSp=myImages.Find(aS); |
4e57c75e |
608 | aIt.Initialize(aLSp); |
609 | for (; aIt.More(); aIt.Next()) { |
610 | const TopoDS_Shape& aSp=aIt.Value(); |
611 | if (aMFence.Add(aSp)) { |
1155d05a |
612 | TopExp::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_EDGE, aMSx); |
613 | TopExp::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_FACE, aMSx); |
614 | TopExp::MapShapesAndAncestors(aSp, TopAbs_EDGE , TopAbs_FACE, aMSx); |
4e57c75e |
615 | aLSd.Append(aSp); |
616 | } |
617 | } |
618 | } |
619 | else { |
620 | if (aMFence.Add(aS)) { |
1155d05a |
621 | TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aMSx); |
622 | TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aMSx); |
623 | TopExp::MapShapesAndAncestors(aS, TopAbs_EDGE , TopAbs_FACE, aMSx); |
4e57c75e |
624 | aLSd.Append(aS); |
625 | aMSOr.Add(aS); |
626 | } |
627 | } |
628 | }// for (i=0; i<aNbS; ++i) { |
629 | // |
4e57c75e |
630 | // 3. Some shapes of aMSI can be already tied with faces of |
631 | // split solids |
319da2e4 |
632 | aNbSI = aMSI.Extent(); |
633 | for (i = 1; i <= aNbSI; ++i) { |
634 | const TopoDS_Shape& aSI = aMSI(i); |
4e57c75e |
635 | if (aMSx.Contains(aSI)) { |
1155d05a |
636 | const TopTools_ListOfShape &aLSx=aMSx.FindFromKey(aSI); |
319da2e4 |
637 | aNbSx = aLSx.Extent(); |
638 | if (!aNbSx) { |
639 | aLSI.Append(aSI); |
4e57c75e |
640 | } |
641 | } |
319da2e4 |
642 | else { |
643 | aLSI.Append(aSI); |
644 | } |
4e57c75e |
645 | } |
646 | // |
647 | // 4. Just check it |
319da2e4 |
648 | aNbSI = aLSI.Extent(); |
4e57c75e |
649 | if (!aNbSI) { |
650 | return; |
651 | } |
652 | // |
653 | // 5 Settle internal vertices and edges into solids |
654 | aMx.Clear(); |
655 | aIt.Initialize(aLSd); |
656 | for (; aIt.More(); aIt.Next()) { |
657 | TopoDS_Solid aSd=TopoDS::Solid(aIt.Value()); |
658 | // |
319da2e4 |
659 | aIt1.Initialize(aLSI); |
660 | for (; aIt1.More();) { |
661 | TopoDS_Shape aSI = aIt1.Value(); |
4e57c75e |
662 | aSI.Orientation(TopAbs_INTERNAL); |
663 | // |
0090ae85 |
664 | aState=BOPTools_AlgoTools::ComputeStateByOnePoint |
665 | (aSI, aSd, 1.e-11, myContext); |
319da2e4 |
666 | // |
667 | if (aState != TopAbs_IN) { |
668 | aIt1.Next(); |
669 | continue; |
670 | } |
671 | // |
b18a83d4 |
672 | if (aMSOr.Contains(aSd)) { |
673 | // make new solid |
319da2e4 |
674 | TopoDS_Solid aSdx; |
675 | // |
676 | aBB.MakeSolid(aSdx); |
677 | aItS.Initialize(aSd); |
678 | for (; aItS.More(); aItS.Next()) { |
679 | const TopoDS_Shape& aSh=aItS.Value(); |
680 | aBB.Add(aSdx, aSh); |
4e57c75e |
681 | } |
319da2e4 |
682 | // |
683 | aBB.Add(aSdx, aSI); |
684 | // |
b18a83d4 |
685 | // no need to check for images of aSd as aMSOr contains only original solids |
1155d05a |
686 | TopTools_ListOfShape* pLS = myImages.Bound(aSd, TopTools_ListOfShape()); |
b18a83d4 |
687 | pLS->Append(aSdx); |
688 | // |
1155d05a |
689 | TopTools_ListOfShape* pLOr = myOrigins.Bound(aSdx, TopTools_ListOfShape()); |
b18a83d4 |
690 | pLOr->Append(aSd); |
4e57c75e |
691 | // |
319da2e4 |
692 | aMSOr.Remove(aSd); |
693 | aSd=aSdx; |
694 | } |
695 | else { |
696 | aBB.Add(aSd, aSI); |
697 | } |
698 | // |
699 | aLSI.Remove(aIt1); |
700 | }//for (; aIt1.More();) { |
701 | }//for (; aIt.More(); aIt.Next()) { |
4e57c75e |
702 | // |
703 | //-----------------------------------------------------scope t |
704 | aLArgs.Clear(); |
705 | aLSd.Clear(); |
706 | aMSOr.Clear(); |
707 | aMFence.Clear(); |
708 | aMSI.Clear(); |
709 | aMx.Clear(); |
710 | aMSx.Clear(); |
711 | } |
712 | //======================================================================= |
713 | //function : OwnInternalShapes |
714 | //purpose : |
715 | //======================================================================= |
a0a3f6ac |
716 | void OwnInternalShapes(const TopoDS_Shape& theS, |
1155d05a |
717 | TopTools_IndexedMapOfShape& theMx) |
4e57c75e |
718 | { |
719 | TopoDS_Iterator aIt; |
720 | // |
721 | aIt.Initialize(theS); |
722 | for (; aIt.More(); aIt.Next()) { |
723 | const TopoDS_Shape& aSx=aIt.Value(); |
724 | if (aSx.ShapeType()!=TopAbs_SHELL) { |
725 | theMx.Add(aSx); |
726 | } |
727 | } |
728 | } |