Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "STLsurfaceFormatCore.H"
00027 #include <OpenFOAM/gzstream.h>
00028 #include <OpenFOAM/OSspecific.H>
00029 #include <OpenFOAM/Map.H>
00030 #include <OpenFOAM/IFstream.H>
00031 #include <OpenFOAM/Ostream.H>
00032
00033 #undef DEBUG_STLBINARY
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 int Foam::fileFormats::STLsurfaceFormatCore::detectBINARY
00044 (
00045 const fileName& filename
00046 )
00047 {
00048 off_t dataFileSize = Foam::fileSize(filename);
00049
00050 IFstream str(filename, IOstream::BINARY);
00051 istream& is = str().stdStream();
00052
00053
00054 char header[headerSize];
00055 is.read(header, headerSize);
00056
00057
00058 if (!is.good())
00059 {
00060 return 0;
00061 }
00062
00063
00064
00065 int nTris;
00066 is.read(reinterpret_cast<char*>(&nTris), sizeof(unsigned int));
00067
00068
00069
00070
00071
00072
00073 if
00074 (
00075 !is
00076 || nTris < 0
00077 || nTris < (dataFileSize - headerSize)/50
00078 || nTris > (dataFileSize - headerSize)/25
00079 )
00080 {
00081 return 0;
00082 }
00083
00084
00085 return nTris;
00086 }
00087
00088
00089 bool Foam::fileFormats::STLsurfaceFormatCore::readBINARY
00090 (
00091 istream& is,
00092 const off_t dataFileSize
00093 )
00094 {
00095 sorted_ = true;
00096
00097
00098 char header[headerSize];
00099 is.read(header, headerSize);
00100
00101
00102 if (!is.good())
00103 {
00104 FatalErrorIn
00105 (
00106 "fileFormats::STLsurfaceFormatCore::readBINARY(IFstream&)"
00107 )
00108 << "problem reading header, perhaps file is not binary "
00109 << exit(FatalError);
00110 }
00111
00112
00113
00114 int nTris;
00115 is.read(reinterpret_cast<char*>(&nTris), sizeof(unsigned int));
00116
00117
00118
00119
00120
00121
00122 if
00123 (
00124 !is
00125 || nTris < 0
00126 || nTris < int(dataFileSize - headerSize)/50
00127 || nTris > int(dataFileSize - headerSize)/25
00128 )
00129 {
00130 FatalErrorIn
00131 (
00132 "fileFormats::STLsurfaceFormatCore::readBINARY(istream&)"
00133 )
00134 << "problem reading number of triangles, perhaps file is not binary"
00135 << exit(FatalError);
00136 }
00137
00138 #ifdef DEBUG_STLBINARY
00139 Info<< "# " << nTris << " facets" << endl;
00140 label prevZone = -1;
00141 #endif
00142
00143 points_.setSize(3*nTris);
00144 zoneIds_.setSize(nTris);
00145
00146 Map<label> lookup;
00147 DynamicList<label> dynSizes;
00148
00149 label ptI = 0;
00150 label zoneI = -1;
00151 forAll(zoneIds_, faceI)
00152 {
00153
00154 STLtriangle stlTri(is);
00155
00156
00157 points_[ptI++] = stlTri.a();
00158 points_[ptI++] = stlTri.b();
00159 points_[ptI++] = stlTri.c();
00160
00161
00162 const label origId = stlTri.attrib();
00163
00164 Map<label>::const_iterator fnd = lookup.find(origId);
00165 if (fnd != lookup.end())
00166 {
00167 if (zoneI != fnd())
00168 {
00169
00170 sorted_ = false;
00171 }
00172 zoneI = fnd();
00173 }
00174 else
00175 {
00176 zoneI = dynSizes.size();
00177 lookup.insert(origId, zoneI);
00178 dynSizes.append(0);
00179 }
00180
00181 zoneIds_[faceI] = zoneI;
00182 dynSizes[zoneI]++;
00183
00184 #ifdef DEBUG_STLBINARY
00185 if (prevZone != zoneI)
00186 {
00187 if (prevZone != -1)
00188 {
00189 Info<< "endsolid zone" << prevZone << nl;
00190 }
00191 prevZone = zoneI;
00192
00193 Info<< "solid zone" << prevZone << nl;
00194 }
00195
00196 Info<< " facet normal " << stlTri.normal() << nl
00197 << " outer loop" << nl
00198 << " vertex " << stlTri.a() << nl
00199 << " vertex " << stlTri.b() << nl
00200 << " vertex " << stlTri.c() << nl
00201 << " outer loop" << nl
00202 << " endfacet" << endl;
00203 #endif
00204 }
00205
00206 names_.clear();
00207 sizes_.transfer(dynSizes);
00208
00209 return true;
00210 }
00211
00212
00213
00214
00215 Foam::fileFormats::STLsurfaceFormatCore::STLsurfaceFormatCore
00216 (
00217 const fileName& filename
00218 )
00219 :
00220 sorted_(true),
00221 points_(0),
00222 zoneIds_(0),
00223 names_(0),
00224 sizes_(0)
00225 {
00226 off_t dataFileSize = Foam::fileSize(filename);
00227
00228
00229 if (detectBINARY(filename))
00230 {
00231 readBINARY
00232 (
00233 IFstream(filename, IOstream::BINARY)().stdStream(),
00234 dataFileSize
00235 );
00236 }
00237 else
00238 {
00239 readASCII
00240 (
00241 IFstream(filename)().stdStream(),
00242 dataFileSize
00243 );
00244 }
00245 }
00246
00247
00248
00249
00250 Foam::fileFormats::STLsurfaceFormatCore::~STLsurfaceFormatCore()
00251 {}
00252
00253
00254
00255
00256 void Foam::fileFormats::STLsurfaceFormatCore::writeHeaderBINARY
00257 (
00258 ostream& os,
00259 unsigned int nTris
00260 )
00261 {
00262
00263 char header[headerSize];
00264 sprintf(header, "STL binary file %u facets", nTris);
00265
00266
00267 for (size_t i = strlen(header); i < headerSize; ++i)
00268 {
00269 header[i] = 0;
00270 }
00271
00272 os.write(header, headerSize);
00273 os.write(reinterpret_cast<char*>(&nTris), sizeof(unsigned int));
00274
00275 }
00276
00277
00278