0030618: Modeling Algorithms, BOPTools_Parallel - avoid using map for thread-local...
[occt.git] / src / BOPAlgo / BOPAlgo_Builder_3.cxx
CommitLineData
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 67static
68 void OwnInternalShapes(const TopoDS_Shape& ,
1155d05a 69 TopTools_IndexedMapOfShape& );
4e57c75e 70
98b37659 71
4e57c75e 72//=======================================================================
73//function : FillImagesSolids
74//purpose :
75//=======================================================================
744511c8 76void 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 108void 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 236void 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//=======================================================================
329class BOPAlgo_SplitSolid : public BOPAlgo_BuilderSolid
330{
331public:
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
338private:
339 TopoDS_Solid mySolid; //!< Solid to split
340};
341
b7cd7c2b 342// Vector of Solid Builders
7f3408c8 343typedef NCollection_Vector<BOPAlgo_SplitSolid> BOPAlgo_VectorOfBuilderSolid;
b7cd7c2b 344
4e57c75e 345//=======================================================================
346//function : BuildSplitSolids
347//purpose :
348//=======================================================================
13c0e402 349void 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 521void 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 745void 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}