357 lines
12 KiB
C++
357 lines
12 KiB
C++
/***************************************************************************
|
|
* Copyright (c) Stefan Tröger (stefantroeger@gmx.net) 2014 *
|
|
* *
|
|
* This file is part of the FreeCAD CAx development system. *
|
|
* *
|
|
* This library is free software; you can redistribute it and/or *
|
|
* modify it under the terms of the GNU Library General Public *
|
|
* License as published by the Free Software Foundation; either *
|
|
* version 2 of the License, or (at your option) any later version. *
|
|
* *
|
|
* This library is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU Library General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Library General Public *
|
|
* License along with this library; see the file COPYING.LIB. If not, *
|
|
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
|
* Suite 330, Boston, MA 02111-1307, USA *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
|
|
#include "PreCompiled.h"
|
|
|
|
#ifndef __InventorAll__
|
|
# include "InventorAll.h"
|
|
#endif
|
|
|
|
|
|
#include "View3DViewerPy.h"
|
|
#include <CXX/Objects.hxx>
|
|
#include <Base/Interpreter.h>
|
|
#include <Base/GeometryPyCXX.h>
|
|
#include <Base/VectorPy.h>
|
|
#include <Gui/View3DInventorViewer.h>
|
|
|
|
using namespace Gui;
|
|
|
|
|
|
void View3DInventorViewerPy::init_type()
|
|
{
|
|
behaviors().name("View3DInventorViewerPy");
|
|
behaviors().doc("Python binding class for the 3D viewer class");
|
|
// you must have overwritten the virtual functions
|
|
behaviors().supportRepr();
|
|
behaviors().supportGetattr();
|
|
behaviors().supportSetattr();
|
|
|
|
add_varargs_method("getSoRenderManager",&View3DInventorViewerPy::getSoRenderManager,"getSoRenderManager() -> SoRenderManager\n"
|
|
"Returns the render manager which is used to handle everything related to\n"
|
|
"rendering the scene graph. It can be used to get full control over the\n"
|
|
"render process\n"
|
|
);
|
|
add_varargs_method("getSoEventManager",&View3DInventorViewerPy::getSoEventManager,"getSoEventManager() -> SoEventManager\n"
|
|
"Returns the event manager which is used to handle everything event related in\n"
|
|
"the viewer. It can be used to change the event processing. This must however be\n"
|
|
"done very carefully to not change the user interaction in an unpredictable manner.\n"
|
|
);
|
|
add_varargs_method("getSceneGraph", &View3DInventorViewerPy::getSceneGraph, "getSceneGraph() -> SoNode");
|
|
add_varargs_method("setSceneGraph", &View3DInventorViewerPy::setSceneGraph, "setSceneGraph(SoNode)");
|
|
|
|
add_varargs_method("seekToPoint",&View3DInventorViewerPy::seekToPoint,"seekToPoint(tuple) -> None\n"
|
|
"Initiate a seek action towards the 3D intersection of the scene and the\n"
|
|
"ray from the screen coordinate's point and in the same direction as the\n"
|
|
"camera is pointing. If the tuple has two entries it is interpretet as the\n"
|
|
"screen coordinates xy and the intersection point with the scene is\n"
|
|
"calculated. If three entries are given it is interpretet as the intersection\n"
|
|
"point xyz and the seek is done towards this point"
|
|
);
|
|
add_varargs_method("setFocalDistance",&View3DInventorViewerPy::setFocalDistance,"setFocalDistance(float) -> None\n");
|
|
add_varargs_method("getFocalDistance",&View3DInventorViewerPy::getFocalDistance,"getFocalDistance() -> float\n");
|
|
add_varargs_method("getPoint", &View3DInventorViewerPy::getPoint, "getPoint(x, y) -> Base::Vector(x,y,z)");
|
|
add_varargs_method("getPickRadius", &View3DInventorViewerPy::getPickRadius,
|
|
"getPickRadius(): returns radius of confusion in pixels for picking objects on screen (selection).");
|
|
add_varargs_method("setPickRadius", &View3DInventorViewerPy::setPickRadius,
|
|
"setPickRadius(new_radius): sets radius of confusion in pixels for picking objects on screen (selection).");
|
|
}
|
|
|
|
View3DInventorViewerPy::View3DInventorViewerPy(View3DInventorViewer *vi)
|
|
: _viewer(vi)
|
|
{
|
|
}
|
|
|
|
View3DInventorViewerPy::~View3DInventorViewerPy()
|
|
{
|
|
Base::PyGILStateLocker lock;
|
|
for (std::list<PyObject*>::iterator it = callbacks.begin(); it != callbacks.end(); ++it)
|
|
Py_DECREF(*it);
|
|
}
|
|
|
|
|
|
Py::Object View3DInventorViewerPy::repr()
|
|
{
|
|
std::ostringstream s_out;
|
|
if (!_viewer)
|
|
throw Py::RuntimeError("Cannot print representation of deleted object");
|
|
s_out << "View3DInventorViewer";
|
|
return Py::String(s_out.str());
|
|
}
|
|
|
|
View3DInventorViewerPy::method_varargs_handler View3DInventorViewerPy::pycxx_handler = 0;
|
|
|
|
PyObject *View3DInventorViewerPy::method_varargs_ext_handler(PyObject *_self_and_name_tuple, PyObject *_args)
|
|
{
|
|
try {
|
|
return pycxx_handler(_self_and_name_tuple, _args);
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
catch (const std::exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
catch(...) {
|
|
throw Py::Exception("Unknown C++ exception");
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorViewerPy::getattr(const char * attr)
|
|
{
|
|
if (!_viewer) {
|
|
std::string s;
|
|
std::ostringstream s_out;
|
|
s_out << "Cannot access attribute '" << attr << "' of deleted object";
|
|
throw Py::RuntimeError(s_out.str());
|
|
}
|
|
else {
|
|
Py::Object obj = Py::PythonExtension<View3DInventorViewerPy>::getattr(attr);
|
|
if (PyCFunction_Check(obj.ptr())) {
|
|
PyCFunctionObject* op = reinterpret_cast<PyCFunctionObject*>(obj.ptr());
|
|
if (!pycxx_handler)
|
|
pycxx_handler = op->m_ml->ml_meth;
|
|
op->m_ml->ml_meth = method_varargs_ext_handler;
|
|
}
|
|
return obj;
|
|
}
|
|
}
|
|
|
|
int View3DInventorViewerPy::setattr(const char * attr, const Py::Object & value)
|
|
{
|
|
if (!_viewer) {
|
|
std::string s;
|
|
std::ostringstream s_out;
|
|
s_out << "Cannot access attribute '" << attr << "' of deleted object";
|
|
throw Py::RuntimeError(s_out.str());
|
|
}
|
|
else {
|
|
return Py::PythonExtension<View3DInventorViewerPy>::setattr(attr, value);
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorViewerPy::getSoRenderManager(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
SoRenderManager* manager = _viewer->getSoRenderManager();
|
|
PyObject* proxy = 0;
|
|
proxy = Base::Interpreter().createSWIGPointerObj("pivy.coin", "SoRenderManager *", (void*)manager, 0);
|
|
return Py::Object(proxy, true);
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorViewerPy::getSceneGraph(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
SoNode* scene = _viewer->getSceneGraph();
|
|
PyObject* proxy = 0;
|
|
proxy = Base::Interpreter().createSWIGPointerObj("pivy.coin", "SoSeparator *", (void*)scene, 1);
|
|
scene->ref();
|
|
return Py::Object(proxy, true);
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorViewerPy::setSceneGraph(const Py::Tuple& args)
|
|
{
|
|
PyObject* proxy;
|
|
if (!PyArg_ParseTuple(args.ptr(), "O", &proxy))
|
|
throw Py::Exception();
|
|
|
|
void* ptr = 0;
|
|
try {
|
|
Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoNode *", proxy, &ptr, 0);
|
|
SoNode* node = static_cast<SoNode*>(ptr);
|
|
_viewer->setSceneGraph(node);
|
|
return Py::None();
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorViewerPy::getSoEventManager(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
SoEventManager* manager = _viewer->getSoEventManager();
|
|
PyObject* proxy = 0;
|
|
proxy = Base::Interpreter().createSWIGPointerObj("pivy.coin", "SoEventManager *", (void*)manager, 0);
|
|
return Py::Object(proxy, true);
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorViewerPy::seekToPoint(const Py::Tuple& args)
|
|
{
|
|
PyObject* object;
|
|
if (!PyArg_ParseTuple(args.ptr(), "O", &object))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
const Py::Tuple tuple(object);
|
|
|
|
// If the 3d point is given
|
|
if (tuple.size() == 3) {
|
|
Py::Float x = tuple[0];
|
|
Py::Float y = tuple[1];
|
|
Py::Float z = tuple[2];
|
|
|
|
SbVec3f hitpoint((float)x,(float)y,(float)z);
|
|
_viewer->seekToPoint(hitpoint);
|
|
}
|
|
else {
|
|
Py::Int x(tuple[0]);
|
|
Py::Int y(tuple[1]);
|
|
|
|
SbVec2s hitpoint ((long)x,(long)y);
|
|
_viewer->seekToPoint(hitpoint);
|
|
}
|
|
|
|
return Py::None();
|
|
}
|
|
catch (const Py::Exception&) {
|
|
throw;
|
|
}
|
|
|
|
return Py::None();
|
|
}
|
|
|
|
|
|
Py::Object View3DInventorViewerPy::setFocalDistance(const Py::Tuple& args)
|
|
{
|
|
float distance;
|
|
if (!PyArg_ParseTuple(args.ptr(), "f", &distance))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
SoCamera* cam = _viewer->getSoRenderManager()->getCamera();
|
|
if (cam)
|
|
cam->focalDistance.setValue(distance);
|
|
}
|
|
catch (const Py::Exception&) {
|
|
throw; // re-throw
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
catch (const std::exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
catch(...) {
|
|
throw Py::Exception("Unknown C++ exception");
|
|
}
|
|
|
|
return Py::None();
|
|
}
|
|
|
|
Py::Object View3DInventorViewerPy::getFocalDistance(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
double d = _viewer->getSoRenderManager()->getCamera()->focalDistance.getValue();
|
|
return Py::Float(d);
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
catch (const std::exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
catch(...) {
|
|
throw Py::Exception("Unknown C++ exception");
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorViewerPy::getPoint(const Py::Tuple& args)
|
|
{
|
|
short x,y;
|
|
if (!PyArg_ParseTuple(args.ptr(), "hh", &x, &y)) {
|
|
PyErr_Clear();
|
|
Py::Tuple t(args[0]);
|
|
x = (int)Py::Int(t[0]);
|
|
y = (int)Py::Int(t[1]);
|
|
}
|
|
try {
|
|
SbVec3f pt = _viewer->getPointOnScreen(SbVec2s(x,y));
|
|
return Py::Vector(Base::Vector3f(pt[0], pt[1], pt[2]));
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
catch (const Py::Exception&) {
|
|
throw;
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorViewerPy::getPickRadius(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
double d = _viewer->getPickRadius();
|
|
return Py::Float(d);
|
|
}
|
|
|
|
Py::Object View3DInventorViewerPy::setPickRadius(const Py::Tuple& args)
|
|
{
|
|
float r = 0.0;
|
|
if (!PyArg_ParseTuple(args.ptr(), "f", &r)) {
|
|
throw Py::Exception();
|
|
}
|
|
|
|
if (r < 0.001){
|
|
throw Py::ValueError(std::string("Pick radius is zero or negative; positive number is required."));
|
|
}
|
|
try {
|
|
_viewer->setPickRadius(r);
|
|
return Py::None();
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
catch (const std::exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
catch(...) {
|
|
throw Py::Exception("Unknown C++ exception");
|
|
}
|
|
}
|