PyObject* TopoShapeFacePy::validate(PyObject *args)
{
    if (!PyArg_ParseTuple(args, ""))
        return 0;

    try {
        const TopoDS_Face& face = TopoDS::Face(getTopoShapePtr()->getShape());
        BRepCheck_Analyzer aChecker(face);
        if (!aChecker.IsValid()) {
            TopoDS_Wire outerwire = ShapeAnalysis::OuterWire(face);
            TopTools_IndexedMapOfShape myMap;
            myMap.Add(outerwire);

            TopExp_Explorer xp(face,TopAbs_WIRE);
            ShapeFix_Wire fix;
            fix.SetFace(face);
            fix.Load(outerwire);
            fix.Perform();
            BRepBuilderAPI_MakeFace mkFace(fix.WireAPIMake());
            while (xp.More()) {
                if (!myMap.Contains(xp.Current())) {
                    fix.Load(TopoDS::Wire(xp.Current()));
                    fix.Perform();
                    mkFace.Add(fix.WireAPIMake());
                }
                xp.Next();
            }

            aChecker.Init(mkFace.Face());
            if (!aChecker.IsValid()) {
                ShapeFix_Shape fix(mkFace.Face());
                fix.SetPrecision(Precision::Confusion());
                fix.SetMaxTolerance(Precision::Confusion());
                fix.SetMaxTolerance(Precision::Confusion());
                fix.Perform();
                fix.FixWireTool()->Perform();
                fix.FixFaceTool()->Perform();
                getTopoShapePtr()->setShape(fix.Shape());
            }
            else {
                getTopoShapePtr()->setShape(mkFace.Face());
            }
        }

        Py_Return;
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
        return 0;
    }
}
예제 #2
0
PyObject* TopoShapeWirePy::fixWire(PyObject *args)
{
    PyObject* face=0;
    double tol = Precision::Confusion();
    if (!PyArg_ParseTuple(args, "|O!d",&(TopoShapeFacePy::Type), &face, &tol))
        return 0;

    try {
        ShapeFix_Wire aFix;
        const TopoDS_Wire& w = TopoDS::Wire(getTopoShapePtr()->_Shape);

        if (face) {
            const TopoDS_Face& f = TopoDS::Face(static_cast<TopoShapePy*>(face)->getTopoShapePtr()->_Shape);
            aFix.Init(w, f, tol);
        }
        else {
            aFix.SetPrecision(tol);
            aFix.Load(w);
        }

        aFix.FixReorder();
        aFix.FixConnected();
        aFix.FixClosed();
        getTopoShapePtr()->_Shape = aFix.Wire();

        Py_Return;
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PyExc_Exception, e->GetMessageString());
        return 0;
    }
}
예제 #3
0
TopoDS_Face FaceMakerCheese::validateFace(const TopoDS_Face& face)
{
    BRepCheck_Analyzer aChecker(face);
    if (!aChecker.IsValid()) {
        TopoDS_Wire outerwire = ShapeAnalysis::OuterWire(face);
        TopTools_IndexedMapOfShape myMap;
        myMap.Add(outerwire);

        TopExp_Explorer xp(face,TopAbs_WIRE);
        ShapeFix_Wire fix;
        fix.SetFace(face);
        fix.Load(outerwire);
        fix.Perform();
        BRepBuilderAPI_MakeFace mkFace(fix.WireAPIMake());
        while (xp.More()) {
            if (!myMap.Contains(xp.Current())) {
                fix.Load(TopoDS::Wire(xp.Current()));
                fix.Perform();
                mkFace.Add(fix.WireAPIMake());
            }
            xp.Next();
        }

        aChecker.Init(mkFace.Face());
        if (!aChecker.IsValid()) {
            ShapeFix_Shape fix(mkFace.Face());
            fix.SetPrecision(Precision::Confusion());
            fix.SetMaxTolerance(Precision::Confusion());
            fix.SetMaxTolerance(Precision::Confusion());
            fix.Perform();
            fix.FixWireTool()->Perform();
            fix.FixFaceTool()->Perform();
            TopoDS_Face fixedFace = TopoDS::Face(fix.Shape());
            aChecker.Init(fixedFace);
            if (!aChecker.IsValid())
                Standard_Failure::Raise("Failed to validate broken face");
            return fixedFace;
        }
        return mkFace.Face();
    }

    return face;
}
예제 #4
0
void Extrusion::makeDraft(ExtrusionParameters params, const TopoDS_Shape& shape, std::list<TopoDS_Shape>& drafts)
{
    double distanceFwd = tan(params.taperAngleFwd)*params.lengthFwd;
    double distanceRev = tan(params.taperAngleRev)*params.lengthRev;

    gp_Vec vecFwd = gp_Vec(params.dir)*params.lengthFwd;
    gp_Vec vecRev = gp_Vec(params.dir.Reversed())*params.lengthRev;

    bool bFwd = fabs(params.lengthFwd) > Precision::Confusion();
    bool bRev = fabs(params.lengthRev) > Precision::Confusion();
    bool bMid = !bFwd || !bRev || params.lengthFwd*params.lengthRev > 0.0; //include the source shape as loft section?

    TopoDS_Wire sourceWire;
    if (shape.IsNull())
        Standard_Failure::Raise("Not a valid shape");
    if (shape.ShapeType() == TopAbs_WIRE) {
        ShapeFix_Wire aFix;
        aFix.Load(TopoDS::Wire(shape));
        aFix.FixReorder();
        aFix.FixConnected();
        aFix.FixClosed();
        sourceWire = aFix.Wire();
    }
    else if (shape.ShapeType() == TopAbs_FACE) {
        TopoDS_Wire outerWire = ShapeAnalysis::OuterWire(TopoDS::Face(shape));
        sourceWire = outerWire;
    }
    else if (shape.ShapeType() == TopAbs_COMPOUND) {
        TopoDS_Iterator it(shape);
        for (; it.More(); it.Next()) {
            makeDraft(params, it.Value(), drafts);
        }
    }
    else {
        Standard_Failure::Raise("Only a wire or a face is supported");
    }

    if (!sourceWire.IsNull()) {
        std::list<TopoDS_Wire> list_of_sections;

        //first. add wire for reversed part of extrusion
        if (bRev){
            gp_Vec translation = vecRev;
            double offset = distanceRev;

            BRepOffsetAPI_MakeOffset mkOffset;
#if OCC_VERSION_HEX >= 0x060800
            mkOffset.Init(GeomAbs_Arc);
#endif
#if OCC_VERSION_HEX >= 0x070000
            mkOffset.Init(GeomAbs_Intersection);
#endif
            gp_Trsf mat;
            mat.SetTranslation(translation);
            TopLoc_Location loc(mat);
            TopoDS_Wire movedSourceWire = TopoDS::Wire(sourceWire.Moved(loc));

            TopoDS_Shape offsetShape;
            if (fabs(offset)>Precision::Confusion()){
                mkOffset.AddWire(movedSourceWire);
                mkOffset.Perform(offset);

                offsetShape = mkOffset.Shape();
            } else {
                //stupid OCC doesn't understand, what to do when offset value is zero =/
                offsetShape = movedSourceWire;
            }

            if (offsetShape.IsNull())
                Standard_Failure::Raise("Tapered shape is empty");
            TopAbs_ShapeEnum type = offsetShape.ShapeType();
            if (type == TopAbs_WIRE) {
                list_of_sections.push_back(TopoDS::Wire(offsetShape));
            }
            else if (type == TopAbs_EDGE) {
                BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(offsetShape));
                list_of_sections.push_back(mkWire.Wire());
            }
            else {
                Standard_Failure::Raise("Tapered shape type is not supported");
            }
        }

        //next. Add source wire as middle section. Order is important.
        if (bMid){
            list_of_sections.push_back(sourceWire);
        }

        //finally. Forward extrusion offset wire.
        if (bFwd){
            gp_Vec translation = vecFwd;
            double offset = distanceFwd;

            BRepOffsetAPI_MakeOffset mkOffset;
#if OCC_VERSION_HEX >= 0x060800
            mkOffset.Init(GeomAbs_Arc);
#endif
#if OCC_VERSION_HEX >= 0x070000
            mkOffset.Init(GeomAbs_Intersection);
#endif
            gp_Trsf mat;
            mat.SetTranslation(translation);
            TopLoc_Location loc(mat);
            TopoDS_Wire movedSourceWire = TopoDS::Wire(sourceWire.Moved(loc));

            TopoDS_Shape offsetShape;
            if (fabs(offset)>Precision::Confusion()){
                mkOffset.AddWire(movedSourceWire);
                mkOffset.Perform(offset);

                offsetShape = mkOffset.Shape();
            } else {
                //stupid OCC doesn't understand, what to do when offset value is zero =/
                offsetShape = movedSourceWire;
            }

            if (offsetShape.IsNull())
                Standard_Failure::Raise("Tapered shape is empty");
            TopAbs_ShapeEnum type = offsetShape.ShapeType();
            if (type == TopAbs_WIRE) {
                list_of_sections.push_back(TopoDS::Wire(offsetShape));
            }
            else if (type == TopAbs_EDGE) {
                BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(offsetShape));
                list_of_sections.push_back(mkWire.Wire());
            }
            else {
                Standard_Failure::Raise("Tapered shape type is not supported");
            }
        }

        //make loft
        BRepOffsetAPI_ThruSections mkGenerator(params.solid ? Standard_True : Standard_False, /*ruled=*/Standard_True);
        for (std::list<TopoDS_Wire>::const_iterator it = list_of_sections.begin(); it != list_of_sections.end(); ++it) {
            const TopoDS_Wire &wire = *it;
            mkGenerator.AddWire(wire);
        }

        try {
#if defined(__GNUC__) && defined (FC_OS_LINUX)
            Base::SignalException se;
#endif
            mkGenerator.Build();
            drafts.push_back(mkGenerator.Shape());
        }
        catch (Standard_Failure &){
            throw;
        }
        catch (...) {
            throw Base::Exception("Unknown exception from BRepOffsetAPI_ThruSections");
        }
    }
}
예제 #5
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
                }
			}
		}
	}
예제 #6
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);
}