Beispiel #1
0
/* 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);
}
Beispiel #2
0
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