/* static */ gp_Pnt HPoint::GetOffset(gp_Pnt location) { wxString message(_("Enter offset in X,Y,Z format (with commas between them)")); wxString caption(_("Apply Offset To Selected Location")); wxString default_value(_T("0,0,0")); wxString value = wxGetTextFromUser(message, caption, default_value); wxStringTokenizer tokens(value,_T(":,\t\n")); for (int i=0; i<3; i++) { if (tokens.HasMoreTokens()) { double offset = 0.0; wxString token = tokens.GetNextToken(); wxString evaluated_version; if (PropertyDouble::EvaluateWithPython( NULL, token, evaluated_version )) { evaluated_version.ToDouble(&offset); offset *= wxGetApp().m_view_units; switch(i) { case 0: location.SetX( location.X() + offset ); break; case 1: location.SetY( location.Y() + offset ); break; case 2: location.SetZ( location.Z() + offset ); break; } } } } return(location); }
bool Excellon::ReadDataBlock( const std::string & data_block ) { std::string _data( data_block ); std::string::size_type offset; while ((offset = _data.find('%')) != _data.npos) _data.erase(offset,1); while ((offset = _data.find('*')) != _data.npos) _data.erase(offset,1); while ((offset = _data.find(',')) != _data.npos) _data.erase(offset,1); while ((offset = _data.find(' ')) != _data.npos) _data.erase(offset,1); while ((offset = _data.find('\t')) != _data.npos) _data.erase(offset,1); while ((offset = _data.find('\r')) != _data.npos) _data.erase(offset,1); char buffer[1024]; memset(buffer,'\0', sizeof(buffer)); strcpy( buffer, data_block.c_str() ); static gp_Pnt position(0.0,0.0,0.0); bool position_has_been_set = false; bool m02_found = false; bool swap_axis = false; bool mirror_image_x_axis = false; bool mirror_image_y_axis = false; unsigned int excellon_tool_number = 0; double tool_diameter = 0.0; while (_data.size() > 0) { if (_data.substr(0,2) == "RT") { // Reset Tool Data _data.erase(0,2); m_tool_table_map.clear(); m_active_tool_number = 0; } else if (_data.substr(0,4) == "FMAT") { // Ignore format _data.erase(0,4); char *end = NULL; unsigned long format = strtoul( _data.c_str(), &end, 10 ); _data.erase(0, end - _data.c_str()); printf("Ignoring Format %ld command\n", format ); } else if (_data.substr(0,3) == "AFS") { // Ignore format _data.erase(0,3); printf("Ignoring Automatic Feeds and Speeds\n"); } else if (_data.substr(0,3) == "CCW") { _data.erase(0,3); printf("Ignoring Counter-Clockwise routing\n"); } else if (_data.substr(0,2) == "CP") { _data.erase(0,2); printf("Ignoring Cutter Compensation\n"); } else if (_data.substr(0,6) == "DETECT") { _data.erase(0,6); printf("Ignoring Broken Tool Detection\n"); } else if (_data.substr(0,2) == "DN") { _data.erase(0,2); printf("Ignoring Down Limit Set\n"); } else if (_data.substr(0,6) == "DTMDIST") { _data.erase(0,6); printf("Ignoring Maximum Route Distance Before Tool Change\n"); } else if (_data.substr(0,4) == "EXDA") { _data.erase(0,4); printf("Ignoring Extended Drill Area\n"); } else if (_data.substr(0,3) == "FSB") { _data.erase(0,3); printf("Ignoring Feeds and Speeds Button OFF\n"); } else if (_data.substr(0,4) == "HBCK") { _data.erase(0,4); printf("Ignoring Home Button Check\n"); } else if (_data.substr(0,4) == "NCSL") { _data.erase(0,4); printf("Ignoring NC Slope Enable/Disable\n"); } else if (_data.substr(0,4) == "OM48") { _data.erase(0,4); printf("Ignoring Override Part Program Header\n"); } else if (_data.substr(0,5) == "OSTOP") { _data.erase(0,5); printf("Ignoring Optional Stop switch\n"); } else if (_data.substr(0,6) == "OTCLMP") { _data.erase(0,6); printf("Ignoring Override Table Clamp\n"); } else if (_data.substr(0,8) == "PCKPARAM") { _data.erase(0,8); printf("Ignoring Set up pecking tool,depth,infeed and retract parameters\n"); } else if (_data.substr(0,2) == "PF") { _data.erase(0,2); printf("Ignoring Floating Pressure Foot Switch\n"); } else if (_data.substr(0,3) == "PPR") { _data.erase(0,3); printf("Ignoring Programmable Plunge Rate Enable\n"); } else if (_data.substr(0,3) == "PVS") { _data.erase(0,3); printf("Ignoring Pre-vacuum Shut-off Switch\n"); } else if (_data.substr(0,3) == "RC") { _data.erase(0,3); printf("Ignoring Reset Clocks\n"); } else if (_data.substr(0,3) == "RCP") { _data.erase(0,3); printf("Ignoring Reset Program Clocks\n"); } else if (_data.substr(0,3) == "RCR") { _data.erase(0,3); printf("Ignoring Reset Run Clocks\n"); } else if (_data.substr(0,2) == "RD") { _data.erase(0,2); printf("Ignoring Reset All Cutter Distances\n"); } else if (_data.substr(0,2) == "RH") { _data.erase(0,2); printf("Ignoring Reset All Hit Counters\n"); } else if (_data.substr(0,3) == "SBK") { _data.erase(0,3); printf("Ignoring Single Block Mode Switch\n"); } else if (_data.substr(0,2) == "SG") { _data.erase(0,2); printf("Ignoring Spindle Group Mode\n"); } else if (_data.substr(0,4) == "SIXM") { _data.erase(0,4); printf("Ignoring Input From External Source\n"); } else if (_data.substr(0,2) == "UP") { _data.erase(0,2); printf("Ignoring Upper Limit Switch Set\n"); } else if (_data.substr(0,2) == "ZA") { _data.erase(0,2); printf("Ignoring Auxiliary Zero\n"); } else if (_data.substr(0,2) == "ZC") { _data.erase(0,2); printf("Ignoring Zero Correction\n"); } else if (_data.substr(0,2) == "ZS") { _data.erase(0,2); printf("Ignoring Zero Preset\n"); } else if (_data.substr(0,1) == "Z") { _data.erase(0,1); printf("Ignoring Zero Set\n"); } else if (_data.substr(0,3) == "VER") { // Ignore version _data.erase(0,3); char *end = NULL; unsigned long version = strtoul( _data.c_str(), &end, 10 ); _data.erase(0, end - _data.c_str()); printf("Ignoring Version %ld command\n", version); } else if (_data.substr(0,6) == "TCSTON") { // Tool Change Stop - ON printf("Ignoring Tool Change Stop - ON command\n"); _data.erase(0,6); } else if (_data.substr(0,7) == "TCSTOFF") { // Tool Change Stop - OFF printf("Ignoring Tool Change Stop - OFF command\n"); _data.erase(0,7); } else if (_data.substr(0,5) == "ATCON") { // Automatic Tool Change - ON printf("Ignoring Tool Change - ON command\n"); _data.erase(0,5); } else if (_data.substr(0,6) == "ATCOFF") { // Automatic Tool Change - OFF printf("Ignoring Tool Change - OFF command\n"); _data.erase(0,6); } else if (_data.substr(0,3) == "M30") { // End of program _data.erase(0,3); } else if (_data.substr(0,1) == ";") { _data.erase(0,1); return(true); // Ignore all subsequent comments until the end of line. } else if (_data.substr(0,4) == "INCH") { _data.erase(0,4); m_units = 25.4; // Imperial } else if (_data.substr(0,6) == "METRIC") { _data.erase(0,6); m_units = 1.0; // mm } else if (_data.substr(0,2) == "MM") { _data.erase(0,2); m_units = 1.0; // mm } else if (_data.substr(0,2) == "TZ") { _data.erase(0,2); // In Excellon files, the TZ means that trailing zeroes are INCLUDED // while in RS274X format, it means they're OMITTED m_trailingZeroSuppression = false; } else if (_data.substr(0,2) == "LZ") { _data.erase(0,2); // In Excellon files, the LZ means that leading zeroes are INCLUDED // while in RS274X format, it means they're OMITTED m_leadingZeroSuppression = false; } else if (_data.substr(0,1) == "T") { _data.erase(0,1); char *end = NULL; excellon_tool_number = strtoul( _data.c_str(), &end, 10 ); _data.erase(0, end - _data.c_str()); } else if (_data.substr(0,1) == "C") { _data.erase(0,1); const char *end = NULL; tool_diameter = special_strtod( _data.c_str(), &end ); _data.erase(0, end - _data.c_str()); } else if (_data.substr(0,3) == "M02") { _data.erase(0,3); m02_found = true; } else if (_data.substr(0,3) == "M00") { // End of program _data.erase(0,3); } else if ((_data.substr(0,3) == "M25") || (_data.substr(0,3) == "M31") || (_data.substr(0,3) == "M08") || (_data.substr(0,3) == "M01")) { // Beginning of pattern printf("Pattern repetition is not yet supported\n"); return(false); } else if (_data.substr(0,1) == "R") { _data.erase(0,1); printf("Pattern repetition is not yet supported\n"); return(false); /* char *end = NULL; repetitions = strtoul( _data.c_str(), &end, 10 ); _data.erase(0, end - _data.c_str()); */ } else if (_data.substr(0,3) == "M70") { _data.erase(0,3); swap_axis = true; } else if (_data.substr(0,3) == "M80") { _data.erase(0,3); mirror_image_x_axis = true; } else if (_data.substr(0,3) == "G90") { _data.erase(0,3); mirror_image_y_axis = true; } else if (_data.substr(0,1) == "N") { // Ignore block numbers _data.erase(0,1); char *end = NULL; strtoul( _data.c_str(), &end, 10 ); _data.erase( 0, end - _data.c_str() ); } else if (_data.substr(0,1) == "X") { _data.erase(0,1); // Erase X const char *end = NULL; double x = special_strtod( _data.c_str(), &end ); if ((end == NULL) || (end == _data.c_str())) { printf("Expected number following 'X'\n"); return(false); } // End if - then std::string x_string = _data.substr(0, end - _data.c_str()); _data.erase(0, end - _data.c_str()); position_has_been_set = true; if (x_string.find('.') == std::string::npos) { double x = InterpretCoord( x_string.c_str(), m_YDigitsLeftOfPoint, m_YDigitsRightOfPoint, m_leadingZeroSuppression, m_trailingZeroSuppression ); if (m_absoluteCoordinatesMode) { position.SetX( x ); } else { // Incremental position. position.SetX( position.X() + x ); } } else { // The number had a decimal point explicitly defined within it. Read it as a correctly // represented number as is. if (m_absoluteCoordinatesMode) { position.SetX( x ); } else { // Incremental position. position.SetX( position.X() + x ); } } } else if (_data.substr(0,1) == "Y") { _data.erase(0,1); // Erase Y const char *end = NULL; double y = special_strtod( _data.c_str(), &end ); if ((end == NULL) || (end == _data.c_str())) { printf("Expected number following 'Y'\n"); return(false); } // End if - then std::string y_string = _data.substr(0, end - _data.c_str()); _data.erase(0, end - _data.c_str()); position_has_been_set = true; if (y_string.find('.') == std::string::npos) { double y = InterpretCoord( y_string.c_str(), m_YDigitsLeftOfPoint, m_YDigitsRightOfPoint, m_leadingZeroSuppression, m_trailingZeroSuppression ); if (m_absoluteCoordinatesMode) { position.SetY( y ); } else { // Incremental position. position.SetY( position.Y() + y ); } } else { // The number already has a decimal point explicitly defined within it. if (m_absoluteCoordinatesMode) { position.SetY( y ); } else { // Incremental position. position.SetY( position.Y() + y ); } } } else if (_data.substr(0,3) == "G05") { _data.erase(0,3); printf("Ignoring select drill mode (G05) command\n"); } else if (_data.substr(0,3) == "G81") { _data.erase(0,3); printf("Ignoring select drill mode (G81) command\n"); } else if (_data.substr(0,3) == "G04") { _data.erase(0,3); printf("Ignoring variable dwell (G04) command\n"); } else if (_data.substr(0,3) == "G90") { _data.erase(0,3); m_absoluteCoordinatesMode = true; // It's the only mode we use anyway. } else if (_data.substr(0,6) == "ICIOFF") { _data.erase(0,6); m_absoluteCoordinatesMode = true; // It's the only mode we use anyway. } else if (_data.substr(0,3) == "G91") // Incremental coordinates mode ON { _data.erase(0,3); m_absoluteCoordinatesMode = false; } else if (_data.substr(0,5) == "ICION") // Incremental coordinates mode ON { _data.erase(0,5); m_absoluteCoordinatesMode = false; } else if (_data.substr(0,3) == "G92") { _data.erase(0,3); printf("Set zero (G92) is not yet supported\n"); return(false); } else if (_data.substr(0,3) == "G93") { _data.erase(0,3); printf("Set zero (G93) is not yet supported\n"); return(false); } else if (_data.substr(0,3) == "M48") { _data.erase(0,3); // Ignore 'Program Header to first "%"' } else if (_data.substr(0,3) == "M47") { _data.erase(0,3); // Ignore 'Operator Message CRT Display' return(true); // Ignore the rest of the line. } else if (_data.substr(0,3) == "M71") { _data.erase(0,3); m_units = 1.0; // Metric } else if (_data.substr(0,3) == "M72") { _data.erase(0,3); m_units = 25.4; // Imperial } else if (_data.substr(0,1) == "S") { _data.erase(0,1); const char *end = NULL; m_spindle_speed = special_strtod( _data.c_str(), &end ); _data.erase(0, end - _data.c_str()); } else if (_data.substr(0,1) == "F") { _data.erase(0,1); const char *end = NULL; m_feed_rate = special_strtod( _data.c_str(), &end ) * m_units; _data.erase(0, end - _data.c_str()); } else { printf("Unexpected command '%s'\n", _data.c_str() ); return(false); } // End if - else } // End while if (excellon_tool_number > 0) { // We either want to find an existing drill bit of this size or we need // to define a new one. if ((tool_diameter <= 0.0) && s_allow_dummy_tool_definitions) { // The file doesn't define the tool's diameter. Just convert the tool number into a value in thousanths // of an inch and let it through. tool_diameter = (excellon_tool_number * 0.001); } bool found = false; for (HeeksObj *tool = theApp.m_program->Tools()->GetFirstChild(); tool != NULL; tool = theApp.m_program->Tools()->GetNextChild() ) { // We're looking for a tool whose diameter is tool_diameter. CTool *pTool = (CTool *)tool; if (fabs(pTool->m_params.m_diameter - tool_diameter) < heeksCAD->GetTolerance()) { // We've found it. // Keep a map of the tool numbers found in the Excellon file to those in our tool table. m_tool_table_map.insert( std::make_pair( excellon_tool_number, pTool->m_tool_number )); m_active_tool_number = pTool->m_tool_number; // Use our internal tool number found = true; break; } // End if - then } // End for if ((! found) && (tool_diameter > 0.0)) { // We didn't find an existing tool with the right diameter. Add one now. int id = heeksCAD->GetNextID(ToolType); CTool *tool = new CTool(NULL, CToolParams::eDrill, id); heeksCAD->SetObjectID( tool, id ); tool->SetDiameter( tool_diameter * m_units ); theApp.m_program->Tools()->Add( tool, NULL ); // Keep a map of the tool numbers found in the Excellon file to those in our tool table. m_tool_table_map.insert( std::make_pair( excellon_tool_number, tool->m_tool_number )); m_active_tool_number = tool->m_tool_number; // Use our internal tool number } } // End if - then if (excellon_tool_number > 0) { // They may have selected a tool. m_active_tool_number = m_tool_table_map[excellon_tool_number]; } // End if - then if (position_has_been_set) { if (m_active_tool_number <= 0) { printf("Hole position defined without selecting a tool first\n"); return(false); } // End if - then else { // We've been given a position. See if we already have a point object // at this location. If so, use it. Otherwise add a new one. CNCPoint cnc_point( position ); if (m_mirror_image_x_axis) cnc_point.SetY( cnc_point.Y() * -1.0 ); // mirror about X axis if (m_mirror_image_y_axis) cnc_point.SetX( cnc_point.X() * -1.0 ); // mirror about Y axis if (m_existing_points.find( cnc_point ) == m_existing_points.end()) { // There are no pre-existing Point objects for this location. Add one now. double location[3]; cnc_point.ToDoubleArray( location ); HeeksObj *point = heeksCAD->NewPoint( location ); heeksCAD->Add( point, NULL ); CDrilling::Symbol_t symbol( point->GetType(), point->m_id ); m_existing_points.insert( std::make_pair( cnc_point, symbol )); } // End if - then // There is already a point here. Use it. if (m_holes.find( m_active_tool_number ) == m_holes.end()) { // We haven't used this drill bit before. Add it now. CDrilling::Symbols_t symbols; CDrilling::Symbol_t symbol( m_existing_points[ cnc_point ] ); symbols.push_back( symbol ); m_holes.insert( std::make_pair( m_active_tool_number, symbols ) ); } else { // We've already used this drill bit. Just add to its list of symbols. m_holes[ m_active_tool_number ].push_back( m_existing_points[ cnc_point ] ); } // End if - else /* printf("Drill hole using tool %d at x=%lf, y=%lf z=%lf\n", m_active_tool_number, pPosition->X(), pPosition->Y(), pPosition->Z() ); */ } // End if - else } // End if - then return(true); } // End ReadDataBlock() method