7fb92d6c54077126bef4cbacb085b648976e3c60
[occt.git] / src / BinMNaming / BinMNaming_NamingDriver.cxx
1 // Created on: 2004-05-13
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 <BinMDF_ADriver.hxx>
18 #include <BinMNaming.hxx>
19 #include <BinMNaming_NamingDriver.hxx>
20 #include <BinObjMgt_Persistent.hxx>
21 #include <BinObjMgt_RRelocationTable.hxx>
22 #include <BinObjMgt_SRelocationTable.hxx>
23 #include <CDM_MessageDriver.hxx>
24 #include <Standard_Type.hxx>
25 #include <TCollection_AsciiString.hxx>
26 #include <TCollection_ExtendedString.hxx>
27 #include <TColStd_Array1OfInteger.hxx>
28 #include <TDF_Attribute.hxx>
29 #include <TDF_Tool.hxx>
30 #include <TNaming_Iterator.hxx>
31 #include <TNaming_ListIteratorOfListOfNamedShape.hxx>
32 #include <TNaming_NamedShape.hxx>
33 #include <TNaming_NameType.hxx>
34 #include <TNaming_Naming.hxx>
35 #include <TopAbs_ShapeEnum.hxx>
36
37 #define  NULL_ENTRY "0:0"
38 #define  OBSOLETE_NUM (int)sizeof(Standard_Integer)
39
40 //=======================================================================
41 // 'Z' - is reserved for: forfidden to use
42 //=======================================================================
43 static Standard_Character NameTypeToChar(const TNaming_NameType theNameType)
44 {
45   switch(theNameType) {
46     case TNaming_UNKNOWN      : return 'N';
47     case TNaming_IDENTITY     : return 'I';
48     case TNaming_MODIFUNTIL   : return 'M';
49     case TNaming_GENERATION   : return 'G';
50     case TNaming_INTERSECTION : return 'S';
51     case TNaming_UNION        : return 'U';
52     case TNaming_SUBSTRACTION : return 'B';
53     case TNaming_CONSTSHAPE   : return 'C';
54     case TNaming_FILTERBYNEIGHBOURGS : return 'F';
55     case TNaming_ORIENTATION  : return 'O'; 
56     case TNaming_WIREIN       : return 'W';
57     case TNaming_SHELLIN      : return 'H';
58   default:
59     Standard_DomainError::Raise("TNaming_NameType:: Name Type Unknown");
60   }
61   return 'N'; // To avoid compilation error message.
62 }
63
64 //=======================================================================
65 static TNaming_NameType CharTypeToName(const Standard_Character theCharType)
66 {
67   switch(theCharType) {
68     case 'N'  : return TNaming_UNKNOWN;
69     case 'I'  : return TNaming_IDENTITY;
70     case 'M'  : return TNaming_MODIFUNTIL;
71     case 'G'  : return TNaming_GENERATION;
72     case 'S'  : return TNaming_INTERSECTION;
73     case 'U'  : return TNaming_UNION;
74     case 'B'  : return TNaming_SUBSTRACTION;
75     case 'C'  : return TNaming_CONSTSHAPE;
76     case 'F'  : return TNaming_FILTERBYNEIGHBOURGS;
77     case 'O'  : return TNaming_ORIENTATION;
78     case 'W'  : return TNaming_WIREIN;
79     case 'H'  : return TNaming_SHELLIN;
80   default:
81     Standard_DomainError::Raise("TNaming_NameType:: Name Type Unknown");
82   }
83   return TNaming_UNKNOWN; // To avoid compilation error message.
84 }
85
86 //=======================================================================
87 static Standard_Character ShapeTypeToChar(const TopAbs_ShapeEnum theShapeType)
88 {
89   switch (theShapeType)
90     {
91     case TopAbs_COMPOUND  : return 'C';
92     case TopAbs_COMPSOLID : return 'O';
93     case TopAbs_SOLID     : return 'S';
94     case TopAbs_SHELL     : return 'H';
95     case TopAbs_FACE      : return 'F';
96     case TopAbs_WIRE      : return 'W';
97     case TopAbs_EDGE      : return 'E';
98     case TopAbs_VERTEX    : return 'V';
99     case TopAbs_SHAPE     : return 'A';
100     }
101   return 'A'; // To avoid compilation error message.
102 }
103 //=======================================================================
104 static TopAbs_ShapeEnum CharToShapeType(const Standard_Character theCharType)
105 {
106   switch (theCharType)
107     {
108     case 'C' : return TopAbs_COMPOUND;
109     case 'O' : return TopAbs_COMPSOLID;
110     case 'S' : return TopAbs_SOLID;
111     case 'H' : return TopAbs_SHELL;
112     case 'F' : return TopAbs_FACE;
113     case 'W' : return TopAbs_WIRE;
114     case 'E' : return TopAbs_EDGE;
115     case 'V' : return TopAbs_VERTEX;
116     case 'A' : return TopAbs_SHAPE;
117     }
118   return TopAbs_SHAPE; // To avoid compilation error message.
119 }
120 //=======================================================================
121 //function : BinMNaming_NamingDriver
122 //purpose  : Constructor
123 //=======================================================================
124
125 BinMNaming_NamingDriver::BinMNaming_NamingDriver
126                         (const Handle(CDM_MessageDriver)& theMsgDriver)
127      : BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(TNaming_Naming)->Name())
128 {
129 }
130
131 //=======================================================================
132 //function : NewEmpty
133 //purpose  : 
134 //=======================================================================
135
136 Handle(TDF_Attribute) BinMNaming_NamingDriver::NewEmpty() const
137 {
138   return new TNaming_Naming();
139 }
140
141 //=======================================================================
142 //function : Paste
143 //purpose  : persistent -> transient (retrieve)
144 //=======================================================================
145
146 Standard_Boolean BinMNaming_NamingDriver::Paste
147                                 (const BinObjMgt_Persistent&  theSource,
148                                  const Handle(TDF_Attribute)& theTarget,
149                                  BinObjMgt_RRelocationTable&  theRelocTable) const
150 {
151   Handle(TNaming_Naming) anAtt = Handle(TNaming_Naming)::DownCast(theTarget);
152   if(anAtt.IsNull()) return Standard_False;
153
154   TNaming_Name& aName = anAtt->ChangeName();
155   TCollection_ExtendedString aMsg;
156 //1. NameType
157   Standard_Character aValue;
158   Standard_Boolean ok = theSource >> aValue;
159   Standard_Boolean aNewF = Standard_False;
160   if (ok) {
161     if(aValue == 'Z') {      // new format
162       aNewF = Standard_True;
163       ok = theSource >> aValue; //skip the sign & get NameType
164       if(!ok) return ok;
165     }
166
167     aName.Type(CharTypeToName(aValue));
168
169 //2. ShapeType    
170     ok = theSource >> aValue;
171     if (ok) {
172       aName.ShapeType(CharToShapeType(aValue));
173       
174 //3. Args
175       Standard_Integer aNbArgs=0;
176       Standard_Integer anIndx;
177       Handle(TNaming_NamedShape) aNS;
178       ok = theSource >> aNbArgs;
179       if (ok) {
180         if(aNbArgs > 0) {
181           Standard_Integer i;
182           // read array
183           for(i=1; i<=aNbArgs;i++) {
184             if(!aNewF && i > OBSOLETE_NUM) break;//interrupt reading as old format can have only 4 items
185             ok = theSource >> anIndx;
186             if (!ok)
187               break;
188             else {
189               if (theRelocTable.IsBound(anIndx))
190                 aNS = Handle(TNaming_NamedShape)::DownCast(theRelocTable.Find(anIndx));
191               else {
192                 aNS = new TNaming_NamedShape;
193                 theRelocTable.Bind(anIndx, aNS);
194               }
195               aName.Append(aNS);
196             }
197           }
198           //patch to release the rest of items  
199           if(!aNewF && aNbArgs < OBSOLETE_NUM) {    
200             for(i = aNbArgs+1;i <= OBSOLETE_NUM;i++)
201               theSource >> anIndx;
202           }
203         }
204 //4. StopNS
205         ok = theSource >> anIndx;
206         if(ok) {
207           if(anIndx > 0) {
208             if (theRelocTable.IsBound(anIndx))
209               aNS = Handle(TNaming_NamedShape)::DownCast(theRelocTable.Find(anIndx));
210             else
211             {
212               aNS = new TNaming_NamedShape;
213               theRelocTable.Bind(anIndx, aNS);
214             }
215             aName.StopNamedShape(aNS);  
216           }
217
218 //5. Index
219           ok = theSource >> anIndx;
220           if(ok) 
221             aName.Index(anIndx);
222           else {
223             aMsg = TCollection_ExtendedString("BinMNaming_NamingDriver: "
224                                               "Cannot retrieve Index of Name");
225             WriteMessage (aMsg); 
226           }
227         } else {
228           aMsg = TCollection_ExtendedString("BinMNaming_NamingDriver: "
229                                             "Cannot retrieve reference on "
230                                             "StopNamedShape");
231           WriteMessage (aMsg); 
232         }
233       } else {
234         aMsg = TCollection_ExtendedString("BinMNaming_NamingDriver: "
235                                           "Cannot retrieve reference on "
236                                           "Arguments of Name");
237         WriteMessage (aMsg);
238           }
239
240     if(BinMNaming::DocumentVersion() > 3) {
241         TCollection_AsciiString entry;
242         ok = theSource >> entry;
243         if(ok) {
244 #ifdef OCCT_DEBUG
245           cout << "NamingDriver:: Retrieved Context Label = " << entry << " Ok = " << theSource.IsOK()  <<endl;
246 #endif
247          
248 //6. context label
249           if(!entry.IsEmpty() && !entry.IsEqual(TCollection_AsciiString(NULL_ENTRY))) 
250             {
251               TDF_Label tLab; // Null label.
252               TDF_Tool::Label(anAtt->Label().Data(),entry, tLab, Standard_True);
253               if (!tLab.IsNull()) 
254                 aName.ContextLabel(tLab);
255             }
256         }
257     if(BinMNaming::DocumentVersion() > 4 && BinMNaming::DocumentVersion() < 7) {
258           // Orientation processing - converting from old format
259       Handle(TNaming_NamedShape) aNS;
260       if(anAtt->Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
261             //const TDF_Label& aLab = aNS->Label();
262         TNaming_Iterator itL (aNS);
263         for (; itL.More(); itL.Next()) {
264           const TopoDS_Shape& S = itL.NewShape();
265           if (S.IsNull()) continue;
266           if(aNS->Evolution() == TNaming_SELECTED) {
267             if (itL.More() && itL.NewShape().ShapeType() != TopAbs_VERTEX &&
268                   !itL.OldShape().IsNull() && itL.OldShape().ShapeType() == TopAbs_VERTEX ) {//OR-N
269               TopAbs_Orientation OrientationToApply = itL.OldShape().Orientation();
270               aName.Orientation(OrientationToApply);
271                         }
272                   }
273                 }
274           }
275         }
276     if(BinMNaming::DocumentVersion() > 6) {
277       ok = theSource >> anIndx;
278       TopAbs_Orientation OrientationToApply(TopAbs_FORWARD);
279       if(ok) {
280         OrientationToApply = (TopAbs_Orientation)anIndx;
281                 aName.Orientation(OrientationToApply);
282 #ifdef OCCT_DEBUG
283             cout << "NamingDriver:: Retrieved Orientation = " << OrientationToApply << " Ok = " << theSource.IsOK()  <<endl;
284 #endif
285           } else {
286           aMsg = TCollection_ExtendedString("BinMNaming_NamingDriver: "
287                                             "Cannot retrieve Name Orientation ");
288           WriteMessage (aMsg);
289           }
290         }
291         }
292 #ifdef OCCT_DEBUG
293       else if(BinMNaming::DocumentVersion() == -1)
294         cout << "Current DocVersion field is not initialized. "  <<endl;
295       else 
296         cout << "Current DocVersion = " << BinMNaming::DocumentVersion() <<endl;
297 #endif
298         }
299   }
300   return ok;
301 }
302
303 //=======================================================================
304 //function : Paste
305 //purpose  : transient -> persistent (store)
306 //=======================================================================
307
308 void BinMNaming_NamingDriver::Paste (const Handle(TDF_Attribute)&  theSource,
309                                        BinObjMgt_Persistent&       theTarget,
310                                        BinObjMgt_SRelocationTable& theRelocTable) const
311 {
312   Handle(TNaming_Naming) anAtt = Handle(TNaming_Naming)::DownCast(theSource);
313   const TNaming_Name& aName = anAtt->GetName();
314
315 //0. add the sign of new format (to fix misprint with Array size)
316   theTarget.PutCharacter('Z');
317
318 //1. << NameType to Char
319   theTarget << NameTypeToChar(aName.Type());
320
321 //2. << ShapeType to Char
322   theTarget << ShapeTypeToChar(aName.ShapeType());
323
324 //3. Keep Args
325   Standard_Integer anIndx;
326   Standard_Integer aNbArgs = aName.Arguments().Extent();
327   theTarget << aNbArgs; // keep Number
328   if (aNbArgs > 0) {
329     Standard_Integer i=0;
330     TColStd_Array1OfInteger anArray(1, aNbArgs);
331     //fill array
332     for (TNaming_ListIteratorOfListOfNamedShape it (aName.Arguments()); it.More(); it.Next()) {
333       Handle(TNaming_NamedShape) anArg = it.Value();
334       anIndx = 0; i++;
335       if (!anArg.IsNull()) {
336         anIndx = theRelocTable.FindIndex(anArg);
337         if (anIndx == 0)
338           anIndx = theRelocTable.Add(anArg);
339       }
340       anArray.SetValue(i, anIndx);
341     }
342     
343     theTarget.PutIntArray ((BinObjMgt_PInteger) &anArray.Value(1), aNbArgs); // keep Array
344   }
345
346 //4. keep StopNS
347   Handle(TNaming_NamedShape) aStopNS = aName.StopNamedShape();
348   if (!aStopNS.IsNull()) {
349     anIndx = theRelocTable.FindIndex(aStopNS);
350     if (anIndx == 0)
351       anIndx = theRelocTable.Add(aStopNS);
352   } else 
353     anIndx = 0;
354   theTarget << anIndx;
355
356 //5. keep Index
357   theTarget << aName.Index();
358
359 //6. keep context label
360   TCollection_AsciiString entry(NULL_ENTRY);
361   if(!aName.ContextLabel().IsNull())
362     TDF_Tool::Entry(aName.ContextLabel(), entry);
363   theTarget << entry;
364
365 //7. keep Orientation
366   theTarget << (Standard_Integer)aName.Orientation();
367
368 }