diff options
author | Daniel Dunbar <daniel@zuster.org> | 2005-07-20 00:14:17 +0400 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2005-07-20 00:14:17 +0400 |
commit | 1df154d14026daf7837f7ed6ea6553145436ae52 (patch) | |
tree | 32eae4e00158f1c9a320ef524b4b53ad7ac4139d /source/blender/blenkernel | |
parent | f1763b2f0878096d5ddb5b6aa96bda71aaeb6be1 (diff) |
- 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)
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_lattice.h | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_modifier.h | 116 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_subsurf.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/SConscript | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 139 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/deform.c | 21 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lattice.c | 85 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 181 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 50 |
10 files changed, 541 insertions, 73 deletions
diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index fb3afc98df8..6b6bae6e4c4 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -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 diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h new file mode 100644 index 00000000000..651eb781fe7 --- /dev/null +++ b/source/blender/blenkernel/BKE_modifier.h @@ -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 + diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h index 3ae15d346bb..5443ab72760 100644 --- a/source/blender/blenkernel/BKE_subsurf.h +++ b/source/blender/blenkernel/BKE_subsurf.h @@ -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]); diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index a30c6488e05..66206f0cc98 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -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', diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 3e6c4ee8587..4f89e8e5634 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -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); } diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 55b49744fbc..2b48e8bf101 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -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; diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index eff9d813afd..140c4d74822 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -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) { - Mesh *me = ob->data; - int a; - - if(ob->parent==NULL || ob->type!=OB_MESH || !me->totvert) return 0; + Curve *cu = cuOb->data; + int a, flag = cu->flag; + CurveDeform cd; - 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(cuOb, target, &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_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<me->totvert; a++) { - calc_curve_deform(ob->parent, vertexCos[a], ob->trackflag, &cd); - Mat4MulVecfl(cd.objectspace, vertexCos[a]); /* move coord back to objectspace */ - } + for(a=0; a<numVerts; a++) { + calc_curve_deform(cuOb, vertexCos[a], target->trackflag, &cd); + Mat4MulVecfl(cd.objectspace, vertexCos[a]); + } - cu->flag = flag; + cu->flag = flag; +} - return 1; - } - 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(); +void lattice_deform_verts(Object *laOb, Object *target, float (*vertexCos)[3], int numVerts) +{ + int a; - return 1; + init_latt_deform(laOb, target); + + for(a=0; a<numVerts; a++) { + calc_latt_deform(vertexCos[a]); } - 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); - for(a=0; a<me->totvert; a++) { - calc_armature_deform(ob->parent, vertexCos[a], a); - } - - return 1; + end_latt_deform(); +} + +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) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c new file mode 100644 index 00000000000..dd0f909f8ab --- /dev/null +++ b/source/blender/blenkernel/intern/modifier.c @@ -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; + } +} + diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 1661711fc60..00134a9c03a 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -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; diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index b5222d21630..bf4d752daa8 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -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; |