2c02f319 |
1 | // Created on: 2017-04-21 |
2 | // Created by: Alexander Bobkov |
3 | // Copyright (c) 2017 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 <BRepTools_History.hxx> |
17 | |
18 | #include <TopExp.hxx> |
19 | #include <TopTools_IndexedMapOfShape.hxx> |
20 | |
21 | // Implement the OCCT RTTI for the type. |
22 | IMPLEMENT_STANDARD_RTTIEXT(BRepTools_History, Standard_Transient) |
23 | |
24 | namespace |
25 | { |
26 | |
27 | //============================================================================== |
28 | //function : add |
29 | //purpose : Adds the elements of the list to the map. |
30 | //============================================================================== |
31 | void add(TopTools_MapOfShape& theMap, const TopTools_ListOfShape& theList) |
32 | { |
33 | for (TopTools_ListOfShape::Iterator aSIt(theList); aSIt.More(); aSIt.Next()) |
34 | { |
35 | theMap.Add(aSIt.Value()); |
36 | } |
37 | } |
38 | |
39 | //============================================================================== |
40 | //function : add |
41 | //purpose : Adds the elements of the collection to the list. |
42 | //============================================================================== |
43 | template<typename TCollection> |
44 | void add(TopTools_ListOfShape& theList, const TCollection& theCollection) |
45 | { |
46 | for (typename TCollection::Iterator aSIt(theCollection); |
47 | aSIt.More(); aSIt.Next()) |
48 | { |
49 | theList.Append(aSIt.Value()); |
50 | } |
51 | } |
52 | |
53 | } |
54 | |
55 | //============================================================================== |
56 | //function : AddGenerated |
57 | //purpose : |
58 | //============================================================================== |
59 | void BRepTools_History::AddGenerated( |
60 | const TopoDS_Shape& theInitial, const TopoDS_Shape& theGenerated) |
61 | { |
62 | if (!prepareGenerated(theInitial, theGenerated)) |
63 | { |
64 | return; |
65 | } |
66 | |
67 | TopTools_ListOfShape* aGenerations = |
68 | myShapeToGenerated.ChangeSeek(theInitial); |
69 | if (aGenerations == NULL) |
70 | { |
71 | aGenerations = myShapeToGenerated.Bound(theInitial, TopTools_ListOfShape()); |
72 | } |
73 | |
74 | Standard_ASSERT_VOID(!aGenerations->Contains(theGenerated), |
75 | "Error: a duplicated generation of a shape."); |
76 | |
77 | aGenerations->Append(theGenerated); |
78 | } |
79 | |
80 | //============================================================================== |
81 | //function : AddModified |
82 | //purpose : |
83 | //============================================================================== |
84 | void BRepTools_History::AddModified( |
85 | const TopoDS_Shape& theInitial, const TopoDS_Shape& theModified) |
86 | { |
87 | if (!prepareModified(theInitial, theModified)) |
88 | { |
89 | return; |
90 | } |
91 | |
92 | TopTools_ListOfShape* aModifications = |
93 | myShapeToModified.ChangeSeek(theInitial); |
94 | if (aModifications == NULL) |
95 | { |
96 | aModifications = |
97 | myShapeToModified.Bound(theInitial, TopTools_ListOfShape()); |
98 | } |
99 | |
100 | Standard_ASSERT_VOID(!aModifications->Contains(theModified), |
101 | "Error: a duplicated modification of a shape."); |
102 | |
103 | aModifications->Append(theModified); |
104 | } |
105 | |
106 | //============================================================================== |
107 | //function : Remove |
108 | //purpose : |
109 | //============================================================================== |
110 | void BRepTools_History::Remove(const TopoDS_Shape& theRemoved) |
111 | { |
112 | // Apply the limitations. |
113 | Standard_ASSERT_RETURN(IsSupportedType(theRemoved), myMsgUnsupportedType,); |
114 | |
2c02f319 |
115 | if (myShapeToModified.UnBind(theRemoved)) |
116 | { |
117 | Standard_ASSERT_INVOKE_(, myMsgModifiedAndRemoved); |
118 | } |
119 | |
2c02f319 |
120 | myRemoved.Add(theRemoved); |
121 | } |
122 | |
123 | //============================================================================== |
124 | //function : ReplaceGenerated |
125 | //purpose : |
126 | //============================================================================== |
127 | void BRepTools_History::ReplaceGenerated( |
128 | const TopoDS_Shape& theInitial, const TopoDS_Shape& theGenerated) |
129 | { |
130 | if (!prepareGenerated(theInitial, theGenerated)) |
131 | { |
132 | return; |
133 | } |
134 | |
135 | TopTools_ListOfShape* aGenerations = |
136 | myShapeToGenerated.Bound(theInitial, TopTools_ListOfShape()); |
137 | aGenerations->Append(theGenerated); |
138 | } |
139 | |
140 | //============================================================================== |
141 | //function : ReplaceModified |
142 | //purpose : |
143 | //============================================================================== |
144 | void BRepTools_History::ReplaceModified( |
145 | const TopoDS_Shape& theInitial, const TopoDS_Shape& theModified) |
146 | { |
147 | if (!prepareModified(theInitial, theModified)) |
148 | { |
149 | return; |
150 | } |
151 | |
152 | TopTools_ListOfShape* aModifications = |
153 | myShapeToModified.Bound(theInitial, TopTools_ListOfShape()); |
154 | aModifications->Append(theModified); |
155 | } |
156 | |
157 | //============================================================================== |
158 | //function : Generated |
159 | //purpose : |
160 | //============================================================================== |
161 | const TopTools_ListOfShape& BRepTools_History::Generated( |
162 | const TopoDS_Shape& theInitial) const |
163 | { |
164 | // Apply the limitations. |
165 | Standard_ASSERT_RETURN(theInitial.IsNull() || IsSupportedType(theInitial), |
166 | myMsgUnsupportedType, emptyList()); |
167 | |
168 | // |
169 | const TopTools_ListOfShape* aGenerations = |
170 | myShapeToGenerated.Seek(theInitial); |
171 | return (aGenerations != NULL) ? *aGenerations : emptyList(); |
172 | } |
173 | |
174 | //============================================================================== |
175 | //function : Modified |
176 | //purpose : |
177 | //============================================================================== |
178 | const TopTools_ListOfShape& BRepTools_History::Modified( |
179 | const TopoDS_Shape& theInitial) const |
180 | { |
181 | // Apply the limitations. |
182 | Standard_ASSERT_RETURN(IsSupportedType(theInitial), |
183 | myMsgUnsupportedType, emptyList()); |
184 | |
185 | // |
186 | const TopTools_ListOfShape* aModifications = |
187 | myShapeToModified.Seek(theInitial); |
188 | return (aModifications != NULL) ? *aModifications : emptyList(); |
189 | } |
190 | |
191 | //============================================================================== |
192 | //function : IsRemoved |
193 | //purpose : |
194 | //============================================================================== |
195 | Standard_Boolean BRepTools_History::IsRemoved( |
196 | const TopoDS_Shape& theInitial) const |
197 | { |
198 | // Apply the limitations. |
199 | Standard_ASSERT_RETURN(IsSupportedType(theInitial), |
200 | myMsgUnsupportedType, Standard_False); |
201 | |
202 | // |
203 | return myRemoved.Contains(theInitial); |
204 | } |
205 | |
206 | //============================================================================== |
207 | //function : Merge |
208 | //purpose : |
209 | //============================================================================== |
210 | void BRepTools_History::Merge(const Handle(BRepTools_History)& theHistory23) |
d9ca2e0c |
211 | { |
3dc58095 |
212 | if (!theHistory23.IsNull()) |
213 | Merge(*theHistory23.get()); |
d9ca2e0c |
214 | } |
215 | //============================================================================== |
216 | //function : Merge |
217 | //purpose : |
218 | //============================================================================== |
219 | void BRepTools_History::Merge(const BRepTools_History& theHistory23) |
2c02f319 |
220 | { |
3dc58095 |
221 | if (!(theHistory23.HasModified() || |
222 | theHistory23.HasGenerated() || |
223 | theHistory23.HasRemoved())) |
224 | // nothing to merge |
225 | return; |
226 | |
2c02f319 |
227 | // Propagate R23 directly and M23 and G23 fully to M12 and G12. |
228 | // Remember the propagated shapes. |
229 | TopTools_DataMapOfShapeListOfShape* aS1ToGAndM[] = |
230 | {&myShapeToGenerated, &myShapeToModified}; |
231 | TopTools_MapOfShape aRPropagated; |
232 | { |
233 | // Propagate R23, M23 and G23 to M12 and G12 directly. |
234 | // Remember the propagated shapes. |
235 | TopTools_MapOfShape aMAndGPropagated; |
236 | for (Standard_Integer aI = 0; aI < 2; ++aI) |
237 | { |
238 | for (TopTools_DataMapOfShapeListOfShape::Iterator aMIt1(*aS1ToGAndM[aI]); |
239 | aMIt1.More(); aMIt1.Next()) |
240 | { |
241 | TopTools_ListOfShape& aL12 = aMIt1.ChangeValue(); |
242 | TopTools_MapOfShape aAdditions[2]; // The G and M additions. |
243 | for (TopTools_ListOfShape::Iterator aSIt2(aL12); aSIt2.More();) |
244 | { |
245 | const TopoDS_Shape& aS2 = aSIt2.Value(); |
d9ca2e0c |
246 | if (theHistory23.IsRemoved(aS2)) |
2c02f319 |
247 | { |
2c02f319 |
248 | aRPropagated.Add(aS2); |
d9ca2e0c |
249 | aL12.Remove(aSIt2); |
2c02f319 |
250 | } |
251 | else |
252 | { |
d9ca2e0c |
253 | if (theHistory23.myShapeToGenerated.IsBound(aS2)) |
2c02f319 |
254 | { |
d9ca2e0c |
255 | add(aAdditions[0], theHistory23.myShapeToGenerated(aS2)); |
2c02f319 |
256 | aMAndGPropagated.Add(aS2); |
257 | } |
258 | |
d9ca2e0c |
259 | if (theHistory23.myShapeToModified.IsBound(aS2)) |
2c02f319 |
260 | { |
d9ca2e0c |
261 | add(aAdditions[aI], theHistory23.myShapeToModified(aS2)); |
2c02f319 |
262 | aMAndGPropagated.Add(aS2); |
263 | |
264 | aL12.Remove(aSIt2); |
265 | } |
266 | else |
267 | { |
268 | aSIt2.Next(); |
269 | } |
270 | } |
271 | } |
272 | |
273 | add(aL12, aAdditions[aI]); |
274 | if (aI != 0 && !aAdditions[0].IsEmpty()) |
275 | { |
276 | const TopoDS_Shape& aS1 = aMIt1.Key(); |
277 | TopTools_ListOfShape* aGAndM = aS1ToGAndM[0]->ChangeSeek(aS1); |
278 | if (aGAndM == NULL) |
279 | { |
280 | aGAndM = aS1ToGAndM[0]->Bound(aS1, TopTools_ListOfShape()); |
281 | } |
282 | |
283 | add(*aGAndM, aAdditions[0]); |
284 | } |
285 | } |
286 | } |
287 | |
288 | // Propagate M23 and G23 to M12 and G12 sequentially. |
289 | const TopTools_DataMapOfShapeListOfShape* aS2ToGAndM[] = |
d9ca2e0c |
290 | {&theHistory23.myShapeToGenerated, &theHistory23.myShapeToModified}; |
2c02f319 |
291 | for (Standard_Integer aI = 0; aI < 2; ++aI) |
292 | { |
293 | for (TopTools_DataMapOfShapeListOfShape::Iterator aMIt2(*aS2ToGAndM[aI]); |
294 | aMIt2.More(); aMIt2.Next()) |
295 | { |
296 | const TopoDS_Shape& aS2 = aMIt2.Key(); |
297 | if (!aMAndGPropagated.Contains(aS2)) |
298 | { |
299 | if (!aS1ToGAndM[aI]->IsBound(aS2)) |
300 | { |
301 | aS1ToGAndM[aI]->Bind(aS2, TopTools_ListOfShape()); |
302 | } |
303 | |
304 | TopTools_ListOfShape aM2 = aMIt2.Value(); |
305 | ((*aS1ToGAndM[aI])(aS2)).Append(aM2); |
4f7d41ea |
306 | myRemoved.Remove(aS2); |
2c02f319 |
307 | } |
308 | } |
309 | } |
310 | } |
311 | |
312 | // Unbound the empty M12 and G12. |
313 | for (Standard_Integer aI = 0; aI < 2; ++aI) |
314 | { |
315 | for (TopTools_DataMapOfShapeListOfShape::Iterator aMIt1(*aS1ToGAndM[aI]); |
316 | aMIt1.More();) |
317 | { |
318 | const TopoDS_Shape& aS1 = aMIt1.Key(); |
319 | const TopTools_ListOfShape& aL12 = aMIt1.Value(); |
320 | aMIt1.Next(); |
321 | if (aL12.IsEmpty()) |
322 | { |
d9ca2e0c |
323 | myRemoved.Add(aS1); |
2c02f319 |
324 | aS1ToGAndM[aI]->UnBind(aS1); |
325 | } |
326 | } |
327 | } |
328 | |
329 | // Propagate R23 to R12 sequentially. |
d9ca2e0c |
330 | for (TopTools_MapOfShape::Iterator aRIt23(theHistory23.myRemoved); |
2c02f319 |
331 | aRIt23.More(); aRIt23.Next()) |
332 | { |
333 | const TopoDS_Shape& aS2 = aRIt23.Value(); |
334 | if (!aRPropagated.Contains(aS2) && |
335 | !myShapeToModified.IsBound(aS2) && |
336 | !myShapeToGenerated.IsBound(aS2)) |
337 | { |
338 | myRemoved.Add(aS2); |
339 | } |
340 | } |
341 | } |
342 | |
343 | //============================================================================== |
344 | //function : prepareGenerated |
345 | //purpose : |
346 | //============================================================================== |
347 | Standard_Boolean BRepTools_History::prepareGenerated( |
348 | const TopoDS_Shape& theInitial, const TopoDS_Shape& theGenerated) |
349 | { |
350 | Standard_ASSERT_RETURN(theInitial.IsNull() || |
351 | IsSupportedType(theInitial), myMsgUnsupportedType, Standard_False); |
352 | |
2c02f319 |
353 | if (myShapeToModified.IsBound(theInitial) && |
354 | myShapeToModified(theInitial).Remove(theGenerated)) |
355 | { |
356 | Standard_ASSERT_INVOKE_(, myMsgGeneratedAndModified); |
357 | } |
358 | |
359 | return Standard_True; |
360 | } |
361 | |
362 | //============================================================================== |
363 | //function : prepareModified |
364 | //purpose : |
365 | //============================================================================== |
366 | Standard_Boolean BRepTools_History::prepareModified( |
367 | const TopoDS_Shape& theInitial, const TopoDS_Shape& theModified) |
368 | { |
369 | Standard_ASSERT_RETURN(IsSupportedType(theInitial), |
370 | myMsgUnsupportedType, Standard_False); |
371 | |
372 | if (myRemoved.Remove(theInitial)) |
373 | { |
374 | Standard_ASSERT_INVOKE_(, myMsgModifiedAndRemoved); |
375 | } |
376 | |
377 | if (myShapeToGenerated.IsBound(theInitial) && |
378 | myShapeToGenerated(theInitial).Remove(theModified)) |
379 | { |
380 | Standard_ASSERT_INVOKE_(, myMsgGeneratedAndModified); |
381 | } |
382 | |
383 | return Standard_True; |
384 | } |
385 | |
386 | //============================================================================== |
387 | //data : myEmptyList |
388 | //purpose : |
389 | //============================================================================== |
390 | const TopTools_ListOfShape BRepTools_History::myEmptyList; |
391 | |
392 | //============================================================================== |
393 | //function : emptyList |
394 | //purpose : |
395 | //============================================================================== |
396 | const TopTools_ListOfShape& BRepTools_History::emptyList() |
397 | { |
398 | return myEmptyList; |
399 | } |
400 | |
401 | //============================================================================== |
402 | //data : myMsgUnsupportedType |
403 | //purpose : |
404 | //============================================================================== |
405 | const char* BRepTools_History::myMsgUnsupportedType = |
406 | "Error: unsupported shape type."; |
407 | |
408 | //============================================================================== |
409 | //data : myMsgGeneratedAndRemoved |
410 | //purpose : |
411 | //============================================================================== |
412 | const char* BRepTools_History::myMsgGeneratedAndRemoved = |
413 | "Error: a shape is generated and removed simultaneously."; |
414 | |
415 | //============================================================================== |
416 | //data : myMsgModifiedAndRemoved |
417 | //purpose : |
418 | //============================================================================== |
419 | const char* BRepTools_History::myMsgModifiedAndRemoved = |
420 | "Error: a shape is modified and removed simultaneously."; |
421 | |
422 | //============================================================================== |
423 | //data : myMsgGeneratedAndModified |
424 | //purpose : |
425 | //============================================================================== |
426 | const char* BRepTools_History::myMsgGeneratedAndModified = |
427 | "Error: a shape is generated and modified " |
428 | "from the same shape simultaneously."; |