- remove calls to showkeypos from exit editmode functions, should be
[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_displist.h"       /* for set_displist_onlyzero */
43 #include "BKE_font.h"           /* for text_to_curve */
44 #include <BLO_readfile.h>
45 #include <BLI_linklist.h>
46 #include <MEM_guardedalloc.h>
47
48 #include "gen_utils.h"
49
50
51 /**
52  * Global variables.
53  */
54 static BlendHandle *bpy_openlib;        /* ptr to the open .blend file */
55 static char *bpy_openlibname;   /* its pathname */
56
57 /**
58  * Function prototypes for the Library submodule.
59  */
60 static PyObject *M_Library_Open( PyObject * self, PyObject * args );
61 static PyObject *M_Library_Close( PyObject * self );
62 static PyObject *M_Library_GetName( PyObject * self );
63 static PyObject *M_Library_Update( PyObject * self );
64 static PyObject *M_Library_Datablocks( PyObject * self, PyObject * args );
65 static PyObject *M_Library_Load( PyObject * self, PyObject * args );
66 static PyObject *M_Library_LinkableGroups( PyObject * self );
67
68 PyObject *Library_Init( void );
69 void EXPP_Library_Close( void );
70
71
72 /**
73  * Module doc strings.
74  */
75 static char M_Library_doc[] = "The Blender.Library submodule:\n\n\
76 This module gives access to .blend files, using them as libraries of\n\
77 data that can be loaded into the current scene in Blender.";
78
79 static char Library_Open_doc[] =
80         "(filename) - Open the given .blend file for access to its objects.\n\
81 If another library file is still open, it's closed automatically.";
82
83 static char Library_Close_doc[] =
84         "() - Close the currently open library file, if any.";
85
86 static char Library_GetName_doc[] =
87         "() - Get the filename of the currently open library file, if any.";
88
89 static char Library_Datablocks_doc[] =
90         "(datablock) - List all datablocks of the given type in the currently\n\
91 open library file.\n\
92 (datablock) - datablock name as a string: Object, Mesh, etc.";
93
94 static char Library_Load_doc[] =
95         "(name, datablock [,update = 1]) - Append object 'name' of type 'datablock'\n\
96 from the open library file to the current scene.\n\
97 (name) - (str) the name of the object.\n\
98 (datablock) - (str) the datablock of the object.\n\
99 (update = 1) - (int) if non-zero, all display lists are recalculated and the\n\
100 links are updated.  This is slow, set it to zero if you have more than one\n\
101 object to load, then call Library.Update() after loading them all.";
102
103 static char Library_Update_doc[] =
104         "() - Update the current scene, linking all loaded library objects and\n\
105 remaking all display lists.  This is slow, call it only once after loading\n\
106 all objects (load each of them with update = 0:\n\
107 Library.Load(name, datablock, 0), or the update will be automatic, repeated\n\
108 for each loaded object.";
109
110 static char Library_LinkableGroups_doc[] =
111         "() - Get all linkable groups from the open .blend library file.";
112
113 /**
114  * Python method structure definition for Blender.Library submodule.
115  */
116 struct PyMethodDef M_Library_methods[] = {
117         {"Open", M_Library_Open, METH_VARARGS, Library_Open_doc},
118         {"Close", ( PyCFunction ) M_Library_Close, METH_NOARGS,
119          Library_Close_doc},
120         {"GetName", ( PyCFunction ) M_Library_GetName, METH_NOARGS,
121          Library_GetName_doc},
122         {"Update", ( PyCFunction ) M_Library_Update, METH_NOARGS,
123          Library_Update_doc},
124         {"Datablocks", M_Library_Datablocks, METH_VARARGS,
125          Library_Datablocks_doc},
126         {"Load", M_Library_Load, METH_VARARGS, Library_Load_doc},
127         {"LinkableGroups", ( PyCFunction ) M_Library_LinkableGroups,
128          METH_NOARGS, Library_LinkableGroups_doc},
129         {NULL, NULL, 0, NULL}
130 };
131
132 /* Submodule Python functions: */
133
134 /**
135  * Open a new .blend file.
136  * Only one can be open at a time, so this function also closes
137  * the previously opened file, if any.
138  */
139 PyObject *M_Library_Open( PyObject * self, PyObject * args )
140 {
141         char *fname = NULL;
142         int len = 0;
143
144         if( !PyArg_ParseTuple( args, "s", &fname ) ) {
145                 return EXPP_ReturnPyObjError( PyExc_TypeError,
146                                               "expected a .blend filename" );
147         }
148
149         if( bpy_openlib ) {
150                 M_Library_Close( self );
151                 Py_DECREF( Py_None );   /* incref'ed by above function */
152         }
153
154         bpy_openlib = BLO_blendhandle_from_file( fname );
155
156         if( !bpy_openlib )
157                 return Py_BuildValue( "i", 0 );
158
159         len = strlen( fname ) + 1;      /* +1 for terminating '\0' */
160
161         bpy_openlibname = MEM_mallocN( len, "bpy_openlibname" );
162
163         if( bpy_openlibname )
164                 PyOS_snprintf( bpy_openlibname, len, "%s", fname );
165
166         return Py_BuildValue( "i", 1 );
167 }
168
169 /**
170  * Close the current .blend file, if any.
171  */
172 PyObject *M_Library_Close( PyObject * self )
173 {
174         if( bpy_openlib ) {
175                 BLO_blendhandle_close( bpy_openlib );
176                 bpy_openlib = NULL;
177         }
178
179         if( bpy_openlibname ) {
180                 MEM_freeN( bpy_openlibname );
181                 bpy_openlibname = NULL;
182         }
183
184         Py_INCREF( Py_None );
185         return Py_None;
186 }
187
188 /**
189  * helper function for 'atexit' clean-ups, used by BPY_end_python,
190  * declared in EXPP_interface.h.
191  */
192 void EXPP_Library_Close( void )
193 {
194         if( bpy_openlib ) {
195                 BLO_blendhandle_close( bpy_openlib );
196                 bpy_openlib = NULL;
197         }
198
199         if( bpy_openlibname ) {
200                 MEM_freeN( bpy_openlibname );
201                 bpy_openlibname = NULL;
202         }
203 }
204
205 /**
206  * Get the filename of the currently open library file, if any.
207  */
208 PyObject *M_Library_GetName( PyObject * self )
209 {
210         if( bpy_openlib && bpy_openlibname )
211                 return Py_BuildValue( "s", bpy_openlibname );
212
213         Py_INCREF( Py_None );
214         return Py_None;
215 }
216
217 /**
218  * Return a list with all items of a given datablock type
219  * (like 'Object', 'Mesh', etc.) in the open library file.
220  */
221 PyObject *M_Library_Datablocks( PyObject * self, PyObject * args )
222 {
223         char *name = NULL;
224         int blocktype = 0;
225         LinkNode *l = NULL, *names = NULL;
226         PyObject *list = NULL;
227
228         if( !bpy_openlib ) {
229                 return EXPP_ReturnPyObjError( PyExc_IOError,
230                                               "no library file: open one first with Blender.Lib_Open(filename)" );
231         }
232
233         if( !PyArg_ParseTuple( args, "s", &name ) ) {
234                 return EXPP_ReturnPyObjError( PyExc_TypeError,
235                                               "expected a string (datablock type) as argument." );
236         }
237
238         blocktype = ( int ) BLO_idcode_from_name( name );
239
240         if( !blocktype ) {
241                 return EXPP_ReturnPyObjError( PyExc_NameError,
242                                               "no such Blender datablock type" );
243         }
244
245         names = BLO_blendhandle_get_datablock_names( bpy_openlib, blocktype );
246
247         if( names ) {
248                 int counter = 0;
249                 list = PyList_New( BLI_linklist_length( names ) );
250                 for( l = names; l; l = l->next ) {
251                         PyList_SET_ITEM( list, counter,
252                                          Py_BuildValue( "s",
253                                                         ( char * ) l->link ) );
254                         counter++;
255                 }
256                 BLI_linklist_free( names, free );       /* free linklist *and* each node's data */
257                 return list;
258         }
259
260         Py_INCREF( Py_None );
261         return Py_None;
262 }
263
264 /**
265  * Return a list with the names of all linkable groups in the
266  * open library file.
267  */
268 PyObject *M_Library_LinkableGroups( PyObject * self )
269 {
270         LinkNode *l = NULL, *names = NULL;
271         PyObject *list = NULL;
272
273         if( !bpy_openlib ) {
274                 return EXPP_ReturnPyObjError( PyExc_IOError,
275                                               "no library file: open one first with Blender.Lib_Open(filename)" );
276         }
277
278         names = BLO_blendhandle_get_linkable_groups( bpy_openlib );
279
280         if( names ) {
281                 int counter = 0;
282                 list = PyList_New( BLI_linklist_length( names ) );
283                 for( l = names; l; l = l->next ) {
284                         PyList_SET_ITEM( list, counter,
285                                          Py_BuildValue( "s",
286                                                         ( char * ) l->link ) );
287                         counter++;
288                 }
289                 BLI_linklist_free( names, free );       /* free linklist *and* each node's data */
290                 return list;
291         }
292
293         Py_INCREF( Py_None );
294         return Py_None;
295 }
296
297 /**
298  * Load (append) a given datablock of a given datablock type
299  * to the current scene.
300  */
301 PyObject *M_Library_Load( PyObject * self, PyObject * args )
302 {
303         char *name = NULL;
304         char *base = NULL;
305         int update = 1;
306         int blocktype = 0;
307
308         if( !bpy_openlib ) {
309                 return EXPP_ReturnPyObjError( PyExc_IOError,
310                                               "no library file: you need to open one, first." );
311         }
312
313         if( !PyArg_ParseTuple( args, "ss|i", &name, &base, &update ) ) {
314                 return EXPP_ReturnPyObjError( PyExc_TypeError,
315                                               "expected two strings as arguments." );
316         }
317
318         blocktype = ( int ) BLO_idcode_from_name( base );
319
320         if( !blocktype ) {
321                 return EXPP_ReturnPyObjError( PyExc_NameError,
322                                               "no such Blender datablock type" );
323         }
324
325         BLO_script_library_append( bpy_openlib, bpy_openlibname, name,
326                                    blocktype );
327
328         if( update ) {
329                 M_Library_Update( self );
330                 Py_DECREF( Py_None );   /* incref'ed by above function */
331         }
332
333         Py_INCREF( Py_None );
334         return Py_None;
335 }
336
337 /**
338  * Update all links and remake displists.
339  */
340 PyObject *M_Library_Update( PyObject * self )
341 {                               /* code adapted from do_library_append in src/filesel.c: */
342         Object *ob = NULL;
343         Library *lib = NULL;
344
345         ob = G.main->object.first;
346         set_displist_onlyzero( 1 );
347         while( ob ) {
348                 if( ob->id.lib ) {
349                         if( ob->type == OB_FONT ) {
350                                 Curve *cu = ob->data;
351                                 if( cu->nurb.first == 0 )
352                                         text_to_curve( ob, 0 );
353                         }
354                         makeDispList( ob );
355                 } else {
356                         if( ob->type == OB_MESH && ob->parent
357                             && ob->parent->type == OB_LATTICE )
358                                 makeDispListMesh( ob );
359                 }
360
361                 ob = ob->id.next;
362         }
363         set_displist_onlyzero( 0 );
364
365         if( bpy_openlibname ) {
366                 strcpy( G.lib, bpy_openlibname );
367
368                 /* and now find the latest append lib file */
369                 lib = G.main->library.first;
370                 while( lib ) {
371                         if( strcmp( bpy_openlibname, lib->name ) == 0 )
372                                 break;
373                         lib = lib->id.next;
374                 }
375                 all_local( lib );
376         }
377
378         Py_INCREF( Py_None );
379         return Py_None;
380 }
381
382 /**
383  * Initialize the Blender.Library submodule.
384  * Called by Blender_Init in Blender.c .
385  * @return the registered submodule.
386  */
387 PyObject *Library_Init( void )
388 {
389         PyObject *submod;
390
391         submod = Py_InitModule3( "Blender.Library", M_Library_methods,
392                                  M_Library_doc );
393
394         return submod;
395 }