0031136: Modeling Data - BinXCAF persistence loses normals from triangulation-only...
[occt.git] / src / BinMNaming / BinMNaming_NamedShapeDriver.cxx
CommitLineData
b311480e 1// Created on: 2004-04-08
2// Created by: Sergey ZARITCHNY
973c2be1 3// Copyright (c) 2004-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 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
973c2be1 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.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
42cf5bc1 16
17#include <BinMNaming_NamedShapeDriver.hxx>
18#include <BinObjMgt_Persistent.hxx>
19#include <BinTools_LocationSet.hxx>
20#include <BinTools_ShapeSet.hxx>
83ae3591 21#include <Message_Messenger.hxx>
7fd59977 22#include <Standard_DomainError.hxx>
42cf5bc1 23#include <Standard_Type.hxx>
24#include <TCollection_AsciiString.hxx>
25#include <TDF_Attribute.hxx>
7fd59977 26#include <TDF_Label.hxx>
9f45d35b 27#include <TDocStd_FormatVersion.hxx>
42cf5bc1 28#include <TNaming_Builder.hxx>
29#include <TNaming_Evolution.hxx>
7fd59977 30#include <TNaming_Iterator.hxx>
42cf5bc1 31#include <TNaming_NamedShape.hxx>
7fd59977 32#include <TopAbs_Orientation.hxx>
42cf5bc1 33#include <TopoDS_Shape.hxx>
7fd59977 34
92efcf78 35IMPLEMENT_STANDARD_RTTIEXT(BinMNaming_NamedShapeDriver,BinMDF_ADriver)
36
7fd59977 37#define SHAPESET "SHAPE_SECTION"
7fd59977 38//=======================================================================
39static Standard_Character EvolutionToChar(const TNaming_Evolution theEvol)
40{
41 switch(theEvol) {
42 case TNaming_PRIMITIVE : return 'P';
43 case TNaming_GENERATED : return 'G';
44 case TNaming_MODIFY : return 'M';
45 case TNaming_DELETE : return 'D';
46 case TNaming_SELECTED : return 'S';
566f8441 47 case TNaming_REPLACE : return 'M'; // for compatibility case TNaming_REPLACE : return 'R';
7fd59977 48 default:
9775fa61 49 throw Standard_DomainError("TNaming_Evolution:: Evolution Unknown");
7fd59977 50 }
7fd59977 51}
52
53//=======================================================================
54static TNaming_Evolution EvolutionToEnum(const Standard_Character theEvol)
55{
56 switch(theEvol) {
57 case 'P': return TNaming_PRIMITIVE;
58 case 'G': return TNaming_GENERATED;
59 case 'M': return TNaming_MODIFY;
60 case 'D': return TNaming_DELETE;
61 case 'S': return TNaming_SELECTED;
1ec8a59e 62 case 'R': return TNaming_MODIFY; //for compatibility //TNaming_REPLACE;
7fd59977 63 default:
9775fa61 64 throw Standard_DomainError("TNaming_Evolution:: Evolution Unknown");
7fd59977 65 }
7fd59977 66}
67//=======================================================================
68static Standard_Character OrientationToChar(const TopAbs_Orientation theOrient)
69{
70 switch(theOrient) {
71 case TopAbs_FORWARD : return 'F';
72 case TopAbs_REVERSED : return 'R';
73 case TopAbs_INTERNAL : return 'I';
74 case TopAbs_EXTERNAL : return 'E';
75 default:
9775fa61 76 throw Standard_DomainError("TopAbs_Orientation:: Orientation Unknown");
7fd59977 77 }
7fd59977 78}
79//=======================================================================
80static TopAbs_Orientation CharToOrientation(const Standard_Character theCharOrient)
81{
82 switch(theCharOrient) {
83 case 'F': return TopAbs_FORWARD;
84 case 'R': return TopAbs_REVERSED;
85 case 'I': return TopAbs_INTERNAL;
86 case 'E': return TopAbs_EXTERNAL;
87 default:
9775fa61 88 throw Standard_DomainError("TopAbs_Orientation:: Orientation Unknown");
7fd59977 89 }
7fd59977 90}
91
92//=======================================================================
93static void TranslateTo (const TopoDS_Shape& theShape,
94 BinObjMgt_Persistent& theResult,
95 BinTools_ShapeSet& theShapeSet)
96{
97 // Check for empty shape
98 if (theShape.IsNull()) {
99 theResult.PutInteger(-1);
100 theResult.PutInteger(-1);
101 theResult.PutInteger(-1);
102 return;
103 }
104 // Add to shape set both TShape and Location contained in <theShape>
105 const Standard_Integer aTShapeID = theShapeSet.Add (theShape);
106 const Standard_Integer aLocID =
107 theShapeSet.Locations().Index (theShape.Location());
108
109 // Fill theResult with shape parameters: TShape ID, Location, Orientation
110 theResult << aTShapeID;
111 theResult << aLocID;
112 theResult << OrientationToChar(theShape.Orientation());
113}
114//=======================================================================
115static int TranslateFrom (const BinObjMgt_Persistent& theSource,
116 TopoDS_Shape& theResult,
117 BinTools_ShapeSet& theShapeSet)
118{
119 Standard_Integer aShapeID, aLocID;
120 Standard_Character aCharOrient;
121 Standard_Boolean Ok = theSource >> aShapeID; //TShapeID;
122 if(!Ok) return 1;
123 // Read TShape and Orientation
124 if (aShapeID <= 0 || aShapeID > theShapeSet.NbShapes())
125 return 1;
126 Ok = theSource >> aLocID;
127 if(!Ok) return 1;
128 Ok = theSource >> aCharOrient;
129 if(!Ok) return 1;
130 TopAbs_Orientation anOrient = CharToOrientation(aCharOrient);
131
132 theResult.TShape (theShapeSet.Shape(aShapeID).TShape());//TShape
133 theResult.Location (theShapeSet.Locations().Location (aLocID)); //Location
134 theResult.Orientation (anOrient);//Orientation
135 return 0;
136}
137
138//=======================================================================
139//function : BinMNaming_NamedShapeDriver
140//purpose : Constructor
141//=======================================================================
142
143BinMNaming_NamedShapeDriver::BinMNaming_NamedShapeDriver
83ae3591 144 (const Handle(Message_Messenger)& theMsgDriver)
9f45d35b 145: BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(TNaming_NamedShape)->Name())
7fd59977 146{
147}
148
149//=======================================================================
150//function : NewEmpty
151//purpose :
152//=======================================================================
153
154Handle(TDF_Attribute) BinMNaming_NamedShapeDriver::NewEmpty() const
155{
156 return new TNaming_NamedShape();
157}
158
159//=======================================================================
160//function : Paste
161//purpose : persistent => transient (retrieve)
162//=======================================================================
163
164Standard_Boolean BinMNaming_NamedShapeDriver::Paste
165 (const BinObjMgt_Persistent& theSource,
166 const Handle(TDF_Attribute)& theTarget,
167 BinObjMgt_RRelocationTable& ) const
168{
169 Handle(TNaming_NamedShape) aTAtt= Handle(TNaming_NamedShape)::DownCast(theTarget);
170 Standard_Integer aNbShapes;
171 theSource >> aNbShapes;
172 TDF_Label aLabel = theTarget->Label ();
173 TNaming_Builder aBuilder (aLabel);
7fd59977 174 Standard_Integer aVer;
175 Standard_Boolean ok = theSource >> aVer;
176 if(!ok) return Standard_False;
177 aTAtt->SetVersion(aVer); //Version
178 Standard_Character aCharEvol;
179 ok = theSource >> aCharEvol;
180 if(!ok) return Standard_False;
181 TNaming_Evolution anEvol = EvolutionToEnum(aCharEvol); //Evolution
182 aTAtt->SetVersion(anEvol);
183
184 BinTools_ShapeSet& aShapeSet = (BinTools_ShapeSet&) myShapeSet;
185
8ce97bc9 186 NCollection_List<TopoDS_Shape> anOldShapes, aNewShapes;
187 for (Standard_Integer i = 1; i <= aNbShapes; i++)
188 {
7fd59977 189 TopoDS_Shape anOldShape, aNewShape;
8ce97bc9 190
191 if (anEvol != TNaming_PRIMITIVE)
192 if (TranslateFrom (theSource, anOldShape, aShapeSet)) return Standard_False;
193
194 if (anEvol != TNaming_DELETE)
195 if (TranslateFrom (theSource, aNewShape, aShapeSet)) return Standard_False;
196
197 // Here we add shapes in reverse order because TNaming_Builder also adds them in reverse order.
198 anOldShapes.Prepend (anOldShape);
199 aNewShapes.Prepend (aNewShape);
200 }
201
202 for (NCollection_List<TopoDS_Shape>::Iterator anOldIt (anOldShapes), aNewIt (aNewShapes);
203 anOldIt.More() && aNewIt.More();
204 anOldIt.Next(), aNewIt.Next())
205 {
206 switch (anEvol)
207 {
208 case TNaming_PRIMITIVE:
209 aBuilder.Generated (aNewIt.Value ());
210 break;
211 case TNaming_GENERATED:
212 aBuilder.Generated (anOldIt.Value(), aNewIt.Value());
213 break;
214 case TNaming_MODIFY:
215 aBuilder.Modify (anOldIt.Value(), aNewIt.Value());
216 break;
217 case TNaming_DELETE:
218 aBuilder.Delete (anOldIt.Value());
219 break;
220 case TNaming_SELECTED:
221 aBuilder.Select (aNewIt.Value(), anOldIt.Value());
222 break;
223 case TNaming_REPLACE:
224 aBuilder.Modify (anOldIt.Value(), aNewIt.Value()); // for compatibility aBuilder.Replace(anOldShape, aNewShape);
225 break;
226 default:
227 throw Standard_DomainError("TNaming_Evolution:: Evolution Unknown");
7fd59977 228 }
7fd59977 229 }
230 return Standard_True;
231}
232
233//=======================================================================
234//function : Paste
235//purpose : transient => persistent (store)
236//=======================================================================
237
238void BinMNaming_NamedShapeDriver::Paste (const Handle(TDF_Attribute)& theSource,
239 BinObjMgt_Persistent& theTarget,
240 BinObjMgt_SRelocationTable& ) const
241{
242 Handle(TNaming_NamedShape) aSAtt= Handle(TNaming_NamedShape)::DownCast(theSource);
243
244 //--------------------------------------------------------------
245 Standard_Integer NbShapes = 0;
246 for (TNaming_Iterator SItr (aSAtt); SItr.More (); SItr.Next ()) NbShapes++;
247 //--------------------------------------------------------------
248
7fd59977 249 BinTools_ShapeSet& aShapeSet = (BinTools_ShapeSet&) myShapeSet;
250 TNaming_Evolution anEvol = aSAtt->Evolution();
251
252 theTarget << NbShapes;
253 theTarget << aSAtt->Version();
254 theTarget << EvolutionToChar(anEvol);
255
256
257 Standard_Integer i = 1;
258 for (TNaming_Iterator SIterator(aSAtt) ;SIterator.More(); SIterator.Next()) {
259 const TopoDS_Shape& OldShape = SIterator.OldShape();
260 const TopoDS_Shape& NewShape = SIterator.NewShape();
261
262 if ( anEvol != TNaming_PRIMITIVE )
263 TranslateTo (OldShape, theTarget, aShapeSet);
264
265 if (anEvol != TNaming_DELETE)
266 TranslateTo (NewShape, theTarget, aShapeSet);
267
268 i++;
269 }
270
271}
272
273
274//=======================================================================
275//function : WriteShapeSection
276//purpose :
277//=======================================================================
278
6d8f9f4a 279void BinMNaming_NamedShapeDriver::WriteShapeSection (Standard_OStream& theOS,
9f45d35b 280 const Standard_Integer theDocVer,
7e785937 281 const Message_ProgressRange& theRange)
7fd59977 282{
283 theOS << SHAPESET;
9f45d35b 284 if (theDocVer >= TDocStd_FormatVersion_VERSION_11)
285 {
286 myShapeSet.SetFormatNb(BinTools_FormatVersion_VERSION_4);
287 }
288 else
289 {
290 myShapeSet.SetFormatNb(BinTools_FormatVersion_VERSION_1);
291 }
292
7e785937 293 myShapeSet.Write (theOS, theRange);
7fd59977 294 myShapeSet.Clear();
295}
296
297//=======================================================================
298//function : Clear
299//purpose :
300//=======================================================================
301
302void BinMNaming_NamedShapeDriver::Clear()
303{
304 myShapeSet.Clear();
305}
306
307//=======================================================================
308//function : ReadShapeSection
309//purpose :
310//=======================================================================
311
6d8f9f4a 312void BinMNaming_NamedShapeDriver::ReadShapeSection (Standard_IStream& theIS,
7e785937 313 const Message_ProgressRange& theRange)
7fd59977 314{
315 // check section title string; note that some versions of OCCT (up to 6.3.1)
316 // might avoid writing shape section if it is empty
105aae76 317 std::streamoff aPos = theIS.tellg();
7fd59977 318 TCollection_AsciiString aSectionTitle;
319 theIS >> aSectionTitle;
320 if(aSectionTitle.Length() > 0 && aSectionTitle == SHAPESET) {
321 myShapeSet.Clear();
7e785937 322 myShapeSet.Read (theIS, theRange);
7fd59977 323 }
324 else
325 theIS.seekg(aPos); // no shape section is present, try to return to initial point
326}