Salome HOME
Merge branch 'OCCT780'
[modules/smesh.git] / src / DriverSTL / DriverSTL_R_SMDS_Mesh.cxx
index 4a02cb29f8d1446d8a45ce33c6bbaf4387b04f3d..c2fd53597f643c596c4dbf1d257ed8c9ff2c2a2a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -23,6 +23,7 @@
 #include "DriverSTL_R_SMDS_Mesh.h"
 
 #include <Basics_Utils.hxx>
+#include <Basics_OCCTVersion.hxx>
 
 #include <gp_Pnt.hxx>
 #include <NCollection_DataMap.hxx>
@@ -41,8 +42,12 @@ namespace
     //function : HashCode
     //purpose  :
     //=======================================================================
+#if OCC_VERSION_LARGE < 0x07080000
     inline static Standard_Integer HashCode
     (const gp_Pnt& point,  Standard_Integer Upper)
+#else
+    size_t operator()(const gp_Pnt& point) const
+#endif
     {
       union
       {
@@ -52,14 +57,22 @@ namespace
 
       point.Coord( U.R[0], U.R[1], U.R[2] );
 
+#if OCC_VERSION_LARGE < 0x07080000
       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);
+#else
+      return static_cast<size_t>(U.I[0]/23+U.I[1]/19+U.I[2]/17+U.I[3]/13+U.I[4]/11+U.I[5]/7);
+#endif
     }
     //=======================================================================
     //function : IsEqual
     //purpose  :
     //=======================================================================
+#if OCC_VERSION_LARGE < 0x07080000
     inline static Standard_Boolean IsEqual
     (const gp_Pnt& point1, const gp_Pnt& point2)
+#else
+    bool operator()(const gp_Pnt& point1, const gp_Pnt& point2) const
+#endif
     {
       static Standard_Real tab1[3], tab2[3];
       point1.Coord(tab1[0],tab1[1],tab1[2]);
@@ -69,7 +82,7 @@ namespace
   };
   typedef NCollection_DataMap<gp_Pnt,SMDS_MeshNode*,Hasher> TDataMapOfPntNodePtr;
 
-  const int HEADER_SIZE           = 84;
+  const int HEADER_SIZE           = 84; // 80 chars + int
   const int SIZEOF_STL_FACET      = 50;
   const int ASCII_LINES_PER_FACET = 7;
   const int SIZE_OF_FLOAT         = 4;
@@ -142,6 +155,9 @@ Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::Perform()
   else
     aResult = readBinary( file );
 
+  myMesh->Modified();
+  myMesh->CompactMesh();
+
   return aResult;
 }
 
@@ -150,11 +166,12 @@ Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::Perform()
 static Standard_Real readFloat(SMESH_File& theFile)
 {
   union {
-    Standard_Boolean i;
-    Standard_ShortReal f;
+    int   i;
+    float f;
   } u;
 
   const char* c = theFile;
+  u.i  = 0;
   u.i  =  c[0] & 0xFF;
   u.i |= (c[1] & 0xFF) << 0x08;
   u.i |= (c[2] & 0xFF) << 0x10;
@@ -205,30 +222,53 @@ static SMDS_MeshNode* readNode(SMESH_File& theFile,
 
 //=======================================================================
 //function : readAscii
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::readAscii(SMESH_File& theFile) const
 {
   Status aResult = DRS_OK;
 
+  // get a solid name
+  if ( strncmp( "solid ", theFile, strlen("solid ")) == 0 ) // not empty
+  {
+    const char * header = theFile;
+    std::string& name = const_cast<std::string&>( myName );
+    for ( header += strlen("solid "); !iscntrl( *header ); ++header )
+      name.push_back( *header );
+
+    std::string::iterator i = name.begin();
+    while ( i != name.end() && isspace( *i )) ++i;
+    name.erase( name.begin(), i );
+
+    size_t n = name.size();
+    while ( n > 0 && isspace( name[ n - 1 ] )) --n;
+    name.resize( n );
+  }
+
   // get the file size
   long filesize = theFile.size();
   theFile.close();
 
-  // Open the file 
-  FILE* file = fopen( myFile.c_str(),"r");
+  // Open the file
+#if defined(WIN32) && defined(UNICODE)
+  std::wstring aFile = Kernel_Utils::utf8_decode_s(myFile);
+  FILE* file = _wfopen( aFile.c_str(), L"r");
+#else
+  FILE* file = fopen(myFile.c_str(), "r");  
+#endif  
 
   // count the number of lines
   Standard_Integer nbLines = 0;
-  for (long ipos = 0; ipos < filesize; ++ipos) {
+  for (long ipos = 0; ipos < filesize; ++ipos)
+  {
     if (getc(file) == '\n')
       nbLines++;
   }
 
   // go back to the beginning of the file
   rewind(file);
-  
+
   Standard_Integer nbTri = (nbLines / ASCII_LINES_PER_FACET);
 
   TDataMapOfPntNodePtr uniqnodes;
@@ -236,8 +276,8 @@ Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::readAscii(SMESH_File& theFile) const
   while (getc(file) != '\n');
 
   // main reading
-  for (Standard_Integer iTri = 0; iTri < nbTri; ++iTri) {
-
+  for (Standard_Integer iTri = 0; iTri < nbTri; ++iTri)
+  {
     // skipping the facet normal
     Standard_ShortReal normal[3];
     fscanf(file,"%*s %*s %f %f %f\n",&normal[0],&normal[1],&normal[2]);
@@ -278,7 +318,7 @@ Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::readBinary(SMESH_File& file) const
 
   long filesize = file.size();
 
-  if ( (filesize - HEADER_SIZE) % SIZEOF_STL_FACET !=0 
+  if ( (filesize - HEADER_SIZE) % SIZEOF_STL_FACET != 
       // Commented to allow reading small files (ex: 1 face)
       /*|| (filesize < STL_MIN_FILE_SIZE)*/) {
     Standard_NoMoreObject::Raise("DriverSTL_R_SMDS_MESH::readBinary (wrong file size)");
@@ -288,6 +328,19 @@ Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::readBinary(SMESH_File& file) const
   // sometimes it is wrong, and with this technique we don't need to swap endians for integer
   Standard_Integer nbTri = ((filesize - HEADER_SIZE) / SIZEOF_STL_FACET);
 
+  // get a solid name
+  if ( strncmp( "name: ", file, strlen("name: ")) == 0 ) // name present
+  {
+    const char * header = file;
+    std::string&   name = const_cast<std::string&>( myName );
+    header += strlen("name: ");
+    name.assign( header, HEADER_SIZE - strlen("name: ") - 4);
+
+    size_t n = name.size();
+    while ( n > 0 && isspace( name[ n - 1 ] )) --n;
+    name.resize( n );
+  }
+
   // skip the header
   file += HEADER_SIZE;