给FreeCAD的开放api函数做重载

FreeCAD对opencascasde的开放程度有限,有时候我们需要occ函数并没有在FreeCAD中开放,于是我们可以采取修改FreeCAD源代码的方式来增强FreeCAD的某个python函数的功能。看如下示例:

PyObject* GeometryCurvePy::toShape(PyObject *args)
{
    Handle(Geom_Geometry) g = getGeometryPtr()->handle();
    Handle(Geom_Curve) c = Handle(Geom_Curve)::DownCast(g);
    try {
        if (!c.IsNull()) {
            double u,v;
            u=c->FirstParameter();
            v=c->LastParameter();
            PyObject* pcVertex0;
            PyObject* pcVertex1;
            if (!PyArg_ParseTuple(args, "|dd", &u,&v)){
                return 0;
              BRepBuilderAPI_MakeEdge mkBuilder(c, u, v);
              TopoDS_Shape sh = mkBuilder.Shape();
              return new TopoShapeEdgePy(new TopoShape(sh));
            }         
        }              
    }
    catch (Standard_Failure& e) {                                        
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
        return 0;             
    }

    PyErr_SetString(PartExceptionOCCError, "Geometry is not a curve");
    return 0;                                               
}

这个函数是原FreeCAD中GeometryCurvePy.cpp的toShape函数。我们的目标是让其可以接收四个参数的传入:两个vertex和两个浮点数的函数。修改结果如下:

PyObject* GeometryCurvePy::toShape(PyObject *args)
{
    Handle(Geom_Geometry) g = getGeometryPtr()->handle();
    Handle(Geom_Curve) c = Handle(Geom_Curve)::DownCast(g);
    try {
        if (!c.IsNull()) {
            double u,v;
            u=c->FirstParameter();
            v=c->LastParameter();
            PyObject* pcVertex0;
            PyObject* pcVertex1;
            if (PyArg_ParseTuple(args, "|dd", &u,&v)){
                //return 0;
              BRepBuilderAPI_MakeEdge mkBuilder(c, u, v);
              TopoDS_Shape sh = mkBuilder.Shape();
              return new TopoShapeEdgePy(new TopoShape(sh));
            }
                       
            PyErr_Clear();
            if(PyArg_ParseTuple(args, "O!O!dd", &(Part::TopoShapeVertexPy::Type), &pcVertex0,
              &(Part::TopoShapeVertexPy::Type), &pcVertex1, &u, &v)){                                   
              TopoShape* shape1 = static_cast<TopoShapePy*>(pcVertex0)->getTopoShapePtr();
              TopoShape* shape2 = static_cast<TopoShapePy*>(pcVertex1)->getTopoShapePtr();
              const TopoDS_Vertex& v1 = TopoDS::Vertex(shape1->getShape());  
              const TopoDS_Vertex& v2 = TopoDS::Vertex(shape2->getShape());                 


              BRepBuilderAPI_MakeEdge mkBuilder(c, v1, v2, u, v);                         
              TopoDS_Shape sh = mkBuilder.Shape();
              return new TopoShapeEdgePy(new TopoShape(sh));
            }else
              return 0; 
        }              
    }
    catch (Standard_Failure& e) {                                        
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
        return 0;             
    }

    PyErr_SetString(PartExceptionOCCError, "Geometry is not a curve");
    return 0;                                               
}

注意,修改后的代码中的PyErr_Clear()函数。这个函数的调用非常重要。否则,上一步的参数校验错误会遗留下来,导致后面的PyArg_ParseTuple函数不可能成功返回true。

发表评论

邮箱地址不会被公开。 必填项已用*标注