View3DPy.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) Jürgen Riegel          (juergen.riegel@web.de) 2002     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 
00026 #ifndef __InventorAll__
00027 # include "InventorAll.h"
00028 # include <sstream>
00029 #endif
00030 
00031 
00032 #include "View3DPy.h"
00033 #include "ViewProviderDocumentObject.h"
00034 #include "ViewProviderExtern.h"
00035 #include "Application.h"
00036 #include "Document.h"
00037 #include "NavigationStyle.h"
00038 #include "SoFCSelection.h"
00039 #include "SoFCSelectionAction.h"
00040 #include "SoFCVectorizeSVGAction.h"
00041 #include "SoFCVectorizeU3DAction.h"
00042 #include "SoFCDB.h"
00043 #include "View3DInventor.h"
00044 #include "View3DInventorViewer.h"
00045 
00046 #include <Base/Console.h>
00047 #include <Base/Exception.h>
00048 #include <Base/Interpreter.h>
00049 #include <Base/PlacementPy.h>
00050 #include <Base/VectorPy.h>
00051 #include <Base/GeometryPyCXX.h>
00052 
00053 #include <App/Document.h>
00054 #include <App/DocumentObject.h>
00055 #include <CXX/Objects.hxx>
00056 
00057 using namespace Gui;
00058 
00059 
00060 void View3DInventorPy::init_type()
00061 {
00062     behaviors().name("View3DInventorPy");
00063     behaviors().doc("Python binding class for the Inventor viewer class");
00064     // you must have overwritten the virtual functions
00065     behaviors().supportRepr();
00066     behaviors().supportGetattr();
00067     behaviors().supportSetattr();
00068 
00069     add_varargs_method("message",&View3DInventorPy::message,"message()");
00070     add_varargs_method("fitAll",&View3DInventorPy::fitAll,"fitAll()");
00071 
00072     add_varargs_method("viewBottom",&View3DInventorPy::viewBottom,"viewBottom()");
00073     add_varargs_method("viewFront",&View3DInventorPy::viewFront,"viewFront()");
00074     add_varargs_method("viewLeft",&View3DInventorPy::viewLeft,"viewLeft()");
00075     add_varargs_method("viewRear",&View3DInventorPy::viewRear,"viewRear()");
00076     add_varargs_method("viewRight",&View3DInventorPy::viewRight,"viewRight()");
00077     add_varargs_method("viewTop",&View3DInventorPy::viewTop,"viewTop()");
00078     add_varargs_method("viewAxometric",&View3DInventorPy::viewAxometric,"viewAxometric()");
00079     add_varargs_method("viewPosition",&View3DInventorPy::viewPosition,"viewPosition()");
00080     add_varargs_method("startAnimating",&View3DInventorPy::startAnimating,"startAnimating()");
00081     add_varargs_method("stopAnimating",&View3DInventorPy::stopAnimating,"stopAnimating()");
00082     add_varargs_method("setAnimationEnabled",&View3DInventorPy::setAnimationEnabled,"setAnimationEnabled()");
00083     add_varargs_method("isAnimationEnabled",&View3DInventorPy::isAnimationEnabled,"isAnimationEnabled()");
00084     add_varargs_method("dump",&View3DInventorPy::dump,"dump()");
00085     add_varargs_method("dumpNode",&View3DInventorPy::dumpNode,"dumpNode(node)");
00086     add_varargs_method("setStereoType",&View3DInventorPy::setStereoType,"setStereoType()");
00087     add_varargs_method("getStereoType",&View3DInventorPy::getStereoType,"getStereoType()");
00088     add_varargs_method("listStereoTypes",&View3DInventorPy::listStereoTypes,"listStereoTypes()");
00089     add_varargs_method("saveImage",&View3DInventorPy::saveImage,"saveImage()");
00090     add_varargs_method("saveVectorGraphic",&View3DInventorPy::saveVectorGraphic,"saveVectorGraphic()");
00091     add_varargs_method("getCamera",&View3DInventorPy::getCamera,"getCamera()");
00092     add_varargs_method("getCameraNode",&View3DInventorPy::getCameraNode,"getCameraNode()");
00093     add_varargs_method("getViewDirection",&View3DInventorPy::getViewDirection,"getViewDirection()");
00094     add_varargs_method("setCamera",&View3DInventorPy::setCamera,"setCamera()");
00095     add_varargs_method("setCameraOrientation",&View3DInventorPy::setCameraOrientation,"setCameraOrientation()");
00096     add_varargs_method("getCameraType",&View3DInventorPy::getCameraType,"getCameraType()");
00097     add_varargs_method("setCameraType",&View3DInventorPy::setCameraType,"setCameraType()");
00098     add_varargs_method("listCameraTypes",&View3DInventorPy::listCameraTypes,"listCameraTypes()");
00099     add_varargs_method("getCursorPos",&View3DInventorPy::getCursorPos,
00100         "getCursorPos() -> tuple of integers\n"
00101         "\n"
00102         "Return the current cursor position relative to the coordinate system of the\n"
00103         "viewport region.\n");
00104     add_varargs_method("getObjectInfo",&View3DInventorPy::getObjectInfo,
00105         "getObjectInfo(tuple of integers) -> dictionary or None\n"
00106         "\n"
00107         "Return a dictionary with the name of document, object and component. The\n"
00108         "dictionary also contains the coordinates of the appropriate 3d point of\n"
00109         "the underlying geometry in the scenegraph.\n"
00110         "If no geometry was found 'None' is returned, instead.\n");
00111     add_varargs_method("getObjectsInfo",&View3DInventorPy::getObjectsInfo,
00112         "getObjectsInfo(tuple of integers) -> dictionary or None\n"
00113         "\n"
00114         "Does the same as getObjectInfo() but returns a list of dictionaries or None.\n");
00115     add_varargs_method("getSize",&View3DInventorPy::getSize,"getSize()");
00116     add_varargs_method("getPoint",&View3DInventorPy::getPoint,
00117         "getPoint(pixel coords (as integer)) -> 3D vector\n"
00118         "\n"
00119         "Return the according 3D point on the focal plane to the given 2D point (in\n"
00120         "pixel coordinates).\n");
00121     add_varargs_method("addEventCallback",&View3DInventorPy::addEventCallback,"addEventCallback()");
00122     add_varargs_method("removeEventCallback",&View3DInventorPy::removeEventCallback,"removeEventCallback()");
00123     add_varargs_method("setAnnotation",&View3DInventorPy::setAnnotation,"setAnnotation()");
00124     add_varargs_method("removeAnnotation",&View3DInventorPy::removeAnnotation,"removeAnnotation()");
00125     add_varargs_method("getSceneGraph",&View3DInventorPy::getSceneGraph,"getSceneGraph()");
00126     add_varargs_method("getViewer",&View3DInventorPy::getViewer,"getViewer()");
00127     add_varargs_method("addEventCallbackPivy",&View3DInventorPy::addEventCallbackPivy,"addEventCallbackPivy()");
00128     add_varargs_method("removeEventCallbackPivy",&View3DInventorPy::removeEventCallbackPivy,"removeEventCallbackPivy()");
00129     add_varargs_method("addEventCallbackSWIG",&View3DInventorPy::addEventCallbackPivy,
00130         "Deprecated -- use addEventCallbackPivy()");
00131     add_varargs_method("removeEventCallbackSWIG",&View3DInventorPy::removeEventCallbackPivy,
00132         "Deprecated -- use removeEventCallbackPivy()");
00133     add_varargs_method("listNavigationTypes",&View3DInventorPy::listNavigationTypes,"listNavigationTypes()");
00134     add_varargs_method("getNavigationType",&View3DInventorPy::getNavigationType,"getNavigationType()");
00135     add_varargs_method("setNavigationType",&View3DInventorPy::setNavigationType,"setNavigationType()");
00136 }
00137 
00138 View3DInventorPy::View3DInventorPy(View3DInventor *vi)
00139   : _view(vi)
00140 {
00141 }
00142 
00143 View3DInventorPy::~View3DInventorPy()
00144 {
00145     for (std::list<PyObject*>::iterator it = callbacks.begin(); it != callbacks.end(); ++it)
00146         Py_DECREF(*it);
00147 }
00148 
00149 Py::Object View3DInventorPy::repr()
00150 {
00151     std::string s;
00152     std::ostringstream s_out;
00153     if (!_view)
00154         throw Py::RuntimeError("Cannot print representation of deleted object");
00155     s_out << "View3DInventor";
00156     return Py::String(s_out.str());
00157 }
00158 
00159 View3DInventorPy::method_varargs_handler View3DInventorPy::pycxx_handler = 0;
00160 
00161 PyObject *View3DInventorPy::method_varargs_ext_handler(PyObject *_self_and_name_tuple, PyObject *_args)
00162 {
00163     try {
00164         return pycxx_handler(_self_and_name_tuple, _args);
00165     }
00166     catch (const Base::Exception& e) {
00167         throw Py::Exception(e.what());
00168     }
00169     catch (const std::exception& e) {
00170         throw Py::Exception(e.what());
00171     }
00172     catch(...) {
00173         throw Py::Exception("Unknown C++ exception");
00174     }
00175 }
00176 
00177 Py::Object View3DInventorPy::getattr(const char * attr)
00178 {
00179     if (!_view) {
00180         std::string s;
00181         std::ostringstream s_out;
00182         s_out << "Cannot access attribute '" << attr << "' of deleted object";
00183         throw Py::RuntimeError(s_out.str());
00184     }
00185     else {
00186         Py::Object obj = Py::PythonExtension<View3DInventorPy>::getattr(attr);
00187         if (PyCFunction_Check(obj.ptr())) {
00188             PyCFunctionObject* op = reinterpret_cast<PyCFunctionObject*>(obj.ptr());
00189             if (!pycxx_handler)
00190                 pycxx_handler = op->m_ml->ml_meth;
00191             op->m_ml->ml_meth = method_varargs_ext_handler;
00192         }
00193         return obj;
00194     }
00195 }
00196 
00197 int View3DInventorPy::setattr(const char * attr, const Py::Object & value)
00198 {
00199     if (!_view) {
00200         std::string s;
00201         std::ostringstream s_out;
00202         s_out << "Cannot access attribute '" << attr << "' of deleted object";
00203         throw Py::RuntimeError(s_out.str());
00204     }
00205     else {
00206         return Py::PythonExtension<View3DInventorPy>::setattr(attr, value);
00207     }
00208 }
00209 
00210 Py::Object View3DInventorPy::message(const Py::Tuple& args)
00211 {
00212     const char **ppReturn = 0;
00213     char *psMsgStr;
00214     if (!PyArg_ParseTuple(args.ptr(), "s;Message string needed (string)",&psMsgStr))     // convert args: Python->C 
00215         throw Py::Exception();
00216 
00217     try {
00218         _view->onMsg(psMsgStr,ppReturn);
00219     }
00220     catch (const Base::Exception& e) {
00221         throw Py::Exception(e.what());
00222     }
00223     catch (const std::exception& e) {
00224         throw Py::Exception(e.what());
00225     }
00226     catch(...) {
00227         throw Py::Exception("Unknown C++ exception");
00228     }
00229     return Py::None();
00230 }
00231 
00232 Py::Object View3DInventorPy::fitAll(const Py::Tuple& args)
00233 {
00234     double factor = 1.0;
00235     if (!PyArg_ParseTuple(args.ptr(), "|d", &factor))
00236         throw Py::Exception();
00237 
00238     try {
00239         _view->getViewer()->viewAll((float)factor);
00240     }
00241     catch (const Base::Exception& e) {
00242         throw Py::Exception(e.what());
00243     }
00244     catch (const std::exception& e) {
00245         throw Py::Exception(e.what());
00246     }
00247     catch(...) {
00248         throw Py::Exception("Unknown C++ exception");
00249     }
00250     return Py::None();
00251 }
00252 
00253 Py::Object View3DInventorPy::viewBottom(const Py::Tuple& args)
00254 {
00255     if (!PyArg_ParseTuple(args.ptr(), ""))
00256         throw Py::Exception();
00257 
00258     try {
00259         _view->getViewer()->setCameraOrientation(SbRotation(-1, 0, 0, 0));
00260     }
00261     catch (const Base::Exception& e) {
00262         throw Py::Exception(e.what());
00263     }
00264     catch (const std::exception& e) {
00265         throw Py::Exception(e.what());
00266     }
00267     catch(...) {
00268         throw Py::Exception("Unknown C++ exception");
00269     }
00270 
00271     return Py::None();
00272 }
00273 
00274 Py::Object View3DInventorPy::viewFront(const Py::Tuple& args)
00275 {
00276     if (!PyArg_ParseTuple(args.ptr(), ""))
00277         throw Py::Exception();
00278 
00279     try {
00280         float root = (float)(sqrt(2.0)/2.0);
00281         _view->getViewer()->setCameraOrientation(SbRotation(-root, 0, 0, -root));
00282     }
00283     catch (const Base::Exception& e) {
00284         throw Py::Exception(e.what());
00285     }
00286     catch (const std::exception& e) {
00287         throw Py::Exception(e.what());
00288     }
00289     catch(...) {
00290         throw Py::Exception("Unknown C++ exception");
00291     }
00292 
00293     return Py::None();
00294 }
00295 
00296 Py::Object View3DInventorPy::viewLeft(const Py::Tuple& args)
00297 {
00298     if (!PyArg_ParseTuple(args.ptr(), ""))
00299         throw Py::Exception();
00300 
00301     try {
00302         _view->getViewer()->setCameraOrientation(SbRotation(-0.5, 0.5, 0.5, -0.5));
00303     }
00304     catch (const Base::Exception& e) {
00305         throw Py::Exception(e.what());
00306     }
00307     catch (const std::exception& e) {
00308         throw Py::Exception(e.what());
00309     }
00310     catch(...) {
00311         throw Py::Exception("Unknown C++ exception");
00312     }
00313 
00314     return Py::None();
00315 }
00316 
00317 Py::Object View3DInventorPy::viewRear(const Py::Tuple& args)
00318 {
00319     if (!PyArg_ParseTuple(args.ptr(), ""))
00320         throw Py::Exception();
00321 
00322     try {
00323         float root = (float)(sqrt(2.0)/2.0);
00324         _view->getViewer()->setCameraOrientation(SbRotation(0, root, root, 0));
00325     }
00326     catch (const Base::Exception& e) {
00327         throw Py::Exception(e.what());
00328     }
00329     catch (const std::exception& e) {
00330         throw Py::Exception(e.what());
00331     }
00332     catch(...) {
00333         throw Py::Exception("Unknown C++ exception");
00334     }
00335 
00336     return Py::None();
00337 }
00338 
00339 Py::Object View3DInventorPy::viewRight(const Py::Tuple& args)
00340 {
00341     if (!PyArg_ParseTuple(args.ptr(), ""))
00342         throw Py::Exception();
00343 
00344     try {
00345         _view->getViewer()->setCameraOrientation(SbRotation(0.5, 0.5, 0.5, 0.5));
00346     }
00347     catch (const Base::Exception& e) {
00348         throw Py::Exception(e.what());
00349     }
00350     catch (const std::exception& e) {
00351         throw Py::Exception(e.what());
00352     }
00353     catch(...) {
00354         throw Py::Exception("Unknown C++ exception");
00355     }
00356 
00357     return Py::None();
00358 }
00359 
00360 Py::Object View3DInventorPy::viewTop(const Py::Tuple& args)
00361 {
00362     if (!PyArg_ParseTuple(args.ptr(), ""))
00363         throw Py::Exception();
00364 
00365     try {
00366         _view->getViewer()->setCameraOrientation(SbRotation(0, 0, 0, 1));
00367     }
00368     catch (const Base::Exception& e) {
00369         throw Py::Exception(e.what());
00370     }
00371     catch (const std::exception& e) {
00372         throw Py::Exception(e.what());
00373     }
00374     catch(...) {
00375         throw Py::Exception("Unknown C++ exception");
00376     }
00377 
00378     return Py::None();
00379 }
00380 
00381 Py::Object View3DInventorPy::viewAxometric(const Py::Tuple& args)
00382 {
00383     if (!PyArg_ParseTuple(args.ptr(), ""))
00384         throw Py::Exception();
00385 
00386     try {
00387         _view->getViewer()->setCameraOrientation(SbRotation
00388             (-0.353553f, -0.146447f, -0.353553f, -0.853553f));
00389     }
00390     catch (const Base::Exception& e) {
00391         throw Py::Exception(e.what());
00392     }
00393     catch (const std::exception& e) {
00394         throw Py::Exception(e.what());
00395     }
00396     catch(...) {
00397         throw Py::Exception("Unknown C++ exception");
00398     }
00399 
00400     return Py::None();
00401 }
00402 
00403 Py::Object View3DInventorPy::setCameraOrientation(const Py::Tuple& args)
00404 {
00405     PyObject* o;
00406     if (!PyArg_ParseTuple(args.ptr(), "O!", &PyTuple_Type, &o))
00407         throw Py::Exception();
00408 
00409     try {
00410         Py::Tuple tuple(o);
00411         float q0 = (float)Py::Float(tuple[0]);
00412         float q1 = (float)Py::Float(tuple[1]);
00413         float q2 = (float)Py::Float(tuple[2]);
00414         float q3 = (float)Py::Float(tuple[3]);
00415         _view->getViewer()->setCameraOrientation(SbRotation(q0, q1, q2, q3));
00416     }
00417     catch (const Base::Exception& e) {
00418         throw Py::Exception(e.what());
00419     }
00420     catch (const std::exception& e) {
00421         throw Py::Exception(e.what());
00422     }
00423     catch(...) {
00424         throw Py::Exception("Unknown C++ exception");
00425     }
00426 
00427     return Py::None();
00428 }
00429 
00430 Py::Object View3DInventorPy::viewPosition(const Py::Tuple& args)
00431 {
00432     PyObject* p=0;
00433     int steps = 20;
00434     int ms = 30;
00435     if (!PyArg_ParseTuple(args.ptr(), "|O!ii",&Base::PlacementPy::Type,&p,&steps,&ms))
00436         throw Py::Exception();
00437 
00438     if (p) {
00439         Base::Placement* plm = static_cast<Base::PlacementPy*>(p)->getPlacementPtr();
00440         Base::Rotation rot = plm->getRotation();
00441         Base::Vector3d pos = plm->getPosition();
00442         double q0,q1,q2,q3;
00443         rot.getValue(q0,q1,q2,q3);
00444         _view->getViewer()->moveCameraTo(
00445             SbRotation((float)q0, (float)q1, (float)q2, (float)q3),
00446             SbVec3f((float)pos.x, (float)pos.y, (float)pos.z), steps, ms);
00447     }
00448 
00449     SoCamera* cam = _view->getViewer()->getCamera();
00450     if (!cam) return Py::None();
00451 
00452     SbRotation rot = cam->orientation.getValue();
00453     SbVec3f pos = cam->position.getValue();
00454     float q0,q1,q2,q3;
00455     rot.getValue(q0,q1,q2,q3);
00456     Base::Placement plm(
00457         Base::Vector3d(pos[0], pos[1], pos[2]),
00458         Base::Rotation(q0, q1, q2, q3));
00459     return Py::Placement(plm);
00460 }
00461 
00462 Py::Object View3DInventorPy::startAnimating(const Py::Tuple& args)
00463 {
00464     float x,y,z;
00465     float velocity;
00466     if (!PyArg_ParseTuple(args.ptr(), "ffff", &x,&y,&z,&velocity))
00467         throw Py::Exception();
00468     _view->getViewer()->startAnimating(SbVec3f(x,y,z),velocity);
00469     return Py::None();
00470 }
00471 
00472 Py::Object View3DInventorPy::stopAnimating(const Py::Tuple& args)
00473 {
00474     if (!PyArg_ParseTuple(args.ptr(), ""))
00475         throw Py::Exception();
00476     _view->getViewer()->stopAnimating();
00477     return Py::None();
00478 }
00479 
00480 Py::Object View3DInventorPy::setAnimationEnabled(const Py::Tuple& args)
00481 {
00482     int ok;
00483     if (!PyArg_ParseTuple(args.ptr(), "i", &ok))
00484         throw Py::Exception();
00485     _view->getViewer()->setAnimationEnabled(ok!=0);
00486     return Py::None();
00487 }
00488 
00489 Py::Object View3DInventorPy::isAnimationEnabled(const Py::Tuple& args)
00490 {
00491     if (!PyArg_ParseTuple(args.ptr(), ""))
00492         throw Py::Exception();
00493     SbBool ok = _view->getViewer()->isAnimationEnabled();
00494     return Py::Boolean(ok ? true : false);
00495 }
00496 
00497 Py::Object View3DInventorPy::saveImage(const Py::Tuple& args)
00498 {
00499     char *cFileName,*cImageType="Current",*cComment="$MIBA";
00500     int w=-1,h=-1,t;
00501 
00502     if (!PyArg_ParseTuple(args.ptr(), "s|iiss",&cFileName,&w,&h,&cImageType,&cComment))
00503         throw Py::Exception();
00504 
00505 #ifdef __GNUC__
00506     if (strcasecmp(cImageType,"Current")==0)
00507         t=0;
00508     else if(strcasecmp(cImageType,"Black")==0)
00509         t=1;
00510     else if(strcasecmp(cImageType,"White")==0)
00511         t=2;
00512     else if(strcasecmp(cImageType,"Transparent")==0)
00513         t=3;
00514     else 
00515         throw Py::Exception("Parameter 4 have to be (Current|Black|White|Transparent)");
00516 #else
00517     if (_stricmp(cImageType,"Current")==0)
00518         t=0;
00519     else if(_stricmp(cImageType,"Black")==0)
00520         t=1;
00521     else if(_stricmp(cImageType,"White")==0)
00522         t=2;
00523     else if(_stricmp(cImageType,"Transparent")==0)
00524         t=3;
00525     else 
00526         throw Py::Exception("Parameter 4 have to be (Current|Black|White|Transparent)");
00527 #endif
00528 
00529     try {
00530         QColor c;
00531         _view->getViewer()->savePicture(cFileName,w,h,t,cComment);
00532         return Py::None();
00533     }
00534     catch (const Base::Exception& e) {
00535         throw Py::Exception(e.what());
00536     }
00537     catch (const std::exception& e) {
00538         throw Py::Exception(e.what());
00539     }
00540     catch(...) {
00541         throw Py::Exception("Unknown C++ exception");
00542     }
00543 }
00544 
00545 Py::Object View3DInventorPy::saveVectorGraphic(const Py::Tuple& args)
00546 {
00547     char* filename;
00548     int ps=4, t=2;
00549 
00550     if (!PyArg_ParseTuple(args.ptr(), "s|ii",&filename,&ps,&t))
00551         throw Py::Exception();
00552 
00553     std::auto_ptr<SoVectorizeAction> vo;
00554     Base::FileInfo fi(filename);
00555     if (fi.hasExtension("ps") || fi.hasExtension("eps")) {
00556         vo = std::auto_ptr<SoVectorizeAction>(new SoVectorizePSAction());
00557         //vo->setGouraudThreshold(0.0f);
00558     }
00559     else if (fi.hasExtension("svg")) {
00560         vo = std::auto_ptr<SoVectorizeAction>(new SoFCVectorizeSVGAction());
00561     }
00562     else if (fi.hasExtension("idtf")) {
00563         vo = std::auto_ptr<SoVectorizeAction>(new SoFCVectorizeU3DAction());
00564     }
00565     else {
00566         throw Py::Exception("Not supported vector graphic");
00567     }
00568 
00569     SoVectorOutput * out = vo->getOutput();
00570     if (!out || !out->openFile(filename)) {
00571         std::ostringstream a_out;
00572         a_out << "Cannot open file '" << filename << "'";
00573         throw Py::Exception(a_out.str());
00574     }
00575 
00576     _view->getViewer()->saveGraphic(ps,t,vo.get());
00577     out->closeFile();
00578     return Py::None();
00579 }
00580 
00581 Py::Object View3DInventorPy::getCameraNode(const Py::Tuple& args)
00582 {
00583     if (!PyArg_ParseTuple(args.ptr(), ""))
00584         throw Py::Exception();
00585 
00586     try {
00587         SoNode* camera = _view->getViewer()->getCamera();
00588         PyObject* proxy = 0;
00589         std::string type;
00590         type = "So"; // seems that So prefix is missing in camera node
00591         type += camera->getTypeId().getName().getString();
00592         type += " *";
00593         proxy = Base::Interpreter().createSWIGPointerObj("pivy.coin", type.c_str(), (void*)camera, 1);
00594         camera->ref();
00595         return Py::Object(proxy, true);
00596     }
00597     catch (const Base::Exception& e) {
00598         throw Py::Exception(e.what());
00599     }
00600 }
00601 
00602 Py::Object View3DInventorPy::getCamera(const Py::Tuple& args)
00603 {
00604     if (!PyArg_ParseTuple(args.ptr(), ""))
00605         throw Py::Exception();
00606 
00607     SoOutput out;
00608     char buffer[512];
00609     out.setBuffer(buffer, 512, 0);
00610 
00611     try {
00612         SoWriteAction wa(&out);
00613         SoCamera * cam = _view->getViewer()->getCamera();
00614         if (cam) wa.apply(cam);
00615         else buffer[0] = '\0';
00616         return Py::String(buffer);
00617     }
00618     catch (const Base::Exception& e) {
00619         throw Py::Exception(e.what());
00620     }
00621     catch (const std::exception& e) {
00622         throw Py::Exception(e.what());
00623     }
00624     catch(...) {
00625         throw Py::Exception("Unknown C++ exception");
00626     }
00627 }
00628 
00629 Py::Object View3DInventorPy::getViewDirection(const Py::Tuple& args)
00630 {
00631     if (!PyArg_ParseTuple(args.ptr(), ""))
00632         throw Py::Exception();
00633     try {
00634         SbVec3f dvec = _view->getViewer()->getViewDirection();
00635         return Py::Vector(Base::Vector3f(dvec[0], dvec[1], dvec[2]));
00636     }
00637     catch (const Base::Exception& e) {
00638         throw Py::Exception(e.what());
00639     }
00640     catch (const std::exception& e) {
00641         throw Py::Exception(e.what());
00642     }
00643     catch(...) {
00644         throw Py::Exception("Unknown C++ exception");
00645     }
00646 }
00647 
00648 
00649 Py::Object View3DInventorPy::setCamera(const Py::Tuple& args)
00650 {
00651     char* buffer;
00652     if (!PyArg_ParseTuple(args.ptr(), "s", &buffer))
00653         throw Py::Exception();
00654 
00655     try {
00656         _view->setCamera(buffer);
00657         return Py::None();
00658     }
00659     catch (const Base::Exception& e) {
00660         throw Py::Exception(e.what());
00661     }
00662     catch (const std::exception& e) {
00663         throw Py::Exception(e.what());
00664     }
00665     catch(...) {
00666         throw Py::Exception("Unknown C++ exception");
00667     }
00668 }
00669 
00670 //FIXME: Once View3DInventor inherits from PropertyContainer we can use PropertyEnumeration.
00671 const char* CameraTypeEnums[]= {"Orthographic","Perspective",NULL};
00672 
00673 Py::Object View3DInventorPy::getCameraType(const Py::Tuple& args)
00674 {
00675     if (!PyArg_ParseTuple(args.ptr(), ""))
00676         throw Py::Exception();
00677 
00678     SoCamera* cam = _view->getViewer()->getCamera();
00679     if (!cam) {
00680         throw Py::Exception("No camera set!");
00681     }
00682     else if (cam->getTypeId() == SoOrthographicCamera::getClassTypeId()) {
00683         return Py::String(CameraTypeEnums[0]);
00684     }
00685     else if (cam->getTypeId() == SoPerspectiveCamera::getClassTypeId()) {
00686         return Py::String(CameraTypeEnums[1]);
00687     }
00688     else {
00689         throw Py::Exception("Unknown camera type");
00690     }
00691 }
00692 
00693 Py::Object View3DInventorPy::setCameraType(const Py::Tuple& args)
00694 {
00695     int cameratype=-1;
00696     if (!PyArg_ParseTuple(args.ptr(), "i", &cameratype)) {    // convert args: Python->C 
00697         char* modename;
00698         PyErr_Clear();
00699         if (!PyArg_ParseTuple(args.ptr(), "s", &modename))
00700             throw Py::Exception();
00701         for (int i=0; i<2; i++ ) {
00702             if (strncmp(CameraTypeEnums[i],modename,20) == 0 ) {
00703                 cameratype = i;
00704                 break;
00705             }
00706         }
00707 
00708         if (cameratype < 0) {
00709             std::string s;
00710             std::ostringstream s_out;
00711             s_out << "Unknown camera type '" << modename << "'";
00712             throw Py::NameError(s_out.str());
00713         }
00714     }
00715 
00716     if (cameratype < 0 || cameratype > 1)
00717         throw Py::Exception("Out of range");
00718     if (cameratype==0)
00719         _view->getViewer()->setCameraType(SoOrthographicCamera::getClassTypeId());
00720     else
00721         _view->getViewer()->setCameraType(SoPerspectiveCamera::getClassTypeId());
00722     return Py::None();
00723 }
00724 
00725 Py::Object View3DInventorPy::listCameraTypes(const Py::Tuple& args)
00726 {
00727     if (!PyArg_ParseTuple(args.ptr(), ""))
00728         throw Py::Exception();
00729 
00730     try {
00731         Py::List list(2);
00732         for (int i=0; i<2; i++) {
00733             list[i] = Py::String(CameraTypeEnums[i]);
00734         }
00735         return list;
00736     }
00737     catch (const Base::Exception& e) {
00738         throw Py::Exception(e.what());
00739     }
00740     catch (const std::exception& e) {
00741         throw Py::Exception(e.what());
00742     }
00743     catch(...) {
00744         throw Py::Exception("Unknown C++ exception");
00745     }
00746 }
00747 
00748 Py::Object View3DInventorPy::dump(const Py::Tuple& args)
00749 {
00750     char* filename;
00751     if (!PyArg_ParseTuple(args.ptr(), "s", &filename))
00752         throw Py::Exception();
00753 
00754     try {
00755         _view->dump(filename);
00756         return Py::None();
00757     }
00758     catch (const Base::Exception& e) {
00759         throw Py::Exception(e.what());
00760     }
00761     catch (const std::exception& e) {
00762         throw Py::Exception(e.what());
00763     }
00764     catch(...) {
00765         throw Py::Exception("Unknown C++ exception");
00766     }
00767 }
00768 
00769 Py::Object View3DInventorPy::dumpNode(const Py::Tuple& args)
00770 {
00771     PyObject* object;
00772     if (!PyArg_ParseTuple(args.ptr(), "O", &object))     // convert args: Python->C 
00773         throw Py::Exception();
00774 
00775     void* ptr = 0;
00776     try {
00777         Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoNode *", object, &ptr, 0);
00778     }
00779     catch (const Base::Exception& e) {
00780         throw Py::Exception(e.what());
00781     }
00782     SoNode* node = reinterpret_cast<SoNode*>(ptr);
00783     return Py::String(SoFCDB::writeNodesToString(node));
00784 }
00785 
00786 //FIXME: Once View3DInventor inherits from PropertyContainer we can use PropertyEnumeration.
00787 const char* StereoTypeEnums[]= {"None","Anaglyph","QuadBuffer","InterleavedRows","InterleavedColumns",NULL};
00788 
00789 Py::Object View3DInventorPy::setStereoType(const Py::Tuple& args)
00790 {
00791     int stereomode=-1;
00792     if (!PyArg_ParseTuple(args.ptr(), "i", &stereomode)) {
00793         char* modename;
00794         PyErr_Clear();
00795         if (!PyArg_ParseTuple(args.ptr(), "s", &modename))
00796             throw Py::Exception();
00797         for (int i=0; i<5; i++) {
00798             if (strncmp(StereoTypeEnums[i],modename,20) == 0) {
00799                 stereomode = i;
00800                 break;
00801             }
00802         }
00803 
00804         if (stereomode < 0) {
00805             std::string s;
00806             std::ostringstream s_out;
00807             s_out << "Unknown stereo type '" << modename << "'";
00808             throw Py::NameError(s_out.str());
00809         }
00810     }
00811 
00812     try {
00813 #if SOQT_MAJOR_VERSION > 1 || (SOQT_MAJOR_VERSION == 1 && SOQT_MINOR_VERSION >= 2)
00814         if (stereomode < 0 || stereomode > 4)
00815             throw Py::Exception("Out of range");
00816         SoQtViewer::StereoType mode = SoQtViewer::StereoType(stereomode);
00817         _view->getViewer()->setStereoType(mode);
00818 #else
00819         throw Py::Exception("Stereo types not supported. Use SoQt 1.2.x or later!");
00820 #endif
00821         return Py::None();
00822     }
00823     catch (const Base::Exception& e) {
00824         throw Py::Exception(e.what());
00825     }
00826     catch (const std::exception& e) {
00827         throw Py::Exception(e.what());
00828     }
00829     catch(...) {
00830         throw Py::Exception("Unknown C++ exception");
00831     }
00832 }
00833 
00834 Py::Object View3DInventorPy::getStereoType(const Py::Tuple& args)
00835 {
00836     if (!PyArg_ParseTuple(args.ptr(), ""))
00837         throw Py::Exception();
00838 
00839     try {
00840 #if SOQT_MAJOR_VERSION > 1 || (SOQT_MAJOR_VERSION == 1 && SOQT_MINOR_VERSION >= 2)
00841         int mode = (int)(_view->getViewer()->getStereoType()); 
00842         return Py::String(StereoTypeEnums[mode]);
00843 #else
00844         throw Py::Exception("Stereo types not supported. Use SoQt 1.2.x or later!");
00845 #endif
00846         return Py::None();
00847     }
00848     catch (const Base::Exception& e) {
00849         throw Py::Exception(e.what());
00850     }
00851     catch (const std::exception& e) {
00852         throw Py::Exception(e.what());
00853     }
00854     catch(...) {
00855         throw Py::Exception("Unknown C++ exception");
00856     }
00857 }
00858 
00859 Py::Object View3DInventorPy::listStereoTypes(const Py::Tuple& args)
00860 {
00861     if (!PyArg_ParseTuple(args.ptr(), ""))
00862         throw Py::Exception();
00863 
00864     try {
00865         Py::List list(5);
00866         for (int i=0; i<5; i++) {
00867             list[i] = Py::String(StereoTypeEnums[i]);
00868         }
00869 
00870         return list;
00871     }
00872     catch (const Base::Exception& e) {
00873         throw Py::Exception(e.what());
00874     }
00875     catch (const std::exception& e) {
00876         throw Py::Exception(e.what());
00877     }
00878     catch(...) {
00879         throw Py::Exception("Unknown C++ exception");
00880     }
00881 }
00882 
00883 Py::Object View3DInventorPy::getCursorPos(const Py::Tuple& args)
00884 {
00885     if (!PyArg_ParseTuple(args.ptr(), ""))
00886         throw Py::Exception();
00887     try {
00888         QPoint pos = _view->mapFromGlobal(QCursor::pos());
00889         Py::Tuple tuple(2);
00890         tuple.setItem(0, Py::Int(pos.x()));
00891         tuple.setItem(1, Py::Int(_view->height()-pos.y()-1));
00892         return tuple;
00893     }
00894     catch (const Py::Exception&) {
00895         throw;
00896     }
00897 }
00898 
00899 Py::Object View3DInventorPy::getObjectInfo(const Py::Tuple& args)
00900 {
00901     PyObject* object;
00902     if (!PyArg_ParseTuple(args.ptr(), "O", &object))
00903         throw Py::Exception();
00904 
00905     try {
00906         //Note: For gcc (4.2) we need the 'const' keyword to avoid the compiler error:
00907         //conversion from 'Py::seqref<Py::Object>' to non-scalar type 'Py::Int' requested
00908         //We should report this problem to the PyCXX project as in the documentation an 
00909         //example without the 'const' keyword is used.
00910         //Or we can also write Py::Int x(tuple[0]);
00911         const Py::Tuple tuple(object);
00912         Py::Int x(tuple[0]);
00913         Py::Int y(tuple[1]);
00914 
00915         // As this method could be called during a SoHandleEventAction scene
00916         // graph traversal we must not use a second SoHandleEventAction as
00917         // we will get Coin warnings because of multiple scene graph traversals
00918         // which is regarded as error-prone.
00919         SoRayPickAction action(_view->getViewer()->getViewportRegion());
00920         action.setPoint(SbVec2s((long)x,(long)y));
00921         action.apply(_view->getViewer()->getSceneManager()->getSceneGraph());
00922         SoPickedPoint *Point = action.getPickedPoint();
00923 
00924         Py::Object ret = Py::None();
00925         if (Point) {
00926             Py::Dict dict;
00927             SbVec3f pt = Point->getPoint();
00928             dict.setItem("x", Py::Float(pt[0]));
00929             dict.setItem("y", Py::Float(pt[1]));
00930             dict.setItem("z", Py::Float(pt[2]));
00931 
00932             ViewProvider *vp = _view->getViewer()->getViewProviderByPath(Point->getPath());
00933             if (vp && vp->useNewSelectionModel() && vp->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) {
00934                 ViewProviderDocumentObject* vpd = static_cast<ViewProviderDocumentObject*>(vp);
00935                 dict.setItem("Document",
00936                     Py::String(vpd->getObject()->getDocument()->getName()));
00937                 dict.setItem("Object",
00938                     Py::String(vpd->getObject()->getNameInDocument()));
00939                 dict.setItem("Component",
00940                     Py::String(vpd->getElement(Point)));
00941                 // ok, found the node of interest
00942                 ret = dict;
00943             }
00944             else {
00945                 // search for a SoFCSelection node
00946                 SoFCDocumentObjectAction objaction;
00947                 objaction.apply(Point->getPath());
00948                 if (objaction.isHandled()) {
00949                     dict.setItem("Document",
00950                         Py::String(objaction.documentName.getString()));
00951                     dict.setItem("Object",
00952                         Py::String(objaction.objectName.getString()));
00953                     dict.setItem("Component",
00954                         Py::String(objaction.componentName.getString()));
00955                     // ok, found the node of interest
00956                     ret = dict;
00957                 }
00958             }
00959         }
00960 
00961         return ret;
00962     }
00963     catch (const Py::Exception&) {
00964         throw;
00965     }
00966 }
00967 
00968 Py::Object View3DInventorPy::getObjectsInfo(const Py::Tuple& args)
00969 {
00970     PyObject* object;
00971     if (!PyArg_ParseTuple(args.ptr(), "O", &object))
00972         throw Py::Exception();
00973 
00974     try {
00975         //Note: For gcc (4.2) we need the 'const' keyword to avoid the compiler error:
00976         //conversion from 'Py::seqref<Py::Object>' to non-scalar type 'Py::Int' requested
00977         //We should report this problem to the PyCXX project as in the documentation an 
00978         //example without the 'const' keyword is used.
00979         //Or we can also write Py::Int x(tuple[0]);
00980         const Py::Tuple tuple(object);
00981         Py::Int x(tuple[0]);
00982         Py::Int y(tuple[1]);
00983 
00984         // As this method could be called during a SoHandleEventAction scene
00985         // graph traversal we must not use a second SoHandleEventAction as
00986         // we will get Coin warnings because of multiple scene graph traversals
00987         // which is regarded as error-prone.
00988         SoRayPickAction action(_view->getViewer()->getViewportRegion());
00989         action.setPickAll(true);
00990         action.setPoint(SbVec2s((long)x,(long)y));
00991         action.apply(_view->getViewer()->getSceneManager()->getSceneGraph());
00992         const SoPickedPointList& pp = action.getPickedPointList();
00993 
00994         Py::Object ret = Py::None();
00995         if (pp.getLength() > 0) {
00996             Py::List list;
00997             for (int i=0; i<pp.getLength(); i++) {
00998                 Py::Dict dict;
00999                 SoPickedPoint* point = static_cast<SoPickedPoint*>(pp.get(i));
01000                 SbVec3f pt = point->getPoint();
01001                 dict.setItem("x", Py::Float(pt[0]));
01002                 dict.setItem("y", Py::Float(pt[1]));
01003                 dict.setItem("z", Py::Float(pt[2]));
01004 
01005                 ViewProvider *vp = _view->getViewer()->getViewProviderByPath(point->getPath());
01006                 if (vp && vp->useNewSelectionModel() && vp->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) {
01007                     ViewProviderDocumentObject* vpd = static_cast<ViewProviderDocumentObject*>(vp);
01008                     dict.setItem("Document",
01009                         Py::String(vpd->getObject()->getDocument()->getName()));
01010                     dict.setItem("Object",
01011                         Py::String(vpd->getObject()->getNameInDocument()));
01012                     dict.setItem("Component",
01013                         Py::String(vpd->getElement(point)));
01014                     // ok, found the node of interest
01015                     list.append(dict);
01016                 }
01017                 else {
01018                     // search for a SoFCSelection node
01019                     SoFCDocumentObjectAction objaction;
01020                     objaction.apply(point->getPath());
01021                     if (objaction.isHandled()) {
01022                         dict.setItem("Document",
01023                             Py::String(objaction.documentName.getString()));
01024                         dict.setItem("Object",
01025                             Py::String(objaction.objectName.getString()));
01026                         dict.setItem("Component",
01027                             Py::String(objaction.componentName.getString()));
01028                         // ok, found the node of interest
01029                         list.append(dict);
01030                     }
01031                 }
01032             }
01033 
01034             ret = list;
01035         }
01036 
01037         return ret;
01038     }
01039     catch (const Py::Exception&) {
01040         throw;
01041     }
01042 }
01043 
01044 Py::Object View3DInventorPy::getSize(const Py::Tuple& args)
01045 {
01046     if (!PyArg_ParseTuple(args.ptr(), ""))
01047         throw Py::Exception();
01048     try {
01049         SbVec2s size = _view->getViewer()->getSize();
01050         Py::Tuple tuple(2);
01051         tuple.setItem(0, Py::Int(size[0]));
01052         tuple.setItem(1, Py::Int(size[1]));
01053         return tuple;
01054     }
01055     catch (const Py::Exception&) {
01056         throw;
01057     }
01058 }
01059 
01060 Py::Object View3DInventorPy::getPoint(const Py::Tuple& args)
01061 {
01062     short x,y;
01063     if (!PyArg_ParseTuple(args.ptr(), "hh", &x, &y)) {
01064         PyErr_Clear();
01065         Py::Tuple t(args[0]);
01066         x = (int)Py::Int(t[0]);
01067         y = (int)Py::Int(t[1]);
01068     }
01069     try {
01070         SbVec3f pt = _view->getViewer()->getPointOnScreen(SbVec2s(x,y));
01071         return Py::Vector(Base::Vector3f(pt[0], pt[1], pt[2]));
01072     }
01073     catch (const Base::Exception& e) {
01074         throw Py::Exception(e.what());
01075     }
01076     catch (const Py::Exception&) {
01077         throw;
01078     }
01079 }
01080 
01081 Py::Object View3DInventorPy::listNavigationTypes(const Py::Tuple&)
01082 {
01083     std::vector<Base::Type> types;
01084     Py::List styles;
01085     Base::Type::getAllDerivedFrom(UserNavigationStyle::getClassTypeId(), types);
01086     for (std::vector<Base::Type>::iterator it = types.begin()+1; it != types.end(); ++it) {
01087         styles.append(Py::String(it->getName()));
01088     }
01089     return styles;
01090 }
01091 
01092 Py::Object View3DInventorPy::getNavigationType(const Py::Tuple&)
01093 {
01094     std::string name = _view->getViewer()->navigationStyle()->getTypeId().getName();
01095     return Py::String(name);
01096 }
01097 
01098 Py::Object View3DInventorPy::setNavigationType(const Py::Tuple& args)
01099 {
01100     char* style;
01101     if (!PyArg_ParseTuple(args.ptr(), "s", &style))
01102         throw Py::Exception();
01103     Base::Type type = Base::Type::fromName(style);
01104     _view->getViewer()->setNavigationType(type);
01105     return Py::None();
01106 }
01107 
01108 void View3DInventorPy::eventCallback(void * ud, SoEventCallback * n)
01109 {
01110     Base::PyGILStateLocker lock;
01111     try {
01112         Py::Dict dict;
01113         const SoEvent* e = n->getEvent();
01114         if (!e) return; // invalid event
01115         // Type
01116         dict.setItem("Type", Py::String(std::string(e->getTypeId().getName().getString())));
01117         // Time
01118         dict.setItem("Time", Py::String(std::string(e->getTime().formatDate().getString())));
01119         SbVec2s p = n->getEvent()->getPosition();
01120         Py::Tuple pos(2);
01121         pos.setItem(0, Py::Int(p[0]));
01122         pos.setItem(1, Py::Int(p[1]));
01123         // Position
01124         dict.setItem("Position", pos);
01125         // Shift, Ctrl, Alt down
01126         dict.setItem("ShiftDown", Py::Object((e->wasShiftDown() ? Py_True : Py_False)));
01127         dict.setItem("CtrlDown",  Py::Object((e->wasCtrlDown()  ? Py_True : Py_False)));
01128         dict.setItem("AltDown",   Py::Object((e->wasAltDown()   ? Py_True : Py_False)));
01129         if (e->isOfType(SoButtonEvent::getClassTypeId())) {
01130             std::string state;
01131             const SoButtonEvent* be = static_cast<const SoButtonEvent*>(e);
01132             switch (be->getState()) {
01133                 case SoButtonEvent::UP:
01134                     state = "UP";
01135                     break;
01136                 case SoButtonEvent::DOWN:
01137                     state = "DOWN";
01138                     break;
01139                 default:
01140                     state = "UNKNOWN";
01141                     break;
01142             }
01143 
01144             dict.setItem("State", Py::String(state));
01145         }
01146         if (e->isOfType(SoKeyboardEvent::getClassTypeId())) {
01147             const SoKeyboardEvent* ke = static_cast<const SoKeyboardEvent*>(e);
01148             switch (ke->getKey()) {
01149                 case SoKeyboardEvent::ANY:
01150                     dict.setItem("Key", Py::String("ANY"));
01151                     break;
01152                 case SoKeyboardEvent::UNDEFINED:
01153                     dict.setItem("Key", Py::String("UNDEFINED"));
01154                     break;
01155                 case SoKeyboardEvent::LEFT_SHIFT:
01156                 case SoKeyboardEvent::RIGHT_SHIFT:
01157                     dict.setItem("Key", Py::String("SHIFT"));
01158                     break;
01159                 case SoKeyboardEvent::LEFT_CONTROL:
01160                 case SoKeyboardEvent::RIGHT_CONTROL:
01161                     dict.setItem("Key", Py::String("CONTROL"));
01162                     break;
01163                 case SoKeyboardEvent::LEFT_ALT:
01164                 case SoKeyboardEvent::RIGHT_ALT:
01165                     dict.setItem("Key", Py::String("ALT"));
01166                     break;
01167                 case SoKeyboardEvent::HOME:
01168                     dict.setItem("Key", Py::String("HOME"));
01169                     break;
01170                 case SoKeyboardEvent::LEFT_ARROW:
01171                     dict.setItem("Key", Py::String("LEFT_ARROW"));
01172                     break;
01173                 case SoKeyboardEvent::UP_ARROW:
01174                     dict.setItem("Key", Py::String("UP_ARROW"));
01175                     break;
01176                 case SoKeyboardEvent::RIGHT_ARROW:
01177                     dict.setItem("Key", Py::String("RIGHT_ARROW"));
01178                     break;
01179                 case SoKeyboardEvent::DOWN_ARROW:
01180                     dict.setItem("Key", Py::String("DOWN_ARROW"));
01181                     break;
01182                 case SoKeyboardEvent::PAGE_UP:
01183                     dict.setItem("Key", Py::String("PAGE_UP"));
01184                     break;
01185                 case SoKeyboardEvent::PAGE_DOWN:
01186                     dict.setItem("Key", Py::String("PAGE_DOWN"));
01187                     break;
01188                 case SoKeyboardEvent::END:
01189                     dict.setItem("Key", Py::String("END"));
01190                     break;
01191                 case SoKeyboardEvent::PAD_ENTER:
01192                     dict.setItem("Key", Py::String("PAD_ENTER"));
01193                     break;
01194                 case SoKeyboardEvent::PAD_F1:
01195                     dict.setItem("Key", Py::String("PAD_F1"));
01196                     break;
01197                 case SoKeyboardEvent::PAD_F2:
01198                     dict.setItem("Key", Py::String("PAD_F2"));
01199                     break;
01200                 case SoKeyboardEvent::PAD_F3:
01201                     dict.setItem("Key", Py::String("PAD_F3"));
01202                     break;
01203                 case SoKeyboardEvent::PAD_F4:
01204                     dict.setItem("Key", Py::String("PAD_F4"));
01205                     break;
01206                 case SoKeyboardEvent::PAD_0:
01207                     dict.setItem("Key", Py::String("PAD_0"));
01208                     break;
01209                 case SoKeyboardEvent::PAD_1:
01210                     dict.setItem("Key", Py::String("PAD_1"));
01211                     break;
01212                 case SoKeyboardEvent::PAD_2:
01213                     dict.setItem("Key", Py::String("PAD_2"));
01214                     break;
01215                 case SoKeyboardEvent::PAD_3:
01216                     dict.setItem("Key", Py::String("PAD_3"));
01217                     break;
01218                 case SoKeyboardEvent::PAD_4:
01219                     dict.setItem("Key", Py::String("PAD_4"));
01220                     break;
01221                 case SoKeyboardEvent::PAD_5:
01222                     dict.setItem("Key", Py::String("PAD_5"));
01223                     break;
01224                 case SoKeyboardEvent::PAD_6:
01225                     dict.setItem("Key", Py::String("PAD_6"));
01226                     break;
01227                 case SoKeyboardEvent::PAD_7:
01228                     dict.setItem("Key", Py::String("PAD_7"));
01229                     break;
01230                 case SoKeyboardEvent::PAD_8:
01231                     dict.setItem("Key", Py::String("PAD_8"));
01232                     break;
01233                 case SoKeyboardEvent::PAD_9:
01234                     dict.setItem("Key", Py::String("PAD_9"));
01235                     break;
01236                 case SoKeyboardEvent::PAD_ADD:
01237                     dict.setItem("Key", Py::String("PAD_ADD"));
01238                     break;
01239                 case SoKeyboardEvent::PAD_SUBTRACT:
01240                     dict.setItem("Key", Py::String("PAD_SUBTRACT"));
01241                     break;
01242                 case SoKeyboardEvent::PAD_MULTIPLY:
01243                     dict.setItem("Key", Py::String("PAD_MULTIPLY"));
01244                     break;
01245                 case SoKeyboardEvent::PAD_DIVIDE:
01246                     dict.setItem("Key", Py::String("PAD_DIVIDE"));
01247                     break;
01248                 case SoKeyboardEvent::PAD_TAB:
01249                     dict.setItem("Key", Py::String("PAD_TAB"));
01250                     break;
01251                 case SoKeyboardEvent::PAD_DELETE:
01252                     dict.setItem("Key", Py::String("PAD_DELETE"));
01253                     break;
01254                 case SoKeyboardEvent::F1:
01255                     dict.setItem("Key", Py::String("F1"));
01256                     break;
01257                 case SoKeyboardEvent::F2:
01258                     dict.setItem("Key", Py::String("F2"));
01259                     break;
01260                 case SoKeyboardEvent::F3:
01261                     dict.setItem("Key", Py::String("F3"));
01262                     break;
01263                 case SoKeyboardEvent::F4:
01264                     dict.setItem("Key", Py::String("F4"));
01265                     break;
01266                 case SoKeyboardEvent::F5:
01267                     dict.setItem("Key", Py::String("F5"));
01268                     break;
01269                 case SoKeyboardEvent::F6:
01270                     dict.setItem("Key", Py::String("F6"));
01271                     break;
01272                 case SoKeyboardEvent::F7:
01273                     dict.setItem("Key", Py::String("F7"));
01274                     break;
01275                 case SoKeyboardEvent::F8:
01276                     dict.setItem("Key", Py::String("F8"));
01277                     break;
01278                 case SoKeyboardEvent::F9:
01279                     dict.setItem("Key", Py::String("F9"));
01280                     break;
01281                 case SoKeyboardEvent::F10:
01282                     dict.setItem("Key", Py::String("F10"));
01283                     break;
01284                 case SoKeyboardEvent::F11:
01285                     dict.setItem("Key", Py::String("F11"));
01286                     break;
01287                 case SoKeyboardEvent::F12:
01288                     dict.setItem("Key", Py::String("F12"));
01289                     break;
01290                 case SoKeyboardEvent::BACKSPACE:
01291                     dict.setItem("Key", Py::String("BACKSPACE"));
01292                     break;
01293                 case SoKeyboardEvent::TAB:
01294                     dict.setItem("Key", Py::String("TAB"));
01295                     break;
01296                 case SoKeyboardEvent::RETURN:
01297                     dict.setItem("Key", Py::String("RETURN"));
01298                     break;
01299                 case SoKeyboardEvent::PAUSE:
01300                     dict.setItem("Key", Py::String("PAUSE"));
01301                     break;
01302                 case SoKeyboardEvent::SCROLL_LOCK:
01303                     dict.setItem("Key", Py::String("SCROLL_LOCK"));
01304                     break;
01305                 case SoKeyboardEvent::ESCAPE:
01306                     dict.setItem("Key", Py::String("ESCAPE"));
01307                     break;
01308                 case SoKeyboardEvent::KEY_DELETE:
01309                     dict.setItem("Key", Py::String("DELETE"));
01310                     break;
01311                 case SoKeyboardEvent::PRINT:
01312                     dict.setItem("Key", Py::String("PRINT"));
01313                     break;
01314                 case SoKeyboardEvent::INSERT:
01315                     dict.setItem("Key", Py::String("INSERT"));
01316                     break;
01317                 case SoKeyboardEvent::NUM_LOCK:
01318                     dict.setItem("Key", Py::String("NUM_LOCK"));
01319                     break;
01320                 case SoKeyboardEvent::CAPS_LOCK:
01321                     dict.setItem("Key", Py::String("CAPS_LOCK"));
01322                     break;
01323                 case SoKeyboardEvent::SHIFT_LOCK:
01324                     dict.setItem("Key", Py::String("SHIFT_LOCK"));
01325                     break;
01326                 case SoKeyboardEvent::SPACE:
01327                     dict.setItem("Key", Py::String("SPACE"));
01328                     break;
01329                 case SoKeyboardEvent::APOSTROPHE:
01330                     dict.setItem("Key", Py::String("APOSTROPHE"));
01331                     break;
01332                 case SoKeyboardEvent::COMMA:
01333                     dict.setItem("Key", Py::String("COMMA"));
01334                     break;
01335                 case SoKeyboardEvent::MINUS:
01336                     dict.setItem("Key", Py::String("MINUS"));
01337                     break;
01338                 case SoKeyboardEvent::PERIOD:
01339                     dict.setItem("Key", Py::String("PERIOD"));
01340                     break;
01341                 case SoKeyboardEvent::SLASH:
01342                     dict.setItem("Key", Py::String("SLASH"));
01343                     break;
01344                 case SoKeyboardEvent::SEMICOLON:
01345                     dict.setItem("Key", Py::String("SEMICOLON"));
01346                     break;
01347                 case SoKeyboardEvent::EQUAL:
01348                     dict.setItem("Key", Py::String("EQUAL"));
01349                     break;
01350                 case SoKeyboardEvent::BRACKETLEFT:
01351                     dict.setItem("Key", Py::String("BRACKETLEFT"));
01352                     break;
01353                 case SoKeyboardEvent::BACKSLASH:
01354                     dict.setItem("Key", Py::String("BACKSLASH"));
01355                     break;
01356                 case SoKeyboardEvent::BRACKETRIGHT:
01357                     dict.setItem("Key", Py::String("BRACKETRIGHT"));
01358                     break;
01359                 case SoKeyboardEvent::GRAVE:
01360                     dict.setItem("Key", Py::String("GRAVE"));
01361                     break;
01362                 default:
01363                     dict.setItem("Key", Py::Char(ke->getPrintableCharacter()));
01364                     break;
01365             }
01366         }
01367         if (e->isOfType(SoMouseButtonEvent::getClassTypeId())) {
01368             const SoMouseButtonEvent* mbe = static_cast<const SoMouseButtonEvent*>(e);
01369             std::string button;
01370             switch (mbe->getButton()) {
01371                 case SoMouseButtonEvent::BUTTON1:
01372                     button = "BUTTON1";
01373                     break;
01374                 case SoMouseButtonEvent::BUTTON2:
01375                     button = "BUTTON2";
01376                     break;
01377                 case SoMouseButtonEvent::BUTTON3:
01378                     button = "BUTTON3";
01379                     break;
01380                 case SoMouseButtonEvent::BUTTON4:
01381                     button = "BUTTON4";
01382                     break;
01383                 case SoMouseButtonEvent::BUTTON5:
01384                     button = "BUTTON5";
01385                     break;
01386                 default:
01387                     button = "ANY";
01388                     break;
01389             }
01390 
01391             dict.setItem("Button", Py::String(button));
01392         }
01393         if (e->isOfType(SoSpaceballButtonEvent::getClassTypeId())) {
01394             const SoSpaceballButtonEvent* sbe = static_cast<const SoSpaceballButtonEvent*>(e);
01395             std::string button;
01396             switch (sbe->getButton()) {
01397                 case SoSpaceballButtonEvent::BUTTON1:
01398                     button = "BUTTON1";
01399                     break;
01400                 case SoSpaceballButtonEvent::BUTTON2:
01401                     button = "BUTTON2";
01402                     break;
01403                 case SoSpaceballButtonEvent::BUTTON3:
01404                     button = "BUTTON3";
01405                     break;
01406                 case SoSpaceballButtonEvent::BUTTON4:
01407                     button = "BUTTON4";
01408                     break;
01409                 case SoSpaceballButtonEvent::BUTTON5:
01410                     button = "BUTTON5";
01411                     break;
01412                 case SoSpaceballButtonEvent::BUTTON6:
01413                     button = "BUTTON6";
01414                     break;
01415                 case SoSpaceballButtonEvent::BUTTON7:
01416                     button = "BUTTON7";
01417                     break;
01418                 default:
01419                     button = "ANY";
01420                     break;
01421             }
01422 
01423             dict.setItem("Button", Py::String(button));
01424         }
01425         if (e->isOfType(SoMotion3Event::getClassTypeId())) {
01426             const SoMotion3Event* me = static_cast<const SoMotion3Event*>(e);
01427             const SbVec3f& m = me->getTranslation();
01428             const SbRotation& r = me->getRotation();
01429             Py::Tuple mov(3);
01430             mov.setItem(0, Py::Float(m[0]));
01431             mov.setItem(1, Py::Float(m[1]));
01432             mov.setItem(2, Py::Float(m[2]));
01433             dict.setItem("Translation", mov);
01434             Py::Tuple rot(4);
01435             rot.setItem(0, Py::Float(r.getValue()[0]));
01436             rot.setItem(1, Py::Float(r.getValue()[1]));
01437             rot.setItem(2, Py::Float(r.getValue()[2]));
01438             rot.setItem(3, Py::Float(r.getValue()[3]));
01439             dict.setItem("Rotation", rot);
01440         }
01441 
01442         // now run the method
01443         Py::Callable method(reinterpret_cast<PyObject*>(ud));
01444         Py::Tuple args(1);
01445         args.setItem(0, dict);
01446         method.apply(args);
01447     }
01448     catch (const Py::Exception& e) {
01449         Py::Object o = Py::type(e);
01450         if (o.isString()) {
01451             Py::String s(o);
01452             Base::Console().Warning("%s\n", s.as_std_string().c_str());
01453         }
01454         else {
01455             Py::String s(o.repr());
01456             Base::Console().Warning("%s\n", s.as_std_string().c_str());
01457         }
01458         // Prints message to console window if we are in interactive mode
01459         PyErr_Print();
01460     }
01461 }
01462 
01463 Py::Object View3DInventorPy::addEventCallback(const Py::Tuple& args)
01464 {
01465     char* eventtype;
01466     PyObject* method;
01467     if (!PyArg_ParseTuple(args.ptr(), "sO", &eventtype, &method))
01468         throw Py::Exception();
01469     try {
01470         if (PyCallable_Check(method) == 0) {
01471             throw Py::Exception("object is not callable");
01472         }
01473         SoType eventId = SoType::fromName(eventtype);
01474         if (eventId.isBad() || !eventId.isDerivedFrom(SoEvent::getClassTypeId())) {
01475             std::string s;
01476             std::ostringstream s_out;
01477             s_out << eventtype << " is not a valid event type";
01478             throw Py::Exception(s_out.str());
01479         }
01480 
01481         _view->getViewer()->addEventCallback(eventId, View3DInventorPy::eventCallback, method);
01482         callbacks.push_back(method);
01483         Py_INCREF(method);
01484         return Py::Callable(method, false);
01485     }
01486     catch (const Py::Exception&) {
01487         throw;
01488     }
01489 }
01490 
01491 Py::Object View3DInventorPy::removeEventCallback(const Py::Tuple& args)
01492 {
01493     char* eventtype;
01494     PyObject* method;
01495     if (!PyArg_ParseTuple(args.ptr(), "sO", &eventtype, &method))
01496         throw Py::Exception();
01497     try {
01498         if (PyCallable_Check(method) == 0) {
01499             throw Py::Exception("object is not callable");
01500         }
01501         SoType eventId = SoType::fromName(eventtype);
01502         if (eventId.isBad() || !eventId.isDerivedFrom(SoEvent::getClassTypeId())) {
01503             std::string s;
01504             std::ostringstream s_out;
01505             s_out << eventtype << " is not a valid event type";
01506             throw Py::Exception(s_out.str());
01507         }
01508 
01509         _view->getViewer()->removeEventCallback(eventId, View3DInventorPy::eventCallback, method);
01510         callbacks.remove(method);
01511         Py_DECREF(method);
01512         return Py::None();
01513     }
01514     catch (const Py::Exception&) {
01515         throw;
01516     }
01517 }
01518 
01519 Py::Object View3DInventorPy::setAnnotation(const Py::Tuple& args)
01520 {
01521     char *psAnnoName,*psBuffer;
01522     if (!PyArg_ParseTuple(args.ptr(), "ss", &psAnnoName, &psBuffer))
01523         throw Py::Exception();
01524     ViewProviderExtern* view = 0;
01525     try {
01526         view = new ViewProviderExtern();
01527         view->setModeByString(psAnnoName, psBuffer);
01528     }
01529     catch (const Base::Exception& e) {
01530         delete view;
01531         throw Py::Exception(e.what());
01532     }
01533 
01534     _view->getGuiDocument()->setAnnotationViewProvider(psAnnoName, view);
01535     return Py::None();
01536 }
01537 
01538 Py::Object View3DInventorPy::removeAnnotation(const Py::Tuple& args)
01539 {
01540     char *psAnnoName;
01541     if (!PyArg_ParseTuple(args.ptr(), "s", &psAnnoName))
01542         throw Py::Exception();
01543     ViewProvider* view = 0;
01544     view = _view->getGuiDocument()->getAnnotationViewProvider(psAnnoName);
01545     if (view) {
01546         _view->getGuiDocument()->removeAnnotationViewProvider(psAnnoName);
01547         return Py::None();
01548     }
01549     else {
01550         std::string s;
01551         std::ostringstream s_out;
01552         s_out << "No such annotation '" << psAnnoName << "'";
01553         throw Py::KeyError(s_out.str());
01554     }
01555 }
01556 
01557 Py::Object View3DInventorPy::getSceneGraph(const Py::Tuple& args)
01558 {
01559     if (!PyArg_ParseTuple(args.ptr(), ""))
01560         throw Py::Exception();
01561 
01562     try {
01563         SoNode* scene = _view->getViewer()->getSceneGraph();
01564         PyObject* proxy = 0;
01565         proxy = Base::Interpreter().createSWIGPointerObj("pivy.coin", "SoSeparator *", (void*)scene, 1);
01566         scene->ref();
01567         return Py::Object(proxy, true);
01568     }
01569     catch (const Base::Exception& e) {
01570         throw Py::Exception(e.what());
01571     }
01572 }
01573 
01574 // -----------------------------------------------------------------
01575 
01576 static PyObject *
01577 wrap_SoQtViewer_setViewDirection(PyObject *proxy, PyObject *args)
01578 {
01579     PyObject* object;
01580     if (!PyArg_ParseTuple(args, "O", &object))     // convert args: Python->C 
01581         return NULL;  // NULL triggers exception 
01582 
01583     void* ptr = 0;
01584     try {
01585         Base::Interpreter().convertSWIGPointerObj("pivy.gui.soqt", "SoQtViewer *", proxy, &ptr, 0);
01586     }
01587     catch (const Base::Exception& e) {
01588         PyErr_SetString(PyExc_RuntimeError, e.what());
01589         return 0;
01590     }
01591 
01592     SoQtViewer* viewer = reinterpret_cast<SoQtViewer*>(ptr);
01593     try {
01594         Py::Tuple tuple(object);
01595         Py::Float x(tuple.getItem(0));
01596         Py::Float y(tuple.getItem(1));
01597         Py::Float z(tuple.getItem(2));
01598         SbVec3f dir;
01599         dir.setValue((float)x, (float)y, (float)z);
01600         if (dir.length() < 0.001f)
01601             throw Py::ValueError("Null vector cannot be used to set direction");
01602         SoCamera* cam = viewer->getCamera();
01603         if (cam)
01604             cam->orientation.setValue(SbRotation(SbVec3f(0, 0, -1), dir));
01605         return Py::new_reference_to(Py::None());
01606     }
01607     catch (Py::Exception&) {
01608         return NULL;
01609     }
01610 }
01611 
01612 static PyObject *
01613 wrap_SoQtViewer_getViewDirection(PyObject *proxy, PyObject *args)
01614 {
01615     if (!PyArg_ParseTuple(args, ""))     // convert args: Python->C 
01616         return NULL;  // NULL triggers exception 
01617 
01618     void* ptr = 0;
01619     try {
01620         Base::Interpreter().convertSWIGPointerObj("pivy.gui.soqt", "SoQtViewer *", proxy, &ptr, 0);
01621     }
01622     catch (const Base::Exception& e) {
01623         PyErr_SetString(PyExc_RuntimeError, e.what());
01624         return 0;
01625     }
01626 
01627     SoQtViewer* viewer = reinterpret_cast<SoQtViewer*>(ptr);
01628     try {
01629         SoCamera* cam = viewer->getCamera();
01630         if (!cam) {
01631             PyErr_SetString(PyExc_RuntimeError, "No camera set");
01632             return 0;
01633         }
01634         SbRotation camrot = cam->orientation.getValue();
01635         SbVec3f lookat(0, 0, -1); // init to default view direction vector
01636         camrot.multVec(lookat, lookat);
01637 
01638         Py::Tuple tuple(3);
01639         tuple.setItem(0, Py::Float(lookat[0]));
01640         tuple.setItem(1, Py::Float(lookat[1]));
01641         tuple.setItem(2, Py::Float(lookat[2]));
01642         return Py::new_reference_to(tuple);
01643     }
01644     catch (Py::Exception&) {
01645         return NULL;
01646     }
01647 }
01648 
01649 static PyObject *
01650 wrap_SoQtViewer_setFocalDistance(PyObject *proxy, PyObject *args)
01651 {
01652     float distance;
01653     if (!PyArg_ParseTuple(args, "f", &distance))     // convert args: Python->C 
01654         return NULL;  // NULL triggers exception 
01655 
01656     void* ptr = 0;
01657     try {
01658         Base::Interpreter().convertSWIGPointerObj("pivy.gui.soqt", "SoQtViewer *", proxy, &ptr, 0);
01659     }
01660     catch (const Base::Exception& e) {
01661         PyErr_SetString(PyExc_RuntimeError, e.what());
01662         return 0;
01663     }
01664 
01665     SoQtViewer* viewer = reinterpret_cast<SoQtViewer*>(ptr);
01666     PY_TRY {
01667         SoCamera* cam = viewer->getCamera();
01668         if (cam)
01669             cam->focalDistance.setValue(distance);
01670     } PY_CATCH;
01671 
01672     Py_Return;
01673 }
01674 
01675 static PyObject *
01676 wrap_SoQtViewer_getFocalDistance(PyObject *proxy, PyObject *args)
01677 {
01678     if (!PyArg_ParseTuple(args, ""))     // convert args: Python->C 
01679         return NULL;  // NULL triggers exception 
01680 
01681     void* ptr = 0;
01682     try {
01683         Base::Interpreter().convertSWIGPointerObj("pivy.gui.soqt", "SoQtViewer *", proxy, &ptr, 0);
01684     }
01685     catch (const Base::Exception& e) {
01686         PyErr_SetString(PyExc_RuntimeError, e.what());
01687         return 0;
01688     }
01689 
01690     SoQtViewer* viewer = reinterpret_cast<SoQtViewer*>(ptr);
01691     double dist = 0;
01692     SoCamera* cam = viewer->getCamera();
01693     if (cam) dist = cam->focalDistance.getValue();
01694     return PyFloat_FromDouble(dist);
01695 }
01696 
01697 static PyObject *
01698 wrap_SoQtViewer_seekToPoint(PyObject *proxy, PyObject *args)
01699 {
01700     PyObject* object;
01701     if (!PyArg_ParseTuple(args, "O", &object))     // convert args: Python->C 
01702         return NULL;                       // NULL triggers exception 
01703 
01704     void* ptr = 0;
01705     try {
01706         Base::Interpreter().convertSWIGPointerObj("pivy.gui.soqt", "SoQtViewer *", proxy, &ptr, 0);
01707     }
01708     catch (const Base::Exception& e) {
01709         PyErr_SetString(PyExc_RuntimeError, e.what());
01710         return 0;
01711     }
01712 
01713     View3DInventorViewer* viewer = reinterpret_cast<View3DInventorViewer*>(ptr);
01714     try {
01715         const Py::Tuple tuple(object);
01716 
01717         // If the 3d point is given
01718         if (tuple.size() == 3) {
01719             Py::Float x = tuple[0];
01720             Py::Float y = tuple[1];
01721             Py::Float z = tuple[2];
01722 
01723             SbVec3f hitpoint((float)x,(float)y,(float)z);
01724             viewer->pubSeekToPoint(hitpoint);
01725         }
01726         else {
01727             Py::Int x(tuple[0]);
01728             Py::Int y(tuple[1]);
01729             
01730             SbVec2s hitpoint ((long)x,(long)y);
01731             viewer->pubSeekToPoint(hitpoint);
01732         }
01733 
01734         return Py::new_reference_to(Py::None());  // increment ref counter
01735     }
01736     catch (const Py::Exception&) {
01737         return NULL;
01738     }
01739 }
01740 
01741 struct PyMethodDef wrap_SoQtViewer_methods[] = { 
01742     {"setViewDirection",wrap_SoQtViewer_setViewDirection,METH_VARARGS,
01743      "setViewDirection(tuple) -> None"},
01744     {"getViewDirection",wrap_SoQtViewer_getViewDirection,METH_VARARGS,
01745      "getViewDirection() -> tuple"},
01746     {"setFocalDistance",wrap_SoQtViewer_setFocalDistance,METH_VARARGS,
01747      "setFocalDistance(float) -> None"},
01748     {"getFocalDistance",wrap_SoQtViewer_getFocalDistance,METH_VARARGS,
01749      "getFocalDistance() -> float"},
01750     {"seekToPoint",wrap_SoQtViewer_seekToPoint,METH_VARARGS,
01751      "seekToPoint(tuple) -> None\n"
01752      "Initiate a seek action towards the 3D intersection of the scene and the\n"
01753      "ray from the screen coordinate's point and in the same direction as the\n"
01754      "camera is pointing"},
01755     {NULL, NULL}  /* sentinel */
01756 };
01757 
01758 Py::Object View3DInventorPy::getViewer(const Py::Tuple& args)
01759 {
01760     if (!PyArg_ParseTuple(args.ptr(), ""))
01761         throw Py::Exception();
01762 
01763     PyObject* proxy = 0;
01764     try {
01765         // Note: As there is no ref'counting mechanism for the viewer class we must
01766         // pass '0' as the third parameter so that the Python object does not 'own'
01767         // the viewer. 
01768         // Note: Once we have closed the viewer the Python object must not be used
01769         // anymore as it has a dangling pointer.
01770         SoQtViewer* view = _view->getViewer();
01771         proxy = Base::Interpreter().createSWIGPointerObj("pivy.gui.soqt", "SoQtViewer *", (void*)view, 0);
01772     }
01773     catch (const Base::Exception& e) {
01774         throw Py::Exception(e.what());
01775     }
01776 
01777     // Add some additional methods to the viewer's type object
01778     static bool first=true;
01779     if (first && proxy) {
01780         first = false;
01781         PyMethodDef *meth = wrap_SoQtViewer_methods;
01782         PyTypeObject *type = proxy->ob_type;
01783         PyObject *dict = type->tp_dict;
01784         for (; meth->ml_name != NULL; meth++) {
01785             PyObject *descr;
01786             descr = PyDescr_NewMethod(type, meth);
01787             if (descr == NULL)
01788                 break;
01789             if (PyDict_SetItemString(dict, meth->ml_name, descr) < 0)
01790                 break;
01791             Py_DECREF(descr);
01792         }
01793     }
01794     return Py::Object(proxy, true); // no further incremention needed
01795 }
01796 
01797 void View3DInventorPy::eventCallbackPivy(void * ud, SoEventCallback * n)
01798 {
01799     Base::PyGILStateLocker lock;
01800     const SoEvent* e = n->getEvent();
01801     std::string type = e->getTypeId().getName().getString();
01802     type += " *";
01803 
01804     PyObject* proxy = 0;
01805     try {
01806         proxy = Base::Interpreter().createSWIGPointerObj("pivy.coin", type.c_str(), (void*)e, 0);
01807         // now run the method
01808         Py::Object event(proxy,true);
01809         Py::Callable method(reinterpret_cast<PyObject*>(ud));
01810         Py::Tuple args(1);
01811         args.setItem(0, event);
01812         method.apply(args);
01813     }
01814     catch (const Base::Exception&) {
01815         return;
01816     }
01817     catch (const Py::Exception& e) {
01818         Py::Object o = Py::type(e);
01819         if (o.isString()) {
01820             Py::String s(o);
01821             Base::Console().Warning("%s\n", s.as_std_string().c_str());
01822         }
01823         else {
01824             Py::String s(o.repr());
01825             Base::Console().Warning("%s\n", s.as_std_string().c_str());
01826         }
01827         // Prints message to console window if we are in interactive mode
01828         PyErr_Print();
01829     }
01830 }
01831 
01832 void View3DInventorPy::eventCallbackPivyEx(void * ud, SoEventCallback * n)
01833 {
01834     Base::PyGILStateLocker lock;
01835     std::string type = "SoEventCallback *";
01836 
01837     PyObject* proxy = 0;
01838     try {
01839         proxy = Base::Interpreter().createSWIGPointerObj("pivy.coin", type.c_str(), (void*)n, 0);
01840         // now run the method
01841         Py::Object event(proxy,true);
01842         Py::Callable method(reinterpret_cast<PyObject*>(ud));
01843         Py::Tuple args(1);
01844         args.setItem(0, event);
01845         method.apply(args);
01846     }
01847     catch (const Base::Exception&) {
01848         return;
01849     }
01850     catch (const Py::Exception& e) {
01851         Py::Object o = Py::type(e);
01852         if (o.isString()) {
01853             Py::String s(o);
01854             Base::Console().Warning("%s\n", s.as_std_string().c_str());
01855         }
01856         else {
01857             Py::String s(o.repr());
01858             Base::Console().Warning("%s\n", s.as_std_string().c_str());
01859         }
01860         // Prints message to console window if we are in interactive mode
01861         PyErr_Print();
01862     }
01863 }
01864 
01865 Py::Object View3DInventorPy::addEventCallbackPivy(const Py::Tuple& args)
01866 {
01867     PyObject* proxy;
01868     PyObject* method;
01869     int ex=1; // if 1, use eventCallbackPivyEx
01870     if (!PyArg_ParseTuple(args.ptr(), "OO|i", &proxy, &method,&ex))
01871         throw Py::Exception();
01872 
01873     void* ptr = 0;
01874     try {
01875         Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoType *", proxy, &ptr, 0);
01876     }
01877     catch (const Base::Exception& e) {
01878         throw Py::Exception(e.what());
01879     }
01880 
01881     SoType* eventId = reinterpret_cast<SoType*>(ptr);
01882     if (eventId->isBad() || !eventId->isDerivedFrom(SoEvent::getClassTypeId())) {
01883         std::string s;
01884         std::ostringstream s_out;
01885         s_out << eventId->getName().getString() << "is not a valid event type";
01886         throw Py::Exception(s_out.str());
01887     }
01888 
01889     try {
01890         if (PyCallable_Check(method) == 0) {
01891             throw Py::Exception("object is not callable");
01892         }
01893 
01894         SoEventCallbackCB* callback = (ex == 1 ? 
01895             View3DInventorPy::eventCallbackPivyEx :
01896             View3DInventorPy::eventCallbackPivy);
01897         _view->getViewer()->addEventCallback(*eventId, callback, method);
01898         callbacks.push_back(method);
01899         Py_INCREF(method);
01900         return Py::Callable(method, false);
01901     }
01902     catch (const Py::Exception&) {
01903         throw;
01904     }
01905 }
01906 
01907 Py::Object View3DInventorPy::removeEventCallbackPivy(const Py::Tuple& args)
01908 {
01909     PyObject* proxy;
01910     PyObject* method;
01911     int ex=1; // if 1, use eventCallbackPivyEx
01912     if (!PyArg_ParseTuple(args.ptr(), "OO|i", &proxy, &method,&ex))
01913         throw Py::Exception();
01914 
01915     void* ptr = 0;
01916     try {
01917         Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoType *", proxy, &ptr, 0);
01918     }
01919     catch (const Base::Exception& e) {
01920         throw Py::Exception(e.what());
01921     }
01922 
01923     SoType* eventId = reinterpret_cast<SoType*>(ptr);
01924     if (eventId->isBad() || !eventId->isDerivedFrom(SoEvent::getClassTypeId())) {
01925         std::string s;
01926         std::ostringstream s_out;
01927         s_out << eventId->getName().getString() << "is not a valid event type";
01928         throw Py::Exception(s_out.str());
01929     }
01930 
01931     try {
01932         if (PyCallable_Check(method) == 0) {
01933             throw Py::Exception("object is not callable");
01934         }
01935 
01936         SoEventCallbackCB* callback = (ex == 1 ? 
01937             View3DInventorPy::eventCallbackPivyEx :
01938             View3DInventorPy::eventCallbackPivy);
01939         _view->getViewer()->removeEventCallback(*eventId, callback, method);
01940         callbacks.remove(method);
01941         Py_DECREF(method);
01942         return Py::Callable(method, false);
01943     }
01944     catch (const Py::Exception&) {
01945         throw;
01946     }
01947 }

Generated on Wed Nov 23 19:00:57 2011 for FreeCAD by  doxygen 1.6.1