b311480e |
1 | // Created on: 2001-07-11 |
2 | // Created by: Julia DOROVSKIKH |
973c2be1 |
3 | // Copyright (c) 2001-2014 OPEN CASCADE SAS |
b311480e |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
b311480e |
6 | // |
973c2be1 |
7 | // This library is free software; you can redistribute it and / or modify it |
8 | // under the terms of the GNU Lesser General Public 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. |
b311480e |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
b311480e |
15 | |
16 | //AGV 150202: Changed prototype LDOM_Node::getOwnerDocument() |
7fd59977 |
17 | |
18 | #include <XmlMNaming_NamedShapeDriver.ixx> |
19 | |
20 | #include <XmlObjMgt.hxx> |
21 | #include <XmlMNaming_Array1OfShape1.hxx> |
22 | #include <XmlMNaming_Shape1.hxx> |
23 | |
24 | #include <TDF_Label.hxx> |
25 | #include <TNaming_Builder.hxx> |
26 | #include <TNaming_NamedShape.hxx> |
27 | #include <TNaming_Iterator.hxx> |
28 | |
29 | #include <TopoDS_Shape.hxx> |
30 | #include <BRepTools.hxx> |
31 | #include <LDOM_Text.hxx> |
32 | #include <LDOM_OSStream.hxx> |
33 | |
34 | #include <Standard_SStream.hxx> |
35 | |
36 | static TNaming_Evolution EvolutionEnum (const XmlObjMgt_DOMString&); |
37 | static const XmlObjMgt_DOMString& EvolutionString (const TNaming_Evolution); |
38 | static void doTranslate (const TopoDS_Shape&, |
39 | XmlMNaming_Shape1&, |
40 | BRepTools_ShapeSet&); |
41 | static int doTranslate (const XmlMNaming_Shape1&, |
42 | TopoDS_Shape&, |
43 | BRepTools_ShapeSet&); |
44 | |
45 | IMPLEMENT_DOMSTRING (OldsString, "olds") |
46 | IMPLEMENT_DOMSTRING (NewsString, "news") |
47 | IMPLEMENT_DOMSTRING (StatusString, "evolution") |
48 | IMPLEMENT_DOMSTRING (VersionString, "version") |
49 | IMPLEMENT_DOMSTRING (ShapesString, "shapes") |
50 | |
51 | IMPLEMENT_DOMSTRING (EvolPrimitiveString, "primitive") |
52 | IMPLEMENT_DOMSTRING (EvolGeneratedString, "generated") |
53 | IMPLEMENT_DOMSTRING (EvolModifyString, "modify") |
54 | IMPLEMENT_DOMSTRING (EvolDeleteString, "delete") |
55 | IMPLEMENT_DOMSTRING (EvolSelectedString, "selected") |
56 | IMPLEMENT_DOMSTRING (EvolReplaceString, "replace") |
57 | |
58 | //======================================================================= |
59 | //function : XmlMNaming_NamedShapeDriver |
60 | //purpose : Constructor |
61 | //======================================================================= |
62 | |
63 | XmlMNaming_NamedShapeDriver::XmlMNaming_NamedShapeDriver |
64 | (const Handle(CDM_MessageDriver&) theMessageDriver) |
65 | : XmlMDF_ADriver (theMessageDriver, NULL), |
66 | myShapeSet (Standard_False) // triangles mode |
67 | {} |
68 | |
69 | //======================================================================= |
70 | //function : NewEmpty() |
71 | //purpose : |
72 | //======================================================================= |
73 | Handle(TDF_Attribute) XmlMNaming_NamedShapeDriver::NewEmpty () const |
74 | { |
75 | return (new TNaming_NamedShape()); |
76 | } |
77 | |
78 | //======================================================================= |
79 | //function : Paste() |
80 | //purpose : retrieval of TNaming_NamedShape |
81 | //======================================================================= |
82 | |
83 | Standard_Boolean XmlMNaming_NamedShapeDriver::Paste |
84 | (const XmlObjMgt_Persistent& theSource, |
85 | const Handle(TDF_Attribute)& theTarget, |
86 | XmlObjMgt_RRelocationTable&) const |
87 | { |
88 | Handle(TNaming_NamedShape) aTarget = |
89 | Handle(TNaming_NamedShape)::DownCast(theTarget); |
90 | TDF_Label Label = aTarget -> Label(); |
91 | TNaming_Builder aBld (Label); |
92 | |
93 | // Get Version |
94 | Standard_Integer aVersion = 0; |
95 | const XmlObjMgt_Element& anElement = theSource; |
96 | XmlObjMgt_DOMString aVerString = anElement.getAttribute (::VersionString()); |
97 | if (aVerString != NULL) |
98 | aVerString.GetInteger (aVersion); |
99 | |
100 | // Get Evolution status |
101 | XmlObjMgt_DOMString aStatus = anElement.getAttribute (::StatusString()); |
102 | TNaming_Evolution evol = EvolutionEnum (aStatus); |
103 | // apres creation Builder qui a mis la version a 1 : |
104 | aTarget -> SetVersion (aVersion); |
105 | |
106 | const XmlMNaming_Array1OfShape1 OldPShapes (anElement, ::OldsString()); |
107 | const XmlMNaming_Array1OfShape1 NewPShapes (anElement, ::NewsString()); |
108 | if (NewPShapes.Length() == 0 && OldPShapes.Length() == 0) |
109 | return Standard_True; |
110 | |
111 | TopoDS_Shape anOldShape; |
112 | TopoDS_Shape aNewShape; |
113 | BRepTools_ShapeSet& aShapeSet = (BRepTools_ShapeSet&) myShapeSet; |
114 | |
115 | Standard_Integer lower = NewPShapes.Lower(); |
116 | if (OldPShapes.Lower() < lower) lower = OldPShapes.Lower(); |
117 | |
118 | Standard_Integer upper = NewPShapes.Upper(); |
119 | if (OldPShapes.Upper() > upper) upper = OldPShapes.Upper(); |
120 | |
121 | for (Standard_Integer i = lower; i <= upper; i++) |
122 | { |
123 | const XmlMNaming_Shape1 aNewPShape = NewPShapes.Value(i); |
124 | const XmlMNaming_Shape1 anOldPShape = OldPShapes.Value(i); |
125 | |
126 | if ( evol != TNaming_PRIMITIVE && anOldPShape.Element() != NULL ) |
127 | { |
128 | if (::doTranslate (anOldPShape, anOldShape, aShapeSet)) { |
129 | WriteMessage ("NamedShapeDriver: Error reading a shape from array"); |
130 | return Standard_False; |
131 | } |
132 | } |
133 | |
134 | if (evol != TNaming_DELETE && aNewPShape.Element() != NULL ) |
135 | { |
136 | if (::doTranslate (aNewPShape, aNewShape, aShapeSet)) { |
137 | WriteMessage ("NamedShapeDriver: Error reading a shape from array"); |
138 | return Standard_False; |
139 | } |
140 | } |
141 | |
142 | switch (evol) |
143 | { |
144 | case TNaming_PRIMITIVE: |
145 | aBld.Generated(aNewShape); |
146 | break; |
147 | case TNaming_GENERATED: |
148 | aBld.Generated(anOldShape,aNewShape); |
149 | break; |
150 | case TNaming_MODIFY: |
151 | aBld.Modify(anOldShape,aNewShape); |
152 | break; |
153 | case TNaming_DELETE: |
154 | aBld.Delete(anOldShape); |
155 | break; |
156 | case TNaming_SELECTED: |
157 | aBld.Select(aNewShape, anOldShape); |
158 | break; |
566f8441 |
159 | case TNaming_REPLACE: |
160 | aBld.Modify(anOldShape,aNewShape); |
161 | break; // for compatibility |
1ec8a59e |
162 | // case TNaming_REPLACE: |
163 | // aBld.Replace(anOldShape,aNewShape); |
164 | // break; |
7fd59977 |
165 | default: |
166 | Standard_DomainError::Raise("TNaming_Evolution; enum term unknown"); |
167 | } |
168 | anOldShape.Nullify(); |
169 | aNewShape.Nullify(); |
170 | } |
171 | return Standard_True; |
172 | } |
173 | |
174 | //======================================================================= |
175 | //function : Paste() |
176 | //purpose : storage of TNaming_NamedShape |
177 | //======================================================================= |
178 | |
179 | void XmlMNaming_NamedShapeDriver::Paste (const Handle(TDF_Attribute)& theSource, |
180 | XmlObjMgt_Persistent& theTarget, |
181 | XmlObjMgt_SRelocationTable&) const |
182 | { |
183 | //AGV XmlObjMgt_Document& aDoc = |
184 | //AGV (XmlObjMgt_Document&) theTarget.Element().getOwnerDocument(); |
185 | XmlObjMgt_Document aDoc = |
186 | XmlObjMgt_Document (theTarget.Element().getOwnerDocument()); |
187 | |
188 | Handle(TNaming_NamedShape) aNamedShape = |
189 | Handle(TNaming_NamedShape)::DownCast(theSource); |
190 | TNaming_Evolution evol = aNamedShape->Evolution(); |
191 | |
192 | // Create arrays |
193 | Standard_Integer NbShapes = 0; |
194 | TNaming_Iterator SItr (aNamedShape); |
195 | while (SItr.More()) { |
196 | NbShapes++; |
197 | SItr.Next (); |
198 | } |
199 | |
200 | BRepTools_ShapeSet& aShapeSet = (BRepTools_ShapeSet&) myShapeSet; |
201 | XmlMNaming_Array1OfShape1 OldPShapes (1,NbShapes), NewPShapes (1,NbShapes); |
202 | |
203 | OldPShapes.CreateArrayElement (theTarget, ::OldsString()); |
204 | NewPShapes.CreateArrayElement (theTarget, ::NewsString()); |
205 | |
206 | // Fill arrays |
207 | Standard_Integer i = 1; |
208 | TNaming_Iterator SIterator(aNamedShape); |
209 | while (SIterator.More()) |
210 | { |
211 | const TopoDS_Shape& OldShape = SIterator.OldShape(); |
212 | const TopoDS_Shape& NewShape = SIterator.NewShape(); |
213 | |
214 | if ( evol != TNaming_PRIMITIVE ) |
215 | { |
216 | XmlMNaming_Shape1 anOldPShape (aDoc); |
217 | ::doTranslate (OldShape, anOldPShape, aShapeSet); |
218 | OldPShapes.SetValue (i, anOldPShape.Element()); |
219 | } |
220 | |
221 | if (evol != TNaming_DELETE) |
222 | { |
223 | XmlMNaming_Shape1 aNewPShape (aDoc); |
224 | ::doTranslate (NewShape, aNewPShape, aShapeSet); |
225 | NewPShapes.SetValue (i, aNewPShape.Element()); |
226 | } |
227 | i++; |
228 | SIterator.Next(); |
229 | } |
230 | |
231 | theTarget.Element().setAttribute (::StatusString(), EvolutionString(evol)); |
232 | Standard_Integer aVersion = aNamedShape -> Version(); |
233 | if (aVersion != 0) |
234 | theTarget.Element().setAttribute (::VersionString(), aVersion); |
235 | } |
236 | |
237 | //======================================================================= |
238 | //function : EvolutionEnum |
239 | //purpose : static |
240 | //======================================================================= |
241 | |
242 | static const XmlObjMgt_DOMString& EvolutionString(const TNaming_Evolution i) |
243 | { |
244 | switch(i) { |
245 | case TNaming_PRIMITIVE : return ::EvolPrimitiveString(); |
246 | case TNaming_GENERATED : return ::EvolGeneratedString(); |
247 | case TNaming_MODIFY : return ::EvolModifyString(); |
248 | case TNaming_DELETE : return ::EvolDeleteString(); |
249 | case TNaming_SELECTED : return ::EvolSelectedString(); |
566f8441 |
250 | case TNaming_REPLACE : return ::EvolModifyString(); // case TNaming_REPLACE : return ::EvolReplaceString(); for compatibility |
7fd59977 |
251 | default: |
252 | Standard_DomainError::Raise("TNaming_Evolution; enum term unknown"); |
253 | } |
254 | static XmlObjMgt_DOMString aNullString; |
255 | return aNullString; // To avoid compilation error message. |
256 | } |
257 | |
258 | //======================================================================= |
259 | //function : EvolutionEnum |
260 | //purpose : static |
261 | //======================================================================= |
262 | |
263 | static TNaming_Evolution EvolutionEnum (const XmlObjMgt_DOMString& theString) |
264 | { |
265 | TNaming_Evolution aResult = TNaming_PRIMITIVE; |
266 | if (theString.equals (::EvolPrimitiveString()) == Standard_False) { |
267 | if (theString.equals (::EvolGeneratedString())) |
268 | aResult = TNaming_GENERATED; |
269 | else if (theString.equals (::EvolModifyString())) |
270 | aResult = TNaming_MODIFY; |
271 | else if (theString.equals (::EvolDeleteString())) |
272 | aResult = TNaming_DELETE; |
273 | else if (theString.equals (::EvolSelectedString())) |
274 | aResult = TNaming_SELECTED; |
275 | else if (theString.equals (::EvolReplaceString())) |
1ec8a59e |
276 | aResult = TNaming_MODIFY; // for compatibility //TNaming_REPLACE; |
7fd59977 |
277 | else |
278 | Standard_DomainError::Raise |
279 | ("TNaming_Evolution; string value without enum term equivalence"); |
280 | } |
281 | return aResult; |
282 | } |
283 | |
284 | //======================================================================= |
285 | //function : doTranslate |
286 | //purpose : shape storage to XML |
287 | //======================================================================= |
288 | |
289 | static void doTranslate (const TopoDS_Shape& theShape, |
290 | XmlMNaming_Shape1& theResult, |
291 | BRepTools_ShapeSet& theShapeSet) |
292 | { |
293 | // Check for empty shape |
294 | if (theShape.IsNull()) return; |
295 | |
296 | // Add to shape set both TShape and Location contained in theShape |
297 | const Standard_Integer aTShapeId = theShapeSet.Add (theShape); |
298 | const Standard_Integer aLocId = |
299 | theShapeSet.Locations().Index (theShape.Location()); |
300 | |
301 | // Fill theResult with shape parameters: TShape ID, Location, Orientation |
302 | theResult.SetShape (aTShapeId, aLocId, theShape.Orientation()); |
303 | |
304 | if (theShape.ShapeType() == TopAbs_VERTEX) |
305 | { |
306 | theResult.SetVertex(theShape); |
307 | } |
308 | } |
309 | |
310 | //======================================================================= |
311 | //function : doTranslate |
312 | //purpose : shape retrieval from XML |
313 | //======================================================================= |
314 | |
315 | static int doTranslate (const XmlMNaming_Shape1& thePShape, |
316 | TopoDS_Shape& theResult, |
317 | BRepTools_ShapeSet& theShapeSet) |
318 | { |
319 | const Standard_Integer aShapeId = thePShape.TShapeId(); |
320 | |
321 | // Read TShape and Orientation |
322 | if (aShapeId <= 0 || aShapeId > theShapeSet.NbShapes()) |
323 | return 1; |
324 | theResult.TShape (theShapeSet.Shape(aShapeId).TShape()); |
325 | theResult.Orientation (thePShape.Orientation()); |
326 | theResult.Location (theShapeSet.Locations().Location (thePShape.LocId())); |
327 | |
328 | return 0; |
329 | } |
330 | |
331 | //======================================================================= |
332 | //function : ReadShapeSection |
333 | //purpose : |
334 | //======================================================================= |
335 | |
336 | void XmlMNaming_NamedShapeDriver::ReadShapeSection |
337 | (const XmlObjMgt_Element& theElement) |
338 | { |
339 | XmlObjMgt_Element anElement = |
340 | XmlObjMgt::FindChildByName (theElement, ::ShapesString()); |
341 | if (anElement != NULL) { |
342 | for (LDOM_Node aNode = anElement.getFirstChild(); |
343 | aNode != NULL; |
344 | aNode = anElement.getNextSibling()) |
345 | { |
346 | if (aNode.getNodeType() == LDOM_Node::TEXT_NODE) { |
347 | LDOM_Text aText = (LDOM_Text&) aNode; |
348 | LDOMString aData = aText.getData(); |
349 | #ifdef USE_STL_STREAM |
350 | std::stringstream aStream (std::string(aData.GetString())); |
351 | #else |
352 | istrstream aStream (Standard_CString(aData.GetString())); |
353 | #endif |
354 | myShapeSet.Clear(); |
355 | myShapeSet.Read (aStream); |
356 | break; |
357 | } |
358 | } |
359 | } |
360 | } |
361 | |
362 | //======================================================================= |
363 | //function : WriteShapeSection |
364 | //purpose : |
365 | //======================================================================= |
366 | |
367 | void XmlMNaming_NamedShapeDriver::WriteShapeSection |
368 | (XmlObjMgt_Element& theElement) |
369 | { |
370 | // Create "shapes" element and append it as child |
371 | XmlObjMgt_Document aDoc = theElement.getOwnerDocument(); |
372 | XmlObjMgt_Element anElement = aDoc.createElement (::ShapesString()); |
373 | theElement.appendChild (anElement); |
374 | |
375 | // Add text to the "shapes" element |
376 | if (myShapeSet.NbShapes() > 0) { |
377 | myShapeSet.SetFormatNb(2); |
378 | LDOM_OSStream aStream (1024); |
379 | // ostrstream aStream; |
380 | // aStream.rdbuf() -> setbuf (0, 16380); |
381 | myShapeSet.Write (aStream); |
382 | aStream << ends; |
383 | char * aStr = (char *)aStream.str(); |
384 | LDOM_Text aText = aDoc.createTextNode (aStr); |
385 | delete [] aStr; |
386 | aText.SetValueClear(); // There are no characters '<' and '&' and like |
387 | // aStream.rdbuf() -> freeze(0); // release the buffer |
388 | anElement.appendChild (aText); |
389 | // Clear the shape set to avoid appending to it on the next write |
390 | BRepTools_ShapeSet& aShapeSet = (BRepTools_ShapeSet&) myShapeSet; |
391 | aShapeSet.Clear(); |
392 | } |
393 | } |
394 | |
395 | //======================================================================= |
396 | //function : Clear |
397 | //purpose : |
398 | //======================================================================= |
399 | |
400 | void XmlMNaming_NamedShapeDriver::Clear() |
401 | { |
402 | myShapeSet.Clear(); |
403 | } |