
-removes all soqtviewer references -create a quarter adaptor class which implements missing functionality -adopts freecad code to make use of SoRenderManager and changed View3DInventorViewer interface
2326 lines
81 KiB
C++
2326 lines
81 KiB
C++
/***************************************************************************
|
|
* Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2002 *
|
|
* *
|
|
* 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"
|
|
# include <sstream>
|
|
# include <QImage>
|
|
# include <QGLFramebufferObject>
|
|
# include <Inventor/SbViewVolume.h>
|
|
# include <Inventor/nodes/SoCamera.h>
|
|
#endif
|
|
|
|
|
|
#include "View3DPy.h"
|
|
#include "ViewProviderDocumentObject.h"
|
|
#include "ViewProviderExtern.h"
|
|
#include "Application.h"
|
|
#include "Document.h"
|
|
#include "NavigationStyle.h"
|
|
#include "SoFCSelection.h"
|
|
#include "SoFCSelectionAction.h"
|
|
#include "SoFCOffscreenRenderer.h"
|
|
#include "SoFCVectorizeSVGAction.h"
|
|
#include "SoFCVectorizeU3DAction.h"
|
|
#include "SoFCDB.h"
|
|
#include "View3DInventor.h"
|
|
#include "View3DInventorViewer.h"
|
|
|
|
#include <Base/Console.h>
|
|
#include <Base/Exception.h>
|
|
#include <Base/Interpreter.h>
|
|
#include <Base/PlacementPy.h>
|
|
#include <Base/Rotation.h>
|
|
#include <Base/RotationPy.h>
|
|
#include <Base/VectorPy.h>
|
|
#include <Base/GeometryPyCXX.h>
|
|
|
|
#include <App/Document.h>
|
|
#include <App/DocumentObject.h>
|
|
#include <CXX/Objects.hxx>
|
|
|
|
using namespace Gui;
|
|
|
|
|
|
void View3DInventorPy::init_type()
|
|
{
|
|
behaviors().name("View3DInventorPy");
|
|
behaviors().doc("Python binding class for the Inventor viewer class");
|
|
// you must have overwritten the virtual functions
|
|
behaviors().supportRepr();
|
|
behaviors().supportGetattr();
|
|
behaviors().supportSetattr();
|
|
|
|
add_varargs_method("message",&View3DInventorPy::message,"message()");
|
|
add_varargs_method("fitAll",&View3DInventorPy::fitAll,"fitAll()");
|
|
|
|
add_varargs_method("viewBottom",&View3DInventorPy::viewBottom,"viewBottom()");
|
|
add_varargs_method("viewFront",&View3DInventorPy::viewFront,"viewFront()");
|
|
add_varargs_method("viewLeft",&View3DInventorPy::viewLeft,"viewLeft()");
|
|
add_varargs_method("viewRear",&View3DInventorPy::viewRear,"viewRear()");
|
|
add_varargs_method("viewRight",&View3DInventorPy::viewRight,"viewRight()");
|
|
add_varargs_method("viewTop",&View3DInventorPy::viewTop,"viewTop()");
|
|
add_varargs_method("viewAxometric",&View3DInventorPy::viewAxometric,"viewAxometric()");
|
|
add_varargs_method("viewRotateLeft",&View3DInventorPy::viewRotateLeft,"viewRotateLeft()");
|
|
add_varargs_method("viewRotateRight",&View3DInventorPy::viewRotateRight,"viewRotateRight()");
|
|
add_varargs_method("zoomIn",&View3DInventorPy::zoomIn,"zoomIn()");
|
|
add_varargs_method("zoomOut",&View3DInventorPy::zoomOut,"zoomOut()");
|
|
add_varargs_method("viewPosition",&View3DInventorPy::viewPosition,"viewPosition()");
|
|
add_varargs_method("startAnimating",&View3DInventorPy::startAnimating,"startAnimating()");
|
|
add_varargs_method("stopAnimating",&View3DInventorPy::stopAnimating,"stopAnimating()");
|
|
add_varargs_method("setAnimationEnabled",&View3DInventorPy::setAnimationEnabled,"setAnimationEnabled()");
|
|
add_varargs_method("isAnimationEnabled",&View3DInventorPy::isAnimationEnabled,"isAnimationEnabled()");
|
|
add_varargs_method("dump",&View3DInventorPy::dump,"dump()");
|
|
add_varargs_method("dumpNode",&View3DInventorPy::dumpNode,"dumpNode(node)");
|
|
add_varargs_method("setStereoType",&View3DInventorPy::setStereoType,"setStereoType()");
|
|
add_varargs_method("getStereoType",&View3DInventorPy::getStereoType,"getStereoType()");
|
|
add_varargs_method("listStereoTypes",&View3DInventorPy::listStereoTypes,"listStereoTypes()");
|
|
add_varargs_method("saveImage",&View3DInventorPy::saveImage,"saveImage()");
|
|
add_varargs_method("saveVectorGraphic",&View3DInventorPy::saveVectorGraphic,"saveVectorGraphic()");
|
|
add_varargs_method("getCamera",&View3DInventorPy::getCamera,"getCamera()");
|
|
add_varargs_method("getCameraNode",&View3DInventorPy::getCameraNode,"getCameraNode()");
|
|
add_varargs_method("getViewDirection",&View3DInventorPy::getViewDirection,"getViewDirection()");
|
|
add_varargs_method("setCamera",&View3DInventorPy::setCamera,"setCamera()");
|
|
add_varargs_method("setCameraOrientation",&View3DInventorPy::setCameraOrientation,"setCameraOrientation()");
|
|
add_varargs_method("getCameraOrientation",&View3DInventorPy::getCameraOrientation,"getCameraOrientation()");
|
|
add_varargs_method("getCameraType",&View3DInventorPy::getCameraType,"getCameraType()");
|
|
add_varargs_method("setCameraType",&View3DInventorPy::setCameraType,"setCameraType()");
|
|
add_varargs_method("listCameraTypes",&View3DInventorPy::listCameraTypes,"listCameraTypes()");
|
|
add_varargs_method("getCursorPos",&View3DInventorPy::getCursorPos,
|
|
"getCursorPos() -> tuple of integers\n"
|
|
"\n"
|
|
"Return the current cursor position relative to the coordinate system of the\n"
|
|
"viewport region.\n");
|
|
add_varargs_method("getObjectInfo",&View3DInventorPy::getObjectInfo,
|
|
"getObjectInfo(tuple of integers) -> dictionary or None\n"
|
|
"\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("getObjectsInfo",&View3DInventorPy::getObjectsInfo,
|
|
"getObjectsInfo(tuple of integers) -> dictionary or None\n"
|
|
"\n"
|
|
"Does the same as getObjectInfo() but returns a list of dictionaries or None.\n");
|
|
add_varargs_method("getSize",&View3DInventorPy::getSize,"getSize()");
|
|
add_varargs_method("getPoint",&View3DInventorPy::getPoint,
|
|
"getPoint(pixel coords (as integer)) -> 3D vector\n"
|
|
"\n"
|
|
"Return the according 3D point on the focal plane to the given 2D point (in\n"
|
|
"pixel coordinates).\n");
|
|
add_varargs_method("getPointOnScreen",&View3DInventorPy::getPointOnScreen,
|
|
"getPointOnScreen(3D vector) -> pixel coords (as integer)\n"
|
|
"\n"
|
|
"Return the projected 3D point (in pixel coordinates).\n");
|
|
add_varargs_method("addEventCallback",&View3DInventorPy::addEventCallback,"addEventCallback()");
|
|
add_varargs_method("removeEventCallback",&View3DInventorPy::removeEventCallback,"removeEventCallback()");
|
|
add_varargs_method("setAnnotation",&View3DInventorPy::setAnnotation,"setAnnotation()");
|
|
add_varargs_method("removeAnnotation",&View3DInventorPy::removeAnnotation,"removeAnnotation()");
|
|
add_varargs_method("getSceneGraph",&View3DInventorPy::getSceneGraph,"getSceneGraph()");
|
|
add_varargs_method("getViewer",&View3DInventorPy::getViewer,"getViewer()");
|
|
add_varargs_method("addEventCallbackPivy",&View3DInventorPy::addEventCallbackPivy,"addEventCallbackPivy()");
|
|
add_varargs_method("removeEventCallbackPivy",&View3DInventorPy::removeEventCallbackPivy,"removeEventCallbackPivy()");
|
|
add_varargs_method("addEventCallbackSWIG",&View3DInventorPy::addEventCallbackPivy,
|
|
"Deprecated -- use addEventCallbackPivy()");
|
|
add_varargs_method("removeEventCallbackSWIG",&View3DInventorPy::removeEventCallbackPivy,
|
|
"Deprecated -- use removeEventCallbackPivy()");
|
|
add_varargs_method("listNavigationTypes",&View3DInventorPy::listNavigationTypes,"listNavigationTypes()");
|
|
add_varargs_method("getNavigationType",&View3DInventorPy::getNavigationType,"getNavigationType()");
|
|
add_varargs_method("setNavigationType",&View3DInventorPy::setNavigationType,"setNavigationType()");
|
|
add_varargs_method("setAxisCross",&View3DInventorPy::setAxisCross,"switch the big axis-cross on and off");
|
|
add_varargs_method("hasAxisCross",&View3DInventorPy::hasAxisCross,"check if the big axis-cross is on or off()");
|
|
add_varargs_method("addDraggerCallback",&View3DInventorPy::addDraggerCallback,
|
|
"addDraggerCallback(SoDragger, String CallbackType, function)\n"
|
|
"Add a DraggerCalback function to the coin node\n"
|
|
"Possibles types :\n"
|
|
"'addFinishCallback','addStartCallback','addMotionCallback','addValueChangedCallback'\n");
|
|
add_varargs_method("removeDraggerCallback",&View3DInventorPy::removeDraggerCallback,
|
|
"removeDraggerCallback(SoDragger, String CallbackType, function)\n"
|
|
"Remove the DraggerCalback function from the coin node\n"
|
|
"Possibles types :\n"
|
|
"'addFinishCallback','addStartCallback','addMotionCallback','addValueChangedCallback'\n");
|
|
}
|
|
|
|
View3DInventorPy::View3DInventorPy(View3DInventor *vi)
|
|
: _view(vi)
|
|
{
|
|
}
|
|
|
|
View3DInventorPy::~View3DInventorPy()
|
|
{
|
|
Base::PyGILStateLocker lock;
|
|
for (std::list<PyObject*>::iterator it = callbacks.begin(); it != callbacks.end(); ++it)
|
|
Py_DECREF(*it);
|
|
}
|
|
|
|
Py::Object View3DInventorPy::repr()
|
|
{
|
|
std::string s;
|
|
std::ostringstream s_out;
|
|
if (!_view)
|
|
throw Py::RuntimeError("Cannot print representation of deleted object");
|
|
s_out << "View3DInventor";
|
|
return Py::String(s_out.str());
|
|
}
|
|
|
|
View3DInventorPy::method_varargs_handler View3DInventorPy::pycxx_handler = 0;
|
|
|
|
PyObject *View3DInventorPy::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 View3DInventorPy::getattr(const char * attr)
|
|
{
|
|
if (!_view) {
|
|
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<View3DInventorPy>::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 View3DInventorPy::setattr(const char * attr, const Py::Object & value)
|
|
{
|
|
if (!_view) {
|
|
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<View3DInventorPy>::setattr(attr, value);
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::message(const Py::Tuple& args)
|
|
{
|
|
const char **ppReturn = 0;
|
|
char *psMsgStr;
|
|
if (!PyArg_ParseTuple(args.ptr(), "s;Message string needed (string)",&psMsgStr)) // convert args: Python->C
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
_view->onMsg(psMsgStr,ppReturn);
|
|
}
|
|
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 View3DInventorPy::fitAll(const Py::Tuple& args)
|
|
{
|
|
double factor = 1.0;
|
|
if (!PyArg_ParseTuple(args.ptr(), "|d", &factor))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
_view->getViewer()->viewAll((float)factor);
|
|
}
|
|
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 View3DInventorPy::viewBottom(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
_view->getViewer()->setCameraOrientation(SbRotation(-1, 0, 0, 0));
|
|
}
|
|
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 View3DInventorPy::viewFront(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
float root = (float)(sqrt(2.0)/2.0);
|
|
_view->getViewer()->setCameraOrientation(SbRotation(-root, 0, 0, -root));
|
|
}
|
|
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 View3DInventorPy::viewLeft(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
_view->getViewer()->setCameraOrientation(SbRotation(-0.5, 0.5, 0.5, -0.5));
|
|
}
|
|
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 View3DInventorPy::viewRear(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
float root = (float)(sqrt(2.0)/2.0);
|
|
_view->getViewer()->setCameraOrientation(SbRotation(0, root, root, 0));
|
|
}
|
|
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 View3DInventorPy::viewRight(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
_view->getViewer()->setCameraOrientation(SbRotation(0.5, 0.5, 0.5, 0.5));
|
|
}
|
|
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 View3DInventorPy::viewTop(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
_view->getViewer()->setCameraOrientation(SbRotation(0, 0, 0, 1));
|
|
}
|
|
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 View3DInventorPy::viewAxometric(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
//from math import sqrt, degrees, asin
|
|
//p1=App.Rotation(App.Vector(1,0,0),90)
|
|
//p2=App.Rotation(App.Vector(0,0,1),45)
|
|
//p3=App.Rotation(App.Vector(1,1,0),45)
|
|
//p3=App.Rotation(App.Vector(1,1,0),degrees(asin(-sqrt(1.0/3.0))))
|
|
//p4=p3.multiply(p2).multiply(p1)
|
|
_view->getViewer()->setCameraOrientation(SbRotation
|
|
(0.424708f, 0.17592f, 0.339851f, 0.820473f));
|
|
}
|
|
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 View3DInventorPy::viewRotateLeft(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
SoCamera* cam = _view->getViewer()->getSoRenderManager()->getCamera();
|
|
SbRotation rot = cam->orientation.getValue();
|
|
SbVec3f vdir(0, 0, -1);
|
|
rot.multVec(vdir, vdir);
|
|
SbRotation nrot(vdir,float( M_PI/2));
|
|
cam->orientation.setValue(rot*nrot);
|
|
}
|
|
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 View3DInventorPy::viewRotateRight(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
SoCamera* cam = _view->getViewer()->getSoRenderManager()->getCamera();
|
|
SbRotation rot = cam->orientation.getValue();
|
|
SbVec3f vdir(0, 0, -1);
|
|
rot.multVec(vdir, vdir);
|
|
SbRotation nrot(vdir, float(-M_PI/2));
|
|
cam->orientation.setValue(rot*nrot);
|
|
}
|
|
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 View3DInventorPy::zoomIn(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
_view->getViewer()->navigationStyle()->zoomIn();
|
|
}
|
|
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 View3DInventorPy::zoomOut(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
_view->getViewer()->navigationStyle()->zoomOut();
|
|
}
|
|
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 View3DInventorPy::setCameraOrientation(const Py::Tuple& args)
|
|
{
|
|
PyObject* o;
|
|
PyObject* m=Py_False;
|
|
if (!PyArg_ParseTuple(args.ptr(), "O|O!", &o, &PyBool_Type, &m))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
if (PyTuple_Check(o)) {
|
|
Py::Tuple tuple(o);
|
|
float q0 = (float)Py::Float(tuple[0]);
|
|
float q1 = (float)Py::Float(tuple[1]);
|
|
float q2 = (float)Py::Float(tuple[2]);
|
|
float q3 = (float)Py::Float(tuple[3]);
|
|
_view->getViewer()->setCameraOrientation(SbRotation(q0, q1, q2, q3), PyObject_IsTrue(m));
|
|
}
|
|
else if (PyObject_TypeCheck(o, &Base::RotationPy::Type)) {
|
|
Base::Rotation r = (Base::Rotation)Py::Rotation(o,false);
|
|
double q0, q1, q2, q3;
|
|
r.getValue(q0, q1, q2, q3);
|
|
_view->getViewer()->setCameraOrientation(SbRotation((float)q0, (float)q1, (float)q2, (float)q3), PyObject_IsTrue(m));
|
|
}
|
|
else {
|
|
throw Py::ValueError("Neither tuple nor rotation object");
|
|
}
|
|
}
|
|
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 View3DInventorPy::getCameraOrientation(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
SbRotation rot = _view->getViewer()->getCameraOrientation();
|
|
float q0,q1,q2,q3;
|
|
rot.getValue(q0,q1,q2,q3);
|
|
return Py::Rotation(Base::Rotation(q0,q1,q2,q3));
|
|
}
|
|
|
|
Py::Object View3DInventorPy::viewPosition(const Py::Tuple& args)
|
|
{
|
|
PyObject* p=0;
|
|
int steps = 20;
|
|
int ms = 30;
|
|
if (!PyArg_ParseTuple(args.ptr(), "|O!ii",&Base::PlacementPy::Type,&p,&steps,&ms))
|
|
throw Py::Exception();
|
|
|
|
if (p) {
|
|
Base::Placement* plm = static_cast<Base::PlacementPy*>(p)->getPlacementPtr();
|
|
Base::Rotation rot = plm->getRotation();
|
|
Base::Vector3d pos = plm->getPosition();
|
|
double q0,q1,q2,q3;
|
|
rot.getValue(q0,q1,q2,q3);
|
|
_view->getViewer()->moveCameraTo(
|
|
SbRotation((float)q0, (float)q1, (float)q2, (float)q3),
|
|
SbVec3f((float)pos.x, (float)pos.y, (float)pos.z), steps, ms);
|
|
}
|
|
|
|
SoCamera* cam = _view->getViewer()->getSoRenderManager()->getCamera();
|
|
if (!cam) return Py::None();
|
|
|
|
SbRotation rot = cam->orientation.getValue();
|
|
SbVec3f pos = cam->position.getValue();
|
|
float q0,q1,q2,q3;
|
|
rot.getValue(q0,q1,q2,q3);
|
|
Base::Placement plm(
|
|
Base::Vector3d(pos[0], pos[1], pos[2]),
|
|
Base::Rotation(q0, q1, q2, q3));
|
|
return Py::Placement(plm);
|
|
}
|
|
|
|
Py::Object View3DInventorPy::startAnimating(const Py::Tuple& args)
|
|
{
|
|
float x,y,z;
|
|
float velocity;
|
|
if (!PyArg_ParseTuple(args.ptr(), "ffff", &x,&y,&z,&velocity))
|
|
throw Py::Exception();
|
|
_view->getViewer()->startAnimating(SbVec3f(x,y,z),velocity);
|
|
return Py::None();
|
|
}
|
|
|
|
Py::Object View3DInventorPy::stopAnimating(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
_view->getViewer()->stopAnimating();
|
|
return Py::None();
|
|
}
|
|
|
|
Py::Object View3DInventorPy::setAnimationEnabled(const Py::Tuple& args)
|
|
{
|
|
int ok;
|
|
if (!PyArg_ParseTuple(args.ptr(), "i", &ok))
|
|
throw Py::Exception();
|
|
_view->getViewer()->setAnimationEnabled(ok!=0);
|
|
return Py::None();
|
|
}
|
|
|
|
Py::Object View3DInventorPy::isAnimationEnabled(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
SbBool ok = _view->getViewer()->isAnimationEnabled();
|
|
return Py::Boolean(ok ? true : false);
|
|
}
|
|
|
|
void View3DInventorPy::createImageFromFramebuffer(int backgroundType, int width, int height, QImage& img)
|
|
{
|
|
QGLFramebufferObject fbo(width, height, QGLFramebufferObject::Depth);
|
|
const QColor col = _view->getViewer()->backgroundColor();
|
|
bool on = _view->getViewer()->hasGradientBackground();
|
|
|
|
switch(backgroundType){
|
|
case 0: // Current
|
|
break;
|
|
case 1: // Black
|
|
_view->getViewer()->setBackgroundColor(QColor(0,0,0));
|
|
_view->getViewer()->setGradientBackground(false);
|
|
break;
|
|
case 2: // White
|
|
_view->getViewer()->setBackgroundColor(QColor(255,255,255));
|
|
_view->getViewer()->setGradientBackground(false);
|
|
break;
|
|
case 3: // Transparent
|
|
_view->getViewer()->setBackgroundColor(QColor(255,255,255));
|
|
_view->getViewer()->setGradientBackground(false);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
_view->getViewer()->renderToFramebuffer(&fbo);
|
|
_view->getViewer()->setBackgroundColor(col);
|
|
_view->getViewer()->setGradientBackground(on);
|
|
img = fbo.toImage();
|
|
}
|
|
|
|
Py::Object View3DInventorPy::saveImage(const Py::Tuple& args)
|
|
{
|
|
char *cFileName,*cImageType="Current",*cComment="$MIBA";
|
|
int w=-1,h=-1,t;
|
|
|
|
if (!PyArg_ParseTuple(args.ptr(), "s|iiss",&cFileName,&w,&h,&cImageType,&cComment))
|
|
throw Py::Exception();
|
|
|
|
#ifdef __GNUC__
|
|
if (strcasecmp(cImageType,"Current")==0)
|
|
t=0;
|
|
else if(strcasecmp(cImageType,"Black")==0)
|
|
t=1;
|
|
else if(strcasecmp(cImageType,"White")==0)
|
|
t=2;
|
|
else if(strcasecmp(cImageType,"Transparent")==0)
|
|
t=3;
|
|
else
|
|
throw Py::Exception("Parameter 4 have to be (Current|Black|White|Transparent)");
|
|
#else
|
|
if (_stricmp(cImageType,"Current")==0)
|
|
t=0;
|
|
else if(_stricmp(cImageType,"Black")==0)
|
|
t=1;
|
|
else if(_stricmp(cImageType,"White")==0)
|
|
t=2;
|
|
else if(_stricmp(cImageType,"Transparent")==0)
|
|
t=3;
|
|
else
|
|
throw Py::Exception("Parameter 4 have to be (Current|Black|White|Transparent)");
|
|
#endif
|
|
QImage img;
|
|
if (App::GetApplication().GetParameterGroupByPath
|
|
("User parameter:BaseApp/Preferences/Document")->GetBool("DisablePBuffers",false)) {
|
|
createImageFromFramebuffer(t, w, h, img);
|
|
}
|
|
else {
|
|
try {
|
|
_view->getViewer()->savePicture(w, h, t, img);
|
|
}
|
|
catch (const Base::Exception&) {
|
|
createImageFromFramebuffer(t, w, h, img);
|
|
}
|
|
}
|
|
|
|
SoFCOffscreenRenderer& renderer = SoFCOffscreenRenderer::instance();
|
|
SoCamera* cam = _view->getViewer()->getSoRenderManager()->getCamera();
|
|
renderer.writeToImageFile(cFileName, cComment, cam->getViewVolume().getMatrix(), img);
|
|
|
|
return Py::None();
|
|
}
|
|
|
|
Py::Object View3DInventorPy::saveVectorGraphic(const Py::Tuple& args)
|
|
{
|
|
char* filename;
|
|
int ps=4, t=2;
|
|
|
|
if (!PyArg_ParseTuple(args.ptr(), "s|ii",&filename,&ps,&t))
|
|
throw Py::Exception();
|
|
|
|
std::auto_ptr<SoVectorizeAction> vo;
|
|
Base::FileInfo fi(filename);
|
|
if (fi.hasExtension("ps") || fi.hasExtension("eps")) {
|
|
vo = std::auto_ptr<SoVectorizeAction>(new SoVectorizePSAction());
|
|
//vo->setGouraudThreshold(0.0f);
|
|
}
|
|
else if (fi.hasExtension("svg")) {
|
|
vo = std::auto_ptr<SoVectorizeAction>(new SoFCVectorizeSVGAction());
|
|
}
|
|
else if (fi.hasExtension("idtf")) {
|
|
vo = std::auto_ptr<SoVectorizeAction>(new SoFCVectorizeU3DAction());
|
|
}
|
|
else {
|
|
throw Py::Exception("Not supported vector graphic");
|
|
}
|
|
|
|
SoVectorOutput * out = vo->getOutput();
|
|
if (!out || !out->openFile(filename)) {
|
|
std::ostringstream a_out;
|
|
a_out << "Cannot open file '" << filename << "'";
|
|
throw Py::Exception(a_out.str());
|
|
}
|
|
|
|
_view->getViewer()->saveGraphic(ps,t,vo.get());
|
|
out->closeFile();
|
|
return Py::None();
|
|
}
|
|
|
|
Py::Object View3DInventorPy::getCameraNode(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
SoNode* camera = _view->getViewer()->getSoRenderManager()->getCamera();
|
|
PyObject* proxy = 0;
|
|
std::string type;
|
|
type = "So"; // seems that So prefix is missing in camera node
|
|
type += camera->getTypeId().getName().getString();
|
|
type += " *";
|
|
proxy = Base::Interpreter().createSWIGPointerObj("pivy.coin", type.c_str(), (void*)camera, 1);
|
|
camera->ref();
|
|
return Py::Object(proxy, true);
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::getCamera(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
SoOutput out;
|
|
char buffer[512];
|
|
out.setBuffer(buffer, 512, 0);
|
|
|
|
try {
|
|
SoWriteAction wa(&out);
|
|
SoCamera * cam = _view->getViewer()->getSoRenderManager()->getCamera();
|
|
if (cam) wa.apply(cam);
|
|
else buffer[0] = '\0';
|
|
return Py::String(buffer);
|
|
}
|
|
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 View3DInventorPy::getViewDirection(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
try {
|
|
SbVec3f dvec = _view->getViewer()->getViewDirection();
|
|
return Py::Vector(Base::Vector3f(dvec[0], dvec[1], dvec[2]));
|
|
}
|
|
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 View3DInventorPy::setCamera(const Py::Tuple& args)
|
|
{
|
|
char* buffer;
|
|
if (!PyArg_ParseTuple(args.ptr(), "s", &buffer))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
_view->setCamera(buffer);
|
|
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");
|
|
}
|
|
}
|
|
|
|
//FIXME: Once View3DInventor inherits from PropertyContainer we can use PropertyEnumeration.
|
|
const char* CameraTypeEnums[]= {"Orthographic","Perspective",NULL};
|
|
|
|
Py::Object View3DInventorPy::getCameraType(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
SoCamera* cam = _view->getViewer()->getSoRenderManager()->getCamera();
|
|
if (!cam) {
|
|
throw Py::Exception("No camera set!");
|
|
}
|
|
else if (cam->getTypeId() == SoOrthographicCamera::getClassTypeId()) {
|
|
return Py::String(CameraTypeEnums[0]);
|
|
}
|
|
else if (cam->getTypeId() == SoPerspectiveCamera::getClassTypeId()) {
|
|
return Py::String(CameraTypeEnums[1]);
|
|
}
|
|
else {
|
|
throw Py::Exception("Unknown camera type");
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::setCameraType(const Py::Tuple& args)
|
|
{
|
|
int cameratype=-1;
|
|
if (!PyArg_ParseTuple(args.ptr(), "i", &cameratype)) { // convert args: Python->C
|
|
char* modename;
|
|
PyErr_Clear();
|
|
if (!PyArg_ParseTuple(args.ptr(), "s", &modename))
|
|
throw Py::Exception();
|
|
for (int i=0; i<2; i++ ) {
|
|
if (strncmp(CameraTypeEnums[i],modename,20) == 0 ) {
|
|
cameratype = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (cameratype < 0) {
|
|
std::string s;
|
|
std::ostringstream s_out;
|
|
s_out << "Unknown camera type '" << modename << "'";
|
|
throw Py::NameError(s_out.str());
|
|
}
|
|
}
|
|
|
|
if (cameratype < 0 || cameratype > 1)
|
|
throw Py::Exception("Out of range");
|
|
if (cameratype==0)
|
|
_view->getViewer()->setCameraType(SoOrthographicCamera::getClassTypeId());
|
|
else
|
|
_view->getViewer()->setCameraType(SoPerspectiveCamera::getClassTypeId());
|
|
return Py::None();
|
|
}
|
|
|
|
Py::Object View3DInventorPy::listCameraTypes(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
Py::List list(2);
|
|
for (int i=0; i<2; i++) {
|
|
list[i] = Py::String(CameraTypeEnums[i]);
|
|
}
|
|
return list;
|
|
}
|
|
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 View3DInventorPy::dump(const Py::Tuple& args)
|
|
{
|
|
char* filename;
|
|
if (!PyArg_ParseTuple(args.ptr(), "s", &filename))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
_view->dump(filename);
|
|
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");
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::dumpNode(const Py::Tuple& args)
|
|
{
|
|
PyObject* object;
|
|
if (!PyArg_ParseTuple(args.ptr(), "O", &object)) // convert args: Python->C
|
|
throw Py::Exception();
|
|
|
|
void* ptr = 0;
|
|
try {
|
|
Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoNode *", object, &ptr, 0);
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
SoNode* node = reinterpret_cast<SoNode*>(ptr);
|
|
return Py::String(SoFCDB::writeNodesToString(node));
|
|
}
|
|
|
|
//FIXME: Once View3DInventor inherits from PropertyContainer we can use PropertyEnumeration.
|
|
const char* StereoTypeEnums[]= {"None","Anaglyph","QuadBuffer","InterleavedRows","InterleavedColumns",NULL};
|
|
|
|
Py::Object View3DInventorPy::setStereoType(const Py::Tuple& args)
|
|
{
|
|
int stereomode=-1;
|
|
if (!PyArg_ParseTuple(args.ptr(), "i", &stereomode)) {
|
|
char* modename;
|
|
PyErr_Clear();
|
|
if (!PyArg_ParseTuple(args.ptr(), "s", &modename))
|
|
throw Py::Exception();
|
|
for (int i=0; i<5; i++) {
|
|
if (strncmp(StereoTypeEnums[i],modename,20) == 0) {
|
|
stereomode = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (stereomode < 0) {
|
|
std::string s;
|
|
std::ostringstream s_out;
|
|
s_out << "Unknown stereo type '" << modename << "'";
|
|
throw Py::NameError(s_out.str());
|
|
}
|
|
}
|
|
|
|
try {
|
|
if (stereomode < 0 || stereomode > 4)
|
|
throw Py::Exception("Out of range");
|
|
Quarter::SoQTQuarterAdaptor::StereoMode mode = Quarter::SoQTQuarterAdaptor::StereoMode(stereomode);
|
|
_view->getViewer()->setProperty("StereoMode",mode);
|
|
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");
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::getStereoType(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
int mode = (int)(_view->getViewer()->stereoMode());
|
|
return Py::String(StereoTypeEnums[mode]);
|
|
}
|
|
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 View3DInventorPy::listStereoTypes(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
Py::List list(5);
|
|
for (int i=0; i<5; i++) {
|
|
list[i] = Py::String(StereoTypeEnums[i]);
|
|
}
|
|
|
|
return list;
|
|
}
|
|
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 View3DInventorPy::getCursorPos(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
try {
|
|
QPoint pos = _view->mapFromGlobal(QCursor::pos());
|
|
Py::Tuple tuple(2);
|
|
tuple.setItem(0, Py::Int(pos.x()));
|
|
tuple.setItem(1, Py::Int(_view->height()-pos.y()-1));
|
|
return tuple;
|
|
}
|
|
catch (const Py::Exception&) {
|
|
throw;
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::getObjectInfo(const Py::Tuple& args)
|
|
{
|
|
PyObject* object;
|
|
if (!PyArg_ParseTuple(args.ptr(), "O", &object))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
//Note: For gcc (4.2) we need the 'const' keyword to avoid the compiler error:
|
|
//conversion from 'Py::seqref<Py::Object>' to non-scalar type 'Py::Int' requested
|
|
//We should report this problem to the PyCXX project as in the documentation an
|
|
//example without the 'const' keyword is used.
|
|
//Or we can also write Py::Int x(tuple[0]);
|
|
const Py::Tuple tuple(object);
|
|
Py::Int x(tuple[0]);
|
|
Py::Int y(tuple[1]);
|
|
|
|
// As this method could be called during a SoHandleEventAction scene
|
|
// graph traversal we must not use a second SoHandleEventAction as
|
|
// we will get Coin warnings because of multiple scene graph traversals
|
|
// which is regarded as error-prone.
|
|
SoRayPickAction action(_view->getViewer()->getSoRenderManager()->getViewportRegion());
|
|
action.setPoint(SbVec2s((long)x,(long)y));
|
|
action.apply(_view->getViewer()->getSoRenderManager()->getSceneGraph());
|
|
SoPickedPoint *Point = action.getPickedPoint();
|
|
|
|
Py::Object ret = Py::None();
|
|
if (Point) {
|
|
Py::Dict dict;
|
|
SbVec3f pt = Point->getPoint();
|
|
dict.setItem("x", Py::Float(pt[0]));
|
|
dict.setItem("y", Py::Float(pt[1]));
|
|
dict.setItem("z", Py::Float(pt[2]));
|
|
|
|
ViewProvider *vp = _view->getViewer()->getViewProviderByPath(Point->getPath());
|
|
if (vp && vp->useNewSelectionModel() && vp->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) {
|
|
ViewProviderDocumentObject* vpd = static_cast<ViewProviderDocumentObject*>(vp);
|
|
dict.setItem("Document",
|
|
Py::String(vpd->getObject()->getDocument()->getName()));
|
|
dict.setItem("Object",
|
|
Py::String(vpd->getObject()->getNameInDocument()));
|
|
dict.setItem("Component",
|
|
Py::String(vpd->getElement(Point->getDetail())));
|
|
// ok, found the node of interest
|
|
ret = dict;
|
|
}
|
|
else {
|
|
// search for a SoFCSelection node
|
|
SoFCDocumentObjectAction objaction;
|
|
objaction.apply(Point->getPath());
|
|
if (objaction.isHandled()) {
|
|
dict.setItem("Document",
|
|
Py::String(objaction.documentName.getString()));
|
|
dict.setItem("Object",
|
|
Py::String(objaction.objectName.getString()));
|
|
dict.setItem("Component",
|
|
Py::String(objaction.componentName.getString()));
|
|
// ok, found the node of interest
|
|
ret = dict;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
catch (const Py::Exception&) {
|
|
throw;
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::getObjectsInfo(const Py::Tuple& args)
|
|
{
|
|
PyObject* object;
|
|
if (!PyArg_ParseTuple(args.ptr(), "O", &object))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
//Note: For gcc (4.2) we need the 'const' keyword to avoid the compiler error:
|
|
//conversion from 'Py::seqref<Py::Object>' to non-scalar type 'Py::Int' requested
|
|
//We should report this problem to the PyCXX project as in the documentation an
|
|
//example without the 'const' keyword is used.
|
|
//Or we can also write Py::Int x(tuple[0]);
|
|
const Py::Tuple tuple(object);
|
|
Py::Int x(tuple[0]);
|
|
Py::Int y(tuple[1]);
|
|
|
|
// As this method could be called during a SoHandleEventAction scene
|
|
// graph traversal we must not use a second SoHandleEventAction as
|
|
// we will get Coin warnings because of multiple scene graph traversals
|
|
// which is regarded as error-prone.
|
|
SoRayPickAction action(_view->getViewer()->getSoRenderManager()->getViewportRegion());
|
|
action.setPickAll(true);
|
|
action.setPoint(SbVec2s((long)x,(long)y));
|
|
action.apply(_view->getViewer()->getSoRenderManager()->getSceneGraph());
|
|
const SoPickedPointList& pp = action.getPickedPointList();
|
|
|
|
Py::Object ret = Py::None();
|
|
if (pp.getLength() > 0) {
|
|
Py::List list;
|
|
for (int i=0; i<pp.getLength(); i++) {
|
|
Py::Dict dict;
|
|
SoPickedPoint* point = static_cast<SoPickedPoint*>(pp.get(i));
|
|
SbVec3f pt = point->getPoint();
|
|
dict.setItem("x", Py::Float(pt[0]));
|
|
dict.setItem("y", Py::Float(pt[1]));
|
|
dict.setItem("z", Py::Float(pt[2]));
|
|
|
|
ViewProvider *vp = _view->getViewer()->getViewProviderByPath(point->getPath());
|
|
if (vp && vp->useNewSelectionModel() && vp->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) {
|
|
ViewProviderDocumentObject* vpd = static_cast<ViewProviderDocumentObject*>(vp);
|
|
dict.setItem("Document",
|
|
Py::String(vpd->getObject()->getDocument()->getName()));
|
|
dict.setItem("Object",
|
|
Py::String(vpd->getObject()->getNameInDocument()));
|
|
dict.setItem("Component",
|
|
Py::String(vpd->getElement(point->getDetail())));
|
|
// ok, found the node of interest
|
|
list.append(dict);
|
|
}
|
|
else {
|
|
// search for a SoFCSelection node
|
|
SoFCDocumentObjectAction objaction;
|
|
objaction.apply(point->getPath());
|
|
if (objaction.isHandled()) {
|
|
dict.setItem("Document",
|
|
Py::String(objaction.documentName.getString()));
|
|
dict.setItem("Object",
|
|
Py::String(objaction.objectName.getString()));
|
|
dict.setItem("Component",
|
|
Py::String(objaction.componentName.getString()));
|
|
// ok, found the node of interest
|
|
list.append(dict);
|
|
}
|
|
}
|
|
}
|
|
|
|
ret = list;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
catch (const Py::Exception&) {
|
|
throw;
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::getSize(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
try {
|
|
SbVec2s size = _view->getViewer()->getSoRenderManager()->getSize();
|
|
Py::Tuple tuple(2);
|
|
tuple.setItem(0, Py::Int(size[0]));
|
|
tuple.setItem(1, Py::Int(size[1]));
|
|
return tuple;
|
|
}
|
|
catch (const Py::Exception&) {
|
|
throw;
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::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 = _view->getViewer()->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 View3DInventorPy::getPointOnScreen(const Py::Tuple& args)
|
|
{
|
|
PyObject* v;
|
|
double vx,vy,vz;
|
|
if (PyArg_ParseTuple(args.ptr(), "O!", &Base::VectorPy::Type, &v)) {
|
|
Base::Vector3d* vec = static_cast<Base::VectorPy*>(v)->getVectorPtr();
|
|
vx = vec->x;
|
|
vy = vec->y;
|
|
vz = vec->z;
|
|
}
|
|
else {
|
|
PyErr_Clear();
|
|
if (!PyArg_ParseTuple(args.ptr(), "ddd", &vx,&vy,&vz)) {
|
|
throw Py::Exception("Wrong argument, Vector or three floats expected expected");
|
|
}
|
|
}
|
|
|
|
try {
|
|
const SbViewportRegion& vp = _view->getViewer()->getSoRenderManager()->getViewportRegion();
|
|
float fRatio = vp.getViewportAspectRatio();
|
|
const SbVec2s& sp = vp.getViewportSizePixels();
|
|
//float dX, dY; vp.getViewportSize().getValue(dX, dY);
|
|
SbViewVolume vv = _view->getViewer()->getSoRenderManager()->getCamera()->getViewVolume(fRatio);
|
|
|
|
SbVec3f pt(vx,vy,vz);
|
|
vv.projectToScreen(pt, pt);
|
|
|
|
//if (fRatio > 1.0f) {
|
|
// pt[0] = (pt[0] - 0.5f*dX) / fRatio + 0.5f*dX;
|
|
//}
|
|
//else {
|
|
// pt[1] = (pt[1] - 0.5f*dY) * fRatio + 0.5f*dY;
|
|
//}
|
|
|
|
int x = pt[0] * sp[0];
|
|
int y = pt[1] * sp[1];
|
|
Py::Tuple tuple(2);
|
|
tuple.setItem(0, Py::Int(x));
|
|
tuple.setItem(1, Py::Int(y));
|
|
|
|
return tuple;
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
catch (const Py::Exception&) {
|
|
throw;
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::listNavigationTypes(const Py::Tuple&)
|
|
{
|
|
std::vector<Base::Type> types;
|
|
Py::List styles;
|
|
Base::Type::getAllDerivedFrom(UserNavigationStyle::getClassTypeId(), types);
|
|
for (std::vector<Base::Type>::iterator it = types.begin()+1; it != types.end(); ++it) {
|
|
styles.append(Py::String(it->getName()));
|
|
}
|
|
return styles;
|
|
}
|
|
|
|
Py::Object View3DInventorPy::getNavigationType(const Py::Tuple&)
|
|
{
|
|
std::string name = _view->getViewer()->navigationStyle()->getTypeId().getName();
|
|
return Py::String(name);
|
|
}
|
|
|
|
Py::Object View3DInventorPy::setNavigationType(const Py::Tuple& args)
|
|
{
|
|
char* style;
|
|
if (!PyArg_ParseTuple(args.ptr(), "s", &style))
|
|
throw Py::Exception();
|
|
Base::Type type = Base::Type::fromName(style);
|
|
_view->getViewer()->setNavigationType(type);
|
|
return Py::None();
|
|
}
|
|
|
|
void View3DInventorPy::eventCallback(void * ud, SoEventCallback * n)
|
|
{
|
|
Base::PyGILStateLocker lock;
|
|
try {
|
|
Py::Dict dict;
|
|
const SoEvent* e = n->getEvent();
|
|
if (!e) return; // invalid event
|
|
// Type
|
|
dict.setItem("Type", Py::String(std::string(e->getTypeId().getName().getString())));
|
|
// Time
|
|
dict.setItem("Time", Py::String(std::string(e->getTime().formatDate().getString())));
|
|
SbVec2s p = n->getEvent()->getPosition();
|
|
Py::Tuple pos(2);
|
|
pos.setItem(0, Py::Int(p[0]));
|
|
pos.setItem(1, Py::Int(p[1]));
|
|
// Position
|
|
dict.setItem("Position", pos);
|
|
// Shift, Ctrl, Alt down
|
|
dict.setItem("ShiftDown", Py::Object((e->wasShiftDown() ? Py_True : Py_False)));
|
|
dict.setItem("CtrlDown", Py::Object((e->wasCtrlDown() ? Py_True : Py_False)));
|
|
dict.setItem("AltDown", Py::Object((e->wasAltDown() ? Py_True : Py_False)));
|
|
if (e->isOfType(SoButtonEvent::getClassTypeId())) {
|
|
std::string state;
|
|
const SoButtonEvent* be = static_cast<const SoButtonEvent*>(e);
|
|
switch (be->getState()) {
|
|
case SoButtonEvent::UP:
|
|
state = "UP";
|
|
break;
|
|
case SoButtonEvent::DOWN:
|
|
state = "DOWN";
|
|
break;
|
|
default:
|
|
state = "UNKNOWN";
|
|
break;
|
|
}
|
|
|
|
dict.setItem("State", Py::String(state));
|
|
}
|
|
if (e->isOfType(SoKeyboardEvent::getClassTypeId())) {
|
|
const SoKeyboardEvent* ke = static_cast<const SoKeyboardEvent*>(e);
|
|
switch (ke->getKey()) {
|
|
case SoKeyboardEvent::ANY:
|
|
dict.setItem("Key", Py::String("ANY"));
|
|
break;
|
|
case SoKeyboardEvent::UNDEFINED:
|
|
dict.setItem("Key", Py::String("UNDEFINED"));
|
|
break;
|
|
case SoKeyboardEvent::LEFT_SHIFT:
|
|
case SoKeyboardEvent::RIGHT_SHIFT:
|
|
dict.setItem("Key", Py::String("SHIFT"));
|
|
break;
|
|
case SoKeyboardEvent::LEFT_CONTROL:
|
|
case SoKeyboardEvent::RIGHT_CONTROL:
|
|
dict.setItem("Key", Py::String("CONTROL"));
|
|
break;
|
|
case SoKeyboardEvent::LEFT_ALT:
|
|
case SoKeyboardEvent::RIGHT_ALT:
|
|
dict.setItem("Key", Py::String("ALT"));
|
|
break;
|
|
case SoKeyboardEvent::HOME:
|
|
dict.setItem("Key", Py::String("HOME"));
|
|
break;
|
|
case SoKeyboardEvent::LEFT_ARROW:
|
|
dict.setItem("Key", Py::String("LEFT_ARROW"));
|
|
break;
|
|
case SoKeyboardEvent::UP_ARROW:
|
|
dict.setItem("Key", Py::String("UP_ARROW"));
|
|
break;
|
|
case SoKeyboardEvent::RIGHT_ARROW:
|
|
dict.setItem("Key", Py::String("RIGHT_ARROW"));
|
|
break;
|
|
case SoKeyboardEvent::DOWN_ARROW:
|
|
dict.setItem("Key", Py::String("DOWN_ARROW"));
|
|
break;
|
|
case SoKeyboardEvent::PAGE_UP:
|
|
dict.setItem("Key", Py::String("PAGE_UP"));
|
|
break;
|
|
case SoKeyboardEvent::PAGE_DOWN:
|
|
dict.setItem("Key", Py::String("PAGE_DOWN"));
|
|
break;
|
|
case SoKeyboardEvent::END:
|
|
dict.setItem("Key", Py::String("END"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_ENTER:
|
|
dict.setItem("Key", Py::String("PAD_ENTER"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_F1:
|
|
dict.setItem("Key", Py::String("PAD_F1"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_F2:
|
|
dict.setItem("Key", Py::String("PAD_F2"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_F3:
|
|
dict.setItem("Key", Py::String("PAD_F3"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_F4:
|
|
dict.setItem("Key", Py::String("PAD_F4"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_0:
|
|
dict.setItem("Key", Py::String("PAD_0"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_1:
|
|
dict.setItem("Key", Py::String("PAD_1"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_2:
|
|
dict.setItem("Key", Py::String("PAD_2"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_3:
|
|
dict.setItem("Key", Py::String("PAD_3"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_4:
|
|
dict.setItem("Key", Py::String("PAD_4"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_5:
|
|
dict.setItem("Key", Py::String("PAD_5"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_6:
|
|
dict.setItem("Key", Py::String("PAD_6"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_7:
|
|
dict.setItem("Key", Py::String("PAD_7"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_8:
|
|
dict.setItem("Key", Py::String("PAD_8"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_9:
|
|
dict.setItem("Key", Py::String("PAD_9"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_ADD:
|
|
dict.setItem("Key", Py::String("PAD_ADD"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_SUBTRACT:
|
|
dict.setItem("Key", Py::String("PAD_SUBTRACT"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_MULTIPLY:
|
|
dict.setItem("Key", Py::String("PAD_MULTIPLY"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_DIVIDE:
|
|
dict.setItem("Key", Py::String("PAD_DIVIDE"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_TAB:
|
|
dict.setItem("Key", Py::String("PAD_TAB"));
|
|
break;
|
|
case SoKeyboardEvent::PAD_DELETE:
|
|
dict.setItem("Key", Py::String("PAD_DELETE"));
|
|
break;
|
|
case SoKeyboardEvent::F1:
|
|
dict.setItem("Key", Py::String("F1"));
|
|
break;
|
|
case SoKeyboardEvent::F2:
|
|
dict.setItem("Key", Py::String("F2"));
|
|
break;
|
|
case SoKeyboardEvent::F3:
|
|
dict.setItem("Key", Py::String("F3"));
|
|
break;
|
|
case SoKeyboardEvent::F4:
|
|
dict.setItem("Key", Py::String("F4"));
|
|
break;
|
|
case SoKeyboardEvent::F5:
|
|
dict.setItem("Key", Py::String("F5"));
|
|
break;
|
|
case SoKeyboardEvent::F6:
|
|
dict.setItem("Key", Py::String("F6"));
|
|
break;
|
|
case SoKeyboardEvent::F7:
|
|
dict.setItem("Key", Py::String("F7"));
|
|
break;
|
|
case SoKeyboardEvent::F8:
|
|
dict.setItem("Key", Py::String("F8"));
|
|
break;
|
|
case SoKeyboardEvent::F9:
|
|
dict.setItem("Key", Py::String("F9"));
|
|
break;
|
|
case SoKeyboardEvent::F10:
|
|
dict.setItem("Key", Py::String("F10"));
|
|
break;
|
|
case SoKeyboardEvent::F11:
|
|
dict.setItem("Key", Py::String("F11"));
|
|
break;
|
|
case SoKeyboardEvent::F12:
|
|
dict.setItem("Key", Py::String("F12"));
|
|
break;
|
|
case SoKeyboardEvent::BACKSPACE:
|
|
dict.setItem("Key", Py::String("BACKSPACE"));
|
|
break;
|
|
case SoKeyboardEvent::TAB:
|
|
dict.setItem("Key", Py::String("TAB"));
|
|
break;
|
|
case SoKeyboardEvent::RETURN:
|
|
dict.setItem("Key", Py::String("RETURN"));
|
|
break;
|
|
case SoKeyboardEvent::PAUSE:
|
|
dict.setItem("Key", Py::String("PAUSE"));
|
|
break;
|
|
case SoKeyboardEvent::SCROLL_LOCK:
|
|
dict.setItem("Key", Py::String("SCROLL_LOCK"));
|
|
break;
|
|
case SoKeyboardEvent::ESCAPE:
|
|
dict.setItem("Key", Py::String("ESCAPE"));
|
|
break;
|
|
case SoKeyboardEvent::KEY_DELETE:
|
|
dict.setItem("Key", Py::String("DELETE"));
|
|
break;
|
|
case SoKeyboardEvent::PRINT:
|
|
dict.setItem("Key", Py::String("PRINT"));
|
|
break;
|
|
case SoKeyboardEvent::INSERT:
|
|
dict.setItem("Key", Py::String("INSERT"));
|
|
break;
|
|
case SoKeyboardEvent::NUM_LOCK:
|
|
dict.setItem("Key", Py::String("NUM_LOCK"));
|
|
break;
|
|
case SoKeyboardEvent::CAPS_LOCK:
|
|
dict.setItem("Key", Py::String("CAPS_LOCK"));
|
|
break;
|
|
case SoKeyboardEvent::SHIFT_LOCK:
|
|
dict.setItem("Key", Py::String("SHIFT_LOCK"));
|
|
break;
|
|
case SoKeyboardEvent::SPACE:
|
|
dict.setItem("Key", Py::String("SPACE"));
|
|
break;
|
|
case SoKeyboardEvent::APOSTROPHE:
|
|
dict.setItem("Key", Py::String("APOSTROPHE"));
|
|
break;
|
|
case SoKeyboardEvent::COMMA:
|
|
dict.setItem("Key", Py::String("COMMA"));
|
|
break;
|
|
case SoKeyboardEvent::MINUS:
|
|
dict.setItem("Key", Py::String("MINUS"));
|
|
break;
|
|
case SoKeyboardEvent::PERIOD:
|
|
dict.setItem("Key", Py::String("PERIOD"));
|
|
break;
|
|
case SoKeyboardEvent::SLASH:
|
|
dict.setItem("Key", Py::String("SLASH"));
|
|
break;
|
|
case SoKeyboardEvent::SEMICOLON:
|
|
dict.setItem("Key", Py::String("SEMICOLON"));
|
|
break;
|
|
case SoKeyboardEvent::EQUAL:
|
|
dict.setItem("Key", Py::String("EQUAL"));
|
|
break;
|
|
case SoKeyboardEvent::BRACKETLEFT:
|
|
dict.setItem("Key", Py::String("BRACKETLEFT"));
|
|
break;
|
|
case SoKeyboardEvent::BACKSLASH:
|
|
dict.setItem("Key", Py::String("BACKSLASH"));
|
|
break;
|
|
case SoKeyboardEvent::BRACKETRIGHT:
|
|
dict.setItem("Key", Py::String("BRACKETRIGHT"));
|
|
break;
|
|
case SoKeyboardEvent::GRAVE:
|
|
dict.setItem("Key", Py::String("GRAVE"));
|
|
break;
|
|
default:
|
|
dict.setItem("Key", Py::Char(ke->getPrintableCharacter()));
|
|
break;
|
|
}
|
|
}
|
|
if (e->isOfType(SoMouseButtonEvent::getClassTypeId())) {
|
|
const SoMouseButtonEvent* mbe = static_cast<const SoMouseButtonEvent*>(e);
|
|
std::string button;
|
|
switch (mbe->getButton()) {
|
|
case SoMouseButtonEvent::BUTTON1:
|
|
button = "BUTTON1";
|
|
break;
|
|
case SoMouseButtonEvent::BUTTON2:
|
|
button = "BUTTON2";
|
|
break;
|
|
case SoMouseButtonEvent::BUTTON3:
|
|
button = "BUTTON3";
|
|
break;
|
|
case SoMouseButtonEvent::BUTTON4:
|
|
button = "BUTTON4";
|
|
break;
|
|
case SoMouseButtonEvent::BUTTON5:
|
|
button = "BUTTON5";
|
|
break;
|
|
default:
|
|
button = "ANY";
|
|
break;
|
|
}
|
|
|
|
dict.setItem("Button", Py::String(button));
|
|
}
|
|
if (e->isOfType(SoSpaceballButtonEvent::getClassTypeId())) {
|
|
const SoSpaceballButtonEvent* sbe = static_cast<const SoSpaceballButtonEvent*>(e);
|
|
std::string button;
|
|
switch (sbe->getButton()) {
|
|
case SoSpaceballButtonEvent::BUTTON1:
|
|
button = "BUTTON1";
|
|
break;
|
|
case SoSpaceballButtonEvent::BUTTON2:
|
|
button = "BUTTON2";
|
|
break;
|
|
case SoSpaceballButtonEvent::BUTTON3:
|
|
button = "BUTTON3";
|
|
break;
|
|
case SoSpaceballButtonEvent::BUTTON4:
|
|
button = "BUTTON4";
|
|
break;
|
|
case SoSpaceballButtonEvent::BUTTON5:
|
|
button = "BUTTON5";
|
|
break;
|
|
case SoSpaceballButtonEvent::BUTTON6:
|
|
button = "BUTTON6";
|
|
break;
|
|
case SoSpaceballButtonEvent::BUTTON7:
|
|
button = "BUTTON7";
|
|
break;
|
|
default:
|
|
button = "ANY";
|
|
break;
|
|
}
|
|
|
|
dict.setItem("Button", Py::String(button));
|
|
}
|
|
if (e->isOfType(SoMotion3Event::getClassTypeId())) {
|
|
const SoMotion3Event* me = static_cast<const SoMotion3Event*>(e);
|
|
const SbVec3f& m = me->getTranslation();
|
|
const SbRotation& r = me->getRotation();
|
|
Py::Tuple mov(3);
|
|
mov.setItem(0, Py::Float(m[0]));
|
|
mov.setItem(1, Py::Float(m[1]));
|
|
mov.setItem(2, Py::Float(m[2]));
|
|
dict.setItem("Translation", mov);
|
|
Py::Tuple rot(4);
|
|
rot.setItem(0, Py::Float(r.getValue()[0]));
|
|
rot.setItem(1, Py::Float(r.getValue()[1]));
|
|
rot.setItem(2, Py::Float(r.getValue()[2]));
|
|
rot.setItem(3, Py::Float(r.getValue()[3]));
|
|
dict.setItem("Rotation", rot);
|
|
}
|
|
|
|
// now run the method
|
|
Py::Callable method(reinterpret_cast<PyObject*>(ud));
|
|
Py::Tuple args(1);
|
|
args.setItem(0, dict);
|
|
method.apply(args);
|
|
}
|
|
catch (const Py::Exception& e) {
|
|
Py::Object o = Py::type(e);
|
|
if (o.isString()) {
|
|
Py::String s(o);
|
|
Base::Console().Warning("%s\n", s.as_std_string().c_str());
|
|
}
|
|
else {
|
|
Py::String s(o.repr());
|
|
Base::Console().Warning("%s\n", s.as_std_string().c_str());
|
|
}
|
|
// Prints message to console window if we are in interactive mode
|
|
PyErr_Print();
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::addEventCallback(const Py::Tuple& args)
|
|
{
|
|
char* eventtype;
|
|
PyObject* method;
|
|
if (!PyArg_ParseTuple(args.ptr(), "sO", &eventtype, &method))
|
|
throw Py::Exception();
|
|
try {
|
|
if (PyCallable_Check(method) == 0) {
|
|
throw Py::Exception("object is not callable");
|
|
}
|
|
SoType eventId = SoType::fromName(eventtype);
|
|
if (eventId.isBad() || !eventId.isDerivedFrom(SoEvent::getClassTypeId())) {
|
|
std::string s;
|
|
std::ostringstream s_out;
|
|
s_out << eventtype << " is not a valid event type";
|
|
throw Py::Exception(s_out.str());
|
|
}
|
|
|
|
_view->getViewer()->addEventCallback(eventId, View3DInventorPy::eventCallback, method);
|
|
callbacks.push_back(method);
|
|
Py_INCREF(method);
|
|
return Py::Callable(method, false);
|
|
}
|
|
catch (const Py::Exception&) {
|
|
throw;
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::removeEventCallback(const Py::Tuple& args)
|
|
{
|
|
char* eventtype;
|
|
PyObject* method;
|
|
if (!PyArg_ParseTuple(args.ptr(), "sO", &eventtype, &method))
|
|
throw Py::Exception();
|
|
try {
|
|
if (PyCallable_Check(method) == 0) {
|
|
throw Py::Exception("object is not callable");
|
|
}
|
|
SoType eventId = SoType::fromName(eventtype);
|
|
if (eventId.isBad() || !eventId.isDerivedFrom(SoEvent::getClassTypeId())) {
|
|
std::string s;
|
|
std::ostringstream s_out;
|
|
s_out << eventtype << " is not a valid event type";
|
|
throw Py::Exception(s_out.str());
|
|
}
|
|
|
|
_view->getViewer()->removeEventCallback(eventId, View3DInventorPy::eventCallback, method);
|
|
callbacks.remove(method);
|
|
Py_DECREF(method);
|
|
return Py::None();
|
|
}
|
|
catch (const Py::Exception&) {
|
|
throw;
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::setAnnotation(const Py::Tuple& args)
|
|
{
|
|
char *psAnnoName,*psBuffer;
|
|
if (!PyArg_ParseTuple(args.ptr(), "ss", &psAnnoName, &psBuffer))
|
|
throw Py::Exception();
|
|
ViewProviderExtern* view = 0;
|
|
try {
|
|
view = new ViewProviderExtern();
|
|
view->setModeByString(psAnnoName, psBuffer);
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
delete view;
|
|
throw Py::Exception(e.what());
|
|
}
|
|
|
|
_view->getGuiDocument()->setAnnotationViewProvider(psAnnoName, view);
|
|
return Py::None();
|
|
}
|
|
|
|
Py::Object View3DInventorPy::removeAnnotation(const Py::Tuple& args)
|
|
{
|
|
char *psAnnoName;
|
|
if (!PyArg_ParseTuple(args.ptr(), "s", &psAnnoName))
|
|
throw Py::Exception();
|
|
ViewProvider* view = 0;
|
|
view = _view->getGuiDocument()->getAnnotationViewProvider(psAnnoName);
|
|
if (view) {
|
|
_view->getGuiDocument()->removeAnnotationViewProvider(psAnnoName);
|
|
return Py::None();
|
|
}
|
|
else {
|
|
std::string s;
|
|
std::ostringstream s_out;
|
|
s_out << "No such annotation '" << psAnnoName << "'";
|
|
throw Py::KeyError(s_out.str());
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::getSceneGraph(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
try {
|
|
SoNode* scene = _view->getViewer()->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());
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------
|
|
|
|
static PyObject *
|
|
wrap_SoQtViewer_setViewDirection(PyObject *proxy, PyObject *args)
|
|
{/*
|
|
PyObject* object;
|
|
if (!PyArg_ParseTuple(args, "O", &object)) // convert args: Python->C
|
|
return NULL; // NULL triggers exception
|
|
|
|
void* ptr = 0;
|
|
try {
|
|
Base::Interpreter().convertSWIGPointerObj("pivy.gui.soqt", "SoQtViewer *", proxy, &ptr, 0);
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
PyErr_SetString(PyExc_RuntimeError, e.what());
|
|
return 0;
|
|
}
|
|
|
|
SoQtViewer* viewer = reinterpret_cast<SoQtViewer*>(ptr);
|
|
try {
|
|
Py::Tuple tuple(object);
|
|
Py::Float x(tuple.getItem(0));
|
|
Py::Float y(tuple.getItem(1));
|
|
Py::Float z(tuple.getItem(2));
|
|
SbVec3f dir;
|
|
dir.setValue((float)x, (float)y, (float)z);
|
|
if (dir.length() < 0.001f)
|
|
throw Py::ValueError("Null vector cannot be used to set direction");
|
|
SoCamera* cam = viewer->getCamera();
|
|
if (cam)
|
|
cam->orientation.setValue(SbRotation(SbVec3f(0, 0, -1), dir));
|
|
return Py::new_reference_to(Py::None());
|
|
}
|
|
catch (Py::Exception&) {
|
|
return NULL;
|
|
}*/
|
|
}
|
|
|
|
static PyObject *
|
|
wrap_SoQtViewer_getViewDirection(PyObject *proxy, PyObject *args)
|
|
{/*
|
|
if (!PyArg_ParseTuple(args, "")) // convert args: Python->C
|
|
return NULL; // NULL triggers exception
|
|
|
|
void* ptr = 0;
|
|
try {
|
|
Base::Interpreter().convertSWIGPointerObj("pivy.gui.soqt", "SoQtViewer *", proxy, &ptr, 0);
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
PyErr_SetString(PyExc_RuntimeError, e.what());
|
|
return 0;
|
|
}
|
|
|
|
SoQtViewer* viewer = reinterpret_cast<SoQtViewer*>(ptr);
|
|
try {
|
|
SoCamera* cam = viewer->getCamera();
|
|
if (!cam) {
|
|
PyErr_SetString(PyExc_RuntimeError, "No camera set");
|
|
return 0;
|
|
}
|
|
SbRotation camrot = cam->orientation.getValue();
|
|
SbVec3f lookat(0, 0, -1); // init to default view direction vector
|
|
camrot.multVec(lookat, lookat);
|
|
|
|
Py::Tuple tuple(3);
|
|
tuple.setItem(0, Py::Float(lookat[0]));
|
|
tuple.setItem(1, Py::Float(lookat[1]));
|
|
tuple.setItem(2, Py::Float(lookat[2]));
|
|
return Py::new_reference_to(tuple);
|
|
}
|
|
catch (Py::Exception&) {
|
|
return NULL;
|
|
}*/
|
|
}
|
|
|
|
static PyObject *
|
|
wrap_SoQtViewer_setFocalDistance(PyObject *proxy, PyObject *args)
|
|
{/*
|
|
float distance;
|
|
if (!PyArg_ParseTuple(args, "f", &distance)) // convert args: Python->C
|
|
return NULL; // NULL triggers exception
|
|
|
|
void* ptr = 0;
|
|
try {
|
|
Base::Interpreter().convertSWIGPointerObj("pivy.gui.soqt", "SoQtViewer *", proxy, &ptr, 0);
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
PyErr_SetString(PyExc_RuntimeError, e.what());
|
|
return 0;
|
|
}
|
|
|
|
SoQtViewer* viewer = reinterpret_cast<SoQtViewer*>(ptr);
|
|
PY_TRY {
|
|
SoCamera* cam = viewer->getCamera();
|
|
if (cam)
|
|
cam->focalDistance.setValue(distance);
|
|
} PY_CATCH;
|
|
|
|
Py_Return;*/
|
|
}
|
|
|
|
static PyObject *
|
|
wrap_SoQtViewer_getFocalDistance(PyObject *proxy, PyObject *args)
|
|
{/*
|
|
if (!PyArg_ParseTuple(args, "")) // convert args: Python->C
|
|
return NULL; // NULL triggers exception
|
|
|
|
void* ptr = 0;
|
|
try {
|
|
Base::Interpreter().convertSWIGPointerObj("pivy.gui.soqt", "SoQtViewer *", proxy, &ptr, 0);
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
PyErr_SetString(PyExc_RuntimeError, e.what());
|
|
return 0;
|
|
}
|
|
|
|
SoQtViewer* viewer = reinterpret_cast<SoQtViewer*>(ptr);
|
|
double dist = 0;
|
|
SoCamera* cam = viewer->getCamera();
|
|
if (cam) dist = cam->focalDistance.getValue();
|
|
return PyFloat_FromDouble(dist);*/
|
|
}
|
|
|
|
static PyObject *
|
|
wrap_SoQtViewer_seekToPoint(PyObject *proxy, PyObject *args)
|
|
{/*
|
|
PyObject* object;
|
|
if (!PyArg_ParseTuple(args, "O", &object)) // convert args: Python->C
|
|
return NULL; // NULL triggers exception
|
|
|
|
void* ptr = 0;
|
|
try {
|
|
Base::Interpreter().convertSWIGPointerObj("pivy.gui.soqt", "SoQtViewer *", proxy, &ptr, 0);
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
PyErr_SetString(PyExc_RuntimeError, e.what());
|
|
return 0;
|
|
}
|
|
|
|
View3DInventorViewer* viewer = reinterpret_cast<View3DInventorViewer*>(ptr);
|
|
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->pubSeekToPoint(hitpoint);
|
|
}
|
|
else {
|
|
Py::Int x(tuple[0]);
|
|
Py::Int y(tuple[1]);
|
|
|
|
SbVec2s hitpoint ((long)x,(long)y);
|
|
viewer->pubSeekToPoint(hitpoint);
|
|
}
|
|
|
|
return Py::new_reference_to(Py::None()); // increment ref counter
|
|
}
|
|
catch (const Py::Exception&) {
|
|
return NULL;
|
|
}*/
|
|
}
|
|
|
|
struct PyMethodDef wrap_SoQtViewer_methods[] = {
|
|
{"setViewDirection",wrap_SoQtViewer_setViewDirection,METH_VARARGS,
|
|
"setViewDirection(tuple) -> None"},
|
|
{"getViewDirection",wrap_SoQtViewer_getViewDirection,METH_VARARGS,
|
|
"getViewDirection() -> tuple"},
|
|
{"setFocalDistance",wrap_SoQtViewer_setFocalDistance,METH_VARARGS,
|
|
"setFocalDistance(float) -> None"},
|
|
{"getFocalDistance",wrap_SoQtViewer_getFocalDistance,METH_VARARGS,
|
|
"getFocalDistance() -> float"},
|
|
{"seekToPoint",wrap_SoQtViewer_seekToPoint,METH_VARARGS,
|
|
"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"},
|
|
{NULL, NULL} /* sentinel */
|
|
};
|
|
|
|
Py::Object View3DInventorPy::getViewer(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
|
|
PyObject* proxy = 0;
|
|
try {
|
|
// Note: As there is no ref'counting mechanism for the viewer class we must
|
|
// pass '0' as the third parameter so that the Python object does not 'own'
|
|
// the viewer.
|
|
// Note: Once we have closed the viewer the Python object must not be used
|
|
// anymore as it has a dangling pointer.
|
|
Quarter::SoQTQuarterAdaptor* view = _view->getViewer();
|
|
proxy = Base::Interpreter().createSWIGPointerObj("pivy.gui.soqt", "SoQtViewer *", (void*)view, 0);
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
|
|
// Add some additional methods to the viewer's type object
|
|
static bool first=true;
|
|
if (first && proxy) {
|
|
first = false;
|
|
PyMethodDef *meth = wrap_SoQtViewer_methods;
|
|
PyTypeObject *type = proxy->ob_type;
|
|
PyObject *dict = type->tp_dict;
|
|
for (; meth->ml_name != NULL; meth++) {
|
|
PyObject *descr;
|
|
descr = PyDescr_NewMethod(type, meth);
|
|
if (descr == NULL)
|
|
break;
|
|
if (PyDict_SetItemString(dict, meth->ml_name, descr) < 0)
|
|
break;
|
|
Py_DECREF(descr);
|
|
}
|
|
}
|
|
return Py::Object(proxy, true); // no further incremention needed
|
|
}
|
|
|
|
void View3DInventorPy::eventCallbackPivy(void * ud, SoEventCallback * n)
|
|
{
|
|
Base::PyGILStateLocker lock;
|
|
const SoEvent* e = n->getEvent();
|
|
std::string type = e->getTypeId().getName().getString();
|
|
type += " *";
|
|
|
|
PyObject* proxy = 0;
|
|
try {
|
|
proxy = Base::Interpreter().createSWIGPointerObj("pivy.coin", type.c_str(), (void*)e, 0);
|
|
// now run the method
|
|
Py::Object event(proxy,true);
|
|
Py::Callable method(reinterpret_cast<PyObject*>(ud));
|
|
Py::Tuple args(1);
|
|
args.setItem(0, event);
|
|
method.apply(args);
|
|
}
|
|
catch (const Base::Exception&) {
|
|
return;
|
|
}
|
|
catch (const Py::Exception& e) {
|
|
Py::Object o = Py::type(e);
|
|
if (o.isString()) {
|
|
Py::String s(o);
|
|
Base::Console().Warning("%s\n", s.as_std_string().c_str());
|
|
}
|
|
else {
|
|
Py::String s(o.repr());
|
|
Base::Console().Warning("%s\n", s.as_std_string().c_str());
|
|
}
|
|
// Prints message to console window if we are in interactive mode
|
|
PyErr_Print();
|
|
}
|
|
}
|
|
|
|
void View3DInventorPy::eventCallbackPivyEx(void * ud, SoEventCallback * n)
|
|
{
|
|
Base::PyGILStateLocker lock;
|
|
std::string type = "SoEventCallback *";
|
|
|
|
PyObject* proxy = 0;
|
|
try {
|
|
proxy = Base::Interpreter().createSWIGPointerObj("pivy.coin", type.c_str(), (void*)n, 0);
|
|
// now run the method
|
|
Py::Object event(proxy,true);
|
|
Py::Callable method(reinterpret_cast<PyObject*>(ud));
|
|
Py::Tuple args(1);
|
|
args.setItem(0, event);
|
|
method.apply(args);
|
|
}
|
|
catch (const Base::Exception&) {
|
|
return;
|
|
}
|
|
catch (const Py::Exception& e) {
|
|
Py::Object o = Py::type(e);
|
|
if (o.isString()) {
|
|
Py::String s(o);
|
|
Base::Console().Warning("%s\n", s.as_std_string().c_str());
|
|
}
|
|
else {
|
|
Py::String s(o.repr());
|
|
Base::Console().Warning("%s\n", s.as_std_string().c_str());
|
|
}
|
|
// Prints message to console window if we are in interactive mode
|
|
PyErr_Print();
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::addEventCallbackPivy(const Py::Tuple& args)
|
|
{
|
|
PyObject* proxy;
|
|
PyObject* method;
|
|
int ex=1; // if 1, use eventCallbackPivyEx
|
|
if (!PyArg_ParseTuple(args.ptr(), "OO|i", &proxy, &method,&ex))
|
|
throw Py::Exception();
|
|
|
|
void* ptr = 0;
|
|
try {
|
|
Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoType *", proxy, &ptr, 0);
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
|
|
SoType* eventId = reinterpret_cast<SoType*>(ptr);
|
|
if (eventId->isBad() || !eventId->isDerivedFrom(SoEvent::getClassTypeId())) {
|
|
std::string s;
|
|
std::ostringstream s_out;
|
|
s_out << eventId->getName().getString() << "is not a valid event type";
|
|
throw Py::Exception(s_out.str());
|
|
}
|
|
|
|
try {
|
|
if (PyCallable_Check(method) == 0) {
|
|
throw Py::Exception("object is not callable");
|
|
}
|
|
|
|
SoEventCallbackCB* callback = (ex == 1 ?
|
|
View3DInventorPy::eventCallbackPivyEx :
|
|
View3DInventorPy::eventCallbackPivy);
|
|
_view->getViewer()->addEventCallback(*eventId, callback, method);
|
|
callbacks.push_back(method);
|
|
Py_INCREF(method);
|
|
return Py::Callable(method, false);
|
|
}
|
|
catch (const Py::Exception&) {
|
|
throw;
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::removeEventCallbackPivy(const Py::Tuple& args)
|
|
{
|
|
PyObject* proxy;
|
|
PyObject* method;
|
|
int ex=1; // if 1, use eventCallbackPivyEx
|
|
if (!PyArg_ParseTuple(args.ptr(), "OO|i", &proxy, &method,&ex))
|
|
throw Py::Exception();
|
|
|
|
void* ptr = 0;
|
|
try {
|
|
Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoType *", proxy, &ptr, 0);
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
|
|
SoType* eventId = reinterpret_cast<SoType*>(ptr);
|
|
if (eventId->isBad() || !eventId->isDerivedFrom(SoEvent::getClassTypeId())) {
|
|
std::string s;
|
|
std::ostringstream s_out;
|
|
s_out << eventId->getName().getString() << "is not a valid event type";
|
|
throw Py::Exception(s_out.str());
|
|
}
|
|
|
|
try {
|
|
if (PyCallable_Check(method) == 0) {
|
|
throw Py::Exception("object is not callable");
|
|
}
|
|
|
|
SoEventCallbackCB* callback = (ex == 1 ?
|
|
View3DInventorPy::eventCallbackPivyEx :
|
|
View3DInventorPy::eventCallbackPivy);
|
|
_view->getViewer()->removeEventCallback(*eventId, callback, method);
|
|
callbacks.remove(method);
|
|
Py_DECREF(method);
|
|
return Py::Callable(method, false);
|
|
}
|
|
catch (const Py::Exception&) {
|
|
throw;
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::setAxisCross(const Py::Tuple& args)
|
|
{
|
|
int ok;
|
|
if (!PyArg_ParseTuple(args.ptr(), "i", &ok))
|
|
throw Py::Exception();
|
|
_view->getViewer()->setAxisCross(ok!=0);
|
|
return Py::None();
|
|
}
|
|
|
|
Py::Object View3DInventorPy::hasAxisCross(const Py::Tuple& args)
|
|
{
|
|
if (!PyArg_ParseTuple(args.ptr(), ""))
|
|
throw Py::Exception();
|
|
SbBool ok = _view->getViewer()->hasAxisCross();
|
|
return Py::Boolean(ok ? true : false);
|
|
}
|
|
|
|
void View3DInventorPy::draggerCallback(void * ud, SoDragger* n)
|
|
{
|
|
Base::PyGILStateLocker lock;
|
|
PyObject* proxy = 0;
|
|
try {
|
|
proxy = Base::Interpreter().createSWIGPointerObj("pivy.coin", "SoDragger *", (void*)n, 0);
|
|
//call the method
|
|
Py::Object dragger(proxy,true);
|
|
Py::Callable method(reinterpret_cast<PyObject*>(ud));
|
|
Py::Tuple args(1);
|
|
args.setItem(0, dragger);
|
|
method.apply(args);
|
|
}
|
|
catch (const Base::Exception& e) {
|
|
throw Py::Exception(e.what());
|
|
}
|
|
catch (const Py::Exception& e) {
|
|
Py::Object o = Py::type(e);
|
|
if (o.isString()) {
|
|
Py::String s(o);
|
|
Base::Console().Warning("%s\n", s.as_std_string().c_str());
|
|
}
|
|
else {
|
|
Py::String s(o.repr());
|
|
Base::Console().Warning("%s\n", s.as_std_string().c_str());
|
|
}
|
|
// Prints message to console window if we are in interactive mode
|
|
PyErr_Print();
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::addDraggerCallback(const Py::Tuple& args)
|
|
{
|
|
PyObject* dragger;
|
|
char* type;
|
|
PyObject* method;
|
|
if (!PyArg_ParseTuple(args.ptr(), "OsO", &dragger,&type, &method))
|
|
throw Py::Exception();
|
|
|
|
|
|
//Check if dragger is a SoDragger object and cast
|
|
void* ptr = 0;
|
|
try {
|
|
Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoDragger *", dragger, &ptr, 0);
|
|
}
|
|
catch (const Base::Exception&) {
|
|
throw Py::Exception("The first argument must be of type SoDragger");
|
|
}
|
|
SoDragger* drag = reinterpret_cast<SoDragger*>(ptr);
|
|
|
|
//Check if method is callable
|
|
if (PyCallable_Check(method) == 0) {
|
|
throw Py::Exception("the method is not callable");
|
|
}
|
|
|
|
try {
|
|
if (strcmp(type,"addFinishCallback")==0) {
|
|
drag->addFinishCallback(draggerCallback,method);
|
|
}
|
|
else if (strcmp(type,"addStartCallback")==0) {
|
|
drag->addStartCallback(draggerCallback,method);
|
|
}
|
|
else if (strcmp(type,"addMotionCallback")==0) {
|
|
drag->addMotionCallback(draggerCallback,method);
|
|
}
|
|
else if (strcmp(type,"addValueChangedCallback")==0) {
|
|
drag->addValueChangedCallback(draggerCallback,method);
|
|
}
|
|
else {
|
|
std::string s;
|
|
std::ostringstream s_out;
|
|
s_out << type << " is not a valid dragger callback type";
|
|
throw Py::Exception(s_out.str());
|
|
}
|
|
|
|
callbacks.push_back(method);
|
|
Py_INCREF(method);
|
|
return Py::Callable(method, false);
|
|
}
|
|
catch (const Py::Exception&) {
|
|
throw;
|
|
}
|
|
}
|
|
|
|
Py::Object View3DInventorPy::removeDraggerCallback(const Py::Tuple& args)
|
|
{
|
|
PyObject* dragger;
|
|
char* type;
|
|
PyObject* method;
|
|
if (!PyArg_ParseTuple(args.ptr(), "OsO", &dragger,&type, &method))
|
|
throw Py::Exception();
|
|
|
|
//Check if dragger is a SoDragger object and cast
|
|
void* ptr = 0;
|
|
try {
|
|
Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoDragger *", dragger, &ptr, 0);
|
|
}
|
|
catch (const Base::Exception&) {
|
|
throw Py::Exception("The first argument must be of type SoDragger");
|
|
}
|
|
|
|
SoDragger* drag = reinterpret_cast<SoDragger*>(ptr);
|
|
try {
|
|
if (strcmp(type,"addFinishCallback")==0) {
|
|
drag->removeFinishCallback(draggerCallback,method);
|
|
}
|
|
else if (strcmp(type,"addStartCallback")==0) {
|
|
drag->removeStartCallback(draggerCallback,method);
|
|
}
|
|
else if (strcmp(type,"addMotionCallback")==0) {
|
|
drag->removeMotionCallback(draggerCallback,method);
|
|
}
|
|
else if (strcmp(type,"addValueChangedCallback")==0) {
|
|
drag->removeValueChangedCallback(draggerCallback,method);
|
|
}
|
|
else {
|
|
std::string s;
|
|
std::ostringstream s_out;
|
|
s_out << type << " is not a valid dragger callback type";
|
|
throw Py::Exception(s_out.str());
|
|
}
|
|
|
|
callbacks.remove(method);
|
|
Py_DECREF(method);
|
|
return Py::Callable(method, false);
|
|
}
|
|
catch (const Py::Exception&) {
|
|
throw;
|
|
}
|
|
}
|