Merge from 2.5 r21112 through r21160
authorArystanbek Dyussenov <arystan.d@gmail.com>
Fri, 26 Jun 2009 13:00:23 +0000 (13:00 +0000)
committerArystanbek Dyussenov <arystan.d@gmail.com>
Fri, 26 Jun 2009 13:00:23 +0000 (13:00 +0000)
84 files changed:
release/ui/buttons_data_mesh.py
release/ui/space_text.py
source/blender/blenfont/BLF_api.h
source/blender/blenfont/intern/blf_font.c
source/blender/blenfont/intern/blf_glyph.c
source/blender/blenkernel/BKE_context.h
source/blender/blenkernel/BKE_material.h
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/context.c
source/blender/blenkernel/intern/material.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/curve/curve_intern.h
source/blender/editors/curve/curve_ops.c
source/blender/editors/curve/editcurve.c
source/blender/editors/curve/editfont.c
source/blender/editors/include/ED_curve.h
source/blender/editors/include/ED_mesh.h
source/blender/editors/include/ED_previewrender.h
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_icons.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_layout.c
source/blender/editors/interface/interface_regions.c
source/blender/editors/interface/interface_style.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/interface_utils.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/mesh/editmesh.c
source/blender/editors/mesh/editmesh_mods.c
source/blender/editors/physics/ed_pointcache.c
source/blender/editors/preview/previewrender.c
source/blender/editors/space_buttons/buttons_context.c
source/blender/editors/space_buttons/buttons_intern.h
source/blender/editors/space_buttons/buttons_ops.c
source/blender/editors/space_buttons/space_buttons.c
source/blender/editors/space_file/file_draw.c
source/blender/editors/space_file/file_ops.c
source/blender/editors/space_file/filesel.c
source/blender/editors/space_image/image_buttons.c
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_info/info_header.c
source/blender/editors/space_outliner/outliner.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_buttons.c
source/blender/editors/space_view3d/view3d_header.c
source/blender/editors/space_view3d/view3d_toolbar.c
source/blender/makesdna/DNA_particle_types.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/RNA_access.h
source/blender/makesrna/RNA_define.h
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_define.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_particle.c
source/blender/makesrna/intern/rna_ui_api.c
source/blender/makesrna/intern/rna_userdef.c
source/blender/python/generic/Geometry.c
source/blender/python/generic/Mathutils.c
source/blender/python/generic/Mathutils.h
source/blender/python/generic/euler.c
source/blender/python/generic/euler.h
source/blender/python/generic/matrix.c
source/blender/python/generic/matrix.h
source/blender/python/generic/quat.c
source/blender/python/generic/quat.h
source/blender/python/generic/vector.c
source/blender/python/generic/vector.h
source/blender/python/intern/bpy_operator_wrap.c
source/blender/python/intern/bpy_rna.c
source/blender/windowmanager/intern/wm_operators.c
source/gameengine/Converter/BL_ActionActuator.cpp
source/gameengine/Expressions/KX_Python.h
source/gameengine/Expressions/PyObjectPlus.cpp
source/gameengine/Expressions/PyObjectPlus.h
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_ObjectActuator.cpp
source/gameengine/Ketsji/KX_ObjectActuator.h
source/gameengine/Ketsji/KX_PyMath.cpp
source/gameengine/Ketsji/KX_PyMath.h
source/gameengine/Ketsji/KX_PythonInitTypes.cpp

index 5f433a5d83dd6612341d31dc4f80387e9a0877ec..6f64de312edca6bcd6b1eb703c21989321ed9a31 100644 (file)
@@ -14,7 +14,7 @@ class DATA_PT_mesh(DataButtonsPanel):
        __label__ = "Mesh"
        
        def poll(self, context):
-               return (context.object.type == 'MESH')
+               return (context.object and context.object.type == 'MESH')
 
        def draw(self, context):
                layout = self.layout
@@ -46,6 +46,34 @@ class DATA_PT_mesh(DataButtonsPanel):
                        sub.itemR(mesh, "vertex_normal_flip")
                        sub.itemR(mesh, "double_sided")
                        
-                       layout.itemR(mesh, "texco_mesh")                        
-                                       
-bpy.types.register(DATA_PT_mesh)
\ No newline at end of file
+                       layout.itemR(mesh, "texco_mesh")
+
+
+class DATA_PT_materials(DataButtonsPanel):
+       __idname__ = "DATA_PT_materials"
+       __label__ = "Materials"
+       
+       def poll(self, context):
+               return (context.object and context.object.type in ('MESH', 'CURVE', 'FONT', 'SURFACE'))
+
+       def draw(self, context):
+               layout = self.layout
+               ob = context.object
+
+               row = layout.row()
+
+               row.template_list(ob, "materials", "active_material_index")
+
+               col = row.column(align=True)
+               col.itemO("OBJECT_OT_material_slot_add", icon="ICON_ZOOMIN", text="")
+               col.itemO("OBJECT_OT_material_slot_remove", icon="ICON_ZOOMOUT", text="")
+
+               row = layout.row(align=True)
+
+               row.itemO("OBJECT_OT_material_slot_assign", text="Assign");
+               row.itemO("OBJECT_OT_material_slot_select", text="Select");
+               row.itemO("OBJECT_OT_material_slot_deselect", text="Deselect");
+
+bpy.types.register(DATA_PT_mesh)
+bpy.types.register(DATA_PT_materials)
+
index 92e7639553f726c8a8c0d4d66f6ac72a42eb8a45..19a495d375ed08846b700bacdf3eb092ea2c1f9f 100644 (file)
@@ -1,10 +1,6 @@
 
 import bpy
 
-# temporary
-ICON_TEXT = 120
-ICON_HELP = 1
-
 class TEXT_HT_header(bpy.types.Header):
        __space_type__ = "TEXT_EDITOR"
        __idname__ = "TEXT_HT_header"
index cb64615d64c86e5ed32831480f6b56c0a59bff91..2ee31a17fa658a411da7c873c85ddc910233b42c 100644 (file)
@@ -135,6 +135,7 @@ void BLF_dir_free(char **dirs, int count);
 #define BLF_FONT_KERNING (1<<2)
 #define BLF_USER_KERNING (1<<3)
 #define BLF_SHADOW (1<<4)
+#define BLF_OVERLAP_CHAR (1<<5)
 
 /* font->mode. */
 #define BLF_MODE_TEXTURE 0
index ee4ba0ee71a6d3b9ce63488bec8d840cf67239fb..a3c5232cc76f8ac05011a5b55b5b255b906732ef 100644 (file)
@@ -146,20 +146,22 @@ void blf_font_draw(FontBLF *font, char *str)
 
                        if (FT_Get_Kerning(font->face, g_prev_index, glyph_index, FT_KERNING_UNFITTED, &delta) == 0) {
                                pen_x += delta.x >> 6;
-/*
-                               if (pen_x < old_pen_x)
-                                       pen_x= old_pen_x;
-*/
+
+                               if (font->flags & BLF_OVERLAP_CHAR) {
+                                       if (pen_x < old_pen_x)
+                                               pen_x= old_pen_x;
+                               }
                        }
                }
 
                if (font->flags & BLF_USER_KERNING) {
                        old_pen_x= pen_x;
                        pen_x += font->kerning;
-/*
-                       if (pen_x < old_pen_x)
-                               pen_x= old_pen_x;
-*/
+
+                       if (font->flags & BLF_OVERLAP_CHAR) {
+                               if (pen_x < old_pen_x)
+                                       pen_x= old_pen_x;
+                       }
                }
 
                /* do not return this loop if clipped, we want every character tested */
@@ -228,20 +230,22 @@ void blf_font_boundbox(FontBLF *font, char *str, rctf *box)
 
                        if (FT_Get_Kerning(font->face, g_prev_index, glyph_index, FT_KERNING_UNFITTED, &delta) == 0) {
                                pen_x += delta.x >> 6;
-/*
-                               if (pen_x < old_pen_x)
-                                       old_pen_x= pen_x;
-*/
+
+                               if (font->flags & BLF_OVERLAP_CHAR) {
+                                       if (pen_x < old_pen_x)
+                                               pen_x= old_pen_x;
+                               }
                        }
                }
 
                if (font->flags & BLF_USER_KERNING) {
                        old_pen_x= pen_x;
                        pen_x += font->kerning;
-/*
-                       if (pen_x < old_pen_x)
-                               old_pen_x= pen_x;
-*/
+
+                       if (font->flags & BLF_OVERLAP_CHAR) {
+                               if (pen_x < old_pen_x)
+                                       pen_x= old_pen_x;
+                       }
                }
 
                gbox.xmin= g->box.xmin + pen_x;
index 5e0868ea68053664e06e358b286f7a7e66357f9b..a637774d7bf8dbd2173f26525ca0322d4f546098 100644 (file)
@@ -500,6 +500,8 @@ int blf_glyph_texture_render(FontBLF *font, GlyphBLF *g, float x, float y)
        float color[4];
 
        gt= g->tex_data;
+       xo= 0.0f;
+       yo= 0.0f;
 
        if (font->flags & BLF_SHADOW) {
                xo= x;
index 898b84ecdc3cab9560e8631f8eeabd1e9000a503..f536e117b7b1ad3dbd926f216f2bc153c61eb67d 100644 (file)
@@ -131,6 +131,7 @@ void CTX_wm_menu_set(bContext *C, struct ARegion *menu);
    - the dir listbase consits of LinkData items */
 
 PointerRNA CTX_data_pointer_get(const bContext *C, const char *member);
+PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type);
 ListBase CTX_data_collection_get(const bContext *C, const char *member);
 ListBase CTX_data_dir_get(const bContext *C);
 void CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb);
index 38a1d9b13b703ded471127d02057210cc459ae1c..382754ee2b287545ee4e84b2356ab9d979ee6b1d 100644 (file)
@@ -39,6 +39,8 @@ struct Material;
 struct ID;
 struct Object;
 
+/* materials */
+
 void init_def_material(void);
 void free_material(struct Material *sc); 
 void test_object_materials(struct ID *id);
@@ -47,15 +49,22 @@ struct Material *add_material(char *name);
 struct Material *copy_material(struct Material *ma);
 void make_local_material(struct Material *ma);
 
+void automatname(struct Material *);
+
+/* material slots */
+
 struct Material ***give_matarar(struct Object *ob);
 short *give_totcolp(struct Object *ob);
 struct Material *give_current_material(struct Object *ob, int act);
 struct ID *material_from(struct Object *ob, int act);
 void assign_material(struct Object *ob, struct Material *ma, int act);
-void new_material_to_objectdata(struct Object *ob);
 
 int find_material_index(struct Object *ob, struct Material *ma);
 
+void object_add_material_slot(struct Object *ob);
+void object_remove_material_slot(struct Object *ob);
+
+/* rendering */
 
 void init_render_material(struct Material *, int, float *);
 void init_render_materials(int, float *);
@@ -64,12 +73,8 @@ void end_render_materials(void);
 
 int material_in_material(struct Material *parmat, struct Material *mat);
 
-void automatname(struct Material *);
-void delete_material_index(struct Object *ob);            
-
 void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col);
 
-
 #ifdef __cplusplus
 }
 #endif
index 30dcb383ef629410eceac9a0ec81c9827fa2f448..441e17f3318a6aa1f1c0d3a5bdc8ff12d558986d 100644 (file)
@@ -43,6 +43,7 @@ static short id_has_animdata (ID *id)
                case ID_OB:
                case ID_CU:
                case ID_KE:
+               case ID_PA:
                case ID_MA: case ID_TE: case ID_NT:
                case ID_LA: case ID_CA: case ID_WO:
                case ID_SCE:
@@ -883,6 +884,9 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
        /* meshes */
        // TODO...
        
+       /* particles */
+       EVAL_ANIM_IDS(main->particle.first, ADT_RECALC_ANIM);
+       
        /* objects */
                /* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets 
                 * this tagged by Depsgraph on framechange 
index 12deec838a8bd9ce6bf757a7e2c0d164592df2a5..90880e354ec0cffd49139bded76e5bc899f4f71b 100644 (file)
@@ -365,15 +365,20 @@ PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
 {
        bContextDataResult result;
 
-       if(ctx_data_get((bContext*)C, member, &result)) {
+       if(ctx_data_get((bContext*)C, member, &result))
                return result.ptr;
-       }
-       else {
-               PointerRNA ptr;
-               memset(&ptr, 0, sizeof(ptr));
-               return ptr;
-       }
+       else
+               return PointerRNA_NULL;
+}
+
+PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
+{
+       PointerRNA ptr = CTX_data_pointer_get(C, member);
 
+       if(ptr.data && ptr.type == type)
+               return ptr;
+       
+       return PointerRNA_NULL;
 }
 
 ListBase CTX_data_collection_get(const bContext *C, const char *member)
index b410c521dea635e8de87c04a0384fa6ecddc25e9..57b88bb0b3f66e69548c51b7d3713aa40ef510f1 100644 (file)
@@ -615,7 +615,7 @@ int find_material_index(Object *ob, Material *ma)
        return 0;          
 }
 
-void new_material_to_objectdata(Object *ob)
+void object_add_material_slot(Object *ob)
 {
        Material *ma;
        
@@ -854,7 +854,7 @@ void automatname(Material *ma)
 }
 
 
-void delete_material_index(Object *ob)
+void object_remove_material_slot(Object *ob)
 {
        Material *mao, ***matarar;
        Object *obt;
index 54caad7f35b85d973336f198c011fb470c888ec5..7921740cbe865fdbb4e09ca37893f2ec11705ffd 100644 (file)
@@ -2899,7 +2899,9 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
        part= main->particle.first;
        while(part) {
                if(part->id.flag & LIB_NEEDLINK) {
+                       if (part->adt) lib_link_animdata(fd, &part->id, part->adt);
                        part->ipo= newlibadr_us(fd, part->id.lib, part->ipo); // XXX depreceated - old animation system
+                       
                        part->dup_ob = newlibadr(fd, part->id.lib, part->dup_ob);
                        part->dup_group = newlibadr(fd, part->id.lib, part->dup_group);
                        part->eff_group = newlibadr(fd, part->id.lib, part->eff_group);
@@ -2912,6 +2914,7 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
 
 static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
 {
+       part->adt= newdataadr(fd, part->adt);
        part->pd= newdataadr(fd, part->pd);
        part->pd2= newdataadr(fd, part->pd2);
 }
@@ -9522,6 +9525,8 @@ static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSetting
        expand_doit(fd, mainvar, part->dup_group);
        expand_doit(fd, mainvar, part->eff_group);
        expand_doit(fd, mainvar, part->bb_ob);
+       
+       expand_animdata(fd, mainvar, part->adt);
 }
 
 static void expand_group(FileData *fd, Main *mainvar, Group *group)
index 172c081570b4da3cdc0aa7723c65328843acaa6c..ef1e7d70a1ebe3ddfc1d3202168ffcb90a91721e 100644 (file)
@@ -382,6 +382,7 @@ static void writedata(WriteData *wd, int filecode, int len, void *adr)      /* do not
 /*These functions are used by blender's .blend system for file saving/loading.*/
 void IDP_WriteProperty_OnlyData(IDProperty *prop, void *wd);
 void IDP_WriteProperty(IDProperty *prop, void *wd);
+static void write_animdata(WriteData *wd, AnimData *adt); // XXX code needs reshuffling, but not before NLA SoC is merged back into 2.5
 
 static void IDP_WriteArray(IDProperty *prop, void *wd)
 {
@@ -575,6 +576,7 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
                        /* write LibData */
                        writestruct(wd, ID_PA, "ParticleSettings", 1, part);
                        if (part->id.properties) IDP_WriteProperty(part->id.properties, wd);
+                       if (part->adt) write_animdata(wd, part->adt);
                        writestruct(wd, DATA, "PartDeflect", 1, part->pd);
                        writestruct(wd, DATA, "PartDeflect", 1, part->pd2);
                }
index a73a54323ee6d5cd0ea5938181f104e5beaf444b..2146855a75ef87098902070c4fc2e82b5978bd79 100644 (file)
@@ -49,7 +49,6 @@ void FONT_OT_case_toggle(struct wmOperatorType *ot);
 void FONT_OT_case_set(struct wmOperatorType *ot);
 void FONT_OT_style_toggle(struct wmOperatorType *ot);
 void FONT_OT_style_set(struct wmOperatorType *ot);
-void FONT_OT_material_set(struct wmOperatorType *ot);
 
 void FONT_OT_text_copy(struct wmOperatorType *ot);
 void FONT_OT_text_cut(struct wmOperatorType *ot);
index 5292d86d3c9ab1385a0e6f63f2a98bc8151845c9..66cde772f3e3f6f6946e327cea211af69090028f 100644 (file)
@@ -106,7 +106,6 @@ void ED_operatortypes_curve(void)
        WM_operatortype_append(FONT_OT_case_set);
        WM_operatortype_append(FONT_OT_style_toggle);
        WM_operatortype_append(FONT_OT_style_set);
-       WM_operatortype_append(FONT_OT_material_set);
 
        WM_operatortype_append(FONT_OT_text_copy);
        WM_operatortype_append(FONT_OT_text_cut);
index 466908c562c4ffe42176b11ae16a85c8e9c1d41e..5283aacf39e0537d846fe73ecd654298326dc92c 100644 (file)
@@ -189,7 +189,7 @@ static short swap_selection_bpoint(BPoint *bp)
                return select_bpoint(bp, SELECT, 1, VISIBLE);
 }
 
-short isNurbsel(Nurb *nu)
+int isNurbsel(Nurb *nu)
 {
        BezTriple *bezt;
        BPoint *bp;
index 5389db9e2eebca4d309d5f55b395156e96490bdd..9f2bd6f26f9ca4f3e9ff162c6ef0f7cf167bc155 100644 (file)
@@ -700,50 +700,6 @@ void FONT_OT_style_toggle(wmOperatorType *ot)
        RNA_def_enum(ot->srna, "style", style_items, CU_BOLD, "Style", "Style to set selection to.");
 }
 
-/******************* set material operator ********************/
-
-static int set_material_exec(bContext *C, wmOperator *op)
-{
-       Scene *scene= CTX_data_scene(C);
-       Object *obedit= CTX_data_edit_object(C);
-       Curve *cu= obedit->data;
-       EditFont *ef= cu->editfont;
-       int i, mat_nr, selstart, selend;
-
-       if(!BKE_font_getselection(obedit, &selstart, &selend))
-               return OPERATOR_CANCELLED;
-
-       if(RNA_property_is_set(op->ptr, "index"))
-               mat_nr= RNA_int_get(op->ptr, "index");
-       else
-               mat_nr= obedit->actcol;
-
-       for(i=selstart; i<=selend; i++)
-               ef->textbufinfo[i].mat_nr = mat_nr;
-
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
-
-       return OPERATOR_FINISHED;
-}
-
-void FONT_OT_material_set(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name= "Set Material";
-       ot->idname= "FONT_OT_material_set";
-       
-       /* api callbacks */
-       ot->exec= set_material_exec;
-       ot->poll= ED_operator_editfont;
-       
-       /* flags */
-       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-
-       /* properties */
-       RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Material Index", "Material slot index.", 0, INT_MAX);
-}
-
 /******************* copy text operator ********************/
 
 static void copy_selection(Object *obedit)
index c619ee80f707802d2bbc32895326edb6ed517ee3..2cebc6a572a688414e10f9417ff870f37d2e8873 100644 (file)
@@ -30,6 +30,7 @@
 
 struct Base;
 struct bContext;
+struct Nurb;
 struct Object;
 struct Scene;
 struct Text;
@@ -52,6 +53,8 @@ void  mouse_nurb              (struct bContext *C, short mval[2], int extend);
 
 struct Nurb *add_nurbs_primitive(struct bContext *C, int type, int newname);
 
+int            isNurbsel               (struct Nurb *nu);;
+
 /* editfont.h */
 void   undo_push_font  (struct bContext *C, char *name);
 void   make_editText   (struct Object *obedit);
index 6dff4ee6ca472e7e617491d610ddf1845baad8e5..937f6384f6a1e860f65ca0991cfb19ee28d6e4e0 100644 (file)
@@ -147,6 +147,9 @@ int                 EM_init_backbuf_circle(struct ViewContext *vc, short xs, short ys, short r
 void           EM_hide_mesh(struct EditMesh *em, int swap);
 void           EM_reveal_mesh(struct EditMesh *em);
 
+void           EM_select_by_material(struct EditMesh *em, int index);
+void           EM_deselect_by_material(struct EditMesh *em, int index); 
+
 /* editface.c */
 struct MTFace  *EM_get_active_mtface(struct EditMesh *em, struct EditFace **act_efa, struct MCol **mcol, int sloppy);
 
index c74cb0f9958da11cb308c580670fde5d12e25037..10067510e53627963fab0ed3042e823b1c24f183 100644 (file)
 struct View3D;
 struct SpaceButs;
 struct RenderInfo;
+struct Scene;
 struct Image;
-struct ScrArea;
-struct uiBlock;
 struct Render;
 struct bContext;
 struct ID;
 
 #define PREVIEW_RENDERSIZE 140
 
-typedef void (*VectorDrawFunc)(int x, int y, int w, int h, float alpha);
-
 /* stores rendered preview  - is also used for icons */
 typedef struct RenderInfo {
        int pr_rectx;
@@ -74,6 +71,7 @@ void ED_preview_init_dbase(void);
 void ED_preview_free_dbase(void);
 
 void ED_preview_shader_job(const struct bContext *C, void *owner, struct ID *id, int sizex, int sizey);
+void ED_preview_iconrender(struct Scene *scene, struct ID *id, int *rect, int sizex, int sizey);
 
 void ED_preview_draw(const struct bContext *C, void *idp, rcti *rect);
 
index 80e57f5e5be00887e0a0a4acb6a5504d592fd213..f5e2b45d41ea824ac6ef214c608bceb488172a3a 100644 (file)
@@ -417,7 +417,7 @@ void uiBlockPickerButtons(struct uiBlock *block, float *col, float *hsv, float *
 void uiBlockColorbandButtons(struct uiBlock *block, struct ColorBand *coba, struct rctf *butr, int event);
 
 uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, char *name, int icon, int x1, int y1, int x2, int y2);
-void uiDefAutoButsRNA(const struct bContext *C, uiLayout *layout, struct PointerRNA *ptr);
+void uiDefAutoButsRNA(const struct bContext *C, uiLayout *layout, struct PointerRNA *ptr, int columns);
 
 /* Links
  *
@@ -454,7 +454,7 @@ typedef void (*uiButSearchFunc)(const struct bContext *C, void *arg, char *str,
 typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event);
                
                /* use inside searchfunc to add items */
-int            uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin);
+int            uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int iconid);
                /* bfunc gets search item *poin as arg2, or if NULL the old string */
 void   uiButSetSearchFunc      (uiBut *but,            uiButSearchFunc sfunc, void *arg1, uiButHandleFunc bfunc);
                /* height in pixels, it's using hardcoded values still */
@@ -617,6 +617,7 @@ void uiTemplateColorRamp(uiLayout *layout, struct ColorBand *coba, int expand);
 void uiTemplateCurveMapping(uiLayout *layout, struct CurveMapping *cumap, int type);
 void uiTemplateLayers(uiLayout *layout, struct PointerRNA *ptr, char *propname);
 void uiTemplateImageLayers(uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser);
+void uiTemplateList(uiLayout *layout, struct PointerRNA *ptr, char *propname, char *activeprop, int items);
 
 /* items */
 void uiItemO(uiLayout *layout, char *name, int icon, char *opname);
index 780d999cfbe2acf9f404df1b9da642dab482a4e2..73425eac0e16e1d4dfd2dbf50065dcfb3c186b6e 100644 (file)
@@ -671,7 +671,8 @@ void uiDrawBlock(const bContext *C, uiBlock *block)
        /* widgets */
        for(but= block->buttons.first; but; but= but->next) {
                ui_but_to_pixelrect(&rect, ar, block, but);
-               ui_draw_but(C, ar, &style, but, &rect);
+               if(!(but->flag & UI_HIDDEN))
+                       ui_draw_but(C, ar, &style, but, &rect);
        }
        
        /* restore matrix */
@@ -1281,17 +1282,13 @@ void ui_get_but_string(uiBut *but, char *str, int maxlen)
                else if(type == PROP_POINTER) {
                        /* RNA pointer */
                        PointerRNA ptr= RNA_property_pointer_get(&but->rnapoin, but->rnaprop);
-                       PropertyRNA *nameprop;
-
-                       if(ptr.data && (nameprop = RNA_struct_name_property(ptr.type)))
-                               buf= RNA_property_string_get_alloc(&ptr, nameprop, str, maxlen);
-                       else
-                               BLI_strncpy(str, "", maxlen);
+                       buf= RNA_struct_name_get_alloc(&ptr, str, maxlen);
                }
-               else
-                       BLI_strncpy(str, "", maxlen);
 
-               if(buf && buf != str) {
+               if(!buf) {
+                       BLI_strncpy(str, "", maxlen);
+               }
+               else if(buf && buf != str) {
                        /* string was too long, we have to truncate */
                        BLI_strncpy(str, buf, maxlen);
                        MEM_freeN(buf);
@@ -1339,20 +1336,14 @@ void ui_get_but_string(uiBut *but, char *str, int maxlen)
 
 static void ui_rna_ID_collection(bContext *C, uiBut *but, PointerRNA *ptr, PropertyRNA **prop)
 {
-       CollectionPropertyIterator iter;
-       PropertyRNA *iterprop, *iprop;
        StructRNA *srna;
 
        /* look for collection property in Main */
        RNA_pointer_create(NULL, &RNA_Main, CTX_data_main(C), ptr);
 
-       iterprop= RNA_struct_iterator_property(ptr->type);
-       RNA_property_collection_begin(ptr, iterprop, &iter);
        *prop= NULL;
 
-       for(; iter.valid; RNA_property_collection_next(&iter)) {
-               iprop= iter.ptr.data;
-
+       RNA_STRUCT_BEGIN(ptr, iprop) {
                /* if it's a collection and has same pointer type, we've got it */
                if(RNA_property_type(iprop) == PROP_COLLECTION) {
                        srna= RNA_property_pointer_type(ptr, iprop);
@@ -1363,8 +1354,7 @@ static void ui_rna_ID_collection(bContext *C, uiBut *but, PointerRNA *ptr, Prope
                        }
                }
        }
-
-       RNA_property_collection_end(&iter);
+       RNA_STRUCT_END;
 }
 
 /* autocomplete callback for RNA pointers */
@@ -1372,9 +1362,8 @@ static void ui_rna_ID_autocomplete(bContext *C, char *str, void *arg_but)
 {
        uiBut *but= arg_but;
        AutoComplete *autocpl;
-       CollectionPropertyIterator iter;
        PointerRNA ptr;
-       PropertyRNA *prop, *nameprop;
+       PropertyRNA *prop;
        char *name;
        
        if(str[0]==0) return;
@@ -1384,22 +1373,19 @@ static void ui_rna_ID_autocomplete(bContext *C, char *str, void *arg_but)
        if(prop==NULL) return;
 
        autocpl= autocomplete_begin(str, ui_get_but_string_max_length(but));
-       RNA_property_collection_begin(&ptr, prop, &iter);
 
        /* loop over items in collection */
-       for(; iter.valid; RNA_property_collection_next(&iter)) {
-               if(iter.ptr.data && (nameprop = RNA_struct_name_property(iter.ptr.type))) {
-                       name= RNA_property_string_get_alloc(&iter.ptr, nameprop, NULL, 0);
-
-                       if(name) {
-                               /* test item name */
-                               autocomplete_do_name(autocpl, name);
-                               MEM_freeN(name);
-                       }
+       RNA_PROP_BEGIN(&ptr, itemptr, prop) {
+               name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
+
+               /* test item name */
+               if(name) {
+                       autocomplete_do_name(autocpl, name);
+                       MEM_freeN(name);
                }
        }
+       RNA_PROP_END;
 
-       RNA_property_collection_end(&iter);
        autocomplete_end(autocpl, str);
 }
 
index fb5afbf5e3660dab33b89211fd9478ecc328f7fc..2382af53a116fcb9e69531e54f62335be2ec2518 100644 (file)
@@ -404,7 +404,15 @@ static void ui_apply_but_TOG(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
 
 static void ui_apply_but_ROW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data)
 {
+       uiBut *bt;
+       
        ui_set_but_val(but, but->hardmax);
+       
+       /* states of other row buttons */
+       for(bt= block->buttons.first; bt; bt= bt->next)
+               if(bt!=but && bt->poin==but->poin && bt->type==ROW)
+                       ui_check_but(bt);
+       
        ui_apply_but_func(C, but);
 
        data->retval= but->retval;
@@ -738,11 +746,8 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
                        ui_apply_but_ROW(C, block, but, data);
                        break;
                case SCROLL:
-                       break;
                case NUM:
                case NUMABS:
-                       ui_apply_but_NUM(C, but, data);
-                       break;
                case SLI:
                case NUMSLI:
                        ui_apply_but_NUM(C, but, data);
@@ -1433,7 +1438,6 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
                                }
                        }
                        else if(inbox) {
-                               printf("release inside \n");
                                button_activate_state(C, but, BUTTON_STATE_EXIT);
                                retval= WM_UI_HANDLER_BREAK;
                        }
@@ -2053,6 +2057,11 @@ static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, int shift, i
 
        if(but->type==NUMSLI) deler= ((but->x2-but->x1) - 5.0*but->aspect);
        else if(but->type==HSVSLI) deler= ((but->x2-but->x1)/2 - 5.0*but->aspect);
+       else if(but->type==SCROLL) {
+               int horizontal= (but->x2 - but->x1 > but->y2 - but->y1);
+               float size= (horizontal)? (but->x2-but->x1): -(but->y2-but->y1);
+               deler= size*(but->softmax - but->softmin)/(but->softmax - but->softmin + but->a1);
+       }
        else deler= (but->x2-but->x1- 5.0*but->aspect);
 
        f= (float)(mx-data->dragstartx)/deler + data->dragfstart;
@@ -2223,6 +2232,54 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
        return retval;
 }
 
+static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+{
+       int mx, my, click= 0;
+       int retval= WM_UI_HANDLER_CONTINUE;
+       int horizontal= (but->x2 - but->x1 > but->y2 - but->y1);
+       
+       mx= event->x;
+       my= event->y;
+       ui_window_to_block(data->region, block, &mx, &my);
+
+       if(data->state == BUTTON_STATE_HIGHLIGHT) {
+               if(event->val==KM_PRESS) {
+                       if(event->type == LEFTMOUSE) {
+                               if(horizontal) {
+                                       data->dragstartx= mx;
+                                       data->draglastx= mx;
+                               }
+                               else {
+                                       data->dragstartx= my;
+                                       data->draglastx= my;
+                               }
+                               button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+                               retval= WM_UI_HANDLER_BREAK;
+                       }
+                       else if(ELEM(event->type, PADENTER, RETKEY) && event->val==KM_PRESS)
+                               click= 1;
+               }
+       }
+       else if(data->state == BUTTON_STATE_NUM_EDITING) {
+               if(event->type == ESCKEY) {
+                       data->cancel= 1;
+                       data->escapecancel= 1;
+                       button_activate_state(C, but, BUTTON_STATE_EXIT);
+               }
+               else if(event->type == LEFTMOUSE && event->val!=KM_PRESS) {
+                       button_activate_state(C, but, BUTTON_STATE_EXIT);
+               }
+               else if(event->type == MOUSEMOVE) {
+                       if(ui_numedit_but_SLI(but, data, 0, 0, (horizontal)? mx: my))
+                               ui_numedit_apply(C, block, but, data);
+               }
+
+               retval= WM_UI_HANDLER_BREAK;
+       }
+       
+       return retval;
+}
+
 static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
 {
        
@@ -3065,13 +3122,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
        case OPTIONN:
                retval= ui_do_but_TOG(C, but, data, event);
                break;
-#if 0
        case SCROLL:
-               /* DrawBut(b, 1); */
-               /* do_scrollbut(b); */
-               /* DrawBut(b,0); */
+               retval= ui_do_but_SCROLL(C, block, but, data, event);
                break;
-#endif
        case NUM:
        case NUMABS:
                retval= ui_do_but_NUM(C, block, but, data, event);
@@ -3232,7 +3285,8 @@ static uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y)
                for(but=block->buttons.first; but; but= but->next) {
                        if(ELEM3(but->type, LABEL, ROUNDBOX, SEPR))
                                continue;
-
+                       if(but->flag & UI_HIDDEN)
+                               continue;
                        if(ui_but_contains_pt(but, mx, my))
                                /* give precedence to already activated buttons */
                                if(!butover || (!butover->active && but->active))
index df069069a33a01f0b7cb7e84f690c5ef9031babe..6b566012525663fe262113040ac617b0c866f943 100644 (file)
 #include "BLI_blenlib.h"
 #include "BLI_storage_types.h"
 
+#include "DNA_material_types.h"
 #include "DNA_screen_types.h"
+#include "DNA_scene_types.h"
 #include "DNA_userdef_types.h"
 
-
-#include "BKE_utildefines.h"
 #include "BKE_image.h"
 #include "BKE_icons.h"
+#include "BKE_utildefines.h"
 
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
 
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
-#include "UI_interface.h"
-#include "UI_interface_icons.h"
 
-// XXX #include "BIF_previewrender.h"
-// XXX #include "BIF_screen.h"
+#include "ED_datafiles.h"
+#include "ED_previewrender.h"
 
+#include "UI_interface.h"
+#include "UI_interface_icons.h"
 #include "UI_resources.h" /* elubie: should be removed once the enum for the ICONS is in BIF_preview_icons.h */
+
 #include "interface_intern.h"
-#include "ED_datafiles.h"
+
 
 #define ICON_IMAGE_W           600
 #define ICON_IMAGE_H           640
@@ -650,7 +652,6 @@ void UI_icons_init(int first_dyn_id)
        init_internal_icons();
 }
 
-#if 0
 static void icon_copy_rect(ImBuf *ibuf, unsigned int w, unsigned int h, unsigned int *rect)
 {
        struct ImBuf *ima;
@@ -771,18 +772,14 @@ static void set_alpha(char* cp, int sizex, int sizey, char alpha)
                }
        }
 }
-#endif
 
 /* only called when icon has changed */
 /* only call with valid pointer from UI_icon_draw */
-static void icon_set_image(ID *id, DrawInfo *di, PreviewImage* prv_img, int miplevel)
+static void icon_set_image(Scene *scene, ID *id, PreviewImage* prv_img, int miplevel)
 {
-#if 0 // XXX - preview renders have to be redesigned - possibly low level op (elubie)
        RenderInfo ri;  
        unsigned int pr_size = 0;
        
-       if (!di) return;                                
-       
        if (!prv_img) {
                printf("No preview image for this ID: %s\n", id->name);
                return;
@@ -798,13 +795,12 @@ static void icon_set_image(ID *id, DrawInfo *di, PreviewImage* prv_img, int mipl
 
                ri.curtile= 0;
                ri.tottile= 0;
-               ri.rect = NULL;
                ri.pr_rectx = prv_img->w[miplevel];
                ri.pr_recty = prv_img->h[miplevel];
-
                pr_size = ri.pr_rectx*ri.pr_recty*sizeof(unsigned int);
+               ri.rect = MEM_callocN(pr_size, "pr icon rect");
 
-               BIF_previewrender(id, &ri, NULL, PR_ICON_RENDER);
+               ED_preview_iconrender(scene, id, ri.rect, ri.pr_rectx, ri.pr_recty);
 
                /* world is rendered with alpha=0, so it wasn't displayed 
                   this could be render option for sky to, for later */
@@ -818,15 +814,11 @@ static void icon_set_image(ID *id, DrawInfo *di, PreviewImage* prv_img, int mipl
                        }
                }
 
-               if (ri.rect) {
-                       memcpy(prv_img->rect[miplevel], ri.rect, pr_size);
+               memcpy(prv_img->rect[miplevel], ri.rect, pr_size);
 
-                       /* and clean up */
-                       MEM_freeN(ri.rect);
-                       ri.rect = 0;
-               }
+               /* and clean up */
+               MEM_freeN(ri.rect);
        }
-#endif
 }
 
 static void icon_draw_rect(float x, float y, int w, int h, float aspect, int rw, int rh, unsigned int *rect)
@@ -912,14 +904,7 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, int mipl
                PreviewImage* pi = BKE_previewimg_get((ID*)icon->obj); 
 
                if (pi) {                       
-                       if (!nocreate && (pi->changed[miplevel] ||!pi->rect[miplevel])) /* changed only ever set by dynamic icons */
-                       {
-                               // XXX waitcursor(1);
-                               /* create the preview rect if necessary */                              
-                               icon_set_image((ID*)icon->obj, icon->drawinfo, pi, miplevel);
-                               pi->changed[miplevel] = 0;
-                               // XXX waitcursor(0);
-                       }
+                       /* no create icon on this level in code */
                        
                        if (!pi->rect[miplevel]) return; /* something has gone wrong! */
                        
@@ -928,6 +913,22 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, int mipl
        }
 }
 
+void ui_id_icon_render(Scene *scene, ID *id)
+{
+       PreviewImage *pi = BKE_previewimg_get(id); 
+               
+       if (pi) {                       
+               if ((pi->changed[0] ||!pi->rect[0])) /* changed only ever set by dynamic icons */
+               {
+                       /* create the preview rect if necessary */                              
+                       icon_set_image(scene, id, pi, 0);
+                       pi->changed[0] = 0;
+               }
+       }
+}
+
+
+
 static void icon_draw_mipmap(float x, float y, int icon_id, float aspect, int miplevel, int nocreate)
 {
        int draw_size = preview_size(miplevel);
index 19a87c40d9c7b9998f1c67c6725dff01b9e7efbc..c27eafd501cddc9af3d872b2e24bc70f9a74e6a2 100644 (file)
@@ -44,12 +44,17 @@ struct uiStyle;
 struct uiWidgetColors;
 struct uiLayout;
 struct bContextStore;
+struct Scene;
+struct ID;
 
 /* ****************** general defines ************** */
 
 /* visual types for drawing */
 /* for time being separated from functional types */
 typedef enum {
+       /* default */
+       UI_WTYPE_REGULAR,
+
        /* standard set */
        UI_WTYPE_LABEL,
        UI_WTYPE_TOGGLE,
@@ -78,7 +83,8 @@ typedef enum {
        UI_WTYPE_SWATCH,
        UI_WTYPE_RGB_PICKER,
        UI_WTYPE_NORMAL,
-       UI_WTYPE_BOX
+       UI_WTYPE_BOX,
+       UI_WTYPE_SCROLL
        
 } uiWidgetTypeEnum;
 
@@ -98,7 +104,7 @@ typedef enum {
 #define UI_ACTIVE              4
 #define UI_HAS_ICON            8
 #define UI_TEXTINPUT   16
-
+#define UI_HIDDEN              32
 /* warn: rest of uiBut->flag in UI_interface.h */
 
 /* internal panel drawing defines */
@@ -416,11 +422,14 @@ extern void ui_draw_but(const struct bContext *C, ARegion *ar, struct uiStyle *s
 struct ThemeUI;
 void ui_widget_color_init(struct ThemeUI *tui);
 
-void ui_draw_menu_item(struct uiFontStyle *fstyle, rcti *rect, char *name, int state);
+void ui_draw_menu_item(struct uiFontStyle *fstyle, rcti *rect, char *name, int iconid, int state);
 
 /* interface_style.c */
 void uiStyleInit(void);
 
+/* interface_icons.c */
+void ui_id_icon_render(struct Scene *scene, struct ID *id);
+
 /* resources.c */
 void init_userdef_do_versions(void);
 void ui_theme_init_userdef(void);
index 555500004ea9f5ae9d52d258f51534d89aebce0d..03da6861974d528b40894b6536546ecacc40ac22 100644 (file)
@@ -1271,7 +1271,6 @@ static void ui_litem_layout_box(uiLayout *litem)
        h= litem->h;
 
        litem->x += style->boxspace;
-       litem->y -= style->boxspace;
 
        if(w != 0) litem->w -= 2*style->boxspace;
        if(h != 0) litem->h -= 2*style->boxspace;
@@ -1352,6 +1351,7 @@ static void ui_litem_estimate_column_flow(uiLayout *litem)
                }
        }
 
+       litem->w= x;
        litem->h= litem->y - miny;
 }
 
index 32bcae77e6b1d5219714bcbe36409e5f7ad1c080..a1dae39d68768bd34e957654cfebafeb6cdbe945 100644 (file)
@@ -40,6 +40,7 @@
 #include "BLI_dynstr.h"
 
 #include "BKE_context.h"
+#include "BKE_icons.h"
 #include "BKE_report.h"
 #include "BKE_screen.h"
 #include "BKE_texture.h"
@@ -181,7 +182,7 @@ MenuData *decompose_menu_string(char *str)
                                *s= '\0';
                                s++;
                        }
-               } else if (c=='|' || c=='\0') {
+               } else if (c=='|' || c == '\n' || c=='\0') {
                        if (nitem) {
                                *s= '\0';
 
@@ -433,7 +434,7 @@ struct uiSearchItems {
        
        char **names;
        void **pointers;
-       
+       int *icons;
 };
 
 typedef struct uiSearchboxData {
@@ -448,7 +449,7 @@ typedef struct uiSearchboxData {
 
 /* exported for use by search callbacks */
 /* returns zero if nothing to add */
-int uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin)
+int uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int iconid)
 {
        
        if(items->totitem>=items->maxitem) {
@@ -464,6 +465,7 @@ int uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin)
        
        BLI_strncpy(items->names[items->totitem], name, items->maxstrlen);
        items->pointers[items->totitem]= poin;
+       items->icons[items->totitem]= iconid;
        
        items->totitem++;
        
@@ -639,7 +641,8 @@ static void ui_searchbox_region_draw(const bContext *C, ARegion *ar)
                for(a=0; a<data->items.totitem; a++) {
                        ui_searchbox_butrect(&rect, data, a);
                        
-                       ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], (a+1)==data->active?UI_ACTIVE:0);
+                       /* widget itself */
+                       ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a+1)==data->active?UI_ACTIVE:0);
                        
                }
                /* indicate more */
@@ -666,6 +669,7 @@ static void ui_searchbox_region_free(ARegion *ar)
                MEM_freeN(data->items.names[a]);
        MEM_freeN(data->items.names);
        MEM_freeN(data->items.pointers);
+       MEM_freeN(data->items.icons);
        
        MEM_freeN(data);
        ar->regiondata= NULL;
@@ -794,6 +798,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
        data->items.totitem= 0;
        data->items.names= MEM_callocN(SEARCH_ITEMS*sizeof(void *), "search names");
        data->items.pointers= MEM_callocN(SEARCH_ITEMS*sizeof(void *), "search pointers");
+       data->items.icons= MEM_callocN(SEARCH_ITEMS*sizeof(int), "search icons");
        for(x1=0; x1<SEARCH_ITEMS; x1++)
                data->items.names[x1]= MEM_callocN(but->hardmax+1, "search pointers");
        
@@ -1720,24 +1725,118 @@ static void do_picker_small_cb(bContext *C, void *bt1, void *hsv1)
                popup->menuretval= UI_RETURN_UPDATE;
 }
 
+/* picker sizes S hsize, F full size, D spacer, B button/pallette height  */
+#define SPICK1 150.0
+#define DPICK1 6.0
 
-/* only the color, a circle, slider */
-void uiBlockPickerSmall(uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval)
+/* only the color, a HS circle and V slider */
+static void uiBlockPickerSmall(uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval)
 {
        uiBut *bt;
        
        VECCOPY(old, col);      // old color stored there, for palette_cb to work
        
        /* HS circle */
-       bt= uiDefButF(block, HSVCIRCLE, retval, "",     0, 0,SPICK,SPICK, col, 0.0, 0.0, 0, 0, "");
+       bt= uiDefButF(block, HSVCIRCLE, retval, "",     0, 0,SPICK1,SPICK1, col, 0.0, 0.0, 0, 0, "");
+       uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
+
+       /* value */
+       bt= uiDefButF(block, HSVCUBE, retval, "",       SPICK1+DPICK1,0,14,SPICK1, col, 0.0, 0.0, 4, 0, "");
        uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
+}
+
+
+static void picker_new_hide_reveal(uiBlock *block, short colormode)
+{
+       uiBut *bt;
+       
+       /* tag buttons */
+       for(bt= block->buttons.first; bt; bt= bt->next) {
+               
+               if(bt->type==NUMSLI || bt->type==TEX) {
+                       if( bt->str[1]=='e') {
+                               if(colormode==2) bt->flag &= ~UI_HIDDEN;
+                               else bt->flag |= UI_HIDDEN;
+                       }
+                       else if( ELEM3(bt->str[0], 'R', 'G', 'B')) {
+                               if(colormode==0) bt->flag &= ~UI_HIDDEN;
+                               else bt->flag |= UI_HIDDEN;
+                       }
+                       else if( ELEM3(bt->str[0], 'H', 'S', 'V')) {
+                               if(colormode==1) bt->flag &= ~UI_HIDDEN;
+                               else bt->flag |= UI_HIDDEN;
+                       }
+               }
+       }
+}
+
+static void do_picker_new_mode_cb(bContext *C, void *bt1, void *colv)
+{
+       uiBut *bt= bt1;
+       short colormode= ui_get_but_val(bt);
+
+       picker_new_hide_reveal(bt->block, colormode);
+}
+
 
+/* a HS circle, V slider, rgb/hsv/hex sliders */
+static void uiBlockPickerNew(uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval)
+{
+       static short colormode= 0;      /* temp? 0=rgb, 1=hsv, 2=hex */
+       uiBut *bt;
+       int width;
+       
+       VECCOPY(old, col);      // old color stored there, for palette_cb to work
+       
+       /* HS circle */
+       bt= uiDefButF(block, HSVCIRCLE, retval, "",     0, 0,SPICK1,SPICK1, col, 0.0, 0.0, 0, 0, "");
+       uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
+       
        /* value */
-       bt= uiDefButF(block, HSVCUBE, retval, "",       SPICK+DPICK,0,14,SPICK, col, 0.0, 0.0, 4, 0, "");
+       bt= uiDefButF(block, HSVCUBE, retval, "",       SPICK1+DPICK1,0,14,SPICK1, col, 0.0, 0.0, 4, 0, "");
        uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
+       
+       /* mode */
+       width= (SPICK1+DPICK1+14)/3;
+       uiBlockBeginAlign(block);
+       bt= uiDefButS(block, ROW, retval, "RGB",        0, -30, width, 19, &colormode, 0.0, 0.0, 0, 0, "");
+       uiButSetFunc(bt, do_picker_new_mode_cb, bt, col);
+       bt= uiDefButS(block, ROW, retval, "HSV",        width, -30, width, 19, &colormode, 0.0, 1.0, 0, 0, "");
+       uiButSetFunc(bt, do_picker_new_mode_cb, bt, hsv);
+       bt= uiDefButS(block, ROW, retval, "Hex",        2*width, -30, width, 19, &colormode, 0.0, 2.0, 0, 0, "");
+       uiButSetFunc(bt, do_picker_new_mode_cb, bt, hexcol);
+       uiBlockEndAlign(block);
+       
+       /* sliders or hex */
+       width= (SPICK1+DPICK1+14);
+       rgb_to_hsv(col[0], col[1], col[2], hsv, hsv+1, hsv+2);
+       sprintf(hexcol, "%02X%02X%02X", (unsigned int)(col[0]*255.0), (unsigned int)(col[1]*255.0), (unsigned int)(col[2]*255.0));      
+
+       uiBlockBeginAlign(block);
+       bt= uiDefButF(block, NUMSLI, 0, "R ",   0, -60, width, 19, col, 0.0, 1.0, 10, 3, "");
+       uiButSetFunc(bt, do_palette1_cb, bt, hsv);
+       bt= uiDefButF(block, NUMSLI, 0, "G ",   0, -80, width, 19, col+1, 0.0, 1.0, 10, 3, "");
+       uiButSetFunc(bt, do_palette1_cb, bt, hsv);
+       bt= uiDefButF(block, NUMSLI, 0, "B ",   0, -100, width, 19, col+2, 0.0, 1.0, 10, 3, "");
+       uiButSetFunc(bt, do_palette1_cb, bt, hsv);
+       uiBlockEndAlign(block);
+
+       uiBlockBeginAlign(block);
+       bt= uiDefButF(block, NUMSLI, 0, "H ",   0, -60, width, 19, hsv, 0.0, 1.0, 10, 3, "");
+       uiButSetFunc(bt, do_palette2_cb, bt, col);
+       bt= uiDefButF(block, NUMSLI, 0, "S ",   0, -80, width, 19, hsv+1, 0.0, 1.0, 10, 3, "");
+       uiButSetFunc(bt, do_palette2_cb, bt, col);
+       bt= uiDefButF(block, NUMSLI, 0, "V ",   0, -100, width, 19, hsv+2, 0.0, 1.0, 10, 3, "");
+       uiButSetFunc(bt, do_palette2_cb, bt, col);
+       uiBlockEndAlign(block);
+
+       bt= uiDefBut(block, TEX, 0, "Hex: ", 0, -80, width, 19, hexcol, 0, 8, 0, 0, "Hex triplet for color (#RRGGBB)");
+       uiButSetFunc(bt, do_palette_hex_cb, bt, hexcol);
 
+       picker_new_hide_reveal(block, colormode);
 }
 
+
 static int ui_picker_small_wheel(const bContext *C, uiBlock *block, wmEvent *event)
 {
        float add= 0.0f;
@@ -1790,13 +1889,22 @@ uiBlock *ui_block_func_COL(bContext *C, uiPopupBlockHandle *handle, void *arg_bu
                block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_KEEP_OPEN;
                uiBoundsBlock(block, 3);
        }
-       else {
+       else if(win->eventstate->alt) {
                uiBlockPickerSmall(block, handle->retvec, hsvcol, oldcol, hexcol, 'p', 0);
                block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1|UI_BLOCK_OUT_1;
                uiBoundsBlock(block, 10);
                
                block->block_event_func= ui_picker_small_wheel;
-       }               
+       }
+       else {
+               uiBlockPickerNew(block, handle->retvec, hsvcol, oldcol, hexcol, 'p', 0);
+               block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_KEEP_OPEN;
+               uiBoundsBlock(block, 10);
+               
+               block->block_event_func= ui_picker_small_wheel;
+       }
+       
+       
        /* and lets go */
        block->direction= UI_TOP;
        
@@ -2464,7 +2572,6 @@ static uiPopupBlockHandle *ui_pup_menu(bContext *C, int maxrow, uiMenuHandleFunc
        return menu;
 }
 
-
 static void operator_name_cb(bContext *C, void *arg, int retval)
 {
        const char *opname= arg;
index 0d30d8e69c02b447c395e316da86153ac410cd44..e8fba38f793f5f06a35068f4cac3a15cda337556 100644 (file)
@@ -92,6 +92,7 @@ static uiStyle *ui_style_new(ListBase *styles, const char *name)
        style->paneltitle.uifont_id= UIFONT_DEFAULT;
        style->paneltitle.points= 13;
        style->paneltitle.kerning= 0.0;
+       style->paneltitle.overlap= 0;
        style->paneltitle.shadow= 5;
        style->paneltitle.shadx= 2;
        style->paneltitle.shady= -2;
@@ -101,6 +102,7 @@ static uiStyle *ui_style_new(ListBase *styles, const char *name)
        style->grouplabel.uifont_id= UIFONT_DEFAULT;
        style->grouplabel.points= 12;
        style->grouplabel.kerning= 0.0;
+       style->grouplabel.overlap= 0;
        style->grouplabel.shadow= 3;
        style->grouplabel.shadx= 1;
        style->grouplabel.shady= -1;
@@ -109,6 +111,7 @@ static uiStyle *ui_style_new(ListBase *styles, const char *name)
        style->widgetlabel.uifont_id= UIFONT_DEFAULT;
        style->widgetlabel.points= 11;
        style->widgetlabel.kerning= 0.0;
+       style->widgetlabel.overlap= 0;
        style->widgetlabel.shadow= 3;
        style->widgetlabel.shadx= 1;
        style->widgetlabel.shady= -1;
@@ -171,10 +174,15 @@ void uiStyleFontDraw(uiFontStyle *fs, rcti *rect, char *str)
                BLF_shadow_offset(fs->shadx, fs->shady);
        }
 
+       if (fs->overlap)
+               BLF_enable(BLF_OVERLAP_CHAR);
+
        BLF_draw(str);
        BLF_disable(BLF_CLIPPING);
        if (fs->shadow)
                BLF_disable(BLF_SHADOW);
+       if (fs->overlap)
+               BLF_disable(BLF_OVERLAP_CHAR);
 }
 
 /* ************** helpers ************************ */
index 9dd7ae90f20c376600262678427b7c11e7bcbca6..37b2a4af84e219e2e76fc7a9eadb1247b3f040fa 100644 (file)
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_screen_types.h"
+
 #include "BLI_string.h"
 
 #include "BKE_context.h"
+#include "BKE_icons.h"
 #include "BKE_library.h"
 #include "BKE_utildefines.h"
 
@@ -43,6 +46,7 @@
 
 #include "UI_interface.h"
 #include "UI_resources.h"
+#include "interface_intern.h"
 
 void ui_template_fix_linking()
 {
@@ -146,9 +150,26 @@ static void id_search_cb(const struct bContext *C, void *arg_litem, char *str, u
        ID *id;
        
        for(id= lb->first; id; id= id->next) {
+               int iconid= 0;
+               
+               /* icon */
+               switch(GS(id->name))
+               {
+                       case ID_MA: /* fall through */
+                       case ID_TE: /* fall through */
+                       case ID_IM: /* fall through */
+                       case ID_WO: /* fall through */
+                       case ID_LA: /* fall through */
+                               iconid= BKE_icon_getid(id);
+                               /* checks if not exists, or changed */
+                               ui_id_icon_render(CTX_data_scene(C), id);
+                               break;
+                       default:
+                               break;
+               }
                
                if(BLI_strcasestr(id->name+2, str)) {
-                       if(0==uiSearchItemAdd(items, id->name+2, id))
+                       if(0==uiSearchItemAdd(items, id->name+2, id, iconid))
                                break;
                }
        }
@@ -362,6 +383,15 @@ static void modifiers_del(bContext *C, void *ob_v, void *md_v)
        BKE_reports_clear(&reports);
 }
 
+static void modifiers_activate(bContext *C, void *ob_v, void *md_v)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *ob= ob_v;
+
+       WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
+       DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+}
+
 static void modifiers_moveUp(bContext *C, void *ob_v, void *md_v)
 {
        Scene *scene= CTX_data_scene(C);
@@ -575,8 +605,10 @@ static uiLayout *draw_modifier(uiLayout *layout, Object *ob, ModifierData *md, i
                if (((md->type!=eModifierType_Softbody && md->type!=eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) && (md->type!=eModifierType_Surface)) {
                        uiDefIconButBitI(block, TOG, eModifierMode_Render, 0, ICON_SCENE, 0, 0, 19, UI_UNIT_Y,&md->mode, 0, 0, 1, 0, "Enable modifier during rendering");
                        but= uiDefIconButBitI(block, TOG, eModifierMode_Realtime, 0, ICON_VIEW3D, 0, 0, 19, UI_UNIT_Y,&md->mode, 0, 0, 1, 0, "Enable modifier during interactive display");
+                       uiButSetFunc(but, modifiers_activate, ob, md);
                        if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
-                               uiDefIconButBitI(block, TOG, eModifierMode_Editmode, 0, ICON_EDITMODE_HLT, 0, 0, 19, UI_UNIT_Y,&md->mode, 0, 0, 1, 0, "Enable modifier during Editmode (only if enabled for display)");
+                               but= uiDefIconButBitI(block, TOG, eModifierMode_Editmode, 0, ICON_EDITMODE_HLT, 0, 0, 19, UI_UNIT_Y,&md->mode, 0, 0, 1, 0, "Enable modifier during Editmode (only if enabled for display)");
+                               uiButSetFunc(but, modifiers_activate, ob, md);
                        }
                }
                uiBlockEndAlign(block);
@@ -1494,3 +1526,148 @@ void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, char *propname)
        }
 }
 
+
+/************************* List Template **************************/
+
+typedef struct ListItem {
+       PointerRNA ptr;
+       PropertyRNA *prop;
+       PropertyRNA *activeprop;
+
+       PointerRNA activeptr;
+       int activei;
+
+       int selected;
+} ListItem;
+
+static void list_item_cb(bContext *C, void *arg_item, void *arg_unused)
+{
+       ListItem *item= (ListItem*)arg_item;
+       PropertyType activetype;
+       char *activename;
+
+       if(item->selected) {
+               activetype= RNA_property_type(item->activeprop);
+
+               if(activetype == PROP_POINTER)
+                       RNA_property_pointer_set(&item->ptr, item->activeprop, item->activeptr);
+               else if(activetype == PROP_INT)
+                       RNA_property_int_set(&item->ptr, item->activeprop, item->activei);
+               else if(activetype == PROP_STRING) {
+                       activename= RNA_struct_name_get_alloc(&item->activeptr, NULL, 0);
+                       RNA_property_string_set(&item->ptr, item->activeprop, activename);
+                       MEM_freeN(activename);
+               }
+       }
+}
+
+void uiTemplateList(uiLayout *layout, PointerRNA *ptr, char *propname, char *activepropname, int items)
+{
+       PropertyRNA *prop, *activeprop;
+       PropertyType type, activetype;
+       PointerRNA activeptr;
+       uiLayout *box, *row, *col;
+       uiBlock *block;
+       uiBut *but;
+       char *name, *activename= NULL;
+       int i= 1, activei= 0, len;
+       static int scroll = 1;
+       
+       /* validate arguments */
+       if(!ptr->data)
+               return;
+       
+       prop= RNA_struct_find_property(ptr, propname);
+       if(!prop) {
+               printf("uiTemplateList: property not found: %s\n", propname);
+               return;
+       }
+
+       activeprop= RNA_struct_find_property(ptr, activepropname);
+       if(!activeprop) {
+               printf("uiTemplateList: property not found: %s\n", activepropname);
+               return;
+       }
+
+       type= RNA_property_type(prop);
+       if(type != PROP_COLLECTION) {
+               printf("uiTemplateList: expected collection property.\n");
+               return;
+       }
+
+       activetype= RNA_property_type(activeprop);
+       if(!ELEM3(activetype, PROP_POINTER, PROP_INT, PROP_STRING)) {
+               printf("uiTemplateList: expected pointer, integer or string property.\n");
+               return;
+       }
+
+       if(items == 0)
+               items= 5;
+
+       /* get active data */
+       if(activetype == PROP_POINTER)
+               activeptr= RNA_property_pointer_get(ptr, activeprop);
+       else if(activetype == PROP_INT)
+               activei= RNA_property_int_get(ptr, activeprop);
+       else if(activetype == PROP_STRING)
+               activename= RNA_property_string_get_alloc(ptr, activeprop, NULL, 0);
+
+       box= uiLayoutBox(layout);
+       row= uiLayoutRow(box, 0);
+       col = uiLayoutColumn(row, 1);
+
+       block= uiLayoutGetBlock(col);
+       uiBlockSetEmboss(block, UI_EMBOSSN);
+
+       len= RNA_property_collection_length(ptr, prop);
+       scroll= MIN2(scroll, len-items+1);
+       scroll= MAX2(scroll, 1);
+
+       RNA_PROP_BEGIN(ptr, itemptr, prop) {
+               if(i >= scroll && i<scroll+items) {
+                       name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
+
+                       if(name) {
+                               ListItem *item= MEM_callocN(sizeof(ListItem), "uiTemplateList ListItem");
+
+                               item->ptr= *ptr;
+                               item->prop= prop;
+                               item->activeprop= activeprop;
+                               item->activeptr= itemptr;
+                               item->activei= i;
+
+                               if(activetype == PROP_POINTER)
+                                       item->selected= (activeptr.data == itemptr.data)? i: -1;
+                               else if(activetype == PROP_INT)
+                                       item->selected= (activei == i)? i: -1;
+                               else if(activetype == PROP_STRING)
+                                       item->selected= (strcmp(activename, name) == 0)? i: -1;
+
+                               but= uiDefIconTextButI(block, ROW, 0, RNA_struct_ui_icon(itemptr.type), name, 0,0,UI_UNIT_X*10,UI_UNIT_Y, &item->selected, 0, i, 0, 0, "");
+                               uiButSetFlag(but, UI_ICON_LEFT|UI_TEXT_LEFT);
+                               uiButSetNFunc(but, list_item_cb, item, NULL);
+
+                               MEM_freeN(name);
+                       }
+               }
+
+               i++;
+       }
+       RNA_PROP_END;
+
+       while(i < scroll+items) {
+               if(i >= scroll)
+                       uiItemL(col, "", 0);
+               i++;
+       }
+
+       uiBlockSetEmboss(block, UI_EMBOSS);
+
+       if(len > items) {
+               col= uiLayoutColumn(row, 0);
+               uiDefButI(block, SCROLL, 0, "", 0,0,UI_UNIT_X*0.75,UI_UNIT_Y*items, &scroll, 1, len-items+1, items, 0, "");
+       }
+
+       //uiDefButI(block, SCROLL, 0, "", 0,0,UI_UNIT_X*15,UI_UNIT_Y*0.75, &scroll, 1, 16-5, 5, 0, "");
+}
+
index a75a3402774705ae413932064a085be428b64934..e67e5b5a871dd94d771f43cc7cf58cbd715ea748 100644 (file)
@@ -43,6 +43,7 @@
 #include "BKE_colortools.h"
 #include "BKE_context.h"
 #include "BKE_idprop.h"
+#include "BKE_icons.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_texture.h"
@@ -120,6 +121,8 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
                        if(!pptr.type)
                                pptr.type= RNA_property_pointer_type(ptr, prop);
                        icon= RNA_struct_ui_icon(pptr.type);
+                       if(icon == ICON_DOT)
+                               icon= 0;
 
                        but= uiDefIconTextButR(block, IDPOIN, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
                        break;
@@ -139,69 +142,39 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
        return but;
 }
 
-void uiDefAutoButsRNA(const bContext *C, uiLayout *layout, PointerRNA *ptr)
+void uiDefAutoButsRNA(const bContext *C, uiLayout *layout, PointerRNA *ptr, int columns)
 {
-       CollectionPropertyIterator iter;
-       PropertyRNA *iterprop, *prop;
-       uiLayout *split;
+       uiLayout *split, *col;
        char *name;
 
        uiItemL(layout, (char*)RNA_struct_ui_name(ptr->type), 0);
 
-       iterprop= RNA_struct_iterator_property(ptr->type);
-       RNA_property_collection_begin(ptr, iterprop, &iter);
-
-       for(; iter.valid; RNA_property_collection_next(&iter)) {
-               prop= iter.ptr.data;
-
+       RNA_STRUCT_BEGIN(ptr, prop) {
                if(strcmp(RNA_property_identifier(prop), "rna_type") == 0)
                        continue;
 
-               split = uiLayoutSplit(layout, 0.5f);
-
                name= (char*)RNA_property_ui_name(prop);
 
-               uiItemL(uiLayoutColumn(split, 0), name, 0);
-               uiItemFullR(uiLayoutColumn(split, 0), "", 0, ptr, prop, -1, 0, 0, 0, 0);
-       }
+               if(columns == 1) {
+                       col= uiLayoutColumn(layout, 1);
+                       uiItemL(col, name, 0);
+               }
+               else if(columns == 2) {
+                       split = uiLayoutSplit(layout, 0.5f);
 
-       RNA_property_collection_end(&iter);
-}
+                       uiItemL(uiLayoutColumn(split, 0), name, 0);
+                       col= uiLayoutColumn(split, 0);
+               }
 
-/* temp call, single collumn, test for toolbar only */
-void uiDefAutoButsRNA_single(const bContext *C, uiLayout *layout, PointerRNA *ptr)
-{
-       CollectionPropertyIterator iter;
-       PropertyRNA *iterprop, *prop;
-       uiLayout *col;
-       char *name;
-       
-       uiItemL(layout, (char*)RNA_struct_ui_name(ptr->type), 0);
-       
-       iterprop= RNA_struct_iterator_property(ptr->type);
-       RNA_property_collection_begin(ptr, iterprop, &iter);
-       
-       for(; iter.valid; RNA_property_collection_next(&iter)) {
-               prop= iter.ptr.data;
-               
-               if(strcmp(RNA_property_identifier(prop), "rna_type") == 0)
-                       continue;
-               
-               name= (char*)RNA_property_ui_name(prop);
-               col= uiLayoutColumn(layout, 1);
-               uiItemL(col, name, 0);
-               
                /* temp hack to show normal button for spin/screw */
                if(strcmp(name, "Axis")==0) {
-                       uiDefButR(uiLayoutGetBlock(layout), BUT_NORMAL, 0, name, 0, 0, 100, 100, ptr, "axis", -1, 0, 0, -1, -1, NULL);
+                       uiDefButR(uiLayoutGetBlock(col), BUT_NORMAL, 0, name, 0, 0, 100, 100, ptr, "axis", -1, 0, 0, -1, -1, NULL);
                }
                else uiItemFullR(col, "", 0, ptr, prop, -1, 0, 0, 0, 0);
        }
-       
-       RNA_property_collection_end(&iter);
+       RNA_STRUCT_END;
 }
 
-
 /***************************** ID Utilities *******************************/
 /* note, C code version, will be replaced with version in interface_templates.c */
 
@@ -304,9 +277,25 @@ static void id_search_cb(const struct bContext *C, void *arg_params, char *str,
        ID *id;
        
        for(id= params->lb->first; id; id= id->next) {
+               int iconid= 0;
+               
+               
+               /* icon */
+               switch(GS(id->name))
+               {
+                       case ID_MA: /* fall through */
+                       case ID_TE: /* fall through */
+                       case ID_IM: /* fall through */
+                       case ID_WO: /* fall through */
+                       case ID_LA: /* fall through */
+                               iconid= BKE_icon_getid(id);
+                               break;
+                       default:
+                               break;
+               }
                
                if(BLI_strcasestr(id->name+2, str)) {
-                       if(0==uiSearchItemAdd(items, id->name+2, id))
+                       if(0==uiSearchItemAdd(items, id->name+2, id, iconid))
                                break;
                }
        }
index bae8cdab2cdb6ad0c9f3ec7d33970cf89ff2dccf..735cfe742c60af279c27915ec545cbe7d82b9087 100644 (file)
@@ -102,6 +102,7 @@ typedef struct uiWidgetBase {
        float inner_uv[64][2];
        
        short inner, outline, emboss; /* set on/off */
+       short shadedir;
        
        uiWidgetTrias tria1;
        uiWidgetTrias tria2;
@@ -199,6 +200,7 @@ static void widget_init(uiWidgetBase *wtb)
        wtb->inner= 1;
        wtb->outline= 1;
        wtb->emboss= 1;
+       wtb->shadedir= 1;
 }
 
 /* helper call, makes shadow rect, with 'sun' above menu, so only shadow to left/right/bottom */
@@ -583,7 +585,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
                        glShadeModel(GL_SMOOTH);
                        glBegin(GL_POLYGON);
                        for(a=0; a<wtb->totvert; a++) {
-                               round_box_shade_col4(col1, col2, wtb->inner_uv[a][1]);
+                               round_box_shade_col4(col1, col2, wtb->inner_uv[a][wtb->shadedir]);
                                glVertex2fv(wtb->inner_v[a]);
                        }
                        glEnd();
@@ -1088,6 +1090,32 @@ static struct uiWidgetColors wcol_box= {
        0, 0
 };
 
+static struct uiWidgetColors wcol_toggle= {
+       {25, 25, 25, 255},
+       {153, 153, 153, 255},
+       {100, 100, 100, 255},
+       {25, 25, 25, 255},
+       
+       {0, 0, 0, 255},
+       {255, 255, 255, 255},
+       
+       0,
+       0, 0
+};
+
+static struct uiWidgetColors wcol_scroll= {
+       {25, 25, 25, 255},
+       {180, 180, 180, 255},
+       {153, 153, 153, 255},
+       {90, 90, 90, 255},
+       
+       {0, 0, 0, 255},
+       {255, 255, 255, 255},
+       
+       1,
+       0, -20
+};
+
 /* free wcol struct to play with */
 static struct uiWidgetColors wcol_tmp= {
        {0, 0, 0, 255},
@@ -1109,9 +1137,10 @@ void ui_widget_color_init(ThemeUI *tui)
 
        tui->wcol_regular= wcol_regular;
        tui->wcol_tool= wcol_tool;
-       tui->wcol_radio= wcol_radio;
        tui->wcol_text= wcol_text;
+       tui->wcol_radio= wcol_radio;
        tui->wcol_option= wcol_option;
+       tui->wcol_toggle= wcol_toggle;
        tui->wcol_num= wcol_num;
        tui->wcol_numslider= wcol_numslider;
        tui->wcol_menu= wcol_menu;
@@ -1119,6 +1148,7 @@ void ui_widget_color_init(ThemeUI *tui)
        tui->wcol_menu_back= wcol_menu_back;
        tui->wcol_menu_item= wcol_menu_item;
        tui->wcol_box= wcol_box;
+       tui->wcol_scroll= wcol_scroll;
 }
 
 /* ************ button callbacks, state ***************** */
@@ -1602,6 +1632,75 @@ void ui_draw_link_bezier(rcti *rect)
        }
 }
 
+static void widget_scroll(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
+{
+       uiWidgetBase wtb;
+       rcti rect1;
+       double value;
+       char inner[3];
+       float fac, size, rad;
+       int horizontal;
+
+       /* determine horizontal/vertical */
+       horizontal= (rect->xmax - rect->xmin > rect->ymax - rect->ymin);
+
+       if(horizontal)
+               rad= 0.5f*(rect->ymax - rect->ymin);
+       else
+               rad= 0.5f*(rect->xmax - rect->xmin);
+
+       widget_init(&wtb);
+       wtb.shadedir= (horizontal)? 1: 0;
+
+       /* draw back part, colors swapped and shading inverted */
+       VECCOPY(inner, wcol->inner);
+       VECCOPY(wcol->inner, wcol->item);
+       if(horizontal)
+               SWAP(short, wcol->shadetop, wcol->shadedown);
+       if(state & UI_SELECT)
+               SWAP(short, wcol->shadetop, wcol->shadedown);
+       
+       round_box_edges(&wtb, roundboxalign, rect, rad); /* XXX vertical gradient is wrong */
+       widgetbase_draw(&wtb, wcol);
+
+       VECCOPY(wcol->inner, inner);
+       if(horizontal)
+               SWAP(short, wcol->shadetop, wcol->shadedown);
+       if(state & UI_SELECT)
+               SWAP(short, wcol->shadetop, wcol->shadedown);
+       
+       /* front part */
+       value= ui_get_but_val(but);
+
+       size= (but->softmax + but->a1 - but->softmin);
+       size= MAX2(size, 2);
+       
+       /* position */
+       rect1= *rect;
+
+       if(horizontal) {
+               fac= (rect->xmax - rect->xmin)/(size-1);
+               rect1.xmin= rect1.xmin + ceil(fac*(value - but->softmin));
+               rect1.xmax= rect1.xmin + ceil(fac*(but->a1 - but->softmin));
+       }
+       else {
+               fac= (rect->ymax - rect->ymin)/(size-1);
+               rect1.ymax= rect1.ymax - ceil(fac*(value - but->softmin));
+               rect1.ymin= rect1.ymax - ceil(fac*(but->a1 - but->softmin));
+       }
+
+       /* draw */
+       wtb.emboss= 0; /* only emboss once */
+
+       if(!horizontal)
+               SWAP(short, wcol->shadetop, wcol->shadedown);
+
+       round_box_edges(&wtb, roundboxalign, &rect1, rad); /* XXX vertical gradient is wrong */
+       widgetbase_draw(&wtb, wcol);
+
+       if(!horizontal)
+               SWAP(short, wcol->shadetop, wcol->shadedown);
+}
 
 static void widget_link(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
 {
@@ -1896,13 +1995,16 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
        wt.text= widget_draw_text_icon;
        
        switch(type) {
+               case UI_WTYPE_REGULAR:
+                       break;
+
                case UI_WTYPE_LABEL:
                        wt.draw= NULL;
                        wt.state= widget_state_label;
                        break;
                        
                case UI_WTYPE_TOGGLE:
-                       wt.wcol_theme= &btheme->tui.wcol_radio;/*use radio theme for toggles*/
+                       wt.wcol_theme= &btheme->tui.wcol_toggle;
                        break;
                        
                case UI_WTYPE_OPTION:
@@ -1915,7 +2017,7 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
                        wt.wcol_theme= &btheme->tui.wcol_radio;
                        wt.draw= widget_radiobut;
                        break;
-                       
+
                case UI_WTYPE_NUMBER:
                        wt.wcol_theme= &btheme->tui.wcol_num;
                        wt.draw= widget_numbut;
@@ -1996,6 +2098,11 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
                        
                case UI_WTYPE_NORMAL:
                        break;
+
+               case UI_WTYPE_SCROLL:
+                       wt.wcol_theme= &btheme->tui.wcol_scroll;
+                       wt.custom= widget_scroll;
+                       break;
        }
        
        return &wt;
@@ -2090,6 +2197,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
                        case BUT:
                                wt= widget_type(UI_WTYPE_EXEC);
                                break;
+
                        case NUM:
                                wt= widget_type(UI_WTYPE_NUMBER);
                                break;
@@ -2185,9 +2293,13 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
                        case BUT_CURVE:
                                ui_draw_but_CURVE(ar, but, &tui->wcol_regular, rect);
                                break;
-                               
+
+                       case SCROLL:
+                               wt= widget_type(UI_WTYPE_SCROLL);
+                               break;
+
                        default:
-                               wt= widget_type(UI_WTYPE_TOGGLE);
+                               wt= widget_type(UI_WTYPE_REGULAR);
                }
        }
        
@@ -2196,6 +2308,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
                int roundboxalign, state;
                
                roundboxalign= widget_roundbox_set(but, rect);
+
                state= but->flag;
                if(but->editstr) state |= UI_TEXTINPUT;
                
@@ -2243,7 +2356,7 @@ void ui_draw_search_back(uiStyle *style, uiBlock *block, rcti *rect)
 
 /* helper call to draw a menu item without button */
 /* state: UI_ACTIVE or 0 */
-void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, char *name, int state)
+void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, char *name, int iconid, int state)
 {
        uiWidgetType *wt= widget_type(UI_WTYPE_MENU_ITEM);
        rcti _rect= *rect;
@@ -2257,6 +2370,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, char *name, int state)
        
        /* text location offset */
        rect->xmin+=5;
+       if(iconid) rect->xmin+= ICON_HEIGHT;
 
        /* cut string in 2 parts? */
        cpoin= strchr(name, '|');
@@ -2279,5 +2393,12 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, char *name, int state)
        /* restore rect, was messed with */
        *rect= _rect;
 
+       if(iconid) {
+               int xs= rect->xmin+4;
+               int ys= 1 + (rect->ymin+rect->ymax- ICON_HEIGHT)/2;
+               glEnable(GL_BLEND);
+               UI_icon_draw_aspect_blended(xs, ys, iconid, 1.2f, 0); /* XXX scale weak get from fstyle? */
+               glDisable(GL_BLEND);
+       }
 }
 
index c05751feddccc9d1f53677766156da19158fa470..7f5201f4704f026660fbeef6d1b6f5276969219e 100644 (file)
@@ -1556,7 +1556,7 @@ static int mesh_separate_material(Scene *scene, Base *editbase)
                /* clear selection, we're going to use that to select material group */
                EM_clear_flag_all(em, SELECT);
                /* select the material */
-               editmesh_select_by_material(em, curr_mat);
+               EM_select_by_material(em, curr_mat);
                /* and now separate */
                if(0==mesh_separate_selected(scene, editbase)) {
                        BKE_mesh_end_editmesh(me, em);
index 07ed6ae7a0136d38368e475bf488c32576ae0263..7e9fcb10984ff8e3c09e4028ed7cc13be57ec019 100644 (file)
@@ -3484,7 +3484,7 @@ void MESH_OT_select_random(wmOperatorType *ot)
        RNA_def_float_percentage(ot->srna, "percent", 0.5f, 0.0f, 1.0f, "Percent", "Percentage of vertices to select randomly.", 0.0001f, 1.0f);
 }
 
-void editmesh_select_by_material(EditMesh *em, int index) 
+void EM_select_by_material(EditMesh *em, int index) 
 {
        EditFace *efa;
        
@@ -3497,7 +3497,7 @@ void editmesh_select_by_material(EditMesh *em, int index)
        EM_selectmode_flush(em);
 }
 
-void editmesh_deselect_by_material(EditMesh *em, int index) 
+void EM_deselect_by_material(EditMesh *em, int index) 
 {
        EditFace *efa;
        
index e47f44c5c1ab733bde17e39d04130c4c4b4333ca..3374e05883cf8f99fc3f5412d27afcfc97ec482b 100644 (file)
@@ -83,7 +83,7 @@ static int ptcache_bake_all_exec(bContext *C, wmOperator *op)
        baker.render = 0;
        baker.break_test = cache_break_test;
        baker.break_data = NULL;
-       baker.progressbar = WM_timecursor;
+       baker.progressbar = (void (*)(void *, int))WM_timecursor;
        baker.progresscontext = CTX_wm_window(C);
 
        BKE_ptcache_make_cache(&baker);
@@ -170,7 +170,7 @@ static int ptcache_bake_particle_system_exec(bContext *C, wmOperator *op)
        baker.render = 0;
        baker.break_test = cache_break_test;
        baker.break_data = NULL;
-       baker.progressbar = WM_timecursor;
+       baker.progressbar = (void (*)(void *, int))WM_timecursor;
        baker.progresscontext = CTX_wm_window(C);
 
        BKE_ptcache_make_cache(&baker);
index 1ce20fcb0afe4d40ccbc2019c5620208e499509b..1efa5108b96081bd3dca99d3b223d8d1347087b9 100644 (file)
@@ -114,46 +114,12 @@ typedef struct ShaderPreview {
        ID *id;
        
        int sizex, sizey;
+       int *pr_rect;
        int pr_method;
        
 } ShaderPreview;
 
 
-static void set_previewrect(ScrArea *sa, RenderInfo *ri)
-{
-       ARegion *ar= NULL; // XXX
-       rctf viewplane;
-       
-       BLI_init_rctf(&viewplane, PR_XMIN, PR_XMAX, PR_YMIN, PR_YMAX);
-
-//     ui_graphics_to_window_rct(ar->win, &viewplane, &ri->disprect);
-       
-       /* correction for gla draw */
-       BLI_translate_rcti(&ri->disprect, -ar->winrct.xmin, -ar->winrct.ymin);
-       
-       glMatrixMode(GL_PROJECTION);
-       glPushMatrix();
-       glMatrixMode(GL_MODELVIEW);
-       glPushMatrix();
-       
-       glaDefine2DArea(&ar->winrct);
-
-       ri->pr_rectx= (ri->disprect.xmax-ri->disprect.xmin);
-       ri->pr_recty= (ri->disprect.ymax-ri->disprect.ymin);
-}
-
-static void end_previewrect(ARegion *ar)
-{
-       glMatrixMode(GL_PROJECTION);
-       glPopMatrix();
-       glMatrixMode(GL_MODELVIEW);
-       glPopMatrix();
-       
-       // restore viewport / scissor which was set by glaDefine2DArea
-       glViewport(ar->winrct.xmin, ar->winrct.ymin, ar->winx, ar->winy);
-       glScissor(ar->winrct.xmin, ar->winrct.ymin, ar->winx, ar->winy);
-
-}
 
 /* unused now */
 void draw_tex_crop(Tex *tex)
@@ -438,196 +404,6 @@ static Scene *preview_prepare_scene(Scene *scene, int id_type, ShaderPreview *sp
        return NULL;
 }
 
-void previewrender_progress(void *handle, RenderResult *rr, volatile rcti *renrect)
-{
-       SpaceButs *sbuts= NULL; // XXX
-       RenderLayer *rl;
-       RenderInfo *ri= sbuts->ri;
-       float ofsx, ofsy;
-       
-       if(renrect) return;
-       
-       rl= rr->layers.first;
-       
-       ofsx= ri->disprect.xmin + rr->tilerect.xmin;
-       ofsy= ri->disprect.ymin + rr->tilerect.ymin;
-       
-       glDrawBuffer(GL_FRONT);
-       glaDrawPixelsSafe_to32(ofsx, ofsy, rr->rectx, rr->recty, rr->rectx, rl->rectf);
-       bglFlush();
-       glDrawBuffer(GL_BACK);
-}
-
-
-/* called by interface_icons.c, or by BIF_previewrender_buts or by nodes... */
-void BIF_previewrender(Scene *scene, struct ID *id, struct RenderInfo *ri, struct ScrArea *area, int pr_method)
-{
-       SpaceButs *sbuts= NULL; // XXX
-       Render *re;
-       RenderStats *rstats;
-       Scene *sce;
-       int oldx= ri->pr_rectx, oldy= ri->pr_recty;
-       char name [32];
-       
-       if(ri->tottile && ri->curtile>=ri->tottile) return;
-       
-       /* check for return with a new event */
-       if(pr_method!=PR_ICON_RENDER && qtest()) {
-//             if(area)
-//                     addafterqueue(area->win, RENDERPREVIEW, 1);
-               return;
-       }
-       
-       /* get the stuff from the builtin preview dbase */
-//     sce= preview_prepare_scene(scene, ri, GS(id->name), id, pr_method);
-       if(sce==NULL) return;
-       
-       /* set drawing conditions OK */
-       if(area) {
-               sbuts= area->spacedata.first;   /* needed for flag */
-               
-               set_previewrect(area, ri); // uses UImat
-               
-               /* because preview render size can differs */
-               if(ri->rect && (oldx!=ri->pr_rectx || oldy!=ri->pr_recty)) {
-                       MEM_freeN(ri->rect);
-                       ri->rect= NULL;
-                       ri->curtile= 0;
-               }
-       }
-       
-// XXX sprintf(name, "ButsPreview %d", area?area->win:0);
-       re= RE_GetRender(name);
-       
-       /* full refreshed render from first tile */
-       if(re==NULL || ri->curtile==0) {
-               
-               re= RE_NewRender(name);
-               
-               /* handle cases */
-               if(pr_method==PR_DRAW_RENDER) {
-//                     RE_display_draw_cb(re, previewrender_progress);
-//                     RE_test_break_cb(re, qtest);
-                       sce->r.scemode |= R_NODE_PREVIEW;
-                       if(sbuts->flag & SB_PRV_OSA)
-                               sce->r.mode |= R_OSA;
-                       sce->r.scemode &= ~R_NO_IMAGE_LOAD;
-               }
-               else if(pr_method==PR_DO_RENDER) {
-//                     RE_test_break_cb(re, qtest);
-                       sce->r.scemode |= R_NODE_PREVIEW;
-                       sce->r.scemode &= ~R_NO_IMAGE_LOAD;
-               }
-               else {  /* PR_ICON_RENDER */
-                       sce->r.scemode &= ~R_NODE_PREVIEW;
-                       sce->r.scemode |= R_NO_IMAGE_LOAD;
-               }
-               
-               /* allocates render result */
-               RE_InitState(re, NULL, &sce->r, ri->pr_rectx, ri->pr_recty, NULL);
-               
-               /* enforce preview image clear */
-               if(GS(id->name)==ID_MA) {
-                       Material *ma= (Material *)id;
-                       ntreeClearPreview(ma->nodetree);
-               }
-       }
-       /* entire cycle for render engine */
-       RE_SetCamera(re, sce->camera);
-       RE_Database_FromScene(re, sce, 1);
-       RE_TileProcessor(re, ri->curtile, 0);   // actual render engine
-       RE_Database_Free(re);
-       
-       /* handle results */
-       if(pr_method==PR_ICON_RENDER) {
-               if(ri->rect==NULL)
-                       ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "BIF_previewrender");
-               RE_ResultGet32(re, ri->rect);
-       }
-       else {
-               rstats= RE_GetStats(re);
-               
-               if(rstats->partsdone!=ri->curtile) {
-                       if(ri->rect==NULL)
-                               ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "BIF_previewrender");
-                       RE_ResultGet32(re, ri->rect);
-               }
-               
-               if(rstats->totpart==rstats->partsdone && rstats->partsdone) {
-                       // allqueues
-               }
-               else {
-//                     if(pr_method==PR_DRAW_RENDER && qtest())
-//                             addafterqueue(area->win, RENDERPREVIEW, 1);
-               }
-               
-               ri->curtile= rstats->partsdone;
-               ri->tottile= rstats->totpart;
-       }
-
-       /* unassign the pointers, reset vars */
-//     preview_prepare_scene(scene, ri, GS(id->name), NULL, 0);
-       
-}
-
-
-/* afterqueue call */
-void BIF_previewrender_buts(Scene *scene, SpaceButs *sbuts)
-{
-//     ScrArea *sa= NULL; // XXX
-       ARegion *ar= NULL; // XXX
-       uiBlock *block;
-       struct ID* id = 0;
-//     struct ID* idfrom = 0;
-       struct ID* idshow = 0;
-       Object *ob;
-       
-       if (!sbuts->ri) return;
-       
-       
-//     block= uiFindOpenPanelBlockName(&sa->uiblocks, "Preview");
-       if(block==NULL) return;
-       
-       ob= ((scene->basact)? (scene->basact)->object: 0);
-       
-       /* we cant trust this global lockpoin.. for example with headerless window */
-//     buttons_active_id(&id, &idfrom);
-       sbuts->lockpoin= id;
-       
-       if(sbuts->mainb==CONTEXT_SHADING) {
-               int tab= TAB_SHADING_MAT; // XXX sbuts->tab[CONTEXT_SHADING];
-               
-               if(tab==TAB_SHADING_MAT) 
-                       idshow = sbuts->lockpoin;
-               else if(tab==TAB_SHADING_TEX) 
-                       idshow = sbuts->lockpoin;
-               else if(tab==TAB_SHADING_LAMP) {
-                       if(ob && ob->type==OB_LAMP) idshow= ob->data;
-               }
-               else if(tab==TAB_SHADING_WORLD)
-                       idshow = sbuts->lockpoin;
-       }
-       else if(sbuts->mainb==CONTEXT_OBJECT) {
-               if(ob && ob->type==OB_LAMP) idshow = ob->data;
-       }
-       
-       if (idshow) {
-               BKE_icon_changed(BKE_icon_getid(idshow));
-//             uiPanelPush(block);
-//             BIF_previewrender(scene, idshow, sbuts->ri, sbuts->area, PR_DRAW_RENDER);
-//             uiPanelPop(block);
-               end_previewrect(ar);
-       }
-       else {
-               /* no active block to draw. But we do draw black if possible */
-               if(sbuts->ri->rect) {
-                       memset(sbuts->ri->rect, 0, sizeof(int)*sbuts->ri->pr_rectx*sbuts->ri->pr_recty);
-                       sbuts->ri->tottile= 10000;
-//                     addqueue(sa->win, REDRAW, 1);
-               }
-               return;
-       }
-}
 
 /* new UI convention: draw is in pixel space already. */
 /* uses ROUNDBOX button in block to get the rect */
@@ -1006,7 +782,7 @@ static void shader_preview_updatejob(void *spv)
        
 }
 
-/* runs inside thread */
+/* runs inside thread for material, in foreground for icons */
 static void shader_preview_startjob(void *customdata, short *stop, short *do_update)
 {
        ShaderPreview *sp= customdata;
@@ -1064,9 +840,8 @@ static void shader_preview_startjob(void *customdata, short *stop, short *do_upd
 
        /* handle results */
        if(sp->pr_method==PR_ICON_RENDER) {
-               //if(ri->rect==NULL)
-               //      ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "BIF_previewrender");
-               //RE_ResultGet32(re, ri->rect);
+               if(sp->pr_rect)
+                       RE_ResultGet32(re, sp->pr_rect);
        }
        else {
                /* validate owner */
@@ -1113,6 +888,29 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, int sizex, in
        WM_jobs_callbacks(steve, shader_preview_startjob, NULL, shader_preview_updatejob);
        
        WM_jobs_start(CTX_wm_manager(C), steve);
+       
+       /* signal to rerender icon in menus */
+       BKE_icon_changed(BKE_icon_getid(id));
 }
 
+/* rect should be allocated, sizex/sizy pixels, 32 bits */
+void ED_preview_iconrender(Scene *scene, ID *id, int *rect, int sizex, int sizey)
+{
+       ShaderPreview *sp= MEM_callocN(sizeof(ShaderPreview), "ShaderPreview");
+       short stop=0, do_update=0;
+       
+       /* customdata for preview thread */
+       sp->scene= scene;
+       sp->sizex= sizex;
+       sp->sizey= sizey;
+       sp->pr_method= PR_ICON_RENDER;
+       sp->pr_rect= rect;
+       sp->id = id;
+
+       shader_preview_startjob(sp, &stop, &do_update);
+       
+       MEM_freeN(sp);
+}
+
+
 
index d97b4acdb96540797e0a1beb6e74e3c790de92f0..01794d1bba805f0988470f4e43797aaff9179142 100644 (file)
@@ -552,7 +552,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
                if(ptr) {
                        Object *ob= ptr->data;
 
-                       if(ob && ob->type && (ob->type<OB_LAMP))
+                       if(ob && ob->type && (ob->type<OB_LAMP) && ob->totcol)
                                CTX_data_pointer_set(result, &ob->id, &RNA_MaterialSlot, ob->mat+ob->actcol-1);
                }
 
@@ -668,7 +668,6 @@ void buttons_context_draw(const bContext *C, uiLayout *layout)
        uiBlock *block;
        uiBut *but;
        PointerRNA *ptr;
-       PropertyRNA *nameprop;
        char namebuf[128], *name;
        int a, icon;
 
@@ -688,7 +687,7 @@ void buttons_context_draw(const bContext *C, uiLayout *layout)
 
                if(ptr->data) {
                        icon= RNA_struct_ui_icon(ptr->type);
-                       nameprop= RNA_struct_name_property(ptr->type);
+                       name= RNA_struct_name_get_alloc(ptr, namebuf, sizeof(namebuf));
 
 #if 0
                        if(sbuts->mainb != BCONTEXT_SCENE && ptr->type == &RNA_Scene) {
@@ -696,9 +695,7 @@ void buttons_context_draw(const bContext *C, uiLayout *layout)
                        }
                        else
 #endif
-                       if(nameprop) {
-                               name= RNA_property_string_get_alloc(ptr, nameprop, namebuf, sizeof(namebuf));
-
+                       if(name) {
                                uiItemL(row, name, icon);
 
                                if(name != namebuf)
index 196647a37503eb73319da3bd3c77ea0a34d3fbee..b213e4288be407dd67245f205f469412ab7e0f2c 100644 (file)
@@ -61,6 +61,12 @@ void buttons_context_draw(const struct bContext *C, struct uiLayout *layout);
 void buttons_context_register(struct ARegionType *art);
 
 /* buttons_ops.c */
+void OBJECT_OT_material_slot_add(struct wmOperatorType *ot);
+void OBJECT_OT_material_slot_remove(struct wmOperatorType *ot);
+void OBJECT_OT_material_slot_assign(struct wmOperatorType *ot);
+void OBJECT_OT_material_slot_select(struct wmOperatorType *ot);
+void OBJECT_OT_material_slot_deselect(struct wmOperatorType *ot);
+
 void MATERIAL_OT_new(struct wmOperatorType *ot);
 void TEXTURE_OT_new(struct wmOperatorType *ot);
 void WORLD_OT_new(struct wmOperatorType *ot);
index 63469a8294d887b5c7f964589e0685ab321d4e4d..6755a2be1b7fea4b419984917ec2972eec68380b 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_curve_types.h"
 #include "DNA_object_types.h"
 #include "DNA_material_types.h"
 #include "DNA_texture_types.h"
 #include "DNA_world_types.h"
 
 #include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_font.h"
 #include "BKE_library.h"
 #include "BKE_material.h"
 #include "BKE_texture.h"
+#include "BKE_utildefines.h"
 #include "BKE_world.h"
 
+#include "BLI_editVert.h"
+
 #include "RNA_access.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
 
+#include "ED_curve.h"
+#include "ED_mesh.h"
+
 #include "buttons_intern.h"    // own include
 
+/********************** material slot operators *********************/
+
+static int material_slot_add_exec(bContext *C, wmOperator *op)
+{
+       Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+       if(!ob)
+               return OPERATOR_CANCELLED;
+
+       object_add_material_slot(ob);
+       WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+       
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_material_slot_add(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Add Material Slot";
+       ot->idname= "OBJECT_OT_material_slot_add";
+       
+       /* api callbacks */
+       ot->exec= material_slot_add_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int material_slot_remove_exec(bContext *C, wmOperator *op)
+{
+       Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+       if(!ob)
+               return OPERATOR_CANCELLED;
+
+       object_remove_material_slot(ob);
+       WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+       
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_material_slot_remove(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Remove Material Slot";
+       ot->idname= "OBJECT_OT_material_slot_remove";
+       
+       /* api callbacks */
+       ot->exec= material_slot_remove_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int material_slot_assign_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+       if(!ob)
+               return OPERATOR_CANCELLED;
+
+       if(ob && ob->actcol>0) {
+               if(ob->type == OB_MESH) {
+                       EditMesh *em= ((Mesh*)ob->data)->edit_mesh;
+                       EditFace *efa;
+
+                       if(em) {
+                               for(efa= em->faces.first; efa; efa=efa->next)
+                                       if(efa->f & SELECT)
+                                               efa->mat_nr= ob->actcol-1;
+                       }
+               }
+               else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
+                       ListBase *editnurb= ((Curve*)ob->data)->editnurb;
+                       Nurb *nu;
+
+                       if(editnurb) {
+                               for(nu= editnurb->first; nu; nu= nu->next)
+                                       if(isNurbsel(nu))
+                                               nu->mat_nr= nu->charidx= ob->actcol-1;
+                       }
+               }
+               else if(ob->type == OB_FONT) {
+                       EditFont *ef= ((Curve*)ob->data)->editfont;
+               int i, selstart, selend;
+
+                       if(ef && BKE_font_getselection(ob, &selstart, &selend)) {
+                               for(i=selstart; i<=selend; i++)
+                                       ef->textbufinfo[i].mat_nr = ob->actcol-1;
+                       }
+               }
+       }
+
+    DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+    WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+       
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Assign Material Slot";
+       ot->idname= "OBJECT_OT_material_slot_assign";
+       
+       /* api callbacks */
+       ot->exec= material_slot_assign_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int material_slot_de_select(bContext *C, int select)
+{
+       Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+       if(!ob)
+               return OPERATOR_CANCELLED;
+
+       if(ob->type == OB_MESH) {
+               EditMesh *em= ((Mesh*)ob->data)->edit_mesh;
+
+               if(em) {
+                       if(select)
+                               EM_select_by_material(em, ob->actcol-1);
+                       else
+                               EM_deselect_by_material(em, ob->actcol-1);
+               }
+       }
+       else if ELEM(ob->type, OB_CURVE, OB_SURF) {
+               ListBase *editnurb= ((Curve*)ob->data)->editnurb;
+               Nurb *nu;
+               BPoint *bp;
+               BezTriple *bezt;
+               int a;
+
+               for(nu= editnurb->first; nu; nu=nu->next) {
+                       if(nu->mat_nr==ob->actcol-1) {
+                               if(nu->bezt) {
+                                       a= nu->pntsu;
+                                       bezt= nu->bezt;
+                                       while(a--) {
+                                               if(bezt->hide==0) {
+                                                       if(select) {
+                                                               bezt->f1 |= SELECT;
+                                                               bezt->f2 |= SELECT;
+                                                               bezt->f3 |= SELECT;
+                                                       }
+                                                       else {
+                                                               bezt->f1 &= ~SELECT;
+                                                               bezt->f2 &= ~SELECT;
+                                                               bezt->f3 &= ~SELECT;
+                                                       }
+                                               }
+                                               bezt++;
+                                       }
+                               }
+                               else if(nu->bp) {
+                                       a= nu->pntsu*nu->pntsv;
+                                       bp= nu->bp;
+                                       while(a--) {
+                                               if(bp->hide==0) {
+                                                       if(select) bp->f1 |= SELECT;
+                                                       else bp->f1 &= ~SELECT;
+                                               }
+                                               bp++;
+                                       }
+                               }
+                       }
+               }
+       }
+
+    WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob);
+
+       return OPERATOR_FINISHED;
+}
+
+static int material_slot_select_exec(bContext *C, wmOperator *op)
+{
+       return material_slot_de_select(C, 1);
+}
+
+void OBJECT_OT_material_slot_select(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Select Material Slot";
+       ot->idname= "OBJECT_OT_material_slot_select";
+       
+       /* api callbacks */
+       ot->exec= material_slot_select_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int material_slot_deselect_exec(bContext *C, wmOperator *op)
+{
+       return material_slot_de_select(C, 0);
+}
+
+void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Deselect Material Slot";
+       ot->idname= "OBJECT_OT_material_slot_deselect";
+       
+       /* api callbacks */
+       ot->exec= material_slot_deselect_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
 /********************** new material operator *********************/
 
 static int new_material_exec(bContext *C, wmOperator *op)
 {
-       PointerRNA ptr;
-       Material *ma;
+       Material *ma= CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
        Object *ob;
+       PointerRNA ptr;
        int index;
 
        /* add or copy material */
-       ptr= CTX_data_pointer_get(C, "material");
-       ma= (RNA_struct_is_a(ptr.type, &RNA_Material))? ptr.data: NULL;
-
        if(ma)
                ma= copy_material(ma);
        else
@@ -70,9 +290,9 @@ static int new_material_exec(bContext *C, wmOperator *op)
        ma->id.us--; /* compensating for us++ in assign_material */
 
        /* attempt to assign to material slot */
-       ptr= CTX_data_pointer_get(C, "material_slot");
+       ptr= CTX_data_pointer_get_type(C, "material_slot", &RNA_MaterialSlot);
 
-       if(RNA_struct_is_a(ptr.type, &RNA_MaterialSlot)) {
+       if(ptr.data) {
                ob= ptr.id.data;
                index= (Material**)ptr.data - ob->mat;
 
@@ -80,6 +300,8 @@ static int new_material_exec(bContext *C, wmOperator *op)
 
                WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
        }
+
+       WM_event_add_notifier(C, NC_MATERIAL|NA_ADDED, ma);
        
        return OPERATOR_FINISHED;
 }
@@ -101,15 +323,12 @@ void MATERIAL_OT_new(wmOperatorType *ot)
 
 static int new_texture_exec(bContext *C, wmOperator *op)
 {
-       PointerRNA ptr;
+       Tex *tex= CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
        ID *id;
-       Tex *tex;
        MTex *mtex;
+       PointerRNA ptr;
 
        /* add or copy texture */
-       ptr= CTX_data_pointer_get(C, "texture");
-       tex= (RNA_struct_is_a(ptr.type, &RNA_Texture))? ptr.data: NULL;
-
        if(tex)
                tex= copy_texture(tex);
        else
@@ -118,9 +337,9 @@ static int new_texture_exec(bContext *C, wmOperator *op)
        id_us_min(&tex->id);
 
        /* attempt to assign to texture slot */
-       ptr= CTX_data_pointer_get(C, "texture_slot");
+       ptr= CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot);
 
-       if(RNA_struct_is_a(ptr.type, &RNA_TextureSlot)) {
+       if(ptr.data) {
                id= ptr.id.data;
                mtex= ptr.data;
 
@@ -133,6 +352,8 @@ static int new_texture_exec(bContext *C, wmOperator *op)
 
                /* XXX nodes, notifier .. */
        }
+
+       WM_event_add_notifier(C, NC_TEXTURE|NA_ADDED, tex);
        
        return OPERATOR_FINISHED;
 }
@@ -154,27 +375,21 @@ void TEXTURE_OT_new(wmOperatorType *ot)
 
 static int new_world_exec(bContext *C, wmOperator *op)
 {
-       PointerRNA ptr;
-       Scene *scene;
-       World *wo;
+       Scene *scene= CTX_data_scene(C);
+       World *wo= CTX_data_pointer_get_type(C, "world", &RNA_World).data;
 
        /* add or copy world */
-       ptr= CTX_data_pointer_get(C, "world");
-       wo= (RNA_struct_is_a(ptr.type, &RNA_World))? ptr.data: NULL;
-
        if(wo)
                wo= copy_world(wo);
        else
                wo= add_world("World");
 
        /* assign to scene */
-       scene= CTX_data_scene(C);
-
        if(scene->world)
                id_us_min(&scene->world->id);
        scene->world= wo;
 
-       // XXX notifier
+       WM_event_add_notifier(C, NC_WORLD|NA_ADDED, wo);
        
        return OPERATOR_FINISHED;
 }
index e5d2215be299dfdffadcdb8c81fa7c4a721069f3..483a1dc61002c60f7fb1385865513847a4041b12 100644 (file)
@@ -210,6 +210,12 @@ static void buttons_main_area_draw(const bContext *C, ARegion *ar)
 
 void buttons_operatortypes(void)
 {
+       WM_operatortype_append(OBJECT_OT_material_slot_add);
+       WM_operatortype_append(OBJECT_OT_material_slot_remove);
+       WM_operatortype_append(OBJECT_OT_material_slot_assign);
+       WM_operatortype_append(OBJECT_OT_material_slot_select);
+       WM_operatortype_append(OBJECT_OT_material_slot_deselect);
+
        WM_operatortype_append(MATERIAL_OT_new);
        WM_operatortype_append(TEXTURE_OT_new);
        WM_operatortype_append(WORLD_OT_new);
@@ -337,6 +343,11 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
                                case ND_GEOM_SELECT:
                                        ED_area_tag_redraw(sa);
                                        break;
+                               case ND_SHADING:
+                               case ND_SHADING_DRAW:
+                                       /* currently works by redraws... if preview is set, it (re)starts job */
+                                       sbuts->preview= 1;
+                                       break;
                        }
                        break;
                case NC_MATERIAL:
@@ -347,7 +358,6 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
                                case ND_SHADING_DRAW:
                                        /* currently works by redraws... if preview is set, it (re)starts job */
                                        sbuts->preview= 1;
-                                       printf("shader notifier \n");
                                        break;
                        }                                       
                        break;
index 6ed8f87d987ef8855015b7454f1468ec868a7e69..bb47d3458feeba54178185b27ef8fefd76a39dde 100644 (file)
@@ -550,7 +550,24 @@ void file_draw_list(const bContext *C, ARegion *ar)
        }
 }
 
-static void file_draw_fsmenu_category(const bContext *C, ARegion *ar, FSMenuCategory category, const char* category_name, short *starty)
+static void file_draw_fsmenu_category_name(ARegion *ar, const char *category_name, short *starty)
+{
+       short sx, sy;
+       int bmwidth = ar->v2d.cur.xmax - ar->v2d.cur.xmin - 2*TILE_BORDER_X - ICON_DEFAULT_WIDTH - 4;
+       int fontsize = file_font_pointsize();
+
+       sx = ar->v2d.cur.xmin + TILE_BORDER_X;
+       sy = *starty;
+
+       UI_ThemeColor(TH_TEXT_HI);
+       file_draw_string(sx, sy, category_name, bmwidth, fontsize, FILE_SHORTEN_END);
+       
+       sy -= fontsize*2.0f;
+
+       *starty= sy;
+}
+
+static void file_draw_fsmenu_category(const bContext *C, ARegion *ar, FSMenuCategory category, short *starty)
 {
        struct FSMenu* fsmenu = fsmenu_get();
        char bookmark[FILE_MAX];
@@ -565,11 +582,6 @@ static void file_draw_fsmenu_category(const bContext *C, ARegion *ar, FSMenuCate
        sx = ar->v2d.cur.xmin + TILE_BORDER_X;
        sy = *starty;
 
-       UI_ThemeColor(TH_TEXT_HI);
-       file_draw_string(sx, sy, category_name, bmwidth, fontsize, FILE_SHORTEN_END);
-       
-       sy -= fontsize*2.0f;
-
        switch(category) {
                case FS_CATEGORY_SYSTEM:
                        cat_icon = ICON_DISK_DRIVE; break;
@@ -616,15 +628,54 @@ static void file_draw_fsmenu_category(const bContext *C, ARegion *ar, FSMenuCate
        *starty = sy;
 }
 
+void file_draw_fsmenu_operator(const bContext *C, ARegion *ar, wmOperator *op, short *starty)
+{
+       uiStyle *style= U.uistyles.first;
+       uiBlock *block;
+       uiLayout *layout;
+       int sy;
+
+       sy= *starty;
+       
+       block= uiBeginBlock(C, ar, "file_options", UI_EMBOSS);
+       layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, TILE_BORDER_X, sy, ar->winx-2*TILE_BORDER_X, 20, style);
+
+    RNA_STRUCT_BEGIN(op->ptr, prop) {
+        if(strcmp(RNA_property_identifier(prop), "rna_type") == 0)
+            continue;
+        if(strcmp(RNA_property_identifier(prop), "filename") == 0)
+            continue;
+
+        uiItemFullR(layout, NULL, 0, op->ptr, prop, -1, 0, 0, 0, 0);
+    }
+    RNA_STRUCT_END;
+
+       uiBlockLayoutResolve(C, block, NULL, &sy);
+       uiEndBlock(C, block);
+       uiDrawBlock(C, block);
+
+       *starty= sy;
+}
+
 void file_draw_fsmenu(const bContext *C, ARegion *ar)
 {
+       SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
        int linestep = file_font_pointsize()*2.0f;
        short sy= ar->v2d.cur.ymax-2*TILE_BORDER_Y;
 
-       file_draw_fsmenu_category(C, ar, FS_CATEGORY_SYSTEM, "SYSTEM", &sy);
+       file_draw_fsmenu_category_name(ar, "SYSTEM", &sy);
+       file_draw_fsmenu_category(C, ar, FS_CATEGORY_SYSTEM, &sy);
        sy -= linestep;
-       file_draw_fsmenu_category(C, ar, FS_CATEGORY_BOOKMARKS, "BOOKMARKS", &sy);
+       file_draw_fsmenu_category_name(ar, "BOOKMARKS", &sy);
+       file_draw_fsmenu_category(C, ar, FS_CATEGORY_BOOKMARKS, &sy);
        sy -= linestep;
-       file_draw_fsmenu_category(C, ar, FS_CATEGORY_RECENT, "RECENT", &sy);
-       
+       file_draw_fsmenu_category_name(ar, "RECENT", &sy);
+       file_draw_fsmenu_category(C, ar, FS_CATEGORY_RECENT, &sy);
+
+       if(sfile->op) {
+               sy -= linestep;
+               file_draw_fsmenu_category_name(ar, "OPTIONS", &sy);
+               file_draw_fsmenu_operator(C, ar, sfile->op, &sy);
+       }
 }
+
index 0c6cadc05c13671de2e72586ab7036dd2f459e05..ab02147d020fdf60481cff41fa339f1f49f1ff1f 100644 (file)
@@ -190,7 +190,7 @@ static int file_border_select_exec(bContext *C, wmOperator *op)
        rect.xmax= RNA_int_get(op->ptr, "xmax");
        rect.ymax= RNA_int_get(op->ptr, "ymax");
 
-       BLI_isect_rctf(&(ar->v2d.mask), &rect, &rect);
+       BLI_isect_rcti(&(ar->v2d.mask), &rect, &rect);
        
        file_select(sfile, ar, &rect, val );
        WM_event_add_notifier(C, NC_WINDOW, NULL);
index d57fc7f90bc4ef7c73bdd146f195a0dac3831c25..479d9cabc55b86e249703e0eb6903a9928c75b62 100644 (file)
@@ -159,7 +159,7 @@ float file_string_width(const char* str)
 {
        uiStyle *style= U.uistyles.first;
        uiStyleFontSet(&style->widget);
-       return BLF_width(str);
+       return BLF_width((char *)str);
 }
 
 float file_font_pointsize()
index 8aa955f0b349b438e07b6f8f11ad5cea97d8de02..a08a23c1263ad8eb7c9f808920c4b3b8b4f6b728 100644 (file)
@@ -383,6 +383,7 @@ static void image_editcursor_buts(const bContext *C, View2D *v2d, uiBlock *block
        }
 }
 
+#if 0
 static void image_panel_view_properties(const bContext *C, Panel *pa)
 {
        SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
@@ -439,6 +440,7 @@ static void image_panel_view_properties(const bContext *C, Panel *pa)
        }
        image_editcursor_buts(C, &ar->v2d, block);
 }
+#endif
 
 void brush_buttons(const bContext *C, uiBlock *block, short fromsima,
                                   int evt_nop, int evt_change,
index 537996601b8c60f1ee39e08f45dcb74b6b744171..8f9bb0d05fe8c3d5c5ea61097645f8a6d9d6387a 100644 (file)
@@ -577,34 +577,30 @@ void IMAGE_OT_view_zoom_ratio(wmOperatorType *ot)
 
 /**************** load/replace/save callbacks ******************/
 
-static char *filesel_imagetype_string(Image *ima)
-{
-       char *strp, *str= MEM_callocN(15*32, "menu for filesel");
-       
-       strp= str;
-       str += sprintf(str, "Save Image as: %%t|");
-       str += sprintf(str, "Targa %%x%d|", R_TARGA);
-       str += sprintf(str, "Targa Raw %%x%d|", R_RAWTGA);
-       str += sprintf(str, "PNG %%x%d|", R_PNG);
-       str += sprintf(str, "BMP %%x%d|", R_BMP);
-       str += sprintf(str, "Jpeg %%x%d|", R_JPEG90);
+/* XXX make dynamic */
+static const EnumPropertyItem image_file_type_items[] = {
+               {R_TARGA, "TARGA", 0, "Targa", ""},
+               {R_RAWTGA, "TARGA RAW", 0, "Targa Raw", ""},
+               {R_PNG, "PNG", 0, "PNG", ""},
+               {R_BMP, "BMP", 0, "BMP", ""},
+               {R_JPEG90, "JPEG", 0, "Jpeg", ""},
 #ifdef WITH_OPENJPEG
-       str += sprintf(str, "Jpeg 2000 %%x%d|", R_JP2);
+               {R_JP2, "JPEG_2000", 0, "Jpeg 2000", ""},
 #endif
-       str += sprintf(str, "Iris %%x%d|", R_IRIS);
-       if(G.have_libtiff)
-               str += sprintf(str, "Tiff %%x%d|", R_TIFF);
-       str += sprintf(str, "Radiance HDR %%x%d|", R_RADHDR);
-       str += sprintf(str, "Cineon %%x%d|", R_CINEON);
-       str += sprintf(str, "DPX %%x%d|", R_DPX);
+               {R_IRIS, "IRIS", 0, "Iris", ""},
+       //if(G.have_libtiff)
+               {R_TIFF, "TIFF", 0, "Tiff", ""},
+               {R_RADHDR, "RADIANCE_HDR", 0, "Radiance HDR", ""},
+               {R_CINEON, "CINEON", 0, "Cineon", ""},
+               {R_DPX, "DPX", 0, "DPX", ""},
 #ifdef WITH_OPENEXR
-       str += sprintf(str, "OpenEXR %%x%d|", R_OPENEXR);
+               {R_OPENEXR, "OPENEXR", 0, "OpenEXR", ""},
        /* saving sequences of multilayer won't work, they copy buffers  */
-       if(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER);
-       else str += sprintf(str, "MultiLayer %%x%d|", R_MULTILAYER);
+       /*if(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER);
+       else*/
+               {R_MULTILAYER, "MULTILAYER", 0, "MultiLayer", ""},
 #endif 
-       return strp;
-}
+               {0, NULL, 0, NULL, NULL}};
 
 static void image_filesel(bContext *C, wmOperator *op, const char *path)
 {
@@ -799,7 +795,9 @@ static int save_as_exec(bContext *C, wmOperator *op)
        if(!ima)
                return OPERATOR_CANCELLED;
 
+       sima->imtypenr= RNA_enum_get(op->ptr, "file_type");
        RNA_string_get(op->ptr, "filename", str);
+
        save_image_doit(C, sima, scene, op, str);
 
        return OPERATOR_FINISHED;
@@ -820,10 +818,6 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event)
 
        /* always opens fileselect */
        if(ibuf) {
-               char *strp;
-               
-               strp= filesel_imagetype_string(ima); // XXX unused still
-               
                /* cant save multilayer sequence, ima->rr isn't valid for a specific frame */
                if(ima->rr && !(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER))
                        sima->imtypenr= R_MULTILAYER;
@@ -831,14 +825,14 @@ static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event)
                        sima->imtypenr= scene->r.imtype;
                else
                        sima->imtypenr= BKE_ftype_to_imtype(ibuf->ftype);
+
+               RNA_enum_set(op->ptr, "file_type", sima->imtypenr);
                
                if(ibuf->name[0]==0)
                        BLI_strncpy(ibuf->name, G.ima, FILE_MAX);
                
                // XXX note: we can give default menu enums to operator for this 
                image_filesel(C, op, ibuf->name);
-
-               MEM_freeN(strp);
                
                return OPERATOR_RUNNING_MODAL;
        }
@@ -862,6 +856,7 @@ void IMAGE_OT_save_as(wmOperatorType *ot)
 
        /* properties */
        RNA_def_string_file_path(ot->srna, "filename", "", FILE_MAX, "Filename", "File path to save image to.");
+       RNA_def_enum(ot->srna, "file_type", image_file_type_items, R_PNG, "File Type", "File type to save image as.");
 }
 
 /******************** save image operator ********************/
index c8dd3df8425b3d3d9c608b343f8c0930026c0aed..7b65a70117c5281d4eeca8e48cc5821188d73266 100644 (file)
@@ -415,7 +415,7 @@ static void operator_search_cb(const struct bContext *C, void *arg, char *str, u
                                                name[len]= '|';
                                }
                                
-                               if(0==uiSearchItemAdd(items, name, ot))
+                               if(0==uiSearchItemAdd(items, name, ot, 0))
                                        break;
                        }
                }
index 16748af39d5967ca043a4f9798226bff5bc19fff..8017b8437ff729af75520624cc143da9790105cc 100644 (file)
@@ -1031,7 +1031,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
        }
        else if(ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
                PointerRNA pptr, propptr, *ptr= (PointerRNA*)idv;
-               PropertyRNA *prop, *iterprop, *nameprop;
+               PropertyRNA *prop, *iterprop;
                PropertyType proptype;
                PropertySubType propsubtype;
                int a, tot;
@@ -1043,12 +1043,10 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                }
                else if(type == TSE_RNA_STRUCT) {
                        /* struct */
-                       nameprop= RNA_struct_name_property(ptr->type);
+                       te->name= RNA_struct_name_get_alloc(ptr, NULL, 0);
 
-                       if(nameprop) {
-                               te->name= RNA_property_string_get_alloc(ptr, nameprop, NULL, 0);
+                       if(te->name)
                                te->flag |= TE_FREE_NAME;
-                       }
                        else
                                te->name= (char*)RNA_struct_ui_name(ptr->type);
 
@@ -3075,7 +3073,7 @@ static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreEle
        TreeElement *tem, *temnext, *temsub;
        TreeStoreElem *tse, *tsenext;
        PointerRNA *ptr, *nextptr;
-       PropertyRNA *prop, *nameprop;
+       PropertyRNA *prop;
        char *newpath=NULL;
        
        /* optimise tricks:
@@ -3119,17 +3117,16 @@ static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreEle
                                        newpath= RNA_path_append(*path, ptr, prop, 0, NULL);
                                }
                                else if(RNA_property_type(prop) == PROP_COLLECTION) {
+                                       char buf[128], *name;
+
                                        temnext= (TreeElement*)(ld->next->data);
                                        tsenext= TREESTORE(temnext);
                                        
                                        nextptr= &temnext->rnaptr;
-                                       nameprop= RNA_struct_name_property(nextptr->type);
+                                       name= RNA_struct_name_get_alloc(nextptr, buf, sizeof(buf));
                                        
-                                       if(nameprop) {
+                                       if(name) {
                                                /* if possible, use name as a key in the path */
-                                               char buf[128], *name;
-                                               name= RNA_property_string_get_alloc(nextptr, nameprop, buf, sizeof(buf));
-                                               
                                                newpath= RNA_path_append(*path, NULL, prop, 0, name);
                                                
                                                if(name != buf)
index ea9fb66dae0d33b3f88578d0015fb95ce99f1672..05490e2fce192c1ffb539b121bc6a83df03691ee 100644 (file)
@@ -3566,7 +3566,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 
 static void draw_particle_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, ParticleSystem *psys, int dt)
 {
-       ToolSettings *ts= scene->toolsettings;
        ParticleEdit *edit = psys->edit;
        ParticleData *pa;
        ParticleCacheKey **path;
index ca911876c891a8854efb26ea3996516fc0d5bb18..915652355918201d7ec12d179d3e2889e16cb4dd 100644 (file)
@@ -1710,7 +1710,7 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
        }
        
        RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
-       uiDefAutoButsRNA(C, pa->layout, &ptr);
+       uiDefAutoButsRNA(C, pa->layout, &ptr, 2);
 }
 
 void view3d_buttons_register(ARegionType *art)
index 13ebeb05a5b82f2b6212f517089b4d0188476316..79ea90864f32b2bc008fa5138590119391efdb26 100644 (file)
@@ -5513,11 +5513,11 @@ void view3d_header_buttons(const bContext *C, ARegion *ar)
                }
                else if(G.f & G_PARTICLEEDIT) {
                        uiBlockBeginAlign(block);
-                       uiDefIconButBitS(block, TOG, SCE_SELECT_PATH, B_SEL_PATH, ICON_EDGESEL, xco,yco,XIC,YIC, &ts->particle.selectmode, 1.0, 0.0, 0, 0, "Path edit mode");
+                       uiDefIconButBitI(block, TOG, SCE_SELECT_PATH, B_SEL_PATH, ICON_EDGESEL, xco,yco,XIC,YIC, &ts->particle.selectmode, 1.0, 0.0, 0, 0, "Path edit mode");
                        xco+= XIC;
-                       uiDefIconButBitS(block, TOG, SCE_SELECT_POINT, B_SEL_POINT, ICON_VERTEXSEL, xco,yco,XIC,YIC, &ts->particle.selectmode, 1.0, 0.0, 0, 0, "Point select mode");
+                       uiDefIconButBitI(block, TOG, SCE_SELECT_POINT, B_SEL_POINT, ICON_VERTEXSEL, xco,yco,XIC,YIC, &ts->particle.selectmode, 1.0, 0.0, 0, 0, "Point select mode");
                        xco+= XIC;
-                       uiDefIconButBitS(block, TOG, SCE_SELECT_END, B_SEL_END, ICON_FACESEL, xco,yco,XIC,YIC, &ts->particle.selectmode, 1.0, 0.0, 0, 0, "Tip select mode");
+                       uiDefIconButBitI(block, TOG, SCE_SELECT_END, B_SEL_END, ICON_FACESEL, xco,yco,XIC,YIC, &ts->particle.selectmode, 1.0, 0.0, 0, 0, "Tip select mode");
                        xco+= XIC;
                        uiBlockEndAlign(block);
                        
index 1e55f2e4a9adace6b2047cd650a8a7010617460f..15254ba505edfe958c6a76c47dba6a1c7bdd1018 100644 (file)
@@ -120,8 +120,6 @@ static void redo_cb(bContext *C, void *arg_op, void *arg2)
 
 static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
 {
-       /* XXX temp */
-       extern void uiDefAutoButsRNA_single(const bContext *C, uiLayout *layout, PointerRNA *ptr);
        wmWindowManager *wm= CTX_wm_manager(C);
        wmOperator *op;
        PointerRNA ptr;
@@ -147,7 +145,7 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
        }
        
        RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
-       uiDefAutoButsRNA_single(C, pa->layout, &ptr);
+       uiDefAutoButsRNA(C, pa->layout, &ptr, 1);
 }
 
 void view3d_toolbar_register(ARegionType *art)
index b10f35b909169439bd6fcaa5b0cdf3468db72eb3..05f1cc1f3516a5ecf7ac652aad9fb62309a094b5 100644 (file)
@@ -34,6 +34,8 @@
 
 #include "DNA_ID.h"
 
+struct AnimData;
+
 typedef struct HairKey {
        float co[3];    /* location of hair vertex */
        float time;             /* time along hair, default 0-100 */
@@ -100,6 +102,7 @@ typedef struct ParticleData {
 
 typedef struct ParticleSettings {
        ID id;
+       struct AnimData *adt;
 
        int flag;
        short type, from, distr;
@@ -167,7 +170,7 @@ typedef struct ParticleSettings {
        struct Group *eff_group;
        struct Object *dup_ob;
        struct Object *bb_ob;
-       struct Ipo *ipo;
+       struct Ipo *ipo;                                // xxx depreceated... old animation system
        struct PartDeflect *pd;
        struct PartDeflect *pd2;
 } ParticleSettings;
index 6be855a27dad1672d8ef5dc8c34324331fdd2d16..771a7e4379338046d5dbb8bed46764727bc240da 100644 (file)
@@ -67,7 +67,8 @@ typedef struct uiFontStyle {
        short uifont_id;                /* saved in file, 0 is default */
        short points;                   /* actual size depends on 'global' dpi */
        float kerning;                  /* kerning space between characters. */
-       float pad;
+       short overlap;                  /* check overlaped characters. */
+       short pad;
        short italic, bold;             /* style hint */
        short shadow;                   /* value is amount of pixels blur */
        short shadx, shady;             /* shadow offset in pixels */
@@ -123,10 +124,11 @@ typedef struct uiWidgetColors {
 typedef struct ThemeUI {
        
        /* Interface Elements (buttons, menus, icons) */
-       uiWidgetColors wcol_regular, wcol_tool, wcol_radio, wcol_text, wcol_option;
+       uiWidgetColors wcol_regular, wcol_tool, wcol_text;
+       uiWidgetColors wcol_radio, wcol_option, wcol_toggle;
        uiWidgetColors wcol_num, wcol_numslider;
        uiWidgetColors wcol_menu, wcol_pulldown, wcol_menu_back, wcol_menu_item;
-       uiWidgetColors wcol_box;
+       uiWidgetColors wcol_box, wcol_scroll;
        
        char iconfile[80];      // FILE_MAXFILE length
        
index 4a074ab1546ff5dad7e4d5004eb9fb9cb04d0ac3..9f7559312eda2884d82ef96441b6826005b62b48 100644 (file)
@@ -514,6 +514,8 @@ const struct ListBase *RNA_struct_defined_properties(StructRNA *srna);
 FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier);
 const struct ListBase *RNA_struct_defined_functions(StructRNA *srna);
 
+char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen);
+
 /* Properties
  *
  * Access to struct properties. All this works with RNA pointers rather than
@@ -693,6 +695,28 @@ void RNA_collection_clear(PointerRNA *ptr, const char *name);
                RNA_property_collection_end(&rna_macro_iter); \
        }
 
+#define RNA_PROP_BEGIN(sptr, itemptr, prop) \
+       { \
+               CollectionPropertyIterator rna_macro_iter; \
+               for(RNA_property_collection_begin(sptr, prop, &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) { \
+                       PointerRNA itemptr= rna_macro_iter.ptr;
+
+#define RNA_PROP_END \
+               } \
+               RNA_property_collection_end(&rna_macro_iter); \
+       }
+
+#define RNA_STRUCT_BEGIN(sptr, prop) \
+       { \
+               CollectionPropertyIterator rna_macro_iter; \
+               for(RNA_property_collection_begin(sptr, RNA_struct_iterator_property(sptr->type), &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) { \
+                       PropertyRNA *prop= rna_macro_iter.ptr.data;
+
+#define RNA_STRUCT_END \
+               } \
+               RNA_property_collection_end(&rna_macro_iter); \
+       }
+
 /* check if the idproperty exists, for operators */
 int RNA_property_is_set(PointerRNA *ptr, const char *name);
 
index b620a31508532134d936ef4dc8843fd7d43820a2..85a148be2e2d12f9fda47b29258771aea1a0d596 100644 (file)
@@ -80,7 +80,7 @@ PropertyRNA *RNA_def_string(StructOrFunctionRNA *cont, const char *identifier, c
 PropertyRNA *RNA_def_string_file_path(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description);
 PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description);
 
-PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont, const char *identifier, EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description);
+PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description);
 
 PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
 PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax);
index 60774c8432c1f0384b420bcdd7023c090ebbf75f..66127ebc6df3c225640c490aa3decb4f4835116b 100644 (file)
@@ -426,23 +426,16 @@ PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
 /* Find the property which uses the given nested struct */
 PropertyRNA *RNA_struct_find_nested(PointerRNA *ptr, StructRNA *srna)
 {
-       CollectionPropertyIterator iter;
-       PropertyRNA *iterprop, *prop;
-       int i = 0;
+       PropertyRNA *prop= NULL;
 
-       iterprop= RNA_struct_iterator_property(ptr->type);
-       RNA_property_collection_begin(ptr, iterprop, &iter);
-       prop= NULL;
-
-       for(; iter.valid; RNA_property_collection_next(&iter), i++) {
+       RNA_STRUCT_BEGIN(ptr, iprop) {
                /* This assumes that there can only be one user of this nested struct */
-               if (RNA_property_pointer_type(ptr, iter.ptr.data) == srna) {
-                       prop= iter.ptr.data;
+               if (RNA_property_pointer_type(ptr, iprop) == srna) {
+                       prop= iprop;
                        break;
                }
        }
-
-       RNA_property_collection_end(&iter);
+       RNA_PROP_END;
 
        return prop;
 }
@@ -455,25 +448,21 @@ const struct ListBase *RNA_struct_defined_properties(StructRNA *srna)
 FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier)
 {
        PointerRNA tptr;
-       CollectionPropertyIterator iter;
        PropertyRNA *iterprop;
        FunctionRNA *func;
-       int i = 0;
 
        RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr);
        iterprop= RNA_struct_find_property(&tptr, "functions");
 
-       RNA_property_collection_begin(&tptr, iterprop, &iter);
        func= NULL;
 
-       for(; iter.valid; RNA_property_collection_next(&iter), i++) {
-               if(strcmp(identifier, RNA_function_identifier(iter.ptr.data)) == 0) {
-                       func= iter.ptr.data;
+       RNA_PROP_BEGIN(&tptr, funcptr, iterprop) {
+               if(strcmp(identifier, RNA_function_identifier(funcptr.data)) == 0) {
+                       func= funcptr.data;
                        break;
                }
        }
-
-       RNA_property_collection_end(&iter);
+       RNA_PROP_END;
 
        return func;
 }
@@ -518,6 +507,16 @@ void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
        srna->blender_type= blender_type;
 }
 
+char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen)
+{
+       PropertyRNA *nameprop;
+
+       if(ptr->data && (nameprop = RNA_struct_name_property(ptr->type)))
+               return RNA_property_string_get_alloc(ptr, nameprop, fixedbuf, fixedlen);
+
+       return NULL;
+}
+
 /* Property Information */
 
 const char *RNA_property_identifier(PropertyRNA *prop)
@@ -658,7 +657,6 @@ void RNA_property_enum_items(PointerRNA *ptr, PropertyRNA *prop, const EnumPrope
 int RNA_property_enum_value(PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value)
 {      
        const EnumPropertyItem *item;
-       int i;
        
        RNA_property_enum_items(ptr, prop, &item, NULL);
        
@@ -2247,17 +2245,12 @@ char *RNA_pointer_as_string(PointerRNA *ptr)
        DynStr *dynstr= BLI_dynstr_new();
        char *cstring;
        
-       PropertyRNA *prop, *iterprop;
-       CollectionPropertyIterator iter;
        const char *propname;
        int first_time = 1;
        
        BLI_dynstr_append(dynstr, "{");
        
-       iterprop= RNA_struct_iterator_property(ptr->type);
-
-       for(RNA_property_collection_begin(ptr, iterprop, &iter); iter.valid; RNA_property_collection_next(&iter)) {
-               prop= iter.ptr.data;
+       RNA_STRUCT_BEGIN(ptr, prop) {
                propname = RNA_property_identifier(prop);
                
                if(strcmp(propname, "rna_type")==0)
@@ -2271,8 +2264,8 @@ char *RNA_pointer_as_string(PointerRNA *ptr)
                BLI_dynstr_appendf(dynstr, "\"%s\":%s", propname, cstring);
                MEM_freeN(cstring);
        }
+       RNA_STRUCT_END;
 
-       RNA_property_collection_end(&iter);
        BLI_dynstr_append(dynstr, "}"); 
        
        
index 51c1818eed98c0e43c53f79de1b8aed3ee9b5602..bd449acc050bfb2c1e99670cee483485c573205c 100644 (file)
@@ -1946,7 +1946,7 @@ PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont_, const char *ide
        return prop;
 }
 
-PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, EnumPropertyItem *items, int default_value, 
+PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, 
        const char *ui_name, const char *ui_description)
 {
        ContainerRNA *cont= cont_;
index 7538f103245eca4d50a7b6d914f1a4f806af4f17..09b46a32cb9f3ebbe8de9fdea0ca31115fc9437e 100644 (file)
@@ -192,6 +192,7 @@ void RNA_api_mesh(struct StructRNA *srna);
 void RNA_api_object(struct StructRNA *srna);
 void RNA_api_ui_layout(struct StructRNA *srna);
 void RNA_api_wm(struct StructRNA *srna);
+void RNA_api_scene(struct StructRNA *srna); 
 
 /* ID Properties */
 
index 14ce5954cb7c946d19fa82407525193423fbbde1..76553e09fb2b97677e3962891ed89707224d2c8b 100644 (file)
@@ -417,11 +417,13 @@ static void rna_def_material_slot(BlenderRNA *brna)
        RNA_def_property_flag(prop, PROP_EDITABLE);
        RNA_def_property_pointer_funcs(prop, "rna_MaterialSlot_material_get", "rna_MaterialSlot_material_set", NULL);
        RNA_def_property_ui_text(prop, "Material", "Material datablock used by this material slot.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_SHADING, "rna_Object_update");
 
        prop= RNA_def_property(srna, "link", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_items(prop, link_items);
        RNA_def_property_enum_funcs(prop, "rna_MaterialSlot_link_get", "rna_MaterialSlot_link_set", NULL);
        RNA_def_property_ui_text(prop, "Link", "Link material to object or the object's data.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_SHADING, "rna_Object_update");
 
        prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
        RNA_def_property_string_funcs(prop, "rna_MaterialSlot_name_get", "rna_MaterialSlot_name_length", NULL);
index c48c1006588618945c611fee18bdb1798ce82aec..ae53c815ed9c84a6758f4439528953ff7c4dc618 100644 (file)
@@ -1470,14 +1470,9 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_flag(prop, PROP_EDITABLE);
        RNA_def_property_ui_text(prop, "Billboard Object", "Billboards face this object (default is active camera)");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo");
-
-#if 0
-       prop= RNA_def_property(srna, "ipo", PROP_POINTER, PROP_NONE);
-       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-       RNA_def_property_pointer_sdna(prop, NULL, "ipo");
-       RNA_def_property_struct_type(prop, "Ipo");
-       RNA_def_property_ui_text(prop, "Ipo", "");
-#endif
+       
+       /* animation here? */
+       rna_def_animdata_common(srna);
 
 //     struct PartDeflect *pd;
 //     struct PartDeflect *pd2;
index d8648e051533d07e338b9f519965c948ce8d66b1..75de9d5376649d1ac36ce7d8b8b9c010dd0244c6 100644 (file)
@@ -249,6 +249,12 @@ void RNA_api_ui_layout(StructRNA *srna)
        RNA_def_property_flag(parm, PROP_REQUIRED);
        parm= RNA_def_pointer(func, "image_user", "ImageUser", "", "");
        RNA_def_property_flag(parm, PROP_REQUIRED);
+
+       func= RNA_def_function(srna, "template_list", "uiTemplateList");
+       api_ui_item_rna_common(func);
+       parm= RNA_def_string(func, "active_property", "", 0, "", "Identifier of property in data, indicating the active element.");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+       parm= RNA_def_int(func, "items", 5, 0, INT_MAX, "", "Number of items to display.", 0, INT_MAX);
 }
 
 #endif
index f3811938e28b54f3de9dffe2c1363a2427fb19de..609082144e1c2497e7913602825ce6c8c2853b65 100644 (file)
@@ -139,7 +139,12 @@ static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna)
 
        prop= RNA_def_property(srna, "kerning", PROP_FLOAT, PROP_NONE);
        RNA_def_property_range(prop, -5.0, 5.0);
-       RNA_def_property_ui_text(prop, "Kerning", "");
+       RNA_def_property_ui_text(prop, "Kerning", "User kerning value in pixels");
+       RNA_def_property_update(prop, NC_WINDOW, NULL);
+
+       prop= RNA_def_property(srna, "overlap", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "overlap", 1);
+       RNA_def_property_ui_text(prop, "Overlap", "Check for overlap characters");
        RNA_def_property_update(prop, NC_WINDOW, NULL);
 
        prop= RNA_def_property(srna, "shadow", PROP_INT, PROP_NONE);
@@ -301,6 +306,12 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
        RNA_def_property_struct_type(prop, "ThemeWidgetColors");
        RNA_def_property_ui_text(prop, "Option Widget Colors", "");
        RNA_def_property_update(prop, NC_WINDOW, NULL);
+
+       prop= RNA_def_property(srna, "wcol_toggle", PROP_POINTER, PROP_NEVER_NULL);
+       RNA_def_property_pointer_sdna(prop, NULL, "wcol_toggle");
+       RNA_def_property_struct_type(prop, "ThemeWidgetColors");
+       RNA_def_property_ui_text(prop, "Toggle Widget Colors", "");
+       RNA_def_property_update(prop, NC_WINDOW, NULL);
        
        prop= RNA_def_property(srna, "wcol_num", PROP_POINTER, PROP_NEVER_NULL);
        RNA_def_property_pointer_sdna(prop, NULL, "wcol_num");
@@ -343,7 +354,12 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
        RNA_def_property_struct_type(prop, "ThemeWidgetColors");
        RNA_def_property_ui_text(prop, "Menu Item Colors", "");
        RNA_def_property_update(prop, NC_WINDOW, NULL);
-       
+
+       prop= RNA_def_property(srna, "wcol_scroll", PROP_POINTER, PROP_NEVER_NULL);
+       RNA_def_property_pointer_sdna(prop, NULL, "wcol_scroll");
+       RNA_def_property_struct_type(prop, "ThemeWidgetColors");
+       RNA_def_property_ui_text(prop, "Scroll Widget Colors", "");
+       RNA_def_property_update(prop, NC_WINDOW, NULL);
        
        prop= RNA_def_property(srna, "icon_file", PROP_STRING, PROP_FILEPATH);
        RNA_def_property_string_sdna(prop, NULL, "iconfile");
index ec76675f6522e1e93b6bfaa8a72639faba0e36f6..8a748241570f62bbdf6f760622d6998a88a8c73b 100644 (file)
@@ -165,7 +165,7 @@ static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * polyLineSeq )
                                polyVec= PySequence_GetItem( polyLine, index );
                                if(VectorObject_Check(polyVec)) {
                                        
-                                       if(!Vector_ReadCallback((VectorObject *)polyVec))
+                                       if(!BaseMath_ReadCallback((VectorObject *)polyVec))
                                                ls_error= 1;
                                        
                                        fp[0] = ((VectorObject *)polyVec)->vec[0];
@@ -238,7 +238,7 @@ static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args )
                return NULL;
        }
        
-       if(!Vector_ReadCallback(line_a1) || !Vector_ReadCallback(line_a2) || !Vector_ReadCallback(line_b1) || !Vector_ReadCallback(line_b2))
+       if(!BaseMath_ReadCallback(line_a1) || !BaseMath_ReadCallback(line_a2) || !BaseMath_ReadCallback(line_b1) || !BaseMath_ReadCallback(line_b2))
                return NULL;
        
        a1x= line_a1->vec[0];
@@ -338,7 +338,7 @@ static PyObject *M_Geometry_ClosestPointOnLine( PyObject * self, PyObject * args
                return NULL;
        }
        
-       if(!Vector_ReadCallback(pt) || !Vector_ReadCallback(line_1) || !Vector_ReadCallback(line_2))
+       if(!BaseMath_ReadCallback(pt) || !BaseMath_ReadCallback(line_1) || !BaseMath_ReadCallback(line_2))
                return NULL;
        
        /* accept 2d verts */
@@ -374,7 +374,7 @@ static PyObject *M_Geometry_PointInTriangle2D( PyObject * self, PyObject * args
                return NULL;
        }
        
-       if(!Vector_ReadCallback(pt_vec) || !Vector_ReadCallback(tri_p1) || !Vector_ReadCallback(tri_p2) || !Vector_ReadCallback(tri_p3))
+       if(!BaseMath_ReadCallback(pt_vec) || !BaseMath_ReadCallback(tri_p1) || !BaseMath_ReadCallback(tri_p2) || !BaseMath_ReadCallback(tri_p3))
                return NULL;
        
        return PyLong_FromLong(IsectPT2Df(pt_vec->vec, tri_p1->vec, tri_p2->vec, tri_p3->vec));
@@ -395,7 +395,7 @@ static PyObject *M_Geometry_PointInQuad2D( PyObject * self, PyObject * args )
                return NULL;
        }
        
-       if(!Vector_ReadCallback(pt_vec) || !Vector_ReadCallback(quad_p1) || !Vector_ReadCallback(quad_p2) || !Vector_ReadCallback(quad_p3) || !Vector_ReadCallback(quad_p4))
+       if(!BaseMath_ReadCallback(pt_vec) || !BaseMath_ReadCallback(quad_p1) || !BaseMath_ReadCallback(quad_p2) || !BaseMath_ReadCallback(quad_p3) || !BaseMath_ReadCallback(quad_p4))
                return NULL;
        
        return PyLong_FromLong(IsectPQ2Df(pt_vec->vec, quad_p1->vec, quad_p2->vec, quad_p3->vec, quad_p4->vec));
@@ -517,7 +517,7 @@ static PyObject *M_Geometry_BezierInterp( PyObject * self, PyObject * args )
                return NULL;
        }
        
-       if(!Vector_ReadCallback(vec_k1) || !Vector_ReadCallback(vec_h1) || !Vector_ReadCallback(vec_k2) || !Vector_ReadCallback(vec_h2))
+       if(!BaseMath_ReadCallback(vec_k1) || !BaseMath_ReadCallback(vec_h1) || !BaseMath_ReadCallback(vec_k2) || !BaseMath_ReadCallback(vec_h2))
                return NULL;
        
        dims= MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size);
index cd9705236d7a162c0a3aa949d52718f7b7462936..ec94a48ddbd4e57bfc1c9fee248bdb1f16534324 100644 (file)
@@ -155,10 +155,13 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2)
 
        if(QuaternionObject_Check(arg1)){
                quat = (QuaternionObject*)arg1;
+               if(!BaseMath_ReadCallback(quat))
+                       return NULL;
+
                if(VectorObject_Check(arg2)){
                        vec = (VectorObject*)arg2;
                        
-                       if(!Vector_ReadCallback(vec))
+                       if(!BaseMath_ReadCallback(vec))
                                return NULL;
                        
                        rot[0] = quat->quat[0]*quat->quat[0]*vec->vec[0] + 2*quat->quat[2]*quat->quat[0]*vec->vec[2] - 
@@ -178,11 +181,14 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2)
        }else if(VectorObject_Check(arg1)){
                vec = (VectorObject*)arg1;
                
-               if(!Vector_ReadCallback(vec))
+               if(!BaseMath_ReadCallback(vec))
                        return NULL;
                
                if(QuaternionObject_Check(arg2)){
                        quat = (QuaternionObject*)arg2;
+                       if(!BaseMath_ReadCallback(quat))
+                               return NULL;
+
                        rot[0] = quat->quat[0]*quat->quat[0]*vec->vec[0] + 2*quat->quat[2]*quat->quat[0]*vec->vec[2] - 
                                2*quat->quat[3]*quat->quat[0]*vec->vec[1] + quat->quat[1]*quat->quat[1]*vec->vec[0] + 
                                2*quat->quat[2]*quat->quat[1]*vec->vec[1] + 2*quat->quat[3]*quat->quat[1]*vec->vec[2] - 
@@ -247,7 +253,7 @@ static PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args)
        if(vec1->size != vec2->size)
                goto AttributeError1; //bad sizes
 
-       if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
+       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
                return NULL;
        
        //since size is the same....
@@ -269,8 +275,11 @@ static PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args)
 
        angleRads = (double)saacos(dot);
 
+#ifdef USE_MATHUTILS_DEG
        return PyFloat_FromDouble(angleRads * (180/ Py_PI));
-
+#else
+       return PyFloat_FromDouble(angleRads);
+#endif
 AttributeError1:
        PyErr_SetString(PyExc_AttributeError, "Mathutils.AngleBetweenVecs(): expects (2) VECTOR objects of the same size\n");
        return NULL;
@@ -296,7 +305,7 @@ static PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args)
                return NULL;
        }
        
-       if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
+       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
                return NULL;
 
        for(x = 0; x < vec1->size; x++) {
@@ -322,7 +331,7 @@ static PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args)
                return NULL;
        }
 
-       if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
+       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
                return NULL;
 
        
@@ -358,12 +367,19 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
                PyErr_SetString(PyExc_TypeError, "Mathutils.RotationMatrix(): expected float int and optional string and vector\n");
                return NULL;
        }
-       
+
+#ifdef USE_MATHUTILS_DEG
        /* Clamp to -360:360 */
        while (angle<-360.0f)
                angle+=360.0;
        while (angle>360.0f)
                angle-=360.0;
+#else
+       while (angle<-(Py_PI*2))
+               angle+=(Py_PI*2);
+       while (angle>(Py_PI*2))
+               angle-=(Py_PI*2);
+#endif
        
        if(matSize != 2 && matSize != 3 && matSize != 4) {
                PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n");
@@ -389,12 +405,15 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
                        return NULL;
                }
                
-               if(!Vector_ReadCallback(vec))
+               if(!BaseMath_ReadCallback(vec))
                        return NULL;
                
        }
+#ifdef USE_MATHUTILS_DEG
        //convert to radians
        angle = angle * (float) (Py_PI / 180);
+#endif
+
        if(axis == NULL && matSize == 2) {
                //2D rotation matrix
                mat[0] = (float) cos (angle);
@@ -492,7 +511,7 @@ static PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * v
                return NULL;
        }
        
-       if(!Vector_ReadCallback(vec))
+       if(!BaseMath_ReadCallback(vec))
                return NULL;
        
        //create a identity matrix and add translation
@@ -528,7 +547,7 @@ static PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args)
                        return NULL;
                }
                
-               if(!Vector_ReadCallback(vec))
+               if(!BaseMath_ReadCallback(vec))
                        return NULL;
                
        }
@@ -607,7 +626,7 @@ static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * a
                        return NULL;
                }
                
-               if(!Vector_ReadCallback(vec))
+               if(!BaseMath_ReadCallback(vec))
                        return NULL;
                
        }
@@ -766,6 +785,10 @@ static PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args)
                PyErr_SetString(PyExc_TypeError, "Mathutils.DifferenceQuats(): expected Quaternion types");
                return NULL;
        }
+
+       if(!BaseMath_ReadCallback(quatU) || !BaseMath_ReadCallback(quatV))
+               return NULL;
+
        tempQuat[0] = quatU->quat[0];
        tempQuat[1] = -quatU->quat[1];
        tempQuat[2] = -quatU->quat[2];
@@ -793,6 +816,10 @@ static PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args)
                PyErr_SetString(PyExc_TypeError, "Mathutils.Slerp(): expected Quaternion types and float");
                return NULL;
        }
+
+       if(!BaseMath_ReadCallback(quatU) || !BaseMath_ReadCallback(quatV))
+               return NULL;
+
        if(param > 1.0f || param < 0.0f) {
                PyErr_SetString(PyExc_AttributeError, "Mathutils.Slerp(): interpolation factor must be between 0.0 and 1.0");
                return NULL;
@@ -856,7 +883,7 @@ static PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args )
                return NULL;
        }
 
-       if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3) || !Vector_ReadCallback(ray) || !Vector_ReadCallback(ray_off))
+       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(ray) || !BaseMath_ReadCallback(ray_off))
                return NULL;
        
        VECCOPY(v1, vec1->vec);
@@ -928,7 +955,7 @@ static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
                return NULL;
        }
        
-       if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3) || !Vector_ReadCallback(vec4))
+       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(vec4))
                return NULL;
        
        if( vec1->size == 3 || vec1->size == 2) {
@@ -1002,7 +1029,7 @@ static PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args )
                return NULL;
        }
        
-       if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3) || !Vector_ReadCallback(vec4))
+       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(vec4))
                return NULL;
        
        VECCOPY(v1, vec1->vec);
@@ -1050,7 +1077,7 @@ static PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args )
                return NULL;
        }
        
-       if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3))
+       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3))
                return NULL;
 
        VECCOPY(v1, vec1->vec);
@@ -1085,7 +1112,7 @@ static PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args )
                return NULL;
        }
        
-       if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2) || !Vector_ReadCallback(vec3))
+       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3))
                return NULL;
 
        if (vec1->size == 3) {
@@ -1167,75 +1194,66 @@ int Mathutils_RegisterCallback(Mathutils_Callback *cb)
 }
 
 /* use macros to check for NULL */
-int _Vector_ReadCallback(VectorObject *self)
+int _BaseMathObject_ReadCallback(BaseMathObject *self)
 {
        Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
-       if(cb->get(self->cb_user, self->cb_subtype, self->vec)) {
+       if(cb->get(self->cb_user, self->cb_subtype, self->data))
                return 1;
-       }
-       else {
-               PyErr_SetString(PyExc_SystemError, "Vector user has become invalid");
-               return 0;
-       }
+
+       PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name);
+       return 0;
 }
 
-int _Vector_WriteCallback(VectorObject *self)
+int _BaseMathObject_WriteCallback(BaseMathObject *self)
 {
        Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
-       if(cb->set(self->cb_user, self->cb_subtype, self->vec)) {
+       if(cb->set(self->cb_user, self->cb_subtype, self->data))
                return 1;
-       }
-       else {
-               PyErr_SetString(PyExc_SystemError, "Vector user has become invalid");
-               return 0;
-       }
+
+       PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name);
+       return 0;
 }
 
-int _Vector_ReadIndexCallback(VectorObject *self, int index)
+int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index)
 {
        Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
-       if(cb->get_index(self->cb_user, self->cb_subtype, self->vec, index)) {
+       if(cb->get_index(self->cb_user, self->cb_subtype, self->data, index))
                return 1;
-       }
-       else {
-               PyErr_SetString(PyExc_SystemError, "Vector user has become invalid");
-               return 0;
-       }
+
+       PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name);
+       return 0;
 }
 
-int _Vector_WriteIndexCallback(VectorObject *self, int index)
+int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index)
 {
        Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
-       if(cb->set_index(self->cb_user, self->cb_subtype, self->vec, index)) {
+       if(cb->set_index(self->cb_user, self->cb_subtype, self->data, index))
                return 1;
-       }
-       else {
-               PyErr_SetString(PyExc_SystemError, "Vector user has become invalid");
-               return 0;
-       }
+
+       PyErr_Format(PyExc_SystemError, "%s user has become invalid", Py_TYPE(self)->tp_name);
+       return 0;
 }
 
-/* matrix callbacks */
-int _Matrix_ReadCallback(MatrixObject *self)
+/* BaseMathObject generic functions for all mathutils types */
+PyObject *BaseMathObject_getOwner( BaseMathObject * self, void *type )
 {
-       Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
-       if(cb->get(self->cb_user, self->cb_subtype, self->contigPtr)) {
-               return 1;
-       }
-       else {
-               PyErr_SetString(PyExc_SystemError, "Matrix user has become invalid");
-               return 0;
-       }
+       PyObject *ret= self->cb_user ? self->cb_user : Py_None;
+       Py_INCREF(ret);
+       return ret;
 }
 
-int _Matrix_WriteCallback(MatrixObject *self)
+PyObject *BaseMathObject_getWrapped( BaseMathObject *self, void *type )
 {
-       Mathutils_Callback *cb= mathutils_callbacks[self->cb_type];
-       if(cb->set(self->cb_user, self->cb_subtype, self->contigPtr)) {
-               return 1;
-       }
-       else {
-               PyErr_SetString(PyExc_SystemError, "Matrix user has become invalid");
-               return 0;
-       }
+       PyBool_FromLong((self->wrapped == Py_WRAP) ? 1:0);
+}
+
+void BaseMathObject_dealloc(BaseMathObject * self)
+{
+       /* only free non wrapped */
+       if(self->wrapped != Py_WRAP)
+               PyMem_Free(self->data);
+
+       Py_XDECREF(self->cb_user);
+       PyObject_DEL(self);
 }
+
index a89b779ecbb2c178f1844bebd92714c4041394d5..6a4e28d6068e5e32d6b76b401c84284f484750b2 100644 (file)
 #include "quat.h"
 #include "euler.h"
 
+/* #define USE_MATHUTILS_DEG - for backwards compat */
+
+/* Can cast different mathutils types to this, use for generic funcs */
+
+typedef struct {
+       PyObject_VAR_HEAD
+       float *data;                                    /*array of data (alias), wrapped status depends on wrapped status */
+       PyObject *cb_user;                                      /* if this vector references another object, otherwise NULL, *Note* this owns its reference */
+       unsigned char cb_type;  /* which user funcs do we adhere to, RNA, GameObject, etc */
+       unsigned char cb_subtype;               /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */
+       unsigned char wrapped;          /* wrapped data type? */
+} BaseMathObject;
+
+PyObject *BaseMathObject_getOwner( BaseMathObject * self, void * );
+PyObject *BaseMathObject_getWrapped( BaseMathObject *self, void * );
+void BaseMathObject_dealloc(BaseMathObject * self);
+
+
+
+
 PyObject *Mathutils_Init( const char * from );
 
 PyObject *quat_rotation(PyObject *arg1, PyObject *arg2);
@@ -75,22 +95,15 @@ struct Mathutils_Callback {
 
 int Mathutils_RegisterCallback(Mathutils_Callback *cb);
 
-int _Vector_ReadCallback(VectorObject *self);
-int _Vector_WriteCallback(VectorObject *self);
-int _Vector_ReadIndexCallback(VectorObject *self, int index);
-int _Vector_WriteIndexCallback(VectorObject *self, int index);
+int _BaseMathObject_ReadCallback(BaseMathObject *self);
+int _BaseMathObject_WriteCallback(BaseMathObject *self);
+int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index);
+int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index);
 
 /* since this is called so often avoid where possible */
-#define Vector_ReadCallback(_self) (((_self)->cb_user ?        _Vector_ReadCallback(_self):1))
-#define Vector_WriteCallback(_self) (((_self)->cb_user ?_Vector_WriteCallback(_self):1))
-#define Vector_ReadIndexCallback(_self, _index) (((_self)->cb_user ?   _Vector_ReadIndexCallback(_self, _index):1))
-#define Vector_WriteIndexCallback(_self, _index) (((_self)->cb_user ?  _Vector_WriteIndexCallback(_self, _index):1))
-
-
-int _Matrix_ReadCallback(MatrixObject *self);
-int _Matrix_WriteCallback(MatrixObject *self);
-
-#define Matrix_ReadCallback(_self) (((_self)->cb_user  ?_Matrix_ReadCallback(_self):1))
-#define Matrix_WriteCallback(_self) (((_self)->cb_user ?_Matrix_WriteCallback(_self):1))
+#define BaseMath_ReadCallback(_self) (((_self)->cb_user ?      _BaseMathObject_ReadCallback((BaseMathObject *)_self):1))
+#define BaseMath_WriteCallback(_self) (((_self)->cb_user ?_BaseMathObject_WriteCallback((BaseMathObject *)_self):1))
+#define BaseMath_ReadIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_ReadIndexCallback((BaseMathObject *)_self, _index):1))
+#define BaseMath_WriteIndexCallback(_self, _index) (((_self)->cb_user ?        _BaseMathObject_WriteIndexCallback((BaseMathObject *)_self, _index):1))
 
 #endif                         /* EXPP_Mathutils_H */
index e78a57393477f1bd9e1f8c9a3e62495be6de4254..9041eb84a3d05c9040044c0a3334a0bac2ae66c0 100644 (file)
@@ -70,7 +70,7 @@ static PyObject *Euler_new(PyObject * self, PyObject * args)
 
        PyObject *listObject = NULL;
        int size, i;
-       float eul[3], scalar;
+       float eul[3];
        PyObject *e;
 
        size = PyTuple_GET_SIZE(args);
@@ -102,15 +102,13 @@ static PyObject *Euler_new(PyObject * self, PyObject * args)
                        return NULL;
                }
 
-               scalar= (float)PyFloat_AsDouble(e);
+               eul[i]= (float)PyFloat_AsDouble(e);
                Py_DECREF(e);
                
-               if(scalar==-1 && PyErr_Occurred()) { // parsed item is not a number
+               if(eul[i]==-1 && PyErr_Occurred()) { // parsed item is not a number
                        PyErr_SetString(PyExc_TypeError, "Mathutils.Euler(): 3d numeric sequence expected\n");
                        return NULL;
                }
-
-               eul[i]= scalar;
        }
        return newEulerObject(eul, Py_NEW);
 }
@@ -123,10 +121,18 @@ static PyObject *Euler_ToQuat(EulerObject * self)
        float eul[3], quat[4];
        int x;
 
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
+
+#ifdef USE_MATHUTILS_DEG
        for(x = 0; x < 3; x++) {
                eul[x] = self->eul[x] * ((float)Py_PI / 180);
        }
        EulToQuat(eul, quat);
+#else
+       EulToQuat(self->eul, quat);
+#endif
+
        return newQuaternionObject(quat, Py_NEW);
 }
 //----------------------------Euler.toMatrix()---------------------
@@ -137,10 +143,17 @@ static PyObject *Euler_ToMatrix(EulerObject * self)
        float mat[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
        int x;
 
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
+
+#ifdef USE_MATHUTILS_DEG
        for(x = 0; x < 3; x++) {
                eul[x] = self->eul[x] * ((float)Py_PI / 180);
        }
        EulToMat3(eul, (float (*)[3]) mat);
+#else
+       EulToMat3(self->eul, (float (*)[3]) mat);
+#endif
        return newMatrixObject(mat, 3, 3 , Py_NEW);
 }
 //----------------------------Euler.unique()-----------------------
@@ -152,10 +165,15 @@ static PyObject *Euler_Unique(EulerObject * self)
        double piO2 = Py_PI / 2.0f;
        double Opi2 = 1.0f / pi2;
 
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
+
+#ifdef USE_MATHUTILS_DEG
        //radians
        heading = self->eul[0] * (float)Py_PI / 180;
        pitch = self->eul[1] * (float)Py_PI / 180;
        bank = self->eul[2] * (float)Py_PI / 180;
+#endif
 
        //wrap heading in +180 / -180
        pitch += Py_PI;
@@ -186,11 +204,14 @@ static PyObject *Euler_Unique(EulerObject * self)
        heading -= (floor(heading * Opi2)) * pi2;
        heading -= Py_PI;
 
+#ifdef USE_MATHUTILS_DEG
        //back to degrees
        self->eul[0] = (float)(heading * 180 / (float)Py_PI);
        self->eul[1] = (float)(pitch * 180 / (float)Py_PI);
        self->eul[2] = (float)(bank * 180 / (float)Py_PI);
+#endif
 
+       BaseMath_WriteCallback(self);
        Py_INCREF(self);
        return (PyObject *)self;
 }
@@ -202,6 +223,7 @@ static PyObject *Euler_Zero(EulerObject * self)
        self->eul[1] = 0.0;
        self->eul[2] = 0.0;
 
+       BaseMath_WriteCallback(self);
        Py_INCREF(self);
        return (PyObject *)self;
 }
@@ -223,17 +245,26 @@ static PyObject *Euler_Rotate(EulerObject * self, PyObject *args)
                return NULL;
        }
 
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
+
+#ifdef USE_MATHUTILS_DEG
        //covert to radians
        angle *= ((float)Py_PI / 180);
        for(x = 0; x < 3; x++) {
                self->eul[x] *= ((float)Py_PI / 180);
        }
+#endif
        euler_rot(self->eul, angle, *axis);
+
+#ifdef USE_MATHUTILS_DEG
        //convert back from radians
        for(x = 0; x < 3; x++) {
                self->eul[x] *= (180 / (float)Py_PI);
        }
+#endif
 
+       BaseMath_WriteCallback(self);
        Py_INCREF(self);
        return (PyObject *)self;
 }
@@ -248,17 +279,27 @@ static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value)
                return NULL;
        }
        
+       if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
+               return NULL;
+
+#ifdef USE_MATHUTILS_DEG
        //covert to radians
        for(x = 0; x < 3; x++) {
                self->eul[x] = self->eul[x] * ((float)Py_PI / 180);
                eul_from_rad[x] = value->eul[x] * ((float)Py_PI / 180);
        }
        compatible_eul(self->eul, eul_from_rad);
+#else
+       compatible_eul(self->eul, value->eul);
+#endif
+
+#ifdef USE_MATHUTILS_DEG
        //convert back from radians
        for(x = 0; x < 3; x++) {
                self->eul[x] *= (180 / (float)Py_PI);
        }
-       
+#endif
+       BaseMath_WriteCallback(self);
        Py_INCREF(self);
        return (PyObject *)self;
 }
@@ -267,19 +308,10 @@ static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value)
 // return a copy of the euler
 static PyObject *Euler_copy(EulerObject * self, PyObject *args)
 {
-       return newEulerObject(self->eul, Py_NEW);
-}
-
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
 
-//----------------------------dealloc()(internal) ------------------
-//free the py_object
-static void Euler_dealloc(EulerObject * self)
-{
-       //only free py_data
-       if(self->data.py_data){
-               PyMem_Free(self->data.py_data);
-       }
-       PyObject_DEL(self);
+       return newEulerObject(self->eul, Py_NEW);
 }
 
 //----------------------------print object (internal)--------------
@@ -287,6 +319,10 @@ static void Euler_dealloc(EulerObject * self)
 static PyObject *Euler_repr(EulerObject * self)
 {
        char str[64];
+
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
+
        sprintf(str, "[%.6f, %.6f, %.6f](euler)", self->eul[0], self->eul[1], self->eul[2]);
        return PyUnicode_FromString(str);
 }
@@ -297,7 +333,18 @@ static PyObject* Euler_richcmpr(PyObject *objectA, PyObject *objectB, int compar
        EulerObject *eulA = NULL, *eulB = NULL;
        int result = 0;
 
-       if (!EulerObject_Check(objectA) || !EulerObject_Check(objectB)){
+       if(EulerObject_Check(objectA)) {
+               eulA = (EulerObject*)objectA;
+               if(!BaseMath_ReadCallback(eulA))
+                       return NULL;
+       }
+       if(EulerObject_Check(objectB)) {
+               eulB = (EulerObject*)objectB;
+               if(!BaseMath_ReadCallback(eulB))
+                       return NULL;
+       }
+
+       if (!eulA || !eulB){
                if (comparison_type == Py_NE){
                        Py_RETURN_TRUE;
                }else{
@@ -342,13 +389,16 @@ static int Euler_len(EulerObject * self)
 //sequence accessor (get)
 static PyObject *Euler_item(EulerObject * self, int i)
 {
-       if(i<0)
-               i= 3-i;
+       if(i<0) i= 3-i;
        
        if(i < 0 || i >= 3) {
                PyErr_SetString(PyExc_IndexError, "euler[attribute]: array index out of range");
                return NULL;
        }
+
+       if(!BaseMath_ReadIndexCallback(self, i))
+               return NULL;
+
        return PyFloat_FromDouble(self->eul[i]);
 
 }
@@ -363,8 +413,7 @@ static int Euler_ass_item(EulerObject * self, int i, PyObject * value)
                return -1;
        }
 
-       if(i<0)
-               i= 3-i;
+       if(i<0) i= 3-i;
        
        if(i < 0 || i >= 3){
                PyErr_SetString(PyExc_IndexError, "euler[attribute] = x: array assignment index out of range\n");
@@ -372,6 +421,10 @@ static int Euler_ass_item(EulerObject * self, int i, PyObject * value)
        }
        
        self->eul[i] = f;
+
+       if(!BaseMath_WriteIndexCallback(self, i))
+               return -1;
+
        return 0;
 }
 //----------------------------object[z:y]------------------------
@@ -381,6 +434,9 @@ static PyObject *Euler_slice(EulerObject * self, int begin, int end)
        PyObject *list = NULL;
        int count;
 
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
+
        CLAMP(begin, 0, 3);
        if (end<0) end= 4+end;
        CLAMP(end, 0, 3);
@@ -401,7 +457,10 @@ static int Euler_ass_slice(EulerObject * self, int begin, int end,
 {
        int i, y, size = 0;
        float eul[3];
-       PyObject *e, *f;
+       PyObject *e;
+
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
 
        CLAMP(begin, 0, 3);
        if (end<0) end= 4+end;
@@ -421,21 +480,20 @@ static int Euler_ass_slice(EulerObject * self, int begin, int end,
                        return -1;
                }
 
-               f = PyNumber_Float(e);
-               if(f == NULL) { // parsed item not a number
-                       Py_DECREF(e);
+               eul[i] = (float)PyFloat_AsDouble(e);
+               Py_DECREF(e);
+
+               if(eul[i]==-1 && PyErr_Occurred()) { // parsed item not a number
                        PyErr_SetString(PyExc_TypeError, "euler[begin:end] = []: sequence argument not a number");
                        return -1;
                }
-
-               eul[i] = (float)PyFloat_AS_DOUBLE(f);
-               Py_DECREF(f);
-               Py_DECREF(e);
        }
        //parsed well - now set in vector
        for(y = 0; y < 3; y++){
                self->eul[begin + y] = eul[y];
        }
+
+       BaseMath_WriteCallback(self);
        return 0;
 }
 //-----------------PROTCOL DECLARATIONS--------------------------
@@ -450,79 +508,30 @@ static PySequenceMethods Euler_SeqMethods = {
 };
 
 
-
 /*
  * vector axis, vector.x/y/z/w
  */
        
 static PyObject *Euler_getAxis( EulerObject * self, void *type )
 {
-       switch( (long)type ) {
-    case 'X':  /* these are backwards, but that how it works */
-               return PyFloat_FromDouble(self->eul[0]);
-    case 'Y':
-               return PyFloat_FromDouble(self->eul[1]);
-    case 'Z':
-               return PyFloat_FromDouble(self->eul[2]);
-       }
-       
-       PyErr_SetString(PyExc_SystemError, "corrupt euler, cannot get axis");
-       return NULL;
+       return Euler_item(self, GET_INT_FROM_POINTER(type));
 }
 
 static int Euler_setAxis( EulerObject * self, PyObject * value, void * type )
 {
-       float param= (float)PyFloat_AsDouble( value );
-       
-       if (param==-1 && PyErr_Occurred()) {
-               PyErr_SetString(PyExc_TypeError, "expected a number for the vector axis");
-               return -1;
-       }
-       
-       switch( (long)type ) {
-    case 'X':  /* these are backwards, but that how it works */
-               self->eul[0]= param;
-               break;
-    case 'Y':
-               self->eul[1]= param;
-               break;
-    case 'Z':
-               self->eul[2]= param;
-               break;
-       }
-
-       return 0;
-}
-
-static PyObject *Euler_getWrapped( VectorObject * self, void *type )
-{
-       if (self->wrapped == Py_WRAP)
-               Py_RETURN_TRUE;
-       else
-               Py_RETURN_FALSE;
+       return Euler_ass_item(self, GET_INT_FROM_POINTER(type), value);
 }
 
-
 /*****************************************************************************/
 /* Python attributes get/set structure:                                      */
 /*****************************************************************************/
 static PyGetSetDef Euler_getseters[] = {
-       {"x",
-        (getter)Euler_getAxis, (setter)Euler_setAxis,
-        "Euler X axis",
-        (void *)'X'},
-       {"y",
-        (getter)Euler_getAxis, (setter)Euler_setAxis,
-        "Euler Y axis",
-        (void *)'Y'},
-       {"z",
-        (getter)Euler_getAxis, (setter)Euler_setAxis,
-        "Euler Z axis",
-        (void *)'Z'},
-       {"wrapped",
-        (getter)Euler_getWrapped, (setter)NULL,
-        "True when this wraps blenders internal data",
-        NULL},
+       {"x", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler X axis", (void *)0},
+       {"y", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Y axis", (void *)1},
+       {"z", (getter)Euler_getAxis, (setter)Euler_setAxis, "Euler Z axis", (void *)2},
+
+       {"wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, "True when this wraps blenders internal data", NULL},
+       {"__owner__", (getter)BaseMathObject_getOwner, (setter)NULL, "Read only owner for vectors that depend on another object", NULL},
        {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
 };
 
@@ -538,7 +547,7 @@ PyTypeObject euler_Type = {
        "euler",                                                //tp_name
        sizeof(EulerObject),                    //tp_basicsize
        0,                                                              //tp_itemsize
-       (destructor)Euler_dealloc,              //tp_dealloc
+       (destructor)BaseMathObject_dealloc,             //tp_dealloc
        0,                                                              //tp_print
        0,                                                              //tp_getattr
        0,                                                              //tp_setattr
@@ -593,24 +602,22 @@ PyObject *newEulerObject(float *eul, int type)
        int x;
 
        self = PyObject_NEW(EulerObject, &euler_Type);
-       self->data.blend_data = NULL;
-       self->data.py_data = NULL;
+
+       /* init callbacks as NULL */
+       self->cb_user= NULL;
+       self->cb_type= self->cb_subtype= 0;
 
        if(type == Py_WRAP){
-               self->data.blend_data = eul;
-               self->eul = self->data.blend_data;
+               self->eul = eul;
                self->wrapped = Py_WRAP;
        }else if (type == Py_NEW){
-               self->data.py_data = PyMem_Malloc(3 * sizeof(float));
-               self->eul = self->data.py_data;
+               self->eul = PyMem_Malloc(3 * sizeof(float));
                if(!eul) { //new empty
                        for(x = 0; x < 3; x++) {
                                self->eul[x] = 0.0f;
                        }
                }else{
-                       for(x = 0; x < 3; x++){
-                               self->eul[x] = eul[x];
-                       }
+                       VECCOPY(self->eul, eul);
                }
                self->wrapped = Py_NEW;
        }else{ //bad type
@@ -618,3 +625,16 @@ PyObject *newEulerObject(float *eul, int type)
        }
        return (PyObject *)self;
 }
+
+PyObject *newEulerObject_cb(PyObject *cb_user, int cb_type, int cb_subtype)
+{
+       EulerObject *self= (EulerObject *)newEulerObject(NULL, Py_NEW);
+       if(self) {
+               Py_INCREF(cb_user);
+               self->cb_user=                  cb_user;
+               self->cb_type=                  (unsigned char)cb_type;
+               self->cb_subtype=               (unsigned char)cb_subtype;
+       }
+
+       return self;
+}
index 3be629351cbff336453877ed02c53ab62725bd08..0bff6de6964e0ca59aed9ac9af6c97a3f333bc97 100644 (file)
@@ -40,12 +40,13 @@ extern PyTypeObject euler_Type;
 
 typedef struct {
        PyObject_VAR_HEAD 
-       struct{
-               float *py_data;         //python managed
-               float *blend_data;      //blender managed
-       }data;
-       float *eul;                             //1D array of data (alias)
-       int wrapped;                    //is wrapped data?
+       float *eul;                                     /*1D array of data */
+       PyObject *cb_user;                      /* if this vector references another object, otherwise NULL, *Note* this owns its reference */
+       unsigned char cb_type;          /* which user funcs do we adhere to, RNA, GameObject, etc */
+       unsigned char cb_subtype;       /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */
+       unsigned char wrapped;          /* wrapped data type? */
+       /* end BaseMathObject */
+
 } EulerObject;
 
 /*struct data contains a pointer to the actual data that the
@@ -55,5 +56,6 @@ blender (stored in blend_data). This is an either/or struct not both*/
 
 //prototypes
 PyObject *newEulerObject( float *eul, int type );
+PyObject *newEulerObject_cb(PyObject *cb_user, int cb_type, int cb_subtype);
 
 #endif                         /* EXPP_euler_h */
index db5b4ab08bfaef761ee04d1699abb7e3f9bba34a..b546aa1226c5ec76e0c3a545bc5668c3f18594cf 100644 (file)
@@ -39,13 +39,13 @@ int mathutils_matrix_vector_cb_index= -1;
 
 static int mathutils_matrix_vector_check(MatrixObject *self)
 {
-       return Matrix_ReadCallback(self);
+       return BaseMath_ReadCallback(self);
 }
 
 static int mathutils_matrix_vector_get(MatrixObject *self, int subtype, float *vec_from)
 {
        int i;
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return 0;
 
        for(i=0; i<self->colSize; i++)
@@ -57,19 +57,19 @@ static int mathutils_matrix_vector_get(MatrixObject *self, int subtype, float *v
 static int mathutils_matrix_vector_set(MatrixObject *self, int subtype, float *vec_to)
 {
        int i;
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return 0;
 
        for(i=0; i<self->colSize; i++)
                self->matrix[subtype][i]= vec_to[i];
 
-       Matrix_WriteCallback(self);
+       BaseMath_WriteCallback(self);
        return 1;
 }
 
 static int mathutils_matrix_vector_get_index(MatrixObject *self, int subtype, float *vec_from, int index)
 {
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return 0;
 
        vec_from[index]= self->matrix[subtype][index];
@@ -78,12 +78,12 @@ static int mathutils_matrix_vector_get_index(MatrixObject *self, int subtype, fl
 
 static int mathutils_matrix_vector_set_index(MatrixObject *self, int subtype, float *vec_to, int index)
 {
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return 0;
 
        self->matrix[subtype][index]= vec_to[index];
 
-       Matrix_WriteCallback(self);
+       BaseMath_WriteCallback(self);
        return 1;
 }
 
@@ -164,7 +164,7 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
                argObject = PyTuple_GET_ITEM(args, 0);
                if(MatrixObject_Check(argObject)){
                        mat = (MatrixObject*)argObject;
-                       if(!Matrix_ReadCallback(mat))
+                       if(!BaseMath_ReadCallback(mat))
                                return NULL;
 
                        argSize = mat->rowSize; //rows
@@ -225,7 +225,7 @@ static PyObject *Matrix_toQuat(MatrixObject * self)
 {
        float quat[4];
 
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        /*must be 3-4 cols, 3-4 rows, square matrix*/
@@ -248,16 +248,23 @@ PyObject *Matrix_toEuler(MatrixObject * self, PyObject *args)
        EulerObject *eul_compat = NULL;
        int x;
        
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        if(!PyArg_ParseTuple(args, "|O!:toEuler", &euler_Type, &eul_compat))
                return NULL;
        
        if(eul_compat) {
+               if(!BaseMath_ReadCallback(eul_compat))
+                       return NULL;
+
+#ifdef USE_MATHUTILS_DEG
                for(x = 0; x < 3; x++) {
                        eul_compatf[x] = eul_compat->eul[x] * ((float)Py_PI / 180);
                }
+#else
+               VECCOPY(eul_compatf, eul_compat->eul);
+#endif
        }
        
        /*must be 3-4 cols, 3-4 rows, square matrix*/
@@ -275,10 +282,12 @@ PyObject *Matrix_toEuler(MatrixObject * self, PyObject *args)
                PyErr_SetString(PyExc_AttributeError, "Matrix.toEuler(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n");
                return NULL;
        }
+#ifdef USE_MATHUTILS_DEG
        /*have to convert to degrees*/
        for(x = 0; x < 3; x++) {
                eul[x] *= (float) (180 / Py_PI);
        }
+#endif
        return newEulerObject(eul, Py_NEW);
 }
 /*---------------------------Matrix.resize4x4() ------------------*/
@@ -343,7 +352,7 @@ PyObject *Matrix_TranslationPart(MatrixObject * self)
 {
        float vec[4];
        
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        if(self->colSize < 3 || self->rowSize < 4){
@@ -363,7 +372,7 @@ PyObject *Matrix_RotationPart(MatrixObject * self)
        float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
 
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
 
        if(self->colSize < 3 || self->rowSize < 3){
@@ -389,7 +398,7 @@ PyObject *Matrix_scalePart(MatrixObject * self)
        float scale[3], rot[3];
        float mat[3][3], imat[3][3], tmat[3][3];
 
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        /*must be 3-4 cols, 3-4 rows, square matrix*/
@@ -422,7 +431,7 @@ PyObject *Matrix_Invert(MatrixObject * self)
        float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
 
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
 
        if(self->rowSize != self->colSize){
@@ -465,7 +474,7 @@ PyObject *Matrix_Invert(MatrixObject * self)
                return NULL;
        }
        
-       Matrix_WriteCallback(self);
+       BaseMath_WriteCallback(self);
        Py_INCREF(self);
        return (PyObject *)self;
 }
@@ -476,7 +485,7 @@ PyObject *Matrix_Determinant(MatrixObject * self)
 {
        float det = 0.0f;
 
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        if(self->rowSize != self->colSize){
@@ -504,7 +513,7 @@ PyObject *Matrix_Transpose(MatrixObject * self)
 {
        float t = 0.0f;
 
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        if(self->rowSize != self->colSize){
@@ -522,7 +531,7 @@ PyObject *Matrix_Transpose(MatrixObject * self)
                Mat4Transp((float (*)[4])*self->matrix);
        }
 
-       Matrix_WriteCallback(self);
+       BaseMath_WriteCallback(self);
        Py_INCREF(self);
        return (PyObject *)self;
 }
@@ -539,7 +548,7 @@ PyObject *Matrix_Zero(MatrixObject * self)
                }
        }
        
-       if(!Matrix_WriteCallback(self))
+       if(!BaseMath_WriteCallback(self))
                return NULL;
        
        Py_INCREF(self);
@@ -548,7 +557,7 @@ PyObject *Matrix_Zero(MatrixObject * self)
 /*---------------------------Matrix.identity(() ------------------*/
 PyObject *Matrix_Identity(MatrixObject * self)
 {
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        if(self->rowSize != self->colSize){
@@ -567,7 +576,7 @@ PyObject *Matrix_Identity(MatrixObject * self)
                Mat4One((float (*)[4]) *self->matrix);
        }
 
-       if(!Matrix_WriteCallback(self))
+       if(!BaseMath_WriteCallback(self))
                return NULL;
        
        Py_INCREF(self);
@@ -577,25 +586,12 @@ PyObject *Matrix_Identity(MatrixObject * self)
 /*---------------------------Matrix.inverted() ------------------*/
 PyObject *Matrix_copy(MatrixObject * self)
 {
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        return (PyObject*)(MatrixObject*)newMatrixObject((float (*))*self->matrix, self->rowSize, self->colSize, Py_NEW);
 }
 
-/*----------------------------dealloc()(internal) ----------------*/
-/*free the py_object*/
-static void Matrix_dealloc(MatrixObject * self)
-{
-       PyMem_Free(self->matrix);
-       /*only free py_data*/
-       if(self->wrapped==Py_WRAP)
-               PyMem_Free(self->contigPtr);
-       
-       Py_XDECREF(self->cb_user);
-       PyObject_DEL(self);
-}
-
 /*----------------------------print object (internal)-------------*/
 /*print the object to screen*/
 static PyObject *Matrix_repr(MatrixObject * self)
@@ -603,7 +599,7 @@ static PyObject *Matrix_repr(MatrixObject * self)
        int x, y;
        char buffer[48], str[1024];
 
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        BLI_strncpy(str,"",1024);
@@ -642,7 +638,7 @@ static PyObject* Matrix_richcmpr(PyObject *objectA, PyObject *objectB, int compa
        matA = (MatrixObject*)objectA;
        matB = (MatrixObject*)objectB;
 
-       if(!Matrix_ReadCallback(matA) || !Matrix_ReadCallback(matB))
+       if(!BaseMath_ReadCallback(matA) || !BaseMath_ReadCallback(matB))
                return NULL;
        
        if (matA->colSize != matB->colSize || matA->rowSize != matB->rowSize){
@@ -692,7 +688,7 @@ static int Matrix_len(MatrixObject * self)
   the wrapped vector gives direct access to the matrix data*/
 static PyObject *Matrix_item(MatrixObject * self, int i)
 {
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        if(i < 0 || i >= self->rowSize) {
@@ -709,7 +705,7 @@ static int Matrix_ass_item(MatrixObject * self, int i, PyObject * ob)
        float vec[4];
        PyObject *m, *f;
 
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return -1;
        
        if(i >= self->rowSize || i < 0){
@@ -746,7 +742,7 @@ static int Matrix_ass_item(MatrixObject * self, int i, PyObject * ob)
                        self->matrix[i][y] = vec[y];
                }
                
-               Matrix_WriteCallback(self);
+               BaseMath_WriteCallback(self);
                return 0;
        }else{
                PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: expects a sequence of column size\n");
@@ -761,7 +757,7 @@ static PyObject *Matrix_slice(MatrixObject * self, int begin, int end)
        PyObject *list = NULL;
        int count;
        
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
 
        CLAMP(begin, 0, self->rowSize);
@@ -787,7 +783,7 @@ static int Matrix_ass_slice(MatrixObject * self, int begin, int end,
        PyObject *subseq;
        PyObject *m;
 
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return -1;
        
        CLAMP(begin, 0, self->rowSize);
@@ -848,7 +844,7 @@ static int Matrix_ass_slice(MatrixObject * self, int begin, int end,
                        self->matrix[begin + (int)floor(x / self->colSize)][x % self->colSize] = mat[x];
                }
                
-               Matrix_WriteCallback(self);
+               BaseMath_WriteCallback(self);
                return 0;
        }else{
                PyErr_SetString(PyExc_TypeError, "matrix[begin:end] = []: illegal argument type for built-in operation\n");
@@ -872,7 +868,7 @@ static PyObject *Matrix_add(PyObject * m1, PyObject * m2)
                return NULL;
        }
        
-       if(!Matrix_ReadCallback(mat1) || !Matrix_ReadCallback(mat2))
+       if(!BaseMath_ReadCallback(mat1) || !BaseMath_ReadCallback(mat2))
                return NULL;
        
        if(mat1->rowSize != mat2->rowSize || mat1->colSize != mat2->colSize){
@@ -905,7 +901,7 @@ static PyObject *Matrix_sub(PyObject * m1, PyObject * m2)
                return NULL;
        }
        
-       if(!Matrix_ReadCallback(mat1) || !Matrix_ReadCallback(mat2))
+       if(!BaseMath_ReadCallback(mat1) || !BaseMath_ReadCallback(mat2))
                return NULL;
        
        if(mat1->rowSize != mat2->rowSize || mat1->colSize != mat2->colSize){
@@ -934,12 +930,12 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
 
        if(MatrixObject_Check(m1)) {
                mat1 = (MatrixObject*)m1;
-               if(!Matrix_ReadCallback(mat1))
+               if(!BaseMath_ReadCallback(mat1))
                        return NULL;
        }
        if(MatrixObject_Check(m2)) {
                mat2 = (MatrixObject*)m2;
-               if(!Matrix_ReadCallback(mat2))
+               if(!BaseMath_ReadCallback(mat2))
                        return NULL;
        }
 
@@ -1000,7 +996,7 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
 }
 static PyObject* Matrix_inv(MatrixObject *self)
 {
-       if(!Matrix_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        return Matrix_Invert(self);
@@ -1052,33 +1048,15 @@ static PyObject *Matrix_getColSize( MatrixObject * self, void *type )
        return PyLong_FromLong((long) self->colSize);
 }
 
-static PyObject *Matrix_getOwner( MatrixObject * self, void *type )
-{
-       if(self->cb_user==NULL) {
-               Py_RETURN_NONE;
-       }
-       else {
-               Py_INCREF(self->cb_user);
-               return self->cb_user;
-       }
-}
-
-static PyObject *Matrix_getWrapped( MatrixObject * self, void *type )
-{
-       if (self->wrapped == Py_WRAP)
-               Py_RETURN_TRUE;
-       else
-               Py_RETURN_FALSE;
-}
-
 /*****************************************************************************/
 /* Python attributes get/set structure:                                      */
 /*****************************************************************************/
 static PyGetSetDef Matrix_getseters[] = {
        {"rowSize", (getter)Matrix_getRowSize, (setter)NULL, "", NULL},
        {"colSize", (getter)Matrix_getColSize, (setter)NULL, "", NULL},
-       {"wrapped", (getter)Matrix_getWrapped, (setter)NULL, "", NULL},
-       {"__owner__",(getter)Matrix_getOwner, (setter)NULL, "Read only owner for vectors that depend on another object", NULL},
+       {"wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, "", NULL},
+       {"__owner__",(getter)BaseMathObject_getOwner, (setter)NULL, "",
+        NULL},
        {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
 };
 
@@ -1094,7 +1072,7 @@ PyTypeObject matrix_Type = {
        "matrix",                                               /*tp_name*/
        sizeof(MatrixObject),                   /*tp_basicsize*/
        0,                                                              /*tp_itemsize*/
-       (destructor)Matrix_dealloc,             /*tp_dealloc*/
+       (destructor)BaseMathObject_dealloc,             /*tp_dealloc*/
        0,                                                              /*tp_print*/
        0,                                                              /*tp_getattr*/
        0,                                                              /*tp_setattr*/
@@ -1245,7 +1223,7 @@ static PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject*
        double dot = 0.0f;
        int x, y, z = 0;
 
-       if(!Matrix_ReadCallback(mat) || !Vector_ReadCallback(vec))
+       if(!BaseMath_ReadCallback(mat) || !BaseMath_ReadCallback(vec))
                return NULL;
        
        if(mat->rowSize != vec->size){
index cc3928f163265d4c7ef5b0326201ebfe7663e0f0..4b07366896953a0d747a7fc6153d61223ba46bbb 100644 (file)
@@ -37,16 +37,19 @@ extern PyTypeObject matrix_Type;
 #define MatrixObject_Check(v) ((v)->ob_type == &matrix_Type)
 
 typedef float **ptRow;
-typedef struct _Matrix {
-       PyObject_VAR_HEAD 
-       ptRow                   matrix;         /*ptr to the contigPtr (accessor)*/
-       float*                  contigPtr;      /*1D array of data (alias)*/
-       PyObject*               cb_user;        /* if this vector references another object, otherwise NULL, *Note* this owns its reference */
-       unsigned char rowSize;
-       unsigned char colSize;
-       unsigned char wrapped;  /*is wrapped data?*/
+typedef struct _Matrix { /* keep aligned with BaseMathObject in Mathutils.h */
+       PyObject_VAR_HEAD
+       float *contigPtr;       /*1D array of data (alias)*/
+       PyObject *cb_user;      /* if this vector references another object, otherwise NULL, *Note* this owns its reference */
        unsigned char cb_type;  /* which user funcs do we adhere to, RNA, GameObject, etc */
-       unsigned int cb_subtype;        /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */
+       unsigned char cb_subtype;       /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */
+       unsigned char wrapped;  /*is wrapped data?*/
+       /* end BaseMathObject */
+
+       unsigned char rowSize;
+       unsigned int colSize;
+       ptRow                   matrix;         /*ptr to the contigPtr (accessor)*/
+
 } MatrixObject;
 
 /*struct data contains a pointer to the actual data that the
index 8a3ded80455e50ba4b7f941c11f29ebe7c210f65..e7413d38ee5a424b33dbca1fefcde35e19118c97 100644 (file)
@@ -77,8 +77,8 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw
 {
        PyObject *listObject = NULL, *n, *q;
        int size, i;
-       float quat[4], scalar;
-       double norm = 0.0f, angle = 0.0f;
+       float quat[4];
+       double angle = 0.0f;
 
        size = PyTuple_GET_SIZE(args);
        if (size == 1 || size == 2) { //seq?
@@ -151,29 +151,22 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw
                        return NULL;
                }
 
-               scalar = PyFloat_AsDouble(q);
-               if (scalar==-1 && PyErr_Occurred()) {
-                       Py_DECREF(q);
+               quat[i] = PyFloat_AsDouble(q);
+               Py_DECREF(q);
+
+               if (quat[i]==-1 && PyErr_Occurred()) {
                        PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
                        return NULL;
                }
-
-               quat[i] = scalar;
-               Py_DECREF(q);
-       }
-       if(size == 3){ //calculate the quat based on axis/angle
-               norm = sqrt(quat[0] * quat[0] + quat[1] * quat[1] + quat[2] * quat[2]);
-               quat[0] /= (float)norm;
-               quat[1] /= (float)norm;
-               quat[2] /= (float)norm;
-
-               angle = angle * (Py_PI / 180);
-               quat[3] =(float) (sin(angle/ 2.0f)) * quat[2];
-               quat[2] =(float) (sin(angle/ 2.0f)) * quat[1];
-               quat[1] =(float) (sin(angle/ 2.0f)) * quat[0];
-               quat[0] =(float) (cos(angle/ 2.0f));
        }
 
+       if(size == 3) //calculate the quat based on axis/angle
+#ifdef USE_MATHUTILS_DEG
+               AxisAngleToQuat(quat, quat, angle * (Py_PI / 180));
+#else
+               AxisAngleToQuat(quat, quat, angle);
+#endif
+
        return newQuaternionObject(quat, Py_NEW);
 }
 
@@ -189,33 +182,47 @@ static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
        if(!PyArg_ParseTuple(args, "|O!:toEuler", &euler_Type, &eul_compat))
                return NULL;
        
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
+
        if(eul_compat) {
                float mat[3][3], eul_compatf[3];
                
+               if(!BaseMath_ReadCallback(eul_compat))
+                       return NULL;
+               
+               QuatToMat3(self->quat, mat);
+
+#ifdef USE_MATHUTILS_DEG
                for(x = 0; x < 3; x++) {
                        eul_compatf[x] = eul_compat->eul[x] * ((float)Py_PI / 180);
                }
-               
-               QuatToMat3(self->quat, mat);
                Mat3ToCompatibleEul(mat, eul, eul_compatf);
+#else
+               Mat3ToCompatibleEul(mat, eul, eul_compat->eul);
+#endif
        }
        else {
                QuatToEul(self->quat, eul);
        }
        
-       
+#ifdef USE_MATHUTILS_DEG
        for(x = 0; x < 3; x++) {
                eul[x] *= (180 / (float)Py_PI);
        }
+#endif
        return newEulerObject(eul, Py_NEW);
 }
 //----------------------------Quaternion.toMatrix()------------------
 //return the quat as a matrix
 static PyObject *Quaternion_ToMatrix(QuaternionObject * self)
 {
-       float mat[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
-       QuatToMat3(self->quat, (float (*)[3]) mat);
+       float mat[9]; /* all values are set */
+
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
 
+       QuatToMat3(self->quat, (float (*)[3]) mat);
        return newMatrixObject(mat, 3, 3, Py_NEW);
 }
 
@@ -230,6 +237,9 @@ static PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * va
                return NULL;
        }
        
+       if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
+               return NULL;
+
        QuatMul(quat, self->quat, value->quat);
        return newQuaternionObject(quat, Py_NEW);
 }
@@ -238,25 +248,27 @@ static PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * va
 //return the dot quat
 static PyObject *Quaternion_Dot(QuaternionObject * self, QuaternionObject * value)
 {
-       int x;
-       double dot = 0.0;
-       
        if (!QuaternionObject_Check(value)) {
                PyErr_SetString( PyExc_TypeError, "quat.dot(value): expected a quaternion argument" );
                return NULL;
        }
-       
-       for(x = 0; x < 4; x++) {
-               dot += self->quat[x] * value->quat[x];
-       }
-       return PyFloat_FromDouble(dot);
+
+       if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
+               return NULL;
+
+       return PyFloat_FromDouble(QuatDot(self->quat, value->quat));
 }
 
 //----------------------------Quaternion.normalize()----------------
 //normalize the axis of rotation of [theta,vector]
 static PyObject *Quaternion_Normalize(QuaternionObject * self)
 {
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
+
        NormalQuat(self->quat);
+
+       BaseMath_WriteCallback(self);
        Py_INCREF(self);
        return (PyObject*)self;
 }
@@ -264,20 +276,12 @@ static PyObject *Quaternion_Normalize(QuaternionObject * self)
 //invert the quat
 static PyObject *Quaternion_Inverse(QuaternionObject * self)
 {
-       double mag = 0.0f;
-       int x;
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
 
-       for(x = 1; x < 4; x++) {
-               self->quat[x] = -self->quat[x];
-       }
-       for(x = 0; x < 4; x++) {
-               mag += (self->quat[x] * self->quat[x]);
-       }
-       mag = sqrt(mag);
-       for(x = 0; x < 4; x++) {
-               self->quat[x] /= (float)(mag * mag);
-       }
+       QuatInv(self->quat);
 
+       BaseMath_WriteCallback(self);
        Py_INCREF(self);
        return (PyObject*)self;
 }
@@ -285,11 +289,12 @@ static PyObject *Quaternion_Inverse(QuaternionObject * self)
 //generate the identity quaternion
 static PyObject *Quaternion_Identity(QuaternionObject * self)
 {
-       self->quat[0] = 1.0;
-       self->quat[1] = 0.0;
-       self->quat[2] = 0.0;
-       self->quat[3] = 0.0;
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
 
+       QuatOne(self->quat);
+
+       BaseMath_WriteCallback(self);
        Py_INCREF(self);
        return (PyObject*)self;
 }
@@ -297,10 +302,12 @@ static PyObject *Quaternion_Identity(QuaternionObject * self)
 //negate the quat
 static PyObject *Quaternion_Negate(QuaternionObject * self)
 {
-       int x;
-       for(x = 0; x < 4; x++) {
-               self->quat[x] = -self->quat[x];
-       }
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
+
+       QuatMulf(self->quat, -1.0f);
+
+       BaseMath_WriteCallback(self);
        Py_INCREF(self);
        return (PyObject*)self;
 }
@@ -308,10 +315,12 @@ static PyObject *Quaternion_Negate(QuaternionObject * self)
 //negate the vector part
 static PyObject *Quaternion_Conjugate(QuaternionObject * self)
 {
-       int x;
-       for(x = 1; x < 4; x++) {
-               self->quat[x] = -self->quat[x];
-       }
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
+
+       QuatConj(self->quat);
+
+       BaseMath_WriteCallback(self);
        Py_INCREF(self);
        return (PyObject*)self;
 }
@@ -319,18 +328,10 @@ static PyObject *Quaternion_Conjugate(QuaternionObject * self)
 //return a copy of the quat
 static PyObject *Quaternion_copy(QuaternionObject * self)
 {
-       return newQuaternionObject(self->quat, Py_NEW); 
-}
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
 
-//----------------------------dealloc()(internal) ------------------
-//free the py_object
-static void Quaternion_dealloc(QuaternionObject * self)
-{
-       //only free py_data
-       if(self->data.py_data){
-               PyMem_Free(self->data.py_data);
-       }
-       PyObject_DEL(self);
+       return newQuaternionObject(self->quat, Py_NEW); 
 }
 
 //----------------------------print object (internal)--------------
@@ -338,6 +339,10 @@ static void Quaternion_dealloc(QuaternionObject * self)
 static PyObject *Quaternion_repr(QuaternionObject * self)
 {
        char str[64];
+
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
+
        sprintf(str, "[%.6f, %.6f, %.6f, %.6f](quaternion)", self->quat[0], self->quat[1], self->quat[2], self->quat[3]);
        return PyUnicode_FromString(str);
 }
@@ -348,15 +353,24 @@ static PyObject* Quaternion_richcmpr(PyObject *objectA, PyObject *objectB, int c
        QuaternionObject *quatA = NULL, *quatB = NULL;
        int result = 0;
 
-       if (!QuaternionObject_Check(objectA) || !QuaternionObject_Check(objectB)){
+       if(QuaternionObject_Check(objectA)) {
+               quatA = (QuaternionObject*)objectA;
+               if(!BaseMath_ReadCallback(quatA))
+                       return NULL;
+       }
+       if(QuaternionObject_Check(objectB)) {
+               quatB = (QuaternionObject*)objectB;
+               if(!BaseMath_ReadCallback(quatB))
+                       return NULL;
+       }
+
+       if (!quatA || !quatB){
                if (comparison_type == Py_NE){
                        Py_RETURN_TRUE;
                }else{
                        Py_RETURN_FALSE;
                }
        }
-       quatA = (QuaternionObject*)objectA;
-       quatB = (QuaternionObject*)objectB;
 
        switch (comparison_type){
                case Py_EQ:
@@ -393,10 +407,16 @@ static int Quaternion_len(QuaternionObject * self)
 //sequence accessor (get)
 static PyObject *Quaternion_item(QuaternionObject * self, int i)
 {
+       if(i<0) i= 4-i;
+
        if(i < 0 || i >= 4) {
                PyErr_SetString(PyExc_IndexError, "quaternion[attribute]: array index out of range\n");
                return NULL;
        }
+
+       if(!BaseMath_ReadIndexCallback(self, i))
+               return NULL;
+
        return PyFloat_FromDouble(self->quat[i]);
 
 }
@@ -404,21 +424,23 @@ static PyObject *Quaternion_item(QuaternionObject * self, int i)
 //sequence accessor (set)
 static int Quaternion_ass_item(QuaternionObject * self, int i, PyObject * ob)
 {
-       PyObject *f = NULL;
-
-       f = PyNumber_Float(ob);
-       if(f == NULL) { // parsed item not a number
-               PyErr_SetString(PyExc_TypeError, "quaternion[attribute] = x: argument not a number\n");
+       float scalar= (float)PyFloat_AsDouble(ob);
+       if(scalar==-1.0f && PyErr_Occurred()) { /* parsed item not a number */
+               PyErr_SetString(PyExc_TypeError, "quaternion[index] = x: index argument not a number\n");
                return -1;
        }
 
+       if(i<0) i= 4-i;
+
        if(i < 0 || i >= 4){
-               Py_DECREF(f);
                PyErr_SetString(PyExc_IndexError, "quaternion[attribute] = x: array assignment index out of range\n");
                return -1;
        }
-       self->quat[i] = (float)PyFloat_AS_DOUBLE(f);
-       Py_DECREF(f);
+       self->quat[i] = scalar;
+
+       if(!BaseMath_WriteIndexCallback(self, i))
+               return -1;
+
        return 0;
 }
 //----------------------------object[z:y]------------------------
@@ -428,6 +450,9 @@ static PyObject *Quaternion_slice(QuaternionObject * self, int begin, int end)
        PyObject *list = NULL;
        int count;
 
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
+
        CLAMP(begin, 0, 4);
        if (end<0) end= 5+end;
        CLAMP(end, 0, 4);
@@ -443,12 +468,14 @@ static PyObject *Quaternion_slice(QuaternionObject * self, int begin, int end)
 }
 //----------------------------object[z:y]------------------------
 //sequence slice (set)
-static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end,
-                            PyObject * seq)
+static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end, PyObject * seq)
 {
        int i, y, size = 0;
        float quat[4];
-       PyObject *q, *f;
+       PyObject *q;
+
+       if(!BaseMath_ReadCallback(self))
+               return -1;
 
        CLAMP(begin, 0, 4);
        if (end<0) end= 5+end;
@@ -468,21 +495,19 @@ static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end,
                        return -1;
                }
 
-               f = PyNumber_Float(q);
-               if(f == NULL) { // parsed item not a number
-                       Py_DECREF(q);
+               quat[i]= (float)PyFloat_AsDouble(q);
+               Py_DECREF(q);
+
+               if(quat[i]==-1.0f && PyErr_Occurred()) { /* parsed item not a number */
                        PyErr_SetString(PyExc_TypeError, "quaternion[begin:end] = []: sequence argument not a number\n");
                        return -1;
                }
-
-               quat[i] = (float)PyFloat_AS_DOUBLE(f);
-               Py_DECREF(f);
-               Py_DECREF(q);
        }
        //parsed well - now set in vector
-       for(y = 0; y < size; y++){
+       for(y = 0; y < size; y++)
                self->quat[begin + y] = quat[y];
-       }
+
+       BaseMath_WriteCallback(self);
        return 0;
 }
 //------------------------NUMERIC PROTOCOLS----------------------
@@ -490,7 +515,6 @@ static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end,
 //addition
 static PyObject *Quaternion_add(PyObject * q1, PyObject * q2)
 {
-       int x;
        float quat[4];
        QuaternionObject *quat1 = NULL, *quat2 = NULL;
 
@@ -498,14 +522,13 @@ static PyObject *Quaternion_add(PyObject * q1, PyObject * q2)
                PyErr_SetString(PyExc_AttributeError, "Quaternion addition: arguments not valid for this operation....\n");
                return NULL;
        }
-       
        quat1 = (QuaternionObject*)q1;
        quat2 = (QuaternionObject*)q2;
        
-       for(x = 0; x < 4; x++) {
-               quat[x] = quat1->quat[x] + quat2->quat[x];
-       }
+       if(!BaseMath_ReadCallback(quat1) || !BaseMath_ReadCallback(quat2))
+               return NULL;
 
+       QuatAdd(quat, quat1->quat, quat2->quat, 1.0f);
        return newQuaternionObject(quat, Py_NEW);
 }
 //------------------------obj - obj------------------------------
@@ -524,6 +547,9 @@ static PyObject *Quaternion_sub(PyObject * q1, PyObject * q2)
        quat1 = (QuaternionObject*)q1;
        quat2 = (QuaternionObject*)q2;
        
+       if(!BaseMath_ReadCallback(quat1) || !BaseMath_ReadCallback(quat2))
+               return NULL;
+
        for(x = 0; x < 4; x++) {
                quat[x] = quat1->quat[x] - quat2->quat[x];
        }
@@ -534,29 +560,31 @@ static PyObject *Quaternion_sub(PyObject * q1, PyObject * q2)
 //mulplication
 static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2)
 {
-       int x;
        float quat[4], scalar;
-       double dot = 0.0f;
        QuaternionObject *quat1 = NULL, *quat2 = NULL;
        VectorObject *vec = NULL;
 
-       quat1 = (QuaternionObject*)q1;
-       quat2 = (QuaternionObject*)q2;
+       if(QuaternionObject_Check(q1)) {
+               quat1 = (QuaternionObject*)q1;
+               if(!BaseMath_ReadCallback(quat1))
+                       return NULL;
+       }
+       if(QuaternionObject_Check(q2)) {
+               quat2 = (QuaternionObject*)q2;
+               if(!BaseMath_ReadCallback(quat2))
+                       return NULL;
+       }
 
-       if(QuaternionObject_Check(q1) && QuaternionObject_Check(q2)) { /* QUAT*QUAT (dot product) */
-               for(x = 0; x < 4; x++) {
-                       dot += quat1->quat[x] * quat1->quat[x];
-               }
-               return PyFloat_FromDouble(dot);
+       if(quat1 && quat2) { /* QUAT*QUAT (dot product) */
+               return PyFloat_FromDouble(QuatDot(quat1->quat, quat2->quat));
        }
        
        /* the only case this can happen (for a supported type is "FLOAT*QUAT" ) */
        if(!QuaternionObject_Check(q1)) {
                scalar= PyFloat_AsDouble(q1);
                if ((scalar == -1.0 && PyErr_Occurred())==0) { /* FLOAT*QUAT */
-                       for(x = 0; x < 4; x++) {
-                               quat[x] = quat2->quat[x] * scalar;
-                       }
+                       QUATCOPY(quat, quat2->quat);
+                       QuatMulf(quat, scalar);
                        return newQuaternionObject(quat, Py_NEW);
                }
                PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: val * quat, val is not an acceptable type");
@@ -574,9 +602,8 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2)
                
                scalar= PyFloat_AsDouble(q2);
                if ((scalar == -1.0 && PyErr_Occurred())==0) { /* QUAT*FLOAT */
-                       for(x = 0; x < 4; x++) {
-                               quat[x] = quat1->quat[x] * scalar;
-                       }
+                       QUATCOPY(quat, quat1->quat);
+                       QuatMulf(quat, scalar);
                        return newQuaternionObject(quat, Py_NEW);
                }
        }
@@ -625,70 +652,26 @@ static PyNumberMethods Quaternion_NumMethods = {
 
 static PyObject *Quaternion_getAxis( QuaternionObject * self, void *type )
 {
-       switch( (long)type ) {
-    case 'W':
-               return PyFloat_FromDouble(self->quat[0]);
-    case 'X':
-               return PyFloat_FromDouble(self->quat[1]);
-    case 'Y':
-               return PyFloat_FromDouble(self->quat[2]);
-    case 'Z':
-               return PyFloat_FromDouble(self->quat[3]);
-       }
-       
-       PyErr_SetString(PyExc_SystemError, "corrupt quaternion, cannot get axis");
-       return NULL;
+       return Quaternion_item(self, GET_INT_FROM_POINTER(type));
 }
 
 static int Quaternion_setAxis( QuaternionObject * self, PyObject * value, void * type )
 {
-       float param= (float)PyFloat_AsDouble( value );
-       
-       if (param==-1 && PyErr_Occurred()) {
-               PyErr_SetString( PyExc_TypeError, "expected a number for the vector axis" );
-               return -1;
-       }
-       switch( (long)type ) {
-    case 'W':
-               self->quat[0]= param;
-               break;
-    case 'X':
-               self->quat[1]= param;
-               break;
-    case 'Y':
-               self->quat[2]= param;
-               break;
-    case 'Z':
-               self->quat[3]= param;
-               break;
-       }
-
-       return 0;
-}
-
-static PyObject *Quaternion_getWrapped( QuaternionObject * self, void *type )
-{
-       if (self->wrapped == Py_WRAP)
-               Py_RETURN_TRUE;
-       else
-               Py_RETURN_FALSE;
+       return Quaternion_ass_item(self, GET_INT_FROM_POINTER(type), value);
 }
 
 static PyObject *Quaternion_getMagnitude( QuaternionObject * self, void *type )
 {
-       double mag = 0.0;
-       int i;
-       for(i = 0; i < 4; i++) {
-               mag += self->quat[i] * self->quat[i];
-       }
-       return PyFloat_FromDouble(sqrt(mag));
+       return PyFloat_FromDouble(sqrt(QuatDot(self->quat, self->quat)));
 }
 
 static PyObject *Quaternion_getAngle( QuaternionObject * self, void *type )
 {
        double ang = self->quat[0];
        ang = 2 * (saacos(ang));
+#ifdef USE_MATHUTILS_DEG
        ang *= (180 / Py_PI);
+#endif
        return PyFloat_FromDouble(ang);
 }
 
@@ -720,19 +703,19 @@ static PyGetSetDef Quaternion_getseters[] = {
        {"w",
         (getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
         "Quaternion W value",
-        (void *)'W'},
+        (void *)0},
        {"x",
         (getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
         "Quaternion X axis",
-        (void *)'X'},
+        (void *)1},
        {"y",
         (getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
         "Quaternion Y axis",
-        (void *)'Y'},
+        (void *)2},
        {"z",
         (getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
         "Quaternion Z axis",
-        (void *)'Z'},
+        (void *)3},
        {"magnitude",
         (getter)Quaternion_getMagnitude, (setter)NULL,
         "Size of the quaternion",
@@ -746,9 +729,14 @@ static PyGetSetDef Quaternion_getseters[] = {
         "quaternion axis as a vector",
         NULL},
        {"wrapped",
-        (getter)Quaternion_getWrapped, (setter)NULL,
+        (getter)BaseMathObject_getWrapped, (setter)NULL,
         "True when this wraps blenders internal data",
         NULL},
+       {"__owner__",
+        (getter)BaseMathObject_getOwner, (setter)NULL,
+        "Read only owner for vectors that depend on another object",
+        NULL},
+
        {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
 };
 
@@ -765,7 +753,7 @@ PyTypeObject quaternion_Type = {
        "quaternion",                                           //tp_name
        sizeof(QuaternionObject),                       //tp_basicsize
        0,                                                              //tp_itemsize
-       (destructor)Quaternion_dealloc,         //tp_dealloc
+       (destructor)BaseMathObject_dealloc,             //tp_dealloc
        0,                                                              //tp_print
        0,                                                              //tp_getattr
        0,                                                              //tp_setattr
@@ -817,26 +805,22 @@ PyTypeObject quaternion_Type = {
 PyObject *newQuaternionObject(float *quat, int type)
 {
        QuaternionObject *self;
-       int x;
        
        self = PyObject_NEW(QuaternionObject, &quaternion_Type);
-       self->data.blend_data = NULL;
-       self->data.py_data = NULL;
+
+       /* init callbacks as NULL */
+       self->cb_user= NULL;
+       self->cb_type= self->cb_subtype= 0;
 
        if(type == Py_WRAP){
-               self->data.blend_data = quat;
-               self->quat = self->data.blend_data;
+               self->quat = quat;
                self->wrapped = Py_WRAP;
        }else if (type == Py_NEW){
-               self->data.py_data = PyMem_Malloc(4 * sizeof(float));
-               self->quat = self->data.py_data;
+               self->quat = PyMem_Malloc(4 * sizeof(float));
                if(!quat) { //new empty
-                       Quaternion_Identity(self);
-                       Py_DECREF(self);
+                       QuatOne(self->quat);
                }else{
-                       for(x = 0; x < 4; x++){
-                               self->quat[x] = quat[x];
-                       }
+                       QUATCOPY(self->quat, quat);
                }
                self->wrapped = Py_NEW;
        }else{ //bad type
@@ -844,3 +828,16 @@ PyObject *newQuaternionObject(float *quat, int type)
        }
        return (PyObject *) self;
 }
+
+PyObject *newQuaternionObject_cb(PyObject *cb_user, int cb_type, int cb_subtype)
+{
+       QuaternionObject *self= (QuaternionObject *)newQuaternionObject(NULL, Py_NEW);
+       if(self) {
+               Py_INCREF(cb_user);
+               self->cb_user=                  cb_user;
+               self->cb_type=                  (unsigned char)cb_type;
+               self->cb_subtype=               (unsigned char)cb_subtype;
+       }
+
+       return (PyObject *)self;
+}
index ebbac26e39cb4034478587e2544b1165448694f0..2e74b5fa7f9d1c67ee19d281aa2a31b016431e0e 100644 (file)
@@ -38,14 +38,15 @@ extern PyTypeObject quaternion_Type;
 
 #define QuaternionObject_Check(v) (Py_TYPE(v) == &quaternion_Type)
 
-typedef struct {
+typedef struct { /* keep aligned with BaseMathObject in Mathutils.h */
        PyObject_VAR_HEAD 
-       struct{
-               float *py_data;         //python managed
-               float *blend_data;      //blender managed
-       }data;
-       float *quat;                            //1D array of data (alias)
-       int wrapped;                    //is wrapped data?
+       float *quat;                            /* 1D array of data (alias) */
+       PyObject *cb_user;                      /* if this vector references another object, otherwise NULL, *Note* this owns its reference */
+       unsigned char cb_type;          /* which user funcs do we adhere to, RNA, GameObject, etc */
+       unsigned char cb_subtype;       /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */
+       unsigned char wrapped;          /* wrapped data type? */
+       /* end BaseMathObject */
+
 } QuaternionObject;
 
 /*struct data contains a pointer to the actual data that the
@@ -55,5 +56,6 @@ blender (stored in blend_data). This is an either/or struct not both*/
 
 //prototypes
 PyObject *newQuaternionObject( float *quat, int type );
+PyObject *newQuaternionObject_cb(PyObject *cb_user, int cb_type, int cb_subtype);
 
 #endif                         /* EXPP_quat_h */
index dea5bc93898379d54d933a5f2a3cdb2c179e0b81..9ce0a7ca2f9ee329808f95fc7df11e15c7e1a739 100644 (file)
@@ -144,7 +144,7 @@ static PyObject *Vector_Zero(VectorObject * self)
                self->vec[i] = 0.0f;
        }
        
-       Vector_WriteCallback(self);
+       BaseMath_WriteCallback(self);
        Py_INCREF(self);
        return (PyObject*)self;
 }
@@ -155,7 +155,7 @@ static PyObject *Vector_Normalize(VectorObject * self)
        int i;
        float norm = 0.0f;
 
-       if(!Vector_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        for(i = 0; i < self->size; i++) {
@@ -166,7 +166,7 @@ static PyObject *Vector_Normalize(VectorObject * self)
                self->vec[i] /= norm;
        }
        
-       Vector_WriteCallback(self);
+       BaseMath_WriteCallback(self);
        Py_INCREF(self);
        return (PyObject*)self;
 }
@@ -266,7 +266,7 @@ static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
                return NULL;
        }
        
-       if(!Vector_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
 
        if (strack) {
@@ -385,7 +385,7 @@ static PyObject *Vector_Reflect( VectorObject * self, VectorObject * value )
                return NULL;
        }
        
-       if(!Vector_ReadCallback(self) || !Vector_ReadCallback(value))
+       if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
                return NULL;
        
        mirror[0] = value->vec[0];
@@ -431,7 +431,7 @@ static PyObject *Vector_Cross( VectorObject * self, VectorObject * value )
                return NULL;
        }
        
-       if(!Vector_ReadCallback(self) || !Vector_ReadCallback(value))
+       if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
                return NULL;
        
        vecCross = (VectorObject *)newVectorObject(NULL, 3, Py_NEW);
@@ -454,7 +454,7 @@ static PyObject *Vector_Dot( VectorObject * self, VectorObject * value )
                return NULL;
        }
        
-       if(!Vector_ReadCallback(self) || !Vector_ReadCallback(value))
+       if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
                return NULL;
        
        for(x = 0; x < self->size; x++) {
@@ -467,24 +467,12 @@ static PyObject *Vector_Dot( VectorObject * self, VectorObject * value )
   return a copy of the vector */
 static PyObject *Vector_copy(VectorObject * self)
 {
-       if(!Vector_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        return newVectorObject(self->vec, self->size, Py_NEW);
 }
 
-/*----------------------------dealloc()(internal) ----------------
-  free the py_object */
-static void Vector_dealloc(VectorObject * self)
-{
-       /* only free non wrapped */
-       if(self->wrapped != Py_WRAP)
-               PyMem_Free(self->vec);
-       
-       Py_XDECREF(self->cb_user);
-       PyObject_DEL(self);
-}
-
 /*----------------------------print object (internal)-------------
   print the object to screen */
 static PyObject *Vector_repr(VectorObject * self)
@@ -492,7 +480,7 @@ static PyObject *Vector_repr(VectorObject * self)
        int i;
        char buffer[48], str[1024];
 
-       if(!Vector_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        BLI_strncpy(str,"[",1024);
@@ -520,12 +508,14 @@ static int Vector_len(VectorObject * self)
   sequence accessor (get)*/
 static PyObject *Vector_item(VectorObject * self, int i)
 {
+       if(i<0) i= self->size-i;
+
        if(i < 0 || i >= self->size) {
                PyErr_SetString(PyExc_IndexError,"vector[index]: out of range\n");
                return NULL;
        }
 
-       if(!Vector_ReadIndexCallback(self, i))
+       if(!BaseMath_ReadIndexCallback(self, i))
                return NULL;
        
        return PyFloat_FromDouble(self->vec[i]);
@@ -541,13 +531,15 @@ static int Vector_ass_item(VectorObject * self, int i, PyObject * ob)
                return -1;
        }
 
+       if(i<0) i= self->size-i;
+
        if(i < 0 || i >= self->size){
                PyErr_SetString(PyExc_IndexError, "vector[index] = x: assignment index out of range\n");
                return -1;
        }
        self->vec[i] = scalar;
        
-       if(!Vector_WriteIndexCallback(self, i))
+       if(!BaseMath_WriteIndexCallback(self, i))
                return -1;
        return 0;
 }
@@ -559,7 +551,7 @@ static PyObject *Vector_slice(VectorObject * self, int begin, int end)
        PyObject *list = NULL;
        int count;
 
-       if(!Vector_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        CLAMP(begin, 0, self->size);
@@ -584,7 +576,7 @@ static int Vector_ass_slice(VectorObject * self, int begin, int end,
        float vec[4], scalar;
        PyObject *v;
 
-       if(!Vector_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return -1;
        
        CLAMP(begin, 0, self->size);
@@ -620,7 +612,7 @@ static int Vector_ass_slice(VectorObject * self, int begin, int end,
                self->vec[begin + y] = vec[y];
        }
        
-       if(!Vector_WriteCallback(self))
+       if(!BaseMath_WriteCallback(self))
                return -1;
        
        return 0;
@@ -644,7 +636,7 @@ static PyObject *Vector_add(PyObject * v1, PyObject * v2)
        /* make sure v1 is always the vector */
        if (vec1 && vec2 ) {
                
-               if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
+               if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
                        return NULL;
                
                /*VECTOR + VECTOR*/
@@ -679,7 +671,7 @@ static PyObject *Vector_iadd(PyObject * v1, PyObject * v2)
        /* make sure v1 is always the vector */
        if (vec1 && vec2 ) {
                
-               if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
+               if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
                        return NULL;
                
                /*VECTOR + VECTOR*/
@@ -694,7 +686,7 @@ static PyObject *Vector_iadd(PyObject * v1, PyObject * v2)
                return v1;
        }
        
-       Vector_WriteCallback(vec1);
+       BaseMath_WriteCallback(vec1);
        PyErr_SetString(PyExc_AttributeError, "Vector addition: arguments not valid for this operation....\n");
        return NULL;
 }
@@ -714,7 +706,7 @@ static PyObject *Vector_sub(PyObject * v1, PyObject * v2)
        vec1 = (VectorObject*)v1;
        vec2 = (VectorObject*)v2;
        
-       if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
+       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
                return NULL;
        
        if(vec1->size != vec2->size) {
@@ -747,14 +739,14 @@ static PyObject *Vector_isub(PyObject * v1, PyObject * v2)
                return NULL;
        }
        
-       if(!Vector_ReadCallback(vec1) || !Vector_ReadCallback(vec2))
+       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
                return NULL;
 
        for(i = 0; i < vec1->size; i++) {
                vec1->vec[i] = vec1->vec[i] -   vec2->vec[i];
        }
 
-       Vector_WriteCallback(vec1);
+       BaseMath_WriteCallback(vec1);
        Py_INCREF( v1 );
        return v1;
 }
@@ -768,12 +760,12 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
        
        if VectorObject_Check(v1) {
                vec1= (VectorObject *)v1;
-               if(!Vector_ReadCallback(vec1))
+               if(!BaseMath_ReadCallback(vec1))
                        return NULL;
        }
        if VectorObject_Check(v2) {
                vec2= (VectorObject *)v2;
-               if(!Vector_ReadCallback(vec2))
+               if(!BaseMath_ReadCallback(vec2))
                        return NULL;
        }
        
@@ -805,7 +797,8 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
                /* VEC * MATRIX */
                return row_vector_multiplication(vec1, (MatrixObject*)v2);
        } else if (QuaternionObject_Check(v2)) {
-               QuaternionObject *quat = (QuaternionObject*)v2;
+               QuaternionObject *quat = (QuaternionObject*)v2; /* quat_rotation validates */
+
                if(vec1->size != 3) {
                        PyErr_SetString(PyExc_TypeError, "Vector multiplication: only 3D vector rotations (with quats) currently supported\n");
                        return NULL;
@@ -835,7 +828,7 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2)
        int i;
        float scalar;
        
-       if(!Vector_ReadCallback(vec))
+       if(!BaseMath_ReadCallback(vec))
                return NULL;
        
        /* only support vec*=float and vec*=mat
@@ -845,7 +838,7 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2)
                int x,y, size = vec->size;
                MatrixObject *mat= (MatrixObject*)v2;
                
-               if(!Vector_ReadCallback(mat))
+               if(!BaseMath_ReadCallback(mat))
                        return NULL;
                
                if(mat->colSize != size){
@@ -883,7 +876,7 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2)
                return NULL;
        }
        
-       Vector_WriteCallback(vec);
+       BaseMath_WriteCallback(vec);
        Py_INCREF( v1 );
        return v1;
 }
@@ -902,7 +895,7 @@ static PyObject *Vector_div(PyObject * v1, PyObject * v2)
        }
        vec1 = (VectorObject*)v1; /* vector */
        
-       if(!Vector_ReadCallback(vec1))
+       if(!BaseMath_ReadCallback(vec1))
                return NULL;
        
        scalar = (float)PyFloat_AsDouble(v2);
@@ -930,7 +923,7 @@ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2)
        float scalar;
        VectorObject *vec1 = (VectorObject*)v1;
        
-       if(!Vector_ReadCallback(vec1))
+       if(!BaseMath_ReadCallback(vec1))
                return NULL;
 
        scalar = (float)PyFloat_AsDouble(v2);
@@ -947,7 +940,7 @@ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2)
                vec1->vec[i] /= scalar;
        }
        
-       Vector_WriteCallback(vec1);
+       BaseMath_WriteCallback(vec1);
        
        Py_INCREF( v1 );
        return v1;
@@ -960,7 +953,7 @@ static PyObject *Vector_neg(VectorObject *self)
        int i;
        float vec[4];
        
-       if(!Vector_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        for(i = 0; i < self->size; i++){
@@ -1008,7 +1001,7 @@ static PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa
        vecA = (VectorObject*)objectA;
        vecB = (VectorObject*)objectB;
 
-       if(!Vector_ReadCallback(vecA) || !Vector_ReadCallback(vecB))
+       if(!BaseMath_ReadCallback(vecA) || !BaseMath_ReadCallback(vecB))
                return NULL;
        
        if (vecA->size != vecB->size){
@@ -1137,12 +1130,12 @@ static PyNumberMethods Vector_NumMethods = {
        
 static PyObject *Vector_getAxis( VectorObject * self, void *type )
 {
-       return Vector_item(self, (int)type);
+       return Vector_item(self, GET_INT_FROM_POINTER(type));
 }
 
 static int Vector_setAxis( VectorObject * self, PyObject * value, void * type )
 {
-       return Vector_ass_item(self, (int)type, value);
+       return Vector_ass_item(self, GET_INT_FROM_POINTER(type), value);
 }
 
 /* vector.length */
@@ -1151,7 +1144,7 @@ static PyObject *Vector_getLength( VectorObject * self, void *type )
        double dot = 0.0f;
        int i;
        
-       if(!Vector_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        for(i = 0; i < self->size; i++){
@@ -1165,7 +1158,7 @@ static int Vector_setLength( VectorObject * self, PyObject * value )
        double dot = 0.0f, param;
        int i;
        
-       if(!Vector_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return -1;
        
        param= PyFloat_AsDouble( value );
@@ -1203,30 +1196,11 @@ static int Vector_setLength( VectorObject * self, PyObject * value )
                self->vec[i]= self->vec[i] / (float)dot;
        }
        
-       Vector_WriteCallback(self); /* checked alredy */
+       BaseMath_WriteCallback(self); /* checked alredy */
        
        return 0;
 }
 
-static PyObject *Vector_getWrapped( VectorObject * self, void *type )
-{
-       if (self->wrapped == Py_WRAP)
-               Py_RETURN_TRUE;
-       else
-               Py_RETURN_FALSE;
-}
-
-static PyObject *Vector_getOwner( VectorObject * self, void *type )
-{
-       if(self->cb_user==NULL) {
-               Py_RETURN_NONE;
-       }
-       else {
-               Py_INCREF(self->cb_user);
-               return self->cb_user;
-       }
-}
-
 /* Get a new Vector according to the provided swizzle. This function has little
    error checking, as we are in control of the inputs: the closure is set by us
    in Vector_createSwizzleGetSeter. */
@@ -1237,7 +1211,7 @@ static PyObject *Vector_getSwizzle(VectorObject * self, void *closure)
        float vec[MAX_DIMENSIONS];
        unsigned int swizzleClosure;
        
-       if(!Vector_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        /* Unpack the axes from the closure into an array. */
@@ -1277,7 +1251,7 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur
        
        float vecTemp[MAX_DIMENSIONS];
        
-       if(!Vector_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return -1;
        
        /* Check that the closure can be used with this vector: even 2D vectors have
@@ -1309,7 +1283,7 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur
                        axisB++;
                }
                memcpy(self->vec, vecTemp, axisB * sizeof(float));
-               /* continue with Vector_WriteCallback at the end */
+               /* continue with BaseMathObject_WriteCallback at the end */
        }
        else if (PyList_Check(value))
        {
@@ -1335,7 +1309,7 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur
                        axisB++;
                }
                memcpy(self->vec, vecTemp, axisB * sizeof(float));
-               /* continue with Vector_WriteCallback at the end */
+               /* continue with BaseMathObject_WriteCallback at the end */
        }
        else if (((scalarVal = (float)PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred())==0)
        {
@@ -1348,14 +1322,14 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur
                        
                        swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
                }
-               /* continue with Vector_WriteCallback at the end */
+               /* continue with BaseMathObject_WriteCallback at the end */
        }
        else {
                PyErr_SetString( PyExc_TypeError, "Expected a Vector, list or scalar value." );
                return -1;
        }
        
-       if(!Vector_WriteCallback(vecVal))
+       if(!BaseMath_WriteCallback(vecVal))
                return -1;
        else
                return 0;
@@ -1390,11 +1364,11 @@ static PyGetSetDef Vector_getseters[] = {
         "Vector Length",
         NULL},
        {"wrapped",
-        (getter)Vector_getWrapped, (setter)NULL,
+        (getter)BaseMathObject_getWrapped, (setter)NULL,
         "True when this wraps blenders internal data",
         NULL},
        {"__owner__",
-        (getter)Vector_getOwner, (setter)NULL,
+        (getter)BaseMathObject_getOwner, (setter)NULL,
         "Read only owner for vectors that depend on another object",
         NULL},
        
@@ -1797,13 +1771,13 @@ PyTypeObject vector_Type = {
        0,                          /* ob_size */
 #endif
        /*  For printing, in format "<module>.<name>" */
-       "Blender Vector",             /* char *tp_name; */
+       "vector",             /* char *tp_name; */
        sizeof( VectorObject ),         /* int tp_basicsize; */
        0,                          /* tp_itemsize;  For allocation */
 
        /* Methods to implement standard operations */
 
-       ( destructor ) Vector_dealloc,/* destructor tp_dealloc; */
+       ( destructor ) BaseMathObject_dealloc,/* destructor tp_dealloc; */
        NULL,                       /* printfunc tp_print; */
        NULL,                       /* getattrfunc tp_getattr; */
        NULL,                       /* setattrfunc tp_setattr; */
@@ -1920,7 +1894,7 @@ PyObject *newVectorObject(float *vec, int size, int type)
 PyObject *newVectorObject_cb(PyObject *cb_user, int size, int cb_type, int cb_subtype)
 {
        float dummy[4] = {0.0, 0.0, 0.0, 0.0}; /* dummy init vector, callbacks will be used on access */
-       VectorObject *self= newVectorObject(dummy, size, Py_NEW);
+       VectorObject *self= (VectorObject *)newVectorObject(dummy, size, Py_NEW);
        if(self) {
                Py_INCREF(cb_user);
                self->cb_user=                  cb_user;
@@ -1928,7 +1902,7 @@ PyObject *newVectorObject_cb(PyObject *cb_user, int size, int cb_type, int cb_su
                self->cb_subtype=               (unsigned char)cb_subtype;
        }
        
-       return self;
+       return (PyObject *)self;
 }
 
 //-----------------row_vector_multiplication (internal)-----------
@@ -1952,7 +1926,7 @@ static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat
                }
        }
        
-       if(!Vector_ReadCallback(vec) || !Matrix_ReadCallback(mat))
+       if(!BaseMath_ReadCallback(vec) || !BaseMath_ReadCallback(mat))
                return NULL;
        
        for(x = 0; x < vec_size; x++){
@@ -1975,13 +1949,13 @@ static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat
 static PyObject *Vector_Negate(VectorObject * self)
 {
        int i;
-       if(!Vector_ReadCallback(self))
+       if(!BaseMath_ReadCallback(self))
                return NULL;
        
        for(i = 0; i < self->size; i++)
                self->vec[i] = -(self->vec[i]);
        
-       Vector_WriteCallback(self); // alredy checked for error
+       BaseMath_WriteCallback(self); // alredy checked for error
        
        Py_INCREF(self);
        return (PyObject*)self;
index 82dbf13b9aa222b580f21a311caeae5ae92812aa..f519b2808cbf94e8af540aa2fcec11a5f05abbcd 100644 (file)
@@ -37,15 +37,16 @@ extern PyTypeObject vector_Type;
 
 #define VectorObject_Check(v) (((PyObject *)v)->ob_type == &vector_Type)
 
-typedef struct {
+typedef struct { /* keep aligned with BaseMathObject in Mathutils.h */
        PyObject_VAR_HEAD 
        float *vec;                                     /*1D array of data (alias), wrapped status depends on wrapped status */
        PyObject *cb_user;                                      /* if this vector references another object, otherwise NULL, *Note* this owns its reference */
-       unsigned char size;                     /* vec size 2,3 or 4 */
-       unsigned char wrapped;          /* wrapped data type? */
        unsigned char cb_type;  /* which user funcs do we adhere to, RNA, GameObject, etc */
        unsigned char cb_subtype;               /* subtype: location, rotation... to avoid defining many new functions for every attribute of the same type */
-       
+       unsigned char wrapped;          /* wrapped data type? */
+       /* end BaseMathObject */
+
+       unsigned char size;                     /* vec size 2,3 or 4 */
 } VectorObject;
 
 /*prototypes*/
index 542de6bd9b84f4f653d83b48a655c331e6d7eac3..b7e3c86dd91bef8394fd9ee11f43e465d27e3f33 100644 (file)
@@ -107,15 +107,9 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
                
                /* Assign instance attributes from operator properties */
                {
-                       PropertyRNA *prop, *iterprop;
-                       CollectionPropertyIterator iter;
                        const char *arg_name;
 
-                       iterprop= RNA_struct_iterator_property(op->ptr->type);
-                       RNA_property_collection_begin(op->ptr, iterprop, &iter);
-
-                       for(; iter.valid; RNA_property_collection_next(&iter)) {
-                               prop= iter.ptr.data;
+                       RNA_STRUCT_BEGIN(op->ptr, prop) {
                                arg_name= RNA_property_identifier(prop);
 
                                if (strcmp(arg_name, "rna_type")==0) continue;
@@ -124,8 +118,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
                                PyObject_SetAttrString(py_class_instance, arg_name, item);
                                Py_DECREF(item);
                        }
-
-                       RNA_property_collection_end(&iter);
+                       RNA_STRUCT_END;
                }
 
                /* set operator pointer RNA as instance "__operator__" attribute */
index e91b96d6f26c92075aed55a86b6c7b0e1014f724..0b8a7df1ae128a3f2c17b1787cc27b975236c036 100644 (file)
@@ -44,8 +44,8 @@
 #ifdef USE_MATHUTILS
 #include "../generic/Mathutils.h" /* so we can have mathutils callbacks */
 
-/* bpyrna vector callbacks */
-static int mathutils_rna_vector_cb_index= -1; /* index for our callbacks */
+/* bpyrna vector/euler/quat callbacks */
+static int mathutils_rna_array_cb_index= -1; /* index for our callbacks */
 
 static int mathutils_rna_generic_check(BPy_PropertyRNA *self)
 {
@@ -88,7 +88,7 @@ static int mathutils_rna_vector_set_index(BPy_PropertyRNA *self, int subtype, fl
        return 1;
 }
 
-Mathutils_Callback mathutils_rna_vector_cb = {
+Mathutils_Callback mathutils_rna_array_cb = {
        mathutils_rna_generic_check,
        mathutils_rna_vector_get,
        mathutils_rna_vector_set,
@@ -161,14 +161,15 @@ static PyObject *pyrna_prop_richcmp(BPy_PropertyRNA * a, BPy_PropertyRNA * b, in
 /*----------------------repr--------------------------------------------*/
 static PyObject *pyrna_struct_repr( BPy_StructRNA * self )
 {
-       PropertyRNA *prop;
-       char str[512];
+       PyObject *pyob;
+       char *name;
 
        /* print name if available */
-       prop= RNA_struct_name_property(self->ptr.type);
-       if(prop) {
-               RNA_property_string_get(&self->ptr, prop, str);
-               return PyUnicode_FromFormat( "[BPy_StructRNA \"%s\" -> \"%s\"]", RNA_struct_identifier(self->ptr.type), str);
+       name= RNA_struct_name_get_alloc(&self->ptr, NULL, 0);
+       if(name) {
+               pyob= PyUnicode_FromFormat( "[BPy_StructRNA \"%s\" -> \"%s\"]", RNA_struct_identifier(self->ptr.type), name);
+               MEM_freeN(name);
+               return pyob;
        }
 
        return PyUnicode_FromFormat( "[BPy_StructRNA \"%s\"]", RNA_struct_identifier(self->ptr.type));
@@ -176,20 +177,19 @@ static PyObject *pyrna_struct_repr( BPy_StructRNA * self )
 
 static PyObject *pyrna_prop_repr( BPy_PropertyRNA * self )
 {
-       PropertyRNA *prop;
+       PyObject *pyob;
        PointerRNA ptr;
-       char str[512];
+       char *name;
 
        /* if a pointer, try to print name of pointer target too */
        if(RNA_property_type(self->prop) == PROP_POINTER) {
                ptr= RNA_property_pointer_get(&self->ptr, self->prop);
+               name= RNA_struct_name_get_alloc(&ptr, NULL, 0);
 
-               if(ptr.data) {
-                       prop= RNA_struct_name_property(ptr.type);
-                       if(prop) {
-                               RNA_property_string_get(&ptr, prop, str);
-                               return PyUnicode_FromFormat( "[BPy_PropertyRNA \"%s\" -> \"%s\" -> \"%s\" ]", RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop), str);
-                       }
+               if(name) {
+                       pyob= PyUnicode_FromFormat( "[BPy_PropertyRNA \"%s\" -> \"%s\" -> \"%s\" ]", RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop), name);
+                       MEM_freeN(name);
+                       return pyob;
                }
        }
 
@@ -218,7 +218,6 @@ static void pyrna_struct_dealloc( BPy_StructRNA * self )
 static char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
 {
        const EnumPropertyItem *item;
-       int totitem;
        
        RNA_property_enum_items(ptr, prop, &item, NULL);
        return (char*)BPy_enum_as_string((EnumPropertyItem*)item);
@@ -235,26 +234,41 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
                PyObject *ret = pyrna_prop_CreatePyObject(ptr, prop);
                
 #ifdef USE_MATHUTILS
+
                /* return a mathutils vector where possible */
                if(RNA_property_type(prop)==PROP_FLOAT) {
-                       if(RNA_property_subtype(prop)==PROP_VECTOR) {
+                       switch(RNA_property_subtype(prop)) {
+                       case PROP_VECTOR:
                                if(len>=2 && len <= 4) {
-                                       PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_vector_cb_index, 0);
+                                       PyObject *vec_cb= newVectorObject_cb(ret, len, mathutils_rna_array_cb_index, 0);
                                        Py_DECREF(ret); /* the vector owns now */
                                        ret= vec_cb; /* return the vector instead */
                                }
-                       }
-                       else if(RNA_property_subtype(prop)==PROP_MATRIX) {
+                               break;
+                       case PROP_MATRIX:
                                if(len==16) {
-                                       PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_vector_cb_index, 0);
+                                       PyObject *mat_cb= newMatrixObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, 0);
                                        Py_DECREF(ret); /* the matrix owns now */
                                        ret= mat_cb; /* return the matrix instead */
                                }
                                else if (len==9) {
-                                       PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_vector_cb_index, 0);
+                                       PyObject *mat_cb= newMatrixObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, 0);
                                        Py_DECREF(ret); /* the matrix owns now */
                                        ret= mat_cb; /* return the matrix instead */
                                }
+                               break;
+                       case PROP_ROTATION:
+                               if(len==3) { /* euler */
+                             &n