Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-05-21 19:34:09 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-05-21 19:34:09 +0400
commit94902dac977cfc089e9740782a19c6ab370cdc03 (patch)
treebf715f3e99859913a741dd37e3338a6f5cfe7eb6 /source
parent65143c50e0cbbd111c5fa01f54d0177d1a50704f (diff)
2.5 UI: Modifier Template
* template_modifier creates the modifier box, and returns a layout to put the buttons in. * Only the armature modifier is now done with python code, all other modifiers use C code. To convert a modifier to python, remove the corresponding C code and create a function in DATA_PT_modifiers. * Some modifiers still require some RNA work to get it working well, especially to make pointers editable. Mostly that is a matter of defining an own _set callback and put some of the modifier C code into it. * Still various buttons that don't work, like for hooks or mesh deform binding. * Fix for crashing decimate modifier (still disabled). * Removed UI_BUT_NO_HILITE, HMENU. * Make uiLayoutBox work with align.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_object.h1
-rw-r--r--source/blender/blenkernel/intern/modifier.c15
-rw-r--r--source/blender/blenkernel/intern/object.c12
-rw-r--r--source/blender/editors/include/ED_object.h9
-rw-r--r--source/blender/editors/include/UI_interface.h9
-rw-r--r--source/blender/editors/interface/interface.c15
-rw-r--r--source/blender/editors/interface/interface_api.c8
-rw-r--r--source/blender/editors/interface/interface_handlers.c59
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/interface/interface_layout.c27
-rw-r--r--source/blender/editors/interface/interface_regions.c2
-rw-r--r--source/blender/editors/interface/interface_templates.c1428
-rw-r--r--source/blender/editors/interface/interface_widgets.c1
-rw-r--r--source/blender/editors/object/object_edit.c15
-rw-r--r--source/blender/editors/object/object_modifier.c346
-rw-r--r--source/blender/makesrna/intern/rna_access.c5
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c42
-rw-r--r--source/blender/python/intern/bpy_ui.c1
18 files changed, 1893 insertions, 104 deletions
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 2af72d98701..3d71193f37a 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -85,6 +85,7 @@ struct Object *add_object(struct Scene *scene, int type);
struct Object *copy_object(struct Object *ob);
void expand_local_object(struct Object *ob);
void make_local_object(struct Object *ob);
+int object_data_is_libdata(struct Object *ob);
void set_mblur_offs(float blur);
void set_field_offs(float field);
void disable_speed_curve(int val);
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 6578feeeed1..d02b660d992 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -4058,17 +4058,15 @@ static void decimateModifier_copyData(ModifierData *md, ModifierData *target)
tdmd->percent = dmd->percent;
}
-//XXX
-#if 0
static DerivedMesh *decimateModifier_applyModifier(
ModifierData *md, Object *ob, DerivedMesh *derivedData,
int useRenderParams, int isFinalCalc)
{
- DecimateModifierData *dmd = (DecimateModifierData*) md;
+ // DecimateModifierData *dmd = (DecimateModifierData*) md;
DerivedMesh *dm = derivedData, *result = NULL;
MVert *mvert;
MFace *mface;
- LOD_Decimation_Info lod;
+ // LOD_Decimation_Info lod;
int totvert, totface;
int a, numTris;
@@ -4090,6 +4088,8 @@ static DerivedMesh *decimateModifier_applyModifier(
goto exit;
}
+ // XXX
+#if 0
lod.vertex_buffer= MEM_mallocN(3*sizeof(float)*totvert, "vertices");
lod.vertex_normal_buffer= MEM_mallocN(3*sizeof(float)*totvert, "normals");
lod.triangle_index_buffer= MEM_mallocN(3*sizeof(int)*numTris, "trias");
@@ -4174,11 +4174,14 @@ static DerivedMesh *decimateModifier_applyModifier(
MEM_freeN(lod.vertex_buffer);
MEM_freeN(lod.vertex_normal_buffer);
MEM_freeN(lod.triangle_index_buffer);
+#else
+ modifier_setError(md, "Modifier not working yet in 2.5.");
+ goto exit;
+#endif
exit:
return result;
}
-#endif
/* Smooth */
@@ -8271,7 +8274,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->flags = eModifierTypeFlag_AcceptsMesh;
mti->initData = decimateModifier_initData;
mti->copyData = decimateModifier_copyData;
- //XXX mti->applyModifier = decimateModifier_applyModifier;
+ mti->applyModifier = decimateModifier_applyModifier;
mti = INIT_TYPE(Smooth);
mti->type = eModifierTypeType_OnlyDeform;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index b913651d856..d7619010808 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1320,6 +1320,18 @@ void make_local_object(Object *ob)
expand_local_object(ob);
}
+/* returns true if the Object data is a from an external blend file (libdata) */
+int object_data_is_libdata(Object *ob)
+{
+ if(!ob) return 0;
+ if(ob->proxy) return 0;
+ if(ob->id.lib) return 1;
+ if(!ob->data) return 0;
+ if(((ID *)ob->data)->lib) return 1;
+
+ return 0;
+}
+
/* *************** PROXY **************** */
/* when you make proxy, ensure the exposed layers are extern */
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 8ff716476ad..1074c53bec6 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -39,6 +39,7 @@ struct KeyBlock;
struct Lattice;
struct Mesh;
struct Curve;
+struct ReportList;
/* object_edit.c */
void ED_operatortypes_object(void);
@@ -86,7 +87,13 @@ void latt_to_key(struct Lattice *lt, struct KeyBlock *kb);
void key_to_curve(struct KeyBlock *kb, struct Curve *cu, struct ListBase *nurb);
void curve_to_key(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb);
-
+/* object_modifier.c */
+int ED_object_modifier_delete(struct ReportList *reports, struct Object *ob, struct ModifierData *md);
+int ED_object_modifier_move_down(struct ReportList *reports, struct Object *ob, struct ModifierData *md);
+int ED_object_modifier_move_up(struct ReportList *reports, struct Object *ob, struct ModifierData *md);
+int ED_object_modifier_convert(struct ReportList *reports, struct Scene *scene, struct Object *ob, struct ModifierData *md);
+int ED_object_modifier_apply(struct ReportList *reports, struct Scene *scene, struct Object *ob, struct ModifierData *md);
+int ED_object_modifier_copy(struct ReportList *reports, struct Object *ob, struct ModifierData *md);
#endif /* ED_OBJECT_H */
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 61fd6cb0b79..3a52e00b981 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -86,7 +86,7 @@ typedef struct uiLayout uiLayout;
#define UI_BLOCK_NUMSELECT 8
#define UI_BLOCK_ENTER_OK 16
#define UI_BLOCK_NOSHADOW 32
-#define UI_BLOCK_NO_HILITE 64 /* XXX 2.5 not implemented */
+#define UI_BLOCK_UNUSED 64
#define UI_BLOCK_MOVEMOUSE_QUIT 128
#define UI_BLOCK_KEEP_OPEN 256
#define UI_BLOCK_POPUP 512
@@ -127,8 +127,7 @@ typedef struct uiLayout uiLayout;
#define UI_BUT_ALIGN_DOWN (1<<17)
#define UI_BUT_DISABLED (1<<18)
- /* dont draw hilite on mouse over */
-#define UI_NO_HILITE (1<<19)
+#define UI_BUT_UNUSED (1<<19)
#define UI_BUT_ANIMATED (1<<20)
#define UI_BUT_ANIMATED_KEY (1<<21)
#define UI_BUT_DRIVEN (1<<22)
@@ -188,8 +187,7 @@ typedef struct uiLayout uiLayout;
#define ICONTOGN (34<<9)
#define FTPREVIEW (35<<9)
#define NUMABS (36<<9)
-#define HMENU (37<<9)
-#define TOGBUT (38<<9)
+#define TOGBUT (37<<9)
#define BUTTYPE (63<<9)
/* Drawing
@@ -560,6 +558,7 @@ uiBlock *uiLayoutFreeBlock(uiLayout *layout);
void uiTemplateHeader(uiLayout *layout, struct bContext *C);
void uiTemplateHeaderID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname,
char *newop, char *openop, char *unlinkop);
+uiLayout *uiTemplateModifier(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr);
/* items */
void uiItemO(uiLayout *layout, char *name, int icon, char *opname);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index b4c2969c955..3ec91975a91 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1987,7 +1987,7 @@ void uiBlockEndAlign(uiBlock *block)
int ui_but_can_align(uiBut *but)
{
- return !ELEM(but->type, LABEL, ROUNDBOX);
+ return (but->type != LABEL);
}
static void ui_block_do_align_but(uiBlock *block, uiBut *first, int nr)
@@ -2221,8 +2221,6 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short
}
but->flag |= (block->flag & UI_BUT_ALIGN);
- if(block->flag & UI_BLOCK_NO_HILITE)
- but->flag |= UI_NO_HILITE;
if (but->lock) {
if (but->lockstr) {
@@ -2230,12 +2228,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short
}
}
- if(but->type == ROUNDBOX) {
- but->flag |= UI_NO_HILITE;
- BLI_addhead(&block->buttons, but);
- }
- else
- BLI_addtail(&block->buttons, but);
+ BLI_addtail(&block->buttons, but);
if(block->curlayout)
ui_layout_add_but(block->curlayout, but);
@@ -2999,7 +2992,7 @@ uiBut *uiDefPulldownBut(uiBlock *block, uiBlockCreateFunc func, void *arg, char
uiBut *uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, char *str, short x1, short y1, short x2, short y2, char *tip)
{
- uiBut *but= ui_def_but(block, HMENU, 0, str, x1, y1, x2, y2, arg, 0.0, 0.0, 0.0, 0.0, tip);
+ uiBut *but= ui_def_but(block, PULLDOWN, 0, str, x1, y1, x2, y2, arg, 0.0, 0.0, 0.0, 0.0, tip);
but->menu_create_func= func;
ui_check_but(but);
return but;
@@ -3007,7 +3000,7 @@ uiBut *uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, char *str,
uiBut *uiDefIconTextMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, char *str, short x1, short y1, short x2, short y2, char *tip)
{
- uiBut *but= ui_def_but(block, HMENU, 0, str, x1, y1, x2, y2, arg, 0.0, 0.0, 0.0, 0.0, tip);
+ uiBut *but= ui_def_but(block, PULLDOWN, 0, str, x1, y1, x2, y2, arg, 0.0, 0.0, 0.0, 0.0, tip);
but->icon= (BIFIconID) icon;
but->flag|= UI_HAS_ICON;
diff --git a/source/blender/editors/interface/interface_api.c b/source/blender/editors/interface/interface_api.c
index b593aef2208..0aa6d9895cb 100644
--- a/source/blender/editors/interface/interface_api.c
+++ b/source/blender/editors/interface/interface_api.c
@@ -189,5 +189,13 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_string(func, "new", "", 0, "", "Operator identifier to create a new ID block.");
RNA_def_string(func, "open", "", 0, "", "Operator identifier to open a new ID block.");
RNA_def_string(func, "unlink", "", 0, "", "Operator identifier to unlink the ID block.");
+
+ func= RNA_def_function(srna, "template_modifier", "uiTemplateModifier");
+ parm= RNA_def_pointer(func, "context", "Context", "", "Current context.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_pointer(func, "data", "AnyType", "", "Modifier data.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in.");
+ RNA_def_function_return(func, parm);
}
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index ea5eb354b54..c15e4664862 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -431,13 +431,6 @@ static void ui_apply_but_NUM(bContext *C, uiBut *but, uiHandleButtonData *data)
data->applied= 1;
}
-static void ui_apply_but_LABEL(bContext *C, uiBut *but, uiHandleButtonData *data)
-{
- ui_apply_but_func(C, but);
- data->retval= but->retval;
- data->applied= 1;
-}
-
static void ui_apply_but_TOG3(bContext *C, uiBut *but, uiHandleButtonData *data)
{
if(but->pointype==SHO ) {
@@ -590,10 +583,6 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
break;
case HSVSLI:
break;
- case ROUNDBOX:
- case LABEL:
- ui_apply_but_LABEL(C, but, data);
- break;
case TOG3:
ui_apply_but_TOG3(C, but, data);
break;
@@ -602,7 +591,6 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
case ICONTEXTROW:
case BLOCK:
case PULLDOWN:
- case HMENU:
case COL:
ui_apply_but_BLOCK(C, but, data);
break;
@@ -630,6 +618,8 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
case LINK:
case INLINK:
break;
+ default:
+ break;
}
but->editstr= editstr;
@@ -1423,20 +1413,28 @@ static void ui_blockopen_begin(bContext *C, uiBut *but, uiHandleButtonData *data
switch(but->type) {
case BLOCK:
case PULLDOWN:
- func= but->block_create_func;
- arg= but->poin;
- break;
- case HMENU:
- menufunc= but->menu_create_func;
- arg= but->poin;
+ if(but->menu_create_func) {
+ menufunc= but->menu_create_func;
+ arg= but->poin;
+ }
+ else {
+ func= but->block_create_func;
+ arg= but->poin;
+ }
break;
case MENU:
- data->origvalue= ui_get_but_val(but);
- data->value= data->origvalue;
- but->editval= &data->value;
+ if(but->menu_create_func) {
+ menufunc= but->menu_create_func;
+ arg= but->poin;
+ }
+ else {
+ data->origvalue= ui_get_but_val(but);
+ data->value= data->origvalue;
+ but->editval= &data->value;
- handlefunc= ui_block_func_MENU;
- arg= but;
+ handlefunc= ui_block_func_MENU;
+ arg= but;
+ }
break;
case ICONROW:
handlefunc= ui_block_func_ICONROW;
@@ -2698,17 +2696,10 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
retval= ui_do_but_TEX(C, block, but, data, event);
break;
case MENU:
- retval= ui_do_but_BLOCK(C, but, data, event);
- break;
case ICONROW:
- retval= ui_do_but_BLOCK(C, but, data, event);
- break;
case ICONTEXTROW:
- retval= ui_do_but_BLOCK(C, but, data, event);
- break;
case BLOCK:
case PULLDOWN:
- case HMENU:
retval= ui_do_but_BLOCK(C, but, data, event);
break;
case BUTM:
@@ -2841,9 +2832,7 @@ static uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y)
ui_window_to_block(ar, block, &mx, &my);
for(but=block->buttons.first; but; but= but->next) {
- if(but->flag & UI_NO_HILITE)
- continue;
- if(but->type==LABEL)
+ if(ELEM3(but->type, LABEL, ROUNDBOX, SEPR))
continue;
if(ui_but_contains_pt(but, mx, my))
@@ -2896,7 +2885,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
button_tooltip_timer_reset(but);
/* automatic open pulldown block timer */
- if(ELEM4(but->type, BLOCK, PULLDOWN, HMENU, ICONTEXTROW)) {
+ if(ELEM3(but->type, BLOCK, PULLDOWN, ICONTEXTROW)) {
if(!data->autoopentimer) {
int time;
@@ -3410,7 +3399,7 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle *menu,
else but= ui_but_first(block);
}
- if(but && ELEM(but->type, BLOCK, HMENU))
+ if(but && ELEM(but->type, BLOCK, PULLDOWN))
ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_OPEN);
}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 13c9d09aff1..b59846738ce 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -188,7 +188,7 @@ struct uiBut {
/* BLOCK data */
uiBlockCreateFunc block_create_func;
- /* HMENU data */
+ /* PULLDOWN/MENU data */
uiMenuCreateFunc menu_create_func;
/* RNA data */
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 56183bfb314..3fa0a8849fe 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -147,6 +147,7 @@ typedef struct uiLayoutItemSplt {
typedef struct uiLayoutItemBx {
uiLayout litem;
+ uiBut *roundbox;
} uiLayoutItemBx;
typedef struct uiLayoutItemRoot {
@@ -839,6 +840,8 @@ static void ui_item_menu(uiLayout *layout, char *name, int icon, uiMenuCreateFun
if(layout->root->type == UI_LAYOUT_HEADER)
uiBlockSetEmboss(block, UI_EMBOSS);
+ else if(layout->root->type == UI_LAYOUT_PANEL)
+ but->type= MENU;
}
void uiItemM(uiLayout *layout, bContext *C, char *name, int icon, char *menuname)
@@ -1146,12 +1149,14 @@ static void ui_litem_estimate_box(uiLayout *litem)
ui_litem_estimate_column(litem);
litem->w += 2*style->boxspace;
- litem->h += 2*style->boxspace;
+ litem->h += style->boxspace;
}
static void ui_litem_layout_box(uiLayout *litem)
{
+ uiLayoutItemBx *box= (uiLayoutItemBx*)litem;
uiStyle *style= litem->root->style;
+ uiBut *but;
int w, h;
w= litem->w;
@@ -1169,10 +1174,14 @@ static void ui_litem_layout_box(uiLayout *litem)
litem->y -= style->boxspace;
if(w != 0) litem->w += 2*style->boxspace;
- if(h != 0) litem->h += 2*style->boxspace;
+ if(h != 0) litem->h += style->boxspace;
/* roundbox around the sublayout */
- uiDefBut(litem->root->block, ROUNDBOX, 0, "", litem->x, litem->y, litem->w, litem->h, NULL, 7.0, 0.0, 3, 20, "");
+ but= box->roundbox;
+ but->x1= litem->x;
+ but->y1= litem->y;
+ but->x2= litem->x+litem->w;
+ but->y2= litem->y+litem->h;
}
/* multi-column layout, automatically flowing to the next */
@@ -1475,6 +1484,8 @@ uiLayout *uiLayoutBox(uiLayout *layout)
uiBlockSetCurLayout(layout->root->block, &box->litem);
+ box->roundbox= uiDefBut(layout->root->block, ROUNDBOX, 0, "", 0, 0, 0, 0, NULL, 0.0, 0.0, 0, 0, "");
+
return &box->litem;
}
@@ -1564,13 +1575,21 @@ static void ui_item_align(uiLayout *litem, int nr)
{
uiItem *item;
uiButtonItem *bitem;
+ uiLayoutItemBx *box;
- for(item=litem->items.first; item; item=item->next) {
+ for(item=litem->items.last; item; item=item->prev) {
if(item->type == ITEM_BUTTON) {
bitem= (uiButtonItem*)item;
if(ui_but_can_align(bitem->but))
bitem->but->alignnr= nr;
}
+ else if(item->type == ITEM_LAYOUT_FREE);
+ else if(item->type == ITEM_LAYOUT_BOX) {
+ box= (uiLayoutItemBx*)item;
+ box->roundbox->alignnr= nr;
+ BLI_remlink(&litem->root->block->buttons, box->roundbox);
+ BLI_addhead(&litem->root->block->buttons, box->roundbox);
+ }
else
ui_item_align((uiLayout*)item, nr);
}
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 847c0a02ee4..4148f36726b 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -654,7 +654,7 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
/* if this is being created from a button */
if(but) {
- if(ELEM3(but->type, BLOCK, PULLDOWN, HMENU))
+ if(ELEM(but->type, BLOCK, PULLDOWN))
block->xofs = -2; /* for proper alignment */
/* only used for automatic toolbox, so can set the shift flag */
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 8969e2b69ae..d90869a1059 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -236,3 +236,1431 @@ void uiTemplateHeaderID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
MEM_freeN(template);
}
+/************************ Modifier Template *************************/
+
+#define ERROR_LIBDATA_MESSAGE "Can't edit external libdata"
+
+#define B_NOP 0
+#define B_MODIFIER_RECALC 1
+#define B_MODIFIER_REDRAW 2
+#define B_CHANGEDEP 3
+#define B_ARM_RECALCDATA 4
+
+#include <string.h>
+
+#include "DNA_armature_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_object_force.h"
+#include "DNA_object_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_particle_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_bmesh.h"
+#include "BKE_curve.h"
+#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_displist.h"
+#include "BKE_global.h"
+#include "BKE_lattice.h"
+#include "BKE_main.h"
+#include "BKE_mesh.h"
+#include "BKE_modifier.h"
+#include "BKE_object.h"
+#include "BKE_particle.h"
+#include "BKE_report.h"
+
+#include "UI_resources.h"
+#include "ED_util.h"
+
+#include "BLI_arithb.h"
+#include "BLI_listbase.h"
+
+#include "ED_object.h"
+
+void do_modifier_panels(bContext *C, void *arg, int event)
+{
+ Scene *scene= CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+
+ switch(event) {
+ case B_MODIFIER_REDRAW:
+ WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
+ break;
+
+ case B_MODIFIER_RECALC:
+ WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
+ DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+ object_handle_update(scene, ob);
+ // XXX countall();
+ break;
+ }
+}
+
+static void modifiers_del(bContext *C, void *ob_v, void *md_v)
+{
+ ReportList reports;
+
+ BKE_reports_init(&reports, RPT_STORE);
+
+ if(ED_object_modifier_delete(&reports, ob_v, md_v))
+ ED_undo_push(C, "Delete modifier");
+ else
+ uiPupMenuReports(C, &reports);
+
+ BKE_reports_clear(&reports);
+}
+
+static void modifiers_moveUp(bContext *C, void *ob_v, void *md_v)
+{
+ ReportList reports;
+
+ BKE_reports_init(&reports, RPT_STORE);
+
+ if(ED_object_modifier_move_up(&reports, ob_v, md_v))
+ ED_undo_push(C, "Move modifier");
+ else
+ uiPupMenuReports(C, &reports);
+
+ BKE_reports_clear(&reports);
+}
+
+static void modifiers_moveDown(bContext *C, void *ob_v, void *md_v)
+{
+ ReportList reports;
+
+ BKE_reports_init(&reports, RPT_STORE);
+
+ if(ED_object_modifier_move_down(&reports, ob_v, md_v))
+ ED_undo_push(C, "Move modifier");
+ else
+ uiPupMenuReports(C, &reports);
+
+ BKE_reports_clear(&reports);
+}
+
+static void modifier_testLatticeObj(bContext *C, char *name, ID **idpp)
+{
+ Main *bmain= CTX_data_main(C);
+ ID *id;
+
+ for (id= bmain->object.first; id; id= id->next) {
+ if( strcmp(name, id->name+2)==0 ) {
+ if (((Object *)id)->type != OB_LATTICE) {
+ uiPupMenuError(C, "Lattice deform object must be a lattice");
+ break;
+ }
+ *idpp= id;
+ return;
+ }
+ }
+ *idpp= 0;
+}
+
+static void modifier_testCurveObj(bContext *C, char *name, ID **idpp)
+{
+ Main *bmain= CTX_data_main(C);
+ ID *id;
+
+ for (id= bmain->object.first; id; id= id->next) {
+ if( strcmp(name, id->name+2)==0 ) {
+ if (((Object *)id)->type != OB_CURVE) {
+ uiPupMenuError(C, "Curve deform object must be a curve");
+ break;
+ }
+ *idpp= id;
+ return;
+ }
+ }
+ *idpp= 0;
+}
+
+static void modifier_testMeshObj(bContext *C, char *name, ID **idpp)
+{
+ Main *bmain= CTX_data_main(C);
+ Object *obact= CTX_data_active_object(C);
+ ID *id;
+
+ for (id= bmain->object.first; id; id= id->next) {
+ /* no boolean on its own object */
+ if(id != (ID *)obact) {
+ if( strcmp(name, id->name+2)==0 ) {
+ if (((Object *)id)->type != OB_MESH) {
+ uiPupMenuError(C, "Boolean modifier object must be a mesh");
+ break;
+ }
+ *idpp= id;
+ return;
+ }
+ }
+ }
+ *idpp= NULL;
+}
+
+static void modifier_testArmatureObj(bContext *C, char *name, ID **idpp)
+{
+ Main *bmain= CTX_data_main(C);
+ ID *id;
+
+ for (id= bmain->object.first; id; id= id->next) {
+ if( strcmp(name, id->name+2)==0 ) {
+ if (((Object *)id)->type != OB_ARMATURE) {
+ uiPupMenuError(C, "Armature deform object must be an armature");
+ break;
+ }
+ *idpp= id;
+ return;
+ }
+ }
+ *idpp= 0;
+}
+
+static void modifier_testTexture(bContext *C, char *name, ID **idpp)
+{
+ Main *bmain= CTX_data_main(C);
+ ID *id;
+
+ for(id = bmain->tex.first; id; id = id->next) {
+ if(strcmp(name, id->name + 2) == 0) {
+ *idpp = id;
+ /* texture gets user, objects not: delete object = clear modifier */
+ id_us_plus(id);
+ return;
+ }
+ }
+ *idpp = 0;
+}
+
+#if 0 /* this is currently unused, but could be useful in the future */
+static void modifier_testMaterial(bContext *C, char *name, ID **idpp)
+{
+ Main *bmain= CTX_data_main(C);
+ ID *id;
+
+ for(id = bmain->mat.first; id; id = id->next) {
+ if(strcmp(name, id->name + 2) == 0) {
+ *idpp = id;
+ return;
+ }
+ }
+ *idpp = 0;
+}
+#endif
+
+static void modifier_testImage(bContext *C, char *name, ID **idpp)
+{
+ Main *bmain= CTX_data_main(C);
+ ID *id;
+
+ for(id = bmain->image.first; id; id = id->next) {
+ if(strcmp(name, id->name + 2) == 0) {
+ *idpp = id;
+ return;
+ }
+ }
+ *idpp = 0;
+}
+
+/* autocomplete callback for ID buttons */
+void autocomplete_image(bContext *C, char *str, void *arg_v)
+{
+ Main *bmain= CTX_data_main(C);
+
+ /* search if str matches the beginning of an ID struct */
+ if(str[0]) {
+ AutoComplete *autocpl = autocomplete_begin(str, 22);
+ ID *id;
+
+ for(id = bmain->image.first; id; id = id->next)
+ autocomplete_do_name(autocpl, id->name+2);
+
+ autocomplete_end(autocpl, str);
+ }
+}
+
+/* autocomplete callback for ID buttons */
+void autocomplete_meshob(bContext *C, char *str, void *arg_v)
+{
+ Main *bmain= CTX_data_main(C);
+
+ /* search if str matches the beginning of an ID struct */
+ if(str[0]) {
+ AutoComplete *autocpl = autocomplete_begin(str, 22);
+ ID *id;
+
+ for(id = bmain->object.first; id; id = id->next)
+ if(((Object *)id)->type == OB_MESH)
+ autocomplete_do_name(autocpl, id->name+2);
+
+ autocomplete_end(autocpl, str);
+ }
+}
+
+static void modifiers_convertParticles(bContext *C, void *obv, void *mdv)
+{
+ Scene *scene= CTX_data_scene(C);
+ ReportList reports;
+
+ BKE_reports_init(&reports, RPT_STORE);
+
+ if(ED_object_modifier_convert(&reports, scene, obv, mdv))
+ ED_undo_push(C, "Convert particles to mesh object(s).");
+ else
+ uiPupMenuReports(C, &reports);
+
+ BKE_reports_clear(&reports);
+}
+
+static void modifiers_applyModifier(bContext *C, void *obv, void *mdv)
+{
+ Scene *scene= CTX_data_scene(C);
+ ReportList reports;
+
+ BKE_reports_init(&reports, RPT_STORE);
+
+ if(ED_object_modifier_apply(&reports, scene, obv, mdv))
+ ED_undo_push(C, "Apply modifier");
+ else
+ uiPupMenuReports(C, &reports);
+
+ BKE_reports_clear(&reports);
+}
+
+static void modifiers_copyModifier(bContext *C, void *ob_v, void *md_v)
+{
+ ReportList reports;
+
+ BKE_reports_init(&reports, RPT_STORE);
+
+ if(ED_object_modifier_copy(&reports, ob_v, md_v))
+ ED_undo_push(C, "Copy modifier");
+ else
+ uiPupMenuReports(C, &reports);
+
+ BKE_reports_clear(&reports);
+}
+
+static void modifiers_setOnCage(bContext *C, void *ob_v, void *md_v)
+{
+ Object *ob = ob_v;
+ ModifierData *md;
+
+ int i, cageIndex = modifiers_getCageIndex(ob, NULL );
+
+ for( i = 0, md=ob->modifiers.first; md; ++i, md=md->next )
+ if( md == md_v ) {
+ if( i >= cageIndex )
+ md->mode ^= eModifierMode_OnCage;
+ break;
+ }
+}
+
+static void modifiers_clearHookOffset(bContext *C, void *ob_v, void *md_v)
+{
+ Object *ob = ob_v;
+ ModifierData *md = md_v;
+ HookModifierData *hmd = (HookModifierData*) md;
+
+ if (hmd->object) {
+ Mat4Invert(hmd->object->imat, hmd->object->obmat);
+ Mat4MulSerie(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
+ ED_undo_push(C, "Clear hook offset");
+ }
+}
+
+static void modifiers_cursorHookCenter(bContext *C, void *ob_v, void *md_v)
+{
+ /* XXX
+ Object *ob = ob_v;
+ ModifierData *md = md_v;
+ HookModifierData *hmd = (HookModifierData*) md;
+
+ if(G.vd) {
+ float *curs = give_cursor();
+ float bmat[3][3], imat[3][3];
+
+ where_is_object(ob);
+
+ Mat3CpyMat4(bmat, ob->obmat);
+ Mat3Inv(imat, bmat);
+
+ curs= give_cursor();
+ hmd->cent[0]= curs[0]-ob->obmat[3][0];
+ hmd->cent[1]= curs[1]-ob->obmat[3][1];
+ hmd->cent[2]= curs[2]-ob->obmat[3][2];
+ Mat3MulVecfl(imat, hmd->cent);
+
+ ED_undo_push(C, "Hook cursor center");
+ }*/
+}
+
+static void modifiers_selectHook(bContext *C, void *ob_v, void *md_v)
+{
+ /* XXX ModifierData *md = md_v;
+ HookModifierData *hmd = (HookModifierData*) md;
+
+ hook_select(hmd);*/
+}
+
+static void modifiers_reassignHook(bContext *C, void *ob_v, void *md_v)
+{
+ /* XXX ModifierData *md = md_v;
+ HookModifierData *hmd = (HookModifierData*) md;
+ float cent[3];
+ int *indexar, tot, ok;
+ char name[32];
+
+ ok= hook_getIndexArray(&tot, &indexar, name, cent);
+
+ if (!ok) {
+ uiPupMenuError(C, "Requires selected vertices or active Vertex Group");
+ } else {
+ if (hmd->indexar) {
+ MEM_freeN(hmd->indexar);
+ }
+
+ VECCOPY(hmd->cent, cent);
+ hmd->indexar = indexar;
+ hmd->totindex = tot;
+ }*/
+}
+
+static void modifiers_convertToReal(bContext *C, void *ob_v, void *md_v)
+{
+ Object *ob = ob_v;
+ ModifierData *md = md_v;
+ ModifierData *nmd = modifier_new(md->type);
+
+ modifier_copyData(md, nmd);
+ nmd->mode &= ~eModifierMode_Virtual;
+
+ BLI_addhead(&ob->modifiers, nmd);
+
+ ob->partype = PAROBJECT;
+
+ ED_undo_push(C, "Modifier convert to real");
+}
+
+static void build_uvlayer_menu_vars(CustomData *data, char **menu_string,
+ int *uvlayer_tmp, char *uvlayer_name)
+{
+ char strtmp[38];
+ int totuv, i;
+ CustomDataLayer *layer
+ = &data->layers[CustomData_get_layer_index(data, CD_MTFACE)];
+
+ *uvlayer_tmp = -1;
+
+ totuv = CustomData_number_of_layers(data, CD_MTFACE);
+
+ *menu_string = MEM_callocN(sizeof(**menu_string) * (totuv * 38 + 10),
+ "menu_string");
+ sprintf(*menu_string, "UV Layer%%t");
+ for(i = 0; i < totuv; i++) {
+ /* assign first layer as uvlayer_name if uvlayer_name is null. */
+ if(strcmp(layer->name, uvlayer_name) == 0) *uvlayer_tmp = i + 1;
+ sprintf(strtmp, "|%s%%x%d", layer->name, i + 1);
+ strcat(*menu_string, strtmp);
+ layer++;
+ }
+
+ /* there is no uvlayer defined, or else it was deleted. Assign active
+ * layer, then recalc modifiers.
+ */
+ if(*uvlayer_tmp == -1) {
+ if(CustomData_get_active_layer_index(data, CD_MTFACE) != -1) {
+ *uvlayer_tmp = 1;
+ layer = data->layers;
+ for(i = 0; i < CustomData_get_active_layer_index(data, CD_MTFACE);
+ i++, layer++) {
+ if(layer->type == CD_MTFACE) (*uvlayer_tmp)++;
+ }
+ strcpy(uvlayer_name, layer->name);
+
+ /* update the modifiers */
+ /* XXX do_modifier_panels(B_MODIFIER_RECALC);*/
+ } else {
+ /* ok we have no uv layers, so make sure menu button knows that.*/
+ *uvlayer_tmp = 0;
+ }
+ }
+}
+
+void set_wave_uvlayer(bContext *C, void *arg1, void *arg2)
+{
+ WaveModifierData *wmd=arg1;
+ CustomDataLayer *layer = arg2;
+
+ /*check we have UV layers*/
+ if (wmd->uvlayer_tmp < 1) return;
+ layer = layer + (wmd->uvlayer_tmp-1);
+
+ strcpy(wmd->uvlayer_name, layer->name);
+}
+
+void set_displace_uvlayer(bContext *C, void *arg1, void *arg2)
+{
+ DisplaceModifierData *dmd=arg1;
+ CustomDataLayer *layer = arg2;
+
+ /*check we have UV layers*/
+ if (dmd->uvlayer_tmp < 1) return;
+ layer = layer + (dmd->uvlayer_tmp-1);
+
+ strcpy(dmd->uvlayer_name, layer->name);
+}
+
+void set_uvproject_uvlayer(bContext *C, void *arg1, void *arg2)
+{
+ UVProjectModifierData *umd=arg1;
+ CustomDataLayer *layer = arg2;
+
+ /*check we have UV layers*/
+ if (umd->uvlayer_tmp < 1) return;
+ layer = layer + (umd->uvlayer_tmp-1);
+
+ strcpy(umd->uvlayer_name, layer->name);
+}
+
+static void modifiers_bindMeshDeform(bContext *C, void *ob_v, void *md_v)
+{
+ Scene *scene= CTX_data_scene(C);
+ MeshDeformModifierData *mmd = (MeshDeformModifierData*) md_v;
+ Object *ob = (Object*)ob_v;
+
+ if(mmd->bindcos) {
+ if(mmd->bindweights) MEM_freeN(mmd->bindweights);
+ if(mmd->bindcos) MEM_freeN(mmd->bindcos);
+ if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
+ if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
+ if(mmd->dynverts) MEM_freeN(mmd->dynverts);
+ mmd->bindweights= NULL;
+ mmd->bindcos= NULL;
+ mmd->dyngrid= NULL;
+ mmd->dyninfluences= NULL;
+ mmd->dynverts= NULL;
+ mmd->totvert= 0;
+ mmd->totcagevert= 0;
+ mmd->totinfluence= 0;
+ }
+ else {
+ DerivedMesh *dm;
+ int mode= mmd->modifier.mode;
+
+ /* force modifier to run, it will call binding routine */
+ mmd->needbind= 1;
+ mmd->modifier.mode |= eModifierMode_Realtime;
+
+ if(ob->type == OB_MESH) {
+ dm= mesh_create_derived_view(scene, ob, 0);
+ dm->release(dm);
+ }
+ else if(ob->type == OB_LATTICE) {
+ lattice_calc_modifiers(scene, ob);
+ }
+ else if(ob->type==OB_MBALL) {
+ makeDispListMBall(scene, ob);
+ }
+ else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
+ makeDispListCurveTypes(scene, ob, 0);
+ }
+
+ mmd->needbind= 0;
+ mmd->modifier.mode= mode;
+ }
+}
+
+void modifiers_explodeFacepa(bContext *C, void *arg1, void *arg2)
+{
+ ExplodeModifierData *emd=arg1;
+
+ emd->flag |= eExplodeFlag_CalcFaces;
+}
+
+void modifiers_explodeDelVg(bContext *C, void *arg1, void *arg2)
+{
+ ExplodeModifierData *emd=arg1;
+ emd->vgroup = 0;
+}
+
+static int modifier_is_fluid_particles(ModifierData *md)
+{
+ if(md->type == eModifierType_ParticleSystem) {
+ if(((ParticleSystemModifierData *)md)->psys->part->type == PART_FLUID)
+ return 1;
+ }
+ return 0;
+}
+
+static uiLayout *draw_modifier(bContext *C, uiLayout *layout, Object *ob, ModifierData *md, int index, int cageIndex, int lastCageIndex)
+{
+ Object *obedit= CTX_data_edit_object(C);
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ uiBut *but;
+ uiBlock *block;
+ uiLayout *column, *row, *result= NULL;
+ int isVirtual = md->mode&eModifierMode_Virtual;
+ int x = 0, y = 0; // XXX , color = md->error?TH_REDALERT:TH_BUT_NEUTRAL;
+ int editing = (obedit==ob);
+ short width = 295, buttonWidth = width-120-10;
+ char str[128];
+
+ column= uiLayoutColumn(layout, 1);
+
+ /* rounded header */
+ /* XXX uiBlockSetCol(block, color); */
+ /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
+ block= uiLayoutFreeBlock(uiLayoutBox(column));
+ uiBlockSetHandleFunc(block, do_modifier_panels, NULL);
+
+ //uiDefBut(block, ROUNDBOX, 0, "", x-10, y-4, width, 25, NULL, 7.0, 0.0,
+ // (!isVirtual && (md->mode&eModifierMode_Expanded))?3:15, 20, "");
+ /* XXX uiBlockSetCol(block, TH_AUTO); */
+
+ /* open/close icon */
+ if (!isVirtual) {
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+ uiDefIconButBitI(block, ICONTOG, eModifierMode_Expanded, B_MODIFIER_REDRAW, VICON_DISCLOSURE_TRI_RIGHT, x-10, y-2, 20, 20, &md->mode, 0.0, 0.0, 0.0, 0.0, "Collapse/Expand Modifier");
+ }
+
+ uiBlockSetEmboss(block, UI_EMBOSS);
+
+ if (isVirtual) {
+ sprintf(str, "%s parent deform", md->name);
+ uiDefBut(block, LABEL, 0, str, x+10, y-1, width-110, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Modifier name");
+
+ but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Make Real", x+width-100, y, 80, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Convert virtual modifier to a real modifier");
+ uiButSetFunc(but, modifiers_convertToReal, ob, md);
+ } else {
+ uiBlockBeginAlign(block);
+ uiDefBut(block, TEX, B_MODIFIER_REDRAW, "", x+10, y-1, buttonWidth-60, 19, md->name, 0.0, sizeof(md->name)-1, 0.0, 0.0, "Modifier name");
+
+ /* Softbody not allowed in this situation, enforce! */
+ if (((md->type!=eModifierType_Softbody && md->type!=eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) && (md->type!=eModifierType_Surface)) {
+ uiDefIconButBitI(block, TOG, eModifierMode_Render, B_MODIFIER_RECALC, ICON_SCENE, x+10+buttonWidth-60, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during rendering");
+ but= uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_MODIFIER_RECALC, VICON_VIEW3D, x+10+buttonWidth-40, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during interactive display");
+ if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
+ uiDefIconButBitI(block, TOG, eModifierMode_Editmode, B_MODIFIER_RECALC, VICON_EDIT, x+10+buttonWidth-20, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during Editmode (only if enabled for display)");
+ }
+ }
+ uiBlockEndAlign(block);
+
+ /* XXX uiBlockSetEmboss(block, UI_EMBOSSR); */
+
+ if (ob->type==OB_MESH && modifier_couldBeCage(md) && index<=lastCageIndex) {
+ int icon; //, color;
+
+ if (index==cageIndex) {
+ // XXX color = TH_BUT_SETTING;
+ icon = VICON_EDITMODE_HLT;
+ } else if (index<cageIndex) {
+ // XXX color = TH_BUT_NEUTRAL;
+ icon = VICON_EDITMODE_DEHLT;
+ } else {
+ // XXX color = TH_BUT_NEUTRAL;
+ icon = ICON_BLANK1;
+ }
+ /* XXX uiBlockSetCol(block, color); */
+ but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, icon, x+width-105, y, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Apply modifier to editing cage during Editmode");
+ uiButSetFunc(but, modifiers_setOnCage, ob, md);
+ /* XXX uiBlockSetCol(block, TH_AUTO); */
+ }
+
+ /* XXX uiBlockSetCol(block, TH_BUT_ACTION); */
+
+ but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, VICON_MOVE_UP, x+width-75, y, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Move modifier up in stack");
+ uiButSetFunc(but, modifiers_moveUp, ob, md);
+
+ but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, VICON_MOVE_DOWN, x+width-75+20, y, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Move modifier down in stack");
+ uiButSetFunc(but, modifiers_moveDown, ob, md);
+
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+
+ // deletion over the deflection panel
+ // fluid particle modifier can't be deleted here
+ if(md->type!=eModifierType_Fluidsim && md->type!=eModifierType_Collision && md->type!=eModifierType_Surface && !modifier_is_fluid_particles(md))
+ {
+ but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, VICON_X, x+width-70+40, y, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Delete modifier");
+ uiButSetFunc(but, modifiers_del, ob, md);
+ }
+ /* XXX uiBlockSetCol(block, TH_AUTO); */
+ }
+
+ uiBlockSetEmboss(block, UI_EMBOSS);
+
+ if(!isVirtual && (md->mode&eModifierMode_Expanded)) {
+ int cy = y - 8;
+ int lx = x + width - 60 - 15;
+ uiLayout *box;
+
+ box= uiLayoutBox(column);
+ row= uiLayoutRow(box, 1);
+
+ y -= 18;
+
+ if (!isVirtual && (md->type!=eModifierType_Collision) && (md->type!=eModifierType_Surface)) {
+ uiBlockSetButLock(block, object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE); /* only here obdata, the rest of modifiers is ob level */
+
+ uiBlockBeginAlign(block);
+ if (md->type==eModifierType_ParticleSystem) {
+ ParticleSystem *psys= ((ParticleSystemModifierData *)md)->psys;
+
+ if(!(G.f & G_PARTICLEEDIT)) {
+ if(ELEM3(psys->part->draw_as, PART_DRAW_PATH, PART_DRAW_GR, PART_DRAW_OB) && psys->pathcache) {
+ but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Convert", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Convert the current particles to a mesh object");
+ uiButSetFunc(but, modifiers_convertParticles, ob, md);
+ }
+ }
+ }
+ else{
+ but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Apply", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Apply the current modifier and remove from the stack");
+ uiButSetFunc(but, modifiers_applyModifier, ob, md);
+ }
+
+ uiBlockClearButLock(block);
+ uiBlockSetButLock(block, ob && ob->id.lib, ERROR_LIBDATA_MESSAGE);
+
+ if (md->type!=eModifierType_Fluidsim && md->type!=eModifierType_Softbody && md->type!=eModifierType_ParticleSystem && (md->type!=eModifierType_Cloth)) {
+ but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Copy", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Duplicate the current modifier at the same position in the stack");
+ uiButSetFunc(but, modifiers_copyModifier, ob, md);
+ }
+ uiBlockEndAlign(block);
+ }
+
+ result= uiLayoutColumn(box, 0);
+ block= uiLayoutFreeBlock(box);
+
+ lx = x + 10;
+ cy = y + 10 - 1;
+ uiBlockBeginAlign(block);
+ if (md->type==eModifierType_Subsurf) {
+ SubsurfModifierData *smd = (SubsurfModifierData*) md;
+ char subsurfmenu[]="Subsurf Type%t|Catmull-Clark%x0|Simple Subdiv.%x1";
+ uiDefButS(block, MENU, B_MODIFIER_RECALC, subsurfmenu, lx,(cy-=19),buttonWidth,19, &smd->subdivType, 0, 0, 0, 0, "Selects type of subdivision algorithm.");
+ uiDefButS(block, NUM, B_MODIFIER_RECALC, "Levels:", lx, (cy-=19), buttonWidth,19, &smd->levels, 1, 6, 0, 0, "Number subdivisions to perform");
+ uiDefButS(block, NUM, B_MODIFIER_REDRAW, "Render Levels:", lx, (cy-=19), buttonWidth,19, &smd->renderLevels, 1, 6, 0, 0, "Number subdivisions to perform when rendering");
+
+ /* Disabled until non-EM DerivedMesh implementation is complete */
+
+ /*
+ uiDefButBitS(block, TOG, eSubsurfModifierFlag_Incremental, B_MODIFIER_RECALC, "Incremental", lx, (cy-=19),90,19,&smd->flags, 0, 0, 0, 0, "Use incremental calculation, even outside of mesh mode");
+ uiDefButBitS(block, TOG, eSubsurfModifierFlag_DebugIncr, B_MODIFIER_RECALC, "Debug", lx+90, cy,buttonWidth-90,19,&smd->flags, 0, 0, 0, 0, "Visualize the subsurf incremental calculation, for debugging effect of other modifiers");
+ */
+
+ uiDefButBitS(block, TOG, eSubsurfModifierFlag_ControlEdges, B_MODIFIER_RECALC, "Optimal Draw", lx, (cy-=19), buttonWidth,19,&smd->flags, 0, 0, 0, 0, "Skip drawing/rendering of interior subdivided edges");
+ uiDefButBitS(block, TOG, eSubsurfModifierFlag_SubsurfUv, B_MODIFIER_RECALC, "Subsurf UV", lx, (cy-=19),buttonWidth,19,&smd->flags, 0, 0, 0, 0, "Use subsurf to subdivide UVs");
+ } else if (md->type==eModifierType_Lattice) {
+ LatticeModifierData *lmd = (LatticeModifierData*) md;
+ uiDefIDPoinBut(block, modifier_testLatticeObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &lmd->object, "Lattice object to deform with");
+ but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &lmd->name, 0.0, 31.0, 0, 0, "Vertex Group name");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
+ } else if (md->type==eModifierType_Curve) {
+ CurveModifierData *cmd = (CurveModifierData*) md;
+ uiDefIDPoinBut(block, modifier_testCurveObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &cmd->object, "Curve object to deform with");
+ but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &cmd->name, 0.0, 31.0, 0, 0, "Vertex Group name");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
+
+ uiDefButS(block, ROW,B_MODIFIER_RECALC,"X", lx, (cy-=19), 19,19, &cmd->defaxis, 12.0, MOD_CURVE_POSX, 0, 0, "The axis that the curve deforms along");
+ uiDefButS(block, ROW,B_MODIFIER_RECALC,"Y", (lx+buttonWidth/6), cy, 19,19, &cmd->defaxis, 12.0, MOD_CURVE_POSY, 0, 0, "The axis that the curve deforms along");
+ uiDefButS(block, ROW,B_MODIFIER_RECALC,"Z", (lx+2*buttonWidth/6), cy, 19,19, &cmd->defaxis, 12.0, MOD_CURVE_POSZ, 0, 0, "The axis that the curve deforms along");
+ uiDefButS(block, ROW,B_MODIFIER_RECALC,"-X", (lx+3*buttonWidth/6), cy, 24,19, &cmd->defaxis, 12.0, MOD_CURVE_NEGX, 0, 0, "The axis that the curve deforms along");
+ uiDefButS(block, ROW,B_MODIFIER_RECALC,"-Y", (lx+4*buttonWidth/6), cy, 24,19, &cmd->defaxis, 12.0, MOD_CURVE_NEGY, 0, 0, "The axis that the curve deforms along");
+ uiDefButS(block, ROW,B_MODIFIER_RECALC,"-Z", (lx+buttonWidth-buttonWidth/6), cy, 24,19, &cmd->defaxis, 12.0, MOD_CURVE_NEGZ, 0, 0, "The axis that the curve deforms along");
+ } else if (md->type==eModifierType_Build) {
+ BuildModifierData *bmd = (BuildModifierData*) md;
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Start:", lx, (cy-=19), buttonWidth,19, &bmd->start, 1.0, MAXFRAMEF, 100, 0, "Specify the start frame of the effect");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Length:", lx, (cy-=19), buttonWidth,19, &bmd->length, 1.0, MAXFRAMEF, 100, 0, "Specify the total time the build effect requires");
+ uiDefButI(block, TOG, B_MODIFIER_RECALC, "Randomize", lx, (cy-=19), buttonWidth,19, &bmd->randomize, 0, 0, 1, 0, "Randomize the faces or edges during build.");
+ uiDefButI(block, NUM, B_MODIFIER_RECALC, "Seed:", lx, (cy-=19), buttonWidth,19, &bmd->seed, 1.0, MAXFRAMEF, 100, 0, "Specify the seed for random if used.");
+ } else if (md->type==eModifierType_Mirror) {
+ MirrorModifierData *mmd = (MirrorModifierData*) md;
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Merge Limit:", lx, (cy-=19), buttonWidth,19, &mmd->tolerance, 0.0, 1.0, 10, 10, "Distance from axis within which mirrored vertices are merged");
+ uiDefButBitS(block, TOG, MOD_MIR_AXIS_X, B_MODIFIER_RECALC, "X", lx,(cy-=19),20,19, &mmd->flag, 0, 0, 0, 0, "Enable X axis mirror");
+ uiDefButBitS(block, TOG, MOD_MIR_AXIS_Y, B_MODIFIER_RECALC, "Y", lx+20,cy,20,19, &mmd->flag, 0, 0, 0, 0, "Enable Y axis mirror");
+ uiDefButBitS(block, TOG, MOD_MIR_AXIS_Z, B_MODIFIER_RECALC, "Z", lx+40,cy,20,19, &mmd->flag, 0, 0, 0, 0, "Enable Z axis mirror");
+ uiDefButBitS(block, TOG, MOD_MIR_CLIPPING, B_MODIFIER_RECALC, "Do Clipping", lx+60, cy, buttonWidth-60,19, &mmd->flag, 1, 2, 0, 0, "Prevents during Transform vertices to go through Mirror");
+ uiDefButBitS(block, TOG, MOD_MIR_VGROUP, B_MODIFIER_RECALC, "Mirror Vgroups", lx, (cy-=19), buttonWidth,19, &mmd->flag, 1, 2, 0, 0, "Mirror vertex groups (e.g. .R->.L)");
+ uiDefButBitS(block, TOG, MOD_MIR_MIRROR_U, B_MODIFIER_RECALC,
+ "Mirror U",
+ lx, (cy-=19), buttonWidth/2, 19,
+ &mmd->flag, 0, 0, 0, 0,
+ "Mirror the U texture coordinate around "
+ "the 0.5 point");
+ uiDefButBitS(block, TOG, MOD_MIR_MIRROR_V, B_MODIFIER_RECALC,
+ "Mirror V",
+ lx + buttonWidth/2 + 1, cy, buttonWidth/2, 19,
+ &mmd->flag, 0, 0, 0, 0,
+ "Mirror the V texture coordinate around "
+ "the 0.5 point");
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
+ "Ob: ", lx, (cy -= 19), buttonWidth, 19,
+ &mmd->mirror_ob,
+ "Object to use as mirror");
+ } else if (md->type==eModifierType_Bevel) {
+ BevelModifierData *bmd = (BevelModifierData*) md;
+ /*uiDefButS(block, ROW, B_MODIFIER_RECALC, "Distance",
+ lx, (cy -= 19), (buttonWidth/2), 19, &bmd->val_flags,
+ 11.0, 0, 0, 0,
+ "Interpret bevel value as a constant distance from each edge");
+ uiDefButS(block, ROW, B_MODIFIER_RECALC, "Radius",
+ (lx+buttonWidth/2), cy, (buttonWidth - buttonWidth/2), 19, &bmd->val_flags,
+ 11.0, BME_BEVEL_RADIUS, 0, 0,
+ "Interpret bevel value as a radius - smaller angles will be beveled more");*/
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Width: ",
+ lx, (cy -= 19), buttonWidth, 19, &bmd->value,
+ 0.0, 0.5, 5, 4,
+ "Bevel value/amount");
+ /*uiDefButI(block, NUM, B_MODIFIER_RECALC, "Recurs",
+ lx, (cy -= 19), buttonWidth, 19, &bmd->res,
+ 1, 4, 5, 2,
+ "Number of times to bevel");*/
+ uiDefButBitS(block, TOG, BME_BEVEL_VERT,
+ B_MODIFIER_RECALC, "Only Vertices",
+ lx, (cy -= 19), buttonWidth, 19,
+ &bmd->flags, 0, 0, 0, 0,
+ "Bevel only verts/corners; not edges");
+ uiBlockEndAlign(block);
+
+ uiDefBut(block, LABEL, 1, "Limit using:", lx, (cy-=25), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButS(block, ROW, B_MODIFIER_RECALC, "None",
+ lx, (cy -= 19), (buttonWidth/3), 19, &bmd->lim_flags,
+ 12.0, 0, 0, 0,
+ "Bevel the entire mesh by a constant amount");
+ uiDefButS(block, ROW, B_MODIFIER_RECALC, "Angle",
+ (lx+buttonWidth/3), cy, (buttonWidth/3), 19, &bmd->lim_flags,
+ 12.0, BME_BEVEL_ANGLE, 0, 0,
+ "Only bevel edges with sharp enough angles between faces");
+ uiDefButS(block, ROW, B_MODIFIER_RECALC, "BevWeight",
+ lx+(2*buttonWidth/3), cy, buttonWidth-2*(buttonWidth/3), 19, &bmd->lim_flags,
+ 12.0, BME_BEVEL_WEIGHT, 0, 0,
+ "Use bevel weights to determine how much bevel is applied; apply them separately in vert/edge select mode");
+ if ((bmd->lim_flags & BME_BEVEL_WEIGHT) && !(bmd->flags & BME_BEVEL_VERT)) {
+ uiDefButS(block, ROW, B_MODIFIER_RECALC, "Min",
+ lx, (cy -= 19), (buttonWidth/3), 19, &bmd->e_flags,
+ 13.0, BME_BEVEL_EMIN, 0, 0,
+ "The sharpest edge's weight is used when weighting a vert");
+ uiDefButS(block, ROW, B_MODIFIER_RECALC, "Average",
+ (lx+buttonWidth/3), cy, (buttonWidth/3), 19, &bmd->e_flags,
+ 13.0, 0, 0, 0,
+ "The edge weights are averaged when weighting a vert");
+ uiDefButS(block, ROW, B_MODIFIER_RECALC, "Max",
+ (lx+2*(buttonWidth/3)), cy, buttonWidth-2*(buttonWidth/3), 19, &bmd->e_flags,
+ 13.0, BME_BEVEL_EMAX, 0, 0,
+ "The largest edge's wieght is used when weighting a vert");
+ }
+ else if (bmd->lim_flags & BME_BEVEL_ANGLE) {
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Angle:",
+ lx, (cy -= 19), buttonWidth, 19, &bmd->bevel_angle,
+ 0.0, 180.0, 100, 2,
+ "Angle above which to bevel edges");
+ }
+ } else if (md->type==eModifierType_EdgeSplit) {
+ EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md;
+ uiDefButBitI(block, TOG, MOD_EDGESPLIT_FROMANGLE,
+ B_MODIFIER_RECALC, "From Edge Angle",
+ lx, (cy -= 19), buttonWidth, 19,
+ &emd->flags, 0, 0, 0, 0,
+ "Split edges with high angle between faces");
+ if(emd->flags & MOD_EDGESPLIT_FROMANGLE) {
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Split Angle:",
+ lx, (cy -= 19), buttonWidth, 19, &emd->split_angle,
+ 0.0, 180.0, 100, 2,
+ "Angle above which to split edges");
+ }
+ uiDefButBitI(block, TOG, MOD_EDGESPLIT_FROMFLAG,
+ B_MODIFIER_RECALC, "From Marked As Sharp",
+ lx, (cy -= 19), buttonWidth, 19,
+ &emd->flags, 0, 0, 0, 0,
+ "Split edges that are marked as sharp");
+ } else if (md->type==eModifierType_Displace) {
+ DisplaceModifierData *dmd = (DisplaceModifierData*) md;
+ but = uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ",
+ lx, (cy -= 19), buttonWidth, 19,
+ &dmd->defgrp_name, 0.0, 31.0, 0, 0,
+ "Name of vertex group to displace"
+ " (displace whole mesh if blank)");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
+ uiDefIDPoinBut(block, modifier_testTexture, ID_TE, B_CHANGEDEP,
+ "Texture: ", lx, (cy -= 19), buttonWidth, 19,
+ &dmd->texture,
+ "Texture to use as displacement input");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Midlevel:",
+ lx, (cy -= 19), buttonWidth, 19, &dmd->midlevel,
+ 0, 1, 10, 3,
+ "Material value that gives no displacement");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Strength:",
+ lx, (cy -= 19), buttonWidth, 19, &dmd->strength,
+ -1000, 1000, 10, 0.1,
+ "Strength of displacement");
+ sprintf(str, "Direction%%t|Normal%%x%d|RGB -> XYZ%%x%d|"
+ "Z%%x%d|Y%%x%d|X%%x%d",
+ MOD_DISP_DIR_NOR, MOD_DISP_DIR_RGB_XYZ,
+ MOD_DISP_DIR_Z, MOD_DISP_DIR_Y, MOD_DISP_DIR_X);
+ uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
+ lx, (cy -= 19), buttonWidth, 19, &dmd->direction,
+ 0.0, 1.0, 0, 0, "Displace direction");
+ sprintf(str, "Texture Coordinates%%t"
+ "|Local%%x%d|Global%%x%d|Object%%x%d|UV%%x%d",
+ MOD_DISP_MAP_LOCAL, MOD_DISP_MAP_GLOBAL,
+ MOD_DISP_MAP_OBJECT, MOD_DISP_MAP_UV);
+ uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
+ lx, (cy -= 19), buttonWidth, 19, &dmd->texmapping,
+ 0.0, 1.0, 0, 0,
+ "Texture coordinates used for displacement input");
+ if (dmd->texmapping == MOD_DISP_MAP_UV) {
+ char *strtmp;
+ int i;
+ Mesh *me= (Mesh*)ob->data;
+ CustomData *fdata = obedit? &me->edit_mesh->fdata: &me->fdata;
+ build_uvlayer_menu_vars(fdata, &strtmp, &dmd->uvlayer_tmp,
+ dmd->uvlayer_name);
+ but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp,
+ lx, (cy -= 19), buttonWidth, 19, &dmd->uvlayer_tmp,
+ 0.0, 1.0, 0, 0, "Set the UV layer to use");
+ MEM_freeN(strtmp);
+ i = CustomData_get_layer_index(fdata, CD_MTFACE);
+ uiButSetFunc(but, set_displace_uvlayer, dmd,
+ &fdata->layers[i]);
+ }
+ if(dmd->texmapping == MOD_DISP_MAP_OBJECT) {
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
+ "Ob: ", lx, (cy -= 19), buttonWidth, 19,
+ &dmd->map_object,
+ "Object to get texture coordinates from");
+ }
+ } else if (md->type==eModifierType_UVProject) {
+ UVProjectModifierData *umd = (UVProjectModifierData *) md;
+ int i;
+ char *strtmp;
+ Mesh *me= (Mesh*)ob->data;
+ CustomData *fdata = obedit? &me->edit_mesh->fdata: &me->fdata;
+ build_uvlayer_menu_vars(fdata, &strtmp, &umd->uvlayer_tmp,
+ umd->uvlayer_name);
+ but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp,
+ lx, (cy -= 19), buttonWidth, 19, &umd->uvlayer_tmp,
+ 0.0, 1.0, 0, 0, "Set the UV layer to use");
+ i = CustomData_get_layer_index(fdata, CD_MTFACE);
+ uiButSetFunc(but, set_uvproject_uvlayer, umd, &fdata->layers[i]);
+ MEM_freeN(strtmp);
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "AspX:",
+ lx, (cy -= 19), buttonWidth / 2, 19, &umd->aspectx,
+ 1, 1000, 100, 2,
+ "Horizontal Aspect Ratio");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "AspY:",
+ lx + (buttonWidth / 2) + 1, cy, buttonWidth / 2, 19,
+ &umd->aspecty,
+ 1, 1000, 100, 2,
+ "Vertical Aspect Ratio");
+ uiDefButI(block, NUM, B_MODIFIER_RECALC, "Projectors:",
+ lx, (cy -= 19), buttonWidth, 19, &umd->num_projectors,
+ 1, MOD_UVPROJECT_MAXPROJECTORS, 0, 0,
+ "Number of objects to use as projectors");
+ for(i = 0; i < umd->num_projectors; ++i) {
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
+ "Ob: ", lx, (cy -= 19), buttonWidth, 19,
+ &umd->projectors[i],
+ "Object to use as projector");
+ }
+ uiDefIDPoinBut(block, modifier_testImage, ID_IM, B_CHANGEDEP,
+ "Image: ", lx, (cy -= 19), buttonWidth, 19,
+ &umd->image,
+ "Image to project (only faces with this image "
+ "will be altered");
+ uiButSetCompleteFunc(but, autocomplete_image, (void *)ob);
+ uiDefButBitI(block, TOG, MOD_UVPROJECT_OVERRIDEIMAGE,
+ B_MODIFIER_RECALC, "Override Image",
+ lx, (cy -= 19), buttonWidth, 19,
+ &umd->flags, 0, 0, 0, 0,
+ "Override faces' current images with the "
+ "given image");
+ } else if (md->type==eModifierType_Decimate) {
+ DecimateModifierData *dmd = (DecimateModifierData*) md;
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Ratio:", lx,(cy-=19),buttonWidth,19, &dmd->percent, 0.0, 1.0, 10, 0, "Defines the percentage of triangles to reduce to");
+ sprintf(str, "Face Count: %d", dmd->faceCount);
+ uiDefBut(block, LABEL, 1, str, lx, (cy-=19), 160,19, NULL, 0.0, 0.0, 0, 0, "Displays the current number of faces in the decimated mesh");
+ } else if (md->type==eModifierType_Mask) {
+ MaskModifierData *mmd = (MaskModifierData *)md;
+
+ sprintf(str, "Mask Mode%%t|Vertex Group%%x%d|Selected Bones%%x%d|",
+ MOD_MASK_MODE_VGROUP,MOD_MASK_MODE_ARM);
+ uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
+ lx, (cy -= 19), buttonWidth, 19, &mmd->mode,
+ 0.0, 1.0, 0, 0, "How masking region is defined");
+
+ if (mmd->mode == MOD_MASK_MODE_ARM) {
+ uiDefIDPoinBut(block, modifier_testArmatureObj, ID_OB, B_CHANGEDEP,
+ "Ob: ", lx, (cy -= 19), buttonWidth, 19, &mmd->ob_arm,
+ "Armature to use as source of bones to mask");
+ }
+ else {
+ but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ",
+ lx, (cy-=19), buttonWidth, 19, &mmd->vgroup,
+ 0.0, 31.0, 0, 0, "Vertex Group name");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
+ }
+
+ uiDefButBitI(block, TOG, MOD_MASK_INV, B_MODIFIER_RECALC, "Inverse",
+ lx, (cy-=19), buttonWidth, 19, &mmd->flag,
+ 0, 0, 0, 0, "Use vertices that are not part of region defined");
+ } else if (md->type==eModifierType_Smooth) {
+ SmoothModifierData *smd = (SmoothModifierData*) md;
+
+ uiDefButBitS(block, TOG, MOD_SMOOTH_X, B_MODIFIER_RECALC, "X", lx,(cy-=19),45,19, &smd->flag, 0, 0, 0, 0, "Enable X axis smoothing");
+ uiDefButBitS(block, TOG, MOD_SMOOTH_Y, B_MODIFIER_RECALC, "Y", lx+45,cy,45,19, &smd->flag, 0, 0, 0, 0, "Enable Y axis smoothing");
+ uiDefButBitS(block, TOG, MOD_SMOOTH_Z, B_MODIFIER_RECALC, "Z", lx+90,cy,45,19, &smd->flag, 0, 0, 0, 0, "Enable Z axis smoothing");
+
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Factor:", lx,(cy-=19),buttonWidth, 19, &smd->fac, -10.0, 10.0, 0.5, 0, "Define the amount of smoothing, from 0.0 to 1.0 (lower / higher values can deform the mesh)");
+ uiDefButS(block, NUM, B_MODIFIER_RECALC, "Repeat:", lx,(cy-=19),buttonWidth, 19, &smd->repeat, 0.0, 30.0, 1, 0, "Number of smoothing iterations");
+ but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &smd->defgrp_name, 0.0, 31.0, 0, 0, "Vertex Group name to define which vertices are affected");
+ } else if (md->type==eModifierType_Cast) {
+ CastModifierData *cmd = (CastModifierData*) md;
+
+ char casttypemenu[]="Projection Type%t|Sphere%x0|Cylinder%x1|Cuboid%x2";
+ uiDefButS(block, MENU, B_MODIFIER_RECALC, casttypemenu, lx,(cy-=19),buttonWidth - 30,19, &cmd->type, 0, 0, 0, 0, "Projection type to apply");
+ uiDefButBitS(block, TOG, MOD_CAST_X, B_MODIFIER_RECALC, "X", lx,(cy-=19),45,19, &cmd->flag, 0, 0, 0, 0, "Enable (local) X axis deformation");
+ uiDefButBitS(block, TOG, MOD_CAST_Y, B_MODIFIER_RECALC, "Y", lx+45,cy,45,19, &cmd->flag, 0, 0, 0, 0, "Enable (local) Y axis deformation");
+ if (cmd->type != MOD_CAST_TYPE_CYLINDER) {
+ uiDefButBitS(block, TOG, MOD_CAST_Z, B_MODIFIER_RECALC, "Z", lx+90,cy,45,19, &cmd->flag, 0, 0, 0, 0, "Enable (local) Z axis deformation");
+ }
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Factor:", lx,(cy-=19),buttonWidth, 19, &cmd->fac, -10.0, 10.0, 5, 0, "Define the amount of deformation");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Radius:", lx,(cy-=19),buttonWidth, 19, &cmd->radius, 0.0, 100.0, 10.0, 0, "Only deform vertices within this distance from the center of the effect (leave as 0 for infinite)");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Size:", lx,(cy-=19),buttonWidth, 19, &cmd->size, 0.0, 100.0, 10.0, 0, "Size of projection shape (leave as 0 for auto)");
+ uiDefButBitS(block, TOG, MOD_CAST_SIZE_FROM_RADIUS, B_MODIFIER_RECALC, "From radius", lx+buttonWidth,cy,80,19, &cmd->flag, 0, 0, 0, 0, "Use radius as size of projection shape (0 = auto)");
+ if (ob->type == OB_MESH) {
+ but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &cmd->defgrp_name, 0.0, 31.0, 0, 0, "Vertex Group name to define which vertices are affected");
+ }
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx,(cy-=19), buttonWidth,19, &cmd->object, "Control object: if available, its location determines the center of the effect");
+ if(cmd->object) {
+ uiDefButBitS(block, TOG, MOD_CAST_USE_OB_TRANSFORM, B_MODIFIER_RECALC, "Use transform", lx+buttonWidth,cy,80,19, &cmd->flag, 0, 0, 0, 0, "Use object transform to control projection shape");
+ }
+ } else if (md->type==eModifierType_Wave) {
+ WaveModifierData *wmd = (WaveModifierData*) md;
+ uiDefButBitS(block, TOG, MOD_WAVE_X, B_MODIFIER_RECALC, "X", lx,(cy-=19),45,19, &wmd->flag, 0, 0, 0, 0, "Enable X axis motion");
+ uiDefButBitS(block, TOG, MOD_WAVE_Y, B_MODIFIER_RECALC, "Y", lx+45,cy,45,19, &wmd->flag, 0, 0, 0, 0, "Enable Y axis motion");
+ uiDefButBitS(block, TOG, MOD_WAVE_CYCL, B_MODIFIER_RECALC, "Cycl", lx+90,cy,buttonWidth-90,19, &wmd->flag, 0, 0, 0, 0, "Enable cyclic wave effect");
+ uiDefButBitS(block, TOG, MOD_WAVE_NORM, B_MODIFIER_RECALC, "Normals", lx,(cy-=19),buttonWidth,19, &wmd->flag, 0, 0, 0, 0, "Displace along normals");
+ if (wmd->flag & MOD_WAVE_NORM){
+ if (ob->type==OB_MESH) {
+ uiDefButBitS(block, TOG, MOD_WAVE_NORM_X, B_MODIFIER_RECALC, "X", lx,(cy-=19),buttonWidth/3,19, &wmd->flag, 0, 0, 0, 0, "Enable displacement along the X normal");
+ uiDefButBitS(block, TOG, MOD_WAVE_NORM_Y, B_MODIFIER_RECALC, "Y", lx+(buttonWidth/3),cy,buttonWidth/3,19, &wmd->flag, 0, 0, 0, 0, "Enable displacement along the Y normal");
+ uiDefButBitS(block, TOG, MOD_WAVE_NORM_Z, B_MODIFIER_RECALC, "Z", lx+(buttonWidth/3)*2,cy,buttonWidth/3,19, &wmd->flag, 0, 0, 0, 0, "Enable displacement along the Z normal");
+ }
+ else
+ uiDefBut(block, LABEL, 1, "Meshes Only", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
+ }
+
+ uiBlockBeginAlign(block);
+ if(wmd->speed >= 0)
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time sta:", lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify starting frame of the wave");
+ else
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time end:", lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify ending frame of the wave");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Lifetime:", lx,(cy-=19),buttonWidth,19, &wmd->lifetime, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the lifespan of the wave");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Damptime:", lx,(cy-=19),buttonWidth,19, &wmd->damp, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the dampingtime of the wave");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Falloff:", lx,(cy-=19),buttonWidth,19, &wmd->falloff, 0, 100, 100, 0, "Specify the falloff radius of the waves");
+
+ cy -= 9;
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Sta x:", lx,(cy-=19),113,19, &wmd->startx, -100.0, 100.0, 100, 0, "Starting position for the X axis");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Sta y:", lx+115,cy,105,19, &wmd->starty, -100.0, 100.0, 100, 0, "Starting position for the Y axis");
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MODIFIER_RECALC, "Ob: ", lx, (cy-=19), 220,19, &wmd->objectcenter, "Object to use as Starting Position (leave blank to disable)");
+ uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ",lx, (cy -= 19), 220, 19,&wmd->defgrp_name, 0.0, 31.0, 0, 0, "Name of vertex group with which to modulate displacement");
+ uiDefIDPoinBut(block, modifier_testTexture, ID_TE, B_CHANGEDEP,"Texture: ", lx, (cy -= 19), 220, 19, &wmd->texture,"Texture with which to modulate wave");
+ sprintf(str, "Texture Coordinates%%t"
+ "|Local%%x%d|Global%%x%d|Object%%x%d|UV%%x%d",
+ MOD_WAV_MAP_LOCAL, MOD_WAV_MAP_GLOBAL,
+ MOD_WAV_MAP_OBJECT, MOD_WAV_MAP_UV);
+ uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
+ lx, (cy -= 19), 220, 19, &wmd->texmapping,
+ 0.0, 1.0, 0, 0,
+ "Texture coordinates used for modulation input");
+ if (wmd->texmapping == MOD_WAV_MAP_UV) {
+ char *strtmp;
+ int i;
+ Mesh *me = (Mesh*)ob->data;
+ CustomData *fdata = obedit? &me->edit_mesh->fdata: &me->fdata;
+ build_uvlayer_menu_vars(fdata, &strtmp, &wmd->uvlayer_tmp,
+ wmd->uvlayer_name);
+ but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp,
+ lx, (cy -= 19), 220, 19, &wmd->uvlayer_tmp,
+ 0.0, 1.0, 0, 0, "Set the UV layer to use");
+ MEM_freeN(strtmp);
+ i = CustomData_get_layer_index(fdata, CD_MTFACE);
+ uiButSetFunc(but, set_wave_uvlayer, wmd,
+ &fdata->layers[i]);
+ }
+ if(wmd->texmapping == MOD_DISP_MAP_OBJECT) {
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
+ "Ob: ", lx, (cy -= 19), 220, 19,
+ &wmd->map_object,
+ "Object to get texture coordinates from");
+ }
+ cy -= 9;
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Speed:", lx,(cy-=19),220,19, &wmd->speed, -2.0, 2.0, 0, 0, "Specify the wave speed");
+ uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Height:", lx,(cy-=19),220,19, &wmd->height, -2.0, 2.0, 0, 0, "Specify the amplitude of the wave");
+ uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Width:", lx,(cy-=19),220,19, &wmd->width, 0.0, 5.0, 0, 0, "Specify the width of the wave");
+ uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Narrow:", lx,(cy-=19),220,19, &wmd->narrow, 0.0, 10.0, 0, 0, "Specify how narrow the wave follows");
+ } else if (md->type==eModifierType_Hook) {
+ HookModifierData *hmd = (HookModifierData*) md;
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Falloff: ", lx, (cy-=19), buttonWidth,19, &hmd->falloff, 0.0, 100.0, 100, 0, "If not zero, the distance from hook where influence ends");
+ uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Force: ", lx, (cy-=19), buttonWidth,19, &hmd->force, 0.0, 1.0, 100, 0, "Set relative force of hook");
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &hmd->object, "Parent Object for hook, also recalculates and clears offset");
+ if(hmd->indexar==NULL) {
+ but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &hmd->name, 0.0, 31.0, 0, 0, "Vertex Group name");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
+ }
+ uiBlockBeginAlign(block);
+ but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Reset", lx, (cy-=19), 80,19, NULL, 0.0, 0.0, 0, 0, "Recalculate and clear offset (transform) of hook");
+ uiButSetFunc(but, modifiers_clearHookOffset, ob, md);
+ but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Recenter", lx+80, cy, buttonWidth-80,19, NULL, 0.0, 0.0, 0, 0, "Sets hook center to cursor position");
+ uiButSetFunc(but, modifiers_cursorHookCenter, ob, md);
+
+ if (editing) {
+ but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Select", lx, (cy-=19), 80,19, NULL, 0.0, 0.0, 0, 0, "Selects effected vertices on mesh");
+ uiButSetFunc(but, modifiers_selectHook, ob, md);
+ but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Reassign", lx+80, cy, buttonWidth-80,19, NULL, 0.0, 0.0, 0, 0, "Reassigns selected vertices to hook");
+ uiButSetFunc(but, modifiers_reassignHook, ob, md);
+ }
+ } else if (md->type==eModifierType_Softbody) {
+ uiDefBut(block, LABEL, 1, "See Soft Body panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
+ } else if (md->type==eModifierType_Cloth) {
+ uiDefBut(block, LABEL, 1, "See Cloth panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
+
+ } else if (md->type==eModifierType_Collision) {
+ uiDefBut(block, LABEL, 1, "See Collision panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
+ } else if (md->type==eModifierType_Surface) {
+ uiDefBut(block, LABEL, 1, "See Fields panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
+ } else if (md->type==eModifierType_Fluidsim) {
+ uiDefBut(block, LABEL, 1, "See Fluidsim panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
+ } else if (md->type==eModifierType_Boolean) {
+ BooleanModifierData *bmd = (BooleanModifierData*) md;
+ uiDefButI(block, MENU, B_MODIFIER_RECALC, "Operation%t|Intersect%x0|Union%x1|Difference%x2", lx,(cy-=19),buttonWidth,19, &bmd->operation, 0.0, 1.0, 0, 0, "Boolean operation to perform");
+ uiDefIDPoinBut(block, modifier_testMeshObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &bmd->object, "Mesh object to use for boolean operation");
+ } else if (md->type==eModifierType_Array) {
+ ArrayModifierData *amd = (ArrayModifierData*) md;
+ float range = 10000;
+ int cytop, halfwidth = (width - 5)/2 - 15;
+ int halflx = lx + halfwidth + 10;
+
+ // XXX uiBlockSetEmboss(block, UI_EMBOSSX);
+ uiBlockEndAlign(block);
+
+ /* length parameters */
+ uiBlockBeginAlign(block);
+ sprintf(str, "Length Fit%%t|Fixed Count%%x%d|Fixed Length%%x%d"
+ "|Fit To Curve Length%%x%d",
+ MOD_ARR_FIXEDCOUNT, MOD_ARR_FITLENGTH, MOD_ARR_FITCURVE);
+ uiDefButI(block, MENU, B_MODIFIER_RECALC, str,
+ lx, (cy-=19), buttonWidth, 19, &amd->fit_type,
+ 0.0, 1.0, 0, 0, "Array length calculation method");
+ switch(amd->fit_type)
+ {
+ case MOD_ARR_FIXEDCOUNT:
+ uiDefButI(block, NUM, B_MODIFIER_RECALC, "Count:",
+ lx, (cy -= 19), buttonWidth, 19, &amd->count,
+ 1, 1000, 0, 0, "Number of duplicates to make");
+ break;
+ case MOD_ARR_FITLENGTH:
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Length:",
+ lx, (cy -= 19), buttonWidth, 19, &amd->length,
+ 0, range, 10, 2,
+ "Length to fit array within");
+ break;
+ case MOD_ARR_FITCURVE:
+ uiDefIDPoinBut(block, modifier_testCurveObj, ID_OB,
+ B_CHANGEDEP, "Ob: ",
+ lx, (cy -= 19), buttonWidth, 19, &amd->curve_ob,
+ "Curve object to fit array length to");
+ break;
+ }
+ uiBlockEndAlign(block);
+
+ /* offset parameters */
+ cy -= 10;
+ cytop= cy;
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, MOD_ARR_OFF_CONST, B_MODIFIER_RECALC,
+ "Constant Offset", lx, (cy-=19), halfwidth, 19,
+ &amd->offset_type, 0, 0, 0, 0,
+ "Constant offset between duplicates "
+ "(local coordinates)");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "X:",
+ lx, (cy-=19), halfwidth, 19,
+ &amd->offset[0],
+ -range, range, 10, 3,
+ "Constant component for duplicate offsets "
+ "(local coordinates)");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Y:",
+ lx, (cy-=19), halfwidth, 19,
+ &amd->offset[1],
+ -range, range, 10, 3,
+ "Constant component for duplicate offsets "
+ "(local coordinates)");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Z:",
+ lx, (cy-=19), halfwidth, 19,
+ &amd->offset[2],
+ -range, range, 10, 3,
+ "Constant component for duplicate offsets "
+ "(local coordinates)");
+ uiBlockEndAlign(block);
+
+ cy= cytop;
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, MOD_ARR_OFF_RELATIVE, B_MODIFIER_RECALC,
+ "Relative Offset", halflx, (cy-=19), halfwidth, 19,
+ &amd->offset_type, 0, 0, 0, 0,
+ "Offset between duplicates relative to object width "
+ "(local coordinates)");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "X:",
+ halflx, (cy-=19), halfwidth, 19,
+ &amd->scale[0],
+ -range, range, 10, 3,
+ "Component for duplicate offsets relative to object "
+ "width (local coordinates)");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Y:",
+ halflx, (cy-=19), halfwidth, 19,
+ &amd->scale[1],
+ -range, range, 10, 3,
+ "Component for duplicate offsets relative to object "
+ "width (local coordinates)");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Z:",
+ halflx, (cy-=19), halfwidth, 19,
+ &amd->scale[2],
+ -range, range, 10, 3,
+ "Component for duplicate offsets relative to object "
+ "width (local coordinates)");
+ uiBlockEndAlign(block);
+
+ /* vertex merging parameters */
+ cy -= 10;
+ cytop= cy;
+
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, MOD_ARR_MERGE, B_MODIFIER_RECALC,
+ "Merge",
+ lx, (cy-=19), halfwidth/2, 19, &amd->flags,
+ 0, 0, 0, 0,
+ "Merge vertices in adjacent duplicates");
+ uiDefButBitI(block, TOG, MOD_ARR_MERGEFINAL, B_MODIFIER_RECALC,
+ "First Last",
+ lx + halfwidth/2, cy, (halfwidth+1)/2, 19,
+ &amd->flags,
+ 0, 0, 0, 0,
+ "Merge vertices in first duplicate with vertices"
+ " in last duplicate");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Limit:",
+ lx, (cy-=19), halfwidth, 19, &amd->merge_dist,
+ 0, 1.0f, 1, 4,
+ "Limit below which to merge vertices");
+
+ /* offset ob */
+ cy = cytop;
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, MOD_ARR_OFF_OBJ, B_MODIFIER_RECALC,
+ "Object Offset", halflx, (cy -= 19), halfwidth, 19,
+ &amd->offset_type, 0, 0, 0, 0,
+ "Add an object transformation to the total offset");
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
+ "Ob: ", halflx, (cy -= 19), halfwidth, 19,
+ &amd->offset_ob,
+ "Object from which to take offset transformation");
+ uiBlockEndAlign(block);
+
+ cy -= 10;
+ but = uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB,
+ B_CHANGEDEP, "Start cap: ",
+ lx, (cy -= 19), halfwidth, 19,
+ &amd->start_cap,
+ "Mesh object to use as start cap");
+ uiButSetCompleteFunc(but, autocomplete_meshob, (void *)ob);
+ but = uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB,
+ B_CHANGEDEP, "End cap: ",
+ halflx, cy, halfwidth, 19,
+ &amd->end_cap,
+ "Mesh object to use as end cap");
+ uiButSetCompleteFunc(but, autocomplete_meshob, (void *)ob);
+ } else if (md->type==eModifierType_MeshDeform) {
+ MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
+
+ uiBlockBeginAlign(block);
+ uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &mmd->object, "Mesh object to be use as cage");
+ but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-19), buttonWidth-40,19, &mmd->defgrp_name, 0.0, 31.0, 0, 0, "Vertex Group name to control overall meshdeform influence");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
+ uiDefButBitS(block, TOG, MOD_MDEF_INVERT_VGROUP, B_MODIFIER_RECALC, "Inv", lx+buttonWidth-40, (cy-=19), 40,19, &mmd->flag, 0.0, 31.0, 0, 0, "Invert vertex group influence");
+
+ uiBlockBeginAlign(block);
+ if(mmd->bindcos) {
+ but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Unbind", lx,(cy-=24), buttonWidth,19, 0, 0, 0, 0, 0, "Unbind mesh from cage");
+ uiButSetFunc(but,modifiers_bindMeshDeform,ob,md);
+ }
+ else {
+ but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Bind", lx,(cy-=24), buttonWidth,19, 0, 0, 0, 0, 0, "Bind mesh to cage");
+ uiButSetFunc(but,modifiers_bindMeshDeform,ob,md);
+ uiDefButS(block, NUM, B_NOP, "Precision:", lx,(cy-19), buttonWidth/2 + 20,19, &mmd->gridsize, 2, 10, 0.5, 0, "The grid size for binding");
+ uiDefButBitS(block, TOG, MOD_MDEF_DYNAMIC_BIND, B_MODIFIER_RECALC, "Dynamic", lx+(buttonWidth+1)/2 + 20, (cy-=19), buttonWidth/2 - 20,19, &mmd->flag, 0.0, 31.0, 0, 0, "Recompute binding dynamically on top of other deformers like Shape Keys (slower and more memory consuming!)");
+ }
+ uiBlockEndAlign(block);
+ } else if (md->type==eModifierType_ParticleSystem) {
+ uiDefBut(block, LABEL, 1, "See Particle buttons.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
+ } else if (md->type==eModifierType_ParticleInstance) {
+ ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData*) md;
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy -= 19), buttonWidth, 19, &pimd->ob, "Object that has the particlesystem");
+ uiDefButS(block, NUM, B_MODIFIER_RECALC, "PSYS:", lx, (cy -= 19), buttonWidth, 19, &pimd->psys, 1, 10, 10, 3, "Particlesystem number in the object");
+ uiDefButBitS(block, TOG, eParticleInstanceFlag_Parents, B_MODIFIER_RECALC, "Normal", lx, (cy -= 19), buttonWidth/3,19, &pimd->flag, 0, 0, 0, 0, "Create instances from normal particles");
+ uiDefButBitS(block, TOG, eParticleInstanceFlag_Children, B_MODIFIER_RECALC, "Children", lx+buttonWidth/3, cy, buttonWidth/3,19, &pimd->flag, 0, 0, 0, 0, "Create instances from child particles");
+ uiDefButBitS(block, TOG, eParticleInstanceFlag_Path, B_MODIFIER_RECALC, "Path", lx+buttonWidth*2/3, cy, buttonWidth/3,19, &pimd->flag, 0, 0, 0, 0, "Create instances along particle paths");
+ uiDefButBitS(block, TOG, eParticleInstanceFlag_Unborn, B_MODIFIER_RECALC, "Unborn", lx, (cy -= 19), buttonWidth/3,19, &pimd->flag, 0, 0, 0, 0, "Show instances when particles are unborn");
+ uiDefButBitS(block, TOG, eParticleInstanceFlag_Alive, B_MODIFIER_RECALC, "Alive", lx+buttonWidth/3, cy, buttonWidth/3,19, &pimd->flag, 0, 0, 0, 0, "Show instances when particles are alive");
+ uiDefButBitS(block, TOG, eParticleInstanceFlag_Dead, B_MODIFIER_RECALC, "Dead", lx+buttonWidth*2/3, cy, buttonWidth/3,19, &pimd->flag, 0, 0, 0, 0, "Show instances when particles are dead");
+ } else if (md->type==eModifierType_Explode) {
+ ExplodeModifierData *emd = (ExplodeModifierData*) md;
+ uiBut *but;
+ char *menustr= NULL; /* XXX get_vertexgroup_menustr(ob); */
+ int defCount=BLI_countlist(&ob->defbase);
+ if(defCount==0) emd->vgroup=0;
+ uiBlockBeginAlign(block);
+ but=uiDefButS(block, MENU, B_MODIFIER_RECALC, menustr, lx, (cy-=19), buttonWidth-20,19, &emd->vgroup, 0, defCount, 0, 0, "Protect this vertex group");
+ uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
+ MEM_freeN(menustr);
+
+ but=uiDefIconBut(block, BUT, B_MODIFIER_RECALC, ICON_X, (lx+buttonWidth)-20, cy, 20,19, 0, 0, 0, 0, 0, "Disable use of vertex group");
+ uiButSetFunc(but, modifiers_explodeDelVg, (void *)emd, (void *)NULL);
+
+
+ but=uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "", lx, (cy-=19), buttonWidth,19, &emd->protect, 0.0f, 1.0f, 0, 0, "Clean vertex group edges");
+ uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
+
+ but=uiDefBut(block, BUT, B_MODIFIER_RECALC, "Refresh", lx, (cy-=19), buttonWidth/2,19, 0, 0, 0, 0, 0, "Recalculate faces assigned to particles");
+ uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
+
+ uiDefButBitS(block, TOG, eExplodeFlag_EdgeSplit, B_MODIFIER_RECALC, "Split Edges", lx+buttonWidth/2, cy, buttonWidth/2,19, &emd->flag, 0, 0, 0, 0, "Split face edges for nicer shrapnel");
+ uiDefButBitS(block, TOG, eExplodeFlag_Unborn, B_MODIFIER_RECALC, "Unborn", lx, (cy-=19), buttonWidth/3,19, &emd->flag, 0, 0, 0, 0, "Show mesh when particles are unborn");
+ uiDefButBitS(block, TOG, eExplodeFlag_Alive, B_MODIFIER_RECALC, "Alive", lx+buttonWidth/3, cy, buttonWidth/3,19, &emd->flag, 0, 0, 0, 0, "Show mesh when particles are alive");
+ uiDefButBitS(block, TOG, eExplodeFlag_Dead, B_MODIFIER_RECALC, "Dead", lx+buttonWidth*2/3, cy, buttonWidth/3,19, &emd->flag, 0, 0, 0, 0, "Show mesh when particles are dead");
+ uiBlockEndAlign(block);
+ } else if (md->type==eModifierType_Shrinkwrap) {
+ ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
+
+ char shrinktypemenu[]="Shrinkwrap type%t|nearest surface point %x0|projection %x1|nearest vertex %x2";
+
+ uiDefIDPoinBut(block, modifier_testMeshObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &smd->target, "Target to shrink to");
+
+ but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &smd->vgroup_name, 0, 31, 0, 0, "Vertex Group name");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
+
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Offset:", lx,(cy-=19),buttonWidth,19, &smd->keepDist, 0.0f, 100.0f, 1.0f, 0, "Specify distance to keep from the target");
+
+ cy -= 3;
+ uiDefButS(block, MENU, B_MODIFIER_RECALC, shrinktypemenu, lx,(cy-=19),buttonWidth,19, &smd->shrinkType, 0, 0, 0, 0, "Selects type of shrinkwrap algorithm for target position.");
+
+ uiDefButC(block, NUM, B_MODIFIER_RECALC, "SS Levels:", lx, (cy-=19), buttonWidth,19, &smd->subsurfLevels, 0, 6, 0, 0, "This indicates the number of CCSubdivisions that must be performed before extracting vertexs positions and normals");
+
+ if (smd->shrinkType == MOD_SHRINKWRAP_PROJECT){
+
+
+ /* UI for projection axis */
+ uiBlockBeginAlign(block);
+ uiDefButC(block, ROW, B_MODIFIER_RECALC, "Normal" , lx,(cy-=19),buttonWidth,19, &smd->projAxis, 18.0, MOD_SHRINKWRAP_PROJECT_OVER_NORMAL, 0, 0, "Projection over X axis");
+
+ uiDefButBitC(block, TOG, MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS, B_MODIFIER_RECALC, "X", lx+buttonWidth/3*0,(cy-=19),buttonWidth/3,19, &smd->projAxis, 0, 0, 0, 0, "Projection over X axis");
+ uiDefButBitC(block, TOG, MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS, B_MODIFIER_RECALC, "Y", lx+buttonWidth/3*1,cy,buttonWidth/3,19, &smd->projAxis, 0, 0, 0, 0, "Projection over Y axis");
+ uiDefButBitC(block, TOG, MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS, B_MODIFIER_RECALC, "Z", lx+buttonWidth/3*2,cy,buttonWidth/3,19, &smd->projAxis, 0, 0, 0, 0, "Projection over Z axis");
+
+
+ /* allowed directions of projection axis */
+ uiDefButBitS(block, TOG, MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR, B_MODIFIER_RECALC, "Negative", lx,(cy-=19),buttonWidth/2,19, &smd->shrinkOpts, 0, 0, 0, 0, "Allows to move the vertex in the negative direction of axis");
+ uiDefButBitS(block, TOG, MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR, B_MODIFIER_RECALC, "Positive", lx + buttonWidth/2,cy,buttonWidth/2,19, &smd->shrinkOpts, 0, 0, 0, 0, "Allows to move the vertex in the positive direction of axis");
+
+ uiDefButBitS(block, TOG, MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE, B_MODIFIER_RECALC, "Cull frontfaces",lx,(cy-=19),buttonWidth/2,19, &smd->shrinkOpts, 0, 0, 0, 0, "Controls whether a vertex can be projected to a front face on target");
+ uiDefButBitS(block, TOG, MOD_SHRINKWRAP_CULL_TARGET_BACKFACE, B_MODIFIER_RECALC, "Cull backfaces", lx+buttonWidth/2,cy,buttonWidth/2,19, &smd->shrinkOpts, 0, 0, 0, 0, "Controls whether a vertex can be projected to a back face on target");
+ uiDefIDPoinBut(block, modifier_testMeshObj, ID_OB, B_CHANGEDEP, "Ob2: ", lx, (cy-=19), buttonWidth,19, &smd->auxTarget, "Aditional mesh to project over");
+ }
+ else if (smd->shrinkType == MOD_SHRINKWRAP_NEAREST_SURFACE){
+ uiDefButBitS(block, TOG, MOD_SHRINKWRAP_KEEP_ABOVE_SURFACE, B_MODIFIER_RECALC, "Above surface", lx,(cy-=19),buttonWidth,19, &smd->shrinkOpts, 0, 0, 0, 0, "Vertices are kept on the front side of faces");
+ }
+
+ uiBlockEndAlign(block);
+
+ } else if (md->type==eModifierType_SimpleDeform) {
+ SimpleDeformModifierData *smd = (SimpleDeformModifierData*) md;
+ char simpledeform_modemenu[] = "Deform type%t|Twist %x1|Bend %x2|Taper %x3|Strech %x4";
+
+ uiDefButC(block, MENU, B_MODIFIER_RECALC, simpledeform_modemenu, lx,(cy-=19),buttonWidth,19, &smd->mode, 0, 0, 0, 0, "Selects type of deform to apply to object.");
+
+ but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &smd->vgroup_name, 0, 31, 0, 0, "Vertex Group name");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
+
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &smd->origin, "Origin of modifier space coordinates");
+ if(smd->origin != NULL)
+ uiDefButBitC(block, TOG, MOD_SIMPLEDEFORM_ORIGIN_LOCAL, B_MODIFIER_RECALC, "Relative",lx,(cy-=19),buttonWidth,19, &smd->originOpts, 0, 0, 0, 0, "Sets the origin of deform space to be relative to the object");
+
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Factor:", lx,(cy-=19),buttonWidth,19, &smd->factor, -10.0f, 10.0f, 0.5f, 0, "Deform Factor");
+
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Upper Limit:", lx,(cy-=19),buttonWidth,19, &smd->limit[1], 0.0f, 1.0f, 5.0f, 0, "Upper Limit for deform");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Lower Limit:", lx,(cy-=19),buttonWidth,19, &smd->limit[0], 0.0f, 1.0f, 5.0f, 0, "Lower Limit for deform");
+
+ if(smd->mode == MOD_SIMPLEDEFORM_MODE_STRETCH
+ || smd->mode == MOD_SIMPLEDEFORM_MODE_TAPER )
+ {
+ uiDefButBitC(block, TOG, MOD_SIMPLEDEFORM_LOCK_AXIS_X, B_MODIFIER_RECALC, "Loc X", lx, (cy-=19),buttonWidth/2,19, &smd->axis, 0, 0, 0, 0, "Disallow changes on the X coordinate");
+ uiDefButBitC(block, TOG, MOD_SIMPLEDEFORM_LOCK_AXIS_Y, B_MODIFIER_RECALC, "Loc Y", lx+(buttonWidth/2), (cy),buttonWidth/2,19, &smd->axis, 0, 0, 0, 0, "Disallow changes on the Y coordinate");
+ }
+ }
+
+ uiBlockEndAlign(block);
+ }
+
+ if (md->error) {
+
+ row = uiLayoutRow(uiLayoutBox(column), 0);
+
+ /* XXX uiBlockSetCol(block, color); */
+ uiItemL(row, md->error, ICON_ERROR);
+ /* XXX uiBlockSetCol(block, TH_AUTO); */
+ }
+
+ return result;
+}
+
+uiLayout *uiTemplateModifier(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ Object *ob;
+ ModifierData *md, *vmd;
+ int i, lastCageIndex, cageIndex;
+
+ /* verify we have valid data */
+ if(!RNA_struct_is_a(ptr->type, &RNA_Modifier)) {
+ printf("uiTemplateModifier: expected modifier on object.\n");
+ return NULL;
+ }
+
+ ob= ptr->id.data;
+ md= ptr->data;
+
+ if(!ob || !(GS(ob->id.name) == ID_OB)) {
+ printf("uiTemplateModifier: expected modifier on object.\n");
+ return NULL;
+ }
+
+ uiBlockSetButLock(uiLayoutBlock(layout), (ob && ob->id.lib), ERROR_LIBDATA_MESSAGE);
+
+ /* find modifier and draw it */
+ cageIndex = modifiers_getCageIndex(ob, &lastCageIndex);
+
+ // XXX virtual modifiers are not accesible for python
+ vmd = modifiers_getVirtualModifierList(ob);
+
+ for(i=0; vmd; i++, vmd=vmd->next) {
+ if(md == vmd)
+ return draw_modifier(C, layout, ob, md, i, cageIndex, lastCageIndex);
+ else if(vmd->mode&eModifierMode_Virtual)
+ i--;
+ }
+
+ return NULL;
+}
+
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 18b39518ee6..c243b6abdbc 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -1818,7 +1818,6 @@ void ui_draw_but(ARegion *ar, uiStyle *style, uiBut *but, rcti *rect)
break;
case PULLDOWN:
- case HMENU:
wt= widget_type(UI_WTYPE_PULLDOWN);
break;
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index cf61c16fbe4..15ace3b02b1 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -203,21 +203,6 @@ void ED_base_object_activate(bContext *C, Base *base)
}
-/*
- * Returns true if the Object data is a from an external blend file (libdata)
- */
-int object_data_is_libdata(Object *ob)
-{
- if (!ob) return 0;
- if (ob->proxy) return 0;
- if (ob->id.lib) return 1;
- if (!ob->data) return 0;
- if (((ID *)ob->data)->lib) return 1;
- return 0;
-}
-
-
-
/* exported */
void ED_object_base_init_from_view(bContext *C, Base *base)
{
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index b430cdd67bc..04bcc4e3717 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -28,15 +28,28 @@
#include <stdio.h>
#include <stdlib.h>
+#include "MEM_guardedalloc.h"
+
+#include "DNA_curve_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "BLI_listbase.h"
+#include "BKE_curve.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_global.h"
+#include "BKE_mesh.h"
#include "BKE_modifier.h"
+#include "BKE_report.h"
+#include "BKE_object.h"
+#include "BKE_particle.h"
+#include "BKE_utildefines.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -49,7 +62,265 @@
#include "object_intern.h"
-/********************* add modifier operator ********************/
+/******************************** API ****************************/
+
+int ED_object_modifier_delete(ReportList *reports, Object *ob, ModifierData *md)
+{
+ ModifierData *obmd;
+
+ /* It seems on rapid delete it is possible to
+ * get called twice on same modifier, so make
+ * sure it is in list. */
+ for (obmd=ob->modifiers.first; obmd; obmd=obmd->next)
+ if (obmd==md)
+ break;
+
+ if (!obmd)
+ return 0;
+
+ if(md->type == eModifierType_ParticleSystem) {
+ ParticleSystemModifierData *psmd=(ParticleSystemModifierData*)md;
+
+ BLI_remlink(&ob->particlesystem, psmd->psys);
+ psys_free(ob, psmd->psys);
+ }
+
+ BLI_remlink(&ob->modifiers, md);
+
+ modifier_free(md);
+
+ return 1;
+}
+
+int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md)
+{
+ if(md->prev) {
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+
+ if(mti->type!=eModifierTypeType_OnlyDeform) {
+ ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type);
+
+ if(nmti->flags&eModifierTypeFlag_RequiresOriginalData)
+ BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data.");
+ return 0;
+ }
+
+ BLI_remlink(&ob->modifiers, md);
+ BLI_insertlink(&ob->modifiers, md->prev->prev, md);
+ }
+
+ return 1;
+}
+
+int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md)
+{
+ if(md->next) {
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+
+ if(mti->flags&eModifierTypeFlag_RequiresOriginalData) {
+ ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type);
+
+ if(nmti->type!=eModifierTypeType_OnlyDeform) {
+ BKE_report(reports, RPT_WARNING, "Cannot move beyond a non-deforming modifier.");
+ return 0;
+ }
+ }
+
+ BLI_remlink(&ob->modifiers, md);
+ BLI_insertlink(&ob->modifiers, md->next, md);
+ }
+
+ return 1;
+}
+
+int ED_object_modifier_convert(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
+{
+ Object *obn;
+ ParticleSystem *psys;
+ ParticleCacheKey *key, **cache;
+ ParticleSettings *part;
+ Mesh *me;
+ MVert *mvert;
+ MEdge *medge;
+ int a, k, kmax;
+ int totvert=0, totedge=0, cvert=0;
+ int totpart=0, totchild=0;
+
+ if(md->type != eModifierType_ParticleSystem) return 0;
+ if(G.f & G_PARTICLEEDIT) return 0;
+
+ psys=((ParticleSystemModifierData *)md)->psys;
+ part= psys->part;
+
+ if(part->draw_as == PART_DRAW_GR || part->draw_as == PART_DRAW_OB) {
+ ; // XXX make_object_duplilist_real(NULL);
+ }
+ else {
+ if(part->draw_as != PART_DRAW_PATH || psys->pathcache == 0)
+ return 0;
+
+ totpart= psys->totcached;
+ totchild= psys->totchildcache;
+
+ if(totchild && (part->draw&PART_DRAW_PARENT)==0)
+ totpart= 0;
+
+ /* count */
+ cache= psys->pathcache;
+ for(a=0; a<totpart; a++) {
+ key= cache[a];
+ totvert+= key->steps+1;
+ totedge+= key->steps;
+ }
+
+ cache= psys->childcache;
+ for(a=0; a<totchild; a++) {
+ key= cache[a];
+ totvert+= key->steps+1;
+ totedge+= key->steps;
+ }
+
+ if(totvert==0) return 0;
+
+ /* add new mesh */
+ obn= add_object(scene, OB_MESH);
+ me= obn->data;
+
+ me->totvert= totvert;
+ me->totedge= totedge;
+
+ me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
+ me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
+ me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
+
+ mvert= me->mvert;
+ medge= me->medge;
+
+ /* copy coordinates */
+ cache= psys->pathcache;
+ for(a=0; a<totpart; a++) {
+ key= cache[a];
+ kmax= key->steps;
+ for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
+ VECCOPY(mvert->co,key->co);
+ if(k) {
+ medge->v1= cvert-1;
+ medge->v2= cvert;
+ medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
+ medge++;
+ }
+ }
+ }
+
+ cache=psys->childcache;
+ for(a=0; a<totchild; a++) {
+ key=cache[a];
+ kmax=key->steps;
+ for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
+ VECCOPY(mvert->co,key->co);
+ if(k) {
+ medge->v1=cvert-1;
+ medge->v2=cvert;
+ medge->flag= ME_EDGEDRAW|ME_EDGERENDER|ME_LOOSEEDGE;
+ medge++;
+ }
+ }
+ }
+ }
+
+ DAG_scene_sort(scene);
+
+ return 1;
+}
+
+int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
+{
+ DerivedMesh *dm;
+ Mesh *me = ob->data;
+ int converted = 0;
+
+ if (scene->obedit) {
+ BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in editmode");
+ return 0;
+ } else if (((ID*) ob->data)->us>1) {
+ BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
+ return 0;
+ }
+
+ if (md!=ob->modifiers.first)
+ BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected.");
+
+ if (ob->type==OB_MESH) {
+ if(me->key) {
+ BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to Mesh with Shape Keys");
+ return 0;
+ }
+
+ mesh_pmv_off(ob, me);
+
+ dm = mesh_create_derived_for_modifier(scene, ob, md);
+ if (!dm) {
+ BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
+ return 0;
+ }
+
+ DM_to_mesh(dm, me);
+ converted = 1;
+
+ dm->release(dm);
+ }
+ else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ Curve *cu = ob->data;
+ int numVerts;
+ float (*vertexCos)[3];
+
+ BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tesselated/bevel vertices");
+
+ if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md))) {
+ BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
+ return 0;
+ }
+
+ vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts);
+ mti->deformVerts(md, ob, NULL, vertexCos, numVerts);
+ curve_applyVertexCos(cu, &cu->nurb, vertexCos);
+
+ converted = 1;
+
+ MEM_freeN(vertexCos);
+
+ DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+ }
+ else {
+ BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
+ return 0;
+ }
+
+ if (converted) {
+ BLI_remlink(&ob->modifiers, md);
+ modifier_free(md);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+int ED_object_modifier_copy(ReportList *reports, Object *ob, ModifierData *md)
+{
+ ModifierData *nmd;
+
+ nmd = modifier_new(md->type);
+ modifier_copyData(md, nmd);
+ BLI_insertlink(&ob->modifiers, md, nmd);
+
+ return 1;
+}
+
+/***************************** OPERATORS ****************************/
+
+/************************ add modifier operator *********************/
static int modifier_add_exec(bContext *C, wmOperator *op)
{
@@ -96,3 +367,76 @@ void OBJECT_OT_modifier_add(wmOperatorType *ot)
RNA_def_enum(ot->srna, "type", modifier_type_items, 0, "Type", "");
}
+#if 0
+static void modifiers_add(void *ob_v, int type)
+{
+ Object *ob = ob_v;
+ ModifierTypeInfo *mti = modifierType_getInfo(type);
+
+ if (mti->flags&eModifierTypeFlag_RequiresOriginalData) {
+ ModifierData *md = ob->modifiers.first;
+
+ while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) {
+ md = md->next;
+ }
+
+ BLI_insertlinkbefore(&ob->modifiers, md, modifier_new(type));
+ } else {
+ BLI_addtail(&ob->modifiers, modifier_new(type));
+ }
+ ED_undo_push("Add modifier");
+}
+
+typedef struct MenuEntry {
+ char *name;
+ int ID;
+} MenuEntry;
+
+static int menuEntry_compare_names(const void *entry1, const void *entry2)
+{
+ return strcmp(((MenuEntry *)entry1)->name, ((MenuEntry *)entry2)->name);
+}
+
+static uiBlock *modifiers_add_menu(void *ob_v)
+{
+ Object *ob = ob_v;
+ uiBlock *block;
+ int i, yco=0;
+ int numEntries = 0;
+ MenuEntry entries[NUM_MODIFIER_TYPES];
+
+ block= uiNewBlock(&curarea->uiblocks, "modifier_add_menu",
+ UI_EMBOSSP, UI_HELV, curarea->win);
+ uiBlockSetButmFunc(block, modifiers_add, ob);
+
+ for (i=eModifierType_None+1; i<NUM_MODIFIER_TYPES; i++) {
+ ModifierTypeInfo *mti = modifierType_getInfo(i);
+
+ /* Only allow adding through appropriate other interfaces */
+ if(ELEM3(i, eModifierType_Softbody, eModifierType_Hook, eModifierType_ParticleSystem)) continue;
+
+ if(ELEM4(i, eModifierType_Cloth, eModifierType_Collision, eModifierType_Surface, eModifierType_Fluidsim)) continue;
+
+ if((mti->flags&eModifierTypeFlag_AcceptsCVs) ||
+ (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
+ entries[numEntries].name = mti->name;
+ entries[numEntries].ID = i;
+
+ ++numEntries;
+ }
+ }
+
+ qsort(entries, numEntries, sizeof(*entries), menuEntry_compare_names);
+
+
+ for(i = 0; i < numEntries; ++i)
+ uiDefBut(block, BUTM, B_MODIFIER_RECALC, entries[i].name,
+ 0, yco -= 20, 160, 19, NULL, 0, 0, 1, entries[i].ID, "");
+
+ uiTextBoundsBlock(block, 50);
+ uiBlockSetDirection(block, UI_DOWN);
+
+ return block;
+}
+#endif
+
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index fb284aab99f..dad02b2fadd 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -650,6 +650,7 @@ const char *RNA_property_ui_description(PropertyRNA *prop)
int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
{
+ ID *id;
int flag;
prop= rna_ensure_property(prop);
@@ -658,8 +659,10 @@ int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
flag= prop->editable(ptr);
else
flag= prop->flag;
+
+ id= ptr->id.data;
- return (flag & PROP_EDITABLE);
+ return (flag & PROP_EDITABLE) && (!id || !id->lib);
}
int RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 3263c6d4bfc..db07ac68655 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -41,35 +41,35 @@
#include "WM_types.h"
EnumPropertyItem modifier_type_items[] ={
- {eModifierType_Subsurf, "SUBSURF", "Subsurf", ""},
- {eModifierType_Lattice, "LATTICE", "Lattice", ""},
- {eModifierType_Curve, "CURVE", "Curve", ""},
- {eModifierType_Build, "BUILD", "Build", ""},
- {eModifierType_Mirror, "MIRROR", "Mirror", ""},
- {eModifierType_Decimate, "DECIMATE", "Decimate", ""},
- {eModifierType_Wave, "WAVE", "Wave", ""},
{eModifierType_Armature, "ARMATURE", "Armature", ""},
- {eModifierType_Hook, "HOOK", "Hook", ""},
- {eModifierType_Softbody, "SOFTBODY", "Softbody", ""},
- {eModifierType_Boolean, "BOOLEAN", "Boolean", ""},
{eModifierType_Array, "ARRAY", "Array", ""},
- {eModifierType_EdgeSplit, "EDGE_SPLIT", "Edge Split", ""},
- {eModifierType_Displace, "DISPLACE", "Displace", ""},
- {eModifierType_UVProject, "UV_PROJECT", "UV Project", ""},
- {eModifierType_Smooth, "SMOOTH", "Smooth", ""},
+ {eModifierType_Bevel, "BEVEL", "Bevel", ""},
+ {eModifierType_Boolean, "BOOLEAN", "Boolean", ""},
+ {eModifierType_Build, "BUILD", "Build", ""},
{eModifierType_Cast, "CAST", "Cast", ""},
- {eModifierType_MeshDeform, "MESH_DEFORM", "Mesh Deform", ""},
- {eModifierType_ParticleSystem, "PARTICLE_SYSTEM", "Particle System", ""},
- {eModifierType_ParticleInstance, "PARTICLE_INSTANCE", "Particle Instance", ""},
- {eModifierType_Explode, "EXPLODE", "Explode", ""},
{eModifierType_Cloth, "CLOTH", "Cloth", ""},
{eModifierType_Collision, "COLLISION", "Collision", ""},
- {eModifierType_Bevel, "BEVEL", "Bevel", ""},
- {eModifierType_Shrinkwrap, "SHRINKWRAP", "Shrinkwrap", ""},
+ {eModifierType_Curve, "CURVE", "Curve", ""},
+ {eModifierType_Decimate, "DECIMATE", "Decimate", ""},
+ {eModifierType_Displace, "DISPLACE", "Displace", ""},
+ {eModifierType_EdgeSplit, "EDGE_SPLIT", "Edge Split", ""},
+ {eModifierType_Explode, "EXPLODE", "Explode", ""},
{eModifierType_Fluidsim, "FLUID_SIMULATION", "Fluid Simulation", ""},
+ {eModifierType_Hook, "HOOK", "Hook", ""},
+ {eModifierType_Lattice, "LATTICE", "Lattice", ""},
{eModifierType_Mask, "MASK", "Mask", ""},
- {eModifierType_SimpleDeform, "SIMPLE_DEFORM", "Simple Deform", ""},
+ {eModifierType_MeshDeform, "MESH_DEFORM", "Mesh Deform", ""},
+ {eModifierType_Mirror, "MIRROR", "Mirror", ""},
{eModifierType_Multires, "MULTIRES", "Multires", ""},
+ {eModifierType_ParticleInstance, "PARTICLE_INSTANCE", "Particle Instance", ""},
+ {eModifierType_ParticleSystem, "PARTICLE_SYSTEM", "Particle System", ""},
+ {eModifierType_Shrinkwrap, "SHRINKWRAP", "Shrinkwrap", ""},
+ {eModifierType_SimpleDeform, "SIMPLE_DEFORM", "Simple Deform", ""},
+ {eModifierType_Smooth, "SMOOTH", "Smooth", ""},
+ {eModifierType_Softbody, "SOFTBODY", "Softbody", ""},
+ {eModifierType_Subsurf, "SUBSURF", "Subsurf", ""},
+ {eModifierType_UVProject, "UV_PROJECT", "UV Project", ""},
+ {eModifierType_Wave, "WAVE", "Wave", ""},
{0, NULL, NULL, NULL}};
diff --git a/source/blender/python/intern/bpy_ui.c b/source/blender/python/intern/bpy_ui.c
index 0f2142f4b62..bdf656e5e57 100644
--- a/source/blender/python/intern/bpy_ui.c
+++ b/source/blender/python/intern/bpy_ui.c
@@ -406,7 +406,6 @@ PyObject *BPY_ui_module( void )
PyModule_AddObject( mod, "BLOCK_NUMSELECT", PyLong_FromSsize_t(UI_BLOCK_NUMSELECT) );
PyModule_AddObject( mod, "BLOCK_ENTER_OK", PyLong_FromSsize_t(UI_BLOCK_ENTER_OK) );
PyModule_AddObject( mod, "BLOCK_NOSHADOW", PyLong_FromSsize_t(UI_BLOCK_NOSHADOW) );
- PyModule_AddObject( mod, "BLOCK_NO_HILITE", PyLong_FromSsize_t(UI_BLOCK_NO_HILITE) );
PyModule_AddObject( mod, "BLOCK_MOVEMOUSE_QUIT", PyLong_FromSsize_t(UI_BLOCK_MOVEMOUSE_QUIT) );
PyModule_AddObject( mod, "BLOCK_KEEP_OPEN", PyLong_FromSsize_t(UI_BLOCK_KEEP_OPEN) );
PyModule_AddObject( mod, "BLOCK_POPUP", PyLong_FromSsize_t(UI_BLOCK_POPUP) );