0030169: Application Framework - Document format version management improvement
[occt.git] / src / XmlMXCAFDoc / XmlMXCAFDoc_LocationDriver.cxx
1 // Created on: 2001-09-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
17 #include <Message_Messenger.hxx>
18 #include <Standard_Type.hxx>
19 #include <TDF_Attribute.hxx>
20 #include <TopLoc_Datum3D.hxx>
21 #include <TopLoc_Location.hxx>
22 #include <TopTools_LocationSet.hxx>
23 #include <XCAFDoc_Location.hxx>
24 #include <XmlMNaming.hxx>
25 #include <XmlMXCAFDoc_LocationDriver.hxx>
26 #include <XmlObjMgt.hxx>
27 #include <XmlObjMgt_Document.hxx>
28 #include <XmlObjMgt_DOMString.hxx>
29 #include <XmlObjMgt_GP.hxx>
30 #include <XmlObjMgt_Persistent.hxx>
31
32 IMPLEMENT_STANDARD_RTTIEXT(XmlMXCAFDoc_LocationDriver,XmlMDF_ADriver)
33 IMPLEMENT_DOMSTRING (DatumString,    "datum")
34 IMPLEMENT_DOMSTRING (LocationString, "location")
35 IMPLEMENT_DOMSTRING (PowerString,    "power")
36 IMPLEMENT_DOMSTRING (TrsfString,     "trsf")
37 IMPLEMENT_DOMSTRING (LocIdString,    "locId")
38
39 //=======================================================================
40 //function : XmlMXCAFDoc_LocationDriver
41 //purpose  : Constructor
42 //=======================================================================
43 XmlMXCAFDoc_LocationDriver::XmlMXCAFDoc_LocationDriver
44                         (const Handle(Message_Messenger)& theMsgDriver)
45       : XmlMDF_ADriver (theMsgDriver, "xcaf", "Location")
46       , myLocations(0)
47 {}
48
49 //=======================================================================
50 //function : NewEmpty
51 //purpose  : 
52 //=======================================================================
53 Handle(TDF_Attribute) XmlMXCAFDoc_LocationDriver::NewEmpty() const
54 {
55   return (new XCAFDoc_Location());
56 }
57
58 //=======================================================================
59 //function : Paste
60 //purpose  : 
61 //=======================================================================
62 Standard_Boolean XmlMXCAFDoc_LocationDriver::Paste
63                               (const XmlObjMgt_Persistent&  theSource,
64                                const Handle(TDF_Attribute)& theTarget,
65                                XmlObjMgt_RRelocationTable&  theRelocTable) const
66 {
67   TopLoc_Location aLoc;
68   Translate (theSource.Element(), aLoc, theRelocTable);
69
70   Handle(XCAFDoc_Location) aT = Handle(XCAFDoc_Location)::DownCast (theTarget);
71   aT->Set(aLoc);
72
73   return Standard_True;
74 }
75
76 //=======================================================================
77 //function : Paste
78 //purpose  : 
79 //=======================================================================
80 void XmlMXCAFDoc_LocationDriver::Paste
81                               (const Handle(TDF_Attribute)& theSource,
82                                XmlObjMgt_Persistent&        theTarget,
83                                XmlObjMgt_SRelocationTable&  theRelocTable) const
84 {
85   Handle(XCAFDoc_Location) aS = Handle(XCAFDoc_Location)::DownCast(theSource);
86   XmlObjMgt_Element anElem = theTarget.Element();
87   Translate (aS->Get(), anElem, theRelocTable);
88 }
89
90 //=======================================================================
91 //function : Translate
92 //purpose  : .. from Transient to Persistent
93 //=======================================================================
94 void XmlMXCAFDoc_LocationDriver::Translate (const TopLoc_Location&      theLoc,
95                                      XmlObjMgt_Element&          theParent,
96                                      XmlObjMgt_SRelocationTable& theMap) const
97 {
98   if (theLoc.IsIdentity())
99   {
100     return;
101   }
102   
103   // The location is not identity  
104   if( myLocations == 0 )
105   {
106 #ifdef OCCT_DEBUG
107     cout<<"Pointer to LocationSet is NULL\n";
108 #endif
109     return;
110   }
111   
112   //  Create Location element
113   XmlObjMgt_Document aDoc = theParent.getOwnerDocument();
114   XmlObjMgt_Element aLocElem = aDoc.createElement(::LocationString());
115   
116   Standard_Integer anId = myLocations->Add(theLoc);
117   
118   aLocElem.setAttribute (::LocIdString(), anId);
119   theParent.appendChild (aLocElem);
120
121   
122   // In earlier version of this driver a datums from location stored in 
123   // the relocation table, but now it's not necessary
124   // (try to uncomment it if some problems appear)
125   /*
126   Handle(TopLoc_Datum3D) aDatum = theLoc.FirstDatum();
127   
128   if(!theMap.Contains(aDatum)) {
129     theMap.Add(aDatum);
130   }
131   */
132
133   //  Add next Location from the list
134   Translate (theLoc.NextLocation(), aLocElem, theMap);
135 }
136
137 //=======================================================================
138 //function : Translate
139 //purpose  : .. from Persistent to Transient
140 //=======================================================================
141 Standard_Boolean XmlMXCAFDoc_LocationDriver::Translate
142                                         (const XmlObjMgt_Element&    theParent,
143                                          TopLoc_Location&            theLoc,
144                                          XmlObjMgt_RRelocationTable& theMap) const
145 {
146   XmlObjMgt_Element aLocElem =
147     XmlObjMgt::FindChildByName (theParent, ::LocationString());
148   if (aLocElem == NULL)
149     return Standard_False;
150   
151   Standard_Integer aFileVer = theMap.GetHeaderData()->StorageVersion().IntegerValue();
152   if( aFileVer > 5 && myLocations == 0 )
153   {
154     return Standard_False;
155   }
156   
157   Standard_Integer aPower;
158   Handle(TopLoc_Datum3D) aDatum;
159   
160   if( aFileVer > 5 )
161   {
162     //  Get Location ID
163     Standard_Integer anId;
164     aLocElem.getAttribute (::LocIdString()).GetInteger (anId);
165     
166     const TopLoc_Location& aLoc = myLocations->Location(anId);
167     aPower = aLoc.FirstPower();
168     aDatum = aLoc.FirstDatum();
169   } else
170   {
171     //  Get Power
172     aLocElem.getAttribute (::PowerString()).GetInteger (aPower);
173
174     //  get datum
175     XmlObjMgt_Persistent aPD (aLocElem, ::DatumString());
176     if (aPD.Id() <= 0) {
177       Standard_Integer aDatumID;
178       aLocElem.getAttribute (::DatumString()).GetInteger (aDatumID);
179       if (aDatumID > 0 && theMap.IsBound (aDatumID))
180         aDatum = Handle(TopLoc_Datum3D)::DownCast (theMap.Find (aDatumID));
181       else
182         return Standard_False;
183     }else{
184       gp_Trsf aTrsf;
185       XmlObjMgt_GP::Translate (aPD.Element().getAttribute(::TrsfString()), aTrsf);
186       aDatum = new TopLoc_Datum3D (aTrsf);
187       theMap.Bind (aPD.Id(), aDatum);
188     }
189   }
190   
191   //  Get Next Location
192   TopLoc_Location aNextLoc;
193   Translate (aLocElem, aNextLoc, theMap);
194   
195   //  Calculate the result
196   theLoc = aNextLoc * TopLoc_Location (aDatum).Powered (aPower);
197   return Standard_True;
198 }