92ae0f2f |
1 | // Created by: Eugeny MALTCHIKOV |
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 | |
92ae0f2f |
15 | #include <Bnd_Box.hxx> |
42cf5bc1 |
16 | #include <BOPAlgo_BuilderSolid.hxx> |
17 | #include <BOPAlgo_MakerVolume.hxx> |
18 | #include <BOPAlgo_PaveFiller.hxx> |
977ad983 |
19 | #include <BOPAlgo_Tools.hxx> |
33ba8565 |
20 | #include <BOPAlgo_Alerts.hxx> |
92ae0f2f |
21 | #include <BOPDS_DS.hxx> |
92ae0f2f |
22 | #include <BOPTools_AlgoTools.hxx> |
42cf5bc1 |
23 | #include <BRepPrimAPI_MakeBox.hxx> |
1155d05a |
24 | #include <TopExp.hxx> |
42cf5bc1 |
25 | #include <TopExp_Explorer.hxx> |
26 | #include <TopoDS_Solid.hxx> |
1155d05a |
27 | #include <TopTools_ListOfShape.hxx> |
92ae0f2f |
28 | |
29 | static |
30 | void AddFace(const TopoDS_Shape& theF, |
1155d05a |
31 | TopTools_ListOfShape& theLF); |
92ae0f2f |
32 | |
b1d15f53 |
33 | //======================================================================= |
34 | //function : CheckData |
35 | //purpose : |
36 | //======================================================================= |
37 | void BOPAlgo_MakerVolume::CheckData() |
38 | { |
39 | if (myArguments.IsEmpty()) { |
33ba8565 |
40 | AddError (new BOPAlgo_AlertTooFewArguments); // no arguments to process |
b1d15f53 |
41 | return; |
42 | } |
43 | // |
33ba8565 |
44 | CheckFiller(); |
b1d15f53 |
45 | } |
46 | |
92ae0f2f |
47 | //======================================================================= |
48 | //function : Perform |
49 | //purpose : |
50 | //======================================================================= |
51 | void BOPAlgo_MakerVolume::Perform() |
52 | { |
33ba8565 |
53 | GetReport()->Clear(); |
92ae0f2f |
54 | // |
55 | if (myEntryPoint == 1) { |
56 | if (myPaveFiller) { |
57 | delete myPaveFiller; |
58 | myPaveFiller = NULL; |
59 | } |
60 | } |
61 | // |
488e5b9d |
62 | Handle(NCollection_BaseAllocator) aAllocator = |
63 | NCollection_BaseAllocator::CommonBaseAllocator(); |
92ae0f2f |
64 | BOPAlgo_PaveFiller* pPF = new BOPAlgo_PaveFiller(aAllocator); |
65 | // |
66 | if (!myIntersect) { |
67 | //if there is no need to intersect the arguments, then it is necessary |
68 | //to create the compound of them and use it as one argument |
69 | TopoDS_Compound anArgs; |
70 | BRep_Builder aBB; |
1155d05a |
71 | TopTools_ListIteratorOfListOfShape aIt; |
72 | TopTools_ListOfShape aLS; |
92ae0f2f |
73 | // |
74 | aBB.MakeCompound(anArgs); |
75 | aIt.Initialize(myArguments); |
76 | for (; aIt.More(); aIt.Next()) { |
77 | const TopoDS_Shape& aS = aIt.Value(); |
78 | aBB.Add(anArgs, aS); |
79 | } |
80 | aLS.Append(anArgs); |
81 | // |
82 | pPF->SetArguments(aLS); |
83 | } |
84 | else { |
85 | pPF->SetArguments(myArguments); |
86 | } |
87 | // |
88 | pPF->SetRunParallel(myRunParallel); |
b1d15f53 |
89 | pPF->SetProgressIndicator(myProgressIndicator); |
90 | pPF->SetFuzzyValue(myFuzzyValue); |
3510db62 |
91 | pPF->SetNonDestructive(myNonDestructive); |
483ce1bd |
92 | pPF->SetGlue(myGlue); |
944768d2 |
93 | pPF->SetUseOBB(myUseOBB); |
92ae0f2f |
94 | pPF->Perform(); |
95 | // |
96 | myEntryPoint = 1; |
97 | PerformInternal(*pPF); |
98 | } |
99 | |
100 | //======================================================================= |
101 | //function : PerformInternal1 |
102 | //purpose : |
103 | //======================================================================= |
104 | void BOPAlgo_MakerVolume::PerformInternal1 |
105 | (const BOPAlgo_PaveFiller& theFiller) |
106 | { |
92ae0f2f |
107 | myPaveFiller = (BOPAlgo_PaveFiller*)&theFiller; |
108 | myDS = myPaveFiller->PDS(); |
109 | myContext = myPaveFiller->Context(); |
110 | // |
111 | // 1. CheckData |
112 | CheckData(); |
33ba8565 |
113 | if (HasErrors()) { |
92ae0f2f |
114 | return; |
115 | } |
116 | // |
117 | // 2. Prepare |
118 | Prepare(); |
33ba8565 |
119 | if (HasErrors()) { |
92ae0f2f |
120 | return; |
121 | } |
122 | // |
123 | // 3. Fill Images |
124 | // 3.1. Vertice |
125 | if (myIntersect) { |
126 | FillImagesVertices(); |
33ba8565 |
127 | if (HasErrors()) { |
92ae0f2f |
128 | return; |
129 | } |
130 | // 3.2. Edges |
131 | FillImagesEdges(); |
33ba8565 |
132 | if (HasErrors()) { |
92ae0f2f |
133 | return; |
134 | } |
135 | // 3.3. Wires |
136 | FillImagesContainers(TopAbs_WIRE); |
33ba8565 |
137 | if (HasErrors()) { |
92ae0f2f |
138 | return; |
139 | } |
140 | // 3.4. Faces |
141 | FillImagesFaces(); |
33ba8565 |
142 | if (HasErrors()) { |
92ae0f2f |
143 | return; |
144 | } |
145 | } |
146 | // |
147 | // 4. Collect faces |
148 | CollectFaces(); |
33ba8565 |
149 | if (HasErrors()) { |
92ae0f2f |
150 | return; |
151 | } |
152 | // |
1155d05a |
153 | TopTools_MapOfShape aBoxFaces; |
154 | TopTools_ListOfShape aLSR; |
92ae0f2f |
155 | // |
156 | // 5. Create bounding box |
157 | MakeBox(aBoxFaces); |
158 | // |
159 | // 6. Make volumes |
160 | BuildSolids(aLSR); |
33ba8565 |
161 | if (HasErrors()) { |
92ae0f2f |
162 | return; |
163 | } |
164 | // |
165 | // 7. Treat the result |
166 | RemoveBox(aLSR, aBoxFaces); |
167 | // |
168 | // 8. Fill internal shapes |
169 | FillInternalShapes(aLSR); |
170 | // |
171 | // 9. Build Result |
172 | BuildShape(aLSR); |
173 | // |
174 | // 10. History |
175 | PrepareHistory(); |
176 | // |
177 | // 11. Post-treatment |
178 | PostTreat(); |
179 | } |
180 | |
181 | //======================================================================= |
182 | //function : CollectFaces |
183 | //purpose : |
184 | //======================================================================= |
185 | void BOPAlgo_MakerVolume::CollectFaces() |
186 | { |
187 | UserBreak(); |
188 | // |
189 | Standard_Integer i, aNbShapes; |
1155d05a |
190 | TopTools_ListIteratorOfListOfShape aIt; |
191 | TopTools_MapOfShape aMFence; |
92ae0f2f |
192 | // |
193 | aNbShapes = myDS->NbSourceShapes(); |
194 | for (i = 0; i < aNbShapes; ++i) { |
195 | const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); |
196 | if (aSI.ShapeType() != TopAbs_FACE) { |
197 | continue; |
198 | } |
199 | // |
200 | const Bnd_Box& aB = aSI.Box(); |
201 | myBBox.Add(aB); |
202 | // |
203 | const TopoDS_Shape& aF = aSI.Shape(); |
204 | if (myImages.IsBound(aF)) { |
1155d05a |
205 | const TopTools_ListOfShape& aLFIm = myImages.Find(aF); |
92ae0f2f |
206 | aIt.Initialize(aLFIm); |
207 | for (; aIt.More(); aIt.Next()) { |
208 | const TopoDS_Shape& aFIm = aIt.Value(); |
c45fefa7 |
209 | if (aMFence.Add(aFIm)) { |
210 | AddFace(aFIm, myFaces); |
211 | } |
92ae0f2f |
212 | } |
213 | } |
214 | else { |
215 | AddFace(aF, myFaces); |
216 | } |
217 | } |
218 | } |
219 | |
220 | //======================================================================= |
221 | //function : MakeBox |
222 | //purpose : |
223 | //======================================================================= |
1155d05a |
224 | void BOPAlgo_MakerVolume::MakeBox(TopTools_MapOfShape& theBoxFaces) |
92ae0f2f |
225 | { |
226 | UserBreak(); |
227 | // |
228 | Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, anExt; |
229 | // |
0f04f1e1 |
230 | anExt = sqrt(myBBox.SquareExtent()) * 0.5; |
92ae0f2f |
231 | myBBox.Enlarge(anExt); |
232 | myBBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); |
233 | // |
234 | gp_Pnt aPMin(aXmin, aYmin, aZmin), |
235 | aPMax(aXmax, aYmax, aZmax); |
236 | // |
237 | mySBox = BRepPrimAPI_MakeBox(aPMin, aPMax).Solid(); |
238 | // |
239 | TopExp_Explorer aExp(mySBox, TopAbs_FACE); |
240 | for (; aExp.More(); aExp.Next()) { |
241 | const TopoDS_Shape& aF = aExp.Current(); |
242 | myFaces.Append(aF); |
243 | theBoxFaces.Add(aF); |
244 | } |
245 | } |
246 | |
247 | //======================================================================= |
248 | //function : BuildSolids |
249 | //purpose : |
250 | //======================================================================= |
1155d05a |
251 | void BOPAlgo_MakerVolume::BuildSolids(TopTools_ListOfShape& theLSR) |
92ae0f2f |
252 | { |
253 | UserBreak(); |
254 | // |
255 | BOPAlgo_BuilderSolid aBS; |
256 | // |
92ae0f2f |
257 | aBS.SetShapes(myFaces); |
258 | aBS.SetRunParallel(myRunParallel); |
291fced1 |
259 | aBS.SetAvoidInternalShapes(myAvoidInternalShapes); |
92ae0f2f |
260 | aBS.Perform(); |
33ba8565 |
261 | if (aBS.HasErrors()) |
262 | { |
263 | AddError (new BOPAlgo_AlertSolidBuilderFailed); // SolidBuilder failed |
92ae0f2f |
264 | return; |
265 | } |
266 | // |
7f3408c8 |
267 | myReport->Merge(aBS.GetReport()); |
268 | // |
92ae0f2f |
269 | theLSR = aBS.Areas(); |
270 | } |
271 | |
272 | //======================================================================= |
273 | //function : TreatResult |
274 | //purpose : |
275 | //======================================================================= |
1155d05a |
276 | void BOPAlgo_MakerVolume::RemoveBox(TopTools_ListOfShape& theLSR, |
277 | const TopTools_MapOfShape& theBoxFaces) |
92ae0f2f |
278 | { |
279 | UserBreak(); |
280 | // |
1155d05a |
281 | TopTools_ListIteratorOfListOfShape aIt; |
92ae0f2f |
282 | TopExp_Explorer aExp; |
283 | Standard_Boolean bFound; |
284 | // |
285 | bFound = Standard_False; |
286 | aIt.Initialize(theLSR); |
287 | for (; aIt.More(); aIt.Next()) { |
288 | const TopoDS_Shape& aSR = aIt.Value(); |
289 | // |
290 | aExp.Init(aSR, TopAbs_FACE); |
291 | for (; aExp.More(); aExp.Next()) { |
292 | const TopoDS_Shape& aF = aExp.Current(); |
293 | if (theBoxFaces.Contains(aF)) { |
294 | bFound = Standard_True; |
295 | theLSR.Remove(aIt); |
296 | break; |
297 | } |
298 | } |
299 | if (bFound) { |
300 | break; |
301 | } |
302 | } |
303 | } |
304 | |
305 | //======================================================================= |
306 | //function : BuildShape |
307 | //purpose : |
308 | //======================================================================= |
1155d05a |
309 | void BOPAlgo_MakerVolume::BuildShape(const TopTools_ListOfShape& theLSR) |
92ae0f2f |
310 | { |
311 | if (theLSR.Extent() == 1) { |
312 | myShape = theLSR.First(); |
313 | } |
314 | else { |
315 | BRep_Builder aBB; |
1155d05a |
316 | TopTools_ListIteratorOfListOfShape aIt; |
92ae0f2f |
317 | // |
318 | aIt.Initialize(theLSR); |
319 | for (; aIt.More(); aIt.Next()) { |
320 | const TopoDS_Shape& aSol = aIt.Value(); |
321 | aBB.Add(myShape, aSol); |
322 | } |
323 | } |
324 | } |
325 | |
326 | //======================================================================= |
327 | //function : FillInternalShapes |
328 | //purpose : |
329 | //======================================================================= |
1155d05a |
330 | void BOPAlgo_MakerVolume::FillInternalShapes(const TopTools_ListOfShape& theLSR) |
92ae0f2f |
331 | { |
291fced1 |
332 | if (myAvoidInternalShapes) { |
333 | return; |
334 | } |
13c0e402 |
335 | |
92ae0f2f |
336 | UserBreak(); |
13c0e402 |
337 | |
338 | // Get all non-compound shapes |
339 | TopTools_ListOfShape aLSC; |
340 | // Fence map |
1155d05a |
341 | TopTools_MapOfShape aMFence; |
13c0e402 |
342 | |
343 | TopTools_ListOfShape::Iterator itLA(myDS->Arguments()); |
344 | for (; itLA.More(); itLA.Next()) |
345 | BOPAlgo_Tools::TreatCompound(itLA.Value(), aMFence, aLSC); |
346 | |
347 | // Get only edges and vertices from arguments |
348 | TopTools_ListOfShape aLVE; |
349 | |
350 | itLA.Initialize(aLSC); |
351 | for (; itLA.More(); itLA.Next()) |
352 | { |
353 | const TopoDS_Shape& aS = itLA.Value(); |
354 | TopAbs_ShapeEnum aType = aS.ShapeType(); |
355 | if (aType == TopAbs_WIRE) |
356 | { |
357 | for (TopoDS_Iterator it(aS); it.More(); it.Next()) |
358 | { |
359 | const TopoDS_Shape& aSS = it.Value(); |
360 | if (aMFence.Add(aSS)) |
361 | aLVE.Append(aSS); |
92ae0f2f |
362 | } |
363 | } |
13c0e402 |
364 | else if (aType == TopAbs_VERTEX || aType == TopAbs_EDGE) |
92ae0f2f |
365 | aLVE.Append(aS); |
92ae0f2f |
366 | } |
13c0e402 |
367 | |
368 | BOPAlgo_Tools::FillInternals(theLSR, aLVE, myImages, myContext); |
92ae0f2f |
369 | } |
370 | |
371 | //======================================================================= |
372 | //function : AddFace |
373 | //purpose : |
374 | //======================================================================= |
375 | void AddFace(const TopoDS_Shape& theF, |
1155d05a |
376 | TopTools_ListOfShape& theLF) |
92ae0f2f |
377 | { |
378 | TopoDS_Shape aFF = theF; |
379 | aFF.Orientation(TopAbs_FORWARD); |
380 | theLF.Append(aFF); |
381 | aFF.Orientation(TopAbs_REVERSED); |
382 | theLF.Append(aFF); |
383 | } |