merge with 2.5 at r18865
authorJoseph Eagar <joeedh@gmail.com>
Sun, 8 Feb 2009 14:25:04 +0000 (14:25 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Sun, 8 Feb 2009 14:25:04 +0000 (14:25 +0000)
127 files changed:
CMakeLists.txt
projectfiles_vc9/blender/editors/ED_editors.vcproj
projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj
projectfiles_vc9/blender/makesrna/RNA_rna.vcproj
source/Makefile
source/blender/blenkernel/BKE_context.h
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/BKE_utildefines.h
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/brush.c
source/blender/blenkernel/intern/context.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/ipo.c
source/blender/blenkernel/intern/multires.c
source/blender/blenkernel/intern/node.c
source/blender/blenloader/intern/readfile.c
source/blender/bmesh/bmesh_operators.h
source/blender/bmesh/intern/bmesh_opdefines.c
source/blender/bmesh/operators/subdivideop.c
source/blender/editors/Makefile
source/blender/editors/SConscript
source/blender/editors/animation/anim_deps.c
source/blender/editors/armature/armature_intern.h
source/blender/editors/armature/armature_ops.c
source/blender/editors/armature/editarmature.c
source/blender/editors/armature/poseobject.c
source/blender/editors/curve/editcurve.c
source/blender/editors/include/BIF_transform.h
source/blender/editors/include/ED_anim_api.h
source/blender/editors/include/ED_armature.h
source/blender/editors/include/ED_image.h
source/blender/editors/include/ED_mesh.h
source/blender/editors/include/ED_screen.h
source/blender/editors/include/ED_util.h
source/blender/editors/include/UI_interface.h
source/blender/editors/include/UI_resources.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_regions.c
source/blender/editors/interface/interface_utils.c [new file with mode: 0644]
source/blender/editors/interface/view2d_ops.c
source/blender/editors/mesh/editmesh_lib.c
source/blender/editors/mesh/editmesh_loop.c
source/blender/editors/mesh/editmesh_mods.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/mesh/mesh_intern.h
source/blender/editors/mesh/mesh_ops.c
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_intern.h
source/blender/editors/object/object_ops.c
source/blender/editors/screen/Makefile
source/blender/editors/screen/SConscript
source/blender/editors/screen/area.c
source/blender/editors/screen/screen_edit.c
source/blender/editors/screen/screen_intern.h
source/blender/editors/screen/screen_ops.c
source/blender/editors/sculpt/sculpt.c
source/blender/editors/space_action/action_edit.c
source/blender/editors/space_action/action_header.c
source/blender/editors/space_action/space_action.c
source/blender/editors/space_api/spacetypes.c
source/blender/editors/space_file/file_draw.c
source/blender/editors/space_graph/Makefile [moved from source/blender/editors/space_ipo/Makefile with 98% similarity]
source/blender/editors/space_graph/SConscript [moved from source/blender/editors/space_ipo/SConscript with 69% similarity]
source/blender/editors/space_graph/graph_draw.c [moved from source/blender/editors/space_ipo/ipo_draw.c with 99% similarity]
source/blender/editors/space_graph/graph_edit.c [moved from source/blender/editors/space_ipo/ipo_edit.c with 99% similarity]
source/blender/editors/space_graph/graph_header.c [moved from source/blender/editors/space_ipo/ipo_header.c with 99% similarity]
source/blender/editors/space_graph/graph_intern.h [moved from source/blender/editors/space_ipo/ipo_intern.h with 100% similarity]
source/blender/editors/space_graph/graph_ops.c [moved from source/blender/editors/space_ipo/ipo_ops.c with 99% similarity]
source/blender/editors/space_graph/graph_select.c [moved from source/blender/editors/space_ipo/ipo_select.c with 99% similarity]
source/blender/editors/space_graph/space_graph.c [moved from source/blender/editors/space_ipo/space_ipo.c with 99% similarity]
source/blender/editors/space_image/image_draw.c
source/blender/editors/space_image/image_header.c
source/blender/editors/space_image/image_render.c
source/blender/editors/space_image/space_image.c
source/blender/editors/space_info/info_header.c
source/blender/editors/space_info/space_info.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/node_draw.c
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_node/node_header.c
source/blender/editors/space_node/node_intern.h
source/blender/editors/space_node/node_ops.c
source/blender/editors/space_node/node_select.c
source/blender/editors/space_node/node_state.c
source/blender/editors/space_outliner/outliner.c
source/blender/editors/space_outliner/outliner_intern.h
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_header.c
source/blender/editors/space_view3d/view3d_ops.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_ops.c
source/blender/editors/transform/transform_orientations.c
source/blender/editors/util/undo.c
source/blender/editors/uvedit/uvedit_intern.h
source/blender/editors/uvedit/uvedit_ops.c
source/blender/editors/uvedit/uvedit_unwrap_ops.c
source/blender/makesdna/DNA_action_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/intern/CMakeLists.txt
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_action.c
source/blender/makesrna/intern/rna_armature.c
source/blender/makesrna/intern/rna_mesh.c
source/blender/makesrna/intern/rna_modifier.c
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_scene.c
source/blender/nodes/intern/CMP_nodes/CMP_composite.c
source/blender/render/extern/include/RE_pipeline.h
source/blender/render/intern/include/render_types.h
source/blender/render/intern/source/envmap.c
source/blender/render/intern/source/pipeline.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm.c
source/blender/windowmanager/intern/wm_draw.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_files.c
source/blender/windowmanager/intern/wm_gesture.c
source/blender/windowmanager/intern/wm_init_exit.c
source/blender/windowmanager/intern/wm_operators.c
source/blender/windowmanager/intern/wm_window.c

index 50cd07820f998d04d4613f7ae2fd8a7db60b38c8..be2c9b6b950c73894f2f5c17afbb409a38df5b56 100644 (file)
@@ -198,7 +198,7 @@ IF(UNIX)
   SET(PLATFORM_LINKFLAGS "-pthread")
 
   # Better warnings
-  SET(C_WARNINGS "-Wall -Wno-char-subscripts -Wpointer-arith -Wcast-align -Waggregate-return -Wnested-externs -Wdeclaration-after-statement")
+  SET(C_WARNINGS "-Wall -Wno-char-subscripts -Wpointer-arith -Wcast-align -Wnested-externs -Wdeclaration-after-statement")
 
   INCLUDE_DIRECTORIES(/usr/include /usr/local/include)
 ENDIF(UNIX)
index 9336ec7750fb0815eb2afcb8ad166786a7e1265f..2f7009432203c6120550ccdcb43f57e68c8191bd 100644 (file)
                                RelativePath="..\..\..\source\blender\editors\interface\interface_regions.c"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\..\source\blender\editors\interface\interface_utils.c"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\..\source\blender\editors\interface\keyval.c"\r
                                >\r
                        </File>\r
                </Filter>\r
                <Filter\r
-                       Name="space_ipo"\r
+                       Name="space_graph"\r
                        >\r
                        <File\r
-                               RelativePath="..\..\..\source\blender\editors\space_ipo\ipo_draw.c"\r
+                               RelativePath="..\..\..\source\blender\editors\space_graph\graph_draw.c"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\..\..\source\blender\editors\space_ipo\ipo_edit.c"\r
+                               RelativePath="..\..\..\source\blender\editors\space_graph\graph_edit.c"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\..\..\source\blender\editors\space_ipo\ipo_header.c"\r
+                               RelativePath="..\..\..\source\blender\editors\space_graph\graph_header.c"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\..\..\source\blender\editors\space_ipo\ipo_intern.h"\r
+                               RelativePath="..\..\..\source\blender\editors\space_graph\graph_intern.h"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\..\..\source\blender\editors\space_ipo\ipo_ops.c"\r
+                               RelativePath="..\..\..\source\blender\editors\space_graph\graph_ops.c"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\..\..\source\blender\editors\space_ipo\ipo_select.c"\r
+                               RelativePath="..\..\..\source\blender\editors\space_graph\graph_select.c"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\..\..\source\blender\editors\space_ipo\space_ipo.c"\r
+                               RelativePath="..\..\..\source\blender\editors\space_graph\space_graph.c"\r
                                >\r
                        </File>\r
                </Filter>\r
                                RelativePath="..\..\..\source\blender\editors\armature\armature_intern.h"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\..\source\blender\editors\armature\armature_ops.c"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\..\source\blender\editors\armature\editarmature.c"\r
                                >\r
index 6be2a254a447546feed5a86342e45603ff4e8b19..1257207f7d446435a436c6bdc3481240e6e20285 100644 (file)
                                RelativePath="..\..\..\source\blender\makesrna\intern\rna_image.c"\r
                                >\r
                        </File>\r
-                       <File\r
-                               RelativePath="..\..\..\source\blender\makesrna\intern\rna_ipo.c"\r
-                               >\r
-                       </File>\r
                        <File\r
                                RelativePath="..\..\..\source\blender\makesrna\intern\rna_key.c"\r
                                >\r
index 39f915ffa617709848d9498fe33fb15e2e56fe62..5c3da3cead9e01c71352b0164513423cd12c1070 100644 (file)
                                RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_image_gen.c"\r
                                >\r
                        </File>\r
-                       <File\r
-                               RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_ipo_gen.c"\r
-                               >\r
-                       </File>\r
                        <File\r
                                RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_key_gen.c"\r
                                >\r
index fedf438d4cc4d71a7bbd37089a48da6ee6af2440..d9dd29143b540979448bde13158e5a591b23b47d 100644 (file)
@@ -232,8 +232,7 @@ PULIB += $(OCGDIR)/blender/ed_file/libed_file.a
 PULIB += $(OCGDIR)/blender/ed_info/libed_info.a
 PULIB += $(OCGDIR)/blender/ed_buttons/libed_buttons.a
 PULIB += $(OCGDIR)/blender/ed_node/libed_node.a
-PULIB += $(OCGDIR)/blender/ed_image/libed_image.a
-PULIB += $(OCGDIR)/blender/ed_ipo/libed_ipo.a
+PULIB += $(OCGDIR)/blender/ed_graph/libed_graph.a
 PULIB += $(OCGDIR)/blender/ed_outliner/libed_outliner.a
 PULIB += $(OCGDIR)/blender/ed_time/libed_time.a
 PULIB += $(OCGDIR)/blender/ed_preview/libed_preview.a
@@ -248,8 +247,9 @@ PULIB += $(OCGDIR)/blender/ed_physics/libed_physics.a
 PULIB += $(OCGDIR)/blender/ed_animation/libed_animation.a
 PULIB += $(OCGDIR)/blender/ed_transform/libed_transform.a
 PULIB += $(OCGDIR)/blender/ed_util/libed_util.a
-PULIB += $(OCGDIR)/blender/ed_uvedit/libed_uvedit.a
 PULIB += $(OCGDIR)/blender/ed_datafiles/libed_datafiles.a
+PULIB += $(OCGDIR)/blender/ed_image/libed_image.a
+PULIB += $(OCGDIR)/blender/ed_uvedit/libed_uvedit.a
 PULIB += $(OCGDIR)/blender/ed_screen/libed_screen.a
 PULIB += $(OCGDIR)/blender/windowmanager/libwindowmanager.a
 PULIB += $(OCGDIR)/blender/python/$(DEBUG_DIR)libpython.a
index c489aba33266a3c68e6d091534bc65da58e650db..5af97a7d8d5e9aff4f984951c3f95ee3a7097498 100644 (file)
@@ -51,6 +51,8 @@ struct StructRNA;
 struct ToolSettings;
 struct Image;
 struct ImBuf;
+struct EditBone;
+struct bPoseChannel;
 struct wmWindow;
 struct wmWindowManager;
 
@@ -81,7 +83,14 @@ enum {
        CTX_DATA_EDIT_IMAGE,
        CTX_DATA_EDIT_IMAGE_BUFFER,
 
-       CTX_DATA_SELECTED_NODES
+       CTX_DATA_SELECTED_NODES,
+       
+       CTX_DATA_SELECTED_BONES,
+       CTX_DATA_SELECTED_EDITABLE_BONES,
+       CTX_DATA_SELECTED_PCHANS,
+       
+       CTX_DATA_ACTIVE_BONE,
+       CTX_DATA_ACTIVE_PCHAN,
 };
 
 typedef int bContextDataMember;
@@ -185,6 +194,13 @@ struct ImBuf *CTX_data_edit_image_buffer(const bContext *C);
 
 int CTX_data_selected_nodes(const bContext *C, ListBase *list);
 
+struct EditBone *CTX_data_active_bone(const bContext *C);
+int CTX_data_selected_bones(const bContext *C, ListBase *list);
+int CTX_data_selected_editable_bones(const bContext *C, ListBase *list);
+
+struct bPoseChannel *CTX_data_active_pchan(const bContext *C);
+int CTX_data_selected_pchans(const bContext *C, ListBase *list);
+
 /* Data Evaluation Context */
 
 float CTX_eval_frame(const bContext *C);
index bf2da8925069664964b794fe8e7c48975eaa4a4e..7d0c5b83e6e9d44070ee6e864e0c7e65285e6c93 100644 (file)
@@ -52,9 +52,6 @@ struct GPUMaterial;
 struct GPUNode;
 struct GPUNodeStack;
 
-#define SOCK_IN                1
-#define SOCK_OUT       2
-
 /* ************** NODE TYPE DEFINITIONS ***** */
 
 typedef struct bNodeSocketType {
index 0eccf0cf56b2723836e3c6080476bd9a33aa846f..605858bef58c20755336266d8d217fc95e73e87f 100644 (file)
@@ -224,7 +224,7 @@ behaviour, though it may not be the best in practice.
 #define V_DECLARE(vec) int _##vec##_count=0; void *_##vec##_tmp
 
 /*this returns the entire size of the array, including any buffering.*/
-#define V_SIZE(vec) ((vec)==NULL ? 0 : MEM_allocN_len(vec) / sizeof(*vec))
+#define V_SIZE(vec) ((signed int)((vec)==NULL ? 0 : MEM_allocN_len(vec) / sizeof(*vec)))
 
 /*this returns the logical size of the array, not including buffering.*/
 #define V_COUNT(vec) _##vec##_count
index c05aad07fce9fb4fa4a6b4a4517c89c857bf4c11..72fd0259b89380e3f0cf4b3472357044ed918832 100644 (file)
@@ -511,7 +511,7 @@ static float get_actionstrip_frame(bActionStrip *strip, float cframe, int invert
        repeat = (strip->flag & ACTSTRIP_USESTRIDE) ? (1.0f) : (strip->repeat);
        
        if (strip->scale == 0.0f) strip->scale= 1.0f;
-       scale = fabs(strip->scale); /* scale must be positive (for now) */
+       scale = (float)fabs(strip->scale); /* scale must be positive (for now) */
        
        actlength = strip->actend-strip->actstart;
        if (actlength == 0.0f) actlength = 1.0f;
index c0882451f6ce2c5157ef31b4b22006d1b3adf83e..08a2b1dcecb482979eb344de41fea674736417fd 100644 (file)
@@ -242,10 +242,18 @@ void brush_curve_preset(Brush *b, BrushCurvePreset preset)
        if(cm->curve)
                MEM_freeN(cm->curve);
 
-       if(preset == BRUSH_PRESET_SHARP) {
-               cm->curve= MEM_callocN(3*sizeof(CurveMapPoint), "curve points");
-               cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
+       if(preset == BRUSH_PRESET_SHARP)
                cm->totpoint= 3;
+       if(preset == BRUSH_PRESET_SMOOTH)
+               cm->totpoint= 6;
+       if(preset == BRUSH_PRESET_MAX)
+               cm->totpoint= 2;
+
+
+       cm->curve= MEM_callocN(cm->totpoint*sizeof(CurveMapPoint), "curve points");
+       cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
+
+       if(preset == BRUSH_PRESET_SHARP) {
                cm->curve[0].x= 0;
                cm->curve[0].y= 1;
                cm->curve[1].x= 0.33;
@@ -254,10 +262,24 @@ void brush_curve_preset(Brush *b, BrushCurvePreset preset)
                cm->curve[2].y= 0;
        }
        else if(preset == BRUSH_PRESET_SMOOTH) {
-               // XXX: todo
+               cm->curve[0].x= 0;
+               cm->curve[0].y= 1;
+               cm->curve[1].x= 0.1;
+               cm->curve[1].y= 0.97553;
+               cm->curve[2].x= 0.3;
+               cm->curve[2].y= 0.79389;
+               cm->curve[3].x= 0.9;
+               cm->curve[3].y= 0.02447;
+               cm->curve[4].x= 0.7;
+               cm->curve[4].y= 0.20611;
+               cm->curve[5].x= 1;
+               cm->curve[5].y= 0;
        }
        else if(preset == BRUSH_PRESET_MAX) {
-               // XXX: todo
+               cm->curve[0].x= 0;
+               cm->curve[0].y= 1;
+               cm->curve[1].x= 1;
+               cm->curve[1].y= 1;
        }
 
        curvemapping_changed(b->curve, 0);
index ccdbea87d877d5d30138a0c8b0923337c069b446..714965102d4ea8c027b6f2a1394eb852dc0fe57b 100644 (file)
@@ -333,8 +333,11 @@ int ctx_data_list_count(const bContext *C, int (*func)(const bContext*, ListBase
 {
        ListBase list;
 
-       if(func(C, &list))
-               return BLI_countlist(&list);
+       if(func(C, &list)) {
+               int tot= BLI_countlist(&list);
+               BLI_freelistN(&list);
+               return tot;
+       }
        else
                return 0;
 }
@@ -441,6 +444,31 @@ struct ImBuf *CTX_data_edit_image_buffer(const bContext *C)
        return ctx_data_pointer_get(C, CTX_DATA_EDIT_IMAGE_BUFFER);
 }
 
+struct EditBone *CTX_data_active_bone(const bContext *C)
+{
+       return ctx_data_pointer_get(C, CTX_DATA_ACTIVE_BONE);
+}
+
+int CTX_data_selected_bones(const bContext *C, ListBase *list)
+{
+       return ctx_data_collection_get(C, CTX_DATA_SELECTED_BONES, list);
+}
+
+int CTX_data_selected_editable_bones(const bContext *C, ListBase *list)
+{
+       return ctx_data_collection_get(C, CTX_DATA_SELECTED_EDITABLE_BONES, list);
+}
+
+struct bPoseChannel *CTX_data_active_pchan(const bContext *C)
+{
+       return ctx_data_pointer_get(C, CTX_DATA_ACTIVE_PCHAN);
+}
+
+int CTX_data_selected_pchans(const bContext *C, ListBase *list)
+{
+       return ctx_data_collection_get(C, CTX_DATA_SELECTED_PCHANS, list);
+}
+
 /* data evaluation */
 
 float CTX_eval_frame(const bContext *C)
index ee631a8908388317eda64b97ffc66daa8b7df57d..f6d604bdec72c30424f4bf6baff312ec37ee9dd0 100644 (file)
@@ -1797,14 +1797,30 @@ static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser)
 
 /* showing RGBA result itself (from compo/sequence) or
    like exr, using layers etc */
+/* always returns a single ibuf, also during render progress */
 static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
 {
+       Render *re;
        RenderResult *rr= NULL;
        
-       if(iuser->scene)
-                rr= RE_GetResult(RE_GetRender(iuser->scene->id.name));
+       if(iuser->scene) {
+               re= RE_GetRender(iuser->scene->id.name);
+               rr= RE_GetResult(re);
+       }
+       if(rr==NULL) return NULL;
        
-       if(rr) {
+       if(RE_RenderInProgress(re)) {
+               ImBuf *ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
+               
+               /* make ibuf if needed, and initialize it */
+               /* this only gets called when mutex locked */
+               if(ibuf==NULL) {
+                       ibuf= IMB_allocImBuf(rr->rectx, rr->recty, 32, IB_rect, 0);
+                       image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
+               }
+               return ibuf;
+       }
+       else {
                RenderResult rres;
                float *rectf;
                unsigned int *rect;
index 20bed37e4bcad7f4b8117cb80aa40d95d52f3ac2..103e2f7edac03462859656b0374a88d20a6e238d 100644 (file)
@@ -151,39 +151,40 @@ static AdrBit2Path ob_layer_bits[]= {
        {(1<<20), "layer", 20}
 };
 
+/* Material mode */
+static AdrBit2Path ma_mode_bits[]= {
+//     {MA_TRACEBLE, "traceable", 0},
+//     {MA_SHADOW, "shadow", 0},
+//     {MA_SHLESS, "shadeless", 0},
+//     ...
+       {MA_RAYTRANSP, "raytrace_transparency.enabled", 0},
+       {MA_RAYMIRROR, "raytrace_mirror.enabled", 0},
+       {MA_HALO, "halo.enabled", 0}
+};
+
 /* ----------------- */
 
+/* quick macro for returning the appropriate array for adrcode_bitmaps_to_paths() */
+#define RET_ABP(items) \
+       { \
+               *tot= sizeof(items)/sizeof(AdrBit2Path); \
+               return items; \
+       }
+
 /* This function checks if a Blocktype+Adrcode combo, returning a mapping table */
 static AdrBit2Path *adrcode_bitmaps_to_paths (int blocktype, int adrcode, int *tot)
 {
        /* Object layers */
-       if ((blocktype == ID_OB) && (adrcode == OB_LAY)) {
-               *tot= sizeof(ob_layer_bits)/sizeof(AdrBit2Path);
-               return ob_layer_bits;
-       }
-       else if ((blocktype == ID_MA) && (adrcode == MA_MODE)) {
-               // XXX to be added...
-       }
+       if ((blocktype == ID_OB) && (adrcode == OB_LAY)) 
+               RET_ABP(ob_layer_bits)
+       else if ((blocktype == ID_MA) && (adrcode == MA_MODE))
+               RET_ABP(ma_mode_bits)
        // XXX TODO: add other types...
        
        /* Normal curve */
        return NULL;
 }
 
-/* This function makes a copy of a path stored in AdrBit2Path entry, and makes a guardedalloc copy */
-static char *adrcode_bitmap_path_copy (const char *abp_path)
-{
-       char *path;
-       int len;
-       
-       /* copy the path */
-       len= strlen(abp_path) + 1; // XXX is this safe?
-       path= MEM_callocN(len, "Bitflag IPO-Curve RNA-Path");
-       memcpy(path, abp_path, len);
-       
-       return path;
-}
-
 /* *************************************************** */
 /* ADRCODE to RNA-Path Conversion Code  - Standard */
 
@@ -351,6 +352,76 @@ static char *shapekey_adrcodes_to_paths (int adrcode, int *array_index)
        return buf;
 }
 
+/* MTex (Texture Slot) types */
+static char *mtex_adrcodes_to_paths (int adrcode, int *array_index)
+{
+       char *base=NULL, *prop=NULL;
+       static char buf[128];
+       
+       /* base part of path */
+       if (adrcode & MA_MAP1) base= "textures[0]";
+       else if (adrcode & MA_MAP2) base= "textures[1]";
+       else if (adrcode & MA_MAP3) base= "textures[2]";
+       else if (adrcode & MA_MAP4) base= "textures[3]";
+       else if (adrcode & MA_MAP5) base= "textures[4]";
+       else if (adrcode & MA_MAP6) base= "textures[5]";
+       else if (adrcode & MA_MAP7) base= "textures[6]";
+       else if (adrcode & MA_MAP8) base= "textures[7]";
+       else if (adrcode & MA_MAP9) base= "textures[8]";
+       else if (adrcode & MA_MAP10) base= "textures[9]";
+       else if (adrcode & MA_MAP11) base= "textures[10]";
+       else if (adrcode & MA_MAP12) base= "textures[11]";
+       else if (adrcode & MA_MAP13) base= "textures[12]";
+       else if (adrcode & MA_MAP14) base= "textures[13]";
+       else if (adrcode & MA_MAP15) base= "textures[14]";
+       else if (adrcode & MA_MAP16) base= "textures[15]";
+       else if (adrcode & MA_MAP17) base= "textures[16]";
+       else if (adrcode & MA_MAP18) base= "textures[17]";
+               
+       /* property identifier for path */
+       adrcode= (adrcode & (MA_MAP1-1));
+       switch (adrcode) {
+#if 0 // XXX these are not wrapped in RNA yet!
+               case MAP_OFS_X:
+                       poin= &(mtex->ofs[0]); break;
+               case MAP_OFS_Y:
+                       poin= &(mtex->ofs[1]); break;
+               case MAP_OFS_Z:
+                       poin= &(mtex->ofs[2]); break;
+               case MAP_SIZE_X:
+                       poin= &(mtex->size[0]); break;
+               case MAP_SIZE_Y:
+                       poin= &(mtex->size[1]); break;
+               case MAP_SIZE_Z:
+                       poin= &(mtex->size[2]); break;
+               case MAP_R:
+                       poin= &(mtex->r); break;
+               case MAP_G:
+                       poin= &(mtex->g); break;
+               case MAP_B:
+                       poin= &(mtex->b); break;
+               case MAP_DVAR:
+                       poin= &(mtex->def_var); break;
+               case MAP_COLF:
+                       poin= &(mtex->colfac); break;
+               case MAP_NORF:
+                       poin= &(mtex->norfac); break;
+               case MAP_VARF:
+                       poin= &(mtex->varfac); break;
+#endif
+               case MAP_DISP:
+                       prop= "warp_factor"; break;
+       }
+       
+       /* only build and return path if there's a property */
+       if (prop) {
+               BLI_snprintf(buf, 128, "%s.%s", base, prop);
+               return buf;
+       }
+       else
+               return NULL;
+}
+
 /* Texture types */
 static char *texture_adrcodes_to_paths (int adrcode, int *array_index)
 {
@@ -465,67 +536,54 @@ static char *material_adrcodes_to_paths (int adrcode, int *array_index)
                        
                case MA_REF:
                        return "diffuse_reflection";
+               
+               case MA_EMIT:
+                       return "emit";
+               
+               case MA_AMB:
+                       return "ambient";
+               
+               case MA_SPEC:
+                       return "specularity";
+               
+               case MA_HARD:
+                       return "specular_hardness";
                        
-               // XXX add other types...
-       }
-       
-       return NULL;
-       
-#if 0
-       case MA_EMIT:
-               poin= &(ma->emit); break;
-       case MA_AMB:
-               poin= &(ma->amb); break;
-       case MA_SPEC:
-               poin= &(ma->spec); break;
-       case MA_HARD:
-               poin= &(ma->har); *type= IPO_SHORT; break;
-       case MA_SPTR:
-               poin= &(ma->spectra); break;
-       case MA_IOR:
-               poin= &(ma->ang); break;
-       case MA_HASIZE:
-               poin= &(ma->hasize); break;
-       case MA_TRANSLU:
-               poin= &(ma->translucency); break;
-       case MA_RAYM:
-               poin= &(ma->ray_mirror); break;
-       case MA_FRESMIR:
-               poin= &(ma->fresnel_mir); break;
-       case MA_FRESMIRI:
-               poin= &(ma->fresnel_mir_i); break;
-       case MA_FRESTRA:
-               poin= &(ma->fresnel_tra); break;
-       case MA_FRESTRAI:
-               poin= &(ma->fresnel_tra_i); break;
-       case MA_ADD:
-               poin= &(ma->add); break;
-       
-       if (poin == NULL) {
-               if (icu->adrcode & MA_MAP1) mtex= ma->mtex[0];
-               else if (icu->adrcode & MA_MAP2) mtex= ma->mtex[1];
-               else if (icu->adrcode & MA_MAP3) mtex= ma->mtex[2];
-               else if (icu->adrcode & MA_MAP4) mtex= ma->mtex[3];
-               else if (icu->adrcode & MA_MAP5) mtex= ma->mtex[4];
-               else if (icu->adrcode & MA_MAP6) mtex= ma->mtex[5];
-               else if (icu->adrcode & MA_MAP7) mtex= ma->mtex[6];
-               else if (icu->adrcode & MA_MAP8) mtex= ma->mtex[7];
-               else if (icu->adrcode & MA_MAP9) mtex= ma->mtex[8];
-               else if (icu->adrcode & MA_MAP10) mtex= ma->mtex[9];
-               else if (icu->adrcode & MA_MAP12) mtex= ma->mtex[11];
-               else if (icu->adrcode & MA_MAP11) mtex= ma->mtex[10];
-               else if (icu->adrcode & MA_MAP13) mtex= ma->mtex[12];
-               else if (icu->adrcode & MA_MAP14) mtex= ma->mtex[13];
-               else if (icu->adrcode & MA_MAP15) mtex= ma->mtex[14];
-               else if (icu->adrcode & MA_MAP16) mtex= ma->mtex[15];
-               else if (icu->adrcode & MA_MAP17) mtex= ma->mtex[16];
-               else if (icu->adrcode & MA_MAP18) mtex= ma->mtex[17];
+               case MA_SPTR:
+                       return "specular_opacity";
+                       
+               case MA_IOR:
+                       return "ior";
+                       
+               case MA_HASIZE:
+                       return "halo.size";
+                       
+               case MA_TRANSLU:
+                       return "translucency";
+                       
+               case MA_RAYM:
+                       return "raytrace_mirror.reflect";
+                       
+               case MA_FRESMIR:
+                       return "raytrace_mirror.fresnel";
+                       
+               case MA_FRESMIRI:
+                       return "raytrace_mirror.fresnel_fac";
+                       
+               case MA_FRESTRA:
+                       return "raytrace_transparency.fresnel";
+                       
+               case MA_FRESTRAI:
+                       return "raytrace_transparency.fresnel_fac";
+                       
+               case MA_ADD:
+                       return "halo.add";
                
-               if (mtex)
-                       poin= give_mtex_poin(mtex, (icu->adrcode & (MA_MAP1-1)));
+               default: /* for now, we assume that the others were MTex channels */
+                       return mtex_adrcodes_to_paths(adrcode, array_index);
        }
-#endif
        
+       return NULL;    
 }
 
 /* Camera Types */
@@ -600,38 +658,91 @@ static char *lamp_adrcodes_to_paths (int adrcode, int *array_index)
                        
                case LA_HALOINT:
                        return "halo_intensity";
+                       
+               default: /* for now, we assume that the others were MTex channels */
+                       return mtex_adrcodes_to_paths(adrcode, array_index);
        }
        
-#if 0 // XXX to be converted
-               if (poin == NULL) {
-                       if (icu->adrcode & MA_MAP1) mtex= la->mtex[0];
-                       else if (icu->adrcode & MA_MAP2) mtex= la->mtex[1];
-                       else if (icu->adrcode & MA_MAP3) mtex= la->mtex[2];
-                       else if (icu->adrcode & MA_MAP4) mtex= la->mtex[3];
-                       else if (icu->adrcode & MA_MAP5) mtex= la->mtex[4];
-                       else if (icu->adrcode & MA_MAP6) mtex= la->mtex[5];
-                       else if (icu->adrcode & MA_MAP7) mtex= la->mtex[6];
-                       else if (icu->adrcode & MA_MAP8) mtex= la->mtex[7];
-                       else if (icu->adrcode & MA_MAP9) mtex= la->mtex[8];
-                       else if (icu->adrcode & MA_MAP10) mtex= la->mtex[9];
-                       else if (icu->adrcode & MA_MAP11) mtex= la->mtex[10];
-                       else if (icu->adrcode & MA_MAP12) mtex= la->mtex[11];
-                       else if (icu->adrcode & MA_MAP13) mtex= la->mtex[12];
-                       else if (icu->adrcode & MA_MAP14) mtex= la->mtex[13];
-                       else if (icu->adrcode & MA_MAP15) mtex= la->mtex[14];
-                       else if (icu->adrcode & MA_MAP16) mtex= la->mtex[15];
-                       else if (icu->adrcode & MA_MAP17) mtex= la->mtex[16];
-                       else if (icu->adrcode & MA_MAP18) mtex= la->mtex[17];
-                       
-                       if (mtex)
-                               poin= give_mtex_poin(mtex, (icu->adrcode & (MA_MAP1-1)));
-               }
-#endif // XXX to be converted
+       /* unrecognised adrcode, or not-yet-handled ones! */
+       return NULL;
+}
+
+/* Sound Types */
+static char *sound_adrcodes_to_paths (int adrcode, int *array_index)
+{
+       /* set array index like this in-case nothing sets it correctly  */
+       *array_index= 0;
+       
+       /* result depends on adrcode */
+       switch (adrcode) {
+               case SND_VOLUME:
+                       return "volume";
+               case SND_PITCH:
+                       return "pitch";
+       /* XXX Joshua -- I had wrapped panning in rna, but someone commented out, calling it "unused" */
+       /*      case SND_PANNING:
+                       return "panning"; */
+               case SND_ATTEN:
+                       return "attenuation";
+       }
        
        /* unrecognised adrcode, or not-yet-handled ones! */
        return NULL;
 }
 
+/* World Types */
+static char *world_adrcodes_to_paths (int adrcode, int *array_index)
+{
+       /* set array index like this in-case nothing sets it correctly  */
+       *array_index= 0;
+       
+       /* result depends on adrcode */
+       switch (adrcode) {
+               case WO_HOR_R:
+                       *array_index= 0; return "horizon_color";
+               case WO_HOR_G:
+                       *array_index= 1; return "horizon_color";
+               case WO_HOR_B:
+                       *array_index= 2; return "horizon_color";
+               case WO_ZEN_R:
+                       *array_index= 0; return "zenith_color";
+               case WO_ZEN_G:
+                       *array_index= 1; return "zenith_color";
+               case WO_ZEN_B:
+                       *array_index= 2; return "zenith_color";
+               
+               case WO_EXPOS:
+                       return "exposure";
+               
+               case WO_MISI:
+                       return "mist.intensity";
+               case WO_MISTDI:
+                       return "mist.depth";
+               case WO_MISTSTA:
+                       return "mist.start";
+               case WO_MISTHI:
+                       return "mist.height";
+               
+       /*      Star Color is unused -- recommend removal */
+       /*      case WO_STAR_R:
+                       *array_index= 0; return "stars.color";
+               case WO_STAR_G:
+                       *array_index= 1; return "stars.color";
+               case WO_STAR_B:
+                       *array_index= 2; return "stars.color"; */
+               
+               case WO_STARDIST:
+                       return "stars.min_distance";
+               case WO_STARSIZE:
+                       return "stars.size";
+               
+               default: /* for now, we assume that the others were MTex channels */
+                       return mtex_adrcodes_to_paths(adrcode, array_index);
+               }
+               
+       return NULL;    
+}
+
 /* ------- */
 
 /* Allocate memory for RNA-path for some property given a blocktype, adrcode, and 'root' parts of path
@@ -682,6 +793,12 @@ char *get_rna_access (int blocktype, int adrcode, char actname[], char constname
                case ID_LA: /* lamp */
                        propname= lamp_adrcodes_to_paths(adrcode, &dummy_index);
                        break;
+               
+               case ID_SO: /* sound */
+                       propname= sound_adrcodes_to_paths(adrcode, &dummy_index);
+               
+               case ID_WO: /* world */
+                       propname= world_adrcodes_to_paths(adrcode, &dummy_index);
                        
                /* XXX problematic blocktypes */
                case ID_CU: /* curve */
@@ -936,7 +1053,7 @@ static void icu_to_fcurves (ListBase *list, IpoCurve *icu, char *actname, char *
                                fcurve= fcu;
                                
                        /* set path */
-                       fcurve->rna_path= adrcode_bitmap_path_copy(abp->path);
+                       fcurve->rna_path= BLI_strdupn(abp->path, strlen(abp->path));
                        fcurve->array_index= abp->array_index;
                        
                        /* convert keyframes 
@@ -1490,45 +1607,6 @@ void do_versions_ipos_to_animato(Main *main)
 
 /* --------------------- Get Pointer API ----------------------------- */ 
 
-/* get texture-slot/mapping channel */
-void *give_mtex_poin (MTex *mtex, int adrcode)
-{
-       void *poin= NULL;
-       
-       switch (adrcode) {
-       case MAP_OFS_X:
-               poin= &(mtex->ofs[0]); break;
-       case MAP_OFS_Y:
-               poin= &(mtex->ofs[1]); break;
-       case MAP_OFS_Z:
-               poin= &(mtex->ofs[2]); break;
-       case MAP_SIZE_X:
-               poin= &(mtex->size[0]); break;
-       case MAP_SIZE_Y:
-               poin= &(mtex->size[1]); break;
-       case MAP_SIZE_Z:
-               poin= &(mtex->size[2]); break;
-       case MAP_R:
-               poin= &(mtex->r); break;
-       case MAP_G:
-               poin= &(mtex->g); break;
-       case MAP_B:
-               poin= &(mtex->b); break;
-       case MAP_DVAR:
-               poin= &(mtex->def_var); break;
-       case MAP_COLF:
-               poin= &(mtex->colfac); break;
-       case MAP_NORF:
-               poin= &(mtex->norfac); break;
-       case MAP_VARF:
-               poin= &(mtex->varfac); break;
-       case MAP_DISP:
-               poin= &(mtex->dispfac); break;
-       }
-       
-       /* return pointer */
-       return poin;
-}
 
 /* GS reads the memory pointed at in a specific ordering. There are,
  * however two definitions for it. I have jotted them down here, both,
@@ -1555,90 +1633,6 @@ void *get_ipo_poin (ID *id, IpoCurve *icu, int *type)
 
        /* data is divided into 'blocktypes' based on ID-codes */
        switch (GS(id->name)) {
-               case ID_WO: /* world channels -----------------------------  */
-               {
-                       World *wo= (World *)id;
-                       
-                       switch (icu->adrcode) {
-                       case WO_HOR_R:
-                               poin= &(wo->horr); break;
-                       case WO_HOR_G:
-                               poin= &(wo->horg); break;
-                       case WO_HOR_B:
-                               poin= &(wo->horb); break;
-                       case WO_ZEN_R:
-                               poin= &(wo->zenr); break;
-                       case WO_ZEN_G:
-                               poin= &(wo->zeng); break;
-                       case WO_ZEN_B:
-                               poin= &(wo->zenb); break;
-                       
-                       case WO_EXPOS:
-                               poin= &(wo->exposure); break;
-                       
-                       case WO_MISI:
-                               poin= &(wo->misi); break;
-                       case WO_MISTDI:
-                               poin= &(wo->mistdist); break;
-                       case WO_MISTSTA:
-                               poin= &(wo->miststa); break;
-                       case WO_MISTHI:
-                               poin= &(wo->misthi); break;
-                       
-                       case WO_STAR_R:
-                               poin= &(wo->starr); break;
-                       case WO_STAR_G:
-                               poin= &(wo->starg); break;
-                       case WO_STAR_B:
-                               poin= &(wo->starb); break;
-                       
-                       case WO_STARDIST:
-                               poin= &(wo->stardist); break;
-                       case WO_STARSIZE:
-                               poin= &(wo->starsize); break;
-                       }
-                       
-                       if (poin == NULL) {
-                               if (icu->adrcode & MA_MAP1) mtex= wo->mtex[0];
-                               else if (icu->adrcode & MA_MAP2) mtex= wo->mtex[1];
-                               else if (icu->adrcode & MA_MAP3) mtex= wo->mtex[2];
-                               else if (icu->adrcode & MA_MAP4) mtex= wo->mtex[3];
-                               else if (icu->adrcode & MA_MAP5) mtex= wo->mtex[4];
-                               else if (icu->adrcode & MA_MAP6) mtex= wo->mtex[5];
-                               else if (icu->adrcode & MA_MAP7) mtex= wo->mtex[6];
-                               else if (icu->adrcode & MA_MAP8) mtex= wo->mtex[7];
-                               else if (icu->adrcode & MA_MAP9) mtex= wo->mtex[8];
-                               else if (icu->adrcode & MA_MAP10) mtex= wo->mtex[9];
-                               else if (icu->adrcode & MA_MAP11) mtex= wo->mtex[10];
-                               else if (icu->adrcode & MA_MAP12) mtex= wo->mtex[11];
-                               else if (icu->adrcode & MA_MAP13) mtex= wo->mtex[12];
-                               else if (icu->adrcode & MA_MAP14) mtex= wo->mtex[13];
-                               else if (icu->adrcode & MA_MAP15) mtex= wo->mtex[14];
-                               else if (icu->adrcode & MA_MAP16) mtex= wo->mtex[15];
-                               else if (icu->adrcode & MA_MAP17) mtex= wo->mtex[16];
-                               else if (icu->adrcode & MA_MAP18) mtex= wo->mtex[17];
-                               
-                               if (mtex)
-                                       poin= give_mtex_poin(mtex, (icu->adrcode & (MA_MAP1-1)));
-                       }
-               }
-                       break;
-               case ID_SO: /* sound channels -----------------------------  */
-               {
-                       bSound *snd= (bSound *)id;
-                       
-                       switch (icu->adrcode) {
-                       case SND_VOLUME:
-                               poin= &(snd->volume); break;
-                       case SND_PITCH:
-                               poin= &(snd->pitch); break;
-                       case SND_PANNING:
-                               poin= &(snd->panning); break;
-                       case SND_ATTEN:
-                               poin= &(snd->attenuation); break;
-                       }
-               }
-                       break;
                case ID_PA: /* particle channels -----------------------------  */
                {
                        ParticleSettings *part= (ParticleSettings *)id;
index a09a428dc067fbee08e11766679011a905d0427f..ddbb1c81e12e17a242995191dfc567671ba719b7 100644 (file)
@@ -1204,7 +1204,7 @@ static void multiresModifier_update(DerivedMesh *dm)
 
 void multires_force_update(Object *ob)
 {
-       if(ob->derivedFinal) {
+       if(ob && ob->derivedFinal) {
                ob->derivedFinal->needsFree =1;
                ob->derivedFinal->release(ob->derivedFinal);
                ob->derivedFinal = NULL;
index d41dda4c81ea06c04755e5d59e1df2813d6efb89..65a935c1349042e7c802af3a8b41a81f4e971531 100644 (file)
@@ -1124,7 +1124,8 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree, int internal_select)
        
        /* check for copying links */
        for(link= ntree->links.first; link; link= link->next) {
-               if(link->fromnode->new_node && link->tonode->new_node) {
+               if(link->fromnode==NULL || link->tonode==NULL);
+               else if(link->fromnode->new_node && link->tonode->new_node) {
                        nlink= nodeAddLink(newtree, link->fromnode->new_node, NULL, link->tonode->new_node, NULL);
                        /* sockets were copied in order */
                        for(a=0, sock= link->fromnode->outputs.first; sock; sock= sock->next, a++) {
@@ -2269,8 +2270,10 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
                        /* is sock in use? */
                        else if(sock->link) {
                                bNodeLink *link= sock->link;
+                               
                                /* this is the test for a cyclic case */
-                               if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
+                               if(link->fromnode==NULL || link->tonode==NULL);
+                               else if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
                                        if(link->fromnode->need_exec) {
                                                node->need_exec= 1;
                                                break;
index 5dab59daef1c41ed2deb21c32fab31a9b65111f4..d22fc83f1e45bcdb79ca022b9ea3ab578ae5a79c 100644 (file)
@@ -3672,6 +3672,17 @@ static void direct_link_object(FileData *fd, Object *ob)
 
 /* ************ READ SCENE ***************** */
 
+/* patch for missing scene IDs, can't be in do-versions */
+static void composite_patch(bNodeTree *ntree, Scene *scene)
+{
+       bNode *node;
+       
+       for(node= ntree->nodes.first; node; node= node->next)
+               if(node->id==NULL && ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE))
+                       node->id= &scene->id;
+}
+
+
 static void lib_link_scene(FileData *fd, Main *main)
 {
        Scene *sce;
@@ -3736,8 +3747,10 @@ static void lib_link_scene(FileData *fd, Main *main)
                        
                        lib_link_scriptlink(fd, &sce->id, &sce->scriptlink);
                        
-                       if(sce->nodetree)
+                       if(sce->nodetree) {
                                lib_link_ntree(fd, &sce->id, sce->nodetree);
+                               composite_patch(sce->nodetree, sce);
+                       }
                        
                        for(srl= sce->r.layers.first; srl; srl= srl->next) {
                                srl->mat_override= newlibadr_us(fd, sce->id.lib, srl->mat_override);
@@ -4503,7 +4516,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                /* 2.50: we now always add spacedata for info */
                if(sa->spacedata.first==NULL) {
                        SpaceInfo *sinfo= MEM_callocN(sizeof(SpaceInfo), "spaceinfo");
-                       sa->spacetype= SPACE_INFO;
+                       sa->spacetype= sinfo->spacetype= SPACE_INFO;
                        BLI_addtail(&sa->spacedata, sinfo);
                }
                /* add local view3d too */
index ed12cf3b81152c15e55365a690ee75d5d47f8b6b..9f0d6cb1c8c1b5ef5b24d0ef529becae8376a09a 100644 (file)
@@ -157,6 +157,13 @@ enum {
        BMOP_ESUBDIVIDE_FLAG, //beauty flag in esubdivide
        BMOP_ESUBDIVIDE_RADIUS,
        BMOP_ESUBDIVIDE_SELACTION,
+
+       BMOP_ESUBDIVIDE_CUSTOMFILL_FACES,
+       BMOP_ESUBDIVIDE_CUSTOMFILL_PATTERNS,
+
+       BMOP_ESUBDIVIDE_PERCENT_VERTS,
+       BMOP_ESUBDIVIDE_PERCENT_VALUES,
+
        BMOP_ESUBDIVIDE_TOTSLOT,
 };
 /*
index 49e51e11e31b6d1a1f5b391f6b5dbdfa07651bab..ac13f8319a6453e7fcdc2614ae85949dad30061c 100644 (file)
@@ -38,7 +38,11 @@ BMOpDefine def_subdop = {
         BMOP_OPSLOT_INT,
         BMOP_OPSLOT_INT,
         BMOP_OPSLOT_FLT,
-        BMOP_OPSLOT_INT},
+        BMOP_OPSLOT_INT,
+        BMOP_OPSLOT_PNT_BUF,
+        BMOP_OPSLOT_PNT_BUF,
+        BMOP_OPSLOT_PNT_BUF,
+        BMOP_OPSLOT_FLT},
        esubdivide_exec,
        BMOP_ESUBDIVIDE_TOTSLOT,
        0
index c94381a3f2054d0a85f6f1883af25321da662014..076f47786ba6ae4c505de176351808cb04e42333 100644 (file)
@@ -4,6 +4,7 @@
 
 #include "BLI_arithb.h"
 #include "BLI_rand.h"
+#include "BLI_ghash.h"
 
 #include "DNA_object_types.h"
 
@@ -11,6 +12,7 @@
 
 #include "bmesh.h"
 #include "mesh_intern.h"
+#include "subdivideop.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 
 #define SUBD_SPLIT     1
-#define FACE_NEW       1
-#define MAX_FACE       800
+
+/*I don't think new faces are flagged, currently, but
+  better safe than sorry.*/
+#define FACE_NEW       2
+#define FACE_CUSTOMFILL        4
 
 /*stuff for the flag paramter.  note that
   what used to live in "beauty" and
   collision).*/
 #define SELTYPE_INNER  128
 
-
 /*
 NOTE: beauty has been renamed to flag!
 */
 
-/*
-note: this is a pattern-based edge subdivider.
-it tries to match a pattern to edge selections on faces,
-then executes functions to cut them.
-*/
-typedef struct subdpattern {
-       int seledges[20]; //selected edges mask, for splitting
-
-       /*verts starts at the first new vert cut, not the first vert in the
-         face*/
-       void (*connectexec)(BMesh *bm, BMFace *face, BMVert **verts, 
-                           int numcuts, int flag, float rad);
-       int len; /*total number of verts*/
-} subdpattern;
-
 /*generic subdivision rules:
   
   * two selected edges in a face should make a link
@@ -256,6 +245,7 @@ v4---v3---v2
 v5---v0---v1
 
 */
+
 static void q_2edge_op_split(BMesh *bm, BMFace *face, BMVert **vlist, 
                             int numcuts, int flag, float rad) {
        BMFace *nf;
@@ -587,19 +577,20 @@ typedef struct subd_facedata {
 
 void esubdivide_exec(BMesh *bmesh, BMOperator *op)
 {
-       BMOpSlot *einput;
-       BMEdge *edge, **edges = NULL;
+       V_DECLARE(facedata);
+       V_DECLARE(verts);
        V_DECLARE(edges);
+       BMOpSlot *einput, *finput, *pinput;
+       BMEdge *edge, **edges = NULL;
        BMFace *face;
        BMLoop *nl;
        BMVert **verts = NULL;
-       V_DECLARE(verts);
        BMIter fiter, liter;
+       GHash *customfill_hash; 
        subdpattern *pat;
-       float rad;
-       int i, j, matched, a, b, numcuts, flag, selaction;
        subd_facedata *facedata = NULL;
-       V_DECLARE(facedata);
+       float rad;
+       int i, j, matched, a, b, numcuts, flag, selaction, fillindex;
        
        BMO_Flag_Buffer(bmesh, op, BMOP_ESUBDIVIDE_EDGES, SUBD_SPLIT);
        
@@ -618,12 +609,26 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
                BMO_SetFlag(bmesh, edge, SUBD_SPLIT);
        }
        
+       customfill_hash = BLI_ghash_new(BLI_ghashutil_ptrhash,
+                                       BLI_ghashutil_ptrcmp);
+       
+       /*process custom fill patterns*/
+       finput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_CUSTOMFILL_FACES);
+       pinput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_CUSTOMFILL_PATTERNS);
+       for (i=0; i<finput->len; i++) {
+               face = ((BMFace**)finput->data.p)[i];
+               BMO_SetFlag(bmesh, face, FACE_CUSTOMFILL);
+               BLI_ghash_insert(customfill_hash, face,
+                               ((void**)pinput->data.p)[i]);
+       }
+       
        for (face=BMIter_New(&fiter, bmesh, BM_FACES, NULL);
             face; face=BMIter_Step(&fiter)) {
                /*figure out which pattern to use*/
-               i = 0;
+
                V_RESET(edges);
                V_RESET(verts);
+               i = 0;
                for (nl=BMIter_New(&liter, bmesh, BM_LOOPS_OF_FACE, face);
                     nl; nl=BMIter_Step(&liter)) {
                        V_GROW(edges);
@@ -633,6 +638,35 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
                        i++;
                }
 
+               if (BMO_TestFlag(bmesh, face, FACE_CUSTOMFILL)) {
+                       pat = BLI_ghash_lookup(customfill_hash, face);
+                       for (i=0; i<pat->len; i++) {
+                               matched = 1;
+                               for (j=0; j<pat->len; j++) {
+                                       a = (j + i) % pat->len;
+                                       if ((!!BMO_TestFlag(bmesh, edges[a], SUBD_SPLIT))
+                                               != (!!pat->seledges[j])) {
+                                                       matched = 0;
+                                                       break;
+                                       }
+                               }
+                               if (matched) {
+                                       V_GROW(facedata);
+                                       b = V_COUNT(facedata)-1;
+                                       facedata[b].pat = pat;
+                                       facedata[b].start = verts[i];
+                                       break;
+                               }
+                       }
+                       if (!matched) {
+                               /*if no match, append null element to array.*/
+                               V_GROW(facedata);
+                       }
+
+                       /*obvously don't test for other patterns matching*/
+                       continue;
+               }
+
                for (i=0; i<PLEN; i++) {
                        pat = patterns[i];
                        if (pat->len == face->len) {
@@ -677,7 +711,7 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
                /*figure out which pattern to use*/
                V_RESET(verts);
                if (BMO_TestFlag(bmesh, face, SUBD_SPLIT) == 0) continue;
-               
+
                pat = facedata[i].pat;
                if (!pat) continue;
 
index af446811d6f9c6d7a3e0137e123b2c31f55e7767..312227ba4e9614be1ab0feba99c590037b3a1279 100644 (file)
@@ -29,6 +29,6 @@
 # Bounces make to subdirectories.
 
 SOURCEDIR = source/blender/editors
-DIRS = armature mesh animation object sculpt datafiles transform screen curve gpencil physics preview uvedit space_outliner space_time space_view3d interface util  space_api space_ipo space_image space_node space_buttons space_info space_file space_sound space_action space_nla space_script space_text space_sequencer
+DIRS = armature mesh animation object sculpt datafiles transform screen curve gpencil physics preview uvedit space_outliner space_time space_view3d interface util  space_api space_graph space_image space_node space_buttons space_info space_file space_sound space_action space_nla space_script space_text space_sequencer
 
 include nan_subdirs.mk
index fc71319afa1e69f62c7ba9f3f69f542dc556f663..8346092976e66035a09cddf0c313bdffd7bc39e9 100644 (file)
@@ -18,7 +18,7 @@ SConscript(['datafiles/SConscript',
                        'space_file/SConscript',
                        'space_image/SConscript',
                        'space_info/SConscript',
-                       'space_ipo/SConscript',
+                       'space_graph/SConscript',
                        'space_node/SConscript',
                        'space_outliner/SConscript',
                        'space_time/SConscript',
index f8e6cd2d8e8ceda0ab4f2d601cbed195d6143bcc..1ff2169bf61687d5cdb93d0b3c41112a48b0db7b 100644 (file)
 #include "DNA_armature_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_view3d_types.h"
-#include "DNA_windowmanager_types.h"
 
 #include "BLI_blenlib.h"
 
 #include "BKE_action.h"
 #include "BKE_context.h"
 #include "BKE_depsgraph.h"
-#include "BKE_global.h"
-#include "BKE_scene.h"
 #include "BKE_main.h"
-#include "BKE_node.h"
+#include "BKE_scene.h"
 #include "BKE_utildefines.h"
 
 #include "RNA_access.h"
 #include "WM_types.h"
 
 /* ***************** depsgraph calls and anim updates ************* */
-
-static unsigned int screen_view3d_layers(bScreen *screen)
-{
-       if(screen) {
-               unsigned int layer= screen->scene->lay; /* as minimum this */
-               ScrArea *sa;
-               
-               /* get all used view3d layers */
-               for(sa= screen->areabase.first; sa; sa= sa->next) {
-                       if(sa->spacetype==SPACE_VIEW3D)
-                               layer |= ((View3D *)sa->spacedata.first)->lay;
-               }
-               return layer;
-       }
-       return 0;
-}
+/* ***************** only these can be called from editors ******** */
 
 /* generic update flush, reads from context Screen (layers) and scene */
 /* this is for compliancy, later it can do all windows etc */
@@ -86,7 +64,7 @@ void ED_anim_dag_flush_update(const bContext *C)
        Scene *scene= CTX_data_scene(C);
        bScreen *screen= CTX_wm_screen(C);
        
-       DAG_scene_flush_update(scene, screen_view3d_layers(screen), 0);
+       DAG_scene_flush_update(scene, ED_screen_view3d_layers(screen), 0);
 }
 
 /* flushes changes from object to all relations in scene */
@@ -95,46 +73,10 @@ void ED_anim_object_flush_update(const bContext *C, Object *ob)
        Scene *scene= CTX_data_scene(C);
        bScreen *screen= CTX_wm_screen(C);
        
-       DAG_object_update_flags(scene, ob, screen_view3d_layers(screen));
+       DAG_object_update_flags(scene, ob, ED_screen_view3d_layers(screen));
 }
 
 
-/* results in fully updated anim system */
-/* in future sound should be on WM level, only 1 sound can play! */
-void ED_update_for_newframe(const bContext *C, int mute)
-{
-       bScreen *screen= CTX_wm_screen(C);
-       Scene *scene= screen->scene;
-       
-       //extern void audiostream_scrub(unsigned int frame);    /* seqaudio.c */
-       
-       /* this function applies the changes too */
-       /* XXX future: do all windows */
-       scene_update_for_newframe(scene, screen_view3d_layers(screen)); /* BKE_scene.h */
-       
-       //if ( (CFRA>1) && (!mute) && (scene->audio.flag & AUDIO_SCRUB)) 
-       //      audiostream_scrub( CFRA );
-       
-       /* 3d window, preview */
-       //BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
-       
-       /* all movie/sequence images */
-       //BIF_image_update_frame();
-       
-       /* composite */
-       if(scene->use_nodes && scene->nodetree)
-               ntreeCompositTagAnimated(scene->nodetree);
-       
-       /* update animated texture nodes */
-       {
-               Tex *tex;
-               for(tex= G.main->tex.first; tex; tex= tex->id.next)
-                       if( tex->use_nodes && tex->nodetree ) {
-                               ntreeTexTagAnimated( tex->nodetree );
-                       }
-       }
-}
-
 /* **************************** animation tool notifiers ******************************** */
 
 /* Send notifiers on behalf of animation editing tools, based on various context info 
@@ -153,10 +95,10 @@ void ANIM_animdata_send_notifiers (bContext *C, bAnimContext *ac, short data_cha
                                case ANIM_CHANGED_KEYFRAMES_VALUES:
                                        /* keyframe values changed, so transform may have changed */
                                        // XXX what about other cases? maybe we need general ND_KEYFRAMES or ND_ANIMATION?
-                                       WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+                                       WM_event_add_notifier(C, NC_OBJECT|ND_KEYS|ND_TRANSFORM, NULL);
                                        break;
-                               case ANIM_CHANGED_KEYFRAMES_SELECT:     // XXX what to do here?
-                                       WM_event_add_notifier(C, NC_SCENE, NULL);
+                               case ANIM_CHANGED_KEYFRAMES_SELECT:
+                                       WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, NULL);
                                        break;
                                case ANIM_CHANGED_CHANNELS:
                                        // XXX err... check available datatypes in dopesheet first?
@@ -175,8 +117,24 @@ void ANIM_animdata_send_notifiers (bContext *C, bAnimContext *ac, short data_cha
                {
                        Object *obact= CTX_data_active_object(C);
                        
-                       // only update active object for now... more detail to come!
-                       WM_event_add_notifier(C, NC_OBJECT, obact);
+                       switch (data_changed) {
+                               case ANIM_CHANGED_KEYFRAMES_VALUES:
+                                       /* keyframe values changed, so transform may have changed */
+                                       // XXX what about other cases? maybe we need general ND_KEYFRAMES or ND_ANIMATION?
+                                       WM_event_add_notifier(C, NC_OBJECT|ND_KEYS|ND_TRANSFORM, obact);
+                                       break;
+                               case ANIM_CHANGED_KEYFRAMES_SELECT:
+                                       WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, obact);
+                                       break;
+                               case ANIM_CHANGED_CHANNELS:
+                                       // XXX err... check available datatypes in dopesheet first?
+                                       // FIXME: this currently doesn't work (to update own view)
+                                       WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE|ND_BONE_SELECT, obact);
+                                       break;
+                       }
+                       
+                       // XXX for now, at least update own editor!
+                       ED_area_tag_redraw(CTX_wm_area(C));
                }
                        break;
                        
index 7673acabe3aeda1ea5903ce1fb44f57ff10062a2..fd91b70dcdd0c0d2cebb5e928e7255767e438af5 100644 (file)
@@ -33,11 +33,15 @@ struct wmOperatorType;
 
 /* editarmature.c */
 void armature_bone_rename(Object *ob, char *oldnamep, char *newnamep);
-EditBone *armature_bone_get_mirrored(ListBase *edbo, EditBone *ebo);
+
+void ARMATURE_OT_align_bones(struct wmOperatorType *ot);
+void ARMATURE_OT_calculate_roll(struct wmOperatorType *ot);
 
 void POSE_OT_hide(struct wmOperatorType *ot);
 void POSE_OT_reveil(struct wmOperatorType *ot);
-
+void POSE_OT_rot_clear(struct wmOperatorType *ot);
+void POSE_OT_loc_clear(struct wmOperatorType *ot);
+void POSE_OT_scale_clear(struct wmOperatorType *ot);
 
 #endif /* ED_ARMATURE_INTERN_H */
 
index eaa8207bc116f060c3073dba4a04a56785edd520..6736561e36c7fd7537871476837dc90c735e823e 100644 (file)
 
 #include "armature_intern.h"
 
+/* ************************** quick tests **********************************/
+
+/*  XXX This is a quick test operator to print names of all EditBones in context
+ *             that should be removed once tool coding starts...
+ */
+
+static int armature_test_exec (bContext *C, wmOperator *op)
+{
+       printf("EditMode Armature Test: \n");
+       
+       printf("\tSelected Bones \n");
+       CTX_DATA_BEGIN(C, EditBone*, ebone, selected_bones)
+       {
+               printf("\t\tEditBone '%s' \n", ebone->name);
+       }
+       CTX_DATA_END;
+       
+       printf("\tEditable Bones \n");
+       CTX_DATA_BEGIN(C, EditBone*, ebone, selected_editable_bones) 
+       {
+               printf("\t\tEditBone '%s' \n", ebone->name);
+       }
+       CTX_DATA_END;
+       
+       printf("\tActive Bone \n");
+       {
+               EditBone *ebone= CTX_data_active_bone(C);
+               if (ebone) printf("\t\tEditBone '%s' \n", ebone->name);
+               else printf("\t\t<None> \n");
+       }
+       
+       return OPERATOR_FINISHED;
+}
+
+void ARMATURE_OT_test(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Test Context";
+       ot->idname= "ARMATURE_OT_test";
+       
+       /* api callbacks */
+       ot->exec= armature_test_exec;
+}
 
 /* ************************** registration **********************************/
 
 /* Both operators ARMATURE_OT_xxx and POSE_OT_xxx here */
 void ED_operatortypes_armature(void)
 {
+       WM_operatortype_append(ARMATURE_OT_align_bones);
+       WM_operatortype_append(ARMATURE_OT_calculate_roll);
+       
        WM_operatortype_append(POSE_OT_hide);
        WM_operatortype_append(POSE_OT_reveil);
+       WM_operatortype_append(POSE_OT_rot_clear);
+       WM_operatortype_append(POSE_OT_loc_clear);
+       WM_operatortype_append(POSE_OT_scale_clear);
+       
+       WM_operatortype_append(ARMATURE_OT_test); // XXX temp test for context iterators... to be removed
 }
 
 void ED_keymap_armature(wmWindowManager *wm)
 {
-       ListBase *keymap= WM_keymap_listbase(wm, "Armature", 0, 0);
+       ListBase *keymap;
        wmKeymapItem *kmi;
        
+       /* Armature ------------------------ */
+       keymap= WM_keymap_listbase(wm, "Armature", 0, 0);
+       
        /* only set in editmode armature, by space_view3d listener */
 //     WM_keymap_add_item(keymap, "ARMATURE_OT_hide", HKEY, KM_PRESS, 0, 0);
-
+       WM_keymap_add_item(keymap, "ARMATURE_OT_align_bones", AKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
+       WM_keymap_add_item(keymap, "ARMATURE_OT_calculate_roll", NKEY, KM_PRESS, KM_CTRL, 0);
+       
+       WM_keymap_add_item(keymap, "ARMATURE_OT_test", TKEY, KM_PRESS, 0, 0);  // XXX temp test for context iterators... to be removed
+       
+       /* Pose ------------------------ */
        /* only set in posemode, by space_view3d listener */
        keymap= WM_keymap_listbase(wm, "Pose", 0, 0);
        
@@ -83,6 +142,9 @@ void ED_keymap_armature(wmWindowManager *wm)
        kmi= WM_keymap_add_item(keymap, "POSE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
        RNA_boolean_set(kmi->ptr, "invert", 1);
        WM_keymap_add_item(keymap, "POSE_OT_reveil", HKEY, KM_PRESS, KM_ALT, 0);
-
+       /*clear pose*/
+       WM_keymap_add_item(keymap, "POSE_OT_rot_clear", RKEY, KM_PRESS, KM_ALT, 0);
+       WM_keymap_add_item(keymap, "POSE_OT_loc_clear", GKEY, KM_PRESS, KM_ALT, 0);
+       WM_keymap_add_item(keymap, "POSE_OT_scale_clear", SKEY, KM_PRESS, KM_ALT, 0);
 }
 
index 631f6ce39dfc4ec142b6098b881a1a1fdb7129d3..1d3d1f9b567a5ba310320441aae2250d71680885 100644 (file)
@@ -67,6 +67,7 @@
 #include "BKE_global.h"
 #include "BKE_main.h"
 #include "BKE_object.h"
+#include "BKE_report.h"
 #include "BKE_subsurf.h"
 #include "BKE_utildefines.h"
 #include "BKE_modifier.h"
@@ -102,7 +103,6 @@ static void error() {};
 static void error_libdata() {}
 static void BIF_undo_push() {}
 static void adduplicate() {}
-static void countall() {}
 /* ************* XXX *************** */
 
 /* **************** tools on Editmode Armature **************** */
@@ -113,12 +113,13 @@ static void armature_sync_selection(ListBase *edbo)
        EditBone *ebo;
        
        for (ebo=edbo->first; ebo; ebo= ebo->next) {
-               if ((ebo->flag & BONE_CONNECTED) && ebo->parent){
+               if ((ebo->flag & BONE_CONNECTED) && (ebo->parent)) {
                        if (ebo->parent->flag & BONE_TIPSEL)
                                ebo->flag |= BONE_ROOTSEL;
                        else
                                ebo->flag &= ~BONE_ROOTSEL;
                }
+               
                if ((ebo->flag & BONE_TIPSEL) && (ebo->flag & BONE_ROOTSEL))
                        ebo->flag |= BONE_SELECTED;
                else
@@ -1038,8 +1039,6 @@ void separate_armature (Scene *scene, View3D *v3d)
        
        /* recalc/redraw + cleanup */
        waitcursor(0);
-
-       countall(); // flush!
        
        BIF_undo_push("Separate Armature");
 }
@@ -1247,7 +1246,7 @@ void armature_select_hierarchy(Scene *scene, short direction, short add_to_sel)
                }
        }
 
-       countall(); // flushes selection!
+       armature_sync_selection(arm->edbo);
        
        if (direction==BONE_SELECT_PARENT)
                BIF_undo_push("Select edit bone parent");
@@ -1380,7 +1379,8 @@ void selectconnected_posearmature(bContext *C)
                selectconnected_posebonechildren (ob, curBone);
        }
        
-       countall(); // flushes selection!
+               // XXX this only counted the number of pose channels selected
+       //countall(); // flushes selection!
 
        BIF_undo_push("Select connected");
 
@@ -1444,7 +1444,7 @@ void selectconnected_armature(bContext *C)
 
        }
 
-       countall(); // flushes selection!
+       armature_sync_selection(arm->edbo);
 
        BIF_undo_push("Select connected");
 
@@ -1556,11 +1556,14 @@ static void delete_bone(ListBase *edbo, EditBone* exBone)
 }
 
 /* context: editmode armature */
-EditBone *armature_bone_get_mirrored(ListBase *edbo, EditBone *ebo)
+EditBone *ED_armature_bone_get_mirrored(ListBase *edbo, EditBone *ebo)
 {
        EditBone *eboflip= NULL;
        char name[32];
        
+       if (ebo == NULL)
+               return NULL;
+       
        BLI_strncpy(name, ebo->name, sizeof(name));
        bone_flip_name(name, 0);                // 0 = don't strip off number extensions
        
@@ -1589,7 +1592,7 @@ void delete_armature(Scene *scene)
                for (curBone=arm->edbo->first; curBone; curBone=curBone->next) {
                        if (arm->layer & curBone->layer) {
                                if (curBone->flag & BONE_SELECTED) {
-                                       next = armature_bone_get_mirrored(arm->edbo, curBone);
+                                       next = ED_armature_bone_get_mirrored(arm->edbo, curBone);
                                        if (next)
                                                next->flag |= BONE_SELECTED;
                                }
@@ -1647,16 +1650,16 @@ void delete_armature(Scene *scene)
        }
        
        
-       countall(); // flushes selection!
+       armature_sync_selection(arm->edbo);
        
        BIF_undo_push("Delete bone(s)");
 }
 
 /* toggle==0: deselect
-toggle==1: swap (based on test)
-toggle==2: only active tag
-toggle==3: swap (no test)
-*/
+ * toggle==1: swap (based on test)
+ * toggle==2: only active tag
+ * toggle==3: swap (no test)
+ */
 void deselectall_armature(Object *obedit, int toggle, int doundo)
 {
        bArmature *arm= obedit->data;
@@ -1704,7 +1707,7 @@ void deselectall_armature(Object *obedit, int toggle, int doundo)
                }
        }
        
-       countall(); // flushes selection!
+       armature_sync_selection(arm->edbo);
        if (doundo) {
                if (sel==1) BIF_undo_push("Select All");
                else BIF_undo_push("Deselect All");
@@ -1844,92 +1847,131 @@ float ED_rollBoneToVector(EditBone *bone, float new_up_axis[3])
        return roll;
 }
 
-/* Sets the roll value of selected bones, depending on the mode
- *     mode == 0: their z-axes point upwards 
- *     mode == 1: their z-axes point towards 3d-cursor
- */
-void auto_align_armature(Scene *scene, View3D *v3d, short mode)
+
+/* Set roll value for given bone -> Z-Axis Point up (original method) */
+void auto_align_ebone_zaxisup(Scene *scene, View3D *v3d, EditBone *ebone)
+{
+       float   delta[3], curmat[3][3];
+       float   xaxis[3]={1.0f, 0.0f, 0.0f}, yaxis[3], zaxis[3]={0.0f, 0.0f, 1.0f};
+       float   targetmat[3][3], imat[3][3], diffmat[3][3];
+       
+       /* Find the current bone matrix */
+       VecSubf(delta, ebone->tail, ebone->head);
+       vec_roll_to_mat3(delta, 0.0f, curmat);
+       
+       /* Make new matrix based on y axis & z-up */
+       VECCOPY(yaxis, curmat[1]);
+       
+       Mat3One(targetmat);
+       VECCOPY(targetmat[0], xaxis);
+       VECCOPY(targetmat[1], yaxis);
+       VECCOPY(targetmat[2], zaxis);
+       Mat3Ortho(targetmat);
+       
+       /* Find the difference between the two matrices */
+       Mat3Inv(imat, targetmat);
+       Mat3MulMat3(diffmat, imat, curmat);
+       
+       // old-method... let's see if using mat3_to_vec_roll is more accurate
+       //ebone->roll = atan2(diffmat[2][0], diffmat[2][2]);  
+       mat3_to_vec_roll(diffmat, delta, &ebone->roll);
+}
+
+/* Set roll value for given bone -> Z-Axis point towards cursor */
+void auto_align_ebone_tocursor(Scene *scene, View3D *v3d, EditBone *ebone)
 {
        Object *obedit= scene->obedit; // XXX get from context
-       bArmature *arm= obedit->data;
-       EditBone *ebone;
-       EditBone *flipbone = NULL;
-       float   delta[3];
-       float   curmat[3][3];
        float   *cursor= give_cursor(scene, v3d);
+       float   delta[3], curmat[3][3];
+       float   mat[4][4], tmat[4][4], imat[4][4];
+       float   rmat[4][4], rot[3];
+       float   vec[3];
+       
+       /* find the current bone matrix as a 4x4 matrix (in Armature Space) */
+       VecSubf(delta, ebone->tail, ebone->head);
+       vec_roll_to_mat3(delta, ebone->roll, curmat);
+       Mat4CpyMat3(mat, curmat);
+       VECCOPY(mat[3], ebone->head);
+       
+       /* multiply bone-matrix by object matrix (so that bone-matrix is in WorldSpace) */
+       Mat4MulMat4(tmat, mat, obedit->obmat);
+       Mat4Invert(imat, tmat);
+       
+       /* find position of cursor relative to bone */
+       VecMat4MulVecfl(vec, imat, cursor);
+       
+       /* check that cursor is in usable position */
+       if ((IS_EQ(vec[0], 0)==0) && (IS_EQ(vec[2], 0)==0)) {
+               /* Compute a rotation matrix around y */
+               rot[1] = atan2(vec[0], vec[2]);
+               rot[0] = rot[2] = 0.0f;
+               EulToMat4(rot, rmat);
                
-       for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
-               if (EBONE_VISIBLE(arm, ebone)) {
-                       if (arm->flag & ARM_MIRROR_EDIT)
-                               flipbone = armature_bone_get_mirrored(arm->edbo, ebone);
-                       
-                       if ((ebone->flag & BONE_SELECTED) || 
-                               (flipbone && (flipbone->flag & BONE_SELECTED))) 
-                       {
-                               /* specific method used to calculate roll depends on mode */
-                               if (mode == 1) {
-                                       /* Z-Axis point towards cursor */
-                                       float   mat[4][4], tmat[4][4], imat[4][4];
-                                       float   rmat[4][4], rot[3];
-                                       float   vec[3];
-                                       
-                                       /* find the current bone matrix as a 4x4 matrix (in Armature Space) */
-                                       VecSubf(delta, ebone->tail, ebone->head);
-                                       vec_roll_to_mat3(delta, ebone->roll, curmat);
-                                       Mat4CpyMat3(mat, curmat);
-                                       VECCOPY(mat[3], ebone->head);
-                                       
-                                       /* multiply bone-matrix by object matrix (so that bone-matrix is in WorldSpace) */
-                                       Mat4MulMat4(tmat, mat, obedit->obmat);
-                                       Mat4Invert(imat, tmat);
-                                       
-                                       /* find position of cursor relative to bone */
-                                       VecMat4MulVecfl(vec, imat, cursor);
-                                       
-                                       /* check that cursor is in usable position */
-                                       if ((IS_EQ(vec[0], 0)==0) && (IS_EQ(vec[2], 0)==0)) {
-                                               /* Compute a rotation matrix around y */
-                                               rot[1] = atan2(vec[0], vec[2]);
-                                               rot[0] = rot[2] = 0.0f;
-                                               EulToMat4(rot, rmat);
-                                               
-                                               /* Multiply the bone matrix by rotation matrix. This should be new bone-matrix */
-                                               Mat4MulMat4(tmat, rmat, mat);
-                                               Mat3CpyMat4(curmat, tmat);
-                                               
-                                               /* Now convert from new bone-matrix, back to a roll value (in radians) */
-                                               mat3_to_vec_roll(curmat, delta, &ebone->roll);
-                                       }
-                               }
-                               else { 
-                                       /* Z-Axis Point Up */
-                                       float   xaxis[3]={1.0, 0.0, 0.0}, yaxis[3], zaxis[3]={0.0, 0.0, 1.0};
-                                       float   targetmat[3][3], imat[3][3], diffmat[3][3];
-                                       
-                                       /* Find the current bone matrix */
-                                       VecSubf(delta, ebone->tail, ebone->head);
-                                       vec_roll_to_mat3(delta, 0.0, curmat);
-                                       
-                                       /* Make new matrix based on y axis & z-up */
-                                       VECCOPY (yaxis, curmat[1]);
-                                       
-                                       Mat3One(targetmat);
-                                       VECCOPY (targetmat[0], xaxis);
-                                       VECCOPY (targetmat[1], yaxis);
-                                       VECCOPY (targetmat[2], zaxis);
-                                       Mat3Ortho(targetmat);
-                                       
-                                       /* Find the difference between the two matrices */
-                                       Mat3Inv(imat, targetmat);
-                                       Mat3MulMat3(diffmat, imat, curmat);
-                                       
-                                       ebone->roll = atan2(diffmat[2][0], diffmat[2][2]);
-                               }                               
-                       }
-               }
+               /* Multiply the bone matrix by rotation matrix. This should be new bone-matrix */
+               Mat4MulMat4(tmat, rmat, mat);
+               Mat3CpyMat4(curmat, tmat);
+               
+               /* Now convert from new bone-matrix, back to a roll value (in radians) */
+               mat3_to_vec_roll(curmat, delta, &ebone->roll);
        }
 }
 
+
+static EnumPropertyItem prop_calc_roll_types[] = {
+       {0, "GLOBALUP", "Z-Axis Up", ""},
+       {1, "CURSOR", "Z-Axis to Cursor", ""},
+       {0, NULL, NULL, NULL}
+};
+
+static int armature_calc_roll_exec(bContext *C, wmOperator *op) 
+{
+       Scene *scene= CTX_data_scene(C);
+       View3D *v3d= (View3D *)CTX_wm_space_data(C);
+       Object *ob= CTX_data_edit_object(C);
+       void (*roll_func)(Scene *, View3D *, EditBone *) = NULL;
+       
+       /* specific method used to calculate roll depends on mode */
+       switch (RNA_enum_get(op->ptr, "type")) {
+               case 1:  /* Z-Axis point towards cursor */
+                       roll_func= auto_align_ebone_tocursor;
+                       break;
+               default: /* Z-Axis Point Up */
+                       roll_func= auto_align_ebone_zaxisup;
+                       break;
+       }
+       
+       /* recalculate roll on selected bones */
+       CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) {
+               /* roll func is a callback which assumes that all is well */
+               roll_func(scene, v3d, ebone);
+       }
+       CTX_DATA_END;
+       
+
+       /* note, notifier might evolve */
+       WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
+       
+       return OPERATOR_FINISHED;
+}
+
+void ARMATURE_OT_calculate_roll(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Recalculate Roll";
+       ot->idname= "ARMATURE_OT_calculate_roll";
+       
+       /* api callbacks */
+       ot->invoke = WM_menu_invoke;
+       ot->exec = armature_calc_roll_exec;
+       ot->poll = ED_operator_editarmature;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       
+       /* properties */
+       RNA_def_enum(ot->srna, "type", prop_calc_roll_types, 0, "Type", "");
+}
+
 /* **************** undo for armatures ************** */
 
 static void undoBones_to_editBones(void *lbuv, void *lbev)
@@ -2023,14 +2065,14 @@ static EditBone *add_editbone(Object *obedit, char *name)
        BLI_addtail(arm->edbo, bone);
        
        bone->flag |= BONE_TIPSEL;
-       bone->weight= 1.0F;
-       bone->dist= 0.25F;
-       bone->xwidth= 0.1;
-       bone->zwidth= 0.1;
-       bone->ease1= 1.0;
-       bone->ease2= 1.0;
-       bone->rad_head= 0.10;
-       bone->rad_tail= 0.05;
+       bone->weight= 1.0f;
+       bone->dist= 0.25f;
+       bone->xwidth= 0.1f;
+       bone->zwidth= 0.1f;
+       bone->ease1= 1.0f;
+       bone->ease2= 1.0f;
+       bone->rad_head= 0.10f;
+       bone->rad_tail= 0.05f;
        bone->segments= 1;
        bone->layer= arm->layer;
        
@@ -2100,7 +2142,7 @@ void add_primitiveArmature(Scene *scene, View3D *v3d, int type)
        /* no primitive support yet */
        add_primitive_bone(scene, v3d, rv3d, newob);
        
-       countall(); // flushes selection!
+       //armature_sync_selection(arm->edbo); // XXX which armature?
 
        if ((newob) && !(U.flag & USER_ADD_EDITMODE)) {
                ED_armature_from_edit(scene, obedit);
@@ -2145,7 +2187,7 @@ void addvert_armature(Scene *scene, View3D *v3d)
        /* we re-use code for mirror editing... */
        flipbone= NULL;
        if (arm->flag & ARM_MIRROR_EDIT)
-               flipbone= armature_bone_get_mirrored(arm->edbo, ebone);
+               flipbone= ED_armature_bone_get_mirrored(arm->edbo, ebone);
 
        for (a=0; a<2; a++) {
                if (a==1) {
@@ -2188,7 +2230,7 @@ void addvert_armature(Scene *scene, View3D *v3d)
                
        }
        
-       countall();
+       armature_sync_selection(arm->edbo);
        
        BIF_undo_push("Add Bone");
 }
@@ -2279,14 +2321,14 @@ void adduplicate_armature(Scene *scene)
        EditBone        *curBone;
        EditBone        *firstDup=NULL; /*      The beginning of the duplicated bones in the edbo list */
        
-       countall(); // flushes selection!
+       armature_sync_selection(arm->edbo); // XXX why is this needed?
 
        /* Select mirrored bones */
        if (arm->flag & ARM_MIRROR_EDIT) {
                for (curBone=arm->edbo->first; curBone; curBone=curBone->next) {
                        if (EBONE_VISIBLE(arm, curBone)) {
                                if (curBone->flag & BONE_SELECTED) {
-                                       eBone = armature_bone_get_mirrored(arm->edbo, curBone);
+                                       eBone = ED_armature_bone_get_mirrored(arm->edbo, curBone);
                                        if (eBone)
                                                eBone->flag |= BONE_SELECTED;
                                }
@@ -2795,7 +2837,7 @@ void merge_armature(Scene *scene)
        }
        
        /* undo + updates */
-       countall();
+       armature_sync_selection(arm->edbo);
        BIF_undo_push("Merge Bones");
 }
 
@@ -2817,7 +2859,7 @@ void hide_selected_armature_bones(Scene *scene)
                        }
                }
        }
-       countall();
+       armature_sync_selection(arm->edbo);
        BIF_undo_push("Hide Bones");
 }
 
@@ -2837,7 +2879,7 @@ void hide_unselected_armature_bones(Scene *scene)
                        }
                }
        }
-       countall();
+       armature_sync_selection(arm->edbo);
        BIF_undo_push("Hide Unselected Bones");
 }
 
@@ -2855,7 +2897,7 @@ void show_all_armature_bones(Scene *scene)
                        }
                }
        }
-       countall();
+       armature_sync_selection(arm->edbo);
        BIF_undo_push("Reveal Bones");
 }
 
@@ -2966,7 +3008,7 @@ void make_bone_parent(Scene *scene)
                bone_connect_to_existing_parent(actbone);
                
                if (arm->flag & ARM_MIRROR_EDIT) {
-                       flipbone = armature_bone_get_mirrored(arm->edbo, actbone);
+                       flipbone = ED_armature_bone_get_mirrored(arm->edbo, actbone);
                        if (flipbone)
                                bone_connect_to_existing_parent(flipbone);
                }
@@ -2986,8 +3028,8 @@ void make_bone_parent(Scene *scene)
                                                 * - if there's no mirrored copy of actbone (i.e. actbone = "parent.C" or "parent")
                                                 *      then just use actbone. Useful when doing upper arm to spine.
                                                 */
-                                               flipbone = armature_bone_get_mirrored(arm->edbo, selbone);
-                                               flippar = armature_bone_get_mirrored(arm->edbo, actbone);
+                                               flipbone = ED_armature_bone_get_mirrored(arm->edbo, selbone);
+                                               flippar = ED_armature_bone_get_mirrored(arm->edbo, actbone);
                                                
                                                if (flipbone) {
                                                        if (flippar)
@@ -3001,7 +3043,7 @@ void make_bone_parent(Scene *scene)
                }
        }
 
-       countall(); /* checks selection */
+       armature_sync_selection(arm->edbo);
        BIF_undo_push("Make Parent");
 
        return;
@@ -3033,7 +3075,7 @@ void clear_bone_parent(Scene *scene)
                if (EBONE_VISIBLE(arm, ebone)) {
                        if (ebone->flag & BONE_SELECTED) {
                                if (arm->flag & ARM_MIRROR_EDIT)
-                                       flipbone = armature_bone_get_mirrored(arm->edbo, ebone);
+                                       flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
                                        
                                if (flipbone)
                                        editbone_clear_parent(flipbone, val);
@@ -3042,7 +3084,7 @@ void clear_bone_parent(Scene *scene)
                }
        }
        
-       countall(); // checks selection
+       armature_sync_selection(arm->edbo);
        BIF_undo_push("Clear Parent");
 }
        
@@ -3085,7 +3127,7 @@ void extrude_armature(Scene *scene, int forked)
                                /* we re-use code for mirror editing... */
                                flipbone= NULL;
                                if (arm->flag & ARM_MIRROR_EDIT) {
-                                       flipbone= armature_bone_get_mirrored(arm->edbo, ebone);
+                                       flipbone= ED_armature_bone_get_mirrored(arm->edbo, ebone);
                                        if (flipbone) {
                                                forked= 0;      // we extrude 2 different bones
                                                if (flipbone->flag & (BONE_TIPSEL|BONE_ROOTSEL|BONE_SELECTED))
@@ -3169,7 +3211,7 @@ void extrude_armature(Scene *scene, int forked)
        if (totbone==1 && first) first->flag |= BONE_ACTIVE;
        
        /* Transform the endpoints */
-       countall(); // flushes selection!
+       armature_sync_selection(arm->edbo);
 // XXX BIF_TransformSetUndo("Extrude");
 //     initTransform(TFM_TRANSLATION, CTX_NO_PET);
 //     Transform();
@@ -3203,7 +3245,7 @@ void subdivide_armature(Scene *scene, int numcuts)
                                                /* try to find mirrored bone on a != 0 */
                                                if (a) {
                                                        if (arm->flag & ARM_MIRROR_EDIT)
-                                                               ebone= armature_bone_get_mirrored(arm->edbo, mbone);
+                                                               ebone= ED_armature_bone_get_mirrored(arm->edbo, mbone);
                                                        else 
                                                                ebone= NULL;
                                                }
@@ -3326,7 +3368,7 @@ void switch_direction_armature (Scene *scene)
        BIF_undo_push("Switch Direction");
 }
 
-/* editbone alignment */
+/* ***************** EditBone Alignment ********************* */
 
 /* helper to fix a ebone position if its parent has moved due to alignment*/
 static void fix_connected_bone(EditBone *ebone)
@@ -3378,159 +3420,85 @@ static void bone_align_to_bone(ListBase *edbo, EditBone *selbone, EditBone *actb
        return;
 }
 
-void align_selected_bones(Scene *scene)
+static int armature_align_bones_exec(bContext *C, wmOperator *op) 
 {
-       Object *obedit= scene->obedit; // XXX get from context
-       bArmature *arm= obedit->data;
-       EditBone *actbone, *ebone, *selbone;
-       EditBone *flipbone, *flippar;
-       short allchildbones= 0, foundselbone= 0;
+       Object *ob= CTX_data_edit_object(C);
+       bArmature *arm= (bArmature *)ob->data;
+       EditBone *actbone= CTX_data_active_bone(C);
+       EditBone *actmirb= NULL;
        
-       /* find active bone to align to */
-       for (actbone = arm->edbo->first; actbone; actbone=actbone->next) {
-               if (arm->layer & actbone->layer) {
-                       if (actbone->flag & BONE_ACTIVE)
-                               break;
-               }
-       }
+       /* there must be an active bone */
        if (actbone == NULL) {
-               error("Needs an active bone");
-               return; 
-       }
-
-       /* find selected bones */
-       for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
-               if (arm->layer & ebone->layer) {
-                       if ((ebone->flag & BONE_SELECTED) && (ebone != actbone)) {
-                               foundselbone++;
-                               if (ebone->parent != actbone) allchildbones= 1; 
-                       }       
-               }
-       }
-       /* abort if no selected bones, and active bone doesn't have a parent to work with instead */
-       if (foundselbone==0 && actbone->parent==NULL) {
-               error("Need selected bone(s)");
-               return;
+               BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Bone");
+               return OPERATOR_CANCELLED;
+       }
+       else if (arm->flag & ARM_MIRROR_EDIT) {
+               /* For X-Axis Mirror Editing option, we may need a mirror copy of actbone
+                * - if there's a mirrored copy of selbone, try to find a mirrored copy of actbone 
+                *      (i.e.  selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
+                *      This is useful for arm-chains, for example parenting lower arm to upper arm
+                * - if there's no mirrored copy of actbone (i.e. actbone = "parent.C" or "parent")
+                *      then just use actbone. Useful when doing upper arm to spine.
+                */
+               actmirb= ED_armature_bone_get_mirrored(arm->edbo, actbone);
+               if (actmirb == NULL) 
+                       actmirb= actbone;
        }
        
-       if (foundselbone==0 && actbone->parent) {
+       /* if there is only 1 selected bone, we assume that that is the active bone, 
+        * since a user will need to have clicked on a bone (thus selecting it) to make it active
+        */
+       if (CTX_DATA_COUNT(C, selected_editable_bones) <= 1) {
                /* When only the active bone is selected, and it has a parent,
                 * align it to the parent, as that is the only possible outcome. 
                 */
-               bone_align_to_bone(arm->edbo, actbone, actbone->parent);
-               
-               if (arm->flag & ARM_MIRROR_EDIT) {
-                       flipbone = armature_bone_get_mirrored(arm->edbo, actbone);
-                       if (flipbone)
-                               bone_align_to_bone(arm->edbo, flipbone, flipbone->parent);
+               if (actbone->parent) {
+                       bone_align_to_bone(arm->edbo, actbone, actbone->parent);
+                       
+                       if ((arm->flag & ARM_MIRROR_EDIT) && (actmirb->parent))
+                               bone_align_to_bone(arm->edbo, actmirb, actmirb->parent);
                }
        }
        else {
-               /* loop through all editbones, aligning all selected bones to the active bone */
-               for (selbone = arm->edbo->first; selbone; selbone=selbone->next) {
-                       if (arm->layer & selbone->layer) {
-                               if ((selbone->flag & BONE_SELECTED) && (selbone!=actbone)) {
-                                       /* align selbone to actbone */
-                                       bone_align_to_bone(arm->edbo, selbone, actbone);
-                                       
-                                       if (arm->flag & ARM_MIRROR_EDIT) {
-                                               /* - if there's a mirrored copy of selbone, try to find a mirrored copy of actbone 
-                                                *      (i.e.  selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
-                                                *      This is useful for arm-chains, for example parenting lower arm to upper arm
-                                                * - if there's no mirrored copy of actbone (i.e. actbone = "parent.C" or "parent")
-                                                *      then just use actbone. Useful when doing upper arm to spine.
-                                                */
-                                               flipbone = armature_bone_get_mirrored(arm->edbo, selbone);
-                                               flippar = armature_bone_get_mirrored(arm->edbo, actbone);
-                                               
-                                               if (flipbone) {
-                                                       if (flippar)
-                                                               bone_align_to_bone(arm->edbo, flipbone, flippar);
-                                                       else
-                                                               bone_align_to_bone(arm->edbo, flipbone, actbone);
-                                               }
-                                       }
-                               }
-                       }
+               /* Align 'selected' bones to the active one
+                * - the context iterator contains both selected bones and their mirrored copies,
+                *   so we assume that unselected bones are mirrored copies of some selected bone
+                */
+               
+               /* align selected bones to the active one */
+               CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) {
+                       if (ebone->flag & BONE_SELECTED)
+                               bone_align_to_bone(arm->edbo, ebone, actbone);
+                       else
+                               bone_align_to_bone(arm->edbo, ebone, actmirb);
                }
+               CTX_DATA_END;
        }
+       
 
-       countall(); /* checks selection */
-       BIF_undo_push("Align bones");
-
-       return;
+       /* note, notifier might evolve */
+       WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
+       
+       return OPERATOR_FINISHED;
 }
 
-/* ***************** Pose tools ********************* */
-
-void clear_armature(Scene *scene, Object *ob, char mode)
+void ARMATURE_OT_align_bones(wmOperatorType *ot)
 {
-       bPoseChannel *pchan;
-       bArmature       *arm= ob->data;
+       /* identifiers */
+       ot->name= "Align Bones";
+       ot->idname= "ARMATURE_OT_align_bones";
        
-       /* only clear those channels that are not locked */
-       for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-               if (pchan->bone && (pchan->bone->flag & BONE_SELECTED)) {
-                       if (arm->layer & pchan->bone->layer) {
-                               switch (mode) {
-                                       case 'r':
-                                               if (pchan->protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ)) {
-                                                       float eul[3], oldeul[3], quat1[4];
-                                                       
-                                                       QUATCOPY(quat1, pchan->quat);
-                                                       QuatToEul(pchan->quat, oldeul);
-                                                       eul[0]= eul[1]= eul[2]= 0.0f;
-                                                       
-                                                       if (pchan->protectflag & OB_LOCK_ROTX)
-                                                               eul[0]= oldeul[0];
-                                                       if (pchan->protectflag & OB_LOCK_ROTY)
-                                                               eul[1]= oldeul[1];
-                                                       if (pchan->protectflag & OB_LOCK_ROTZ)
-                                                               eul[2]= oldeul[2];
-                                                       
-                                                       EulToQuat(eul, pchan->quat);
-                                                       /* quaternions flip w sign to accumulate rotations correctly */
-                                                       if ((quat1[0]<0.0f && pchan->quat[0]>0.0f) || (quat1[0]>0.0f && pchan->quat[0]<0.0f)) {
-                                                               QuatMulf(pchan->quat, -1.0f);
-                                                       }
-                                               }                                               
-                                               else { 
-                                                       pchan->quat[1]=pchan->quat[2]=pchan->quat[3]=0.0F; 
-                                                       pchan->quat[0]=1.0F;
-                                               }
-                                               break;
-                                       case 'g':
-                                               if ((pchan->protectflag & OB_LOCK_LOCX)==0)
-                                                       pchan->loc[0]= 0.0f;
-                                               if ((pchan->protectflag & OB_LOCK_LOCY)==0)
-                                                       pchan->loc[1]= 0.0f;
-                                               if ((pchan->protectflag & OB_LOCK_LOCZ)==0)
-                                                       pchan->loc[2]= 0.0f;
-                                               break;
-                                       case 's':
-                                               if ((pchan->protectflag & OB_LOCK_SCALEX)==0)
-                                                       pchan->size[0]= 1.0f;
-                                               if ((pchan->protectflag & OB_LOCK_SCALEY)==0)
-                                                       pchan->size[1]= 1.0f;
-                                               if ((pchan->protectflag & OB_LOCK_SCALEZ)==0)
-                                                       pchan->size[2]= 1.0f;
-                                               break;
-                                               
-                               }
-                               
-                               /* the current values from IPO's may not be zero, so tag as unkeyed */
-                               pchan->bone->flag |= BONE_UNKEYED;
-                       }
-               }
-       }
+       /* api callbacks */
+       ot->invoke = WM_operator_confirm;
+       ot->exec = armature_align_bones_exec;
+       ot->poll = ED_operator_editarmature;
        
-       DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
-       /* no update for this object, this will execute the action again */
-       /* is weak... like for ipo editing which uses ctime now... */
-       where_is_pose (scene, ob);
-       ob->recalc= 0;
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+/* ***************** Pose tools ********************* */
+
 /* helper for function below */
 static int clear_active_flag(Object *ob, Bone *bone, void *data) 
 {
@@ -3539,6 +3507,7 @@ static int clear_active_flag(Object *ob, Bone *bone, void *data)
 }
 
 
+// XXX bone_looper is only to be used when we want to access settings (i.e. editability/visibility/selected) that context doesn't offer 
 static int bone_looper(Object *ob, Bone *bone, void *data,
                                int (*bone_func)(Object *, Bone *, void *)) 
 {
@@ -3669,7 +3638,7 @@ void ED_pose_deselectall (Object *ob, int test, int doundo)
                }
        }
        
-       countall();
+       //countall(); // XXX need an equivalent to this...
        
        if (doundo) {
                if (selectmode==1) BIF_undo_push("Select All");
@@ -4058,7 +4027,167 @@ void create_vgroups_from_armature(Scene *scene, Object *ob, Object *par)
                break;
        }
 } 
+/* ************* Clear Pose *****************************/
 
+static int pose_clear_scale_exec(bContext *C, wmOperator *op) 
+{
+       Scene *scene = CTX_data_scene(C);
+       Object *ob= CTX_data_active_object(C);
+       
+       /* only clear those channels that are not locked */
+       CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) {
+               if ((pchan->protectflag & OB_LOCK_SCALEX)==0)
+                       pchan->size[0]= 1.0f;
+               if ((pchan->protectflag & OB_LOCK_SCALEY)==0)
+                       pchan->size[1]= 1.0f;
+               if ((pchan->protectflag & OB_LOCK_SCALEZ)==0)
+                       pchan->size[2]= 1.0f;
+                       
+               /* the current values from IPO's may not be zero, so tag as unkeyed */
+               //pchan->bone->flag |= BONE_UNKEYED;
+       }
+       CTX_DATA_END;
+       
+       DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+
+       /* note, notifier might evolve */
+       WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
+       
+       return OPERATOR_FINISHED;
+}
+
+void POSE_OT_scale_clear(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Clear Pose Scale";
+       ot->idname= "POSE_OT_scale_clear";
+       
+       /* api callbacks */
+       ot->invoke = WM_operator_confirm;
+       ot->exec = pose_clear_scale_exec;
+       ot->poll = ED_operator_posemode;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int pose_clear_loc_exec(bContext *C, wmOperator *op) 
+{
+       Scene *scene = CTX_data_scene(C);
+       Object *ob= CTX_data_active_object(C);
+       
+       /* only clear those channels that are not locked */
+       CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) {
+               if ((pchan->protectflag & OB_LOCK_LOCX)==0)
+                       pchan->loc[0]= 0.0f;
+               if ((pchan->protectflag & OB_LOCK_LOCY)==0)
+                       pchan->loc[1]= 0.0f;
+               if ((pchan->protectflag & OB_LOCK_LOCZ)==0)
+                       pchan->loc[2]= 0.0f;
+                       
+               /* the current values from IPO's may not be zero, so tag as unkeyed */
+               //pchan->bone->flag |= BONE_UNKEYED;
+       }
+       CTX_DATA_END;
+       
+       DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+
+       /* note, notifier might evolve */
+       WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
+       
+       return OPERATOR_FINISHED;
+}
+
+void POSE_OT_loc_clear(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Clear Pose Location";
+       ot->idname= "POSE_OT_loc_clear";
+       
+       /* api callbacks */
+       ot->invoke = WM_operator_confirm;
+       ot->exec = pose_clear_loc_exec;
+       ot->poll = ED_operator_posemode;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int pose_clear_rot_exec(bContext *C, wmOperator *op) 
+{
+       Scene *scene = CTX_data_scene(C);
+       Object *ob= CTX_data_active_object(C);
+       
+       /* only clear those channels that are not locked */
+       CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) {
+               if (pchan->protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ)) {
+                       float eul[3], oldeul[3], quat1[4];
+                       
+                       if (pchan->rotmode == PCHAN_ROT_QUAT) {
+                               QUATCOPY(quat1, pchan->quat);
+                               QuatToEul(pchan->quat, oldeul);
+                       }
+                       else {
+                               VECCOPY(oldeul, pchan->eul);
+                       }
+                       eul[0]= eul[1]= eul[2]= 0.0f;
+                       
+                       if (pchan->protectflag & OB_LOCK_ROTX)
+                               eul[0]= oldeul[0];
+                       if (pchan->protectflag & OB_LOCK_ROTY)
+                               eul[1]= oldeul[1];
+                       if (pchan->protectflag & OB_LOCK_ROTZ)
+                               eul[2]= oldeul[2];
+                       
+                       if (pchan->rotmode == PCHAN_ROT_QUAT) {
+                               EulToQuat(eul, pchan->quat);
+                               /* quaternions flip w sign to accumulate rotations correctly */
+                               if ((quat1[0]<0.0f && pchan->quat[0]>0.0f) || (quat1[0]>0.0f && pchan->quat[0]<0.0f)) {
+                                       QuatMulf(pchan->quat, -1.0f);
+                               }
+                       }
+                       else {
+                               VECCOPY(pchan->eul, eul);
+                       }
+               }                                               
+               else { 
+                       if (pchan->rotmode == PCHAN_ROT_QUAT) {
+                               pchan->quat[1]=pchan->quat[2]=pchan->quat[3]= 0.0f; 
+                               pchan->quat[0]= 1.0f;
+                       }
+                       else {
+                               pchan->eul[0]= pchan->eul[1]= pchan->eul[2]= 0.0f;
+                       }
+               }
+               
+               /* the current values from IPO's may not be zero, so tag as unkeyed */
+               //pchan->bone->flag |= BONE_UNKEYED;
+       }
+       CTX_DATA_END;
+       
+       DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+
+       /* note, notifier might evolve */
+       WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
+       
+       return OPERATOR_FINISHED;
+}
+
+void POSE_OT_rot_clear(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Clear Pose Rotation";
+       ot->idname= "POSE_OT_rot_clear";
+       
+       /* api callbacks */
+       ot->invoke = WM_operator_confirm;
+       ot->exec = pose_clear_rot_exec;
+       ot->poll = ED_operator_posemode;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+} 
 /* ************* hide/unhide pose bones ******************* */
 
 static int hide_selected_pose_bone(Object *ob, Bone *bone, void *ptr) 
@@ -4414,7 +4543,7 @@ void transform_armature_mirror_update(Object *obedit)
        for (ebo= arm->edbo->first; ebo; ebo=ebo->next) {
                /* no layer check, correct mirror is more important */
                if (ebo->flag & (BONE_TIPSEL|BONE_ROOTSEL)) {
-                       eboflip= armature_bone_get_mirrored(arm->edbo, ebo);
+                       eboflip= ED_armature_bone_get_mirrored(arm->edbo, ebo);
                        
                        if (eboflip) {
                                /* we assume X-axis flipping for now */
index bb883c5a98d3273f02ce1d32adb057b9aaa06926..ea0b492486e182857ba07abcf24b675ad1e27f59 100644 (file)
@@ -91,11 +91,10 @@ static void error() {};
 static void BIF_undo_push() {}
 static void countall() {}
 static void add_constraint() {}
-static void select_actionchannel_by_name() {}
 static void autokeyframe_pose_cb_func() {}
 /* ************* XXX *************** */
 
-
+/* This function is used to indicate that a bone is selected and needs keyframes inserted */
 void set_pose_keys (Object *ob)
 {
        bArmature *arm= ob->data;
@@ -104,16 +103,15 @@ void set_pose_keys (Object *ob)
        if (ob->pose){
                for (chan=ob->pose->chanbase.first; chan; chan=chan->next){
                        Bone *bone= chan->bone;
-                       if(bone && (bone->flag & BONE_SELECTED) && (arm->layer & bone->layer)) {
-                               chan->flag |= POSE_KEY;         
-                       }
-                       else {
+                       if ((bone) && (bone->flag & BONE_SELECTED) && (arm->layer & bone->layer))
+                               chan->flag |= POSE_KEY; 
+                       else
                                chan->flag &= ~POSE_KEY;
-                       }
                }
        }
 }
 
+/* This function is used to process the necessary updates for */
 void ED_armature_enter_posemode(bContext *C, Base *base)
 {
        Object *ob= base->object;
@@ -472,9 +470,7 @@ void pose_select_hierarchy(Scene *scene, short direction, short add_to_sel)
                                                curbone->flag &= ~BONE_ACTIVE;
                                                pabone->flag |= (BONE_ACTIVE|BONE_SELECTED);
                                                
-                                               // XXX this is evil... this sort of stuff is to be handled in one go as a result of a notifier
-                                               select_actionchannel_by_name (ob->action, pchan->name, 0);
-                                               select_actionchannel_by_name (ob->action, pchan->parent->name, 1);
+                                               // XXX notifiers need to be sent to other editors to update
                                                break;
                                        }
                                } else { // BONE_SELECT_CHILD
@@ -488,9 +484,7 @@ void pose_select_hierarchy(Scene *scene, short direction, short add_to_sel)
                                                curbone->flag &= ~BONE_ACTIVE;
                                                chbone->flag |= (BONE_ACTIVE|BONE_SELECTED);
                                                
-                                               // XXX this is evil... this sort of stuff is to be handled in one go as a result of a notifier
-                                               select_actionchannel_by_name (ob->action, pchan->name, 0);
-                                               select_actionchannel_by_name (ob->action, pchan->child->name, 1);
+                                               // XXX notifiers need to be sent to other editors to update
                                                break;
                                        }
                                }
@@ -1339,8 +1333,7 @@ void pose_activate_flipped_bone(Scene *scene)
                                        DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA);
                                }
                                
-                               // XXX this is evil... this sort of stuff is to be handled in one go as a result of a notifier
-                               select_actionchannel_by_name(ob->action, name, 1);
+                               // XXX notifiers need to be sent to other editors to update
                                
                        }                       
                }
@@ -1392,7 +1385,7 @@ void pose_movetolayer(Scene *scene)
                                if (ebo->flag & BONE_SELECTED) {
                                        ebo->layer= lay;
                                        if (arm->flag & ARM_MIRROR_EDIT) {
-                                               flipBone = armature_bone_get_mirrored(arm->edbo, ebo);
+                                               flipBone = ED_armature_bone_get_mirrored(arm->edbo, ebo);
                                                if (flipBone)
                                                        flipBone->layer = lay;
                                        }
index 075b10473923783040aca4b119d4be897f80d424..4962a238f2e18e47b3ff1af0d7babbe5624e528b 100644 (file)
@@ -66,6 +66,9 @@
 #include "BKE_object.h"
 #include "BKE_utildefines.h"
 
+#include "WM_api.h"
+#include "WM_types.h"
+
 #include "ED_anim_api.h"
 #include "ED_keyframes_edit.h"
 #include "ED_object.h"
@@ -2759,7 +2762,7 @@ void addsegment_nurb(Scene *scene)
 
 void mouse_nurb(bContext *C, short mval[2], int extend)
 {
-       Object *obedit= CTX_data_edit_object(C); // XXX
+       Object *obedit= CTX_data_edit_object(C); 
        ListBase *editnurb= curve_get_editcurve(obedit);
        Curve *cu= obedit->data;
        ViewContext vc;
@@ -2812,7 +2815,7 @@ void mouse_nurb(bContext *C, short mval[2], int extend)
 
        }
 
-//     rightmouse_transform();
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
        
        if(nu!=get_actNurb(obedit)) {
                set_actNurb(obedit, nu);
index 5039d5e0f7e2b5543369cb49e9d12a6b20033bc4..4375bd027d7cbb7b6fb268c7a0b1708364087fbd 100644 (file)
@@ -37,6 +37,7 @@ struct ListBase;
 struct wmEvent;
 struct bContext;
 struct Object;
+struct uiMenuItem;
 
 void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *keymap, int spaceid);
 void transform_operatortypes(void);
@@ -113,6 +114,7 @@ int BIF_menuselectTransformOrientation(void);
 void BIF_selectTransformOrientation(struct bContext *C, struct TransformOrientation *ts);
 void BIF_selectTransformOrientationValue(struct bContext *C, int orientation);
 
+void BIF_menuTransformOrientation(struct bContext *C, struct uiMenuItem *head, void *arg);
 char * BIF_menustringTransformOrientation(const struct bContext *C, char *title); /* the returned value was allocated and needs to be freed after use */
 int BIF_countTransformOrientation(const struct bContext *C);
 
index ee9f0a5bb6ec6f2480014c46a3c8c2c3e3a7098e..c0287380567e36f23ba0e3e3970400922e6fd2df 100644 (file)
@@ -304,12 +304,10 @@ void ANIM_nla_mapping_apply_fcurve(struct Object *ob, struct FCurve *fcu, short
 
 /* --------- anim_deps.c, animation updates -------- */
 
-       /* generic update flush, reads from Context screen (layers) and scene */
+       /* generic update flush, does tagged objects only, reads from Context screen (layers) and scene */
 void ED_anim_dag_flush_update(const struct bContext *C);
        /* only flush object */
 void ED_anim_object_flush_update(const struct bContext *C, struct Object *ob);
-       /* flush + do the actual update for all involved objects */
-void ED_update_for_newframe(const struct bContext *C, int mute);
 
 /* pose <-> action syncing */
 void ANIM_action_to_pose_sync(struct Object *ob);
index 4d22f30c44cac5c6b3c28c7bcd3725ae53de5c4f..9c17e002cb029f8d5d6333298ac4161cd2de1b1d 100644 (file)
@@ -100,6 +100,7 @@ int ED_do_pose_selectbuffer(struct Scene *scene, struct Base *base, unsigned int
 void mouse_armature(struct bContext *C, short mval[2], int extend);
 struct Bone *get_indexed_bone (struct Object *ob, int index);
 float ED_rollBoneToVector(EditBone *bone, float new_up_axis[3]);
+EditBone *ED_armature_bone_get_mirrored(struct ListBase *edbo, EditBone *ebo); // XXX this is needed for populating the context iterators
 
 void transform_armature_mirror_update(struct Object *obedit);
 void clear_armature(struct Scene *scene, struct Object *ob, char mode);
index ac73aa10e4f9880908166c40450bb71b91b80d17..84225d858779e365ae88e3b6365e7b3e4d880a9e 100644 (file)
 #define ED_IMAGE_H
 
 struct SpaceImage;
+struct bContext;
 
 /* space_image.c, exported for transform */
 struct Image *ED_space_image(struct SpaceImage *sima);
 void ED_space_image_size(struct SpaceImage *sima, int *width, int *height);
 void ED_space_image_uv_aspect(struct SpaceImage *sima, float *aspx, float *aspy);
 
+/* image_render.c, export for screen_ops.c, render operator */
+void ED_space_image_output(struct bContext *C);
+
 #endif /* ED_IMAGE_H */
 
index 5a72ab201f42df1896e5e7e624642bb1713e03e3..bd997e93e9b62d3049a521357c86add3f48754ca 100644 (file)
@@ -112,6 +112,8 @@ void             EM_add_data_layer(struct EditMesh *em, struct CustomData *data,
 void           EM_select_edge(struct EditEdge *eed, int sel);
 void           EM_select_face(struct EditFace *efa, int sel);
 void           EM_select_face_fgon(struct EditMesh *em, struct EditFace *efa, int val);
+void           EM_select_swap(struct EditMesh *em);
+void           EM_toggle_select_all(struct EditMesh *em);
 void           EM_selectmode_flush(struct EditMesh *em);
 void           EM_deselect_flush(struct EditMesh *em);
 void           EM_selectmode_set(struct EditMesh *em);
index 00740b20b4c4cff03a24316e2b5bfa19e6bf9daf..b5e2558c893b541cf8d2d328d215c86a3769051c 100644 (file)
@@ -39,12 +39,14 @@ struct wmNotifier;
 struct wmEvent;
 struct bContext;
 struct SpaceType;
-struct AreagionType;
+struct Scene;
+struct bScreen;
+struct ARegion;
 struct uiBlock;
 struct rcti;
 
 /* regions */
-void   ED_region_do_listen(ARegion *ar, struct wmNotifier *note);
+void   ED_region_do_listen(struct ARegion *ar, struct wmNotifier *note);
 void   ED_region_do_draw(struct bContext *C, struct ARegion *ar);
 void   ED_region_exit(struct bContext *C, struct ARegion *ar);
 void   ED_region_pixelspace(struct ARegion *ar);
@@ -78,12 +80,17 @@ void        ED_screen_draw(struct wmWindow *win);
 void   ED_screen_refresh(struct wmWindowManager *wm, struct wmWindow *win);
 void   ED_screen_do_listen(struct wmWindow *win, struct wmNotifier *note);
 bScreen *ED_screen_duplicate(struct wmWindow *win, struct bScreen *sc);
+void   ED_screen_set(struct bContext *C, struct bScreen *sc);
+void   ED_screen_set_scene(struct bContext *C, struct Scene *scene);
 void   ED_screen_set_subwinactive(struct wmWindow *win, struct wmEvent *event);
 void   ED_screen_exit(struct bContext *C, struct wmWindow *window, struct bScreen *screen);
 void   ED_screen_animation_timer(struct bContext *C, int enable);
-void   ED_screen_full_newspace(struct bContext *C, ScrArea *sa, int type);
+int            ED_screen_full_newspace(struct bContext *C, ScrArea *sa, int type);
 void   ED_screen_full_prevspace(struct bContext *C);
 
+/* anim */
+void   ED_update_for_newframe(const struct bContext *C, int mute);
+unsigned int ED_screen_view3d_layers(struct bScreen *screen);
 
 void   ED_operatortypes_screen(void);
 void   ED_keymap_screen(struct wmWindowManager *wm);
@@ -104,12 +111,14 @@ int               ED_operator_buttons_active(struct bContext *C);
 int            ED_operator_node_active(struct bContext *C);
 int            ED_operator_ipo_active(struct bContext *C);
 int            ED_operator_sequencer_active(struct bContext *C);
+int            ED_operator_image_active(struct bContext *C);
 
 int            ED_operator_object_active(struct bContext *C);
 int            ED_operator_editmesh(struct bContext *C);
 int            ED_operator_editarmature(struct bContext *C);
 int            ED_operator_editcurve(struct bContext *C);
 int            ED_operator_uvedit(struct bContext *C);
+int            ED_operator_uvmap(struct bContext *C);
 int            ED_operator_posemode(struct bContext *C);
 
 
index 6f0c475f39c2af1e7344175c0f82948b5dbede19..7002524be7e27e03d21bfb92fed268c4f6b0c18b 100644 (file)
@@ -44,6 +44,7 @@ void  ED_editors_exit                 (struct bContext *C);
 /* undo.c */
 void   ED_undo_push                    (struct bContext *C, char *str);
 void   ED_undo_push_op                 (struct bContext *C, struct wmOperator *op);
+void   ED_undo_pop                             (struct bContext *C);
 void   ED_OT_undo                              (struct wmOperatorType *ot);
 void   ED_OT_redo                              (struct wmOperatorType *ot);
 
index 8ad4ea2a1e759e9e8fdd0c7cfcc574dc4d8e4003..575654f49b1669ba4d1132b2e0d3a9cc0ccd6b77 100644 (file)
@@ -33,6 +33,7 @@
 /* Struct Declarations */
 
 struct ID;
+struct Main;
 struct ListBase;
 struct ARegion;
 struct wmWindow;
@@ -210,11 +211,12 @@ void uiMenuContext(uiMenuItem *head, int opcontext);
 
 void uiMenuItemVal(uiMenuItem *head, const char *name, int icon, int argval);
 
-void uiMenuItemEnumO(uiMenuItem *head, char *opname, char *propname, int value);
-void uiMenuItemBooleanO(uiMenuItem *head, char *opname, char *propname, int value);
+void uiMenuItemEnumO(uiMenuItem *head, int icon, char *opname, char *propname, int value);
+void uiMenuItemBooleanO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, int value);
 void uiMenuItemsEnumO(uiMenuItem *head, char *opname, char *propname);
-void uiMenuItemFloatO(uiMenuItem *head, const char *name, char *opname, char *propname, float value);
-void uiMenuItemO(uiMenuItem *head, char *name, int icon);
+void uiMenuItemIntO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, int value);
+void uiMenuItemFloatO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, float value);
+void uiMenuItemO(uiMenuItem *head, int icon, char *opname);
 
 void uiMenuItemBooleanR(uiMenuItem *head, struct PointerRNA *ptr, char *propname);
 void uiMenuItemEnumR(uiMenuItem *head, struct PointerRNA *ptr, char *propname, int value);
@@ -233,11 +235,10 @@ void uiMenuSeparator(uiMenuItem *head);
  * the uiMenu functions inbetween. If it is a simple confirmation menu
  * or similar, popups can be created with a single function call. */
 
-uiMenuItem *uiPupMenuBegin(const char *title);
+uiMenuItem *uiPupMenuBegin(const char *title, int icon);
 void uiPupMenuEnd(struct bContext *C, struct uiMenuItem *head);
 
 void uiPupMenu(struct bContext *C, int maxrow, uiMenuHandleFunc func, void *arg, char *str, ...);
-void uiPupMenuOperator(struct bContext *C, int maxrow, struct  wmOperator *op, const char *propname, char *str);
 void uiPupMenuOkee(struct bContext *C, char *opname, char *str, ...);
 void uiPupMenuSaveOver(struct bContext *C, char *opname, char *filename, ...);
 void uiPupMenuNotice(struct bContext *C, char *str, ...);
@@ -251,8 +252,10 @@ void uiPupMenuSetActive(int val);
  * Functions used to create popup blocks. These are like popup menus
  * but allow using all button types and creating an own layout. */
 
-uiBlock *uiPupBlockBegin(struct bContext *C, const char *title);
-void uiPupBlockEnd(struct bContext *C, uiBlock *block);
+typedef uiBlock* (*uiBlockCreateFunc)(struct bContext *C, struct ARegion *ar, void *arg1);
+
+void uiPupBlock(struct bContext *C, uiBlockCreateFunc func, void *arg);
+void uiPupBlockO(struct bContext *C, uiBlockCreateFunc func, void *arg, char *opname, int opcontext);
 
 /* Blocks
  *
@@ -295,7 +298,8 @@ void uiBlockEndAlign(uiBlock *block);
 
 void uiBoundsBlock(struct uiBlock *block, int addval);
 void uiTextBoundsBlock(uiBlock *block, int addval);
-void uiPopupBoundsBlock(uiBlock *block, int addval);
+void uiPopupBoundsBlock(uiBlock *block, int addval, int mx, int my);
+void uiMenuPopupBoundsBlock(uiBlock *block, int addvall, int mx, int my);
 
 int            uiBlocksGetYMin         (ListBase *lb);
 int            uiBlockGetCol           (uiBlock *block);
@@ -389,13 +393,28 @@ struct PointerRNA *uiButGetOperatorPtrRNA(uiBut *but);
  * - PulldownBut: like MenuBut, but creating a uiBlock (for compatibility).
  * - BlockBut: buttons that popup a block with more buttons.
  * - KeyevtBut: buttons that can be used to turn key events into values.
- * - PickerButtons: buttons like the color picker (for code sharing). */
-
-typedef uiBlock* (*uiBlockCreateFunc)(struct bContext *C, struct ARegion *ar, void *arg1);
-typedef void     (*uiIDPoinFuncFP)(struct bContext *C, char *str, struct ID **idpp);
-
-uiBut *uiDefIDPoinBut(struct uiBlock *block, uiIDPoinFuncFP func, short blocktype, int retval, char *str,
+ * - PickerButtons: buttons like the color picker (for code sharing).
+ * - AutoButR: RNA property button with type automatically defined. */
+
+#define UI_ID_RENAME           1
+#define UI_ID_BROWSE           2
+#define UI_ID_ADD_NEW          4
+#define UI_ID_OPEN                     8
+#define UI_ID_ALONE                    16
+#define UI_ID_DELETE           32
+#define UI_ID_LOCAL                    64
+#define UI_ID_AUTO_NAME                128
+#define UI_ID_FAKE_USER                256
+#define UI_ID_PIN                      512
+#define UI_ID_BROWSE_RENDER    1024
+#define UI_ID_FULL                     (UI_ID_RENAME|UI_ID_BROWSE|UI_ID_ADD_NEW|UI_ID_OPEN|UI_ID_ALONE|UI_ID_DELETE|UI_ID_LOCAL)
+
+typedef void (*uiIDPoinFuncFP)(struct bContext *C, char *str, struct ID **idpp);
+typedef void (*uiIDPoinFunc)(struct bContext *C, struct ID *id, int event);
+
+uiBut *uiDefIDPoinBut(uiBlock *block, uiIDPoinFuncFP func, short blocktype, int retval, char *str,
                                                short x1, short y1, short x2, short y2, void *idpp, char *tip);
+int uiDefIDPoinButs(uiBlock *block, struct Main *main, struct ID *parid, struct ID **id_p, int id_code, short *pin_p, int x, int y, uiIDPoinFunc func, int events);
 
 uiBut *uiDefPulldownBut(uiBlock *block, uiBlockCreateFunc func, void *arg, char *str, short x1, short y1, short x2, short y2, char *tip);
 uiBut *uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, char *str, short x1, short y1, short x2, short y2, char *tip);
@@ -409,6 +428,9 @@ void uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1,
 
 void uiBlockPickerButtons(struct uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval);
 
+uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, char *name, int x1, int y1, int x2, int y2);
+int uiDefAutoButsRNA(uiBlock *block, struct PointerRNA *ptr);
+
 /* Links
  *
  * Game engine logic brick links. Non-functional currently in 2.5,
@@ -428,9 +450,12 @@ uiBut *uiFindInlink(uiBlock *block, void *poin);
  * uiButSetCompleteFunc is for tab completion.
  *
  * uiBlockSetFunc and uiButSetFunc are callbacks run when a button is used,
- * in case events, operators or RNA are not sufficient to handle the button. */
+ * in case events, operators or RNA are not sufficient to handle the button.
+ *
+ * uiButSetNFunc will free the argument with MEM_freeN. */
 
 typedef void (*uiButHandleFunc)(struct bContext *C, void *arg1, void *arg2);
+typedef void (*uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2);
 typedef void (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg);
 typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event);
 
@@ -439,6 +464,7 @@ void        uiBlockSetButmFunc      (uiBlock *block,        uiMenuHandleFunc func, void *arg);
 
 void   uiBlockSetFunc          (uiBlock *block,        uiButHandleFunc func, void *arg1, void *arg2);
 void   uiButSetFunc            (uiBut *but,            uiButHandleFunc func, void *arg1, void *arg2);
+void   uiButSetNFunc           (uiBut *but,            uiButHandleNFunc func, void *argN, void *arg2);
 
 void   uiButSetCompleteFunc(uiBut *but,                uiButCompleteFunc func, void *arg);
 
index 939c5b005c297186a1ca044e8e2d8bfca7312367..5012a71a64723f8011ea04dcd3bb343f8fda7084 100644 (file)
@@ -878,6 +878,7 @@ enum {
 /* specific defines per space should have higher define values */
 
 struct bTheme;
+struct PointerRNA;
 
 // THE CODERS API FOR THEMES:
 
@@ -919,6 +920,8 @@ void        UI_ColorPtrBlendShade3ubv(char *cp1, char *cp2, float fac, int offset);
 // get a 3 byte color, blended and shaded between two other char color pointers
 void   UI_GetColorPtrBlendShade3ubv(char *cp1, char *cp2, char *col, float fac, int offset);
 
+// get pointer from RNA pointer
+int            UI_GetIconRNA(struct PointerRNA *ptr);
 
 struct ScrArea;
 
index ce842699ce2b0171b26d3274a91d963832904df7..a2f272767cbbdb39de45eef6603e7de280286188 100644 (file)
@@ -304,23 +304,28 @@ void ui_bounds_block(uiBlock *block)
        block->safety.ymax= block->maxy+xof;
 }
 
-static void ui_popup_bounds_block(const bContext *C, uiBlock *block)
+static void ui_popup_bounds_block(const bContext *C, uiBlock *block, int menu)
 {
+       wmWindow *window= CTX_wm_window(C);
        int startx, starty, endx, endy, width, height;
        int oldbounds, mx, my, xmax, ymax;
 
        oldbounds= block->bounds;
 
-       /* compute bounds */
+       /* compute mouse position with user defined offset */
        ui_bounds_block(block);
-       mx= block->minx;
-       my= block->miny;
+       mx= window->eventstate->x + block->minx + block->mx;
+       my= window->eventstate->y + block->miny + block->my;
 
-       wm_window_get_size(CTX_wm_window(C), &xmax, &ymax);
+       wm_window_get_size(window, &xmax, &ymax);
 
        /* first we ensure wide enough text bounds */
-       block->bounds= 50;
-       ui_text_bounds_block(block, block->minx);
+       if(menu) {
+               if(block->flag & UI_BLOCK_LOOP) {
+                       block->bounds= 50;
+                       ui_text_bounds_block(block, block->minx);
+               }
+       }
 
        /* next we recompute bounds */
        block->bounds= oldbounds;
@@ -373,11 +378,22 @@ void uiTextBoundsBlock(uiBlock *block, int addval)
        block->dobounds= 2;
 }
 
-/* used for menu popups */
-void uiPopupBoundsBlock(uiBlock *block, int addval)
+/* used for block popups */
+void uiPopupBoundsBlock(uiBlock *block, int addval, int mx, int my)
 {
        block->bounds= addval;
        block->dobounds= 3;
+       block->mx= mx;
+       block->my= my;
+}
+
+/* used for menu popups */
+void uiMenuPopupBoundsBlock(uiBlock *block, int addval, int mx, int my)
+{
+       block->bounds= addval;
+       block->dobounds= 4;
+       block->mx= mx;
+       block->my= my;
 }
 
 void ui_autofill(uiBlock *block)
@@ -487,13 +503,14 @@ static int ui_but_equals_old(uiBut *but, uiBut *oldbut)
        /* various properties are being compared here, hopfully sufficient
         * to catch all cases, but it is simple to add more checks later */
        if(but->retval != oldbut->retval) return 0;
-       if(but->poin != oldbut->poin || but->pointype != oldbut->pointype) return 0;
        if(but->rnapoin.data != oldbut->rnapoin.data) return 0;
        if(but->rnaprop != oldbut->rnaprop)
        if(but->rnaindex != oldbut->rnaindex) return 0;
        if(but->func != oldbut->func) return 0;
+       if(but->funcN != oldbut->funcN) return 0;
        if(oldbut->func_arg1 != oldbut && but->func_arg1 != oldbut->func_arg1) return 0;
        if(oldbut->func_arg2 != oldbut && but->func_arg2 != oldbut->func_arg2) return 0;
+       if(!but->funcN && (but->poin != oldbut->poin || but->pointype != oldbut->pointype)) return 0;
 
        return 1;
 }
@@ -594,7 +611,7 @@ void uiEndBlock(const bContext *C, uiBlock *block)
        /* after keymaps! */
        if(block->dobounds == 1) ui_bounds_block(block);
        else if(block->dobounds == 2) ui_text_bounds_block(block, 0.0f);
-       else if(block->dobounds == 3) ui_popup_bounds_block(C, block);
+       else if(block->dobounds) ui_popup_bounds_block(C, block, (block->dobounds == 4));
 
        if(block->autofill) ui_autofill(block);
        if(block->minx==0.0 && block->maxx==0.0) uiBoundsBlock(block, 0);
@@ -886,8 +903,10 @@ static int ui_do_but_LINK(uiBlock *block, uiBut *but)
 
 void uiBlockSetButLock(uiBlock *block, int val, char *lockstr)
 {
-       block->lock |= val;
-       if(val) block->lockstr= lockstr;
+       if(val) {
+               block->lock |= val;
+               block->lockstr= lockstr;
+       }
 }
 
 void uiBlockClearButLock(uiBlock *block)
@@ -1480,6 +1499,7 @@ static void ui_free_but(const bContext *C, uiBut *but)
                WM_operator_properties_free(but->opptr);
                MEM_freeN(but->opptr);
        }
+       if(but->func_argN) MEM_freeN(but->func_argN);
        if(but->active) ui_button_active_cancel(C, but);
        if(but->str && but->str != but->strdata) MEM_freeN(but->str);
        ui_free_link(but->link);
@@ -2836,19 +2856,19 @@ PointerRNA *uiButGetOperatorPtrRNA(uiBut *but)
        return but->opptr;
 }
 
-void uiBlockSetHandleFunc(uiBlock *block, void (*func)(struct bContext *C, void *arg, int event), void *arg)
+void uiBlockSetHandleFunc(uiBlock *block, uiBlockHandleFunc func, void *arg)
 {
        block->handle_func= func;
        block->handle_func_arg= arg;
 }
 
-void uiBlockSetButmFunc(uiBlock *block, void (*func)(struct bContext *C, void *arg, int but_a2), void *arg)
+void uiBlockSetButmFunc(uiBlock *block, uiMenuHandleFunc func, void *arg)
 {
        block->butm_func= func;
        block->butm_func_arg= arg;
 }
 
-void uiBlockSetFunc(uiBlock *block, void (*func)(struct bContext *C, void *arg1, void *arg2), void *arg1, void *arg2)
+void uiBlockSetFunc(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2)
 {
        block->func= func;
        block->func_arg1= arg1;
@@ -2860,14 +2880,21 @@ void uiBlockSetDrawExtraFunc(uiBlock *block, void (*func)())
        block->drawextra= func;
 }
 
-void uiButSetFunc(uiBut *but, void (*func)(struct bContext *C, void *arg1, void *arg2), void *arg1, void *arg2)
+void uiButSetFunc(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)
 {
        but->func= func;
        but->func_arg1= arg1;
        but->func_arg2= arg2;
 }
 
-void uiButSetCompleteFunc(uiBut *but, void (*func)(struct bContext *C, char *str, void *arg), void *arg)
+void uiButSetNFunc(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2)
+{
+       but->funcN= funcN;
+       but->func_argN= argN;
+       but->func_arg2= arg2;
+}
+
+void uiButSetCompleteFunc(uiBut *but, uiButCompleteFunc func, void *arg)
 {
        but->autocomplete_func= func;
        but->autofunc_arg= arg;
index f2275a18db40009774b6eda4eacfc3db8f0d14cd..c23124de5861803d3b497cf4b185933f909a69ca 100644 (file)
@@ -23,6 +23,7 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
+#include <float.h>
 #include <math.h>
 #include <stdlib.h>
 #include <string.h>
@@ -133,15 +134,18 @@ typedef struct uiHandleButtonData {
 typedef struct uiAfterFunc {
        struct uiAfterFunc *next, *prev;
 
-       void (*func)(struct bContext*, void *, void *);
+       uiButHandleFunc func;
        void *func_arg1;
        void *func_arg2;
 
-       void (*handle_func)(struct bContext*, void *arg, int event);
+       uiButHandleNFunc funcN;
+       void *func_argN;
+
+       uiBlockHandleFunc handle_func;
        void *handle_func_arg;
        int retval;
 
-       void (*butm_func)(struct bContext*, void *arg, int event);
+       uiMenuHandleFunc butm_func;
        void *butm_func_arg;
        int a2;
 
@@ -216,13 +220,16 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
         * handling is done, i.e. menus are closed, in order to avoid conflicts
         * with these functions removing the buttons we are working with */
 
-       if(but->func || block->handle_func || (but->type == BUTM && block->butm_func) || but->opname || but->rnaprop) {
+       if(but->func || but->funcN || block->handle_func || (but->type == BUTM && block->butm_func) || but->opname || but->rnaprop) {
                after= MEM_callocN(sizeof(uiAfterFunc), "uiAfterFunc");
 
                after->func= but->func;
                after->func_arg1= but->func_arg1;
                after->func_arg2= but->func_arg2;
 
+               after->funcN= but->funcN;
+               after->func_argN= but->func_argN;
+
                after->handle_func= block->handle_func;
                after->handle_func_arg= block->handle_func_arg;
                after->retval= but->retval;
@@ -250,34 +257,37 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
 
 static void ui_apply_but_funcs_after(bContext *C)
 {
-       uiAfterFunc *after;
+       uiAfterFunc *afterf, after;
        ListBase funcs;
 
        /* copy to avoid recursive calls */
        funcs= UIAfterFuncs;
        UIAfterFuncs.first= UIAfterFuncs.last= NULL;
 
-       for(after=funcs.first; after; after=after->next) {
-               if(after->func)
-                       after->func(C, after->func_arg1, after->func_arg2);
+       for(afterf=funcs.first; afterf; afterf=after.next) {
+               after= *afterf; /* copy to avoid memleak on exit() */
+               BLI_freelinkN(&funcs, afterf);
+
+               if(after.func)
+                       after.func(C, after.func_arg1, after.func_arg2);
+               if(after.funcN)
+                       after.funcN(C, after.func_argN, after.func_arg2);
                
-               if(after->handle_func)
-                       after->handle_func(C, after->handle_func_arg, after->retval);
-               if(after->butm_func)
-                       after->butm_func(C, after->butm_func_arg, after->a2);
+               if(after.handle_func)
+                       after.handle_func(C, after.handle_func_arg, after.retval);
+               if(after.butm_func)
+                       after.butm_func(C, after.butm_func_arg, after.a2);
 
-               if(after->opname)
-                       WM_operator_name_call(C, after->opname, after->opcontext, after->opptr);
-               if(after->opptr) {
-                       WM_operator_properties_free(after->opptr);
-                       MEM_freeN(after->opptr);
+               if(after.opname)
+                       WM_operator_name_call(C, after.opname, after.opcontext, after.opptr);
+               if(after.opptr) {
+                       WM_operator_properties_free(after.opptr);
+                       MEM_freeN(after.opptr);
                }
 
-               if(after->rnapoin.data)
-                       RNA_property_update(C, &after->rnapoin, after->rnaprop);
+               if(after.rnapoin.data)
+                       RNA_property_update(C, &after.rnapoin, after.rnaprop);
        }
-
-       BLI_freelistN(&funcs);
 }
 
 static void ui_apply_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data)
@@ -1373,9 +1383,18 @@ static void ui_do_but_textedit_select(bContext *C, uiBlock *block, uiBut *but, u
 
 /* ************* number editing for various types ************* */
 
+static void but_clamped_range(uiBut *but, float *butmin, float *butmax, float *butrange)
+{
+       /* clamp button range to something reasonable in case
+        * we get -inf/inf from RNA properties */
+       *butmin= MAX2(but->min, -1e4f);
+       *butmax= MIN2(but->max, 1e4f);
+       *butrange= *butmax - *butmin;
+}
+
 static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data)
 {
-       float butrange;
+       float butrange, butmin, butmax;
 
        if(but->type == BUT_CURVE) {
                data->cumap= (CurveMapping*)but->poin;
@@ -1395,8 +1414,9 @@ static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data)
                data->value= data->origvalue;
                but->editval= &data->value;
 
-               butrange= (but->max - but->min);
-               data->dragfstart= (butrange == 0.0)? 0.0f: (data->value - but->min)/butrange;
+               but_clamped_range(but, &butmin, &butmax, &butrange);
+
+               data->dragfstart= (butrange == 0.0)? 0.0f: (data->value - butmin)/butrange;
                data->dragf= data->dragfstart;
        }
 
@@ -1603,7 +1623,7 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, wmE
 
 static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, int snap, int mx)
 {
-       float deler, tempf;
+       float deler, tempf, butmin, butmax, butrange;
        int lvalue, temp, changed= 0;
        
        if(mx == data->draglastx)
@@ -1619,28 +1639,30 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
                data->dragstartx= mx;  /* ignore mouse movement within drag-lock */
        }
 
+       but_clamped_range(but, &butmin, &butmax, &butrange);
+
        deler= 500;
        if(!ui_is_but_float(but)) {
-               if((but->max-but->min)<100) deler= 200.0;
-               if((but->max-but->min)<25) deler= 50.0;
+               if((butrange)<100) deler= 200.0;
+               if((butrange)<25) deler= 50.0;
        }
        deler /= fac;
 
-       if(ui_is_but_float(but) && but->max-but->min > 11) {
+       if(ui_is_but_float(but) && butrange > 11) {
                /* non linear change in mouse input- good for high precicsion */
                data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.002);
-       } else if (!ui_is_but_float(but) && but->max-but->min > 129) { /* only scale large int buttons */
+       } else if (!ui_is_but_float(but) && butrange > 129) { /* only scale large int buttons */
                /* non linear change in mouse input- good for high precicsionm ints need less fine tuning */
                data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.004);
        } else {
                /*no scaling */
                data->dragf+= ((float)(mx-data->draglastx))/deler ;
        }
-       
+
        if(data->dragf>1.0) data->dragf= 1.0;
        if(data->dragf<0.0) data->dragf= 0.0;
        data->draglastx= mx;
-       tempf= ( but->min + data->dragf*(but->max-but->min));
+       tempf= (butmin + data->dragf*butrange);
        
        if(!ui_is_but_float(but)) {
                
@@ -1667,14 +1689,14 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
                if(snap) {
                        if(snap == 2) {
                                if(tempf==but->min || tempf==but->max);
-                               else if(but->max-but->min < 2.10) tempf= 0.01*floor(100.0*tempf);
-                               else if(but->max-but->min < 21.0) tempf= 0.1*floor(10.0*tempf);
+                               else if(butrange < 2.10) tempf= 0.01*floor(100.0*tempf);
+                               else if(butrange < 21.0) tempf= 0.1*floor(10.0*tempf);
                                else tempf= floor(tempf);
                        }
                        else {
                                if(tempf==but->min || tempf==but->max);
-                               else if(but->max-but->min < 2.10) tempf= 0.1*floor(10*tempf);
-                               else if(but->max-but->min < 21.0) tempf= floor(tempf);
+                               else if(butrange < 2.10) tempf= 0.1*floor(10*tempf);
+                               else if(butrange < 21.0) tempf= floor(tempf);
                                else tempf= 10.0*floor(tempf/10.0);
                        }
                }
@@ -1818,9 +1840,11 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
 
 static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, int shift, int ctrl, int mx)
 {
-       float deler, f, tempf;
+       float deler, f, tempf, butmin, butmax, butrange;
        int temp, lvalue, changed= 0;
 
+       but_clamped_range(but, &butmin, &butmax, &butrange);
+
        if(but->type==NUMSLI) deler= ((but->x2-but->x1)/2 - 5.0*but->aspect);
        else if(but->type==HSVSLI) deler= ((but->x2-but->x1)/2 - 5.0*but->aspect);
        else deler= (but->x2-but->x1- 5.0*but->aspect);
@@ -1831,7 +1855,7 @@ static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, int shift, i
                f= (f-data->dragfstart)/10.0 + data->dragfstart;
 
        CLAMP(f, 0.0, 1.0);
-       tempf= but->min+f*(but->max-but->min);          
+       tempf= butmin + f*butrange;
        temp= floor(tempf+.5);
 
        if(ctrl) {
@@ -1927,11 +1951,13 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
 
        if(click) {
                float f, h;
-               float tempf;
+               float tempf, butmin, butmax, butrange;
                int temp;
                
                button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
 
+               but_clamped_range(but, &butmin, &butmax, &butrange);
+
                tempf= data->value;
                temp= (int)data->value;
 
@@ -1940,7 +1966,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
                if(but->type==SLI) f= (float)(mx-but->x1)/(but->x2-but->x1-h);
                else f= (float)(mx- (but->x1+but->x2)/2)/((but->x2-but->x1)/2 - h);
                
-               f= but->min+f*(but->max-but->min);
+               f= butmin + f*butrange;
 
                if(!ui_is_but_float(but)) {
                        if(f<temp) temp--;
@@ -2593,6 +2619,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
        data= but->active;
        retval= WM_UI_HANDLER_CONTINUE;
 
+       if(but->flag & UI_BUT_DISABLED)
+               return WM_UI_HANDLER_BREAK;
+
        /* handle copy-paste */
        if(data->state == BUTTON_STATE_HIGHLIGHT) {
                if(ELEM(event->type, CKEY, VKEY) && event->val==KM_PRESS && (event->ctrl || event->oskey)) {
@@ -2848,7 +2877,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
                button_tooltip_timer_reset(but);
 
                /* automatic open pulldown block timer */
-               if(ELEM5(but->type, BLOCK, MENU, PULLDOWN, HMENU, ICONTEXTROW)) {
+               if(ELEM4(but->type, BLOCK, PULLDOWN, HMENU, ICONTEXTROW)) {
                        if(!data->autoopentimer) {
                                int time;
 
@@ -3510,8 +3539,18 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle *menu,
        if((/*inside &&*/ !menu->menuretval && retval == WM_UI_HANDLER_CONTINUE) || event->type == TIMER) {
                but= ui_but_find_activated(ar);
 
-               if(but)
+               if(but) {
+                       ScrArea *ctx_area= CTX_wm_area(C);
+                       ARegion *ctx_region= CTX_wm_region(C);
+                       
+                       if(menu->ctx_area) CTX_wm_area_set(C, menu->ctx_area);
+                       if(menu->ctx_region) CTX_wm_region_set(C, menu->ctx_region);
+                       
                        retval= ui_handle_button_event(C, event, but);
+                       
+                       if(menu->ctx_area) CTX_wm_area_set(C, ctx_area);
+                       if(menu->ctx_region) CTX_wm_region_set(C, ctx_region);
+               }
                else
                        retval= ui_handle_button_over(C, event, ar);
        }
@@ -3709,19 +3748,11 @@ static int ui_handler_popup(bContext *C, wmEvent *event, void *userdata)
                WM_event_remove_ui_handler(&CTX_wm_window(C)->handlers, ui_handler_popup, ui_handler_remove_popup, menu);
 
                if(temp.menuretval == UI_RETURN_OK) {
-                       if(temp.popup_func) {
-                               temp.popup_func(C, temp.op_arg, temp.retvalue);
-                       }
-                       else if(temp.op_arg) {
-                               if(temp.propname)
-                                       RNA_enum_set(temp.op_arg->ptr, temp.propname, temp.retvalue);
-                               WM_operator_call(C, temp.op_arg);
-                       }
+                       if(temp.popup_func)
+                               temp.popup_func(C, temp.popup_arg, temp.retvalue);
+                       if(temp.opname)
+                               WM_operator_name_call(C, temp.opname, temp.opcontext, NULL);
                }
-               /* always free operator */
-               else if(temp.op_arg)
-                       WM_operator_free(temp.op_arg);
-               
        }
        else {
                /* re-enable tooltips */
@@ -3757,3 +3788,4 @@ void UI_add_popup_handlers(ListBase *handlers, uiPopupBlockHandle *menu)
 {
        WM_event_add_ui_handler(NULL, handlers, ui_handler_popup, ui_handler_remove_popup, menu);
 }
+
index d66c6e4129e5a8007c30ff168103cd7e1f64d7ca..4f3b211c9deb8381f66558c78cadd91abfc2202e 100644 (file)
@@ -125,6 +125,9 @@ struct uiBut {
        void *func_arg1;
        void *func_arg2;
 
+       uiButHandleNFunc funcN;
+       void *func_argN;
+
        void (*embossfunc)(int , int , float, float, float, float, float, int);
        void (*sliderfunc)(int , float, float, float, float, float, float, int);
 
@@ -218,7 +221,7 @@ struct uiBlock {
        char *lockstr;
        
        float xofs, yofs;                               // offset to parent button
-       int bounds, dobounds;                   // for doing delayed
+       int bounds, dobounds, mx, my;   // for doing delayed
        int endblock;                                   // uiEndBlock done?
 
        rctf safety;                            // pulldowns, to detect outside, can differ per case how it is created
@@ -277,9 +280,12 @@ struct uiPopupBlockHandle {
        int popup;
        void (*popup_func)(struct bContext *C, void *arg, int event);
        void *popup_arg;
-       /* for operator menus */
-       struct wmOperator *op_arg;
-       const char *propname;
+
+       /* for operator popups */
+       const char *opname;
+       int opcontext;
+       ScrArea *ctx_area;
+       ARegion *ctx_region;
        
        /* return values */
        int butretval;
index 7fb3567033b95f79ef4e9a613080412c57725792..4dd5dd766375a439c942ed905e0cc0db39cfd0df 100644 (file)
@@ -635,6 +635,10 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
        /* create handle */
        handle= MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
 
+       /* store context for operator */
+       handle->ctx_area= CTX_wm_area(C);
+       handle->ctx_region= CTX_wm_region(C);
+       
        /* create area region */
        ar= ui_add_temporary_region(CTX_wm_screen(C));
 
@@ -1657,13 +1661,14 @@ static uiBlock *ui_block_func_MENU_ITEM(bContext *C, uiPopupBlockHandle *handle,
 #define MENU_ITEM_OPNAME                       2
 #define MENU_ITEM_OPNAME_BOOL          3
 #define MENU_ITEM_OPNAME_ENUM          4
-#define MENU_ITEM_OPNAME_FLOAT         5
-#define MENU_ITEM_RNA_BOOL                     6
-#define MENU_ITEM_RNA_ENUM                     7
-#define MENU_ITEM_LEVEL                                8
-#define MENU_ITEM_LEVEL_OPNAME_ENUM    9
-#define MENU_ITEM_LEVEL_RNA_ENUM       10
-#define MENU_ITEM_SEPARATOR                    11
+#define MENU_ITEM_OPNAME_INT           5
+#define MENU_ITEM_OPNAME_FLOAT         6
+#define MENU_ITEM_RNA_BOOL                     7
+#define MENU_ITEM_RNA_ENUM                     8
+#define MENU_ITEM_LEVEL                                9
+#define MENU_ITEM_LEVEL_OPNAME_ENUM    10
+#define MENU_ITEM_LEVEL_RNA_ENUM       11
+#define MENU_ITEM_SEPARATOR                    12
 
 struct uiMenuItem {
        struct uiMenuItem *next, *prev;
@@ -1675,7 +1680,7 @@ struct uiMenuItem {
        char *opname;   /* static string */
        char *propname; /* static string */
        
-       int retval, enumval, boolval;
+       int retval, enumval, boolval, intval;
        float fltval;
        int opcontext;
        uiMenuHandleFunc eventfunc;
@@ -1762,15 +1767,15 @@ static uiBlock *ui_block_func_MENU_ITEM(bContext *C, uiPopupBlockHandle *handle,
        block->themecol= TH_MENU_ITEM;
        block->direction= UI_DOWN;
 
-       width= 50; // fixed with, uiPopupBoundsBlock will compute actual width
+       width= 50; // fixed with, uiMenuPopupBoundsBlock will compute actual width
 
        for(item= head->items.first; item; item= item->next) {
                if(0) height+= PUP_LABELH; // XXX sepr line
                else height+= MENU_BUTTON_HEIGHT;
        }
 
-       startx= info->mx;
-       starty= info->my-height+MENU_BUTTON_HEIGHT/2;
+       startx= 0;
+       starty= 0;
        
        /* here we go! */
        if(head->name[0]) {
@@ -1819,7 +1824,7 @@ static uiBlock *ui_block_func_MENU_ITEM(bContext *C, uiPopupBlockHandle *handle,
                        y1 -= MENU_BUTTON_HEIGHT;
                }
                else if(item->type==MENU_ITEM_OPNAME_BOOL) {
-                       but= uiDefIconTextButO(block, BUTM, item->opname, head->opcontext, item->icon, item->name, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, "");
+                       but= uiDefIconTextButO(block, BUTM, item->opname, item->opcontext, item->icon, item->name, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, "");
                        RNA_boolean_set(uiButGetOperatorPtrRNA(but), item->propname, item->boolval);
                        
                        y1 -= MENU_BUTTON_HEIGHT;
@@ -1831,19 +1836,25 @@ static uiBlock *ui_block_func_MENU_ITEM(bContext *C, uiPopupBlockHandle *handle,
                        name= ui_menu_enumpropname(item->opname, item->propname, item->enumval);
                        BLI_strncpy(bname, name, sizeof(bname));
                        
-                       but= uiDefIconTextButO(block, BUTM, item->opname, head->opcontext, item->icon, bname, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, "");
+                       but= uiDefIconTextButO(block, BUTM, item->opname, item->opcontext, item->icon, bname, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, "");
                        RNA_enum_set(uiButGetOperatorPtrRNA(but), item->propname, item->enumval);
                        
                        y1 -= MENU_BUTTON_HEIGHT;
                }
-               else if(item->type==MENU_ITEM_OPNAME_FLOAT) {
+               else if(item->type==MENU_ITEM_OPNAME_INT) {
                        but= uiDefIconTextButO(block, BUTM, item->opname, head->opcontext, item->icon, item->name, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, "");
+                       RNA_int_set(uiButGetOperatorPtrRNA(but), item->propname, item->intval);
+                       
+                       y1 -= MENU_BUTTON_HEIGHT;
+               }
+               else if(item->type==MENU_ITEM_OPNAME_FLOAT) {
+                       but= uiDefIconTextButO(block, BUTM, item->opname, item->opcontext, item->icon, item->name, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, "");
                        RNA_float_set(uiButGetOperatorPtrRNA(but), item->propname, item->fltval);
                        
                        y1 -= MENU_BUTTON_HEIGHT;
                }
                else if(item->type==MENU_ITEM_OPNAME) {
-                       uiDefIconTextButO(block, BUTM, item->opname, head->opcontext, item->icon, NULL, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, NULL);
+                       uiDefIconTextButO(block, BUTM, item->opname, item->opcontext, item->icon, NULL, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, NULL);
                        y1 -= MENU_BUTTON_HEIGHT;
                }
                else if(item->type==MENU_ITEM_RNA_BOOL) {
@@ -1890,7 +1901,8 @@ static uiBlock *ui_block_func_MENU_ITEM(bContext *C, uiPopupBlockHandle *handle,
                uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT|UI_BLOCK_RET_1);
                uiBlockSetDirection(block, UI_DOWN);
 
-               uiPopupBoundsBlock(block, 1);
+               /* here we set an offset for the mouse position */
+               uiMenuPopupBoundsBlock(block, 1, 0, -height+MENU_BUTTON_HEIGHT/2);
        }
        else {
                /* for a header menu we set the direction automatic */
@@ -1954,7 +1966,8 @@ static uiMenuItem *ui_menu_add_item(uiMenuItem *head, const char *name, int icon
        else
                item->icon= ICON_BLANK1;
        item->retval= argval;
-       item->opcontext= WM_OP_EXEC_REGION_WIN; 
+       
+       item->opcontext= head->opcontext; 
        
        BLI_addtail(&head->items, item);
        
@@ -1984,18 +1997,18 @@ void uiMenuItemVal(uiMenuItem *head, const char *name, int icon, int argval)
 }
 
 /* regular operator item */
-void uiMenuItemO(uiMenuItem *head, char *name, int icon)
+void uiMenuItemO(uiMenuItem *head, int icon, char *opname)
 {
-       uiMenuItem *item= ui_menu_add_item(head, name, icon, 0);
+       uiMenuItem *item= ui_menu_add_item(head, "", icon, 0);
        
-       item->opname= name; // static!
+       item->opname= opname; // static!
        item->type = MENU_ITEM_OPNAME;
 }
 
 /* single operator item with property */
-void uiMenuItemEnumO(uiMenuItem *head, char *opname, char *propname, int value)
+void uiMenuItemEnumO(uiMenuItem *head, int icon, char *opname, char *propname, int value)
 {
-       uiMenuItem *item= ui_menu_add_item(head, "", 0, 0);
+       uiMenuItem *item= ui_menu_add_item(head, "", icon, 0);
        
        item->opname= opname; // static!
        item->propname= propname; // static!
@@ -2004,9 +2017,20 @@ void uiMenuItemEnumO(uiMenuItem *head, char *opname, char *propname, int value)
 }
 
 /* single operator item with property */
-void uiMenuItemFloatO(uiMenuItem *head, const char *name, char *opname, char *propname, float value)
+void uiMenuItemIntO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, int value)
 {
-       uiMenuItem *item= ui_menu_add_item(head, name, 0, 0);
+       uiMenuItem *item= ui_menu_add_item(head, name, icon, 0);
+       
+       item->opname= opname; // static!
+       item->propname= propname; // static!
+       item->intval= value;
+       item->type = MENU_ITEM_OPNAME_INT;
+}
+
+/* single operator item with property */
+void uiMenuItemFloatO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, float value)
+{
+       uiMenuItem *item= ui_menu_add_item(head, name, icon, 0);
        
        item->opname= opname; // static!
        item->propname= propname; // static!
@@ -2015,9 +2039,9 @@ void uiMenuItemFloatO(uiMenuItem *head, const char *name, char *opname, char *pr
 }
 
 /* single operator item with property */
-void uiMenuItemBooleanO(uiMenuItem *head, char *opname, char *propname, int value)
+void uiMenuItemBooleanO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, int value)
 {
-       uiMenuItem *item= ui_menu_add_item(head, "", 0, 0);
+       uiMenuItem *item= ui_menu_add_item(head, name, icon, 0);
        
        item->opname= opname; // static!
        item->propname= propname; // static!
@@ -2045,7 +2069,7 @@ void uiMenuItemsEnumO(uiMenuItem *head, char *opname, char *propname)
                RNA_property_enum_items(&ptr, prop, &item, &totitem);
                
                for (i=0; i<totitem; i++)
-                       uiMenuItemEnumO(head, opname, propname, item[i].value);
+                       uiMenuItemEnumO(head, 0, opname, propname, item[i].value);
        }
 }
 
@@ -2141,12 +2165,13 @@ void uiMenuSeparator(uiMenuItem *head)
 /*************************** Popup Menu API **************************/
 
 /* only return handler, and set optional title */
-uiMenuItem *uiPupMenuBegin(const char *title)
+uiMenuItem *uiPupMenuBegin(const char *title, int icon)
 {
        uiMenuItem *item= MEM_callocN(sizeof(uiMenuItem), "menu start");
        
        item->type = MENU_ITEM_TITLE;
        item->opcontext= WM_OP_EXEC_REGION_WIN; 
+       item->icon= icon;
        
        /* NULL is no title */
        if(title)
@@ -2178,32 +2203,6 @@ void uiPupMenuEnd(bContext *C, uiMenuItem *head)
        MEM_freeN(head);
 }
 
-/* This one will set enum propname, call operator and register it, and free the operator itself, 
-   call it in op->invoke with returning OPERATOR_RUNNING_MODAL */
-/* Note: propname has to be static */
-void uiPupMenuOperator(bContext *C, int maxrow, wmOperator *op, const char *propname, char *str)
-{
-       wmWindow *window= CTX_wm_window(C);
-       uiPupMenuInfo info;
-       uiPopupBlockHandle *menu;
-       
-       memset(&info, 0, sizeof(info));
-       info.mx= window->eventstate->x;
-       info.my= window->eventstate->y;
-       info.maxrow= maxrow;
-       info.instr= str;
-       
-       menu= ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_PUPMENU, &info);
-       menu->popup= 1;
-       
-       UI_add_popup_handlers(&window->handlers, menu);
-       WM_event_add_mousemove(C);
-       
-       menu->op_arg= op;
-       menu->propname= propname;
-}
-
-
 /* this one only to be called with operatortype name option */
 void uiPupMenu(bContext *C, int maxrow, uiMenuHandleFunc func, void *arg, char *str, ...)
 {
@@ -2338,3 +2337,24 @@ void uiPupMenuReports(bContext *C, ReportList *reports)
        BLI_dynstr_free(ds);
 }
 
+/*************************** Popup Block API **************************/
+
+void uiPupBlockO(bContext *C, uiBlockCreateFunc func, void *arg, char *opname, int opcontext)
+{
+       wmWindow *window= CTX_wm_window(C);
+       uiPopupBlockHandle *handle;
+       
+       handle= ui_popup_block_create(C, NULL, NULL, func, NULL, arg);
+       handle->popup= 1;
+       handle->opname= opname;
+       handle->opcontext= opcontext;
+       
+       UI_add_popup_handlers(&window->handlers, handle);
+       WM_event_add_mousemove(C);
+}
+
+void uiPupBlock(bContext *C, uiBlockCreateFunc func, void *arg)
+{
+       uiPupBlockO(C, func, arg, NULL, 0);
+}
+
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
new file mode 100644 (file)
index 0000000..5c9ed4d
--- /dev/null
@@ -0,0 +1,672 @@
+/**
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. 
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ * 
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_listBase.h"
+#include "DNA_material_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BKE_context.h"
+#include "BKE_idprop.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_utildefines.h"
+
+#include "RNA_access.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "ED_util.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#define DEF_BUT_WIDTH          150
+#define DEF_ICON_BUT_WIDTH     20
+#define DEF_BUT_HEIGHT         20
+
+/*************************** RNA Utilities ******************************/
+
+int UI_GetIconRNA(PointerRNA *ptr)
+{
+       StructRNA *rnatype= ptr->type;
+
+       if(rnatype == &RNA_Scene)
+               return ICON_SCENE_DEHLT;
+       else if(rnatype == &RNA_World)
+               return ICON_WORLD;
+       else if(rnatype == &RNA_Object)
+               return ICON_OBJECT;
+       else if(rnatype == &RNA_Mesh)
+               return ICON_MESH;
+       else if(rnatype == &RNA_MeshVertex)
+               return ICON_VERTEXSEL;
+       else if(rnatype == &RNA_MeshEdge)
+               return ICON_EDGESEL;
+       else if(rnatype == &RNA_MeshFace)
+               return ICON_FACESEL;
+       else if(rnatype == &RNA_MeshTextureFace)
+               return ICON_FACESEL_HLT;
+       else if(rnatype == &RNA_VertexGroup)
+               return ICON_VGROUP;
+       else if(rnatype == &RNA_VertexGroupElement)
+               return ICON_VGROUP;
+       else if(rnatype == &RNA_Curve)
+               return ICON_CURVE;
+       else if(rnatype == &RNA_MetaBall)
+               return ICON_MBALL;
+       else if(rnatype == &RNA_MetaElement)
+               return ICON_OUTLINER_DATA_META;
+       else if(rnatype == &RNA_Lattice)
+               return ICON_LATTICE;
+       else if(rnatype == &RNA_Armature)
+               return ICON_ARMATURE;
+       else if(rnatype == &RNA_Bone)
+               return ICON_BONE_DEHLT;
+       else if(rnatype == &RNA_Camera)
+               return ICON_CAMERA;
+       else if(rnatype == &RNA_LocalLamp)
+               return ICON_LAMP;
+       else if(rnatype == &RNA_AreaLamp)
+               return ICON_LAMP;
+       else if(rnatype == &RNA_SpotLamp)
+               return ICON_LAMP;
+       else if(rnatype == &RNA_SunLamp)
+               return ICON_LAMP;
+       else if(rnatype == &RNA_HemiLamp)
+               return ICON_LAMP;
+       else if(rnatype == &RNA_Lamp)
+               return ICON_LAMP;
+       else if(rnatype == &RNA_Group)
+               return ICON_GROUP;
+       else if(rnatype == &RNA_ParticleSystem)
+               return ICON_PARTICLES;
+       else if(rnatype == &RNA_ParticleSettings)
+               return ICON_PARTICLES;
+       else if(rnatype == &RNA_Material)
+               return ICON_MATERIAL;
+       else if(rnatype == &RNA_Texture)
+               return ICON_TEXTURE;
+       else if(rnatype == &RNA_TextureSlot)
+               return ICON_TEXTURE;
+       else if(rnatype == &RNA_WorldTextureSlot)
+               return ICON_TEXTURE;
+       else if(rnatype == &RNA_MaterialTextureSlot)
+               return ICON_TEXTURE;
+       else if(rnatype == &RNA_Image)
+               return ICON_TEXTURE;
+       else if(rnatype == &RNA_Screen)
+               return ICON_SPLITSCREEN;
+       else if(rnatype == &RNA_NodeTree)
+               return ICON_NODE;
+       else if(rnatype == &RNA_Text)
+               return ICON_TEXT;
+       else if(rnatype == &RNA_Sound)
+               return ICON_SOUND;
+       else if(rnatype == &RNA_Brush)
+               return ICON_TPAINT_HLT;
+       else if(rnatype == &RNA_Library)
+               return ICON_LIBRARY_DEHLT;
+       else if(rnatype == &RNA_Action)
+               return ICON_ACTION;
+       else if(rnatype == &RNA_FCurve)
+               return ICON_IPO_DEHLT;
+       //else if(rnatype == &RNA_Ipo)
+       //      return ICON_IPO_DEHLT;
+       else if(rnatype == &RNA_Key)
+               return ICON_SHAPEKEY;
+       else if(rnatype == &RNA_Main)
+               return ICON_BLENDER;
+       else if(rnatype == &RNA_Struct)
+               return ICON_RNA;
+       else if(rnatype == &RNA_Property)
+               return ICON_RNA;
+       else if(rnatype == &RNA_BooleanProperty)
+               return ICON_RNA;
+       else if(rnatype == &RNA_IntProperty)
+               return ICON_RNA;
+       else if(rnatype == &RNA_FloatProperty)
+               return ICON_RNA;
+       else if(rnatype == &RNA_StringProperty)
+               return ICON_RNA;
+       else if(rnatype == &RNA_EnumProperty)
+               return ICON_RNA;
+       else if(rnatype == &RNA_EnumPropertyItem)
+               return ICON_RNA;
+       else if(rnatype == &RNA_PointerProperty)
+               return ICON_RNA;
+       else if(rnatype == &RNA_CollectionProperty)
+               return ICON_RNA;
+       else if(rnatype == &RNA_GameObjectSettings)
+               return ICON_GAME;
+       else if(rnatype == &RNA_ScriptLink)
+               return ICON_PYTHON;
+       
+       /* modifiers */
+       else if(rnatype == &RNA_SubsurfModifier)
+               return ICON_MOD_SUBSURF;
+       else if(rnatype == &RNA_ArmatureModifier)
+               return ICON_ARMATURE;
+       else if(rnatype == &RNA_LatticeModifier)
+               return ICON_LATTICE;
+       else if(rnatype == &RNA_CurveModifier)
+               return ICON_CURVE;
+       else if(rnatype == &RNA_BuildModifier)
+               return ICON_MOD_BUILD;
+       else if(rnatype == &RNA_MirrorModifier)
+               return ICON_MOD_MIRROR;
+       else if(rnatype == &RNA_DecimateModifier)
+               return ICON_MOD_DECIM;
+       else if(rnatype == &RNA_WaveModifier)
+               return ICON_MOD_WAVE;
+       else if(rnatype == &RNA_HookModifier)
+               return ICON_HOOK;
+       else if(rnatype == &RNA_SoftbodyModifier)
+               return ICON_MOD_SOFT;
+       else if(rnatype == &RNA_BooleanModifier)
+               return ICON_MOD_BOOLEAN;
+       else if(rnatype == &RNA_ParticleInstanceModifier)
+               return ICON_MOD_PARTICLEINSTANCE;
+       else if(rnatype == &RNA_ParticleSystemModifier)
+               return ICON_MOD_PARTICLES;
+       else if(rnatype == &RNA_EdgeSplitModifier)
+               return ICON_MOD_EDGESPLIT;
+       else if(rnatype == &RNA_ArrayModifier)
+               return ICON_MOD_ARRAY;
+       else if(rnatype == &RNA_UVProjectModifier)
+               return ICON_MOD_UVPROJECT;
+       else if(rnatype == &RNA_DisplaceModifier)
+               return ICON_MOD_DISPLACE;
+       else
+               return ICON_DOT;
+}
+
+uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, char *name, int x1, int y1, int x2, int y2)
+{
+       uiBut *but=NULL;
+       const char *propname= RNA_property_identifier(ptr, prop);
+       int arraylen= RNA_property_array_length(ptr, prop);
+
+       switch(RNA_property_type(ptr, prop)) {
+               case PROP_BOOLEAN: {
+                       int value, length;
+
+                       if(arraylen && index == -1)
+                               return NULL;
+
+                       length= RNA_property_array_length(ptr, prop);
+
+                       if(length)
+                               value= RNA_property_boolean_get_index(ptr, prop, index);
+                       else
+                               value= RNA_property_boolean_get(ptr, prop);
+
+                       if(name && strcmp(name, "") == 0)
+                               name= (value)? "Enabled": "Disabled";
+
+                       but= uiDefButR(block, TOG, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+                       break;
+               }
+               case PROP_INT:
+               case PROP_FLOAT:
+                       if(arraylen && index == -1) {
+                               if(RNA_property_subtype(ptr, prop) == PROP_COLOR)
+                                       but= uiDefButR(block, COL, 0, name, x1, y1, x2, y2, ptr, propname, 0, 0, 0, -1, -1, NULL);
+                       }
+                       else
+                               but= uiDefButR(block, NUM, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+                       break;
+               case PROP_ENUM:
+                       but= uiDefButR(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+                       break;
+               case PROP_STRING:
+                       but= uiDefButR(block, TEX, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+                       break;
+               case PROP_POINTER: {
+                       PointerRNA pptr;
+                       PropertyRNA *nameprop;
+                       char *text, *descr, textbuf[256];
+                       int icon;
+
+                       pptr= RNA_property_pointer_get(ptr, prop);
+
+                       if(!pptr.data)
+                               return NULL;
+
+                       icon= UI_GetIconRNA(&pptr);
+                       nameprop= RNA_struct_name_property(&pptr);
+
+                       if(nameprop) {
+                               text= RNA_property_string_get_alloc(&pptr, nameprop, textbuf, sizeof(textbuf));
+                               descr= (char*)RNA_property_ui_description(&pptr, prop);
+                               but= uiDefIconTextBut(block, LABEL, 0, icon, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, descr);
+                               if(text != textbuf)
+                                       MEM_freeN(text);
+                       }
+                       else {
+                               text= (char*)RNA_struct_ui_name(&pptr);
+                               descr= (char*)RNA_property_ui_description(&pptr, prop);
+                               but= uiDefIconTextBut(block, LABEL, 0, icon, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, descr);
+                       }
+                       break;
+               }
+               case PROP_COLLECTION: {
+                       char text[256];
+                       sprintf(text, "%d items", RNA_property_collection_length(ptr, prop));
+                       but= uiDefBut(block, LABEL, 0, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, NULL);
+                       uiButSetFlag(but, UI_BUT_DISABLED);
+                       break;
+               }
+               default:
+                       but= NULL;
+                       break;
+       }
+
+       return but;
+}
+
+int uiDefAutoButsRNA(uiBlock *block, PointerRNA *ptr)
+{
+       CollectionPropertyIterator iter;
+       PropertyRNA *iterprop, *prop;
+       PropertySubType subtype;
+       char *name, namebuf[128];
+       int a, length, x= 0, y= 0;
+
+       x= 0;
+       y= 0;
+
+       /* create buttons */
+       uiSetCurFont(block, UI_HELVB);
+       uiDefBut(block, LABEL, 0, (char*)RNA_struct_ui_name(ptr), x, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
+       y -= DEF_BUT_HEIGHT;
+       uiSetCurFont(block, UI_HELV);
+
+       iterprop= RNA_struct_iterator_property(ptr);
+       RNA_property_collection_begin(ptr, iterprop, &iter);
+
+       for(; iter.valid; RNA_property_collection_next(&iter)) {
+               prop= iter.ptr.data;
+
+               if(strcmp(RNA_property_identifier(ptr, prop), "rna_type") == 0)
+                       continue;
+
+               if((length= RNA_property_array_length(ptr, prop))) {
+                       name= (char*)RNA_property_ui_name(ptr, prop);
+                       uiDefBut(block, LABEL, 0, name, x, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
+               }
+               else
+                       length= 1;
+
+               subtype= RNA_property_subtype(ptr, prop);
+
+               name= (char*)RNA_property_ui_name(ptr, prop);
+               uiDefBut(block, LABEL, 0, name, x, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
+
+               uiBlockBeginAlign(block);
+
+               if(length <= 16 && subtype == PROP_MATRIX) {
+                       /* matrix layout */
+                       int size, row, col, butwidth;
+
+                       size= ceil(sqrt(length));
+                       butwidth= DEF_BUT_WIDTH*2/size;
+                       y -= DEF_BUT_HEIGHT;
+
+                       for(a=0; a<length; a++) {
+                               col= a%size;
+                               row= a/size;
+
+                               uiDefAutoButR(block, ptr, prop, a, "", x+butwidth*col, y-row*DEF_BUT_HEIGHT, butwidth, DEF_BUT_HEIGHT-1);
+                       }
+
+                       y -= DEF_BUT_HEIGHT*(length/size);
+               }
+               else if(length <= 4 && ELEM3(subtype, PROP_ROTATION, PROP_VECTOR, PROP_COLOR)) {
+                       static char *vectoritem[4]= {"X:", "Y:", "Z:", "W:"};
+                       static char *quatitem[4]= {"W:", "X:", "Y:", "Z:"};
+                       static char *coloritem[4]= {"R:", "G:", "B:", "A:"};
+                       int butwidth;
+
+                       butwidth= DEF_BUT_WIDTH*2/length;
+                       y -= DEF_BUT_HEIGHT;
+
+                       for(a=0; a<length; a++) {
+                               if(length == 4 && subtype == PROP_ROTATION)
+                                       name= quatitem[a];
+                               else if(subtype == PROP_VECTOR || subtype == PROP_ROTATION)
+                                       name= vectoritem[a];
+                               else
+                                       name= coloritem[a];
+
+                               uiDefAutoButR(block, ptr, prop, a, name, x+butwidth*a, y, butwidth, DEF_BUT_HEIGHT-1);
+                       }
+                       y -= DEF_BUT_HEIGHT;
+               }
+               else {
+                       if(RNA_property_array_length(ptr, prop)) {
+                               sprintf(namebuf, "%d:", a+1);
+                               name= namebuf;
+                       }
+                       else
+                               name= "";
+
+                       uiDefAutoButR(block, ptr, prop, a, name, x+DEF_BUT_WIDTH, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1);
+                       y -= DEF_BUT_HEIGHT;
+               }
+
+               uiBlockEndAlign(block);
+       }
+
+       RNA_property_collection_end(&iter);
+
+       return -y;
+}
+
+/***************************** ID Utilities *******************************/
+
+typedef struct uiIDPoinParams {
+       uiIDPoinFunc func;
+       ID **id_p;
+       short id_code;
+       short browsenr;
+} uiIDPoinParams;
+
+static void idpoin_cb(bContext *C, void *arg_params, void *arg_event)
+{
+       Main *bmain;
+       ListBase *lb;
+       uiIDPoinParams *params= (uiIDPoinParams*)arg_params;
+       uiIDPoinFunc func= params->func;
+       ID **id_p= params->id_p;
+       ID *id= *id_p, *idtest;
+       int nr, event= GET_INT_FROM_POINTER(arg_event);
+
+       bmain= CTX_data_main(C);
+       lb= wich_libbase(bmain, params->id_code);
+
+       switch(event) {
+               case UI_ID_RENAME:
+                       if(id) test_idbutton(id->name+2);
+                       else return;
+                       break;
+               case UI_ID_BROWSE: {
+                       if(id==0) id= lb->first;
+                       if(id==0) return;
+
+                       if(params->browsenr== -2) {
+                               /* XXX implement or find a replacement
+                                * activate_databrowse((ID *)G.buts->lockpoin, GS(id->name), 0, B_MESHBROWSE, &params->browsenr, do_global_buttons); */
+                               return;
+                       }
+                       if(params->browsenr < 0)
+                               return;
+
+                       for(idtest=lb->first, nr=1; idtest; idtest=idtest->next, nr++) {
+                               if(nr==params->browsenr) {
+                                       if(id == idtest)
+                                               return;
+
+                                       *id_p= idtest;
+                                       break;
+                               }
+                       }
+                       break;
+               }
+               case UI_ID_DELETE:
+                       *id_p= NULL;
+                       break;
+               case UI_ID_FAKE_USER:
+                       if(id) {
+                               if(id->flag & LIB_FAKEUSER) id->us++;
+                               else id->us--;
+                       }
+                       else return;
+                       break;
+               case UI_ID_PIN:
+                       break;
+               case UI_ID_ADD_NEW:
+                       break;
+               case UI_ID_OPEN:
+                       break;
+               case UI_ID_ALONE:
+                       if(!id || id->us < 1)
+                               return;
+                       break;
+               case UI_ID_LOCAL:
+                       if(!id || id->us < 1)
+                               return;
+                       break;
+               case UI_ID_AUTO_NAME:
+                       break;
+       }
+
+       if(func)
+               func(C, *id_p, event);
+}
+
+int uiDefIDPoinButs(uiBlock *block, Main *bmain, ID *parid, ID **id_p, int id_code, short *pin_p, int x, int y, uiIDPoinFunc func, int events)
+{
+       ListBase *lb;
+       uiBut *but;
+       ID *id= *id_p;
+       uiIDPoinParams *params, *dup_params;
+       char *str=NULL, str1[10];
+       int len, oldcol, add_addbutton=0;
+
+       /* setup struct that we will pass on with the buttons */
+       params= MEM_callocN(sizeof(uiIDPoinParams), "uiIDPoinParams");
+       params->id_p= id_p;
+       params->id_code= id_code;
+       params->func= func;
+
+       lb= wich_libbase(bmain, id_code);
+
+       /* create buttons */
+       uiBlockBeginAlign(block);
+       oldcol= uiBlockGetCol(block);
+
+       if(id && id->us>1)
+               uiBlockSetCol(block, TH_BUT_SETTING1);
+
+       if((events & UI_ID_PIN) && *pin_p)
+               uiBlockSetCol(block, TH_BUT_SETTING2);
+
+       /* pin button */
+       if(id && (events & UI_ID_PIN)) {
+               but= uiDefIconButS(block, ICONTOG, (events & UI_ID_PIN), ICON_KEY_DEHLT, x, y ,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, pin_p, 0, 0, 0, 0, "Keeps this view displaying the current data regardless of what object is selected");
+               uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_PIN));
+               x+= DEF_ICON_BUT_WIDTH;
+       }
+
+       /* browse menu */
+       if(events & UI_ID_BROWSE) {
+               char *extrastr= NULL;
+               
+               if(ELEM4(id_code, ID_MA, ID_TE, ID_BR, ID_PA))
+                       add_addbutton= 1;
+               
+               if(ELEM8(id_code, ID_SCE, ID_SCR, ID_MA, ID_TE, ID_WO, ID_IP, ID_AC, ID_BR) || id_code == ID_PA)
+                       extrastr= "ADD NEW %x 32767";
+               else if(id_code==ID_TXT)
+                       extrastr= "OPEN NEW %x 32766 |ADD NEW %x 32767";
+               else if(id_code==ID_SO)
+                       extrastr= "OPEN NEW %x 32766";
+
+               /* XXX should be moved out of this function
+               uiBlockSetButLock(block, G.scene->id.lib!=0, "Can't edit external libdata");
+               if( id_code==ID_SCE || id_code==ID_SCR ) uiBlockClearButLock(block); */
+               
+               /* XXX should be moved out of this function
+               if(curarea->spacetype==SPACE_BUTS)
+                       uiBlockSetButLock(block, id_code!=ID_SCR && G.obedit!=0 && G.buts->mainb==CONTEXT_EDITING, "Cannot perform in EditMode"); */
+               
+               if(parid)
+                       uiBlockSetButLock(block, parid->lib!=0, "Can't edit external libdata");
+
+               if(lb) {
+                       if(id_code!=ID_IM || (events & UI_ID_BROWSE_RENDER))
+                               IDnames_to_pupstring(&str, NULL, extrastr, lb, id, &params->browsenr);
+                       else
+                               IMAnames_to_pupstring(&str, NULL, extrastr, lb, id, &params->browsenr);
+               }
+
+               dup_params= MEM_dupallocN(params);
+               but= uiDefButS(block, MENU, 0, str, x, y, DEF_ICON_BUT_WIDTH, DEF_BUT_HEIGHT, &dup_params->browsenr, 0, 0, 0, 0, "Browse existing choices, or add new");
+               uiButSetNFunc(but, idpoin_cb, dup_params, SET_INT_IN_POINTER(UI_ID_BROWSE));
+               x+= DEF_ICON_BUT_WIDTH;
+               
+               uiBlockClearButLock(block);
+       
+               MEM_freeN(str);
+       }
+
+       uiBlockSetCol(block, oldcol);
+
+       /* text button with name */
+       if(id) {
+               /* name */
+               if(id->us > 1)
+                       uiBlockSetCol(block, TH_BUT_SETTING1);
+
+               /* pinned data? */
+               if((events & UI_ID_PIN) && *pin_p)
+                       uiBlockSetCol(block, TH_BUT_SETTING2);
+
+               /* redalert overrides pin color */
+               if(id->us<=0)
+                       uiBlockSetCol(block, TH_REDALERT);
+
+               uiBlockSetButLock(block, id->lib!=0, "Can't edit external libdata");
+               
+               /* name button */
+               if(GS(id->name)==ID_SCE)
+                       strcpy(str1, "SCE:");
+               else if(GS(id->name)==ID_SCE)
+                       strcpy(str1, "SCR:");
+               else if(GS(id->name)==ID_MA && ((Material*)id)->use_nodes)
+                       strcpy(str1, "NT:");
+               else {
+                       str1[0]= id->name[0];
+                       str1[1]= id->name[1];
+                       str1[2]= ':';
+                       str1[3]= 0;
+               }
+               
+               if(GS(id->name)==ID_IP) len= 110;
+               else if((y) && (GS(id->name)==ID_AC)) len= 100; // comes from button panel (poselib)
+               else if(y) len= 140;    // comes from button panel
+               else len= 120;
+               
+               but= uiDefBut(block, TEX, 0, str1,x, y, (short)len, DEF_BUT_HEIGHT, id->name+2, 0.0, 21.0, 0, 0, "Displays current Datablock name. Click to change.");
+               uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_RENAME));
+
+               x+= len;
+
+               uiBlockClearButLock(block);
+               
+               /* lib make local button */
+               if(id->lib) {
+                       if(id->flag & LIB_INDIRECT) uiDefIconBut(block, BUT, 0, 0 /* XXX ICON_DATALIB */,x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Indirect Library Datablock. Cannot change.");
+                       else {
+                               but= uiDefIconBut(block, BUT, 0, 0 /* XXX ICON_PARLIB */, x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, 
+                                                         (events & UI_ID_LOCAL)? "Direct linked Library Datablock. Click to make local.": "Direct linked Library Datablock, cannot make local.");
+                               uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_ALONE));
+                       }
+                       
+                       x+= DEF_ICON_BUT_WIDTH;
+               }
+               
+               /* number of users / make local button */
+               if((events & UI_ID_ALONE) && id->us>1) {
+                       int butwidth;
+
+                       uiBlockSetButLock(block, (events & UI_ID_PIN) && *pin_p, "Can't make pinned data single-user");
+                       
+                       sprintf(str1, "%d", id->us);
+                       butwidth= (id->us<10)? DEF_ICON_BUT_WIDTH: DEF_ICON_BUT_WIDTH+10;
+
+                       but= uiDefBut(block, BUT, 0, str1, x, y, butwidth, DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Displays number of users of this data. Click to make a single-user copy.");
+                       uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_ALONE));
+                       x+= butwidth;
+                       
+                       uiBlockClearButLock(block);
+               }
+               
+               /* delete button */
+               if(events & UI_ID_DELETE) {
+                       uiBlockSetButLock(block, (events & UI_ID_PIN) && *pin_p, "Can't unlink pinned data");
+                       if(parid && parid->lib);
+                       else {
+                               but= uiDefIconBut(block, BUT, 0, ICON_X, x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Deletes link to this Datablock");
+                               uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_DELETE));
+                               x+= DEF_ICON_BUT_WIDTH;
+                       }
+                       
+                       uiBlockClearButLock(block);
+               }
+
+               /* auto name button */
+               if(events & UI_ID_AUTO_NAME) {
+                       if(parid && parid->lib);
+                       else {
+                               but= uiDefIconBut(block, BUT, 0, ICON_AUTO,x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Generates an automatic name");
+                               uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_AUTO_NAME));
+                               x+= DEF_ICON_BUT_WIDTH;
+                       }
+               }
+
+               /* fake user button */
+               if(events & UI_ID_FAKE_USER) {
+                       but= uiDefButBitS(block, TOG, LIB_FAKEUSER, 0, "F", x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, &id->flag, 0, 0, 0, 0, "Saves this datablock even if it has no users");
+                       uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_FAKE_USER));
+                       x+= DEF_ICON_BUT_WIDTH;
+               }
+       }
+       /* add new button */
+       else if(add_addbutton) {
+               uiBlockSetCol(block, oldcol);
+               if(parid) uiBlockSetButLock(block, parid->lib!=0, "Can't edit external libdata");
+               dup_params= MEM_dupallocN(params);
+               but= uiDefButS(block, TOG, 0, "Add New", x, y, 110, DEF_BUT_HEIGHT, &dup_params->browsenr, params->browsenr, 32767.0, 0, 0, "Add new data block");
+               uiButSetNFunc(but, idpoin_cb, dup_params, SET_INT_IN_POINTER(UI_ID_ADD_NEW));
+               x+= 110;
+       }
+       
+       uiBlockSetCol(block, oldcol);
+       uiBlockEndAlign(block);
+
+       MEM_freeN(params);
+
+       return x;
+}
+
index d7f887e9e557a48ee2aafc98c6f9cb8d14a241e3..cd89c5200920cc87e87ee708c58d099b852af775 100644 (file)
@@ -487,12 +487,12 @@ static void view_zoomstep_apply(bContext *C, wmOperator *op)
        dx= (v2d->cur.xmax - v2d->cur.xmin) * (float)RNA_float_get(op->ptr, "zoomfacx");
        dy= (v2d->cur.ymax - v2d->cur.ymin) * (float)RNA_float_get(op->ptr, "zoomfacy");
        
-       /* only move view on an axis if change is allowed */
-       if ((v2d->keepzoom & V2D_LOCKOFS_X)==0) {
+       /* only resize view on an axis if change is allowed */
+       if ((v2d->keepzoom & V2D_LOCKZOOM_X)==0) {
                v2d->cur.xmin += dx;
                v2d->cur.xmax -= dx;
        }
-       if ((v2d->keepzoom & V2D_LOCKOFS_Y)==0) {
+       if ((v2d->keepzoom & V2D_LOCKZOOM_Y)==0) {
                v2d->cur.ymin += dy;
                v2d->cur.ymax -= dy;
        }
index 40e2179ddbefe67a6a98f86d595bb3da2e8cdbc5..0ee4d2f8274a4a9466c5021372e3f4439ce40cb6 100644 (file)
@@ -1895,42 +1895,7 @@ static int check_vnormal_flip(float *n, float *vnorm)
 }
 #endif
 
-void flipface(EditMesh *em, EditFace *efa)
-{
-       if(efa->v4) {
-               SWAP(EditVert *, efa->v2, efa->v4);
-               SWAP(EditEdge *, efa->e1, efa->e4);
-               SWAP(EditEdge *, efa->e2, efa->e3);
-               EM_data_interp_from_faces(em, efa, NULL, efa, 0, 3, 2, 1);
-       }
-       else {
-               SWAP(EditVert *, efa->v2, efa->v3);
-               SWAP(EditEdge *, efa->e1, efa->e3);
-               efa->e2->dir= 1-efa->e2->dir;
-               EM_data_interp_from_faces(em, efa, NULL, efa, 0, 2, 1, 3);
-       }
-
-       if(efa->v4) CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n);
-       else CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n);
-}
-
 
-void flip_editnormals(EditMesh *em)
-{
-       EditFace *efa;
-       
-       efa= em->faces.first;
-       while(efa) {
-               if( efa->f & SELECT ){
-                       flipface(em, efa);
-               }
-               efa= efa->next;
-       }
-       
-       /* update vertex normals too */
-       recalc_editnormals(em);
-       
-}
 
 /* does face centers too */
 void recalc_editnormals(EditMesh *em)
index bb41accc10d952b071dc48522f812db97b3292f0..d93ceaf07b873794953e646ab15047c6ffe3fc6f 100644 (file)
@@ -52,6 +52,7 @@ editmesh_loop: tools with own drawing subloops, select, knife, subdiv
 #include "BLI_editVert.h"
 #include "BLI_ghash.h"
 
+#include "BKE_context.h"
 #include "BKE_depsgraph.h"
 #include "BKE_displist.h"
 #include "BKE_global.h"
@@ -64,9 +65,14 @@ editmesh_loop: tools with own drawing subloops, select, knife, subdiv
 
 #include "BIF_gl.h"
 
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
 #include "WM_types.h"
 
 #include "ED_mesh.h"
+#include "ED_screen.h"
 #include "ED_view3d.h"
 
 #include "mesh_intern.h"
@@ -75,7 +81,6 @@ editmesh_loop: tools with own drawing subloops, select, knife, subdiv
 static void BIF_undo_push() {}
 static void BIF_undo() {}
 static void error() {}
-static int pupmenu() {return 0;}
 static int qtest() {return 0;}
 /* **** XXX ******** */
 
@@ -427,11 +432,6 @@ typedef struct CutCurve {
        float  y;
 } CutCurve;
 
-static CutCurve *get_mouse_trail(int *len, char mode, char cutmode, struct GHash *gh)
-{
-       return NULL;    // XXX
-}
-
 
 /* ******************************************************************** */
 /* Knife Subdivide Tool.  Subdivides edges intersected by a mouse trail
@@ -444,94 +444,24 @@ static CutCurve *get_mouse_trail(int *len, char mode, char cutmode, struct GHash
                ESC cancels as expected.
    
        Contributed by Robert Wenzlaff (Det. Thorn).
-*/
 
-/* prototype */
-static float seg_intersect(struct EditEdge * e, CutCurve *c, int len, char mode, struct GHash *gh);
+    2.5 revamp:
+    - non modal (no menu before cutting)
+    - exit on mouse release
+    - polygon/segment drawing can become handled by WM cb later
 
-void KnifeSubdivide(Object *obedit, EditMesh *em, char mode)
-{
-       EditEdge *eed;
-       EditVert *eve;
-       CutCurve *curve;                
-       
-       struct GHash *gh;
-       int len=0;
-       float isect=0.0;
-       short numcuts=1;
-       float  *scr, co[4];
-       
-       if (em==NULL) return;
-
-       if (EM_nvertices_selected(em) < 2) {
-               error("No edges are selected to operate on");
-               return;
-       }
-
-       if (mode==KNIFE_PROMPT) {
-               short val= pupmenu("Cut Type %t|Exact Line%x1|Midpoints%x2|Multicut%x3");
-               if(val<1) return;
-               mode = val;     // warning, mode is char, pupmenu returns -1 with ESC
-       }
-
-       if(mode == KNIFE_MULTICUT) {
-// XXX         if(button(&numcuts, 2, 128, "Number of Cuts:")==0) return;
-       }
-
-       /*  XXX Set a knife cursor here */
-       
-       for(eed=em->edges.first; eed; eed= eed->next) eed->tmp.fp = 0.0; /*store percentage of edge cut for KNIFE_EXACT here.*/
-       
-       /*the floating point coordinates of verts in screen space will be stored in a hash table according to the vertices pointer*/
-       gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
-       for(eve=em->verts.first; eve; eve=eve->next){
-               scr = MEM_mallocN(sizeof(float)*2, "Vertex Screen Coordinates");
-               VECCOPY(co, eve->co);
-               co[3]= 1.0;
-//             Mat4MulVec4fl(obedit->obmat, co);
-// XXX         project_float(co,scr);
-               BLI_ghash_insert(gh, eve, scr);
-               eve->f1 = 0; /*store vertex intersection flag here*/
-       
-       }
-       
-       curve=get_mouse_trail(&len, TRAIL_MIXED, mode, gh);
-       
-       if (curve && len && mode){
-               eed= em->edges.first;           
-               while(eed) {    
-                       if( eed->v1->f & eed->v2->f & SELECT ){         // NOTE: uses vertex select, subdiv doesnt do edges yet
-                               isect=seg_intersect(eed, curve, len, mode, gh);
-                               if (isect) eed->f2= 1;
-                               else eed->f2=0;
-                               eed->tmp.fp= isect;
-                               //printf("isect=%i\n", isect);
-                       }
-                       else {
-                               eed->f2=0;
-                               eed->f1=0;
-                       }
-                       eed= eed->next;
-               }
-               
-               if(mode==KNIFE_EXACT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE|B_PERCENTSUBD,1,SUBDIV_SELECT_ORIG);
-               else if (mode==KNIFE_MIDPOINT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE,1,SUBDIV_SELECT_ORIG);
-               else if (mode==KNIFE_MULTICUT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE,numcuts,SUBDIV_SELECT_ORIG);
+*/
 
-               eed=em->edges.first;
-               while(eed){
-                       eed->f2=0;
-                       eed->f1=0;
-                       eed=eed->next;
-               }       
-       }
-       /* Return to old cursor and flags...*/
-       
-       BLI_ghash_free(gh, NULL, (GHashValFreeFP)MEM_freeN);
-       if (curve) MEM_freeN(curve);
+#define KNIFE_EXACT            1
+#define KNIFE_MIDPOINT 2
+#define KNIFE_MULTICUT 3
 
-       BIF_undo_push("Knife");
-}
+static EnumPropertyItem knife_items[]= {
+       {KNIFE_EXACT, "EXACT", "Exact", ""},
+       {KNIFE_MIDPOINT, "MIDPOINTS", "Midpoints", ""},
+       {KNIFE_MULTICUT, "MULTICUT", "Multicut", ""},
+       {0, NULL, NULL}
+};
 
 /* seg_intersect() Determines if and where a mouse trail intersects an EditEdge */
 
@@ -547,7 +477,7 @@ static float seg_intersect(EditEdge *e, CutCurve *c, int len, char mode, struct
        int  i;
        
        //threshold = 0.000001; /*tolerance for vertex intersection*/
-// XXX threshold = scene->toolsettings->select_thresh / 100;
+       // XXX  threshold = scene->toolsettings->select_thresh / 100;
        
        /* Get screen coords of verts */
        scr = BLI_ghash_lookup(gh, e->v1);
@@ -612,7 +542,7 @@ static float seg_intersect(EditEdge *e, CutCurve *c, int len, char mode, struct
                
                /* Perp. Distance from point to line */
                if (m2!=MAXSLOPE) dist=(y12-m2*x12-b2);/* /sqrt(m2*m2+1); Only looking for */
-                                                      /* change in sign.  Skip extra math */   
+                       /* change in sign.  Skip extra math */  
                else dist=x22-x12;      
                
                if (i==0) lastdist=dist;
@@ -635,7 +565,7 @@ static float seg_intersect(EditEdge *e, CutCurve *c, int len, char mode, struct
                        
                        /* Found an intersect,  calc intersect point */
                        if (m1==m2){ /* co-incident lines */
-                                               /* cut at 50% of overlap area*/
+                               /* cut at 50% of overlap area*/
                                x1max=MAX2(x11, x12);
                                x1min=MIN2(x11, x12);
                                xi= (MIN2(x2max,x1max)+MAX2(x2min,x1min))/2.0;  
@@ -679,6 +609,7 @@ static float seg_intersect(EditEdge *e, CutCurve *c, int len, char mode, struct
                                if ((m2<=1.0)&&(m2>=-1.0)) perc = (xi-x21)/(x22-x21);   
                                else perc=(yi-y21)/(y22-y21); /*lower slope more accurate*/
                                //isect=32768.0*(perc+0.0000153); /* Percentage in 1/32768ths */
+                               
                                break;
                        }
                }       
@@ -687,27 +618,112 @@ static float seg_intersect(EditEdge *e, CutCurve *c, int len, char mode, struct
        return(perc);
 } 
 
-void LoopMenu(Object *obedit, EditMesh *em) /* Called by KKey */
+
+#define MAX_CUTS 256
+
+static int knife_cut_exec(bContext *C, wmOperator *op)
 {
-       short ret;
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+       ARegion *ar= CTX_wm_region(C);
+       EditEdge *eed;
+       EditVert *eve;
+       CutCurve curve[MAX_CUTS];
+       struct GHash *gh;
+       float isect=0.0;
+       float  *scr, co[4];
+       int len=0;
+       short numcuts=1, mode= RNA_int_get(op->ptr, "type");
        
-       ret=pupmenu("Loop/Cut Menu %t|Loop Cut (CTRL-R)%x2|"
-                               "Knife (Exact) %x3|Knife (Midpoints)%x4|Knife (Multicut)%x5");
-                               
-       switch (ret){
-               case 2:
-                       CutEdgeloop(obedit, em, 1);
-                       break;
-               case 3: 
-                       KnifeSubdivide(obedit, em, KNIFE_EXACT);
-                       break;
-               case 4:
-                       KnifeSubdivide(obedit, em, KNIFE_MIDPOINT);
-                       break;
-               case 5:
-                       KnifeSubdivide(obedit, em, KNIFE_MULTICUT);
-                       break;
+       if (EM_nvertices_selected(em) < 2) {
+               error("No edges are selected to operate on");
+               return OPERATOR_CANCELLED;;
        }
 
+       /* get the cut curve */
+       RNA_BEGIN(op->ptr, itemptr, "path") {
+               
+               RNA_float_get_array(&itemptr, "loc", (float *)&curve[len]);
+               len++;
+               if(len>= MAX_CUTS) break;
+       }
+       RNA_END;
+       
+       if(len<2) return OPERATOR_CANCELLED;
+       
+       /*store percentage of edge cut for KNIFE_EXACT here.*/
+       for(eed=em->edges.first; eed; eed= eed->next) 
+               eed->tmp.fp = 0.0; 
+       
+       /*the floating point coordinates of verts in screen space will be stored in a hash table according to the vertices pointer*/
+       gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+       for(eve=em->verts.first; eve; eve=eve->next){
+               scr = MEM_mallocN(sizeof(float)*2, "Vertex Screen Coordinates");
+               VECCOPY(co, eve->co);
+               co[3]= 1.0;
+               Mat4MulVec4fl(obedit->obmat, co);
+               project_float(ar, co, scr);
+               BLI_ghash_insert(gh, eve, scr);
+               eve->f1 = 0; /*store vertex intersection flag here*/
+       
+       }
+       
+       eed= em->edges.first;           
+       while(eed) {    
+               if( eed->v1->f & eed->v2->f & SELECT ){         // NOTE: uses vertex select, subdiv doesnt do edges yet
+                       isect= seg_intersect(eed, curve, len, mode, gh);
+                       if (isect!=0.0f) eed->f2= 1;
+                       else eed->f2=0;
+                       eed->tmp.fp= isect;
+                       //printf("isect=%i\n", isect);
+               }
+               else {
+                       eed->f2=0;
+                       eed->f1=0;
+               }
+               eed= eed->next;
+       }
+       
+       if (mode==KNIFE_MIDPOINT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE, 1, SUBDIV_SELECT_ORIG);
+       else if (mode==KNIFE_MULTICUT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE, numcuts, SUBDIV_SELECT_ORIG);
+       else esubdivideflag(obedit, em, SELECT, 0, B_KNIFE|B_PERCENTSUBD, 1, SUBDIV_SELECT_ORIG);
+
+       eed=em->edges.first;
+       while(eed){
+               eed->f2=0;
+               eed->f1=0;
+               eed=eed->next;
+       }       
+       
+       BLI_ghash_free(gh, NULL, (GHashValFreeFP)MEM_freeN);
+       
+       return OPERATOR_FINISHED;
+}
+
+
+void MESH_OT_knife_cut(wmOperatorType *ot)
+{
+       PropertyRNA *prop;
+       
+       ot->name= "Knife Cut";
+       ot->idname= "MESH_OT_knife_cut";
+       
+       ot->invoke= WM_gesture_lines_invoke;
+       ot->modal= WM_gesture_lines_modal;
+       ot->exec= knife_cut_exec;
+       
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       
+       RNA_def_enum(ot->srna, "type", knife_items, KNIFE_EXACT, "Type", "");
+       prop= RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
+       RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
+       
+       /* internal */
+       RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
 }
 
+/* ******************************************************* */
+
index 778a7b36842e1195902367674d71703ae5a14b52..f3e09e644d6547ec1008e1e97c77514ad75fd162 100644 (file)
@@ -3355,7 +3355,7 @@ void MESH_OT_select_non_manifold(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-static void selectswap_mesh(EditMesh *em) /* UI level */
+void EM_select_swap(EditMesh *em) /* exported for UV */
 {
        EditVert *eve;
        EditEdge *eed;
@@ -3396,7 +3396,7 @@ static int selectswap_mesh_exec(bContext *C, wmOperator *op)
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
        
-       selectswap_mesh(em);
+       EM_select_swap(em);
        
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
        return OPERATOR_FINISHED;       
@@ -3418,21 +3418,23 @@ void MESH_OT_select_invert(wmOperatorType *ot)
        
 /* ******************** (de)select all operator **************** */
 
+void EM_toggle_select_all(EditMesh *em) /* exported for UV */
+{
+       if(EM_nvertices_selected(em))
+               EM_clear_flag_all(em, SELECT);
+       else 
+               EM_set_flag_all(em, SELECT);
+}
+
 static int toggle_select_all_exec(bContext *C, wmOperator *op)
 {
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
        
-       if( EM_nvertices_selected(em) ) {
-               EM_clear_flag_all(em, SELECT);
-       }
-       else  {
-               EM_set_flag_all(em, SELECT);
-       }
-               
-//             if (EM_texFaceCheck())
+       EM_toggle_select_all(em);
        
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
        return OPERATOR_FINISHED;
 }
 
@@ -3853,10 +3855,13 @@ void MESH_OT_selection_type(wmOperatorType *ot)
 }
 /* ************************* SEAMS AND EDGES **************** */
 
-void editmesh_mark_seam(EditMesh *em, int clear)
+static int editmesh_mark_seam(bContext *C, wmOperator *op)
 {
-       Mesh *me= NULL; // XXX
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+       Mesh *me= ((Mesh *)obedit->data);
        EditEdge *eed;
+       int clear = RNA_boolean_get(op->ptr, "clear");
        
        /* auto-enable seams drawing */
        if(clear==0) {
@@ -3882,11 +3887,33 @@ void editmesh_mark_seam(EditMesh *em, int clear)
                }
        }
 
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+       return OPERATOR_FINISHED;
 }
 
-void editmesh_mark_sharp(EditMesh *em, int set)
+void MESH_OT_mark_seam(wmOperatorType *ot)
 {
-       Mesh *me= NULL;
+       /* identifiers */
+       ot->name= "Mark seam";
+       ot->idname= "MESH_OT_mark_seam";
+       
+       /* api callbacks */
+       ot->exec= editmesh_mark_seam;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       
+       RNA_def_boolean(ot->srna, "clear", 0, "Clear", "");
+}
+
+static int editmesh_mark_sharp(bContext *C, wmOperator *op)
+{
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+       Mesh *me= ((Mesh *)obedit->data);
+       int set = RNA_boolean_get(op->ptr, "set");
        EditEdge *eed;
 
        /* auto-enable sharp edge drawing */
@@ -3908,6 +3935,25 @@ void editmesh_mark_sharp(EditMesh *em, int set)
                }
        }
 
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_mark_sharp(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Mark sharp";
+       ot->idname= "MESH_OT_mark_sharp";
+       
+       /* api callbacks */
+       ot->exec= editmesh_mark_sharp;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       
+       RNA_def_boolean(ot->srna, "set", 0, "Set", "");
 }
 
 void BME_Menu()        {
@@ -3964,10 +4010,10 @@ void Edge_Menu(EditMesh *em)
        switch(ret)
        {
        case 1:
-               editmesh_mark_seam(em, 0);
+               //editmesh_mark_seam(em, 0);
                break;
        case 2:
-               editmesh_mark_seam(em, 1);
+               //editmesh_mark_seam(em, 1);
                break;
        case 3:
 //             edge_rotate_selected(em, 2);
@@ -4488,9 +4534,13 @@ void editmesh_align_view_to_selected(Object *obedit, EditMesh *em, View3D *v3d,
 
 /* **************** VERTEX DEFORMS *************** */
 
-void vertexsmooth(Object *obedit, EditMesh *em)
+static int smooth_vertex(bContext *C, wmOperator *op)
 {
-       Scene *scene= NULL; // XXX
+       Scene *scene= CTX_data_scene(C);
+       Object *obedit= CTX_data_edit_object(C);
+       Mesh *me= obedit->data;
+       EditMesh *em= me->edit_mesh; 
+
        EditVert *eve, *eve_mir = NULL;
        EditEdge *eed;
        float *adror, *adr, fac;
@@ -4498,7 +4548,7 @@ void vertexsmooth(Object *obedit, EditMesh *em)
        int teller=0;
        ModifierData *md= obedit->modifiers.first;
 
-       if(em==NULL) return;
+       if(em==NULL) return OPERATOR_CANCELLED;
 
        /* count */
        eve= em->verts.first;
@@ -4506,7 +4556,7 @@ void vertexsmooth(Object *obedit, EditMesh *em)
                if(eve->f & SELECT) teller++;
                eve= eve->next;
        }
-       if(teller==0) return;
+       if(teller==0) return OPERATOR_CANCELLED;
        
        adr=adror= (float *)MEM_callocN(3*sizeof(float *)*teller, "vertsmooth");
        eve= em->verts.first;
@@ -4615,8 +4665,25 @@ void vertexsmooth(Object *obedit, EditMesh *em)
 
        recalc_editnormals(em);
 
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
 //     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
 
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_smooth_vertex(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Smooth Vertex";
+       ot->idname= "MESH_OT_smooth_vertex";
+       
+       /* api callbacks */
+       ot->exec= smooth_vertex;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_UNDO;
 }
 
 void vertexnoise(Object *obedit, EditMesh *em)
@@ -4751,3 +4818,57 @@ void MESH_OT_vertices_to_sphere(wmOperatorType *ot)
        /* props */
        RNA_def_float(ot->srna, "percent", 100.0f, 0.0f, 100.0f, "Percent", "DOC_BROKEN", 0.01f, 100.0f);
 }
+
+void flipface(EditMesh *em, EditFace *efa)
+{
+       if(efa->v4) {
+               SWAP(EditVert *, efa->v2, efa->v4);
+               SWAP(EditEdge *, efa->e1, efa->e4);
+               SWAP(EditEdge *, efa->e2, efa->e3);
+               EM_data_interp_from_faces(em, efa, NULL, efa, 0, 3, 2, 1);
+       }
+       else {
+               SWAP(EditVert *, efa->v2, efa->v3);
+               SWAP(EditEdge *, efa->e1, efa->e3);
+               efa->e2->dir= 1-efa->e2->dir;
+               EM_data_interp_from_faces(em, efa, NULL, efa, 0, 2, 1, 3);
+       }
+
+       if(efa->v4) CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n);
+       else CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n);
+}
+
+
+static int flip_editnormals(bContext *C, wmOperator *op)
+{
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+       EditFace *efa;
+       
+       efa= em->faces.first;
+       while(efa) {
+               if( efa->f & SELECT ){
+                       flipface(em, efa);
+               }
+               efa= efa->next;
+       }
+       
+       /* update vertex normals too */
+       recalc_editnormals(em);
+
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_flip_editnormals(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Flip Normals";
+       ot->idname= "MESH_OT_flip_editnormals";
+       
+       /* api callbacks */
+       ot->exec= flip_editnormals;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
index 805081b6a6ff4e523ab938030ddcf1e2e89a5236..419971eff103d26de7a36c2630c7dd0a2d4f0b37 100644 (file)
@@ -1,5 +1,4 @@
-/**
- * $Id: 
+ /* $Id: 
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -717,10 +716,12 @@ void MESH_OT_extrude(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-void split_mesh(EditMesh *em)
+static int split_mesh(bContext *C, wmOperator *op)
 {
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
 
-       waitcursor(1);
+       WM_cursor_wait(1);
 
        /* make duplicate first */
        adduplicateflag(em, SELECT);
@@ -728,14 +729,40 @@ void split_mesh(EditMesh *em)
        delfaceflag(em, 128);
        recalc_editnormals(em);
 
-       waitcursor(0);
+       WM_cursor_wait(0);
+
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
 
 //     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+       return OPERATOR_FINISHED;
+}
 
+void MESH_OT_split_mesh(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Split Mesh";
+       ot->idname= "MESH_OT_split_mesh";
+       
+       /* api callbacks */
+       ot->exec= split_mesh;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-void extrude_repeat_mesh(RegionView3D *rv3d, Object *obedit, EditMesh *em, int steps, float offs)
+
+static int extrude_repeat_mesh(bContext *C, wmOperator *op)
 {
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+       
+       RegionView3D *rv3d = CTX_wm_region_view3d(C);           
+               
+       int steps = RNA_int_get(op->ptr,"steps");
+       
+       float offs = RNA_float_get(op->ptr,"offset");
+
        float dvec[3], tmat[3][3], bmat[3][3], nor[3]= {0.0, 0.0, 0.0};
        short a;
 
@@ -762,10 +789,30 @@ void extrude_repeat_mesh(RegionView3D *rv3d, Object *obedit, EditMesh *em, int s
        
        EM_fgon_flags(em);
        
-//     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
 
+//     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+       return OPERATOR_FINISHED;
 }
 
+void MESH_OT_extrude_repeat(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Extrude Repeat Mesh";
+       ot->idname= "MESH_OT_extrude_repeat";
+       
+       /* api callbacks */
+       ot->exec= extrude_repeat_mesh;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       
+       /* props */
+       RNA_def_float(ot->srna, "offset", 2.0f, 0.0f, 100.0f, "Offset", "", 0.0f, FLT_MAX);
+       RNA_def_int(ot->srna, "steps", 10, 0, 180, "Steps", "", 0, INT_MAX);
+}
+       
 void spin_mesh(View3D *v3d, Object *obedit, EditMesh *em, int steps, float degr, float *dvec, int mode)
 {
        Scene *scene= NULL; // XXX from context!
@@ -1215,11 +1262,12 @@ void fill_mesh(EditMesh *em)
 
        // XXX option beautyfill */
 
-       waitcursor(0);
+       WM_cursor_wait(0);
        EM_select_flush(em);
 //     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
 
 }
+
 /*GB*/
 /*-------------------------------------------------------------------------------*/
 /*--------------------------- Edge Based Subdivide ------------------------------*/
@@ -3726,9 +3774,14 @@ static void edge_rotate(EditMesh *em, EditEdge *eed,int dir)
        free_editface(em, face[1]);             
 }
 
+// XXX ton please check
 /* only accepts 1 selected edge, or 2 selected faces */
-void edge_rotate_selected(EditMesh *em, int dir)
+static int edge_rotate_selected(bContext *C, wmOperator *op)
 {
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+               
+       int dir = RNA_int_get(op->ptr,"dir"); // dir == 2 when clockwise and ==1 for counter CW.
        EditEdge *eed;
        EditFace *efa;
        short edgeCount = 0;
@@ -3762,7 +3815,11 @@ void edge_rotate_selected(EditMesh *em, int dir)
                                }
                        }
                }
-               else error("Select one edge or two adjacent faces");
+               else 
+               {
+                       error("Select one edge or two adjacent faces");
+                       return OPERATOR_CANCELLED;
+               }
        }
        else if(edgeCount==1) {
                for(eed= em->edges.first; eed; eed= eed->next) {
@@ -3773,16 +3830,43 @@ void edge_rotate_selected(EditMesh *em, int dir)
                        }
                }
        }
-       else error("Select one edge or two adjacent faces");
+       else 
+       {       
+               error("Select one edge or two adjacent faces");
+               return OPERATOR_CANCELLED;
+       }
        
 
        /* flush selected vertices (again) to edges/faces */
        EM_select_flush(em);
        
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+       
 //     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+       
+       return OPERATOR_FINISHED;
+
+}
 
+void MESH_OT_edge_rotate_selected(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Rotate Selected Edge";
+       ot->idname= "MESH_OT_edge_rotate_selected";
+       
+       /* api callbacks */
+       ot->exec= edge_rotate_selected;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       
+       /* props */
+       RNA_def_int(ot->srna, "dir", 1, 1, 2, "Direction", "Clockwise and Counter Clockwise", 1, 2);
 }
 
+
 /******************* BEVEL CODE STARTS HERE ********************/
 
   /* XXX old bevel not ported yet */
@@ -5916,8 +6000,11 @@ void pathselect(EditMesh *em)
        }
 }
 
-void region_to_loop(EditMesh *em)
+static int region_to_loop(bContext *C, wmOperator *op)
 {
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+
        EditEdge *eed;
        EditFace *efa;
        
@@ -5947,6 +6034,24 @@ void region_to_loop(EditMesh *em)
 //             if (EM_texFaceCheck())
 
        }
+       
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_region_to_loop(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Region to Loop";
+       ot->idname= "MESH_OT_region_to_loop";
+       
+       /* api callbacks */
+       ot->exec= region_to_loop;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
 static int validate_loop(EditMesh *em, Collection *edgecollection)
@@ -6073,8 +6178,12 @@ static int loop_bisect(EditMesh *em, Collection *edgecollection){
        else return(2);
 }
 
-void loop_to_region(EditMesh *em)
+static int loop_to_region(bContext *C, wmOperator *op)
 {
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+
+
        EditFace *efa;
        ListBase allcollections={NULL,NULL};
        Collection *edgecollection;
@@ -6103,13 +6212,34 @@ void loop_to_region(EditMesh *em)
 
 //     if (EM_texFaceCheck())
 
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_loop_to_region(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Loop to Region";
+       ot->idname= "MESH_OT_loop_to_region";
+       
+       /* api callbacks */
+       ot->exec= loop_to_region;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
 
+// XXX please check if these functions do what you want them to
 /* texface and vertex color editmode tools for the face menu */
 
-void mesh_rotate_uvs(EditMesh *em)
+static int mesh_rotate_uvs(bContext *C, wmOperator *op)
 {
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+
        EditFace *efa;
        short change = 0, ccw;
        MTFace *tf;
@@ -6118,7 +6248,7 @@ void mesh_rotate_uvs(EditMesh *em)
 
        if (!EM_texFaceCheck(em)) {
                error("mesh has no uv/image layers");
-               return;
+               return OPERATOR_CANCELLED;
        }
        
        ccw = (shift);
@@ -6171,12 +6301,17 @@ void mesh_rotate_uvs(EditMesh *em)
        
        if (change) {
 //             DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-
+               WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
        }
+       
+       return OPERATOR_FINISHED;
 }
 
-void mesh_mirror_uvs(EditMesh *em)
+static int mesh_mirror_uvs(bContext *C, wmOperator *op)
 {
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+
        EditFace *efa;
        short change = 0, altaxis;
        MTFace *tf;
@@ -6185,7 +6320,7 @@ void mesh_mirror_uvs(EditMesh *em)
        
        if (!EM_texFaceCheck(em)) {
                error("mesh has no uv/image layers");
-               return;
+               return OPERATOR_CANCELLED;
        }
        
        altaxis = (shift);
@@ -6253,12 +6388,16 @@ void mesh_mirror_uvs(EditMesh *em)
        
        if (change) {
 //             DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-
+               WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
        }
+       return OPERATOR_FINISHED;
 }
 
-void mesh_rotate_colors(EditMesh *em)
+static int mesh_rotate_colors(bContext *C, wmOperator *op)
 {
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+
        EditFace *efa;
        short change = 0, ccw;
        MCol tmpcol, *mcol;
@@ -6266,7 +6405,7 @@ void mesh_rotate_colors(EditMesh *em)
        
        if (!EM_vertColorCheck(em)) {
                error("mesh has no color layers");
-               return;
+               return OPERATOR_CANCELLED;
        }
        
        ccw = (shift);
@@ -6302,13 +6441,18 @@ void mesh_rotate_colors(EditMesh *em)
        
        if (change) {
 //             DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-
+               WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
        }       
+       
+       return OPERATOR_FINISHED;
 }
 
 
-void mesh_mirror_colors(EditMesh *em)
+static int mesh_mirror_colors(bContext *C, wmOperator *op)
 {
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+
        EditFace *efa;
        short change = 0, altaxis;
        MCol tmpcol, *mcol;
@@ -6316,7 +6460,7 @@ void mesh_mirror_colors(EditMesh *em)
        
        if (!EM_vertColorCheck(em)) {
                error("mesh has no color layers");
-               return;
+               return OPERATOR_CANCELLED;
        }
        
        altaxis = (shift);
@@ -6351,7 +6495,66 @@ void mesh_mirror_colors(EditMesh *em)
        
        if (change) {
 //             DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+               WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
        }
+       
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_rotate_uvs(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Rotate UVs";
+       ot->idname= "MESH_OT_rotate_uvs";
+       
+       /* api callbacks */
+       ot->exec= mesh_rotate_uvs;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+void MESH_OT_mirror_uvs(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Mirror UVs";
+       ot->idname= "MESH_OT_mirror_uvs";
+       
+       /* api callbacks */
+       ot->exec= mesh_mirror_uvs;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+void MESH_OT_rotate_colors(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Rotate Colors";
+       ot->idname= "MESH_OT_rotate_colors";
+       
+       /* api callbacks */
+       ot->exec= mesh_rotate_colors;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+void MESH_OT_mirror_colors(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Mirror Colors";
+       ot->idname= "MESH_OT_mirror_colors";
+       
+       /* api callbacks */
+       ot->exec= mesh_mirror_colors;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
 static int subdivide_exec(bContext *C, wmOperator *op)
@@ -6474,39 +6677,29 @@ void MESH_OT_subdivide_smooth(wmOperatorType *ot)
 
 static int subdivs_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
-       int items;
-       char *menu, *p;
-       
-       items = 4;
-       
-       menu= MEM_callocN(items * OP_MAX_TYPENAME, "string");
-       
-       p= menu + sprintf(menu, "%s %%t", "subdiv");
-       p+= sprintf(p, "|%s %%x%d", "simple", 3);
-       p+= sprintf(p, "|%s %%x%d", "multi", 2);
-       p+= sprintf(p, "|%s %%x%d", "fractal", 1);
-       p+= sprintf(p, "|%s %%x%d", "smooth", 0);
-       
-       uiPupMenuOperator(C, 20, op, "index", menu);
-       MEM_freeN(menu);
+       uiMenuItem *head;
+
+       head= uiPupMenuBegin("Subdivision Type", 0);
+       uiMenuItemsEnumO(head, "MESH_OT_subdivs", "type");
+       uiPupMenuEnd(C, head);
        
-       return OPERATOR_RUNNING_MODAL;
+       return OPERATOR_CANCELLED;
 }
 
 static int subdivs_exec(bContext *C, wmOperator *op)
 {      
-       switch(RNA_int_get(op->ptr, "index"))
+       switch(RNA_int_get(op->ptr, "type"))
        {
-               case 3: // simple
+               case 0: // simple
                        subdivide_exec(C,op);
                        break;
-               case 2: // multi
+               case 1: // multi
                        subdivide_multi_exec(C,op);
                        break;
-               case 1: // fractal;
+               case 2: // fractal;
                        subdivide_multi_fractal_exec(C,op);
                        break;
-               case 0: //smooth
+               case 3: //smooth
                        subdivide_smooth_exec(C,op);
                        break;
        }
@@ -6516,6 +6709,13 @@ static int subdivs_exec(bContext *C, wmOperator *op)
 
 void MESH_OT_subdivs(wmOperatorType *ot)
 {
+       static EnumPropertyItem type_items[]= {
+               {0, "SIMPLE", "Simple", ""},
+               {1, "MULTI", "Multi", ""},
+               {2, "FRACTAL", "Fractal", ""},
+               {3, "SMOOTH", "Smooth", ""},
+               {0, NULL, NULL}};
+
        /* identifiers */
        ot->name= "subdivs";
        ot->idname= "MESH_OT_subdivs";
@@ -6530,7 +6730,7 @@ void MESH_OT_subdivs(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
        /*props */
-       RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, 1000);
+       RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
        
        /* this is temp, the ops are different, but they are called from subdivs, so all the possible props should be here as well*/
        RNA_def_int(ot->srna, "number_cuts", 4, 0, 100, "Number of Cuts", "", 0, INT_MAX);
index 58401d79bf12c3bbc0cab64708f4ab62e6b766c9..debf7f3b1da0c2d732d912a26b908ce9b3c2c194 100644 (file)
@@ -168,14 +168,10 @@ extern struct EditFace *EM_face_from_faces(EditMesh *em, struct EditFace *efa1,
 
 /* ******************* editmesh_loop.c */
 
-#define KNIFE_PROMPT 0
-#define KNIFE_EXACT 1
-#define KNIFE_MIDPOINT 2
-#define KNIFE_MULTICUT 3
-
 #define LOOP_SELECT    1
 #define LOOP_CUT       2
 
+void MESH_OT_knife_cut(struct wmOperatorType *ot);
 
 /* ******************* editmesh_mods.c */
 void MESH_OT_loop_select(struct wmOperatorType *ot);
@@ -200,6 +196,10 @@ void MESH_OT_select_random(struct wmOperatorType *ot);
 void MESH_OT_vertices_to_sphere(struct wmOperatorType *ot);
 void MESH_OT_selection_type(struct wmOperatorType *ot);
 void MESH_OT_select_multi_loop(struct wmOperatorType *ot);
+void MESH_OT_mark_seam(struct wmOperatorType *ot);
+void MESH_OT_mark_sharp(struct wmOperatorType *ot);
+void MESH_OT_smooth_vertex(struct wmOperatorType *ot);
+void MESH_OT_flip_editnormals(struct wmOperatorType *ot);
 
 extern EditEdge *findnearestedge(struct ViewContext *vc, int *dist);
 extern void EM_automerge(int update);
@@ -247,6 +247,16 @@ void MESH_OT_convert_tris_to_quads(struct wmOperatorType *ot);
 void MESH_OT_edge_flip(struct wmOperatorType *ot);
 void MESH_OT_faces_shade_smooth(struct wmOperatorType *ot);
 void MESH_OT_faces_shade_solid(struct wmOperatorType *ot);
+void MESH_OT_split_mesh(struct wmOperatorType *ot);
+void MESH_OT_extrude_repeat(struct wmOperatorType *ot);
+void MESH_OT_edge_rotate_selected(struct wmOperatorType *ot);
+void MESH_OT_loop_to_region(struct wmOperatorType *ot);
+void MESH_OT_region_to_loop(struct wmOperatorType *ot);
+
+void MESH_OT_rotate_uvs(struct wmOperatorType *ot);
+void MESH_OT_mirror_uvs(struct wmOperatorType *ot);
+void MESH_OT_rotate_colors(struct wmOperatorType *ot);
+void MESH_OT_mirror_colors(struct wmOperatorType *ot);
 
 void MESH_OT_delete(struct wmOperatorType *ot);
 
index 8f5a63b484f1ee2d1c0075e3019c3d183fb78920..f119c347915fe6877e7392523ba4e4dd627e3f47 100644 (file)
@@ -107,7 +107,6 @@ static void MESH_OT_add_duplicate(wmOperatorType *ot)
 void ED_operatortypes_mesh(void)
 {
        WM_operatortype_append(MESH_OT_de_select_all);
-       WM_operatortype_append(MESH_OT_bmesh_test);
        WM_operatortype_append(MESH_OT_select_more);
        WM_operatortype_append(MESH_OT_select_less);
        WM_operatortype_append(MESH_OT_select_invert);
@@ -142,7 +141,17 @@ void ED_operatortypes_mesh(void)
        WM_operatortype_append(MESH_OT_removedoublesflag);
        WM_operatortype_append(MESH_OT_extrude);
        WM_operatortype_append(MESH_OT_vertices_to_sphere);
-
+       WM_operatortype_append(MESH_OT_split_mesh);
+       WM_operatortype_append(MESH_OT_extrude_repeat);
+       WM_operatortype_append(MESH_OT_edge_rotate_selected);
+       WM_operatortype_append(MESH_OT_loop_to_region);
+       WM_operatortype_append(MESH_OT_region_to_loop);
+       
+       WM_operatortype_append(MESH_OT_rotate_uvs);
+       WM_operatortype_append(MESH_OT_mirror_uvs);
+       WM_operatortype_append(MESH_OT_rotate_colors);
+       WM_operatortype_append(MESH_OT_mirror_colors);
+       
        WM_operatortype_append(MESH_OT_fill);
        WM_operatortype_append(MESH_OT_beauty_fill);
        WM_operatortype_append(MESH_OT_convert_quads_to_tris);
@@ -162,7 +171,11 @@ void ED_operatortypes_mesh(void)
        WM_operatortype_append(MESH_OT_similar_edge_select);
        WM_operatortype_append(MESH_OT_similar_face_select);
        WM_operatortype_append(MESH_OT_select_multi_loop);
-       WM_operatortype_append(MESH_OT_separate);
+       WM_operatortype_append(MESH_OT_mark_seam);
+       WM_operatortype_append(MESH_OT_mark_sharp);
+       WM_operatortype_append(MESH_OT_smooth_vertex);
+       WM_operatortype_append(MESH_OT_flip_editnormals);
+       WM_operatortype_append(MESH_OT_knife_cut);
        
 }
 
@@ -186,7 +199,6 @@ void ED_keymap_mesh(wmWindowManager *wm)
        WM_keymap_add_item(keymap, "MESH_OT_shortest_path_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
        
        WM_keymap_add_item(keymap, "MESH_OT_de_select_all", AKEY, KM_PRESS, 0, 0);
-       WM_keymap_add_item(keymap, "MESH_OT_bmesh_test", JKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "MESH_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
        WM_keymap_add_item(keymap, "MESH_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
        WM_keymap_add_item(keymap, "MESH_OT_select_invert", IKEY, KM_PRESS, KM_CTRL, 0);
@@ -201,7 +213,17 @@ void ED_keymap_mesh(wmWindowManager *wm)
        
        WM_keymap_add_item(keymap, "MESH_OT_select_random", SPACEKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "MESH_OT_vertices_to_sphere", SKEY, KM_PRESS, KM_CTRL|KM_SHIFT , 0);
-       
+
+       WM_keymap_add_item(keymap, "MESH_OT_mark_seam", ONEKEY, KM_PRESS, KM_CTRL , 0);
+       RNA_boolean_set(WM_keymap_add_item(keymap, "MESH_OT_mark_seam", ONEKEY, KM_PRESS, KM_ALT , 0)->ptr,"clear",1);
+
+       WM_keymap_add_item(keymap, "MESH_OT_mark_sharp", TWOKEY, KM_PRESS, KM_CTRL , 0);
+       RNA_boolean_set(WM_keymap_add_item(keymap, "MESH_OT_mark_sharp", TWOKEY, KM_PRESS, KM_ALT , 0)->ptr,"set",1);
+
+       WM_keymap_add_item(keymap, "MESH_OT_smooth_vertex", THREEKEY, KM_PRESS, KM_CTRL , 0);
+
+       WM_keymap_add_item(keymap, "MESH_OT_flip_editnormals", THREEKEY, KM_PRESS, KM_ALT , 0);
+
        /* temp hotkeys! */
        WM_keymap_add_item(keymap, "MESH_OT_similar_vertex_select", GKEY, KM_PRESS, KM_SHIFT, 0);
        WM_keymap_add_item(keymap, "MESH_OT_similar_edge_select", GKEY, KM_PRESS, KM_SHIFT2|KM_CTRL, 0);
@@ -233,6 +255,21 @@ void ED_keymap_mesh(wmWindowManager *wm)
        WM_keymap_add_item(keymap, "MESH_OT_convert_quads_to_tris", TKEY, KM_PRESS, KM_CTRL, 0);
        WM_keymap_add_item(keymap, "MESH_OT_convert_tris_to_quads", JKEY, KM_PRESS, KM_ALT, 0);
        
+       WM_keymap_add_item(keymap, "MESH_OT_split_mesh", FOURKEY, KM_PRESS, KM_CTRL, 0);
+       WM_keymap_add_item(keymap, "MESH_OT_extrude_repeat", FOURKEY, KM_PRESS, KM_ALT, 0);
+       WM_keymap_add_item(keymap, "MESH_OT_edge_rotate_selected", FIVEKEY, KM_PRESS, KM_CTRL, 0);
+       
+       WM_keymap_add_item(keymap, "MESH_OT_loop_to_region",SIXKEY, KM_PRESS, KM_CTRL, 0);
+       WM_keymap_add_item(keymap, "MESH_OT_region_to_loop",SIXKEY, KM_PRESS, KM_ALT, 0);
+       
+       WM_keymap_add_item(keymap, "MESH_OT_rotate_uvs",SEVENKEY, KM_PRESS, KM_CTRL, 0);
+       WM_keymap_add_item(keymap, "MESH_OT_mirror_uvs",SEVENKEY, KM_PRESS, KM_ALT, 0);
+       WM_keymap_add_item(keymap, "MESH_OT_rotate_colors",EIGHTKEY, KM_PRESS, KM_CTRL, 0);
+       WM_keymap_add_item(keymap, "MESH_OT_mirror_colors",EIGHTKEY, KM_PRESS, KM_ALT, 0);
+
+       
+       
+       
        /* add/remove */
        WM_keymap_add_item(keymap, "MESH_OT_add_edge_face", FKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "MESH_OT_add_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
@@ -246,6 +283,9 @@ void ED_keymap_mesh(wmWindowManager *wm)
        WM_keymap_add_item(keymap, "MESH_OT_make_fgon", FKEY, KM_PRESS, KM_ALT, 0);
        WM_keymap_add_item(keymap, "MESH_OT_clear_fgon", FKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0);
        
+       WM_keymap_add_item(keymap, "MESH_OT_knife_cut", LEFTMOUSE, KM_PRESS, KM_ALT|KM_CTRL, 0);
+       
+       
        
 }
 
index 373bc81b3b1ba1fc62d6fb1d2b8a448e3bee27ed..b90009adfa83d62c01540809cec16b83e04d535a 100644 (file)
@@ -479,17 +479,17 @@ void OBJECT_OT_curve_add(wmOperatorType *ot)
 
 static int object_add_primitive_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
-       uiMenuItem *head= uiPupMenuBegin("Add Object");
+       uiMenuItem *head= uiPupMenuBegin("Add Object", 0);
        
        uiMenuLevelEnumO(head, "OBJECT_OT_mesh_add", "type");
        uiMenuLevelEnumO(head, "OBJECT_OT_curve_add", "type");
-       uiMenuItemEnumO(head, "OBJECT_OT_object_add", "type", OB_SURF);
-       uiMenuItemEnumO(head, "OBJECT_OT_object_add", "type", OB_MBALL);
-       uiMenuItemEnumO(head, "OBJECT_OT_object_add", "type", OB_CAMERA);
-       uiMenuItemEnumO(head, "OBJECT_OT_object_add", "type", OB_LAMP);
-       uiMenuItemEnumO(head, "OBJECT_OT_object_add", "type", OB_EMPTY);
-       uiMenuItemEnumO(head, "OBJECT_OT_object_add", "type", OB_ARMATURE);
-       uiMenuItemEnumO(head, "OBJECT_OT_object_add", "type", OB_LATTICE);
+       uiMenuItemEnumO(head, 0, "OBJECT_OT_object_add", "type", OB_SURF);
+       uiMenuItemEnumO(head, 0, "OBJECT_OT_object_add", "type", OB_MBALL);
+       uiMenuItemEnumO(head, 0, "OBJECT_OT_object_add", "type", OB_CAMERA);
+       uiMenuItemEnumO(head, 0, "OBJECT_OT_object_add", "type", OB_LAMP);
+       uiMenuItemEnumO(head, 0, "OBJECT_OT_object_add", "type", OB_EMPTY);
+       uiMenuItemEnumO(head, 0, "OBJECT_OT_object_add", "type", OB_ARMATURE);
+       uiMenuItemEnumO(head, 0, "OBJECT_OT_object_add", "type", OB_LATTICE);
        
        uiPupMenuEnd(C, head);
        
@@ -526,70 +526,53 @@ void ED_base_object_free_and_unlink(Scene *scene, Base *base)
        MEM_freeN(base);
 }
 
-void delete_obj(Scene *scene, View3D *v3d, int ok)
+static int object_delete_exec(bContext *C, wmOperator *op)
 {
-       Base *base, *nbase;
+       Scene *scene= CTX_data_scene(C);
        int islamp= 0;
        
-       if(scene->obedit) return; // XXX get from context
-       if(scene->id.lib) return;
-
-       for(base= FIRSTBASE; base; base= nbase) {
-               nbase= base->next;
-
-               if(TESTBASE(v3d, base)) { 
-                       if(ok==0) {
-                               int shift= 0; // XXX
-                               /* Shift Del is global delete */
-                               if (shift) {
-                                       if(!okee("Erase selected Object(s) Globally")) return;
-                                       ok= 2;
-                               } else {
-                                       if(!okee("Erase selected Object(s)")) return;
-                                       ok= 1;
-                               }
-                       }
-                       
-//                     ED_view3d_exit_paint_modes(C);
+       if(CTX_data_edit_object(C)) 
+               return OPERATOR_CANCELLED;
+       
+       ED_view3d_exit_paint_modes(C);
 
-                       if(base->object->type==OB_LAMP) islamp= 1;
+       CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
 
-                       if (ok==2) {
-                               Scene *scene; 
-                               Base *base_other;
-                               
-                               for (scene= G.main->scene.first; scene; scene= scene->id.next) {
-                                       if (scene != scene && !(scene->id.lib)) {
-                                               base_other= object_in_scene( base->object, scene );
-                                               if (base_other) {
-                                                       ED_base_object_free_and_unlink( scene, base_other );
-                                               }
-                                       }
-                               }
-                       }
-                       
-                       /* remove from current scene only */
-                       ED_base_object_free_and_unlink(scene, base);
-               }
+               if(base->object->type==OB_LAMP) islamp= 1;
+               
+               /* remove from current scene only */
+               ED_base_object_free_and_unlink(scene, base);
        }
+       CTX_DATA_END;
 
        if(islamp) reshadeall_displist(scene);  /* only frees displist */
-
-// XXX redraw_test_buttons(OBACT);
-       allqueue(REDRAWVIEW3D, 0);
-       allqueue (REDRAWACTION, 0);
-       allqueue(REDRAWIPO, 0);
-       allqueue(REDRAWDATASELECT, 0);
-//     allspace(OOPS_TEST, 0);
-       allqueue(REDRAWOOPS, 0);
-       allqueue(REDRAWACTION, 0);
-       allqueue(REDRAWNLA, 0);
        
        DAG_scene_sort(scene);
-       ED_anim_dag_flush_update(C);    
+       ED_anim_dag_flush_update(C);
+       
+       WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, CTX_data_scene(C));
+       
+       return OPERATOR_FINISHED;
+}
 
+void OBJECT_OT_delete(wmOperatorType *ot)
+{
+       
+       /* identifiers */
+       ot->name= "Delete Objects";
+       ot->idname= "OBJECT_OT_delete";
+       
+       /* api callbacks */
+       ot->invoke= WM_operator_confirm;
+       ot->exec= object_delete_exec;
+       ot->poll= ED_operator_scene_editable;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       
 }
 
+
 static void single_object_users__forwardModifierLinks(void *userData, Object *ob, Object **obpoin)
 {
        ID_NEW(*obpoin);
@@ -1686,17 +1669,7 @@ static int object_clear_location_exec(bContext *C, wmOperator *op)
        int armature_clear= 0;
 
        CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
-               if ((ob->flag & OB_POSEMODE)) {
-                       /* only clear pose transforms if:
-                        *      - with a mesh in weightpaint mode, it's related armature needs to be cleared
-                        *      - with clearing transform of object being edited at the time
-                        */
-                       if ((G.f & G_WEIGHTPAINT) || (ob==OBACT)) {
-                               clear_armature(scene, ob, 'g');
-                               armature_clear= 1;      /* silly system to prevent another dag update, so no action applied */
-                       }
-               }
-               else if((G.f & G_WEIGHTPAINT)==0) {
+               if((G.f & G_WEIGHTPAINT)==0) {
                        if ((ob->protectflag & OB_LOCK_LOCX)==0)
                                ob->loc[0]= ob->dloc[0]= 0.0f;
                        if ((ob->protectflag & OB_LOCK_LOCY)==0)
@@ -1739,17 +1712,7 @@ static int object_clear_rotation_exec(bContext *C, wmOperator *op)
        int armature_clear= 0;
 
        CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
-               if ((ob->flag & OB_POSEMODE)) {
-                       /* only clear pose transforms if:
-                        *      - with a mesh in weightpaint mode, it's related armature needs to be cleared
-                        *      - with clearing transform of object being edited at the time
-                        */
-                       if ((G.f & G_WEIGHTPAINT) || (ob==OBACT)) {
-                               clear_armature(scene, ob, 'r');
-                               armature_clear= 1;      /* silly system to prevent another dag update, so no action applied */
-                       }
-               }
-               else if((G.f & G_WEIGHTPAINT)==0) {
+               if((G.f & G_WEIGHTPAINT)==0) {
                        /* eulers can only get cleared if they are not protected */
                        if ((ob->protectflag & OB_LOCK_ROTX)==0)
                                ob->rot[0]= ob->drot[0]= 0.0f;
@@ -1793,17 +1756,7 @@ static int object_clear_scale_exec(bContext *C, wmOperator *op)
        int armature_clear= 0;
 
        CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
-               if ((ob->flag & OB_POSEMODE)) {
-                       /* only clear pose transforms if:
-                        *      - with a mesh in weightpaint mode, it's related armature needs to be cleared
-                        *      - with clearing transform of object being edited at the time
-                        */
-                       if ((G.f & G_WEIGHTPAINT) || (ob==OBACT)) {
-                               clear_armature(scene, ob, 's');
-                               armature_clear= 1;      /* silly system to prevent another dag update, so no action applied */
-                       }
-               }
-               else if((G.f & G_WEIGHTPAINT)==0) {
+    &nbs