0025748: Parallel version of progress indicator
[occt.git] / src / BRepAlgoAPI / BRepAlgoAPI_BuilderAlgo.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15
16 #include <BRepAlgoAPI_BuilderAlgo.hxx>
17
18 #include <BOPAlgo_Builder.hxx>
19 #include <BOPAlgo_PaveFiller.hxx>
20 #include <BOPDS_DS.hxx>
21 #include <ShapeUpgrade_UnifySameDomain.hxx>
22 #include <TopoDS_Shape.hxx>
23
24 //=======================================================================
25 // function: BRepAlgoAPI_BuilderAlgo
26 // purpose: 
27 //=======================================================================
28 BRepAlgoAPI_BuilderAlgo::BRepAlgoAPI_BuilderAlgo()
29 :
30   BRepAlgoAPI_Algo(),
31   myNonDestructive(Standard_False),
32   myGlue(BOPAlgo_GlueOff),
33   myCheckInverted(Standard_True),
34   myFillHistory(Standard_True),
35   myIsIntersectionNeeded(Standard_True),
36   myDSFiller(NULL),
37   myBuilder(NULL)
38 {}
39 //=======================================================================
40 // function: BRepAlgoAPI_BuilderAlgo
41 // purpose: 
42 //=======================================================================
43 BRepAlgoAPI_BuilderAlgo::BRepAlgoAPI_BuilderAlgo(const BOPAlgo_PaveFiller& aPF)
44 :
45   BRepAlgoAPI_Algo(),
46   myNonDestructive(Standard_False),
47   myGlue(BOPAlgo_GlueOff),
48   myCheckInverted(Standard_True),
49   myFillHistory(Standard_True),
50   myIsIntersectionNeeded(Standard_False),
51   myBuilder(NULL)
52 {
53   myDSFiller = (BOPAlgo_PaveFiller*)&aPF;
54 }
55 //=======================================================================
56 // function: ~
57 // purpose: 
58 //=======================================================================
59 BRepAlgoAPI_BuilderAlgo::~BRepAlgoAPI_BuilderAlgo()
60 {
61   Clear();
62 }
63 //=======================================================================
64 //function : Clear
65 //purpose  : 
66 //=======================================================================
67 void BRepAlgoAPI_BuilderAlgo::Clear()
68 {
69   BRepAlgoAPI_Algo::Clear();
70   if (myDSFiller && myIsIntersectionNeeded)
71   {
72     delete myDSFiller;
73     myDSFiller = NULL;
74   }
75   if (myBuilder)
76   {
77     delete myBuilder;
78     myBuilder=NULL;
79   }
80   if (myHistory)
81     myHistory.Nullify();
82
83   if (mySimplifierHistory)
84     mySimplifierHistory.Nullify();
85 }
86 //=======================================================================
87 //function : Build
88 //purpose  : 
89 //=======================================================================
90 void BRepAlgoAPI_BuilderAlgo::Build()
91 {
92   // Setting not done status
93   NotDone();
94   // Destroy the tools if necessary
95   Clear();
96   // If necessary perform intersection of the argument shapes
97   IntersectShapes(myArguments);
98   if (HasErrors())
99     return;
100
101   // Initialization of the Building tool
102   myBuilder = new BOPAlgo_Builder(myAllocator);
103   // Set arguments to builder
104   myBuilder->SetArguments(myArguments);
105
106   // Build the result basing on intersection results
107   BuildResult();
108 }
109
110 //=======================================================================
111 //function : IntersectShapes
112 //purpose  : Intersects the given shapes with the intersection tool
113 //=======================================================================
114 void BRepAlgoAPI_BuilderAlgo::IntersectShapes(const TopTools_ListOfShape& theArgs)
115 {
116   if (!myIsIntersectionNeeded)
117     return;
118
119   if (myDSFiller)
120     delete myDSFiller;
121
122   // Create new Filler
123   myDSFiller = new BOPAlgo_PaveFiller(myAllocator);
124   // Set arguments for intersection
125   myDSFiller->SetArguments(theArgs);
126   // Set options for intersection
127   myDSFiller->SetRunParallel(myRunParallel);
128   myDSFiller->SetProgressIndicator(*myProgressScope);
129   myDSFiller->SetFuzzyValue(myFuzzyValue);
130   myDSFiller->SetNonDestructive(myNonDestructive);
131   myDSFiller->SetGlue(myGlue);
132   myDSFiller->SetUseOBB(myUseOBB);
133   // Set Face/Face intersection options to the intersection algorithm
134   SetAttributes();
135   // Perform intersection
136   myDSFiller->Perform();
137   // Check for the errors during intersection
138   GetReport()->Merge(myDSFiller->GetReport());
139 }
140 //=======================================================================
141 //function : BuildResult
142 //purpose  : Builds the result shape
143 //=======================================================================
144 void BRepAlgoAPI_BuilderAlgo::BuildResult()
145 {
146   // Set options to the builder
147   myBuilder->SetRunParallel(myRunParallel);
148   myBuilder->SetProgressIndicator(*myProgressScope);
149   myBuilder->SetCheckInverted(myCheckInverted);
150   myBuilder->SetToFillHistory(myFillHistory);
151   // Perform building of the result with pre-calculated intersections
152   myBuilder->PerformWithFiller(*myDSFiller);
153   // Merge the warnings of the Building part
154   GetReport()->Merge(myBuilder->GetReport());
155   // Check for the errors
156   if (myBuilder->HasErrors())
157     return;
158   // Set done status
159   Done();
160   // Get the result shape
161   myShape = myBuilder->Shape();
162   // Fill history
163   if (myFillHistory)
164   {
165     myHistory = new BRepTools_History;
166     myHistory->Merge(myBuilder->History());
167   }
168 }
169 //=======================================================================
170 //function : SimplifyResult
171 //purpose  : 
172 //=======================================================================
173 void BRepAlgoAPI_BuilderAlgo::SimplifyResult(const Standard_Boolean theUnifyEdges,
174                                              const Standard_Boolean theUnifyFaces,
175                                              const Standard_Real    theAngularTol)
176 {
177   if (HasErrors())
178     return;
179
180   if (!theUnifyEdges && !theUnifyFaces)
181     return;
182
183   // Simplification tool
184   ShapeUpgrade_UnifySameDomain anUnifier(myShape, theUnifyEdges, theUnifyFaces, Standard_True);
185   // Pass options
186   anUnifier.SetLinearTolerance(myFuzzyValue);
187   anUnifier.SetAngularTolerance(theAngularTol);
188   anUnifier.SetSafeInputMode(myNonDestructive);
189   anUnifier.AllowInternalEdges(Standard_False);
190   // Perform simplification
191   anUnifier.Build();
192   // Overwrite result with simplified shape
193   myShape = anUnifier.Shape();
194   // Keep simplification history
195   mySimplifierHistory = anUnifier.History();
196   if (myFillHistory)
197     // Merge simplification history into result history
198     myHistory->Merge(mySimplifierHistory);
199 }
200 //=======================================================================
201 //function : Modified
202 //purpose  : 
203 //=======================================================================
204 const TopTools_ListOfShape& BRepAlgoAPI_BuilderAlgo::Modified(const TopoDS_Shape& theS)
205 {
206   if (myFillHistory && myHistory)
207     return myHistory->Modified(theS);
208   myGenerated.Clear();
209   return myGenerated;
210 }
211 //=======================================================================
212 //function : Generated
213 //purpose  : 
214 //=======================================================================
215 const TopTools_ListOfShape& BRepAlgoAPI_BuilderAlgo::Generated(const TopoDS_Shape& theS)
216 {
217   if (myFillHistory && myHistory)
218     return myHistory->Generated(theS);
219   myGenerated.Clear();
220   return myGenerated;
221 }
222 //=======================================================================
223 //function : IsDeleted
224 //purpose  : 
225 //=======================================================================
226 Standard_Boolean BRepAlgoAPI_BuilderAlgo::IsDeleted(const TopoDS_Shape& theS)
227 {
228   return (myFillHistory && myHistory ? myHistory->IsRemoved(theS) : Standard_False);
229 }
230 //=======================================================================
231 //function : HasModified
232 //purpose  : 
233 //=======================================================================
234 Standard_Boolean BRepAlgoAPI_BuilderAlgo::HasModified() const
235 {
236   return (myFillHistory && myHistory ? myHistory->HasModified() : Standard_False);
237 }
238 //=======================================================================
239 //function : HasGenerated
240 //purpose  : 
241 //=======================================================================
242 Standard_Boolean BRepAlgoAPI_BuilderAlgo::HasGenerated() const
243 {
244   return (myFillHistory && myHistory ? myHistory->HasGenerated() : Standard_False);
245 }
246 //=======================================================================
247 //function : HasDeleted
248 //purpose  : 
249 //=======================================================================
250 Standard_Boolean BRepAlgoAPI_BuilderAlgo::HasDeleted() const
251 {
252   return (myFillHistory && myHistory ? myHistory->HasRemoved() : Standard_False);
253 }
254 //=======================================================================
255 //function : SectionEdges
256 //purpose  : 
257 //=======================================================================
258 const TopTools_ListOfShape& BRepAlgoAPI_BuilderAlgo::SectionEdges()
259 {
260   myGenerated.Clear();
261   if (myBuilder == NULL)
262     return myGenerated;
263
264   // Fence map to avoid duplicated section edges in the result list
265   TopTools_MapOfShape aMFence;
266   // Intersection results
267   const BOPDS_PDS& pDS = myDSFiller->PDS();
268   // Iterate on all Face/Face interferences and take section edges
269   BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF();
270   const Standard_Integer aNbFF = aFFs.Length();
271   for (Standard_Integer i = 0; i < aNbFF; ++i)
272   {
273     BOPDS_InterfFF& aFFi = aFFs(i);
274     // Section curves between pair of faces
275     const BOPDS_VectorOfCurve& aSectionCurves = aFFi.Curves();
276     const Standard_Integer aNbC = aSectionCurves.Length();
277     for (Standard_Integer j = 0; j < aNbC; ++j)
278     {
279       const BOPDS_Curve& aCurve = aSectionCurves(j);
280       // Section edges created from the curve
281       const BOPDS_ListOfPaveBlock& aSectionEdges = aCurve.PaveBlocks();
282       BOPDS_ListIteratorOfListOfPaveBlock aItPB(aSectionEdges);
283       for (; aItPB.More(); aItPB.Next())
284       {
285         const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
286         const TopoDS_Shape& aSE = pDS->Shape(aPB->Edge());
287         if (!aMFence.Add(aSE))
288           continue;
289         // Take into account simplification of the result shape
290         if (mySimplifierHistory)
291         {
292           if (mySimplifierHistory->IsRemoved(aSE))
293             continue;
294
295           const TopTools_ListOfShape& aLSEIm = mySimplifierHistory->Modified(aSE);
296           if (!aLSEIm.IsEmpty())
297           {
298             TopTools_ListIteratorOfListOfShape aItLEIm(aLSEIm);
299             for (; aItLEIm.More(); aItLEIm.Next())
300             {
301               if (aMFence.Add(aItLEIm.Value()))
302                 myGenerated.Append(aItLEIm.Value());
303             }
304           }
305           else
306             myGenerated.Append(aSE);
307         }
308         else
309           myGenerated.Append(aSE);
310       }
311     }
312   }
313   return myGenerated;
314 }