Example #1
0
/**
 * 	This method looks through the symbols in the list.  If they're PointType objects
 * 	then the object's location is added to the result set.  If it's a circle object
 * 	that doesn't intersect any other element (selected) then add its centre to
 * 	the result set.  Finally, find the intersections of all of these elements and
 * 	add the intersection points to the result vector.
 */
/* static */ std::vector<CNCPoint> CDrilling::FindAllLocations(
                    ObjList *parent,
                    const CNCPoint starting_location, // = CNCPoint(0.0, 0.0, 0.0)
                    const bool sort_locations, // = false
                    std::list<int> *pToolNumbersReferenced /* = NULL */ )
{
	std::vector<CNCPoint> locations;
	parent->ReloadPointers();   // Make sure our integer lists have been converted into children first.

	// Look to find all intersections between all selected objects.  At all these locations, create
	// a drilling cycle.

	std::list<HeeksObj *> lhs_children;
	std::list<HeeksObj *> rhs_children;
	for (HeeksObj *lhsPtr = parent->GetFirstChild(); lhsPtr != NULL; lhsPtr = parent->GetNextChild())
	{
	    lhs_children.push_back( lhsPtr );
	    rhs_children.push_back( lhsPtr );
	}

	for (std::list<HeeksObj *>::iterator itLhs = lhs_children.begin(); itLhs != lhs_children.end(); itLhs++)
	{
	    HeeksObj *lhsPtr = *itLhs;
		bool l_bIntersectionsFound = false;	// If it's a circle and it doesn't
							// intersect anything else, we want to know
							// about it.

		if (lhsPtr->GetType() == PointType)
		{
			double pos[3];
			lhsPtr->GetStartPoint(pos);

			// Copy the results in ONLY if each point doesn't already exist.
			if (std::find( locations.begin(), locations.end(), CNCPoint( pos ) ) == locations.end())
			{
				locations.push_back( CNCPoint( pos ) );
			} // End if - then

			continue;	// No need to intersect a point with anything.
		} // End if - then

        for (std::list<HeeksObj *>::iterator itRhs = rhs_children.begin(); itRhs != rhs_children.end(); itRhs++)
        {
            HeeksObj *rhsPtr = *itRhs;

			if (lhsPtr == rhsPtr) continue;
			if (lhsPtr->GetType() == PointType) continue;	// No need to intersect a point type.

            std::list<double> results;

            if ((lhsPtr != NULL) && (rhsPtr != NULL) && (lhsPtr->Intersects( rhsPtr, &results )))
            {
				l_bIntersectionsFound = true;
                while (((results.size() % 3) == 0) && (results.size() > 0))
                {
                    CNCPoint intersection;

                    intersection.SetX( *(results.begin()) );
                    results.erase(results.begin());

                    intersection.SetY( *(results.begin()) );
                    results.erase(results.begin());

                    intersection.SetZ( *(results.begin()) );
                    results.erase(results.begin());

					// Copy the results in ONLY if each point doesn't already exist.
					if (std::find( locations.begin(), locations.end(), intersection ) == locations.end())
					{
						locations.push_back(intersection);
					} // End if - then
				} // End while
			} // End if - then
		} // End for

		if (! l_bIntersectionsFound)
		{
			// This element didn't intersect anything else.  If it's a circle
			// then add its centre point to the result set.

			if (lhsPtr->GetType() == CircleType)
			{
				double pos[3];
				if ((lhsPtr != NULL) && (heeksCAD->GetArcCentre( lhsPtr, pos )))
				{
					// Copy the results in ONLY if each point doesn't already exist.
					if (std::find( locations.begin(), locations.end(), CNCPoint( pos ) ) == locations.end())
					{
						locations.push_back( CNCPoint( pos ) );
					} // End if - then
				} // End if - then
			} // End if - then


			if (lhsPtr->GetType() == SketchType)
			{
				CBox bounding_box;
				lhsPtr->GetBox( bounding_box );
				double pos[3];
				bounding_box.Centre(pos);
				// Copy the results in ONLY if each point doesn't already exist.
				if (std::find( locations.begin(), locations.end(), CNCPoint( pos ) ) == locations.end())
				{
					locations.push_back( CNCPoint( pos ) );
				} // End if - then
			} // End if - then

			if (lhsPtr->GetType() == ProfileType)
			{
				std::vector<CNCPoint> starting_points;
				CMachineState machine;
#ifndef STABLE_OPS_ONLY
				CFixture perfectly_aligned_fixture(NULL,CFixture::G54, false, 0.0);
				machine.Fixture(perfectly_aligned_fixture);
#endif

				// to do, make this get the starting point again
				//((CProfile *)lhsPtr)->AppendTextToProgram( starting_points, &machine );

				// Copy the results in ONLY if each point doesn't already exist.
				for (std::vector<CNCPoint>::const_iterator l_itPoint = starting_points.begin(); l_itPoint != starting_points.end(); l_itPoint++)
				{
					if (std::find( locations.begin(), locations.end(), *l_itPoint ) == locations.end())
					{
						locations.push_back( *l_itPoint );
					} // End if - then
				} // End for
			} // End if - then

            if (lhsPtr->GetType() == DrillingType)
            {
                // Ask the Drilling object what reference points it uses.
                if ((((COp *) lhsPtr)->m_tool_number > 0) && (pToolNumbersReferenced != NULL))
                {
                    pToolNumbersReferenced->push_back( ((COp *) lhsPtr)->m_tool_number );
                } // End if - then

                std::vector<CNCPoint> holes = CDrilling::FindAllLocations((CDrilling *)lhsPtr, starting_location, false, pToolNumbersReferenced);
                for (std::vector<CNCPoint>::const_iterator l_itHole = holes.begin(); l_itHole != holes.end(); l_itHole++)
                {
                    if (std::find( locations.begin(), locations.end(), *l_itHole ) == locations.end())
                    {
                        locations.push_back( *l_itHole );
                    } // End if - then
                } // End for
            } // End if - then

#ifndef STABLE_OPS_ONLY
            if (lhsPtr->GetType() == CounterBoreType)
            {
                std::vector<CNCPoint> holes = CDrilling::FindAllLocations((CCounterBore *)lhsPtr, starting_location, false, NULL);
                for (std::vector<CNCPoint>::const_iterator l_itHole = holes.begin(); l_itHole != holes.end(); l_itHole++)
                {
                    if (std::find( locations.begin(), locations.end(), *l_itHole ) == locations.end())
                    {
                        locations.push_back( *l_itHole );
                    } // End if - then
                } // End for
            } // End if - then
#endif

		} // End if - then
	} // End for

	if (sort_locations)
	{
		// This drilling cycle has the 'sort' option turned on.
		//
		// If the sorting option is turned off then the points need to be returned in order of the m_symbols list.  One day,
		// we will allow the operator to re-order the m_symbols list by using a drag-n-drop operation on the sub-elements
		// in the menu.  When this is done, the operator's decision as to order should be respected.  Until then, we can
		// use the 'sort' option in the drilling cycle's parameters.

		for (std::vector<CNCPoint>::iterator l_itPoint = locations.begin(); l_itPoint != locations.end(); l_itPoint++)
		{
			if (l_itPoint == locations.begin())
			{
				// It's the first point.
				CNCPoint reference_location(0.0, 0.0, 0.0);
                reference_location = starting_location;

				sort_points_by_distance compare( reference_location );
				std::sort( locations.begin(), locations.end(), compare );
			} // End if - then
			else
			{
				// We've already begun.  Just sort based on the previous point's location.
				std::vector<CNCPoint>::iterator l_itNextPoint = l_itPoint;
				l_itNextPoint++;

				if (l_itNextPoint != locations.end())
				{
					sort_points_by_distance compare( *l_itPoint );
					std::sort( l_itNextPoint, locations.end(), compare );
				} // End if - then
			} // End if - else
		} // End for
	} // End if - then

	return(locations);
} // End FindAllLocations() method
Example #2
0
/**
	This method adjusts any parameters that don't make sense.  It should report a list
	of changes in the list of strings.
 */
std::list<wxString> CDrilling::DesignRulesAdjustment(const bool apply_changes)
{
	std::list<wxString> changes;

	// Make some special checks if we're using a chamfering bit.
	if (m_tool_number > 0)
	{
		CTool *pChamfer = (CTool *) CTool::Find( m_tool_number );
		if (pChamfer != NULL)
		{
			std::vector<CNCPoint> these_locations = CDrilling::FindAllLocations(this);

			if (pChamfer->m_params.m_type == CToolParams::eChamfer)
			{
				// We need to make sure that the diameter of the hole (that will
				// have been drilled in a previous drilling operation) is between
				// the chamfering bit's flat_radius (smallest) and diamter/2 (largest).

				// First find ALL drilling cycles that created this hole.  Make sure
				// to get them all as we may have used a centre drill before the
				// main hole is drilled.

				for (HeeksObj *obj = theApp.m_program->Operations()->GetFirstChild();
					obj != NULL;
					obj = theApp.m_program->Operations()->GetNextChild())
				{
					if (obj->GetType() == DrillingType)
					{
						// Make sure we're looking at a hole drilled with something
						// more than a centre drill.
						CToolParams::eToolType type = CTool::CutterType( ((COp *)obj)->m_tool_number );
						if (	(type == CToolParams::eDrill) ||
							(type == CToolParams::eEndmill) ||
							(type == CToolParams::eSlotCutter) ||
							(type == CToolParams::eBallEndMill))
						{
							// See if any of the other drilling locations line up
							// with our drilling locations.  If so, we must be
							// chamfering a previously drilled hole.

							std::vector<CNCPoint> previous_locations = CDrilling::FindAllLocations((CDrilling *)obj);
							std::vector<CNCPoint> common_locations;
							std::set_intersection( previous_locations.begin(), previous_locations.end(),
										these_locations.begin(), these_locations.end(),
										std::inserter( common_locations, common_locations.begin() ));
							if (common_locations.size() > 0)
							{
								// We're here.  We must be chamfering a hole we've
								// drilled previously.  Check the diameters.

								CTool *pPreviousTool = CTool::Find( ((COp *)obj)->m_tool_number );
								if (pPreviousTool->CuttingRadius() < pChamfer->m_params.m_flat_radius)
								{
#ifdef UNICODE
									std::wostringstream l_ossChange;
#else
									std::ostringstream l_ossChange;
#endif
									l_ossChange << _("Chamfering bit for drilling op") << " (id=" << m_id << ") " << _("is too big for previously drilled hole") << " (drilling id=" << obj->m_id << ")\n";
									changes.push_back( l_ossChange.str().c_str() );
								} // End if - then

								if (pPreviousTool->CuttingRadius() > (pChamfer->m_params.m_diameter/2.0))
								{
#ifdef UNICODE
									std::wostringstream l_ossChange;
#else
									std::ostringstream l_ossChange;
#endif
									l_ossChange << _("Chamfering bit for drilling op") << " (id=" << m_id << ") " << _("is too small for previously drilled hole") << " (drilling id=" << obj->m_id << ")\n";
									changes.push_back( l_ossChange.str().c_str() );
								} // End if - then
							} // End if - then

						} // End if - then
					} // End if - then
				} // End for
			} // End if - then
		} // End if - then
	} // End if - then

	if (m_tool_number > 0)
	{
		// Make sure the hole depth isn't greater than the tool's cutting depth.
		CTool *pDrill = (CTool *) CTool::Find( m_tool_number );
		if ((pDrill != NULL) && (pDrill->m_params.m_cutting_edge_height < m_params.m_depth))
		{
			// The drill bit we've chosen can't cut as deep as we've setup to go.

			if (apply_changes)
			{
#ifdef UNICODE
				std::wostringstream l_ossChange;
#else
				std::ostringstream l_ossChange;
#endif

				l_ossChange << _("Adjusting depth of drill cycle") << " id='" << m_id << "' " << _("from") << " '"
					<< m_params.m_depth / theApp.m_program->m_units << "' " << _("to") << " "
					<< pDrill->m_params.m_cutting_edge_height / theApp.m_program->m_units << "\n";
				changes.push_back(l_ossChange.str().c_str());

				m_params.m_depth = pDrill->m_params.m_cutting_edge_height;
			} // End if - then
			else
			{
#ifdef UNICODE
				std::wostringstream l_ossChange;
#else
				std::ostringstream l_ossChange;
#endif

				l_ossChange << _("WARNING") << ": " << _("Drilling") << " (id=" << m_id << ").  " << _("Can't drill hole") << " " << m_params.m_depth / theApp.m_program->m_units << " when the drill bit's cutting length is only " << pDrill->m_params.m_cutting_edge_height << " long\n";
				changes.push_back(l_ossChange.str().c_str());
			} // End if - else
		} // End if - then
	} // End if - then

	// See if there is anything in the reference objects that may be in conflict with this object's current configuration.
	for (Symbols_t::const_iterator l_itSymbol = m_symbols.begin(); l_itSymbol != m_symbols.end(); l_itSymbol++)
	{
		switch (l_itSymbol->first)
		{
			case ProfileType:
				{
					CProfile *pProfile = (CProfile *) heeksCAD->GetIDObject( l_itSymbol->first, l_itSymbol->second );
					if (pProfile != NULL)
					{
                        double depthOp_depth = ((CDepthOp *) pProfile)->m_depth_op_params.m_start_depth  - ((CDepthOp *) pProfile)->m_depth_op_params.m_final_depth;
                        if (depthOp_depth != m_params.m_depth)
                        {
    #ifdef UNICODE
                    std::wostringstream l_ossChange;
    #else
                    std::ostringstream l_ossChange;
    #endif

                            l_ossChange << _("Adjusting depth of drill cycle") << " (id='" << m_id << "') " << _("from") << " '"
                                << m_params.m_depth / theApp.m_program->m_units << "' " << _("to") << " '"
                                << depthOp_depth  / theApp.m_program->m_units<< "'\n";
                            changes.push_back(l_ossChange.str().c_str());

                            if (apply_changes)
                            {
                                m_params.m_depth = depthOp_depth;
                            } // End if - then
                        } // End if - then
					}
				}
				break;

			default:
				break;
		} // End switch
	} // End for

	// see wether combination of retract_mode, spindle_mode and peck_depth is valid:
	// move to design rule check
	if ((m_params.m_retract_mode == 1) || (m_params.m_spindle_mode == 1))
	{
		// if we feed retract, or stop the spindle at the bottom, this is a boring cycle.
		// cant have peck_depth > 0 then
		if (m_params.m_peck_depth > 0)
		{
#ifdef UNICODE
			std::wostringstream l_ossChange;
#else
			std::ostringstream l_ossChange;
#endif

			l_ossChange << _("WARNING") << ": " << _("cant have boring cycle with pecking > 0") << " (id=" << m_id << ")\n";
			changes.push_back(l_ossChange.str().c_str());

		}
	}



	return(changes);

} // End DesignRulesAdjustment() method
Example #3
0
void CProfileParams::GetProperties(CProfile* parent, std::list<Property *> *list)
{
	CToolParams::eToolType tool_type = CTool::FindToolType(parent->m_tool_number);

	if(CTool::IsMillingToolType(tool_type)){
		std::list< wxString > choices;

		SketchOrderType order = SketchOrderTypeUnknown;

		if(parent->GetNumSketches() == 1)
		{
#ifdef OP_SKETCHES_AS_CHILDREN
			HeeksObj* sketch = parent->GetFirstChild();
#else
			HeeksObj* sketch = heeksCAD->GetIDObject(SketchType, parent->m_sketches.front());
#endif
			if((sketch) && (sketch->GetType() == SketchType))
			{
				order = heeksCAD->GetSketchOrder(sketch);
			}
		}

		switch(order)
		{
		case SketchOrderTypeOpen:
			choices.push_back(_("Left"));
			choices.push_back(_("Right"));
			break;

		case SketchOrderTypeCloseCW:
		case SketchOrderTypeCloseCCW:
			choices.push_back(_("Outside"));
			choices.push_back(_("Inside"));
			break;

		default:
			choices.push_back(_("Outside or Left"));
			choices.push_back(_("Inside or Right"));
			break;
		}
		choices.push_back(_("On"));

		int choice = int(eOn);
		switch (m_tool_on_side)
		{
			case eRightOrInside:	choice = 1;
					break;

			case eOn:	choice = 2;
					break;

			case eLeftOrOutside:	choice = 0;
					break;
		} // End switch

		list->push_back(new PropertyChoice(_("tool on side"), choices, choice, parent, on_set_tool_on_side));
	}

	if(CTool::IsMillingToolType(tool_type)){
		std::list< wxString > choices;
		choices.push_back(_("Conventional"));
		choices.push_back(_("Climb"));
		list->push_back(new PropertyChoice(_("cut mode"), choices, m_cut_mode, parent, on_set_cut_mode));
	}

	if(parent->GetNumSketches() == 1) // multiple sketches must use auto roll on, and can not have start and end points specified
	{
		list->push_back(new PropertyCheck(_("auto roll on"), m_auto_roll_on, parent, on_set_auto_roll_on));
		if(!m_auto_roll_on)list->push_back(new PropertyVertex(_("roll on point"), m_roll_on_point, parent, on_set_roll_on_point));
		list->push_back(new PropertyCheck(_("auto roll off"), m_auto_roll_off, parent, on_set_auto_roll_off));
		if(!m_auto_roll_off)list->push_back(new PropertyVertex(_("roll off point"), m_roll_off_point, parent, on_set_roll_off_point));
		if(m_auto_roll_on || m_auto_roll_off)list->push_back(new PropertyLength(_("roll radius"), m_auto_roll_radius, parent, on_set_roll_radius));
		list->push_back(new PropertyCheck(_("use start point"), m_start_given, parent, on_set_start_given));
		if(m_start_given)list->push_back(new PropertyVertex(_("start point"), m_start, parent, on_set_start));
		list->push_back(new PropertyCheck(_("use end point"), m_end_given, parent, on_set_end_given));
		if(m_end_given)
		{
			list->push_back(new PropertyVertex(_("end point"), m_end, parent, on_set_end));
			list->push_back(new PropertyCheck(_("end beyond full profile"), m_end_beyond_full_profile, parent, on_set_end_beyond_full_profile));
		}
	}
	else
	{
		std::list< wxString > choices;

		choices.push_back(_("Respect existing order"));	// Must be 'false' (0)
		choices.push_back(_("True"));			// Must be 'true' (non-zero)

		int choice = int(m_sort_sketches);
		list->push_back(new PropertyChoice(_("sort_sketches"), choices, choice, parent, on_set_sort_sketches));

		// roll on radius
		list->push_back(new PropertyLength(_("roll radius"), m_auto_roll_radius, parent, on_set_roll_radius));
	} // End if - else
    
    list->push_back(new PropertyLength(_("extend before start"), m_extend_at_start, parent, on_set_extend_at_start));
    list->push_back(new PropertyLength(_("extend past end"), m_extend_at_end, parent, on_set_extend_at_end));

    //lead in lead out line length
    list->push_back(new PropertyLength(_("lead in line length"), m_lead_in_line_len, parent, on_set_lead_in_line_len));
    list->push_back(new PropertyLength(_("lead out line length"), m_lead_out_line_len, parent, on_set_lead_out_line_len));

	list->push_back(new PropertyLength(_("offset_extra"), m_offset_extra, parent, on_set_offset_extra));
	if(CTool::IsMillingToolType(tool_type))
	{
		list->push_back(new PropertyCheck(_("do finishing pass"), m_do_finishing_pass, parent, on_set_do_finishing_pass));
		if(m_do_finishing_pass)
		{
			list->push_back(new PropertyCheck(_("only finishing pass"), m_only_finishing_pass, parent, on_set_only_finishing_pass));
			list->push_back(new PropertyLength(_("finishing feed rate"), m_finishing_h_feed_rate, parent, on_set_finishing_h_feed_rate));

			{
				std::list< wxString > choices;
				choices.push_back(_("Conventional"));
				choices.push_back(_("Climb"));
				list->push_back(new PropertyChoice(_("finish cut mode"), choices, m_finishing_cut_mode, parent, on_set_finish_cut_mode));
			}
			list->push_back(new PropertyLength(_("finishing step down"), m_finishing_step_down, parent, on_set_finish_step_down));
		}
	}
}
Example #4
0
void SaveSolids::Run(){
	std::list<HeeksObj*> objects;

	for(std::list<HeeksObj*>::const_iterator It = wxGetApp().m_marked_list->list().begin(); It != wxGetApp().m_marked_list->list().end(); It++){
		HeeksObj* object = *It;
		switch(object->GetType())
		{
		case SolidType:
		case StlSolidType:
		case FaceType:
		{
				objects.push_back(object);
			}
			break;
		}
	}

	if(objects.size() > 0)
	{
		wxString filepath(_T(""));
		{
			// get last used filepath
			HeeksConfig config;
			config.Read(_T("SolidExportFilepath"), &filepath, _T(""));
		}

		wxFileDialog fd(wxGetApp().m_frame, _("Save solid file"), wxEmptyString, filepath, wxString(_("Solid Files")) + _T(" |*.igs;*.iges;*.stp;*.step;*.stl;*.cpp;*.py;*.obj|") + _("IGES files") + _T(" (*.igs *.iges)|*.igs;*.iges|") + _("STEP files") + _T(" (*.stp *.step)|*.stp;*.step|") + _("STL files") + _T(" (*.stl)|*.stl|") + _("CPP files") + _T(" (*.cpp)|*.cpp|") + _("OpenCAMLib python files") + _T(" (*.py)|*.py|") + _("Wavefront .obj files") + _T(" (*.obj)|*.obj"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
		fd.SetFilterIndex(0);

		if (fd.ShowModal() == wxID_CANCEL)return;
		filepath = fd.GetPath();

		wxString wf(filepath);
		wf.LowerCase();

		if(wf.EndsWith(_T(".stl")))
		{
			wxGetApp().SaveSTLFile(objects, filepath, -1.0, NULL, wxGetApp().m_stl_save_as_binary);
		}
		else if(wf.EndsWith(_T(".cpp")))
		{
			wxGetApp().SaveCPPFile(objects, filepath);
		}
		else if (wf.EndsWith(_T(".py")))
		{
			wxGetApp().SavePyFile(objects, filepath);
		}
		else if (wf.EndsWith(_T(".obj")))
		{
			wxGetApp().SaveOBJFileAscii(objects, filepath);
		}
		else if (CShape::ExportSolidsFile(objects, filepath))
		{
		}
		else
		{
			wxMessageBox(_("Invalid solid file type chosen"));
			return;
		}

		{
			// save last used filepath
			HeeksConfig config;
			config.Write(_T("SolidExportFilepath"), filepath);
		}
	}
}
Example #5
0
void CSketch::CalculateSketchOrder()
{
	if(m_objects.size() == 0)
	{
		m_order = SketchOrderTypeEmpty;
		return;
	}

	HeeksObj* prev_object = NULL;
	HeeksObj* first_object = NULL;

	bool well_ordered = true;

	std::list<HeeksObj*>::iterator It;
	for(It=m_objects.begin(); It!=m_objects.end() ;It++)
	{
		HeeksObj* object = *It;

		if(object->GetType() == CircleType)
		{
			m_order = SketchOrderHasCircles;
			return;
		}

		if(prev_object)
		{
			double prev_e[3], s[3];
			if(!prev_object->GetEndPoint(prev_e)){well_ordered = false; break;}
			if(!object->GetStartPoint(s)){well_ordered = false; break;}
			if(!(make_point(prev_e).IsEqual(make_point(s), wxGetApp().m_geom_tol))){well_ordered = false; break;}
		}

		if(first_object == NULL)first_object = object;
		prev_object = object;
	}

	if(well_ordered)
	{
		if(prev_object && first_object)
		{
			double e[3], s[3];
			if(prev_object->GetEndPoint(e))
			{
				if(first_object->GetStartPoint(s))
				{
					if(make_point(e).IsEqual(make_point(s), wxGetApp().m_geom_tol))
					{
						// closed
						if(IsClockwise())m_order = SketchOrderTypeCloseCW;
						else m_order = SketchOrderTypeCloseCCW;
						return;
					}
				}
			}
		}

		m_order = SketchOrderTypeOpen;
		return;
	}

	m_order = SketchOrderTypeBad; // although it might still be multiple, but will have to wait until ReOrderSketch is done.
}
Example #6
0
//static
void TransformTools::Mirror(bool copy)
{
	// pick items
	if(wxGetApp().m_marked_list->size() == 0){
		wxGetApp().PickObjects(_("Pick objects to mirror"));
	}
	if(wxGetApp().m_marked_list->size() == 0)return;

	if(copy)
	{
		// check for uncopyable objects
		RemoveUncopyable();
		if(wxGetApp().m_marked_list->size() == 0)return;
	}

	// clear the selection
	std::list<HeeksObj *> selected_items = wxGetApp().m_marked_list->list();
	wxGetApp().m_marked_list->Clear(true);

	// pick a line to mirror about
	bool line_found = false;
	gp_Lin line;
	int save_filter = wxGetApp().m_marked_list->m_filter;
	wxGetApp().PickObjects(_("Pick line to mirror about"), MARKING_FILTER_LINE | MARKING_FILTER_ILINE, true);
	wxGetApp().m_marked_list->m_filter = save_filter;
	for(std::list<HeeksObj *>::const_iterator It = wxGetApp().m_marked_list->list().begin(); It != wxGetApp().m_marked_list->list().end(); It++)
	{
		HeeksObj* object = *It;
		if(object->GetType() == LineType)
		{
			line = ((HLine*)object)->GetLine();
			line_found = true;
		}
		else if(object->GetType() == ILineType)
		{
			line = ((HILine*)object)->GetLine();
			line_found = true;
		}
	}
	if(!line_found)return;

	// transform the objects
	wxGetApp().CreateUndoPoint();
	gp_Trsf mat;
	mat.SetMirror(gp_Ax1(line.Location(), line.Direction()));
	double m[16];
	extract(mat, m);

	if(copy)
	{
		for(std::list<HeeksObj*>::iterator It = selected_items.begin(); It != selected_items.end(); It++)
		{
			HeeksObj* object = *It;
			HeeksObj* new_object = object->MakeACopy();
#ifdef MULTIPLE_OWNERS
			object->HEEKSOBJ_OWNER->Add(new_object, NULL);
#else
			object->m_owner->Add(new_object, NULL);
#endif
			new_object->ModifyByMatrix(m);
		}
		wxGetApp().m_marked_list->Clear(true);
	}
	else
	{
		wxGetApp().Transform(selected_items, m);
	}
	wxGetApp().Changed();
}
Example #7
0
/**
	This method adjusts any parameters that don't make sense.  It should report a list
	of changes in the list of strings.
 */
std::list<wxString> CChamfer::DesignRulesAdjustment(const bool apply_changes)
{
	std::list<wxString> changes;

	// Make some special checks if we're using a chamfering bit.
	if (m_tool_number > 0)
	{
		CTool *pChamfer = (CTool *) CTool::Find( m_tool_number );
		if (pChamfer != NULL)
		{
			std::vector<CNCPoint> these_locations = CDrilling::FindAllLocations(this);

			if (pChamfer->m_params.m_type == CToolParams::eChamfer)
			{
				// We need to make sure that the diameter of the hole (that will
				// have been drilled in a previous drilling operation) is between
				// the chamfering bit's flat_radius (smallest) and diamter/2 (largest).

				// First find ALL drilling cycles that created this hole.  Make sure
				// to get them all as we may have used a centre drill before the
				// main hole is drilled.

				for (HeeksObj *obj = theApp.m_program->Operations()->GetFirstChild();
					obj != NULL;
					obj = theApp.m_program->Operations()->GetNextChild())
				{
					if (obj->GetType() == DrillingType)
					{
						// Make sure we're looking at a hole drilled with something
						// more than a centre drill.
						CToolParams::eToolType type = CTool::CutterType( ((COp *)obj)->m_tool_number );
						if (	(type == CToolParams::eDrill) ||
							(type == CToolParams::eEndmill) ||
							(type == CToolParams::eSlotCutter) ||
							(type == CToolParams::eBallEndMill))
						{
							// See if any of the other drilling locations line up
							// with our drilling locations.  If so, we must be
							// chamfering a previously drilled hole.

							std::vector<CNCPoint> previous_locations = CDrilling::FindAllLocations((CDrilling *)obj);
							std::vector<CNCPoint> common_locations;
							std::set_intersection( previous_locations.begin(), previous_locations.end(),
										these_locations.begin(), these_locations.end(),
										std::inserter( common_locations, common_locations.begin() ));
							if (common_locations.size() > 0)
							{
								// We're here.  We must be chamfering a hole we've
								// drilled previously.  Check the diameters.

								CTool *pPreviousTool = CTool::Find( ((COp *)obj)->m_tool_number );
								if (pPreviousTool->CuttingRadius() < pChamfer->m_params.m_flat_radius)
								{
									wxString change;
									change << DesignRulesPreamble() << _("Chamfering bit for drilling op") << _(" (id=") << m_id << _T(") ") << _("is too big for previously drilled hole") ;
									changes.push_back( change );
								} // End if - then

								if (pPreviousTool->CuttingRadius() > (pChamfer->m_params.m_diameter/2.0))
								{
									wxString change;
									change << DesignRulesPreamble() << _("Chamfering bit for drilling op") << _(" (id=") << m_id << _T(") ") << _("is too small for previously drilled hole");
									changes.push_back( change );
								} // End if - then
							} // End if - then

						} // End if - then
					} // End if - then
				} // End for
			} // End if - then
			else
			{
				wxString change;
				change << DesignRulesPreamble() << _("found with ") << pChamfer->m_params.m_type;
				changes.push_back(change);
			}
		} // End if - then
	} // End if - then

	std::list<wxString> extra_changes = CDepthOp::DesignRulesAdjustment(apply_changes);
	std::copy( extra_changes.begin(), extra_changes.end(), std::inserter( changes, changes.end() ));

	return(changes);

} // End DesignRulesAdjustment() method
Example #8
0
static void SimplifySketch(const double deviation, bool make_bspline )
{

    wxGetApp().CreateUndoPoint();

    double original_tolerance = wxGetApp().m_geom_tol;
    wxGetApp().m_geom_tol = sketch_tool_options.m_cleanup_tolerance;

    std::list<HeeksObj *> selected_sketches;
    std::copy( wxGetApp().m_marked_list->list().begin(), wxGetApp().m_marked_list->list().end(),
                std::inserter( selected_sketches, selected_sketches.begin() ));

	std::list<HeeksObj*>::const_iterator It;
	for(It = selected_sketches.begin(); It != selected_sketches.end(); It++){
		HeeksObj* object = *It;
		std::list<HeeksObj *> new_objects;

		if (object->GetType() == SketchType)
		{
			std::list<TopoDS_Shape> wires;
			try {
				heekscad_interface.ConvertSketchToFaceOrWire(object, wires, false);
			} // End try
			catch(...)
			{
				continue;
			}
			for (std::list<TopoDS_Shape>::iterator itWire = wires.begin(); itWire != wires.end(); itWire++)
			{
				std::list<SimplifySketchTool::SortPoint> points = SimplifySketchTool::GetPoints( TopoDS::Wire(*itWire), deviation );

				if (sketch_tool_options.m_sort_points)
				{
					// The sort points option is turned on.  The idea of this is to detect shapes that include
					// sections that 'double back' on themselves.  The first example being a shape made up of
					// a box as well as a single line that layed along one edge of the box.  In this case the extra
					// line was superfluous.  If we sort the points so that each point is closest to the previous
					// point then, hopefully, we will reorder these shapes that double back on themselves.  If this
					// doesn't work then the user can always turn the 'sort points' option off and try again.

					std::vector<SimplifySketchTool::SortPoint> sorted_points;
					std::copy( points.begin(), points.end(), std::inserter( sorted_points, sorted_points.begin() ));

					for (std::vector<SimplifySketchTool::SortPoint>::iterator l_itPoint = sorted_points.begin(); l_itPoint != sorted_points.end(); l_itPoint++)
					{
						// We've already begun.  Just sort based on the previous point's location.
						std::vector<SimplifySketchTool::SortPoint>::iterator l_itNextPoint = l_itPoint;
						l_itNextPoint++;

						if (l_itNextPoint != sorted_points.end())
						{
							SimplifySketchTool::sort_points_by_distance compare( *l_itPoint );
							std::sort( l_itNextPoint, sorted_points.end(), compare );
						} // End if - then
					} // End for

					points.clear();
					std::copy( sorted_points.begin(), sorted_points.end(), std::inserter( points, points.begin() ));

					// This sorting process will have resulted in the start and end points being located next to each other
					// and hence removed.  If the original wire was periodic (closed shape) then make sure the last point
					// is the same as the first point.

					TopoDS_Wire wire(TopoDS::Wire(*itWire));
					if (wire.Closed())
					{
						if (*(points.begin()) != *(points.rbegin()))
						{
							points.push_back(*points.begin());	// Close the shape manually.
						}
					}
				}

				// Whether we sorted or not, we may want to close the shape.
				if (sketch_tool_options.m_force_closed_shape)
				{
					if (*(points.begin()) != *(points.rbegin()))
					{
						points.push_back(*points.begin());	// Close the shape manually.
					}
				}

				// Now keep removing points from this list as long as the midpoints are within deviation of
				// the line between the two neighbour points.
				bool points_removed = false;
				do {
					points_removed = false;

					for (std::list<SimplifySketchTool::SortPoint>::iterator itPoint = points.begin(); itPoint != points.end(); itPoint++ )
					{
						std::list<SimplifySketchTool::SortPoint>::iterator itP1 = itPoint;
						std::list<SimplifySketchTool::SortPoint>::iterator itP2 = itPoint;
						std::list<SimplifySketchTool::SortPoint>::iterator itP3 = itPoint;

						itP2++;
						if (itP2 != points.end())
						{
							itP3 = itP2;
							itP3++;

							if (itP3 != points.end())
							{
								// First see if p1 and p2 are too close to each other.
								if (itP1->Distance(*itP2) < deviation)
								{
									// Discard p2.
									points.erase(itP2);
									points_removed = true;
									continue;
								}

								if (itP2->Distance(*itP3) < deviation)
								{
									// Discard p2
									points.erase(itP2);
									points_removed = true;
									continue;
								}

                                if (itP1->Distance(*itP3) > deviation)
                                {
                                    // Now draw a line between p1 and p3.  Measure the distance between p2 and the nearest point
                                    // along that line.  If this distance is less than the max deviation then discard p2.
                                    gp_Lin line(*itP1, gp_Dir(itP3->X() - itP1->X(), itP3->Y() - itP1->Y(), itP3->Z() - itP1->Z()));
                                    if (line.SquareDistance(*itP2) < deviation)
                                    {
                                        // Discard p2
                                        points.erase(itP2);
                                        points_removed = true;
                                        continue;
                                    }
                                }
							}
						}
					} // End for
				} while (points_removed == true);

				if (points.size() >= 2)
				{
					


				    if (make_bspline)
				    {
				        try {
                            TColgp_Array1OfPnt Points(0, points.size()-1);
                            Standard_Integer i=0;
                            for (std::list<SimplifySketchTool::SortPoint>::iterator itPoint = points.begin(); itPoint != points.end(); itPoint++, i++)
                            {
                                Points.SetValue(i, *itPoint);
                            }

                            // GeomAPI_PointsToBSpline bspline(Points);

                            GeomAPI_PointsToBSpline bspline(Points,
                                                            sketch_tool_options.m_degree_min,
                                                            sketch_tool_options.m_degree_max,
                                                            GeomAbs_Shape(sketch_tool_options.m_continuity),
                                                            sketch_tool_options.m_cleanup_tolerance);

                            // Standard_EXPORT GeomAPI_PointsToBSpline(const TColgp_Array1OfPnt& Points,const Standard_Integer DegMin = 3,const Standard_Integer DegMax = 8,const GeomAbs_Shape Continuity = GeomAbs_C2,const Standard_Real Tol3D = 1.0e-3);

                            HSpline *hspline = new HSpline(bspline.Curve(), &(wxGetApp().current_color));
                            heekscad_interface.Add( hspline, NULL );
				        }
				        catch (Standard_Failure) {
                            Handle_Standard_Failure e = Standard_Failure::Caught();
                            wxMessageBox(_("Failed to create BSpline curve"));
                        }
				    } // End if - then
				    else
				    {
				        // We're making straight lines

                        HeeksObj *sketch = heekscad_interface.NewSketch();
                        for (std::list<SimplifySketchTool::SortPoint>::iterator itPoint = points.begin(); itPoint != points.end(); itPoint++)
                        {
                            std::list<SimplifySketchTool::SortPoint>::iterator itNext = itPoint;
                            itNext++;
                            if (itNext == points.end()) continue;

                            double start[3], end[3];
                            itPoint->ToDoubleArray(start);
                            itNext->ToDoubleArray(end);

                            sketch->Add(heekscad_interface.NewLine(start, end), NULL);
                        } // End for

                        // heekscad_interface.Add(sketch, NULL);
                        new_objects.push_back(sketch);
				    } // End if - else
				} // End if - then
			} // End for

            if (new_objects.size() > 0)
            {
#ifdef MULTIPLE_OWNERS
                std::list<HeeksObj *> parents = object->Owners();
                for (std::list<HeeksObj *>::iterator itOwner = parents.begin(); itOwner != parents.end(); itOwner++)
                {
#else
				if(object->m_owner)
				{
#endif
                    if ((object->CanEditString()) && (object->GetShortString()))
                    {
                        // (*itOwner)->Remove(object);

                        // Mark the old sketches with a name that can be easily recognised so that we can delete the
                        // old objects if we're satisfied with the replacements.
                        wxString title;
                        title << _("Replaced ") << object->GetShortString();
                        object->OnEditString(title);
                    } // End if - then

                    for (std::list<HeeksObj *>::iterator itNewChild = new_objects.begin(); itNewChild != new_objects.end(); itNewChild++)
                    {
#ifdef MULTIPLE_OWNERS
                        (*itOwner)->Add( *itNewChild, NULL );
#else
                        object->m_owner->Add( *itNewChild, NULL );
#endif
                    } // End for
                } // End for
            } // End if - then
		} // End if - then
	} // End for

    wxGetApp().m_geom_tol = original_tolerance;
    wxGetApp().Changed();
}

void SimplifySketchTool::Run()
{
    SimplifySketch(m_deviation, false);
} // End Run() method
Example #9
0
Python CChamfer::AppendTextToProgram(CMachineState *pMachineState)
{
	Python python;

	// Look at the child operations objects and generate a toolpath as appropriate.
	python << CDepthOp::AppendTextToProgram( pMachineState );

	// Whatever underlying sharp edges we're going to cleanup, we need to know how deep
	// we need to plunge the chamfering bit into the work before we can get the chamfering
	// width required.
	// NOTE: At this stage, we won't allow multiple passes to produce an overly wide
	// chamfer.  i.e. if the chamfering width is longer than the chamfering bit's cutting
	// edge length then we're out of business.

	CTool *pChamferingBit = CTool::Find( m_tool_number );
	if (pChamferingBit == NULL)
	{
		// No socks, no shirt, no service.
		return(python);
	} // End if - then

	if (pChamferingBit->m_params.m_type != CToolParams::eChamfer)
	{
		// We need to make the various radius and angle calculations based on the
		// assumption that it's a chamfering bit.  If not, we can't handle the
		// mathematics (at least I can't).

		wxMessageBox(_T("Only chamfering bits are supported for chamfer operations"));
		return(python);
	}

	if (m_params.m_chamfer_width > pChamferingBit->m_params.m_cutting_edge_height)
	{
		// We don't support multiple passes to chamfer the edge (yet).  Just don't try.
		wxString text;
		text << _("Chamfer width ") << m_params.m_chamfer_width / theApp.m_program->m_units
			<< _(" is too large for a single pass of the chamfering bit's edge (")
			<< pChamferingBit->m_params.m_cutting_edge_height / theApp.m_program->m_units
			<< _(")");
		wxMessageBox(text);
		return(python);
	}

	// How deep do we have to plunge in order to cut this width of chamfer?
	double theta = pChamferingBit->m_params.m_cutting_edge_angle / 360.0 * 2.0 * PI;	// in radians.




	for (HeeksObj *child = GetFirstChild(); child != NULL; child = GetNextChild())
	{
		switch (child->GetType())
		{
        case DrillingType:
		case CounterBoreType:
			python << AppendTextForCircularChildren(pMachineState, theta, child, pChamferingBit);
			break;

		case ProfileType:
		case ContourType:
		case PocketType:
		case SketchType:
			python << AppendTextForProfileChildren(pMachineState, theta, child, pChamferingBit);
			break;

		default:
			break;
		} // End switch
	} // End for

	return(python);
}
Example #10
0
void CChamferParams::GetProperties(CChamfer * parent, std::list<Property *> *list)
{
	list->push_back(new PropertyLength(_("Chamfer Width"), m_chamfer_width, parent, on_set_chamfer_width));

	{
        std::list< wxString > choices;

        SketchOrderType order = SketchOrderTypeUnknown;

        if(parent->GetNumChildren() > 0)
        {
            HeeksObj* sketch = NULL;

            for (HeeksObj *object = parent->GetFirstChild(); ((sketch == NULL) && (object != NULL)); object = parent->GetNextChild())
            {
                if (object->GetType() == SketchType)
                {
                    sketch = object;
                }
            }

            if(sketch != NULL)
            {
                order = heeksCAD->GetSketchOrder(sketch);
                switch(order)
                {
                case SketchOrderTypeOpen:
                    choices.push_back(_("Left"));
                    choices.push_back(_("Right"));
                    break;

                case SketchOrderTypeCloseCW:
                case SketchOrderTypeCloseCCW:
                    choices.push_back(_("Outside"));
                    choices.push_back(_("Inside"));
                    break;

                default:
                    choices.push_back(_("Outside or Left"));
                    choices.push_back(_("Inside or Right"));
                    break;
                }

				choices.push_back(_("On"));

				int choice = int(CChamferParams::eOn);
				switch (parent->m_params.m_tool_on_side)
				{
					case CChamferParams::eRightOrInside:	choice = 1;
							break;

					case CChamferParams::eOn:	choice = 2;
							break;

					case CChamferParams::eLeftOrOutside:	choice = 0;
							break;
				} // End switch

				list->push_back(new PropertyChoice(_("tool on side"), choices, choice, parent, on_set_tool_on_side));
            }
        }
    }
}
Example #11
0
/**
	We can see what diameter tool was used to create the pocket or contour child operation.  We assume
	that this has already occured.  We want to fit down into the slot cut by these operations as far
	as possible but only touching the appropriate side of the material (inside or outside).
	We also need to make sure we don't go too deep.  If the chamfering bit is small while the endmill
	used to cut the profile or contour was large then we may need to limit the depth of cut.
 */
Python CChamfer::AppendTextForProfileChildren(
	CMachineState *pMachineState,
	const double theta,
	HeeksObj *child,
	CTool *pChamferingBit )
{
	Python python;

	unsigned int number_of_bad_sketches = 0;
	double tolerance = heeksCAD->GetTolerance();

	double start_depth = 0.0;
	double final_depth = 0.0;
	double clearance_height = 0.0;
	double rapid_safety_space = 0.0;
	std::list<HeeksObj *> sketches;

	CDepthOp *pDepthOp = dynamic_cast<CDepthOp *>(child);
	if (pDepthOp == NULL)
	{
		start_depth = m_depth_op_params.m_start_depth;
		final_depth = m_depth_op_params.m_final_depth;
		clearance_height = m_depth_op_params.ClearanceHeight();
		rapid_safety_space = m_depth_op_params.m_rapid_safety_space;

		if (child->GetType() == SketchType)
		{
			sketches.push_back(child);
		}
	}
	else
	{
		start_depth = pDepthOp->m_depth_op_params.m_start_depth;
		final_depth = pDepthOp->m_depth_op_params.m_final_depth;
		clearance_height = pDepthOp->m_depth_op_params.ClearanceHeight();
		rapid_safety_space = pDepthOp->m_depth_op_params.m_rapid_safety_space;

		for (HeeksObj *object = child->GetFirstChild(); object != NULL; object = child->GetNextChild())
		{
			if (object->GetType() == SketchType)
			{
				sketches.push_back(object);
			}
		}
	}

	for (std::list<HeeksObj *>::iterator itChild = sketches.begin(); itChild != sketches.end(); itChild++)
    {
		HeeksObj *object = *itChild;

        std::list<TopoDS_Shape> wires;
        if (! heeksCAD->ConvertSketchToFaceOrWire( object, wires, false))
        {
            number_of_bad_sketches++;
        } // End if - then
        else
        {
            // The wire(s) represent the sketch objects for a tool path.
            if (object->GetShortString() != NULL)
            {
				wxString comment;
				comment << _T("Chamfering of ") << object->GetShortString();
                python << _T("comment(") << PythonString(comment).c_str() << _T(")\n");
            }

            try {
                for(std::list<TopoDS_Shape>::iterator It2 = wires.begin(); It2 != wires.end(); It2++)
                {
                    TopoDS_Shape& wire_to_fix = *It2;
                    ShapeFix_Wire fix;
                    fix.Load( TopoDS::Wire(wire_to_fix) );
                    fix.FixReorder();

                    TopoDS_Shape wire = fix.Wire();

                    wire = pMachineState->Fixture().Adjustment(wire);

                    BRepOffsetAPI_MakeOffset offset_wire(TopoDS::Wire(wire));

                    // Now generate a toolpath along this wire.
                    std::list<double> depths = GetProfileChamferingDepths(child);

                    for (std::list<double>::iterator itDepth = depths.begin(); itDepth != depths.end(); itDepth++)
                    {
                        double radius = pChamferingBit->CuttingRadius(false,fabs(*itDepth - start_depth));

						// We know what offset we'd really like.  See how far we can offset the shape before we start
                        // getting cross-over of graphics.
                        double max_offset = CInlay::FindMaxOffset( radius, TopoDS::Wire(wire), radius / 10.0 );

						if (radius > max_offset) radius = max_offset;

						// Now move the tool slightly less than this offset so that the chamfering width is
						// produced.
						double theta = pChamferingBit->m_params.m_cutting_edge_angle / 360.0 * 2.0 * PI;
						radius -= this->m_params.m_chamfer_width * sin(theta);

						switch (child->GetType())
						{
						case ProfileType:
							if (((CProfile *) child)->m_profile_params.m_tool_on_side == CProfileParams::eLeftOrOutside) radius *= +1.0;
							if (((CProfile *) child)->m_profile_params.m_tool_on_side == CProfileParams::eRightOrInside) radius *= -1.0;
							if (((CProfile *) child)->m_profile_params.m_tool_on_side == CProfileParams::eOn) radius *= +1.0;
							break;

						case ContourType:
							if (((CContour *) child)->m_params.m_tool_on_side == CContourParams::eLeftOrOutside) radius *= +1.0;
							if (((CContour *) child)->m_params.m_tool_on_side == CContourParams::eRightOrInside) radius *= -1.0;
							if (((CContour *) child)->m_params.m_tool_on_side == CContourParams::eOn) radius *= +1.0;
							break;

						case PocketType:
							radius *= -1.0;
							break;

						default:
							if (m_params.m_tool_on_side == CContourParams::eLeftOrOutside) radius *= +1.0;
							if (m_params.m_tool_on_side == CContourParams::eRightOrInside) radius *= -1.0;
							if (m_params.m_tool_on_side == CContourParams::eOn) radius *= +1.0;
							break;
						} // End switch

                        TopoDS_Wire tool_path_wire(TopoDS::Wire(wire));

                        double offset = radius;
                        if (offset < 0) offset *= -1.0;

                        if (offset > tolerance)
                        {
                            offset_wire.Perform(radius);
                            if (! offset_wire.IsDone())
                            {
                                break;
                            }
                            tool_path_wire = TopoDS::Wire(offset_wire.Shape());
                        }

                        if (offset > tolerance)
                        {
                            gp_Trsf matrix;

                            matrix.SetTranslation( gp_Vec( gp_Pnt(0,0,0), gp_Pnt( 0,0,*itDepth)));
                            BRepBuilderAPI_Transform transform(matrix);
                            transform.Perform(tool_path_wire, false); // notice false as second parameter
                            tool_path_wire = TopoDS::Wire(transform.Shape());

							python << CContour::GCode(	tool_path_wire,
                                                        pMachineState,
                                                        clearance_height,
                                                        rapid_safety_space,
                                                        start_depth,
                                                        CContourParams::ePlunge );
                        } // End if - then
                    } // End for
                } // End for
            } // End try
            catch (Standard_Failure & error) {
                (void) error;	// Avoid the compiler warning.
                Handle_Standard_Failure e = Standard_Failure::Caught();
                number_of_bad_sketches++;
            } // End catch
        } // End if - else
    } // End for

    if (pMachineState->Location().Z() < (m_depth_op_params.ClearanceHeight() / theApp.m_program->m_units))
    {
        // Move up above workpiece to relocate to the start of the next operation.
        python << _T("rapid(z=") << m_depth_op_params.ClearanceHeight() / theApp.m_program->m_units << _T(")\n");

        CNCPoint where(pMachineState->Location());
        where.SetZ(m_depth_op_params.ClearanceHeight() / theApp.m_program->m_units);
        pMachineState->Location(where);
    }

    if (number_of_bad_sketches > 0)
    {
        wxString message;
        message << _("Failed to create contours around ") << number_of_bad_sketches << _(" sketches");
        wxMessageBox(message);
    }

	return(python);
}
Example #12
0
Python CProfile::AppendTextToProgram(CMachineState *pMachineState, bool finishing_pass)
{
	Python python;

	CTool *pTool = CTool::Find( m_tool_number );
	if (pTool == NULL)
	{
		if(!finishing_pass)wxMessageBox(_T("Cannot generate GCode for profile without a tool assigned"));
		return(python);
	} // End if - then

	if(!finishing_pass || m_profile_params.m_only_finishing_pass)
	{
		python << CDepthOp::AppendTextToProgram(pMachineState);

		if(m_profile_params.m_auto_roll_on || m_profile_params.m_auto_roll_off)
		{
			python << _T("roll_radius = float(");
			python << m_profile_params.m_auto_roll_radius / theApp.m_program->m_units;
			python << _T(")\n");
		}
	}

	if(finishing_pass)
	{
		python << _T("feedrate_hv(") << m_profile_params.m_finishing_h_feed_rate / theApp.m_program->m_units << _T(", ");
		python << m_speed_op_params.m_vertical_feed_rate / theApp.m_program->m_units << _T(")\n");
		python << _T("flush_nc()\n");
		python << _T("offset_extra = 0.0\n");
		python << _T("step_down = ") << m_profile_params.m_finishing_step_down << _T("\n");
	}
	else
	{
		python << _T("offset_extra = ") << m_profile_params.m_offset_extra / theApp.m_program->m_units << _T("\n");
	}

	CProfileParams::eCutMode cut_mode = finishing_pass ? m_profile_params.m_finishing_cut_mode : m_profile_params.m_cut_mode;

#ifdef OP_SKETCHES_AS_CHILDREN
	for(std::list<HeeksObj*>::iterator It = m_objects.begin(); It != m_objects.end(); It++)
	{
		// write a kurve definition
		HeeksObj* object = *It;
		if((object == NULL) || (object->GetType() != SketchType) || (object->GetNumChildren() == 0))continue;
#else
	for (std::list<int>::iterator It = m_sketches.begin(); It != m_sketches.end(); It++)
    {
		HeeksObj* object = heeksCAD->GetIDObject(SketchType, *It);
		if((object == NULL) || (object->GetNumChildren() == 0))continue;
#endif

		HeeksObj* re_ordered_sketch = NULL;
		SketchOrderType sketch_order = heeksCAD->GetSketchOrder(object);
		if(sketch_order == SketchOrderTypeBad)
		{
			re_ordered_sketch = object->MakeACopy();
			heeksCAD->ReOrderSketch(re_ordered_sketch, SketchOrderTypeReOrder);
			object = re_ordered_sketch;
		}

		if(sketch_order == SketchOrderTypeMultipleCurves || sketch_order == SketchOrderHasCircles)
		{
			std::list<HeeksObj*> new_separate_sketches;
			heeksCAD->ExtractSeparateSketches(object, new_separate_sketches, false);
			for(std::list<HeeksObj*>::iterator It = new_separate_sketches.begin(); It != new_separate_sketches.end(); It++)
			{
				HeeksObj* one_curve_sketch = *It;
				python << AppendTextForOneSketch(one_curve_sketch, pMachineState, cut_mode).c_str();
				delete one_curve_sketch;
			}
		}
		else
		{
			python << AppendTextForOneSketch(object, pMachineState, cut_mode).c_str();
		}

		if(re_ordered_sketch)
		{
			delete re_ordered_sketch;
		}
	}

	return python;
} // End AppendTextToProgram() method

static unsigned char cross16[32] = {0x80, 0x01, 0x40, 0x02, 0x20, 0x04, 0x10, 0x08, 0x08, 0x10, 0x04, 0x20, 0x02, 0x40, 0x01, 0x80, 0x01, 0x80, 0x02, 0x40, 0x04, 0x20, 0x08, 0x10, 0x10, 0x08, 0x20, 0x04, 0x40, 0x02, 0x80, 0x01};

void CProfile::glCommands(bool select, bool marked, bool no_color)
{
	CDepthOp::glCommands(select, marked, no_color);

	if(marked && !no_color)
	{
		if(GetNumSketches() == 1)
		{
			// draw roll on point
			if(!m_profile_params.m_auto_roll_on)
			{
				glColor3ub(0, 200, 200);
				glRasterPos3dv(m_profile_params.m_roll_on_point);
				glBitmap(16, 16, 8, 8, 10.0, 0.0, cross16);
			}
			// draw roll off point
			if(!m_profile_params.m_auto_roll_on)
			{
				glColor3ub(255, 128, 0);
				glRasterPos3dv(m_profile_params.m_roll_off_point);
				glBitmap(16, 16, 8, 8, 10.0, 0.0, cross16);
			}
			// draw start point
			if(m_profile_params.m_start_given)
			{
				glColor3ub(128, 0, 255);
				glRasterPos3dv(m_profile_params.m_start);
				glBitmap(16, 16, 8, 8, 10.0, 0.0, cross16);
			}
			// draw end point
			if(m_profile_params.m_end_given)
			{
				glColor3ub(200, 200, 0);
				glRasterPos3dv(m_profile_params.m_end);
				glBitmap(16, 16, 8, 8, 10.0, 0.0, cross16);
			}
		}
	}
}
Example #13
0
Python CProfile::WriteSketchDefn(HeeksObj* sketch, CMachineState *pMachineState, bool reversed )
{
	// write the python code for the sketch
	Python python;

	if ((sketch->GetShortString() != NULL) && (wxString(sketch->GetShortString()).size() > 0))
	{
		python << (wxString::Format(_T("comment(%s)\n"), PythonString(sketch->GetShortString()).c_str()));
	}

	python << _T("curve = area.Curve()\n");

	bool started = false;
	std::list<HeeksObj*> spans;
	for(HeeksObj* span_object = sketch->GetFirstChild(); span_object; span_object = sketch->GetNextChild())
	{
		if(reversed)spans.push_front(span_object);
		else spans.push_back(span_object);
	}

	std::list<HeeksObj*> new_spans;
	for(std::list<HeeksObj*>::iterator It = spans.begin(); It != spans.end(); It++)
	{
		HeeksObj* span = *It;
		if(span->GetType() == SplineType)
		{
			std::list<HeeksObj*> new_spans2;
			heeksCAD->SplineToBiarcs(span, new_spans2, CProfile::max_deviation_for_spline_to_arc);
			for(std::list<HeeksObj*>::iterator It2 = new_spans2.begin(); It2 != new_spans2.end(); It2++)
			{
				HeeksObj* s = *It2;
				if(reversed)new_spans.push_front(s);
				else new_spans.push_back(s);
			}
		}
		else
		{
			new_spans.push_back(span->MakeACopy());
		}
	}

	for(std::list<HeeksObj*>::iterator It = new_spans.begin(); It != new_spans.end(); It++)
	{
		HeeksObj* span_object = *It;
		double s[3] = {0, 0, 0};
		double e[3] = {0, 0, 0};
		double c[3] = {0, 0, 0};


		if(span_object){
			int type = span_object->GetType();
			if(type == LineType || type == ArcType || type == CircleType)
			{
				if(!started && type != CircleType)
				{
					if(reversed)span_object->GetEndPoint(s);
					else span_object->GetStartPoint(s);
					CNCPoint start(s);

					python << _T("curve.append(area.Point(");
					python << start.X(true);
					python << _T(", ");
					python << start.Y(true);
					python << _T("))\n");
					started = true;
				}
				if(reversed)span_object->GetStartPoint(e);
				else span_object->GetEndPoint(e);
				CNCPoint end(e);

				if(type == LineType)
				{
					python << _T("curve.append(area.Point(");
					python << end.X(true);
					python << _T(", ");
					python << end.Y(true);
					python << _T("))\n");
				}
				else if(type == ArcType)
				{
					span_object->GetCentrePoint(c);
					CNCPoint centre(c);

					double pos[3];
					heeksCAD->GetArcAxis(span_object, pos);
					int span_type = ((pos[2] >=0) != reversed) ? 1: -1;
					python << _T("curve.append(area.Vertex(");
					python << (span_type);
					python << (_T(", area.Point("));
					python << end.X(true);
					python << (_T(", "));
					python << end.Y(true);
					python << (_T("), area.Point("));
					python << centre.X(true);
					python << (_T(", "));
					python << centre.Y(true);
					python << (_T(")))\n"));
				}
				else if(type == CircleType)
				{
					std::list< std::pair<int, gp_Pnt > > points;
					span_object->GetCentrePoint(c);

					double radius = heeksCAD->CircleGetRadius(span_object);

					// Setup the four arcs to make up the full circle using UNadjusted
					// coordinates.  We do this so that the offsets are expressed along the
					// X and Y axes.  We will adjust the resultant points later.

					// The kurve code needs a start point first.
					points.push_back( std::make_pair(0, gp_Pnt( c[0], c[1] + radius, c[2] )) ); // north
					if(reversed)
					{
						points.push_back( std::make_pair(1, gp_Pnt( c[0] - radius, c[1], c[2] )) ); // west
						points.push_back( std::make_pair(1, gp_Pnt( c[0], c[1] - radius, c[2] )) ); // south
						points.push_back( std::make_pair(1, gp_Pnt( c[0] + radius, c[1], c[2] )) ); // east
						points.push_back( std::make_pair(1, gp_Pnt( c[0], c[1] + radius, c[2] )) ); // north
					}
					else
					{
						points.push_back( std::make_pair(-1, gp_Pnt( c[0] + radius, c[1], c[2] )) ); // east
						points.push_back( std::make_pair(-1, gp_Pnt( c[0], c[1] - radius, c[2] )) ); // south
						points.push_back( std::make_pair(-1, gp_Pnt( c[0] - radius, c[1], c[2] )) ); // west
						points.push_back( std::make_pair(-1, gp_Pnt( c[0], c[1] + radius, c[2] )) ); // north
					}

					CNCPoint centre(c);

					for (std::list< std::pair<int, gp_Pnt > >::iterator l_itPoint = points.begin(); l_itPoint != points.end(); l_itPoint++)
					{
						CNCPoint pnt( l_itPoint->second );

						python << (_T("curve.append(area.Vertex("));
						python << l_itPoint->first << _T(", area.Point(");
						python << pnt.X(true);
						python << (_T(", "));
						python << pnt.Y(true);
						python << (_T("), area.Point("));
						python << centre.X(true);
						python << (_T(", "));
						python << centre.Y(true);
						python << (_T(")))\n"));
					} // End for
				}
			}
		}
	}

	// delete the spans made
	for(std::list<HeeksObj*>::iterator It = new_spans.begin(); It != new_spans.end(); It++)
	{
		HeeksObj* span = *It;
		delete span;
	}

	python << _T("\n");

	if(GetNumSketches() == 1 && (m_profile_params.m_start_given || m_profile_params.m_end_given))
	{
		double startx, starty, finishx, finishy;

		wxString start_string;
		if(m_profile_params.m_start_given)
		{
#ifdef UNICODE
			std::wostringstream ss;
#else
			std::ostringstream ss;
#endif

			gp_Pnt starting(m_profile_params.m_start[0] / theApp.m_program->m_units,
					m_profile_params.m_start[1] / theApp.m_program->m_units,
					0.0 );

			startx = starting.X();
			starty = starting.Y();

			ss.imbue(std::locale("C"));
			ss<<std::setprecision(10);
			ss << ", start = area.Point(" << startx << ", " << starty << ")";
			start_string = ss.str().c_str();
		}


		wxString finish_string;
		wxString beyond_string;
		if(m_profile_params.m_end_given)
		{
#ifdef UNICODE
			std::wostringstream ss;
#else
			std::ostringstream ss;
#endif

			gp_Pnt finish(m_profile_params.m_end[0] / theApp.m_program->m_units,
					m_profile_params.m_end[1] / theApp.m_program->m_units,
					0.0 );

			finishx = finish.X();
			finishy = finish.Y();

			ss.imbue(std::locale("C"));
			ss<<std::setprecision(10);
			ss << ", finish = area.Point(" << finishx << ", " << finishy << ")";
			finish_string = ss.str().c_str();

			if(m_profile_params.m_end_beyond_full_profile)beyond_string = _T(", end_beyond = True");
		}

		python << (wxString::Format(_T("kurve_funcs.make_smaller( curve%s%s%s)\n"), start_string.c_str(), finish_string.c_str(), beyond_string.c_str())).c_str();
	}

	return(python);
}
Example #14
0
Python CPocket::AppendTextToProgram()
{
	Python python;

	CTool *pTool = CTool::Find( m_tool_number );
	if (pTool == NULL)
	{
		wxMessageBox(_T("Cannot generate GCode for pocket without a tool assigned"));
		return python;
	} // End if - then


	python << CSketchOp::AppendTextToProgram();

	HeeksObj* object = heeksCAD->GetIDObject(SketchType, m_sketch);

	if(object == NULL) {
		wxMessageBox(wxString::Format(_("Pocket operation - Sketch doesn't exist")));
		return python;
	}

	int type = object->GetType();

	// do areas and circles first, separately
    {
		switch(type)
		{
		case CircleType:
		case AreaType:
			{
				heeksCAD->ObjectAreaString(object, python);
				WritePocketPython(python);
			}
			break;
		}
	}

	if(type == SketchType)
	{
		python << _T("a = area.Area()\n");
		python << _T("entry_moves = []\n");

		double c[3] = {0, 0, 0};

		if (object->GetNumChildren() == 0){
			wxMessageBox(wxString::Format(_("Pocket operation - Sketch %d has no children"), object->GetID()));
			return python;
		}

		HeeksObj* re_ordered_sketch = NULL;
		SketchOrderType order = heeksCAD->GetSketchOrder(object);
		if( 	(order != SketchOrderTypeCloseCW) &&
			(order != SketchOrderTypeCloseCCW) &&
			(order != SketchOrderTypeMultipleCurves) &&
			(order != SketchOrderHasCircles))
		{
			re_ordered_sketch = object->MakeACopy();
			heeksCAD->ReOrderSketch(re_ordered_sketch, SketchOrderTypeReOrder);
			object = re_ordered_sketch;
			order = heeksCAD->GetSketchOrder(object);
			if(	(order != SketchOrderTypeCloseCW) &&
				(order != SketchOrderTypeCloseCCW) &&
				(order != SketchOrderTypeMultipleCurves) &&
				(order != SketchOrderHasCircles))
			{
				switch(heeksCAD->GetSketchOrder(object))
				{
				case SketchOrderTypeOpen:
					{
						wxMessageBox(wxString::Format(_("Pocket operation - Sketch must be a closed shape - sketch %d"), object->m_id));
						delete re_ordered_sketch;
						return python;
					}
					break;

				default:
					{
						wxMessageBox(wxString::Format(_("Pocket operation - Badly ordered sketch - sketch %d"), object->m_id));
						delete re_ordered_sketch;
						return python;
					}
					break;
				}
			}
		}

		if(object)
		{
			python << WriteSketchDefn(object);
		}

		if(re_ordered_sketch)
		{
			delete re_ordered_sketch;
		}

	} // End for

	// reorder the area, the outside curves must be made anti-clockwise and the insides clockwise
	python << _T("a.Reorder()\n");

	WritePocketPython(python);

	return python;
}
Example #15
0
void CSketch::ExtractSeparateSketches(std::list<HeeksObj*> &new_separate_sketches, const bool allow_individual_objects /* = false */ )
{
	CSketch* re_ordered_sketch = NULL;
	CSketch* sketch = this;

	if(GetSketchOrder() == SketchOrderTypeBad)
	{
	    // Duplicate and reorder the sketch to see if it's possible to make separate connected sketches.
		re_ordered_sketch = (CSketch*)(this->MakeACopy());
		re_ordered_sketch->ReOrderSketch(SketchOrderTypeReOrder);
		sketch = re_ordered_sketch;
	}
	if(sketch->GetSketchOrder() == SketchOrderTypeMultipleCurves || GetSketchOrder() == SketchOrderHasCircles)
	{
		std::list<HeeksObj*> objects_for_relinker;
		for(std::list<HeeksObj*>::iterator It=m_objects.begin(); It!=m_objects.end() ;It++)
		{
			HeeksObj* object = *It;
			if(object->GetType() == CircleType)
			{
				CSketch* new_object = new CSketch();
				new_object->color = color;
				new_object->Add(object->MakeACopy(), NULL);
				new_separate_sketches.push_back(new_object);
			}
			else
			{
				objects_for_relinker.push_back(object);
			}
		}

		// Make separate connected sketches from the child elements.
		CSketchRelinker relinker(objects_for_relinker);

		relinker.Do();

		for(std::list< std::list<HeeksObj*> >::iterator It = relinker.m_new_lists.begin(); It != relinker.m_new_lists.end(); It++)
		{
			std::list<HeeksObj*>& list = *It;
			CSketch* new_object = new CSketch();
			new_object->color = color;
			for(std::list<HeeksObj*>::iterator It2 = list.begin(); It2 != list.end(); It2++)
			{
				HeeksObj* object = *It2;
				new_object->Add(object->MakeACopy(), NULL);
			}
			new_separate_sketches.push_back(new_object);
		}
	}
	else
	{
        // The sketch does not seem to relink into separate connected shapes.  Just export
        // all the sketch's children as separate objects instead.
		if (allow_individual_objects)
		{
			for (HeeksObj *child = sketch->GetFirstChild(); child != NULL; child = sketch->GetNextChild())
			{
				new_separate_sketches.push_back( child->MakeACopy() );
			}
		}
	}

	if(re_ordered_sketch)delete re_ordered_sketch;
}
Example #16
0
	void Run()
	{
		std::list<HeeksObj*>::const_iterator It;
		for(It = wxGetApp().m_marked_list->list().begin(); It != wxGetApp().m_marked_list->list().end(); It++)
		{
			HeeksObj* obj = (HeeksObj*)*It;
			if(obj->GetType() == SketchType)
			{
				CSketch* sketch = (CSketch*)obj;

                std::list<TopoDS_Shape> wires;
                if (! ConvertSketchToFaceOrWire( sketch, wires, false))
                {
                    wxMessageBox(_("Failed to convert sketch to wire"));
                } // End if - then
                else
                {
                    try {
                        // For all wires in this sketch...
                        for(std::list<TopoDS_Shape>::iterator It2 = wires.begin(); It2 != wires.end(); It2++)
                        {
                            TopoDS_Shape& wire_to_fix = *It2;
                            ShapeFix_Wire fix;
                            fix.Load( TopoDS::Wire(wire_to_fix) );
                            // fix.ClearModes();

                            fix.ModifyTopologyMode() = sketch_tool_options.m_modify_topology;
                            fix.ModifyGeometryMode() = sketch_tool_options.m_modify_geometry;
                            fix.ClosedWireMode() = sketch_tool_options.m_closed_wire;
                            fix.PreferencePCurveMode() = sketch_tool_options.m_preference_pcurve;
                            fix.FixGapsByRangesMode() = sketch_tool_options.m_fix_gaps_by_ranges;
                            fix.FixSelfIntersectionMode() = sketch_tool_options.m_fix_self_intersection;
                            fix.FixReorderMode() = sketch_tool_options.m_reorder;
                            fix.FixDegeneratedMode() = sketch_tool_options.m_fix_degenerated;

                            if (sketch_tool_options.m_fix_small)
                            {
                                fix.FixSmallMode() = true;
                                fix.FixSmall( false, sketch_tool_options.m_fix_small_precision );
                            }

                            if (sketch_tool_options.m_fix_lacking)
                            {
                                fix.FixLackingMode() = sketch_tool_options.m_fix_lacking;
                                fix.FixLacking(false);
                            }

                            if (! fix.Perform())
                            {
                                wxMessageBox(_("Wire fix failed"));
                            }
                            else
                            {
                                TopoDS_Shape wire = fix.Wire();
                                HeeksObj *new_sketch = heekscad_interface.NewSketch();
                                double deviation = 0.001;
                                if (!  ConvertWireToSketch(TopoDS::Wire(wire), new_sketch, deviation))
                                {
                                    wxMessageBox(_("Failed to convert wire to sketch"));
                                }
                                else
                                {
                                    if (sketch != NULL)
                                    {
                                        heekscad_interface.Remove( sketch );
                                        sketch = NULL;
                                    }

                                    heekscad_interface.Add(new_sketch, NULL);
                                }
                            }
                        }
                    } // End try
                    catch (Standard_Failure & error) {
                        (void) error;	// Avoid the compiler warning.
                        Handle_Standard_Failure e = Standard_Failure::Caught();
                        wxMessageBox(_("Failed to fix wire"));
                    } // End catch
                }
			}
		}
	}
Example #17
0
void CSelectMode::OnLeftDown( wxMouseEvent& event )
{
	button_down_point = wxPoint(event.GetX(), event.GetY());
	CurrentPoint = button_down_point;
	m_button_down = true;
	m_highlighted_objects.clear();

	if(wxGetApp().m_dragging_moves_objects)
	{
		MarkedObjectManyOfSame marked_object;
		wxGetApp().FindMarkedObject(button_down_point, &marked_object);
		if(marked_object.m_map.size()>0)
		{
			HeeksObj* object = marked_object.GetFirstOfTopOnly();

			if (event.ShiftDown())
			{
				// Augment the marked_object list with objects that 'look' like
				// the one selected.

				CCorrelationTool correlate(wxGetApp().m_min_correlation_factor, wxGetApp().m_max_scale_threshold, wxGetApp().m_number_of_sample_points, wxGetApp().m_correlate_by_color );
				std::list<HeeksObj *> similar_objects = correlate.SimilarSymbols( object );
				std::list<HeeksObj *>::const_iterator l_itSymbol;

				for (l_itSymbol = similar_objects.begin(); l_itSymbol != similar_objects.end(); l_itSymbol++)
				{
					HeeksObj *ob = *l_itSymbol;
					if (! wxGetApp().m_marked_list->ObjectMarked(ob))
					{
						wxGetApp().m_marked_list->Add(ob, true);
					}
				} // End for
			} // End if - then

			while(object)
			{
				if(object->GetType() == GripperType)
				{
					wxGetApp().m_current_viewport->DrawFront();
					wxGetApp().drag_gripper = (Gripper*)object;
					wxGetApp().m_digitizing->SetOnlyCoords(wxGetApp().drag_gripper, true);
					wxGetApp().m_digitizing->digitize(button_down_point);
					wxGetApp().grip_from = wxGetApp().m_digitizing->digitized_point.m_point;
					wxGetApp().grip_to = wxGetApp().grip_from;
					double from[3];
					from[0] = wxGetApp().grip_from.X();
					from[1] = wxGetApp().grip_from.Y();
					from[2] = wxGetApp().grip_from.Z();

					std::list<HeeksObj*> selected_objects;
					for(std::list<HeeksObj*>::iterator It = wxGetApp().m_marked_list->list().begin(); It != wxGetApp().m_marked_list->list().end(); It++)
					{
						HeeksObj* object = *It;
						if(object->CanBeDragged())selected_objects.push_back(object);
					}

					wxGetApp().drag_gripper->OnGripperGrabbed(selected_objects, true, from);
					wxGetApp().grip_from = gp_Pnt(from[0], from[1], from[2]);
					wxGetApp().m_current_viewport->EndDrawFront();
					return;
				}
				object = marked_object.Increment();
			}
		}
	}
}
Example #18
0
Python CWaterline::AppendTextToProgram(CMachineState *pMachineState)
{
	Python python;

    ReloadPointers();   // Make sure all the solids in m_solids are included as child objects.

	CTool *pTool = CTool::Find(m_tool_number);
	if(pTool == NULL)
	{
		return(python);
	}

	python << CDepthOp::AppendTextToProgram(pMachineState);

	// write the corner radius
	python << _T("corner_radius = float(");
	double cr = pTool->m_params.m_corner_radius - pTool->m_params.m_flat_radius;
	if(cr<0)cr = 0.0;
	python << ( cr / theApp.m_program->m_units ) << _T(")\n");

	heeksCAD->CreateUndoPoint();

	//write stl file
	std::list<HeeksObj*> solids;
	for (HeeksObj *object = GetFirstChild(); object != NULL; object = GetNextChild())
	{
	    if (object->GetType() != SolidType && object->GetType() != StlSolidType)
	    {
	        continue;
	    }

		if (object != NULL)
		{
			// Need to rotate a COPY of the solid by the fixture settings.
			HeeksObj* copy = object->MakeACopy();
			if (copy != NULL)
			{
				double m[16];	// A different form of the transformation matrix.
				CFixture::extract( pMachineState->Fixture().GetMatrix(CFixture::YZ), m );
                copy->ModifyByMatrix(m);

                CFixture::extract( pMachineState->Fixture().GetMatrix(CFixture::XZ), m );
                copy->ModifyByMatrix(m);

                CFixture::extract( pMachineState->Fixture().GetMatrix(CFixture::XY), m );
                copy->ModifyByMatrix(m);

                solids.push_back(copy);
            } // End if - then
        } // End if - then
	} // End for


    wxStandardPaths standard_paths;
    wxFileName filepath( standard_paths.GetTempDir().c_str(), wxString::Format(_T("waterline%d.stl"), number_for_stl_file).c_str() );
	number_for_stl_file++;

	heeksCAD->SaveSTLFile(solids, filepath.GetFullPath(), m_params.m_tolerance);

	// We don't need the duplicate solids any more.  Delete them.
	for (std::list<HeeksObj*>::iterator l_itSolid = solids.begin(); l_itSolid != solids.end(); l_itSolid++)
	{
		heeksCAD->Remove( *l_itSolid );
	} // End for
	heeksCAD->Changed();

    python << _T("ocl_funcs.waterline( filepath = ") << PythonString(filepath.GetFullPath()) << _T(", ")
            << _T("tool_diameter = ") << pTool->CuttingRadius() * 2.0 << _T(", ")
            << _T("corner_radius = ") << pTool->m_params.m_corner_radius / theApp.m_program->m_units << _T(", ")
            << _T("step_over = ") << m_params.m_step_over / theApp.m_program->m_units << _T(", ")
            << _T("mat_allowance = ") << m_params.m_material_allowance / theApp.m_program->m_units << _T(", ")
            << _T("clearance = clearance, ")
            << _T("rapid_safety_space = rapid_safety_space, ")
            << _T("start_depth = start_depth, ")
            << _T("step_down = step_down, ")
            << _T("final_depth = final_depth, ")
            << _T("units = ") << theApp.m_program->m_units << _T(", ")
            << _T("x0 = ") << m_params.m_box.m_x[0] / theApp.m_program->m_units << _T(", ")
            << _T("y0 = ") << m_params.m_box.m_x[1] / theApp.m_program->m_units << _T(", ")
            << _T("x1 = ") << m_params.m_box.m_x[3] / theApp.m_program->m_units << _T(", ")
            << _T("y1 = ") << m_params.m_box.m_x[4] / theApp.m_program->m_units << _T(", ")
            << _T("tolerance = ") << m_params.m_tolerance << _T(")\n");

	return(python);
}
Example #19
0
void CSelectMode::OnLeftUp( wxMouseEvent& event )
{
	if(wxGetApp().drag_gripper)
	{
		double to[3], from[3];
		wxGetApp().m_digitizing->digitize(wxPoint(event.GetX(), event.GetY()));
		extract(wxGetApp().m_digitizing->digitized_point.m_point, to);
		wxGetApp().grip_to = wxGetApp().m_digitizing->digitized_point.m_point;
		extract(wxGetApp().grip_from, from);
		wxGetApp().drag_gripper->OnGripperReleased(from, to);
		wxGetApp().m_digitizing->SetOnlyCoords(wxGetApp().drag_gripper, false);
		wxGetApp().drag_gripper = NULL;
	}
	else if(window_box_exists)
	{
		if(!event.ControlDown())wxGetApp().m_marked_list->Clear(true);
		std::list<HeeksObj*> obj_list;
		GetObjectsInWindow(event, obj_list);
		wxGetApp().m_marked_list->Add(obj_list, true);
		wxGetApp().m_current_viewport->DrawWindow(window_box, true); // undraw the window
		window_box_exists = false;
	}
	else
	{
		// select one object
		m_last_click_point = CClickPoint();
		MarkedObjectOneOfEach marked_object;
		wxGetApp().FindMarkedObject(wxPoint(event.GetX(), event.GetY()), &marked_object);
		if(marked_object.m_map.size()>0){
			HeeksObj* previously_marked = NULL;
			if(wxGetApp().m_marked_list->size() == 1)
			{
				previously_marked = *(wxGetApp().m_marked_list->list().begin());
			}
			HeeksObj* o = marked_object.GetFirstOfTopOnly();
			unsigned long depth = marked_object.GetDepth();
			HeeksObj* object = o;

			while(o)
			{
				if(o == previously_marked)
				{
					object = o;
					break;
				}

				o = marked_object.Increment();

				if(o)
				{
					// prefer highest order objects
					if(o->GetType() < object->GetType())object = o;
				}
			}
			if(!event.ShiftDown() && !event.ControlDown())
			{
				wxGetApp().m_marked_list->Clear(true);
			}
			if (wxGetApp().m_marked_list->ObjectMarked(object))
			{
				if (!event.ShiftDown())
				{
					wxGetApp().m_marked_list->Remove(object, true);
				}
			}
			else
			{
				wxGetApp().m_marked_list->Add(object, true);
				m_last_click_point = CClickPoint(wxPoint(event.GetX(), event.GetY()), depth);
				gp_Lin ray = wxGetApp().m_current_viewport->m_view_point.SightLine(wxPoint(event.GetX(), event.GetY()));
				double ray_start[3], ray_direction[3];
				extract(ray.Location(), ray_start);
				extract(ray.Direction(), ray_direction);
				marked_object.GetFirstOfTopOnly();
				object->SetClickMarkPoint(marked_object.GetCurrent(), ray_start, ray_direction);
			}
		}
		else
		{
			if(!event.ShiftDown() && !event.ControlDown())
			{
				wxGetApp().m_marked_list->Clear(true);
			}
		}
	}

	if(m_just_one && m_doing_a_main_loop && (wxGetApp().m_marked_list->size() > 0))
	{
		ExitMainLoop();
	}
	else
	{
		wxGetApp().m_current_viewport->m_need_refresh = true;
	}
}
Example #20
0
void CSelectMode::OnMouse( wxMouseEvent& event )
{
	bool event_used = false;
	if(LeftAndRightPressed(event, event_used))
	{
		if(m_doing_a_main_loop){
			wxGetApp().ExitMainLoop();
		}
	}

	if(event_used)return;

	if(event.LeftDown())
	{
		button_down_point = wxPoint(event.GetX(), event.GetY());
		CurrentPoint = button_down_point;

		if(wxGetApp().m_dragging_moves_objects)
		{
			MarkedObjectManyOfSame marked_object;
			wxGetApp().FindMarkedObject(button_down_point, &marked_object);
			if(marked_object.m_map.size()>0)
			{
				HeeksObj* object = marked_object.GetFirstOfTopOnly();

				if (event.ShiftDown())
				{
					// Augment the marked_object list with objects that 'look' like
					// the one selected.

					CCorrelationTool correlate(wxGetApp().m_min_correlation_factor, wxGetApp().m_max_scale_threshold, wxGetApp().m_number_of_sample_points, wxGetApp().m_correlate_by_color );
					std::list<HeeksObj *> similar_objects = correlate.SimilarSymbols( object );
					std::list<HeeksObj *>::const_iterator l_itSymbol;

					for (l_itSymbol = similar_objects.begin(); l_itSymbol != similar_objects.end(); l_itSymbol++)
					{
						HeeksObj *ob = *l_itSymbol;
						if (! wxGetApp().m_marked_list->ObjectMarked(ob))
						{
							wxGetApp().m_marked_list->Add(ob, true);
						}
					} // End for
				} // End if - then

				while(object)
				{
					if(object->GetType() == GripperType)
					{
						wxGetApp().m_current_viewport->DrawFront();
						wxGetApp().drag_gripper = (Gripper*)object;
						wxGetApp().m_digitizing->SetOnlyCoords(wxGetApp().drag_gripper, true);
						wxGetApp().m_digitizing->digitize(button_down_point);
						wxGetApp().grip_from = wxGetApp().m_digitizing->digitized_point.m_point;
						wxGetApp().grip_to = wxGetApp().grip_from;
						double from[3];
						from[0] = wxGetApp().grip_from.X();
						from[1] = wxGetApp().grip_from.Y();
						from[2] = wxGetApp().grip_from.Z();
						wxGetApp().drag_gripper->OnGripperGrabbed(wxGetApp().m_marked_list->list(), true, from);
						wxGetApp().grip_from = gp_Pnt(from[0], from[1], from[2]);
						wxGetApp().m_current_viewport->EndDrawFront();
						return;
					}
					object = marked_object.Increment();
				}
			}
		}
	}

	if(event.MiddleDown())
	{
		button_down_point = wxPoint(event.GetX(), event.GetY());
		CurrentPoint = button_down_point;
		wxGetApp().m_current_viewport->StoreViewPoint();
		wxGetApp().m_current_viewport->m_view_point.SetStartMousePoint(button_down_point);
	}

	if(event.LeftUp())
	{
		if(wxGetApp().drag_gripper)
		{
			double to[3], from[3];
			wxGetApp().m_digitizing->digitize(wxPoint(event.GetX(), event.GetY()));
			extract(wxGetApp().m_digitizing->digitized_point.m_point, to);
			wxGetApp().grip_to = wxGetApp().m_digitizing->digitized_point.m_point;
			extract(wxGetApp().grip_from, from);
			wxGetApp().drag_gripper->OnGripperReleased(from, to);
			wxGetApp().m_digitizing->SetOnlyCoords(wxGetApp().drag_gripper, false);
			wxGetApp().drag_gripper = NULL;
		}
		else if(window_box_exists)
		{
			if(!event.ControlDown())wxGetApp().m_marked_list->Clear(true);
			if(window_box.width > 0){
				// only select objects which are completely within the window
				MarkedObjectManyOfSame marked_object;
				wxGetApp().m_marked_list->ObjectsInWindow(window_box, &marked_object, false);
				std::set<HeeksObj*> obj_set;
				for(HeeksObj* object = marked_object.GetFirstOfTopOnly(); object; object = marked_object.Increment())if(object->GetType() != GripperType)
					obj_set.insert(object);

				int bottom = window_box.y;
				int top = window_box.y + window_box.height;
				int height = abs(window_box.height);
				if(top < bottom)
				{
					int temp = bottom;
					bottom = top;
					top = temp;
				}

				wxRect strip_boxes[4];
				// top
				strip_boxes[0] = wxRect(window_box.x - 1, top, window_box.width + 2, 1);
				// bottom
				strip_boxes[1] = wxRect(window_box.x - 1, bottom - 1, window_box.width + 2, 1);
				// left
				strip_boxes[2] = wxRect(window_box.x - 1, bottom, 1, height);
				// right
				strip_boxes[3] = wxRect(window_box.x + window_box.width, bottom, 1, height);

				for(int i = 0; i<4; i++)
				{
					MarkedObjectManyOfSame marked_object2;
					wxGetApp().m_marked_list->ObjectsInWindow(strip_boxes[i], &marked_object2, false);
					for(HeeksObj* object = marked_object2.GetFirstOfTopOnly(); object; object = marked_object2.Increment())if(object->GetType() != GripperType)
						obj_set.erase(object);
				}

				std::list<HeeksObj*> obj_list;
				for(std::set<HeeksObj*>::iterator It = obj_set.begin(); It != obj_set.end(); It++)
				{
					if(!event.ControlDown() || !wxGetApp().m_marked_list->ObjectMarked(*It))obj_list.push_back(*It);
				}
				wxGetApp().m_marked_list->Add(obj_list, true);
			}
			else{
				// select all the objects in the window, even if only partly in the window
				MarkedObjectManyOfSame marked_object;
				wxGetApp().m_marked_list->ObjectsInWindow(window_box, &marked_object, false);
				std::list<HeeksObj*> obj_list;
				for(HeeksObj* object = marked_object.GetFirstOfTopOnly(); object; object = marked_object.Increment())
				{
					if(object->GetType() != GripperType && (!event.ControlDown() || !wxGetApp().m_marked_list->ObjectMarked(object)))
						obj_list.push_back(object);
				}
				wxGetApp().m_marked_list->Add(obj_list, true);
			}
			wxGetApp().m_current_viewport->DrawWindow(window_box, true); // undraw the window
			window_box_exists = false;
		}
		else
		{
			// select one object
			m_last_click_point = CClickPoint();
			MarkedObjectOneOfEach marked_object;
			wxGetApp().FindMarkedObject(wxPoint(event.GetX(), event.GetY()), &marked_object);
			if(marked_object.m_map.size()>0){
				HeeksObj* previously_marked = NULL;
				if(wxGetApp().m_marked_list->size() == 1)
				{
					previously_marked = *(wxGetApp().m_marked_list->list().begin());
				}
				HeeksObj* o = marked_object.GetFirstOfTopOnly();
				unsigned long depth = marked_object.GetDepth();
				HeeksObj* object = o;

				while(o)
				{
					if(o == previously_marked)
					{
						object = o;
						break;
					}

					o = marked_object.Increment();

					if(o)
					{
						// prefer highest order objects
						if(o->GetType() < object->GetType())object = o;
					}
				}
				if(!event.ShiftDown() && !event.ControlDown())
				{
					wxGetApp().m_marked_list->Clear(true);
				}
				if (wxGetApp().m_marked_list->ObjectMarked(object))
				{
				    if (!event.ShiftDown())
				    {
                        wxGetApp().m_marked_list->Remove(object, true);
				    }
				}
				else
				{
					wxGetApp().m_marked_list->Add(object, true);
					m_last_click_point = CClickPoint(wxPoint(event.GetX(), event.GetY()), depth);
					gp_Lin ray = wxGetApp().m_current_viewport->m_view_point.SightLine(wxPoint(event.GetX(), event.GetY()));
					double ray_start[3], ray_direction[3];
					extract(ray.Location(), ray_start);
					extract(ray.Direction(), ray_direction);
					object->SetClickMarkPoint(&marked_object, ray_start, ray_direction);
				}
			}
			else
			{
				wxGetApp().m_marked_list->Clear(true);
			}
		}

		if(m_just_one && m_doing_a_main_loop && (wxGetApp().m_marked_list->size() > 0))
		{
			wxGetApp().ExitMainLoop();
		}
		else
		{
			wxGetApp().m_current_viewport->m_need_refresh = true;
		}
	}
	else if(event.RightUp())
	{
		MarkedObjectOneOfEach marked_object;
		wxGetApp().FindMarkedObject(wxPoint(event.GetX(), event.GetY()), &marked_object);
		wxGetApp().DoDropDownMenu(wxGetApp().m_frame->m_graphics, wxPoint(event.GetX(), event.GetY()), &marked_object, false, event.ControlDown());
	}
	else if(event.Dragging())
	{
		if(event.MiddleIsDown())
		{
			wxPoint dm;
			dm.x = event.GetX() - CurrentPoint.x;
			dm.y = event.GetY() - CurrentPoint.y;
			if(wxGetApp().ctrl_does_rotate == event.ControlDown())
			{
				if(wxGetApp().m_rotate_mode)
				{
					wxGetApp().m_current_viewport->m_view_point.Turn(dm);
				}
				else
				{
					wxGetApp().m_current_viewport->m_view_point.TurnVertical(dm);
				}
			}
			else
			{
				wxGetApp().m_current_viewport->m_view_point.Shift(dm, wxPoint(event.GetX(), event.GetY()));
			}
			wxGetApp().m_current_viewport->m_need_update = true;
			wxGetApp().m_current_viewport->m_need_refresh = true;
		}
		else if(event.LeftIsDown())
		{
			if(wxGetApp().drag_gripper)
			{
				double to[3], from[3];
				wxGetApp().m_digitizing->digitize(wxPoint(event.GetX(), event.GetY()));
				extract(wxGetApp().m_digitizing->digitized_point.m_point, to);
				wxGetApp().grip_to = wxGetApp().m_digitizing->digitized_point.m_point;
				extract(wxGetApp().grip_from, from);
				wxGetApp().drag_gripper->OnGripperMoved(from, to);
				wxGetApp().grip_from = gp_Pnt(from[0], from[1], from[2]);
				wxGetApp().grip_from = make_point(from);
			}
			else if(abs(button_down_point.x - event.GetX())>2 || abs(button_down_point.y - event.GetY())>2)
			{
				if(wxGetApp().m_dragging_moves_objects && !window_box_exists)
				{
					std::list<HeeksObj*> selected_objects_dragged;
					wxGetApp().m_show_grippers_on_drag = true;

					if(	wxGetApp().m_marked_list->list().size() > 0)
					{
						selected_objects_dragged = wxGetApp().m_marked_list->list();
					}
					else
					{
						MarkedObjectManyOfSame marked_object;
						wxGetApp().FindMarkedObject(button_down_point, &marked_object);
						if(marked_object.m_map.size()>0){
							HeeksObj* object = marked_object.GetFirstOfTopOnly();
							double min_depth = 0.0;
							HeeksObj* closest_object = NULL;
							while(object)
							{
								double depth = marked_object.GetDepth();
								if(closest_object == NULL || depth<min_depth)
								{
									min_depth = depth;
									closest_object = object;
								}
								object = marked_object.Increment();
							}
							if(selected_objects_dragged.size() == 0 && closest_object){
								selected_objects_dragged.push_back(closest_object);
								wxGetApp().m_show_grippers_on_drag = false;
							}
						}
					}

					if(selected_objects_dragged.size() > 0)
					{
						wxGetApp().drag_gripper = &drag_object_gripper;
						wxGetApp().m_digitizing->SetOnlyCoords(wxGetApp().drag_gripper, true);
						wxGetApp().m_digitizing->digitize(button_down_point);
						wxGetApp().grip_from = wxGetApp().m_digitizing->digitized_point.m_point;
						wxGetApp().grip_to = wxGetApp().grip_from;
						double from[3];
						from[0] = wxGetApp().grip_from.X();
						from[1] = wxGetApp().grip_from.Y();
						from[2] = wxGetApp().grip_from.Z();
						wxGetApp().drag_gripper->OnGripperGrabbed(selected_objects_dragged, wxGetApp().m_show_grippers_on_drag, from);
						wxGetApp().grip_from = gp_Pnt(from[0], from[1], from[2]);
						double to[3];
						wxGetApp().m_digitizing->digitize(wxPoint(event.GetX(), event.GetY()));
						extract(wxGetApp().m_digitizing->digitized_point.m_point, to);
						wxGetApp().grip_to = wxGetApp().m_digitizing->digitized_point.m_point;
						extract(wxGetApp().grip_from, from);
						wxGetApp().drag_gripper->OnGripperMoved(from, to);
						wxGetApp().grip_from = gp_Pnt(from[0], from[1], from[2]);
						return;
					}
				}

				// do window selection
				if(!m_just_one)
				{
					//wxGetApp().m_frame->m_graphics->SetCurrent();
					wxGetApp().m_current_viewport->SetXOR();
					if(window_box_exists)wxGetApp().m_current_viewport->DrawWindow(window_box, true); // undraw the window
					window_box.x = button_down_point.x;
					window_box.width = event.GetX() - button_down_point.x;
					window_box.y = wxGetApp().m_current_viewport->GetViewportSize().GetHeight() - button_down_point.y;
					window_box.height = button_down_point.y - event.GetY();
					wxGetApp().m_current_viewport->DrawWindow(window_box, true);// draw the window
					wxGetApp().m_current_viewport->EndXOR();
					window_box_exists = true;
				}
			}
		}
		CurrentPoint = wxPoint(event.GetX(), event.GetY());
	}
	else if(event.Moving())
	{
		CurrentPoint = wxPoint(event.GetX(), event.GetY());
	}

	if(event.GetWheelRotation() != 0)
	{
		double wheel_value = (double)(event.GetWheelRotation());
		double multiplier = wheel_value /1000.0, multiplier2;
		if(wxGetApp().mouse_wheel_forward_away)multiplier = -multiplier;

		// make sure these are actually inverses, so if you
		// zoom in and out the same number of steps, you'll be
		// at the same zoom level again

		if(multiplier > 0) {
			multiplier2 = 1 + multiplier;
		} else {
			multiplier2 = 1/(1 - multiplier);
		}

		wxSize client_size = wxGetApp().m_current_viewport->GetViewportSize();

		double pixelscale_before = wxGetApp().GetPixelScale();
		wxGetApp().m_current_viewport->m_view_point.Scale(multiplier2);
		double pixelscale_after = wxGetApp().GetPixelScale();

		double event_x = event.GetX();
		double event_y = event.GetY();
		double center_x = client_size.GetWidth() / 2.;
		double center_y = client_size.GetHeight() / 2.;

		// how many pixels are we from the center (the center
		// is the point that doesn't move when you zoom)?
		double px = event_x - center_x;
		double py = event_y - center_y;

		// that number of pixels represented how many mm
		// before and after the zoom ...
		double xbefore = px / pixelscale_before;
		double ybefore = py / pixelscale_before;
		double xafter = px / pixelscale_after;
		double yafter = py / pixelscale_after;

		// which caused a change in how many mm at that point
		// on the screen?
		double xchange = xafter - xbefore;
		double ychange = yafter - ybefore;

		// and how many pixels worth of motion is that?
		double x_moved_by = xchange * pixelscale_after;
		double y_moved_by = ychange * pixelscale_after;

		// so move that many pixels to keep the coordinate
		// under the cursor approximately the same
		wxGetApp().m_current_viewport->m_view_point.Shift(wxPoint((int)x_moved_by, (int)y_moved_by), wxPoint(0, 0));
		wxGetApp().m_current_viewport->m_need_refresh = true;
	}

}
Example #21
0
/**
	This method adjusts any parameters that don't make sense.  It should report a list
	of changes in the list of strings.
 */
std::list<wxString> CTapping::DesignRulesAdjustment(const bool apply_changes)
{
	std::list<wxString> changes;

	// Check that we're using a tapping tool and see if it's one of the standard sizes.
	if (m_tool_number > 0)
	{
		CTool *pTool = (CTool *) CTool::Find( m_tool_number );
		if (pTool != NULL)
		{
		    if (pTool->m_params.m_type != CToolParams::eTapTool)
		    {
		        changes.push_back(_("The tapping operation has not selected a tapping tool to use\n"));
		    }
		    else
		    {
		        // It is a tapping tool.  Check to see if the diameter and pitch combination match a standard size.

		        std::list<wxString> tool_check = pTool->DesignRulesAdjustment(apply_changes);
		        for (std::list<wxString>::iterator itChange = tool_check.begin(); itChange != tool_check.end(); itChange++)
		        {
		            changes.push_back(*itChange);
		        }
			
			// see wether tapping direction and spindle direction match
			if (pTool->m_params.m_direction && (m_speed_op_params.m_spindle_speed > 0)) 
			{
			    changes.push_back(_("Left-hand tapping needs a counterclockwise spindle rotation (negative spindle_speed)\n"));
			    if (apply_changes)
			    {
			        changes.push_back(_("Adjusting spindle rotation to counterclockwise.\n"));
				m_speed_op_params.m_spindle_speed  = - m_speed_op_params.m_spindle_speed;
			    } // End if - then
			}
			if (!pTool->m_params.m_direction && (m_speed_op_params.m_spindle_speed < 0) )
			{
			    changes.push_back(_("right-hand tapping needs clockwise spindle rotation (positive spindle_speed)\n"));
			    if (apply_changes)
			    {
				changes.push_back(_("Adjusting spindle rotation to clockwise.\n"));
				m_speed_op_params.m_spindle_speed  = - m_speed_op_params.m_spindle_speed;
			    } // End if - then
			}
		    }
		}
	}


	// Make some special checks if we're using a chamfering bit.
	if (m_tool_number > 0)
	{
		CTool *pTap = (CTool *) CTool::Find( m_tool_number );
		if (pTap != NULL)
		{
			std::vector<CNCPoint> these_locations = CDrilling::FindAllLocations(this);

			if (pTap->m_params.m_type == CToolParams::eTapTool)
			{
				// We need to make sure that the depth of the hole we're drilling is at least
				// as deep as the depth of our tapping operation.

				for (HeeksObj *obj = theApp.m_program->Operations()->GetFirstChild();
					obj != NULL;
					obj = theApp.m_program->Operations()->GetNextChild())
				{
					if (obj->GetType() == DrillingType)
					{
					    CDrilling *pDrilling = (CDrilling *) obj;

						// Make sure we're looking at a hole taped with something
						// more than a centre tap.
						CToolParams::eToolType type = CTool::CutterType( pDrilling->m_tool_number );
						if (	(type == CToolParams::eDrill) ||
							(type == CToolParams::eEndmill) ||
							(type == CToolParams::eSlotCutter) ||
							(type == CToolParams::eBallEndMill))
						{
							// See if any of the other drilling locations line up
							// with our tapping locations.  If so, we must be
							// tapping a previously drilled hole.

							std::vector<CNCPoint> previous_locations = CDrilling::FindAllLocations((CTapping *)obj);
							std::vector<CNCPoint> common_locations;
							std::set_intersection( previous_locations.begin(), previous_locations.end(),
										these_locations.begin(), these_locations.end(),
										std::inserter( common_locations, common_locations.begin() ));
							if (common_locations.size() > 0)
							{
								// We're here.  We must be tapping a hole we've
								// drilled previously.  Check the depths.

								if (pDrilling->m_params.m_depth < m_params.m_depth)
								{
								    wxString change;
								    change << _("ID ") << this->m_id << _(" The tapping operation's depth is greater than the previously drilled hole\n");
								    changes.push_back(change);
								}
							} // End if - then

						} // End if - then
					} // End if - then
				} // End for
			} // End if - then
		} // End if - then
	} // End if - then

	if (m_tool_number > 0)
	{
		// Make sure the hole depth isn't greater than the tool's cutting depth.
		CTool *pTap = (CTool *) CTool::Find( m_tool_number );
		if ((pTap != NULL) && (pTap->m_params.m_cutting_edge_height < m_params.m_depth))
		{
			// The drill bit we've chosen can't cut as deep as we've setup to go.

			if (apply_changes)
			{
#ifdef UNICODE
				std::wostringstream l_ossChange;
#else
				std::ostringstream l_ossChange;
#endif

				l_ossChange << _("Adjusting depth of tapping cycle") << " id='" << m_id << "' " << _("from") << " '"
					<< m_params.m_depth / theApp.m_program->m_units << "' " << _("to") << " "
					<< pTap->m_params.m_cutting_edge_height / theApp.m_program->m_units << "\n";
				changes.push_back(l_ossChange.str().c_str());

				m_params.m_depth = pTap->m_params.m_cutting_edge_height;
			} // End if - then
			else
			{
#ifdef UNICODE
				std::wostringstream l_ossChange;
#else
				std::ostringstream l_ossChange;
#endif

				l_ossChange << _("WARNING") << ": " << _("Tapping") << " (id=" << m_id << ").  " << _("Can't tap hole") << " " << m_params.m_depth / theApp.m_program->m_units << " when the tapping bit's cutting length is only " << pTap->m_params.m_cutting_edge_height << " long\n";
				changes.push_back(l_ossChange.str().c_str());
			} // End if - else
		} // End if - then
	} // End if - then


	return(changes);

} // End DesignRulesAdjustment() method
Example #22
0
static wxString WriteSketchDefn(HeeksObj* sketch)
{
#ifdef UNICODE
	std::wostringstream gcode;
#else
    std::ostringstream gcode;
#endif
    gcode.imbue(std::locale("C"));
	gcode << std::setprecision(10);

	bool started = false;

	double prev_e[3];

	std::list<HeeksObj*> new_spans;
	for(HeeksObj* span = sketch->GetFirstChild(); span; span = sketch->GetNextChild())
	{
		if(span->GetType() == SplineType)
		{
			((HSpline*)span)->ToBiarcs(new_spans, CPocket::max_deviation_for_spline_to_arc);
		}
		else
		{
			new_spans.push_back(span->MakeACopy());
		}
	}

	for(std::list<HeeksObj*>::iterator It = new_spans.begin(); It != new_spans.end(); It++)
	{
		HeeksObj* span_object = *It;

		double s[3] = {0, 0, 0};
		double e[3] = {0, 0, 0};
		double c[3] = {0, 0, 0};

		if(span_object){
			int type = span_object->GetType();

			if(type == LineType || type == ArcType)
			{
				span_object->GetStartPoint(s);
				CNCPoint start(s);

				if(started && (fabs(s[0] - prev_e[0]) > 0.0001 || fabs(s[1] - prev_e[1]) > 0.0001))
				{
					gcode << _T("a.append(c)\n");
					started = false;
				}

				if(!started)
				{
					gcode << _T("c = area.Curve()\n");
					gcode << _T("c.append(area.Vertex(0, area.Point(") << start.X(true) << _T(", ") << start.Y(true) << _T("), area.Point(0, 0)))\n");
					started = true;
				}
				span_object->GetEndPoint(e);
				CNCPoint end(e);

				if(type == LineType)
				{
					gcode << _T("c.append(area.Vertex(0, area.Point(") << end.X(true) << _T(", ") << end.Y(true) << _T("), area.Point(0, 0)))\n");
				}
				else if(type == ArcType)
				{
					span_object->GetCentrePoint(c);
					CNCPoint centre(c);

					double pos[3];
					extract(((HArc*)span_object)->m_axis.Direction(), pos);
					int span_type = (pos[2] >=0) ? 1:-1;
					gcode << _T("c.append(area.Vertex(") << span_type << _T(", area.Point(") << end.X(true) << _T(", ") << end.Y(true);
					gcode << _T("), area.Point(") << centre.X(true) << _T(", ") << centre.Y(true) << _T(")))\n");
				}
				memcpy(prev_e, e, 3*sizeof(double));
			} // End if - then
			else
			{
				if (type == CircleType)
				{
					if(started)
					{
						gcode << _T("a.append(c)\n");
						started = false;
					}

					std::list< std::pair<int, gp_Pnt > > points;
					span_object->GetCentrePoint(c);

					// Setup the four arcs that will make up the circle using UNadjusted
					// coordinates first so that the offsets align with the X and Y axes.
					double radius = ((HCircle*)span_object)->m_radius;

					points.push_back( std::make_pair(0, gp_Pnt( c[0], c[1] + radius, c[2] )) ); // north
					points.push_back( std::make_pair(-1, gp_Pnt( c[0] + radius, c[1], c[2] )) ); // east
					points.push_back( std::make_pair(-1, gp_Pnt( c[0], c[1] - radius, c[2] )) ); // south
					points.push_back( std::make_pair(-1, gp_Pnt( c[0] - radius, c[1], c[2] )) ); // west
					points.push_back( std::make_pair(-1, gp_Pnt( c[0], c[1] + radius, c[2] )) ); // north

					CNCPoint centre(c);

					gcode << _T("c = area.Curve()\n");
					for (std::list< std::pair<int, gp_Pnt > >::iterator l_itPoint = points.begin(); l_itPoint != points.end(); l_itPoint++)
					{
						CNCPoint pnt( l_itPoint->second );

						gcode << _T("c.append(area.Vertex(") << l_itPoint->first << _T(", area.Point(");
						gcode << pnt.X(true) << (_T(", ")) << pnt.Y(true);
						gcode << _T("), area.Point(") << centre.X(true) << _T(", ") << centre.Y(true) << _T(")))\n");
					} // End for
					gcode << _T("a.append(c)\n");
				}
			} // End if - else
		}
	}

	if(started)
	{
		gcode << _T("a.append(c)\n");
		started = false;
	}

	// delete the spans made
	for(std::list<HeeksObj*>::iterator It = new_spans.begin(); It != new_spans.end(); It++)
	{
		HeeksObj* span = *It;
		delete span;
	}

	gcode << _T("\n");
	return(wxString(gcode.str().c_str()));
}
Example #23
0
unsigned int CProfile::GetNumSketches()
{
	unsigned int num_sketches = 0;
#ifdef OP_SKETCHES_AS_CHILDREN
    for (HeeksObj *object = GetFirstChild(); object != NULL; object = GetNextChild())
    {
#else
	for (std::list<int>::iterator It = m_sketches.begin(); It != m_sketches.end(); It++)
    {
		HeeksObj* object = heeksCAD->GetIDObject(SketchType, *It);
#endif
		if(object && object->GetType() == SketchType)num_sketches++;
	}
	return num_sketches;
}

/**
	The old version of the CDrilling object stored references to graphics as type/id pairs
	that get read into the m_symbols list.  The new version stores these graphics references
	as child elements (based on ObjList).  If we read in an old-format file then the m_symbols
	list will have data in it for which we don't have children.  This routine converts
	these type/id pairs into the HeeksObj pointers as children.
 */
#ifdef OP_SKETCHES_AS_CHILDREN
void CProfile::ReloadPointers()
{
	for (Sketches_t::iterator symbol = m_sketches.begin(); symbol != m_sketches.end(); symbol++)
	{
		HeeksObj *object = heeksCAD->GetIDObject( SketchType, *symbol );
		if (object != NULL)
		{
			Add( object, NULL );
		}
	}

	m_sketches.clear();	// We don't want to convert them twice.

	CDepthOp::ReloadPointers();
}
#endif

/**
	If it's an 'inside' profile then we need to make sure the auto_roll_radius is not so large
	that it's going to gouge the part outside the sketch's area.  This routine only
	reduces the auto_roll_radius.  Its value is not changed unless a gouge scenario is detected.
 */
std::list<wxString> CProfile::ConfirmAutoRollRadius(const bool apply_changes)
{
#ifdef UNICODE
			std::wostringstream l_ossChange;
#else
			std::ostringstream l_ossChange;
#endif

	std::list<wxString> changes;

	if (m_profile_params.m_tool_on_side == CProfileParams::eRightOrInside)
	{
		// Look at the dimensions of the sketches as well as the diameter of the bit to decide if
		// our existing m_auto_roll_radius is too big for this profile.  If so, reduce it now.
		CTool *pTool = NULL;
		if ((m_tool_number > 0) && ((pTool = CTool::Find(m_tool_number)) != NULL))
		{
			for (std::list<int>::iterator l_itSketchId = m_sketches.begin(); l_itSketchId != m_sketches.end(); l_itSketchId++)
			{
				HeeksObj *sketch = heeksCAD->GetIDObject( SketchType, *l_itSketchId );
				if (sketch != NULL)
				{
					CBox bounding_box;
					sketch->GetBox( bounding_box );

					double min_distance_across = (bounding_box.Height() < bounding_box.Width())?bounding_box.Height():bounding_box.Width();
					double max_roll_radius = (min_distance_across - (pTool->CuttingRadius() * 2.0)) / 2.0;

					if (max_roll_radius < m_profile_params.m_auto_roll_radius)
					{
						l_ossChange << "Need to adjust auto_roll_radius for profile id=" << m_id << " from "
								<< m_profile_params.m_auto_roll_radius << " to " << max_roll_radius << "\n";
						changes.push_back(l_ossChange.str().c_str());

						if (apply_changes)
						{
							m_profile_params.m_auto_roll_radius = max_roll_radius;
						} // End if - then
					}
				} // End if - then
			} // End for
		} // End if - then
	} // End if - then

	return(changes);

} // End ConfirmAutoRollRadius() method