Changed frame numbering to only alter hashes if they are in the filename (not the...
[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 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.
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  * This is a new part of Blender.
27  *
28  * Contributor(s): Willian P. Germano, Campbell Barton, Ken Hughes
29  *
30  * ***** END GPL LICENSE BLOCK *****
31 */
32
33 /************************************************************/
34 /* Original library module code                             */
35 /************************************************************/
36
37 #include <Python.h>
38
39 #include "DNA_curve_types.h"
40 #include "DNA_object_types.h"
41 #include "DNA_space_types.h" /* for line linked */
42 #include "BKE_library.h"        /* for all_local */
43 #include "BKE_font.h"           /* for text_to_curve */
44 #include "BKE_utildefines.h"
45 #include "BKE_global.h"
46 #include "BKE_main.h"
47 #include "BLI_blenlib.h"
48 #include "BLO_readfile.h"
49 #include "BLI_linklist.h"
50 #include "MEM_guardedalloc.h"
51 #include "gen_utils.h"
52
53 /**
54  * Global variables.
55  */
56 static BlendHandle *bpy_openlib = NULL; /* ptr to the open .blend file */
57 static char *bpy_openlibname = NULL;    /* its pathname */
58 static int bpy_relative= 0;
59
60 /**
61  * Function prototypes for the Library submodule.
62  */
63 static PyObject *M_Library_Open( PyObject * self, PyObject * args );
64 static PyObject *M_Library_Close( PyObject * self );
65 static PyObject *M_Library_GetName( PyObject * self );
66 static PyObject *M_Library_Update( PyObject * self );
67 static PyObject *M_Library_Datablocks( PyObject * self, PyObject * value );
68 static PyObject *oldM_Library_Load( PyObject * self, PyObject * args );
69 static PyObject *M_Library_LinkableGroups( PyObject * self );
70 static PyObject *M_Library_LinkedLibs( PyObject * self );
71
72 PyObject *Library_Init( void );
73 void EXPP_Library_Close( void );
74
75 /**
76  * Module doc strings.
77  */
78 static char M_Library_doc[] = "The Blender.Library submodule:\n\n\
79 This module gives access to .blend files, using them as libraries of\n\
80 data that can be loaded into the current scene in Blender.";
81
82 static char Library_Open_doc[] =
83         "(filename) - Open the given .blend file for access to its objects.\n\
84 If another library file is still open, it's closed automatically.";
85
86 static char Library_Close_doc[] =
87         "() - Close the currently open library file, if any.";
88
89 static char Library_GetName_doc[] =
90         "() - Get the filename of the currently open library file, if any.";
91
92 static char Library_Datablocks_doc[] =
93         "(datablock) - List all datablocks of the given type in the currently\n\
94 open library file.\n\
95 (datablock) - datablock name as a string: Object, Mesh, etc.";
96
97 static char Library_Load_doc[] =
98         "(name, datablock [,update = 1]) - Append object 'name' of type 'datablock'\n\
99 from the open library file to the current scene.\n\
100 (name) - (str) the name of the object.\n\
101 (datablock) - (str) the datablock of the object.\n\
102 (update = 1) - (int) if non-zero, all display lists are recalculated and the\n\
103 links are updated.  This is slow, set it to zero if you have more than one\n\
104 object to load, then call Library.Update() after loading them all.";
105
106 static char Library_Update_doc[] =
107         "() - Update the current scene, linking all loaded library objects and\n\
108 remaking all display lists.  This is slow, call it only once after loading\n\
109 all objects (load each of them with update = 0:\n\
110 Library.Load(name, datablock, 0), or the update will be automatic, repeated\n\
111 for each loaded object.";
112
113 static char Library_LinkableGroups_doc[] =
114         "() - Get all linkable groups from the open .blend library file.";
115
116 static char Library_LinkedLibs_doc[] =
117         "() - Get all libs used in the the open .blend file.";
118         
119 /**
120  * Python method structure definition for Blender.Library submodule.
121  */
122 struct PyMethodDef oldM_Library_methods[] = {
123         {"Open", M_Library_Open, METH_O, Library_Open_doc},
124         {"Close", ( PyCFunction ) M_Library_Close, METH_NOARGS,
125          Library_Close_doc},
126         {"GetName", ( PyCFunction ) M_Library_GetName, METH_NOARGS,
127          Library_GetName_doc},
128         {"Update", ( PyCFunction ) M_Library_Update, METH_NOARGS,
129          Library_Update_doc},
130         {"Datablocks", M_Library_Datablocks, METH_O,
131          Library_Datablocks_doc},
132         {"Load", oldM_Library_Load, METH_VARARGS, Library_Load_doc},
133         {"LinkableGroups", ( PyCFunction ) M_Library_LinkableGroups,
134          METH_NOARGS, Library_LinkableGroups_doc},
135         {"LinkedLibs", ( PyCFunction ) M_Library_LinkedLibs,
136          METH_NOARGS, Library_LinkedLibs_doc},
137         {NULL, NULL, 0, NULL}
138 };
139
140 /* Submodule Python functions: */
141
142 /**
143  * Open a new .blend file.
144  * Only one can be open at a time, so this function also closes
145  * the previously opened file, if any.
146  */
147 static PyObject *M_Library_Open( PyObject * self, PyObject * value )
148 {
149         char *fname = PyString_AsString(value);
150         char filename[FILE_MAXDIR+FILE_MAXFILE];
151         char fname1[FILE_MAXDIR+FILE_MAXFILE];
152         
153         int len = 0;
154
155         bpy_relative= 0; /* assume non relative each time we load */
156         
157         if( !fname ) {
158                 return EXPP_ReturnPyObjError( PyExc_TypeError,
159                                               "expected a .blend filename" );
160         }
161
162         if( bpy_openlib ) {
163                 M_Library_Close( self );
164                 Py_DECREF( Py_None );   /* incref'ed by above function */
165         }
166         
167         /* copy the name to make it absolute so BLO_blendhandle_from_file doesn't complain */
168         BLI_strncpy(fname1, fname, sizeof(fname1)); 
169         BLI_convertstringcode(fname1, G.sce); /* make absolute */
170         
171         /* G.sce = last file loaded, save for UI and restore after opening file */
172         BLI_strncpy(filename, G.sce, sizeof(filename));
173         bpy_openlib = BLO_blendhandle_from_file( fname1 );
174         BLI_strncpy(G.sce, filename, sizeof(filename)); 
175
176         if( !bpy_openlib )
177                 return EXPP_ReturnPyObjError( PyExc_IOError, "file not found" );
178
179         /* "//someblend.blend" enables relative paths */
180         if (sizeof(fname) > 2 && fname[0] == '/' && fname[1] == '/')
181                 bpy_relative= 1; /* global that makes the library relative on loading */ 
182         
183         len = strlen( fname1 ) + 1;     /* +1 for terminating '\0' */
184
185         bpy_openlibname = MEM_mallocN( len, "bpy_openlibname" );
186
187         if( bpy_openlibname )
188                 PyOS_snprintf( bpy_openlibname, len, "%s", fname1 );
189
190         Py_RETURN_TRUE;
191 }
192
193 /**
194  * Close the current .blend file, if any.
195  */
196 static PyObject *M_Library_Close( PyObject * self )
197 {
198         if( bpy_openlib ) {
199                 BLO_blendhandle_close( bpy_openlib );
200                 bpy_openlib = NULL;
201         }
202
203         if( bpy_openlibname ) {
204                 MEM_freeN( bpy_openlibname );
205                 bpy_openlibname = NULL;
206         }
207
208         Py_RETURN_NONE;
209 }
210
211 /**
212  * helper function for 'atexit' clean-ups, used by BPY_end_python,
213  * declared in EXPP_interface.h.
214  */
215 void EXPP_Library_Close( void )
216 {
217         if( bpy_openlib ) {
218                 BLO_blendhandle_close( bpy_openlib );
219                 bpy_openlib = NULL;
220         }
221
222         if( bpy_openlibname ) {
223                 MEM_freeN( bpy_openlibname );
224                 bpy_openlibname = NULL;
225         }
226 }
227
228 /**
229  * Get the filename of the currently open library file, if any.
230  */
231 static PyObject *M_Library_GetName( PyObject * self )
232 {
233         if( bpy_openlib && bpy_openlibname )
234                 return Py_BuildValue( "s", bpy_openlibname );
235
236         Py_INCREF( Py_None );
237         return Py_None;
238 }
239
240 /**
241  * Return a list with all items of a given datablock type
242  * (like 'Object', 'Mesh', etc.) in the open library file.
243  */
244 static PyObject *M_Library_Datablocks( PyObject * self, PyObject * value )
245 {
246         char *name = PyString_AsString(value);
247         int blocktype = 0;
248         LinkNode *l = NULL, *names = NULL;
249         PyObject *list = NULL;
250
251         if( !bpy_openlib ) {
252                 return EXPP_ReturnPyObjError( PyExc_IOError,
253                                               "no library file: open one first with Blender.Lib_Open(filename)" );
254         }
255
256         if( !name ) {
257                 return EXPP_ReturnPyObjError( PyExc_TypeError,
258                                               "expected a string (datablock type) as argument." );
259         }
260
261         blocktype = ( int ) BLO_idcode_from_name( name );
262
263         if( !blocktype ) {
264                 return EXPP_ReturnPyObjError( PyExc_NameError,
265                                               "no such Blender datablock type" );
266         }
267
268         names = BLO_blendhandle_get_datablock_names( bpy_openlib, blocktype );
269
270         if( names ) {
271                 int counter = 0;
272                 list = PyList_New( BLI_linklist_length( names ) );
273                 for( l = names; l; l = l->next ) {
274                         PyList_SET_ITEM( list, counter,
275                                         PyString_FromString( ( char * ) l->link ) );
276                         counter++;
277                 }
278                 BLI_linklist_free( names, free );       /* free linklist *and* each node's data */
279         } else {
280                 list = PyList_New( 0 );
281         }
282
283         return list;
284 }
285
286 /**
287  * Return a list with the names of all linkable groups in the
288  * open library file.
289  */
290 static PyObject *M_Library_LinkableGroups( PyObject * self )
291 {
292         LinkNode *l = NULL, *names = NULL;
293         PyObject *list = NULL;
294
295         if( !bpy_openlib ) {
296                 return EXPP_ReturnPyObjError( PyExc_IOError,
297                                               "no library file: open one first with Blender.Lib_Open(filename)" );
298         }
299
300         names = BLO_blendhandle_get_linkable_groups( bpy_openlib );
301         list = PyList_New( BLI_linklist_length( names ) );
302         
303         if( names ) {
304                 int counter = 0;
305                 
306                 for( l = names; l; l = l->next ) {
307                         PyList_SET_ITEM( list, counter, PyString_FromString( ( char * ) l->link  ) );
308                         counter++;
309                 }
310                 BLI_linklist_free( names, free );       /* free linklist *and* each node's data */
311                 return list;
312         }
313         return list;
314 }
315
316 /**
317  * Return a list with the names of all externally linked libs used in the current Blend file
318  */
319 static PyObject *M_Library_LinkedLibs( PyObject * self )
320 {
321         int counter = 0;
322         Library *li;
323         PyObject *list;
324
325         list = PyList_New( BLI_countlist( &( G.main->library ) ) );
326         for (li= G.main->library.first; li; li= li->id.next) {
327                 PyList_SET_ITEM( list, counter, PyString_FromString( li->name ));
328                 counter++;
329         }
330         return list;
331 }
332
333 /**
334  * Load (append) a given datablock of a given datablock type
335  * to the current scene.
336  */
337 static PyObject *oldM_Library_Load( PyObject * self, PyObject * args )
338 {
339         char *name = NULL;
340         char *base = NULL;
341         int update = 1;
342         int blocktype = 0;
343         int linked = 0;
344
345         
346         if( !bpy_openlib ) {
347                 return EXPP_ReturnPyObjError( PyExc_IOError,
348                                               "no library file: you need to open one, first." );
349         }
350
351         if( !PyArg_ParseTuple( args, "ss|ii", &name, &base, &update, &linked ) ) {
352                 return EXPP_ReturnPyObjError( PyExc_TypeError,
353                                               "expected two strings as arguments." );
354         }
355
356         blocktype = ( int ) BLO_idcode_from_name( base );
357
358         if( !blocktype )
359                 return EXPP_ReturnPyObjError( PyExc_NameError,
360                                               "no such Blender datablock type" );
361
362         if (linked)
363                 BLO_script_library_append( &bpy_openlib, bpy_openlibname, name, blocktype, FILE_LINK, G.scene);
364         else
365                 BLO_script_library_append( &bpy_openlib, bpy_openlibname, name, blocktype, 0, G.scene);
366
367         /*
368                 NOTE:  BLO_script_library_append() can close the library if there is
369                 an endian issue.  if this happened, reopen for the next call.
370         */
371         if ( !bpy_openlib )
372                 bpy_openlib = BLO_blendhandle_from_file( bpy_openlibname );
373
374         if( update ) {
375                 M_Library_Update( self );
376                 Py_DECREF( Py_None );   /* incref'ed by above function */
377         }
378         
379         if( bpy_relative ) {
380                 /* and now find the latest append lib file */
381                 Library *lib = G.main->library.first;
382                 while( lib ) {
383                         if( strcmp( bpy_openlibname, lib->name ) == 0 ) {
384                                 
385                                 /* use the full path, this could have been read by other library even */
386                                 BLI_strncpy(lib->name, lib->filename, sizeof(lib->name));
387                 
388                                 /* uses current .blend file as reference */
389                                 BLI_makestringcode(G.sce, lib->name);
390                                 break;
391                         }
392                         lib = lib->id.next;
393                 }
394                 
395         }
396
397         Py_INCREF( Py_None );
398         return Py_None;
399 }
400
401 /**
402  * Update all links and remake displists.
403  */
404 static PyObject *M_Library_Update( PyObject * self )
405 {                               /* code adapted from do_library_append in src/filesel.c: */
406         Library *lib = NULL;
407
408                 /* Displist code that was here is obsolete... depending on what
409                  * this function is supposed to do (it should technically be unnecessary)
410                  * can be replaced with depgraph calls - zr
411                  */
412
413         if( bpy_openlibname ) {
414                 strcpy( G.lib, bpy_openlibname );
415
416                 /* and now find the latest append lib file */
417                 lib = G.main->library.first;
418                 while( lib ) {
419                         if( strcmp( bpy_openlibname, lib->name ) == 0 )
420                                 break;
421                         lib = lib->id.next;
422                 }
423                 all_local( lib, 0 );
424         }
425
426         Py_INCREF( Py_None );
427         return Py_None;
428 }
429
430 /**
431  * Initialize the Blender.Library submodule.
432  * Called by Blender_Init in Blender.c .
433  * @return the registered submodule.
434  */
435 PyObject *oldLibrary_Init( void )
436 {
437         PyObject *submod;
438
439         submod = Py_InitModule3( "Blender.Library", oldM_Library_methods,
440                                  M_Library_doc );
441
442         return submod;
443 }
444
445 /************************************************************/
446 /* New library (LibData) module code                        */
447 /************************************************************/
448
449 #include "Library.h"
450
451 /* if this module supercedes the old library module, include these instead */
452 #if 0
453 #include "BLI_blenlib.h"
454 #include "MEM_guardedalloc.h"
455
456 #include "DNA_curve_types.h"
457 #include "DNA_object_types.h"
458 #include "DNA_space_types.h" /* for line linked */
459 #include "BKE_library.h"        /* for all_local */
460 #include "BKE_utildefines.h"
461 #include "BKE_global.h"
462 #include "BKE_main.h"
463 #include "BLO_readfile.h"
464 #include "BLI_linklist.h"
465
466 #include "Object.h"
467 #include "gen_utils.h"
468 #endif
469
470 #include "gen_library.h"
471
472 /* Helper function */
473
474 /*
475  * Try to open a library, set Python exceptions as necessary if not
476  * successful.  On success, return a valid handle; othewise return NULL.
477  */
478
479 static BlendHandle *open_library( char *filename, char *longFilename )
480 {
481         char globalFilename[FILE_MAX];
482         BlendHandle *openlib = NULL;
483
484         /* get complete file name if necessary */
485         BLI_strncpy( longFilename, filename, FILE_MAX ); 
486         BLI_convertstringcode( longFilename, G.sce );
487
488         /* throw exceptions for wrong file type, cyclic reference */
489         if( !BLO_has_bfile_extension(longFilename) ) {
490                 PyErr_SetString( PyExc_ValueError, "file not a library" );
491                 return NULL;
492         }
493         if( BLI_streq(G.main->name, longFilename) ) {
494                 PyErr_SetString( PyExc_ValueError,
495                                 "cannot use current file as library" );
496                 return NULL;
497         }
498
499         /* G.sce = last file loaded, save for UI and restore after opening file */
500         BLI_strncpy(globalFilename, G.sce, sizeof(globalFilename));
501         openlib = BLO_blendhandle_from_file( longFilename );
502         BLI_strncpy(G.sce, globalFilename, sizeof(globalFilename)); 
503
504         /* if failed, set that exception code too */
505         if( !openlib )
506                 PyErr_SetString( PyExc_IOError, "library not found" );
507
508         return openlib;
509 }
510
511 /*
512  * Create a specific type of LibraryData object.  These are used for
513  * .append() and .link() access, for iterators, and (for Blender Objects)
514  * for defining "pseudo objects" for scene linking.
515  */
516
517 static PyObject *CreatePyObject_LibData( int idtype, int kind,
518                 void *name, void *iter, char *filename, int rel )
519 {
520         BPy_LibraryData *seq = PyObject_NEW( BPy_LibraryData, &LibraryData_Type);
521         seq->iter = iter;               /* the name list (for iterators) */
522         seq->type = idtype;             /* the Blender ID type */
523         seq->rel =  rel;                /* relative or absolute library */
524         seq->kind = kind;               /* used by Blender Objects */
525         seq->name = name;               /* object name, iterator name list, or NULL */
526                                                         /* save the library name */
527         BLI_strncpy( seq->filename, filename, strlen(filename)+1 );
528         return (PyObject *)seq;
529 }
530
531 /* 
532  * Link/append data to the current .blend file, or create a pseudo object
533  * which can be linked/appended to a scene.
534  */
535
536 static PyObject *lib_link_or_append( BPy_LibraryData *self, PyObject * value,
537                 int mode )
538 {
539         char *name = PyString_AsString(value);
540
541         /* get the name of the data used wants to append */
542         if( !name )
543                 return EXPP_ReturnPyObjError( PyExc_TypeError,
544                         "expected a string" );
545
546         /* 
547          * For everything except objects, just add to Blender's DB.  For objects,
548          * create an APPEND or LINK "pseudo object" for the Scene module.
549          */
550         if( self->type != ID_OB )
551                 return LibraryData_importLibData( self, name, 0, NULL );
552         else {
553                 /*
554                  * If this is already a pseudo object, throw an exception: re-linking
555                  * or re-appending is not allowed
556                  */
557                 if( self->kind != OTHER ) 
558                         return EXPP_ReturnPyObjError( PyExc_ValueError,
559                                 "object has already been marked for append or link" );
560
561                 /* otherwise, create a pseudo object ready for appending or linking */
562
563                 return CreatePyObject_LibData( ID_OB, mode, 
564                                 BLI_strdupn( name, strlen( name ) ), NULL, self->filename,
565                                 self->rel );
566         }
567 }
568
569 /*
570  * Perform the actual link or append operation.  This procedure is also
571  * called externally from the Scene module using a "pseudo Object" so we
572  * can be sure objects get linked to a scene.
573  */
574
575 PyObject *LibraryData_importLibData( BPy_LibraryData *self, char *name,
576                 int mode, Scene *scene )
577 {
578         char longFilename[FILE_MAX];
579         BlendHandle *openlib;
580         Library *lib;
581         LinkNode *names, *ptr;
582         ID *id;
583         ListBase *lb;
584         char newName[32];
585
586         /* try to open the library */
587         openlib = open_library( self->filename, longFilename );
588         if( !openlib )
589                 return NULL;
590
591         /* fix any /foo/../foo/ */
592         BLI_cleanup_file(NULL, longFilename); 
593
594         /* find all datablocks for the specified type */
595         names = BLO_blendhandle_get_datablock_names ( openlib, self->type ); 
596
597         /* now check for a match to the user-specified name */
598         for( ptr = names; ptr; ptr = ptr->next )
599                 if( strcmp( ptr->link, name ) == 0 ) break;
600         BLI_linklist_free( names, free );
601
602         /* if no match, throw exception */
603         if( !ptr ) {
604                 BLO_blendhandle_close( openlib );
605                 return EXPP_ReturnPyObjError( PyExc_ValueError,
606                                 "library does not contain specified item" );
607         }
608
609         /*
610          * Figure out what the datablock will be named after it's imported.  If
611          * it's a link, nothing to do.  If it's an append, find what it might
612          * be renamed to.
613          */
614
615         if( mode != FILE_LINK ) {
616                 flag_all_listbases_ids(LIB_APPEND_TAG, 1);
617
618                 /* see what new block will be called */
619                 strncpy( newName, name, strlen(name)+1 );
620                 check_for_dupid( wich_libbase(G.main, self->type), NULL, newName );
621         }
622
623         /* import from the libary */
624         BLO_script_library_append( &openlib, longFilename, name, self->type, 
625                         mode | self->rel, scene );
626
627         /*
628          * locate the library.  If this is an append, make the data local.  If it
629          * is link, we need the library for later
630          */
631         for( lib = G.main->library.first; lib; lib = lib->id.next )
632                 if( strcmp( longFilename, lib->filename ) == 0) {
633                         if( mode != FILE_LINK ) {
634                                 all_local( lib, 1 );
635                                 /* important we unset, otherwise these object wont
636                                  * link into other scenes from this blend file */
637                                 flag_all_listbases_ids(LIB_APPEND_TAG, 0);
638                         }
639                         break;
640                 }
641
642         /* done with library; close it */
643         BLO_blendhandle_close( openlib );
644
645         /* this should not happen, but just in case */
646         if( !lib )
647                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
648                                 "could not library" );
649
650         /* find the base for this type */
651         lb = wich_libbase( G.main, self->type );
652
653         /*
654          * Check for linked data matching the name first.  Even if we are trying
655          * to append, if the data has already been linked we need to return it
656          * (it won't be appended from the library).
657          */
658         for( id = lb->first; id; id = id->next ) {
659                 if( id->lib == lib && id->name[2]==name[0] &&
660                                 strcmp(id->name+2, name)==0 )
661                         return GetPyObjectFromID( id );
662         }
663
664         /*
665          * If we didn't find it, and we're appending, then try searching for the
666          * new datablock, possibly under a new name.
667          */
668         if( mode != FILE_LINK )
669                 for( id = lb->first; id; id = id->next ) {
670                         if( id->lib == NULL && id->name[2]==newName[0] &&
671                                         strcmp(id->name+2, newName)==0 )
672                                 return GetPyObjectFromID( id );
673                 }
674
675         /* if we get here, something's really wrong */
676         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
677                         "could not find data after reading from library" );
678 }
679
680 /************************************************************
681  * Python LibraryData_Type getseters
682  ************************************************************/
683
684 /* .append(): make a local copy of the library's data (except for objects) */
685
686 static PyObject *LibraryData_getAppend( BPy_LibraryData *self, PyObject * value)
687 {
688         return lib_link_or_append( self, value, OBJECT_IS_APPEND );
689 }
690
691 /* .link(): make a link to the library's data (except for objects) */
692
693 static PyObject *LibraryData_getLink( BPy_LibraryData *self, PyObject * value)
694 {
695         return lib_link_or_append( self, value, OBJECT_IS_LINK );
696 }
697
698 /************************************************************************
699  * Python LibraryData_Type iterator
700  ************************************************************************/
701
702 /* Create and initialize the interator indices */
703
704 static PyObject *LibraryData_getIter( BPy_LibraryData * self )
705 {
706         char longFilename[FILE_MAX];
707         BlendHandle *openlib;
708         LinkNode *names;
709
710         /* try to open library */
711         openlib = open_library( self->filename, longFilename );
712
713         /* if failed, return exception */
714         if( !openlib )
715                 return NULL;
716
717         /* find all datablocks for the specified type */
718         names = BLO_blendhandle_get_datablock_names ( openlib, self->type ); 
719
720         /* close library*/
721         BLO_blendhandle_close( openlib );
722
723         /* build an iterator object for the name list */
724         return CreatePyObject_LibData( self->type, OTHER, names,
725                         names, self->filename, self->rel );
726 }
727
728 /* Return next name. */
729
730 static PyObject *LibraryData_nextIter( BPy_LibraryData * self )
731 {
732         LinkNode *ptr = (LinkNode *)self->iter;
733         PyObject *ob;
734
735         /* if at the end of list, clean up */
736         if( !ptr ) {
737                 /* If name list is still allocated, free storage.  This check is
738                  * necessary since iter.next() can technically be called repeatedly */
739                 if( self->name ) {
740                         BLI_linklist_free( (LinkNode *)self->name, free );
741                         self->name = NULL;
742                 }
743                 return EXPP_ReturnPyObjError( PyExc_StopIteration,
744                                 "iterator at end" );
745         }
746
747         /* otherwise, return the next name in the list */
748         ob = PyString_FromString( ptr->link );
749         ptr = ptr->next;
750         self->iter = ptr;
751         return ob;
752 }
753
754 /************************************************************************
755  * Python LibraryData_type methods structure
756  ************************************************************************/
757
758 static struct PyMethodDef BPy_LibraryData_methods[] = {
759         {"append", (PyCFunction)LibraryData_getAppend, METH_O,
760          "(str) - create new data from library"},
761         {"link", (PyCFunction)LibraryData_getLink, METH_O,
762          "(str) - link data from library"},
763         {NULL, NULL, 0, NULL}
764 };
765
766 /* Deallocate object and its data */
767
768 static void LibraryData_dealloc( BPy_LibraryData * self )
769 {
770         if( self->name )
771                 MEM_freeN( self->name );
772
773         PyObject_DEL( self );
774 }
775
776 /* Display representation of what Library Data is wrapping */
777
778 static PyObject *LibraryData_repr( BPy_LibraryData * self )
779 {
780         char *linkstate = "";
781         char *str;
782
783         switch (self->type) {
784         case ID_OB:
785                 /* objects can be lib data or pseudo objects */
786                 switch( self->kind ) {
787                 case OBJECT_IS_APPEND :
788                         linkstate = ", appended";
789                         break;
790                 case OBJECT_IS_LINK :
791                         linkstate = ", linked";
792                         break;
793                 default:
794                         break;
795                 }
796                 str = "Object";
797                 break;
798         case ID_SCE:
799                 str = "Scene";
800                 break;
801         case ID_ME:
802                 str = "Mesh";
803                 break;
804         case ID_CU:
805                 str = "Curve";
806                 break;
807         case ID_MB:
808                 str = "Metaball";
809                 break;
810         case ID_MA:
811                 str = "Material";
812                 break;
813         case ID_TE:
814                 str = "Texture";
815                 break;
816         case ID_IM: 
817                 str = "Image";
818                 break;
819         case ID_LT:
820                 str = "Lattice";
821                 break;
822         case ID_LA:
823                 str = "Lamp";
824                 break;
825         case ID_CA:
826                 str = "Camera";
827                 break;
828         case ID_IP:
829                 str = "Ipo";
830                 break;
831         case ID_WO:
832                 str = "World";
833                 break;
834         case ID_VF:
835                 str = "Font";
836                 break;
837         case ID_TXT:
838                 str = "Text";
839                 break;
840         case ID_SO:
841                 str = "Sound";
842                 break;
843         case ID_GR:     
844                 str = "Group";
845                 break;
846         case ID_AR:
847                 str = "Armature";
848                 break;
849         case ID_AC:
850                 str = "Action";
851                 break;
852         default:
853                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
854                                 "unsupported ID type" );
855         }
856
857         return PyString_FromFormat( "[Library Data (%s%s)]", str, linkstate );
858 }
859
860 PyTypeObject LibraryData_Type = {
861         PyObject_HEAD_INIT( NULL )  /* required py macro */
862         0,                          /* ob_size */
863         /*  For printing, in format "<module>.<name>" */
864         "Blender LibData",          /* char *tp_name; */
865         sizeof( BPy_LibraryData ),  /* int tp_basicsize; */
866         0,                          /* tp_itemsize;  For allocation */
867
868         /* Methods to implement standard operations */
869
870         ( destructor ) LibraryData_dealloc,/* destructor tp_dealloc; */
871         NULL,                       /* printfunc tp_print; */
872         NULL,                       /* getattrfunc tp_getattr; */
873         NULL,                       /* setattrfunc tp_setattr; */
874         ( cmpfunc ) NULL,           /* cmpfunc tp_compare; */
875         ( reprfunc ) LibraryData_repr, /* reprfunc tp_repr; */
876
877         /* Method suites for standard classes */
878
879         NULL,                       /* PyNumberMethods *tp_as_number; */
880         NULL,                       /* PySequenceMethods *tp_as_sequence; */
881         NULL,                       /* PyMappingMethods *tp_as_mapping; */
882
883         /* More standard operations (here for binary compatibility) */
884
885         NULL,                       /* hashfunc tp_hash; */
886         NULL,                       /* ternaryfunc tp_call; */
887         NULL,                       /* reprfunc tp_str; */
888         NULL,                       /* getattrofunc tp_getattro; */
889         NULL,                       /* setattrofunc tp_setattro; */
890
891         /* Functions to access object as input/output buffer */
892         NULL,                       /* PyBufferProcs *tp_as_buffer; */
893
894   /*** Flags to define presence of optional/expanded features ***/
895         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
896
897         NULL,                       /*  char *tp_doc;  Documentation string */
898   /*** Assigned meaning in release 2.0 ***/
899         /* call function for all accessible objects */
900         NULL,                       /* traverseproc tp_traverse; */
901
902         /* delete references to contained objects */
903         NULL,                       /* inquiry tp_clear; */
904
905   /***  Assigned meaning in release 2.1 ***/
906   /*** rich comparisons ***/
907         NULL,                       /* richcmpfunc tp_richcompare; */
908
909   /***  weak reference enabler ***/
910         0,                          /* long tp_weaklistoffset; */
911
912   /*** Added in release 2.2 ***/
913         /*   Iterators */
914         (getiterfunc)LibraryData_getIter, /* getiterfunc tp_iter; */
915         (iternextfunc)LibraryData_nextIter, /* iternextfunc tp_iternext; */
916
917   /*** Attribute descriptor and subclassing stuff ***/
918         BPy_LibraryData_methods,    /* struct PyMethodDef *tp_methods; */
919         NULL,                       /* struct PyMemberDef *tp_members; */
920         NULL,                       /* struct PyGetSetDef *tp_getset; */
921         NULL,                       /* struct _typeobject *tp_base; */
922         NULL,                       /* PyObject *tp_dict; */
923         NULL,                       /* descrgetfunc tp_descr_get; */
924         NULL,                       /* descrsetfunc tp_descr_set; */
925         0,                          /* long tp_dictoffset; */
926         NULL,                       /* initproc tp_init; */
927         NULL,                       /* allocfunc tp_alloc; */
928         NULL,                       /* newfunc tp_new; */
929         /*  Low-level free-memory routine */
930         NULL,                       /* freefunc tp_free;  */
931         /* For PyObject_IS_GC */
932         NULL,                       /* inquiry tp_is_gc;  */
933         NULL,                       /* PyObject *tp_bases; */
934         /* method resolution order */
935         NULL,                       /* PyObject *tp_mro;  */
936         NULL,                       /* PyObject *tp_cache; */
937         NULL,                       /* PyObject *tp_subclasses; */
938         NULL,                       /* PyObject *tp_weaklist; */
939         NULL
940 };
941
942 /*
943  * Create a LibraryData object for a specific type of Blender Group (ID_OB,
944  * ID_MA, etc).  These can then be used to link or append the data.
945  */
946
947 static PyObject *LibraryData_CreatePyObject( BPy_Library *self, void *mode )
948 {
949         return CreatePyObject_LibData( GET_INT_FROM_POINTER(mode), OTHER, NULL, NULL,
950                         self->filename, self->rel);
951 }
952
953 /************************************************************
954  * Python Library_Type getseters
955  ************************************************************/
956
957 /*
958  * Return the library's filename.
959  */
960
961 static PyObject *Library_getFilename( BPy_Library * self )
962 {
963         return PyString_FromString( self->filename );
964 }
965
966 /*
967  * Set/change the library's filename.
968  */
969
970 static int Library_setFilename( BPy_Library * self, PyObject * args )
971 {
972         char *filename = PyString_AsString( args );
973         if( !filename )
974                 return EXPP_ReturnIntError( PyExc_TypeError, "expected a string" );
975
976         BLI_strncpy( self->filename, filename, sizeof(self->filename) );
977         return 0;
978 }
979
980 /*
981  * Return the library's name.  The format depends on whether the library is 
982  * accessed as relative or absolute.
983  */
984
985 static PyObject *Library_getName( BPy_Library * self )
986 {
987         Library *lib;
988         BlendHandle *openlib;
989         char longFilename[FILE_MAX];
990
991         /* try to open the library */
992         openlib = open_library( self->filename, longFilename );
993         if( openlib ) {
994                 BLO_blendhandle_close( openlib );
995                 /* remove any /../ or /./ junk */
996                 BLI_cleanup_file(NULL, longFilename); 
997
998                 /* search the loaded libraries for a match */
999                 for( lib = G.main->library.first; lib; lib = lib->id.next )
1000                         if( strcmp( longFilename, lib->filename ) == 0) {
1001                                 return PyString_FromString( lib->name );
1002                         }
1003
1004                 /* library not found in memory */
1005                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1006                                 "library not loaded" );
1007         }
1008         /* could not load library */
1009         return EXPP_ReturnPyObjError( PyExc_IOError, "library not found" );
1010 }
1011
1012
1013 /************************************************************************
1014  * Python Library_type attributes get/set structure
1015  ************************************************************************/
1016
1017 static PyGetSetDef Library_getseters[] = {
1018         {"filename",
1019          (getter)Library_getFilename, (setter)Library_setFilename,
1020          "library filename",
1021          NULL},
1022         {"name",
1023          (getter)Library_getName, (setter)NULL,
1024          "library name (as used by Blender)",
1025          NULL},
1026         {"objects",
1027          (getter)LibraryData_CreatePyObject, (setter)NULL,
1028          "objects from the library",
1029          (void *)ID_OB},
1030         {"scenes",
1031          (getter)LibraryData_CreatePyObject, (setter)NULL,
1032          "scenes from the library",
1033          (void *)ID_SCE},
1034         {"meshes",
1035          (getter)LibraryData_CreatePyObject, (setter)NULL,
1036          "meshes from the library",
1037          (void *)ID_ME},
1038         {"curves",
1039          (getter)LibraryData_CreatePyObject, (setter)NULL,
1040          "curves from the library",
1041          (void *)ID_CU},
1042         {"metaballs",
1043          (getter)LibraryData_CreatePyObject, (setter)NULL,
1044          "metaballs from the library",
1045          (void *)ID_MB},
1046         {"lattices",
1047          (getter)LibraryData_CreatePyObject, (setter)NULL,
1048          "lattices from the library",
1049          (void *)ID_LT},
1050         {"lamps",
1051          (getter)LibraryData_CreatePyObject, (setter)NULL,
1052          "lamps from the library",
1053          (void *)ID_LA},
1054         {"cameras",
1055          (getter)LibraryData_CreatePyObject, (setter)NULL,
1056          "cameras from the library",
1057          (void *)ID_CA},
1058         {"materials",
1059          (getter)LibraryData_CreatePyObject, (setter)NULL,
1060          "objects from the library",
1061          (void *)ID_MA},
1062         {"textures",
1063          (getter)LibraryData_CreatePyObject, (setter)NULL,
1064          "textures from the library",
1065          (void *)ID_TE},
1066         {"images",
1067          (getter)LibraryData_CreatePyObject, (setter)NULL,
1068          "images from the library",
1069          (void *)ID_IM},
1070         {"ipos",
1071          (getter)LibraryData_CreatePyObject, (setter)NULL,
1072          "ipos from the library",
1073          (void *)ID_IP},
1074         {"worlds",
1075          (getter)LibraryData_CreatePyObject, (setter)NULL,
1076          "worlds from the library",
1077          (void *)ID_WO},
1078         {"fonts",
1079          (getter)LibraryData_CreatePyObject, (setter)NULL,
1080          "fonts from the library",
1081          (void *)ID_VF},
1082         {"texts",
1083          (getter)LibraryData_CreatePyObject, (setter)NULL,
1084          "texts from the library",
1085          (void *)ID_TXT},
1086         {"groups",
1087          (getter)LibraryData_CreatePyObject, (setter)NULL,
1088          "groups from the library",
1089          (void *)ID_GR},
1090         {"sounds",
1091          (getter)LibraryData_CreatePyObject, (setter)NULL,
1092          "sounds from the library",
1093          (void *)ID_SO},
1094         {"actions",
1095          (getter)LibraryData_CreatePyObject, (setter)NULL,
1096          "actions from the library",
1097          (void *)ID_AC},
1098         {"armatures",
1099          (getter)LibraryData_CreatePyObject, (setter)NULL,
1100          "armatures from the library",
1101          (void *)ID_AR},
1102         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
1103 };
1104
1105 /*
1106  * Define a new library and create a library object.  We don't actually test
1107  * if the library is valid here since we have to do it when the file is
1108  * actually accessed later. 
1109  */
1110
1111 static PyObject *M_Library_Load(PyObject *self, PyObject * args)
1112 {
1113         char *filename = NULL;
1114         PyObject *relative = NULL;
1115         BPy_Library *lib;
1116
1117         if( !PyArg_ParseTuple( args, "s|O", &filename, &relative ) )
1118                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1119                         "expected strings and optional bool as arguments." );
1120
1121         /* try to create a new object */
1122         lib = (BPy_Library *)PyObject_NEW( BPy_Library, &Library_Type );
1123         if( !lib )
1124                 return NULL;
1125
1126         /* save relative flag value */
1127         if( relative && PyObject_IsTrue(relative) )
1128                 lib->rel = FILE_STRINGCODE;
1129         else
1130                 lib->rel = 0;
1131
1132         /* assign the library filename for future use, then return */
1133         BLI_strncpy( lib->filename, filename, sizeof(lib->filename) );
1134
1135         return (PyObject *)lib;
1136 }
1137
1138 static struct PyMethodDef M_Library_methods[] = {
1139         {"load", (PyCFunction)M_Library_Load, METH_VARARGS,
1140         "(string) - declare a .blend file for use as a library"},
1141         {NULL, NULL, 0, NULL}
1142 };
1143
1144 /*****************************************************************************/
1145 /* Python Library_Type structure definition:                               */
1146 /*****************************************************************************/
1147 PyTypeObject Library_Type = {
1148         PyObject_HEAD_INIT( NULL )  /* required py macro */
1149         0,                          /* ob_size */
1150         /*  For printing, in format "<module>.<name>" */
1151         "Blender Library",          /* char *tp_name; */
1152         sizeof( BPy_Library ),      /* int tp_basicsize; */
1153         0,                          /* tp_itemsize;  For allocation */
1154
1155         /* Methods to implement standard operations */
1156
1157         NULL,                       /* destructor tp_dealloc; */
1158         NULL,                       /* printfunc tp_print; */
1159         NULL,                       /* getattrfunc tp_getattr; */
1160         NULL,                       /* setattrfunc tp_setattr; */
1161         ( cmpfunc ) NULL,           /* cmpfunc tp_compare; */
1162         ( reprfunc ) NULL,          /* reprfunc tp_repr; */
1163
1164         /* Method suites for standard classes */
1165
1166         NULL,                       /* PyNumberMethods *tp_as_number; */
1167         NULL,                       /* PySequenceMethods *tp_as_sequence; */
1168         NULL,                       /* PyMappingMethods *tp_as_mapping; */
1169
1170         /* More standard operations (here for binary compatibility) */
1171
1172         NULL,                       /* hashfunc tp_hash; */
1173         NULL,                       /* ternaryfunc tp_call; */
1174         NULL,                       /* reprfunc tp_str; */
1175         NULL,                       /* getattrofunc tp_getattro; */
1176         NULL,                       /* setattrofunc tp_setattro; */
1177
1178         /* Functions to access object as input/output buffer */
1179         NULL,                       /* PyBufferProcs *tp_as_buffer; */
1180
1181   /*** Flags to define presence of optional/expanded features ***/
1182         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
1183
1184         NULL,                       /*  char *tp_doc;  Documentation string */
1185   /*** Assigned meaning in release 2.0 ***/
1186         /* call function for all accessible objects */
1187         NULL,                       /* traverseproc tp_traverse; */
1188
1189         /* delete references to contained objects */
1190         NULL,                       /* inquiry tp_clear; */
1191
1192   /***  Assigned meaning in release 2.1 ***/
1193   /*** rich comparisons ***/
1194         NULL,                       /* richcmpfunc tp_richcompare; */
1195
1196   /***  weak reference enabler ***/
1197         0,                          /* long tp_weaklistoffset; */
1198
1199   /*** Added in release 2.2 ***/
1200         /*   Iterators */
1201         NULL,                       /* getiterfunc tp_iter; */
1202         NULL,                       /* iternextfunc tp_iternext; */
1203
1204   /*** Attribute descriptor and subclassing stuff ***/
1205         NULL,                       /* struct PyMethodDef *tp_methods; */
1206         NULL,                       /* struct PyMemberDef *tp_members; */
1207         Library_getseters,          /* struct PyGetSetDef *tp_getset; */
1208         NULL,                       /* struct _typeobject *tp_base; */
1209         NULL,                       /* PyObject *tp_dict; */
1210         NULL,                       /* descrgetfunc tp_descr_get; */
1211         NULL,                       /* descrsetfunc tp_descr_set; */
1212         0,                          /* long tp_dictoffset; */
1213         NULL,                       /* initproc tp_init; */
1214         NULL,                       /* allocfunc tp_alloc; */
1215         NULL,                       /* newfunc tp_new; */
1216         /*  Low-level free-memory routine */
1217         NULL,                       /* freefunc tp_free;  */
1218         /* For PyObject_IS_GC */
1219         NULL,                       /* inquiry tp_is_gc;  */
1220         NULL,                       /* PyObject *tp_bases; */
1221         /* method resolution order */
1222         NULL,                       /* PyObject *tp_mro;  */
1223         NULL,                       /* PyObject *tp_cache; */
1224         NULL,                       /* PyObject *tp_subclasses; */
1225         NULL,                       /* PyObject *tp_weaklist; */
1226         NULL
1227 };
1228
1229 /*
1230  * Library module initialization
1231  */
1232
1233 static char M_newLibrary_doc[] = "The Blender.lib submodule";
1234
1235 PyObject *Library_Init( void )
1236 {
1237         PyObject *submodule;
1238
1239         if( PyType_Ready( &Library_Type ) < 0 )
1240                 return NULL;
1241         if( PyType_Ready( &LibraryData_Type ) < 0 )
1242                 return NULL;
1243
1244         submodule = Py_InitModule3( "Blender.lib", M_Library_methods,
1245                         M_newLibrary_doc );
1246         return submodule;
1247 }