patch from Bjørnar Hansen (anachron)
authorCampbell Barton <ideasman42@gmail.com>
Tue, 19 Jan 2010 22:44:43 +0000 (22:44 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 19 Jan 2010 22:44:43 +0000 (22:44 +0000)
Multiple background images displaying each on a different axis.

Changes made from the original patch.
- Use an enum rather then multiple booleans.
- Reduced the space taken up by the user interface.
- Made the image template compact display not show fields & premul options.
- Added readfile.c lines so old blendfile images are loaded.
- Option to hide BGpic UI (like modifiers & constraints)
- Use the index rather then a bgpic from the context for the remove operator.

note: could be good to use 1 image for both left+right, for eg, but for this to work as intended we would need to add image flipping depending on the axis so left this commented out for now.

12 files changed:
release/scripts/ui/space_view3d.py
source/blender/blenkernel/BKE_sequencer.h
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/space_image/image_buttons.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_intern.h
source/blender/editors/space_view3d/view3d_ops.c
source/blender/makesdna/DNA_view3d_types.h
source/blender/makesrna/intern/rna_space.c

index af0e2ec..c422781 100644 (file)
@@ -1783,7 +1783,7 @@ class VIEW3D_PT_3dview_curvedisplay(bpy.types.Panel):
 class VIEW3D_PT_background_image(bpy.types.Panel):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'UI'
-    bl_label = "Background Image"
+    bl_label = "Background Images"
     bl_default_closed = True
 
     def poll(self, context):
@@ -1795,34 +1795,38 @@ class VIEW3D_PT_background_image(bpy.types.Panel):
         layout = self.layout
         view = context.space_data
 
-        layout.prop(view, "display_background_image", text="")
+        layout.prop(view, "display_background_images", text="")
 
     def draw(self, context):
         layout = self.layout
 
         view = context.space_data
-        bg = view.background_image
+        
+        col = layout.column()
+        col.operator("view3d.add_background_image", text="Add Image")
 
-        if bg:
-            layout.active = view.display_background_image
+        for i, bg in enumerate(view.background_images):
+            layout.active = view.display_background_images
             box = layout.box()
-            if (bg.image):
-                box.template_ID(bg, "image", open="image.open")
-                box.template_image(bg, "image", bg.image_user, compact=True)
-            else:
-                box.template_ID(bg, "image", open="image.open")
+            row = box.row(align=True)
+            row.prop(bg, "show_expanded", text="", no_bg=True)
+            row.label(text=getattr(bg.image, "name", "Not Set"))
+            row.operator("view3d.remove_background_image", text="", icon='X').index = i
             
-            col = layout.column()
-            col.label(text="Display Settings")
+            box.prop(bg, "view_axis", text="Axis")
             
-            col = layout.column()
-            col.prop(bg, "size")
-            col.prop(bg, "transparency", slider=True)
-
-            col = layout.column()
-            col.label(text="Offset")
-            col.prop(bg, "offset_x", text="X")
-            col.prop(bg, "offset_y", text="Y")
+            if bg.show_expanded:
+                row = box.row()
+                row.template_ID(bg, "image", open="image.open")
+                if (bg.image):
+                    box.template_image(bg, "image", bg.image_user, compact=True)
+
+                    box.prop(bg, "transparency", slider=True)
+                    box.prop(bg, "size")
+                    row = box.row(align=True)
+                    row.prop(bg, "offset_x", text="X")
+                    row.prop(bg, "offset_y", text="Y")
 
 class VIEW3D_PT_transform_orientations(bpy.types.Panel):
     bl_space_type = 'VIEW_3D'
index dc7b6d3..492ece7 100644 (file)
@@ -28,8 +28,8 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
-#ifndef BKE_SEQUENCE_H
-#define BKE_SEQUENCE_H
+#ifndef BKE_SEQUENCER_H
+#define BKE_SEQUENCER_H
 
 struct Editing;
 struct Sequence;
@@ -77,8 +77,6 @@ void seq_array(struct Editing *ed, struct Sequence ***seqarray, int *tot, int us
                seq_end(&iter); \
        }
 
-#endif
-
 
 /* Wipe effect */
 enum {DO_SINGLE_WIPE, DO_DOUBLE_WIPE, DO_BOX_WIPE, DO_CROSS_WIPE,
@@ -238,3 +236,5 @@ struct Sequence *sequencer_add_movie_strip(struct bContext *C, ListBase *seqbase
 /* copy/paste */
 extern ListBase seqbase_clipboard;
 extern int seqbase_clipboard_frame;
+
+#endif // BKE_SEQUENCER_H
index 96b2b79..11a9a6e 100644 (file)
@@ -4630,12 +4630,20 @@ static void lib_link_screen(FileData *fd, Main *main)
                                for (sl= sa->spacedata.first; sl; sl= sl->next) {
                                        if(sl->spacetype==SPACE_VIEW3D) {
                                                View3D *v3d= (View3D*) sl;
+                                               BGpic *bgpic;
                                                
                                                v3d->camera= newlibadr(fd, sc->id.lib, v3d->camera);
                                                v3d->ob_centre= newlibadr(fd, sc->id.lib, v3d->ob_centre);
                                                
+                                               /* should be do_versions but not easy adding into the listbase */
                                                if(v3d->bgpic) {
-                                                       v3d->bgpic->ima= newlibadr_us(fd, sc->id.lib, v3d->bgpic->ima);
+                                                       v3d->bgpic= newlibadr(fd, sc->id.lib, v3d->bgpic);
+                                                       BLI_addtail(&v3d->bgpicbase, bgpic);
+                                                       v3d->bgpic= NULL;
+                                               }
+
+                                               for(bgpic= v3d->bgpicbase.first; bgpic; bgpic= bgpic->next) {
+                                                       bgpic->ima= newlibadr_us(fd, sc->id.lib, bgpic->ima);
                                                }
                                                if(v3d->localvd) {
                                                        v3d->localvd->camera= newlibadr(fd, sc->id.lib, v3d->localvd->camera);
@@ -4809,14 +4817,15 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
                        for (sl= sa->spacedata.first; sl; sl= sl->next) {
                                if(sl->spacetype==SPACE_VIEW3D) {
                                        View3D *v3d= (View3D*) sl;
+                                       BGpic *bgpic;
                                        
                                        v3d->camera= restore_pointer_by_name(newmain, (ID *)v3d->camera, 1);
                                        if(v3d->camera==NULL)
                                                v3d->camera= sc->scene->camera;
                                        v3d->ob_centre= restore_pointer_by_name(newmain, (ID *)v3d->ob_centre, 1);
                                        
-                                       if(v3d->bgpic) {
-                                               v3d->bgpic->ima= restore_pointer_by_name(newmain, (ID *)v3d->bgpic->ima, 1);
+                                       for(bgpic= v3d->bgpicbase.first; bgpic; bgpic= bgpic->next) {
+                                               bgpic->ima= restore_pointer_by_name(newmain, (ID *)bgpic->ima, 1);
                                        }
                                        if(v3d->localvd) {
                                                /*Base *base;*/
@@ -5089,10 +5098,22 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
 
                        if (sl->spacetype==SPACE_VIEW3D) {
                                View3D *v3d= (View3D*) sl;
-                               v3d->bgpic= newdataadr(fd, v3d->bgpic);
+                               BGpic *bgpic;
+
                                v3d->flag |= V3D_INVALID_BACKBUF;
-                               if(v3d->bgpic)
-                                       v3d->bgpic->iuser.ok= 1;
+
+                               link_list(fd, &(v3d->bgpicbase));
+
+                               /* should be do_versions except this doesnt fit well there */
+                               if(v3d->bgpic) {
+                                       bgpic= newdataadr(fd, v3d->bgpic);
+                                       BLI_addtail(&v3d->bgpicbase, bgpic);
+                                       v3d->bgpic= NULL;
+                               }
+
+                               for(bgpic= v3d->bgpicbase.first; bgpic; bgpic= bgpic->next)
+                                       bgpic->iuser.ok= 1;
+
                                if(v3d->gpd) {
                                        v3d->gpd= newdataadr(fd, v3d->gpd);
                                        direct_link_gpencil(fd, v3d->gpd);
@@ -8350,8 +8371,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                        ((SpaceImage *)sl)->iuser.fie_ima= 2;
                                                else if(sl->spacetype==SPACE_VIEW3D) {
                                                        View3D *v3d= (View3D *)sl;
-                                                       if(v3d->bgpic)
-                                                               v3d->bgpic->iuser.fie_ima= 2;
+                                                       BGpic *bgpic;
+                                                       for(bgpic= v3d->bgpicbase.first; bgpic; bgpic= bgpic->next)
+                                                               bgpic->iuser.fie_ima= 2;
                                                }
                                        }
                                }
index 4c9c540..7064b8c 100644 (file)
@@ -2035,8 +2035,10 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                                
                                if(sl->spacetype==SPACE_VIEW3D) {
                                        View3D *v3d= (View3D *) sl;
+                                       BGpic *bgpic;
                                        writestruct(wd, DATA, "View3D", 1, v3d);
-                                       if(v3d->bgpic) writestruct(wd, DATA, "BGpic", 1, v3d->bgpic);
+                                       for (bgpic= v3d->bgpicbase.first; bgpic; bgpic= bgpic->next)
+                                       writestruct(wd, DATA, "BGpic", 1, bgpic);
                                        if(v3d->localvd) writestruct(wd, DATA, "View3D", 1, v3d->localvd);
                                }
                                else if(sl->spacetype==SPACE_IPO) {
index c882c8d..94df99d 100644 (file)
@@ -888,26 +888,30 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propn
                                uiblock_layer_pass_arrow_buttons(layout, ima->rr, iuser);
                        }
                        else if(ima->source != IMA_SRC_GENERATED) {
-                               ibuf= BKE_image_acquire_ibuf(ima, iuser, &lock);
-                               image_info(ima, ibuf, str);
-                               BKE_image_release_ibuf(ima, lock);
-                               uiItemL(layout, str, 0);
+                               if(compact == 0) {
+                                       ibuf= BKE_image_acquire_ibuf(ima, iuser, &lock);
+                                       image_info(ima, ibuf, str);
+                                       BKE_image_release_ibuf(ima, lock);
+                                       uiItemL(layout, str, 0);
+                               }
                        }
                        
                        if(ima->source != IMA_SRC_GENERATED) {
-                               uiItemS(layout);
+                               if(compact == 0) { /* background image view doesnt need these */
+                                       uiItemS(layout);
 
-                               split= uiLayoutSplit(layout, 0, 0);
+                                       split= uiLayoutSplit(layout, 0, 0);
 
-                               col= uiLayoutColumn(split, 0);
-                               uiItemR(col, NULL, 0, &imaptr, "fields", 0);
-                               row= uiLayoutRow(col, 0);
-                               uiItemR(row, NULL, 0, &imaptr, "field_order", UI_ITEM_R_EXPAND);
-                               uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "fields"));
+                                       col= uiLayoutColumn(split, 0);
+                                       uiItemR(col, NULL, 0, &imaptr, "fields", 0);
+                                       row= uiLayoutRow(col, 0);
+                                       uiItemR(row, NULL, 0, &imaptr, "field_order", UI_ITEM_R_EXPAND);
+                                       uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "fields"));
 
-                               col= uiLayoutColumn(split, 0);
-                               uiItemR(col, NULL, 0, &imaptr, "antialias", 0);
-                               uiItemR(col, NULL, 0, &imaptr, "premultiply", 0);
+                                       col= uiLayoutColumn(split, 0);
+                                       uiItemR(col, NULL, 0, &imaptr, "antialias", 0);
+                                       uiItemR(col, NULL, 0, &imaptr, "premultiply", 0);
+                               }
                        }
 
                        if(ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
index 6ba2787..b3bd31d 100644 (file)
@@ -266,12 +266,13 @@ static SpaceLink *view3d_new(const bContext *C)
 static void view3d_free(SpaceLink *sl)
 {
        View3D *vd= (View3D *) sl;
-       
-       if(vd->bgpic) {
-               if(vd->bgpic->ima) vd->bgpic->ima->id.us--;
-               MEM_freeN(vd->bgpic);
+
+       BGpic *bgpic;
+       for(bgpic= vd->bgpicbase.first; bgpic; bgpic= bgpic->next) {
+               if(bgpic->ima) bgpic->ima->id.us--;
        }
-       
+       BLI_freelistN(&vd->bgpicbase);
+
        if(vd->localvd) MEM_freeN(vd->localvd);
        
        if(vd->properties_storage) MEM_freeN(vd->properties_storage);
@@ -303,9 +304,12 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
        
        /* copy or clear inside new stuff */
 
-       if(v3dn->bgpic) {
-               v3dn->bgpic= MEM_dupallocN(v3dn->bgpic);
-               if(v3dn->bgpic->ima) v3dn->bgpic->ima->id.us++;
+       if(v3dn->bgpicbase.first) {
+               BGpic *bgpic;
+                       for ( bgpic= v3dn->bgpicbase.first; bgpic; bgpic= bgpic->next ) {
+                       bgpic= MEM_dupallocN(bgpic);
+                       if(bgpic->ima) bgpic->ima->id.us++;
+                       }
        }
        v3dn->properties_storage= NULL;
        
@@ -790,11 +794,13 @@ void space_view3d_listener(struct ScrArea *area, struct wmNotifier *wmn)
 {
        if (wmn->category == NC_SCENE && wmn->data == ND_FRAME) {
                View3D *v3d = area->spacedata.first;
-       
-               if (v3d->bgpic && v3d->bgpic->ima) {
-                       Scene *scene = wmn->reference;
+               BGpic *bgpic = v3d->bgpicbase.first;
 
-                       BKE_image_user_calc_frame(&v3d->bgpic->iuser, scene->r.cfra, 0);
+               for (; bgpic; bgpic = bgpic->next) {
+                       if (bgpic->ima) {
+                               Scene *scene = wmn->reference;
+                               BKE_image_user_calc_imanr(&bgpic->iuser, scene->r.cfra, 0);
+                       }
                }
        }
 }
index 529b100..fa15548 100644 (file)
@@ -1312,109 +1312,113 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d)
        ImBuf *ibuf= NULL;
        float vec[4], fac, asp, zoomx, zoomy;
        float x1, y1, x2, y2, cx, cy;
-       
-       bgpic= v3d->bgpic;
-       if(bgpic==NULL) return;
-       
-       ima= bgpic->ima;
 
-       if(ima) {
-               /* notifier can also call this however screen_ops.c */
-               BKE_image_user_calc_frame(&bgpic->iuser, CFRA, 0);
-               ibuf= BKE_image_get_ibuf(ima, &bgpic->iuser);
-       }
-       if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL) ) 
-               return;
-       if(ibuf->channels!=4)
-               return;
-       if(ibuf->rect==NULL)
-               IMB_rect_from_float(ibuf);
-       
-       if(rv3d->persp==2) {
-               rctf vb;
-               
-               calc_viewborder(scene, ar, v3d, &vb);
-               
-               x1= vb.xmin;
-               y1= vb.ymin;
-               x2= vb.xmax;
-               y2= vb.ymax;
-       }
-       else {
-               float sco[2];
-               
-               /* calc window coord */
-               initgrabz(rv3d, 0.0, 0.0, 0.0);
-               window_to_3d_delta(ar, vec, 1, 0);
-               fac= MAX3( fabs(vec[0]), fabs(vec[1]), fabs(vec[1]) );
-               fac= 1.0/fac;
-               
-               asp= ( (float)ibuf->y)/(float)ibuf->x;
-               
-               vec[0] = vec[1] = vec[2] = 0.0;
-               view3d_project_float(ar, vec, sco, rv3d->persmat);
-               cx = sco[0];
-               cy = sco[1];
-               
-               x1=  cx+ fac*(bgpic->xof-bgpic->size);
-               y1=  cy+ asp*fac*(bgpic->yof-bgpic->size);
-               x2=  cx+ fac*(bgpic->xof+bgpic->size);
-               y2=  cy+ asp*fac*(bgpic->yof+bgpic->size);
-       }
-       
-       /* complete clip? */
-       
-       if(x2 < 0 ) return;
-       if(y2 < 0 ) return;
-       if(x1 > ar->winx ) return;
-       if(y1 > ar->winy ) return;
-       
-       zoomx= (x2-x1)/ibuf->x;
-       zoomy= (y2-y1)/ibuf->y;
-       
-       /* for some reason; zoomlevels down refuses to use GL_ALPHA_SCALE */
-       if(zoomx < 1.0f || zoomy < 1.0f) {
-               float tzoom= MIN2(zoomx, zoomy);
-               int mip= 0;
-               
-               if(ibuf->mipmap[0]==NULL)
-                       IMB_makemipmap(ibuf, 0, 0);
-               
-               while(tzoom < 1.0f && mip<8 && ibuf->mipmap[mip]) {
-                       tzoom*= 2.0f;
-                       zoomx*= 2.0f;
-                       zoomy*= 2.0f;
-                       mip++;
+
+       for ( bgpic= v3d->bgpicbase.first; bgpic; bgpic= bgpic->next ) {
+
+               if(     (bgpic->view == 0) || /* zero for any */
+                       (bgpic->view & (1<<rv3d->view)) || /* check agaist flags */
+                       (rv3d->persp==RV3D_CAMOB && bgpic->view == (1<<RV3D_VIEW_CAMERA))
+               ) {
+                       ima= bgpic->ima;
+                       if(ima==NULL)
+                               continue;
+                       BKE_image_user_calc_frame(&bgpic->iuser, CFRA, 0);
+                       ibuf= BKE_image_get_ibuf(ima, &bgpic->iuser);
+                       if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL) )
+                               continue;
+                       if(ibuf->channels!=4)
+                               continue;
+                       if(ibuf->rect==NULL)
+                               IMB_rect_from_float(ibuf);
+
+                       if(rv3d->persp==RV3D_CAMOB) {
+                               rctf vb;
+
+                               calc_viewborder(scene, ar, v3d, &vb);
+
+                               x1= vb.xmin;
+                               y1= vb.ymin;
+                               x2= vb.xmax;
+                               y2= vb.ymax;
+                       }
+                       else {
+                               float sco[2];
+
+                               /* calc window coord */
+                               initgrabz(rv3d, 0.0, 0.0, 0.0);
+                               window_to_3d_delta(ar, vec, 1, 0);
+                               fac= MAX3( fabs(vec[0]), fabs(vec[1]), fabs(vec[1]) );
+                               fac= 1.0/fac;
+
+                               asp= ( (float)ibuf->y)/(float)ibuf->x;
+
+                               vec[0] = vec[1] = vec[2] = 0.0;
+                               view3d_project_float(ar, vec, sco, rv3d->persmat);
+                               cx = sco[0];
+                               cy = sco[1];
+
+                               x1=  cx+ fac*(bgpic->xof-bgpic->size);
+                               y1=  cy+ asp*fac*(bgpic->yof-bgpic->size);
+                               x2=  cx+ fac*(bgpic->xof+bgpic->size);
+                               y2=  cy+ asp*fac*(bgpic->yof+bgpic->size);
+                       }
+
+                       /* complete clip? */
+
+                       if(x2 < 0 ) continue;
+                       if(y2 < 0 ) continue;
+                       if(x1 > ar->winx ) continue;
+                       if(y1 > ar->winy ) continue;
+
+                       zoomx= (x2-x1)/ibuf->x;
+                       zoomy= (y2-y1)/ibuf->y;
+
+                       /* for some reason; zoomlevels down refuses to use GL_ALPHA_SCALE */
+                       if(zoomx < 1.0f || zoomy < 1.0f) {
+                               float tzoom= MIN2(zoomx, zoomy);
+                               int mip= 0;
+
+                               if(ibuf->mipmap[0]==NULL)
+                                       IMB_makemipmap(ibuf, 0, 0);
+
+                               while(tzoom < 1.0f && mip<8 && ibuf->mipmap[mip]) {
+                                       tzoom*= 2.0f;
+                                       zoomx*= 2.0f;
+                                       zoomy*= 2.0f;
+                                       mip++;
+                               }
+                               if(mip>0)
+                                       ibuf= ibuf->mipmap[mip-1];
+                       }
+
+                       if(v3d->zbuf) glDisable(GL_DEPTH_TEST);
+                       glDepthMask(0);
+
+                       glBlendFunc(GL_SRC_ALPHA,  GL_ONE_MINUS_SRC_ALPHA);
+
+                       /* need to use wm push/pop matrix because ED_region_pixelspace
+                  uses the wm functions too, otherwise gets out of sync */
+                       wmPushMatrix();
+                       ED_region_pixelspace(ar);
+
+                       glEnable(GL_BLEND);
+
+                       glPixelZoom(zoomx, zoomy);
+                       glColor4f(1.0, 1.0, 1.0, 1.0-bgpic->blend);
+                       glaDrawPixelsTex(x1, y1, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect);
+
+                       glPixelZoom(1.0, 1.0);
+                       glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
+
+                       wmPopMatrix();
+
+                       glDisable(GL_BLEND);
+
+                       glDepthMask(1);
+                       if(v3d->zbuf) glEnable(GL_DEPTH_TEST);
                }
-               if(mip>0)
-                       ibuf= ibuf->mipmap[mip-1];
        }
-       
-       if(v3d->zbuf) glDisable(GL_DEPTH_TEST);
-       glDepthMask(0);
-       
-       glBlendFunc(GL_SRC_ALPHA,  GL_ONE_MINUS_SRC_ALPHA); 
-       
-       /* need to use wm push/pop matrix because ED_region_pixelspace
-          uses the wm functions too, otherwise gets out of sync */
-       wmPushMatrix();
-       ED_region_pixelspace(ar);
-       
-       glEnable(GL_BLEND);
-       
-       glPixelZoom(zoomx, zoomy);
-       glColor4f(1.0, 1.0, 1.0, 1.0-bgpic->blend);
-       glaDrawPixelsTex(x1, y1, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect);
-       
-       glPixelZoom(1.0, 1.0);
-       glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
-       
-       wmPopMatrix();
-       
-       glDisable(GL_BLEND);
-
-       glDepthMask(1);
-       if(v3d->zbuf) glEnable(GL_DEPTH_TEST);
 }
 
 /* ****************** View3d afterdraw *************** */
@@ -2059,7 +2063,7 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
                                                                  star_stuff_term_func);
                                }
                        }
-                       if(v3d->flag & V3D_DISPBGPIC) draw_bgpic(scene, ar, v3d);
+                       if(v3d->flag & V3D_DISPBGPICS) draw_bgpic(scene, ar, v3d);
                }
        }
        else {
@@ -2071,7 +2075,7 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
                glMatrixMode(GL_MODELVIEW);
                wmLoadMatrix(rv3d->viewmat);
                
-               if(v3d->flag & V3D_DISPBGPIC) {
+               if(v3d->flag & V3D_DISPBGPICS) {
                        draw_bgpic(scene, ar, v3d);
                }
        }
index 54e5ff7..77c9f86 100644 (file)
@@ -2071,7 +2071,82 @@ void VIEW3D_OT_view_persportho(wmOperatorType *ot)
        ot->flag= 0;
 }
 
+/* ******************** add background image operator **************** */
 
+static int add_background_image_exec(bContext *C, wmOperator *op)
+{
+       View3D *v3d= CTX_wm_view3d(C);
+
+       BGpic *bgpic= MEM_callocN(sizeof(BGpic), "Background Image");
+       bgpic->size= 5.0;
+       bgpic->blend= 0.5;
+       bgpic->iuser.fie_ima= 2;
+       bgpic->iuser.ok= 1;
+       bgpic->view= 0; /* 0 for all */
+
+       BLI_addtail(&v3d->bgpicbase, bgpic);
+
+       //ED_region_tag_redraw(v3d);
+
+       return OPERATOR_FINISHED;
+}
+
+static int add_background_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       return add_background_image_exec(C, op);
+}
+
+void VIEW3D_OT_add_background_image(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name   = "Add Background Image";
+       ot->description= "Add a new background image.";
+       ot->idname = "VIEW3D_OT_add_background_image";
+
+       /* api callbacks */
+       ot->invoke = add_background_image_invoke;
+       ot->exec   = add_background_image_exec;
+       ot->poll   = ED_operator_view3d_active;
+
+       /* flags */
+       ot->flag   = 0;
+}
+
+/* ***** remove image operator ******* */
+static int remove_background_image_exec(bContext *C, wmOperator *op)
+{
+       BGpic *bgpic_rem = CTX_data_pointer_get_type(C, "bgpic", &RNA_BackgroundImage).data;
+       View3D *vd = CTX_wm_view3d(C);
+       int index = RNA_int_get(op->ptr, "index");
+
+       bgpic_rem = BLI_findlink(&vd->bgpicbase, index);
+       if(bgpic_rem) {
+               BLI_remlink(&vd->bgpicbase, bgpic_rem);
+               if(bgpic_rem->ima) bgpic_rem->ima->id.us--;
+               MEM_freeN(bgpic_rem);
+       }
+
+       WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, vd);
+
+       return OPERATOR_FINISHED;
+}
+
+void VIEW3D_OT_remove_background_image(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name   = "Remove Background Image";
+       ot->description= "Remove a background image from the 3D view";
+       ot->idname = "VIEW3D_OT_remove_background_image";
+
+       /* api callbacks */
+       ot->exec   = remove_background_image_exec;
+       ot->poll   = ED_operator_view3d_active;
+
+       /* flags */
+       ot->flag   = 0;
+
+       RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Background image index to remove ", 0, INT_MAX);
+}
 /* ********************* set clipping operator ****************** */
 
 static void calc_clipping_plane(float clip[6][4], BoundBox *clipbb)
index 81de9ac..bdcaa4a 100644 (file)
@@ -77,6 +77,8 @@ void VIEW3D_OT_view_selected(struct wmOperatorType *ot);
 void VIEW3D_OT_view_center_cursor(struct wmOperatorType *ot);
 void VIEW3D_OT_view_pan(struct wmOperatorType *ot);
 void VIEW3D_OT_view_persportho(struct wmOperatorType *ot);
+void VIEW3D_OT_add_background_image(struct wmOperatorType *ot);
+void VIEW3D_OT_remove_background_image(struct wmOperatorType *ot);
 void VIEW3D_OT_view_orbit(struct wmOperatorType *ot);
 void VIEW3D_OT_clip_border(struct wmOperatorType *ot);
 void VIEW3D_OT_cursor3d(struct wmOperatorType *ot);
index ad5bdcf..2192eb1 100644 (file)
@@ -70,6 +70,8 @@ void view3d_operatortypes(void)
        WM_operatortype_append(VIEW3D_OT_view_orbit);
        WM_operatortype_append(VIEW3D_OT_view_pan);
        WM_operatortype_append(VIEW3D_OT_view_persportho);
+       WM_operatortype_append(VIEW3D_OT_add_background_image);
+       WM_operatortype_append(VIEW3D_OT_remove_background_image);
        WM_operatortype_append(VIEW3D_OT_view_selected);
        WM_operatortype_append(VIEW3D_OT_view_center_cursor);
        WM_operatortype_append(VIEW3D_OT_select);
index 4ad18a9..6546ec5 100644 (file)
@@ -63,9 +63,14 @@ struct wmTimer;
  
 /* Background Picture in 3D-View */
 typedef struct BGpic {
+    struct BGpic *next, *prev;
+
     struct Image *ima;
        struct ImageUser iuser;
     float xof, yof, size, blend;
+    short view;
+    short flag;
+    float pad2;
 } BGpic;
 
 /* ********************************* */
@@ -140,7 +145,10 @@ typedef struct View3D {
        short view;     /* XXX depricated */
        
        struct Object *camera, *ob_centre;
-       struct BGpic *bgpic;
+
+       struct ListBase bgpicbase;
+       struct BGpic *bgpic; /* deprecated, use bgpicbase, only kept for do_versions(...) */
+
        struct View3D *localvd;
        
        char ob_centre_bone[32];                /* optional string for armature bone to define center */
@@ -197,7 +205,7 @@ typedef struct View3D {
 /* View3D->flag (short) */
 #define V3D_MODE                       (16+32+64+128+256+512)
 #define V3D_DISPIMAGE          1
-#define V3D_DISPBGPIC          2
+#define V3D_DISPBGPICS         2
 #define V3D_HIDE_HELPLINES     4
 #define V3D_INVALID_BACKBUF    8
 #define V3D_EDITMODE           16
@@ -283,6 +291,9 @@ typedef struct View3D {
 #define V3D_DRAW_MANIPULATOR   2
 #define V3D_CALC_MANIPULATOR   4
 
+/* BGPic->flag */
+/* may want to use 1 for select ?*/
+#define V3D_BGPIC_EXPANDED             2
 
 #endif
 
index 4f75a77..88c2eb9 100644 (file)
@@ -425,22 +425,6 @@ static void rna_ConsoleLine_cursor_index_range(PointerRNA *ptr, int *min, int *m
        *max= ci->len;
 }
 
-static void rna_View3D_display_background_image_set(PointerRNA *ptr, int value)
-{
-       View3D *vd= (View3D*)ptr->data;
-
-       if(value) vd->flag |= V3D_DISPBGPIC;
-       else vd->flag &= ~V3D_DISPBGPIC;
-
-       if((vd->flag & V3D_DISPBGPIC) && vd->bgpic == NULL) {
-               vd->bgpic= MEM_callocN(sizeof(BGpic), "bgpic");
-               vd->bgpic->size= 5.0;
-               vd->bgpic->blend= 0.5;
-               vd->bgpic->iuser.fie_ima= 2;
-               vd->bgpic->iuser.ok= 1;
-       }
-}
-
 /* Space Time */
 
 static void rna_SpaceTime_redraw_update(Main *bmain, Scene *scene, PointerRNA *ptr)
@@ -667,6 +651,25 @@ static void rna_def_background_image(BlenderRNA *brna)
        StructRNA *srna;
        PropertyRNA *prop;
 
+       /* note: combinations work but dont flip so arnt that useful */
+       static EnumPropertyItem bgpic_axis_items[] = {
+               {0, "", 0, "X Axis", ""},
+               {(1<<RV3D_VIEW_LEFT), "LEFT", 0, "Left", ""},
+               {(1<<RV3D_VIEW_RIGHT), "RIGHT", 0, "Right", ""},
+               /*{(1<<RV3D_VIEW_LEFT)|(1<<RV3D_VIEW_RIGHT), "LEFT_RIGHT", 0, "Left/Right", ""},*/
+               {0, "", 0, "Y Axis", ""},
+               {(1<<RV3D_VIEW_BACK), "BACK", 0, "Back", ""},
+               {(1<<RV3D_VIEW_FRONT), "FRONT", 0, "Front", ""},
+               /*{(1<<RV3D_VIEW_BACK)|(1<<RV3D_VIEW_FRONT), "BACK_FRONT", 0, "Back/Front", ""},*/
+               {0, "", 0, "Z Axis", ""},
+               {(1<<RV3D_VIEW_BOTTOM), "BOTTOM", 0, "Bottom", ""},
+               {(1<<RV3D_VIEW_TOP), "TOP", 0, "Top", ""},
+               /*{(1<<RV3D_VIEW_BOTTOM)|(1<<RV3D_VIEW_TOP), "BOTTOM_TOP", 0, "Top/Bottom", ""},*/
+               {0, "", 0, "Other", ""},
+               {0, "ALL", 0, "All Views", ""},
+               {(1<<RV3D_VIEW_CAMERA), "CAMERA", 0, "Camera", ""},
+               {0, NULL, 0, NULL, NULL}};
+
        srna= RNA_def_struct(brna, "BackgroundImage", NULL);
        RNA_def_struct_sdna(srna, "BGpic");
        RNA_def_struct_ui_text(srna, "Background Image", "Image and settings for display in the 3d View background.");
@@ -704,6 +707,18 @@ static void rna_def_background_image(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Transparency", "Amount to blend the image against the background color.");
        RNA_def_property_range(prop, 0.0, 1.0);
        RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+
+       prop= RNA_def_property(srna, "view_axis", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "view");
+       RNA_def_property_enum_items(prop, bgpic_axis_items);
+       RNA_def_property_ui_text(prop, "Image Axis", "The axis to display the image on.");
+       RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+
+       prop= RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_BGPIC_EXPANDED);
+       RNA_def_property_ui_text(prop, "Show Expanded", "Show the expanded in the user interface.");
+       RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1);
+
 }
 
 static void rna_def_space_3dview(BlenderRNA *brna)
@@ -747,10 +762,6 @@ static void rna_def_space_3dview(BlenderRNA *brna)
        RNA_def_property_string_sdna(prop, NULL, "ob_centre_bone");
        RNA_def_property_ui_text(prop, "Lock Bone", "3D View center is locked to this bone's position");
        RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
-       
-       prop= RNA_def_property(srna, "background_image", PROP_POINTER, PROP_NONE);
-       RNA_def_property_pointer_sdna(prop, NULL, "bgpic");
-       RNA_def_property_ui_text(prop, "Background Image", "Image and settings to display in the 3D View background");
 
        prop= RNA_def_property(srna, "viewport_shading", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "drawtype");
@@ -843,13 +854,18 @@ static void rna_def_space_3dview(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Occlude Geometry", "Limit selection to visible (clipped with depth buffer)");
        RNA_def_property_ui_icon(prop, ICON_ORTHO, 0);
        RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
-       
-       prop= RNA_def_property(srna, "display_background_image", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_funcs(prop, NULL, "rna_View3D_display_background_image_set");
-       RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_DISPBGPIC);
-       RNA_def_property_ui_text(prop, "Display Background Image", "Display a reference image behind objects in the 3D View");
+
+       prop= RNA_def_property(srna, "background_images", PROP_COLLECTION, PROP_NONE);
+       RNA_def_property_collection_sdna(prop, NULL, "bgpicbase", NULL);
+       RNA_def_property_struct_type(prop, "BackgroundImage");
+       RNA_def_property_ui_text(prop, "Background Images", "List of background images");
        RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
-       
+
+       prop= RNA_def_property(srna, "display_background_images", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_DISPBGPICS);
+       RNA_def_property_ui_text(prop, "Display Background Images", "Display reference images behind objects in the 3D View");
+       RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+
        prop= RNA_def_property(srna, "pivot_point", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "around");
        RNA_def_property_enum_items(prop, pivot_items);