0c09fd3c |
1 | // Created on: 2018-03-29 |
2 | // Created by: Eugeny MALTCHIKOV |
3 | // Copyright (c) 2018 OPEN CASCADE SAS |
4 | // |
5 | // This file is part of Open CASCADE Technology software library. |
6 | // |
7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
11 | // distribution for complete text of the license and disclaimer of any warranty. |
12 | // |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
15 | |
16 | #include <BOPAlgo_MakeConnected.hxx> |
17 | |
18 | #include <BOPAlgo_Alerts.hxx> |
19 | #include <BOPAlgo_Builder.hxx> |
20 | #include <BOPAlgo_Tools.hxx> |
21 | |
22 | #include <BOPTools_AlgoTools.hxx> |
23 | |
24 | #include <BRep_Builder.hxx> |
25 | |
26 | #include <TopExp_Explorer.hxx> |
27 | |
28 | #include <TopoDS_Iterator.hxx> |
29 | |
30 | //======================================================================= |
31 | //function : Perform |
32 | //purpose : Makes the shapes connected |
33 | //======================================================================= |
34 | void BOPAlgo_MakeConnected::Perform() |
35 | { |
36 | // Check the input data |
37 | CheckData(); |
38 | if (HasErrors()) |
39 | return; |
40 | |
41 | if (myHistory.IsNull()) |
42 | myHistory = new BRepTools_History; |
43 | |
44 | // Glue the arguments |
45 | MakeConnected(); |
46 | if (HasErrors()) |
47 | return; |
48 | |
49 | // Perform material associations for the faces |
50 | AssociateMaterials(); |
51 | if (HasErrors()) |
52 | return; |
53 | } |
54 | |
55 | //======================================================================= |
56 | //function : CheckData |
57 | //purpose : Check the validity of input data |
58 | //======================================================================= |
59 | void BOPAlgo_MakeConnected::CheckData() |
60 | { |
61 | // Check the number of arguments |
62 | if (myArguments.IsEmpty()) |
63 | { |
64 | // Not enough arguments |
65 | AddError(new BOPAlgo_AlertTooFewArguments()); |
66 | return; |
67 | } |
68 | |
69 | // Check that all shapes in arguments are of the same type |
70 | |
71 | // Extract the shapes from the compound arguments |
72 | TopTools_ListOfShape aLA; |
73 | // Fence map |
74 | TopTools_MapOfShape aMFence; |
75 | |
76 | TopTools_ListIteratorOfListOfShape itLA(myArguments); |
77 | for (; itLA.More(); itLA.Next()) |
739c7e59 |
78 | BOPTools_AlgoTools::TreatCompound(itLA.Value(), aLA, &aMFence); |
0c09fd3c |
79 | |
80 | if (aLA.IsEmpty()) |
81 | { |
82 | // It seems that all argument shapes are empty compounds |
83 | AddError(new BOPAlgo_AlertTooFewArguments()); |
84 | return; |
85 | } |
86 | |
87 | // Check dimensions of the extracted non-compound shapes |
88 | itLA.Initialize(aLA); |
89 | Standard_Integer iDim = BOPTools_AlgoTools::Dimension(itLA.Value()); |
90 | for (itLA.Next(); itLA.More(); itLA.Next()) |
91 | { |
92 | if (iDim != BOPTools_AlgoTools::Dimension(itLA.Value())) |
93 | { |
94 | // The arguments are of different type |
95 | AddError(new BOPAlgo_AlertMultiDimensionalArguments()); |
96 | return; |
97 | } |
98 | } |
99 | } |
100 | |
101 | //======================================================================= |
102 | //function : MakeConnected |
103 | //purpose : Glues the argument shapes |
104 | //======================================================================= |
105 | void BOPAlgo_MakeConnected::MakeConnected() |
106 | { |
107 | // Initialize the history |
108 | if (myGlueHistory.IsNull()) |
109 | myGlueHistory = new BRepTools_History; |
110 | |
111 | if (myArguments.Extent() == 1) |
112 | { |
113 | // No need to glue the single shape |
114 | myShape = myArguments.First(); |
115 | } |
116 | else |
117 | { |
118 | // Glue the shapes |
119 | BOPAlgo_Builder aGluer; |
120 | aGluer.SetArguments(myArguments); |
121 | aGluer.SetGlue(BOPAlgo_GlueShift); |
122 | aGluer.SetRunParallel(myRunParallel); |
123 | aGluer.SetNonDestructive(Standard_True); |
124 | aGluer.Perform(); |
125 | if (aGluer.HasErrors()) |
126 | { |
127 | // Unable to glue the shapes |
128 | TopoDS_Compound aCW; |
129 | BRep_Builder().MakeCompound(aCW); |
130 | for (TopTools_ListIteratorOfListOfShape it(myArguments); it.More(); it.Next()) |
131 | BRep_Builder().Add(aCW, it.Value()); |
132 | AddError(new BOPAlgo_AlertUnableToGlue(aCW)); |
133 | return; |
134 | } |
135 | myShape = aGluer.Shape(); |
136 | // Save the gluing history |
137 | myGlueHistory->Merge(aGluer.Arguments(), aGluer); |
138 | myHistory->Merge(myGlueHistory); |
139 | } |
140 | |
141 | // Keep the glued shape |
142 | myGlued = myShape; |
143 | |
144 | // Fill the map of origins |
145 | FillOrigins(); |
146 | } |
147 | |
148 | //======================================================================= |
149 | //function : FillOrigins |
150 | //purpose : Fills the map of origins |
151 | //======================================================================= |
152 | void BOPAlgo_MakeConnected::FillOrigins() |
153 | { |
154 | myOrigins.Clear(); |
155 | |
156 | // Map the history shapes of the arguments |
157 | if (myAllInputsMap.IsEmpty()) |
158 | { |
159 | TopTools_ListIteratorOfListOfShape itLA(myArguments); |
160 | for (; itLA.More(); itLA.Next()) |
161 | TopExp::MapShapes(itLA.Value(), myAllInputsMap); |
162 | } |
163 | |
164 | const Standard_Integer aNbS = myAllInputsMap.Extent(); |
165 | for (Standard_Integer i = 1; i <= aNbS; ++i) |
166 | { |
167 | const TopoDS_Shape& aS = myAllInputsMap(i); |
168 | if (!BRepTools_History::IsSupportedType(aS)) |
169 | continue; |
170 | |
171 | // Get Modified & Generated shapes |
172 | for (Standard_Integer j = 0; j < 2; ++j) |
173 | { |
174 | const TopTools_ListOfShape& aLH = !j ? myHistory->Modified(aS) : myHistory->Generated(aS); |
175 | TopTools_ListIteratorOfListOfShape itLH(aLH); |
176 | for (; itLH.More(); itLH.Next()) |
177 | { |
178 | const TopoDS_Shape& aHS = itLH.Value(); |
179 | TopTools_ListOfShape* pLOr = myOrigins.ChangeSeek(aHS); |
180 | if (!pLOr) |
181 | pLOr = myOrigins.Bound(aHS, TopTools_ListOfShape()); |
182 | if (!pLOr->Contains(aS)) |
183 | pLOr->Append(aS); |
184 | } |
185 | } |
186 | } |
187 | } |
188 | |
189 | //======================================================================= |
190 | //function : AssociateMaterials |
191 | //purpose : Associates the materials for the border elements |
192 | //======================================================================= |
193 | void BOPAlgo_MakeConnected::AssociateMaterials() |
194 | { |
195 | myMaterials.Clear(); |
196 | |
197 | // Extract all non-compound shapes from the result |
198 | TopTools_ListOfShape aLShapes; |
199 | TopTools_MapOfShape aMFence; |
739c7e59 |
200 | BOPTools_AlgoTools::TreatCompound(myShape, aLShapes, &aMFence); |
0c09fd3c |
201 | |
202 | if (aLShapes.IsEmpty()) |
203 | return; |
204 | |
205 | // Define the element type and the material type |
206 | TopAbs_ShapeEnum anElemType; |
207 | const TopAbs_ShapeEnum aMaterialType = aLShapes.First().ShapeType(); |
208 | if (aMaterialType == TopAbs_SOLID || aMaterialType == TopAbs_COMPSOLID) |
209 | anElemType = TopAbs_FACE; |
210 | else if (aMaterialType == TopAbs_FACE || aMaterialType == TopAbs_SHELL) |
211 | anElemType = TopAbs_EDGE; |
212 | else if (aMaterialType == TopAbs_EDGE || aMaterialType == TopAbs_WIRE) |
213 | anElemType = TopAbs_VERTEX; |
214 | else |
215 | return; |
216 | |
217 | TopTools_ListIteratorOfListOfShape itLS(aLShapes); |
218 | for (; itLS.More(); itLS.Next()) |
219 | { |
220 | const TopoDS_Shape& aS = itLS.Value(); |
221 | const TopTools_ListOfShape& aLOr = GetOrigins(aS); |
222 | const TopoDS_Shape& aSOr = aLOr.IsEmpty() ? aS : aLOr.First(); |
223 | |
224 | TopExp_Explorer anExp(aS, anElemType); |
225 | for (; anExp.More(); anExp.Next()) |
226 | { |
227 | const TopoDS_Shape& anElement = anExp.Current(); |
228 | TopTools_ListOfShape* pLM = myMaterials.ChangeSeek(anElement); |
229 | if (!pLM) |
230 | pLM = myMaterials.Bound(anElement, TopTools_ListOfShape()); |
231 | pLM->Append(aSOr); |
232 | } |
233 | } |
234 | } |
235 | |
236 | //======================================================================= |
237 | //function : Update |
238 | //purpose : Updates the history, material associations and origins map |
239 | // after periodicity operations |
240 | //======================================================================= |
241 | void BOPAlgo_MakeConnected::Update() |
242 | { |
243 | // Update history |
244 | myHistory->Clear(); |
245 | if (!myGlueHistory.IsNull()) |
246 | myHistory->Merge(myGlueHistory); |
247 | if (!myPeriodicityMaker.History().IsNull()) |
248 | myHistory->Merge(myPeriodicityMaker.History()); |
249 | |
250 | // Fill the map of origins |
251 | FillOrigins(); |
252 | |
253 | // Update the material associations after making the shape periodic |
254 | AssociateMaterials(); |
255 | } |
256 | |
257 | //======================================================================= |
258 | //function : MakePeriodic |
259 | //purpose : Makes the shape periodic according to the given parameters |
260 | //======================================================================= |
261 | void BOPAlgo_MakeConnected::MakePeriodic(const BOPAlgo_MakePeriodic::PeriodicityParams& theParams) |
262 | { |
263 | if (HasErrors()) |
264 | return; |
265 | |
266 | // Make the shape periodic |
267 | myPeriodicityMaker.Clear(); |
268 | myPeriodicityMaker.SetShape(myGlued); |
269 | myPeriodicityMaker.SetPeriodicityParameters(theParams); |
270 | myPeriodicityMaker.SetRunParallel(myRunParallel); |
271 | myPeriodicityMaker.Perform(); |
272 | if (myPeriodicityMaker.HasErrors()) |
273 | { |
274 | // Add warning informing the user that periodicity with |
275 | // given parameters is not possible |
276 | AddWarning(new BOPAlgo_AlertUnableToMakePeriodic(myShape)); |
277 | return; |
278 | } |
279 | |
280 | myShape = myPeriodicityMaker.Shape(); |
281 | |
282 | // Update history, materials, origins |
283 | Update(); |
284 | } |
285 | |
286 | //======================================================================= |
287 | //function : RepeatShape |
288 | //purpose : Repeats the shape in the given direction given number of times |
289 | //======================================================================= |
290 | void BOPAlgo_MakeConnected::RepeatShape(const Standard_Integer theDirectionID, |
291 | const Standard_Integer theTimes) |
292 | { |
293 | if (HasErrors()) |
294 | return; |
295 | |
296 | if (myPeriodicityMaker.Shape().IsNull() || myPeriodicityMaker.HasErrors()) |
297 | { |
298 | // The shape has not been made periodic yet |
299 | AddWarning(new BOPAlgo_AlertShapeIsNotPeriodic(myShape)); |
300 | return; |
301 | } |
302 | |
303 | // Repeat the shape |
304 | myShape = myPeriodicityMaker.RepeatShape(theDirectionID, theTimes); |
305 | |
306 | // Update history, materials, origins |
307 | Update(); |
308 | } |
309 | |
310 | //======================================================================= |
311 | //function : ClearRepetitions |
312 | //purpose : Clears the repetitions performed on the periodic shape |
313 | // keeping the shape periodic |
314 | //======================================================================= |
315 | void BOPAlgo_MakeConnected::ClearRepetitions() |
316 | { |
317 | if (HasErrors()) |
318 | return; |
319 | |
320 | if (myPeriodicityMaker.Shape().IsNull() || myPeriodicityMaker.HasErrors()) |
321 | { |
322 | // The shape has not been made periodic yet |
323 | AddWarning(new BOPAlgo_AlertShapeIsNotPeriodic(myShape)); |
324 | return; |
325 | } |
326 | |
327 | // Clear repetitions |
328 | myPeriodicityMaker.ClearRepetitions(); |
329 | myShape = myPeriodicityMaker.Shape(); |
330 | |
331 | // Update history, materials, origins |
332 | Update(); |
333 | } |