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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <triSurface/triSurface.H>
00039 #include <OpenFOAM/IFstream.H>
00040 #include <OpenFOAM/IStringStream.H>
00041
00042
00043
00044 namespace Foam
00045 {
00046
00047
00048
00049
00050 static scalar parseNASCoord(const string& s)
00051 {
00052 size_t expSign = s.find_last_of("+-");
00053
00054 if (expSign != string::npos && expSign > 0 && !isspace(s[expSign-1]))
00055 {
00056 scalar mantissa = readScalar(IStringStream(s.substr(0, expSign))());
00057 scalar exponent = readScalar(IStringStream(s.substr(expSign+1))());
00058
00059 if (s[expSign] == '-')
00060 {
00061 exponent = -exponent;
00062 }
00063 return mantissa*pow(10, exponent);
00064 }
00065 else
00066 {
00067 return readScalar(IStringStream(s)());
00068 }
00069 }
00070
00071
00072 bool triSurface::readNAS(const fileName& fName)
00073 {
00074 IFstream is(fName);
00075
00076 if (!is.good())
00077 {
00078 FatalErrorIn("triSurface::readNAS(const fileName&)")
00079 << "Cannot read file " << fName
00080 << exit(FatalError);
00081 }
00082
00083
00084 DynamicList<point> points;
00085
00086 DynamicList<label> indices;
00087
00088 DynamicList<labelledTri> faces;
00089
00090 Map<label> groupToPatch;
00091 label nPatches = 0;
00092
00093 Map<word> groupToName;
00094
00095
00096
00097
00098 label ansaId = -1;
00099 word ansaType;
00100 string ansaName;
00101
00102
00103 HashSet<word> unhandledCmd;
00104
00105 while (is.good())
00106 {
00107 string line;
00108 is.getLine(line);
00109
00110
00111 if (line.substr(0, 10) == "$ANSA_NAME")
00112 {
00113 string::size_type sem0 = line.find (';', 0);
00114 string::size_type sem1 = line.find (';', sem0+1);
00115 string::size_type sem2 = line.find (';', sem1+1);
00116
00117 if
00118 (
00119 sem0 != string::npos
00120 && sem1 != string::npos
00121 && sem2 != string::npos
00122 )
00123 {
00124 ansaId = readLabel
00125 (
00126 IStringStream(line.substr(sem0+1, sem1-sem0-1))()
00127 );
00128 ansaType = line.substr(sem1+1, sem2-sem1-1);
00129
00130 string nameString;
00131 is.getLine(ansaName);
00132 if (ansaName[ansaName.size()-1] == '\r')
00133 {
00134 ansaName = ansaName.substr(1, ansaName.size()-2);
00135 }
00136 else
00137 {
00138 ansaName = ansaName.substr(1, ansaName.size()-1);
00139 }
00140
00141
00142
00143
00144 }
00145 }
00146
00147
00148
00149
00150 if
00151 (
00152 line.substr(0, 12) == "$HMNAME COMP"
00153 && line.find ('"') != string::npos
00154 )
00155 {
00156 label groupId = readLabel
00157 (
00158 IStringStream(line.substr(16, 16))()
00159 );
00160
00161 IStringStream lineStream(line.substr(32));
00162
00163 string rawName;
00164 lineStream >> rawName;
00165
00166 groupToName.insert(groupId, string::validate<word>(rawName));
00167 Info<< "group " << groupId << " => " << rawName << endl;
00168 }
00169
00170
00171 if (line.empty() || line[0] == '$')
00172 {
00173
00174 continue;
00175 }
00176
00177
00178 if (line.size() > 72 && line[72] == '+')
00179 {
00180 line = line.substr(0, 72);
00181
00182 while (true)
00183 {
00184 string buf;
00185 is.getLine(buf);
00186
00187 if (buf.size() > 72 && buf[72]=='+')
00188 {
00189 line += buf.substr(8, 64);
00190 }
00191 else
00192 {
00193 line += buf.substr(8, buf.size()-8);
00194 break;
00195 }
00196 }
00197 }
00198
00199
00200 IStringStream lineStream(line);
00201 word cmd;
00202 lineStream >> cmd;
00203
00204 if (cmd == "CTRIA3")
00205 {
00206 label groupId = readLabel(IStringStream(line.substr(16,8))());
00207 label a = readLabel(IStringStream(line.substr(24,8))());
00208 label b = readLabel(IStringStream(line.substr(32,8))());
00209 label c = readLabel(IStringStream(line.substr(40,8))());
00210
00211
00212
00213 Map<label>::const_iterator iter = groupToPatch.find(groupId);
00214
00215 label patchI;
00216 if (iter == groupToPatch.end())
00217 {
00218 patchI = nPatches++;
00219 groupToPatch.insert(groupId, patchI);
00220 Info<< "patch " << patchI << " => group " << groupId << endl;
00221 }
00222 else
00223 {
00224 patchI = iter();
00225 }
00226
00227 faces.append(labelledTri(a, b, c, patchI));
00228 }
00229 else if (cmd == "CQUAD4")
00230 {
00231 label groupId = readLabel(IStringStream(line.substr(16,8))());
00232 label a = readLabel(IStringStream(line.substr(24,8))());
00233 label b = readLabel(IStringStream(line.substr(32,8))());
00234 label c = readLabel(IStringStream(line.substr(40,8))());
00235 label d = readLabel(IStringStream(line.substr(48,8))());
00236
00237
00238 Map<label>::const_iterator iter = groupToPatch.find(groupId);
00239
00240 label patchI;
00241 if (iter == groupToPatch.end())
00242 {
00243 patchI = nPatches++;
00244 groupToPatch.insert(groupId, patchI);
00245 Info<< "patch " << patchI << " => group " << groupId << endl;
00246 }
00247 else
00248 {
00249 patchI = iter();
00250 }
00251
00252 faces.append(labelledTri(a, b, c, patchI));
00253 faces.append(labelledTri(c, d, a, patchI));
00254 }
00255 else if (cmd == "PSHELL")
00256 {
00257
00258 label groupId = readLabel(IStringStream(line.substr(8,8))());
00259 if (groupId == ansaId && ansaType == "PSHELL")
00260 {
00261 groupToName.insert(groupId, string::validate<word>(ansaName));
00262 Info<< "group " << groupId << " => " << ansaName << endl;
00263 }
00264 }
00265 else if (cmd == "GRID")
00266 {
00267 label index = readLabel(IStringStream(line.substr(8,8))());
00268 scalar x = parseNASCoord(line.substr(24, 8));
00269 scalar y = parseNASCoord(line.substr(32, 8));
00270 scalar z = parseNASCoord(line.substr(40, 8));
00271
00272 indices.append(index);
00273 points.append(point(x, y, z));
00274 }
00275 else if (cmd == "GRID*")
00276 {
00277
00278
00279
00280
00281
00282
00283 label index = readLabel(IStringStream(line.substr(8,16))());
00284 scalar x = parseNASCoord(line.substr(40, 16));
00285 scalar y = parseNASCoord(line.substr(56, 16));
00286
00287 is.getLine(line);
00288 if (line[0] != '*')
00289 {
00290 FatalErrorIn("triSurface::readNAS(const fileName&)")
00291 << "Expected continuation symbol '*' when reading GRID*"
00292 << " (double precision coordinate) output" << nl
00293 << "Read:" << line << nl
00294 << "File:" << is.name()
00295 << " line:" << is.lineNumber()
00296 << exit(FatalError);
00297 }
00298 scalar z = parseNASCoord(line.substr(8, 16));
00299
00300 indices.append(index);
00301 points.append(point(x, y, z));
00302 }
00303 else if (unhandledCmd.insert(cmd))
00304 {
00305 Info<< "Unhandled Nastran command " << line << nl
00306 << "File:" << is.name() << " line:" << is.lineNumber() << endl;
00307 }
00308 }
00309
00310 points.shrink();
00311 indices.shrink();
00312 faces.shrink();
00313
00314
00315 Info<< "Read triangles:" << faces.size() << " points:" << points.size()
00316 << endl;
00317
00318 {
00319
00320 Map<label> indexToPoint(2*indices.size());
00321 forAll(indices, i)
00322 {
00323 indexToPoint.insert(indices[i], i);
00324 }
00325
00326
00327 forAll(faces, i)
00328 {
00329 labelledTri& f = faces[i];
00330
00331 f[0] = indexToPoint[f[0]];
00332 f[1] = indexToPoint[f[1]];
00333 f[2] = indexToPoint[f[2]];
00334 }
00335 }
00336
00337
00338
00339 geometricSurfacePatchList patches(nPatches);
00340
00341 forAllConstIter(Map<word>, groupToName, iter)
00342 {
00343 label patchI = groupToPatch[iter.key()];
00344
00345 patches[patchI] = geometricSurfacePatch
00346 (
00347 "empty",
00348 iter(),
00349 patchI
00350 );
00351 }
00352
00353 Info<< "patches:" << patches << endl;
00354
00355
00356 pointField allPoints(points.xfer());
00357
00358
00359 *this = triSurface(faces, patches, allPoints, true);
00360
00361 return true;
00362 }
00363
00364
00365
00366
00367 }
00368
00369