0030675: Visualization - remove redundant proxy classes in hierarchy of PrsMgr_Presen...
[occt.git] / src / XmlMNaming / XmlMNaming_NamedShapeDriver.cxx
1 // Created on: 2001-07-11
2 // Created by: Julia DOROVSKIKH
3 // Copyright (c) 2001-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 //AGV 150202: Changed prototype LDOM_Node::getOwnerDocument()
17
18 #include <BRepTools.hxx>
19 #include <Message_Messenger.hxx>
20 #include <LDOM_OSStream.hxx>
21 #include <LDOM_Text.hxx>
22 #include <Standard_SStream.hxx>
23 #include <Standard_Type.hxx>
24 #include <TDF_Attribute.hxx>
25 #include <TDF_Label.hxx>
26 #include <TNaming_Builder.hxx>
27 #include <TNaming_Iterator.hxx>
28 #include <TNaming_NamedShape.hxx>
29 #include <TopoDS_Shape.hxx>
30 #include <TopTools_LocationSet.hxx>
31 #include <XmlMNaming_NamedShapeDriver.hxx>
32 #include <XmlMNaming_Shape1.hxx>
33 #include <XmlObjMgt.hxx>
34 #include <XmlObjMgt_Array1.hxx>
35 #include <XmlObjMgt_Persistent.hxx>
36
37 IMPLEMENT_STANDARD_RTTIEXT(XmlMNaming_NamedShapeDriver,XmlMDF_ADriver)
38
39 static TNaming_Evolution          EvolutionEnum   (const XmlObjMgt_DOMString&);
40 static const XmlObjMgt_DOMString& EvolutionString (const TNaming_Evolution);
41 static void                       doTranslate     (const TopoDS_Shape&,
42                                                    XmlMNaming_Shape1&,
43                                                    BRepTools_ShapeSet&);
44 static int                        doTranslate     (const XmlMNaming_Shape1&,
45                                                    TopoDS_Shape&,
46                                                    BRepTools_ShapeSet&);
47
48 IMPLEMENT_DOMSTRING (OldsString,    "olds")
49 IMPLEMENT_DOMSTRING (NewsString,    "news")
50 IMPLEMENT_DOMSTRING (StatusString,  "evolution")
51 IMPLEMENT_DOMSTRING (VersionString, "version")
52 IMPLEMENT_DOMSTRING (ShapesString,  "shapes")
53
54 IMPLEMENT_DOMSTRING (EvolPrimitiveString, "primitive")
55 IMPLEMENT_DOMSTRING (EvolGeneratedString, "generated")
56 IMPLEMENT_DOMSTRING (EvolModifyString,    "modify")
57 IMPLEMENT_DOMSTRING (EvolDeleteString,    "delete")
58 IMPLEMENT_DOMSTRING (EvolSelectedString,  "selected")
59 IMPLEMENT_DOMSTRING (EvolReplaceString,   "replace")
60
61 //=======================================================================
62 //function : XmlMNaming_NamedShapeDriver
63 //purpose  : Constructor
64 //=======================================================================
65
66 XmlMNaming_NamedShapeDriver::XmlMNaming_NamedShapeDriver
67                         (const Handle(Message_Messenger)& theMessageDriver)
68      : XmlMDF_ADriver (theMessageDriver, NULL),
69   myShapeSet (Standard_False) // triangles mode
70 {}
71
72 //=======================================================================
73 //function : NewEmpty()
74 //purpose  : 
75 //=======================================================================
76 Handle(TDF_Attribute) XmlMNaming_NamedShapeDriver::NewEmpty () const
77 {
78   return (new TNaming_NamedShape());
79 }
80
81 //=======================================================================
82 //function : Paste()
83 //purpose  : retrieval of TNaming_NamedShape
84 //=======================================================================
85
86 Standard_Boolean XmlMNaming_NamedShapeDriver::Paste
87                                        (const XmlObjMgt_Persistent&  theSource,
88                                         const Handle(TDF_Attribute)& theTarget,
89                                         XmlObjMgt_RRelocationTable&) const
90 {
91   Handle(TNaming_NamedShape) aTarget =
92     Handle(TNaming_NamedShape)::DownCast(theTarget);
93   TDF_Label Label = aTarget -> Label();
94   TNaming_Builder aBld (Label);
95
96   //    Get Version
97   Standard_Integer    aVersion = 0;
98   const XmlObjMgt_Element& anElement = theSource;
99   XmlObjMgt_DOMString aVerString = anElement.getAttribute (::VersionString());
100   if (aVerString != NULL)
101     aVerString.GetInteger (aVersion);
102
103   //    Get Evolution status
104   XmlObjMgt_DOMString aStatus = anElement.getAttribute (::StatusString());
105   TNaming_Evolution evol = EvolutionEnum (aStatus);
106   // apres creation Builder qui a mis la version a 1 :
107   aTarget -> SetVersion (aVersion);
108
109   const XmlObjMgt_Array1 OldPShapes (anElement, ::OldsString());
110   const XmlObjMgt_Array1 NewPShapes (anElement, ::NewsString());
111   if (NewPShapes.Length() == 0 && OldPShapes.Length() == 0)
112     return Standard_True;
113
114   TopoDS_Shape anOldShape;
115   TopoDS_Shape aNewShape;
116   BRepTools_ShapeSet& aShapeSet = (BRepTools_ShapeSet&) myShapeSet;
117
118   Standard_Integer lower = NewPShapes.Lower();
119   if (OldPShapes.Lower() < lower) lower = OldPShapes.Lower();
120
121   Standard_Integer upper = NewPShapes.Upper();
122   if (OldPShapes.Upper() > upper) upper = OldPShapes.Upper();
123
124   for (Standard_Integer i = upper; i >= lower; --i)
125   {
126     const XmlMNaming_Shape1 aNewPShape  = NewPShapes.Value(i);
127     const XmlMNaming_Shape1 anOldPShape = OldPShapes.Value(i);
128
129     if ( evol != TNaming_PRIMITIVE && anOldPShape.Element() != NULL )
130     {
131       if (::doTranslate (anOldPShape, anOldShape, aShapeSet)) {
132         myMessageDriver->Send ("NamedShapeDriver: Error reading a shape from array", Message_Fail);
133         return Standard_False;
134       }
135     }
136
137     if (evol != TNaming_DELETE && aNewPShape.Element() != NULL )
138     {
139       if (::doTranslate (aNewPShape, aNewShape, aShapeSet)) {
140         myMessageDriver->Send ("NamedShapeDriver: Error reading a shape from array", Message_Fail);
141         return Standard_False;
142       }
143     }
144
145     switch (evol)
146     {
147     case TNaming_PRIMITIVE:
148       aBld.Generated(aNewShape);
149       break;
150     case TNaming_GENERATED:
151       aBld.Generated(anOldShape,aNewShape);
152       break;
153     case TNaming_MODIFY:
154       aBld.Modify(anOldShape,aNewShape);
155       break;
156     case TNaming_DELETE:
157       aBld.Delete(anOldShape);
158       break;
159     case TNaming_SELECTED:
160       aBld.Select(aNewShape, anOldShape);
161       break;
162     case TNaming_REPLACE:
163       aBld.Modify(anOldShape,aNewShape);
164       break; // for compatibility
165       //    case TNaming_REPLACE:
166       //      aBld.Replace(anOldShape,aNewShape);
167       //      break;
168     default:
169       throw Standard_DomainError("TNaming_Evolution; enum term unknown");
170     }
171     anOldShape.Nullify();
172     aNewShape.Nullify();
173   }
174   return Standard_True;
175 }
176
177 //=======================================================================
178 //function : Paste()
179 //purpose  : storage of TNaming_NamedShape
180 //=======================================================================
181
182 void XmlMNaming_NamedShapeDriver::Paste (const Handle(TDF_Attribute)& theSource,
183                                          XmlObjMgt_Persistent&        theTarget,
184                                          XmlObjMgt_SRelocationTable&) const
185 {
186 //AGV  XmlObjMgt_Document& aDoc =
187 //AGV    (XmlObjMgt_Document&) theTarget.Element().getOwnerDocument();
188   XmlObjMgt_Document aDoc =
189     XmlObjMgt_Document (theTarget.Element().getOwnerDocument());
190
191   Handle(TNaming_NamedShape) aNamedShape =
192     Handle(TNaming_NamedShape)::DownCast(theSource);
193   TNaming_Evolution evol = aNamedShape->Evolution();
194
195   //    Create arrays
196   Standard_Integer NbShapes = 0;
197   TNaming_Iterator SItr (aNamedShape);
198   while (SItr.More()) {
199     NbShapes++;
200     SItr.Next ();
201   }
202
203   BRepTools_ShapeSet& aShapeSet = (BRepTools_ShapeSet&) myShapeSet;
204   XmlObjMgt_Array1 OldPShapes (1,NbShapes), NewPShapes (1,NbShapes);
205
206   OldPShapes.CreateArrayElement (theTarget, ::OldsString());
207   NewPShapes.CreateArrayElement (theTarget, ::NewsString());
208
209   //    Fill arrays
210   Standard_Integer i = 1;
211   TNaming_Iterator SIterator(aNamedShape);
212   while (SIterator.More())
213   {
214     const TopoDS_Shape& OldShape = SIterator.OldShape();
215     const TopoDS_Shape& NewShape = SIterator.NewShape();
216
217     if ( evol != TNaming_PRIMITIVE )
218     {
219       XmlMNaming_Shape1 anOldPShape (aDoc);
220       ::doTranslate (OldShape, anOldPShape, aShapeSet);
221       OldPShapes.SetValue (i, anOldPShape.Element());
222     }
223
224     if (evol != TNaming_DELETE)
225     {
226       XmlMNaming_Shape1 aNewPShape (aDoc);
227       ::doTranslate (NewShape, aNewPShape, aShapeSet);
228       NewPShapes.SetValue (i, aNewPShape.Element());
229     }
230     i++;
231     SIterator.Next();
232   }
233
234   theTarget.Element().setAttribute (::StatusString(), EvolutionString(evol));
235   Standard_Integer aVersion = aNamedShape -> Version();
236   if (aVersion != 0)
237     theTarget.Element().setAttribute (::VersionString(), aVersion);
238 }
239
240 //=======================================================================
241 //function : EvolutionEnum
242 //purpose  : static
243 //=======================================================================
244
245 static const XmlObjMgt_DOMString& EvolutionString(const TNaming_Evolution i)
246 {
247   switch(i) {
248     case TNaming_PRIMITIVE    : return ::EvolPrimitiveString();
249     case TNaming_GENERATED    : return ::EvolGeneratedString();
250     case TNaming_MODIFY       : return ::EvolModifyString();
251     case TNaming_DELETE       : return ::EvolDeleteString();
252     case TNaming_SELECTED     : return ::EvolSelectedString();
253     case TNaming_REPLACE      : return ::EvolModifyString();  //    case TNaming_REPLACE      : return ::EvolReplaceString(); for compatibility
254   default:
255     throw Standard_DomainError("TNaming_Evolution; enum term unknown");
256   }
257 }
258
259 //=======================================================================
260 //function : EvolutionEnum
261 //purpose  : static
262 //=======================================================================
263
264 static TNaming_Evolution EvolutionEnum (const XmlObjMgt_DOMString& theString)
265 {
266   TNaming_Evolution aResult = TNaming_PRIMITIVE;
267   if (theString.equals (::EvolPrimitiveString()) == Standard_False) {
268     if (theString.equals (::EvolGeneratedString()))
269       aResult = TNaming_GENERATED;
270     else if (theString.equals (::EvolModifyString()))
271       aResult = TNaming_MODIFY;
272     else if (theString.equals (::EvolDeleteString()))
273       aResult = TNaming_DELETE;
274     else if (theString.equals (::EvolSelectedString()))
275       aResult = TNaming_SELECTED;
276     else if (theString.equals (::EvolReplaceString()))
277       aResult = TNaming_MODIFY; // for compatibility //TNaming_REPLACE;
278     else
279       throw Standard_DomainError("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         LDOMString aData = aNode.getNodeValue();
348         std::stringstream aStream (std::string(aData.GetString()));
349         myShapeSet.Clear();
350         myShapeSet.Read (aStream);
351         break;
352       }
353     }
354   }
355 }
356
357 //=======================================================================
358 //function : WriteShapeSection
359 //purpose  : 
360 //=======================================================================
361
362 void XmlMNaming_NamedShapeDriver::WriteShapeSection
363                                         (XmlObjMgt_Element& theElement)
364 {
365   //  Create "shapes" element and append it as child
366   XmlObjMgt_Document aDoc     = theElement.getOwnerDocument();
367   XmlObjMgt_Element anElement = aDoc.createElement (::ShapesString());
368   theElement.appendChild (anElement);
369
370   //  Add text to the "shapes" element
371   if (myShapeSet.NbShapes() > 0) {
372     myShapeSet.SetFormatNb(2);
373     LDOM_OSStream aStream (16 * 1024);
374 //    ostrstream aStream;
375 //    aStream.rdbuf() -> setbuf (0, 16380);
376     myShapeSet.Write (aStream);
377     aStream << ends;
378     char * aStr = (char *)aStream.str();
379     LDOM_Text aText = aDoc.createTextNode (aStr);
380     delete [] aStr;
381     aText.SetValueClear();      // There are no characters '<' and '&' and like
382 //    aStream.rdbuf() -> freeze(0);                     // release the buffer
383     anElement.appendChild (aText);
384   // Clear the shape set to avoid appending to it on the next write
385     BRepTools_ShapeSet& aShapeSet = (BRepTools_ShapeSet&) myShapeSet;
386     aShapeSet.Clear();
387   }
388 }
389
390 //=======================================================================
391 //function : Clear
392 //purpose  : 
393 //=======================================================================
394
395 void XmlMNaming_NamedShapeDriver::Clear()
396 {
397   myShapeSet.Clear();
398 }