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; } }
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"); } } }