forked from bartvdbraak/blender
Surface Deform Modifier (SDef)
Implementation of the SDef modifier, which allows meshes to be bound by surface, thus allowing things such as cloth simulation proxies. User documentation: https://wiki.blender.org/index.php/User:Lucarood/SurfaceDeform Reviewers: mont29, sergey Subscribers: Severin, dfelinto, plasmasolutions, kjym3 Differential Revision: https://developer.blender.org/D2462
This commit is contained in:
parent
cd5c853307
commit
4fa4132e45
@ -951,6 +951,20 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
||||
def SURFACE(self, layout, ob, md):
|
||||
layout.label(text="Settings are inside the Physics tab")
|
||||
|
||||
def SURFACE_DEFORM(self, layout, ob, md):
|
||||
col = layout.column()
|
||||
col.active = not md.is_bound
|
||||
|
||||
col.prop(md, "target")
|
||||
col.prop(md, "falloff")
|
||||
|
||||
layout.separator()
|
||||
|
||||
if md.is_bound:
|
||||
layout.operator("object.surfacedeform_bind", text="Unbind")
|
||||
else:
|
||||
layout.operator("object.surfacedeform_bind", text="Bind")
|
||||
|
||||
def UV_PROJECT(self, layout, ob, md):
|
||||
split = layout.split()
|
||||
|
||||
|
@ -5317,6 +5317,37 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
|
||||
MeshSeqCacheModifierData *msmcd = (MeshSeqCacheModifierData *)md;
|
||||
msmcd->reader = NULL;
|
||||
}
|
||||
else if (md->type == eModifierType_SurfaceDeform) {
|
||||
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
|
||||
|
||||
smd->verts = newdataadr(fd, smd->verts);
|
||||
|
||||
if (smd->verts) {
|
||||
for (int i = 0; i < smd->numverts; i++) {
|
||||
smd->verts[i].binds = newdataadr(fd, smd->verts[i].binds);
|
||||
|
||||
if (smd->verts[i].binds) {
|
||||
for (int j = 0; j < smd->verts[i].numbinds; j++) {
|
||||
smd->verts[i].binds[j].vert_inds = newdataadr(fd, smd->verts[i].binds[j].vert_inds);
|
||||
smd->verts[i].binds[j].vert_weights = newdataadr(fd, smd->verts[i].binds[j].vert_weights);
|
||||
|
||||
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
||||
if (smd->verts[i].binds[j].vert_inds)
|
||||
BLI_endian_switch_uint32_array(smd->verts[i].binds[j].vert_inds, smd->verts[i].binds[j].numverts);
|
||||
|
||||
if (smd->verts[i].binds[j].vert_weights) {
|
||||
if (smd->verts[i].binds[j].mode == MOD_SDEF_MODE_CENTROID ||
|
||||
smd->verts[i].binds[j].mode == MOD_SDEF_MODE_LOOPTRI)
|
||||
BLI_endian_switch_float_array(smd->verts[i].binds[j].vert_weights, 3);
|
||||
else
|
||||
BLI_endian_switch_float_array(smd->verts[i].binds[j].vert_weights, smd->verts[i].binds[j].numverts);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1837,6 +1837,32 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
|
||||
writedata(wd, DATA, sizeof(float[3]) * csmd->bind_coords_num, csmd->bind_coords);
|
||||
}
|
||||
}
|
||||
else if (md->type == eModifierType_SurfaceDeform) {
|
||||
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
|
||||
|
||||
writestruct(wd, DATA, SDefVert, smd->numverts, smd->verts);
|
||||
|
||||
if (smd->verts) {
|
||||
for (int i = 0; i < smd->numverts; i++) {
|
||||
writestruct(wd, DATA, SDefBind, smd->verts[i].numbinds, smd->verts[i].binds);
|
||||
|
||||
if (smd->verts[i].binds) {
|
||||
for (int j = 0; j < smd->verts[i].numbinds; j++) {
|
||||
writedata(wd, DATA, sizeof(int) * smd->verts[i].binds[j].numverts, smd->verts[i].binds[j].vert_inds);
|
||||
|
||||
if (smd->verts[i].binds[j].mode == MOD_SDEF_MODE_CENTROID ||
|
||||
smd->verts[i].binds[j].mode == MOD_SDEF_MODE_LOOPTRI)
|
||||
{
|
||||
writedata(wd, DATA, sizeof(float) * 3, smd->verts[i].binds[j].vert_weights);
|
||||
}
|
||||
else {
|
||||
writedata(wd, DATA, sizeof(float) * smd->verts[i].binds[j].numverts, smd->verts[i].binds[j].vert_weights);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,6 +186,7 @@ void OBJECT_OT_skin_loose_mark_clear(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_skin_radii_equalize(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_skin_armature_create(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_laplaciandeform_bind(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_surfacedeform_bind(struct wmOperatorType *ot);
|
||||
|
||||
/* object_constraint.c */
|
||||
void OBJECT_OT_constraint_add(struct wmOperatorType *ot);
|
||||
|
@ -2294,3 +2294,63 @@ void OBJECT_OT_laplaciandeform_bind(wmOperatorType *ot)
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
|
||||
edit_modifier_properties(ot);
|
||||
}
|
||||
|
||||
/************************ sdef bind operator *********************/
|
||||
|
||||
static int surfacedeform_bind_poll(bContext *C)
|
||||
{
|
||||
if (edit_modifier_poll_generic(C, &RNA_SurfaceDeformModifier, 0)) {
|
||||
PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_SurfaceDeformModifier);
|
||||
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)ptr.data;
|
||||
|
||||
return ((smd != NULL) && (smd->target != NULL));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int surfacedeform_bind_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob = ED_object_active_context(C);
|
||||
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_SurfaceDeform);
|
||||
|
||||
if (!smd)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
if (smd->flags & MOD_SDEF_BIND) {
|
||||
smd->flags &= ~MOD_SDEF_BIND;
|
||||
}
|
||||
else if (smd->target) {
|
||||
smd->flags |= MOD_SDEF_BIND;
|
||||
}
|
||||
|
||||
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int surfacedeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
{
|
||||
if (edit_modifier_invoke_properties(C, op))
|
||||
return surfacedeform_bind_exec(C, op);
|
||||
else
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_surfacedeform_bind(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Surface Deform Bind";
|
||||
ot->description = "Bind mesh to target in surface deform modifier";
|
||||
ot->idname = "OBJECT_OT_surfacedeform_bind";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll = surfacedeform_bind_poll;
|
||||
ot->invoke = surfacedeform_bind_invoke;
|
||||
ot->exec = surfacedeform_bind_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
|
||||
edit_modifier_properties(ot);
|
||||
}
|
||||
|
@ -255,6 +255,7 @@ void ED_operatortypes_object(void)
|
||||
|
||||
WM_operatortype_append(OBJECT_OT_data_transfer);
|
||||
WM_operatortype_append(OBJECT_OT_datalayout_transfer);
|
||||
WM_operatortype_append(OBJECT_OT_surfacedeform_bind);
|
||||
}
|
||||
|
||||
void ED_operatormacros_object(void)
|
||||
|
@ -1126,6 +1126,7 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
|
||||
case eModifierType_Cast:
|
||||
UI_icon_draw(x, y, ICON_MOD_CAST); break;
|
||||
case eModifierType_MeshDeform:
|
||||
case eModifierType_SurfaceDeform:
|
||||
UI_icon_draw(x, y, ICON_MOD_MESHDEFORM); break;
|
||||
case eModifierType_Bevel:
|
||||
UI_icon_draw(x, y, ICON_MOD_BEVEL); break;
|
||||
|
@ -86,6 +86,7 @@ typedef enum ModifierType {
|
||||
eModifierType_NormalEdit = 50,
|
||||
eModifierType_CorrectiveSmooth = 51,
|
||||
eModifierType_MeshSequenceCache = 52,
|
||||
eModifierType_SurfaceDeform = 53,
|
||||
NUM_MODIFIER_TYPES
|
||||
} ModifierType;
|
||||
|
||||
@ -1570,6 +1571,45 @@ enum {
|
||||
MOD_MESHSEQ_READ_COLOR = (1 << 3),
|
||||
};
|
||||
|
||||
typedef struct SDefBind {
|
||||
unsigned int *vert_inds;
|
||||
unsigned int numverts;
|
||||
int mode;
|
||||
float *vert_weights;
|
||||
float normal_dist;
|
||||
float influence;
|
||||
} SDefBind;
|
||||
|
||||
typedef struct SDefVert {
|
||||
SDefBind *binds;
|
||||
unsigned int numbinds;
|
||||
char pad[4];
|
||||
} SDefVert;
|
||||
|
||||
typedef struct SurfaceDeformModifierData {
|
||||
ModifierData modifier;
|
||||
|
||||
struct Object *target; /* bind target object */
|
||||
SDefVert *verts; /* vertex bind data */
|
||||
float falloff;
|
||||
unsigned int numverts, numpoly;
|
||||
int flags;
|
||||
} SurfaceDeformModifierData;
|
||||
|
||||
/* Surface Deform modifier flags */
|
||||
enum {
|
||||
MOD_SDEF_BIND = (1 << 0),
|
||||
MOD_SDEF_USES_LOOPTRI = (1 << 1),
|
||||
MOD_SDEF_HAS_CONCAVE = (1 << 2),
|
||||
};
|
||||
|
||||
/* Surface Deform vertex bind modes */
|
||||
enum {
|
||||
MOD_SDEF_MODE_LOOPTRI = 0,
|
||||
MOD_SDEF_MODE_NGON = 1,
|
||||
MOD_SDEF_MODE_CENTROID = 2,
|
||||
};
|
||||
|
||||
#define MOD_MESHSEQ_READ_ALL \
|
||||
(MOD_MESHSEQ_READ_VERT | MOD_MESHSEQ_READ_POLY | MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)
|
||||
|
||||
|
@ -598,6 +598,7 @@ extern StructRNA RNA_StucciTexture;
|
||||
extern StructRNA RNA_SubsurfModifier;
|
||||
extern StructRNA RNA_SunLamp;
|
||||
extern StructRNA RNA_SurfaceCurve;
|
||||
extern StructRNA RNA_SurfaceDeformModifier;
|
||||
extern StructRNA RNA_SurfaceModifier;
|
||||
extern StructRNA RNA_TexMapping;
|
||||
extern StructRNA RNA_Text;
|
||||
|
@ -105,6 +105,7 @@ EnumPropertyItem rna_enum_object_modifier_type_items[] = {
|
||||
{eModifierType_Shrinkwrap, "SHRINKWRAP", ICON_MOD_SHRINKWRAP, "Shrinkwrap", ""},
|
||||
{eModifierType_SimpleDeform, "SIMPLE_DEFORM", ICON_MOD_SIMPLEDEFORM, "Simple Deform", ""},
|
||||
{eModifierType_Smooth, "SMOOTH", ICON_MOD_SMOOTH, "Smooth", ""},
|
||||
{eModifierType_SurfaceDeform, "SURFACE_DEFORM", ICON_MOD_MESHDEFORM, "Surface Deform", ""},
|
||||
{eModifierType_Warp, "WARP", ICON_MOD_WARP, "Warp", ""},
|
||||
{eModifierType_Wave, "WAVE", ICON_MOD_WAVE, "Wave", ""},
|
||||
{0, "", 0, N_("Simulate"), ""},
|
||||
@ -408,6 +409,8 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr)
|
||||
return &RNA_CorrectiveSmoothModifier;
|
||||
case eModifierType_MeshSequenceCache:
|
||||
return &RNA_MeshSequenceCacheModifier;
|
||||
case eModifierType_SurfaceDeform:
|
||||
return &RNA_SurfaceDeformModifier;
|
||||
/* Default */
|
||||
case eModifierType_None:
|
||||
case eModifierType_ShapeKey:
|
||||
@ -573,6 +576,7 @@ RNA_MOD_OBJECT_SET(MeshDeform, object, OB_MESH);
|
||||
RNA_MOD_OBJECT_SET(NormalEdit, target, OB_EMPTY);
|
||||
RNA_MOD_OBJECT_SET(Shrinkwrap, target, OB_MESH);
|
||||
RNA_MOD_OBJECT_SET(Shrinkwrap, auxTarget, OB_MESH);
|
||||
RNA_MOD_OBJECT_SET(SurfaceDeform, target, OB_MESH);
|
||||
|
||||
static void rna_HookModifier_object_set(PointerRNA *ptr, PointerRNA value)
|
||||
{
|
||||
@ -1131,6 +1135,11 @@ static int rna_CorrectiveSmoothModifier_is_bind_get(PointerRNA *ptr)
|
||||
return (csmd->bind_coords != NULL);
|
||||
}
|
||||
|
||||
static int rna_SurfaceDeformModifier_is_bound_get(PointerRNA *ptr)
|
||||
{
|
||||
return (((SurfaceDeformModifierData *)ptr->data)->verts != NULL);
|
||||
}
|
||||
|
||||
static void rna_MeshSequenceCache_object_path_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
#ifdef WITH_ALEMBIC
|
||||
@ -4702,6 +4711,33 @@ static void rna_def_modifier_normaledit(BlenderRNA *brna)
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
}
|
||||
|
||||
static void rna_def_modifier_surfacedeform(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "SurfaceDeformModifier", "Modifier");
|
||||
RNA_def_struct_ui_text(srna, "SurfaceDeform Modifier", "blablabla");
|
||||
RNA_def_struct_sdna(srna, "SurfaceDeformModifierData");
|
||||
RNA_def_struct_ui_icon(srna, ICON_MOD_MESHDEFORM);
|
||||
|
||||
prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Target", "Mesh object to deform with");
|
||||
RNA_def_property_pointer_funcs(prop, NULL, "rna_SurfaceDeformModifier_target_set", NULL, "rna_Mesh_object_poll");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
|
||||
|
||||
prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_range(prop, 2.0f, 16.0f);
|
||||
RNA_def_property_ui_text(prop, "Interpolation falloff", "Controls how much nearby polygons influence deformation");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "is_bound", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_SurfaceDeformModifier_is_bound_get", NULL);
|
||||
RNA_def_property_ui_text(prop, "Bound", "Whether geometry has been bound to target mesh");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
}
|
||||
|
||||
void RNA_def_modifier(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@ -4819,6 +4855,7 @@ void RNA_def_modifier(BlenderRNA *brna)
|
||||
rna_def_modifier_datatransfer(brna);
|
||||
rna_def_modifier_normaledit(brna);
|
||||
rna_def_modifier_meshseqcache(brna);
|
||||
rna_def_modifier_surfacedeform(brna);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -93,6 +93,7 @@ set(SRC
|
||||
intern/MOD_solidify.c
|
||||
intern/MOD_subsurf.c
|
||||
intern/MOD_surface.c
|
||||
intern/MOD_surfacedeform.c
|
||||
intern/MOD_triangulate.c
|
||||
intern/MOD_util.c
|
||||
intern/MOD_uvwarp.c
|
||||
|
@ -85,6 +85,7 @@ extern ModifierTypeInfo modifierType_DataTransfer;
|
||||
extern ModifierTypeInfo modifierType_NormalEdit;
|
||||
extern ModifierTypeInfo modifierType_CorrectiveSmooth;
|
||||
extern ModifierTypeInfo modifierType_MeshSequenceCache;
|
||||
extern ModifierTypeInfo modifierType_SurfaceDeform;
|
||||
|
||||
/* MOD_util.c */
|
||||
void modifier_type_init(ModifierTypeInfo *types[]);
|
||||
|
1189
source/blender/modifiers/intern/MOD_surfacedeform.c
Normal file
1189
source/blender/modifiers/intern/MOD_surfacedeform.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -287,5 +287,6 @@ void modifier_type_init(ModifierTypeInfo *types[])
|
||||
INIT_TYPE(NormalEdit);
|
||||
INIT_TYPE(CorrectiveSmooth);
|
||||
INIT_TYPE(MeshSequenceCache);
|
||||
INIT_TYPE(SurfaceDeform);
|
||||
#undef INIT_TYPE
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user