- split {curve,lattice,armature}_deform_verts out of mesh_deform

- removed mesh_deform (merge into mesh_modifier)
 - switch python lattice_apply function to use object_apply_deform,
   this isn't exactly equivalent but the python system shouldn't
   have been calling that deep into the kernel anyway.

New feature: Modifier stack
 - added Object.modifiers (list of ModifierData elements)
 - added DNA_modifier_types.h
     o contains type definition for the file data for the various
       modifier types
 - added BKE_modifier.h
     o contains modifierType_get_info (access to modifier type registry)
     o structs and defines for runtime modifier usage
 - updated mesh_calc_modifiers to evaluate modifier stack (note that
   for the time being it also evaluates the old style modifiers so files
   should load and work as normal).
 - add file handling modifier code (todo: don't replicate on object copy)
 - add modifier stack UI code (lives in object panel)


Only real new feature at the moment is that you can apply lattices and
curves *after* a subdivision surface which was never possible before.

Todo:
 - DEP graph updating does not work correctly yet, so you generally have
   to tab cycle to see results.
 - editmode calculation does not use modifier stack.
 - bug fixes (there must be a few in there somewhere)
This commit is contained in:
Daniel Dunbar 2005-07-19 20:14:17 +00:00
parent f1763b2f08
commit 1df154d140
17 changed files with 830 additions and 103 deletions

View File

@ -50,11 +50,12 @@ void calc_lat_fudu(int flag, int res, float *fu, float *du);
void init_latt_deform(struct Object *oblatt, struct Object *ob);
void calc_latt_deform(float *co);
void end_latt_deform(void);
int mesh_deform(struct Object *ob, float (*vertexCos)[3]);
int object_deform(struct Object *ob);
struct BPoint *latt_bp(struct Lattice *lt, int u, int v, int w);
void outside_lattice(struct Lattice *lt);
void curve_deform_verts(struct Object *cuOb, struct Object *target, float (*vertexCos)[3], int numVerts);
void lattice_deform_verts(struct Object *laOb, struct Object *target, float (*vertexCos)[3], int numVerts);
void armature_deform_verts(struct Object *armOb, struct Object *target, float (*vertexCos)[3], int numVerts);
#endif

View File

@ -0,0 +1,116 @@
/**
*
* $$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#ifndef BKE_MODIFIER_H
#define BKE_MODIFIER_H
struct DerivedMesh;
struct ModifierData;
struct Object;
typedef enum {
/* Should not be used, only for None modifier type */
eModifierTypeType_None,
/* Modifier only does deformation, implies that modifier
* type should have a valid deformVerts function. OnlyDeform
* style modifiers implicitly accept either mesh or CV
* input but should still declare flags appropriately.
*/
eModifierTypeType_OnlyDeform,
eModifierTypeType_Constructive,
eModifierTypeType_Nonconstructive,
} ModifierTypeType;
typedef enum {
eModifierTypeFlag_AcceptsMesh = (1<<0),
eModifierTypeFlag_AcceptsCVs = (1<<1),
eModifierTypeFlag_SupportsMapping = (1<<2),
eModifierTypeFlag_RequiresObject = (1<<3),
} ModifierTypeFlag;
typedef struct ModifierTypeInfo {
char name[32], structName[32];
ModifierTypeType type;
ModifierTypeFlag flags;
/* Create new instance data for this modifier type.
*
* This function must be present.
*/
struct ModifierData *(*allocData)(void);
/* Return a boolean value indicating if this modifier is able to be calculated
* based on the modifier data. This is *not* regarding the md->flag, that is
* tested by the system, this is just if the data validates (for example, a
* lattice will return false if the lattice object is not defined).
*
* This function must be present.
*/
int (*isDisabled)(struct ModifierData *md);
/* Only for deform types, should apply the deformation
* to the given vertex array. Object is guaranteed to be
* non-NULL.
*/
void (*deformVerts)(struct ModifierData *md, struct Object *ob, float (*vertexCos)[3], int numVerts);
/* For non-deform types: apply the modifier and return a new derived
* data object (type is dependent on object type). If the _derivedData_
* argument is non-NULL then the modifier should read the object data
* from the derived object instead of the _data_ object.
*
* If the _vertexCos_ argument is non-NULL then the modifier should read
* the vertex coordinates from that (even if _derivedData_ is non-NULL).
* The length of the _vertexCos_ array is either the number of verts in
* the derived object (if non-NULL) or otherwise the number of verts in
* the original object.
*
* The _useRenderParams_ indicates if the modifier is being applied in
* the service of the renderer which may alter quality settings.
*
* The modifier is expected to release (or reuse) the _derivedData_ argument
* if non-NULL. The modifier *MAY NOT* share the _vertexCos_ argument.
*
* It is possible for _ob_ to be NULL if the modifier type is not flagged
* to require an object. A NULL _ob_ occurs when original coordinate data
* is requested for an object.
*/
void *(*applyModifier)(struct ModifierData *md, void *data, struct Object *ob,
void *derivedData, float (*vertexCos)[3], int useRenderParams);
} ModifierTypeInfo;
ModifierTypeInfo *modifierType_get_info(ModifierType type);
#endif

View File

@ -37,7 +37,8 @@ struct DerivedMesh;
struct EditMesh;
struct DerivedMesh *subsurf_make_derived_from_editmesh(struct EditMesh *em, int subdivLevels, short type, struct DerivedMesh *oldDerived);
struct DerivedMesh *subsurf_make_derived_from_mesh(struct Mesh *me, int subdivLevels, float (*vertCos)[3]);
struct DerivedMesh *subsurf_make_derived_from_mesh(struct Mesh *me, int subdivType, int subdivLevels, float (*vertCos)[3]);
struct DerivedMesh *subsurf_make_derived_from_dlm(struct DispListMesh *dlm, int subdivType, int subdivLevels);
void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]);

View File

@ -19,6 +19,7 @@ source_files = ['intern/constraint.c',
'intern/deform.c',
'intern/image.c',
'intern/mesh.c',
'intern/modifier.c',
'intern/screen.c',
'intern/anim.c',
'intern/displist.c',

View File

@ -39,6 +39,7 @@
#include "DNA_effect_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"
@ -56,6 +57,7 @@
#include "BKE_object.h"
#include "BKE_subsurf.h"
#include "BKE_deform.h"
#include "BKE_modifier.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
@ -1012,23 +1014,154 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm)
/***/
static void mesh_calc_modifiers(Mesh *me, Object *ob, float (*inputVertexCos)[3], DerivedMesh **deform_r, DerivedMesh **final_r, int useRenderParms, int useDeform)
static void mesh_calc_modifiers(Mesh *me, Object *ob, float (*inputVertexCos)[3], DerivedMesh **deform_r, DerivedMesh **final_r, int useRenderParams, int useDeform)
{
ModifierData *md=ob->modifiers.first;
float (*deformedVerts)[3];
DerivedMesh *dm;
int a, numVerts = me->totvert;
if (deform_r) *deform_r = NULL;
*final_r = NULL;
/* Note: useDeform==1 implies ob must be non-NULL */
if (useDeform && ob) {
mesh_modifier(ob, &deformedVerts);
if (!deformedVerts) {
deformedVerts = MEM_mallocN(sizeof(*deformedVerts)*numVerts, "vertexcos1");
for (a=0; a<numVerts; a++) {
VECCOPY(deformedVerts[a], me->mvert[a].co);
}
}
/* Apply all leading deforming modifiers */
for (; md; md=md->next) {
ModifierTypeInfo *mti = modifierType_get_info(md->type);
if (!(md->mode&(1<<useRenderParams))) continue;
if (mti->isDisabled(md)) continue;
if (mti->type==eModifierTypeType_OnlyDeform) {
mti->deformVerts(md, ob, deformedVerts, numVerts);
} else {
break;
}
}
/* Result of all leading deforming modifiers is cached for
* places that wish to use the original mesh but with deformed
* coordinates (vpaint, etc.)
*/
if (deform_r) *deform_r = getMeshDerivedMesh(me, ob, deformedVerts);
} else {
deformedVerts = inputVertexCos;
}
if ((me->flag&ME_SUBSURF) && me->subdiv) {
*final_r = subsurf_make_derived_from_mesh(me, useRenderParms?me->subdivr:me->subdiv, deformedVerts);
/* Now apply all remaining modifiers. If useDeform is off then skip
* OnlyDeform ones. If we have no _ob_ and the modifier requires one
* also skip.
*/
dm = NULL;
for (; md; md=md->next) {
ModifierTypeInfo *mti = modifierType_get_info(md->type);
if (!(md->mode&(1<<useRenderParams))) continue;
if (mti->type==eModifierTypeType_OnlyDeform && !useDeform) continue;
if (!ob && (mti->flags&eModifierTypeFlag_RequiresObject)) continue;
if (mti->isDisabled(md)) continue;
/* How to apply modifier depends on (a) what we already have as
* a result of previous modifiers (could be a DerivedMesh or just
* deformed vertices) and (b) what type the modifier is.
*/
if (mti->type==eModifierTypeType_OnlyDeform) {
/* No existing verts to deform, need to build them. */
if (!deformedVerts) {
if (dm) {
/* Deforming a derived mesh, read the vertex locations out of the mesh and
* deform them. Once done with this run of deformers will be written back.
*/
numVerts = dm->getNumVerts(dm);
deformedVerts = MEM_mallocN(sizeof(*deformedVerts)*numVerts, "dfmv");
dm->getVertCos(dm, deformedVerts);
} else {
numVerts = me->totvert;
deformedVerts = MEM_mallocN(sizeof(*deformedVerts)*numVerts, "vertexcos2");
for (a=0; a<numVerts; a++) {
VECCOPY(deformedVerts[a], me->mvert[a].co);
}
}
}
mti->deformVerts(md, ob, deformedVerts, numVerts);
} else {
/* There are 4 cases here (have deform? have dm?) but they all are handled
* by the modifier apply function, which will also free the DerivedMesh if
* it exists.
*/
dm = mti->applyModifier(md, me, ob, dm, deformedVerts, useRenderParams);
if (deformedVerts) {
if (deformedVerts!=inputVertexCos) {
MEM_freeN(deformedVerts);
}
deformedVerts = 0;
}
}
}
/* Fake the subsurf modifier */
{
int level = useRenderParams?me->subdivr:me->subdiv;
if ((me->flag&ME_SUBSURF) && level) {
ModifierTypeInfo *mti = modifierType_get_info(eModifierType_Subsurf);
SubsurfModifierData smd;
smd.levels = me->subdiv;
smd.renderLevels = me->subdivr;
smd.subdivType = me->subsurftype;
dm = mti->applyModifier(&smd.modifier, me, ob, dm, deformedVerts, useRenderParams);
if (deformedVerts) {
if (deformedVerts!=inputVertexCos) {
MEM_freeN(deformedVerts);
}
deformedVerts = 0;
}
}
}
/* Yay, we are done. If we have a DerivedMesh and deformed vertices need to apply
* these back onto the DerivedMesh. If we have no DerivedMesh then we need to build
* one.
*/
if (dm && deformedVerts) {
DispListMesh *dlm = dm->convertToDispListMesh(dm); // XXX what if verts or nors were shared
int i;
/* XXX, would like to avoid the conversion to a DLM here if possible.
* Requires adding a DerivedMesh.updateVertCos method.
*/
for (i=0; i<numVerts; i++) {
VECCOPY(dlm->mvert[i].co, deformedVerts[i]);
}
dm->release(dm);
if (dlm->nors && !dlm->dontFreeNors) {
MEM_freeN(dlm->nors);
dlm->nors = 0;
}
mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors);
*final_r = derivedmesh_from_displistmesh(dlm);
} else if (dm) {
*final_r = dm;
} else {
*final_r = getMeshDerivedMesh(me, ob, deformedVerts);
}

View File

@ -248,7 +248,7 @@ void mesh_modifier(Object *ob, float (**vertexCos_r)[3])
if(me->totvert==0) return;
vertexCos = MEM_mallocN(sizeof(*vertexCos)*me->totvert, "vertexcos");
vertexCos = MEM_mallocN(sizeof(*vertexCos)*me->totvert, "mm_vertexcos");
for (a=0; a<me->totvert; a++) {
VECCOPY(vertexCos[a], me->mvert[a].co);
}
@ -288,8 +288,23 @@ void mesh_modifier(Object *ob, float (**vertexCos_r)[3])
sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos);
}
/* object_deform: output for mesh is in mesh->mvert */
done |= mesh_deform(ob, vertexCos);
if (ob->parent && me->totvert) {
if(ob->parent->type==OB_CURVE && ob->partype==PARSKEL) {
curve_deform_verts(ob->parent, ob, vertexCos, me->totvert);
done= 1;
}
else if(ob->parent->type==OB_LATTICE) {
lattice_deform_verts(ob->parent, ob, vertexCos, me->totvert);
done= 1;
}
else if(ob->parent->type==OB_ARMATURE && ob->partype==PARSKEL) {
// misleading making displists... very bad
if (ob->parent!=G.obedit) {
armature_deform_verts(ob->parent, ob, vertexCos, me->totvert);
}
done= 1;
}
}
if((ob->softflag & OB_SB_ENABLE) && (ob->softflag & OB_SB_POSTDEF)) {
done= 1;

View File

@ -516,64 +516,53 @@ static void calc_curve_deform(Object *par, float *co, short axis, CurveDeform *c
}
int mesh_deform(Object *ob, float (*vertexCos)[3])
void curve_deform_verts(Object *cuOb, Object *target, float (*vertexCos)[3], int numVerts)
{
Curve *cu = cuOb->data;
int a, flag = cu->flag;
CurveDeform cd;
cu->flag |= (CU_PATH|CU_FOLLOW); // needed for path & bevlist
init_curve_deform(cuOb, target, &cd);
INIT_MINMAX(cd.dmin, cd.dmax);
for(a=0; a<numVerts; a++) {
Mat4MulVecfl(cd.curvespace, vertexCos[a]);
DO_MINMAX(vertexCos[a], cd.dmin, cd.dmax);
}
for(a=0; a<numVerts; a++) {
calc_curve_deform(cuOb, vertexCos[a], target->trackflag, &cd);
Mat4MulVecfl(cd.objectspace, vertexCos[a]);
}
cu->flag = flag;
}
void lattice_deform_verts(Object *laOb, Object *target, float (*vertexCos)[3], int numVerts)
{
Mesh *me = ob->data;
int a;
if(ob->parent==NULL || ob->type!=OB_MESH || !me->totvert) return 0;
if(ob->parent->type==OB_CURVE && ob->partype==PARSKEL) {
Curve *cu = ob->parent->data;
int flag = cu->flag;
CurveDeform cd;
cu->flag |= (CU_PATH|CU_FOLLOW); // needed for path & bevlist
init_curve_deform(ob->parent, ob, &cd);
/* transformation to curve space, and min max*/
INIT_MINMAX(cd.dmin, cd.dmax);
for(a=0; a<me->totvert; a++) {
Mat4MulVecfl(cd.curvespace, vertexCos[a]);
DO_MINMAX(vertexCos[a], cd.dmin, cd.dmax);
}
init_latt_deform(laOb, target);
for(a=0; a<me->totvert; a++) {
calc_curve_deform(ob->parent, vertexCos[a], ob->trackflag, &cd);
Mat4MulVecfl(cd.objectspace, vertexCos[a]); /* move coord back to objectspace */
}
cu->flag = flag;
return 1;
for(a=0; a<numVerts; a++) {
calc_latt_deform(vertexCos[a]);
}
else if(ob->parent->type==OB_LATTICE) {
init_latt_deform(ob->parent, ob);
if(ob->type==OB_MESH) {
for(a=0; a<me->totvert; a++) {
calc_latt_deform(vertexCos[a]);
}
}
end_latt_deform();
return 1;
}
else if(ob->parent->type==OB_ARMATURE && ob->partype==PARSKEL) {
if (ob->parent==G.obedit) // misleading making displists... very bad
return 1;
init_armature_deform (ob->parent, ob);
end_latt_deform();
}
for(a=0; a<me->totvert; a++) {
calc_armature_deform(ob->parent, vertexCos[a], a);
}
return 1;
void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts)
{
int a;
init_armature_deform(armOb, target);
for(a=0; a<numVerts; a++) {
calc_armature_deform(armOb, vertexCos[a], a);
}
return 0;
}
int object_deform(Object *ob)

View File

@ -0,0 +1,181 @@
#include "string.h"
#include "MEM_guardedalloc.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "BKE_utildefines.h"
#include "BKE_DerivedMesh.h"
#include "BKE_displist.h"
#include "BKE_modifier.h"
#include "BKE_lattice.h"
#include "BKE_subsurf.h"
/***/
static void *allocModifierData(int type, int size)
{
ModifierData *md = MEM_callocN(size, "md");
md->type = type;
md->mode = eModifierMode_RealtimeAndRender;
return md;
}
static ModifierData *noneModifier_allocData(void)
{
return allocModifierData(eModifierType_None, sizeof(ModifierData));
}
static int noneModifier_isDisabled(ModifierData *md)
{
return 1;
}
/* Curve */
static ModifierData *curveModifier_allocData(void)
{
return allocModifierData(eModifierType_Curve, sizeof(CurveModifierData));
}
static int curveModifier_isDisabled(ModifierData *md)
{
CurveModifierData *cmd = (CurveModifierData*) md;
return !cmd->object;
}
static void curveModifier_deformVerts(ModifierData *md, Object *ob, float (*vertexCos)[3], int numVerts)
{
CurveModifierData *cmd = (CurveModifierData*) md;
curve_deform_verts(cmd->object, ob, vertexCos, numVerts);
}
/* Lattice */
static ModifierData *latticeModifier_allocData(void)
{
return allocModifierData(eModifierType_Lattice, sizeof(LatticeModifierData));
}
static int latticeModifier_isDisabled(ModifierData *md)
{
LatticeModifierData *lmd = (LatticeModifierData*) md;
return !lmd->object;
}
static void latticeModifier_deformVerts(ModifierData *md, Object *ob, float (*vertexCos)[3], int numVerts)
{
LatticeModifierData *lmd = (LatticeModifierData*) md;
lattice_deform_verts(lmd->object, ob, vertexCos, numVerts);
}
/* Subsurf */
static ModifierData *subsurfModifier_allocData(void)
{
SubsurfModifierData *smd = allocModifierData(eModifierType_Subsurf, sizeof(SubsurfModifierData));
smd->levels = 1;
smd->renderLevels = 2;
return (ModifierData*) smd;
}
static int subsurfModifier_isDisabled(ModifierData *md)
{
return 0;
}
static void *subsurfModifier_applyModifier(ModifierData *md, void *data, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int useRenderParams)
{
SubsurfModifierData *smd = (SubsurfModifierData*) md;
int levels = useRenderParams?smd->renderLevels:smd->levels;
Mesh *me = data;
if (dm) {
DispListMesh *dlm = dm->convertToDispListMesh(dm); // XXX what if verts were shared
int i;
if (vertexCos) {
int numVerts = dm->getNumVerts(dm);
for (i=0; i<numVerts; i++) {
VECCOPY(dlm->mvert[i].co, vertexCos[i]);
}
}
dm->release(dm);
dm = subsurf_make_derived_from_dlm(dlm, smd->subdivType, levels);
displistmesh_free(dlm);
return dm;
} else {
return subsurf_make_derived_from_mesh(me, smd->subdivType, levels, vertexCos);
}
}
/***/
static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES];
static int typeArrInit = 1;
ModifierTypeInfo *modifierType_get_info(ModifierType type)
{
if (typeArrInit) {
ModifierTypeInfo *mti;
memset(typeArr, 0, sizeof(typeArr));
mti = &typeArr[eModifierType_None];
strcpy(mti->name, "None");
strcpy(mti->structName, "ModifierData");
mti->type = eModifierType_None;
mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_AcceptsCVs;
mti->allocData = noneModifier_allocData;
mti->isDisabled = noneModifier_isDisabled;
mti = &typeArr[eModifierType_Curve];
strcpy(mti->name, "Curve");
strcpy(mti->structName, "CurveModifierData");
mti->type = eModifierTypeType_OnlyDeform;
mti->flags = eModifierTypeFlag_AcceptsCVs;
mti->allocData = curveModifier_allocData;
mti->isDisabled = curveModifier_isDisabled;
mti->deformVerts = curveModifier_deformVerts;
mti = &typeArr[eModifierType_Lattice];
strcpy(mti->name, "Lattice");
strcpy(mti->structName, "LatticeModifierData");
mti->type = eModifierTypeType_OnlyDeform;
mti->flags = eModifierTypeFlag_AcceptsCVs;
mti->allocData = latticeModifier_allocData;
mti->isDisabled = latticeModifier_isDisabled;
mti->deformVerts = latticeModifier_deformVerts;
mti = &typeArr[eModifierType_Subsurf];
strcpy(mti->name, "Subsurf");
strcpy(mti->structName, "SubsurfModifierData");
mti->type = eModifierTypeType_Constructive;
mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_SupportsMapping;
mti->allocData = subsurfModifier_allocData;
mti->isDisabled = subsurfModifier_isDisabled;
mti->applyModifier = subsurfModifier_applyModifier;
typeArrInit = 0;
}
if (type>=0 && type<NUM_MODIFIER_TYPES && typeArr[type].name[0]!='\0') {
return &typeArr[type];
} else {
return NULL;
}
}

View File

@ -54,6 +54,7 @@
#include "DNA_material_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_oops_types.h"
@ -170,6 +171,16 @@ static void copy_hooks(ListBase *new, ListBase *old)
}
static void free_modifiers(ListBase *lb)
{
ModifierData *md;
while (md=lb->first) {
BLI_remlink(lb, md);
MEM_freeN(md);
}
}
/* do not free object itself */
void free_object(Object *ob)
{
@ -210,6 +221,7 @@ void free_object(Object *ob)
free_effects(&ob->effect);
BLI_freelistN(&ob->network);
free_properties(&ob->prop);
free_modifiers(&ob->modifiers);
free_sensors(&ob->sensors);
free_controllers(&ob->controllers);
@ -807,6 +819,7 @@ Object *copy_object(Object *ob)
obn->flag &= ~OB_FROMGROUP;
copy_effects(&obn->effect, &ob->effect);
obn->modifiers.first = obn->modifiers.last= NULL; // XXX fixme
obn->network.first= obn->network.last= 0;

View File

@ -73,6 +73,7 @@ typedef struct _SubSurf {
Mesh *me;
float (*vertCos)[3];
DispListMesh *dlm;
} SubSurf;
typedef struct _VertData {
@ -144,13 +145,14 @@ static SubSurf *subSurf_fromEditmesh(EditMesh *em, int subdivLevels, int useAgin
return ss;
}
static SubSurf *subSurf_fromMesh(Mesh *me, int useFlatSubdiv, int subdivLevels, float (*vertCos)[3]) {
static SubSurf *subSurf_fromMesh(Mesh *me, int useFlatSubdiv, int subdivLevels, float (*vertCos)[3], DispListMesh *dlm) {
SubSurf *ss = MEM_mallocN(sizeof(*ss), "ss_m");
ss->controlType = SUBSURF_CONTROLTYPE_MESH;
ss->useAging=0;
ss->subSurf = _getSubSurf(ss, subdivLevels, 1);
ss->me = me;
ss->dlm = dlm;
ss->vertCos = vertCos;
ccgSubSurf_setAllowEdgeCreation(ss->subSurf, 1, useFlatSubdiv?subdivLevels:0.0f);
@ -505,28 +507,34 @@ static void subSurf_sync(SubSurf *ss, int useFlatSubdiv) {
if (ss->controlType==SUBSURF_CONTROLTYPE_MESH) {
CCGVertHDL fVerts[4];
MVert *mvert = ss->dlm?ss->dlm->mvert:ss->me->mvert;
MEdge *medge = ss->dlm?ss->dlm->medge:ss->me->medge;
MFace *mface = ss->dlm?ss->dlm->mface:ss->me->mface;
int totvert = ss->dlm?ss->dlm->totvert:ss->me->totvert;
int totedge = ss->dlm?ss->dlm->totedge:ss->me->totedge;
int totface = ss->dlm?ss->dlm->totface:ss->me->totface;
int i;
if (ss->vertCos) {
for (i=0; i<ss->me->totvert; i++) {
for (i=0; i<totvert; i++) {
ccgSubSurf_syncVert(ss->subSurf, (CCGVertHDL) i, ss->vertCos[i]);
}
} else {
for (i=0; i<ss->me->totvert; i++) {
ccgSubSurf_syncVert(ss->subSurf, (CCGVertHDL) i, ss->me->mvert[i].co);
for (i=0; i<totvert; i++) {
ccgSubSurf_syncVert(ss->subSurf, (CCGVertHDL) i, mvert[i].co);
}
}
if (ss->me->medge) {
for (i=0; i<ss->me->totedge; i++) {
MEdge *med = &ss->me->medge[i];
if (medge) {
for (i=0; i<totedge; i++) {
MEdge *med = &medge[i];
float crease = useFlatSubdiv?creaseFactor:med->crease*creaseFactor/255.0f;
ccgSubSurf_syncEdge(ss->subSurf, (CCGEdgeHDL) i, (CCGVertHDL) med->v1, (CCGVertHDL) med->v2, crease);
}
} else {
for (i=0; i<ss->me->totface; i++) {
MFace *mf = &((MFace*) ss->me->mface)[i];
for (i=0; i<totface; i++) {
MFace *mf = &((MFace*) mface)[i];
if (!mf->v3) {
ccgSubSurf_syncEdge(ss->subSurf, (CCGEdgeHDL) i, (CCGVertHDL) mf->v1, (CCGVertHDL) mf->v2, useFlatSubdiv?creaseFactor:0.0);
@ -534,8 +542,8 @@ static void subSurf_sync(SubSurf *ss, int useFlatSubdiv) {
}
}
for (i=0; i<ss->me->totface; i++) {
MFace *mf = &((MFace*) ss->me->mface)[i];
for (i=0; i<totface; i++) {
MFace *mf = &((MFace*) mface)[i];
if (mf->v3) {
fVerts[0] = (CCGVertHDL) mf->v1;
@ -1011,12 +1019,22 @@ DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, int subdivLevels,
return (DerivedMesh*) ccgdm;
}
DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, int subdivLevels, float (*vertCos)[3]) {
int useFlatSubdiv = me->subsurftype==ME_SIMPLE_SUBSURF;
SubSurf *ss = subSurf_fromMesh(me, useFlatSubdiv, subdivLevels, vertCos);
DerivedMesh *subsurf_make_derived_from_dlm(DispListMesh *dlm, int subdivType, int subdivLevels) {
SubSurf *ss = subSurf_fromMesh(NULL, subdivType==ME_SIMPLE_SUBSURF, subdivLevels, NULL, dlm);
subSurf_sync(ss, subdivType==ME_SIMPLE_SUBSURF);
dlm = subSurf_createDispListMesh(ss);
subSurf_free(ss);
return derivedmesh_from_displistmesh(dlm);
}
DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, int subdivType, int subdivLevels, float (*vertCos)[3]) {
SubSurf *ss = subSurf_fromMesh(me, subdivType==ME_SIMPLE_SUBSURF, subdivLevels, vertCos, NULL);
DispListMesh *dlm;
subSurf_sync(ss, useFlatSubdiv);
subSurf_sync(ss, subdivType==ME_SIMPLE_SUBSURF);
dlm = subSurf_createDispListMesh(ss);
@ -1032,7 +1050,7 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])
* calculated vert positions is incorrect for the verts
* on the boundary of the mesh.
*/
SubSurf *ss = subSurf_fromMesh(me, 0, 1, NULL);
SubSurf *ss = subSurf_fromMesh(me, 0, 1, NULL, NULL);
float edge_sum[3], face_sum[3];
CCGVertIterator *vi;

View File

@ -79,6 +79,7 @@
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_nla_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
@ -2110,8 +2111,23 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
/* ************ READ OBJECT ***************** */
static void lib_link_modifier_data(FileData *fd, Object *ob, ModifierData *md)
{
if (md->type==eModifierType_Lattice) {
LatticeModifierData *lmd = (LatticeModifierData*) md;
lmd->object = newlibadr_us(fd, ob->id.lib, lmd->object);
}
else if (md->type==eModifierType_Curve) {
CurveModifierData *cmd = (CurveModifierData*) md;
cmd->object = newlibadr_us(fd, ob->id.lib, cmd->object);
}
}
static void lib_link_object(FileData *fd, Main *main)
{
ModifierData *md;
Object *ob;
bSensor *sens;
bController *cont;
@ -2242,6 +2258,10 @@ static void lib_link_object(FileData *fd, Main *main)
for(hook= ob->hooks.first; hook; hook= hook->next) {
hook->parent= newlibadr(fd, ob->id.lib, hook->parent);
}
for (md=ob->modifiers.first; md; md= md->next) {
lib_link_modifier_data(fd, ob, md);
}
}
ob= ob->id.next;
}
@ -2283,6 +2303,7 @@ static void direct_link_object(FileData *fd, Object *ob)
ob->pose= newdataadr(fd, ob->pose);
direct_link_pose(fd, ob->pose);
link_list(fd, &ob->modifiers);
link_list(fd, &ob->defbase);
link_list(fd, &ob->nlastrips);
link_list(fd, &ob->constraintChannels);

View File

@ -120,6 +120,7 @@ Important to know is that 'streaming' has been added to files, for Blender Publi
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_material_types.h"
#include "DNA_modifier_types.h"
#include "DNA_nla_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
@ -155,6 +156,7 @@ Important to know is that 'streaming' has been added to files, for Blender Publi
#include "BKE_scene.h" // for do_seq
#include "BKE_sound.h" /* ... and for samples */
#include "BKE_utildefines.h" // for defines
#include "BKE_modifier.h"
#include "GEN_messaging.h"
@ -657,6 +659,17 @@ static void write_constraint_channels(WriteData *wd, ListBase *chanbase)
}
static void write_modifiers(WriteData *wd, ListBase *modbase)
{
ModifierData *md;
for (md=modbase->first; md; md= md->next) {
ModifierTypeInfo *mti = modifierType_get_info(md->type);
writestruct(wd, DATA, mti->structName, 1, md);
}
}
static void write_objects(WriteData *wd, ListBase *idbase)
{
Object *ob;
@ -699,6 +712,8 @@ static void write_objects(WriteData *wd, ListBase *idbase)
writestruct(wd, DATA, "ObHook", 1, hook);
writedata(wd, DATA, sizeof(int)*hook->totindex, hook->indexar);
}
write_modifiers(wd, &ob->modifiers);
}
ob= ob->id.next;
}

View File

@ -0,0 +1,52 @@
/**
* $Id$
*/
#ifndef DNA_MODIFIER_TYPES_H
#define DNA_MODIFIER_TYPES_H
typedef enum ModifierType {
eModifierType_None = 0,
eModifierType_Subsurf,
eModifierType_Lattice,
eModifierType_Curve,
NUM_MODIFIER_TYPES
} ModifierType;
/* These numerical values are explicitly chosen so that
* (mode&1) is true for realtime calc and (mode&2) is true
* for render calc.
*/
typedef enum ModifierMode {
eModifierMode_Disabled = 0,
eModifierMode_OnlyRealtime = 1,
eModifierMode_OnlyRender = 2,
eModifierMode_RealtimeAndRender = 3,
} ModifierMode;
typedef struct ModifierData {
struct ModifierData *next, *prev;
int type, mode;
} ModifierData;
typedef struct SubsurfModifierData {
ModifierData modifier;
short subdivType, levels, renderLevels, pad;
} SubsurfModifierData;
typedef struct LatticeModifierData {
ModifierData modifier;
struct Object *object;
} LatticeModifierData;
typedef struct CurveModifierData {
ModifierData modifier;
struct Object *object;
} CurveModifierData;
#endif

View File

@ -103,6 +103,7 @@ typedef struct Object {
ListBase network;
ListBase disp;
ListBase defbase;
ListBase modifiers; /* list of ModifierData structures */
struct Material **mat;
/* rot en drot have to be together! (transform('r' en 's')) */

View File

@ -93,6 +93,7 @@ char *includefiles[] = {
"DNA_curve_types.h",
"DNA_mesh_types.h",
"DNA_meshdata_types.h",
"DNA_modifier_types.h",
"DNA_lattice_types.h",
"DNA_object_types.h",
"DNA_object_force.h",
@ -1107,6 +1108,7 @@ int main(int argc, char ** argv)
#include "DNA_curve_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_lattice_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"

View File

@ -705,26 +705,12 @@ static PyObject *Lattice_applyDeform( BPy_Lattice * self, PyObject *args )
* method is needed. Or for users who actually want to apply the
* deformation n times. */
if((self->Lattice == par->data)) {
if ((base->object->type != OB_MESH) || forced) {
if (base->object->type==OB_MESH) {
Mesh *me = base->object->data;
float (*vcos)[3] = malloc(sizeof(*vcos)*me->totvert);
int a;
for (a=0; a<me->totvert; a++) {
VECCOPY(vcos[a], me->mvert[a].co);
}
mesh_deform( base->object, vcos );
for (a=0; a<me->totvert; a++) {
VECCOPY(me->mvert[a].co, vcos[a]);
}
free(vcos);
} else {
object_deform( base->object );
}
}
/* I do not know what to do with this function
* at the moment given the changing modifier system.
* Calling into the modifier system in the first place
* isn't great... -zr
*/
object_apply_deform(base->object);
}
}
base = base->next;

View File

@ -95,6 +95,7 @@
#include "DNA_material_types.h"
#include "DNA_meta_types.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_radio_types.h"
@ -120,6 +121,7 @@
#include "BKE_material.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_sound.h"
#include "BKE_texture.h"
@ -135,11 +137,6 @@ static float prspeed=0.0;
float prlen=0.0;
/* ********************* function prototypes ******************** */
void object_panel_draw(Object *);
void object_panel_hooks(Object *);
void object_panel_effects(Object *);
/* ********************* CONSTRAINT ***************************** */
#if 0
@ -974,7 +971,7 @@ static void object_panel_constraint(void)
}
}
void object_panel_draw(Object *ob)
static void object_panel_draw(Object *ob)
{
uiBlock *block;
int xco, a, dx, dy;
@ -1031,7 +1028,7 @@ void object_panel_draw(Object *ob)
}
void object_panel_hooks(Object *ob)
static void object_panel_hooks(Object *ob)
{
uiBlock *block;
ObHook *hook;
@ -1654,7 +1651,191 @@ static void object_softbodies(Object *ob)
}
void object_panel_effects(Object *ob)
/* Modifiers */
static int actModifier = 0;
static void modifiers_add(void *ob_v, int type)
{
Object *ob = ob_v;
ModifierTypeInfo *mti = modifierType_get_info(type);
if (mti) {
ModifierData *md = mti->allocData();
BLI_addtail(&ob->modifiers, md);
md->type = type;
actModifier = BLI_countlist(&ob->modifiers);
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_get_info(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);
MEM_freeN(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 object_panel_modifiers(Object *ob)
{
uiBlock *block;
uiBut *but;
block= uiNewBlock(&curarea->uiblocks, "modifiers_panel", UI_EMBOSS, UI_HELV, curarea->win);
uiNewPanelTabbed("Constraints", "Object");
if(uiNewPanel(curarea, block, "Modifiers", "Object", 640, 0, 318, 204)==0) return;
uiBlockBeginAlign(block);
uiDefBlockBut(block, modifier_add_menu, ob, "Add Modifier", 550,400,124,27, "Append a new modifier");
but = uiDefBut(block, BUT, B_MAKEDISP, "Delete", 676,400,62,27, 0, 0, 0, 0, 0, "Delete the current modifier");
uiButSetFunc(but, modifiers_del, ob, NULL);
uiBlockEndAlign(block);
if (ob->modifiers.first) {
int i, numModifiers = BLI_countlist(&ob->modifiers);
ModifierData *md;
CLAMP(actModifier, 1, numModifiers);
uiDefButI(block, NUM, B_REDR, "Modifier", 760,400,160,27, &actModifier, 1, numModifiers, 0, 0, "Index of current modifier");
for (i=0, md=ob->modifiers.first; md && i<actModifier-1; i++)
md = md->next;
if (md) {
static char *modifier_mode_menu ="Modifier Mode%t|Disabled%x0|Only Realtime%x1|Only Render%x2|Realtime & Render%x3";
ModifierTypeInfo *mti = modifierType_get_info(md->type);
char str[128];
but = uiDefBut(block, BUT, B_MAKEDISP, "Move Up", 760, 380, 80, 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", 840, 380, 80, 19, 0, 0, 0, 0, 0, "Move modifier up in stack");
uiButSetFunc(but, modifiers_moveDown, ob, md);
sprintf(str, "Modifier: %s", mti->name);
uiDefBut(block, LABEL, 1, str, 550, 360, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
but = uiDefButI(block, MENU, B_MAKEDISP, modifier_mode_menu, 550, 340, 160,19, &md->mode, 0, 0, 0, 0, "Modifier calculation mode");
uiBlockBeginAlign(block);
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, 320, 150,19, &smd->levels, 1, 6, 0, 0, "Number subdivisions to perform");
uiDefButS(block, NUM, B_MAKEDISP, "Render Levels:", 550, 300, 150,19, &smd->renderLevels, 1, 6, 0, 0, "Number subdivisions to perform when rendering");
uiDefButS(block, MENU, B_MAKEDISP, subsurfmenu, 550,280,150,19, &(smd->subdivType), 0, 0, 0, 0, "Selects type of subdivision algorithm.");
} else if (md->type==eModifierType_Lattice) {
LatticeModifierData *lmd = (LatticeModifierData*) md;
uiDefIDPoinBut(block, modifier_testLatticeObj, B_MAKEDISP, "Ob:", 550, 320, 120,19, &lmd->object, "Lattice object to deform with");
} else if (md->type==eModifierType_Curve) {
CurveModifierData *cmd = (CurveModifierData*) md;
uiDefIDPoinBut(block, modifier_testCurveObj, B_MAKEDISP, "Ob:", 550, 320, 120,19, &cmd->object, "Lattice object to deform with");
}
uiBlockEndAlign(block);
}
}
}
/***/
static void object_panel_effects(Object *ob)
{
Effect *eff;
uiBlock *block;
@ -1814,6 +1995,7 @@ 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);