diff options
Diffstat (limited to 'source/blender/modifiers')
-rw-r--r-- | source/blender/modifiers/CMakeLists.txt | 5 | ||||
-rw-r--r-- | source/blender/modifiers/MOD_modifiertypes.h | 1 | ||||
-rw-r--r-- | source/blender/modifiers/SConscript | 28 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_boolean_util.c | 6 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_decimate.c | 4 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_edgesplit.c | 28 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_fluidsim_util.c | 2 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_util.c | 1 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_uvwarp.c | 268 |
9 files changed, 316 insertions, 27 deletions
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index cf3bb05849a..33209095164 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -64,8 +64,8 @@ set(SRC intern/MOD_fluidsim.c intern/MOD_fluidsim_util.c intern/MOD_hook.c - intern/MOD_lattice.c intern/MOD_laplaciansmooth.c + intern/MOD_lattice.c intern/MOD_mask.c intern/MOD_meshdeform.c intern/MOD_mirror.c @@ -86,7 +86,9 @@ set(SRC intern/MOD_solidify.c intern/MOD_subsurf.c intern/MOD_surface.c + intern/MOD_triangulate.c intern/MOD_util.c + intern/MOD_uvwarp.c intern/MOD_uvproject.c intern/MOD_warp.c intern/MOD_wave.c @@ -94,7 +96,6 @@ set(SRC intern/MOD_weightvgedit.c intern/MOD_weightvgmix.c intern/MOD_weightvgproximity.c - intern/MOD_triangulate.c MOD_modifiertypes.h intern/MOD_boolean_util.h diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h index 290ba193567..17e903e9ebb 100644 --- a/source/blender/modifiers/MOD_modifiertypes.h +++ b/source/blender/modifiers/MOD_modifiertypes.h @@ -77,6 +77,7 @@ extern ModifierTypeInfo modifierType_Remesh; extern ModifierTypeInfo modifierType_Skin; extern ModifierTypeInfo modifierType_LaplacianSmooth; extern ModifierTypeInfo modifierType_Triangulate; +extern ModifierTypeInfo modifierType_UVWarp; /* MOD_util.c */ void modifier_type_init(ModifierTypeInfo *types[]); diff --git a/source/blender/modifiers/SConscript b/source/blender/modifiers/SConscript index 62fd9ba2de1..d3430c6a4d5 100644 --- a/source/blender/modifiers/SConscript +++ b/source/blender/modifiers/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/*.c') diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c index 2ff93532d14..0cf4f6a008f 100644 --- a/source/blender/modifiers/intern/MOD_boolean_util.c +++ b/source/blender/modifiers/intern/MOD_boolean_util.c @@ -305,7 +305,7 @@ static Object *AddNewBlenderMesh(Scene *scene, Base *base) static void InterpCSGFace( DerivedMesh *dm, DerivedMesh *orig_dm, int index, int orig_index, int nr, - float mapmat[][4]) + float mapmat[4][4]) { float obco[3], *co[4], *orig_co[4], w[4][4]; MFace *mface, *orig_mface; @@ -344,8 +344,8 @@ static void InterpCSGFace( static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh( CSG_FaceIteratorDescriptor *face_it, CSG_VertexIteratorDescriptor *vertex_it, - float parinv[][4], - float mapmat[][4], + float parinv[4][4], + float mapmat[4][4], Material **mat, int *totmat, DerivedMesh *dm1, diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index 28cdfa810fa..a23b677f8e6 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -188,7 +188,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* update for display only */ dmd->face_count = bm->totface; result = CDDM_from_bmesh(bm, FALSE); - BLI_assert(bm->toolflagpool == NULL); /* make sure we never alloc'd this */ + BLI_assert(bm->vtoolflagpool == NULL); /* make sure we never alloc'd this */ + BLI_assert(bm->etoolflagpool == NULL); + BLI_assert(bm->ftoolflagpool == NULL); BM_mesh_free(bm); #ifdef USE_TIMEIT diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c index ec81c5ce699..5c786626c94 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -30,32 +30,24 @@ /** \file blender/modifiers/intern/MOD_edgesplit.c * \ingroup modifiers + * + * EdgeSplit modifier + * + * Splits edges in the mesh according to sharpness flag + * or edge angle (can be used to achieve autosmoothing) */ - -/* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag - * or edge angle (can be used to achieve autosmoothing) */ - #include "BLI_utildefines.h" #include "BLI_math.h" -#include "MEM_guardedalloc.h" - #include "BKE_cdderivedmesh.h" #include "BKE_modifier.h" -#include "BKE_mesh.h" #include "bmesh.h" +#include "tools/bmesh_edgesplit.h" #include "DNA_object_types.h" -/* EdgeSplit */ -/* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag - * or edge angle (can be used to achieve autosmoothing) - * - * note: this code is very close to MOD_bevel.c - */ - #define EDGE_MARK 1 static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Object *UNUSED(ob)) @@ -67,7 +59,6 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj float threshold = cosf((emd->split_angle + 0.00001f) * (float)M_PI / 180.0f); bm = DM_to_bmesh(dm); - BM_mesh_elem_toolflags_ensure(bm); if (emd->flags & MOD_EDGESPLIT_FROMANGLE) { BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { @@ -81,7 +72,7 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj /* 2 face edge - check angle*/ (dot_v3v3(l1->f->no, l2->f->no) < threshold)) { - BMO_elem_flag_enable(bm, e, EDGE_MARK); + BM_elem_flag_enable(e, BM_ELEM_TAG); } } } @@ -94,14 +85,13 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj (e->l->next != e->l)) { if (!BM_elem_flag_test(e, BM_ELEM_SMOOTH)) { - BMO_elem_flag_enable(bm, e, EDGE_MARK); + BM_elem_flag_enable(e, BM_ELEM_TAG); } } } } - BMO_op_callf(bm, BMO_FLAG_DEFAULTS, - "split_edges edges=%fe", EDGE_MARK); + BM_mesh_edgesplit(bm, FALSE, TRUE); /* BM_mesh_validate(bm); */ /* for troubleshooting */ diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.c b/source/blender/modifiers/intern/MOD_fluidsim_util.c index 13d409dc941..b39ddf62c55 100644 --- a/source/blender/modifiers/intern/MOD_fluidsim_util.c +++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c @@ -301,7 +301,7 @@ static DerivedMesh *fluidsim_read_obj(const char *filename, const MPoly *mp_exam } -void fluid_get_bb(MVert *mvert, int totvert, float obmat[][4], +void fluid_get_bb(MVert *mvert, int totvert, float obmat[4][4], /*RET*/ float start[3], /*RET*/ float size[3]) { float bbsx = 0.0, bbsy = 0.0, bbsz = 0.0; diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index a27d5e5e03b..6c2f68891af 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -279,5 +279,6 @@ void modifier_type_init(ModifierTypeInfo *types[]) INIT_TYPE(Skin); INIT_TYPE(LaplacianSmooth); INIT_TYPE(Triangulate); + INIT_TYPE(UVWarp); #undef INIT_TYPE } diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c new file mode 100644 index 00000000000..249c3c89d5f --- /dev/null +++ b/source/blender/modifiers/intern/MOD_uvwarp.c @@ -0,0 +1,268 @@ +/* + * ***** 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): Pawel Kowal, Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_uvwarp.c + * \ingroup modifiers + */ + +#include <string.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" /* BKE_pose_channel_find_name */ +#include "BKE_cdderivedmesh.h" +#include "BKE_deform.h" +#include "BKE_modifier.h" + +#include "depsgraph_private.h" + +#include "MOD_util.h" + + +static void uv_warp_from_mat4_pair(float uv_dst[2], const float uv_src[2], float warp_mat[4][4], + int axis_u, int axis_v) +{ + float tuv[3] = {0.0f}; + + tuv[axis_u] = uv_src[0]; + tuv[axis_v] = uv_src[1]; + + mul_m4_v3(warp_mat, tuv); + + uv_dst[0] = tuv[axis_u]; + uv_dst[1] = tuv[axis_v]; +} + +static void initData(ModifierData *md) +{ + UVWarpModifierData *umd = (UVWarpModifierData *) md; + umd->axis_u = 0; + umd->axis_v = 1; + copy_v2_fl(umd->center, 0.5f); +} + +static void copyData(ModifierData *md, ModifierData *target) +{ + UVWarpModifierData *umd = (UVWarpModifierData *)md; + UVWarpModifierData *tumd = (UVWarpModifierData *)target; + + tumd->axis_u = umd->axis_u; + tumd->axis_v = umd->axis_v; + copy_v2_v2(tumd->center, umd->center); + tumd->object_src = umd->object_src; + BLI_strncpy(tumd->bone_src, umd->bone_src, sizeof(tumd->bone_src)); + tumd->object_dst = umd->object_dst; + BLI_strncpy(tumd->bone_dst, umd->bone_dst, sizeof(tumd->bone_dst)); + 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) +{ + UVWarpModifierData *umd = (UVWarpModifierData *)md; + CustomDataMask dataMask = 0; + + /* ask for vertexgroups if we need them */ + if (umd->vgroup_name[0]) + dataMask |= CD_MASK_MDEFORMVERT; + + return dataMask; +} + +static void matrix_from_obj_pchan(float mat[4][4], Object *ob, const char *bonename) +{ + bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bonename); + if (pchan) { + mult_m4_m4m4(mat, ob->obmat, pchan->pose_mat); + } + else { + copy_m4_m4(mat, ob->obmat); + } +} + +#define OMP_LIMIT 1000 +static DerivedMesh *applyModifier(ModifierData *md, Object *ob, + DerivedMesh *dm, + ModifierApplyFlag UNUSED(flag)) +{ + UVWarpModifierData *umd = (UVWarpModifierData *) md; + int i, numPolys, numLoops; + MPoly *mpoly; + MLoop *mloop; + MLoopUV *mloopuv; + MDeformVert *dvert; + int defgrp_index; + char uvname[MAX_CUSTOMDATA_LAYER_NAME]; + float mat_src[4][4]; + float mat_dst[4][4]; + float imat_dst[4][4]; + float warp_mat[4][4]; + const int axis_u = umd->axis_u; + const int axis_v = umd->axis_v; + + /* make sure there are UV Maps available */ + if (!CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) { + return dm; + } + else if (ELEM(NULL, umd->object_src, umd->object_dst)) { + modifier_setError(md, "From/To objects must be set"); + return dm; + } + + /* make sure anything moving UVs is available */ + matrix_from_obj_pchan(mat_src, umd->object_src, umd->bone_src); + matrix_from_obj_pchan(mat_dst, umd->object_dst, umd->bone_dst); + + invert_m4_m4(imat_dst, mat_dst); + mult_m4_m4m4(warp_mat, imat_dst, mat_src); + + /* apply warp */ + if (!is_zero_v2(umd->center)) { + float mat_cent[4][4]; + float imat_cent[4][4]; + + unit_m4(mat_cent); + mat_cent[3][axis_u] = umd->center[0]; + mat_cent[3][axis_v] = umd->center[1]; + + invert_m4_m4(imat_cent, mat_cent); + + mult_m4_m4m4(warp_mat, warp_mat, imat_cent); + mult_m4_m4m4(warp_mat, mat_cent, warp_mat); + } + + /* 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); + + if (dvert) { +#pragma omp parallel for if (numPolys > OMP_LIMIT) + for (i = 0; i < numPolys; i++) { + float uv[2]; + MPoly *mp = &mpoly[i]; + MLoop *ml = &mloop[mp->loopstart]; + MLoopUV *mluv = &mloopuv[mp->loopstart]; + int l; + for (l = 0; l < mp->totloop; l++, ml++, mluv++) { + const float weight = defvert_find_weight(&dvert[ml->v], defgrp_index); + uv_warp_from_mat4_pair(uv, mluv->uv, warp_mat, axis_u, axis_v); + interp_v2_v2v2(mluv->uv, mluv->uv, uv, weight); + } + } + } + else { +#pragma omp parallel for if (numPolys > OMP_LIMIT) + for (i = 0; i < numPolys; i++) { + MPoly *mp = &mpoly[i]; + // MLoop *ml = &mloop[mp->loopstart]; + MLoopUV *mluv = &mloopuv[mp->loopstart]; + int l; + for (l = 0; l < mp->totloop; l++, /* ml++, */ mluv++) { + uv_warp_from_mat4_pair(mluv->uv, mluv->uv, warp_mat, axis_u, axis_v); + } + } + } + + dm->dirty |= DM_DIRTY_TESS_CDLAYERS; + + return dm; +} + +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) +{ + UVWarpModifierData *umd = (UVWarpModifierData *) md; + + walk(userData, ob, &umd->object_dst); + walk(userData, ob, &umd->object_src); +} + +static void uv_warp_deps_object_bone(DagForest *forest, DagNode *obNode, + Object *obj, const char *bonename) +{ + if (obj) { + DagNode *curNode = dag_get_node(forest, obj); + + if (bonename[0]) + dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "UVWarp Modifier"); + else + dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA, "UVWarp Modifier"); + } +} + +static void updateDepgraph(ModifierData *md, DagForest *forest, + struct Scene *UNUSED(scene), + Object *UNUSED(ob), + DagNode *obNode) +{ + UVWarpModifierData *umd = (UVWarpModifierData *) md; + + uv_warp_deps_object_bone(forest, obNode, umd->object_src, umd->bone_src); + uv_warp_deps_object_bone(forest, obNode, umd->object_dst, umd->bone_dst); +} + +ModifierTypeInfo modifierType_UVWarp = { + /* name */ "UVWarp", + /* structName */ "UVWarpModifierData", + /* structSize */ sizeof(UVWarpModifierData), + /* 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, +}; |