diff --git a/src/conv/k-g/CMakeLists.txt b/src/conv/k-g/CMakeLists.txt index aeaa65e8af..cc84e7adec 100644 --- a/src/conv/k-g/CMakeLists.txt +++ b/src/conv/k-g/CMakeLists.txt @@ -5,6 +5,7 @@ set(k-g_SRCF region_list.cpp arbs.cpp geometry.cpp + pipe.cpp ) BRLCAD_ADDEXEC(k-g "${k-g_SRCF}" "libwdb;librt;libbu" FOLDER Conv) @@ -15,6 +16,7 @@ set(k-g_ignore_files region_list.h arbs.h geometry.h + pipe.h ) CMAKEFILES(${k-g_ignore_files}) diff --git a/src/conv/k-g/geometry.cpp b/src/conv/k-g/geometry.cpp index 62258d4872..7fb3d0c9f1 100644 --- a/src/conv/k-g/geometry.cpp +++ b/src/conv/k-g/geometry.cpp @@ -26,14 +26,7 @@ #include "geometry.h" -// Local Variables: -// tab-width: 8 -// mode: C++ -// c-basic-offset: 4 -// indent-tabs-mode: t -// c-file-style: "stroustrup" -// End: -// ex: shiftwidth=4 tabstop=8 + void Geometry::setBaseName @@ -47,6 +40,7 @@ void Geometry::setBaseName m_bot.setName(name.c_str()); m_arbs.setName(name.c_str()); + m_pipe.setName(name.c_str()); } void Geometry::setThickness @@ -82,6 +76,12 @@ void Geometry::addArb } +void Geometry::addPipePnt(pipePoint point) +{ + m_pipe.addPipePnt(point); +} + + const char* Geometry::getBaseName(void) const{ return name.c_str(); } @@ -95,15 +95,31 @@ Arbs& Geometry::getArbs(void) { return m_arbs; } +Pipe& Geometry::getPipe(void) +{ + return m_pipe; +} + std::vector Geometry::write ( rt_wdb* wdbp ) { - std::vector ret = m_bot.write(wdbp); - std::vector arbNames = m_arbs.write(wdbp); + std::vector ret = m_bot.write(wdbp); + std::vector arbNames = m_arbs.write(wdbp); + std::vector pipeName = m_pipe.write(wdbp); ret.insert(ret.end(), arbNames.begin(), arbNames.end()); - + ret.insert(ret.end(), pipeName.begin(), pipeName.end()); return ret; } + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/conv/k-g/geometry.h b/src/conv/k-g/geometry.h index 08cfe8c928..e105a7032f 100644 --- a/src/conv/k-g/geometry.h +++ b/src/conv/k-g/geometry.h @@ -17,7 +17,7 @@ * License along with this file; see the file named COPYING for more * information. */ - /** @file region_list.cpp + /** @file geometry.h * * LS Dyna keyword file to BRL-CAD converter: * intermediate geometry structure implementation @@ -29,6 +29,7 @@ #include "bot.h" #include "arbs.h" +#include "pipe.h" class Geometry { @@ -48,16 +49,19 @@ class Geometry { const point_t& point6, const point_t& point7, const point_t& point8); + void addPipePnt(pipePoint point); const char* getBaseName(void) const; Bot& getBot(void); Arbs& getArbs(void); + Pipe& getPipe(void); std::vector write(rt_wdb* wdbp); private: std::string name; Bot m_bot; Arbs m_arbs; + Pipe m_pipe; }; @@ -71,4 +75,4 @@ class Geometry { // indent-tabs-mode: t // c-file-style: "stroustrup" // End: -// ex: shiftwidth=4 tabstop=8 \ No newline at end of file +// ex: shiftwidth=4 tabstop=8 diff --git a/src/conv/k-g/k-g.cpp b/src/conv/k-g/k-g.cpp index d7411082df..830b7b96e7 100644 --- a/src/conv/k-g/k-g.cpp +++ b/src/conv/k-g/k-g.cpp @@ -33,6 +33,7 @@ #include "k_parser.h" #include "region_list.h" +#include "pipe.h" static void AddArb(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8,KData& kData, std::string arbNumber, Geometry& geometry) { @@ -136,7 +137,39 @@ int main std::cout << "Missing section to part" << partName.c_str() << '\n'; for (std::set::iterator itr = (it->second).elements.begin(); itr != (it->second).elements.end(); itr++) { - if (kData.elements[*itr].nodes.size() == 4) { + if ((kData.elements[*itr].nodes.size() == 3)) { + //int n3 = kData.elements[*itr].nodes[2]; + if (section > 0) { + KSectionBeam beamSection = kData.sectionsBeam[section]; + + if (beamSection.CST == 1) { + pipePoint point1; + pipePoint point2; + + + int n1 = kData.elements[*itr].nodes[0]; + int n2 = kData.elements[*itr].nodes[1]; + //int n3 = kData.elements[*itr].nodes[2]; + point1.coords[X] = kData.nodes[n1].x * factor; + point1.coords[Y] = kData.nodes[n1].y * factor; + point1.coords[Z] = kData.nodes[n1].z * factor; + point1.outerDiameter = beamSection.TS1; + point1.innerDiameter = beamSection.TT1; + + point2.coords[X] = kData.nodes[n2].x * factor; + point2.coords[Y] = kData.nodes[n2].y * factor; + point2.coords[Z] = kData.nodes[n2].z * factor; + point2.outerDiameter = beamSection.TS2; + point2.innerDiameter = beamSection.TT2; + + std::string beamNumber = std::to_string(*itr); + + geometry.addPipePnt(point1); + geometry.addPipePnt(point2); + } + } + } + else if (kData.elements[*itr].nodes.size() == 4) { point_t point1; point_t point2; diff --git a/src/conv/k-g/k_parser.cpp b/src/conv/k-g/k_parser.cpp index bc5faf686c..095ec0f02f 100644 --- a/src/conv/k-g/k_parser.cpp +++ b/src/conv/k-g/k_parser.cpp @@ -37,14 +37,69 @@ enum class KState { Ignore, Include, Node, + Element_Beam, + Element_Beam_Pulley, + Element_Beam_Source, + Element_Bearing, + //Element_Blanking, + //Element_Direct_Matrix_Input, + //Element_Discrete, + //Element_Discrete_Sphere, + //Element_Generalized_Shell, + //Element_Generalized_Solid, + //Element_Inertia, + //Element_Interpolation_Shell, + //Element_Interpolation_Solid, + //Element_Lancing, + //Element_Mass, + //Element_Mass_Matrix, + //Element_Mass_Part, + //Element_Plotel, + //Element_Seatbealt, + //Element_Seatbealt_Accelerometer, + //Element_Seatbealt_Pretensioner, + //Element_Seatbealt_Retractor, + //Element_Seatbealt_Sensor, + //Element_Seatbealt_Slipring, Element_Shell, + //Element_Shell_Nurbs_Patch, + //Element_Shell_Source_Sink, Element_Solid, + //Element_Solid_Nurbs_Patch, + //Element_Solid_Peri, + //Element_Sph, + //Element_Trim, + //Element_Tshell, Part, Part_Adaptive_Failure, + Section_Ale1d, + Section_Ale2d, + Section_Beam, + //Section_Beam_AISC, + //Section_Discrete, + //Section_Fpd, + //Section_Point_Source, + //Section_Point_source_Mixture, + //Section_Seatbelt, Section_Shell, - Section_Solid + Section_Solid, + //Section_Solid_Peri, + //Section_Sph, + //Section_Tshell }; +enum class Options { + Title, + Thickness, + Scalar, + Scalr, + Section, + Pid, + Offset, + Orientation, + Warpage, + Elbow +}; static std::string read_line ( @@ -183,11 +238,18 @@ bool parse_k size_t partLinesRead = 0; std::string partTitle; size_t sectionLinesRead = 0; + size_t elementLinesRead = 0; + //size_t cardCounter = 0;// this will replace sectionLinesRead elementLinesRead, and partLinesRead + size_t optionsCounter = 0; std::string sectionTitle; int sectionId = -1; + int sectionElForm = 0; + //int CST = 0; std::string line = read_line(is); std::vector tokens; const size_t FirstNode = 2; + std::vector optionsContainer; + std::vector options; if (line.size() > 0) tokens = parse_line(line.c_str()); @@ -222,19 +284,229 @@ bool parse_k std::cout << "Unexpected command " << tokens[0] << " in k-file " << fileName << "\n"; } else if (command[0] == "ELEMENT") { - if ((command.size() == 2) && (command[1] == "SHELL")) - state = KState::Element_Shell; - else if ((command.size() == 2) && (command[1] == "SOLID")) { - state = KState::Element_Solid; + if ((command.size() > 1) && (command[1] == "BEAM")) { + if ((command.size() > 2) && (command[2] == "PULLEY")) { + state = KState::Element_Beam_Pulley; + } + else if ((command.size() > 2) && (command[2] == "SOURCE")) { + state = KState::Element_Beam_Source; + } + else { + state = KState::Element_Beam; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 2, command.end()); + + if (optionsContainer.size() > 0) { + for (size_t i_o = 0; i_o < optionsContainer.size(); ++i_o) { + if (optionsContainer[i_o] == "THICKNESS") { + options.push_back(Options::Thickness); + } + else if (optionsContainer[i_o] == "SCALAR") { + options.push_back(Options::Scalar); + } + else if (optionsContainer[i_o] == "SCALR") { + options.push_back(Options::Scalr); + } + else if (optionsContainer[i_o] == "SECTION") { + options.push_back(Options::Section); + } + else if (optionsContainer[i_o] == "PID") { + options.push_back(Options::Pid); + } + else if (optionsContainer[i_o] == "OFFSET") { + options.push_back(Options::Offset); + } + else if (optionsContainer[i_o] == "ORIENTATION") { + options.push_back(Options::Orientation); + } + else if (optionsContainer[i_o] == "WARPAGE") { + options.push_back(Options::Warpage); + } + else if (optionsContainer[i_o] == "ELBOW") { + options.push_back(Options::Elbow); + } + else + std::cout << "Unhandeled Element_Beam option" << optionsContainer[i_o] << "in k-file" << fileName << "\n"; + } + } + } + } + else if ((command.size() > 1) && (command[1] == "BEARING")) { + state = KState::Element_Bearing; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 2, command.end()); + + if (optionsContainer.size() > 0) { + elementLinesRead = 0;//element Bearing has only the Tilte option + } + } + else if ((command.size() > 1) && (command[1] == "BLANKING")) { + //state = KState::Element_Blanking; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 2, command.end()); + } + else if ((command.size() > 3) && (command[1] == "DIRECT") && (command[2] == "MATRIX") && (command[3] == "INPUT")) { + //state = KState::Element_Direct_Matrix_Input; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 4, command.end()); + } + else if ((command.size() > 1) && (command[1] == "DISCRETE")) { + if ((command.size() > 2) && (command[2] == "SPHERE")) { + //state = KState::Element_Discrete_Sphere; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 3, command.end()); + } + else { + //state = KState::Element_Discrete; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 2, command.end()); + } + } + else if ((command.size() > 2) && (command[1] == "GENERALIZED")) { + if ((command[2] == "SHELL")) { + //state = KState::Element_Generalized_Shell; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 3, command.end()); + } + else { + //state = KState::Element_Generalized_Solid; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 3, command.end()); + } + } + else if ((command.size() > 1) && (command[1] == "INERTIA")) { + //state = KState::Element_Inertia; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 2, command.end()); + } + else if ((command.size() > 2) && (command[1] == "INTERPOLATION")) { + if (command[2] == "SHELL") { + //state = KState::Element_Interpolation_Shell; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 3, command.end()); + } + else { + //state = KState::Element_Interpolation_Solid; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 3, command.end()); + } + } + else if ((command.size() > 1) && (command[1] == "LANCING")) { + //state = KState::Element_Lancing; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 2, command.end()); + } + else if ((command.size() > 1) && (command[1] == "MASS")) { + if ((command.size() > 2) && (command[2] == "MATRIX")) { + //state = KState::Element_Mass_Matrix; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 3, command.end()); + } + else if ((command.size() > 2) && (command[2] == "PART")) { + //state = KState::Element_Mass_Part; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 3, command.end()); + } + else { + //state = KState::Element_Mass; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 2, command.end()); + } + } + else if ((command.size() > 1) && (command[1] == "PLOTEL")) { + //state = KState::Element_Plotel; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 2, command.end()); + } + else if ((command.size() > 1) && (command[1] == "SEATBELT")) { + if ((command.size() > 2) && (command[2] == "ACCELEROMETER")) { + //state = KState::Element_Seatbealt_Accelerometer; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 3, command.end()); + } + else if ((command.size() > 2) && (command[2] == "PRETENSIONER")) { + //state = KState::Element_Seatbealt_Pretensioner; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 3, command.end()); + } + else if ((command.size() > 2) && (command[2] == "RETRACTOR")) { + //state = KState::Element_Seatbealt_Retractor; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 3, command.end()); + } + else if ((command.size() > 2) && (command[2] == "SENSOR")) { + //state = KState::Element_Seatbealt_Sensor; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 3, command.end()); + } + else if ((command.size() > 2) && (command[2] == "SLIPRING")) { + //state = KState::Element_Seatbealt_Slipring; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 3, command.end()); + } + else { + //state = KState::Element_Seatbealt; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 2, command.end()); + } + } + else if ((command.size() > 1) && (command[1] == "SHELL")) { + if ((command.size() > 2) && (command[2] == "NURBS")) { + //state = KState::Element_Shell_Nurbs_Patch; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 4, command.end()); + } + else if ((command.size() > 2) && (command[2] == "SOURCE")) { + //state = KState::Element_Shell_Source_Sink; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 4, command.end()); + } + else { + //state = KState::Element_Shell; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 2, command.end()); + } + } + else if ((command.size() > 1) && (command[1] == "SOLID")) { + if ((command.size() > 2) && (command[2] == "NURBS")) { + //state = KState::Element_Solid_Nurbs_Patch; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 4, command.end()); + } + else if ((command.size() > 2) && (command[2] == "PERI")) { + //state = KState::Element_Solid_Peri; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 3, command.end()); + } + else { + state = KState::Element_Solid; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 2, command.end()); + } + } + else if ((command.size() > 1) && (command[1] == "SPH")) { + //state = KState::Element_Sph; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 2, command.end()); + } + else if ((command.size() > 1) && (command[1] == "TRIM")) { + //state = KState::Element_Trim; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 2, command.end()); + } + else if ((command.size() > 1) && (command[1] == "TSHELL")) { + //state = KState::Element_Tshell; + + optionsContainer.insert(optionsContainer.end(), command.begin() + 2, command.end()); } else std::cout << "Unexpected command " << tokens[0] << " in k-file " << fileName << "\n"; } else if (command[0] == "PART") { if ((command.size() == 1) || (command[1] == "INERTIA")) { - state = KState::Part; + state = KState::Part; partLinesRead = 0; - partTitle = ""; + partTitle = ""; } else if ((command.size() == 3) && (command[1] == "ADAPTIVE") && (command[2] == "FAILURE")) { state = KState::Part_Adaptive_Failure; @@ -243,7 +515,49 @@ bool parse_k std::cout << "Unexpected command " << tokens[0] << " in k-file " << fileName << "\n"; } else if (command[0] == "SECTION") { - if (command[1] == "SHELL") { + if (command[1] == "ALE1D"){ + state = KState::Section_Ale1d; + sectionTitle = ""; + sectionId = -1; + + if (command.size() > 2) { + if (command[2] == "TITLE") + sectionLinesRead = 0; + else + optionsContainer.insert(optionsContainer.end(), command.begin() + 2, command.end()); + } + else + sectionLinesRead = 1; + } + else if (command[1] == "ALE2D") { + state = KState::Section_Ale2d; + sectionTitle = ""; + sectionId = -1; + + if (command.size() > 2) { + if (command[2] == "TITLE") + sectionLinesRead = 0; + else + optionsContainer.insert(optionsContainer.end(), command.begin() + 2, command.end()); + } + else + sectionLinesRead = 1; + } + else if (command[1] == "BEAM") { + state = KState::Section_Beam; + sectionTitle = ""; + sectionId = -1; + + if (command.size() > 2) { + if (command[2] == "TITLE") + sectionLinesRead = 0; + else + optionsContainer.insert(optionsContainer.end(), command.begin() + 2, command.end()); + } + else + sectionLinesRead = 1; + } + else if (command[1] == "SHELL") { state = KState::Section_Shell; sectionTitle = ""; sectionId = -1; @@ -392,7 +706,168 @@ bool parse_k case KState::Ignore: break; } + case KState::Section_Ale1d: { + switch (sectionLinesRead) + { + case 0: { + sectionTitle = line; + break; + } + case 1: { + if (tokens.size() < 4) { + std::cout << "Too short SECTION_ALE1D in k-file " << fileName << "\n"; + break; + } + sectionId = stoi(tokens[0]); + data.sections[sectionId].title = sectionTitle; + break; + } + case 2: { + if (sectionId < 0) { + std::cout << "Bad SECTION in k-file " << fileName << "\n"; + break; + } + + if (tokens.size() < 2) { + std::cout << "Too short SECTION_ALE1D in k-file " << fileName << "\n"; + break; + } + + data.sections[sectionId].thickness1 = stod(tokens[0]); + data.sections[sectionId].thickness2 = stod(tokens[1]); + } + } + ++sectionLinesRead; + break; + } + case KState::Section_Ale2d: { + switch (sectionLinesRead) + { + case 0: { + sectionTitle = line; + break; + } + case 1: { + if (tokens.size() < 4) { + std::cout << "Too short SECTION_ALE2D in k-file " << fileName << "\n"; + break; + } + sectionId = stoi(tokens[0]); + data.sections[sectionId].title = sectionTitle; + break; + } + } + + ++sectionLinesRead; + break; + } + case KState::Section_Beam: { + KSectionBeam sectionBeam; + switch (sectionLinesRead) + { + case 0: { + sectionTitle = line; + break; + } + case 1: { + if (tokens.size() < 8) { + std::cout << "Too short SECTION_BEAM in k-file " << fileName << "\n"; + break; + } + sectionId = stoi(tokens[0]); + sectionElForm = stoi(tokens[1]); + + sectionBeam.title = sectionTitle; + sectionBeam.CST = stoi(tokens[4]); + data.sections[sectionId].title = sectionTitle; + break; + } + case 2: { + if ((sectionElForm == 1) || (sectionElForm == 11)) { + if (tokens.size() < 6) { + std::cout << "Too short SECTION_BEAM card 2a in k-file " << fileName << "\n"; + break; + } + sectionBeam.TS1 = stod(tokens[0]); + sectionBeam.TS2 = stod(tokens[1]); + sectionBeam.TT1 = stod(tokens[2]); + sectionBeam.TT2 = stod(tokens[3]); + } + else if ((sectionElForm == 2) || (sectionElForm == 3) || (sectionElForm == 12)||(sectionElForm == 13)) { + std::string first7characters; + + if (tokens[0].size() > 7) { + first7characters = tokens[0].substr(0, 7); + } + + if ((first7characters == "SECTION")) { + sectionBeam.sectionType = tokens[0]; + + for (size_t i_d = 1; i_d < 5; ++i_d) { + sectionBeam.D.push_back(stod(tokens[i_d])); + } + } + else { + sectionBeam.CrossSectionalArea = stod(tokens[0]); + } + } + else if ((sectionElForm == 4) || (sectionElForm == 5)) { + if (tokens.size() < 4) { + std::cout << "Too short SECTION_BEAM card 2e in k-file " << fileName << "\n"; + break; + } + + sectionBeam.TS1 = stod(tokens[0]); + sectionBeam.TS2 = stod(tokens[1]); + sectionBeam.TT1 = stod(tokens[2]); + sectionBeam.TT2 = stod(tokens[3]); + } + else if (sectionElForm == 6) { + //nothing to do. + break; + } + else if ((sectionElForm == 7) || (sectionElForm == 8)) { + if (tokens.size() < 2) { + std::cout << "Too short SECTION_BEAM card 2h in k-file " << fileName << "\n"; + break; + } + + sectionBeam.TS1 = stod(tokens[0]); + sectionBeam.TS2 = stod(tokens[1]); + } + else if (sectionElForm == 9) { + if (tokens.size() < 4) { + std::cout << "Too short SECTION_BEAM card 2i in k-file " << fileName << "\n"; + break; + } + + sectionBeam.TS1 = stod(tokens[0]); + sectionBeam.TS2 = stod(tokens[1]); + sectionBeam.TT1 = stod(tokens[2]); + sectionBeam.TT2 = stod(tokens[3]); + } + else if (sectionElForm == 14) { + //nothing to do + break; + } + + data.sectionsBeam[sectionId] = sectionBeam; + break; + } + case 3: { + if (sectionElForm == 12) { + //No information related to geometry. + break; + } + + break; + } + } + data.sectionsBeam[sectionId] = sectionBeam; + ++sectionLinesRead; + break; + } case KState::Section_Shell: { switch (sectionLinesRead) { case 0: @@ -436,6 +911,7 @@ bool parse_k ++sectionLinesRead; break; } + case KState::Section_Solid: { switch (sectionLinesRead) { case 0: @@ -461,6 +937,7 @@ bool parse_k ++sectionLinesRead; break; } + case KState::Part_Adaptive_Failure: { if (tokens.size() < 2) { std::cout << "Too short PART_ADAPTIVE_FAILURE in k-file " << fileName << "\n"; @@ -478,6 +955,332 @@ bool parse_k break; } + case KState::Element_Beam: { + KElement element; + int pid; + int eid; + + if (options.size() == 0 || optionsCounter == 0) { + if (tokens.size() < 10) { + std::cout << "Too short ELEMENT_BEAM in k-file" << fileName << "\n"; + break; + } + eid = stoi(tokens[0]); + + if (data.elements.find(eid) != data.elements.end()) { + std::cout << "Duplicat Element ID" << eid << " in k-file" << fileName << "\n"; + break; + } + + for (int i_n = 0; i_n < 3; ++i_n) { + element.nodes.push_back(stoi(tokens[i_n + FirstNode])); + } + + data.elements[eid] = element; + + pid = stoi(tokens[1]); + data.parts[pid].elements.insert(eid); + break; + } + else if ((options.size() > 0)) { + Options currentOption; + + if (optionsCounter < options.size()) { + currentOption = options[optionsCounter]; + } + else { + optionsCounter = 0; + currentOption = options[optionsCounter]; + } + + switch (currentOption) + { + case Options::Thickness: { + if (tokens.size() < 5) { + std::cout << "Too short option THICKNESS in k-file " << fileName << "\n"; + break; + } + + for (size_t i_p = 0; i_p < tokens.size(); ++i_p) { + double param = stod(tokens[i_p]); + element.options["THICKNESS"].push_back(param); + } + + data.elements[eid] = element; + + ++optionsCounter; + break; + } + case Options::Scalar: { + //Nothing to do + ++optionsCounter; + break; + } + case Options::Scalr: { + //Nothing to do + ++optionsCounter; + break; + } + case Options::Section: { + if (tokens.size() < 7) { + std::cout << "Too short option Section in k-file " << fileName << "\n"; + break; + } + double temp; + + if (tokens[0] == "EQ.SECTION_01") { + temp = 1.0; + } + else if (tokens[0] == "EQ.SECTION_02") { + temp = 2.0; + } + else if (tokens[0] == "EQ.SECTION_03") { + temp = 3.0; + } + else if (tokens[0] == "EQ.SECTION_04") { + temp = 4.0; + } + else if (tokens[0] == "EQ.SECTION_05") { + temp = 5.0; + } + else if (tokens[0] == "EQ.SECTION_06") { + temp = 6.0; + } + else if (tokens[0] == "EQ.SECTION_07") { + temp = 7.0; + } + else if (tokens[0] == "EQ.SECTION_08") { + temp = 8.0; + } + else if (tokens[0] == "EQ.SECTION_09") { + temp = 9.0; + } + else if (tokens[0] == "EQ.SECTION_10") { + temp = 10.0; + } + else if (tokens[0] == "EQ.SECTION_11") { + temp = 11.0; + } + else if (tokens[0] == "EQ.SECTION_12") { + temp = 12.0; + } + else if (tokens[0] == "EQ.SECTION_13") { + temp = 13.0; + } + else if (tokens[0] == "EQ.SECTION_14") { + temp = 14.0; + } + else if (tokens[0] == "EQ.SECTION_15") { + temp = 15.0; + } + else if (tokens[0] == "EQ.SECTION_16") { + temp = 16.0; + } + else if (tokens[0] == "EQ.SECTION_17") { + temp = 17.0; + } + else if (tokens[0] == "EQ.SECTION_18") { + temp = 18.0; + } + else if (tokens[0] == "EQ.SECTION_19") { + temp = 19.0; + } + else if (tokens[0] == "EQ.SECTION_20") { + temp = 20.0; + } + else if (tokens[0] == "EQ.SECTION_21") { + temp = 21.0; + } + else if (tokens[0] == "EQ.SECTION_22") { + temp = 22.0; + } + + element.options["SECTION"].push_back(temp); + + for (size_t i_p = 1; i_p < tokens.size(); ++i_p) { + temp = stod(tokens[1]); + element.options["SECTION"].push_back(temp); + } + data.elements[eid] = element; + ++optionsCounter; + break; + } + case Options::Pid: { + //Nothing to do + ++optionsCounter; + break; + } + case Options::Offset: { + if (tokens.size() < 6) { + std::cout << "To short OFFSET option in k-file " << fileName << "\n"; + break; + } + + for (size_t i_p = 0; i_p < tokens.size(); ++i_p) { + double temp = stod(tokens[i_p]); + element.options["OFFSET"].push_back(temp); + } + + data.elements[eid] = element; + + ++optionsCounter; + break; + } + case Options::Orientation: { + if (tokens.size() < 3) { + std::cout << "To short ORIENTATION option in k-file" << fileName << "\n"; + break; + } + + for (size_t i_p = 0; i_p < tokens.size(); ++i_p) { + double temp = stod(tokens[i_p]); + element.options["ORIENTATION"].push_back(temp); + } + + data.elements[eid] = element; + + ++optionsCounter; + break; + } + case Options::Warpage: { + if (tokens.size() < 2) { + std::cout << "To short WARPAGE option in k-file" << fileName << "\n"; + break; + } + + for (size_t i_p = 0; i_p < tokens.size(); ++i_p) { + double temp = stod(tokens[i_p]); + element.options["WARPAGE"].push_back(temp); + } + + data.elements[eid] = element; + + ++optionsCounter; + break; + } + case Options::Elbow: { + if (tokens.size() < 1) { + std::cout << "Empty ELBOW option in k-file" << fileName << "\n"; + break; + } + double temp = stod(tokens[0]); + element.options["ELBOW"].push_back(temp); + + data.elements[eid] = element; + + ++optionsCounter; + break; + } + default: + break; + } + } + break; + } + + case KState::Element_Beam_Pulley: { + if (tokens.size() < 8) { + std::cout << "Too short ELEMENT_BEAM_PULLEY in k-file " << fileName << "\n"; + break; + } + KElementPulley pulley; + int pulleyId= stoi(tokens[0]); + + pulley.truss1Id = stoi(tokens[1]); + pulley.truss2Id = stoi(tokens[2]); + pulley.pulleyNode = stoi(tokens[3]); + + data.elementsPulley[pulleyId] = pulley; + break; + } + case KState::Element_Beam_Source: { + if (tokens.size() < 7) { + std::cout << "Too short ELEMENT_BEAM_SOURCE in k-file" << fileName << "\n"; + break; + } + + KElementBeamSource source; + + int eid = stoi(tokens[0]); + + source.sourceNodeId = stoi(tokens[1]); + source.sourceElementId = stoi(tokens[2]); + source.nElements = stoi(tokens[3]); + source.beamElementLength = stof(tokens[4]); + source.minmumLengthToPullOut = stof(tokens[6]); + + data.elementsBeamSource[eid] = source; + break; + } + + case KState::Element_Bearing: { + KElementBearing bearing; + int eid; + + switch (elementLinesRead) + { + case 0: { + bearing.title = line; + + break; + } + case 1: { + if (tokens.size() < 7) { + std::cout << "Too short ELEMENT_BEARING in k-file " << fileName << "\n"; + break; + } + + eid = stoi(tokens[0]); + bearing.bearingType = stoi(tokens[1]); + bearing.n1 = stoi(tokens[2]); + bearing.coordinateId1 = stoi(tokens[3]); + bearing.n2 = stoi(tokens[4]); + bearing.coordinateId2 = stoi(tokens[5]); + bearing.numberOfBallsOrRollers = stoi(tokens[6]); + + break; + } + case 2: { + //Nothing related to Geometry here. + break; + } + case 3: { + if (tokens.size() < 4) { + std::cout << "Too short ELEMENT_BEARING in k-file " << fileName << "\n"; + break; + } + + bearing.diameterOfBallsOrRollers = stof(tokens[0]); + bearing.boreInnerDiameter = stof(tokens[1]); + bearing.boreOuterDiameter = stof(tokens[2]); + bearing.pitchDiameter = stof(tokens[3]); + + break; + } + case 4: { + if (tokens.size() < 4) { + std::cout << "Too short ELEMENT_BEARING in k-file " << fileName << "\n"; + break; + } + + bearing.innerGroveRadiusToBallDiameterRatioOrRollerLength = stof(tokens[1]); + bearing.outerRaceGrooveRadiusToBallDiameterRatio = stof(tokens[2]); + bearing.totalRadianceClearenceBetweenBallAndRaces = stof(tokens[3]); + + break; + } + case 5: { + //nothing related to Geometry. + break; + } + + } + + data.elementBearing[eid] = bearing; + ++elementLinesRead; + break; + } + } } diff --git a/src/conv/k-g/k_parser.h b/src/conv/k-g/k_parser.h index 299ff46f33..4a9a1aa13f 100644 --- a/src/conv/k-g/k_parser.h +++ b/src/conv/k-g/k_parser.h @@ -42,14 +42,49 @@ struct KNode { struct KElement { - std::vector nodes; + std::vector nodes; + std::map> options; +}; + + +struct KElementPulley { + int truss1Id; + int truss2Id; + int pulleyNode; +}; + + +struct KElementBeamSource { + int sourceNodeId; + int sourceElementId; + int nElements; + float beamElementLength; + float minmumLengthToPullOut; +}; + + +struct KElementBearing { + std::string title; + int bearingType; + int n1; + int coordinateId1; + int n2; + int coordinateId2; + int numberOfBallsOrRollers; + float diameterOfBallsOrRollers; + float boreInnerDiameter; + float boreOuterDiameter; + float pitchDiameter; + float innerGroveRadiusToBallDiameterRatioOrRollerLength; + float outerRaceGrooveRadiusToBallDiameterRatio; + float totalRadianceClearenceBetweenBallAndRaces; }; struct KPart { - std::string title; - std::set elements; - int section; + std::string title; + std::set elements; + int section; std::map attributes; }; @@ -62,12 +97,27 @@ struct KSection { double thickness4; }; +struct KSectionBeam { + std::string title; + int CST;//cross section type + std::string sectionType;//this is different from cross section type + double TS1; + double TS2; + double TT1; + double TT2; + std::vector D; + double CrossSectionalArea;//The definition on *ELEMENT_BEAM_THICKNESS overrides the value defined here. +}; struct KData { - std::map nodes; - std::map elements; - std::map parts; - std::map sections; + std::map nodes; + std::map elements; + std::map elementsPulley; + std::map elementsBeamSource; + std::map elementBearing; + std::map parts; + std::map sections; + std::map sectionsBeam; }; diff --git a/src/conv/k-g/pipe.cpp b/src/conv/k-g/pipe.cpp new file mode 100644 index 0000000000..c52d545b9a --- /dev/null +++ b/src/conv/k-g/pipe.cpp @@ -0,0 +1,105 @@ +/* P I P E . C P P + * BRL-CAD + * + * Copyright (c) 2024 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + /** @file pipe.cpp + * + * LS Dyna keyword file to BRL-CAD converter: + * intermediate pipe implementation + */ + +#include "pipe.h" + + +Pipe::Pipe(void) { + BU_GET(m_pipe, rt_pipe_internal); + m_pipe->pipe_magic = RT_PIPE_INTERNAL_MAGIC; + BU_LIST_INIT(&(m_pipe->pipe_segs_head)); +} + + +void Pipe::setName +( + const char* value +) { + if (value != nullptr) + name = value; + else + name = ""; +} + + +void Pipe::addPipePnt +( + const pipePoint& point +) { + struct wdb_pipe_pnt* ctlPoint; + BU_ALLOC(ctlPoint, struct wdb_pipe_pnt); + ctlPoint->l.magic = WDB_PIPESEG_MAGIC; + + BU_ALLOC(ctlPoint, struct wdb_pipe_pnt); + + VMOVE(ctlPoint->pp_coord, point.coords); + ctlPoint->pp_id = point.innerDiameter; + ctlPoint->pp_od = point.outerDiameter; + ctlPoint->pp_bendradius = 2*point.outerDiameter; + + BU_LIST_PUSH(&(m_pipe->pipe_segs_head), &(ctlPoint->l)); + m_pipe->pipe_count += 1; +} + +const char* Pipe::getName(void) const +{ + return name.c_str(); +} + +rt_pipe_internal* Pipe::getPipe(void) const +{ + return m_pipe; +} + +std::vector Pipe::write +( + rt_wdb* wdbp +) { + std::vector ret; + + std::string pipeName = name; + pipeName += ".pipe"; + ret.push_back(pipeName); + + rt_pipe_internal* pipe_wdb; + BU_GET(pipe_wdb, rt_pipe_internal); + pipe_wdb->pipe_magic = RT_PIPE_INTERNAL_MAGIC; + BU_LIST_INIT(&pipe_wdb->pipe_segs_head); + BU_LIST_APPEND_LIST(&pipe_wdb->pipe_segs_head, &m_pipe->pipe_segs_head); + + wdb_export(wdbp, pipeName.c_str(), pipe_wdb, ID_PIPE, 1); + + return ret; +} + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/src/conv/k-g/pipe.h b/src/conv/k-g/pipe.h new file mode 100644 index 0000000000..ca498281ae --- /dev/null +++ b/src/conv/k-g/pipe.h @@ -0,0 +1,65 @@ +/* P I P E . H + * BRL-CAD + * + * Copyright (c) 2024 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + /** @file pipe.h + * + * LS Dyna keyword file to BRL-CAD converter: + * intermediate pipe implementation + */ +#ifndef PIPE_INCLUDED +#define PIPE_INCLUDED + +#include "common.h" +#include "wdb.h" + +struct pipePoint { + point_t coords; + double innerDiameter; + double outerDiameter; +}; + +class Pipe { +public: + Pipe(void); + + void setName(const char* value); + + void addPipePnt(const pipePoint& point); + + const char* getName(void) const; + rt_pipe_internal* getPipe(void) const; + + std::vector write(rt_wdb* wdbp); +private: + std::string name; + rt_pipe_internal* m_pipe; +}; + + +#endif // !PIPE_INCLUDED + + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8