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 (myShapeToGenerated.UnBind(theRemoved))
117 Standard_ASSERT_INVOKE_(, myMsgGeneratedAndRemoved);
120 if (myShapeToModified.UnBind(theRemoved))
122 Standard_ASSERT_INVOKE_(, myMsgModifiedAndRemoved);
126 myRemoved.Add(theRemoved);
129 //==============================================================================
130 //function : ReplaceGenerated
132 //==============================================================================
133 void BRepTools_History::ReplaceGenerated(
134 const TopoDS_Shape& theInitial, const TopoDS_Shape& theGenerated)
136 if (!prepareGenerated(theInitial, theGenerated))
141 TopTools_ListOfShape* aGenerations =
142 myShapeToGenerated.Bound(theInitial, TopTools_ListOfShape());
143 aGenerations->Append(theGenerated);
146 //==============================================================================
147 //function : ReplaceModified
149 //==============================================================================
150 void BRepTools_History::ReplaceModified(
151 const TopoDS_Shape& theInitial, const TopoDS_Shape& theModified)
153 if (!prepareModified(theInitial, theModified))
158 TopTools_ListOfShape* aModifications =
159 myShapeToModified.Bound(theInitial, TopTools_ListOfShape());
160 aModifications->Append(theModified);
163 //==============================================================================
164 //function : Generated
166 //==============================================================================
167 const TopTools_ListOfShape& BRepTools_History::Generated(
168 const TopoDS_Shape& theInitial) const
170 // Apply the limitations.
171 Standard_ASSERT_RETURN(theInitial.IsNull() || IsSupportedType(theInitial),
172 myMsgUnsupportedType, emptyList());
175 const TopTools_ListOfShape* aGenerations =
176 myShapeToGenerated.Seek(theInitial);
177 return (aGenerations != NULL) ? *aGenerations : emptyList();
180 //==============================================================================
181 //function : Modified
183 //==============================================================================
184 const TopTools_ListOfShape& BRepTools_History::Modified(
185 const TopoDS_Shape& theInitial) const
187 // Apply the limitations.
188 Standard_ASSERT_RETURN(IsSupportedType(theInitial),
189 myMsgUnsupportedType, emptyList());
192 const TopTools_ListOfShape* aModifications =
193 myShapeToModified.Seek(theInitial);
194 return (aModifications != NULL) ? *aModifications : emptyList();
197 //==============================================================================
198 //function : IsRemoved
200 //==============================================================================
201 Standard_Boolean BRepTools_History::IsRemoved(
202 const TopoDS_Shape& theInitial) const
204 // Apply the limitations.
205 Standard_ASSERT_RETURN(IsSupportedType(theInitial),
206 myMsgUnsupportedType, Standard_False);
209 return myRemoved.Contains(theInitial);
212 //==============================================================================
215 //==============================================================================
216 void BRepTools_History::Merge(const Handle(BRepTools_History)& theHistory23)
218 Merge(*theHistory23.get());
220 //==============================================================================
223 //==============================================================================
224 void BRepTools_History::Merge(const BRepTools_History& theHistory23)
226 // Propagate R23 directly and M23 and G23 fully to M12 and G12.
227 // Remember the propagated shapes.
228 TopTools_DataMapOfShapeListOfShape* aS1ToGAndM[] =
229 {&myShapeToGenerated, &myShapeToModified};
230 TopTools_MapOfShape aRPropagated;
232 // Propagate R23, M23 and G23 to M12 and G12 directly.
233 // Remember the propagated shapes.
234 TopTools_MapOfShape aMAndGPropagated;
235 for (Standard_Integer aI = 0; aI < 2; ++aI)
237 for (TopTools_DataMapOfShapeListOfShape::Iterator aMIt1(*aS1ToGAndM[aI]);
238 aMIt1.More(); aMIt1.Next())
240 TopTools_ListOfShape& aL12 = aMIt1.ChangeValue();
241 TopTools_MapOfShape aAdditions[2]; // The G and M additions.
242 for (TopTools_ListOfShape::Iterator aSIt2(aL12); aSIt2.More();)
244 const TopoDS_Shape& aS2 = aSIt2.Value();
245 if (theHistory23.IsRemoved(aS2))
247 aRPropagated.Add(aS2);
252 if (theHistory23.myShapeToGenerated.IsBound(aS2))
254 add(aAdditions[0], theHistory23.myShapeToGenerated(aS2));
255 aMAndGPropagated.Add(aS2);
258 if (theHistory23.myShapeToModified.IsBound(aS2))
260 add(aAdditions[aI], theHistory23.myShapeToModified(aS2));
261 aMAndGPropagated.Add(aS2);
272 add(aL12, aAdditions[aI]);
273 if (aI != 0 && !aAdditions[0].IsEmpty())
275 const TopoDS_Shape& aS1 = aMIt1.Key();
276 TopTools_ListOfShape* aGAndM = aS1ToGAndM[0]->ChangeSeek(aS1);
279 aGAndM = aS1ToGAndM[0]->Bound(aS1, TopTools_ListOfShape());
282 add(*aGAndM, aAdditions[0]);
287 // Propagate M23 and G23 to M12 and G12 sequentially.
288 const TopTools_DataMapOfShapeListOfShape* aS2ToGAndM[] =
289 {&theHistory23.myShapeToGenerated, &theHistory23.myShapeToModified};
290 for (Standard_Integer aI = 0; aI < 2; ++aI)
292 for (TopTools_DataMapOfShapeListOfShape::Iterator aMIt2(*aS2ToGAndM[aI]);
293 aMIt2.More(); aMIt2.Next())
295 const TopoDS_Shape& aS2 = aMIt2.Key();
296 if (!aMAndGPropagated.Contains(aS2))
298 if (!aS1ToGAndM[aI]->IsBound(aS2))
300 aS1ToGAndM[aI]->Bind(aS2, TopTools_ListOfShape());
303 TopTools_ListOfShape aM2 = aMIt2.Value();
304 ((*aS1ToGAndM[aI])(aS2)).Append(aM2);
310 // Unbound the empty M12 and G12.
311 for (Standard_Integer aI = 0; aI < 2; ++aI)
313 for (TopTools_DataMapOfShapeListOfShape::Iterator aMIt1(*aS1ToGAndM[aI]);
316 const TopoDS_Shape& aS1 = aMIt1.Key();
317 const TopTools_ListOfShape& aL12 = aMIt1.Value();
322 aS1ToGAndM[aI]->UnBind(aS1);
327 // Propagate R23 to R12 sequentially.
328 for (TopTools_MapOfShape::Iterator aRIt23(theHistory23.myRemoved);
329 aRIt23.More(); aRIt23.Next())
331 const TopoDS_Shape& aS2 = aRIt23.Value();
332 if (!aRPropagated.Contains(aS2) &&
333 !myShapeToModified.IsBound(aS2) &&
334 !myShapeToGenerated.IsBound(aS2))
341 //==============================================================================
342 //function : prepareGenerated
344 //==============================================================================
345 Standard_Boolean BRepTools_History::prepareGenerated(
346 const TopoDS_Shape& theInitial, const TopoDS_Shape& theGenerated)
348 Standard_ASSERT_RETURN(theInitial.IsNull() ||
349 IsSupportedType(theInitial), myMsgUnsupportedType, Standard_False);
351 if (myRemoved.Remove(theInitial))
353 Standard_ASSERT_INVOKE_(, myMsgGeneratedAndRemoved);
356 if (myShapeToModified.IsBound(theInitial) &&
357 myShapeToModified(theInitial).Remove(theGenerated))
359 Standard_ASSERT_INVOKE_(, myMsgGeneratedAndModified);
362 return Standard_True;
365 //==============================================================================
366 //function : prepareModified
368 //==============================================================================
369 Standard_Boolean BRepTools_History::prepareModified(
370 const TopoDS_Shape& theInitial, const TopoDS_Shape& theModified)
372 Standard_ASSERT_RETURN(IsSupportedType(theInitial),
373 myMsgUnsupportedType, Standard_False);
375 if (myRemoved.Remove(theInitial))
377 Standard_ASSERT_INVOKE_(, myMsgModifiedAndRemoved);
380 if (myShapeToGenerated.IsBound(theInitial) &&
381 myShapeToGenerated(theInitial).Remove(theModified))
383 Standard_ASSERT_INVOKE_(, myMsgGeneratedAndModified);
386 return Standard_True;
389 //==============================================================================
392 //==============================================================================
393 const TopTools_ListOfShape BRepTools_History::myEmptyList;
395 //==============================================================================
396 //function : emptyList
398 //==============================================================================
399 const TopTools_ListOfShape& BRepTools_History::emptyList()
404 //==============================================================================
405 //data : myMsgUnsupportedType
407 //==============================================================================
408 const char* BRepTools_History::myMsgUnsupportedType =
409 "Error: unsupported shape type.";
411 //==============================================================================
412 //data : myMsgGeneratedAndRemoved
414 //==============================================================================
415 const char* BRepTools_History::myMsgGeneratedAndRemoved =
416 "Error: a shape is generated and removed simultaneously.";
418 //==============================================================================
419 //data : myMsgModifiedAndRemoved
421 //==============================================================================
422 const char* BRepTools_History::myMsgModifiedAndRemoved =
423 "Error: a shape is modified and removed simultaneously.";
425 //==============================================================================
426 //data : myMsgGeneratedAndModified
428 //==============================================================================
429 const char* BRepTools_History::myMsgGeneratedAndModified =
430 "Error: a shape is generated and modified "
431 "from the same shape simultaneously.";