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