1 /*
2  * Copyright (c) 2002-2007 Systems in Motion
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /* header include needed to let nodekit extensions find the SbTime header */
18 %{
19 #include <Inventor/SbTime.h>
20 
21 #if (PY_VERSION_HEX < 0x02050000)
22 /* Py_ssize_t needed for Python 2.5 compatibility, but isn't defined
23  * in earlier Python versions. */
24 typedef int Py_ssize_t;
25 #endif
26 
27 #if PY_MAJOR_VERSION >= 3
28   #define IS_PY3K
29 #endif
30 
31 /* a casting helper function */
32 SWIGEXPORT PyObject *
cast(PyObject * self,PyObject * args)33 cast(PyObject * self, PyObject * args)
34 {
35   swig_type_info * swig_type = 0;
36   void * cast_obj = 0;
37   char * type_name, * ptr_type;
38   int type_len;
39   PyObject * obj = 0;
40 
41   if (!PyArg_ParseTuple(args, "Os#:cast", &obj, &type_name, &type_len)) {
42     SWIG_fail;
43   }
44 
45   /*
46    * add a pointer sign to the string coming from the interpreter
47    * e.g. "SoSeparator" becomes "SoSeparator *" - so that SWIG_TypeQuery()
48    * can do its job.
49    */
50   if (!(ptr_type = (char*)malloc(type_len+3))) { SWIG_fail; }
51 
52   memset(ptr_type, 0, type_len+3);
53   strncpy(ptr_type, type_name, type_len);
54   strcat(ptr_type, " *");
55 
56   if (!(swig_type = SWIG_TypeQuery(ptr_type))) {
57     /* the britney maneuver: "baby one more time" by prefixing 'So' */
58     char * cast_name = (char*)malloc(type_len + 5);
59     memset(cast_name, 0, type_len + 5);
60     cast_name[0] = 'S'; cast_name[1] = 'o';
61     strncpy(cast_name+2, ptr_type, type_len+2);
62 
63     if (!(swig_type = SWIG_TypeQuery(cast_name))) {
64       free(cast_name); free(ptr_type);
65       SWIG_fail;
66     }
67 
68     free(cast_name);
69   }
70 
71   free(ptr_type);
72 
73   SWIG_ConvertPtr(obj, (void**)&cast_obj, NULL, SWIG_POINTER_EXCEPTION | 0);
74   if (SWIG_arg_fail(1)) { SWIG_fail; }
75 
76   return SWIG_NewPointerObj((void*)cast_obj, swig_type, 0);
77   fail:
78   return NULL;
79 }
80 
81 /* autocasting helper function for SoBase */
82 SWIGEXPORT PyObject *
autocast_base(SoBase * base)83 autocast_base(SoBase * base)
84 {
85   PyObject * result = NULL;
86 
87   /* autocast the result to the corresponding type */
88   if (base && base->isOfType(SoFieldContainer::getClassTypeId())) {
89     PyObject * cast_args = NULL;
90     PyObject * obj = NULL;
91     SoType type = base->getTypeId();
92 
93     /* in case of a non built-in type get the closest built-in parent */
94     while (!(type.isBad() || result)) {
95       obj = SWIG_NewPointerObj((void*)base, SWIGTYPE_p_SoBase, 0);
96       cast_args = Py_BuildValue("(Os)", obj, type.getName().getString());
97 
98       result = cast(NULL, cast_args);
99 
100       Py_DECREF(cast_args);
101       Py_DECREF(obj);
102 
103       if (!result) { type = type.getParent(); }
104     }
105   }
106 
107   if (!result) {
108     Py_INCREF(Py_None);
109     result = Py_None;
110   }
111 
112   return result;
113 }
114 
115 /* autocasting helper function for SoPath */
116 SWIGEXPORT PyObject *
autocast_path(SoPath * path)117 autocast_path(SoPath * path)
118 {
119   PyObject * result = NULL;
120 
121   /* autocast the result to the corresponding type */
122   if (path) {
123     PyObject * cast_args = NULL;
124     PyObject * obj = NULL;
125     SoType type = path->getTypeId();
126 
127     /* in case of a non built-in type get the closest built-in parent */
128     while (!(type.isBad() || result)) {
129       obj = SWIG_NewPointerObj((void*)path, SWIGTYPE_p_SoPath, 0);
130       cast_args = Py_BuildValue("(Os)", obj, type.getName().getString());
131 
132       result = cast(NULL, cast_args);
133 
134       Py_DECREF(cast_args);
135       Py_DECREF(obj);
136 
137       if (!result) { type = type.getParent(); }
138     }
139   }
140 
141   if (!result) {
142     Py_INCREF(Py_None);
143     result = Py_None;
144   }
145 
146   return result;
147 }
148 
149 /* autocasting helper function for SoField */
150 SWIGEXPORT PyObject *
autocast_field(SoField * field)151 autocast_field(SoField * field)
152 {
153   PyObject * result = NULL;
154 
155   /* autocast the result to the corresponding type */
156   if (field) {
157     PyObject * cast_args = NULL;
158     PyObject * obj = NULL;
159     SoType type = field->getTypeId();
160 
161     /* in case of a non built-in type get the closest built-in parent */
162     while (!(type.isBad() || result)) {
163       obj = SWIG_NewPointerObj((void*)field, SWIGTYPE_p_SoField, 0);
164       cast_args = Py_BuildValue("(Os)", obj, type.getName().getString());
165 
166       result = cast(NULL, cast_args);
167 
168       Py_DECREF(cast_args);
169       Py_DECREF(obj);
170 
171       if (!result) { type = type.getParent(); }
172     }
173   }
174 
175   if (!result) {
176     Py_INCREF(Py_None);
177     result = Py_None;
178   }
179 
180   return result;
181 }
182 
183 /* autocasting helper function for SoEvent */
184 SWIGEXPORT PyObject *
autocast_event(SoEvent * event)185 autocast_event(SoEvent * event)
186 {
187   PyObject * result = NULL;
188 
189   /* autocast the result to the corresponding type */
190   if (event) {
191     PyObject * cast_args = NULL;
192     PyObject * obj = NULL;
193     SoType type = event->getTypeId();
194 
195     /* in case of a non built-in type get the closest built-in parent */
196     while (!(type.isBad() || result)) {
197       obj = SWIG_NewPointerObj((void*)event, SWIGTYPE_p_SoEvent, 0);
198       cast_args = Py_BuildValue("(Os)", obj, type.getName().getString());
199 
200       result = cast(NULL, cast_args);
201 
202       Py_DECREF(cast_args);
203       Py_DECREF(obj);
204 
205       if (!result) { type = type.getParent(); }
206     }
207   }
208 
209   if (!result) {
210     Py_INCREF(Py_None);
211     result = Py_None;
212   }
213 
214   return result;
215 }
216 %}
217 
218 /* typemaps for autocasting types through the Inventor type system */
219 %typemap(out) SoBase * {
220   $result = autocast_base($1);
221 }
222 
223 %typemap(out) SoFieldContainer * {
224   $result = autocast_base($1);
225 }
226 
227 %typemap(out) SoNode * {
228   $result = autocast_base($1);
229 }
230 
231 %typemap(out) SoPath * {
232   $result = autocast_path($1);
233 }
234 
235 %typemap(out) SoEngine * {
236   $result = autocast_base($1);
237 }
238 
239 %typemap(out) SoField * {
240   $result = autocast_field($1);
241 }
242 
243 %typemap(out) SoEvent * {
244   $result = autocast_event($1);
245 }
246 
247 %native(cast) PyObject * cast(PyObject * self, PyObject * args);
248 
249 /**
250  * SWIG - interface includes and general typemap definitions
251  **/
252 
253 %include "typemaps.i"
254 %include "cpointer.i"
255 
256 %pointer_class(char, charp);
257 %pointer_class(int, intp);
258 %pointer_class(long, longp);
259 %pointer_class(float, floatp);
260 %pointer_class(double, doublep);
261 
262 /* if SWIG determines the class abstract it doesn't generate
263  * constructors of any kind. the following %feature
264  * declarations take care about this for the classes we still
265  * want a constructor for.
266  */
267 %feature("notabstract") SoBoolOperation;
268 %feature("notabstract") SoComposeRotation;
269 %feature("notabstract") SoComposeVec3f;
270 %feature("notabstract") SoDecomposeVec3f;
271 
272 %rename(output) print(FILE * fp) const;
273 %rename(output) print(FILE * const fp) const;
274 %rename(output) print(FILE * const file = stdout) const;
275 %rename(srcFrom) from;
276 %rename(destTo) to;
277 
278 /* generic typemaps to allow using python types instead of instances
279  * within the python interpreter
280  */
281 %typemap(in) int32_t = int;
282 %typemap(out) int32_t = int;
283 %typemap(typecheck) int32_t = int;
284 
285 %typemap(in) uint32_t = unsigned int;
286 %typemap(out) uint32_t = unsigned int;
287 %typemap(typecheck) uint32_t = unsigned int;
288 
289 %typemap(typecheck) SbName & {
290   void *ptr = NULL;
291   $1 = 1;
292 #ifdef PY_2
293   if (!PyString_Check($input) &&
294      (SWIG_ConvertPtr($input, (void**)(&ptr), SWIGTYPE_p_SbName, 0) == -1))
295 #else
296   if (!PyBytes_Check($input) &&
297     !PyUnicode_Check($input) &&
298     (SWIG_ConvertPtr($input, (void**)(&ptr), $descriptor(SbName *), 0) == -1))
299 #endif
300   {
301     $1 = 0;
302   }
303 }
304 
305 %typemap(in) SbName & {
306 #ifdef PY_2
307   if (PyString_Check($input))
308   {
309     $1 = new SbName(PyString_AsString($input));
310   }
311 #else
312   if (PyBytes_Check($input))
313   {
314     $1 = new SbName(PyBytes_AsString($input));
315   }
316   else if  (PyUnicode_Check($input)){
317     $1 = new SbName(PyBytes_AsString(PyUnicode_AsEncodedString($input, "utf-8", "Error ~")));
318   }
319 #endif
320    else {
321     SbName * tmp = NULL;
322     $1 = new SbName;
323 #ifdef PY_2
324     SWIG_ConvertPtr($input, (void**)&tmp, SWIGTYPE_p_SbName, 1);
325 #else
326     SWIG_ConvertPtr($input, (void**)&tmp,  $descriptor(SbName *), 1);
327 #endif
328     *$1 = *tmp;
329   }
330 }
331 
332 %typemap(freearg) SbName & {
333   if ($1) { delete $1; }
334 }
335 
336 %typemap(typecheck) SbName {
337   void *ptr = NULL;
338   $1 = 1;
339 #ifdef PY_2
340   if (!PyString_Check($input) &&
341       !PyUnicode_Check($input) &&
342      (SWIG_ConvertPtr($input, (void**)(&ptr), SWIGTYPE_p_SbName, 0) == -1))
343 #else
344   // http://stackoverflow.com/questions/2807887/cs-char-by-swig-got-problem-in-python-3-0
345   if (!PyBytes_Check($input) &&
346      !PyUnicode_Check($input) &&
347      (SWIG_ConvertPtr($input, (void**)(&ptr), $descriptor(SbString *), 0) == -1))
348 #endif
349   {
350     $1 = 0;
351   }
352 }
353 
354 %typemap(in) SbName {
355 #ifdef PY_2
356   if (PyString_Check($input)){
357     $1 = SbName(PyString_AsString($input));
358   }
359 #else
360   if (PyBytes_Check($input)){
361     $1 = SbName(PyBytes_AsString($input));
362   }
363   else if  (PyUnicode_Check($input)){
364     $1 = SbName(PyBytes_AsString(PyUnicode_AsEncodedString($input, "utf-8", "Error ~")));
365   }
366 #endif
367   else {
368     SbName * namePtr;
369 #ifdef PY_2
370     SWIG_ConvertPtr($input, (void**)&namePtr, SWIGTYPE_p_SbName, 1);
371 #else
372     SWIG_ConvertPtr($input, (void**)&namePtr, $descriptor(SbName *), 1);
373 #endif
374     $1 = *namePtr;
375   }
376 }
377 
378 %typemap(typecheck) SbString & {
379   void *ptr = NULL;
380   $1 = 1;
381 #ifdef PY_2
382   if (!PyString_Check($input) &&
383      (SWIG_ConvertPtr($input, (void**)(&ptr), SWIGTYPE_p_SbString, 0) == -1))
384 #else
385   if (!PyBytes_Check($input) &&
386       !PyUnicode_Check($input) &&
387      (SWIG_ConvertPtr($input, (void**)(&ptr), $descriptor(SbString *), 0) == -1))
388 #endif
389   {
390     $1 = 0;
391   }
392 }
393 
394 %typemap(in) SbString & {
395 #ifdef PY_2
396   if (PyString_Check($input))
397   {
398     $1 = new SbString(PyString_AsString($input));
399   }
400 #else
401   if (PyBytes_Check($input))
402   {
403     $1 = new SbString(PyBytes_AsString($input));
404   }
405   else if  (PyUnicode_Check($input)){
406      $1 = new SbString(PyBytes_AsString(PyUnicode_AsEncodedString($input, "utf-8", "Error ~")));
407   }
408 #endif
409   else {
410     SbString * tmp = NULL;
411     $1 = new SbString;
412 #ifdef PY_2
413     SWIG_ConvertPtr($input, (void**)&tmp, SWIGTYPE_p_SbString, 1);
414 #else
415     SWIG_ConvertPtr($input, (void**)&tmp, $descriptor(SbString *), 1);
416 #endif
417     *$1 = *tmp;
418   }
419 }
420 
421 %typemap(freearg) SbString & {
422   if ($1) { delete $1; }
423 }
424 
425 %typemap(typecheck) SbTime & {
426   void *ptr = NULL;
427   $1 = 1;
428 #ifdef PY_2
429   if (!PyFloat_Check($input) && (SWIG_ConvertPtr($input, (void**)(&ptr), SWIGTYPE_p_SbTime, 0) == -1))
430 #else
431   if (!PyFloat_Check($input) && (SWIG_ConvertPtr($input, (void**)(&ptr), $descriptor(SbTime *), 0) == -1))
432 #endif
433   {
434     $1 = 0;
435   }
436 }
437 
438 %typemap(in) SbTime & {
439   if (PyFloat_Check($input)) {
440     $1 = new SbTime(PyFloat_AsDouble($input));
441   } else {
442     SbTime * tmp = NULL;
443     $1 = new SbTime;
444 #ifdef PY_2
445     SWIG_ConvertPtr($input, (void**)&tmp, SWIGTYPE_p_SbTime, 1);
446 #else
447     SWIG_ConvertPtr($input, (void**)&tmp, $descriptor(SbTime *), 1);
448 #endif
449     *$1 = *tmp;
450   }
451 }
452 
453 %typemap(freearg) SbTime & {
454   if ($1) { delete $1; }
455 }
456 
457 %typemap(in) FILE * {
458 #ifdef PY_2
459   if (PyFile_Check($input)) {
460     $1 = PyFile_AsFile($input);
461   }
462 #else
463   if (PyObject_IsInstance($input, PyIOBase_TypeObj)) {
464     int fd = PyObject_AsFileDescriptor($input);
465     $1 = fdopen(fd, "w");
466   }
467 #endif
468   else {
469     PyErr_SetString(PyExc_TypeError, "expected a file object.");
470   }
471 }
472 
473 %include Inventor/events/SoEvent.h
474 %include Inventor/fields/SoField.h
475 %include Inventor/SbString.h
476 
477 /* some ignores for missing COIN_DLL_API specifications */
478 %ignore cc_rbptree_init;
479 %ignore cc_rbptree_clean;
480 %ignore cc_rbptree_insert;
481 %ignore cc_rbptree_remove;
482 %ignore cc_rbptree_size;
483 %ignore cc_rbptree_traverse;
484 %ignore cc_rbptree_debug;
485 %ignore so_plane_data::so_plane_data;
486 %ignore SoGLRenderCache::SoGLRenderCache;
487 %ignore SoGLRenderCache::open;
488 %ignore SoGLRenderCache::close;
489 %ignore SoGLRenderCache::call;
490 %ignore SoGLRenderCache::getCacheContext;
491 %ignore SoGLRenderCache::getPreLazyState;
492 %ignore SoGLRenderCache::getPostLazyState;
493 %ignore SoGLCacheList::SoGLCacheList;
494 %ignore SoGLCacheList::~SoGLCacheList;
495 %ignore SoGLCacheList::call;
496 %ignore SoGLCacheList::open;
497 %ignore SoGLCacheList::close;
498 %ignore SoGLCacheList::invalidateAll;
499 %ignore SoNormalBundle::SoNormalBundle;
500 %ignore SoNormalBundle::~SoNormalBundle;
501 %ignore SoNormalBundle::shouldGenerate;
502 %ignore SoNormalBundle::initGenerator;
503 %ignore SoNormalBundle::beginPolygon;
504 %ignore SoNormalBundle::polygonVertex;
505 %ignore SoNormalBundle::endPolygon;
506 %ignore SoNormalBundle::triangle;
507 %ignore SoNormalBundle::generate;
508 %ignore SoNormalBundle::getGeneratedNormals;
509 %ignore SoNormalBundle::getNumGeneratedNormals;
510 %ignore SoNormalBundle::set;
511 %ignore SoNormalBundle::get;
512 %ignore SoNormalBundle::send;
513 
514 %ignore SoMultiTextureCoordinateElement::setFunction;
515 %ignore SoGLMultiTextureCoordinateElement::setTexGen;
516