3237ae4e311dd61b6c5a9128a3aacffb380e04c8
[occt.git] / src / DDocStd / DDocStd_ShapeSchemaCommands.cxx
1 // Created on: 2017-03-28
2 // Created by: Sergey NIKONOV
3 // Copyright (c) 2000-2017 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 <DDocStd.hxx>
17 #include <DBRep.hxx>
18 #include <FSD_File.hxx>
19 #include <FSD_CmpFile.hxx>
20 #include <FSD_BinaryFile.hxx>
21 #include <BRep_Builder.hxx>
22 #include <NCollection_Handle.hxx>
23 #include <TCollection_AsciiString.hxx>
24 #include <TopTools_SequenceOfShape.hxx>
25 #include <Storage_BaseDriver.hxx>
26 #include <StdStorage.hxx>
27 #include <StdStorage_Data.hxx>
28 #include <StdStorage_HeaderData.hxx>
29 #include <StdStorage_RootData.hxx>
30 #include <StdStorage_TypeData.hxx>
31 #include <ShapePersistent_TopoDS.hxx>
32
33 //=======================================================================
34 //function : DDocStd_ShapeSchema_Write 
35 //=======================================================================
36
37 static Standard_Integer DDocStd_fsdwrite(Draw_Interpretor& theDI,
38                                          Standard_Integer theArgNb,
39                                          const char** theArgs)
40 {
41   if (theArgNb < 3)
42   {
43     theDI << "Usage : fsdwrite shapes filename [gen | cmp | bin]\n";
44     theDI << "        Arguments:\n";
45     theDI << "        shapes   : list os shape names\n";
46     theDI << "        filename : output file name\n";
47     theDI << "        Storage driver:\n";
48     theDI << "          gen : FSD_File driver (default)\n";
49     theDI << "          cmp : FSD_CmpFile driver\n";
50     theDI << "          bin : FSD_BinaryFile driver\n";
51     return 1;
52   }
53
54   NCollection_Handle<Storage_BaseDriver> aFileDriver(new FSD_File);
55
56   Standard_Boolean hasStorageDriver = Standard_False;
57   Standard_Integer iArgN = theArgNb - 1;
58
59   if (strncmp(theArgs[iArgN], "gen", 3) == 0)
60   {
61     aFileDriver = new FSD_File;
62     hasStorageDriver = Standard_True;
63   }
64   else if (strncmp(theArgs[iArgN], "cmp", 3) == 0)
65   {
66     aFileDriver = new FSD_CmpFile;
67     hasStorageDriver = Standard_True;
68   }
69   else if (strncmp(theArgs[iArgN], "bin", 3) == 0)
70   {
71     aFileDriver = new FSD_BinaryFile;
72     hasStorageDriver = Standard_True;
73   }
74
75   if (hasStorageDriver) --iArgN;
76
77   Storage_Error aStatus = aFileDriver->Open(theArgs[iArgN], Storage_VSWrite);
78   if (aStatus != Storage_VSOk) {
79     theDI << "Error : couldn't open file '" << "' for writing (" << aStatus << ")\n";
80     return 1;
81   }
82
83   TopTools_SequenceOfShape aShapes;
84   NCollection_DataMap<TCollection_AsciiString, Standard_Integer> aShapeNames;
85   for (Standard_Integer i = 1; i < iArgN; ++i)
86   {
87     TopoDS_Shape aShape = DBRep::Get(theArgs[i]);
88     if (aShape.IsNull())
89     {
90       theDI << "Error : null shape " << theArgs[i] << "\n";
91       return 1;
92     }
93     aShapes.Append(aShape);
94     if (aShapeNames.IsBound(theArgs[i]))
95       aShapeNames.ChangeFind(theArgs[i]) += 1;
96     else
97       aShapeNames.Bind(theArgs[i], 1);
98   }
99
100   Handle(StdStorage_Data) aData = new StdStorage_Data;
101
102   aData->HeaderData()->SetApplicationName(TCollection_ExtendedString("DDocStd_ShapeSchema_Write"));
103
104   StdObjMgt_TransientPersistentMap aMap;
105   for (Standard_Integer i = 1; i <= aShapes.Length(); ++i)
106   {
107     TopoDS_Shape aShape = aShapes.Value(i);
108
109     Handle(ShapePersistent_TopoDS::HShape) aPShape =
110       ShapePersistent_TopoDS::Translate(aShape, aMap, ShapePersistent_WithTriangle);
111     if (aPShape.IsNull())
112     {
113       theDI << "Error : couldn't translate shape " << theArgs[i] << "\n";
114       return 1;
115     }
116     
117     TCollection_AsciiString aName = theArgs[i];
118     if (aShapeNames.IsBound(aName))
119     {
120       Standard_Integer n = aShapeNames.Find(theArgs[i]);
121       if (n > 1)
122       {
123         aName += "_";
124         aName += n;
125       }
126     }
127
128     Handle(StdStorage_Root) aRoot = new StdStorage_Root(aName, aPShape);
129     aData->RootData()->AddRoot(aRoot);
130   }
131
132   Storage_Error anError = StdStorage::Write(*aFileDriver, aData);
133
134   aFileDriver->Close();
135
136   if (anError != Storage_VSOk)
137   {
138     theDI << "Error : " << anError << "\n";
139     return 1;
140   }
141
142   return 0;
143 }
144
145 //=======================================================================
146 //function : DDocStd_ShapeSchema_Read 
147 //=======================================================================
148
149 static Standard_Integer DDocStd_fsdread(Draw_Interpretor& theDI, 
150                                         Standard_Integer theArgNb, 
151                                         const char** theArgs)
152 {
153   if (theArgNb < 3)
154   {
155     theDI << "Usage : fsdread filename shape\n";
156     theDI << "        Arguments:\n";
157     theDI << "        filename : input file name\n";
158     theDI << "        shape    : name of an output shape, or \n";
159     theDI << "                   reserved name = 'restore_with_names';\n";
160     theDI << "                   by default root shapes will be put into \n";
161     theDI << "                   a compound in case of multiple roots in the file;\n";
162     theDI << "                   if name = restore_with_names, the shapes will be put to\n";
163     theDI << "                   separate variables according kept names.\n";
164     return 1;
165   }
166   Standard_Boolean rflag(Standard_False);
167   if (strcmp(theArgs[2],"restore_with_names") == 0) 
168     rflag = Standard_True;
169   Handle(StdStorage_Data) aData;
170   Storage_Error anError = StdStorage::Read(TCollection_AsciiString(theArgs[1]), aData);
171   if (anError != Storage_VSOk)
172   {
173     theDI << "Error : " << anError << "\n";
174     return 1;
175   }
176
177   TopTools_SequenceOfShape aShapes;
178
179   Handle(StdStorage_TypeData) aTypeData = aData->TypeData();
180   Handle(StdStorage_RootData) aRootData = aData->RootData();
181   Handle(StdStorage_HSequenceOfRoots) aRoots = aRootData->Roots();
182   if (!aRoots.IsNull())
183   {
184     for (StdStorage_HSequenceOfRoots::Iterator anIt(*aRoots); anIt.More(); anIt.Next())
185     {
186       Handle(StdStorage_Root)& aRoot = anIt.ChangeValue();
187       Handle(StdObjMgt_Persistent) aPObject = aRoot->Object();
188       if (!aPObject.IsNull())
189       {
190         Handle(ShapePersistent_TopoDS::HShape) aHShape = Handle(ShapePersistent_TopoDS::HShape)::DownCast(aPObject);
191         if (aHShape) // shapes are expected
192         {
193           TopoDS_Shape aShape = aHShape->Import();
194           if(rflag) {
195             if(!aRoot->Name().IsEmpty())
196               DBRep::Set(aRoot->Name().ToCString(), aShape);
197             else {
198               TCollection_AsciiString aNam("name_");
199               aNam += aRoot->Reference();
200               DBRep::Set(aNam.ToCString(), aShape);
201             }
202 #ifdef DEBUG_FSDREAD
203             Standard_Integer indx = aRoot->Reference();
204             theDI << "Ref indx = " <<indx << " Name = " << aRoot->Name().ToCString() << "\n";
205 #endif
206           } else
207             aShapes.Append(aShape);
208         }
209       }
210     }
211   }
212
213   theDI << "Info : " << aTypeData->NumberOfTypes() << " type(s)\n";
214   theDI << "       " << aRoots->Length() << " root(s)\n";
215
216   if (!rflag) {
217     if (aShapes.Length() > 1)
218     {
219       theDI << "       " << aShapes.Length() << " shape(s) translated\n";
220       BRep_Builder aB;
221       TopoDS_Compound aC;
222       aB.MakeCompound(aC);
223       for (Standard_Integer i = 1; i <= aShapes.Length(); ++i)
224         aB.Add(aC, aShapes.Value(i));
225       DBRep::Set(theArgs[2], aC);
226     }
227     else
228       DBRep::Set(theArgs[2], aShapes.First());
229   }
230   return 0;
231 }
232
233 //=======================================================================
234 //function : ShapeSchemaCommands
235 //purpose  : registers shape schema related commands in Draw interpreter
236 //=======================================================================
237
238 void DDocStd::ShapeSchemaCommands(Draw_Interpretor& theCommands)
239 {
240   static Standard_Boolean done = Standard_False;
241   if (done) return;
242   done = Standard_True;
243
244   const char* g = "Shape persistence commands";
245
246   theCommands.Add("fsdwrite",
247     "fsdrite shape filename [driver]",
248     __FILE__, DDocStd_fsdwrite, g);
249
250   theCommands.Add("fsdread",
251     "fsdread filename shape [name | or key 'restore_with_names']",
252     __FILE__, DDocStd_fsdread, g);
253
254 }