b311480e |
1 | // Created on: 2004-04-08 |
2 | // Created by: Sergey ZARITCHNY |
973c2be1 |
3 | // Copyright (c) 2004-2014 OPEN CASCADE SAS |
b311480e |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
b311480e |
6 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
7fd59977 |
15 | |
42cf5bc1 |
16 | |
17 | #include <BinMNaming_NamedShapeDriver.hxx> |
18 | #include <BinObjMgt_Persistent.hxx> |
19 | #include <BinTools_LocationSet.hxx> |
20 | #include <BinTools_ShapeSet.hxx> |
83ae3591 |
21 | #include <Message_Messenger.hxx> |
7fd59977 |
22 | #include <Standard_DomainError.hxx> |
42cf5bc1 |
23 | #include <Standard_Type.hxx> |
24 | #include <TCollection_AsciiString.hxx> |
25 | #include <TDF_Attribute.hxx> |
7fd59977 |
26 | #include <TDF_Label.hxx> |
9f45d35b |
27 | #include <TDocStd_FormatVersion.hxx> |
42cf5bc1 |
28 | #include <TNaming_Builder.hxx> |
29 | #include <TNaming_Evolution.hxx> |
7fd59977 |
30 | #include <TNaming_Iterator.hxx> |
42cf5bc1 |
31 | #include <TNaming_NamedShape.hxx> |
7fd59977 |
32 | #include <TopAbs_Orientation.hxx> |
42cf5bc1 |
33 | #include <TopoDS_Shape.hxx> |
7fd59977 |
34 | |
92efcf78 |
35 | IMPLEMENT_STANDARD_RTTIEXT(BinMNaming_NamedShapeDriver,BinMDF_ADriver) |
36 | |
7fd59977 |
37 | #define SHAPESET "SHAPE_SECTION" |
7fd59977 |
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'; |
566f8441 |
47 | case TNaming_REPLACE : return 'M'; // for compatibility case TNaming_REPLACE : return 'R'; |
7fd59977 |
48 | default: |
9775fa61 |
49 | throw Standard_DomainError("TNaming_Evolution:: Evolution Unknown"); |
7fd59977 |
50 | } |
7fd59977 |
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; |
1ec8a59e |
62 | case 'R': return TNaming_MODIFY; //for compatibility //TNaming_REPLACE; |
7fd59977 |
63 | default: |
9775fa61 |
64 | throw Standard_DomainError("TNaming_Evolution:: Evolution Unknown"); |
7fd59977 |
65 | } |
7fd59977 |
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: |
9775fa61 |
76 | throw Standard_DomainError("TopAbs_Orientation:: Orientation Unknown"); |
7fd59977 |
77 | } |
7fd59977 |
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: |
9775fa61 |
88 | throw Standard_DomainError("TopAbs_Orientation:: Orientation Unknown"); |
7fd59977 |
89 | } |
7fd59977 |
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 |
83ae3591 |
144 | (const Handle(Message_Messenger)& theMsgDriver) |
9f45d35b |
145 | : BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(TNaming_NamedShape)->Name()) |
7fd59977 |
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); |
7fd59977 |
174 | Standard_Integer aVer; |
175 | Standard_Boolean ok = theSource >> aVer; |
176 | if(!ok) return Standard_False; |
177 | aTAtt->SetVersion(aVer); //Version |
178 | Standard_Character aCharEvol; |
179 | ok = theSource >> aCharEvol; |
180 | if(!ok) return Standard_False; |
181 | TNaming_Evolution anEvol = EvolutionToEnum(aCharEvol); //Evolution |
182 | aTAtt->SetVersion(anEvol); |
183 | |
184 | BinTools_ShapeSet& aShapeSet = (BinTools_ShapeSet&) myShapeSet; |
185 | |
8ce97bc9 |
186 | NCollection_List<TopoDS_Shape> anOldShapes, aNewShapes; |
187 | for (Standard_Integer i = 1; i <= aNbShapes; i++) |
188 | { |
7fd59977 |
189 | TopoDS_Shape anOldShape, aNewShape; |
8ce97bc9 |
190 | |
191 | if (anEvol != TNaming_PRIMITIVE) |
192 | if (TranslateFrom (theSource, anOldShape, aShapeSet)) return Standard_False; |
193 | |
194 | if (anEvol != TNaming_DELETE) |
195 | if (TranslateFrom (theSource, aNewShape, aShapeSet)) return Standard_False; |
196 | |
197 | // Here we add shapes in reverse order because TNaming_Builder also adds them in reverse order. |
198 | anOldShapes.Prepend (anOldShape); |
199 | aNewShapes.Prepend (aNewShape); |
200 | } |
201 | |
202 | for (NCollection_List<TopoDS_Shape>::Iterator anOldIt (anOldShapes), aNewIt (aNewShapes); |
203 | anOldIt.More() && aNewIt.More(); |
204 | anOldIt.Next(), aNewIt.Next()) |
205 | { |
206 | switch (anEvol) |
207 | { |
208 | case TNaming_PRIMITIVE: |
209 | aBuilder.Generated (aNewIt.Value ()); |
210 | break; |
211 | case TNaming_GENERATED: |
212 | aBuilder.Generated (anOldIt.Value(), aNewIt.Value()); |
213 | break; |
214 | case TNaming_MODIFY: |
215 | aBuilder.Modify (anOldIt.Value(), aNewIt.Value()); |
216 | break; |
217 | case TNaming_DELETE: |
218 | aBuilder.Delete (anOldIt.Value()); |
219 | break; |
220 | case TNaming_SELECTED: |
221 | aBuilder.Select (aNewIt.Value(), anOldIt.Value()); |
222 | break; |
223 | case TNaming_REPLACE: |
224 | aBuilder.Modify (anOldIt.Value(), aNewIt.Value()); // for compatibility aBuilder.Replace(anOldShape, aNewShape); |
225 | break; |
226 | default: |
227 | throw Standard_DomainError("TNaming_Evolution:: Evolution Unknown"); |
7fd59977 |
228 | } |
7fd59977 |
229 | } |
230 | return Standard_True; |
231 | } |
232 | |
233 | //======================================================================= |
234 | //function : Paste |
235 | //purpose : transient => persistent (store) |
236 | //======================================================================= |
237 | |
238 | void BinMNaming_NamedShapeDriver::Paste (const Handle(TDF_Attribute)& theSource, |
239 | BinObjMgt_Persistent& theTarget, |
240 | BinObjMgt_SRelocationTable& ) const |
241 | { |
242 | Handle(TNaming_NamedShape) aSAtt= Handle(TNaming_NamedShape)::DownCast(theSource); |
243 | |
244 | //-------------------------------------------------------------- |
245 | Standard_Integer NbShapes = 0; |
246 | for (TNaming_Iterator SItr (aSAtt); SItr.More (); SItr.Next ()) NbShapes++; |
247 | //-------------------------------------------------------------- |
248 | |
7fd59977 |
249 | BinTools_ShapeSet& aShapeSet = (BinTools_ShapeSet&) myShapeSet; |
250 | TNaming_Evolution anEvol = aSAtt->Evolution(); |
251 | |
252 | theTarget << NbShapes; |
253 | theTarget << aSAtt->Version(); |
254 | theTarget << EvolutionToChar(anEvol); |
255 | |
256 | |
257 | Standard_Integer i = 1; |
258 | for (TNaming_Iterator SIterator(aSAtt) ;SIterator.More(); SIterator.Next()) { |
259 | const TopoDS_Shape& OldShape = SIterator.OldShape(); |
260 | const TopoDS_Shape& NewShape = SIterator.NewShape(); |
261 | |
262 | if ( anEvol != TNaming_PRIMITIVE ) |
263 | TranslateTo (OldShape, theTarget, aShapeSet); |
264 | |
265 | if (anEvol != TNaming_DELETE) |
266 | TranslateTo (NewShape, theTarget, aShapeSet); |
267 | |
268 | i++; |
269 | } |
270 | |
271 | } |
272 | |
273 | |
274 | //======================================================================= |
275 | //function : WriteShapeSection |
276 | //purpose : |
277 | //======================================================================= |
278 | |
6d8f9f4a |
279 | void BinMNaming_NamedShapeDriver::WriteShapeSection (Standard_OStream& theOS, |
9f45d35b |
280 | const Standard_Integer theDocVer, |
7e785937 |
281 | const Message_ProgressRange& theRange) |
7fd59977 |
282 | { |
283 | theOS << SHAPESET; |
9f45d35b |
284 | if (theDocVer >= TDocStd_FormatVersion_VERSION_11) |
285 | { |
286 | myShapeSet.SetFormatNb(BinTools_FormatVersion_VERSION_4); |
287 | } |
288 | else |
289 | { |
290 | myShapeSet.SetFormatNb(BinTools_FormatVersion_VERSION_1); |
291 | } |
292 | |
7e785937 |
293 | myShapeSet.Write (theOS, theRange); |
7fd59977 |
294 | myShapeSet.Clear(); |
295 | } |
296 | |
297 | //======================================================================= |
298 | //function : Clear |
299 | //purpose : |
300 | //======================================================================= |
301 | |
302 | void BinMNaming_NamedShapeDriver::Clear() |
303 | { |
304 | myShapeSet.Clear(); |
305 | } |
306 | |
307 | //======================================================================= |
308 | //function : ReadShapeSection |
309 | //purpose : |
310 | //======================================================================= |
311 | |
6d8f9f4a |
312 | void BinMNaming_NamedShapeDriver::ReadShapeSection (Standard_IStream& theIS, |
7e785937 |
313 | const Message_ProgressRange& theRange) |
7fd59977 |
314 | { |
315 | // check section title string; note that some versions of OCCT (up to 6.3.1) |
316 | // might avoid writing shape section if it is empty |
105aae76 |
317 | std::streamoff aPos = theIS.tellg(); |
7fd59977 |
318 | TCollection_AsciiString aSectionTitle; |
319 | theIS >> aSectionTitle; |
320 | if(aSectionTitle.Length() > 0 && aSectionTitle == SHAPESET) { |
321 | myShapeSet.Clear(); |
7e785937 |
322 | myShapeSet.Read (theIS, theRange); |
7fd59977 |
323 | } |
324 | else |
325 | theIS.seekg(aPos); // no shape section is present, try to return to initial point |
326 | } |