- removed makeDispList, set_displist_onlyzero
[blender.git] / source / blender / python / api2_2x / Library.c
1 /**
2  * $Id$
3  *
4  * Blender.Library BPython module implementation.
5  * This submodule has functions to append data from .blend files.
6  * 
7  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version. The Blender
13  * Foundation also sells licenses for use in proprietary software under
14  * the Blender License.  See http://www.blender.org/BL/ for information
15  * about this.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software Foundation,
24  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
25  *
26  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
27  * All rights reserved.
28  *
29  * This is a new part of Blender.
30  *
31  * Contributor(s): Willian P. Germano
32  *
33  * ***** END GPL/BL DUAL LICENSE BLOCK *****
34 */
35
36 #include <Python.h>
37 #include <stdio.h>
38
39 #include <DNA_ID.h>
40 #include <DNA_curve_types.h>
41 #include <BKE_library.h>        /* for all_local */
42 #include "BKE_font.h"           /* for text_to_curve */
43 #include <BLO_readfile.h>
44 #include <BLI_linklist.h>
45 #include <MEM_guardedalloc.h>
46
47 #include "gen_utils.h"
48
49
50 /**
51  * Global variables.
52  */
53 static BlendHandle *bpy_openlib;        /* ptr to the open .blend file */
54 static char *bpy_openlibname;   /* its pathname */
55
56 /**
57  * Function prototypes for the Library submodule.
58  */
59 static PyObject *M_Library_Open( PyObject * self, PyObject * args );
60 static PyObject *M_Library_Close( PyObject * self );
61 static PyObject *M_Library_GetName( PyObject * self );
62 static PyObject *M_Library_Update( PyObject * self );
63 static PyObject *M_Library_Datablocks( PyObject * self, PyObject * args );
64 static PyObject *M_Library_Load( PyObject * self, PyObject * args );
65 static PyObject *M_Library_LinkableGroups( PyObject * self );
66
67 PyObject *Library_Init( void );
68 void EXPP_Library_Close( void );
69
70
71 /**
72  * Module doc strings.
73  */
74 static char M_Library_doc[] = "The Blender.Library submodule:\n\n\
75 This module gives access to .blend files, using them as libraries of\n\
76 data that can be loaded into the current scene in Blender.";
77
78 static char Library_Open_doc[] =
79         "(filename) - Open the given .blend file for access to its objects.\n\
80 If another library file is still open, it's closed automatically.";
81
82 static char Library_Close_doc[] =
83         "() - Close the currently open library file, if any.";
84
85 static char Library_GetName_doc[] =
86         "() - Get the filename of the currently open library file, if any.";
87
88 static char Library_Datablocks_doc[] =
89         "(datablock) - List all datablocks of the given type in the currently\n\
90 open library file.\n\
91 (datablock) - datablock name as a string: Object, Mesh, etc.";
92
93 static char Library_Load_doc[] =
94         "(name, datablock [,update = 1]) - Append object 'name' of type 'datablock'\n\
95 from the open library file to the current scene.\n\
96 (name) - (str) the name of the object.\n\
97 (datablock) - (str) the datablock of the object.\n\
98 (update = 1) - (int) if non-zero, all display lists are recalculated and the\n\
99 links are updated.  This is slow, set it to zero if you have more than one\n\
100 object to load, then call Library.Update() after loading them all.";
101
102 static char Library_Update_doc[] =
103         "() - Update the current scene, linking all loaded library objects and\n\
104 remaking all display lists.  This is slow, call it only once after loading\n\
105 all objects (load each of them with update = 0:\n\
106 Library.Load(name, datablock, 0), or the update will be automatic, repeated\n\
107 for each loaded object.";
108
109 static char Library_LinkableGroups_doc[] =
110         "() - Get all linkable groups from the open .blend library file.";
111
112 /**
113  * Python method structure definition for Blender.Library submodule.
114  */
115 struct PyMethodDef M_Library_methods[] = {
116         {"Open", M_Library_Open, METH_VARARGS, Library_Open_doc},
117         {"Close", ( PyCFunction ) M_Library_Close, METH_NOARGS,
118          Library_Close_doc},
119         {"GetName", ( PyCFunction ) M_Library_GetName, METH_NOARGS,
120          Library_GetName_doc},
121         {"Update", ( PyCFunction ) M_Library_Update, METH_NOARGS,
122          Library_Update_doc},
123         {"Datablocks", M_Library_Datablocks, METH_VARARGS,
124          Library_Datablocks_doc},
125         {"Load", M_Library_Load, METH_VARARGS, Library_Load_doc},
126         {"LinkableGroups", ( PyCFunction ) M_Library_LinkableGroups,
127          METH_NOARGS, Library_LinkableGroups_doc},
128         {NULL, NULL, 0, NULL}
129 };
130
131 /* Submodule Python functions: */
132
133 /**
134  * Open a new .blend file.
135  * Only one can be open at a time, so this function also closes
136  * the previously opened file, if any.
137  */
138 PyObject *M_Library_Open( PyObject * self, PyObject * args )
139 {
140         char *fname = NULL;
141         int len = 0;
142
143         if( !PyArg_ParseTuple( args, "s", &fname ) ) {
144                 return EXPP_ReturnPyObjError( PyExc_TypeError,
145                                               "expected a .blend filename" );
146         }
147
148         if( bpy_openlib ) {
149                 M_Library_Close( self );
150                 Py_DECREF( Py_None );   /* incref'ed by above function */
151         }
152
153         bpy_openlib = BLO_blendhandle_from_file( fname );
154
155         if( !bpy_openlib )
156                 return Py_BuildValue( "i", 0 );
157
158         len = strlen( fname ) + 1;      /* +1 for terminating '\0' */
159
160         bpy_openlibname = MEM_mallocN( len, "bpy_openlibname" );
161
162         if( bpy_openlibname )
163                 PyOS_snprintf( bpy_openlibname, len, "%s", fname );
164
165         return Py_BuildValue( "i", 1 );
166 }
167
168 /**
169  * Close the current .blend file, if any.
170  */
171 PyObject *M_Library_Close( PyObject * self )
172 {
173         if( bpy_openlib ) {
174                 BLO_blendhandle_close( bpy_openlib );
175                 bpy_openlib = NULL;
176         }
177
178         if( bpy_openlibname ) {
179                 MEM_freeN( bpy_openlibname );
180                 bpy_openlibname = NULL;
181         }
182
183         Py_INCREF( Py_None );
184         return Py_None;
185 }
186
187 /**
188  * helper function for 'atexit' clean-ups, used by BPY_end_python,
189  * declared in EXPP_interface.h.
190  */
191 void EXPP_Library_Close( void )
192 {
193         if( bpy_openlib ) {
194                 BLO_blendhandle_close( bpy_openlib );
195                 bpy_openlib = NULL;
196         }
197
198         if( bpy_openlibname ) {
199                 MEM_freeN( bpy_openlibname );
200                 bpy_openlibname = NULL;
201         }
202 }
203
204 /**
205  * Get the filename of the currently open library file, if any.
206  */
207 PyObject *M_Library_GetName( PyObject * self )
208 {
209         if( bpy_openlib && bpy_openlibname )
210                 return Py_BuildValue( "s", bpy_openlibname );
211
212         Py_INCREF( Py_None );
213         return Py_None;
214 }
215
216 /**
217  * Return a list with all items of a given datablock type
218  * (like 'Object', 'Mesh', etc.) in the open library file.
219  */
220 PyObject *M_Library_Datablocks( PyObject * self, PyObject * args )
221 {
222         char *name = NULL;
223         int blocktype = 0;
224         LinkNode *l = NULL, *names = NULL;
225         PyObject *list = NULL;
226
227         if( !bpy_openlib ) {
228                 return EXPP_ReturnPyObjError( PyExc_IOError,
229                                               "no library file: open one first with Blender.Lib_Open(filename)" );
230         }
231
232         if( !PyArg_ParseTuple( args, "s", &name ) ) {
233                 return EXPP_ReturnPyObjError( PyExc_TypeError,
234                                               "expected a string (datablock type) as argument." );
235         }
236
237         blocktype = ( int ) BLO_idcode_from_name( name );
238
239         if( !blocktype ) {
240                 return EXPP_ReturnPyObjError( PyExc_NameError,
241                                               "no such Blender datablock type" );
242         }
243
244         names = BLO_blendhandle_get_datablock_names( bpy_openlib, blocktype );
245
246         if( names ) {
247                 int counter = 0;
248                 list = PyList_New( BLI_linklist_length( names ) );
249                 for( l = names; l; l = l->next ) {
250                         PyList_SET_ITEM( list, counter,
251                                          Py_BuildValue( "s",
252                                                         ( char * ) l->link ) );
253                         counter++;
254                 }
255                 BLI_linklist_free( names, free );       /* free linklist *and* each node's data */
256                 return list;
257         }
258
259         Py_INCREF( Py_None );
260         return Py_None;
261 }
262
263 /**
264  * Return a list with the names of all linkable groups in the
265  * open library file.
266  */
267 PyObject *M_Library_LinkableGroups( PyObject * self )
268 {
269         LinkNode *l = NULL, *names = NULL;
270         PyObject *list = NULL;
271
272         if( !bpy_openlib ) {
273                 return EXPP_ReturnPyObjError( PyExc_IOError,
274                                               "no library file: open one first with Blender.Lib_Open(filename)" );
275         }
276
277         names = BLO_blendhandle_get_linkable_groups( bpy_openlib );
278
279         if( names ) {
280                 int counter = 0;
281                 list = PyList_New( BLI_linklist_length( names ) );
282                 for( l = names; l; l = l->next ) {
283                         PyList_SET_ITEM( list, counter,
284                                          Py_BuildValue( "s",
285                                                         ( char * ) l->link ) );
286                         counter++;
287                 }
288                 BLI_linklist_free( names, free );       /* free linklist *and* each node's data */
289                 return list;
290         }
291
292         Py_INCREF( Py_None );
293         return Py_None;
294 }
295
296 /**
297  * Load (append) a given datablock of a given datablock type
298  * to the current scene.
299  */
300 PyObject *M_Library_Load( PyObject * self, PyObject * args )
301 {
302         char *name = NULL;
303         char *base = NULL;
304         int update = 1;
305         int blocktype = 0;
306
307         if( !bpy_openlib ) {
308                 return EXPP_ReturnPyObjError( PyExc_IOError,
309                                               "no library file: you need to open one, first." );
310         }
311
312         if( !PyArg_ParseTuple( args, "ss|i", &name, &base, &update ) ) {
313                 return EXPP_ReturnPyObjError( PyExc_TypeError,
314                                               "expected two strings as arguments." );
315         }
316
317         blocktype = ( int ) BLO_idcode_from_name( base );
318
319         if( !blocktype ) {
320                 return EXPP_ReturnPyObjError( PyExc_NameError,
321                                               "no such Blender datablock type" );
322         }
323
324         BLO_script_library_append( bpy_openlib, bpy_openlibname, name,
325                                    blocktype );
326
327         if( update ) {
328                 M_Library_Update( self );
329                 Py_DECREF( Py_None );   /* incref'ed by above function */
330         }
331
332         Py_INCREF( Py_None );
333         return Py_None;
334 }
335
336 /**
337  * Update all links and remake displists.
338  */
339 PyObject *M_Library_Update( PyObject * self )
340 {                               /* code adapted from do_library_append in src/filesel.c: */
341         Object *ob = NULL;
342         Library *lib = NULL;
343
344                 /* Displist code that was here is obsolete... depending on what
345                  * this function is supposed to do (it should technically be unnecessary)
346                  * can be replaced with depgraph calls - zr
347                  */
348
349         if( bpy_openlibname ) {
350                 strcpy( G.lib, bpy_openlibname );
351
352                 /* and now find the latest append lib file */
353                 lib = G.main->library.first;
354                 while( lib ) {
355                         if( strcmp( bpy_openlibname, lib->name ) == 0 )
356                                 break;
357                         lib = lib->id.next;
358                 }
359                 all_local( lib );
360         }
361
362         Py_INCREF( Py_None );
363         return Py_None;
364 }
365
366 /**
367  * Initialize the Blender.Library submodule.
368  * Called by Blender_Init in Blender.c .
369  * @return the registered submodule.
370  */
371 PyObject *Library_Init( void )
372 {
373         PyObject *submod;
374
375         submod = Py_InitModule3( "Blender.Library", M_Library_methods,
376                                  M_Library_doc );
377
378         return submod;
379 }