1
/***************************************************************************
2
* Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de> *
4
* This file is part of the FreeCAD CAx development system. *
6
* This library is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU Library General Public *
8
* License as published by the Free Software Foundation; either *
9
* version 2 of the License, or (at your option) any later version. *
11
* This library is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU Library General Public License for more details. *
16
* You should have received a copy of the GNU Library General Public *
17
* License along with this library; see the file COPYING.LIB. If not, *
18
* write to the Free Software Foundation, Inc., 59 Temple Place, *
19
* Suite 330, Boston, MA 02111-1307, USA *
21
***************************************************************************/
23
#include "PreCompiled.h"
31
# include <Inventor/SoPickedPoint.h>
32
# include <Inventor/actions/SoWriteAction.h>
33
# include <Inventor/annex/HardCopy/SoVectorizePSAction.h>
34
# include <Inventor/draggers/SoDragger.h>
35
# include <Inventor/nodes/SoCamera.h>
36
# include <Inventor/nodes/SoOrthographicCamera.h>
37
# include <Inventor/nodes/SoPerspectiveCamera.h>
40
#include <App/Application.h>
41
#include <App/Document.h>
42
#include <App/DocumentObject.h>
43
#include <App/DocumentObjectPy.h>
44
#include <App/GeoFeature.h>
45
#include <Base/Console.h>
46
#include <Base/Exception.h>
47
#include <Base/GeometryPyCXX.h>
48
#include <Base/Interpreter.h>
49
#include <Base/PlacementPy.h>
50
#include <Base/PyWrapParseTupleAndKeywords.h>
51
#include <Base/RotationPy.h>
52
#include <Base/VectorPy.h>
58
#include "NavigationStyle.h"
59
#include "PythonWrapper.h"
61
#include "SoFCOffscreenRenderer.h"
62
#include "SoFCSelectionAction.h"
63
#include "SoFCVectorizeSVGAction.h"
64
#include "SoFCVectorizeU3DAction.h"
65
#include "SoMouseWheelEvent.h"
66
#include "View3DInventor.h"
67
#include "View3DInventorViewer.h"
68
#include "ViewProviderDocumentObject.h"
69
#include "ViewProviderExtern.h"
75
void View3DInventorPy::init_type()
77
behaviors().name("View3DInventorPy");
78
behaviors().doc("Python binding class for the Inventor viewer class");
79
// you must have overwritten the virtual functions
80
behaviors().supportRepr();
81
behaviors().supportGetattr();
82
behaviors().supportSetattr();
84
add_varargs_method("fitAll",&View3DInventorPy::fitAll,"fitAll()");
85
add_keyword_method("boxZoom",&View3DInventorPy::boxZoom,"boxZoom()");
87
add_noargs_method("viewBottom",&View3DInventorPy::viewBottom,"viewBottom()");
88
add_noargs_method("viewFront",&View3DInventorPy::viewFront,"viewFront()");
89
add_noargs_method("viewLeft",&View3DInventorPy::viewLeft,"viewLeft()");
90
add_noargs_method("viewRear",&View3DInventorPy::viewRear,"viewRear()");
91
add_noargs_method("viewRight",&View3DInventorPy::viewRight,"viewRight()");
92
add_noargs_method("viewTop",&View3DInventorPy::viewTop,"viewTop()");
93
add_noargs_method("viewAxometric",&View3DInventorPy::viewIsometric,"viewAxonometric()"); // for backward compatibility
94
add_noargs_method("viewAxonometric",&View3DInventorPy::viewIsometric,"viewAxonometric()");
95
add_noargs_method("viewIsometric",&View3DInventorPy::viewIsometric,"viewIsometric()");
96
add_noargs_method("viewDimetric",&View3DInventorPy::viewDimetric,"viewDimetric()");
97
add_noargs_method("viewTrimetric",&View3DInventorPy::viewTrimetric,"viewTrimetric()");
98
add_varargs_method("viewDefaultOrientation",&View3DInventorPy::viewDefaultOrientation,
99
"viewDefaultOrientation(ori_str = '', scale = -1.0): sets camera rotation to a predefined one, \n"
100
"and camera position and zoom to show certain amount of model space. \n"
101
"ori_string can be 'Top', 'Bottom', 'Front', 'Rear', 'Left', 'Right', \n"
102
"'Isometric', 'Dimetric', 'Trimetric', 'Custom'. If empty, the value is \n"
103
"fetched from Parameters.\n"
104
"scale sets distance from camera to origin, and height of the screen in \n"
105
"model space, so that a sphere of diameter <scale> fits the height of the\n"
106
"viewport. If zero, scaling is not done. If negative, the value is \n"
107
"fetched from Parameters.");
108
add_noargs_method("viewRotateLeft",&View3DInventorPy::viewRotateLeft,"viewRotateLeft()");
109
add_noargs_method("viewRotateRight",&View3DInventorPy::viewRotateRight,"viewRotateRight()");
110
add_noargs_method("zoomIn",&View3DInventorPy::zoomIn,"zoomIn()");
111
add_noargs_method("zoomOut",&View3DInventorPy::zoomOut,"zoomOut()");
112
add_varargs_method("viewPosition",&View3DInventorPy::viewPosition,"viewPosition()");
113
add_varargs_method("startAnimating",&View3DInventorPy::startAnimating,"startAnimating()");
114
add_noargs_method("stopAnimating",&View3DInventorPy::stopAnimating,"stopAnimating()");
115
add_varargs_method("setAnimationEnabled",&View3DInventorPy::setAnimationEnabled,"setAnimationEnabled()");
116
add_noargs_method("isAnimationEnabled",&View3DInventorPy::isAnimationEnabled,"isAnimationEnabled()");
117
add_varargs_method("setPopupMenuEnabled",&View3DInventorPy::setPopupMenuEnabled,"setPopupMenuEnabled()");
118
add_noargs_method("isPopupMenuEnabled",&View3DInventorPy::isPopupMenuEnabled,"isPopupMenuEnabled()");
119
add_varargs_method("dump",&View3DInventorPy::dump,"dump(filename, [onlyVisible=False])");
120
add_varargs_method("dumpNode",&View3DInventorPy::dumpNode,"dumpNode(node)");
121
add_varargs_method("setStereoType",&View3DInventorPy::setStereoType,"setStereoType()");
122
add_noargs_method("getStereoType",&View3DInventorPy::getStereoType,"getStereoType()");
123
add_noargs_method("listStereoTypes",&View3DInventorPy::listStereoTypes,"listStereoTypes()");
124
add_varargs_method("saveImage",&View3DInventorPy::saveImage,"saveImage()");
125
add_varargs_method("saveVectorGraphic",&View3DInventorPy::saveVectorGraphic,"saveVectorGraphic()");
126
add_noargs_method("getCamera",&View3DInventorPy::getCamera,"getCamera()");
127
add_noargs_method("getCameraNode",&View3DInventorPy::getCameraNode,"getCameraNode()");
128
add_noargs_method("getViewDirection",&View3DInventorPy::getViewDirection,"getViewDirection() --> tuple of floats\n"
129
"returns the direction vector the view is currently pointing at as tuple with xyz values\n"
131
add_noargs_method("getUpDirection",&View3DInventorPy::getUpDirection,"getUpDirection() --> tuple of integers\n"
132
"Returns the up direction vector\n"
134
add_varargs_method("setViewDirection",&View3DInventorPy::setViewDirection,"setViewDirection(tuple) --> None\n"
135
"Sets the direction the view is pointing at. The direction must be given as tuple with\n"
136
"three coordinates xyz"
138
add_varargs_method("setCamera",&View3DInventorPy::setCamera,"setCamera()");
139
add_varargs_method("setCameraOrientation",&View3DInventorPy::setCameraOrientation,"setCameraOrientation()");
140
add_noargs_method("getCameraOrientation",&View3DInventorPy::getCameraOrientation,"getCameraOrientation()");
141
add_noargs_method("getCameraType",&View3DInventorPy::getCameraType,"getCameraType()");
142
add_varargs_method("setCameraType",&View3DInventorPy::setCameraType,"setCameraType()");
143
add_noargs_method("listCameraTypes",&View3DInventorPy::listCameraTypes,"listCameraTypes()");
144
add_noargs_method("getCursorPos",&View3DInventorPy::getCursorPos,
145
"getCursorPos() -> tuple of integers\n"
147
"Return the current cursor position relative to the coordinate system of the\n"
148
"viewport region.\n");
149
add_varargs_method("getObjectInfo",&View3DInventorPy::getObjectInfo,
150
"getObjectInfo(tuple(int,int), [pick_radius]) -> dictionary or None\n"
152
"Return a dictionary with the name of document, object and component. The\n"
153
"dictionary also contains the coordinates of the appropriate 3d point of\n"
154
"the underlying geometry in the scenegraph.\n"
155
"If no geometry was found 'None' is returned, instead.\n");
156
add_varargs_method("getObjectsInfo",&View3DInventorPy::getObjectsInfo,
157
"getObjectsInfo(tuple(int,int), [pick_radius]) -> dictionary or None\n"
159
"Does the same as getObjectInfo() but returns a list of dictionaries or None.\n");
160
add_noargs_method("getSize",&View3DInventorPy::getSize,"getSize()");
161
add_varargs_method("getPoint",&View3DInventorPy::getPointOnFocalPlane,
162
"Same as getPointOnFocalPlane");
163
add_varargs_method("getPointOnFocalPlane",&View3DInventorPy::getPointOnFocalPlane,
164
"getPointOnFocalPlane(pixel coords (as integer)) -> 3D vector\n"
166
"Return the according 3D point on the focal plane to the given 2D point (in\n"
167
"pixel coordinates).\n");
168
add_varargs_method("getPointOnScreen",&View3DInventorPy::getPointOnViewport,
169
"Same as getPointOnViewport");
170
add_varargs_method("getPointOnViewport",&View3DInventorPy::getPointOnViewport,
171
"getPointOnViewport(3D vector) -> pixel coords (as integer)\n"
173
"Return the projected 3D point (in pixel coordinates).\n");
174
add_varargs_method("projectPointToLine",&View3DInventorPy::projectPointToLine,
175
"projectPointToLine(pixel coords (as integer)) -> line defined by two points\n"
177
"Return the projecting 3D line to the given 2D point");
178
add_varargs_method("addEventCallback",&View3DInventorPy::addEventCallback,"addEventCallback()");
179
add_varargs_method("removeEventCallback",&View3DInventorPy::removeEventCallback,"removeEventCallback()");
180
add_varargs_method("setAnnotation",&View3DInventorPy::setAnnotation,"setAnnotation()");
181
add_varargs_method("removeAnnotation",&View3DInventorPy::removeAnnotation,"removeAnnotation()");
182
add_noargs_method("getSceneGraph",&View3DInventorPy::getSceneGraph,"getSceneGraph()");
183
add_noargs_method("getViewer",&View3DInventorPy::getViewer,"getViewer()");
184
add_varargs_method("addEventCallbackPivy",&View3DInventorPy::addEventCallbackPivy,"addEventCallbackPivy()");
185
add_varargs_method("removeEventCallbackPivy",&View3DInventorPy::removeEventCallbackPivy,"removeEventCallbackPivy()");
186
add_varargs_method("addEventCallbackSWIG",&View3DInventorPy::addEventCallbackPivy,
187
"Deprecated -- use addEventCallbackPivy()");
188
add_varargs_method("removeEventCallbackSWIG",&View3DInventorPy::removeEventCallbackPivy,
189
"Deprecated -- use removeEventCallbackPivy()");
190
add_noargs_method("listNavigationTypes",&View3DInventorPy::listNavigationTypes,"listNavigationTypes()");
191
add_noargs_method("getNavigationType",&View3DInventorPy::getNavigationType,"getNavigationType()");
192
add_varargs_method("setNavigationType",&View3DInventorPy::setNavigationType,"setNavigationType()");
193
add_varargs_method("setAxisCross",&View3DInventorPy::setAxisCross,"switch the big axis-cross on and off");
194
add_noargs_method("hasAxisCross",&View3DInventorPy::hasAxisCross,"check if the big axis-cross is on or off()");
195
add_varargs_method("addDraggerCallback",&View3DInventorPy::addDraggerCallback,
196
"addDraggerCallback(SoDragger, String CallbackType, function)\n"
197
"Add a DraggerCalback function to the coin node\n"
198
"Possibles types :\n"
199
"'addFinishCallback','addStartCallback','addMotionCallback','addValueChangedCallback'\n");
200
add_varargs_method("removeDraggerCallback",&View3DInventorPy::removeDraggerCallback,
201
"removeDraggerCallback(SoDragger, String CallbackType, function)\n"
202
"Remove the DraggerCalback function from the coin node\n"
203
"Possibles types :\n"
204
"'addFinishCallback','addStartCallback','addMotionCallback','addValueChangedCallback'\n");
205
add_varargs_method("getViewProvidersOfType", &View3DInventorPy::getViewProvidersOfType, "getViewProvidersOfType(name)\nreturns a list of view providers for the given type");
206
add_noargs_method("redraw", &View3DInventorPy::redraw, "redraw(): renders the scene on screen (useful for animations)");
207
add_varargs_method("setName",&View3DInventorPy::setName,"setName(str): sets a name to this viewer\nThe name sets the widget's windowTitle and appears on the viewer tab");
208
add_keyword_method("toggleClippingPlane", &View3DInventorPy::toggleClippingPlane,
209
"toggleClippingPlane(toggle=-1, beforeEditing=False, noManip=True, pla=App.Placement()\n"
210
"Toggle a global clipping plane\n\n"
211
"toggle: -1 toggle, 1 show, 0 hide\n"
212
"beforeEditing: whether to insert the clipping node before or after editing root node\n"
213
"noManip: whether to create a manipulator\n"
214
"pla: clipping plane placement");
215
add_noargs_method("hasClippingPlane",&View3DInventorPy::hasClippingPlane,
216
"hasClippingPlane(): check whether this clipping plane is active");
217
add_noargs_method("graphicsView",&View3DInventorPy::graphicsView,
218
"graphicsView(): Access this view as QGraphicsView");
219
add_varargs_method("setCornerCrossVisible",&View3DInventorPy::setCornerCrossVisible,
220
"setCornerCrossVisible(bool): Defines corner axis cross visibility");
221
add_noargs_method("isCornerCrossVisible",&View3DInventorPy::isCornerCrossVisible,
222
"isCornerCrossVisible(): Returns current corner axis cross visibility");
223
add_varargs_method("setCornerCrossSize",&View3DInventorPy::setCornerCrossSize,
224
"setCornerCrossSize(int): Defines corner axis cross size");
225
add_noargs_method("getCornerCrossSize",&View3DInventorPy::getCornerCrossSize,
226
"getCornerCrossSize(): Returns current corner axis cross size");
227
add_noargs_method("cast_to_base", &View3DInventorPy::cast_to_base, "cast_to_base() cast to MDIView class");
230
View3DInventorPy::View3DInventorPy(View3DInventor *vi)
235
View3DInventorPy::~View3DInventorPy()
237
Base::PyGILStateLocker lock;
238
for (auto it : callbacks)
242
View3DInventor* View3DInventorPy::getView3DIventorPtr()
244
return qobject_cast<View3DInventor*>(base.getMDIViewPtr());
247
Py::Object View3DInventorPy::repr()
250
std::ostringstream s_out;
251
if (!getView3DIventorPtr())
252
throw Py::RuntimeError("Cannot print representation of deleted object");
253
s_out << "View3DInventor";
254
return Py::String(s_out.str());
257
View3DInventorPy::method_varargs_handler View3DInventorPy::pycxx_handler = nullptr;
259
PyObject *View3DInventorPy::method_varargs_ext_handler(PyObject *_self_and_name_tuple, PyObject *_args)
262
return pycxx_handler(_self_and_name_tuple, _args);
264
catch (const Base::Exception& e) {
265
throw Py::RuntimeError(e.what());
267
catch (const std::exception& e) {
268
throw Py::RuntimeError(e.what());
270
catch (const Py::Exception&) {
274
throw Py::RuntimeError("Unknown C++ exception");
278
// Since with PyCXX it's not possible to make a sub-class of MDIViewPy
279
// a trick is to use MDIViewPy as class member and override getattr() to
280
// join the attributes of both classes. This way all methods of MDIViewPy
281
// appear for SheetViewPy, too.
282
Py::Object View3DInventorPy::getattribute(const char * attr)
284
if (!getView3DIventorPtr())
285
throw Py::RuntimeError("Cannot print representation of deleted object");
286
std::string name( attr );
287
if (name == "__dict__" || name == "__class__") {
288
Py::Dict dict_self(BaseType::getattr("__dict__"));
289
Py::Dict dict_base(base.getattr("__dict__"));
290
for (const auto& it : dict_base) {
291
dict_self.setItem(it.first, it.second);
297
return BaseType::getattr(attr);
299
catch (Py::AttributeError& e) {
301
return base.getattr(attr);
305
Py::Object View3DInventorPy::getattr(const char * attr)
307
if (!getView3DIventorPtr()) {
308
std::ostringstream s_out;
309
s_out << "Cannot access attribute '" << attr << "' of deleted object";
310
throw Py::RuntimeError(s_out.str());
313
// see if an active object has the same name
314
App::DocumentObject *docObj = getView3DIventorPtr()->getActiveObject<App::DocumentObject*>(attr);
316
return Py::Object(docObj->getPyObject(),true);
319
// else looking for a method with the name and call it
320
Py::Object obj = getattribute(attr);
321
if (PyCFunction_Check(obj.ptr())) {
322
auto op = reinterpret_cast<PyCFunctionObject*>(obj.ptr());
323
if (op->m_ml->ml_flags == METH_VARARGS) {
325
pycxx_handler = op->m_ml->ml_meth;
326
op->m_ml->ml_meth = method_varargs_ext_handler;
334
int View3DInventorPy::setattr(const char * attr, const Py::Object & value)
336
if (!getView3DIventorPtr()) {
338
std::ostringstream s_out;
339
s_out << "Cannot access attribute '" << attr << "' of deleted object";
340
throw Py::RuntimeError(s_out.str());
343
return BaseType::setattr(attr, value);
347
Py::Object View3DInventorPy::fitAll(const Py::Tuple& args)
350
if (!PyArg_ParseTuple(args.ptr(), "|d", &factor))
351
throw Py::Exception();
354
getView3DIventorPtr()->getViewer()->viewAll((float)factor);
356
catch (const Base::Exception& e) {
357
throw Py::RuntimeError(e.what());
359
catch (const std::exception& e) {
360
throw Py::RuntimeError(e.what());
363
throw Py::RuntimeError("Unknown C++ exception");
368
Py::Object View3DInventorPy::boxZoom(const Py::Tuple& args, const Py::Dict& kwds)
370
static const std::array<const char *, 5> kwds_box{"XMin", "YMin", "XMax", "YMax", nullptr};
371
short xmin, ymin, xmax, ymax;
372
if (!Base::Wrapped_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "hhhh", kwds_box,
373
&xmin, &ymin, &xmax, &ymax)) {
374
throw Py::Exception();
377
SbBox2s box(xmin, ymin, xmax, ymax);
378
getView3DIventorPtr()->getViewer()->boxZoom(box);
382
Py::Object View3DInventorPy::viewBottom()
385
getView3DIventorPtr()->getViewer()->setCameraOrientation(Camera::rotation(Camera::Bottom));
387
catch (const Base::Exception& e) {
388
throw Py::RuntimeError(e.what());
390
catch (const std::exception& e) {
391
throw Py::RuntimeError(e.what());
394
throw Py::RuntimeError("Unknown C++ exception");
400
Py::Object View3DInventorPy::viewFront()
403
getView3DIventorPtr()->getViewer()->setCameraOrientation(Camera::rotation(Camera::Front));
405
catch (const Base::Exception& e) {
406
throw Py::RuntimeError(e.what());
408
catch (const std::exception& e) {
409
throw Py::RuntimeError(e.what());
412
throw Py::RuntimeError("Unknown C++ exception");
418
Py::Object View3DInventorPy::viewLeft()
421
getView3DIventorPtr()->getViewer()->setCameraOrientation(Camera::rotation(Camera::Left));
423
catch (const Base::Exception& e) {
424
throw Py::RuntimeError(e.what());
426
catch (const std::exception& e) {
427
throw Py::RuntimeError(e.what());
430
throw Py::RuntimeError("Unknown C++ exception");
436
Py::Object View3DInventorPy::viewRear()
439
getView3DIventorPtr()->getViewer()->setCameraOrientation(Camera::rotation(Camera::Rear));
441
catch (const Base::Exception& e) {
442
throw Py::RuntimeError(e.what());
444
catch (const std::exception& e) {
445
throw Py::RuntimeError(e.what());
448
throw Py::RuntimeError("Unknown C++ exception");
454
Py::Object View3DInventorPy::viewRight()
457
getView3DIventorPtr()->getViewer()->setCameraOrientation(Camera::rotation(Camera::Right));
459
catch (const Base::Exception& e) {
460
throw Py::RuntimeError(e.what());
462
catch (const std::exception& e) {
463
throw Py::RuntimeError(e.what());
466
throw Py::RuntimeError("Unknown C++ exception");
472
Py::Object View3DInventorPy::viewTop()
475
getView3DIventorPtr()->getViewer()->setCameraOrientation(Camera::rotation(Camera::Top));
477
catch (const Base::Exception& e) {
478
throw Py::RuntimeError(e.what());
480
catch (const std::exception& e) {
481
throw Py::RuntimeError(e.what());
484
throw Py::RuntimeError("Unknown C++ exception");
490
Py::Object View3DInventorPy::viewIsometric()
493
getView3DIventorPtr()->getViewer()->setCameraOrientation(Camera::rotation(Camera::Isometric));
495
catch (const Base::Exception& e) {
496
throw Py::RuntimeError(e.what());
498
catch (const std::exception& e) {
499
throw Py::RuntimeError(e.what());
502
throw Py::RuntimeError("Unknown C++ exception");
508
Py::Object View3DInventorPy::viewDimetric()
511
getView3DIventorPtr()->getViewer()->setCameraOrientation(Camera::rotation(Camera::Dimetric));
513
catch (const Base::Exception& e) {
514
throw Py::RuntimeError(e.what());
516
catch (const std::exception& e) {
517
throw Py::RuntimeError(e.what());
520
throw Py::RuntimeError("Unknown C++ exception");
526
Py::Object View3DInventorPy::viewTrimetric()
529
getView3DIventorPtr()->getViewer()->setCameraOrientation(Camera::rotation(Camera::Trimetric));
531
catch (const Base::Exception& e) {
532
throw Py::RuntimeError(e.what());
534
catch (const std::exception& e) {
535
throw Py::RuntimeError(e.what());
538
throw Py::RuntimeError("Unknown C++ exception");
544
Py::Object View3DInventorPy::viewDefaultOrientation(const Py::Tuple& args)
546
char* view = nullptr;
548
if (!PyArg_ParseTuple(args.ptr(), "|sd", &view, &scale))
549
throw Py::Exception();
552
std::string newDocView;
553
SbRotation rot(0,0,0,1);
558
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
559
newDocView = hGrp->GetASCII("NewDocumentCameraOrientation", "Trimetric");
562
if (newDocView == "Top") {
563
rot = Camera::rotation(Camera::Top);
565
else if (newDocView == "Bottom") {
566
rot = Camera::rotation(Camera::Bottom);
568
else if (newDocView == "Front") {
569
rot = Camera::rotation(Camera::Front);
571
else if (newDocView == "Rear") {
572
rot = Camera::rotation(Camera::Rear);
574
else if (newDocView == "Left") {
575
rot = Camera::rotation(Camera::Left);
577
else if (newDocView == "Right") {
578
rot = Camera::rotation(Camera::Right);
580
else if (newDocView == "Isometric") {
581
rot = Camera::rotation(Camera::Isometric);
583
else if (newDocView == "Dimetric") {
584
rot = Camera::rotation(Camera::Dimetric);
586
else if (newDocView == "Trimetric") {
587
rot = Camera::rotation(Camera::Trimetric);
589
else if (newDocView == "Custom") {
590
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View/Custom");
591
auto q0 = static_cast<float>(hGrp->GetFloat("Q0", 0));
592
auto q1 = static_cast<float>(hGrp->GetFloat("Q1", 0));
593
auto q2 = static_cast<float>(hGrp->GetFloat("Q2", 0));
594
auto q3 = static_cast<float>(hGrp->GetFloat("Q3", 1));
595
rot.setValue(q0, q1, q2, q3);
598
SoCamera* cam = getView3DIventorPtr()->getViewer()->getCamera();
599
cam->orientation = rot;
602
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
603
scale = hGrp->GetFloat("NewDocumentCameraScale",100.0);
606
setDefaultCameraHeight(scale);
608
catch (const Base::Exception& e) {
609
throw Py::RuntimeError(e.what());
611
catch (const std::exception& e) {
612
throw Py::RuntimeError(e.what());
615
throw Py::RuntimeError("Unknown C++ exception");
621
void View3DInventorPy::setDefaultCameraHeight(float scale)
624
SoCamera* cam = getView3DIventorPtr()->getViewer()->getCamera();
625
SbRotation rot = cam->orientation.getValue();
627
double f = 0.0; //focal dist
628
if (cam->isOfType(SoOrthographicCamera::getClassTypeId())){
629
static_cast<SoOrthographicCamera*>(cam)->height = scale;
632
else if (cam->isOfType(SoPerspectiveCamera::getClassTypeId())){
634
double ang = static_cast<SoPerspectiveCamera*>(cam)->heightAngle.getValue();
635
f = 0.5 * scale / sin(ang * 0.5);
639
rot.multVec(SbVec3f(0,0,-1), lookDir);
640
SbVec3f pos = lookDir * -f;
641
cam->focalDistance = f;
646
Py::Object View3DInventorPy::viewRotateLeft()
649
SoCamera* cam = getView3DIventorPtr()->getViewer()->getSoRenderManager()->getCamera();
650
SbRotation rot = cam->orientation.getValue();
651
SbVec3f vdir(0, 0, -1);
652
rot.multVec(vdir, vdir);
653
SbRotation nrot(vdir, (float)M_PI/2);
654
cam->orientation.setValue(rot*nrot);
656
catch (const Base::Exception& e) {
657
throw Py::RuntimeError(e.what());
659
catch (const std::exception& e) {
660
throw Py::RuntimeError(e.what());
663
throw Py::RuntimeError("Unknown C++ exception");
669
Py::Object View3DInventorPy::viewRotateRight()
672
SoCamera* cam = getView3DIventorPtr()->getViewer()->getSoRenderManager()->getCamera();
673
SbRotation rot = cam->orientation.getValue();
674
SbVec3f vdir(0, 0, -1);
675
rot.multVec(vdir, vdir);
676
SbRotation nrot(vdir, (float)-M_PI/2);
677
cam->orientation.setValue(rot*nrot);
679
catch (const Base::Exception& e) {
680
throw Py::RuntimeError(e.what());
682
catch (const std::exception& e) {
683
throw Py::RuntimeError(e.what());
686
throw Py::RuntimeError("Unknown C++ exception");
692
Py::Object View3DInventorPy::zoomIn()
695
getView3DIventorPtr()->getViewer()->navigationStyle()->zoomIn();
697
catch (const Base::Exception& e) {
698
throw Py::RuntimeError(e.what());
700
catch (const std::exception& e) {
701
throw Py::RuntimeError(e.what());
704
throw Py::RuntimeError("Unknown C++ exception");
710
Py::Object View3DInventorPy::zoomOut()
713
getView3DIventorPtr()->getViewer()->navigationStyle()->zoomOut();
715
catch (const Base::Exception& e) {
716
throw Py::RuntimeError(e.what());
718
catch (const std::exception& e) {
719
throw Py::RuntimeError(e.what());
722
throw Py::RuntimeError("Unknown C++ exception");
728
Py::Object View3DInventorPy::setCameraOrientation(const Py::Tuple& args)
731
PyObject* m=Py_False;
732
if (!PyArg_ParseTuple(args.ptr(), "O|O!", &o, &PyBool_Type, &m))
733
throw Py::Exception();
736
if (PyTuple_Check(o)) {
738
float q0 = (float)Py::Float(tuple[0]);
739
float q1 = (float)Py::Float(tuple[1]);
740
float q2 = (float)Py::Float(tuple[2]);
741
float q3 = (float)Py::Float(tuple[3]);
742
getView3DIventorPtr()->getViewer()->setCameraOrientation(SbRotation(q0, q1, q2, q3), Base::asBoolean(m));
744
else if (PyObject_TypeCheck(o, &Base::RotationPy::Type)) {
745
Base::Rotation r = static_cast<Base::Rotation>(Py::Rotation(o,false));
746
double q0, q1, q2, q3;
747
r.getValue(q0, q1, q2, q3);
748
getView3DIventorPtr()->getViewer()->setCameraOrientation(SbRotation((float)q0, (float)q1, (float)q2, (float)q3), Base::asBoolean(m));
751
throw Py::ValueError("Neither tuple nor rotation object");
754
catch (const Py::Exception&) {
757
catch (const Base::Exception& e) {
758
throw Py::RuntimeError(e.what());
760
catch (const std::exception& e) {
761
throw Py::RuntimeError(e.what());
764
throw Py::RuntimeError("Unknown C++ exception");
770
Py::Object View3DInventorPy::getCameraOrientation()
772
SbRotation rot = getView3DIventorPtr()->getViewer()->getCameraOrientation();
774
rot.getValue(q0,q1,q2,q3);
775
return Py::Rotation(Base::Rotation(q0,q1,q2,q3));
778
Py::Object View3DInventorPy::viewPosition(const Py::Tuple& args)
780
PyObject* p = nullptr;
781
int steps; // Unused but kept as parameter to not break the Python interface
782
int duration = -1; // Duration in ms, will be replaced with User parameter:BaseApp/Preferences/View/AnimationDuration when not explicitly provided
783
if (!PyArg_ParseTuple(args.ptr(), "|O!ii", &Base::PlacementPy::Type, &p, &steps, &duration))
784
throw Py::Exception();
787
Base::Placement* plm = static_cast<Base::PlacementPy*>(p)->getPlacementPtr();
788
Base::Rotation rot = plm->getRotation();
789
Base::Vector3d pos = plm->getPosition();
791
rot.getValue(q0,q1,q2,q3);
792
getView3DIventorPtr()->getViewer()->moveCameraTo(
793
SbRotation((float)q0, (float)q1, (float)q2, (float)q3),
794
SbVec3f((float)pos.x, (float)pos.y, (float)pos.z), duration);
797
SoCamera* cam = getView3DIventorPtr()->getViewer()->getSoRenderManager()->getCamera();
801
SbRotation rot = cam->orientation.getValue();
802
SbVec3f pos = cam->position.getValue();
804
rot.getValue(q0,q1,q2,q3);
806
Base::Vector3d(pos[0], pos[1], pos[2]),
807
Base::Rotation(q0, q1, q2, q3));
808
return Py::Placement(plm);
811
Py::Object View3DInventorPy::startAnimating(const Py::Tuple& args)
815
if (!PyArg_ParseTuple(args.ptr(), "ffff", &x, &y, &z, &velocity))
816
throw Py::Exception();
817
getView3DIventorPtr()->getViewer()->startSpinningAnimation(SbVec3f(x, y, z), velocity);
821
Py::Object View3DInventorPy::stopAnimating()
823
getView3DIventorPtr()->getViewer()->stopAnimating();
827
Py::Object View3DInventorPy::setAnimationEnabled(const Py::Tuple& args)
830
if (!PyArg_ParseTuple(args.ptr(), "i", &ok))
831
throw Py::Exception();
832
getView3DIventorPtr()->getViewer()->setAnimationEnabled(ok!=0);
836
Py::Object View3DInventorPy::isAnimationEnabled()
838
SbBool ok = getView3DIventorPtr()->getViewer()->isAnimationEnabled();
839
return Py::Boolean(ok ? true : false);
842
Py::Object View3DInventorPy::setPopupMenuEnabled(const Py::Tuple& args)
845
if (!PyArg_ParseTuple(args.ptr(), "i", &ok))
846
throw Py::Exception();
847
getView3DIventorPtr()->getViewer()->setPopupMenuEnabled(ok!=0);
851
Py::Object View3DInventorPy::isPopupMenuEnabled()
853
SbBool ok = getView3DIventorPtr()->getViewer()->isPopupMenuEnabled();
854
return Py::Boolean(ok ? true : false);
857
Py::Object View3DInventorPy::saveImage(const Py::Tuple& args)
859
char *cFileName = nullptr;
860
const char *cColor="Current";
861
const char *cComment="$MIBA";
863
int s=View3DInventorViewer::getNumSamples();
865
if (!PyArg_ParseTuple(args.ptr(), "et|iissi","utf-8",&cFileName,&w,&h,&cColor,&cComment,&s))
866
throw Py::Exception();
868
std::string encodedName = std::string(cFileName);
869
PyMem_Free(cFileName);
870
QFileInfo fi(QString::fromUtf8(encodedName.c_str()));
872
if (!fi.absoluteDir().exists())
873
throw Py::RuntimeError("Directory where to save image doesn't exist");
876
QString colname = QString::fromLatin1(cColor);
877
if (colname.compare(QLatin1String("Current"), Qt::CaseInsensitive) == 0)
878
bg = QColor(); // assign an invalid color here
880
bg = QColor(colname);
883
getView3DIventorPtr()->getViewer()->savePicture(w, h, s, bg, img);
885
SoFCOffscreenRenderer& renderer = SoFCOffscreenRenderer::instance();
886
SoCamera* cam = getView3DIventorPtr()->getViewer()->getSoRenderManager()->getCamera();
887
renderer.writeToImageFile(encodedName.c_str(), cComment, cam->getViewVolume().getMatrix(), img);
892
Py::Object View3DInventorPy::saveVectorGraphic(const Py::Tuple& args)
896
const char* name="white";
898
if (!PyArg_ParseTuple(args.ptr(), "s|is",&filename,&ps,&name))
899
throw Py::Exception();
901
std::unique_ptr<SoVectorizeAction> vo;
902
Base::FileInfo fi(filename);
903
if (fi.hasExtension({"ps", "eps"})) {
904
vo = std::unique_ptr<SoVectorizeAction>(new SoVectorizePSAction());
905
//vo->setGouraudThreshold(0.0f);
907
else if (fi.hasExtension("svg")) {
908
vo = std::unique_ptr<SoVectorizeAction>(new SoFCVectorizeSVGAction());
910
else if (fi.hasExtension("idtf")) {
911
vo = std::unique_ptr<SoVectorizeAction>(new SoFCVectorizeU3DAction());
914
throw Py::RuntimeError("Not supported vector graphic");
917
SoVectorOutput * out = vo->getOutput();
918
if (!out || !out->openFile(filename)) {
919
std::ostringstream a_out;
920
a_out << "Cannot open file '" << filename << "'";
921
throw Py::RuntimeError(a_out.str());
925
QString colname = QString::fromLatin1(name);
926
if (colname.compare(QLatin1String("Current"), Qt::CaseInsensitive) == 0)
927
bg = getView3DIventorPtr()->getViewer()->backgroundColor();
929
bg = QColor(colname);
931
getView3DIventorPtr()->getViewer()->saveGraphic(ps,bg,vo.get());
936
Py::Object View3DInventorPy::getCameraNode()
939
SoNode* camera = getView3DIventorPtr()->getViewer()->getSoRenderManager()->getCamera();
940
PyObject* proxy = nullptr;
942
type = "So"; // seems that So prefix is missing in camera node
943
type += camera->getTypeId().getName().getString();
945
proxy = Base::Interpreter().createSWIGPointerObj("pivy.coin", type.c_str(), static_cast<void*>(camera), 1);
947
return Py::Object(proxy, true);
949
catch (const Base::Exception& e) {
950
throw Py::RuntimeError(e.what());
954
Py::Object View3DInventorPy::getCamera()
958
out.setBuffer(buffer, 512, nullptr);
961
SoWriteAction wa(&out);
962
SoCamera * cam = getView3DIventorPtr()->getViewer()->getSoRenderManager()->getCamera();
963
if (cam) wa.apply(cam);
964
else buffer[0] = '\0';
965
return Py::String(buffer);
967
catch (const Base::Exception& e) {
968
throw Py::RuntimeError(e.what());
970
catch (const std::exception& e) {
971
throw Py::RuntimeError(e.what());
974
throw Py::RuntimeError("Unknown C++ exception");
978
Py::Object View3DInventorPy::getViewDirection()
981
SbVec3f dvec = getView3DIventorPtr()->getViewer()->getViewDirection();
982
return Py::Vector(Base::Vector3f(dvec[0], dvec[1], dvec[2]));
984
catch (const Base::Exception& e) {
985
throw Py::RuntimeError(e.what());
987
catch (const std::exception& e) {
988
throw Py::RuntimeError(e.what());
991
throw Py::RuntimeError("Unknown C++ exception");
996
Py::Object View3DInventorPy::getUpDirection()
999
SbVec3f dvec = getView3DIventorPtr()->getViewer()->getUpDirection();
1000
return Py::Vector(Base::Vector3f(dvec[0], dvec[1], dvec[2]));
1002
catch (const Base::Exception& e) {
1003
throw Py::RuntimeError(e.what());
1005
catch (const std::exception& e) {
1006
throw Py::RuntimeError(e.what());
1009
throw Py::RuntimeError("Unknown C++ exception");
1013
Py::Object View3DInventorPy::setViewDirection(const Py::Tuple& args)
1016
if (!PyArg_ParseTuple(args.ptr(), "O", &object))
1017
throw Py::Exception();
1020
if (PyTuple_Check(object)) {
1021
Py::Tuple tuple(object);
1022
Py::Float x(tuple.getItem(0));
1023
Py::Float y(tuple.getItem(1));
1024
Py::Float z(tuple.getItem(2));
1026
dir.setValue((float)x, (float)y, (float)z);
1027
if (dir.length() < 0.001f)
1028
throw Py::ValueError("Null vector cannot be used to set direction");
1029
getView3DIventorPtr()->getViewer()->setViewDirection(dir);
1033
catch (const Py::Exception&) {
1036
catch (const Base::Exception& e) {
1037
throw Py::RuntimeError(e.what());
1039
catch (const std::exception& e) {
1040
throw Py::RuntimeError(e.what());
1043
throw Py::RuntimeError("Unknown C++ exception");
1051
Py::Object View3DInventorPy::setCamera(const Py::Tuple& args)
1054
if (!PyArg_ParseTuple(args.ptr(), "s", &buffer))
1055
throw Py::Exception();
1058
getView3DIventorPtr()->setCamera(buffer);
1061
catch (const Base::Exception& e) {
1062
throw Py::RuntimeError(e.what());
1064
catch (const std::exception& e) {
1065
throw Py::RuntimeError(e.what());
1068
throw Py::RuntimeError("Unknown C++ exception");
1072
//FIXME: Once View3DInventor inherits from PropertyContainer we can use PropertyEnumeration.
1073
const char* CameraTypeEnums[]= {"Orthographic","Perspective",nullptr};
1075
Py::Object View3DInventorPy::getCameraType()
1077
SoCamera* cam = getView3DIventorPtr()->getViewer()->getSoRenderManager()->getCamera();
1079
throw Py::RuntimeError("No camera set!");
1081
else if (cam->getTypeId() == SoOrthographicCamera::getClassTypeId()) {
1082
return Py::String(CameraTypeEnums[0]);
1084
else if (cam->getTypeId() == SoPerspectiveCamera::getClassTypeId()) {
1085
return Py::String(CameraTypeEnums[1]);
1088
throw Py::TypeError("Unknown camera type");
1092
Py::Object View3DInventorPy::setCameraType(const Py::Tuple& args)
1095
if (!PyArg_ParseTuple(args.ptr(), "i", &cameratype)) {
1098
if (!PyArg_ParseTuple(args.ptr(), "s", &modename))
1099
throw Py::Exception();
1100
for (int i=0; i<2; i++ ) {
1101
if (strncmp(CameraTypeEnums[i],modename,20) == 0 ) {
1107
if (cameratype < 0) {
1109
std::ostringstream s_out;
1110
s_out << "Unknown camera type '" << modename << "'";
1111
throw Py::NameError(s_out.str());
1115
if (cameratype < 0 || cameratype > 1)
1116
throw Py::IndexError("Out of range");
1118
getView3DIventorPtr()->getViewer()->setCameraType(SoOrthographicCamera::getClassTypeId());
1120
getView3DIventorPtr()->getViewer()->setCameraType(SoPerspectiveCamera::getClassTypeId());
1124
Py::Object View3DInventorPy::listCameraTypes()
1128
for (int i=0; i<2; i++) {
1129
list[i] = Py::String(CameraTypeEnums[i]);
1133
catch (const Base::Exception& e) {
1134
throw Py::RuntimeError(e.what());
1136
catch (const std::exception& e) {
1137
throw Py::RuntimeError(e.what());
1140
throw Py::RuntimeError("Unknown C++ exception");
1144
Py::Object View3DInventorPy::dump(const Py::Tuple& args)
1147
PyObject *onlyVisible = Py_False;
1148
if (!PyArg_ParseTuple(args.ptr(), "s|O!", &filename, &PyBool_Type, &onlyVisible))
1149
throw Py::Exception();
1152
getView3DIventorPtr()->dump(filename, Base::asBoolean(onlyVisible));
1155
catch (const Base::Exception& e) {
1156
throw Py::RuntimeError(e.what());
1158
catch (const std::exception& e) {
1159
throw Py::RuntimeError(e.what());
1162
throw Py::RuntimeError("Unknown C++ exception");
1166
Py::Object View3DInventorPy::dumpNode(const Py::Tuple& args)
1169
if (!PyArg_ParseTuple(args.ptr(), "O", &object))
1170
throw Py::Exception();
1172
void* ptr = nullptr;
1174
Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoNode *", object, &ptr, 0);
1176
catch (const Base::Exception& e) {
1177
throw Py::RuntimeError(e.what());
1179
auto node = static_cast<SoNode*>(ptr);
1180
return Py::String(SoFCDB::writeNodesToString(node));
1183
//FIXME: Once View3DInventor inherits from PropertyContainer we can use PropertyEnumeration.
1184
const char* StereoTypeEnums[]= {"Mono","Anaglyph","QuadBuffer","InterleavedRows","InterleavedColumns",nullptr};
1186
Py::Object View3DInventorPy::setStereoType(const Py::Tuple& args)
1189
if (!PyArg_ParseTuple(args.ptr(), "i", &stereomode)) {
1192
if (!PyArg_ParseTuple(args.ptr(), "s", &modename))
1193
throw Py::Exception();
1194
for (int i=0; i<5; i++) {
1195
if (strncmp(StereoTypeEnums[i],modename,20) == 0) {
1201
if (stereomode < 0) {
1203
std::ostringstream s_out;
1204
s_out << "Unknown stereo type '" << modename << "'";
1205
throw Py::NameError(s_out.str());
1210
if (stereomode < 0 || stereomode > 4)
1211
throw Py::IndexError("Out of range");
1212
Quarter::SoQTQuarterAdaptor::StereoMode mode = Quarter::SoQTQuarterAdaptor::StereoMode(stereomode);
1213
getView3DIventorPtr()->getViewer()->setStereoMode(mode);
1216
catch (const Base::Exception& e) {
1217
throw Py::RuntimeError(e.what());
1219
catch (const std::exception& e) {
1220
throw Py::RuntimeError(e.what());
1223
throw Py::RuntimeError("Unknown C++ exception");
1227
Py::Object View3DInventorPy::getStereoType()
1230
int mode = int(getView3DIventorPtr()->getViewer()->stereoMode());
1231
if (mode < 0 || mode > 4)
1232
throw Py::ValueError("Invalid stereo mode");
1233
return Py::String(StereoTypeEnums[mode]);
1235
catch (const Base::Exception& e) {
1236
throw Py::RuntimeError(e.what());
1238
catch (const std::exception& e) {
1239
throw Py::RuntimeError(e.what());
1242
throw Py::RuntimeError("Unknown C++ exception");
1246
Py::Object View3DInventorPy::listStereoTypes()
1250
for (int i=0; i<5; i++) {
1251
list[i] = Py::String(StereoTypeEnums[i]);
1256
catch (const Base::Exception& e) {
1257
throw Py::RuntimeError(e.what());
1259
catch (const std::exception& e) {
1260
throw Py::RuntimeError(e.what());
1263
throw Py::RuntimeError("Unknown C++ exception");
1267
Py::Object View3DInventorPy::getCursorPos()
1270
QPoint pos = getView3DIventorPtr()->mapFromGlobal(QCursor::pos());
1271
auto viewer = getView3DIventorPtr()->getViewer();
1272
SbVec2s vec = viewer->fromQPoint(pos);
1274
tuple.setItem(0, Py::Int(vec[0]));
1275
tuple.setItem(1, Py::Int(vec[1]));
1278
catch (const Py::Exception&) {
1283
Py::Object View3DInventorPy::getObjectInfo(const Py::Tuple& args)
1286
float r = getView3DIventorPtr()->getViewer()->getPickRadius();
1287
if (!PyArg_ParseTuple(args.ptr(), "O|f", &object, &r))
1288
throw Py::Exception();
1291
//Note: For gcc (4.2) we need the 'const' keyword to avoid the compiler error:
1292
//conversion from 'Py::seqref<Py::Object>' to non-scalar type 'Py::Int' requested
1293
//We should report this problem to the PyCXX project as in the documentation an
1294
//example without the 'const' keyword is used.
1295
//Or we can also write Py::Int x(tuple[0]);
1296
const Py::Tuple tuple(object);
1297
Py::Int x(tuple[0]);
1298
Py::Int y(tuple[1]);
1300
// As this method could be called during a SoHandleEventAction scene
1301
// graph traversal we must not use a second SoHandleEventAction as
1302
// we will get Coin warnings because of multiple scene graph traversals
1303
// which is regarded as error-prone.
1304
SoRayPickAction action(getView3DIventorPtr()->getViewer()->getSoRenderManager()->getViewportRegion());
1305
action.setPoint(SbVec2s((long)x,(long)y));
1306
action.setRadius(r);
1307
action.apply(getView3DIventorPtr()->getViewer()->getSoRenderManager()->getSceneGraph());
1308
SoPickedPoint *Point = action.getPickedPoint();
1310
Py::Object ret = Py::None();
1313
SbVec3f pt = Point->getPoint();
1314
dict.setItem("x", Py::Float(pt[0]));
1315
dict.setItem("y", Py::Float(pt[1]));
1316
dict.setItem("z", Py::Float(pt[2]));
1318
ViewProvider *vp = getView3DIventorPtr()->getViewer()->getViewProviderByPath(Point->getPath());
1319
if (vp && vp->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) {
1320
if (!vp->isSelectable())
1322
auto vpd = static_cast<ViewProviderDocumentObject*>(vp);
1323
if (vp->useNewSelectionModel()) {
1324
std::string subname;
1325
if (!vp->getElementPicked(Point,subname))
1327
auto obj = vpd->getObject();
1330
if (!subname.empty()) {
1331
App::ElementNamePair elementName;
1332
auto sobj = App::GeoFeature::resolveElement(obj,subname.c_str(),elementName);
1336
dict.setItem("ParentObject",Py::Object(obj->getPyObject(),true));
1337
dict.setItem("SubName",Py::String(subname));
1340
subname = !elementName.oldName.empty()?elementName.oldName:elementName.newName;
1342
dict.setItem("Document",
1343
Py::String(obj->getDocument()->getName()));
1344
dict.setItem("Object",
1345
Py::String(obj->getNameInDocument()));
1346
dict.setItem("Component",Py::String(subname));
1349
dict.setItem("Document",
1350
Py::String(vpd->getObject()->getDocument()->getName()));
1351
dict.setItem("Object",
1352
Py::String(vpd->getObject()->getNameInDocument()));
1353
// search for a SoFCSelection node
1354
SoFCDocumentObjectAction objaction;
1355
objaction.apply(Point->getPath());
1356
if (objaction.isHandled()) {
1357
dict.setItem("Component",
1358
Py::String(objaction.componentName.getString()));
1362
// ok, found the node of interest
1366
// custom nodes not in a VP: search for a SoFCSelection node
1367
SoFCDocumentObjectAction objaction;
1368
objaction.apply(Point->getPath());
1369
if (objaction.isHandled()) {
1370
dict.setItem("Document",
1371
Py::String(objaction.documentName.getString()));
1372
dict.setItem("Object",
1373
Py::String(objaction.objectName.getString()));
1374
dict.setItem("Component",
1375
Py::String(objaction.componentName.getString()));
1376
// ok, found the node of interest
1384
catch (const Py::Exception&) {
1389
Py::Object View3DInventorPy::getObjectsInfo(const Py::Tuple& args)
1392
float r = getView3DIventorPtr()->getViewer()->getPickRadius();
1393
if (!PyArg_ParseTuple(args.ptr(), "O|f", &object, &r))
1394
throw Py::Exception();
1397
//Note: For gcc (4.2) we need the 'const' keyword to avoid the compiler error:
1398
//conversion from 'Py::seqref<Py::Object>' to non-scalar type 'Py::Int' requested
1399
//We should report this problem to the PyCXX project as in the documentation an
1400
//example without the 'const' keyword is used.
1401
//Or we can also write Py::Int x(tuple[0]);
1402
const Py::Tuple tuple(object);
1403
Py::Int x(tuple[0]);
1404
Py::Int y(tuple[1]);
1406
// As this method could be called during a SoHandleEventAction scene
1407
// graph traversal we must not use a second SoHandleEventAction as
1408
// we will get Coin warnings because of multiple scene graph traversals
1409
// which is regarded as error-prone.
1410
SoRayPickAction action(getView3DIventorPtr()->getViewer()->getSoRenderManager()->getViewportRegion());
1411
action.setPickAll(true);
1412
action.setRadius(r);
1413
action.setPoint(SbVec2s((long)x,(long)y));
1414
action.apply(getView3DIventorPtr()->getViewer()->getSoRenderManager()->getSceneGraph());
1415
const SoPickedPointList& pp = action.getPickedPointList();
1417
Py::Object ret = Py::None();
1418
if (pp.getLength() > 0) {
1420
for (int i=0; i<pp.getLength(); i++) {
1422
auto point = static_cast<SoPickedPoint*>(pp.get(i));
1423
SbVec3f pt = point->getPoint();
1424
dict.setItem("x", Py::Float(pt[0]));
1425
dict.setItem("y", Py::Float(pt[1]));
1426
dict.setItem("z", Py::Float(pt[2]));
1428
ViewProvider *vp = getView3DIventorPtr()->getViewer()->getViewProviderByPath(point->getPath());
1429
if(vp && vp->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) {
1430
if(!vp->isSelectable())
1432
auto vpd = static_cast<ViewProviderDocumentObject*>(vp);
1433
if (vp->useNewSelectionModel()) {
1434
std::string subname;
1435
if (!vp->getElementPicked(point,subname))
1437
auto obj = vpd->getObject();
1440
if (!subname.empty()) {
1441
App::ElementNamePair elementName;
1442
auto sobj = App::GeoFeature::resolveElement(obj,subname.c_str(),elementName);
1446
dict.setItem("ParentObject",Py::Object(obj->getPyObject(),true));
1447
dict.setItem("SubName",Py::String(subname));
1450
subname = !elementName.oldName.empty()?elementName.oldName:elementName.newName;
1452
dict.setItem("Document",
1453
Py::String(obj->getDocument()->getName()));
1454
dict.setItem("Object",
1455
Py::String(obj->getNameInDocument()));
1456
dict.setItem("Component",Py::String(subname));
1459
dict.setItem("Document",
1460
Py::String(vpd->getObject()->getDocument()->getName()));
1461
dict.setItem("Object",
1462
Py::String(vpd->getObject()->getNameInDocument()));
1463
// search for a SoFCSelection node
1464
SoFCDocumentObjectAction objaction;
1465
objaction.apply(point->getPath());
1466
if (objaction.isHandled()) {
1467
dict.setItem("Component",
1468
Py::String(objaction.componentName.getString()));
1471
// ok, found the node of interest
1475
// custom nodes not in a VP: search for a SoFCSelection node
1476
SoFCDocumentObjectAction objaction;
1477
objaction.apply(point->getPath());
1478
if (objaction.isHandled()) {
1479
dict.setItem("Document",
1480
Py::String(objaction.documentName.getString()));
1481
dict.setItem("Object",
1482
Py::String(objaction.objectName.getString()));
1483
dict.setItem("Component",
1484
Py::String(objaction.componentName.getString()));
1485
// ok, found the node of interest
1496
catch (const Py::Exception&) {
1501
Py::Object View3DInventorPy::getSize()
1504
SbVec2s size = getView3DIventorPtr()->getViewer()->getSoRenderManager()->getSize();
1506
tuple.setItem(0, Py::Int(size[0]));
1507
tuple.setItem(1, Py::Int(size[1]));
1510
catch (const Py::Exception&) {
1515
Py::Object View3DInventorPy::getPointOnFocalPlane(const Py::Tuple& args)
1518
if (!PyArg_ParseTuple(args.ptr(), "hh", &x, &y)) {
1520
Py::Tuple t(args[0]);
1521
x = (int)Py::Int(t[0]);
1522
y = (int)Py::Int(t[1]);
1525
SbVec3f pt = getView3DIventorPtr()->getViewer()->getPointOnFocalPlane(SbVec2s(x,y));
1526
return Py::Vector(Base::Vector3f(pt[0], pt[1], pt[2]));
1528
catch (const Base::Exception& e) {
1529
throw Py::RuntimeError(e.what());
1531
catch (const Py::Exception&) {
1536
Py::Object View3DInventorPy::getPointOnViewport(const Py::Tuple& args)
1540
if (PyArg_ParseTuple(args.ptr(), "O!", &Base::VectorPy::Type, &v)) {
1541
Base::Vector3d* vec = static_cast<Base::VectorPy*>(v)->getVectorPtr();
1548
if (!PyArg_ParseTuple(args.ptr(), "ddd", &vx,&vy,&vz)) {
1549
throw Py::TypeError("Wrong argument, Vector or three floats expected expected");
1554
SbVec2s pt = getView3DIventorPtr()->getViewer()->getPointOnViewport(SbVec3f(vx,vy,vz));
1556
tuple.setItem(0, Py::Int(pt[0]));
1557
tuple.setItem(1, Py::Int(pt[1]));
1561
catch (const Base::Exception& e) {
1562
throw Py::RuntimeError(e.what());
1564
catch (const Py::Exception&) {
1569
Py::Object View3DInventorPy::projectPointToLine(const Py::Tuple& args)
1572
if (!PyArg_ParseTuple(args.ptr(), "hh", &x, &y)) {
1574
Py::Tuple t(args[0]);
1575
x = (int)Py::Int(t[0]);
1576
y = (int)Py::Int(t[1]);
1580
getView3DIventorPtr()->getViewer()->projectPointToLine(SbVec2s(x,y), pt1, pt2);
1582
tuple.setItem(0, Py::Vector(Base::Vector3f(pt1[0], pt1[1], pt1[2])));
1583
tuple.setItem(1, Py::Vector(Base::Vector3f(pt2[0], pt2[1], pt2[2])));
1586
catch (const Base::Exception& e) {
1587
throw Py::RuntimeError(e.what());
1589
catch (const Py::Exception&) {
1594
Py::Object View3DInventorPy::listNavigationTypes()
1596
std::vector<Base::Type> types;
1598
Base::Type::getAllDerivedFrom(UserNavigationStyle::getClassTypeId(), types);
1599
for (auto it = types.begin() + 1; it != types.end(); ++it) {
1600
styles.append(Py::String(it->getName()));
1605
Py::Object View3DInventorPy::getNavigationType()
1607
std::string name = getView3DIventorPtr()->getViewer()->navigationStyle()->getTypeId().getName();
1608
return Py::String(name);
1611
Py::Object View3DInventorPy::setNavigationType(const Py::Tuple& args)
1614
if (!PyArg_ParseTuple(args.ptr(), "s", &style))
1615
throw Py::Exception();
1616
Base::Type type = Base::Type::fromName(style);
1617
getView3DIventorPtr()->getViewer()->setNavigationType(type);
1621
void View3DInventorPy::eventCallback(void * ud, SoEventCallback * n)
1623
Base::PyGILStateLocker lock;
1626
const SoEvent* e = n->getEvent();
1627
if (!e) // invalid event
1630
dict.setItem("Type", Py::String(std::string(e->getTypeId().getName().getString())));
1632
dict.setItem("Time", Py::String(std::string(e->getTime().formatDate("%Y-%m-%d %H:%M:%S").getString())));
1633
SbVec2s p = n->getEvent()->getPosition();
1635
pos.setItem(0, Py::Int(p[0]));
1636
pos.setItem(1, Py::Int(p[1]));
1638
dict.setItem("Position", pos);
1639
// Shift, Ctrl, Alt down
1640
dict.setItem("ShiftDown", Py::Object((e->wasShiftDown() ? Py_True : Py_False)));
1641
dict.setItem("CtrlDown", Py::Object((e->wasCtrlDown() ? Py_True : Py_False)));
1642
dict.setItem("AltDown", Py::Object((e->wasAltDown() ? Py_True : Py_False)));
1643
if (e->isOfType(SoButtonEvent::getClassTypeId())) {
1645
const auto be = static_cast<const SoButtonEvent*>(e);
1646
switch (be->getState()) {
1647
case SoButtonEvent::UP:
1650
case SoButtonEvent::DOWN:
1658
dict.setItem("State", Py::String(state));
1660
if (e->isOfType(SoKeyboardEvent::getClassTypeId())) {
1661
const auto ke = static_cast<const SoKeyboardEvent*>(e);
1662
switch (ke->getKey()) {
1663
case SoKeyboardEvent::ANY:
1664
dict.setItem("Key", Py::String("ANY"));
1666
case SoKeyboardEvent::UNDEFINED:
1667
dict.setItem("Key", Py::String("UNDEFINED"));
1669
case SoKeyboardEvent::LEFT_SHIFT:
1670
case SoKeyboardEvent::RIGHT_SHIFT:
1671
dict.setItem("Key", Py::String("SHIFT"));
1673
case SoKeyboardEvent::LEFT_CONTROL:
1674
case SoKeyboardEvent::RIGHT_CONTROL:
1675
dict.setItem("Key", Py::String("CONTROL"));
1677
case SoKeyboardEvent::LEFT_ALT:
1678
case SoKeyboardEvent::RIGHT_ALT:
1679
dict.setItem("Key", Py::String("ALT"));
1681
case SoKeyboardEvent::HOME:
1682
dict.setItem("Key", Py::String("HOME"));
1684
case SoKeyboardEvent::LEFT_ARROW:
1685
dict.setItem("Key", Py::String("LEFT_ARROW"));
1687
case SoKeyboardEvent::UP_ARROW:
1688
dict.setItem("Key", Py::String("UP_ARROW"));
1690
case SoKeyboardEvent::RIGHT_ARROW:
1691
dict.setItem("Key", Py::String("RIGHT_ARROW"));
1693
case SoKeyboardEvent::DOWN_ARROW:
1694
dict.setItem("Key", Py::String("DOWN_ARROW"));
1696
case SoKeyboardEvent::PAGE_UP:
1697
dict.setItem("Key", Py::String("PAGE_UP"));
1699
case SoKeyboardEvent::PAGE_DOWN:
1700
dict.setItem("Key", Py::String("PAGE_DOWN"));
1702
case SoKeyboardEvent::END:
1703
dict.setItem("Key", Py::String("END"));
1705
case SoKeyboardEvent::PAD_ENTER:
1706
dict.setItem("Key", Py::String("PAD_ENTER"));
1708
case SoKeyboardEvent::PAD_F1:
1709
dict.setItem("Key", Py::String("PAD_F1"));
1711
case SoKeyboardEvent::PAD_F2:
1712
dict.setItem("Key", Py::String("PAD_F2"));
1714
case SoKeyboardEvent::PAD_F3:
1715
dict.setItem("Key", Py::String("PAD_F3"));
1717
case SoKeyboardEvent::PAD_F4:
1718
dict.setItem("Key", Py::String("PAD_F4"));
1720
case SoKeyboardEvent::PAD_0:
1721
dict.setItem("Key", Py::String("PAD_0"));
1723
case SoKeyboardEvent::PAD_1:
1724
dict.setItem("Key", Py::String("PAD_1"));
1726
case SoKeyboardEvent::PAD_2:
1727
dict.setItem("Key", Py::String("PAD_2"));
1729
case SoKeyboardEvent::PAD_3:
1730
dict.setItem("Key", Py::String("PAD_3"));
1732
case SoKeyboardEvent::PAD_4:
1733
dict.setItem("Key", Py::String("PAD_4"));
1735
case SoKeyboardEvent::PAD_5:
1736
dict.setItem("Key", Py::String("PAD_5"));
1738
case SoKeyboardEvent::PAD_6:
1739
dict.setItem("Key", Py::String("PAD_6"));
1741
case SoKeyboardEvent::PAD_7:
1742
dict.setItem("Key", Py::String("PAD_7"));
1744
case SoKeyboardEvent::PAD_8:
1745
dict.setItem("Key", Py::String("PAD_8"));
1747
case SoKeyboardEvent::PAD_9:
1748
dict.setItem("Key", Py::String("PAD_9"));
1750
case SoKeyboardEvent::PAD_ADD:
1751
dict.setItem("Key", Py::String("PAD_ADD"));
1753
case SoKeyboardEvent::PAD_SUBTRACT:
1754
dict.setItem("Key", Py::String("PAD_SUBTRACT"));
1756
case SoKeyboardEvent::PAD_MULTIPLY:
1757
dict.setItem("Key", Py::String("PAD_MULTIPLY"));
1759
case SoKeyboardEvent::PAD_DIVIDE:
1760
dict.setItem("Key", Py::String("PAD_DIVIDE"));
1762
case SoKeyboardEvent::PAD_TAB:
1763
dict.setItem("Key", Py::String("PAD_TAB"));
1765
case SoKeyboardEvent::PAD_DELETE:
1766
dict.setItem("Key", Py::String("PAD_DELETE"));
1768
case SoKeyboardEvent::F1:
1769
dict.setItem("Key", Py::String("F1"));
1771
case SoKeyboardEvent::F2:
1772
dict.setItem("Key", Py::String("F2"));
1774
case SoKeyboardEvent::F3:
1775
dict.setItem("Key", Py::String("F3"));
1777
case SoKeyboardEvent::F4:
1778
dict.setItem("Key", Py::String("F4"));
1780
case SoKeyboardEvent::F5:
1781
dict.setItem("Key", Py::String("F5"));
1783
case SoKeyboardEvent::F6:
1784
dict.setItem("Key", Py::String("F6"));
1786
case SoKeyboardEvent::F7:
1787
dict.setItem("Key", Py::String("F7"));
1789
case SoKeyboardEvent::F8:
1790
dict.setItem("Key", Py::String("F8"));
1792
case SoKeyboardEvent::F9:
1793
dict.setItem("Key", Py::String("F9"));
1795
case SoKeyboardEvent::F10:
1796
dict.setItem("Key", Py::String("F10"));
1798
case SoKeyboardEvent::F11:
1799
dict.setItem("Key", Py::String("F11"));
1801
case SoKeyboardEvent::F12:
1802
dict.setItem("Key", Py::String("F12"));
1804
case SoKeyboardEvent::BACKSPACE:
1805
dict.setItem("Key", Py::String("BACKSPACE"));
1807
case SoKeyboardEvent::TAB:
1808
dict.setItem("Key", Py::String("TAB"));
1810
case SoKeyboardEvent::RETURN:
1811
dict.setItem("Key", Py::String("RETURN"));
1813
case SoKeyboardEvent::PAUSE:
1814
dict.setItem("Key", Py::String("PAUSE"));
1816
case SoKeyboardEvent::SCROLL_LOCK:
1817
dict.setItem("Key", Py::String("SCROLL_LOCK"));
1819
case SoKeyboardEvent::ESCAPE:
1820
dict.setItem("Key", Py::String("ESCAPE"));
1822
case SoKeyboardEvent::KEY_DELETE:
1823
dict.setItem("Key", Py::String("DELETE"));
1825
case SoKeyboardEvent::PRINT:
1826
dict.setItem("Key", Py::String("PRINT"));
1828
case SoKeyboardEvent::INSERT:
1829
dict.setItem("Key", Py::String("INSERT"));
1831
case SoKeyboardEvent::NUM_LOCK:
1832
dict.setItem("Key", Py::String("NUM_LOCK"));
1834
case SoKeyboardEvent::CAPS_LOCK:
1835
dict.setItem("Key", Py::String("CAPS_LOCK"));
1837
case SoKeyboardEvent::SHIFT_LOCK:
1838
dict.setItem("Key", Py::String("SHIFT_LOCK"));
1840
case SoKeyboardEvent::SPACE:
1841
dict.setItem("Key", Py::String("SPACE"));
1843
case SoKeyboardEvent::APOSTROPHE:
1844
dict.setItem("Key", Py::String("APOSTROPHE"));
1846
case SoKeyboardEvent::COMMA:
1847
dict.setItem("Key", Py::String("COMMA"));
1849
case SoKeyboardEvent::MINUS:
1850
dict.setItem("Key", Py::String("MINUS"));
1852
case SoKeyboardEvent::PERIOD:
1853
dict.setItem("Key", Py::String("PERIOD"));
1855
case SoKeyboardEvent::SLASH:
1856
dict.setItem("Key", Py::String("SLASH"));
1858
case SoKeyboardEvent::SEMICOLON:
1859
dict.setItem("Key", Py::String("SEMICOLON"));
1861
case SoKeyboardEvent::EQUAL:
1862
dict.setItem("Key", Py::String("EQUAL"));
1864
case SoKeyboardEvent::BRACKETLEFT:
1865
dict.setItem("Key", Py::String("BRACKETLEFT"));
1867
case SoKeyboardEvent::BACKSLASH:
1868
dict.setItem("Key", Py::String("BACKSLASH"));
1870
case SoKeyboardEvent::BRACKETRIGHT:
1871
dict.setItem("Key", Py::String("BRACKETRIGHT"));
1873
case SoKeyboardEvent::GRAVE:
1874
dict.setItem("Key", Py::String("GRAVE"));
1877
dict.setItem("Key", Py::Char(ke->getPrintableCharacter()));
1881
if (e->isOfType(SoMouseButtonEvent::getClassTypeId())) {
1882
const auto mbe = static_cast<const SoMouseButtonEvent*>(e);
1884
switch (mbe->getButton()) {
1885
case SoMouseButtonEvent::BUTTON1:
1888
case SoMouseButtonEvent::BUTTON2:
1891
case SoMouseButtonEvent::BUTTON3:
1894
case SoMouseButtonEvent::BUTTON4:
1897
case SoMouseButtonEvent::BUTTON5:
1905
dict.setItem("Button", Py::String(button));
1907
if (e->isOfType(SoMouseWheelEvent::getClassTypeId())){
1908
const auto mwe = static_cast<const SoMouseWheelEvent*>(e);
1909
dict.setItem("Delta", Py::Long(mwe->getDelta()));
1911
if (e->isOfType(SoSpaceballButtonEvent::getClassTypeId())) {
1912
const auto sbe = static_cast<const SoSpaceballButtonEvent*>(e);
1914
switch (sbe->getButton()) {
1915
case SoSpaceballButtonEvent::BUTTON1:
1918
case SoSpaceballButtonEvent::BUTTON2:
1921
case SoSpaceballButtonEvent::BUTTON3:
1924
case SoSpaceballButtonEvent::BUTTON4:
1927
case SoSpaceballButtonEvent::BUTTON5:
1930
case SoSpaceballButtonEvent::BUTTON6:
1933
case SoSpaceballButtonEvent::BUTTON7:
1941
dict.setItem("Button", Py::String(button));
1943
if (e->isOfType(SoMotion3Event::getClassTypeId())) {
1944
const auto me = static_cast<const SoMotion3Event*>(e);
1945
const SbVec3f& m = me->getTranslation();
1946
const SbRotation& r = me->getRotation();
1948
mov.setItem(0, Py::Float(m[0]));
1949
mov.setItem(1, Py::Float(m[1]));
1950
mov.setItem(2, Py::Float(m[2]));
1951
dict.setItem("Translation", mov);
1953
rot.setItem(0, Py::Float(r.getValue()[0]));
1954
rot.setItem(1, Py::Float(r.getValue()[1]));
1955
rot.setItem(2, Py::Float(r.getValue()[2]));
1956
rot.setItem(3, Py::Float(r.getValue()[3]));
1957
dict.setItem("Rotation", rot);
1960
// now run the method
1961
Py::Callable method(reinterpret_cast<PyObject*>(ud));
1963
args.setItem(0, dict);
1966
catch (const Py::Exception& e) {
1967
Py::Object o = Py::type(e);
1970
Base::Console().Warning("%s\n", s.as_std_string("utf-8").c_str());
1973
Py::String s(o.repr());
1974
Base::Console().Warning("%s\n", s.as_std_string("utf-8").c_str());
1976
// Prints message to console window if we are in interactive mode
1981
Py::Object View3DInventorPy::addEventCallback(const Py::Tuple& args)
1985
if (!PyArg_ParseTuple(args.ptr(), "sO", &eventtype, &method))
1986
throw Py::Exception();
1988
if (PyCallable_Check(method) == 0) {
1989
throw Py::TypeError("object is not callable");
1991
SoType eventId = SoType::fromName(eventtype);
1992
if (eventId.isBad() || !eventId.isDerivedFrom(SoEvent::getClassTypeId())) {
1994
std::ostringstream s_out;
1995
s_out << eventtype << " is not a valid event type";
1996
throw Py::TypeError(s_out.str());
1999
getView3DIventorPtr()->getViewer()->addEventCallback(eventId, View3DInventorPy::eventCallback, method);
2000
callbacks.push_back(method);
2002
return Py::Callable(method, false);
2004
catch (const Py::Exception&) {
2009
Py::Object View3DInventorPy::removeEventCallback(const Py::Tuple& args)
2013
if (!PyArg_ParseTuple(args.ptr(), "sO", &eventtype, &method))
2014
throw Py::Exception();
2016
if (PyCallable_Check(method) == 0) {
2017
throw Py::RuntimeError("object is not callable");
2019
SoType eventId = SoType::fromName(eventtype);
2020
if (eventId.isBad() || !eventId.isDerivedFrom(SoEvent::getClassTypeId())) {
2022
std::ostringstream s_out;
2023
s_out << eventtype << " is not a valid event type";
2024
throw Py::TypeError(s_out.str());
2027
getView3DIventorPtr()->getViewer()->removeEventCallback(eventId, View3DInventorPy::eventCallback, method);
2028
callbacks.remove(method);
2032
catch (const Py::Exception&) {
2037
Py::Object View3DInventorPy::setAnnotation(const Py::Tuple& args)
2039
char *psAnnoName,*psBuffer;
2040
if (!PyArg_ParseTuple(args.ptr(), "ss", &psAnnoName, &psBuffer))
2041
throw Py::Exception();
2042
ViewProviderExtern* view = nullptr;
2044
view = new ViewProviderExtern();
2045
view->setModeByString(psAnnoName, psBuffer);
2047
catch (const Base::Exception& e) {
2049
throw Py::RuntimeError(e.what());
2052
getView3DIventorPtr()->getGuiDocument()->setAnnotationViewProvider(psAnnoName, view);
2056
Py::Object View3DInventorPy::removeAnnotation(const Py::Tuple& args)
2059
if (!PyArg_ParseTuple(args.ptr(), "s", &psAnnoName))
2060
throw Py::Exception();
2061
ViewProvider* view = nullptr;
2062
view = getView3DIventorPtr()->getGuiDocument()->getAnnotationViewProvider(psAnnoName);
2064
getView3DIventorPtr()->getGuiDocument()->removeAnnotationViewProvider(psAnnoName);
2069
std::ostringstream s_out;
2070
s_out << "No such annotation '" << psAnnoName << "'";
2071
throw Py::KeyError(s_out.str());
2075
Py::Object View3DInventorPy::getSceneGraph()
2078
SoNode* scene = getView3DIventorPtr()->getViewer()->getSceneGraph();
2079
PyObject* proxy = nullptr;
2080
proxy = Base::Interpreter().createSWIGPointerObj("pivy.coin", "SoSeparator *", static_cast<void*>(scene), 1);
2082
return Py::Object(proxy, true);
2084
catch (const Base::Exception& e) {
2085
throw Py::RuntimeError(e.what());
2089
Py::Object View3DInventorPy::getViewer()
2091
View3DInventorViewer* viewer = getView3DIventorPtr()->getViewer();
2092
return Py::Object(viewer->getPyObject(), true);
2095
void View3DInventorPy::eventCallbackPivy(void * ud, SoEventCallback * n)
2097
Base::PyGILStateLocker lock;
2098
const SoEvent* e = n->getEvent();
2099
std::string type = e->getTypeId().getName().getString();
2102
PyObject* proxy = nullptr;
2104
proxy = Base::Interpreter().createSWIGPointerObj("pivy.coin", type.c_str(), const_cast<void*>(static_cast<const void*>(e)), 0);
2105
// now run the method
2106
Py::Object event(proxy,true);
2107
Py::Callable method(static_cast<PyObject*>(ud));
2109
args.setItem(0, event);
2112
catch (const Base::Exception&) {
2115
catch (const Py::Exception& e) {
2116
Py::Object o = Py::type(e);
2119
Base::Console().Warning("%s\n", s.as_std_string("utf-8").c_str());
2122
Py::String s(o.repr());
2123
Base::Console().Warning("%s\n", s.as_std_string("utf-8").c_str());
2125
// Prints message to console window if we are in interactive mode
2130
void View3DInventorPy::eventCallbackPivyEx(void * ud, SoEventCallback * n)
2132
Base::PyGILStateLocker lock;
2133
std::string type = "SoEventCallback *";
2135
PyObject* proxy = nullptr;
2137
proxy = Base::Interpreter().createSWIGPointerObj("pivy.coin", type.c_str(), static_cast<void*>(n), 0);
2138
// now run the method
2139
Py::Object event(proxy,true);
2140
Py::Callable method(reinterpret_cast<PyObject*>(ud));
2142
args.setItem(0, event);
2145
catch (const Base::Exception&) {
2148
catch (const Py::Exception& e) {
2149
Py::Object o = Py::type(e);
2152
Base::Console().Warning("%s\n", s.as_std_string("utf-8").c_str());
2155
Py::String s(o.repr());
2156
Base::Console().Warning("%s\n", s.as_std_string("utf-8").c_str());
2158
// Prints message to console window if we are in interactive mode
2163
Py::Object View3DInventorPy::addEventCallbackPivy(const Py::Tuple& args)
2167
int ex=1; // if 1, use eventCallbackPivyEx
2168
if (!PyArg_ParseTuple(args.ptr(), "OO|i", &proxy, &method,&ex))
2169
throw Py::Exception();
2171
void* ptr = nullptr;
2173
Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoType *", proxy, &ptr, 0);
2175
catch (const Base::Exception& e) {
2176
throw Py::RuntimeError(e.what());
2179
auto eventId = static_cast<SoType*>(ptr);
2180
if (eventId->isBad() || !eventId->isDerivedFrom(SoEvent::getClassTypeId())) {
2182
std::ostringstream s_out;
2183
s_out << eventId->getName().getString() << "is not a valid event type";
2184
throw Py::TypeError(s_out.str());
2188
if (PyCallable_Check(method) == 0) {
2189
throw Py::TypeError("object is not callable");
2192
SoEventCallbackCB* callback = (ex == 1 ?
2193
View3DInventorPy::eventCallbackPivyEx :
2194
View3DInventorPy::eventCallbackPivy);
2195
getView3DIventorPtr()->getViewer()->addEventCallback(*eventId, callback, method);
2196
callbacks.push_back(method);
2198
return Py::Callable(method, false);
2200
catch (const Py::Exception&) {
2205
Py::Object View3DInventorPy::removeEventCallbackPivy(const Py::Tuple& args)
2209
int ex=1; // if 1, use eventCallbackPivyEx
2210
if (!PyArg_ParseTuple(args.ptr(), "OO|i", &proxy, &method,&ex))
2211
throw Py::Exception();
2213
void* ptr = nullptr;
2215
Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoType *", proxy, &ptr, 0);
2217
catch (const Base::Exception& e) {
2218
throw Py::RuntimeError(e.what());
2221
auto eventId = static_cast<SoType*>(ptr);
2222
if (eventId->isBad() || !eventId->isDerivedFrom(SoEvent::getClassTypeId())) {
2224
std::ostringstream s_out;
2225
s_out << eventId->getName().getString() << "is not a valid event type";
2226
throw Py::TypeError(s_out.str());
2230
if (PyCallable_Check(method) == 0) {
2231
throw Py::TypeError("object is not callable");
2234
SoEventCallbackCB* callback = (ex == 1 ?
2235
View3DInventorPy::eventCallbackPivyEx :
2236
View3DInventorPy::eventCallbackPivy);
2237
getView3DIventorPtr()->getViewer()->removeEventCallback(*eventId, callback, method);
2238
callbacks.remove(method);
2240
return Py::Callable(method, false);
2242
catch (const Py::Exception&) {
2247
Py::Object View3DInventorPy::setAxisCross(const Py::Tuple& args)
2250
if (!PyArg_ParseTuple(args.ptr(), "i", &ok))
2251
throw Py::Exception();
2252
getView3DIventorPtr()->getViewer()->setAxisCross(ok!=0);
2256
Py::Object View3DInventorPy::hasAxisCross()
2258
SbBool ok = getView3DIventorPtr()->getViewer()->hasAxisCross();
2259
return Py::Boolean(ok ? true : false);
2262
void View3DInventorPy::draggerCallback(void * ud, SoDragger* n)
2264
Base::PyGILStateLocker lock;
2265
PyObject* proxy = nullptr;
2267
proxy = Base::Interpreter().createSWIGPointerObj("pivy.coin", "SoDragger *", static_cast<void*>(n), 0);
2269
Py::Object dragger(proxy,true);
2270
Py::Callable method(reinterpret_cast<PyObject*>(ud));
2272
args.setItem(0, dragger);
2275
catch (const Base::Exception& e) {
2276
throw Py::RuntimeError(e.what());
2278
catch (const Py::Exception& e) {
2279
Py::Object o = Py::type(e);
2282
Base::Console().Warning("%s\n", s.as_std_string("utf-8").c_str());
2285
Py::String s(o.repr());
2286
Base::Console().Warning("%s\n", s.as_std_string("utf-8").c_str());
2288
// Prints message to console window if we are in interactive mode
2293
Py::Object View3DInventorPy::addDraggerCallback(const Py::Tuple& args)
2298
if (!PyArg_ParseTuple(args.ptr(), "OsO", &dragger,&type, &method))
2299
throw Py::Exception();
2302
//Check if dragger is a SoDragger object and cast
2303
void* ptr = nullptr;
2305
Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoDragger *", dragger, &ptr, 0);
2307
catch (const Base::Exception&) {
2308
throw Py::TypeError("The first argument must be of type SoDragger");
2310
auto drag = static_cast<SoDragger*>(ptr);
2312
//Check if method is callable
2313
if (PyCallable_Check(method) == 0) {
2314
throw Py::TypeError("the method is not callable");
2318
if (strcmp(type,"addFinishCallback")==0) {
2319
drag->addFinishCallback(draggerCallback,method);
2321
else if (strcmp(type,"addStartCallback")==0) {
2322
drag->addStartCallback(draggerCallback,method);
2324
else if (strcmp(type,"addMotionCallback")==0) {
2325
drag->addMotionCallback(draggerCallback,method);
2327
else if (strcmp(type,"addValueChangedCallback")==0) {
2328
drag->addValueChangedCallback(draggerCallback,method);
2332
std::ostringstream s_out;
2333
s_out << type << " is not a valid dragger callback type";
2334
throw Py::TypeError(s_out.str());
2337
callbacks.push_back(method);
2339
return Py::Callable(method, false);
2341
catch (const Py::Exception&) {
2346
Py::Object View3DInventorPy::removeDraggerCallback(const Py::Tuple& args)
2351
if (!PyArg_ParseTuple(args.ptr(), "OsO", &dragger, &type, &method))
2352
throw Py::Exception();
2354
//Check if dragger is a SoDragger object and cast
2355
void* ptr = nullptr;
2357
Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoDragger *", dragger, &ptr, 0);
2359
catch (const Base::Exception&) {
2360
throw Py::TypeError("The first argument must be of type SoDragger");
2363
auto drag = static_cast<SoDragger*>(ptr);
2365
if (strcmp(type, "addFinishCallback") == 0) {
2366
drag->removeFinishCallback(draggerCallback, method);
2368
else if (strcmp(type, "addStartCallback") == 0) {
2369
drag->removeStartCallback(draggerCallback, method);
2371
else if (strcmp(type, "addMotionCallback") == 0) {
2372
drag->removeMotionCallback(draggerCallback, method);
2374
else if (strcmp(type, "addValueChangedCallback") == 0) {
2375
drag->removeValueChangedCallback(draggerCallback, method);
2379
std::ostringstream s_out;
2380
s_out << type << " is not a valid dragger callback type";
2381
throw Py::TypeError(s_out.str());
2384
callbacks.remove(method);
2386
return Py::Callable(method, false);
2388
catch (const Py::Exception&) {
2393
Py::Object View3DInventorPy::getViewProvidersOfType(const Py::Tuple& args)
2396
if (!PyArg_ParseTuple(args.ptr(), "s", &name))
2397
throw Py::Exception();
2399
std::vector<ViewProvider*> vps = getView3DIventorPtr()->getViewer()->getViewProvidersOfType(Base::Type::fromName(name));
2401
for (const auto & vp : vps) {
2402
list.append(Py::asObject(vp->getPyObject()));
2408
Py::Object View3DInventorPy::redraw()
2410
getView3DIventorPtr()->getViewer()->redraw();
2414
Py::Object View3DInventorPy::setName(const Py::Tuple& args)
2417
if (!PyArg_ParseTuple(args.ptr(), "s", &buffer))
2418
throw Py::Exception();
2421
getView3DIventorPtr()->setWindowTitle(QString::fromUtf8(buffer));
2424
catch (const Base::Exception& e) {
2425
throw Py::RuntimeError(e.what());
2427
catch (const std::exception& e) {
2428
throw Py::RuntimeError(e.what());
2431
throw Py::RuntimeError("Unknown C++ exception");
2435
Py::Object View3DInventorPy::toggleClippingPlane(const Py::Tuple& args, const Py::Dict& kwds)
2437
static const std::array<const char *, 5> keywords {"toggle", "beforeEditing", "noManip", "pla", nullptr};
2439
PyObject *beforeEditing = Py_False;
2440
PyObject *noManip = Py_True;
2441
PyObject *pyPla = Py_None;
2442
if (!Base::Wrapped_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "|iO!O!O!", keywords,
2443
&toggle, &PyBool_Type, &beforeEditing, &PyBool_Type, &noManip,
2444
&Base::PlacementPy::Type, &pyPla)) {
2445
throw Py::Exception();
2448
Base::Placement pla;
2450
pla = *static_cast<Base::PlacementPy*>(pyPla)->getPlacementPtr();
2451
getView3DIventorPtr()->getViewer()->toggleClippingPlane(toggle, Base::asBoolean(beforeEditing),
2452
Base::asBoolean(noManip), pla);
2456
Py::Object View3DInventorPy::hasClippingPlane()
2458
return Py::Boolean(getView3DIventorPtr()->getViewer()->hasClippingPlane());
2461
Py::Object View3DInventorPy::graphicsView()
2464
wrap.loadWidgetsModule();
2465
return wrap.fromQWidget(getView3DIventorPtr()->getViewer(), "QGraphicsView");
2468
Py::Object View3DInventorPy::setCornerCrossVisible(const Py::Tuple& args)
2471
if (!PyArg_ParseTuple(args.ptr(), "i", &ok))
2472
throw Py::Exception();
2473
getView3DIventorPtr()->getViewer()->setFeedbackVisibility(ok!=0);
2474
getView3DIventorPtr()->getViewer()->redraw(); // added because isViewing() returns False when focus is in Python Console
2478
Py::Object View3DInventorPy::isCornerCrossVisible()
2480
bool ok = getView3DIventorPtr()->getViewer()->isFeedbackVisible();
2481
return Py::Boolean(ok ? true : false);
2484
Py::Object View3DInventorPy::setCornerCrossSize(const Py::Tuple& args)
2487
if (!PyArg_ParseTuple(args.ptr(), "i", &size))
2488
throw Py::Exception();
2489
getView3DIventorPtr()->getViewer()->setFeedbackSize(size);
2490
getView3DIventorPtr()->getViewer()->redraw(); // added because isViewing() returns False when focus is in Python Console
2494
Py::Object View3DInventorPy::getCornerCrossSize()
2496
int size = getView3DIventorPtr()->getViewer()->getFeedbackSize();
2497
return Py::Int(size);
2500
Py::Object View3DInventorPy::cast_to_base()
2502
return Gui::MDIViewPy::create(getView3DIventorPtr());