Index: release/scripts/startup/bl_ui/properties_data_empty.py =================================================================== --- release/scripts/startup/bl_ui/properties_data_empty.py (revision 36543) +++ release/scripts/startup/bl_ui/properties_data_empty.py (working copy) @@ -39,7 +39,21 @@ ob = context.object layout.prop(ob, "empty_draw_type", text="Display") + layout.template_ID(ob, "data", open="image.open", unlink="image.unlink") + # layout.template_image(ob, "data", None) + + if not ob.data: + layout.prop(ob, "empty_draw_type", text="Display") + layout.prop(ob, "empty_draw_size", text="Size") + if ob.data: + row = layout.row(align = True) + row.prop(ob, "color", text="Transparency", index = 3, slider=True) + row = layout.row(align = True) + row.prop(ob, "origin_offset", text="X", index = 0) + row.prop(ob, "origin_offset", text="Y", index = 1) + + if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) Index: source/blender/makesdna/DNA_object_types.h =================================================================== --- source/blender/makesdna/DNA_object_types.h (revision 36543) +++ source/blender/makesdna/DNA_object_types.h (working copy) @@ -259,6 +259,9 @@ ListBase gpulamp; /* runtime, for lamps only */ ListBase pc_ids; ListBase *duplilist; /* for temporary dupli list storage, only for use by RNA API */ + + float origin_offset[2]; /* offset for image empties */ + char pad3[8]; } Object; /* Warning, this is not used anymore because hooks are now modifiers */ Index: source/blender/makesrna/intern/rna_ui_api.c =================================================================== --- source/blender/makesrna/intern/rna_ui_api.c (revision 36543) +++ source/blender/makesrna/intern/rna_ui_api.c (working copy) @@ -389,7 +389,7 @@ RNA_def_function_flag(func, FUNC_USE_CONTEXT); api_ui_item_rna_common(func); parm= RNA_def_pointer(func, "image_user", "ImageUser", "", ""); - RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); RNA_def_boolean(func, "compact", 0, "", "Use more compact layout."); func= RNA_def_function(srna, "template_list", "uiTemplateList"); Index: source/blender/makesrna/intern/rna_object.c =================================================================== --- source/blender/makesrna/intern/rna_object.c (revision 36543) +++ source/blender/makesrna/intern/rna_object.c (working copy) @@ -307,22 +307,26 @@ WM_main_add_notifier(NC_SCENE|ND_LAYER_CONTENT, scene); } -static int rna_Object_data_editable(PointerRNA *ptr) -{ - Object *ob= (Object*)ptr->data; - - return (ob->type == OB_EMPTY)? 0: PROP_EDITABLE; -} - static void rna_Object_data_set(PointerRNA *ptr, PointerRNA value) { Object *ob= (Object*)ptr->data; ID *id= value.data; - if(ob->type == OB_EMPTY || id == NULL || ob->mode & OB_MODE_EDIT) + if (id == NULL || ob->mode & OB_MODE_EDIT) return; - - if(ob->type == OB_MESH) { + + if (ob->type == OB_EMPTY) { + if(ob->data) { + id_us_min((ID*)ob->data); + ob->data = NULL; + } + + if (id && GS(id->name) == ID_IM) { + id_us_plus(id); + ob->data = id; + } + } + else if(ob->type == OB_MESH) { set_mesh(ob, (Mesh*)id); } else { @@ -346,6 +350,7 @@ Object *ob= (Object*)ptr->data; switch(ob->type) { + case OB_EMPTY: return &RNA_Image; case OB_MESH: return &RNA_Mesh; case OB_CURVE: return &RNA_Curve; case OB_SURF: return &RNA_Curve; @@ -1758,7 +1763,6 @@ prop= RNA_def_property(srna, "data", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "ID"); RNA_def_property_pointer_funcs(prop, NULL, "rna_Object_data_set", "rna_Object_data_typef", NULL); - RNA_def_property_editable_func(prop, "rna_Object_data_editable"); RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); RNA_def_property_ui_text(prop, "Data", "Object data"); RNA_def_property_update(prop, 0, "rna_Object_internal_update_data"); @@ -2043,6 +2047,12 @@ RNA_def_property_ui_text(prop, "Empty Display Size", "Size of display for empties in the viewport"); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); + prop= RNA_def_property(srna, "origin_offset", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_float_sdna(prop, NULL, "origin_offset"); + RNA_def_property_ui_text(prop, "Origin Offset", "Origin offset distance"); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 0.1f, 2); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); + /* render */ prop= RNA_def_property(srna, "pass_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "index"); Index: source/blender/editors/space_view3d/view3d_ops.c =================================================================== --- source/blender/editors/space_view3d/view3d_ops.c (revision 36543) +++ source/blender/editors/space_view3d/view3d_ops.c (working copy) @@ -306,4 +306,3 @@ viewmove_modal_keymap(keyconf); viewzoom_modal_keymap(keyconf); } - Index: source/blender/editors/space_view3d/drawobject.c =================================================================== --- source/blender/editors/space_view3d/drawobject.c (revision 36543) +++ source/blender/editors/space_view3d/drawobject.c (working copy) @@ -46,6 +46,7 @@ #include "DNA_scene_types.h" #include "DNA_smoke_types.h" #include "DNA_world_types.h" +#include "DNA_armature_types.h" #include "BLI_blenlib.h" #include "BLI_math.h" @@ -76,6 +77,9 @@ #include "smoke_API.h" +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + #include "BIF_gl.h" #include "BIF_glutil.h" @@ -515,6 +519,74 @@ } } + +//*** Function to draw an Image on a empty Object *** +static void draw_image_3D(Object *ob) +{ + Image *img = (Image*)ob->data; + ImBuf *ibuf = img ? BKE_image_get_ibuf(img, NULL) : NULL; + + float scale, ofsx, ofsy; + + if(ibuf) { + if (!ibuf->rect) { + if (ibuf->rect_float) { + IMB_rect_from_float(ibuf); + } + } + } + + if(!ibuf || !ibuf->rect) + return; + + //Calculate Image scale + scale = 1.0 / (float)MAX2(ibuf->x, ibuf->y); + + //Setup GL params + glDepthMask(1); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + //Set color to outline color and object alpha + glColor4fv(ob->col); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + //Make sure we are drawing at the origin + glTranslatef(0.0f, 0.0f, 0.0f); + + //Calculate the scale center based on objects origin + ofsx= ob->origin_offset[0] * ibuf->x; + ofsy= ob->origin_offset[1] * ibuf->y; + + //Set the object scale + glScalef((scale * ob->empty_drawsize), (scale * ob->empty_drawsize), (scale * ob->empty_drawsize)); + + //Draw the Image on the screen + glaDrawPixelsTex(ofsx, ofsy, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect); + glPixelTransferf(GL_ALPHA_SCALE, 1.0f); + + //Set zbuffer, outline shows up better + glDepthMask(1); + + UI_ThemeColor((ob->flag & SELECT) ? TH_SELECT : TH_WIRE); + + //Calculate the outline vertex positions + glBegin(GL_LINE_LOOP); + glVertex2f(ofsx, ofsy); + glVertex2f(ofsx+ibuf->x, ofsy); + glVertex2f(ofsx+ibuf->x, ofsy+ibuf->y); + glVertex2f(ofsx, ofsy+ibuf->y); + glEnd(); + + /* Reset GL settings */ + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glDisable(GL_BLEND); + glDepthMask(1); +} + void drawcircball(int mode, const float cent[3], float rad, float tmat[][4]) { float vec[3], vx[3], vy[3]; @@ -5954,8 +6026,14 @@ break; } case OB_EMPTY: - if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) - drawaxes(ob->empty_drawsize, ob->empty_drawtype); + if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) { + if (ob->data) { + draw_image_3D(ob); + } + else { + drawaxes(ob->empty_drawsize, ob->empty_drawtype); + } + } break; case OB_LAMP: if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) { @@ -6516,7 +6594,7 @@ else dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); - if(dt<=OB_WIRE) { + if(dt==OB_WIRE || dt==BONE_DRAWWIRE) { if(dm) dm->drawEdges(dm, 1, 0); else if(edm) @@ -6564,7 +6642,12 @@ draw_object_mesh_instance(scene, v3d, rv3d, ob, dt, outline); break; case OB_EMPTY: - drawaxes(ob->empty_drawsize, ob->empty_drawtype); + if (ob->data) { + draw_image_3D(ob); + } + else { + drawaxes(ob->empty_drawsize, ob->empty_drawtype); + } break; } }