1 // Created on: 2016-11-10
2 // Created by: Anton KOZULIN
3 // Copyright (c) 2016 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
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>
26 IMPLEMENT_STANDARD_RTTIEXT(XmlMDataXtd_TriangulationDriver,XmlMDF_ADriver)
27 IMPLEMENT_DOMSTRING (TriangString, "triangulation")
28 IMPLEMENT_DOMSTRING (NullString, "null")
29 IMPLEMENT_DOMSTRING (ExistString, "exists")
31 //=======================================================================
32 //function : XmlMDataXtd_TriangulationDriver
33 //purpose : Constructor
34 //=======================================================================
35 XmlMDataXtd_TriangulationDriver::XmlMDataXtd_TriangulationDriver(const Handle(CDM_MessageDriver)& theMsgDriver)
36 : XmlMDF_ADriver (theMsgDriver, NULL)
41 //=======================================================================
44 //=======================================================================
45 Handle(TDF_Attribute) XmlMDataXtd_TriangulationDriver::NewEmpty() const
47 return new TDataXtd_Triangulation();
50 //=======================================================================
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
58 const XmlObjMgt_Element& element = theSource;
59 Handle(TDataXtd_Triangulation) attribute = Handle(TDataXtd_Triangulation)::DownCast(theTarget);
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()))
71 // Get mesh as a string.
72 const XmlObjMgt_DOMString& data = XmlObjMgt::GetStringValue(element);
73 std::stringstream stream(std::string(data.GetString()));
75 Standard_Integer i, n1, n2, n3;
76 Standard_Integer nbNodes, nbTriangles, hasUV;
77 Standard_Real deflection, x, y, z;
79 stream >> nbNodes >> nbTriangles >> hasUV;
80 GetReal(stream, deflection);
82 TColgp_Array1OfPnt Nodes(1, nbNodes);
83 TColgp_Array1OfPnt2d UVNodes(1, nbNodes);
85 for (i = 1; i <= nbNodes; i++)
90 Nodes(i).SetCoord(x, y, z);
95 for (i = 1; i <= nbNodes; i++) {
98 UVNodes(i).SetCoord(x,y);
102 // read the triangles
103 Poly_Array1OfTriangle Triangles(1, nbTriangles);
104 for (i = 1; i <= nbTriangles; i++)
106 stream >> n1 >> n2 >> n3;
107 Triangles(i).Set(n1, n2, n3);
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);
117 return Standard_True;
120 //=======================================================================
122 //purpose : transient -> persistent (store)
123 //=======================================================================
124 void XmlMDataXtd_TriangulationDriver::Paste(const Handle(TDF_Attribute)& theSource,
125 XmlObjMgt_Persistent& theTarget,
126 XmlObjMgt_SRelocationTable& ) const
128 const Handle(TDataXtd_Triangulation) attribute = Handle(TDataXtd_Triangulation)::DownCast(theSource);
129 if (attribute->Get().IsNull())
130 theTarget.Element().setAttribute(::TriangString(), ::NullString());
133 theTarget.Element().setAttribute(::TriangString(), ::ExistString());
135 Standard_Integer i, n1, n2, n3;
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 :-)
151 // Allocate a string stream.
152 LDOM_OSStream stream(size);
153 stream.precision(17);
155 stream << nbNodes << " " << nbTriangles << " ";
156 stream << ((PT->HasUVNodes()) ? "1" : "0") << " ";
158 stream << PT->Deflection() << "\n";
160 // write the 3d nodes
161 const TColgp_Array1OfPnt& Nodes = PT->Nodes();
162 for (i = 1; i <= nbNodes; i++)
164 stream << Nodes(i).X() << " "
165 << Nodes(i).Y() << " "
166 << Nodes(i).Z() << " ";
169 if (PT->HasUVNodes())
171 const TColgp_Array1OfPnt2d& UVNodes = PT->UVNodes();
172 for (i = 1; i <= nbNodes; i++)
174 stream << UVNodes(i).X() << " "
175 << UVNodes(i).Y() << " ";
179 const Poly_Array1OfTriangle& Triangles = PT->Triangles();
180 for (i = 1; i <= nbTriangles; i++)
182 Triangles(i).Get(n1, n2, n3);
190 Standard_Character* dump = (Standard_Character*)stream.str(); // copying! Don't forget to delete it.
191 XmlObjMgt::SetStringValue(theTarget, dump, Standard_True);
196 //=======================================================================
199 //=======================================================================
201 void XmlMDataXtd_TriangulationDriver::GetReal(Standard_IStream& IS,Standard_Real& theValue) const
209 std::streamsize anOldWide = IS.width(256);
212 theValue = Strtod(buffer, NULL);