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