00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include <gp_Pnt.hxx>
00025
00026
00027
00028
00029 inline Standard_Integer HashCode
00030 (const gp_Pnt& point, Standard_Integer Upper)
00031 {
00032 union
00033 {
00034 Standard_Real R[3];
00035 Standard_Integer I[6];
00036 } U;
00037
00038 point.Coord(U.R[0],U.R[1],U.R[2]);
00039
00040 return ::HashCode(U.I[0]/23+U.I[1]/19+U.I[2]/17+U.I[3]/13+U.I[4]/11+U.I[5]/7,Upper);
00041 }
00042 static Standard_Real tab1[3];
00043 static Standard_Real tab2[3];
00044
00045
00046
00047
00048 inline Standard_Boolean IsEqual
00049 (const gp_Pnt& point1, const gp_Pnt& point2)
00050 {
00051 point1.Coord(tab1[0],tab1[1],tab1[2]);
00052 point2.Coord(tab2[0],tab2[1],tab2[2]);
00053 return (memcmp(tab1,tab2,sizeof(tab1)) == 0);
00054 }
00055 #include "DriverSTL_R_SMDS_Mesh.h"
00056
00057 #include "SMDS_Mesh.hxx"
00058 #include "SMDS_MeshElement.hxx"
00059 #include "SMDS_MeshNode.hxx"
00060
00061 #include <OSD_Path.hxx>
00062 #include <OSD_File.hxx>
00063 #include <OSD_FromWhere.hxx>
00064 #include <OSD_Protection.hxx>
00065 #include <OSD_SingleProtection.hxx>
00066 #include <Standard_NoMoreObject.hxx>
00067
00068 #include "utilities.h"
00069
00070 static const int HEADER_SIZE = 84;
00071 static const int SIZEOF_STL_FACET = 50;
00072
00073 static const int ASCII_LINES_PER_FACET = 7;
00074
00075
00076
00077
00078
00079 #include <NCollection_DataMap.hxx>
00080 typedef NCollection_DataMap<gp_Pnt,SMDS_MeshNode*> DriverSTL_DataMapOfPntNodePtr;
00081
00082
00083
00084
00085
00086 DriverSTL_R_SMDS_Mesh::DriverSTL_R_SMDS_Mesh()
00087 {
00088 myIsCreateFaces = true;
00089 myIsAscii = Standard_True;
00090 }
00091
00092
00093
00094
00095
00096
00097 void DriverSTL_R_SMDS_Mesh::SetIsCreateFaces( const bool theIsCreate )
00098 { myIsCreateFaces = theIsCreate; }
00099
00100
00101
00102
00103
00104
00105 Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::Perform()
00106 {
00107 Status aResult = DRS_OK;
00108
00109 TCollection_AsciiString aFileName( (char *)myFile.c_str() );
00110 if ( aFileName.IsEmpty() ) {
00111 fprintf(stderr, ">> ERREOR : invalid file name \n");
00112 return DRS_FAIL;
00113 }
00114
00115 filebuf fic;
00116 Standard_IStream is(&fic);
00117 if (!fic.open(aFileName.ToCString(),ios::in)) {
00118 fprintf(stderr, ">> ERROR : cannot open file %s \n", aFileName.ToCString());
00119 return DRS_FAIL;
00120 }
00121
00122
00123 OSD_Path aPath( aFileName );
00124 OSD_File file = OSD_File( aPath );
00125 file.Open(OSD_ReadOnly,OSD_Protection(OSD_RWD,OSD_RWD,OSD_RWD,OSD_RWD));
00126 unsigned char str[128];
00127 Standard_Integer lread,i;
00128 Standard_Address ach;
00129 ach = (Standard_Address)str;
00130
00131 file.Read(ach,HEADER_SIZE,lread);
00132
00133
00134 file.Read(ach,sizeof(str),lread);
00135
00136 myIsAscii = Standard_True;
00137 for (i = 0; i < lread; ++i) {
00138 if (str[i] > '~') {
00139 myIsAscii = Standard_False;
00140 break;
00141 }
00142 }
00143
00144 file.Close();
00145
00146 if ( !myMesh ) {
00147 fprintf(stderr, ">> ERREOR : cannot create mesh \n");
00148 return DRS_FAIL;
00149 }
00150
00151 if ( myIsAscii )
00152 aResult = readAscii();
00153 else
00154 aResult = readBinary();
00155
00156 return aResult;
00157 }
00158
00159
00160
00161 static Standard_Real readFloat(OSD_File& theFile)
00162 {
00163 union {
00164 Standard_Boolean i;
00165 Standard_ShortReal f;
00166 }u;
00167
00168 char c[4];
00169 Standard_Address adr;
00170 adr = (Standard_Address)c;
00171 Standard_Integer lread;
00172 theFile.Read(adr,4,lread);
00173 u.i = c[0] & 0xFF;
00174 u.i |= (c[1] & 0xFF) << 0x08;
00175 u.i |= (c[2] & 0xFF) << 0x10;
00176 u.i |= (c[3] & 0xFF) << 0x18;
00177
00178 return u.f;
00179 }
00180
00181 static SMDS_MeshNode* addNode(const gp_Pnt& P,
00182 DriverSTL_DataMapOfPntNodePtr& uniqnodes,
00183 SMDS_Mesh* theMesh)
00184 {
00185 SMDS_MeshNode* node = 0;
00186 if ( uniqnodes.IsBound(P) ) {
00187 node = uniqnodes.Find(P);
00188 } else {
00189 node = theMesh->AddNode(P.X(), P.Y(), P.Z() );
00190 uniqnodes.Bind(P,node);
00191 }
00192
00193 return node;
00194 }
00195
00196 static SMDS_MeshNode* readNode(FILE* file,
00197 DriverSTL_DataMapOfPntNodePtr& uniqnodes,
00198 SMDS_Mesh* theMesh)
00199 {
00200 Standard_ShortReal coord[3];
00201
00202 fscanf(file,"%*s %f %f %f\n",&coord[0],&coord[1],&coord[2]);
00203
00204 gp_Pnt P(coord[0],coord[1],coord[2]);
00205 return addNode( P, uniqnodes, theMesh );
00206 }
00207
00208 static SMDS_MeshNode* readNode(OSD_File& theFile,
00209 DriverSTL_DataMapOfPntNodePtr& uniqnodes,
00210 SMDS_Mesh* theMesh)
00211 {
00212 Standard_ShortReal coord[3];
00213 coord[0] = readFloat(theFile);
00214 coord[1] = readFloat(theFile);
00215 coord[2] = readFloat(theFile);
00216
00217 gp_Pnt P(coord[0],coord[1],coord[2]);
00218 return addNode( P, uniqnodes, theMesh );
00219 }
00220
00221
00222
00223
00224
00225
00226 Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::readAscii() const
00227 {
00228 Status aResult = DRS_OK;
00229 long ipos;
00230 Standard_Integer nbLines = 0;
00231
00232
00233 TCollection_AsciiString aFileName( (char *)myFile.c_str() );
00234 FILE* file = fopen(aFileName.ToCString(),"r");
00235 fseek(file,0L,SEEK_END);
00236
00237 long filesize = ftell(file);
00238 fclose(file);
00239 file = fopen(aFileName.ToCString(),"r");
00240
00241
00242 for (ipos = 0; ipos < filesize; ++ipos) {
00243 if (getc(file) == '\n')
00244 nbLines++;
00245 }
00246
00247
00248
00249
00250 rewind(file);
00251
00252 Standard_Integer nbTri = (nbLines / ASCII_LINES_PER_FACET);
00253
00254 DriverSTL_DataMapOfPntNodePtr uniqnodes;
00255
00256 while (getc(file) != '\n');
00257
00258
00259 for (Standard_Integer iTri = 0; iTri < nbTri; ++iTri) {
00260
00261
00262 Standard_ShortReal normal[3];
00263 fscanf(file,"%*s %*s %f %f %f\n",&normal[0],&normal[1],&normal[2]);
00264
00265
00266 fscanf(file,"%*s %*s");
00267
00268
00269 SMDS_MeshNode* node1 = readNode( file, uniqnodes, myMesh );
00270 SMDS_MeshNode* node2 = readNode( file, uniqnodes, myMesh );
00271 SMDS_MeshNode* node3 = readNode( file, uniqnodes, myMesh );
00272
00273 if (myIsCreateFaces)
00274 myMesh->AddFace(node1,node2,node3);
00275
00276
00277 fscanf(file,"%*s");
00278
00279
00280 fscanf(file,"%*s");
00281 }
00282
00283 fclose(file);
00284 return aResult;
00285 }
00286
00287
00288
00289
00290
00291
00292 Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::readBinary() const
00293 {
00294 Status aResult = DRS_OK;
00295
00296 char buftest[5];
00297 Standard_Address adr;
00298 adr = (Standard_Address)buftest;
00299
00300 TCollection_AsciiString aFileName( (char *)myFile.c_str() );
00301 OSD_File aFile = OSD_File(OSD_Path( aFileName ));
00302 aFile.Open(OSD_ReadOnly,OSD_Protection(OSD_RWD,OSD_RWD,OSD_RWD,OSD_RWD));
00303
00304
00305
00306
00307
00308 Standard_Integer filesize = aFile.Size();
00309
00310 if ( (filesize - HEADER_SIZE) % SIZEOF_STL_FACET !=0
00311
00312 ) {
00313 Standard_NoMoreObject::Raise("DriverSTL_R_SMDS_MESH::readBinary (wrong file size)");
00314 }
00315
00316
00317
00318 Standard_Integer nbTri = ((filesize - HEADER_SIZE) / SIZEOF_STL_FACET);
00319
00320
00321 aFile.Seek(HEADER_SIZE,OSD_FromBeginning);
00322
00323 DriverSTL_DataMapOfPntNodePtr uniqnodes;
00324 Standard_Integer lread;
00325
00326 for (Standard_Integer iTri = 0; iTri < nbTri; ++iTri) {
00327
00328
00329 readFloat(aFile);
00330 readFloat(aFile);
00331 readFloat(aFile);
00332
00333
00334 SMDS_MeshNode* node1 = readNode( aFile, uniqnodes, myMesh );
00335 SMDS_MeshNode* node2 = readNode( aFile, uniqnodes, myMesh );
00336 SMDS_MeshNode* node3 = readNode( aFile, uniqnodes, myMesh );
00337
00338 if (myIsCreateFaces)
00339 myMesh->AddFace(node1,node2,node3);
00340
00341
00342 aFile.Read(adr,2,lread);
00343 }
00344 aFile.Close();
00345 return aResult;
00346 }