1 // Created on: 2004-04-08
2 // Created by: Sergey ZARITCHNY
3 // Copyright (c) 2004-2014 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.
17 #include <BinMNaming_NamedShapeDriver.hxx>
18 #include <BinObjMgt_Persistent.hxx>
19 #include <BinTools_LocationSet.hxx>
20 #include <BinTools_ShapeSet.hxx>
21 #include <Message_Messenger.hxx>
22 #include <Standard_DomainError.hxx>
23 #include <Standard_Type.hxx>
24 #include <TCollection_AsciiString.hxx>
25 #include <TDF_Attribute.hxx>
26 #include <TDF_Label.hxx>
27 #include <TNaming_Builder.hxx>
28 #include <TNaming_Evolution.hxx>
29 #include <TNaming_Iterator.hxx>
30 #include <TNaming_NamedShape.hxx>
31 #include <TopAbs_Orientation.hxx>
32 #include <TopoDS_Shape.hxx>
34 IMPLEMENT_STANDARD_RTTIEXT(BinMNaming_NamedShapeDriver,BinMDF_ADriver)
36 #define SHAPESET "SHAPE_SECTION"
37 //=======================================================================
38 static Standard_Character EvolutionToChar(const TNaming_Evolution theEvol)
41 case TNaming_PRIMITIVE : return 'P';
42 case TNaming_GENERATED : return 'G';
43 case TNaming_MODIFY : return 'M';
44 case TNaming_DELETE : return 'D';
45 case TNaming_SELECTED : return 'S';
46 case TNaming_REPLACE : return 'M'; // for compatibility case TNaming_REPLACE : return 'R';
48 throw Standard_DomainError("TNaming_Evolution:: Evolution Unknown");
52 //=======================================================================
53 static TNaming_Evolution EvolutionToEnum(const Standard_Character theEvol)
56 case 'P': return TNaming_PRIMITIVE;
57 case 'G': return TNaming_GENERATED;
58 case 'M': return TNaming_MODIFY;
59 case 'D': return TNaming_DELETE;
60 case 'S': return TNaming_SELECTED;
61 case 'R': return TNaming_MODIFY; //for compatibility //TNaming_REPLACE;
63 throw Standard_DomainError("TNaming_Evolution:: Evolution Unknown");
66 //=======================================================================
67 static Standard_Character OrientationToChar(const TopAbs_Orientation theOrient)
70 case TopAbs_FORWARD : return 'F';
71 case TopAbs_REVERSED : return 'R';
72 case TopAbs_INTERNAL : return 'I';
73 case TopAbs_EXTERNAL : return 'E';
75 throw Standard_DomainError("TopAbs_Orientation:: Orientation Unknown");
78 //=======================================================================
79 static TopAbs_Orientation CharToOrientation(const Standard_Character theCharOrient)
81 switch(theCharOrient) {
82 case 'F': return TopAbs_FORWARD;
83 case 'R': return TopAbs_REVERSED;
84 case 'I': return TopAbs_INTERNAL;
85 case 'E': return TopAbs_EXTERNAL;
87 throw Standard_DomainError("TopAbs_Orientation:: Orientation Unknown");
91 //=======================================================================
92 static void TranslateTo (const TopoDS_Shape& theShape,
93 BinObjMgt_Persistent& theResult,
94 BinTools_ShapeSet& theShapeSet)
96 // Check for empty shape
97 if (theShape.IsNull()) {
98 theResult.PutInteger(-1);
99 theResult.PutInteger(-1);
100 theResult.PutInteger(-1);
103 // Add to shape set both TShape and Location contained in <theShape>
104 const Standard_Integer aTShapeID = theShapeSet.Add (theShape);
105 const Standard_Integer aLocID =
106 theShapeSet.Locations().Index (theShape.Location());
108 // Fill theResult with shape parameters: TShape ID, Location, Orientation
109 theResult << aTShapeID;
111 theResult << OrientationToChar(theShape.Orientation());
113 //=======================================================================
114 static int TranslateFrom (const BinObjMgt_Persistent& theSource,
115 TopoDS_Shape& theResult,
116 BinTools_ShapeSet& theShapeSet)
118 Standard_Integer aShapeID, aLocID;
119 Standard_Character aCharOrient;
120 Standard_Boolean Ok = theSource >> aShapeID; //TShapeID;
122 // Read TShape and Orientation
123 if (aShapeID <= 0 || aShapeID > theShapeSet.NbShapes())
125 Ok = theSource >> aLocID;
127 Ok = theSource >> aCharOrient;
129 TopAbs_Orientation anOrient = CharToOrientation(aCharOrient);
131 theResult.TShape (theShapeSet.Shape(aShapeID).TShape());//TShape
132 theResult.Location (theShapeSet.Locations().Location (aLocID)); //Location
133 theResult.Orientation (anOrient);//Orientation
137 //=======================================================================
138 //function : BinMNaming_NamedShapeDriver
139 //purpose : Constructor
140 //=======================================================================
142 BinMNaming_NamedShapeDriver::BinMNaming_NamedShapeDriver
143 (const Handle(Message_Messenger)& theMsgDriver)
144 : BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(TNaming_NamedShape)->Name()),
145 myShapeSet (Standard_False),
146 myFormatNb (BinTools_FormatVersion_VERSION_1)
150 //=======================================================================
151 //function : NewEmpty
153 //=======================================================================
155 Handle(TDF_Attribute) BinMNaming_NamedShapeDriver::NewEmpty() const
157 return new TNaming_NamedShape();
160 //=======================================================================
162 //purpose : persistent => transient (retrieve)
163 //=======================================================================
165 Standard_Boolean BinMNaming_NamedShapeDriver::Paste
166 (const BinObjMgt_Persistent& theSource,
167 const Handle(TDF_Attribute)& theTarget,
168 BinObjMgt_RRelocationTable& ) const
170 Handle(TNaming_NamedShape) aTAtt= Handle(TNaming_NamedShape)::DownCast(theTarget);
171 Standard_Integer aNbShapes;
172 theSource >> aNbShapes;
173 TDF_Label aLabel = theTarget->Label ();
174 TNaming_Builder aBuilder (aLabel);
175 Standard_Integer aVer;
176 Standard_Boolean ok = theSource >> aVer;
177 if(!ok) return Standard_False;
178 aTAtt->SetVersion(aVer); //Version
179 Standard_Character aCharEvol;
180 ok = theSource >> aCharEvol;
181 if(!ok) return Standard_False;
182 TNaming_Evolution anEvol = EvolutionToEnum(aCharEvol); //Evolution
183 aTAtt->SetVersion(anEvol);
185 BinTools_ShapeSet& aShapeSet = (BinTools_ShapeSet&) myShapeSet;
187 NCollection_List<TopoDS_Shape> anOldShapes, aNewShapes;
188 for (Standard_Integer i = 1; i <= aNbShapes; i++)
190 TopoDS_Shape anOldShape, aNewShape;
192 if (anEvol != TNaming_PRIMITIVE)
193 if (TranslateFrom (theSource, anOldShape, aShapeSet)) return Standard_False;
195 if (anEvol != TNaming_DELETE)
196 if (TranslateFrom (theSource, aNewShape, aShapeSet)) return Standard_False;
198 // Here we add shapes in reverse order because TNaming_Builder also adds them in reverse order.
199 anOldShapes.Prepend (anOldShape);
200 aNewShapes.Prepend (aNewShape);
203 for (NCollection_List<TopoDS_Shape>::Iterator anOldIt (anOldShapes), aNewIt (aNewShapes);
204 anOldIt.More() && aNewIt.More();
205 anOldIt.Next(), aNewIt.Next())
209 case TNaming_PRIMITIVE:
210 aBuilder.Generated (aNewIt.Value ());
212 case TNaming_GENERATED:
213 aBuilder.Generated (anOldIt.Value(), aNewIt.Value());
216 aBuilder.Modify (anOldIt.Value(), aNewIt.Value());
219 aBuilder.Delete (anOldIt.Value());
221 case TNaming_SELECTED:
222 aBuilder.Select (aNewIt.Value(), anOldIt.Value());
224 case TNaming_REPLACE:
225 aBuilder.Modify (anOldIt.Value(), aNewIt.Value()); // for compatibility aBuilder.Replace(anOldShape, aNewShape);
228 throw Standard_DomainError("TNaming_Evolution:: Evolution Unknown");
231 return Standard_True;
234 //=======================================================================
236 //purpose : transient => persistent (store)
237 //=======================================================================
239 void BinMNaming_NamedShapeDriver::Paste (const Handle(TDF_Attribute)& theSource,
240 BinObjMgt_Persistent& theTarget,
241 BinObjMgt_SRelocationTable& ) const
243 Handle(TNaming_NamedShape) aSAtt= Handle(TNaming_NamedShape)::DownCast(theSource);
245 //--------------------------------------------------------------
246 Standard_Integer NbShapes = 0;
247 for (TNaming_Iterator SItr (aSAtt); SItr.More (); SItr.Next ()) NbShapes++;
248 //--------------------------------------------------------------
250 BinTools_ShapeSet& aShapeSet = (BinTools_ShapeSet&) myShapeSet;
251 TNaming_Evolution anEvol = aSAtt->Evolution();
253 theTarget << NbShapes;
254 theTarget << aSAtt->Version();
255 theTarget << EvolutionToChar(anEvol);
258 Standard_Integer i = 1;
259 for (TNaming_Iterator SIterator(aSAtt) ;SIterator.More(); SIterator.Next()) {
260 const TopoDS_Shape& OldShape = SIterator.OldShape();
261 const TopoDS_Shape& NewShape = SIterator.NewShape();
263 if ( anEvol != TNaming_PRIMITIVE )
264 TranslateTo (OldShape, theTarget, aShapeSet);
266 if (anEvol != TNaming_DELETE)
267 TranslateTo (NewShape, theTarget, aShapeSet);
275 //=======================================================================
276 //function : WriteShapeSection
278 //=======================================================================
280 void BinMNaming_NamedShapeDriver::WriteShapeSection (Standard_OStream& theOS,
281 const Message_ProgressRange& theRange)
284 myShapeSet.SetFormatNb(myFormatNb);
285 myShapeSet.Write (theOS, theRange);
289 //=======================================================================
292 //=======================================================================
294 void BinMNaming_NamedShapeDriver::Clear()
299 //=======================================================================
300 //function : ReadShapeSection
302 //=======================================================================
304 void BinMNaming_NamedShapeDriver::ReadShapeSection (Standard_IStream& theIS,
305 const Message_ProgressRange& theRange)
307 // check section title string; note that some versions of OCCT (up to 6.3.1)
308 // might avoid writing shape section if it is empty
309 std::streamoff aPos = theIS.tellg();
310 TCollection_AsciiString aSectionTitle;
311 theIS >> aSectionTitle;
312 if(aSectionTitle.Length() > 0 && aSectionTitle == SHAPESET) {
314 myShapeSet.Read (theIS, theRange);
315 SetFormatNb(myShapeSet.FormatNb());
318 theIS.seekg(aPos); // no shape section is present, try to return to initial point