Warnings on vc14 were eliminated
[occt.git] / src / XmlMDataXtd / XmlMDataXtd_TriangulationDriver.cxx
1 // Created on: 2016-11-10
2 // Created by: Anton KOZULIN
3 // Copyright (c) 2016 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 <XmlMDataXtd_TriangulationDriver.hxx>
17 #include <CDM_MessageDriver.hxx>
18 #include <NCollection_LocalArray.hxx>
19 #include <Standard_Type.hxx>
20 #include <TDF_Attribute.hxx>
21 #include <XmlObjMgt.hxx>
22 #include <XmlObjMgt_Persistent.hxx>
23 #include <TDataXtd_Triangulation.hxx>
24 #include <LDOM_OSStream.hxx>
25
26 IMPLEMENT_STANDARD_RTTIEXT(XmlMDataXtd_TriangulationDriver,XmlMDF_ADriver)
27 IMPLEMENT_DOMSTRING (TriangString, "triangulation")
28 IMPLEMENT_DOMSTRING (NullString, "null")
29 IMPLEMENT_DOMSTRING (ExistString, "exists")
30
31 //=======================================================================
32 //function : XmlMDataXtd_TriangulationDriver
33 //purpose  : Constructor
34 //=======================================================================
35 XmlMDataXtd_TriangulationDriver::XmlMDataXtd_TriangulationDriver(const Handle(CDM_MessageDriver)& theMsgDriver)
36   : XmlMDF_ADriver (theMsgDriver, NULL)
37 {
38
39 }
40
41 //=======================================================================
42 //function : NewEmpty
43 //purpose  : 
44 //=======================================================================
45 Handle(TDF_Attribute) XmlMDataXtd_TriangulationDriver::NewEmpty() const
46 {
47   return new TDataXtd_Triangulation();
48 }
49
50 //=======================================================================
51 //function : Paste
52 //purpose  : persistent -> transient (retrieve)
53 //=======================================================================
54 Standard_Boolean XmlMDataXtd_TriangulationDriver::Paste(const XmlObjMgt_Persistent&  theSource,
55                                                         const Handle(TDF_Attribute)& theTarget,
56                                                         XmlObjMgt_RRelocationTable&  ) const
57 {
58   const XmlObjMgt_Element& element = theSource;
59   Handle(TDataXtd_Triangulation) attribute = Handle(TDataXtd_Triangulation)::DownCast(theTarget);
60
61   // Read the FirstIndex; if the attribute is absent initialize to 1
62   XmlObjMgt_DOMString triangStatus = element.getAttribute(::TriangString());
63   if (triangStatus == NULL ||
64       triangStatus.Type() != LDOMBasicString::LDOM_AsciiDoc ||
65       strcmp(triangStatus.GetString(), ::ExistString().GetString()))
66   {
67     // No triangulation.
68     return Standard_True;
69   }
70
71   // Get mesh as a string.
72   const XmlObjMgt_DOMString& data = XmlObjMgt::GetStringValue(element);
73   std::stringstream stream(std::string(data.GetString()));
74
75   Standard_Integer i, n1, n2, n3;
76   Standard_Integer nbNodes, nbTriangles, hasUV;
77   Standard_Real deflection, x, y, z;
78
79   stream >> nbNodes >> nbTriangles >> hasUV;
80   GetReal(stream, deflection);
81
82   TColgp_Array1OfPnt Nodes(1, nbNodes);
83   TColgp_Array1OfPnt2d UVNodes(1, nbNodes);
84
85   for (i = 1; i <= nbNodes; i++)
86   {
87     GetReal(stream, x);
88     GetReal(stream, y);
89     GetReal(stream, z);
90     Nodes(i).SetCoord(x, y, z);
91   }
92
93   if (hasUV)
94   {
95     for (i = 1; i <= nbNodes; i++) {
96       GetReal(stream, x);
97       GetReal(stream, y);
98       UVNodes(i).SetCoord(x,y);
99     }
100   }
101
102   // read the triangles
103   Poly_Array1OfTriangle Triangles(1, nbTriangles);
104   for (i = 1; i <= nbTriangles; i++)
105   {
106     stream >> n1 >> n2 >> n3;
107     Triangles(i).Set(n1, n2, n3);
108   }
109
110   Handle(Poly_Triangulation) PT;
111   if (hasUV) PT =  new Poly_Triangulation(Nodes, UVNodes, Triangles);
112   else PT = new Poly_Triangulation(Nodes, Triangles);
113   PT->Deflection(deflection);
114
115   attribute->Set(PT);
116
117   return Standard_True;
118 }
119
120 //=======================================================================
121 //function : Paste
122 //purpose  : transient -> persistent (store)
123 //=======================================================================
124 void XmlMDataXtd_TriangulationDriver::Paste(const Handle(TDF_Attribute)& theSource,
125                                             XmlObjMgt_Persistent&        theTarget,
126                                             XmlObjMgt_SRelocationTable&  ) const
127 {
128   const Handle(TDataXtd_Triangulation) attribute = Handle(TDataXtd_Triangulation)::DownCast(theSource);
129   if (attribute->Get().IsNull())
130     theTarget.Element().setAttribute(::TriangString(), ::NullString());
131   else
132   {
133     theTarget.Element().setAttribute(::TriangString(), ::ExistString());
134
135     Standard_Integer i, n1, n2, n3;
136
137     // Analyse the size of the triangulation
138     // (to allocate properly the string array).
139     const Handle(Poly_Triangulation)& PT = attribute->Get();
140     Standard_Integer nbNodes = PT->NbNodes();
141     Standard_Integer nbTriangles = PT->NbTriangles();
142     Standard_Integer size = PT->NbNodes();
143     size *= 3 * 25; // 3 coordinates for a node * 25 characters are used to represent a coordinate (double) in XML
144     if (PT->HasUVNodes()) 
145       size += 2 * 25 * nbNodes; // 2 coordinates for a 2D node * 25 characters are used to represent a coordinate (double) in XML
146     size += 3 * 10 * nbTriangles; // space for triangles
147     size *= 2; // just in case :-)
148     if (!size)
149       size = 1;
150
151     // Allocate a string stream.
152     LDOM_OSStream stream(size);
153     stream.precision(17);
154
155     stream << nbNodes << " " << nbTriangles << " ";
156     stream << ((PT->HasUVNodes()) ? "1" : "0") << " ";
157
158     stream << PT->Deflection() << "\n";
159
160     // write the 3d nodes
161     const TColgp_Array1OfPnt& Nodes = PT->Nodes();
162     for (i = 1; i <= nbNodes; i++)
163     {
164       stream << Nodes(i).X() << " "
165              << Nodes(i).Y() << " "
166              << Nodes(i).Z() << " ";
167     }
168
169     if (PT->HasUVNodes())
170     {
171       const TColgp_Array1OfPnt2d& UVNodes = PT->UVNodes();
172       for (i = 1; i <= nbNodes; i++)
173       {
174         stream << UVNodes(i).X() << " "
175                << UVNodes(i).Y() << " ";
176       }
177     }
178
179     const Poly_Array1OfTriangle& Triangles = PT->Triangles();
180     for (i = 1; i <= nbTriangles; i++)
181     {
182       Triangles(i).Get(n1, n2, n3);
183       stream << n1 << " "
184              << n2 << " "
185              << n3 << " ";
186     }
187
188     stream << ends;
189
190     Standard_Character* dump = (Standard_Character*)stream.str(); // copying! Don't forget to delete it.
191     XmlObjMgt::SetStringValue(theTarget, dump, Standard_True);
192     delete[] dump;
193   }
194 }
195
196 //=======================================================================
197 //function : GetReal
198 //purpose  : 
199 //=======================================================================
200
201 void XmlMDataXtd_TriangulationDriver::GetReal(Standard_IStream& IS,Standard_Real& theValue) const
202 {
203   theValue = 0.;
204   if (IS.eof()) 
205     return;
206
207   char buffer[256];
208   buffer[0] = '\0';
209   std::streamsize anOldWide = IS.width(256);
210   IS >> buffer;
211   IS.width(anOldWide);
212   theValue = Strtod(buffer, NULL);
213 }