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