2.5
authorTon Roosendaal <ton@blender.org>
Mon, 20 Apr 2009 10:13:55 +0000 (10:13 +0000)
committerTon Roosendaal <ton@blender.org>
Mon, 20 Apr 2009 10:13:55 +0000 (10:13 +0000)
Patch from Joshua, converting Grease Pencil to 2.5.
All GP data now is an ID block, allowing re-use, link and append.
For better contextual control within 2.5, these GP ID's will get
linked to actual data, like NodeTrees, Scenes, Images or Objects.
That will ensure Undo works, and opens up exciting new use cases
as well. :)

Patch note: on reading files, GPencils linked from editors will
get moved to the main library, using standard naming (indicating
where it was used), and with "Fake User" set. That way the user
can manually relink the pencils where appropriate.
We can check on just linking GP to some default, like 3d window
pencils to Scene? Nice to experiment with.

Notes for Joshua:
- for reading old GPencil, it has to use old code as well, meaning
  to tread data as "indirect data, within another ID".
- Saving ID data means the chunk in file BHead needs the ID_GD code,
  and not "DATA", which indicates 'indirect data'. That's the file
  format spec.
- I've added do_versions_gpencil_2_50(), feel free to further tweak
  things here, like linking things to scene or so.
- Formerly GPencil saved 2.50 files won't convert gpencil

source/blender/blenkernel/BKE_main.h
source/blender/blenkernel/intern/library.c
source/blender/blenloader/intern/readblenentry.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/gpencil/drawgpencil.c
source/blender/editors/gpencil/editaction_gpencil.c
source/blender/editors/gpencil/gpencil_intern.h
source/blender/editors/include/ED_gpencil.h
source/blender/makesdna/DNA_ID.h
source/blender/makesdna/DNA_gpencil_types.h

index 30cf800a3d8c47fcb27a9405496876c90524ba78..6881bdfdb2cdba1254a18574c954ff4e21b3a9f0 100644 (file)
@@ -77,6 +77,7 @@ typedef struct Main {
        ListBase brush;
        ListBase particle;
        ListBase wm;
+       ListBase gpencil;
 } Main;
 
 
index 0712b53c5dd058af81955f92d80d1b37144e4239..5728b844a883dfcec586bbb21ef8c5bf9d85438f 100644 (file)
@@ -79,6 +79,7 @@
 #include "DNA_space_types.h"
 #include "DNA_windowmanager_types.h"
 #include "DNA_anim_types.h"
+#include "DNA_gpencil_types.h"
 
 #include "BLI_blenlib.h"
 #include "BLI_dynstr.h"
 #include "BKE_brush.h"
 #include "BKE_idprop.h"
 #include "BKE_particle.h"
+#include "BKE_gpencil.h"
 
 #define MAX_IDPUP              60      /* was 24 */
 
@@ -199,6 +201,8 @@ ListBase *wich_libbase(Main *mainlib, short type)
                        return &(mainlib->particle);
                case ID_WM:
                        return &(mainlib->wm);
+               case ID_GD:
+                       return &(mainlib->gpencil);
        }
        return 0;
 }
@@ -269,6 +273,7 @@ int set_listbasepointers(Main *main, ListBase **lb)
        lb[a++]= &(main->scene);
        lb[a++]= &(main->library);
        lb[a++]= &(main->wm);
+       lb[a++]= &(main->gpencil);
        
        lb[a]= NULL;
 
@@ -374,6 +379,9 @@ static ID *alloc_libblock_notest(short type)
                case ID_WM:
                        id = MEM_callocN(sizeof(wmWindowManager), "Window manager");
                        break;
+               case ID_GD:
+                       id = MEM_callocN(sizeof(bGPdata), "Grease Pencil");
+                       break;
        }
        return id;
 }
@@ -577,6 +585,9 @@ void free_libblock(ListBase *lb, void *idv)
                        if(free_windowmanager_cb)
                                free_windowmanager_cb(NULL, (wmWindowManager *)id);
                        break;
+               case ID_GD:
+                       free_gpencil_data((bGPdata *)id);
+                       break;
        }
 
        if (id->properties) {
@@ -986,14 +997,15 @@ static void lib_indirect_test_id(ID *id)
        
        if(id->lib)
                return;
-
+       
        if(GS(id->name)==ID_OB) {               
                Object *ob= (Object *)id;
                bActionStrip *strip;
                Mesh *me;
 
                int a;
-
+       
+               // XXX old animation system!
                for (strip=ob->nlastrips.first; strip; strip=strip->next){
                        LIBTAG(strip->object); 
                        LIBTAG(strip->act);
index 23e334fbbd17df1e688169ac191673ca05e42a1c..0c8b8a6b31d25e142a165048c4441db16c134589 100644 (file)
@@ -86,6 +86,7 @@ static IDType idtypes[]= {
        { ID_BR,                "Brush",        IDTYPE_FLAGS_ISLINKABLE}, 
        { ID_CA,                "Camera",       IDTYPE_FLAGS_ISLINKABLE}, 
        { ID_CU,                "Curve",        IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_GD,                "GPencil",      IDTYPE_FLAGS_ISLINKABLE}, 
        { ID_GR,                "Group",        IDTYPE_FLAGS_ISLINKABLE}, 
        { ID_ID,                "ID",           0}, 
        { ID_IM,                "Image",        IDTYPE_FLAGS_ISLINKABLE}, 
index f74f09a11ee9d38e565d8a66d448b33f7da12b84..5ea83f0375f215658ff67341b3d1a126f7447565 100644 (file)
@@ -4065,8 +4065,8 @@ static void lib_link_windowmanager(FileData *fd, Main *main)
 
 /* ****************** READ GREASE PENCIL ***************** */
 
-/* relinks grease-pencil data for 3d-view(s) - used for direct_link */
-static void link_gpencil(FileData *fd, bGPdata *gpd)
+/* relinks grease-pencil data - used for direct_link and old file linkage */
+static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
 {
        bGPDlayer *gpl;
        bGPDframe *gpf;
@@ -4242,7 +4242,6 @@ static void lib_link_screen(FileData *fd, Main *main)
                                                        else if(GS(snode->id->name)==ID_TE)
                                                                snode->nodetree= ((Tex *)snode->id)->nodetree;
                                                }
-                                               
                                        }
                                }
                                sa= sa->next;
@@ -4353,7 +4352,7 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
                                                */
                                        }
                                        else if(v3d->scenelock) v3d->lay= sc->scene->lay;
-                                       
+
                                        /* not very nice, but could help */
                                        if((v3d->layact & v3d->lay)==0) v3d->layact= v3d->lay;
                                        
@@ -4592,7 +4591,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                        v3d->bgpic->iuser.ok= 1;
                                if(v3d->gpd) {
                                        v3d->gpd= newdataadr(fd, v3d->gpd);
-                                       link_gpencil(fd, v3d->gpd);
+                                       direct_link_gpencil(fd, v3d->gpd);
                                }
                                v3d->localvd= newdataadr(fd, v3d->localvd);
                                v3d->afterdraw.first= v3d->afterdraw.last= NULL;
@@ -4621,11 +4620,11 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                SpaceImage *sima= (SpaceImage *)sl;
                                
                                sima->cumap= newdataadr(fd, sima->cumap);
-                               if(sima->cumap)
-                                       direct_link_curvemapping(fd, sima->cumap);
                                sima->gpd= newdataadr(fd, sima->gpd);
                                if (sima->gpd)
-                                       link_gpencil(fd, sima->gpd);
+                                       direct_link_gpencil(fd, sima->gpd);
+                               if(sima->cumap)
+                                       direct_link_curvemapping(fd, sima->cumap);
                                sima->iuser.ok= 1;
                        }
                        else if(sl->spacetype==SPACE_NODE) {
@@ -4633,7 +4632,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                
                                if(snode->gpd) {
                                        snode->gpd= newdataadr(fd, snode->gpd);
-                                       link_gpencil(fd, snode->gpd);
+                                       direct_link_gpencil(fd, snode->gpd);
                                }
                                snode->nodetree= snode->edittree= NULL;
                        }
@@ -4641,7 +4640,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                SpaceSeq *sseq= (SpaceSeq *)sl;
                                if(sseq->gpd) {
                                        sseq->gpd= newdataadr(fd, sseq->gpd);
-                                       link_gpencil(fd, sseq->gpd);
+                                       direct_link_gpencil(fd, sseq->gpd);
                                }
                        }
                }
@@ -4818,6 +4817,7 @@ static char *dataname(short id_code)
                case ID_NT: return "Data from NT";
                case ID_BR: return "Data from BR";
                case ID_PA: return "Data from PA";
+               case ID_GD: return "Data from GD";
        }
        return "Data from Lib Block";
        
@@ -4974,6 +4974,9 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
                case ID_SCRIPT:
                        direct_link_script(fd, (Script*)id);
                        break;
+               case ID_GD:
+                       direct_link_gpencil(fd, (bGPdata *)id);
+                       break;
        }
        
        /*link direct data of ID properties*/
@@ -5677,6 +5680,64 @@ static void do_versions_windowmanager_2_50(bScreen *screen)
        }
 }
 
+static void versions_gpencil_add_main(ListBase *lb, ID *id, char *name)
+{
+       
+       BLI_addtail(lb, id);
+       id->us= 1;
+       id->flag= LIB_FAKEUSER;
+       *( (short *)id->name )= ID_GD;
+       
+       new_id(lb, id, name);
+       /* alphabetic insterion: is in new_id */
+       
+       if(G.f & G_DEBUG)
+               printf("Converted GPencil to ID: %s\n", id->name+2);
+}
+
+static void do_versions_gpencil_2_50(Main *main, bScreen *screen)
+{
+       ScrArea *sa;
+       SpaceLink *sl;
+       
+       /* add regions */
+       for(sa= screen->areabase.first; sa; sa= sa->next) {
+               sl= sa->spacedata.first;
+               for(sl; sl; sl= sl->next) {
+                       if (sl->spacetype==SPACE_VIEW3D) {
+                               View3D *v3d= (View3D*) sl;
+                               if(v3d->gpd) {
+                                       versions_gpencil_add_main(&main->gpencil, (ID *)v3d->gpd, "GPencil View3D");
+                                       v3d->gpd= NULL;
+                               }
+                       }
+                       else if (sl->spacetype==SPACE_NODE) {
+                               SpaceNode *snode= (SpaceNode *)sl;
+                               if(snode->gpd) {
+                                       versions_gpencil_add_main(&main->gpencil, (ID *)snode->gpd, "GPencil Node");
+                                       snode->gpd= NULL;
+                               }
+                       }
+                       else if (sl->spacetype==SPACE_SEQ) {
+                               SpaceSeq *sseq= (SpaceSeq *)sl;
+                               if(sseq->gpd) {
+                                       versions_gpencil_add_main(&main->gpencil, (ID *)sseq->gpd, "GPencil Node");
+                                       sseq->gpd= NULL;
+                               }
+                       }
+                       else if (sl->spacetype==SPACE_IMAGE) {
+                               SpaceImage *sima= (SpaceImage *)sl;
+                               if(sima->gpd) {
+                                       versions_gpencil_add_main(&main->gpencil, (ID *)sima->gpd, "GPencil Image");
+                                       sima->gpd= NULL;
+                               }
+                       }
+               }
+       }               
+}
+
+
+
 static void do_versions(FileData *fd, Library *lib, Main *main)
 {
        /* WATCH IT!!!: pointers from libdata have not been converted */
@@ -8748,8 +8809,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                Scene *sce;
                Tex *tx;
                
-               for(screen= main->screen.first; screen; screen= screen->id.next)
+               for(screen= main->screen.first; screen; screen= screen->id.next) {
                        do_versions_windowmanager_2_50(screen);
+                       do_versions_gpencil_2_50(main, screen);
+               }
                
                /* old Animation System (using IPO's) needs to be converted to the new Animato system 
                 * (NOTE: conversion code in blenkernel/intern/ipo.c for now)
index 10f88e4d2916fe53790cc243fe6dd905c17c59b1..d7d7ad792399d6e02ec8075f651e19432e5366e8 100644 (file)
@@ -1693,27 +1693,30 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
        mywrite(wd, MYWRITE_FLUSH, 0);
 }
 
-static void write_gpencil(WriteData *wd, bGPdata *gpd)
+static void write_gpencils(WriteData *wd, ListBase *lb)
 {
+       bGPdata *gpd;
        bGPDlayer *gpl;
        bGPDframe *gpf;
        bGPDstroke *gps;
        
-       /* write gpd data block to file */
-       writestruct(wd, DATA, "bGPdata", 1, gpd);
-       
-       /* write grease-pencil layers to file */
-       for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
-               writestruct(wd, DATA, "bGPDlayer", 1, gpl);
+       for (gpd= lb->first; gpd; gpd= gpd->id.next) {
+               /* write gpd data block to file */
+               writestruct(wd, ID_GD, "bGPdata", 1, gpd);
                
-               /* write this layer's frames to file */
-               for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
-                       writestruct(wd, DATA, "bGPDframe", 1, gpf);
+               /* write grease-pencil layers to file */
+               for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
+                       writestruct(wd, DATA, "bGPDlayer", 1, gpl);
                        
-                       /* write strokes */
-                       for (gps= gpf->strokes.first; gps; gps= gps->next) {
-                               writestruct(wd, DATA, "bGPDstroke", 1, gps);
-                               writestruct(wd, DATA, "bGPDspoint", gps->totpoints, gps->points);                               
+                       /* write this layer's frames to file */
+                       for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
+                               writestruct(wd, DATA, "bGPDframe", 1, gpf);
+                               
+                               /* write strokes */
+                               for (gps= gpf->strokes.first; gps; gps= gps->next) {
+                                       writestruct(wd, DATA, "bGPDstroke", 1, gps);
+                                       writestruct(wd, DATA, "bGPDspoint", gps->totpoints, gps->points);                               
+                               }
                        }
                }
        }
@@ -1808,7 +1811,6 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                                        writestruct(wd, DATA, "View3D", 1, v3d);
                                        if(v3d->bgpic) writestruct(wd, DATA, "BGpic", 1, v3d->bgpic);
                                        if(v3d->localvd) writestruct(wd, DATA, "View3D", 1, v3d->localvd);
-                                       if(v3d->gpd) write_gpencil(wd, v3d->gpd);
                                }
                                else if(sl->spacetype==SPACE_IPO) {
                                        SpaceIpo *sipo= (SpaceIpo *)sl;
@@ -1832,7 +1834,6 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                                else if(sl->spacetype==SPACE_SEQ) {
                                        SpaceSeq *sseq= (SpaceSeq *)sl;
                                        writestruct(wd, DATA, "SpaceSeq", 1, sl);
-                                       if(sseq->gpd) write_gpencil(wd, sseq->gpd);
                                }
                                else if(sl->spacetype==SPACE_OUTLINER) {
                                        SpaceOops *so= (SpaceOops *)sl;
@@ -1852,8 +1853,6 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                                        writestruct(wd, DATA, "SpaceImage", 1, sl);
                                        if(sima->cumap)
                                                write_curvemapping(wd, sima->cumap);
-                                       if(sima->gpd) 
-                                               write_gpencil(wd, sima->gpd);
                                }
                                else if(sl->spacetype==SPACE_IMASEL) {
                                        writestruct(wd, DATA, "SpaceImaSel", 1, sl);
@@ -1881,7 +1880,6 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                                else if(sl->spacetype==SPACE_NODE){
                                        SpaceNode *snode= (SpaceNode *)sl;
                                        writestruct(wd, DATA, "SpaceNode", 1, sl);
-                                       if(snode->gpd) write_gpencil(wd, snode->gpd);
                                }
                                sl= sl->next;
                        }
@@ -2208,6 +2206,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
        write_nodetrees(wd, &mainvar->nodetree);
        write_brushes  (wd, &mainvar->brush);
        write_scripts  (wd, &mainvar->script);
+       write_gpencils (wd, &mainvar->gpencil);
        if(current==NULL)       
                write_libraries(wd,  mainvar->next); /* no library save in undo */
 
index 9c24cd8b1e84003dd98be8c383e02742e8ba5540..2b63c1f2d3ba09e45c68a0006452e4421ba51346 100644 (file)
@@ -53,6 +53,7 @@
 #include "BKE_blender.h"
 #include "BKE_context.h"
 #include "BKE_global.h"
+#include "BKE_gpencil.h"
 #include "BKE_sequence.h"
 #include "BKE_utildefines.h"
 
index 33ab06c0f67ca5e8bc3886c55c7474a13f4dd6e8..28748d4a631ddcdad4fc6de4436e2ad04077b181 100644 (file)
@@ -51,6 +51,7 @@
 #include "BKE_utildefines.h"
 #include "BKE_blender.h"
 #include "BKE_fcurve.h"
+#include "BKE_gpencil.h"
 
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
index 38cee1e559ce7215f5f84f09cf774dcf4fe60ab0..721d8544225618f237b0a52a2c7190e083ccfa30 100644 (file)
@@ -32,7 +32,7 @@
 /******************************************************* */
 /* FILTERED ACTION DATA - TYPES */
 
-/* XXX */
+/* XXX - TODO: replace this with the modern bAnimListElem... */
 /* This struct defines a structure used for quick access */
 typedef struct bActListElem {
        struct bActListElem *next, *prev;
index f3f054c2b6f49d71026862d09a2f04b49b0cfd28..ad8124c89d78142c24563dbbaf07f0b4de36ca8e 100644 (file)
@@ -52,32 +52,13 @@ typedef struct tGPspoint {
        float pressure;                 /* pressure of tablet at this point */
 } tGPspoint;
 
-/* ------------ Grease-Pencil API ------------------ */
-
-void free_gpencil_strokes(struct bGPDframe *gpf);
-void free_gpencil_frames(struct bGPDlayer *gpl);
-void free_gpencil_layers(struct ListBase *list);
-void free_gpencil_data(struct bGPdata *gpd);
-
-struct bGPDframe *gpencil_frame_addnew(struct bGPDlayer *gpl, int cframe);
-struct bGPDlayer *gpencil_layer_addnew(struct bGPdata *gpd);
-struct bGPdata *gpencil_data_addnew(void);
-
-struct bGPDframe *gpencil_frame_duplicate(struct bGPDframe *src);
-struct bGPDlayer *gpencil_layer_duplicate(struct bGPDlayer *src);
-struct bGPdata *gpencil_data_duplicate(struct bGPdata *gpd);
+/* ------------ Grease-Pencil Depreceated Stuff ------------------ */
 
 struct bGPdata *gpencil_data_getactive(struct ScrArea *sa);
 short gpencil_data_setactive(struct ScrArea *sa, struct bGPdata *gpd);
 struct ScrArea *gpencil_data_findowner(struct bGPdata *gpd);
 
-void gpencil_frame_delete_laststroke(struct bGPDframe *gpf);
-
-struct bGPDframe *gpencil_layer_getframe(struct bGPDlayer *gpl, int cframe, short addnew);
-void gpencil_layer_delframe(struct bGPDlayer *gpl, struct bGPDframe *gpf);
-struct bGPDlayer *gpencil_layer_getactive(struct bGPdata *gpd);
-void gpencil_layer_setactive(struct bGPdata *gpd, struct bGPDlayer *active);
-void gpencil_layer_delactive(struct bGPdata *gpd);
+/* ------------ Grease-Pencil Editing API ------------------ */
 
 void gpencil_delete_actframe(struct bGPdata *gpd, int cfra);
 void gpencil_delete_laststroke(struct bGPdata *gpd, int cfra);
@@ -90,6 +71,7 @@ void gpencil_convert_menu(void);
 
 short gpencil_do_paint(struct bContext *C);
 
+/* ------------ Grease-Pencil Drawing API ------------------ */
 /* drawgpencil.c */
 
 void draw_gpencil_2dimage(struct bContext *C, struct ImBuf *ibuf);
index 71c57b3df718f391c665cde4aaad4679ea8da820..9e5212e159feaade20942860a2186a190d014592 100644 (file)
@@ -187,6 +187,7 @@ typedef struct PreviewImage {
 #define ID_NT          MAKE_ID2('N', 'T')
 #define ID_BR          MAKE_ID2('B', 'R')
 #define ID_PA          MAKE_ID2('P', 'A')
+#define ID_GD          MAKE_ID2('G', 'D')
 #define ID_WM          MAKE_ID2('W', 'M')
 
        /* NOTE! Fake IDs, needed for g.sipo->blocktype or outliner */
index 70f469b2bb8fc80840ce8055bd5f6cb786fa0f5d..ed209a127c7187fc6c59d28abe9fa86c1fe5bcce 100644 (file)
@@ -117,6 +117,8 @@ typedef struct bGPDlayer {
 
 /* Grease-Pencil Annotations - 'DataBlock' */
 typedef struct bGPdata {
+       ID id;                                  /* Grease Pencil data is */
+       
        /* saved Grease-Pencil data */
        ListBase layers;                /* bGPDlayers */
        int flag;                               /* settings for this datablock */
@@ -131,6 +133,7 @@ typedef struct bGPdata {
 } bGPdata;
 
 /* bGPdata->flag */
+// XXX many of these flags should be depreceated for more general ideas in 2.5
        /* don't allow painting to occur at all */
 #define GP_DATA_LMBPLOCK       (1<<0)
        /* show debugging info in viewport (i.e. status print) */