1 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
22 #include "DriverSTL_W_SMDS_Mesh.h"
24 #include "SMDS_Mesh.hxx"
25 #include "SMDS_MeshElement.hxx"
26 #include "SMDS_MeshNode.hxx"
28 #include <OSD_Path.hxx>
29 #include <OSD_File.hxx>
30 #include <OSD_FromWhere.hxx>
31 #include <OSD_Protection.hxx>
32 #include <OSD_SingleProtection.hxx>
33 #include <TCollection_AsciiString.hxx>
34 #include <TColgp_Array1OfXYZ.hxx>
36 #include "utilities.h"
38 //using namespace std;
40 // definition des constantes
41 static const int LABEL_SIZE = 80;
43 DriverSTL_W_SMDS_Mesh::DriverSTL_W_SMDS_Mesh()
48 void DriverSTL_W_SMDS_Mesh::SetIsAscii( const bool theIsAscii )
50 myIsAscii = theIsAscii;
53 Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::Perform()
55 Status aResult = DRS_OK;
58 fprintf(stderr, ">> ERROR : Mesh is null \n");
62 aResult = writeAscii();
64 aResult = writeBinary();
71 static void writeInteger( const Standard_Integer& theVal,
81 Standard_Integer entier;
82 entier = u.c[0] & 0xFF;
83 entier |= (u.c[1] & 0xFF) << 0x08;
84 entier |= (u.c[2] & 0xFF) << 0x10;
85 entier |= (u.c[3] & 0xFF) << 0x18;
87 ofile.Write((char *)&entier,sizeof(u.c));
90 static void writeFloat ( const Standard_ShortReal& theVal,
100 Standard_Integer entier;
102 entier = u.c[0] & 0xFF;
103 entier |= (u.c[1] & 0xFF) << 0x08;
104 entier |= (u.c[2] & 0xFF) << 0x10;
105 entier |= (u.c[3] & 0xFF) << 0x18;
107 ofile.Write((char *)&entier,sizeof(u.c));
110 static gp_XYZ getNormale( const SMDS_MeshFace* theFace )
113 int aNbNode = theFace->NbNodes();
114 TColgp_Array1OfXYZ anArrOfXYZ(1,4);
115 gp_XYZ p1, p2, p3, p4;
116 SMDS_ElemIteratorPtr aNodeItr = theFace->nodesIterator();
118 for ( ; aNodeItr->more() && i <= 4; i++ )
120 SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next();
121 anArrOfXYZ.SetValue(i, gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) );
124 gp_XYZ q1 = anArrOfXYZ.Value(2) - anArrOfXYZ.Value(1);
125 gp_XYZ q2 = anArrOfXYZ.Value(3) - anArrOfXYZ.Value(1);
129 gp_XYZ q3 = anArrOfXYZ.Value(4) - anArrOfXYZ.Value(1);
132 double len = n.Modulus();
141 Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeAscii() const
143 Status aResult = DRS_OK;
144 TCollection_AsciiString aFileName( (char *)myFile.c_str() );
145 if ( aFileName.IsEmpty() ) {
146 fprintf(stderr, ">> ERREOR : invalid file name \n");
150 OSD_File aFile = OSD_File(OSD_Path(aFileName));
151 aFile.Build(OSD_WriteOnly,OSD_Protection());
152 TCollection_AsciiString buf = TCollection_AsciiString ("solid\n");
153 aFile.Write (buf,buf.Length());buf.Clear();
156 SMDS_FaceIteratorPtr itFaces = myMesh->facesIterator();
158 for (; itFaces->more() ;) {
159 SMDS_MeshFace* aFace = (SMDS_MeshFace*)itFaces->next();
161 if (aFace->NbNodes() == 3) {
162 gp_XYZ normale = getNormale( aFace );
164 buf += " facet normal ";
165 sprintf (sval,"% 12e",normale.X());
168 sprintf (sval,"% 12e",normale.Y());
171 sprintf (sval,"% 12e",normale.Z());
174 aFile.Write (buf,buf.Length());buf.Clear();
175 buf += " outer loop\n";
176 aFile.Write (buf,buf.Length());buf.Clear();
178 SMDS_ElemIteratorPtr aNodeIter = aFace->nodesIterator();
179 for (; aNodeIter->more(); ) {
180 SMDS_MeshNode* node = (SMDS_MeshNode*)aNodeIter->next();
182 sprintf (sval,"% 12e",node->X());
185 sprintf (sval,"% 12e",node->Y());
188 sprintf (sval,"% 12e",node->Z());
191 aFile.Write (buf,buf.Length());buf.Clear();
194 aFile.Write (buf,buf.Length());buf.Clear();
195 buf += " endfacet\n";
196 aFile.Write (buf,buf.Length());buf.Clear();
200 aFile.Write (buf,buf.Length());buf.Clear();
207 Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeBinary() const
209 Status aResult = DRS_OK;
210 TCollection_AsciiString aFileName( (char *)myFile.c_str() );
211 if ( aFileName.IsEmpty() ) {
212 fprintf(stderr, ">> ERREOR : invalid filename \n");
216 OSD_File aFile = OSD_File(OSD_Path(aFileName));
217 aFile.Build(OSD_WriteOnly,OSD_Protection());
220 Standard_Integer nbTri = 0;
221 SMDS_FaceIteratorPtr itFaces = myMesh->facesIterator();
223 // we first count the number of triangles
224 for (;itFaces->more();) {
225 SMDS_MeshFace* aFace = (SMDS_MeshFace*)itFaces->next();
226 if (aFace->NbNodes() == 3)
230 // write number of triangles
231 unsigned int NBT = nbTri;
232 aFile.Write((Standard_Address)sval,LABEL_SIZE);
233 writeInteger(nbTri,aFile);
235 // loop writing nodes. take face iterator again
237 itFaces = myMesh->facesIterator();
239 for (;itFaces->more();) {
240 SMDS_MeshFace* aFace = (SMDS_MeshFace*)itFaces->next();
242 if (aFace->NbNodes() == 3) {
243 gp_XYZ aNorm = getNormale( aFace );
244 writeFloat(aNorm.X(),aFile);
245 writeFloat(aNorm.Y(),aFile);
246 writeFloat(aNorm.Z(),aFile);
248 SMDS_ElemIteratorPtr aNodeIter = aFace->nodesIterator();
249 for (; aNodeIter->more(); ) {
250 SMDS_MeshNode* node = (SMDS_MeshNode*)aNodeIter->next();
251 writeFloat(node->X(),aFile);
252 writeFloat(node->Y(),aFile);
253 writeFloat(node->Z(),aFile);
255 aFile.Write (&dum,2);