1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 OPEN CASCADE SAS
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
7 // This file is part of Open CASCADE Technology software library.
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
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.
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
19 #include <BOPAlgo_PaveFiller.hxx>
20 #include <BOPAlgo_SectionAttribute.hxx>
21 #include <BOPAlgo_Alerts.hxx>
22 #include <BOPDS_DS.hxx>
23 #include <BOPDS_Iterator.hxx>
24 #include <IntTools_Context.hxx>
25 #include <NCollection_BaseAllocator.hxx>
26 #include <Standard_ErrorHandler.hxx>
27 #include <Standard_Failure.hxx>
31 //=======================================================================
32 //function : BOPAlgo_PIOperation
33 //purpose : List of operations to be supported by the Progress Indicator
34 //=======================================================================
35 enum BOPAlgo_PIOperation
37 PIOperation_Prepare = 0,
38 PIOperation_PerformVV,
39 PIOperation_PerformVE,
40 PIOperation_PerformEE,
41 PIOperation_PerformVF,
42 PIOperation_PerformEF,
43 PIOperation_RepeatIntersection,
44 PIOperation_ForceInterfEE,
45 PIOperation_ForceInterfEF,
46 PIOperation_PerformFF,
47 PIOperation_MakeSplitEdges,
48 PIOperation_MakeBlocks,
49 PIOperation_MakePCurves,
50 PIOperation_ProcessDE,
55 //=======================================================================
58 //=======================================================================
59 BOPAlgo_PaveFiller::BOPAlgo_PaveFiller()
65 myNonDestructive = Standard_False;
66 myIsPrimary = Standard_True;
67 myAvoidBuildPCurve = Standard_False;
68 myGlue = BOPAlgo_GlueOff;
70 //=======================================================================
73 //=======================================================================
74 BOPAlgo_PaveFiller::BOPAlgo_PaveFiller
75 (const Handle (NCollection_BaseAllocator)& theAllocator)
77 BOPAlgo_Algo (theAllocator),
78 myFPBDone (1, theAllocator),
79 myIncreasedSS (1, theAllocator),
80 myVertsToAvoidExtension (1, theAllocator),
81 myDistances (1, theAllocator)
85 myNonDestructive = Standard_False;
86 myIsPrimary = Standard_True;
87 myAvoidBuildPCurve = Standard_False;
88 myGlue = BOPAlgo_GlueOff;
90 //=======================================================================
93 //=======================================================================
94 BOPAlgo_PaveFiller::~BOPAlgo_PaveFiller()
98 //=======================================================================
99 //function : SetNonDestructive
101 //=======================================================================
102 void BOPAlgo_PaveFiller::SetNonDestructive (const Standard_Boolean bFlag)
104 myNonDestructive = bFlag;
106 //=======================================================================
107 //function : NonDestructive
109 //=======================================================================
110 Standard_Boolean BOPAlgo_PaveFiller::NonDestructive() const
112 return myNonDestructive;
114 //=======================================================================
117 //=======================================================================
118 void BOPAlgo_PaveFiller::SetGlue (const BOPAlgo_GlueEnum theGlue)
122 //=======================================================================
125 //=======================================================================
126 BOPAlgo_GlueEnum BOPAlgo_PaveFiller::Glue() const
130 //=======================================================================
131 //function : SetIsPrimary
133 //=======================================================================
134 void BOPAlgo_PaveFiller::SetIsPrimary (const Standard_Boolean bFlag)
138 //=======================================================================
139 //function : IsPrimary
141 //=======================================================================
142 Standard_Boolean BOPAlgo_PaveFiller::IsPrimary() const
146 //=======================================================================
149 //=======================================================================
150 void BOPAlgo_PaveFiller::Clear()
152 BOPAlgo_Algo::Clear();
161 myIncreasedSS.Clear();
163 //=======================================================================
166 //=======================================================================
167 const BOPDS_DS& BOPAlgo_PaveFiller::DS()
171 //=======================================================================
174 //=======================================================================
175 BOPDS_PDS BOPAlgo_PaveFiller::PDS()
179 //=======================================================================
182 //=======================================================================
183 const Handle (IntTools_Context)& BOPAlgo_PaveFiller::Context()
187 //=======================================================================
188 //function : SectionAttribute
190 //=======================================================================
191 void BOPAlgo_PaveFiller::SetSectionAttribute
192 (const BOPAlgo_SectionAttribute& theSecAttr)
194 mySectionAttribute = theSecAttr;
196 //=======================================================================
199 //=======================================================================
200 void BOPAlgo_PaveFiller::Init (const Message_ProgressRange& theRange)
202 if (!myArguments.Extent()) {
203 AddError (new BOPAlgo_AlertTooFewArguments);
207 Message_ProgressScope aPS (theRange, "Initialization of Intersection algorithm", 1);
208 TopTools_ListIteratorOfListOfShape aIt (myArguments);
209 for (; aIt.More(); aIt.Next()) {
210 if (aIt.Value().IsNull()) {
211 AddError (new BOPAlgo_AlertNullInputShapes);
220 myDS = new BOPDS_DS (myAllocator);
221 myDS->SetArguments (myArguments);
222 myDS->Init (myFuzzyValue);
225 myContext = new IntTools_Context;
228 myIterator = new BOPDS_Iterator (myAllocator);
229 myIterator->SetRunParallel (myRunParallel);
230 myIterator->SetDS (myDS);
231 myIterator->Prepare (myContext, myUseOBB, myFuzzyValue);
233 // 4 NonDestructive flag
237 //=======================================================================
240 //=======================================================================
241 void BOPAlgo_PaveFiller::Perform (const Message_ProgressRange& theRange)
246 PerformInternal (theRange);
249 catch (Standard_Failure const&) {
250 AddError (new BOPAlgo_AlertIntersectionFailed);
254 //=======================================================================
255 // function: PerformInternal
257 //=======================================================================
258 void BOPAlgo_PaveFiller::PerformInternal (const Message_ProgressRange& theRange)
260 Message_ProgressScope aPS (theRange, "Performing intersection of shapes", 100);
267 // Compute steps of the PI
268 BOPAlgo_PISteps aSteps (PIOperation_Last);
269 analyzeProgress (95, aSteps);
271 Prepare (aPS.Next (aSteps.GetStep (PIOperation_Prepare)));
276 PerformVV (aPS.Next (aSteps.GetStep (PIOperation_PerformVV)));
281 PerformVE (aPS.Next (aSteps.GetStep (PIOperation_PerformVE)));
286 UpdatePaveBlocksWithSDVertices();
288 PerformEE (aPS.Next (aSteps.GetStep (PIOperation_PerformEE)));
292 UpdatePaveBlocksWithSDVertices();
294 PerformVF (aPS.Next (aSteps.GetStep (PIOperation_PerformVF)));
298 UpdatePaveBlocksWithSDVertices();
300 PerformEF (aPS.Next (aSteps.GetStep (PIOperation_PerformEF)));
304 UpdatePaveBlocksWithSDVertices();
305 UpdateInterfsWithSDVertices();
307 // Repeat Intersection with increased vertices
308 RepeatIntersection (aPS.Next (aSteps.GetStep (PIOperation_RepeatIntersection)));
311 // Force intersection of edges after increase
312 // of the tolerance values of their vertices
313 ForceInterfEE (aPS.Next (aSteps.GetStep (PIOperation_ForceInterfEE)));
318 // Force Edge/Face intersection after increase
319 // of the tolerance values of their vertices
320 ForceInterfEF (aPS.Next (aSteps.GetStep (PIOperation_ForceInterfEF)));
327 PerformFF (aPS.Next (aSteps.GetStep (PIOperation_PerformFF)));
332 UpdateBlocksWithSharedVertices();
334 myDS->RefineFaceInfoIn();
336 MakeSplitEdges (aPS.Next (aSteps.GetStep (PIOperation_MakeSplitEdges)));
341 UpdatePaveBlocksWithSDVertices();
343 MakeBlocks (aPS.Next (aSteps.GetStep (PIOperation_MakeBlocks)));
348 CheckSelfInterference();
350 UpdateInterfsWithSDVertices();
351 myDS->ReleasePaveBlocks();
352 myDS->RefineFaceInfoOn();
356 MakePCurves (aPS.Next (aSteps.GetStep (PIOperation_MakePCurves)));
361 ProcessDE (aPS.Next (aSteps.GetStep (PIOperation_ProcessDE)));
367 //=======================================================================
368 // function: RepeatIntersection
370 //=======================================================================
371 void BOPAlgo_PaveFiller::RepeatIntersection (const Message_ProgressRange& theRange)
373 // Find all vertices with increased tolerance
374 TColStd_MapOfInteger anExtraInterfMap;
375 const Standard_Integer aNbS = myDS->NbSourceShapes();
376 Message_ProgressScope aPS (theRange, "Repeat intersection", 3);
377 for (Standard_Integer i = 0; i < aNbS; ++i)
379 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo (i);
380 if (aSI.ShapeType() != TopAbs_VERTEX)
382 // Check if the tolerance of the original vertex has been increased
383 if (myIncreasedSS.Contains (i))
385 anExtraInterfMap.Add (i);
389 // Check if the vertex created a new vertex with greater tolerance
390 Standard_Integer nVSD;
391 if (!myDS->HasShapeSD (i, nVSD))
394 if (myIncreasedSS.Contains (nVSD))
395 anExtraInterfMap.Add (i);
398 if (anExtraInterfMap.IsEmpty())
401 // Update iterator of pairs of shapes with interfering boxes
402 myIterator->IntersectExt (anExtraInterfMap);
404 // Perform intersections with vertices
406 PerformVV (aPS.Next());
409 UpdatePaveBlocksWithSDVertices();
411 PerformVE (aPS.Next());
414 UpdatePaveBlocksWithSDVertices();
416 PerformVF (aPS.Next());
420 UpdatePaveBlocksWithSDVertices();
421 UpdateInterfsWithSDVertices();
425 //=======================================================================
426 // function: fillPISteps
428 //=======================================================================
429 void BOPAlgo_PaveFiller::fillPIConstants (const Standard_Real theWhole,
430 BOPAlgo_PISteps& theSteps) const
432 if (!myNonDestructive)
434 theSteps.SetStep (PIOperation_Prepare, 1 * theWhole / 100.);
438 //=======================================================================
439 // function: fillPISteps
441 //=======================================================================
442 void BOPAlgo_PaveFiller::fillPISteps (BOPAlgo_PISteps& theSteps) const
444 // Get number of all intersecting pairs
445 Standard_Integer aVVSize = 0, aVESize = 0, aEESize = 0, aVFSize = 0, aEFSize = 0, aFFSize = 0;
447 myIterator->Initialize (TopAbs_VERTEX, TopAbs_VERTEX);
448 aVVSize = myIterator->ExpectedLength();
450 myIterator->Initialize (TopAbs_VERTEX, TopAbs_EDGE);
451 aVESize = myIterator->ExpectedLength();
453 myIterator->Initialize (TopAbs_EDGE, TopAbs_EDGE);
454 aEESize = myIterator->ExpectedLength();
456 myIterator->Initialize (TopAbs_VERTEX, TopAbs_FACE);
457 aVFSize = myIterator->ExpectedLength();
459 if (myGlue != BOPAlgo_GlueFull)
461 myIterator->Initialize (TopAbs_EDGE, TopAbs_FACE);
462 aEFSize = myIterator->ExpectedLength();
465 myIterator->Initialize (TopAbs_FACE, TopAbs_FACE);
466 aFFSize = myIterator->ExpectedLength();
468 theSteps.SetStep (PIOperation_PerformVV, aVVSize);
469 theSteps.SetStep (PIOperation_PerformVE, 2 * aVESize);
470 theSteps.SetStep (PIOperation_PerformEE, 5 * aEESize);
471 theSteps.SetStep (PIOperation_PerformVF, 5 * aVFSize);
472 theSteps.SetStep (PIOperation_PerformEF, 10 * aEFSize);
473 theSteps.SetStep (PIOperation_RepeatIntersection, 0.2 * (aVVSize + aVESize + aVFSize));
474 theSteps.SetStep (PIOperation_ForceInterfEE, 2 * aEESize);
475 theSteps.SetStep (PIOperation_ForceInterfEF, 2 * aEFSize);
476 theSteps.SetStep (PIOperation_PerformFF, (myGlue == BOPAlgo_GlueFull ? 1 : 30) * aFFSize);
477 theSteps.SetStep (PIOperation_MakeSplitEdges, aEESize);
478 theSteps.SetStep (PIOperation_MakeBlocks, (myGlue == BOPAlgo_GlueFull ? 0 : 5) * aFFSize);
479 theSteps.SetStep (PIOperation_MakePCurves, myAvoidBuildPCurve ? 0 : 0.2 * (aEESize + aEFSize));
480 theSteps.SetStep (PIOperation_ProcessDE, 0.1 * aEESize);