├── .gitignore ├── CMakeLists.txt ├── LICENSE.txt ├── README.md ├── StepKernel.cpp ├── StepKernel.h ├── doc ├── example.jpg └── input_output.jpg ├── main.cpp └── test ├── bucket.stl ├── cat_dish.stl └── cat_dish_bin.stl /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | CMakeCache.txt 3 | CMakeFiles/ 4 | CTestTestfile.cmake 5 | Makefile 6 | cmake_install.cmake 7 | install_manifest.txt 8 | stltostp 9 | *.exe 10 | *.o 11 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | PROJECT (stltostp) 3 | 4 | SET(STLTOSTP_SRC 5 | StepKernel.cpp 6 | main.cpp) 7 | ENABLE_TESTING() 8 | 9 | set (CMAKE_CXX_STANDARD 11) 10 | 11 | ADD_EXECUTABLE (stltostp ${STLTOSTP_SRC}) 12 | 13 | ADD_TEST( 14 | NAME cat_dish 15 | COMMAND stltostp cat_dish.stl cat_dish.stp tol .0000001 16 | WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/test" 17 | ) 18 | 19 | ADD_TEST( 20 | NAME bucket 21 | COMMAND stltostp bucket.stl bucket.stp 22 | WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/test" 23 | ) 24 | 25 | ADD_TEST( 26 | NAME cat_dish_bin 27 | COMMAND stltostp cat_dish_bin.stl cat_dish_bin.stp 28 | WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/test" 29 | ) 30 | 31 | ADD_TEST( 32 | NAME single_tri 33 | COMMAND stltostp single_tri.stl single_tri.stp 34 | WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/test" 35 | ) 36 | 37 | INSTALL(TARGETS ${PROJECT_NAME} DESTINATION "bin/") 38 | 39 | if(WIN32) 40 | set(CPACK_GENERATOR WIX) 41 | set(CPACK_PACKAGE_NAME "stltostp") 42 | set(CPACK_PACKAGE_VENDOR "slugdev") 43 | set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.txt") 44 | set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Command line utility to convert stl files to STEP brep files.") 45 | set(CPACK_PACKAGE_VERSION_MAJOR "1") 46 | set(CPACK_PACKAGE_VERSION_MINOR "0") 47 | set(CPACK_PACKAGE_VERSION_PATCH "1") 48 | set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CMAKE_PROJECT_NAME}/${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}") 49 | set(CPACK_WIX_UPGRADE_GUID "F9AEABA2-D7AF-4EA6-BF46-B3E165410D17") 50 | include (InstallRequiredSystemLibraries) 51 | include(CPack) 52 | endif(WIN32) 53 | 54 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018, slugdev 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 1. Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | 2. Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | 3. All advertising materials mentioning features or use of this software 12 | must display the following acknowledgement: 13 | This product includes software developed by slugdev. 14 | 4. Neither the name of the slugdev nor the 15 | names of its contributors may be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY SLUGDEV ''AS IS'' AND ANY 19 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL SLUGDEV BE LIABLE FOR ANY 22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # stltostp 2 | Command line utility to convert stl files to STEP (ISO 10303-21) files. The translation is a direct triangle to triangle conversion with a tolerance based merging of edges. stltostp translates without depending on 3rd party tools such as OpenCascade or FreeCAD. 3 | ![Image of stltostp input_output](https://github.com/slugdev/stltostp/blob/master/doc/input_output.jpg) 4 | 5 | ### Usage 6 | stltostp \[ tol \ \] 7 | ![Image of stltostp usage](https://github.com/slugdev/stltostp/blob/master/doc/example.jpg) 8 | 9 | ### Build 10 | ``` 11 | mkdir build 12 | cd build 13 | cmake .. 14 | make clean all && sudo make install 15 | ``` 16 | ### License 17 | BSD 18 | 19 | ## Windows Installer 20 | [stltostp-1.0.1-win64.msi](https://github.com/slugdev/stltostp/releases/download/v1.0.1/stltostp-1.0.1-win64.msi) 21 | -------------------------------------------------------------------------------- /StepKernel.cpp: -------------------------------------------------------------------------------- 1 | /*Copyright(c) 2018, slugdev 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met : 6 | 1. Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | 2. Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | 3. All advertising materials mentioning features or use of this software 12 | must display the following acknowledgement : 13 | This product includes software developed by slugdev. 14 | 4. Neither the name of the slugdev nor the 15 | names of its contributors may be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY SLUGDEV ''AS IS'' AND ANY 19 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED.IN NO EVENT SHALL SLUGDEV BE LIABLE FOR ANY 22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/ 28 | 29 | #include "StepKernel.h" 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include // put_time 36 | StepKernel::StepKernel() 37 | { 38 | 39 | } 40 | 41 | StepKernel::~StepKernel() 42 | { 43 | } 44 | 45 | StepKernel::EdgeCurve* StepKernel::create_edge_curve(StepKernel::Vertex * vert1, StepKernel::Vertex * vert2,bool dir) 46 | { 47 | // curve 1 48 | auto line_point1 = new Point(entities, vert1->point->x, vert1->point->y, vert1->point->z); 49 | double vx = vert2->point->x - vert1->point->x; 50 | double vy = vert2->point->y - vert1->point->y; 51 | double vz = vert2->point->z - vert1->point->z; 52 | double dist = sqrt(vx * vx + vy * vy + vz * vz); 53 | vx = vx / dist; 54 | vy = vy / dist; 55 | vz = vz / dist; 56 | 57 | auto line_dir1 = new Direction(entities, vx, vy, vz); 58 | auto line_vector1 = new Vector(entities, line_dir1, 1.0); 59 | auto line1 = new Line(entities, line_point1, line_vector1); 60 | auto surf_curve1 = new SurfaceCurve(entities, line1); 61 | return new EdgeCurve(entities, vert1, vert2, surf_curve1, dir); 62 | } 63 | 64 | void StepKernel::build_tri_body(std::vector tris,double tol, int &merged_edge_cnt) 65 | { 66 | auto point = new Point(entities, 0.0, 0.0, 0.0); 67 | auto dir_1 = new Direction(entities, 0.0, 0.0, 1.0); 68 | auto dir_2 = new Direction(entities, 1.0, 0.0, 0.0); 69 | 70 | auto base_csys = new Csys3D(entities, dir_1, dir_2, point); 71 | std::vector faces; 72 | std::map, EdgeCurve*> edge_map; 73 | for (std::size_t i = 0; i < tris.size() / 9; i++) 74 | { 75 | double p0[3] = { tris[i * 9 + 0],tris[i * 9 + 1] ,tris[i * 9 + 2] }; 76 | double p1[3] = { tris[i * 9 + 3],tris[i * 9 + 4] ,tris[i * 9 + 5] }; 77 | double p2[3] = { tris[i * 9 + 6],tris[i * 9 + 7] ,tris[i * 9 + 8] }; 78 | 79 | double d0[3] = { 1,0,0 }; 80 | d0[0] = p1[0] - p0[0]; 81 | d0[1] = p1[1] - p0[1]; 82 | d0[2] = p1[2] - p0[2]; 83 | double dist0 = sqrt(d0[0] * d0[0] + d0[1] * d0[1] + d0[2] * d0[2]); 84 | if (dist0 < tol) 85 | continue; 86 | d0[0] = d0[0] / dist0; 87 | d0[1] = d0[1] / dist0; 88 | d0[2] = d0[2] / dist0; 89 | 90 | double d1[3] = { 1,0,0 }; 91 | d1[0] = p2[0] - p0[0]; 92 | d1[1] = p2[1] - p0[1]; 93 | d1[2] = p2[2] - p0[2]; 94 | double dist1 = sqrt(d1[0] * d1[0] + d1[1] * d1[1] + d1[2] * d1[2]); 95 | if (dist1 < tol) 96 | continue; 97 | d1[0] = d1[0] / dist1; 98 | d1[1] = d1[1] / dist1; 99 | d1[2] = d1[2] / dist1; 100 | 101 | // now cross 102 | // cross to get the thrid direction for the beam csys 103 | double d2[3] = { d0[1] * d1[2] - d0[2] * d1[1], d0[2] * d1[0] - d0[0] * d1[2], d0[0] * d1[1] - d0[1] * d1[0] }; 104 | double dist2 = sqrt(d2[0] * d2[0] + d2[1] * d2[1] + d2[2] * d2[2]); 105 | if (dist2 < tol) 106 | continue; 107 | d2[0] = d2[0] / dist2; 108 | d2[1] = d2[1] / dist2; 109 | d2[2] = d2[2] / dist2; 110 | 111 | // correct the m direction 112 | double d1_cor[3] = { d2[1] * d0[2] - d2[2] * d0[1], d2[2] * d0[0] - d2[0] * d0[2], d2[0] * d0[1] - d2[1] * d0[0] }; 113 | double d1_cor_len = sqrt(d1_cor[0] * d1_cor[0] + d1_cor[1] * d1_cor[1] + d1_cor[2] * d1_cor[2]); 114 | d1[0] = d1_cor[0] / d1_cor_len; 115 | d1[1] = d1_cor[1] / d1_cor_len; 116 | d1[2] = d1_cor[2] / d1_cor_len; 117 | 118 | 119 | // build the face 120 | // the 3 vertex locations 121 | auto point1 = new Point(entities, p0[0], p0[1], p0[2]); 122 | auto vert1 = new Vertex(entities, point1); 123 | 124 | auto point2 = new Point(entities, p1[0], p1[1], p1[2]); 125 | auto vert2 = new Vertex(entities, point2); 126 | 127 | auto point3 = new Point(entities, p2[0], p2[1], p2[2]); 128 | auto vert3 = new Vertex(entities, point3); 129 | 130 | 131 | EdgeCurve* edge_curve1 = 0; 132 | bool edge1_dir = true; 133 | get_edge_from_map(p0, p1, edge_map, vert1, vert2, edge_curve1, edge1_dir, merged_edge_cnt); 134 | 135 | EdgeCurve* edge_curve2 = 0; 136 | bool edge2_dir = true; 137 | get_edge_from_map(p1, p2, edge_map, vert2, vert3, edge_curve2, edge2_dir, merged_edge_cnt); 138 | 139 | EdgeCurve* edge_curve3 = 0; 140 | bool edge3_dir = true; 141 | get_edge_from_map(p2, p0, edge_map, vert3, vert1, edge_curve3, edge3_dir, merged_edge_cnt); 142 | 143 | std::vector oriented_edges; 144 | oriented_edges.push_back(new OrientedEdge(entities, edge_curve1, edge1_dir)); 145 | oriented_edges.push_back(new OrientedEdge(entities, edge_curve2, edge2_dir)); 146 | oriented_edges.push_back(new OrientedEdge(entities, edge_curve3, edge3_dir)); 147 | 148 | // create the plane 149 | auto plane_point = new Point(entities, p0[0], p0[1], p0[2]); 150 | auto plane_dir_1 = new Direction(entities, d2[0], d2[1], d2[2]); 151 | auto plane_dir_2 = new Direction(entities, d0[0], d0[1], d0[2]); 152 | auto plane_csys = new Csys3D(entities, plane_dir_1, plane_dir_2, plane_point); 153 | auto plane = new Plane(entities, plane_csys); 154 | 155 | // build the faces 156 | 157 | auto edge_loop = new EdgeLoop(entities, oriented_edges); 158 | std::vector face_bounds; 159 | face_bounds.push_back(new FaceBound(entities, edge_loop, true)); 160 | faces.push_back(new Face(entities, face_bounds, plane, true)); 161 | } 162 | 163 | // build the model 164 | auto open_shell = new Shell(entities, faces); 165 | std::vector shells; 166 | shells.push_back(open_shell); 167 | auto shell_model = new ShellModel(entities, shells); 168 | auto manifold_shape = new ManifoldShape(entities, base_csys, shell_model); 169 | } 170 | 171 | void StepKernel::get_edge_from_map( 172 | double p0[3], 173 | double p1[3], 174 | std::map, StepKernel::EdgeCurve *> &edge_map, 175 | StepKernel::Vertex * vert1, 176 | StepKernel::Vertex * vert2, 177 | EdgeCurve *& edge_curve, 178 | bool &edge_dir, 179 | int &merge_cnt) 180 | { 181 | edge_curve = 0; 182 | edge_dir = true; 183 | auto edge_tuple1_f = std::make_tuple(p0[0], p0[1], p0[2], p1[0], p1[1], p1[2]); 184 | auto edge_tuple1_r = std::make_tuple(p1[0], p1[1], p1[2], p0[0], p0[1], p0[2]); 185 | if (edge_map.count(edge_tuple1_f)) 186 | { 187 | edge_curve = edge_map[edge_tuple1_f]; 188 | edge_dir = true; 189 | merge_cnt++; 190 | } 191 | else if (edge_map.count(edge_tuple1_r)) 192 | { 193 | edge_curve = edge_map[edge_tuple1_r]; 194 | edge_dir = false; 195 | merge_cnt++; 196 | } 197 | if (!edge_curve) 198 | { 199 | edge_curve = create_edge_curve(vert1, vert2, true); 200 | edge_map[edge_tuple1_f] = edge_curve; 201 | } 202 | } 203 | 204 | void StepKernel::write_step(std::string file_name) 205 | { 206 | std::time_t tt = std ::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); 207 | struct std::tm * ptm = std::localtime(&tt); 208 | std::stringstream iso_time; 209 | iso_time << std::put_time(ptm, "%FT%T"); 210 | 211 | std::ofstream stp_file; 212 | stp_file.open(file_name); 213 | if (!stp_file) 214 | return; 215 | std::string author = "slugdev"; 216 | std::string org = "org"; 217 | // header info 218 | stp_file << "ISO-10303-21;\n"; 219 | stp_file << "HEADER;\n"; 220 | stp_file << "FILE_DESCRIPTION(('STP203'),'2;1');\n"; 221 | stp_file << "FILE_NAME('" << file_name << "','" << iso_time.str() << "',('" << author << "'),('" << org << "'),' ','stltostp',' ');\n"; 222 | stp_file << "FILE_SCHEMA(('CONFIG_CONTROL_DESIGN'));\n"; 223 | stp_file << "ENDSEC; \n"; 224 | 225 | // data section 226 | stp_file << "DATA;\n"; 227 | 228 | for (auto e:entities ) 229 | e->serialize(stp_file); 230 | // create the base csys 231 | stp_file << "ENDSEC;\n"; 232 | stp_file << "END-ISO-10303-21;\n"; 233 | stp_file.close(); 234 | } 235 | 236 | std::string StepKernel::read_line(std::ifstream &stp_file, bool skip_all_space) 237 | { 238 | std::string line_str; 239 | bool leading_space = true; 240 | while (stp_file) 241 | { 242 | char get_char = ' '; 243 | stp_file.get(get_char); 244 | if (get_char == ';') 245 | break; 246 | 247 | if (get_char == '\n' || get_char == '\r' || get_char == '\t') 248 | continue; 249 | 250 | if (leading_space && (get_char == ' ' || get_char == '\t')) 251 | continue; 252 | if (!skip_all_space) 253 | leading_space = false; 254 | line_str.push_back(get_char); 255 | } 256 | return line_str; 257 | } 258 | 259 | void StepKernel::read_step(std::string file_name) 260 | { 261 | std::ifstream stp_file; 262 | stp_file.open(file_name); 263 | if (!stp_file) 264 | return; 265 | 266 | // read the first line to get the iso stuff 267 | std::string iso_line = read_line(stp_file, true); 268 | 269 | bool data_section = false; 270 | std::vector ents; 271 | std::map ent_map; 272 | std::vector args; 273 | while (stp_file) 274 | { 275 | std::string cur_str = read_line(stp_file, false); 276 | if (cur_str == "DATA") 277 | { 278 | data_section = true; 279 | continue; 280 | } 281 | if (!data_section) 282 | continue; 283 | 284 | if (cur_str == "ENDSEC") 285 | { 286 | data_section = false; 287 | break; 288 | } 289 | // parse the id 290 | int id = -1; 291 | if (cur_str.size() > 0 && cur_str[0] == '#' && cur_str.find('=')) 292 | { 293 | auto equal_pos = cur_str.find('='); 294 | auto paren_pos = cur_str.find('('); 295 | auto id_str = cur_str.substr(1, equal_pos - 1); 296 | id = std::atoi(id_str.c_str()); 297 | auto func_start = cur_str.find_first_not_of("\t ", equal_pos+1); 298 | auto func_end = cur_str.find_first_of("\t (", equal_pos + 1); 299 | auto func_name = cur_str.substr(func_start, func_end - func_start); 300 | 301 | // now parse the args 302 | auto arg_end = cur_str.find_last_of(')'); 303 | auto arg_str = cur_str.substr(func_end + 1, arg_end - func_end - 1); 304 | Entity* ent = 0; 305 | if (func_name == "CARTESIAN_POINT") 306 | ent = new Point(entities); 307 | else if (func_name == "DIRECTION") 308 | ent = new Direction(entities); 309 | else if (func_name == "AXIS2_PLACEMENT_3D") 310 | ent = new Csys3D(entities); 311 | else if (func_name == "PLANE") 312 | ent = new Plane(entities); 313 | else if (func_name == "EDGE_LOOP") 314 | ent = new EdgeLoop(entities); 315 | else if (func_name == "FACE_BOUND") 316 | ent = new FaceBound(entities); 317 | else if (func_name == "FACE_OUTER_BOUND") 318 | ent = new FaceBound(entities); 319 | else if (func_name == "ADVANCED_FACE") 320 | ent = new Face(entities); 321 | else if (func_name == "FACE_SURFACE") 322 | ent = new Face(entities); 323 | else if (func_name == "OPEN_SHELL") 324 | ent = new Shell(entities); 325 | else if (func_name == "CLOSED_SHELL") 326 | ent = new Shell(entities); 327 | else if (func_name == "SHELL_BASED_SURFACE_MODEL") 328 | ent = new ShellModel(entities); 329 | else if (func_name == "MANIFOLD_SURFACE_SHAPE_REPRESENTATION") 330 | ent = new ManifoldShape(entities); 331 | else if (func_name == "VERTEX_POINT") 332 | ent = new Vertex(entities); 333 | else if (func_name == "SURFACE_CURVE") 334 | ent = new SurfaceCurve(entities); 335 | else if (func_name == "EDGE_CURVE") 336 | ent = new EdgeCurve(entities); 337 | else if (func_name == "ORIENTED_EDGE") 338 | ent = new OrientedEdge(entities); 339 | else if (func_name == "VECTOR") 340 | ent = new Vector(entities); 341 | else if (func_name == "LINE") 342 | ent = new Line(entities); 343 | 344 | if (ent) 345 | { 346 | ent->id = id; 347 | ent_map[id] = ent; 348 | ents.push_back(ent); 349 | args.push_back(arg_str); 350 | } 351 | } 352 | std::cout << cur_str << "\n"; 353 | } 354 | // processes all the arguments 355 | for (int i = 0; i < ents.size(); i++) 356 | { 357 | ents[i]->parse_args(ent_map,args[i]); 358 | } 359 | stp_file.close(); 360 | } 361 | -------------------------------------------------------------------------------- /StepKernel.h: -------------------------------------------------------------------------------- 1 | /*Copyright(c) 2018, slugdev 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met : 6 | 1. Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | 2. Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | 3. All advertising materials mentioning features or use of this software 12 | must display the following acknowledgement : 13 | This product includes software developed by slugdev. 14 | 4. Neither the name of the slugdev nor the 15 | names of its contributors may be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY SLUGDEV ''AS IS'' AND ANY 19 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED.IN NO EVENT SHALL SLUGDEV BE LIABLE FOR ANY 22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | class StepKernel 37 | { 38 | public: 39 | class Entity 40 | { 41 | public: 42 | Entity(std::vector &ent_list) 43 | { 44 | ent_list.push_back(this); 45 | id = int(ent_list.size()); 46 | } 47 | virtual ~Entity() 48 | {} 49 | 50 | std::vector tokenize(const std::string& str, const std::string& delimiters = ",") 51 | { 52 | std::vector tokens; 53 | // Skip delimiters at beginning. 54 | std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); 55 | 56 | // Find first non-delimiter. 57 | std::string::size_type pos = str.find_first_of(delimiters, lastPos); 58 | 59 | while (std::string::npos != pos || std::string::npos != lastPos) 60 | { 61 | // Found a token, add it to the vector. 62 | tokens.push_back(str.substr(lastPos, pos - lastPos)); 63 | 64 | // Skip delimiters. 65 | lastPos = str.find_first_not_of(delimiters, pos); 66 | 67 | // Find next non-delimiter. 68 | pos = str.find_first_of(delimiters, lastPos); 69 | } 70 | return tokens; 71 | } 72 | 73 | virtual void serialize(std::ostream& stream_in) = 0; 74 | virtual void parse_args(std::map &ent_map, std::string args) = 0; 75 | int id; 76 | std::string label; 77 | }; 78 | 79 | class Direction : public Entity 80 | { 81 | public: 82 | Direction(std::vector &ent_list) : Entity(ent_list) 83 | { 84 | x = 0; 85 | y = 0; 86 | z = 0; 87 | } 88 | Direction(std::vector &ent_list, double x_in, double y_in, double z_in): Entity(ent_list) 89 | { 90 | x = x_in; 91 | y = y_in; 92 | z = z_in; 93 | } 94 | 95 | virtual ~Direction() 96 | {} 97 | 98 | virtual void serialize(std::ostream& stream_in) 99 | { 100 | stream_in << "#" << id << " = DIRECTION('"<< label<<"', (" << x << ", " << y << ", " << z << "));\n"; 101 | } 102 | 103 | virtual void parse_args(std::map &ent_map, std::string args) 104 | { 105 | auto st = args.find_first_of('('); 106 | auto en = args.find_last_of(')'); 107 | auto arg_str = args.substr(st+1, en - st - 1); 108 | std::replace(arg_str.begin(), arg_str.end(), ',', ' '); 109 | std::stringstream ss(arg_str); 110 | ss >> x >> y >> z; 111 | } 112 | 113 | double x, y, z; 114 | }; 115 | 116 | class Point : public Entity 117 | { 118 | public: 119 | Point(std::vector &ent_list) : Entity(ent_list) 120 | { 121 | x = 0; 122 | y = 0; 123 | z = 0; 124 | } 125 | Point(std::vector &ent_list, double x_in, double y_in, double z_in) : Entity(ent_list) 126 | { 127 | x = x_in; 128 | y = y_in; 129 | z = z_in; 130 | } 131 | 132 | virtual ~Point() 133 | {} 134 | 135 | virtual void serialize(std::ostream& stream_in) 136 | { 137 | stream_in << "#" << id << " = CARTESIAN_POINT('" << label << "', (" << x << "," << y << "," << z << "));\n"; 138 | } 139 | virtual void parse_args(std::map &ent_map, std::string args) 140 | { 141 | auto st = args.find_first_of('('); 142 | auto en = args.find_last_of(')'); 143 | auto arg_str = args.substr(st + 1, en - st - 1); 144 | std::replace(arg_str.begin(), arg_str.end(), ',', ' '); 145 | std::stringstream ss(arg_str); 146 | ss >> x >> y >> z; 147 | } 148 | double x, y, z; 149 | }; 150 | 151 | class Csys3D : public Entity 152 | { 153 | public: 154 | Csys3D(std::vector &ent_list) : Entity(ent_list) 155 | { 156 | dir1 = 0; 157 | dir2 = 0; 158 | point = 0; 159 | } 160 | 161 | Csys3D(std::vector &ent_list, Direction* dir1_in,Direction* dir2_in,Point* point_in) : Entity(ent_list) 162 | { 163 | dir1 = dir1_in; 164 | dir2 = dir2_in; 165 | point = point_in; 166 | } 167 | 168 | virtual ~Csys3D() 169 | {} 170 | 171 | virtual void serialize(std::ostream& stream_in) 172 | { 173 | stream_in << "#" << id << " = AXIS2_PLACEMENT_3D('" << label << "',#" << point->id << ",#" << dir1->id << ",#" << dir2->id << ");\n"; 174 | } 175 | 176 | virtual void parse_args(std::map &ent_map, std::string args) 177 | { 178 | auto st = args.find_first_of(','); 179 | auto arg_str = args.substr(st + 1); 180 | std::replace(arg_str.begin(), arg_str.end(), ',', ' '); 181 | std::replace(arg_str.begin(), arg_str.end(), '#', ' '); 182 | std::stringstream ss(arg_str); 183 | int d1_id, d2_id, p_id; 184 | ss >> p_id >> d1_id >> d2_id; 185 | 186 | dir1 = dynamic_cast(ent_map[d1_id]); 187 | dir2 = dynamic_cast(ent_map[d2_id]); 188 | point = dynamic_cast(ent_map[p_id]); 189 | } 190 | 191 | Direction* dir1; 192 | Direction* dir2; 193 | Point* point; 194 | }; 195 | 196 | class Plane : public Entity 197 | { 198 | public: 199 | Plane(std::vector &ent_list) : Entity(ent_list) 200 | { 201 | csys = 0; 202 | } 203 | 204 | Plane(std::vector &ent_list, Csys3D* csys_in) : Entity(ent_list) 205 | { 206 | csys = csys_in; 207 | } 208 | virtual ~Plane() 209 | {} 210 | 211 | virtual void serialize(std::ostream& stream_in) 212 | { 213 | stream_in << "#" << id << " = PLANE('" << label << "',#" << csys->id <<");\n"; 214 | } 215 | virtual void parse_args(std::map &ent_map, std::string args) 216 | { 217 | auto st = args.find_first_of(','); 218 | auto arg_str = args.substr(st + 1); 219 | std::replace(arg_str.begin(), arg_str.end(), ',', ' '); 220 | std::replace(arg_str.begin(), arg_str.end(), '#', ' '); 221 | std::stringstream ss(arg_str); 222 | int p_id; 223 | ss >> p_id; 224 | 225 | csys = dynamic_cast(ent_map[p_id]); 226 | } 227 | 228 | Csys3D* csys; 229 | }; 230 | 231 | class OrientedEdge; 232 | 233 | class EdgeLoop : public Entity 234 | { 235 | public: 236 | EdgeLoop(std::vector &ent_list) : Entity(ent_list) 237 | { 238 | } 239 | EdgeLoop(std::vector &ent_list, std::vector& edges_in) : Entity(ent_list) 240 | { 241 | faces = edges_in; 242 | } 243 | virtual ~EdgeLoop() 244 | {} 245 | 246 | virtual void serialize(std::ostream& stream_in) 247 | { 248 | // #17 = ADVANCED_FACE('', (#18), #32, .T.); 249 | stream_in << "#" << id << " = EDGE_LOOP('" << label << "', ("; 250 | for (int i = 0; i < faces.size(); i++) 251 | { 252 | stream_in << "#" << faces[i]->id; 253 | if (i != faces.size() - 1) 254 | stream_in << ","; 255 | } 256 | stream_in << "));\n"; 257 | } 258 | virtual void parse_args(std::map &ent_map, std::string args) 259 | { 260 | auto st = args.find_first_of('('); 261 | auto en = args.find_last_of(')'); 262 | auto arg_str = args.substr(st + 1, en - st - 1); 263 | std::replace(arg_str.begin(), arg_str.end(), '#', ' '); 264 | auto vals = tokenize(arg_str); 265 | for (auto v : vals) 266 | { 267 | int id = std::atoi(v.c_str()); 268 | faces.push_back(dynamic_cast(ent_map[id])); 269 | } 270 | //csys = dynamic_cast(ent_map[p_id]); 271 | } 272 | std::vector faces; 273 | }; 274 | 275 | class FaceBound : public Entity 276 | { 277 | public: 278 | FaceBound(std::vector &ent_list) : Entity(ent_list) 279 | { 280 | edgeLoop = 0; 281 | dir = true; 282 | } 283 | FaceBound(std::vector &ent_list, EdgeLoop* edge_loop_in, bool dir_in) : Entity(ent_list) 284 | { 285 | edgeLoop = edge_loop_in; 286 | dir = dir_in; 287 | } 288 | virtual ~FaceBound() 289 | {} 290 | 291 | virtual void serialize(std::ostream& stream_in) 292 | { 293 | stream_in << "#" << id << " = FACE_BOUND('" << label << "', #" << edgeLoop->id << "," << (dir?".T.":".F.") << ");\n"; 294 | } 295 | virtual void parse_args(std::map &ent_map, std::string args) 296 | { 297 | auto st = args.find_first_of(','); 298 | auto arg_str = args.substr(st + 1); 299 | std::replace(arg_str.begin(), arg_str.end(), ',', ' '); 300 | std::replace(arg_str.begin(), arg_str.end(), '#', ' '); 301 | std::stringstream ss(arg_str); 302 | int p_id; 303 | std::string tf; 304 | ss >> p_id >> tf; 305 | 306 | edgeLoop = dynamic_cast(ent_map[p_id]); 307 | dir = (tf == ".T."); 308 | } 309 | EdgeLoop* edgeLoop; 310 | bool dir; 311 | }; 312 | 313 | class Face : public Entity 314 | { 315 | public: 316 | Face(std::vector &ent_list) : Entity(ent_list) 317 | { 318 | dir = true; 319 | plane = 0; 320 | } 321 | Face(std::vector &ent_list, std::vector face_bounds_in, Plane* plane_in, bool dir_in) : Entity(ent_list) 322 | { 323 | faceBounds = face_bounds_in; 324 | dir = dir_in; 325 | plane = plane_in; 326 | } 327 | virtual ~Face() 328 | {} 329 | 330 | virtual void serialize(std::ostream& stream_in) 331 | { 332 | stream_in << "#" << id << " = ADVANCED_FACE('" << label << "', ("; 333 | for (int i = 0; i < faceBounds.size(); i++) 334 | { 335 | stream_in << "#" << faceBounds[i]->id; 336 | if (i != faceBounds.size() - 1) 337 | stream_in << ","; 338 | } 339 | stream_in << "),#" << plane->id << "," << (dir?".T.":".F.") << ");\n"; 340 | } 341 | virtual void parse_args(std::map &ent_map, std::string args) 342 | { 343 | auto st = args.find_first_of('('); 344 | auto en = args.find_last_of(')'); 345 | auto arg_str = args.substr(st + 1, en - st - 1); 346 | std::replace(arg_str.begin(), arg_str.end(), '#', ' '); 347 | auto vals = tokenize(arg_str); 348 | for (auto v : vals) 349 | { 350 | int id = std::atoi(v.c_str()); 351 | faceBounds.push_back(dynamic_cast(ent_map[id])); 352 | } 353 | auto remaining = args.substr(en + 1); 354 | std::replace(remaining.begin(), remaining.end(), '#', ' '); 355 | std::replace(remaining.begin(), remaining.end(), ',', ' '); 356 | std::stringstream ss(remaining); 357 | int p_id; 358 | std::string tf; 359 | ss >> p_id >> tf; 360 | 361 | plane = dynamic_cast(ent_map[p_id]); 362 | dir = (tf == ".T."); 363 | } 364 | 365 | std::vector faceBounds; 366 | bool dir; 367 | Plane* plane; 368 | }; 369 | 370 | class Shell : public Entity 371 | { 372 | public: 373 | Shell(std::vector &ent_list) : Entity(ent_list) 374 | { 375 | isOpen = true; 376 | } 377 | Shell(std::vector &ent_list, std::vector& faces_in) : Entity(ent_list) 378 | { 379 | faces = faces_in; 380 | isOpen = true; 381 | } 382 | virtual ~Shell() 383 | {} 384 | 385 | virtual void serialize(std::ostream& stream_in) 386 | { 387 | if (isOpen) 388 | stream_in << "#" << id << " = OPEN_SHELL('" << label << "',("; 389 | else 390 | stream_in << "#" << id << " = CLOSED_SHELL('" << label << "',("; 391 | 392 | for (int i = 0; i < faces.size(); i++) 393 | { 394 | stream_in << "#" << faces[i]->id; 395 | if (i != faces.size() - 1) 396 | stream_in << ","; 397 | } 398 | stream_in << "));\n"; 399 | } 400 | virtual void parse_args(std::map &ent_map, std::string args) 401 | { 402 | auto st = args.find_first_of('('); 403 | auto en = args.find_last_of(')'); 404 | auto arg_str = args.substr(st + 1, en - st - 1); 405 | std::replace(arg_str.begin(), arg_str.end(), '#', ' '); 406 | auto vals = tokenize(arg_str); 407 | for (auto v : vals) 408 | { 409 | int id = std::atoi(v.c_str()); 410 | faces.push_back(dynamic_cast(ent_map[id])); 411 | } 412 | } 413 | 414 | std::vector faces; 415 | bool isOpen; 416 | }; 417 | 418 | class ShellModel : public Entity 419 | { 420 | public: 421 | ShellModel(std::vector &ent_list) : Entity(ent_list) 422 | { 423 | } 424 | ShellModel(std::vector &ent_list, std::vector shells_in) : Entity(ent_list) 425 | { 426 | shells = shells_in; 427 | } 428 | virtual ~ShellModel() 429 | {} 430 | 431 | virtual void serialize(std::ostream& stream_in) 432 | { 433 | stream_in << "#" << id << " = SHELL_BASED_SURFACE_MODEL('" << label << "', ("; 434 | for (int i = 0; i < shells.size(); i++) 435 | { 436 | stream_in << "#" << shells[i]->id; 437 | if(i != shells.size()-1) 438 | stream_in << ","; 439 | } 440 | stream_in << "));\n"; 441 | } 442 | virtual void parse_args(std::map &ent_map, std::string args) 443 | { 444 | auto st = args.find_first_of('('); 445 | auto en = args.find_last_of(')'); 446 | auto arg_str = args.substr(st + 1, en - st - 1); 447 | std::replace(arg_str.begin(), arg_str.end(), '#', ' '); 448 | auto vals = tokenize(arg_str); 449 | for (auto v : vals) 450 | { 451 | int id = std::atoi(v.c_str()); 452 | shells.push_back(dynamic_cast(ent_map[id])); 453 | } 454 | } 455 | 456 | std::vector shells; 457 | }; 458 | 459 | class ManifoldShape : public Entity 460 | { 461 | public: 462 | ManifoldShape(std::vector &ent_list) : Entity(ent_list) 463 | { 464 | csys = 0; 465 | shellModel = 0; 466 | } 467 | ManifoldShape(std::vector &ent_list, Csys3D* csys_in, ShellModel* shell_model_in) : Entity(ent_list) 468 | { 469 | csys = csys_in; 470 | shellModel = shell_model_in; 471 | } 472 | virtual ~ManifoldShape() 473 | {} 474 | 475 | virtual void serialize(std::ostream& stream_in) 476 | { 477 | stream_in << "#" << id << " = MANIFOLD_SURFACE_SHAPE_REPRESENTATION('" << label << "', (#" << csys->id << ", #" << shellModel->id << "));\n"; 478 | } 479 | virtual void parse_args(std::map &ent_map, std::string args) 480 | { 481 | auto st = args.find_first_of('('); 482 | auto en = args.find_last_of(')'); 483 | auto arg_str = args.substr(st + 1, en - st - 1); 484 | std::replace(arg_str.begin(), arg_str.end(), ',', ' '); 485 | std::replace(arg_str.begin(), arg_str.end(), '#', ' '); 486 | std::stringstream ss(arg_str); 487 | int p1_id, p2_id; 488 | ss >> p1_id >> p2_id; 489 | 490 | csys = dynamic_cast(ent_map[p1_id]); 491 | shellModel = dynamic_cast(ent_map[p2_id]); 492 | 493 | if (!csys && !shellModel) 494 | { 495 | csys = dynamic_cast(ent_map[p2_id]); 496 | shellModel = dynamic_cast(ent_map[p1_id]); 497 | } 498 | } 499 | 500 | Csys3D* csys; 501 | ShellModel* shellModel; 502 | }; 503 | 504 | class Vertex : public Entity 505 | { 506 | public: 507 | Vertex(std::vector &ent_list) : Entity(ent_list) 508 | { 509 | point = 0; 510 | } 511 | Vertex(std::vector &ent_list, Point* point_in) : Entity(ent_list) 512 | { 513 | point = point_in; 514 | } 515 | virtual ~Vertex() 516 | {} 517 | 518 | virtual void serialize(std::ostream& stream_in) 519 | { 520 | stream_in << "#" << id << " = VERTEX_POINT('" << label << "', #" << point->id << ");\n"; 521 | } 522 | virtual void parse_args(std::map &ent_map, std::string args) 523 | { 524 | auto st = args.find_first_of(','); 525 | auto arg_str = args.substr(st + 1); 526 | std::replace(arg_str.begin(), arg_str.end(), ',', ' '); 527 | std::replace(arg_str.begin(), arg_str.end(), '#', ' '); 528 | std::stringstream ss(arg_str); 529 | int p1_id; 530 | ss >> p1_id ; 531 | 532 | point = dynamic_cast(ent_map[p1_id]); 533 | } 534 | 535 | Point* point; 536 | }; 537 | 538 | class Line; 539 | 540 | class SurfaceCurve : public Entity 541 | { 542 | public: 543 | SurfaceCurve(std::vector &ent_list) : Entity(ent_list) 544 | { 545 | line = 0; 546 | } 547 | SurfaceCurve(std::vector &ent_list, Line* surface_curve_in) : Entity(ent_list) 548 | { 549 | line = surface_curve_in; 550 | } 551 | virtual ~SurfaceCurve() 552 | {} 553 | 554 | virtual void serialize(std::ostream& stream_in) 555 | { 556 | stream_in << "#" << id << " = SURFACE_CURVE('" << label << "', #" << line->id << ");\n"; 557 | } 558 | virtual void parse_args(std::map &ent_map, std::string args) 559 | { 560 | auto st = args.find_first_of(','); 561 | auto arg_str = args.substr(st + 1); 562 | std::replace(arg_str.begin(), arg_str.end(), ',', ' '); 563 | std::replace(arg_str.begin(), arg_str.end(), '#', ' '); 564 | std::stringstream ss(arg_str); 565 | int p1_id; 566 | ss >> p1_id; 567 | 568 | line = dynamic_cast(ent_map[p1_id]); 569 | } 570 | 571 | Line* line; 572 | }; 573 | 574 | class EdgeCurve : public Entity 575 | { 576 | public: 577 | EdgeCurve(std::vector &ent_list) : Entity(ent_list) 578 | { 579 | vert1 = 0; 580 | vert2 = 0; 581 | surfCurve = 0; 582 | dir = true; 583 | } 584 | EdgeCurve(std::vector &ent_list,Vertex* vert1_in, Vertex* vert2_in, SurfaceCurve* surf_curve_in, bool dir_in) : Entity(ent_list) 585 | { 586 | vert1 = vert1_in; 587 | vert2 = vert2_in; 588 | surfCurve = surf_curve_in; 589 | dir = dir_in; 590 | } 591 | virtual ~EdgeCurve() 592 | {} 593 | 594 | virtual void serialize(std::ostream& stream_in) 595 | { 596 | stream_in << "#" << id << " = EDGE_CURVE('', #" << vert1->id << ", #" << vert2->id << ",#" << (surfCurve ? surfCurve->id: line->id) << "," << (dir ? ".T." : ".F.") << ");\n"; 597 | } 598 | 599 | virtual void parse_args(std::map &ent_map, std::string args) 600 | { 601 | auto st = args.find_first_of(','); 602 | auto arg_str = args.substr(st + 1); 603 | std::replace(arg_str.begin(), arg_str.end(), ',', ' '); 604 | std::replace(arg_str.begin(), arg_str.end(), '#', ' '); 605 | std::stringstream ss(arg_str); 606 | int p1_id, p2_id, p3_id; 607 | std::string tf; 608 | ss >> p1_id >> p2_id >> p3_id >> tf; 609 | 610 | vert1 = dynamic_cast(ent_map[p1_id]); 611 | vert2 = dynamic_cast(ent_map[p2_id]); 612 | surfCurve = dynamic_cast(ent_map[p3_id]); 613 | if(!surfCurve) 614 | line = dynamic_cast(ent_map[p3_id]); 615 | dir = (tf == ".T."); 616 | } 617 | 618 | Vertex* vert1; 619 | Vertex* vert2; 620 | SurfaceCurve* surfCurve; 621 | Line* line; 622 | bool dir; 623 | }; 624 | 625 | class OrientedEdge : public Entity 626 | { 627 | public: 628 | OrientedEdge(std::vector &ent_list) : Entity(ent_list) 629 | { 630 | edge = 0; 631 | dir = 0; 632 | } 633 | OrientedEdge(std::vector &ent_list,EdgeCurve* edge_curve_in,bool dir_in) : Entity(ent_list) 634 | { 635 | edge = edge_curve_in; 636 | dir = dir_in; 637 | } 638 | virtual ~OrientedEdge() 639 | {} 640 | 641 | virtual void serialize(std::ostream& stream_in) 642 | { 643 | stream_in << "#" << id << " = ORIENTED_EDGE('"<id << "," << (dir ? ".T." : ".F.") << ");\n"; 644 | } 645 | 646 | virtual void parse_args(std::map &ent_map, std::string args) 647 | { 648 | auto st = args.find_first_of(','); 649 | auto arg_str = args.substr(st + 1); 650 | std::replace(arg_str.begin(), arg_str.end(), ',', ' '); 651 | std::replace(arg_str.begin(), arg_str.end(), '#', ' '); 652 | std::stringstream ss(arg_str); 653 | int p1_id; 654 | std::string s1,s2,tf; 655 | ss >> s1 >> s2 >> p1_id >> tf; 656 | 657 | edge = dynamic_cast(ent_map[p1_id]); 658 | dir = (tf == ".T."); 659 | } 660 | 661 | bool dir; 662 | EdgeCurve* edge; 663 | }; 664 | 665 | class Vector : public Entity 666 | { 667 | public: 668 | Vector(std::vector &ent_list) : Entity(ent_list) 669 | { 670 | dir = 0; 671 | length = 0; 672 | } 673 | Vector(std::vector &ent_list, Direction* dir_in, double len_in) : Entity(ent_list) 674 | { 675 | dir = dir_in; 676 | length = len_in; 677 | } 678 | virtual ~Vector() 679 | {} 680 | 681 | virtual void serialize(std::ostream& stream_in) 682 | { 683 | stream_in << "#" << id << " = VECTOR('" << label << "',#" << dir->id << "," << length << ");\n"; 684 | } 685 | 686 | virtual void parse_args(std::map &ent_map, std::string args) 687 | { 688 | auto st = args.find_first_of(','); 689 | auto arg_str = args.substr(st + 1); 690 | std::replace(arg_str.begin(), arg_str.end(), ',', ' '); 691 | std::replace(arg_str.begin(), arg_str.end(), '#', ' '); 692 | std::stringstream ss(arg_str); 693 | int p1_id; 694 | ss >> p1_id >> length; 695 | 696 | dir = dynamic_cast(ent_map[p1_id]); 697 | } 698 | 699 | double length; 700 | Direction* dir; 701 | }; 702 | 703 | class Line : public Entity 704 | { 705 | public: 706 | Line(std::vector &ent_list) : Entity(ent_list) 707 | { 708 | vector = 0; 709 | point = 0; 710 | } 711 | Line(std::vector &ent_list,Point* point_in,Vector* vec_in) : Entity(ent_list) 712 | { 713 | vector = vec_in; 714 | point = point_in; 715 | } 716 | virtual ~Line() 717 | {} 718 | 719 | virtual void serialize(std::ostream& stream_in) 720 | { 721 | stream_in << "#" << id << " = LINE('" << label << "',#" << point->id << ", #" << vector->id << ");\n"; 722 | } 723 | 724 | virtual void parse_args(std::map &ent_map, std::string args) 725 | { 726 | auto st = args.find_first_of(','); 727 | auto arg_str = args.substr(st + 1); 728 | std::replace(arg_str.begin(), arg_str.end(), ',', ' '); 729 | std::replace(arg_str.begin(), arg_str.end(), '#', ' '); 730 | std::stringstream ss(arg_str); 731 | int p1_id, p2_id; 732 | ss >> p1_id >> p2_id; 733 | 734 | point = dynamic_cast(ent_map[p1_id]); 735 | vector = dynamic_cast(ent_map[p2_id]); 736 | } 737 | 738 | Point* point; 739 | Vector* vector; 740 | }; 741 | 742 | public: 743 | StepKernel(); 744 | virtual ~StepKernel(); 745 | 746 | StepKernel::EdgeCurve* create_edge_curve(StepKernel::Vertex * vert1, StepKernel::Vertex * vert2, bool dir); 747 | 748 | void build_tri_body(std::vector tris, double tol, int &merged_edge_cnt); 749 | void get_edge_from_map( 750 | double p0[3], 751 | double p1[3], 752 | std::map, StepKernel::EdgeCurve *> &edge_map, 753 | StepKernel::Vertex * vert1, 754 | StepKernel::Vertex * vert2, 755 | EdgeCurve *& edge_curve, 756 | bool &edge_dir, 757 | int &merge_cnt); 758 | void write_step(std::string file_name); 759 | std::string read_line(std::ifstream &stp_file, bool skip_all_space); 760 | void read_step(std::string file_name); 761 | std::vector entities; 762 | }; 763 | -------------------------------------------------------------------------------- /doc/example.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slugdev/stltostp/439c03995ff01c4c4ac8fde1c5955a1352240164/doc/example.jpg -------------------------------------------------------------------------------- /doc/input_output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slugdev/stltostp/439c03995ff01c4c4ac8fde1c5955a1352240164/doc/input_output.jpg -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slugdev/stltostp/439c03995ff01c4c4ac8fde1c5955a1352240164/main.cpp -------------------------------------------------------------------------------- /test/cat_dish_bin.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slugdev/stltostp/439c03995ff01c4c4ac8fde1c5955a1352240164/test/cat_dish_bin.stl --------------------------------------------------------------------------------