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