b0b43acb8daaebe23ab7114f53f65db117fd8773
[blender.git] / source / blender / freestyle / intern / python / BPy_Convert.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 /** \file source/blender/freestyle/intern/python/BPy_Convert.cpp
22  *  \ingroup freestyle
23  */
24
25 #include "BPy_Convert.h"
26
27 #include "BPy_BBox.h"
28 #include "BPy_FrsMaterial.h"
29 #include "BPy_Id.h"
30 #include "BPy_IntegrationType.h"
31 #include "BPy_Interface0D.h"
32 #include "Interface0D/BPy_CurvePoint.h"
33 #include "Interface0D/CurvePoint/BPy_StrokeVertex.h"
34 #include "Interface0D/BPy_SVertex.h"
35 #include "Interface0D/BPy_ViewVertex.h"
36 #include "Interface0D/ViewVertex/BPy_NonTVertex.h"
37 #include "Interface0D/ViewVertex/BPy_TVertex.h"
38 #include "BPy_Interface1D.h"
39 #include "Interface1D/BPy_FEdge.h"
40 #include "Interface1D/BPy_Stroke.h"
41 #include "Interface1D/BPy_ViewEdge.h"
42 #include "Interface1D/Curve/BPy_Chain.h"
43 #include "Interface1D/FEdge/BPy_FEdgeSharp.h"
44 #include "Interface1D/FEdge/BPy_FEdgeSmooth.h"
45 #include "BPy_Nature.h"
46 #include "BPy_MediumType.h"
47 #include "BPy_SShape.h"
48 #include "BPy_StrokeAttribute.h"
49 #include "BPy_ViewShape.h"
50
51 #include "Iterator/BPy_AdjacencyIterator.h"
52 #include "Iterator/BPy_ChainPredicateIterator.h"
53 #include "Iterator/BPy_ChainSilhouetteIterator.h"
54 #include "Iterator/BPy_ChainingIterator.h"
55 #include "Iterator/BPy_CurvePointIterator.h"
56 #include "Iterator/BPy_Interface0DIterator.h"
57 #include "Iterator/BPy_SVertexIterator.h"
58 #include "Iterator/BPy_StrokeVertexIterator.h"
59 #include "Iterator/BPy_ViewEdgeIterator.h"
60 #include "Iterator/BPy_orientedViewEdgeIterator.h"
61
62 #include "../stroke/StrokeRep.h"
63
64 #ifdef __cplusplus
65 extern "C" {
66 #endif
67
68 ///////////////////////////////////////////////////////////////////////////////////////////
69
70 //==============================
71 // C++ => Python
72 //==============================
73
74 PyObject *PyBool_from_bool(bool b)
75 {
76         return PyBool_FromLong(b ? 1 : 0);
77 }
78
79 PyObject *Vector_from_Vec2f(Vec2f& vec)
80 {
81         float vec_data[2]; // because vec->_coord is protected
82         vec_data[0] = vec.x();
83         vec_data[1] = vec.y();
84         return Vector_CreatePyObject(vec_data, 2, NULL);
85 }
86
87 PyObject *Vector_from_Vec3f(Vec3f& vec)
88 {
89         float vec_data[3]; // because vec->_coord is protected
90         vec_data[0] = vec.x();
91         vec_data[1] = vec.y();
92         vec_data[2] = vec.z(); 
93         return Vector_CreatePyObject(vec_data, 3, NULL);
94 }
95
96 PyObject *Vector_from_Vec3r(Vec3r& vec)
97 {
98         float vec_data[3]; // because vec->_coord is protected
99         vec_data[0] = vec.x();
100         vec_data[1] = vec.y();
101         vec_data[2] = vec.z();
102         return Vector_CreatePyObject(vec_data, 3, NULL);
103 }
104
105 PyObject *BPy_Id_from_Id(Id& id)
106 {
107         PyObject *py_id = Id_Type.tp_new(&Id_Type, 0, 0);
108         ((BPy_Id *)py_id)->id = new Id(id.getFirst(), id.getSecond());
109         return py_id;
110 }
111
112 PyObject *Any_BPy_Interface0D_from_Interface0D(Interface0D& if0D)
113 {
114         if (typeid(if0D) == typeid(CurvePoint)) {
115                 return BPy_CurvePoint_from_CurvePoint(dynamic_cast<CurvePoint&>(if0D));
116         }
117         else if (typeid(if0D) == typeid(StrokeVertex)) {
118                 return BPy_StrokeVertex_from_StrokeVertex(dynamic_cast<StrokeVertex&>(if0D));
119         }
120         else if (typeid(if0D) == typeid(SVertex)) {
121                 return BPy_SVertex_from_SVertex(dynamic_cast<SVertex&>(if0D));
122         }
123         else if (typeid(if0D) == typeid(ViewVertex)) {
124                 return BPy_ViewVertex_from_ViewVertex(dynamic_cast<ViewVertex&>(if0D));
125         }
126         else if (typeid(if0D) == typeid(NonTVertex)) {
127                 return BPy_NonTVertex_from_NonTVertex(dynamic_cast<NonTVertex&>(if0D));
128         }
129         else if (typeid(if0D) == typeid(TVertex)) {
130                 return BPy_TVertex_from_TVertex(dynamic_cast<TVertex&>(if0D));
131         }
132         else if (typeid(if0D) == typeid(Interface0D)) {
133                 return BPy_Interface0D_from_Interface0D(if0D);
134         }
135         string msg("unexpected type: " + if0D.getExactTypeName());
136         PyErr_SetString(PyExc_TypeError, msg.c_str());
137         return NULL;
138 }
139
140 PyObject *Any_BPy_Interface1D_from_Interface1D(Interface1D& if1D)
141 {
142         if (typeid(if1D) == typeid(ViewEdge)) {
143                 return BPy_ViewEdge_from_ViewEdge(dynamic_cast<ViewEdge&>(if1D));
144         }
145         else if (typeid(if1D) == typeid(Chain)) {
146                 return BPy_Chain_from_Chain(dynamic_cast<Chain&>(if1D));
147         }
148         else if (typeid(if1D) == typeid(Stroke)) {
149                 return BPy_Stroke_from_Stroke(dynamic_cast<Stroke&>(if1D));
150         }
151         else if (typeid(if1D) == typeid(FEdgeSharp)) {
152                 return BPy_FEdgeSharp_from_FEdgeSharp(dynamic_cast<FEdgeSharp&>(if1D));
153         }
154         else if (typeid(if1D) == typeid(FEdgeSmooth)) {
155                 return BPy_FEdgeSmooth_from_FEdgeSmooth(dynamic_cast<FEdgeSmooth&>(if1D));
156         }
157         else if (typeid(if1D) == typeid(FEdge)) {
158                 return BPy_FEdge_from_FEdge(dynamic_cast<FEdge&>(if1D));
159         }
160         else if (typeid(if1D) == typeid(Interface1D)) {
161                 return BPy_Interface1D_from_Interface1D(if1D);
162         }
163         string msg("unexpected type: " + if1D.getExactTypeName());
164         PyErr_SetString(PyExc_TypeError, msg.c_str());
165         return NULL;
166 }
167
168 PyObject *Any_BPy_FEdge_from_FEdge(FEdge& fe)
169 {
170         if (typeid(fe) == typeid(FEdgeSharp)) {
171                 return BPy_FEdgeSharp_from_FEdgeSharp(dynamic_cast<FEdgeSharp&>(fe));
172         }
173         else if (typeid(fe) == typeid(FEdgeSmooth)) {
174                 return BPy_FEdgeSmooth_from_FEdgeSmooth(dynamic_cast<FEdgeSmooth&>(fe));
175         }
176         else if (typeid(fe) == typeid(FEdge)) {
177                 return BPy_FEdge_from_FEdge(fe);
178         }
179         string msg("unexpected type: " + fe.getExactTypeName());
180         PyErr_SetString(PyExc_TypeError, msg.c_str());
181         return NULL;
182 }
183
184 PyObject *Any_BPy_ViewVertex_from_ViewVertex(ViewVertex& vv)
185 {
186         if (typeid(vv) == typeid(NonTVertex)) {
187                 return BPy_NonTVertex_from_NonTVertex(dynamic_cast<NonTVertex&>(vv));
188         }
189         else if (typeid(vv) == typeid(TVertex)) {
190                 return BPy_TVertex_from_TVertex(dynamic_cast<TVertex&>(vv));
191         }
192         else if (typeid(vv) == typeid(ViewVertex)) {
193                 return BPy_ViewVertex_from_ViewVertex(vv);
194         }
195         string msg("unexpected type: " + vv.getExactTypeName());
196         PyErr_SetString(PyExc_TypeError, msg.c_str());
197         return NULL;
198 }
199
200 PyObject *BPy_Interface0D_from_Interface0D(Interface0D& if0D)
201 {
202         PyObject *py_if0D =  Interface0D_Type.tp_new(&Interface0D_Type, 0, 0);
203         ((BPy_Interface0D *)py_if0D)->if0D = &if0D;
204         ((BPy_Interface0D *)py_if0D)->borrowed = true;
205         return py_if0D;
206 }
207
208 PyObject *BPy_Interface1D_from_Interface1D(Interface1D& if1D)
209 {
210         PyObject *py_if1D =  Interface1D_Type.tp_new(&Interface1D_Type, 0, 0);
211         ((BPy_Interface1D *)py_if1D)->if1D = &if1D;
212         ((BPy_Interface1D *)py_if1D)->borrowed = true;
213         return py_if1D;
214 }
215
216 PyObject *BPy_SVertex_from_SVertex(SVertex& sv)
217 {
218         PyObject *py_sv = SVertex_Type.tp_new(&SVertex_Type, 0, 0);
219         ((BPy_SVertex *)py_sv)->sv = &sv;
220         ((BPy_SVertex *)py_sv)->py_if0D.if0D = ((BPy_SVertex *)py_sv)->sv;
221         ((BPy_SVertex *)py_sv)->py_if0D.borrowed = true;
222         return py_sv;
223 }
224
225 PyObject *BPy_FEdgeSharp_from_FEdgeSharp(FEdgeSharp& fes)
226 {
227         PyObject *py_fe = FEdgeSharp_Type.tp_new(&FEdgeSharp_Type, 0, 0);
228         ((BPy_FEdgeSharp *)py_fe)->fes = &fes;
229         ((BPy_FEdgeSharp *)py_fe)->py_fe.fe = ((BPy_FEdgeSharp *)py_fe)->fes;
230         ((BPy_FEdgeSharp *)py_fe)->py_fe.py_if1D.if1D = ((BPy_FEdgeSharp *)py_fe)->fes;
231         ((BPy_FEdgeSharp *)py_fe)->py_fe.py_if1D.borrowed = true;
232         return py_fe;
233 }
234
235 PyObject *BPy_FEdgeSmooth_from_FEdgeSmooth(FEdgeSmooth& fes)
236 {
237         PyObject *py_fe = FEdgeSmooth_Type.tp_new(&FEdgeSmooth_Type, 0, 0);
238         ((BPy_FEdgeSmooth *)py_fe)->fes = &fes;
239         ((BPy_FEdgeSmooth *)py_fe)->py_fe.fe = ((BPy_FEdgeSmooth *)py_fe)->fes;
240         ((BPy_FEdgeSmooth *)py_fe)->py_fe.py_if1D.if1D = ((BPy_FEdgeSmooth *)py_fe)->fes;
241         ((BPy_FEdgeSmooth *)py_fe)->py_fe.py_if1D.borrowed = true;
242         return py_fe;
243 }
244
245 PyObject *BPy_FEdge_from_FEdge(FEdge& fe)
246 {
247         PyObject *py_fe = FEdge_Type.tp_new(&FEdge_Type, 0, 0);
248         ((BPy_FEdge *)py_fe)->fe = &fe;
249         ((BPy_FEdge *)py_fe)->py_if1D.if1D = ((BPy_FEdge *)py_fe)->fe;
250         ((BPy_FEdge *)py_fe)->py_if1D.borrowed = true;
251         return py_fe;
252 }
253
254 PyObject *BPy_Nature_from_Nature(unsigned short n)
255 {
256         PyObject *args = PyTuple_New(1);
257         PyTuple_SET_ITEM(args, 0, PyLong_FromLong(n));
258         PyObject *py_n =  Nature_Type.tp_new(&Nature_Type, args, NULL);
259         Py_DECREF(args);
260         return py_n;
261 }
262
263 PyObject *BPy_Stroke_from_Stroke(Stroke& s)
264 {
265         PyObject *py_s = Stroke_Type.tp_new(&Stroke_Type, 0, 0);
266         ((BPy_Stroke *)py_s)->s = &s;
267         ((BPy_Stroke *)py_s)->py_if1D.if1D = ((BPy_Stroke *)py_s)->s;
268         ((BPy_Stroke *)py_s)->py_if1D.borrowed = true;
269         return py_s;
270 }
271
272 PyObject *BPy_StrokeAttribute_from_StrokeAttribute(StrokeAttribute& sa)
273 {
274         PyObject *py_sa = StrokeAttribute_Type.tp_new(&StrokeAttribute_Type, 0, 0);
275         ((BPy_StrokeAttribute *)py_sa)->sa = &sa;
276         ((BPy_StrokeAttribute *)py_sa)->borrowed = true;
277         return py_sa;
278 }
279
280 PyObject *BPy_MediumType_from_MediumType(Stroke::MediumType n)
281 {
282         PyObject *args = PyTuple_New(1);
283         PyTuple_SET_ITEM(args, 0, PyLong_FromLong(n));
284         PyObject *py_mt = MediumType_Type.tp_new(&MediumType_Type, args, NULL);
285         Py_DECREF(args);
286         return py_mt;
287 }
288
289 PyObject *BPy_StrokeVertex_from_StrokeVertex(StrokeVertex& sv)
290 {
291         PyObject *py_sv = StrokeVertex_Type.tp_new(&StrokeVertex_Type, 0, 0);
292         ((BPy_StrokeVertex *)py_sv)->sv = &sv;
293         ((BPy_StrokeVertex *)py_sv)->py_cp.cp = ((BPy_StrokeVertex *)py_sv)->sv;
294         ((BPy_StrokeVertex *)py_sv)->py_cp.py_if0D.if0D = ((BPy_StrokeVertex *)py_sv)->sv;
295         ((BPy_StrokeVertex *)py_sv)->py_cp.py_if0D.borrowed = true;
296         return py_sv;
297 }
298
299 PyObject *BPy_ViewVertex_from_ViewVertex(ViewVertex& vv)
300 {
301         PyObject *py_vv = ViewVertex_Type.tp_new(&ViewVertex_Type, 0, 0);
302         ((BPy_ViewVertex *)py_vv)->vv = &vv;
303         ((BPy_ViewVertex *)py_vv)->py_if0D.if0D = ((BPy_ViewVertex *)py_vv)->vv;
304         ((BPy_ViewVertex *)py_vv)->py_if0D.borrowed = true;
305         return py_vv;
306 }
307
308 PyObject *BPy_NonTVertex_from_NonTVertex(NonTVertex& ntv)
309 {
310         PyObject *py_ntv = NonTVertex_Type.tp_new(&NonTVertex_Type, 0, 0);
311         ((BPy_NonTVertex *)py_ntv)->ntv = &ntv;
312         ((BPy_NonTVertex *)py_ntv)->py_vv.vv = ((BPy_NonTVertex *)py_ntv)->ntv;
313         ((BPy_NonTVertex *)py_ntv)->py_vv.py_if0D.if0D = ((BPy_NonTVertex *)py_ntv)->ntv;
314         ((BPy_NonTVertex *)py_ntv)->py_vv.py_if0D.borrowed = true;
315         return py_ntv;
316 }
317
318 PyObject *BPy_TVertex_from_TVertex(TVertex& tv)
319 {
320         PyObject *py_tv = TVertex_Type.tp_new(&TVertex_Type, 0, 0);
321         ((BPy_TVertex *)py_tv)->tv = &tv;
322         ((BPy_TVertex *)py_tv)->py_vv.vv = ((BPy_TVertex *)py_tv)->tv;
323         ((BPy_TVertex *)py_tv)->py_vv.py_if0D.if0D = ((BPy_TVertex *)py_tv)->tv;
324         ((BPy_TVertex *)py_tv)->py_vv.py_if0D.borrowed = true;
325         return py_tv;
326 }
327
328 PyObject *BPy_BBox_from_BBox(const BBox< Vec3r > &bb)
329 {
330         PyObject *py_bb = BBox_Type.tp_new(&BBox_Type, 0, 0);
331         ((BPy_BBox *)py_bb)->bb = new BBox< Vec3r >(bb);
332         return py_bb;
333 }
334
335 PyObject *BPy_ViewEdge_from_ViewEdge(ViewEdge& ve)
336 {
337         PyObject *py_ve = ViewEdge_Type.tp_new(&ViewEdge_Type, 0, 0);
338         ((BPy_ViewEdge *)py_ve)->ve = &ve;
339         ((BPy_ViewEdge *)py_ve)->py_if1D.if1D = ((BPy_ViewEdge *)py_ve)->ve;
340         ((BPy_ViewEdge *)py_ve)->py_if1D.borrowed = true;
341         return py_ve;
342 }
343
344 PyObject *BPy_Chain_from_Chain(Chain& c)
345 {
346         PyObject *py_c = Chain_Type.tp_new(&Chain_Type, 0, 0);
347         ((BPy_Chain *)py_c)->c = &c;
348         ((BPy_Chain *)py_c)->py_c.c = ((BPy_Chain *)py_c)->c;
349         ((BPy_Chain *)py_c)->py_c.py_if1D.if1D = ((BPy_Chain *)py_c)->c;
350         ((BPy_Chain *)py_c)->py_c.py_if1D.borrowed = true;
351         return py_c;
352 }
353
354 PyObject *BPy_SShape_from_SShape(SShape& ss)
355 {
356         PyObject *py_ss = SShape_Type.tp_new(&SShape_Type, 0, 0);
357         ((BPy_SShape *)py_ss)->ss = &ss;
358         ((BPy_SShape *)py_ss)->borrowed = true;
359         return py_ss;   
360 }
361
362 PyObject *BPy_ViewShape_from_ViewShape(ViewShape& vs)
363 {
364         PyObject *py_vs = ViewShape_Type.tp_new(&ViewShape_Type, 0, 0);
365         ((BPy_ViewShape *)py_vs)->vs = &vs;
366         ((BPy_ViewShape *)py_vs)->borrowed = true;
367         ((BPy_ViewShape *)py_vs)->py_ss = NULL;
368         return py_vs;
369 }
370
371 PyObject *BPy_FrsMaterial_from_FrsMaterial(const FrsMaterial& m)
372 {
373         PyObject *py_m = FrsMaterial_Type.tp_new(&FrsMaterial_Type, 0, 0);
374         ((BPy_FrsMaterial *) py_m)->m = new FrsMaterial(m);
375         return py_m;
376 }
377
378 PyObject *BPy_IntegrationType_from_IntegrationType(IntegrationType i)
379 {
380         PyObject *args = PyTuple_New(1);
381         PyTuple_SET_ITEM(args, 0, PyLong_FromLong(i));
382         PyObject *py_it = IntegrationType_Type.tp_new(&IntegrationType_Type, args, NULL);
383         Py_DECREF(args);
384         return py_it;
385 }
386
387 PyObject *BPy_CurvePoint_from_CurvePoint(CurvePoint& cp)
388 {
389         PyObject *py_cp = CurvePoint_Type.tp_new(&CurvePoint_Type, 0, 0);
390         // CurvePointIterator::operator*() returns a reference of a class data
391         // member whose value is mutable upon iteration over different CurvePoints.
392         // It is likely that such a mutable reference is passed to this function,
393         // so that a new allocated CurvePoint instance is created here to avoid
394         // nasty bugs (cf. T41464).
395         ((BPy_CurvePoint *) py_cp)->cp = new CurvePoint(cp);
396         ((BPy_CurvePoint *) py_cp)->py_if0D.if0D = ((BPy_CurvePoint *)py_cp)->cp;
397         ((BPy_CurvePoint *) py_cp)->py_if0D.borrowed = false;
398         return py_cp;
399 }
400
401 PyObject *BPy_directedViewEdge_from_directedViewEdge(ViewVertex::directedViewEdge& dve)
402 {
403         PyObject *py_dve = PyTuple_New(2);
404         PyTuple_SET_ITEM(py_dve, 0, BPy_ViewEdge_from_ViewEdge(*(dve.first)));
405         PyTuple_SET_ITEM(py_dve, 1, PyBool_from_bool(dve.second));
406         return py_dve;
407 }
408
409 //==============================
410 // Iterators
411 //==============================
412
413 PyObject *BPy_AdjacencyIterator_from_AdjacencyIterator(AdjacencyIterator& a_it)
414 {
415         PyObject *py_a_it = AdjacencyIterator_Type.tp_new(&AdjacencyIterator_Type, 0, 0);
416         ((BPy_AdjacencyIterator *)py_a_it)->a_it = new AdjacencyIterator(a_it);
417         ((BPy_AdjacencyIterator *)py_a_it)->py_it.it = ((BPy_AdjacencyIterator *)py_a_it)->a_it;
418         ((BPy_AdjacencyIterator *)py_a_it)->at_start = true;
419         return py_a_it;
420 }
421
422 PyObject *BPy_Interface0DIterator_from_Interface0DIterator(Interface0DIterator& if0D_it, bool reversed)
423 {
424         PyObject *py_if0D_it = Interface0DIterator_Type.tp_new(&Interface0DIterator_Type, 0, 0);
425         ((BPy_Interface0DIterator *)py_if0D_it)->if0D_it = new Interface0DIterator(if0D_it);
426         ((BPy_Interface0DIterator *)py_if0D_it)->py_it.it = ((BPy_Interface0DIterator *)py_if0D_it)->if0D_it;
427         ((BPy_Interface0DIterator *)py_if0D_it)->at_start = true;
428         ((BPy_Interface0DIterator *)py_if0D_it)->reversed = reversed;
429         return py_if0D_it;
430 }
431
432 PyObject *BPy_CurvePointIterator_from_CurvePointIterator(CurveInternal::CurvePointIterator& cp_it)
433 {
434         PyObject *py_cp_it = CurvePointIterator_Type.tp_new(&CurvePointIterator_Type, 0, 0);
435         ((BPy_CurvePointIterator *)py_cp_it)->cp_it = new CurveInternal::CurvePointIterator(cp_it);
436         ((BPy_CurvePointIterator *)py_cp_it)->py_it.it = ((BPy_CurvePointIterator *)py_cp_it)->cp_it;
437         return py_cp_it;
438 }
439
440 PyObject *BPy_StrokeVertexIterator_from_StrokeVertexIterator(StrokeInternal::StrokeVertexIterator& sv_it, bool reversed)
441 {
442         PyObject *py_sv_it = StrokeVertexIterator_Type.tp_new(&StrokeVertexIterator_Type, 0, 0);
443         ((BPy_StrokeVertexIterator *)py_sv_it)->sv_it = new StrokeInternal::StrokeVertexIterator(sv_it);
444         ((BPy_StrokeVertexIterator *)py_sv_it)->py_it.it = ((BPy_StrokeVertexIterator *)py_sv_it)->sv_it;
445         ((BPy_StrokeVertexIterator *)py_sv_it)->at_start = true;
446         ((BPy_StrokeVertexIterator *)py_sv_it)->reversed = reversed;
447         return py_sv_it;
448 }
449
450 PyObject *BPy_SVertexIterator_from_SVertexIterator(ViewEdgeInternal::SVertexIterator& sv_it)
451 {
452         PyObject *py_sv_it = SVertexIterator_Type.tp_new(&SVertexIterator_Type, 0, 0);
453         ((BPy_SVertexIterator *)py_sv_it)->sv_it = new ViewEdgeInternal::SVertexIterator(sv_it);
454         ((BPy_SVertexIterator *)py_sv_it)->py_it.it = ((BPy_SVertexIterator *)py_sv_it)->sv_it;
455         return py_sv_it;
456 }
457
458 PyObject *BPy_orientedViewEdgeIterator_from_orientedViewEdgeIterator(ViewVertexInternal::orientedViewEdgeIterator& ove_it, bool reversed)
459 {
460         PyObject *py_ove_it = orientedViewEdgeIterator_Type.tp_new(&orientedViewEdgeIterator_Type, 0, 0);
461         ((BPy_orientedViewEdgeIterator *)py_ove_it)->ove_it = new ViewVertexInternal::orientedViewEdgeIterator(ove_it);
462         ((BPy_orientedViewEdgeIterator *)py_ove_it)->py_it.it = ((BPy_orientedViewEdgeIterator *)py_ove_it)->ove_it;
463         ((BPy_orientedViewEdgeIterator *)py_ove_it)->at_start = true;
464         ((BPy_orientedViewEdgeIterator *)py_ove_it)->reversed = reversed;
465         return py_ove_it;
466 }
467
468 PyObject *BPy_ViewEdgeIterator_from_ViewEdgeIterator(ViewEdgeInternal::ViewEdgeIterator& ve_it)
469 {
470         PyObject *py_ve_it = ViewEdgeIterator_Type.tp_new(&ViewEdgeIterator_Type, 0, 0);
471         ((BPy_ViewEdgeIterator *)py_ve_it)->ve_it = new ViewEdgeInternal::ViewEdgeIterator(ve_it);
472         ((BPy_ViewEdgeIterator *)py_ve_it)->py_it.it =  ((BPy_ViewEdgeIterator *)py_ve_it)->ve_it;
473         return py_ve_it;
474 }
475
476 PyObject *BPy_ChainingIterator_from_ChainingIterator(ChainingIterator& c_it)
477 {
478         PyObject *py_c_it = ChainingIterator_Type.tp_new(&ChainingIterator_Type, 0, 0);
479         ((BPy_ChainingIterator *)py_c_it)->c_it = new ChainingIterator(c_it);
480         ((BPy_ChainingIterator *)py_c_it)->py_ve_it.py_it.it = ((BPy_ChainingIterator *)py_c_it)->c_it;
481         return py_c_it;
482 }
483
484 PyObject *BPy_ChainPredicateIterator_from_ChainPredicateIterator(ChainPredicateIterator& cp_it)
485 {
486         PyObject *py_cp_it = ChainPredicateIterator_Type.tp_new(&ChainPredicateIterator_Type, 0, 0);
487         ((BPy_ChainPredicateIterator *)py_cp_it)->cp_it = new ChainPredicateIterator(cp_it);
488         ((BPy_ChainPredicateIterator *)py_cp_it)->py_c_it.py_ve_it.py_it.it = ((BPy_ChainPredicateIterator *)py_cp_it)->cp_it;
489         return py_cp_it;
490 }
491
492 PyObject *BPy_ChainSilhouetteIterator_from_ChainSilhouetteIterator(ChainSilhouetteIterator& cs_it)
493 {
494         PyObject *py_cs_it = ChainSilhouetteIterator_Type.tp_new(&ChainSilhouetteIterator_Type, 0, 0);
495         ((BPy_ChainSilhouetteIterator *)py_cs_it)->cs_it = new ChainSilhouetteIterator(cs_it);
496         ((BPy_ChainSilhouetteIterator *)py_cs_it)->py_c_it.py_ve_it.py_it.it = ((BPy_ChainSilhouetteIterator *)py_cs_it)->cs_it;
497         return py_cs_it;
498 }
499
500 //==============================
501 // Python => C++
502 //==============================
503
504 bool bool_from_PyBool(PyObject *b)
505 {
506         return PyObject_IsTrue(b) != 0;
507 }
508
509 IntegrationType IntegrationType_from_BPy_IntegrationType(PyObject *obj)
510 {
511         return static_cast<IntegrationType>(PyLong_AsLong(obj));
512 }
513
514 Stroke::MediumType MediumType_from_BPy_MediumType(PyObject *obj)
515 {
516         return static_cast<Stroke::MediumType>(PyLong_AsLong(obj));
517 }
518
519 Nature::EdgeNature EdgeNature_from_BPy_Nature(PyObject *obj)
520 {
521         return static_cast<Nature::EdgeNature>(PyLong_AsLong(obj));
522 }
523
524 bool Vec2f_ptr_from_PyObject(PyObject *obj, Vec2f &vec)
525 {
526         if (Vec2f_ptr_from_Vector(obj, vec))
527                 return true;
528         if (Vec2f_ptr_from_PyList(obj, vec))
529                 return true;
530         if (Vec2f_ptr_from_PyTuple(obj, vec))
531                 return true;
532         return false;
533 }
534
535 bool Vec3f_ptr_from_PyObject(PyObject *obj, Vec3f &vec)
536 {
537         if (Vec3f_ptr_from_Vector(obj, vec))
538                 return true;
539         if (Vec3f_ptr_from_Color(obj, vec))
540                 return true;
541         if (Vec3f_ptr_from_PyList(obj, vec))
542                 return true;
543         if (Vec3f_ptr_from_PyTuple(obj, vec))
544                 return true;
545         return false;
546 }
547
548 bool Vec3r_ptr_from_PyObject(PyObject *obj, Vec3r &vec)
549 {
550         if (Vec3r_ptr_from_Vector(obj, vec))
551                 return true;
552         if (Vec3r_ptr_from_Color(obj, vec))
553                 return true;
554         if (Vec3r_ptr_from_PyList(obj, vec))
555                 return true;
556         if (Vec3r_ptr_from_PyTuple(obj, vec))
557                 return true;
558         return false;
559 }
560
561 bool Vec2f_ptr_from_Vector(PyObject *obj, Vec2f &vec)
562 {
563         if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 2)
564                 return false;
565         if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1)
566                 return false;
567         vec[0] = ((VectorObject *)obj)->vec[0];
568         vec[1] = ((VectorObject *)obj)->vec[1];
569         return true;
570 }
571
572 bool Vec3f_ptr_from_Vector(PyObject *obj, Vec3f &vec)
573 {
574         if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 3)
575                 return false;
576         if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1)
577                 return false;
578         vec[0] = ((VectorObject *)obj)->vec[0];
579         vec[1] = ((VectorObject *)obj)->vec[1];
580         vec[2] = ((VectorObject *)obj)->vec[2];
581         return true;
582 }
583
584 bool Vec3r_ptr_from_Vector(PyObject *obj, Vec3r &vec)
585 {
586         if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 3)
587                 return false;
588         if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1)
589                 return false;
590         vec[0] = ((VectorObject *)obj)->vec[0];
591         vec[1] = ((VectorObject *)obj)->vec[1];
592         vec[2] = ((VectorObject *)obj)->vec[2];
593         return true;
594 }
595
596 bool Vec3f_ptr_from_Color(PyObject *obj, Vec3f &vec)
597 {
598         if (!ColorObject_Check(obj))
599                 return false;
600         if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1)
601                 return false;
602         vec[0] = ((ColorObject *)obj)->col[0];
603         vec[1] = ((ColorObject *)obj)->col[1];
604         vec[2] = ((ColorObject *)obj)->col[2];
605         return true;
606 }
607
608 bool Vec3r_ptr_from_Color(PyObject *obj, Vec3r &vec)
609 {
610         if (!ColorObject_Check(obj))
611                 return false;
612         if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1)
613                 return false;
614         vec[0] = ((ColorObject *)obj)->col[0];
615         vec[1] = ((ColorObject *)obj)->col[1];
616         vec[2] = ((ColorObject *)obj)->col[2];
617         return true;
618 }
619
620 static bool float_array_from_PyList(PyObject *obj, float *v, int n)
621 {
622         for (int i = 0; i < n; i++) {
623                 v[i] = PyFloat_AsDouble(PyList_GET_ITEM(obj, i));
624                 if (v[i] == -1.0f && PyErr_Occurred()) {
625                         PyErr_SetString(PyExc_TypeError, "list elements must be a number");
626                         return 0;
627                 }
628         }
629         return 1;
630 }
631
632 bool Vec2f_ptr_from_PyList(PyObject *obj, Vec2f &vec)
633 {
634         float v[2];
635
636         if (!PyList_Check(obj) || PyList_GET_SIZE(obj) != 2)
637                 return false;
638         if (!float_array_from_PyList(obj, v, 2))
639                 return false;
640         vec[0] = v[0];
641         vec[1] = v[1];
642         return true;
643 }
644
645 bool Vec3f_ptr_from_PyList(PyObject *obj, Vec3f &vec)
646 {
647         float v[3];
648
649         if (!PyList_Check(obj) || PyList_GET_SIZE(obj) != 3)
650                 return false;
651         if (!float_array_from_PyList(obj, v, 3))
652                 return false;
653         vec[0] = v[0];
654         vec[1] = v[1];
655         vec[2] = v[2];
656         return true;
657 }
658
659 bool Vec3r_ptr_from_PyList(PyObject *obj, Vec3r &vec)
660 {
661         float v[3];
662
663         if (!PyList_Check(obj) || PyList_GET_SIZE(obj) != 3)
664                 return false;
665         if (!float_array_from_PyList(obj, v, 3))
666                 return false;
667         vec[0] = v[0];
668         vec[1] = v[1];
669         vec[2] = v[2];
670         return true;
671 }
672
673 static bool float_array_from_PyTuple(PyObject *obj, float *v, int n)
674 {
675         for (int i = 0; i < n; i++) {
676                 v[i] = PyFloat_AsDouble(PyTuple_GET_ITEM(obj, i));
677                 if (v[i] == -1.0f && PyErr_Occurred()) {
678                         PyErr_SetString(PyExc_TypeError, "tuple elements must be a number");
679                         return 0;
680                 }
681         }
682         return 1;
683 }
684
685 bool Vec2f_ptr_from_PyTuple(PyObject *obj, Vec2f &vec)
686 {
687         float v[2];
688
689         if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 2)
690                 return false;
691         if (!float_array_from_PyTuple(obj, v, 2))
692                 return false;
693         vec[0] = v[0];
694         vec[1] = v[1];
695         return true;
696 }
697
698 bool Vec3f_ptr_from_PyTuple(PyObject *obj, Vec3f &vec)
699 {
700         float v[3];
701
702         if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 3)
703                 return false;
704         if (!float_array_from_PyTuple(obj, v, 3))
705                 return false;
706         vec[0] = v[0];
707         vec[1] = v[1];
708         vec[2] = v[2];
709         return true;
710 }
711
712 bool Vec3r_ptr_from_PyTuple(PyObject *obj, Vec3r &vec)
713 {
714         float v[3];
715
716         if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 3)
717                 return false;
718         if (!float_array_from_PyTuple(obj, v, 3))
719                 return false;
720         vec[0] = v[0];
721         vec[1] = v[1];
722         vec[2] = v[2];
723         return true;
724 }
725
726 // helpers for argument parsing
727
728 bool float_array_from_PyObject(PyObject *obj, float *v, int n)
729 {
730         if (VectorObject_Check(obj) && ((VectorObject *)obj)->size == n) {
731                 if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1)
732                         return 0;
733                 for (int i = 0; i < n; i++)
734                         v[i] = ((VectorObject *)obj)->vec[i];
735                 return 1;
736         }
737         else if (ColorObject_Check(obj) && n == 3) {
738                 if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1)
739                         return 0;
740                 for (int i = 0; i < n; i++)
741                         v[i] = ((ColorObject *)obj)->col[i];
742                 return 1;
743         }
744         else if (PyList_Check(obj) && PyList_GET_SIZE(obj) == n) {
745                 return float_array_from_PyList(obj, v, n);
746         }
747         else if (PyTuple_Check(obj) && PyTuple_GET_SIZE(obj) == n) {
748                 return float_array_from_PyTuple(obj, v, n);
749         }
750         return 0;
751 }
752
753 int convert_v4(PyObject *obj, void *v)
754 {
755         return mathutils_array_parse((float *)v, 4, 4, obj, "Error parsing 4D vector");
756 }
757
758 int convert_v3(PyObject *obj, void *v)
759 {
760         return mathutils_array_parse((float *)v, 3, 3, obj, "Error parsing 3D vector");
761 }
762
763 int convert_v2(PyObject *obj, void *v)
764 {
765         return mathutils_array_parse((float *)v, 2, 2, obj, "Error parsing 2D vector");
766 }
767
768
769 ///////////////////////////////////////////////////////////////////////////////////////////
770
771 #ifdef __cplusplus
772 }
773 #endif