Gui: add method to select objects with a 3D ray (#16789)

* Implementation of ray picking method for 3d picking

* Ray picking logic moved to C++

(cherry picked from commit ed23214c0bce7b70fd1003a7c4612e2d0d7da4cb)

* formatting, do not return unecessary dict keys, near plane clipping
This commit is contained in:
kwahoo2
2024-12-13 18:32:37 +01:00
committed by GitHub
parent c8530ae0a8
commit 64b24cd27d
4 changed files with 165 additions and 0 deletions

View File

@@ -158,6 +158,14 @@ void View3DInventorPy::init_type()
"\n"
"Does the same as getObjectInfo() but returns a list of dictionaries or None.\n");
add_noargs_method("getSize",&View3DInventorPy::getSize,"getSize()");
add_varargs_method("getObjectInfoRay",&View3DInventorPy::getObjectInfoRay,
"getObjectInfoRay(tuple(3D vector,3D vector) or tuple of 6 floats) -> dictionary or None\n"
"\n"
"Vectors represent start point and direction of intersection ray\n"
"Return a dictionary with the name of document, object and component. The\n"
"dictionary also contains the coordinates of the appropriate 3d point of\n"
"the underlying geometry in the scenegraph.\n"
"If no geometry was found 'None' is returned, instead.\n");
add_varargs_method("getPoint",&View3DInventorPy::getPointOnFocalPlane,
"Same as getPointOnFocalPlane");
add_varargs_method("getPointOnFocalPlane",&View3DInventorPy::getPointOnFocalPlane,
@@ -1501,6 +1509,54 @@ Py::Object View3DInventorPy::getObjectsInfo(const Py::Tuple& args)
}
}
Py::Object View3DInventorPy::getObjectInfoRay(const Py::Tuple& args)
{
PyObject* vs;
PyObject* vd;
double vsx, vsy, vsz;
double vdx, vdy, vdz;
Py::Object ret = Py::None();
if (PyArg_ParseTuple(args.ptr(),
"O!O!",
&Base::VectorPy::Type,
&vs,
&Base::VectorPy::Type,
&vd)) {
Base::Vector3d* startvec = static_cast<Base::VectorPy*>(vs)->getVectorPtr();
Base::Vector3d* dirvec = static_cast<Base::VectorPy*>(vd)->getVectorPtr();
try {
RayPickInfo pinfo = getView3DIventorPtr()->getObjInfoRay(startvec, dirvec);
if (!pinfo.isValid) {
return ret;
}
Py::Dict dict;
dict.setItem("PickedPoint", Py::asObject(new Base::VectorPy(pinfo.point)));
dict.setItem("Document", Py::String(pinfo.document));
dict.setItem("Object", Py::String(pinfo.object));
if (pinfo.parentObject) {
dict.setItem("ParentObject", Py::String(pinfo.parentObject.value()));
}
if (pinfo.component) {
dict.setItem("Component", Py::String(pinfo.component.value()));
}
if (pinfo.subName) {
dict.setItem("SubName", Py::String(pinfo.subName.value()));
}
ret = dict;
}
catch (const Py::Exception&) {
throw;
}
}
else {
PyErr_Clear();
if (!PyArg_ParseTuple(args.ptr(), "dddddd", &vsx, &vsy, &vsz, &vdx, &vdy, &vdz)) {
throw Py::TypeError("Wrong arguments, two Vectors or six floats expected");
}
}
return ret;
}
Py::Object View3DInventorPy::getSize()
{
try {