HeeksObj *CSketch::Parallel( const double distance ) { try { double deviation = heekscad_interface.GetTolerance(); std::list<TopoDS_Shape> wires; if(ConvertSketchToFaceOrWire(this, wires, false)) { HeeksObj *sketch = heekscad_interface.NewSketch(); for(std::list<TopoDS_Shape>::iterator It2 = wires.begin(); It2 != wires.end(); It2++) { TopoDS_Shape& wire = *It2; BRepOffsetAPI_MakeOffset offset_wire(TopoDS::Wire(wire)); offset_wire.Perform(distance); ConvertWireToSketch(TopoDS::Wire(offset_wire.Shape()), sketch, deviation); } return(sketch); } } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); // wxMessageBox(wxString(_("Error making offset")) + _T(": ") + Ctt(e->GetMessageString())); return(NULL); } return(NULL); }
/** 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); }