bool Foam::fileFormats::NASsurfaceFormat<Face>::read ( const fileName& filename ) { const bool mustTriangulate = this->isTri(); this->clear(); IFstream is(filename); if (!is.good()) { FatalErrorIn ( "fileFormats::NASsurfaceFormat::read(const fileName&)" ) << "Cannot read file " << filename << exit(FatalError); } // Nastran index of points DynamicList<label> pointId; DynamicList<point> dynPoints; DynamicList<Face> dynFaces; DynamicList<label> dynZones; DynamicList<label> dynSizes; Map<label> lookup; // assume the types are not intermixed // leave faces that didn't have a group in 0 bool sorted = true; label zoneI = 0; // Name for face group Map<word> nameLookup; // Ansa tags. Denoted by $ANSA_NAME. // These will appear just before the first use of a type. // We read them and store the PSHELL types which are used to name // the zones. label ansaId = -1; word ansaType, ansaName; // A single warning per unrecognized command HashSet<word> unhandledCmd; while (is.good()) { string line; is.getLine(line); // Ansa extension if (line.substr(0, 10) == "$ANSA_NAME") { string::size_type sem0 = line.find (';', 0); string::size_type sem1 = line.find (';', sem0+1); string::size_type sem2 = line.find (';', sem1+1); if ( sem0 != string::npos && sem1 != string::npos && sem2 != string::npos ) { ansaId = readLabel ( IStringStream(line.substr(sem0+1, sem1-sem0-1))() ); ansaType = line.substr(sem1+1, sem2-sem1-1); string rawName; is.getLine(rawName); if (rawName[rawName.size()-1] == '\r') { rawName = rawName.substr(1, rawName.size()-2); } else { rawName = rawName.substr(1, rawName.size()-1); } string::stripInvalid<word>(rawName); ansaName = rawName; // Info<< "ANSA tag for NastranID:" << ansaId // << " of type " << ansaType // << " name " << ansaName << endl; } } // Hypermesh extension // $HMNAME COMP 1"partName" if ( line.substr(0, 12) == "$HMNAME COMP" && line.find ('"') != string::npos ) { label groupId = readLabel ( IStringStream(line.substr(16, 16))() ); IStringStream lineStream(line.substr(32)); string rawName; lineStream >> rawName; string::stripInvalid<word>(rawName); word groupName(rawName); nameLookup.insert(groupId, groupName); // Info<< "group " << groupId << " => " << groupName << endl; } // Skip empty or comment if (line.empty() || line[0] == '$') { continue; } // Check if character 72 is continuation if (line.size() > 72 && line[72] == '+') { line = line.substr(0, 72); while (true) { string buf; is.getLine(buf); if (buf.size() > 72 && buf[72] == '+') { line += buf.substr(8, 64); } else { line += buf.substr(8, buf.size()-8); break; } } } // Read first word IStringStream lineStream(line); word cmd; lineStream >> cmd; if (cmd == "CTRIA3") { triFace fTri; label groupId = readLabel(IStringStream(line.substr(16,8))()); fTri[0] = readLabel(IStringStream(line.substr(24,8))()); fTri[1] = readLabel(IStringStream(line.substr(32,8))()); fTri[2] = readLabel(IStringStream(line.substr(40,8))()); // Convert groupID into zoneId Map<label>::const_iterator fnd = lookup.find(groupId); if (fnd != lookup.end()) { if (zoneI != fnd()) { // pshell types are intermixed sorted = false; } zoneI = fnd(); } else { zoneI = dynSizes.size(); lookup.insert(groupId, zoneI); dynSizes.append(0); // Info<< "zone" << zoneI << " => group " << groupId <<endl; } dynFaces.append(fTri); dynZones.append(zoneI); dynSizes[zoneI]++; } else if (cmd == "CQUAD4") { face fQuad(4); UList<label>& f = static_cast<UList<label>&>(fQuad); label groupId = readLabel(IStringStream(line.substr(16,8))()); fQuad[0] = readLabel(IStringStream(line.substr(24,8))()); fQuad[1] = readLabel(IStringStream(line.substr(32,8))()); fQuad[2] = readLabel(IStringStream(line.substr(40,8))()); fQuad[3] = readLabel(IStringStream(line.substr(48,8))()); // Convert groupID into zoneId Map<label>::const_iterator fnd = lookup.find(groupId); if (fnd != lookup.end()) { if (zoneI != fnd()) { // pshell types are intermixed sorted = false; } zoneI = fnd(); } else { zoneI = dynSizes.size(); lookup.insert(groupId, zoneI); dynSizes.append(0); // Info<< "zone" << zoneI << " => group " << groupId <<endl; } if (mustTriangulate) { dynFaces.append(triFace(f[0], f[1], f[2])); dynFaces.append(triFace(f[0], f[2], f[3])); dynZones.append(zoneI); dynZones.append(zoneI); dynSizes[zoneI] += 2; } else { dynFaces.append(Face(f)); dynZones.append(zoneI); dynSizes[zoneI]++; } } else if (cmd == "GRID") { label index = readLabel(IStringStream(line.substr(8,8))()); scalar x = parseNASCoord(line.substr(24, 8)); scalar y = parseNASCoord(line.substr(32, 8)); scalar z = parseNASCoord(line.substr(40, 8)); pointId.append(index); dynPoints.append(point(x, y, z)); } else if (cmd == "GRID*") { // Long format is on two lines with '*' continuation symbol // on start of second line. // Typical line (spaces compacted) // GRID* 126 0 -5.55999875E+02 -5.68730474E+02 // * 2.14897901E+02 label index = readLabel(IStringStream(line.substr(8,16))()); scalar x = parseNASCoord(line.substr(40, 16)); scalar y = parseNASCoord(line.substr(56, 16)); is.getLine(line); if (line[0] != '*') { FatalErrorIn ( "fileFormats::NASsurfaceFormat::read(const fileName&)" ) << "Expected continuation symbol '*' when reading GRID*" << " (double precision coordinate) format" << nl << "Read:" << line << nl << "File:" << is.name() << " line:" << is.lineNumber() << exit(FatalError); } scalar z = parseNASCoord(line.substr(8, 16)); pointId.append(index); dynPoints.append(point(x, y, z)); } else if (cmd == "PSHELL") { // pshell type for zone names with the Ansa extension label groupId = readLabel(IStringStream(line.substr(8,8))()); if (groupId == ansaId && ansaType == "PSHELL") { nameLookup.insert(ansaId, ansaName); // Info<< "group " << groupId << " => " << ansaName << endl; } } else if (unhandledCmd.insert(cmd)) { Info<< "Unhandled Nastran command " << line << nl << "File:" << is.name() << " line:" << is.lineNumber() << endl; } }
bool triSurface::readNAS(const fileName& fName) { IFstream is(fName); if (!is.good()) { FatalErrorIn("triSurface::readNAS(const fileName&)") << "Cannot read file " << fName << exit(FatalError); } // coordinates of point DynamicList<point> points; // Nastran index of point DynamicList<label> indices; // Faces in terms of Nastran point indices DynamicList<labelledTri> faces; // From face group to patch Map<label> groupToPatch; label nPatches = 0; // Name for face group Map<word> groupToName; // Ansa tags. Denoted by $ANSA_NAME. These will appear just before the // first use of a type. We read them and store the pshell types which // are used to name the patches. label ansaId = -1; word ansaType; string ansaName; // A single warning per unrecognized command HashSet<word> unhandledCmd; while (is.good()) { string line; is.getLine(line); // Ansa extension if (line.substr(0, 10) == "$ANSA_NAME") { string::size_type sem0 = line.find (';', 0); string::size_type sem1 = line.find (';', sem0+1); string::size_type sem2 = line.find (';', sem1+1); if ( sem0 != string::npos && sem1 != string::npos && sem2 != string::npos ) { ansaId = readLabel ( IStringStream(line.substr(sem0+1, sem1-sem0-1))() ); ansaType = line.substr(sem1+1, sem2-sem1-1); string nameString; is.getLine(ansaName); if (ansaName[ansaName.size()-1] == '\r') { ansaName = ansaName.substr(1, ansaName.size()-2); } else { ansaName = ansaName.substr(1, ansaName.size()-1); } // Info<< "ANSA tag for NastranID:" << ansaId // << " of type " << ansaType // << " name " << ansaName << endl; } } // Hypermesh extension // $HMNAME COMP 1"partName" if ( line.substr(0, 12) == "$HMNAME COMP" && line.find ('"') != string::npos ) { label groupId = readLabel ( IStringStream(line.substr(16, 16))() ); IStringStream lineStream(line.substr(32)); string rawName; lineStream >> rawName; groupToName.insert(groupId, string::validate<word>(rawName)); Info<< "group " << groupId << " => " << rawName << endl; } if (line.empty() || line[0] == '$') { // Skip empty or comment continue; } // Check if character 72 is continuation if (line.size() > 72 && line[72] == '+') { line = line.substr(0, 72); while (true) { string buf; is.getLine(buf); if (buf.size() > 72 && buf[72]=='+') { line += buf.substr(8, 64); } else { line += buf.substr(8, buf.size()-8); break; } } } // Read first word IStringStream lineStream(line); word cmd; lineStream >> cmd; if (cmd == "CTRIA3") { label groupId = readLabel(IStringStream(line.substr(16,8))()); label a = readLabel(IStringStream(line.substr(24,8))()); label b = readLabel(IStringStream(line.substr(32,8))()); label c = readLabel(IStringStream(line.substr(40,8))()); // Convert group into patch Map<label>::const_iterator iter = groupToPatch.find(groupId); label patchI; if (iter == groupToPatch.end()) { patchI = nPatches++; groupToPatch.insert(groupId, patchI); Info<< "patch " << patchI << " => group " << groupId << endl; } else { patchI = iter(); } faces.append(labelledTri(a, b, c, patchI)); } else if (cmd == "CQUAD4") { label groupId = readLabel(IStringStream(line.substr(16,8))()); label a = readLabel(IStringStream(line.substr(24,8))()); label b = readLabel(IStringStream(line.substr(32,8))()); label c = readLabel(IStringStream(line.substr(40,8))()); label d = readLabel(IStringStream(line.substr(48,8))()); // Convert group into patch Map<label>::const_iterator iter = groupToPatch.find(groupId); label patchI; if (iter == groupToPatch.end()) { patchI = nPatches++; groupToPatch.insert(groupId, patchI); Info<< "patch " << patchI << " => group " << groupId << endl; } else { patchI = iter(); } faces.append(labelledTri(a, b, c, patchI)); faces.append(labelledTri(c, d, a, patchI)); } else if (cmd == "PSHELL") { // Read shell type since group gives patchnames label groupId = readLabel(IStringStream(line.substr(8,8))()); if (groupId == ansaId && ansaType == "PSHELL") { groupToName.insert(groupId, string::validate<word>(ansaName)); Info<< "group " << groupId << " => " << ansaName << endl; } } else if (cmd == "GRID") { label index = readLabel(IStringStream(line.substr(8,8))()); scalar x = parseNASCoord(line.substr(24, 8)); scalar y = parseNASCoord(line.substr(32, 8)); scalar z = parseNASCoord(line.substr(40, 8)); indices.append(index); points.append(point(x, y, z)); } else if (cmd == "GRID*") { // Long format is on two lines with '*' continuation symbol // on start of second line. // Typical line (spaces compacted) // GRID* 126 0 -5.55999875E+02 -5.68730474E+02 // * 2.14897901E+02 label index = readLabel(IStringStream(line.substr(8,16))()); scalar x = parseNASCoord(line.substr(40, 16)); scalar y = parseNASCoord(line.substr(56, 16)); is.getLine(line); if (line[0] != '*') { FatalErrorIn("triSurface::readNAS(const fileName&)") << "Expected continuation symbol '*' when reading GRID*" << " (double precision coordinate) output" << nl << "Read:" << line << nl << "File:" << is.name() << " line:" << is.lineNumber() << exit(FatalError); } scalar z = parseNASCoord(line.substr(8, 16)); indices.append(index); points.append(point(x, y, z)); } else if (unhandledCmd.insert(cmd)) { Info<< "Unhandled Nastran command " << line << nl << "File:" << is.name() << " line:" << is.lineNumber() << endl; } }
bool Foam::fileFormats::NASedgeFormat::read ( const fileName& filename ) { clear(); IFstream is(filename); if (!is.good()) { FatalErrorInFunction << "Cannot read file " << filename << exit(FatalError); } DynamicList<point> dynPoints; DynamicList<edge> dynEdges; DynamicList<label> pointId; // Nastran index of points while (is.good()) { string line; is.getLine(line); // Skip empty or comment if (line.empty() || line[0] == '$') { continue; } // Check if character 72 is continuation if (line.size() > 72 && line[72] == '+') { line = line.substr(0, 72); while (true) { string buf; is.getLine(buf); if (buf.size() > 72 && buf[72] == '+') { line += buf.substr(8, 64); } else { line += buf.substr(8, buf.size()-8); break; } } } // Read first word IStringStream lineStream(line); word cmd; lineStream >> cmd; if (cmd == "CBEAM" || cmd == "CROD") { edge e; // label groupId = readLabel(IStringStream(line.substr(16,8))()); e[0] = readLabel(IStringStream(line.substr(24,8))()); e[1] = readLabel(IStringStream(line.substr(32,8))()); // discard groupID dynEdges.append(e); } else if (cmd == "PLOTEL") { edge e; // label groupId = readLabel(IStringStream(line.substr(16,8))()); e[0] = readLabel(IStringStream(line.substr(16,8))()); e[1] = readLabel(IStringStream(line.substr(24,8))()); // discard groupID dynEdges.append(e); } else if (cmd == "GRID") { label index = readLabel(IStringStream(line.substr(8,8))()); scalar x = parseNASCoord(line.substr(24, 8)); scalar y = parseNASCoord(line.substr(32, 8)); scalar z = parseNASCoord(line.substr(40, 8)); pointId.append(index); dynPoints.append(point(x, y, z)); } else if (cmd == "GRID*") { // Long format is on two lines with '*' continuation symbol // on start of second line. // Typical line (spaces compacted) // GRID* 126 0 -5.55999875E+02 -5.68730474E+02 // * 2.14897901E+02 label index = readLabel(IStringStream(line.substr(8,16))()); scalar x = parseNASCoord(line.substr(40, 16)); scalar y = parseNASCoord(line.substr(56, 16)); is.getLine(line); if (line[0] != '*') { FatalErrorInFunction << "Expected continuation symbol '*' when reading GRID*" << " (double precision coordinate) format" << nl << "Read:" << line << nl << "File:" << is.name() << " line:" << is.lineNumber() << exit(FatalError); } scalar z = parseNASCoord(line.substr(8, 16)); pointId.append(index); dynPoints.append(point(x, y, z)); } } // transfer to normal lists storedPoints().transfer(dynPoints); pointId.shrink(); dynEdges.shrink(); // Build inverse mapping (NASTRAN pointId -> index) Map<label> mapPointId(2*pointId.size()); forAll(pointId, i) { mapPointId.insert(pointId[i], i); }