1 // Created on: 2017-04-21
2 // Created by: Alexander Bobkov
3 // Copyright (c) 2017 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <BRepTools_History.hxx>
19 #include <TopTools_IndexedMapOfShape.hxx>
21 // Implement the OCCT RTTI for the type.
22 IMPLEMENT_STANDARD_RTTIEXT(BRepTools_History, Standard_Transient)
27 //==============================================================================
29 //purpose : Adds the elements of the list to the map.
30 //==============================================================================
31 void add(TopTools_MapOfShape& theMap, const TopTools_ListOfShape& theList)
33 for (TopTools_ListOfShape::Iterator aSIt(theList); aSIt.More(); aSIt.Next())
35 theMap.Add(aSIt.Value());
39 //==============================================================================
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)
46 for (typename TCollection::Iterator aSIt(theCollection);
47 aSIt.More(); aSIt.Next())
49 theList.Append(aSIt.Value());
55 //==============================================================================
56 //function : AddGenerated
58 //==============================================================================
59 void BRepTools_History::AddGenerated(
60 const TopoDS_Shape& theInitial, const TopoDS_Shape& theGenerated)
62 if (!prepareGenerated(theInitial, theGenerated))
67 TopTools_ListOfShape* aGenerations =
68 myShapeToGenerated.ChangeSeek(theInitial);
69 if (aGenerations == NULL)
71 aGenerations = myShapeToGenerated.Bound(theInitial, TopTools_ListOfShape());
74 Standard_ASSERT_VOID(!aGenerations->Contains(theGenerated),
75 "Error: a duplicated generation of a shape.");
77 aGenerations->Append(theGenerated);
80 //==============================================================================
81 //function : AddModified
83 //==============================================================================
84 void BRepTools_History::AddModified(
85 const TopoDS_Shape& theInitial, const TopoDS_Shape& theModified)
87 if (!prepareModified(theInitial, theModified))
92 TopTools_ListOfShape* aModifications =
93 myShapeToModified.ChangeSeek(theInitial);
94 if (aModifications == NULL)
97 myShapeToModified.Bound(theInitial, TopTools_ListOfShape());
100 Standard_ASSERT_VOID(!aModifications->Contains(theModified),
101 "Error: a duplicated modification of a shape.");
103 aModifications->Append(theModified);
106 //==============================================================================
109 //==============================================================================
110 void BRepTools_History::Remove(const TopoDS_Shape& theRemoved)
112 // Apply the limitations.
113 Standard_ASSERT_RETURN(IsSupportedType(theRemoved), myMsgUnsupportedType,);
115 if (myShapeToModified.UnBind(theRemoved))
117 Standard_ASSERT_INVOKE_(, myMsgModifiedAndRemoved);
120 myRemoved.Add(theRemoved);
123 //==============================================================================
124 //function : ReplaceGenerated
126 //==============================================================================
127 void BRepTools_History::ReplaceGenerated(
128 const TopoDS_Shape& theInitial, const TopoDS_Shape& theGenerated)
130 if (!prepareGenerated(theInitial, theGenerated))
135 TopTools_ListOfShape* aGenerations =
136 myShapeToGenerated.Bound(theInitial, TopTools_ListOfShape());
137 aGenerations->Append(theGenerated);
140 //==============================================================================
141 //function : ReplaceModified
143 //==============================================================================
144 void BRepTools_History::ReplaceModified(
145 const TopoDS_Shape& theInitial, const TopoDS_Shape& theModified)
147 if (!prepareModified(theInitial, theModified))
152 TopTools_ListOfShape* aModifications =
153 myShapeToModified.Bound(theInitial, TopTools_ListOfShape());
154 aModifications->Append(theModified);
157 //==============================================================================
158 //function : Generated
160 //==============================================================================
161 const TopTools_ListOfShape& BRepTools_History::Generated(
162 const TopoDS_Shape& theInitial) const
164 // Apply the limitations.
165 Standard_ASSERT_RETURN(theInitial.IsNull() || IsSupportedType(theInitial),
166 myMsgUnsupportedType, emptyList());
169 const TopTools_ListOfShape* aGenerations =
170 myShapeToGenerated.Seek(theInitial);
171 return (aGenerations != NULL) ? *aGenerations : emptyList();
174 //==============================================================================
175 //function : Modified
177 //==============================================================================
178 const TopTools_ListOfShape& BRepTools_History::Modified(
179 const TopoDS_Shape& theInitial) const
181 // Apply the limitations.
182 Standard_ASSERT_RETURN(IsSupportedType(theInitial),
183 myMsgUnsupportedType, emptyList());
186 const TopTools_ListOfShape* aModifications =
187 myShapeToModified.Seek(theInitial);
188 return (aModifications != NULL) ? *aModifications : emptyList();
191 //==============================================================================
192 //function : IsRemoved
194 //==============================================================================
195 Standard_Boolean BRepTools_History::IsRemoved(
196 const TopoDS_Shape& theInitial) const
198 // Apply the limitations.
199 Standard_ASSERT_RETURN(IsSupportedType(theInitial),
200 myMsgUnsupportedType, Standard_False);
203 return myRemoved.Contains(theInitial);
206 //==============================================================================
209 //==============================================================================
210 void BRepTools_History::Merge(const Handle(BRepTools_History)& theHistory23)
212 Merge(*theHistory23.get());
214 //==============================================================================
217 //==============================================================================
218 void BRepTools_History::Merge(const BRepTools_History& theHistory23)
220 // Propagate R23 directly and M23 and G23 fully to M12 and G12.
221 // Remember the propagated shapes.
222 TopTools_DataMapOfShapeListOfShape* aS1ToGAndM[] =
223 {&myShapeToGenerated, &myShapeToModified};
224 TopTools_MapOfShape aRPropagated;
226 // Propagate R23, M23 and G23 to M12 and G12 directly.
227 // Remember the propagated shapes.
228 TopTools_MapOfShape aMAndGPropagated;
229 for (Standard_Integer aI = 0; aI < 2; ++aI)
231 for (TopTools_DataMapOfShapeListOfShape::Iterator aMIt1(*aS1ToGAndM[aI]);
232 aMIt1.More(); aMIt1.Next())
234 TopTools_ListOfShape& aL12 = aMIt1.ChangeValue();
235 TopTools_MapOfShape aAdditions[2]; // The G and M additions.
236 for (TopTools_ListOfShape::Iterator aSIt2(aL12); aSIt2.More();)
238 const TopoDS_Shape& aS2 = aSIt2.Value();
239 if (theHistory23.IsRemoved(aS2))
241 aRPropagated.Add(aS2);
246 if (theHistory23.myShapeToGenerated.IsBound(aS2))
248 add(aAdditions[0], theHistory23.myShapeToGenerated(aS2));
249 aMAndGPropagated.Add(aS2);
252 if (theHistory23.myShapeToModified.IsBound(aS2))
254 add(aAdditions[aI], theHistory23.myShapeToModified(aS2));
255 aMAndGPropagated.Add(aS2);
266 add(aL12, aAdditions[aI]);
267 if (aI != 0 && !aAdditions[0].IsEmpty())
269 const TopoDS_Shape& aS1 = aMIt1.Key();
270 TopTools_ListOfShape* aGAndM = aS1ToGAndM[0]->ChangeSeek(aS1);
273 aGAndM = aS1ToGAndM[0]->Bound(aS1, TopTools_ListOfShape());
276 add(*aGAndM, aAdditions[0]);
281 // Propagate M23 and G23 to M12 and G12 sequentially.
282 const TopTools_DataMapOfShapeListOfShape* aS2ToGAndM[] =
283 {&theHistory23.myShapeToGenerated, &theHistory23.myShapeToModified};
284 for (Standard_Integer aI = 0; aI < 2; ++aI)
286 for (TopTools_DataMapOfShapeListOfShape::Iterator aMIt2(*aS2ToGAndM[aI]);
287 aMIt2.More(); aMIt2.Next())
289 const TopoDS_Shape& aS2 = aMIt2.Key();
290 if (!aMAndGPropagated.Contains(aS2))
292 if (!aS1ToGAndM[aI]->IsBound(aS2))
294 aS1ToGAndM[aI]->Bind(aS2, TopTools_ListOfShape());
297 TopTools_ListOfShape aM2 = aMIt2.Value();
298 ((*aS1ToGAndM[aI])(aS2)).Append(aM2);
299 myRemoved.Remove(aS2);
305 // Unbound the empty M12 and G12.
306 for (Standard_Integer aI = 0; aI < 2; ++aI)
308 for (TopTools_DataMapOfShapeListOfShape::Iterator aMIt1(*aS1ToGAndM[aI]);
311 const TopoDS_Shape& aS1 = aMIt1.Key();
312 const TopTools_ListOfShape& aL12 = aMIt1.Value();
317 aS1ToGAndM[aI]->UnBind(aS1);
322 // Propagate R23 to R12 sequentially.
323 for (TopTools_MapOfShape::Iterator aRIt23(theHistory23.myRemoved);
324 aRIt23.More(); aRIt23.Next())
326 const TopoDS_Shape& aS2 = aRIt23.Value();
327 if (!aRPropagated.Contains(aS2) &&
328 !myShapeToModified.IsBound(aS2) &&
329 !myShapeToGenerated.IsBound(aS2))
336 //==============================================================================
337 //function : prepareGenerated
339 //==============================================================================
340 Standard_Boolean BRepTools_History::prepareGenerated(
341 const TopoDS_Shape& theInitial, const TopoDS_Shape& theGenerated)
343 Standard_ASSERT_RETURN(theInitial.IsNull() ||
344 IsSupportedType(theInitial), myMsgUnsupportedType, Standard_False);
346 if (myShapeToModified.IsBound(theInitial) &&
347 myShapeToModified(theInitial).Remove(theGenerated))
349 Standard_ASSERT_INVOKE_(, myMsgGeneratedAndModified);
352 return Standard_True;
355 //==============================================================================
356 //function : prepareModified
358 //==============================================================================
359 Standard_Boolean BRepTools_History::prepareModified(
360 const TopoDS_Shape& theInitial, const TopoDS_Shape& theModified)
362 Standard_ASSERT_RETURN(IsSupportedType(theInitial),
363 myMsgUnsupportedType, Standard_False);
365 if (myRemoved.Remove(theInitial))
367 Standard_ASSERT_INVOKE_(, myMsgModifiedAndRemoved);
370 if (myShapeToGenerated.IsBound(theInitial) &&
371 myShapeToGenerated(theInitial).Remove(theModified))
373 Standard_ASSERT_INVOKE_(, myMsgGeneratedAndModified);
376 return Standard_True;
379 //==============================================================================
382 //==============================================================================
383 const TopTools_ListOfShape BRepTools_History::myEmptyList;
385 //==============================================================================
386 //function : emptyList
388 //==============================================================================
389 const TopTools_ListOfShape& BRepTools_History::emptyList()
394 //==============================================================================
395 //data : myMsgUnsupportedType
397 //==============================================================================
398 const char* BRepTools_History::myMsgUnsupportedType =
399 "Error: unsupported shape type.";
401 //==============================================================================
402 //data : myMsgGeneratedAndRemoved
404 //==============================================================================
405 const char* BRepTools_History::myMsgGeneratedAndRemoved =
406 "Error: a shape is generated and removed simultaneously.";
408 //==============================================================================
409 //data : myMsgModifiedAndRemoved
411 //==============================================================================
412 const char* BRepTools_History::myMsgModifiedAndRemoved =
413 "Error: a shape is modified and removed simultaneously.";
415 //==============================================================================
416 //data : myMsgGeneratedAndModified
418 //==============================================================================
419 const char* BRepTools_History::myMsgGeneratedAndModified =
420 "Error: a shape is generated and modified "
421 "from the same shape simultaneously.";