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> |
13c0e402 |
26 | #include <TopoDS_AlertWithShape.hxx> |
4e57c75e |
27 | #include <TopoDS_Iterator.hxx> |
28 | #include <TopoDS_Solid.hxx> |
29 | #include <TopoDS_Shape.hxx> |
30 | #include <TopoDS_Face.hxx> |
744511c8 |
31 | #include <TopoDS_Edge.hxx> |
4e57c75e |
32 | #include <TopoDS_Solid.hxx> |
4e57c75e |
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 | } |
13c0e402 |
94 | |
95 | // Draft solids |
96 | TopTools_DataMapOfShapeShape aDraftSolids; |
97 | // Find all IN faces for all IN faces |
98 | FillIn3DParts(aDraftSolids); |
99 | // Build split of the solids |
100 | BuildSplitSolids(aDraftSolids); |
101 | // Fill solids with internal parts |
4e57c75e |
102 | FillInternalShapes(); |
4e57c75e |
103 | } |
104 | //======================================================================= |
105 | //function : FillIn3DParts |
106 | //purpose : |
107 | //======================================================================= |
13c0e402 |
108 | void BOPAlgo_Builder::FillIn3DParts(TopTools_DataMapOfShapeShape& theDraftSolids) |
4e57c75e |
109 | { |
b7cd7c2b |
110 | Handle(NCollection_BaseAllocator) anAlloc = new NCollection_IncAllocator; |
111 | |
112 | // Find all faces that are IN solids |
113 | |
114 | // Store boxes of the shapes into a map |
1155d05a |
115 | TopTools_DataMapOfShapeBox aShapeBoxMap(1, anAlloc); |
b7cd7c2b |
116 | |
117 | // Fence map |
1155d05a |
118 | TopTools_MapOfShape aMFence(1, anAlloc); |
b7cd7c2b |
119 | |
120 | // Get all faces |
1155d05a |
121 | TopTools_ListOfShape aLFaces(anAlloc); |
b7cd7c2b |
122 | |
123 | Standard_Integer i, aNbS = myDS->NbSourceShapes(); |
124 | for (i = 0; i < aNbS; ++i) |
125 | { |
126 | const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); |
127 | if (aSI.ShapeType() != TopAbs_FACE) |
744511c8 |
128 | continue; |
b7cd7c2b |
129 | |
130 | const TopoDS_Shape& aS = aSI.Shape(); |
1155d05a |
131 | const TopTools_ListOfShape* pLSIm = myImages.Seek(aS); |
b7cd7c2b |
132 | |
133 | if (pLSIm) |
134 | { |
1155d05a |
135 | TopTools_ListIteratorOfListOfShape aItLSIm(*pLSIm); |
b7cd7c2b |
136 | for (; aItLSIm.More(); aItLSIm.Next()) |
137 | { |
138 | const TopoDS_Shape& aSIm = aItLSIm.Value(); |
139 | if (aMFence.Add(aSIm)) |
140 | aLFaces.Append(aSIm); |
4e57c75e |
141 | } |
744511c8 |
142 | } |
b7cd7c2b |
143 | else |
144 | { |
145 | aLFaces.Append(aS); |
146 | aShapeBoxMap.Bind(aS, aSI.Box()); |
4e57c75e |
147 | } |
30ecd5f8 |
148 | } |
b7cd7c2b |
149 | |
150 | BRep_Builder aBB; |
151 | |
152 | // Get all solids |
1155d05a |
153 | TopTools_ListOfShape aLSolids(anAlloc); |
b7cd7c2b |
154 | // Keep INTERNAL faces of the solids |
1155d05a |
155 | TopTools_DataMapOfShapeListOfShape aSolidsIF(1, anAlloc); |
b7cd7c2b |
156 | // Draft solids |
1155d05a |
157 | TopTools_IndexedDataMapOfShapeShape aDraftSolid(1, anAlloc); |
b7cd7c2b |
158 | |
159 | for (i = 0; i < aNbS; ++i) |
160 | { |
161 | BOPDS_ShapeInfo& aSI = myDS->ChangeShapeInfo(i); |
162 | if (aSI.ShapeType() != TopAbs_SOLID) |
744511c8 |
163 | continue; |
b7cd7c2b |
164 | |
165 | const TopoDS_Shape& aS = aSI.Shape(); |
166 | const TopoDS_Solid& aSolid = (*(TopoDS_Solid*)(&aS)); |
4e57c75e |
167 | // |
b7cd7c2b |
168 | // Bounding box for the solid aS |
98b37659 |
169 | Bnd_Box& aBoxS = aSI.ChangeBox(); |
170 | if (aBoxS.IsVoid()) |
171 | myDS->BuildBndBoxSolid(i, aBoxS, myCheckInverted); |
b7cd7c2b |
172 | |
173 | // Build Draft Solid |
1155d05a |
174 | TopTools_ListOfShape aLIF; |
b7cd7c2b |
175 | TopoDS_Solid aSD; |
0090ae85 |
176 | aBB.MakeSolid(aSD); |
744511c8 |
177 | BuildDraftSolid(aSolid, aSD, aLIF); |
b7cd7c2b |
178 | |
179 | aLSolids.Append(aSD); |
180 | aSolidsIF.Bind(aSD, aLIF); |
181 | aShapeBoxMap.Bind(aSD, aBoxS); |
182 | aDraftSolid.Add(aS, aSD); |
183 | } |
184 | |
185 | // Perform classification of the faces |
1155d05a |
186 | TopTools_IndexedDataMapOfShapeListOfShape anInParts; |
b7cd7c2b |
187 | |
188 | BOPAlgo_Tools::ClassifyFaces(aLFaces, aLSolids, myRunParallel, |
189 | myContext, anInParts, aShapeBoxMap, aSolidsIF); |
190 | |
191 | // Analyze the results of classification |
192 | Standard_Integer aNbSol = aDraftSolid.Extent(); |
193 | for (i = 1; i <= aNbSol; ++i) |
194 | { |
195 | const TopoDS_Solid& aSolid = TopoDS::Solid(aDraftSolid.FindKey(i)); |
196 | const TopoDS_Solid& aSDraft = TopoDS::Solid(aDraftSolid(i)); |
1155d05a |
197 | const TopTools_ListOfShape& aLInFaces = anInParts.FindFromKey(aSDraft); |
198 | const TopTools_ListOfShape& aLInternal = aSolidsIF.Find(aSDraft); |
b7cd7c2b |
199 | |
200 | Standard_Integer aNbIN = aLInFaces.Extent(); |
201 | |
202 | if (!aNbIN) |
203 | { |
204 | Standard_Boolean bHasImage = Standard_False; |
205 | // Check if the shells of the solid have image |
206 | for (TopoDS_Iterator it(aSolid); it.More() && !bHasImage; it.Next()) |
207 | bHasImage = myImages.IsBound(it.Value()); |
208 | |
209 | if (!bHasImage) |
210 | // no need to split the solid |
211 | continue; |
4e57c75e |
212 | } |
b7cd7c2b |
213 | |
214 | theDraftSolids.Bind(aSolid, aSDraft); |
215 | |
216 | Standard_Integer aNbInt = aLInternal.Extent(); |
217 | if (aNbInt || aNbIN) |
218 | { |
219 | // Combine the lists |
13c0e402 |
220 | TopTools_ListOfShape *pLIN = myInParts.Bound(aSolid, TopTools_ListOfShape()); |
b7cd7c2b |
221 | |
1155d05a |
222 | TopTools_ListIteratorOfListOfShape aItLS(aLInFaces); |
b7cd7c2b |
223 | for (; aItLS.More(); aItLS.Next()) |
224 | pLIN->Append(aItLS.Value()); |
225 | |
226 | aItLS.Initialize(aLInternal); |
227 | for (; aItLS.More(); aItLS.Next()) |
228 | pLIN->Append(aItLS.Value()); |
4e57c75e |
229 | } |
0090ae85 |
230 | } |
4e57c75e |
231 | } |
232 | //======================================================================= |
233 | //function : BuildDraftSolid |
234 | //purpose : |
235 | //======================================================================= |
744511c8 |
236 | void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid, |
a0a3f6ac |
237 | TopoDS_Shape& theDraftSolid, |
1155d05a |
238 | TopTools_ListOfShape& theLIF) |
4e57c75e |
239 | { |
4e57c75e |
240 | Standard_Boolean bToReverse; |
241 | Standard_Integer iFlag; |
242 | TopAbs_Orientation aOrF, aOrSh, aOrSd; |
243 | TopoDS_Iterator aIt1, aIt2; |
244 | TopoDS_Shell aShD; |
81a55a69 |
245 | TopoDS_Shape aFx; |
4e57c75e |
246 | BRep_Builder aBB; |
1155d05a |
247 | TopTools_ListIteratorOfListOfShape aItS; |
4e57c75e |
248 | // |
249 | aOrSd=theSolid.Orientation(); |
250 | theDraftSolid.Orientation(aOrSd); |
251 | // |
252 | aIt1.Initialize(theSolid); |
253 | for (; aIt1.More(); aIt1.Next()) { |
254 | const TopoDS_Shape& aSh=aIt1.Value(); |
255 | if(aSh.ShapeType()!=TopAbs_SHELL) { |
256 | continue; // mb internal edges,vertices |
257 | } |
258 | // |
259 | aOrSh=aSh.Orientation(); |
260 | aBB.MakeShell(aShD); |
261 | aShD.Orientation(aOrSh); |
262 | iFlag=0; |
263 | // |
264 | aIt2.Initialize(aSh); |
265 | for (; aIt2.More(); aIt2.Next()) { |
266 | const TopoDS_Shape& aF=aIt2.Value(); |
267 | aOrF=aF.Orientation(); |
268 | // |
269 | if (myImages.IsBound(aF)) { |
1155d05a |
270 | const TopTools_ListOfShape& aLSp=myImages.Find(aF); |
4e57c75e |
271 | aItS.Initialize(aLSp); |
272 | for (; aItS.More(); aItS.Next()) { |
273 | aFx=aItS.Value(); |
274 | // |
275 | if (myShapesSD.IsBound(aFx)) { |
4e57c75e |
276 | // |
277 | if (aOrF==TopAbs_INTERNAL) { |
81a55a69 |
278 | aFx.Orientation(aOrF); |
279 | theLIF.Append(aFx); |
4e57c75e |
280 | } |
281 | else { |
80d55adf |
282 | bToReverse=BOPTools_AlgoTools::IsSplitToReverseWithWarn |
283 | (aFx, aF, myContext, myReport); |
4e57c75e |
284 | if (bToReverse) { |
81a55a69 |
285 | aFx.Reverse(); |
4e57c75e |
286 | } |
287 | // |
288 | iFlag=1; |
81a55a69 |
289 | aBB.Add(aShD, aFx); |
4e57c75e |
290 | } |
291 | }//if (myShapesSD.IsBound(aFx)) { |
292 | else { |
293 | aFx.Orientation(aOrF); |
294 | if (aOrF==TopAbs_INTERNAL) { |
295 | theLIF.Append(aFx); |
296 | } |
297 | else{ |
298 | iFlag=1; |
299 | aBB.Add(aShD, aFx); |
300 | } |
301 | } |
302 | } |
303 | } // if (myImages.IsBound(aF)) { |
304 | // |
305 | else { |
306 | if (aOrF==TopAbs_INTERNAL) { |
307 | theLIF.Append(aF); |
308 | } |
309 | else{ |
310 | iFlag=1; |
311 | aBB.Add(aShD, aF); |
312 | } |
313 | } |
314 | } //for (; aIt2.More(); aIt2.Next()) { |
315 | // |
316 | if (iFlag) { |
ab860031 |
317 | aShD.Closed (BRep_Tool::IsClosed (aShD)); |
4e57c75e |
318 | aBB.Add(theDraftSolid, aShD); |
319 | } |
320 | } //for (; aIt1.More(); aIt1.Next()) { |
321 | } |
b7cd7c2b |
322 | |
323 | //======================================================================= |
7f3408c8 |
324 | |
325 | //======================================================================= |
326 | //class : BOPAlgo_SplitSolid |
327 | //purpose : Auxiliary class to extend the BOPAlgo_BuilderSolid with the solid to split |
328 | //======================================================================= |
329 | class BOPAlgo_SplitSolid : public BOPAlgo_BuilderSolid |
330 | { |
331 | public: |
332 | //! Sets the solid |
333 | void SetSolid(const TopoDS_Solid& theSolid) { mySolid = theSolid; } |
334 | |
335 | //! Returns the solid |
336 | const TopoDS_Solid& Solid() const { return mySolid; } |
337 | |
338 | private: |
339 | TopoDS_Solid mySolid; //!< Solid to split |
340 | }; |
341 | |
b7cd7c2b |
342 | // Vector of Solid Builders |
7f3408c8 |
343 | typedef NCollection_Vector<BOPAlgo_SplitSolid> BOPAlgo_VectorOfBuilderSolid; |
b7cd7c2b |
344 | |
4e57c75e |
345 | //======================================================================= |
346 | //function : BuildSplitSolids |
347 | //purpose : |
348 | //======================================================================= |
13c0e402 |
349 | void BOPAlgo_Builder::BuildSplitSolids(TopTools_DataMapOfShapeShape& theDraftSolids) |
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); |
13c0e402 |
403 | const TopTools_ListOfShape* pLFIN = myInParts.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 |
7f3408c8 |
431 | BOPAlgo_SplitSolid& 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 | //=================================================== |
fc867b96 |
443 | BOPTools_Parallel::Perform (myRunParallel, aVBS); |
30ecd5f8 |
444 | //=================================================== |
445 | // |
98b37659 |
446 | for (k = 0; k < aNbBS; ++k) |
447 | { |
7f3408c8 |
448 | BOPAlgo_SplitSolid& aBS = aVBS(k); |
98b37659 |
449 | aSolidsIm.Add(aBS.Solid(), aBS.Areas()); |
13c0e402 |
450 | |
451 | // Merge BuilderSolid's report into main report, |
452 | // assigning the solid with the warnings/errors which |
453 | // have been generated for it. |
454 | // Convert all errors of BuilderSolid into warnings for main report. |
455 | const Handle(Message_Report)& aBSReport = aBS.GetReport(); |
456 | Message_Gravity anAlertTypes[2] = { Message_Warning, Message_Fail }; |
457 | for (Standard_Integer iGravity = 0; iGravity < 2; iGravity++) |
458 | { |
459 | const Message_ListOfAlert& anLAlerts = aBSReport->GetAlerts(anAlertTypes[iGravity]); |
460 | for (Message_ListOfAlert::Iterator itA(anLAlerts); itA.More(); itA.Next()) |
461 | { |
462 | Handle(Message_Alert) anAlert = itA.Value(); |
463 | |
464 | Handle(TopoDS_AlertWithShape) anAlertWithShape = Handle(TopoDS_AlertWithShape)::DownCast(itA.Value()); |
465 | if (!anAlertWithShape.IsNull()) |
466 | { |
467 | TopoDS_Shape aWarnShape; |
468 | BRep_Builder().MakeCompound(TopoDS::Compound(aWarnShape)); |
469 | BRep_Builder().Add(aWarnShape, aBS.Solid()); |
470 | BRep_Builder().Add(aWarnShape, anAlertWithShape->GetShape()); |
471 | |
472 | anAlertWithShape->SetShape(aWarnShape); |
473 | AddWarning(anAlertWithShape); |
474 | } |
475 | else |
476 | AddWarning(anAlert); |
477 | } |
478 | } |
98b37659 |
479 | } |
480 | // |
481 | // Add new solids to images map |
482 | aNbBS = aSolidsIm.Extent(); |
483 | for (k = 1; k <= aNbBS; ++k) |
484 | { |
485 | const TopoDS_Shape& aS = aSolidsIm.FindKey(k); |
1155d05a |
486 | const TopTools_ListOfShape& aLSR = aSolidsIm(k); |
4e57c75e |
487 | // |
4e57c75e |
488 | if (!myImages.IsBound(aS)) { |
1155d05a |
489 | TopTools_ListOfShape* pLSx = myImages.Bound(aS, TopTools_ListOfShape()); |
4e57c75e |
490 | // |
491 | aIt.Initialize(aLSR); |
492 | for (; aIt.More(); aIt.Next()) { |
493 | BOPTools_Set aST; |
494 | // |
495 | const TopoDS_Shape& aSR=aIt.Value(); |
496 | aST.Add(aSR, TopAbs_FACE); |
497 | // |
498 | bFlagSD=aMST.Contains(aST); |
499 | // |
500 | const BOPTools_Set& aSTx=aMST.Added(aST); |
501 | const TopoDS_Shape& aSx=aSTx.Shape(); |
b18a83d4 |
502 | pLSx->Append(aSx); |
503 | // |
1155d05a |
504 | TopTools_ListOfShape* pLOr = myOrigins.ChangeSeek(aSx); |
b18a83d4 |
505 | if (!pLOr) { |
1155d05a |
506 | pLOr = myOrigins.Bound(aSx, TopTools_ListOfShape()); |
b18a83d4 |
507 | } |
508 | pLOr->Append(aS); |
4e57c75e |
509 | // |
510 | if (bFlagSD) { |
511 | myShapesSD.Bind(aSR, aSx); |
512 | } |
513 | } |
514 | } |
30ecd5f8 |
515 | } |
4e57c75e |
516 | } |
4e57c75e |
517 | //======================================================================= |
518 | //function :FillInternalShapes |
519 | //purpose : |
520 | //======================================================================= |
744511c8 |
521 | void BOPAlgo_Builder::FillInternalShapes() |
4e57c75e |
522 | { |
96a95605 |
523 | Standard_Integer i, j, aNbS, aNbSI, aNbSx; |
4e57c75e |
524 | TopAbs_ShapeEnum aType; |
525 | TopAbs_State aState; |
526 | TopoDS_Iterator aItS; |
527 | BRep_Builder aBB; |
1155d05a |
528 | TopTools_ListIteratorOfListOfShape aIt, aIt1; |
4e57c75e |
529 | // |
488e5b9d |
530 | Handle(NCollection_BaseAllocator) aAllocator; |
4e57c75e |
531 | //-----------------------------------------------------scope f |
488e5b9d |
532 | aAllocator=NCollection_BaseAllocator::CommonBaseAllocator(); |
4e57c75e |
533 | // |
1155d05a |
534 | TopTools_IndexedDataMapOfShapeListOfShape aMSx(100, aAllocator); |
535 | TopTools_IndexedMapOfShape aMx(100, aAllocator); |
536 | TopTools_IndexedMapOfShape aMSI(100, aAllocator); |
537 | TopTools_MapOfShape aMFence(100, aAllocator); |
538 | TopTools_MapOfShape aMSOr(100, aAllocator); |
539 | TopTools_ListOfShape aLSd(aAllocator); |
540 | TopTools_ListOfShape aLArgs(aAllocator); |
541 | TopTools_ListOfShape aLSC(aAllocator); |
542 | TopTools_ListOfShape aLSI(aAllocator); |
4e57c75e |
543 | // |
544 | // 1. Shapes to process |
545 | // |
546 | // 1.1 Shapes from pure arguments aMSI |
547 | // 1.1.1 vertex, edge, wire |
548 | // |
1155d05a |
549 | const TopTools_ListOfShape& aArguments=myDS->Arguments(); |
8620e18d |
550 | aIt.Initialize(aArguments); |
4e57c75e |
551 | for (; aIt.More(); aIt.Next()) { |
552 | const TopoDS_Shape& aS=aIt.Value(); |
977ad983 |
553 | BOPAlgo_Tools::TreatCompound(aS, aMFence, aLSC); |
c884a268 |
554 | } |
555 | aIt.Initialize(aLSC); |
556 | for (; aIt.More(); aIt.Next()) { |
557 | const TopoDS_Shape& aS=aIt.Value(); |
4e57c75e |
558 | aType=aS.ShapeType(); |
559 | if (aType==TopAbs_WIRE) { |
560 | aItS.Initialize(aS); |
561 | for(; aItS.More(); aItS.Next()) { |
562 | const TopoDS_Shape& aE=aItS.Value(); |
563 | if (aMFence.Add(aE)) { |
564 | aLArgs.Append(aE); |
565 | } |
566 | } |
567 | } |
568 | else if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE){ |
569 | aLArgs.Append(aS); |
570 | } |
571 | } |
572 | aMFence.Clear(); |
573 | // |
574 | aIt.Initialize(aLArgs); |
575 | for (; aIt.More(); aIt.Next()) { |
576 | const TopoDS_Shape& aS=aIt.Value(); |
577 | aType=aS.ShapeType(); |
a0a3f6ac |
578 | if (aType==TopAbs_VERTEX || |
579 | aType==TopAbs_EDGE || |
580 | aType==TopAbs_WIRE) { |
4e57c75e |
581 | if (aMFence.Add(aS)) { |
582 | if (myImages.IsBound(aS)) { |
1155d05a |
583 | const TopTools_ListOfShape &aLSp=myImages.Find(aS); |
4e57c75e |
584 | aIt1.Initialize(aLSp); |
585 | for (; aIt1.More(); aIt1.Next()) { |
586 | const TopoDS_Shape& aSp=aIt1.Value(); |
587 | aMSI.Add(aSp); |
588 | } |
589 | } |
590 | else { |
591 | aMSI.Add(aS); |
592 | } |
593 | } |
594 | } |
595 | } |
596 | |
597 | aNbSI=aMSI.Extent(); |
598 | // |
599 | // 2. Internal vertices, edges from source solids |
600 | aMFence.Clear(); |
601 | aLSd.Clear(); |
602 | // |
603 | aNbS=myDS->NbSourceShapes(); |
604 | for (i=0; i<aNbS; ++i) { |
605 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); |
606 | // |
607 | if (aSI.ShapeType()!=TopAbs_SOLID) { |
608 | continue; |
609 | } |
610 | // |
36f4947b |
611 | UserBreak(); |
612 | // |
4e57c75e |
613 | const TopoDS_Shape& aS=aSI.Shape(); |
614 | // |
615 | aMx.Clear(); |
616 | OwnInternalShapes(aS, aMx); |
617 | // |
618 | aNbSx=aMx.Extent(); |
619 | for (j=1; j<=aNbSx; ++j) { |
620 | const TopoDS_Shape& aSi=aMx(j); |
621 | if (myImages.IsBound(aSi)) { |
1155d05a |
622 | const TopTools_ListOfShape &aLSp=myImages.Find(aSi); |
4e57c75e |
623 | aIt1.Initialize(aLSp); |
624 | for (; aIt1.More(); aIt1.Next()) { |
625 | const TopoDS_Shape& aSp=aIt1.Value(); |
626 | aMSI.Add(aSp); |
627 | } |
628 | } |
629 | else { |
630 | aMSI.Add(aSi); |
631 | } |
632 | } |
633 | // |
634 | // build aux map from splits of solids |
635 | if (myImages.IsBound(aS)) { |
1155d05a |
636 | const TopTools_ListOfShape &aLSp=myImages.Find(aS); |
4e57c75e |
637 | aIt.Initialize(aLSp); |
638 | for (; aIt.More(); aIt.Next()) { |
639 | const TopoDS_Shape& aSp=aIt.Value(); |
640 | if (aMFence.Add(aSp)) { |
1155d05a |
641 | TopExp::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_EDGE, aMSx); |
642 | TopExp::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_FACE, aMSx); |
643 | TopExp::MapShapesAndAncestors(aSp, TopAbs_EDGE , TopAbs_FACE, aMSx); |
4e57c75e |
644 | aLSd.Append(aSp); |
645 | } |
646 | } |
647 | } |
648 | else { |
649 | if (aMFence.Add(aS)) { |
1155d05a |
650 | TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aMSx); |
651 | TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aMSx); |
652 | TopExp::MapShapesAndAncestors(aS, TopAbs_EDGE , TopAbs_FACE, aMSx); |
4e57c75e |
653 | aLSd.Append(aS); |
654 | aMSOr.Add(aS); |
655 | } |
656 | } |
657 | }// for (i=0; i<aNbS; ++i) { |
658 | // |
4e57c75e |
659 | // 3. Some shapes of aMSI can be already tied with faces of |
660 | // split solids |
319da2e4 |
661 | aNbSI = aMSI.Extent(); |
662 | for (i = 1; i <= aNbSI; ++i) { |
663 | const TopoDS_Shape& aSI = aMSI(i); |
4e57c75e |
664 | if (aMSx.Contains(aSI)) { |
1155d05a |
665 | const TopTools_ListOfShape &aLSx=aMSx.FindFromKey(aSI); |
319da2e4 |
666 | aNbSx = aLSx.Extent(); |
667 | if (!aNbSx) { |
668 | aLSI.Append(aSI); |
4e57c75e |
669 | } |
670 | } |
319da2e4 |
671 | else { |
672 | aLSI.Append(aSI); |
673 | } |
4e57c75e |
674 | } |
675 | // |
676 | // 4. Just check it |
319da2e4 |
677 | aNbSI = aLSI.Extent(); |
4e57c75e |
678 | if (!aNbSI) { |
679 | return; |
680 | } |
681 | // |
682 | // 5 Settle internal vertices and edges into solids |
683 | aMx.Clear(); |
684 | aIt.Initialize(aLSd); |
685 | for (; aIt.More(); aIt.Next()) { |
686 | TopoDS_Solid aSd=TopoDS::Solid(aIt.Value()); |
687 | // |
319da2e4 |
688 | aIt1.Initialize(aLSI); |
689 | for (; aIt1.More();) { |
690 | TopoDS_Shape aSI = aIt1.Value(); |
4e57c75e |
691 | aSI.Orientation(TopAbs_INTERNAL); |
692 | // |
0090ae85 |
693 | aState=BOPTools_AlgoTools::ComputeStateByOnePoint |
694 | (aSI, aSd, 1.e-11, myContext); |
319da2e4 |
695 | // |
696 | if (aState != TopAbs_IN) { |
697 | aIt1.Next(); |
698 | continue; |
699 | } |
700 | // |
b18a83d4 |
701 | if (aMSOr.Contains(aSd)) { |
702 | // make new solid |
319da2e4 |
703 | TopoDS_Solid aSdx; |
704 | // |
705 | aBB.MakeSolid(aSdx); |
706 | aItS.Initialize(aSd); |
707 | for (; aItS.More(); aItS.Next()) { |
708 | const TopoDS_Shape& aSh=aItS.Value(); |
709 | aBB.Add(aSdx, aSh); |
4e57c75e |
710 | } |
319da2e4 |
711 | // |
712 | aBB.Add(aSdx, aSI); |
713 | // |
b18a83d4 |
714 | // no need to check for images of aSd as aMSOr contains only original solids |
1155d05a |
715 | TopTools_ListOfShape* pLS = myImages.Bound(aSd, TopTools_ListOfShape()); |
b18a83d4 |
716 | pLS->Append(aSdx); |
717 | // |
1155d05a |
718 | TopTools_ListOfShape* pLOr = myOrigins.Bound(aSdx, TopTools_ListOfShape()); |
b18a83d4 |
719 | pLOr->Append(aSd); |
4e57c75e |
720 | // |
319da2e4 |
721 | aMSOr.Remove(aSd); |
722 | aSd=aSdx; |
723 | } |
724 | else { |
725 | aBB.Add(aSd, aSI); |
726 | } |
727 | // |
728 | aLSI.Remove(aIt1); |
729 | }//for (; aIt1.More();) { |
730 | }//for (; aIt.More(); aIt.Next()) { |
4e57c75e |
731 | // |
732 | //-----------------------------------------------------scope t |
733 | aLArgs.Clear(); |
734 | aLSd.Clear(); |
735 | aMSOr.Clear(); |
736 | aMFence.Clear(); |
737 | aMSI.Clear(); |
738 | aMx.Clear(); |
739 | aMSx.Clear(); |
740 | } |
741 | //======================================================================= |
742 | //function : OwnInternalShapes |
743 | //purpose : |
744 | //======================================================================= |
a0a3f6ac |
745 | void OwnInternalShapes(const TopoDS_Shape& theS, |
1155d05a |
746 | TopTools_IndexedMapOfShape& theMx) |
4e57c75e |
747 | { |
748 | TopoDS_Iterator aIt; |
749 | // |
750 | aIt.Initialize(theS); |
751 | for (; aIt.More(); aIt.Next()) { |
752 | const TopoDS_Shape& aSx=aIt.Value(); |
753 | if (aSx.ShapeType()!=TopAbs_SHELL) { |
754 | theMx.Add(aSx); |
755 | } |
756 | } |
757 | } |