diff --git a/src/Mod/Fem/App/FemMesh.cpp b/src/Mod/Fem/App/FemMesh.cpp index 601df01c6b..2255b97982 100644 --- a/src/Mod/Fem/App/FemMesh.cpp +++ b/src/Mod/Fem/App/FemMesh.cpp @@ -1280,6 +1280,433 @@ void FemMesh::readNastran(const std::string &Filename) } +void FemMesh::readNastran95(const std::string &Filename) +{ + Base::TimeInfo Start; + Base::Console().Log("Start: FemMesh::readNastran95() =================================\n"); + + _Mtrx = Base::Matrix4D(); + + std::ifstream inputfile; + inputfile.open(Filename.c_str()); + inputfile.seekg(std::ifstream::beg); + std::string line1,line2,temp,tcard; + float cx, cy, cz; + std::vector token_results; + token_results.clear(); + Base::Vector3d current_node; + std::vector vertices; + vertices.clear(); + std::vector nodal_id; + + nodal_id.clear(); + + std::vector bar_element; + std::vector tri_element; + std::vector quad_element; + std::vector tetra_element; + std::vector wedge_element; + std::vector hexa_element; + + std::vector > all_elements; + + std::vector element_id; + std::vector element_type; + + element_id.clear(); + element_type.clear(); + + bool nastran_free_format = false; + do + { + std::getline(inputfile,line1); + //cout << line1 << endl; + if (line1.size() == 0) continue; + //if (!nastran_free_format && line1.find(',')!= std::string::npos) + // nastran_free_format = true; + tcard = line1.substr(0, 8).c_str(); + //boost::algorithm::trim(tcard); + if (!nastran_free_format && line1.find("GRID*")!= std::string::npos ) //We found a Grid line + { + //Now lets extract the GRID Points = Nodes + //As each GRID Line consists of two subsequent lines we have to + //take care of that as well + std::getline(inputfile,line2); + //Get the Nodal ID + nodal_id.push_back(atoi(line1.substr(8,24).c_str())); + //Extract X Value + current_node.x = atof(line1.substr(40,56).c_str()); + //Extract Y Value + current_node.y = atof(line1.substr(56,72).c_str()); + //Extract Z Value + current_node.z = atof(line2.substr(8,24).c_str()); + + vertices.push_back(current_node); + } + else if (!nastran_free_format && line1.find("GRID") != std::string::npos) //We found a Grid line + { + //Base::Console().Log("Found a GRID\n"); + //D06.inp + //GRID 109 .9 .7 + //Now lets extract the GRID Points = Nodes + //Get the Nodal ID + unsigned int id = atoi(line1.substr(8, 16).c_str()); + + //Extract X Value + cx = atof(line1.substr(24, 32).c_str()); + current_node.x = cx; + //Extract Y Value + cy = atof(line1.substr(32, 40).c_str()); + current_node.y = cy; + //Extract Z Value + cz = atof(line1.substr(40, 48).c_str()); + current_node.z = cz; + // atof(line1.substr(40, 48).c_str()); + //Base::Console().Log("nid = %d %f %f %f\n", id, cx, cy, cz); + + nodal_id.push_back(id); + vertices.push_back(current_node); + } + + //1D + else if (line1.substr(0,6)=="CBAR") + { + //Base::Console().Log("Found a CTRMEM\n"); + bar_element.clear(); + unsigned int id = atoi(line1.substr(8,16).c_str()); + + element_type.push_back(100); + element_id.push_back(id); + bar_element.push_back(atoi(line1.substr(24,32).c_str())); + bar_element.push_back(atoi(line1.substr(32,40).c_str())); + + all_elements.push_back(bar_element); + } + //2d +// else if (!nastran_free_format && line1.find("CTRMEM")!= std::string::npos) + else if (line1.substr(0,6)=="CTRMEM") + { + //Base::Console().Log("Found a CTRMEM\n"); + tri_element.clear(); + unsigned int id = atoi(line1.substr(8,16).c_str()); + + //D06 + //CTRMEM 322 1 179 180 185 + element_type.push_back(230); + element_id.push_back(id); + tri_element.push_back(atoi(line1.substr(24,32).c_str())); + tri_element.push_back(atoi(line1.substr(32,40).c_str())); + tri_element.push_back(atoi(line1.substr(40,48).c_str())); + + all_elements.push_back(tri_element); + } + else if (line1.substr(0, 6) == "CTRIA1") + { + //Base::Console().Log("Found a CTRMEM\n"); + tri_element.clear(); + unsigned int id = atoi(line1.substr(8, 16).c_str()); + + //D06 + //CTRMEM 322 1 179 180 185 + element_type.push_back(231); + element_id.push_back(id); + tri_element.push_back(atoi(line1.substr(24, 32).c_str())); + tri_element.push_back(atoi(line1.substr(32, 40).c_str())); + tri_element.push_back(atoi(line1.substr(40, 48).c_str())); + + all_elements.push_back(tri_element); + } + else if (line1.substr(0, 6) == "CQUAD1") + { + //Base::Console().Log("Found a CQUAD1\n"); + quad_element.clear(); + unsigned int id = atoi(line1.substr(8, 16).c_str()); + + //D06 + //CTRMEM 322 1 179 180 185 + element_type.push_back(241); + element_id.push_back(id); + quad_element.push_back(atoi(line1.substr(24, 32).c_str())); + quad_element.push_back(atoi(line1.substr(32, 40).c_str())); + quad_element.push_back(atoi(line1.substr(40, 48).c_str())); + quad_element.push_back(atoi(line1.substr(48, 56).c_str())); + + all_elements.push_back(quad_element); + } + + //3d element + else if (!nastran_free_format && line1.find("CTETRA")!= std::string::npos) + { + //d011121a.inp + //CTETRA 3 200 104 114 3 103 + tetra_element.clear(); + unsigned int id = atoi(line1.substr(8,16).c_str()); + element_type.push_back(340); + + element_id.push_back(id); + tetra_element.push_back(atoi(line1.substr(24,32).c_str())); + tetra_element.push_back(atoi(line1.substr(32,40).c_str())); + tetra_element.push_back(atoi(line1.substr(40,48).c_str())); + tetra_element.push_back(atoi(line1.substr(48,56).c_str())); + //tetra_element.push_back(atoi(line1.substr(56,64).c_str())); + //tetra_element.push_back(atoi(line1.substr(64,72).c_str())); + + all_elements.push_back(tetra_element); + } + else if (!nastran_free_format && line1.find("CWEDGE")!= std::string::npos) + { + //d011121a.inp + //CWEDGE 11 200 6 17 16 106 117 116 + tetra_element.clear(); + unsigned int id = atoi(line1.substr(8,16).c_str()); + element_type.push_back(360); + + element_id.push_back(id); + wedge_element.push_back(atoi(line1.substr(24,32).c_str())); + wedge_element.push_back(atoi(line1.substr(32,40).c_str())); + wedge_element.push_back(atoi(line1.substr(40,48).c_str())); + wedge_element.push_back(atoi(line1.substr(48,56).c_str())); + wedge_element.push_back(atoi(line1.substr(56,64).c_str())); + wedge_element.push_back(atoi(line1.substr(64,72).c_str())); + + all_elements.push_back(wedge_element); + } + else if (!nastran_free_format && line1.find("CHEXA1")!= std::string::npos) + { + //d011121a.inp + //CHEXA1 1 200 1 2 13 12 101 102 +SOL1 + //+SOL1 113 112 + tetra_element.clear(); + std::getline(inputfile,line2); + unsigned int id = atoi(line1.substr(8,16).c_str()); + element_type.push_back(381); + int offset = 0; + + element_id.push_back(id); + hexa_element.push_back(atoi(line1.substr(24,32).c_str())); + hexa_element.push_back(atoi(line1.substr(32,40).c_str())); + hexa_element.push_back(atoi(line1.substr(40,48).c_str())); + hexa_element.push_back(atoi(line1.substr(48,56).c_str())); + hexa_element.push_back(atoi(line1.substr(56,64).c_str())); + hexa_element.push_back(atoi(line1.substr(64,72).c_str())); + + hexa_element.push_back(atoi(line2.substr(8,16).c_str())); + hexa_element.push_back(atoi(line2.substr(16,24).c_str())); + + all_elements.push_back(hexa_element); + } + else if (!nastran_free_format && line1.find("CHEXA2")!= std::string::npos) + { + //d011121a.inp + //CHEXA1 1 200 1 2 13 12 101 102 +SOL1 + //+SOL1 113 112 + tetra_element.clear(); + std::getline(inputfile,line2); + unsigned int id = atoi(line1.substr(8,16).c_str()); + element_type.push_back(382); + int offset = 0; + + element_id.push_back(id); + hexa_element.push_back(atoi(line1.substr(24,32).c_str())); + hexa_element.push_back(atoi(line1.substr(32,40).c_str())); + hexa_element.push_back(atoi(line1.substr(40,48).c_str())); + hexa_element.push_back(atoi(line1.substr(48,56).c_str())); + hexa_element.push_back(atoi(line1.substr(56,64).c_str())); + hexa_element.push_back(atoi(line1.substr(64,72).c_str())); + + hexa_element.push_back(atoi(line2.substr(8,16).c_str())); + hexa_element.push_back(atoi(line2.substr(16,24).c_str())); + + all_elements.push_back(hexa_element); + } + +// free format + else if (nastran_free_format && line1.find("GRID")!= std::string::npos ) //We found a Grid line + { + //Base::Console().Log("Found a free format GRID\n"); + char_separator sep(","); + tokenizer > tokens(line1, sep); + token_results.assign(tokens.begin(),tokens.end()); + if (token_results.size() < 3) + continue;//Line does not include Nodal coordinates + nodal_id.push_back(atoi(token_results[1].c_str())); + current_node.x = atof(token_results[3].c_str()); + current_node.y = atof(token_results[4].c_str()); + current_node.z = atof(token_results[5].c_str()); + vertices.push_back(current_node); + } + else if (nastran_free_format && line1.find("CTETRA")!= std::string::npos) + { + //Base::Console().Log("Found a CTETRA\n"); + tetra_element.clear(); + //Lets extract the elements + //As each Element Line consists of two subsequent lines as well + //we have to take care of that + //At a first step we only extract Quadratic Tetrahedral Elements + std::getline(inputfile,line2); + char_separator sep(","); + tokenizer > tokens(line1.append(line2), sep); + token_results.assign(tokens.begin(),tokens.end()); + if (token_results.size() < 11) + continue;//Line does not include enough nodal IDs + element_id.push_back(atoi(token_results[1].c_str())); + tetra_element.push_back(atoi(token_results[3].c_str())); + tetra_element.push_back(atoi(token_results[4].c_str())); + tetra_element.push_back(atoi(token_results[5].c_str())); + tetra_element.push_back(atoi(token_results[6].c_str())); + tetra_element.push_back(atoi(token_results[7].c_str())); + tetra_element.push_back(atoi(token_results[8].c_str())); + tetra_element.push_back(atoi(token_results[10].c_str())); + tetra_element.push_back(atoi(token_results[11].c_str())); + tetra_element.push_back(atoi(token_results[12].c_str())); + tetra_element.push_back(atoi(token_results[13].c_str())); + + all_elements.push_back(tetra_element); + } + + } + while (inputfile.good()); + inputfile.close(); + +// Base::Console().Log("Done saving node.\n"); + Base::Console().Log(" %f: File read, start building mesh\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); + + //Now fill the SMESH datastructure + std::vector::const_iterator anodeiterator; + SMESHDS_Mesh* meshds = this->myMesh->GetMeshDS(); + meshds->ClearMesh(); + unsigned int j=0; + for(anodeiterator=vertices.begin(); anodeiterator!=vertices.end(); anodeiterator++) + { + meshds->AddNodeWithID((*anodeiterator).x,(*anodeiterator).y,(*anodeiterator).z,nodal_id[j]); + //Base::Console().Log("nid = %d %f %f %f\n", nodal_id[j], (*anodeiterator).x, (*anodeiterator).y, (*anodeiterator).z); + j++; + } + + + for(unsigned int i=0;iAddVolumeWithID + ( + //tetra 10 point + meshds->FindNode(all_elements[i][1]), + meshds->FindNode(all_elements[i][0]), + meshds->FindNode(all_elements[i][2]), + meshds->FindNode(all_elements[i][3]), + meshds->FindNode(all_elements[i][4]), + meshds->FindNode(all_elements[i][6]), + meshds->FindNode(all_elements[i][5]), + meshds->FindNode(all_elements[i][8]), + meshds->FindNode(all_elements[i][7]), + meshds->FindNode(all_elements[i][9]), + element_id[i] + ); + + //1D element + } else if (element_type[i] == 100) + { + //Base::Console().Log("eid = %d %d %d %d\n", element_id[i], all_elements[i][0], all_elements[i][1], all_elements[i][2]); + //cbar + meshds->AddEdgeWithID( + all_elements[i][0], + all_elements[i][1], + element_id[i] + ); + //2d element + } else if (element_type[i] == 230) + { + //Base::Console().Log("eid = %d %d %d %d\n", element_id[i], all_elements[i][0], all_elements[i][1], all_elements[i][2]); + //ctramem + meshds->AddFaceWithID( + all_elements[i][0], + all_elements[i][1], + all_elements[i][2], + element_id[i] + ); + } else if (element_type[i] == 231) + { + //ctria1 + meshds->AddFaceWithID( + all_elements[i][0], + all_elements[i][1], + all_elements[i][2], + element_id[i] + ); + } + else if (element_type[i] == 241) + { + //cquad1 + meshds->AddFaceWithID( + all_elements[i][0], + all_elements[i][1], + all_elements[i][2], + all_elements[i][3], + element_id[i] + ); + } + + //3d element + else if (element_type[i] == 340) + { + //ctetra + meshds->AddVolumeWithID( + all_elements[i][0], + all_elements[i][1], + all_elements[i][2], + all_elements[i][3], + element_id[i] + ); + } + else if (element_type[i] == 360) + { + //cwedge + meshds->AddVolumeWithID( + all_elements[i][0], + all_elements[i][1], + all_elements[i][2], + all_elements[i][3], + all_elements[i][4], + all_elements[i][5], + element_id[i] + ); + } + else if (element_type[i] == 381) + { + //chexa1 + meshds->AddVolumeWithID( + all_elements[i][0], + all_elements[i][1], + all_elements[i][2], + all_elements[i][3], + all_elements[i][4], + all_elements[i][5], + all_elements[i][6], + all_elements[i][7], + element_id[i] + ); + } + else if (element_type[i] == 382) + { + //chexa2 + meshds->AddVolumeWithID( + all_elements[i][0], + all_elements[i][1], + all_elements[i][2], + all_elements[i][3], + all_elements[i][4], + all_elements[i][5], + all_elements[i][6], + all_elements[i][7], + element_id[i] + ); + } + } + Base::Console().Log(" %f: Done \n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); + +} + void FemMesh::readAbaqus(const std::string &FileName) { Base::TimeInfo Start; @@ -1370,7 +1797,8 @@ void FemMesh::read(const char *FileName) } else if (File.hasExtension("inp") ) { // read Abaqus inp mesh file - readAbaqus(File.filePath()); + // readAbaqus(File.filePath()); + readNastran95(File.filePath()); } else if (File.hasExtension("stl") ) { // read brep-file