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.
This commit is contained in:
Brecht Van Lommel 2009-05-21 15:34:09 +00:00
parent 65143c50e0
commit 94902dac97
19 changed files with 1899 additions and 122 deletions

@ -21,26 +21,16 @@ class DATA_PT_modifiers(DataButtonsPanel):
if not ob:
return
layout.row()
layout.item_menu_enumO("OBJECT_OT_modifier_add", "type")
row = layout.row()
row.item_menu_enumO("OBJECT_OT_modifier_add", "type")
row.itemL();
for md in ob.modifiers:
sub = layout.box()
row = sub.row()
row.itemR(md, "expanded", text="")
row.itemR(md, "name", text="")
row.itemR(md, "render", text="")
row.itemR(md, "realtime", text="")
row.itemR(md, "editmode", text="")
row.itemR(md, "on_cage", text="")
box = layout.template_modifier(context, md)
if md.expanded:
sub.itemS()
if (md.type == 'ARMATURE'):
self.armature(sub, md)
if md.type == 'ARMATURE':
self.armature(box, md)
def armature(self, layout, md):
layout.itemR(md, "object")
@ -51,9 +41,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
flow.itemR(md, "use_vertex_groups")
flow.itemR(md, "use_bone_envelopes")
flow.itemR(md, "quaternion")
flow.itemR(md, "b_bone_rest")
flow.itemR(md, "multi_modifier")
bpy.types.register(DATA_PT_modifiers)

@ -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);

@ -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;

@ -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 */

@ -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 */

@ -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);

@ -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;

@ -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);
}

@ -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);
}

@ -188,7 +188,7 @@ struct uiBut {
/* BLOCK data */
uiBlockCreateFunc block_create_func;
/* HMENU data */
/* PULLDOWN/MENU data */
uiMenuCreateFunc menu_create_func;
/* RNA data */

@ -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);
}

@ -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 */

File diff suppressed because it is too large Load Diff

@ -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;

@ -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)
{

@ -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

@ -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)

@ -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}};

@ -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) );