warp modifier, added in the render branch for durian.
authorCampbell Barton <ideasman42@gmail.com>
Sun, 1 May 2011 15:16:59 +0000 (15:16 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sun, 1 May 2011 15:16:59 +0000 (15:16 +0000)
simple modifier, almost like a hook, except it can deform with 2 object source -> target, has option to preserve rotation and use different falloff types.

12 files changed:
release/scripts/startup/bl_ui/properties_data_modifier.py
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/makesdna/DNA_modifier_types.h
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/rna_modifier.c
source/blender/modifiers/CMakeLists.txt
source/blender/modifiers/MOD_modifiertypes.h
source/blender/modifiers/intern/MOD_displace.c
source/blender/modifiers/intern/MOD_util.c
source/blender/modifiers/intern/MOD_util.h
source/blender/modifiers/intern/MOD_warp.c [new file with mode: 0644]

index e640654..817ad1d 100644 (file)
@@ -635,6 +635,48 @@ class DATA_PT_modifiers(ModifierButtonsPanel, bpy.types.Panel):
             sub.prop(md, "scale_x", text="Scale X")
             sub.prop(md, "scale_y", text="Scale Y")
 
+    def WARP(self, layout, ob, md):
+        use_falloff = (md.falloff_type != 'NONE')
+        split = layout.split()
+
+        col = split.column()
+        col.label(text="From:")
+        col.prop(md, "object_from", text="")
+
+        col.prop(md, "use_volume_preserve")
+
+        col = split.column()
+        col.label(text="To:")
+        col.prop(md, "object_to", text="")
+        col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+
+        col = layout.column()
+
+        row = col.row(align=True)
+        row.prop(md, "strength")
+        if use_falloff:
+            row.prop(md, "falloff_radius")
+
+        col.prop(md, "falloff_type")
+        if use_falloff:
+            if md.falloff_type == 'CURVE':
+                col.template_curve_mapping(md, "falloff_curve")
+
+        # 2 new columns
+        split = layout.split()
+        col = split.column()
+        col.label(text="Texture:")
+        col.prop(md, "texture", text="")
+
+        col = split.column()
+        col.label(text="Texture Coordinates:")
+        col.prop(md, "texture_coords", text="")
+
+        if md.texture_coords == 'OBJECT':
+            layout.prop(md, "texture_coordinate_object", text="Object")
+        elif md.texture_coords == 'UV' and ob.type == 'MESH':
+            layout.prop_object(md, "uv_layer", ob.data, "uv_textures")
+
     def WAVE(self, layout, ob, md):
         split = layout.split()
 
index bfec263..e1b13e0 100644 (file)
@@ -4122,6 +4122,13 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                                                SWITCH_INT(mmd->bindcos[a])
                        }
                }
+               else if (md->type==eModifierType_Warp) {
+                       WarpModifierData *tmd = (WarpModifierData *) md;
+
+                       tmd->curfalloff= newdataadr(fd, tmd->curfalloff);
+                       if(tmd->curfalloff)
+                               direct_link_curvemapping(fd, tmd->curfalloff);
+               }
        }
 }
 
index af4f97f..f84c489 100644 (file)
@@ -1274,6 +1274,12 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
                        writestruct(wd, DATA, "MDefInfluence", mmd->totinfluence, mmd->dyninfluences);
                        writedata(wd, DATA, sizeof(int)*mmd->totvert, mmd->dynverts);
                }
+               else if (md->type==eModifierType_Warp) {
+                       WarpModifierData *tmd = (WarpModifierData*) md;
+                       if(tmd->curfalloff) {
+                               write_curvemapping(wd, tmd->curfalloff);
+                       }
+               }
        }
 }
 
index de84f69..d2d8e01 100644 (file)
@@ -70,8 +70,6 @@ typedef enum ModifierType {
        eModifierType_ShapeKey,
        eModifierType_Solidify,
        eModifierType_Screw,
-       /* placeholder, keep this so durian files load in
-        * trunk with the correct modifier once its merged */
        eModifierType_Warp,
        NUM_MODIFIER_TYPES
 } ModifierType;
@@ -107,6 +105,17 @@ typedef enum {
        eSubsurfModifierFlag_SubsurfUv = (1<<3)
 } SubsurfModifierFlag;
 
+/* not a real modifier */
+typedef struct MappingInfoModifierData {
+       ModifierData modifier;
+
+       struct Tex *texture;
+       struct Object *map_object;
+       char uvlayer_name[32];
+       int uvlayer_tmp;
+       int texmapping;
+} MappingInfoModifierData;
+
 typedef struct SubsurfModifierData {
        ModifierData modifier;
 
@@ -292,15 +301,19 @@ typedef struct SmokeModifierData {
 typedef struct DisplaceModifierData {
        ModifierData modifier;
 
+       /* keep in sync with MappingInfoModifierData */
        struct Tex *texture;
+       struct Object *map_object;
+       char uvlayer_name[32];
+       int uvlayer_tmp;
+       int texmapping;
+       int pad10;
+       /* end MappingInfoModifierData */
+
        float strength;
        int direction;
        char defgrp_name[32];
        float midlevel;
-       int texmapping;
-       struct Object *map_object;
-       char uvlayer_name[32];
-       int uvlayer_tmp, pad;
 } DisplaceModifierData;
 
 /* DisplaceModifierData->direction */
@@ -733,5 +746,42 @@ typedef struct ScrewModifierData {
 #define MOD_SCREW_OBJECT_OFFSET        (1<<2)
 // #define MOD_SCREW_OBJECT_ANGLE      (1<<4)
 
+typedef struct WarpModifierData {
+       ModifierData modifier;
+
+       /* keep in sync with MappingInfoModifierData */
+       struct Tex *texture;
+       struct Object *map_object;
+       char uvlayer_name[32];
+       int uvlayer_tmp;
+       int texmapping;
+       int pad10;
+       /* end MappingInfoModifierData */
+
+       float strength;
+
+       struct Object *object_from;
+       struct Object *object_to;
+       struct CurveMapping *curfalloff;
+       char defgrp_name[32];                   /* optional vertexgroup name */
+       float falloff_radius;
+       char flag; /* not used yet */
+       char falloff_type;
+       char pad[2];
+} WarpModifierData;
+
+#define MOD_WARP_VOLUME_PRESERVE 1
+
+typedef enum {
+       eWarp_Falloff_None =            0,
+       eWarp_Falloff_Curve =           1,
+       eWarp_Falloff_Sharp =           2, /* PROP_SHARP */
+       eWarp_Falloff_Smooth =          3, /* PROP_SMOOTH */
+       eWarp_Falloff_Root =            4, /* PROP_ROOT */
+       eWarp_Falloff_Linear =          5, /* PROP_LIN */
+       eWarp_Falloff_Const =           6, /* PROP_CONST */
+       eWarp_Falloff_Sphere =          7, /* PROP_SPHERE */
+       /* PROP_RANDOM not used */
+} WarpModifierFalloff;
 
 #endif
index 2816a87..53af242 100644 (file)
@@ -559,6 +559,7 @@ extern StructRNA RNA_VertexPaint;
 extern StructRNA RNA_VoronoiTexture;
 extern StructRNA RNA_VoxelData;
 extern StructRNA RNA_VoxelDataTexture;
+extern StructRNA RNA_WarpModifier;
 extern StructRNA RNA_WaveModifier;
 extern StructRNA RNA_Window;
 extern StructRNA RNA_WindowManager;
index b58fa98..18a93b9 100644 (file)
@@ -79,6 +79,7 @@ EnumPropertyItem 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_Warp, "WARP", ICON_MOD_SUBSURF, "Warp", ""},
        {eModifierType_Wave, "WAVE", ICON_MOD_WAVE, "Wave", ""},
        {0, "", 0, "Simulate", ""},
        {eModifierType_Cloth, "CLOTH", ICON_MOD_CLOTH, "Cloth", ""},
@@ -180,6 +181,8 @@ static StructRNA* rna_Modifier_refine(struct PointerRNA *ptr)
                        return &RNA_SolidifyModifier;
                case eModifierType_Screw:
                        return &RNA_ScrewModifier;
+               case eModifierType_Warp:
+                       return &RNA_WarpModifier;
                default:
                        return &RNA_Modifier;
        }
@@ -372,10 +375,10 @@ static void rna_SolidifyModifier_vgroup_set(PointerRNA *ptr, const char *value)
        rna_object_vgroup_name_set(ptr, value, smd->defgrp_name, sizeof(smd->defgrp_name));
 }
 
-static void rna_DisplaceModifier_uvlayer_set(PointerRNA *ptr, const char *value)
+static void rna_MappingInfo_uvlayer_set(PointerRNA *ptr, const char *value)
 {
-       DisplaceModifierData *smd= (DisplaceModifierData*)ptr->data;
-       rna_object_uvlayer_name_set(ptr, value, smd->uvlayer_name, sizeof(smd->uvlayer_name));
+       MappingInfoModifierData *mmd= (MappingInfoModifierData *)ptr->data;
+       rna_object_uvlayer_name_set(ptr, value, mmd->uvlayer_name, sizeof(mmd->uvlayer_name));
 }
 
 static void rna_UVProjectModifier_uvlayer_set(PointerRNA *ptr, const char *value)
@@ -384,6 +387,12 @@ static void rna_UVProjectModifier_uvlayer_set(PointerRNA *ptr, const char *value
        rna_object_uvlayer_name_set(ptr, value, umd->uvlayer_name, sizeof(umd->uvlayer_name));
 }
 
+static void RNA_WarpModifier_vgroup_set(PointerRNA *ptr, const char *value)
+{
+       WarpModifierData *tmd= (WarpModifierData*)ptr->data;
+       rna_object_vgroup_name_set(ptr, value, tmd->defgrp_name, sizeof(tmd->defgrp_name));
+}
+
 static void rna_WaveModifier_uvlayer_set(PointerRNA *ptr, const char *value)
 {
        WaveModifierData *wmd= (WaveModifierData*)ptr->data;
@@ -619,6 +628,106 @@ static void rna_def_modifier_subsurf(BlenderRNA *brna)
        RNA_def_property_update(prop, 0, "rna_Modifier_update");
 }
 
+static void rna_def_modifier_generic_map_info(StructRNA *srna)
+{
+       static EnumPropertyItem prop_texture_coordinates_items[] = {
+               {MOD_DISP_MAP_LOCAL, "LOCAL", 0, "Map", ""},
+               {MOD_DISP_MAP_GLOBAL, "GLOBAL", 0, "Global", ""},
+               {MOD_DISP_MAP_OBJECT, "OBJECT", 0, "Object", ""},
+               {MOD_DISP_MAP_UV, "UV", 0, "UV", ""},
+               {0, NULL, 0, NULL, NULL}};
+
+       PropertyRNA *prop;
+
+       prop= RNA_def_property(srna, "texture", PROP_POINTER, PROP_NONE);
+       RNA_def_property_ui_text(prop, "Texture", "");
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+       prop= RNA_def_property(srna, "texture_coords", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "texmapping");
+       RNA_def_property_enum_items(prop, prop_texture_coordinates_items);
+       RNA_def_property_ui_text(prop, "Texture Coordinates", "");
+       RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+
+       prop= RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_sdna(prop, NULL, "uvlayer_name");
+       RNA_def_property_ui_text(prop, "UV Layer", "UV layer name");
+       RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MappingInfo_uvlayer_set");
+       RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+       prop= RNA_def_property(srna, "texture_coordinate_object", PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "map_object");
+       RNA_def_property_ui_text(prop, "Texture Coordinate Object", "");
+       RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_SELF_CHECK);
+       RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+}
+
+static void rna_def_modifier_warp(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       static EnumPropertyItem prop_falloff_items[] = {
+               {eWarp_Falloff_None,    "NONE", 0, "No Falloff", ""},
+               {eWarp_Falloff_Curve,   "CURVE", 0, "Curve", ""},
+               {eWarp_Falloff_Smooth,  "SMOOTH", ICON_SMOOTHCURVE, "Smooth", ""},
+               {eWarp_Falloff_Sphere,  "SPHERE", ICON_SPHERECURVE, "Sphere", ""},
+               {eWarp_Falloff_Root,    "ROOT", ICON_ROOTCURVE, "Root", ""},
+               {eWarp_Falloff_Sharp,   "SHARP", ICON_SHARPCURVE, "Sharp", ""},
+               {eWarp_Falloff_Linear,  "LINEAR", ICON_LINCURVE, "Linear", ""},
+               {eWarp_Falloff_Const,   "CONSTANT", ICON_NOCURVE, "Constant", ""},
+               {0, NULL, 0, NULL, NULL}};
+
+       srna= RNA_def_struct(brna, "WarpModifier", "Modifier");
+       RNA_def_struct_ui_text(srna, "Warp Modifier", "Warp modifier");
+       RNA_def_struct_sdna(srna, "WarpModifierData");
+       //RNA_def_struct_ui_icon(srna, ICON_MOD_SUBSURF);
+
+       prop= RNA_def_property(srna, "object_from", PROP_POINTER, PROP_NONE);
+       RNA_def_property_ui_text(prop, "From", "Object to transform from");
+       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, "object_to", PROP_POINTER, PROP_NONE);
+       RNA_def_property_ui_text(prop, "To", "Object to transform to");
+       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, "strength", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
+       RNA_def_property_ui_range(prop, -100, 100, 10, 2);
+       RNA_def_property_ui_text(prop, "Strength", "");
+       RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+       prop= RNA_def_property(srna, "falloff_type", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_items(prop, prop_falloff_items);
+       RNA_def_property_ui_text(prop, "Falloff Type", "");
+       RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+       prop= RNA_def_property(srna, "falloff_radius", PROP_FLOAT, PROP_UNSIGNED);
+       RNA_def_property_ui_text(prop, "Radius", "Radius to apply");
+       RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+       prop= RNA_def_property(srna, "falloff_curve", PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "curfalloff");
+       RNA_def_property_ui_text(prop, "Falloff Curve", "Custom Lamp Falloff Curve");
+       RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+       prop= RNA_def_property(srna, "use_volume_preserve", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_WARP_VOLUME_PRESERVE);
+       RNA_def_property_ui_text(prop, "Preserve Volume", "Preserve volume when rotations are used");
+       RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+       prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
+       RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for modulating the deform");
+       RNA_def_property_string_funcs(prop, NULL, NULL, "RNA_WarpModifier_vgroup_set");
+       RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+       rna_def_modifier_generic_map_info(srna);
+}
+
 static void rna_def_modifier_multires(BlenderRNA *brna)
 {
        StructRNA *srna;
@@ -1287,13 +1396,6 @@ static void rna_def_modifier_displace(BlenderRNA *brna)
                {MOD_DISP_DIR_RGB_XYZ, "RGB_TO_XYZ", 0, "RGB to XYZ", ""},
                {0, NULL, 0, NULL, NULL}};
 
-       static EnumPropertyItem prop_texture_coordinates_items[] = {
-               {MOD_DISP_MAP_LOCAL, "LOCAL", 0, "Map", ""},
-               {MOD_DISP_MAP_GLOBAL, "GLOBAL", 0, "Global", ""},
-               {MOD_DISP_MAP_OBJECT, "OBJECT", 0, "Object", ""},
-               {MOD_DISP_MAP_UV, "UV", 0, "UV", ""},
-               {0, NULL, 0, NULL, NULL}};
-
        srna= RNA_def_struct(brna, "DisplaceModifier", "Modifier");
        RNA_def_struct_ui_text(srna, "Displace Modifier", "Displacement modifier");
        RNA_def_struct_sdna(srna, "DisplaceModifierData");
@@ -1305,11 +1407,6 @@ static void rna_def_modifier_displace(BlenderRNA *brna)
        RNA_def_property_string_funcs(prop, NULL, NULL, "rna_DisplaceModifier_vgroup_set");
        RNA_def_property_update(prop, 0, "rna_Modifier_update");
 
-       prop= RNA_def_property(srna, "texture", PROP_POINTER, PROP_NONE);
-       RNA_def_property_ui_text(prop, "Texture", "");
-       RNA_def_property_flag(prop, PROP_EDITABLE);
-       RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
        prop= RNA_def_property(srna, "mid_level", PROP_FLOAT, PROP_DISTANCE);
        RNA_def_property_float_sdna(prop, NULL, "midlevel");
        RNA_def_property_range(prop, 0, 1);
@@ -1328,23 +1425,7 @@ static void rna_def_modifier_displace(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Direction", "");
        RNA_def_property_update(prop, 0, "rna_Modifier_update");
 
-       prop= RNA_def_property(srna, "texture_coords", PROP_ENUM, PROP_NONE);
-       RNA_def_property_enum_sdna(prop, NULL, "texmapping");
-       RNA_def_property_enum_items(prop, prop_texture_coordinates_items);
-       RNA_def_property_ui_text(prop, "Texture Coordinates", "");
-       RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
-
-       prop= RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE);
-       RNA_def_property_string_sdna(prop, NULL, "uvlayer_name");
-       RNA_def_property_ui_text(prop, "UV Layer", "UV layer name");
-       RNA_def_property_string_funcs(prop, NULL, NULL, "rna_DisplaceModifier_uvlayer_set");
-       RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
-       prop= RNA_def_property(srna, "texture_coordinate_object", PROP_POINTER, PROP_NONE);
-       RNA_def_property_pointer_sdna(prop, NULL, "map_object");
-       RNA_def_property_ui_text(prop, "Texture Coordinate Object", "");
-       RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_SELF_CHECK);
-       RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+       rna_def_modifier_generic_map_info(srna);
 }
 
 static void rna_def_modifier_uvproject(BlenderRNA *brna)
@@ -2375,6 +2456,7 @@ void RNA_def_modifier(BlenderRNA *brna)
        rna_def_modifier_fluidsim(brna);
        rna_def_modifier_mask(brna);
        rna_def_modifier_simpledeform(brna);
+       rna_def_modifier_warp(brna);
        rna_def_modifier_multires(brna);
        rna_def_modifier_surface(brna);
        rna_def_modifier_smoke(brna);
index c610a2f..7abcb33 100644 (file)
@@ -74,6 +74,7 @@ set(SRC
        intern/MOD_surface.c
        intern/MOD_util.c
        intern/MOD_uvproject.c
+       intern/MOD_warp.c
        intern/MOD_wave.c
 
        MOD_modifiertypes.h
index 8486e2b..4e44a22 100644 (file)
@@ -71,6 +71,7 @@ extern ModifierTypeInfo modifierType_Smoke;
 extern ModifierTypeInfo modifierType_ShapeKey;
 extern ModifierTypeInfo modifierType_Solidify;
 extern ModifierTypeInfo modifierType_Screw;
+extern ModifierTypeInfo modifierType_Warp;
 
 /* MOD_util.c */
 void modifier_type_init(ModifierTypeInfo *types[]);
index 7f887eb..3288c1b 100644 (file)
@@ -162,92 +162,6 @@ static void updateDepgraph(ModifierData *md, DagForest *forest,
        
 }
 
-static void get_texture_coords(DisplaceModifierData *dmd, Object *ob,
-                                  DerivedMesh *dm,
-         float (*co)[3], float (*texco)[3],
-                 int numVerts)
-{
-       int i;
-       int texmapping = dmd->texmapping;
-       float mapob_imat[4][4];
-
-       if(texmapping == MOD_DISP_MAP_OBJECT) {
-               if(dmd->map_object)
-                       invert_m4_m4(mapob_imat, dmd->map_object->obmat);
-               else /* if there is no map object, default to local */
-                       texmapping = MOD_DISP_MAP_LOCAL;
-       }
-
-       /* UVs need special handling, since they come from faces */
-       if(texmapping == MOD_DISP_MAP_UV) {
-               if(CustomData_has_layer(&dm->faceData, CD_MTFACE)) {
-                       MFace *mface = dm->getFaceArray(dm);
-                       MFace *mf;
-                       char *done = MEM_callocN(sizeof(*done) * numVerts,
-                                       "get_texture_coords done");
-                       int numFaces = dm->getNumFaces(dm);
-                       char uvname[32];
-                       MTFace *tf;
-
-                       validate_layer_name(&dm->faceData, CD_MTFACE, dmd->uvlayer_name, uvname);
-                       tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
-
-                       /* verts are given the UV from the first face that uses them */
-                       for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
-                               if(!done[mf->v1]) {
-                                       texco[mf->v1][0] = tf->uv[0][0];
-                                       texco[mf->v1][1] = tf->uv[0][1];
-                                       texco[mf->v1][2] = 0;
-                                       done[mf->v1] = 1;
-                               }
-                               if(!done[mf->v2]) {
-                                       texco[mf->v2][0] = tf->uv[1][0];
-                                       texco[mf->v2][1] = tf->uv[1][1];
-                                       texco[mf->v2][2] = 0;
-                                       done[mf->v2] = 1;
-                               }
-                               if(!done[mf->v3]) {
-                                       texco[mf->v3][0] = tf->uv[2][0];
-                                       texco[mf->v3][1] = tf->uv[2][1];
-                                       texco[mf->v3][2] = 0;
-                                       done[mf->v3] = 1;
-                               }
-                               if(!done[mf->v4]) {
-                                       texco[mf->v4][0] = tf->uv[3][0];
-                                       texco[mf->v4][1] = tf->uv[3][1];
-                                       texco[mf->v4][2] = 0;
-                                       done[mf->v4] = 1;
-                               }
-                       }
-
-                       /* remap UVs from [0, 1] to [-1, 1] */
-                       for(i = 0; i < numVerts; ++i) {
-                               texco[i][0] = texco[i][0] * 2 - 1;
-                               texco[i][1] = texco[i][1] * 2 - 1;
-                       }
-
-                       MEM_freeN(done);
-                       return;
-               } else /* if there are no UVs, default to local */
-                       texmapping = MOD_DISP_MAP_LOCAL;
-       }
-
-       for(i = 0; i < numVerts; ++i, ++co, ++texco) {
-               switch(texmapping) {
-                       case MOD_DISP_MAP_LOCAL:
-                               copy_v3_v3(*texco, *co);
-                               break;
-                       case MOD_DISP_MAP_GLOBAL:
-                               mul_v3_m4v3(*texco, ob->obmat, *co);
-                               break;
-                       case MOD_DISP_MAP_OBJECT:
-                               mul_v3_m4v3(*texco, ob->obmat, *co);
-                               mul_m4_v3(mapob_imat, *texco);
-                               break;
-               }
-       }
-}
-
 /* dm must be a CDDerivedMesh */
 static void displaceModifier_do(
                                DisplaceModifierData *dmd, Object *ob,
@@ -270,7 +184,7 @@ static void displaceModifier_do(
 
        tex_co = MEM_callocN(sizeof(*tex_co) * numVerts,
                                 "displaceModifier_do tex_co");
-       get_texture_coords(dmd, ob, dm, vertexCos, tex_co, numVerts);
+       get_texture_coords((MappingInfoModifierData *)dmd, ob, dm, vertexCos, tex_co, numVerts);
 
        for(i = 0; i < numVerts; ++i) {
                TexResult texres;
index 8c94e6f..9fe37e2 100644 (file)
 #include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 #include "DNA_curve_types.h"
+#include "DNA_meshdata_types.h"
 
 #include "BLI_utildefines.h"
+#include "BLI_math_vector.h"
+#include "BLI_math_matrix.h"
 
 #include "BKE_cdderivedmesh.h"
 #include "BKE_mesh.h"
@@ -74,6 +77,92 @@ void get_texture_value(Tex *texture, float *tex_co, TexResult *texres)
                texres->tr = texres->tg = texres->tb = texres->tin;
 }
 
+void get_texture_coords(MappingInfoModifierData *dmd, Object *ob,
+                        DerivedMesh *dm,
+                        float (*co)[3], float (*texco)[3],
+                        int numVerts)
+{
+       int i;
+       int texmapping = dmd->texmapping;
+       float mapob_imat[4][4];
+
+       if(texmapping == MOD_DISP_MAP_OBJECT) {
+               if(dmd->map_object)
+                       invert_m4_m4(mapob_imat, dmd->map_object->obmat);
+               else /* if there is no map object, default to local */
+                       texmapping = MOD_DISP_MAP_LOCAL;
+       }
+
+       /* UVs need special handling, since they come from faces */
+       if(texmapping == MOD_DISP_MAP_UV) {
+               if(CustomData_has_layer(&dm->faceData, CD_MTFACE)) {
+                       MFace *mface = dm->getFaceArray(dm);
+                       MFace *mf;
+                       char *done = MEM_callocN(sizeof(*done) * numVerts,
+                                                "get_texture_coords done");
+                       int numFaces = dm->getNumFaces(dm);
+                       char uvname[32];
+                       MTFace *tf;
+
+                       validate_layer_name(&dm->faceData, CD_MTFACE, dmd->uvlayer_name, uvname);
+                       tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
+
+                       /* verts are given the UV from the first face that uses them */
+                       for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
+                               if(!done[mf->v1]) {
+                                       texco[mf->v1][0] = tf->uv[0][0];
+                                       texco[mf->v1][1] = tf->uv[0][1];
+                                       texco[mf->v1][2] = 0;
+                                       done[mf->v1] = 1;
+                               }
+                               if(!done[mf->v2]) {
+                                       texco[mf->v2][0] = tf->uv[1][0];
+                                       texco[mf->v2][1] = tf->uv[1][1];
+                                       texco[mf->v2][2] = 0;
+                                       done[mf->v2] = 1;
+                               }
+                               if(!done[mf->v3]) {
+                                       texco[mf->v3][0] = tf->uv[2][0];
+                                       texco[mf->v3][1] = tf->uv[2][1];
+                                       texco[mf->v3][2] = 0;
+                                       done[mf->v3] = 1;
+                               }
+                               if(!done[mf->v4]) {
+                                       texco[mf->v4][0] = tf->uv[3][0];
+                                       texco[mf->v4][1] = tf->uv[3][1];
+                                       texco[mf->v4][2] = 0;
+                                       done[mf->v4] = 1;
+                               }
+                       }
+
+                       /* remap UVs from [0, 1] to [-1, 1] */
+                       for(i = 0; i < numVerts; ++i) {
+                               texco[i][0] = texco[i][0] * 2 - 1;
+                               texco[i][1] = texco[i][1] * 2 - 1;
+                       }
+
+                       MEM_freeN(done);
+                       return;
+               } else /* if there are no UVs, default to local */
+                       texmapping = MOD_DISP_MAP_LOCAL;
+       }
+
+       for(i = 0; i < numVerts; ++i, ++co, ++texco) {
+               switch(texmapping) {
+               case MOD_DISP_MAP_LOCAL:
+                       copy_v3_v3(*texco, *co);
+                       break;
+               case MOD_DISP_MAP_GLOBAL:
+                       mul_v3_m4v3(*texco, ob->obmat, *co);
+                       break;
+               case MOD_DISP_MAP_OBJECT:
+                       mul_v3_m4v3(*texco, ob->obmat, *co);
+                       mul_m4_v3(mapob_imat, *texco);
+                       break;
+               }
+       }
+}
+
 void modifier_vgroup_cache(ModifierData *md, float (*vertexCos)[3])
 {
        while((md=md->next) && md->type==eModifierType_Armature) {
@@ -189,5 +278,6 @@ void modifier_type_init(ModifierTypeInfo *types[])
        INIT_TYPE(ShapeKey);
        INIT_TYPE(Solidify);
        INIT_TYPE(Screw);
+       INIT_TYPE(Warp);
 #undef INIT_TYPE
 }
index a421519..b786240 100644 (file)
@@ -46,6 +46,7 @@ struct EditMesh;
 struct ModifierData;
 
 void get_texture_value(struct Tex *texture, float *tex_co, struct TexResult *texres);
+void get_texture_coords(struct MappingInfoModifierData *dmd, struct Object *ob, struct DerivedMesh *dm, float (*co)[3], float (*texco)[3], int numVerts);
 void modifier_vgroup_cache(struct ModifierData *md, float (*vertexCos)[3]);
 void validate_layer_name(const struct CustomData *data, int type, char *name, char *outname);
 struct DerivedMesh *get_cddm(struct Object *ob, struct EditMesh *em, struct DerivedMesh *dm, float (*vertexCos)[3]);
diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c
new file mode 100644 (file)
index 0000000..44eea3f
--- /dev/null
@@ -0,0 +1,359 @@
+/*
+* $Id:
+*
+* ***** BEGIN GPL 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.
+*
+* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* Contributor(s): Campbell Barton
+*
+* ***** END GPL LICENSE BLOCK *****
+*
+*/
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_cdderivedmesh.h"
+#include "BKE_modifier.h"
+#include "BKE_deform.h"
+#include "BKE_texture.h"
+#include "BKE_colortools.h"
+
+#include "DNA_object_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "depsgraph_private.h"
+
+#include "RE_shader_ext.h"
+
+#include "MOD_util.h"
+
+
+static void initData(ModifierData *md)
+{
+       WarpModifierData *wmd = (WarpModifierData*) md;
+
+       wmd->curfalloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
+       wmd->texture = NULL;
+       wmd->strength = 1.0f;
+       wmd->falloff_radius = 1.0f;
+       wmd->falloff_type = eWarp_Falloff_Smooth;
+       wmd->flag = 0;
+}
+
+static void copyData(ModifierData *md, ModifierData *target)
+{
+       WarpModifierData *wmd = (WarpModifierData*) md;
+       WarpModifierData *twmd = (WarpModifierData*) target;
+
+       twmd->object_from = wmd->object_from;
+       twmd->object_to = wmd->object_to;
+
+       twmd->strength = wmd->strength;
+       twmd->falloff_radius = wmd->falloff_radius;
+       twmd->falloff_type = wmd->falloff_type;
+       strncpy(twmd->defgrp_name, wmd->defgrp_name, sizeof(twmd->defgrp_name));
+       twmd->curfalloff = curvemapping_copy(wmd->curfalloff);
+
+       /* map info */
+       twmd->texture = wmd->texture;
+       twmd->map_object = wmd->map_object;
+       strncpy(twmd->uvlayer_name, wmd->uvlayer_name, sizeof(twmd->uvlayer_name));
+       twmd->texmapping= wmd->texmapping;
+}
+
+static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
+{
+       WarpModifierData *wmd = (WarpModifierData *)md;
+       CustomDataMask dataMask = 0;
+
+       /* ask for vertexgroups if we need them */
+       if(wmd->defgrp_name[0]) dataMask |= (1 << CD_MDEFORMVERT);
+       dataMask |= (1 << CD_MDEFORMVERT);
+
+       /* ask for UV coordinates if we need them */
+       if(wmd->texmapping == MOD_DISP_MAP_UV) dataMask |= (1 << CD_MTFACE);
+
+       return dataMask;
+}
+
+static int dependsOnTime(ModifierData *md)
+{
+       WarpModifierData *wmd = (WarpModifierData *)md;
+
+       if(wmd->texture) {
+               return BKE_texture_dependsOnTime(wmd->texture);
+       }
+       else {
+               return 0;
+       }
+}
+
+static void freeData(ModifierData *md)
+{
+       WarpModifierData *wmd = (WarpModifierData *) md;
+       curvemapping_free(wmd->curfalloff);
+}
+
+
+static int isDisabled(ModifierData *md, int UNUSED(userRenderParams))
+{
+       WarpModifierData *wmd = (WarpModifierData*) md;
+
+       return !(wmd->object_from && wmd->object_to);
+}
+
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+{
+       WarpModifierData *wmd = (WarpModifierData*) md;
+
+       walk(userData, ob, &wmd->object_from);
+       walk(userData, ob, &wmd->object_to);
+       walk(userData, ob, &wmd->map_object);
+}
+
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
+{
+       WarpModifierData *wmd = (WarpModifierData*) md;
+
+       walk(userData, ob, (ID **)&wmd->texture);
+
+       walk(userData, ob, (ID **)&wmd->object_from);
+       walk(userData, ob, (ID **)&wmd->object_to);
+       walk(userData, ob, (ID **)&wmd->map_object);
+}
+
+static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UNUSED(scene),
+                           Object *UNUSED(ob), DagNode *obNode)
+{
+       WarpModifierData *wmd = (WarpModifierData*) md;
+
+       if(wmd->object_from && wmd->object_to) {
+               DagNode *fromNode = dag_get_node(forest, wmd->object_from);
+               DagNode *toNode = dag_get_node(forest, wmd->object_to);
+
+               dag_add_relation(forest, fromNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Warp Modifier1");
+               dag_add_relation(forest, toNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Warp Modifier2");
+       }
+
+       if((wmd->texmapping == MOD_DISP_MAP_OBJECT) && wmd->map_object) {
+               DagNode *curNode = dag_get_node(forest, wmd->map_object);
+               dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Warp Modifier3");
+       }
+}
+
+static void warpModifier_do(WarpModifierData *wmd, Object *ob,
+                            DerivedMesh *dm, float (*vertexCos)[3], int numVerts)
+{
+       float obinv[4][4];
+       float mat_from[4][4];
+       float mat_from_inv[4][4];
+       float mat_to[4][4];
+       float mat_unit[4][4];
+       float mat_final[4][4];
+
+       float tmat[4][4];
+
+       float strength = wmd->strength;
+       float fac = 1.0f, weight;
+       int i;
+       int defgrp_index = defgroup_name_index(ob, wmd->defgrp_name);
+       MDeformVert *dv= NULL;
+
+       float (*tex_co)[3]= NULL;
+
+       if(!(wmd->object_from && wmd->object_to))
+               return;
+
+       if(wmd->curfalloff==NULL) /* should never happen, but bad lib linking could cause it */
+               wmd->curfalloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
+
+       invert_m4_m4(obinv, ob->obmat);
+
+       mul_m4_m4m4(mat_from, wmd->object_from->obmat, obinv);
+       mul_m4_m4m4(mat_to, wmd->object_to->obmat, obinv);
+
+       invert_m4_m4(tmat, mat_from); // swap?
+       mul_m4_m4m4(mat_final, mat_to, tmat);
+
+       invert_m4_m4(mat_from_inv, mat_from);
+
+       unit_m4(mat_unit);
+
+       if(strength < 0.0f) {
+               strength = -strength;
+               invert_m4(mat_final);
+       }
+       weight= strength;
+
+       if(wmd->texture) {
+               tex_co = MEM_mallocN(sizeof(*tex_co) * numVerts, "warpModifier_do tex_co");
+               get_texture_coords((MappingInfoModifierData *)wmd, ob, dm, vertexCos, tex_co, numVerts);
+       }
+
+       for(i = 0; i < numVerts; i++) {
+               float *co = vertexCos[i];
+
+               if(wmd->falloff_type==eWarp_Falloff_None ||
+                       ((fac=len_v3v3(co, mat_from[3])) < wmd->falloff_radius && (fac=(wmd->falloff_radius-fac)/wmd->falloff_radius)) ) {
+
+                       /* skip if no vert group found */
+                       if(defgrp_index >= 0) {
+                               dv = dm->getVertData(dm, i, CD_MDEFORMVERT);
+
+                               if(dv) {
+                                       weight = defvert_find_weight(dv, defgrp_index) * wmd->strength;
+                                       if(weight <= 0.0f)
+                                               continue;
+                               }
+                       }
+
+
+                       /* closely match PROP_SMOOTH and similar */
+                       switch(wmd->falloff_type) {
+                       case eWarp_Falloff_None:
+                               fac = 1.0f;
+                               break;
+                       case eWarp_Falloff_Curve:
+                               fac = curvemapping_evaluateF(wmd->curfalloff, 0, fac);
+                               break;
+                       case eWarp_Falloff_Sharp:
+                               fac = fac*fac;
+                               break;
+                       case eWarp_Falloff_Smooth:
+                               fac = 3.0f*fac*fac - 2.0f*fac*fac*fac;
+                               break;
+                       case eWarp_Falloff_Root:
+                               fac = (float)sqrt(fac);
+                               break;
+                       case eWarp_Falloff_Linear:
+                               /* pass */
+                               break;
+                       case eWarp_Falloff_Const:
+                               fac = 1.0f;
+                               break;
+                       case eWarp_Falloff_Sphere:
+                               fac = (float)sqrt(2*fac - fac * fac);
+                               break;
+                       }
+
+                       fac *= weight;
+
+                       if(tex_co) {
+                               TexResult texres;
+                               texres.nor = NULL;
+                               get_texture_value(wmd->texture, tex_co[i], &texres);
+                               fac *= texres.tin;
+                       }
+
+                       /* into the 'from' objects space */
+                       mul_m4_v3(mat_from_inv, co);
+
+                       if(fac >= 1.0f) {
+                               mul_m4_v3(mat_final, co);
+                       }
+                       else if(fac > 0.0f) {
+                               if(wmd->flag & MOD_WARP_VOLUME_PRESERVE) {
+                                       /* interpolate the matrix for nicer locations */
+                                       blend_m4_m4m4(tmat, mat_unit, mat_final, fac);
+                                       mul_m4_v3(tmat, co);
+                               }
+                               else {
+                                       float tvec[3];
+                                       mul_v3_m4v3(tvec, mat_final, co);
+                                       interp_v3_v3v3(co, co, tvec, fac);
+                               }
+                       }
+
+                       /* out of the 'from' objects space */
+                       mul_m4_v3(mat_from, co);
+               }
+       }
+
+       if(tex_co)
+               MEM_freeN(tex_co);
+
+}
+
+static int warp_needs_dm(WarpModifierData *wmd)
+{
+       return wmd->texture || wmd->defgrp_name[0];
+}
+
+static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData,
+                        float (*vertexCos)[3], int numVerts, int UNUSED(useRenderParams), int UNUSED(isFinalCalc))
+{
+       DerivedMesh *dm= NULL;
+       int use_dm= warp_needs_dm((WarpModifierData *)md);
+
+       if(use_dm) {
+               dm= get_cddm(ob, NULL, derivedData, vertexCos);
+       }
+
+       warpModifier_do((WarpModifierData *)md, ob, dm, vertexCos, numVerts);
+
+       if(use_dm) {
+               if(dm != derivedData) dm->release(dm);
+       }
+}
+
+static void deformVertsEM(ModifierData *md, Object *ob, struct EditMesh *editData,
+                          DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
+{
+       DerivedMesh *dm = derivedData;
+       int use_dm= warp_needs_dm((WarpModifierData *)md);
+
+       if(use_dm) {
+               if(!derivedData)
+                       dm = CDDM_from_editmesh(editData, ob->data);
+       }
+
+       deformVerts(md, ob, dm, vertexCos, numVerts, 0, 0);
+
+       if(use_dm) {
+               if(!derivedData) dm->release(dm);
+       }
+}
+
+
+ModifierTypeInfo modifierType_Warp = {
+       /* name */              "Warp",
+       /* structName */        "WarpModifierData",
+       /* structSize */        sizeof(WarpModifierData),
+       /* type */              eModifierTypeType_OnlyDeform,
+       /* flags */             eModifierTypeFlag_AcceptsCVs
+                                                       | eModifierTypeFlag_SupportsEditmode,
+       /* copyData */          copyData,
+       /* deformVerts */       deformVerts,
+       /* deformMatrices */    NULL,
+       /* deformVertsEM */     deformVertsEM,
+    /* deformMatricesEM */  NULL,
+       /* applyModifier */     0,
+       /* applyModifierEM */   0,
+       /* initData */          initData,
+       /* requiredDataMask */  requiredDataMask,
+       /* freeData */          freeData,
+       /* isDisabled */        isDisabled,
+       /* updateDepgraph */    updateDepgraph,
+       /* dependsOnTime */     dependsOnTime,
+    /* dependsOnNormals */     NULL,
+       /* foreachObjectLink */ foreachObjectLink,
+       /* foreachIDLink */     foreachIDLink,
+};