- modifier UI update (aka, find the modifier buttons!!)

- moved back to editing buttons, where life is now cramped... switched
   to constraint style foldout panes, still a WIP. In particular not
   sure what buttons should be in header (and if current toggles stay
   in header if they should also be in an expanded pane). Also need
   new icons for move up/move down (and drag and drop would of course
   be nice). Finally current plane is to make it so modifiers will
   expand out in modifier pane for horizontal orientations instead of
   just going down down down to goblin town.
 - added error field to modifiers that is displayed in UI, need to have
   some way for modifiers to return errors back to interface (esp. important
   for python)
 - tweaked cage determination and handling, currently the editmode cage
   is determined by last modifier with OnCage set that is preceeded completely
   by modifiers that support mapping or are disabled in editmode. it is
   kinda confusing, but the interface only lets you toggle OnCage for modifiers
   that support it - it just might not be clear all the time why you can't
   toggle a certain modifier OnCage.
 - update displistmesh_copy to only copy edges if non-NULL

There is a display bug that already existed but is more obvious with
new modifiers where parts of the pane get drawn in a different area
after toggling editmode. It has to do with drawing parts of the interface
using GL instead of 100% buttons. I try to keep my grubby little toes
out of the interface code so this can wait for Ton to return.
This commit is contained in:
Daniel Dunbar 2005-08-04 07:25:43 +00:00
parent 85704d6ef9
commit 8319b3d1fa
11 changed files with 509 additions and 337 deletions

View File

@ -80,6 +80,7 @@ float Phong_Spec(float *, float *, float *, int);
void waitcursor(int);
void allqueue(unsigned short event, short val);
#define REDRAWVIEW3D 0x4010
#define REDRAWBUTSEDIT 0x4019
struct Material;
extern struct Material defmaterial;

View File

@ -180,8 +180,12 @@ void modifier_free (struct ModifierData *md);
void modifier_copyData (struct ModifierData *md, struct ModifierData *target);
int modifier_dependsOnTime (struct ModifierData *md);
int modifier_supportsMapping(struct ModifierData *md);
int modifier_couldBeCage (struct ModifierData *md);
void modifier_setError (struct ModifierData *md, char *format, ...);
struct ModifierData* modifiers_findByType (struct ListBase *lb, ModifierType type);
void modifiers_clearErrors (struct ListBase *lb);
int modifiers_getCageIndex (struct ListBase *lb, int *lastPossibleCageIndex_r);
#endif

View File

@ -1310,6 +1310,8 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
DerivedMesh *dm;
int numVerts = me->totvert;
modifiers_clearErrors(&ob->modifiers);
if (deform_r) *deform_r = NULL;
*final_r = NULL;
@ -1447,33 +1449,19 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r)
{
Object *ob = G.obedit;
EditMesh *em = G.editMesh;
ModifierData *md, *cageModifier;
ModifierData *md;
float (*deformedVerts)[3] = NULL;
DerivedMesh *dm;
int numVerts;
int i, numVerts, cageIndex = modifiers_getCageIndex(&ob->modifiers, NULL);
/* Find the last modifier acting on the cage. */
cageModifier = NULL;
for (md= ob->modifiers.first; md; md=md->next) {
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
modifiers_clearErrors(&ob->modifiers);
if (!(md->mode&eModifierMode_Realtime)) continue;
if (!(md->mode&eModifierMode_Editmode)) continue;
if (mti->isDisabled && mti->isDisabled(md)) continue;
if (!(mti->flags&eModifierTypeFlag_SupportsEditmode)) continue;
if (!modifier_supportsMapping(md) || !(md->mode&eModifierMode_OnCage))
break;
cageModifier = md;
}
if (cage_r && !cageModifier) {
if (cage_r && cageIndex==-1) {
*cage_r = getEditMeshDerivedMesh(em, NULL);
}
dm = NULL;
for (md= ob->modifiers.first; md; md=md->next) {
for (i=0,md= ob->modifiers.first; md; i++,md=md->next) {
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
if (!(md->mode&eModifierMode_Realtime)) continue;
@ -1521,7 +1509,7 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r)
}
}
if (cage_r && md==cageModifier) {
if (cage_r && i==cageIndex) {
if (dm && deformedVerts) {
// XXX this is not right, need to convert the dm
*cage_r = dm;

View File

@ -128,7 +128,7 @@ DispListMesh *displistmesh_copy(DispListMesh *odlm)
{
DispListMesh *ndlm= MEM_dupallocN(odlm);
ndlm->mvert= MEM_dupallocN(odlm->mvert);
ndlm->medge= MEM_dupallocN(odlm->medge);
if (odlm->medge) ndlm->medge= MEM_dupallocN(odlm->medge);
ndlm->mface= MEM_dupallocN(odlm->mface);
if (odlm->nors) ndlm->nors = MEM_dupallocN(odlm->nors);
if (odlm->mcol) ndlm->mcol= MEM_dupallocN(odlm->mcol);

View File

@ -1,4 +1,5 @@
#include "string.h"
#include "stdarg.h"
#include "math.h"
#include "BLI_blenlib.h"
@ -14,6 +15,7 @@
#include "DNA_scene_types.h"
#include "BLI_editVert.h"
#include "BKE_bad_level_calls.h"
#include "BKE_global.h"
#include "BKE_utildefines.h"
#include "BKE_DerivedMesh.h"
@ -752,8 +754,8 @@ static void *decimateModifier_applyModifier(ModifierData *md, Object *ob, void *
}
if(numTris<3) {
// ("You must have more than 3 input faces selected.");
return NULL;
modifier_setError(md, "There must be more than 3 input faces (triangles).");
goto exit;
}
lod.vertex_buffer= MEM_mallocN(3*sizeof(float)*totvert, "vertices");
@ -830,19 +832,20 @@ static void *decimateModifier_applyModifier(ModifierData *md, Object *ob, void *
}
}
else {
// No memory
modifier_setError(md, "Out of memory.");
}
LOD_FreeDecimationData(&lod);
}
else {
// Non-manifold mesh
modifier_setError(md, "Non-manifold mesh as input.");
}
MEM_freeN(lod.vertex_buffer);
MEM_freeN(lod.vertex_normal_buffer);
MEM_freeN(lod.triangle_index_buffer);
exit:
if (dlm) displistmesh_free(dlm);
if (ndlm) {
@ -1057,7 +1060,7 @@ ModifierData *modifier_new(int type)
ModifierData *md = MEM_callocN(mti->structSize, mti->structName);
md->type = type;
md->mode = eModifierMode_Realtime|eModifierMode_Render;
md->mode = eModifierMode_Realtime|eModifierMode_Render|eModifierMode_Expanded;
if (mti->flags&eModifierTypeFlag_EnableInEditmode)
md->mode |= eModifierMode_Editmode;
@ -1072,6 +1075,7 @@ void modifier_free(ModifierData *md)
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
if (mti->freeData) mti->freeData(md);
if (md->error) MEM_freeN(md->error);
MEM_freeN(md);
}
@ -1103,6 +1107,20 @@ ModifierData *modifiers_findByType(struct ListBase *lb, ModifierType type)
return md;
}
void modifiers_clearErrors(struct ListBase *lb)
{
ModifierData *md = lb->first;
for (; md; md=md->next) {
if (md->error) {
MEM_freeN(md->error);
md->error = NULL;
allqueue(REDRAWBUTSEDIT, 0);
}
}
}
void modifier_copyData(ModifierData *md, ModifierData *target)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
@ -1112,3 +1130,55 @@ void modifier_copyData(ModifierData *md, ModifierData *target)
if (mti->copyData)
mti->copyData(md, target);
}
int modifier_couldBeCage(ModifierData *md)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
return ( (md->mode&eModifierMode_Realtime) &&
(md->mode&eModifierMode_Editmode) &&
(!mti->isDisabled || !mti->isDisabled(md)) &&
modifier_supportsMapping(md));
}
void modifier_setError(ModifierData *md, char *format, ...)
{
char buffer[2048];
va_list ap;
va_start(ap, format);
vsprintf(buffer, format, ap);
va_end(ap);
if (md->error)
MEM_freeN(md->error);
md->error = BLI_strdup(buffer);
allqueue(REDRAWBUTSEDIT, 0);
}
int modifiers_getCageIndex(ListBase *lb, int *lastPossibleCageIndex_r)
{
ModifierData *md = lb->first;
int i, cageIndex = -1;
/* Find the last modifier acting on the cage. */
for (i=0; md; i++,md=md->next) {
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
if (!(md->mode&eModifierMode_Realtime)) continue;
if (!(md->mode&eModifierMode_Editmode)) continue;
if (mti->isDisabled && mti->isDisabled(md)) continue;
if (!(mti->flags&eModifierTypeFlag_SupportsEditmode)) continue;
if (!modifier_supportsMapping(md))
break;
if (lastPossibleCageIndex_r) *lastPossibleCageIndex_r = i;
if (md->mode&eModifierMode_OnCage)
cageIndex = i;
}
return cageIndex;
}

View File

@ -2304,6 +2304,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
link_list(fd, lb);
for (md=lb->first; md; md=md->next) {
md->error = NULL;
if (md->type==eModifierType_Subsurf) {
SubsurfModifierData *smd = (SubsurfModifierData*) md;

View File

@ -601,9 +601,11 @@ enum {
#define B_RECALCAL 3411
#define B_RECALC_DEFL 3412
#define B_MDFR_BUTS 3600
#define B_MODIFIER_BUTS 3600
#define B_MODIFIER_RECALC 3501
#define B_MODIFIER_REDRAW 3502
#define B_MDFR_INCREMENTAL 3501
/* *********************** */

View File

@ -28,12 +28,15 @@ typedef enum ModifierMode {
eModifierMode_Render = (1<<1),
eModifierMode_Editmode = (1<<2),
eModifierMode_OnCage = (1<<3),
eModifierMode_Expanded = (1<<4),
} ModifierMode;
typedef struct ModifierData {
struct ModifierData *next, *prev;
int type, mode;
char *error;
} ModifierData;
typedef enum {

View File

@ -320,7 +320,7 @@ void do_butspace(unsigned short event)
else if(event<=B_EFFECTSBUTS) {
do_effects_panels(event);
}
else if(event<=B_MDFR_BUTS) {
else if(event<=B_MODIFIER_BUTS) {
extern void do_modifier_panels(unsigned short event);
do_modifier_panels(event);
}

View File

@ -65,6 +65,7 @@
#include "DNA_meta_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_radio_types.h"
@ -80,6 +81,7 @@
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
#include "BKE_packedFile.h"
#include "BKE_scene.h"
@ -500,7 +502,414 @@ static void editing_panel_mesh_type(Object *ob, Mesh *me)
}
/* *************************** MODIFIERS ******************************** */
void do_modifier_panels(unsigned short event)
{
Object *ob = OBACT;
switch(event) {
case B_MODIFIER_REDRAW:
allqueue(REDRAWBUTSEDIT, 0);
break;
case B_MODIFIER_RECALC:
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWVIEW3D, 0);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
break;
}
}
static void modifiers_add(void *ob_v, int type)
{
Object *ob = ob_v;
BLI_addtail(&ob->modifiers, modifier_new(type));
}
static uiBlock *modifiers_add_menu(void *ob_v)
{
Object *ob = ob_v;
uiBlock *block;
int i, yco=0;
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);
if ( (mti->flags&eModifierTypeFlag_AcceptsCVs) ||
(ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
uiDefBut(block, BUTM, B_MODIFIER_RECALC, mti->name, 0, yco-=20, 160, 19, NULL, 0, 0, 1, i, "");
}
}
uiTextBoundsBlock(block, 50);
uiBlockSetDirection(block, UI_DOWN);
return block;
}
static void modifiers_del(void *ob_v, void *md_v)
{
Object *ob = ob_v;
ModifierData *md;
/* It seems on rapid delete it is possible to
* get called twice on same modifier, so make
* sure it is in list.
*/
for (md=ob->modifiers.first; md; md=md->next)
if (md==md_v)
break;
if (!md)
return;
BLI_remlink(&ob->modifiers, md_v);
modifier_free(md_v);
}
static void modifiers_moveUp(void *ob_v, void *md_v)
{
Object *ob = ob_v;
ModifierData *md = md_v;
if (md->prev) {
BLI_remlink(&ob->modifiers, md);
BLI_insertlink(&ob->modifiers, md->prev->prev, md);
}
}
static void modifiers_moveDown(void *ob_v, void *md_v)
{
Object *ob = ob_v;
ModifierData *md = md_v;
if (md->next) {
BLI_remlink(&ob->modifiers, md);
BLI_insertlink(&ob->modifiers, md->next, md);
}
}
static void modifier_testLatticeObj(char *name, ID **idpp)
{
ID *id;
for (id= G.main->object.first; id; id= id->next) {
if( strcmp(name, id->name+2)==0 ) {
if (((Object *)id)->type != OB_LATTICE) {
error ("Lattice deform object must be a lattice");
break;
}
*idpp= id;
return;
}
}
*idpp= 0;
}
static void modifier_testCurveObj(char *name, ID **idpp)
{
ID *id;
for (id= G.main->object.first; id; id= id->next) {
if( strcmp(name, id->name+2)==0 ) {
if (((Object *)id)->type != OB_CURVE) {
error ("Curve deform object must be a curve");
break;
}
*idpp= id;
return;
}
}
*idpp= 0;
}
static void modifiers_applyModifier(void *obv, void *mdv)
{
Object *ob = obv;
ModifierData *md = mdv;
DerivedMesh *dm;
DispListMesh *dlm;
Mesh *me = ob->data;
if (G.obedit) {
error("Modifiers cannot be applied in editmode");
return;
} else if (me->id.us>1) {
error("Modifiers cannot be applied to a multi-user mesh");
return;
}
if (md!=ob->modifiers.first) {
if (!okee("Modifier is not first, continue with apply?"))
return;
}
// XXX, only for mesh
dm = mesh_create_derived_for_modifier(ob, md);
if (!dm) {
error("Modifier is disabled or returned error, skipping apply");
return;
}
dlm= dm->convertToDispListMesh(dm);
ob->data= add_mesh();
displistmesh_to_mesh(dlm, ob->data);
displistmesh_free(dlm);
dm->release(dm);
free_libblock_us(&G.main->mesh, me);
BLI_remlink(&ob->modifiers, md);
modifier_free(md);
}
static void modifiers_setOnCage(void *ob_v, void *md_v)
{
Object *ob = ob_v;
ModifierData *md;
int i, cageIndex = modifiers_getCageIndex(&ob->modifiers, NULL);
for (i=0,md=ob->modifiers.first; md; i++,md=md->next)
if (md==md_v)
break;
md->mode ^= eModifierMode_OnCage;
md = md->next;
for (; md; md=md->next) {
md->mode &= ~eModifierMode_OnCage;
}
}
static void modifiers_setSubsurfIncremental(void *ob_v, void *md_v)
{
Object *ob = ob_v;
ModifierData *md = md_v;
SubsurfModifierData *smd = (SubsurfModifierData*) md;
if ((smd->flags&eSubsurfModifierFlag_Incremental) && ob->type==OB_MESH) {
Mesh *me = ob->data;
if (!me->medge) {
if (okee("Requires mesh edges, create now?")) {
make_edges(me);
}
}
}
}
static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco, int *yco, int index, int cageIndex, int lastCageIndex)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
uiBut *but;
int x = *xco, y = *yco, color = md->error?TH_REDALERT:TH_BUT_NEUTRAL;
short height, width = 295;
uiBlockSetEmboss(block, UI_EMBOSSN);
uiDefIconButBitI(block, ICONTOG, eModifierMode_Expanded, B_MODIFIER_REDRAW, ICON_DISCLOSURE_TRI_RIGHT, x, y, 20, 20, &md->mode, 0.0, 0.0, 0.0, 0.0, "Collapse/Expand Modifier");
BIF_ThemeColor(color);
uiBlockSetEmboss(block, UI_EMBOSS);
/* rounded header */
BIF_ThemeColorShade(color, -20);
uiSetRoundBox(3);
uiRoundBox(x+4+10, y-18, x+width+10, y+6, 5.0);
BIF_ThemeColor(color);
uiDefBut(block, LABEL, B_NOP, mti->name, x+15, y-1, 100, 19, NULL, 0.0, 0.0, 0.0, 0.0, "");
uiBlockSetEmboss(block, UI_EMBOSSN);
if (modifier_couldBeCage(md) && index<=lastCageIndex) {
int icon;
uiSetRoundBox(15);
if (index==cageIndex) {
BIF_ThemeColorShadeAlpha(color, 40, 40);
icon = ICON_EDITMODE_HLT;
} else if (index<cageIndex) {
BIF_ThemeColorShade(color, 10);
icon = ICON_EDITMODE_DEHLT;
} else {
BIF_ThemeColorShade(color, -20);
icon = ICON_EDITMODE_DEHLT;
}
uiRoundBox(x+width-120+19, y-13, x+width-120+16+19, y+3, 6.0);
but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, icon, x+width-120, y, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Apply modifier to editing cage during Editmode");
uiButSetFunc(but, modifiers_setOnCage, ob, md);
}
but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, ICON_REW, x+width-90, y, 19, 19, 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, ICON_FF, x+width-90+20, y, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Move modifier down in stack");
uiButSetFunc(but, modifiers_moveDown, ob, md);
but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, ICON_X, x+width-30, y, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete modifier");
uiButSetFunc(but, modifiers_del, ob, md);
BIF_ThemeColor(color);
uiBlockSetEmboss(block, UI_EMBOSS);
if (!(md->mode&eModifierMode_Expanded)) {
uiBlockBeginAlign(block);
uiDefIconButBitI(block, TOG, eModifierMode_Render, B_MODIFIER_RECALC, ICON_SCENE, x+width-120-90, y, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during rendering");
uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_MODIFIER_RECALC, ICON_VIEW3D, x+width-120-90+20, y, 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, ICON_EDIT, x+width-120-90+40, y, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during Editmode");
}
uiBlockEndAlign(block);
y -= 18;
} else {
char str[128];
int cy = y - 8;
int lx = x + width - 60 - 15;
y -= 18;
if (md->type==eModifierType_Subsurf) {
height = 86;
} else if (md->type==eModifierType_Lattice) {
height = 86;
} else if (md->type==eModifierType_Curve) {
height = 86;
} else if (md->type==eModifierType_Build) {
height = 86;
} else if (md->type==eModifierType_Mirror) {
height = 86;
} else if (md->type==eModifierType_Decimate) {
height = 66;
} else if (md->type==eModifierType_Wave) {
height = 200;
}
BIF_ThemeColor(color);
glRects(x+3+10, y-height, x+width+10, y);
uiBlockBeginAlign(block);
but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Apply", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Apply the currnt modifier and remove from the stack");
uiButSetFunc(but, modifiers_applyModifier, ob, md);
uiDefButBitI(block, TOG, eModifierMode_Render, B_MODIFIER_RECALC, "Render", lx,(cy-=19),60,19,&md->mode, 0, 0, 1, 0, "Enable modifier during rendering");
uiDefButBitI(block, TOG, eModifierMode_Realtime, B_MODIFIER_RECALC, "3D View", lx,(cy-=19),60,19,&md->mode, 0, 0, 1, 0, "Enable modifier during interactive display");
if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
uiDefButBitI(block, TOG, eModifierMode_Editmode, B_MODIFIER_RECALC, "Editmode", lx,(cy-=19),60,19,&md->mode, 0, 0, 1, 0, "Enable modifier during Editmode");
}
uiBlockEndAlign(block);
lx = x;
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),160,19, &smd->subdivType, 0, 0, 0, 0, "Selects type of subdivision algorithm.");
uiDefButS(block, NUM, B_MODIFIER_RECALC, "Levels:", lx, (cy-=19), 160,19, &smd->levels, 1, 6, 0, 0, "Number subdivisions to perform");
uiDefButS(block, NUM, B_MODIFIER_RECALC, "Render Levels:", lx, (cy-=19), 160,19, &smd->renderLevels, 1, 6, 0, 0, "Number subdivisions to perform when rendering");
but = 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");
uiButSetFunc(but, modifiers_setSubsurfIncremental, ob, md);
uiDefButBitS(block, TOG, eSubsurfModifierFlag_DebugIncr, B_MODIFIER_RECALC, "Debug", lx+90, cy,70,19,&smd->flags, 0, 0, 0, 0, "Visualize the subsurf incremental calculation, for debugging effect of other modifiers");
} else if (md->type==eModifierType_Lattice) {
LatticeModifierData *lmd = (LatticeModifierData*) md;
uiDefIDPoinBut(block, modifier_testLatticeObj, B_CHANGEDEP, "Ob:", lx, (cy-=19), 120,19, &lmd->object, "Lattice object to deform with");
} else if (md->type==eModifierType_Curve) {
CurveModifierData *cmd = (CurveModifierData*) md;
uiDefIDPoinBut(block, modifier_testCurveObj, B_CHANGEDEP, "Ob:", lx, (cy-=19), 120,19, &cmd->object, "Curve object to deform with");
} else if (md->type==eModifierType_Build) {
BuildModifierData *bmd = (BuildModifierData*) md;
uiDefButF(block, NUM, B_MODIFIER_RECALC, "Start:", lx, (cy-=19), 160,19, &bmd->start, 1.0, 9000.0, 100, 0, "Specify the start frame of the effect");
uiDefButF(block, NUM, B_MODIFIER_RECALC, "Length:", lx, (cy-=19), 160,19, &bmd->length, 1.0, 9000.0, 100, 0, "Specify the total time the build effect requires");
uiDefButI(block, TOG, B_MODIFIER_RECALC, "Randomize", lx, (cy-=19), 160,19, &bmd->randomize, 0, 0, 1, 0, "Randomize the faces or edges during build.");
uiDefButI(block, NUM, B_MODIFIER_RECALC, "Seed:", lx, (cy-=19), 160,19, &bmd->seed, 1.0, 9000.0, 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), 160,19, &mmd->tolerance, 0.0, 1, 0, 0, "Distance from axis within which mirrored vertices are merged");
uiDefButI(block, ROW, B_MODIFIER_RECALC, "X", lx, (cy-=19), 20,19, &mmd->axis, 1, 0, 0, 0, "Specify the axis to mirror about");
uiDefButI(block, ROW, B_MODIFIER_RECALC, "Y", lx+20, cy, 20,19, &mmd->axis, 1, 1, 0, 0, "Specify the axis to mirror about");
uiDefButI(block, ROW, B_MODIFIER_RECALC, "Z", lx+40, cy, 20,19, &mmd->axis, 1, 2, 0, 0, "Specify the axis to mirror about");
} else if (md->type==eModifierType_Decimate) {
DecimateModifierData *dmd = (DecimateModifierData*) md;
uiDefButF(block, NUM, B_MODIFIER_RECALC, "Percent:", lx,(cy-=19),160,19, &dmd->percent, 0.0, 1.0, 0, 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_Wave) {
WaveModifierData *wmd = (WaveModifierData*) md;
uiDefButBitS(block, TOG, WAV_X, B_MODIFIER_RECALC, "X", lx,(cy-=19),45,19, &wmd->flag, 0, 0, 0, 0, "Enable X axis motion");
uiDefButBitS(block, TOG, WAV_Y, B_MODIFIER_RECALC, "Y", lx+50,cy,45,19, &wmd->flag, 0, 0, 0, 0, "Enable Y axis motion");
uiDefButBitS(block, TOG, WAV_CYCL, B_MODIFIER_RECALC, "Cycl", lx+100,cy,60,19, &wmd->flag, 0, 0, 0, 0, "Enable cyclic wave effect");
uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time sta:", lx,(cy-=19),150,19, &wmd->timeoffs, -1000.0, 1000.0, 100, 0, "Specify startingframe of the wave");
uiDefButF(block, NUM, B_MODIFIER_RECALC, "Lifetime:", lx,(cy-=19),150,19, &wmd->lifetime, -1000.0, 1000.0, 100, 0, "Specify the lifespan of the wave");
uiDefButF(block, NUM, B_MODIFIER_RECALC, "Damptime:", lx,(cy-=19),150,19, &wmd->damp, -1000.0, 1000.0, 100, 0, "Specify the dampingtime of the wave");
cy -= 19;
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");
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, "Heigth:", 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");
}
uiBlockEndAlign(block);
y-=height;
}
if (md->error) {
char str[512];
y -= 20;
BIF_ThemeColorShade(color, 40);
glRects(x+3+10, y, x+width+10, y+20);
sprintf(str, "Modifier Error: %s", md->error);
uiDefBut(block, LABEL, B_NOP, str, x+15, y+15, width-35, 19, NULL, 0.0, 0.0, 0.0, 0.0, "");
}
y -= 3+6;
*xco = x;
*yco = y;
}
static void editing_panel_modifiers(Object *ob)
{
ModifierData *md;
uiBlock *block;
int xco, yco, i, lastCageIndex, cageIndex = modifiers_getCageIndex(&ob->modifiers, &lastCageIndex);
// XXX ofsx should probably be changed in other panels here
block= uiNewBlock(&curarea->uiblocks, "editing_panel_modifiers", UI_EMBOSS, UI_HELV, curarea->win);
if( uiNewPanel(curarea, block, "Modifiers", "Editing", 640, 0, 318, 204)==0) return;
uiNewPanelHeight(block, 204);
uiDefBlockBut(block, modifiers_add_menu, ob, "Add Modifier", 0, 190, 130, 20, "Add a new modifier");
xco = 0;
yco = 160;
uiPanelPush(block);
for (i=0,md=ob->modifiers.first; md; i++, md=md->next) {
draw_modifier(block, ob, md, &xco, &yco, i, cageIndex, lastCageIndex);
}
uiPanelPop(block);
if(yco < 0) uiNewPanelHeight(block, 204-yco);
}
/* *************************** FONT ******************************** */
@ -2544,6 +2953,7 @@ void editing_panels()
case OB_MESH:
editing_panel_links(ob); // no editmode!
editing_panel_mesh_type(ob, ob->data); // no editmode!
editing_panel_modifiers(ob);
/* modes */
if(G.obedit) {
editing_panel_mesh_tools(ob, ob->data); // no editmode!

View File

@ -1655,313 +1655,6 @@ static void object_softbodies(Object *ob)
}
/* Modifiers */
static int actModifier = 0;
void do_modifier_panels(unsigned short event)
{
Object *ob = OBACT;
ModifierData *md;
int i;
for (i=0, md=ob->modifiers.first; md && i<actModifier-1; i++)
md = md->next;
switch(event) {
case B_MDFR_INCREMENTAL:
if (md && md->type==eModifierType_Subsurf) {
SubsurfModifierData *smd = (SubsurfModifierData*) md;
if ((smd->flags&eSubsurfModifierFlag_Incremental) && ob->type==OB_MESH) {
Mesh *me = ob->data;
if (!me->medge) {
if (okee("Requires mesh edges, create now?")) {
make_edges(me);
}
}
}
}
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */
break;
}
}
static void modifiers_add(void *ob_v, int type)
{
Object *ob = ob_v;
ModifierData *md;
int i;
for (i=0, md=ob->modifiers.first; md && i<actModifier-1; i++)
md = md->next;
BLI_insertlink(&ob->modifiers, md, modifier_new(type));
actModifier++;
allqueue(REDRAWBUTSOBJECT, 0);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
}
static uiBlock *modifier_add_menu(void *ob_v)
{
Object *ob = ob_v;
uiBlock *block;
int i, yco=0;
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);
if ( (mti->flags&eModifierTypeFlag_AcceptsCVs) ||
(ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
uiDefBut(block, BUTM, B_NOP, mti->name, 0, yco-=20, 160, 19, NULL, 0, 0, 1, i, "");
}
}
uiTextBoundsBlock(block, 50);
uiBlockSetDirection(block, UI_DOWN);
return block;
}
static void modifiers_del(void *ob_v, void *arg2)
{
Object *ob = ob_v;
ModifierData *md;
int i;
for (i=0, md=ob->modifiers.first; md && i<actModifier-1; i++)
md = md->next;
if (md) {
BLI_remlink(&ob->modifiers, md);
modifier_free(md);
}
allqueue(REDRAWBUTSOBJECT, 0);
}
static void modifiers_moveUp(void *ob_v, void *md_v)
{
Object *ob = ob_v;
ModifierData *md = md_v;
if (md->prev) {
BLI_remlink(&ob->modifiers, md);
BLI_insertlink(&ob->modifiers, md->prev->prev, md);
actModifier--;
}
allqueue(REDRAWBUTSOBJECT, 0);
}
static void modifiers_moveDown(void *ob_v, void *md_v)
{
Object *ob = ob_v;
ModifierData *md = md_v;
if (md->next) {
BLI_remlink(&ob->modifiers, md);
BLI_insertlink(&ob->modifiers, md->next, md);
actModifier++;
}
allqueue(REDRAWBUTSOBJECT, 0);
}
static void modifier_testLatticeObj(char *name, ID **idpp)
{
ID *id;
for (id= G.main->object.first; id; id= id->next) {
if( strcmp(name, id->name+2)==0 ) {
if (((Object *)id)->type != OB_LATTICE) {
error ("Lattice deform object must be a lattice");
break;
}
*idpp= id;
return;
}
}
*idpp= 0;
}
static void modifier_testCurveObj(char *name, ID **idpp)
{
ID *id;
for (id= G.main->object.first; id; id= id->next) {
if( strcmp(name, id->name+2)==0 ) {
if (((Object *)id)->type != OB_CURVE) {
error ("Curve deform object must be a curve");
break;
}
*idpp= id;
return;
}
}
*idpp= 0;
}
static void modifiers_applyModifier(void *obv, void *mdv)
{
Object *ob = obv;
ModifierData *md = mdv;
DerivedMesh *dm;
DispListMesh *dlm;
Mesh *me = ob->data;
if (G.obedit) {
error("Modifiers cannot be applied in editmode");
return;
} else if (me->id.us>1) {
error("Modifiers cannot be applied to a multi-user mesh");
return;
}
if (md!=ob->modifiers.first) {
if (!okee("Modifier is not first, continue with apply?"))
return;
}
// XXX, only for mesh
dm = mesh_create_derived_for_modifier(ob, md);
if (!dm) {
error("Modifier is disabled or returned error, skipping apply");
return;
}
dlm= dm->convertToDispListMesh(dm);
ob->data= add_mesh();
displistmesh_to_mesh(dlm, ob->data);
displistmesh_free(dlm);
dm->release(dm);
free_libblock_us(&G.main->mesh, me);
BLI_remlink(&ob->modifiers, md);
modifier_free(md);
if (actModifier>1)
actModifier--;
}
static void object_panel_modifiers(Object *ob)
{
uiBlock *block;
uiBut *but;
block= uiNewBlock(&curarea->uiblocks, "modifiers_panel", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Modifiers", "Object", 640, 0, 318, 204)==0) return;
uiBlockBeginAlign(block);
uiDefBlockBut(block, modifier_add_menu, ob, "Add Modifier", 740,400,110,19, "Insert a new modifier after the current one");
but = uiDefBut(block, BUT, B_MAKEDISP, "Delete", 850,400,70,19, 0, 0, 0, 0, 0, "Delete the current modifier");
uiButSetFunc(but, modifiers_del, ob, NULL);
if (ob->modifiers.first) {
int i, canCage=1, numModifiers = BLI_countlist(&ob->modifiers);
ModifierData *md;
CLAMP(actModifier, 1, numModifiers);
uiDefButI(block, NUM, B_REDR, "Modifier", 740,380,180,27, &actModifier, 1, numModifiers, 0, 0, "Index of current modifier");
for (i=0, md=ob->modifiers.first; md && i<actModifier-1; i++) {
if (!modifier_supportsMapping(md) || !(md->mode&eModifierMode_OnCage))
canCage = 0;
md = md->next;
}
if (md) {
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
char str[128];
but = uiDefBut(block, BUT, B_MAKEDISP, "Move Up", 740, 360, 90, 19, 0, 0, 0, 0, 0, "Move modifier up in stack");
uiButSetFunc(but, modifiers_moveUp, ob, md);
but = uiDefBut(block, BUT, B_MAKEDISP, "Move Down", 830, 360, 90, 19, 0, 0, 0, 0, 0, "Move modifier down in stack");
uiButSetFunc(but, modifiers_moveDown, ob, md);
uiDefButBitI(block, TOG, eModifierMode_Render, B_NOP, "Render", 740,340,90,19,&md->mode, 0, 0, 1, 0, "Enable modifier during rendering");
uiDefButBitI(block, TOG, eModifierMode_Realtime, B_MAKEDISP, "3D View", 830,340,90,19,&md->mode, 0, 0, 1, 0, "Enable modifier during interactive display");
if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
uiDefButBitI(block, TOG, eModifierMode_Editmode, B_MAKEDISP, "Editmode", 740,320,90,19,&md->mode, 0, 0, 1, 0, "Enable modifier during Editmode");
if (canCage && modifier_supportsMapping(md)) {
uiDefButBitI(block, TOG, eModifierMode_OnCage, B_MAKEDISP, "On Cage", 830,320,90,19,&md->mode, 0, 0, 1, 0, "Apply modifier to editing cage during Editmode");
}
}
but = uiDefBut(block, BUT, B_MAKEDISP, "Apply Modifier", 740,300,180,19, 0, 0, 0, 0, 0, "Apply the currnt modifier and remove from the stack");
uiButSetFunc(but, modifiers_applyModifier, ob, md);
uiBlockBeginAlign(block);
sprintf(str, "Modifier: %s", mti->name);
uiDefBut(block, LABEL, 1, str, 550, 400, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
if (md->type==eModifierType_Subsurf) {
SubsurfModifierData *smd = (SubsurfModifierData*) md;
char subsurfmenu[]="Subsurf Type%t|Catmull-Clark%x0|Simple Subdiv.%x1";
uiDefButS(block, NUM, B_MAKEDISP, "Levels:", 550, 380, 160,19, &smd->levels, 1, 6, 0, 0, "Number subdivisions to perform");
uiDefButS(block, NUM, B_MAKEDISP, "Render Levels:", 550, 360, 160,19, &smd->renderLevels, 1, 6, 0, 0, "Number subdivisions to perform when rendering");
uiDefButS(block, MENU, B_MAKEDISP, subsurfmenu, 550,340,160,19, &smd->subdivType, 0, 0, 0, 0, "Selects type of subdivision algorithm.");
uiDefButBitS(block, TOG, eSubsurfModifierFlag_Incremental, B_MDFR_INCREMENTAL, "Incremental", 550, 320,160,19,&smd->flags, 0, 0, 0, 0, "Use incremental calculation, even outside of mesh mode");
uiDefButBitS(block, TOG, eSubsurfModifierFlag_DebugIncr, B_MAKEDISP, "Debug Incr.", 550, 300,160,19,&smd->flags, 0, 0, 0, 0, "Visualize the subsurf incremental calculation, for debugging effect of other modifiers");
} else if (md->type==eModifierType_Lattice) {
LatticeModifierData *lmd = (LatticeModifierData*) md;
uiDefIDPoinBut(block, modifier_testLatticeObj, B_CHANGEDEP, "Ob:", 550, 380, 120,19, &lmd->object, "Lattice object to deform with");
} else if (md->type==eModifierType_Curve) {
CurveModifierData *cmd = (CurveModifierData*) md;
uiDefIDPoinBut(block, modifier_testCurveObj, B_CHANGEDEP, "Ob:", 550, 380, 120,19, &cmd->object, "Curve object to deform with");
} else if (md->type==eModifierType_Build) {
BuildModifierData *bmd = (BuildModifierData*) md;
uiDefButF(block, NUM, B_MAKEDISP, "Start:", 550, 380, 150,19, &bmd->start, 1.0, 9000.0, 100, 0, "Specify the start frame of the effect");
uiDefButF(block, NUM, B_MAKEDISP, "Length:", 550, 360, 150,19, &bmd->length, 1.0, 9000.0, 100, 0, "Specify the total time the build effect requires");
uiDefButI(block, TOG, B_MAKEDISP, "Randomize", 550, 340, 150,19, &bmd->randomize, 0, 0, 1, 0, "Randomize the faces or edges during build.");
uiDefButI(block, NUM, B_MAKEDISP, "Seed:", 550, 320, 150,19, &bmd->seed, 1.0, 9000.0, 100, 0, "Specify the seed for random if used.");
} else if (md->type==eModifierType_Mirror) {
MirrorModifierData *mmd = (MirrorModifierData*) md;
uiDefButF(block, NUM, B_MAKEDISP, "Merge Limit:", 550, 380, 150,19, &mmd->tolerance, 0.0, 1, 0, 0, "Distance from axis within which mirrored vertices are merged");
uiDefButI(block, ROW, B_MAKEDISP, "X", 550, 360, 20,19, &mmd->axis, 1, 0, 0, 0, "Specify the axis to mirror about");
uiDefButI(block, ROW, B_MAKEDISP, "Y", 570, 360, 20,19, &mmd->axis, 1, 1, 0, 0, "Specify the axis to mirror about");
uiDefButI(block, ROW, B_MAKEDISP, "Z", 590, 360, 20,19, &mmd->axis, 1, 2, 0, 0, "Specify the axis to mirror about");
} else if (md->type==eModifierType_Decimate) {
DecimateModifierData *dmd = (DecimateModifierData*) md;
uiDefButF(block, NUM, B_MAKEDISP, "Percent:", 550,380,150,19, &dmd->percent, 0.0, 1.0, 0, 0, "Defines the percentage of triangles to reduce to");
sprintf(str, "Face Count: %d", dmd->faceCount);
uiDefBut(block, LABEL, 1, str, 550, 360, 150,19, NULL, 0.0, 0.0, 0, 0, "Displays the current number of faces in the decimated mesh");
} else if (md->type==eModifierType_Wave) {
WaveModifierData *wmd = (WaveModifierData*) md;
uiBlockBeginAlign(block);
uiDefButBitS(block, TOG, WAV_X, B_MAKEDISP, "X", 550,380,45,19, &wmd->flag, 0, 0, 0, 0, "Enable X axis motion");
uiDefButBitS(block, TOG, WAV_Y, B_MAKEDISP, "Y", 600,380,45,19, &wmd->flag, 0, 0, 0, 0, "Enable Y axis motion");
uiDefButBitS(block, TOG, WAV_CYCL, B_MAKEDISP, "Cycl", 650,380,60,19, &wmd->flag, 0, 0, 0, 0, "Enable cyclic wave effect");
uiDefButF(block, NUM, B_MAKEDISP, "Time sta:", 550,360,150,19, &wmd->timeoffs, -1000.0, 1000.0, 100, 0, "Specify startingframe of the wave");
uiDefButF(block, NUM, B_MAKEDISP, "Lifetime:", 550,340,150,19, &wmd->lifetime, -1000.0, 1000.0, 100, 0, "Specify the lifespan of the wave");
uiDefButF(block, NUM, B_MAKEDISP, "Damptime:", 550,320,150,19, &wmd->damp, -1000.0, 1000.0, 100, 0, "Specify the dampingtime of the wave");
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_MAKEDISP, "Sta x:", 550,280,113,19, &wmd->startx, -100.0, 100.0, 100, 0, "Starting position for the X axis");
uiDefButF(block, NUM, B_MAKEDISP, "Sta y:", 665,280,105,19, &wmd->starty, -100.0, 100.0, 100, 0, "Starting position for the Y axis");
uiBlockBeginAlign(block);
uiDefButF(block, NUMSLI, B_MAKEDISP, "Speed:", 550,260,220,19, &wmd->speed, -2.0, 2.0, 0, 0, "Specify the wave speed");
uiDefButF(block, NUMSLI, B_MAKEDISP, "Heigth:", 550,240,220,19, &wmd->height, -2.0, 2.0, 0, 0, "Specify the amplitude of the wave");
uiDefButF(block, NUMSLI, B_MAKEDISP, "Width:", 550,220,220,19, &wmd->width, 0.0, 5.0, 0, 0, "Specify the width of the wave");
uiDefButF(block, NUMSLI, B_MAKEDISP, "Narrow:", 550,200,220,19, &wmd->narrow, 0.0, 10.0, 0, 0, "Specify how narrow the wave follows");
uiBlockEndAlign(block);
}
uiBlockEndAlign(block);
}
}
}
/***/
static void object_panel_effects(Object *ob)
{
Effect *eff;
@ -2091,7 +1784,6 @@ void object_panels()
object_panel_constraint();
if(ob->type==OB_MESH) {
object_panel_effects(ob);
object_panel_modifiers(ob);
}
object_panel_deflectors(ob);
object_softbodies(ob);