Index: release/scripts/startup/bl_ui/properties_data_modifier.py =================================================================== --- release/scripts/startup/bl_ui/properties_data_modifier.py (wersja 46620) +++ release/scripts/startup/bl_ui/properties_data_modifier.py (kopia robocza) @@ -957,5 +957,31 @@ layout.separator() self.vertex_weight_mask(layout, ob, md) + # pkowal + def UV_OFFSET(self, layout, ob, md): + split = layout.split() + col = split.column() + col.prop(md, "offset", text="Add these coordinates to UVs"); + + split = layout.split() + col = split.column() + col.label(text="Controller:") + col.prop(md, "controller", text="") + + col = split.column() + col.label(text="Bone:") + if md.controller and md.controller.type == 'ARMATURE': + col.prop_search(md, "bone", md.controller.data, "bones", text="") + + split = layout.split() + + col = split.column() + col.label(text="Vertex Group:") + col.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + + col = split.column() + col.label(text="UV Map:") + col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="") + if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) Index: source/blender/modifiers/MOD_modifiertypes.h =================================================================== --- source/blender/modifiers/MOD_modifiertypes.h (wersja 46620) +++ source/blender/modifiers/MOD_modifiertypes.h (kopia robocza) @@ -74,6 +74,8 @@ extern ModifierTypeInfo modifierType_WeightVGProximity; extern ModifierTypeInfo modifierType_DynamicPaint; extern ModifierTypeInfo modifierType_Remesh; +/* pkowal */ +extern ModifierTypeInfo modifierType_UVOffset; /* MOD_util.c */ void modifier_type_init(ModifierTypeInfo *types[]); Index: source/blender/modifiers/CMakeLists.txt =================================================================== --- source/blender/modifiers/CMakeLists.txt (wersja 46620) +++ source/blender/modifiers/CMakeLists.txt (kopia robocza) @@ -91,6 +91,8 @@ intern/MOD_weightvgedit.c intern/MOD_weightvgmix.c intern/MOD_weightvgproximity.c +# pkowal + intern/MOD_uvoffset.c MOD_modifiertypes.h intern/MOD_boolean_util.h Index: source/blender/modifiers/intern/MOD_util.c =================================================================== --- source/blender/modifiers/intern/MOD_util.c (wersja 46620) +++ source/blender/modifiers/intern/MOD_util.c (kopia robocza) @@ -276,5 +276,7 @@ INIT_TYPE(WeightVGProximity); INIT_TYPE(DynamicPaint); INIT_TYPE(Remesh); +/* pkowal */ + INIT_TYPE(UVOffset); #undef INIT_TYPE } Index: source/blender/modifiers/intern/MOD_uvoffset.c =================================================================== --- source/blender/modifiers/intern/MOD_uvoffset.c (wersja 0) +++ source/blender/modifiers/intern/MOD_uvoffset.c (wersja 0) @@ -0,0 +1,239 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2005 by the Blender Foundation. + * All rights reserved. + * + * Contributor(s): Pawel Kowal + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_uvoffset.c + * \ingroup modifiers + */ + + +#include + +#include "DNA_action_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" + +#include "BLI_math.h" +#include "BLI_string.h" +#include "BLI_utildefines.h" + +#include "BKE_action.h" +#include "BKE_cdderivedmesh.h" +#include "BKE_deform.h" +#include "BKE_modifier.h" + +#include "depsgraph_private.h" + +#include "MOD_util.h" + + +static void uv_offset_from_mat4_pair(float uv[2], float mat_src[4][4], float mat_dst[4][4], + int axis_u, int axis_v) +{ + float imat_src[4][4]; + float tmat[4][4]; + invert_m4_m4(imat_src, mat_src); + + mult_m4_m4m4(tmat, imat_src, mat_dst); + + uv[0] = tmat[3][axis_u]; + uv[1] = tmat[3][axis_v]; +} + +static void initData(ModifierData *md) +{ + UVOffsetModifierData *umd = (UVOffsetModifierData *) md; + umd->controller = NULL; + zero_v2(umd->offset); +} + +static void copyData(ModifierData *md, ModifierData *target) +{ + UVOffsetModifierData *umd = (UVOffsetModifierData *)md; + UVOffsetModifierData *tumd = (UVOffsetModifierData *)target; + + copy_v2_v2(tumd->offset, umd->offset); + tumd->controller = umd->controller; + BLI_strncpy(tumd->bone, umd->bone, sizeof(tumd->bone)); + BLI_strncpy(tumd->vgroup_name, umd->vgroup_name, sizeof(tumd->vgroup_name)); + BLI_strncpy(tumd->uvlayer_name, umd->uvlayer_name, sizeof(umd->uvlayer_name)); +} + +static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) +{ + UVOffsetModifierData *umd = (UVOffsetModifierData *)md; + CustomDataMask dataMask = 0; + + /* ask for vertexgroups if we need them */ + if (umd->vgroup_name[0]) + dataMask |= CD_MASK_MDEFORMVERT; + + return dataMask; +} + +static DerivedMesh *uvoffsetModifier_do(UVOffsetModifierData *umd, Object *ob, DerivedMesh *dm) +{ + int i, l, numPolys, numLoops; + MPoly *mpoly, *mp; + MLoop *mloop, *ml; + MLoopUV *mloopuv, *mluv; + MDeformVert *dvert; + int defgrp_index; + char uvname[MAX_CUSTOMDATA_LAYER_NAME]; + float weight = 1.0f; + float uv[2] = {0.0f, 0.0f}; + float uv_weighted[2]; + float mat_dst[4][4]; + + /* make sure there are UV Maps available */ + if (!CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) { + return dm; + } + + /* make sure anything moving UVs is available */ + if (umd->controller) { + bPoseChannel *pchan = BKE_pose_channel_find_name(umd->controller->pose, umd->bone); + if (pchan) { + copy_v2_v2(uv, pchan->loc); + } + else { + copy_m4_m4(mat_dst, umd->controller->obmat); + uv_offset_from_mat4_pair(uv, ob->obmat, mat_dst, 0, 1); + } + } + else { + copy_m4_m4(mat_dst, ob->obmat); + uv_offset_from_mat4_pair(uv, ob->obmat, mat_dst, 0, 1); + } + + add_v2_v2(uv, umd->offset); + + /* no offset no problem */ + if (is_zero_v2(uv)) { + return dm; + } + + /* make sure we're using an existing layer */ + CustomData_validate_layer_name(&dm->loopData, CD_MLOOPUV, umd->uvlayer_name, uvname); + + numPolys = dm->getNumPolys(dm); + numLoops = dm->getNumLoops(dm); + + mpoly = dm->getPolyArray(dm); + mloop = dm->getLoopArray(dm); + /* make sure we are not modifying the original UV map */ + mloopuv = CustomData_duplicate_referenced_layer_named(&dm->loopData, CD_MLOOPUV, uvname, numLoops); + modifier_get_vgroup(ob, dm, umd->vgroup_name, &dvert, &defgrp_index); + + for (i = 0, mp = mpoly; i < numPolys; i++, mp++) { + ml = &mloop[mp->loopstart]; + mluv = &mloopuv[mp->loopstart]; + for (l = 0; l < mp->totloop; l++, ml++, mluv++) { + if (dvert) { + copy_v2_v2(uv_weighted, uv); + weight = defvert_find_weight(&dvert[ml->v], defgrp_index); + mul_v2_fl(uv_weighted, weight); + add_v2_v2(mluv->uv, uv_weighted); + } + else { + add_v2_v2(mluv->uv, uv); + } + } + } + + dm->dirty |= DM_DIRTY_TESS_CDLAYERS; + + return dm; +} + +static DerivedMesh *applyModifier(ModifierData *md, Object *ob, + DerivedMesh *derivedData, + ModifierApplyFlag flag) +{ + DerivedMesh *result; + UVOffsetModifierData *umd = (UVOffsetModifierData *) md; + + result = uvoffsetModifier_do(umd, ob, derivedData); + + return result; +} + +static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, + struct BMEditMesh *UNUSED(editData), + DerivedMesh *derivedData) +{ + return applyModifier(md, ob, derivedData, MOD_APPLY_USECACHE); +} + +static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData) +{ + UVOffsetModifierData *umd = (UVOffsetModifierData *) md; + + walk(userData, ob, &umd->controller); +} + +static void updateDepgraph(ModifierData *md, DagForest *forest, + struct Scene *UNUSED(scene), + Object *UNUSED(ob), + DagNode *obNode) +{ + UVOffsetModifierData *umd = (UVOffsetModifierData *) md; + + if (umd->controller) { + DagNode *curNode = dag_get_node(forest, umd->controller); + + if (umd->bone[0]) + dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "UVOffset Modifier"); + else + dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA, "UVOffset Modifier"); + } +} + +ModifierTypeInfo modifierType_UVOffset = { + /* name */ "UVOffset", + /* structName */ "UVOffsetModifierData", + /* structSize */ sizeof(UVOffsetModifierData), + /* type */ eModifierTypeType_NonGeometrical, + /* flags */ eModifierTypeFlag_AcceptsMesh | + eModifierTypeFlag_SupportsEditmode | + eModifierTypeFlag_EnableInEditmode, + /* copyData */ copyData, + /* deformVerts */ NULL, + /* deformMatrices */ NULL, + /* deformVertsEM */ NULL, + /* deformMatricesEM */ NULL, + /* applyModifier */ applyModifier, + /* applyModifierEM */ applyModifierEM, + /* initData */ initData, + /* requiredDataMask */ requiredDataMask, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepgraph */ updateDepgraph, + /* dependsOnTime */ NULL, + /* dependsOnNormals */ NULL, + /* foreachObjectLink */ foreachObjectLink, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; Index: source/blender/makesdna/DNA_modifier_types.h =================================================================== --- source/blender/makesdna/DNA_modifier_types.h (wersja 46620) +++ source/blender/makesdna/DNA_modifier_types.h (kopia robocza) @@ -77,6 +77,7 @@ eModifierType_Ocean, eModifierType_DynamicPaint, eModifierType_Remesh, + eModifierType_UVOffset, NUM_MODIFIER_TYPES } ModifierType; @@ -1063,4 +1064,16 @@ char pad; } RemeshModifierData; +/* pkowal */ +typedef struct UVOffsetModifierData { + ModifierData modifier; + /* modifier-specific data goes here; remember to add pad if necessary! */ + + float offset[2]; /* horizontal and vertical offset */ + struct Object *controller; /* controller */ + char bone[64]; /* optional name of bone controller, MAX_ID_NAME-2 */ + char vgroup_name[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */ + char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ +} UVOffsetModifierData; + #endif Index: source/blender/makesrna/intern/rna_modifier.c =================================================================== --- source/blender/makesrna/intern/rna_modifier.c (wersja 46620) +++ source/blender/makesrna/intern/rna_modifier.c (kopia robocza) @@ -59,6 +59,7 @@ EnumPropertyItem modifier_type_items[] = { {0, "", 0, N_("Modify"), ""}, {eModifierType_UVProject, "UV_PROJECT", ICON_MOD_UVPROJECT, "UV Project", ""}, + {eModifierType_UVOffset, "UV_OFFSET", ICON_MOD_UVPROJECT, "UV Offset", ""}, {eModifierType_WeightVGEdit, "VERTEX_WEIGHT_EDIT", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Edit", ""}, {eModifierType_WeightVGMix, "VERTEX_WEIGHT_MIX", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Mix", ""}, {eModifierType_WeightVGProximity, "VERTEX_WEIGHT_PROXIMITY", ICON_MOD_VERTEX_WEIGHT, @@ -207,6 +208,9 @@ return &RNA_DynamicPaintModifier; case eModifierType_Remesh: return &RNA_RemeshModifier; +/* pkowal */ + case eModifierType_UVOffset: + return &RNA_UVOffsetModifier; default: return &RNA_Modifier; } @@ -734,6 +738,19 @@ md->bevel_angle = (int)value; } +/* pkowal */ +static void rna_UVOffsetModifier_vgroup_set(PointerRNA *ptr, const char *value) +{ + UVOffsetModifierData *umd= (UVOffsetModifierData*)ptr->data; + rna_object_vgroup_name_set(ptr, value, umd->vgroup_name, sizeof(umd->vgroup_name)); +} + +static void rna_UVOffsetModifier_uvlayer_set(PointerRNA *ptr, const char *value) +{ + UVOffsetModifierData *umd= (UVOffsetModifierData*)ptr->data; + rna_object_uvlayer_name_set(ptr, value, umd->uvlayer_name, sizeof(umd->uvlayer_name)); +} + #else static void rna_def_property_subdivision_common(StructRNA *srna, const char type[]) @@ -2635,6 +2652,45 @@ #endif } +/* pkowal */ +static void rna_def_modifier_uvoffset(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "UVOffsetModifier", "Modifier"); + RNA_def_struct_ui_text(srna, "UVOffset Modifier", "Add target position to uv coordinates"); + RNA_def_struct_sdna(srna, "UVOffsetModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_UVPROJECT); + + prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_float_sdna(prop, NULL, "offset"); + RNA_def_property_ui_text(prop, "Constant Offset", "Add these coordinates to UVs"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "controller", PROP_POINTER, PROP_NONE); + RNA_def_property_ui_text(prop, "Controller", "Object defining offset"); + 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, "bone", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "bone"); + RNA_def_property_ui_text(prop, "Bone", "Bone defining offset"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); + + prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "vgroup_name"); + RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_UVOffsetModifier_vgroup_set"); + RNA_def_property_update(prop, 0, "rna_Modifier_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_UVOffsetModifier_uvlayer_set"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); +} + static void rna_def_modifier_weightvg_mask(BlenderRNA *brna, StructRNA *srna) { static EnumPropertyItem weightvg_mask_tex_map_items[] = { @@ -3291,6 +3347,7 @@ rna_def_modifier_dynamic_paint(brna); rna_def_modifier_ocean(brna); rna_def_modifier_remesh(brna); + rna_def_modifier_uvoffset(brna); } #endif Index: source/blender/makesrna/RNA_access.h =================================================================== --- source/blender/makesrna/RNA_access.h (wersja 46620) +++ source/blender/makesrna/RNA_access.h (kopia robocza) @@ -574,6 +574,8 @@ extern StructRNA RNA_TransformSequence; extern StructRNA RNA_UILayout; extern StructRNA RNA_UIListItem; +/* pkowal */ +extern StructRNA RNA_UVOffsetModifier; extern StructRNA RNA_UVProjectModifier; extern StructRNA RNA_UVProjector; extern StructRNA RNA_UnitSettings;