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