Merge branch 'main' into core_LCS3

This commit is contained in:
PaddleStroke
2024-12-13 18:48:35 +01:00
committed by GitHub
20 changed files with 636 additions and 364 deletions

View File

@@ -47,9 +47,11 @@
# include <Inventor/nodes/SoOrthographicCamera.h>
# include <Inventor/nodes/SoPerspectiveCamera.h>
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/SoPickedPoint.h>
#endif
#include <App/Document.h>
#include <App/GeoFeature.h>
#include <Base/Builder3D.h>
#include <Base/Console.h>
#include <Base/Interpreter.h>
@@ -70,8 +72,10 @@
#include "View3DInventorViewer.h"
#include "View3DPy.h"
#include "ViewProvider.h"
#include "ViewProviderDocumentObject.h"
#include "WaitCursor.h"
#include "Utilities.h"
using namespace Gui;
@@ -773,6 +777,97 @@ void View3DInventor::setCurrentViewMode(ViewMode newmode)
}
}
RayPickInfo View3DInventor::getObjInfoRay(Base::Vector3d* startvec, Base::Vector3d* dirvec)
{
double vsx, vsy, vsz;
double vdx, vdy, vdz;
vsx = startvec->x;
vsy = startvec->y;
vsz = startvec->z;
vdx = dirvec->x;
vdy = dirvec->y;
vdz = dirvec->z;
// near plane clipping is required to avoid false intersections
float near = 0.1;
RayPickInfo ret = {.isValid = false,
.point = Base::Vector3d(),
.document = "",
.object = "",
.parentObject = std::nullopt,
.component = std::nullopt,
.subName = std::nullopt};
SoRayPickAction action(getViewer()->getSoRenderManager()->getViewportRegion());
action.setRay(SbVec3f(vsx, vsy, vsz), SbVec3f(vdx, vdy, vdz), near);
action.apply(getViewer()->getSoRenderManager()->getSceneGraph());
SoPickedPoint* Point = action.getPickedPoint();
if (!Point) {
return ret;
}
ret.point = Base::convertTo<Base::Vector3d>(Point->getPoint());
ViewProvider* vp = getViewer()->getViewProviderByPath(Point->getPath());
if (vp && vp->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) {
if (!vp->isSelectable()) {
return ret;
}
auto vpd = static_cast<ViewProviderDocumentObject*>(vp);
if (vp->useNewSelectionModel()) {
std::string subname;
if (!vp->getElementPicked(Point, subname)) {
return ret;
}
auto obj = vpd->getObject();
if (!obj) {
return ret;
}
if (!subname.empty()) {
App::ElementNamePair elementName;
auto sobj = App::GeoFeature::resolveElement(obj, subname.c_str(), elementName);
if (!sobj) {
return ret;
}
if (sobj != obj) {
ret.parentObject = obj->getExportName();
ret.subName = subname;
obj = sobj;
}
subname = !elementName.oldName.empty() ? elementName.oldName : elementName.newName;
}
ret.document = obj->getDocument()->getName();
ret.object = obj->getNameInDocument();
ret.component = subname;
ret.isValid = true;
}
else {
ret.document = vpd->getObject()->getDocument()->getName();
ret.object = vpd->getObject()->getNameInDocument();
// search for a SoFCSelection node
SoFCDocumentObjectAction objaction;
objaction.apply(Point->getPath());
if (objaction.isHandled()) {
ret.component = objaction.componentName.getString();
}
}
// ok, found the node of interest
ret.isValid = true;
}
else {
// custom nodes not in a VP: search for a SoFCSelection node
SoFCDocumentObjectAction objaction;
objaction.apply(Point->getPath());
if (objaction.isHandled()) {
ret.document = objaction.documentName.getString();
ret.object = objaction.objectName.getString();
ret.component = objaction.componentName.getString();
// ok, found the node of interest
ret.isValid = true;
}
}
return ret;
}
bool View3DInventor::eventFilter(QObject* watched, QEvent* e)
{
// As long as this widget is a top-level window (either in 'TopLevel' or 'FullScreen' mode) we

View File

@@ -31,6 +31,7 @@
#include "MDIView.h"
#include "Base/Vector3D.h"
class QPrinter;
class QStackedWidget;
@@ -43,6 +44,16 @@ class View3DPy;
class View3DSettings;
class NaviCubeSettings;
struct RayPickInfo
{
bool isValid;
Base::Vector3d point;
std::string document;
std::string object;
std::optional<std::string> parentObject;
std::optional<std::string> component;
std::optional<std::string> subName;
};
class GuiExport GLOverlayWidget : public QWidget
{
Q_OBJECT
@@ -98,6 +109,8 @@ public:
* GL widget to get all key events in \a TopLevel or \a Fullscreen mode.
*/
void setCurrentViewMode(ViewMode b) override;
RayPickInfo getObjInfoRay(Base::Vector3d* startvec,
Base::Vector3d* dirvec);
bool setCamera(const char* pCamera);
void toggleClippingPlane();
bool hasClippingPlane() const;

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 {

View File

@@ -95,6 +95,7 @@ public:
Py::Object getObjectInfo(const Py::Tuple&);
Py::Object getObjectsInfo(const Py::Tuple&);
Py::Object getSize();
Py::Object getObjectInfoRay(const Py::Tuple&);
Py::Object getPointOnFocalPlane(const Py::Tuple&);
Py::Object projectPointToLine(const Py::Tuple&);
Py::Object getPointOnViewport(const Py::Tuple&);