IDFstepper
IDF to STEP converter
|
00001 #ifndef STEPGENERATOR_HPP_INCLUDED 00002 #define STEPGENERATOR_HPP_INCLUDED 00003 00004 #include "IdfStructure.hpp" 00005 #include "ConfigType.hpp" 00006 #ifdef _WIN32 00007 #include <TopoDS.hxx> 00008 #include <gp_Pnt.hxx> 00009 #else 00010 #include <opencascade/TopoDS.hxx> 00011 #include <opencascade/gp_Pnt.hxx> 00012 #endif 00013 00014 #include <boost/variant.hpp> 00015 #include <string> 00016 #include <set> 00017 #include <iostream> 00018 #include <fstream> 00019 #include <sstream> 00020 #include <streambuf> 00021 00026 #define err(stream); std::cerr << stream; errBuf << stream; 00027 00028 namespace stepper { 00029 00038 class StepGenerator { 00039 00040 public: 00041 00043 static const double EQUAL_PT_DIST; 00044 00048 enum OverwritePolicy { 00051 ASK, 00053 NEVER, 00055 ALWAYS, 00057 YES, 00059 NO 00060 }; 00061 00062 00071 StepGenerator(std::ostringstream& eBuf) 00072 : compOvW(ASK), boardOvW(ASK), panelOvW(ASK), errBuf(eBuf), 00073 libraryNamePattern("%n.stp"), 00074 minSolidHeight(0.1), 00075 boardNamePattern("%n.stp"), panelNamePattern("%n.stp"), 00076 minHoleDiameter(1.0) {} 00077 00084 void setComponentOverwritePolicy(OverwritePolicy policy) { 00085 if ((policy == ASK) || (policy == NEVER) || (policy == ALWAYS)) { 00086 compOvW = policy; 00087 } else { 00088 compOvW = ASK; 00089 } 00090 } 00091 00098 void setBoardOverwritePolicy(OverwritePolicy policy) { 00099 if ((policy == ASK) || (policy == NEVER) || (policy == ALWAYS)) { 00100 boardOvW = policy; 00101 } else { 00102 boardOvW = ASK; 00103 } 00104 } 00105 00112 void setPanelOverwritePolicy(OverwritePolicy policy) { 00113 if ((policy == ASK) || (policy == NEVER) || (policy == ALWAYS)) { 00114 panelOvW = policy; 00115 } else { 00116 panelOvW = ASK; 00117 } 00118 } 00119 00126 void setLibraryPath(const std::string& path) { 00127 libraryPath = path; 00128 if (!path.empty()) { 00129 char e = path[path.size() - 1]; 00130 if (e != '/' && e != '\\') libraryPath += '/'; 00131 } 00132 } 00133 00144 void setLibraryNamePattern(const std::string& pattern) { 00145 libraryNamePattern = pattern; 00146 } 00147 00156 void setMinSolidHeight(double minHeight) { 00157 minSolidHeight = minHeight; 00158 } 00159 00166 void setBoardPath(const std::string& path) { 00167 boardPath = path; 00168 if (!path.empty()) { 00169 char e = path[path.size() - 1]; 00170 if (e != '/' && e != '\\') boardPath += '/'; 00171 } 00172 } 00173 00184 void setBoardNamePattern(const std::string& pattern) { 00185 boardNamePattern = pattern; 00186 } 00187 00194 void setPanelPath(const std::string& path) { 00195 panelPath = path; 00196 if (!path.empty()) { 00197 char e = path[path.size() - 1]; 00198 if (e != '/' && e != '\\') panelPath += '/'; 00199 } 00200 } 00201 00210 void setPanelNamePattern(const std::string& pattern) { 00211 panelNamePattern = pattern; 00212 } 00213 00221 void setMinHoleDiameter(double dia) { 00222 minHoleDiameter = dia; 00223 } 00224 00235 bool setConfigOption(const std::string& key, const config::Value& value) 00236 throw (boost::bad_get); 00237 00243 void generateLibrary(const idf::LibraryStruct& lib) const; 00244 00250 void generateBoard(const idf::BoardPanelStruct& board) const; 00251 00257 void generatePanel(const idf::BoardPanelStruct& panel) const; 00258 00259 private: 00260 00261 mutable OverwritePolicy compOvW; 00262 mutable OverwritePolicy boardOvW; 00263 mutable OverwritePolicy panelOvW; 00264 std::ostringstream& errBuf; 00265 std::string libraryPath; 00266 std::string libraryNamePattern; 00267 double minSolidHeight; 00268 std::string boardPath; 00269 std::string boardNamePattern; 00270 std::string panelPath; 00271 std::string panelNamePattern; 00272 double minHoleDiameter; 00273 00274 void generateComponent( 00275 const idf::Component& comp, 00276 std::set<std::string>& processedFiles) const; 00277 00278 TopoDS_Wire wireFromLoops( 00279 std::vector<idf::Loop>::const_iterator& iter, 00280 std::vector<idf::Loop>::const_iterator end, 00281 idf::Unit u) const; 00282 00283 TopoDS_Shape solidFromLoops( 00284 const std::vector<idf::Loop>& loops, 00285 double height, 00286 idf::Unit u) const; 00287 00288 TopoDS_Shape readShape(const std::string& filename) const; 00289 00290 TopoDS_Shape createBoardShape( 00291 const idf::BoardPanelStruct& board) const; 00292 00293 double measure(double value, idf::Unit unit) const { 00294 // Generate everything in millimeters 00295 if (unit == idf::MM) return value; 00296 if (unit == idf::THOU) return value * 0.0254; 00297 err("WARNING: Got unexpected unit code " << unit << std::endl); 00298 return 1.0; 00299 } 00300 00301 std::string createCompFN( 00302 const std::string& name, 00303 const std::string& number) const 00304 { 00305 std::string res = libraryNamePattern; 00306 bool ok = false; 00307 size_t nloc = res.find("%n"); 00308 if (nloc != std::string::npos) { 00309 res.replace(nloc, 2, name); 00310 ok = true; 00311 } 00312 size_t ploc = res.find("%p"); 00313 if (ploc != std::string::npos) { 00314 res.replace(ploc, 2, number); 00315 ok = true; 00316 } 00317 if (!ok) { 00318 std::cerr << "WARNING: Did not find '%n' or '%p' in library " 00319 "name pattern.\n"; 00320 return std::string(); 00321 } 00322 return res; 00323 } 00324 00325 std::string createBoardPanelFN( 00326 const std::string& pattern, 00327 const std::string& name) const 00328 { 00329 std::string res = pattern; 00330 size_t nloc = res.find("%n"); 00331 if (nloc != std::string::npos) { 00332 res.replace(nloc, 2, name); 00333 return res; 00334 } 00335 std::cerr << "WARNING: Did not find '%n' in board/panel " 00336 "name pattern.\n"; 00337 return std::string(); 00338 } 00339 00340 gp_Pnt pt(const idf::Loop& loop, idf::Unit unit) const { 00341 return gp_Pnt( 00342 measure(loop.x, unit), 00343 measure(loop.y, unit), 00344 0.0); 00345 } 00346 00347 OverwritePolicy askOvW(const std::string& file) const { 00348 std::cout << "File '" << file << "' already exists.\n"; 00349 std::cout << "Overwrite? [N]o [y]es ne[v]er [a]lways: "; 00350 std::string inp; 00351 char r; 00352 for (;;) { 00353 std::getline(std::cin, inp); 00354 if (inp.empty()) { 00355 r = 'n'; 00356 } else { 00357 r = inp[0]; 00358 } 00359 00360 switch (r) { 00361 case 'n': 00362 case 'N': 00363 return NO; 00364 case 'y': 00365 case 'Y': 00366 return YES; 00367 case 'v': 00368 case 'V': 00369 return NEVER; 00370 case 'a': 00371 case 'A': 00372 return ALWAYS; 00373 00374 default: 00375 std::cout << "Invalid input, type n, y, v, or a.\n> "; 00376 } 00377 } 00378 } 00379 00380 bool fexists(const std::string& filename) const { 00381 std::ifstream ifile(filename.c_str()); 00382 return ifile; 00383 } 00384 00385 // Utility class to temporarily inhibit output from stdout 00386 class Silence { 00387 public: 00388 Silence() { 00389 oldBuf = cout.rdbuf(); 00390 cout.rdbuf(tempStr.rdbuf()); 00391 } 00392 00393 ~Silence() { 00394 cout.rdbuf(oldBuf); 00395 } 00396 private: 00397 std::streambuf* oldBuf; 00398 std::ostringstream tempStr; 00399 }; 00400 00401 }; 00402 00403 } 00404 00405 #endif 00406 00407