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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2005-07-20 00:14:17 +0400
committerDaniel Dunbar <daniel@zuster.org>2005-07-20 00:14:17 +0400
commit1df154d14026daf7837f7ed6ea6553145436ae52 (patch)
tree32eae4e00158f1c9a320ef524b4b53ad7ac4139d /source
parentf1763b2f0878096d5ddb5b6aa96bda71aaeb6be1 (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')
-rw-r--r--source/blender/blenkernel/BKE_lattice.h5
-rw-r--r--source/blender/blenkernel/BKE_modifier.h116
-rw-r--r--source/blender/blenkernel/BKE_subsurf.h3
-rw-r--r--source/blender/blenkernel/SConscript1
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c139
-rw-r--r--source/blender/blenkernel/intern/deform.c21
-rw-r--r--source/blender/blenkernel/intern/lattice.c85
-rw-r--r--source/blender/blenkernel/intern/modifier.c181
-rw-r--r--source/blender/blenkernel/intern/object.c13
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c50
-rw-r--r--source/blender/blenloader/intern/readfile.c21
-rw-r--r--source/blender/blenloader/intern/writefile.c15
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h52
-rw-r--r--source/blender/makesdna/DNA_object_types.h1
-rw-r--r--source/blender/makesdna/intern/makesdna.c2
-rw-r--r--source/blender/python/api2_2x/Lattice.c26
-rw-r--r--source/blender/src/buttons_object.c198
17 files changed, 828 insertions, 101 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;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 564017e0de6..436537ca39f 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -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);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 1e754dd3b90..3ee4e1be182 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -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;
}
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
new file mode 100644
index 00000000000..486fc68785c
--- /dev/null
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -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
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 5959f6da594..ee55dcb19fb 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -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')) */
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index 200639cd402..5a8a13f7d50 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -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"
diff --git a/source/blender/python/api2_2x/Lattice.c b/source/blender/python/api2_2x/Lattice.c
index efb19794e39..6fa7423f54f 100644
--- a/source/blender/python/api2_2x/Lattice.c
+++ b/source/blender/python/api2_2x/Lattice.c
@@ -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;
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index b2845765e19..f57728318f1 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -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);