4f0a04a1c8bac77cc2a14323c56bbcbb13889024
[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
17 #include <BinMNaming_NamedShapeDriver.hxx>
18 #include <BinObjMgt_Persistent.hxx>
19 #include <BinTools_LocationSet.hxx>
20 #include <BinTools_ShapeSet.hxx>
21 #include <CDM_MessageDriver.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>
33
34 IMPLEMENT_STANDARD_RTTIEXT(BinMNaming_NamedShapeDriver,BinMDF_ADriver)
35
36 #define SHAPESET "SHAPE_SECTION"
37 #define FORMAT_NUMBER 3
38 //=======================================================================
39 static 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';
47     case TNaming_REPLACE      : return 'M'; // for compatibility case TNaming_REPLACE      : return 'R';
48   default:
49     throw Standard_DomainError("TNaming_Evolution:: Evolution Unknown");
50   }
51 }
52
53 //=======================================================================
54 static 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;
62     case 'R': return TNaming_MODIFY; //for compatibility //TNaming_REPLACE;
63   default:
64     throw Standard_DomainError("TNaming_Evolution:: Evolution Unknown");
65   }
66 }
67 //=======================================================================
68 static 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:
76     throw Standard_DomainError("TopAbs_Orientation:: Orientation Unknown");
77   }
78 }
79 //=======================================================================
80 static 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:
88     throw Standard_DomainError("TopAbs_Orientation:: Orientation Unknown");
89   }
90 }
91
92 //=======================================================================
93 static 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 //=======================================================================
115 static 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
143 BinMNaming_NamedShapeDriver::BinMNaming_NamedShapeDriver
144                         (const Handle(CDM_MessageDriver)& theMsgDriver)
145      : BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(TNaming_NamedShape)->Name()), myShapeSet(Standard_False),myFormatNb(FORMAT_NUMBER)
146 {
147 }
148
149 //=======================================================================
150 //function : NewEmpty
151 //purpose  : 
152 //=======================================================================
153
154 Handle(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
164 Standard_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);
174   if (aNbShapes == 0) return Standard_False;
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);
184
185   BinTools_ShapeSet& aShapeSet = (BinTools_ShapeSet&) myShapeSet;
186
187   NCollection_List<TopoDS_Shape> anOldShapes, aNewShapes;
188   for (Standard_Integer i = 1; i <= aNbShapes; i++)
189   {
190     TopoDS_Shape anOldShape, aNewShape;
191
192     if (anEvol != TNaming_PRIMITIVE)
193       if (TranslateFrom (theSource, anOldShape, aShapeSet)) return Standard_False;
194
195     if (anEvol != TNaming_DELETE)
196       if (TranslateFrom (theSource, aNewShape, aShapeSet)) return Standard_False;
197
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);
201   }
202
203   for (NCollection_List<TopoDS_Shape>::Iterator anOldIt (anOldShapes), aNewIt (aNewShapes);
204       anOldIt.More() && aNewIt.More();
205       anOldIt.Next(), aNewIt.Next())
206   {
207     switch (anEvol)
208     {
209       case TNaming_PRIMITIVE:
210         aBuilder.Generated (aNewIt.Value ());
211         break;
212       case TNaming_GENERATED:
213         aBuilder.Generated (anOldIt.Value(), aNewIt.Value());
214         break;
215       case TNaming_MODIFY:
216         aBuilder.Modify (anOldIt.Value(), aNewIt.Value());
217         break;
218       case TNaming_DELETE:
219         aBuilder.Delete (anOldIt.Value());
220         break;
221       case TNaming_SELECTED:
222         aBuilder.Select (aNewIt.Value(), anOldIt.Value());
223         break;
224       case TNaming_REPLACE:
225         aBuilder.Modify (anOldIt.Value(), aNewIt.Value()); // for compatibility aBuilder.Replace(anOldShape, aNewShape);
226         break;
227       default:
228           throw Standard_DomainError("TNaming_Evolution:: Evolution Unknown");
229     }
230   }
231   return Standard_True;
232 }
233
234 //=======================================================================
235 //function : Paste
236 //purpose  : transient => persistent (store)
237 //=======================================================================
238
239 void BinMNaming_NamedShapeDriver::Paste (const Handle(TDF_Attribute)& theSource,
240                                          BinObjMgt_Persistent&        theTarget,
241                                          BinObjMgt_SRelocationTable&  ) const
242 {
243   Handle(TNaming_NamedShape) aSAtt= Handle(TNaming_NamedShape)::DownCast(theSource);
244
245   //--------------------------------------------------------------
246   Standard_Integer NbShapes = 0;
247   for (TNaming_Iterator SItr (aSAtt); SItr.More (); SItr.Next ()) NbShapes++;
248   //--------------------------------------------------------------
249
250   if (NbShapes == 0) return;
251
252   BinTools_ShapeSet& aShapeSet = (BinTools_ShapeSet&) myShapeSet;
253   TNaming_Evolution anEvol = aSAtt->Evolution();
254   
255   theTarget << NbShapes;
256   theTarget << aSAtt->Version();
257   theTarget << EvolutionToChar(anEvol);
258  
259
260   Standard_Integer i = 1;  
261   for (TNaming_Iterator SIterator(aSAtt) ;SIterator.More(); SIterator.Next()) {
262     const TopoDS_Shape& OldShape = SIterator.OldShape();
263     const TopoDS_Shape& NewShape = SIterator.NewShape();
264     
265     if ( anEvol != TNaming_PRIMITIVE ) 
266       TranslateTo (OldShape, theTarget, aShapeSet); 
267
268     if (anEvol != TNaming_DELETE) 
269       TranslateTo (NewShape, theTarget, aShapeSet);
270     
271     i++;
272   }
273
274 }
275
276
277 //=======================================================================
278 //function : WriteShapeSection
279 //purpose  : 
280 //=======================================================================
281
282 void BinMNaming_NamedShapeDriver::WriteShapeSection (Standard_OStream& theOS)
283 {
284   theOS << SHAPESET; 
285   myShapeSet.SetFormatNb(myFormatNb);
286   myShapeSet.Write (theOS);
287   myShapeSet.Clear();
288 }
289
290 //=======================================================================
291 //function : Clear
292 //purpose  : 
293 //=======================================================================
294
295 void BinMNaming_NamedShapeDriver::Clear()
296 {
297   myShapeSet.Clear();
298 }
299
300 //=======================================================================
301 //function : ReadShapeSection
302 //purpose  : 
303 //=======================================================================
304
305 void BinMNaming_NamedShapeDriver::ReadShapeSection (Standard_IStream& theIS)
306 {
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) {
313     myShapeSet.Clear();
314     myShapeSet.Read (theIS);
315     SetFormatNb(myShapeSet.FormatNb());
316   }
317   else
318     theIS.seekg(aPos); // no shape section is present, try to return to initial point
319 }
320