Initial revision
[blender.git] / source / blender / bpython / intern / BPY_csg.c
1
2 /** CSG wrapper module 
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31   * $Id$
32   */
33
34 // TODO
35
36
37 #include "Python.h" 
38
39 #include "BPY_csg.h"
40
41 #include "BKE_booleanops_mesh.h"                    
42 #include "BKE_booleanops.h"                      
43 #include "MEM_guardedalloc.h"     
44
45 #include "b_interface.h"
46
47 #ifdef DEBUG
48         #define CSG_DEBUG(str)   \
49                         { printf str; }   
50 #else
51         #define CSG_DEBUG(str)   \
52                 {}
53 #endif
54
55
56 ///////////////////////////////////////////////////////////////
57 // CSG python object struct
58
59
60 typedef struct _CSGMesh {
61         PyObject_VAR_HEAD
62         CSG_MeshDescriptor *imesh;
63 } PyCSGMesh;
64
65 // PROTOS
66
67 static PyObject *newPyCSGMesh(CSG_MeshDescriptor *imesh);
68
69 static void CSGMesh_dealloc(PyObject *self);
70 static PyObject *CSGMesh_getattr(PyObject *self, char *attr);
71
72
73 static char CSGMesh_Type_doc[] = "CSG mesh type"; 
74
75 static PyTypeObject PyCSGMesh_Type = {
76         PyObject_HEAD_INIT(NULL)
77         0,                                /*ob_size*/
78         "CSGMesh",                        /*tp_name*/
79         sizeof(PyCSGMesh),                  /*tp_basicsize*/
80         0,                                /*tp_itemsize*/
81         /* methods */
82         (destructor) CSGMesh_dealloc,     /*tp_dealloc*/
83         (printfunc)0,                     /*tp_print*/
84         (getattrfunc)CSGMesh_getattr,     /*tp_getattr*/
85         (setattrfunc)0,                   /*tp_setattr*/
86         (cmpfunc)0,                       /*tp_compare*/
87         (reprfunc)0,                      /*tp_repr*/
88         0,                                /*tp_as_number*/
89         0,                                /*tp_as_sequence*/
90         0,                                /*tp_as_mapping*/
91         (hashfunc)0,                      /*tp_hash*/
92         (ternaryfunc)0,                   /*tp_call*/
93         (reprfunc)0,                      /*tp_str*/
94
95         /* Space for future expansion */
96         0L,0L,0L,0L,
97         CSGMesh_Type_doc /* Documentation string */
98 };
99
100 ///////////////////////////////////////////////////////////////
101 // CSG object methods
102
103
104 static PyObject *CSGMesh_add(PyObject *self, PyObject *args)
105 {
106         CSG_MeshDescriptor *new_imesh = 
107            (CSG_MeshDescriptor *) MEM_mallocN(sizeof(CSG_MeshDescriptor),
108                                               "CSG_IMesh");
109
110         PyCSGMesh *c2;
111         int success = 0;
112
113         PyCSGMesh *c1 = (PyCSGMesh *) self;
114         if (!PyArg_ParseTuple(args, "O!", &PyCSGMesh_Type, &c2)) return NULL;
115
116         success = CSG_PerformOp(c1->imesh, c2->imesh, 2, new_imesh);
117
118         if (!success) {
119                 PyErr_SetString(PyExc_RuntimeError, "Sorry. Didn't work");
120                 return NULL; // exception
121         }
122         return newPyCSGMesh(new_imesh);
123 }
124
125
126 static PyMethodDef CSGMesh_methods[] = {
127         {"union", CSGMesh_add, METH_VARARGS, 0 },
128         // add more methods here
129         {NULL, NULL, 0, NULL}
130 };
131
132
133 static void CSGMesh_dealloc(PyObject *self)
134 {
135         CSG_MeshDescriptor *imesh = ((PyCSGMesh *) self)->imesh;
136         CSG_DEBUG(("object was destroyed\n"));
137         // TODO: delete (free) struct ptr
138         CSG_DestroyMeshDescriptor(imesh);
139         MEM_freeN(imesh);
140         PyMem_DEL(self);
141 }
142
143 static PyObject *CSGMesh_getattr(PyObject *self, char *attr)
144 {
145         return Py_FindMethod(CSGMesh_methods, (PyObject *) self, attr);
146 }
147 ///////////////////////////////////////////////////////////////
148 // CSG module methods
149
150 static PyObject *newPyCSGMesh(CSG_MeshDescriptor *imesh)
151 {
152         PyCSGMesh *c = PyObject_NEW(PyCSGMesh, &PyCSGMesh_Type);
153         CSG_DEBUG(("object was created\n"));
154         c->imesh = imesh;
155         // add init bla here
156         return (PyObject *) c;
157 }
158
159 static PyObject *CSGmodule_CSGMesh(PyObject *self, PyObject *args)
160 {
161         char *name;
162
163         Object *obj;
164         CSG_MeshDescriptor *new_imesh;
165
166         if (!PyArg_ParseTuple(args, "s", &name)) return NULL;
167         new_imesh = (CSG_MeshDescriptor *) MEM_mallocN(
168                                                sizeof(CSG_MeshDescriptor),
169                                               "CSG_IMesh");
170
171         // get object by name, return its mesh data
172         // and do the conversion
173         //      CSG_LoadBlenderMesh(name, new_imesh);
174
175         obj = (Object *) getFromList(getObjectList(), name);
176         
177         if (!obj) {
178                 PyErr_SetString(PyExc_AttributeError, 
179                                 "requested Object does not exist");
180                 return NULL;
181         }       
182
183         if (obj->type != OB_MESH) {
184                 PyErr_SetString(PyExc_TypeError, "Mesh object expected");
185                 return NULL;
186         }
187
188         if (!CSG_LoadBlenderMesh(obj, new_imesh)) {
189                 PyErr_SetString(PyExc_RuntimeError, 
190                                 "FATAL: Could not acquire mesh data");
191                 return NULL;
192         }
193         return newPyCSGMesh(new_imesh);
194 }
195
196 static PyObject *CSGmodule_toBlenderMeshObject(PyObject *self, 
197                                                PyObject *args)
198 {
199         Object *new_object;
200         PyCSGMesh *pmesh;
201         CSG_MeshDescriptor *c;
202
203         float identity[4][4] = { {1.0, 0.0, 0.0, 0.0},
204                                  {0.0, 1.0, 0.0, 0.0},
205                                  {0.0, 0.0, 1.0, 0.0},
206                                  {0.0, 0.0, 0.0, 1.0}};
207
208
209         if (!PyArg_ParseTuple(args, "O!", &PyCSGMesh_Type, &pmesh)) return NULL;
210         c = pmesh->imesh; 
211         new_object = object_new(OB_MESH);
212
213         if (!PyArg_ParseTuple(self, "")) return NULL;
214         // TODO: blender mesh conversion
215         ConvertCSGDescriptorsToMeshObject(new_object, &c->m_descriptor,
216                                           &c->m_face_iterator,
217                                           &c->m_vertex_iterator, 
218                                           identity);
219
220         // return resulting object
221         return DataBlock_fromData(new_object);
222 }
223
224 static PyMethodDef CSGmodule_methods[] = {
225         {"CSGMesh",  CSGmodule_CSGMesh            , METH_VARARGS, 0 },
226         {"toObject", CSGmodule_toBlenderMeshObject, METH_VARARGS, 0 },
227         {NULL, NULL, 0, NULL}
228 };
229
230 // MODULE INITIALIZATION
231
232 void initcsg()
233 {
234         PyObject *mod;
235         PyCSGMesh_Type.ob_type = &PyType_Type;
236         mod = Py_InitModule("csg", CSGmodule_methods);  
237                                                            
238 }
239