diff --git a/src/Mod/Part/App/TopoShapePy.xml b/src/Mod/Part/App/TopoShapePy.xml index 53440bd64..cf2351692 100644 --- a/src/Mod/Part/App/TopoShapePy.xml +++ b/src/Mod/Part/App/TopoShapePy.xml @@ -367,6 +367,13 @@ Boolean indicates if the point lying directly on a face is considered to be insi Removes redundant edges from the B-REP model + + + Find the minimum distance to another shape. +distToShape(Shape s): Returns a list of minimum distance and solution point pairs - [mindist, (pointonthis,supporttype, +pointons,supporttype),(...),...] + + Returns a SubElement diff --git a/src/Mod/Part/App/TopoShapePyImp.cpp b/src/Mod/Part/App/TopoShapePyImp.cpp index f499dbce5..eaabc58f3 100644 --- a/src/Mod/Part/App/TopoShapePyImp.cpp +++ b/src/Mod/Part/App/TopoShapePyImp.cpp @@ -34,6 +34,8 @@ # include # include # include +# include +# include # include # include # include @@ -1452,6 +1454,138 @@ PyObject* TopoShapePy::getElement(PyObject *args) return 0; } +PyObject* _getSupportIndex(char* suppStr, TopoShape* ts, TopoDS_Shape suppShape) { + std::stringstream ss; + TopoDS_Shape subShape; + + unsigned long nSubShapes = ts->countSubShapes(suppStr); + PyObject* pSupportIndex = PyInt_FromLong(-1); + for (unsigned long j=1; j<=nSubShapes; j++){ + ss.str(""); + ss << suppStr << j; + subShape = ts->getSubShape(ss.str().c_str()); + if (subShape.IsEqual(suppShape)) { + pSupportIndex = PyInt_FromLong(j-1); + break; + } + } + return pSupportIndex; +} + +PyObject* TopoShapePy::distToShape(PyObject *args) +{ + PyObject* ps2; + PyObject *soln,*pPt1,*pPt2,*pSuppType1,*pSuppType2, + *pSupportIndex1, *pSupportIndex2, *pParm1, *pParm2; + gp_Pnt P1,P2; + BRepExtrema_SupportType supportType1,supportType2; + TopoDS_Shape suppS1,suppS2; + Standard_Real minDist = -1, t1,t2,u1,v1,u2,v2; + + if (!PyArg_ParseTuple(args, "O!",&(TopoShapePy::Type), &ps2)) + return 0; + + const TopoDS_Shape& s1 = getTopoShapePtr()->_Shape; + TopoShape* ts1 = getTopoShapePtr(); + const TopoDS_Shape& s2 = static_cast(ps2)->getTopoShapePtr()->_Shape; + TopoShape* ts2 = static_cast(ps2)->getTopoShapePtr(); + + if (s2.IsNull()) { + PyErr_SetString(PyExc_TypeError, "distToShape: Shape parameter is invalid"); + return 0; + } + BRepExtrema_DistShapeShape extss(s1, s2); + if (!extss.IsDone()) { + PyErr_SetString(PyExc_TypeError, "BRepExtrema_DistShapeShape failed"); + return 0; + } + PyObject* solutions = PyList_New(0); + unsigned long count = extss.NbSolution(); + if (count != 0) { + minDist = extss.Value(); + //extss.Dump(std::cout); + for (int i=1; i<= count; i++) { + P1 = extss.PointOnShape1(i); + pPt1 = new Base::VectorPy(new Base::Vector3d(P1.X(),P1.Y(),P1.Z())); + supportType1 = extss.SupportTypeShape1(i); + suppS1 = extss.SupportOnShape1(i); + switch (supportType1) { + case BRepExtrema_IsVertex: + pSuppType1 = PyString_FromString("Vertex"); + pSupportIndex1 = _getSupportIndex("Vertex",ts1,suppS1); + pParm1 = Py_None; + break; + case BRepExtrema_IsOnEdge: + pSuppType1 = PyString_FromString("Edge"); + pSupportIndex1 = _getSupportIndex("Edge",ts1,suppS1); + extss.ParOnEdgeS1(i,t1); + pParm1 = PyFloat_FromDouble(t1); + break; + case BRepExtrema_IsInFace: + pSuppType1 = PyString_FromString("Face"); + pSupportIndex1 = _getSupportIndex("Face",ts1,suppS1); + extss.ParOnFaceS1(i,u1,v1); + pParm1 = PyTuple_New(2); + PyTuple_SetItem(pParm1,0,PyFloat_FromDouble(u1)); + PyTuple_SetItem(pParm1,1,PyFloat_FromDouble(v1)); + break; + default: + Base::Console().Message("distToShape: supportType1 is unknown: %d \n",supportType1); + pSuppType1 = PyString_FromString("Unknown"); + pSupportIndex1 = PyInt_FromLong(-1); + pParm1 = Py_None; + } + + P2 = extss.PointOnShape2(i); + pPt2 = new Base::VectorPy(new Base::Vector3d(P2.X(),P2.Y(),P2.Z())); + supportType2 = extss.SupportTypeShape2(i); + suppS2 = extss.SupportOnShape2(i); + switch (supportType2) { + case BRepExtrema_IsVertex: + pSuppType2 = PyString_FromString("Vertex"); + pSupportIndex2 = _getSupportIndex("Vertex",ts2,suppS2); + pParm2 = Py_None; + break; + case BRepExtrema_IsOnEdge: + pSuppType2 = PyString_FromString("Edge"); + pSupportIndex2 = _getSupportIndex("Edge",ts2,suppS2); + extss.ParOnEdgeS2(i,t2); + pParm2 = PyFloat_FromDouble(t2); + break; + case BRepExtrema_IsInFace: + pSuppType2 = PyString_FromString("Face"); + pSupportIndex2 = _getSupportIndex("Face",ts2,suppS2); + extss.ParOnFaceS2(i,u2,v2); + pParm2 = PyTuple_New(2); + PyTuple_SetItem(pParm2,0,PyFloat_FromDouble(u2)); + PyTuple_SetItem(pParm2,1,PyFloat_FromDouble(v2)); + break; + default: + Base::Console().Message("distToShape: supportType2 is unknown: %d \n",supportType1); + pSuppType2 = PyString_FromString("Unknown"); + pSupportIndex2 = PyInt_FromLong(-1); + } + soln = PyTuple_New(8); + PyTuple_SetItem(soln,0,pPt1); + PyTuple_SetItem(soln,1,pSuppType1); + PyTuple_SetItem(soln,2,pSupportIndex1); + PyTuple_SetItem(soln,3,pParm1); + PyTuple_SetItem(soln,4,pPt2); + PyTuple_SetItem(soln,5,pSuppType2); + PyTuple_SetItem(soln,6,pSupportIndex2); + PyTuple_SetItem(soln,7,pParm2); + int PyErr = PyList_Append(solutions, soln); + } + } + else { + PyErr_SetString(PyExc_TypeError, "distToShape: No Solutions Found."); + return 0; + } + return Py_BuildValue("dO", minDist, solutions); +} + +// End of Methods, Start of Attributes + #if 0 // see ComplexGeoDataPy::Matrix which does the same Py::Object TopoShapePy::getLocation(void) const {