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
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/modifiers
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/modifiers')
-rw-r--r--source/blender/modifiers/CMakeLists.txt206
-rw-r--r--source/blender/modifiers/MOD_modifiertypes.h2
-rw-r--r--source/blender/modifiers/intern/MOD_armature.c268
-rw-r--r--source/blender/modifiers/intern/MOD_array.c1370
-rw-r--r--source/blender/modifiers/intern/MOD_bevel.c350
-rw-r--r--source/blender/modifiers/intern/MOD_boolean.c482
-rw-r--r--source/blender/modifiers/intern/MOD_build.c500
-rw-r--r--source/blender/modifiers/intern/MOD_cast.c847
-rw-r--r--source/blender/modifiers/intern/MOD_cloth.c349
-rw-r--r--source/blender/modifiers/intern/MOD_collision.c408
-rw-r--r--source/blender/modifiers/intern/MOD_correctivesmooth.c1108
-rw-r--r--source/blender/modifiers/intern/MOD_curve.c186
-rw-r--r--source/blender/modifiers/intern/MOD_datatransfer.c320
-rw-r--r--source/blender/modifiers/intern/MOD_decimate.c329
-rw-r--r--source/blender/modifiers/intern/MOD_displace.c625
-rw-r--r--source/blender/modifiers/intern/MOD_dynamicpaint.c227
-rw-r--r--source/blender/modifiers/intern/MOD_edgesplit.c203
-rw-r--r--source/blender/modifiers/intern/MOD_explode.c1975
-rw-r--r--source/blender/modifiers/intern/MOD_fluidsim.c166
-rw-r--r--source/blender/modifiers/intern/MOD_fluidsim_util.c897
-rw-r--r--source/blender/modifiers/intern/MOD_fluidsim_util.h8
-rw-r--r--source/blender/modifiers/intern/MOD_hook.c585
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciandeform.c1286
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciansmooth.c904
-rw-r--r--source/blender/modifiers/intern/MOD_lattice.c148
-rw-r--r--source/blender/modifiers/intern/MOD_mask.c616
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache.c484
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_mdd.c438
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_pc2.c411
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_util.c69
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_util.h82
-rw-r--r--source/blender/modifiers/intern/MOD_meshdeform.c814
-rw-r--r--source/blender/modifiers/intern/MOD_meshsequencecache.c228
-rw-r--r--source/blender/modifiers/intern/MOD_mirror.c748
-rw-r--r--source/blender/modifiers/intern/MOD_multires.c279
-rw-r--r--source/blender/modifiers/intern/MOD_none.c51
-rw-r--r--source/blender/modifiers/intern/MOD_normal_edit.c1071
-rw-r--r--source/blender/modifiers/intern/MOD_ocean.c719
-rw-r--r--source/blender/modifiers/intern/MOD_particleinstance.c929
-rw-r--r--source/blender/modifiers/intern/MOD_particlesystem.c377
-rw-r--r--source/blender/modifiers/intern/MOD_remesh.c263
-rw-r--r--source/blender/modifiers/intern/MOD_screw.c2129
-rw-r--r--source/blender/modifiers/intern/MOD_shapekey.c165
-rw-r--r--source/blender/modifiers/intern/MOD_shrinkwrap.c244
-rw-r--r--source/blender/modifiers/intern/MOD_simpledeform.c679
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c3080
-rw-r--r--source/blender/modifiers/intern/MOD_smoke.c189
-rw-r--r--source/blender/modifiers/intern/MOD_smooth.c384
-rw-r--r--source/blender/modifiers/intern/MOD_softbody.c81
-rw-r--r--source/blender/modifiers/intern/MOD_solidify.c1696
-rw-r--r--source/blender/modifiers/intern/MOD_subsurf.c287
-rw-r--r--source/blender/modifiers/intern/MOD_surface.c279
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c2235
-rw-r--r--source/blender/modifiers/intern/MOD_triangulate.c170
-rw-r--r--source/blender/modifiers/intern/MOD_util.c436
-rw-r--r--source/blender/modifiers/intern/MOD_util.h35
-rw-r--r--source/blender/modifiers/intern/MOD_uvproject.c514
-rw-r--r--source/blender/modifiers/intern/MOD_uvwarp.c378
-rw-r--r--source/blender/modifiers/intern/MOD_warp.c538
-rw-r--r--source/blender/modifiers/intern/MOD_wave.c558
-rw-r--r--source/blender/modifiers/intern/MOD_weighted_normal.c1082
-rw-r--r--source/blender/modifiers/intern/MOD_weightvg_util.c371
-rw-r--r--source/blender/modifiers/intern/MOD_weightvg_util.h40
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgedit.c390
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgmix.c631
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgproximity.c855
-rw-r--r--source/blender/modifiers/intern/MOD_wireframe.c162
67 files changed, 19773 insertions, 19163 deletions
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index 33bdd900556..691a0e369e6 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -19,137 +19,137 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- .
- intern
- ../blenkernel
- ../blenlib
- ../blenfont
- ../depsgraph
- ../makesdna
- ../makesrna
- ../bmesh
- ../render/extern/include
- ../../../intern/elbeem/extern
- ../../../intern/guardedalloc
- ../../../intern/eigen
+ .
+ intern
+ ../blenkernel
+ ../blenlib
+ ../blenfont
+ ../depsgraph
+ ../makesdna
+ ../makesrna
+ ../bmesh
+ ../render/extern/include
+ ../../../intern/elbeem/extern
+ ../../../intern/guardedalloc
+ ../../../intern/eigen
)
set(INC_SYS
- ${ZLIB_INCLUDE_DIRS}
+ ${ZLIB_INCLUDE_DIRS}
)
set(SRC
- intern/MOD_armature.c
- intern/MOD_array.c
- intern/MOD_bevel.c
- intern/MOD_boolean.c
- intern/MOD_build.c
- intern/MOD_cast.c
- intern/MOD_cloth.c
- intern/MOD_collision.c
- intern/MOD_correctivesmooth.c
- intern/MOD_curve.c
- intern/MOD_datatransfer.c
- intern/MOD_decimate.c
- intern/MOD_displace.c
- intern/MOD_dynamicpaint.c
- intern/MOD_edgesplit.c
- intern/MOD_explode.c
- intern/MOD_fluidsim.c
- intern/MOD_fluidsim_util.c
- intern/MOD_hook.c
- intern/MOD_laplaciandeform.c
- intern/MOD_laplaciansmooth.c
- intern/MOD_lattice.c
- intern/MOD_mask.c
- intern/MOD_meshcache.c
- intern/MOD_meshcache_mdd.c
- intern/MOD_meshcache_pc2.c
- intern/MOD_meshcache_util.c
- intern/MOD_meshdeform.c
- intern/MOD_meshsequencecache.c
- intern/MOD_mirror.c
- intern/MOD_multires.c
- intern/MOD_none.c
- intern/MOD_normal_edit.c
- intern/MOD_ocean.c
- intern/MOD_particleinstance.c
- intern/MOD_particlesystem.c
- intern/MOD_remesh.c
- intern/MOD_screw.c
- intern/MOD_shapekey.c
- intern/MOD_shrinkwrap.c
- intern/MOD_simpledeform.c
- intern/MOD_skin.c
- intern/MOD_smoke.c
- intern/MOD_smooth.c
- intern/MOD_softbody.c
- 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_uvproject.c
- intern/MOD_uvwarp.c
- intern/MOD_warp.c
- intern/MOD_wave.c
- intern/MOD_weighted_normal.c
- intern/MOD_weightvg_util.c
- intern/MOD_weightvgedit.c
- intern/MOD_weightvgmix.c
- intern/MOD_weightvgproximity.c
- intern/MOD_wireframe.c
+ intern/MOD_armature.c
+ intern/MOD_array.c
+ intern/MOD_bevel.c
+ intern/MOD_boolean.c
+ intern/MOD_build.c
+ intern/MOD_cast.c
+ intern/MOD_cloth.c
+ intern/MOD_collision.c
+ intern/MOD_correctivesmooth.c
+ intern/MOD_curve.c
+ intern/MOD_datatransfer.c
+ intern/MOD_decimate.c
+ intern/MOD_displace.c
+ intern/MOD_dynamicpaint.c
+ intern/MOD_edgesplit.c
+ intern/MOD_explode.c
+ intern/MOD_fluidsim.c
+ intern/MOD_fluidsim_util.c
+ intern/MOD_hook.c
+ intern/MOD_laplaciandeform.c
+ intern/MOD_laplaciansmooth.c
+ intern/MOD_lattice.c
+ intern/MOD_mask.c
+ intern/MOD_meshcache.c
+ intern/MOD_meshcache_mdd.c
+ intern/MOD_meshcache_pc2.c
+ intern/MOD_meshcache_util.c
+ intern/MOD_meshdeform.c
+ intern/MOD_meshsequencecache.c
+ intern/MOD_mirror.c
+ intern/MOD_multires.c
+ intern/MOD_none.c
+ intern/MOD_normal_edit.c
+ intern/MOD_ocean.c
+ intern/MOD_particleinstance.c
+ intern/MOD_particlesystem.c
+ intern/MOD_remesh.c
+ intern/MOD_screw.c
+ intern/MOD_shapekey.c
+ intern/MOD_shrinkwrap.c
+ intern/MOD_simpledeform.c
+ intern/MOD_skin.c
+ intern/MOD_smoke.c
+ intern/MOD_smooth.c
+ intern/MOD_softbody.c
+ 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_uvproject.c
+ intern/MOD_uvwarp.c
+ intern/MOD_warp.c
+ intern/MOD_wave.c
+ intern/MOD_weighted_normal.c
+ intern/MOD_weightvg_util.c
+ intern/MOD_weightvgedit.c
+ intern/MOD_weightvgmix.c
+ intern/MOD_weightvgproximity.c
+ intern/MOD_wireframe.c
- MOD_modifiertypes.h
- intern/MOD_fluidsim_util.h
- intern/MOD_meshcache_util.h
- intern/MOD_util.h
- intern/MOD_weightvg_util.h
+ MOD_modifiertypes.h
+ intern/MOD_fluidsim_util.h
+ intern/MOD_meshcache_util.h
+ intern/MOD_util.h
+ intern/MOD_weightvg_util.h
)
set(LIB
- bf_blenkernel
- bf_blenlib
+ bf_blenkernel
+ bf_blenlib
)
if(WITH_ALEMBIC)
- add_definitions(-DWITH_ALEMBIC)
- list(APPEND INC
- ../alembic
- )
- list(APPEND LIB
- bf_alembic
- )
+ add_definitions(-DWITH_ALEMBIC)
+ list(APPEND INC
+ ../alembic
+ )
+ list(APPEND LIB
+ bf_alembic
+ )
endif()
if(WITH_MOD_REMESH)
- list(APPEND INC
- ../../../intern/dualcon
- )
- list(APPEND LIB
- bf_intern_dualcon
- )
- add_definitions(-DWITH_MOD_REMESH)
+ list(APPEND INC
+ ../../../intern/dualcon
+ )
+ list(APPEND LIB
+ bf_intern_dualcon
+ )
+ add_definitions(-DWITH_MOD_REMESH)
endif()
if(WITH_MOD_FLUID)
- add_definitions(-DWITH_MOD_FLUID)
+ add_definitions(-DWITH_MOD_FLUID)
endif()
if(WITH_MOD_OCEANSIM)
- add_definitions(-DWITH_OCEANSIM)
+ add_definitions(-DWITH_OCEANSIM)
endif()
if(WITH_BULLET)
- list(APPEND LIB
- extern_bullet
- )
- add_definitions(-DWITH_BULLET)
+ list(APPEND LIB
+ extern_bullet
+ )
+ add_definitions(-DWITH_BULLET)
endif()
if(WITH_INTERNATIONAL)
- add_definitions(-DWITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
endif()
# So we can have special tricks in modifier system.
diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h
index 9c71ff7a5e1..96622bf7763 100644
--- a/source/blender/modifiers/MOD_modifiertypes.h
+++ b/source/blender/modifiers/MOD_modifiertypes.h
@@ -85,4 +85,4 @@ extern ModifierTypeInfo modifierType_WeightedNormal;
/* MOD_util.c */
void modifier_type_init(ModifierTypeInfo *types[]);
-#endif /* __MOD_MODIFIERTYPES_H__ */
+#endif /* __MOD_MODIFIERTYPES_H__ */
diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c
index 4cc780431d0..ce58fd172a2 100644
--- a/source/blender/modifiers/intern/MOD_armature.c
+++ b/source/blender/modifiers/intern/MOD_armature.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include <string.h>
#include "BLI_utildefines.h"
@@ -46,157 +45,198 @@
#include "MOD_util.h"
-
static void initData(ModifierData *md)
{
- ArmatureModifierData *amd = (ArmatureModifierData *) md;
+ ArmatureModifierData *amd = (ArmatureModifierData *)md;
- amd->deformflag = ARM_DEF_VGROUP;
+ amd->deformflag = ARM_DEF_VGROUP;
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
#if 0
- const ArmatureModifierData *amd = (const ArmatureModifierData *) md;
+ const ArmatureModifierData *amd = (const ArmatureModifierData *) md;
#endif
- ArmatureModifierData *tamd = (ArmatureModifierData *) target;
+ ArmatureModifierData *tamd = (ArmatureModifierData *)target;
- modifier_copyData_generic(md, target, flag);
- tamd->prevCos = NULL;
+ modifier_copyData_generic(md, target, flag);
+ tamd->prevCos = NULL;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md), CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *UNUSED(md),
+ CustomData_MeshMasks *r_cddata_masks)
{
- /* ask for vertexgroups */
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ /* ask for vertexgroups */
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
}
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(useRenderParams))
{
- ArmatureModifierData *amd = (ArmatureModifierData *) md;
+ ArmatureModifierData *amd = (ArmatureModifierData *)md;
- return !amd->object;
+ return !amd->object;
}
-static void foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- ArmatureModifierData *amd = (ArmatureModifierData *) md;
+ ArmatureModifierData *amd = (ArmatureModifierData *)md;
- walk(userData, ob, &amd->object, IDWALK_CB_NOP);
+ walk(userData, ob, &amd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- ArmatureModifierData *amd = (ArmatureModifierData *)md;
- if (amd->object != NULL) {
- DEG_add_object_relation(ctx->node, amd->object, DEG_OB_COMP_EVAL_POSE, "Armature Modifier");
- DEG_add_object_relation(ctx->node, amd->object, DEG_OB_COMP_TRANSFORM, "Armature Modifier");
- }
- DEG_add_modifier_to_transform_relation(ctx->node, "Armature Modifier");
+ ArmatureModifierData *amd = (ArmatureModifierData *)md;
+ if (amd->object != NULL) {
+ DEG_add_object_relation(ctx->node, amd->object, DEG_OB_COMP_EVAL_POSE, "Armature Modifier");
+ DEG_add_object_relation(ctx->node, amd->object, DEG_OB_COMP_TRANSFORM, "Armature Modifier");
+ }
+ DEG_add_modifier_to_transform_relation(ctx->node, "Armature Modifier");
}
-static void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh,
- float (*vertexCos)[3],
- int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- ArmatureModifierData *amd = (ArmatureModifierData *) md;
-
- MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
-
- armature_deform_verts(amd->object, ctx->object, mesh, vertexCos, NULL,
- numVerts, amd->deformflag, (float(*)[3])amd->prevCos, amd->defgrp_name, NULL);
-
- /* free cache */
- if (amd->prevCos) {
- MEM_freeN(amd->prevCos);
- amd->prevCos = NULL;
- }
+ ArmatureModifierData *amd = (ArmatureModifierData *)md;
+
+ MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
+
+ armature_deform_verts(amd->object,
+ ctx->object,
+ mesh,
+ vertexCos,
+ NULL,
+ numVerts,
+ amd->deformflag,
+ (float(*)[3])amd->prevCos,
+ amd->defgrp_name,
+ NULL);
+
+ /* free cache */
+ if (amd->prevCos) {
+ MEM_freeN(amd->prevCos);
+ amd->prevCos = NULL;
+ }
}
-static void deformVertsEM(
- ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *em,
- Mesh *mesh, float (*vertexCos)[3], int numVerts)
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *em,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- ArmatureModifierData *amd = (ArmatureModifierData *) md;
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false);
-
- MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
-
- armature_deform_verts(amd->object, ctx->object, mesh_src, vertexCos, NULL,
- numVerts, amd->deformflag, (float(*)[3])amd->prevCos, amd->defgrp_name, NULL);
-
- /* free cache */
- if (amd->prevCos) {
- MEM_freeN(amd->prevCos);
- amd->prevCos = NULL;
- }
-
- if (mesh_src != mesh) {
- BKE_id_free(NULL, mesh_src);
- }
+ ArmatureModifierData *amd = (ArmatureModifierData *)md;
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false);
+
+ MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
+
+ armature_deform_verts(amd->object,
+ ctx->object,
+ mesh_src,
+ vertexCos,
+ NULL,
+ numVerts,
+ amd->deformflag,
+ (float(*)[3])amd->prevCos,
+ amd->defgrp_name,
+ NULL);
+
+ /* free cache */
+ if (amd->prevCos) {
+ MEM_freeN(amd->prevCos);
+ amd->prevCos = NULL;
+ }
+
+ if (mesh_src != mesh) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-static void deformMatricesEM(
- ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *em,
- Mesh *mesh, float (*vertexCos)[3],
- float (*defMats)[3][3], int numVerts)
+static void deformMatricesEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *em,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ float (*defMats)[3][3],
+ int numVerts)
{
- ArmatureModifierData *amd = (ArmatureModifierData *) md;
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false);
-
- armature_deform_verts(amd->object, ctx->object, mesh_src, vertexCos, defMats,
- numVerts, amd->deformflag, NULL, amd->defgrp_name, NULL);
-
- if (mesh_src != mesh) {
- BKE_id_free(NULL, mesh_src);
- }
+ ArmatureModifierData *amd = (ArmatureModifierData *)md;
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false);
+
+ armature_deform_verts(amd->object,
+ ctx->object,
+ mesh_src,
+ vertexCos,
+ defMats,
+ numVerts,
+ amd->deformflag,
+ NULL,
+ amd->defgrp_name,
+ NULL);
+
+ if (mesh_src != mesh) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-static void deformMatrices(
- ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh,
- float (*vertexCos)[3], float (*defMats)[3][3], int numVerts)
+static void deformMatrices(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ float (*defMats)[3][3],
+ int numVerts)
{
- ArmatureModifierData *amd = (ArmatureModifierData *) md;
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
-
- armature_deform_verts(amd->object, ctx->object, mesh_src, vertexCos, defMats,
- numVerts, amd->deformflag, NULL, amd->defgrp_name, NULL);
-
- if (mesh_src != mesh) {
- BKE_id_free(NULL, mesh_src);
- }
+ ArmatureModifierData *amd = (ArmatureModifierData *)md;
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+
+ armature_deform_verts(amd->object,
+ ctx->object,
+ mesh_src,
+ vertexCos,
+ defMats,
+ numVerts,
+ amd->deformflag,
+ NULL,
+ amd->defgrp_name,
+ NULL);
+
+ if (mesh_src != mesh) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
ModifierTypeInfo modifierType_Armature = {
- /* name */ "Armature",
- /* structName */ "ArmatureModifierData",
- /* structSize */ sizeof(ArmatureModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_AcceptsLattice |
- eModifierTypeFlag_SupportsEditmode,
-
- /* copyData */ copyData,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ deformMatrices,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ deformMatricesEM,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Armature",
+ /* structName */ "ArmatureModifierData",
+ /* structSize */ sizeof(ArmatureModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice |
+ eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ copyData,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ deformMatrices,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ deformMatricesEM,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index 542c7665807..c909f9dc076 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -50,87 +50,96 @@
static void initData(ModifierData *md)
{
- ArrayModifierData *amd = (ArrayModifierData *) md;
-
- /* default to 2 duplicates distributed along the x-axis by an
- * offset of 1 object-width
- */
- amd->start_cap = amd->end_cap = amd->curve_ob = amd->offset_ob = NULL;
- amd->count = 2;
- zero_v3(amd->offset);
- amd->scale[0] = 1;
- amd->scale[1] = amd->scale[2] = 0;
- amd->length = 0;
- amd->merge_dist = 0.01;
- amd->fit_type = MOD_ARR_FIXEDCOUNT;
- amd->offset_type = MOD_ARR_OFF_RELATIVE;
- amd->flags = 0;
+ ArrayModifierData *amd = (ArrayModifierData *)md;
+
+ /* default to 2 duplicates distributed along the x-axis by an
+ * offset of 1 object-width
+ */
+ amd->start_cap = amd->end_cap = amd->curve_ob = amd->offset_ob = NULL;
+ amd->count = 2;
+ zero_v3(amd->offset);
+ amd->scale[0] = 1;
+ amd->scale[1] = amd->scale[2] = 0;
+ amd->length = 0;
+ amd->merge_dist = 0.01;
+ amd->fit_type = MOD_ARR_FIXEDCOUNT;
+ amd->offset_type = MOD_ARR_OFF_RELATIVE;
+ amd->flags = 0;
}
-static void foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- ArrayModifierData *amd = (ArrayModifierData *) md;
+ ArrayModifierData *amd = (ArrayModifierData *)md;
- walk(userData, ob, &amd->start_cap, IDWALK_CB_NOP);
- walk(userData, ob, &amd->end_cap, IDWALK_CB_NOP);
- walk(userData, ob, &amd->curve_ob, IDWALK_CB_NOP);
- walk(userData, ob, &amd->offset_ob, IDWALK_CB_NOP);
+ walk(userData, ob, &amd->start_cap, IDWALK_CB_NOP);
+ walk(userData, ob, &amd->end_cap, IDWALK_CB_NOP);
+ walk(userData, ob, &amd->curve_ob, IDWALK_CB_NOP);
+ walk(userData, ob, &amd->offset_ob, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- ArrayModifierData *amd = (ArrayModifierData *)md;
- if (amd->start_cap != NULL) {
- DEG_add_object_relation(ctx->node, amd->start_cap, DEG_OB_COMP_TRANSFORM, "Array Modifier Start Cap");
- DEG_add_object_relation(ctx->node, amd->start_cap, DEG_OB_COMP_GEOMETRY, "Array Modifier Start Cap");
- }
- if (amd->end_cap != NULL) {
- DEG_add_object_relation(ctx->node, amd->end_cap, DEG_OB_COMP_TRANSFORM, "Array Modifier End Cap");
- DEG_add_object_relation(ctx->node, amd->end_cap, DEG_OB_COMP_GEOMETRY, "Array Modifier End Cap");
- }
- if (amd->curve_ob) {
- DEG_add_object_relation(ctx->node, amd->curve_ob, DEG_OB_COMP_GEOMETRY, "Array Modifier Curve");
- DEG_add_special_eval_flag(ctx->node, &amd->curve_ob->id, DAG_EVAL_NEED_CURVE_PATH);
- }
- if (amd->offset_ob != NULL) {
- DEG_add_object_relation(ctx->node, amd->offset_ob, DEG_OB_COMP_TRANSFORM, "Array Modifier Offset");
- }
- DEG_add_modifier_to_transform_relation(ctx->node, "Array Modifier");
+ ArrayModifierData *amd = (ArrayModifierData *)md;
+ if (amd->start_cap != NULL) {
+ DEG_add_object_relation(
+ ctx->node, amd->start_cap, DEG_OB_COMP_TRANSFORM, "Array Modifier Start Cap");
+ DEG_add_object_relation(
+ ctx->node, amd->start_cap, DEG_OB_COMP_GEOMETRY, "Array Modifier Start Cap");
+ }
+ if (amd->end_cap != NULL) {
+ DEG_add_object_relation(
+ ctx->node, amd->end_cap, DEG_OB_COMP_TRANSFORM, "Array Modifier End Cap");
+ DEG_add_object_relation(
+ ctx->node, amd->end_cap, DEG_OB_COMP_GEOMETRY, "Array Modifier End Cap");
+ }
+ if (amd->curve_ob) {
+ DEG_add_object_relation(
+ ctx->node, amd->curve_ob, DEG_OB_COMP_GEOMETRY, "Array Modifier Curve");
+ DEG_add_special_eval_flag(ctx->node, &amd->curve_ob->id, DAG_EVAL_NEED_CURVE_PATH);
+ }
+ if (amd->offset_ob != NULL) {
+ DEG_add_object_relation(
+ ctx->node, amd->offset_ob, DEG_OB_COMP_TRANSFORM, "Array Modifier Offset");
+ }
+ DEG_add_modifier_to_transform_relation(ctx->node, "Array Modifier");
}
BLI_INLINE float sum_v3(const float v[3])
{
- return v[0] + v[1] + v[2];
+ return v[0] + v[1] + v[2];
}
/* Structure used for sorting vertices, when processing doubles */
typedef struct SortVertsElem {
- int vertex_num; /* The original index of the vertex, prior to sorting */
- float co[3]; /* Its coordinates */
- float sum_co; /* sum_v3(co), just so we don't do the sum many times. */
+ int vertex_num; /* The original index of the vertex, prior to sorting */
+ float co[3]; /* Its coordinates */
+ float sum_co; /* sum_v3(co), just so we don't do the sum many times. */
} SortVertsElem;
-
static int svert_sum_cmp(const void *e1, const void *e2)
{
- const SortVertsElem *sv1 = e1;
- const SortVertsElem *sv2 = e2;
-
- if (sv1->sum_co > sv2->sum_co) return 1;
- else if (sv1->sum_co < sv2->sum_co) return -1;
- else return 0;
+ const SortVertsElem *sv1 = e1;
+ const SortVertsElem *sv2 = e2;
+
+ if (sv1->sum_co > sv2->sum_co)
+ return 1;
+ else if (sv1->sum_co < sv2->sum_co)
+ return -1;
+ else
+ return 0;
}
-static void svert_from_mvert(SortVertsElem *sv, const MVert *mv, const int i_begin, const int i_end)
+static void svert_from_mvert(SortVertsElem *sv,
+ const MVert *mv,
+ const int i_begin,
+ const int i_end)
{
- int i;
- for (i = i_begin; i < i_end; i++, sv++, mv++) {
- sv->vertex_num = i;
- copy_v3_v3(sv->co, mv->co);
- sv->sum_co = sum_v3(mv->co);
- }
+ int i;
+ for (i = i_begin; i < i_end; i++, sv++, mv++) {
+ sv->vertex_num = i;
+ copy_v3_v3(sv->co, mv->co);
+ sv->sum_co = sum_v3(mv->co);
+ }
}
/**
@@ -139,637 +148,642 @@ static void svert_from_mvert(SortVertsElem *sv, const MVert *mv, const int i_beg
* It builds a mapping for all vertices within source, to vertices within target, or -1 if no double found
* The int doubles_map[num_verts_source] array must have been allocated by caller.
*/
-static void dm_mvert_map_doubles(
- int *doubles_map,
- const MVert *mverts,
- const int target_start,
- const int target_num_verts,
- const int source_start,
- const int source_num_verts,
- const float dist)
+static void dm_mvert_map_doubles(int *doubles_map,
+ const MVert *mverts,
+ const int target_start,
+ const int target_num_verts,
+ const int source_start,
+ const int source_num_verts,
+ const float dist)
{
- const float dist3 = ((float)M_SQRT3 + 0.00005f) * dist; /* Just above sqrt(3) */
- int i_source, i_target, i_target_low_bound, target_end, source_end;
- SortVertsElem *sorted_verts_target, *sorted_verts_source;
- SortVertsElem *sve_source, *sve_target, *sve_target_low_bound;
- bool target_scan_completed;
-
- target_end = target_start + target_num_verts;
- source_end = source_start + source_num_verts;
-
- /* build array of MVerts to be tested for merging */
- sorted_verts_target = MEM_malloc_arrayN(target_num_verts, sizeof(SortVertsElem), __func__);
- sorted_verts_source = MEM_malloc_arrayN(source_num_verts, sizeof(SortVertsElem), __func__);
-
- /* Copy target vertices index and cos into SortVertsElem array */
- svert_from_mvert(sorted_verts_target, mverts + target_start, target_start, target_end);
-
- /* Copy source vertices index and cos into SortVertsElem array */
- svert_from_mvert(sorted_verts_source, mverts + source_start, source_start, source_end);
-
- /* sort arrays according to sum of vertex coordinates (sumco) */
- qsort(sorted_verts_target, target_num_verts, sizeof(SortVertsElem), svert_sum_cmp);
- qsort(sorted_verts_source, source_num_verts, sizeof(SortVertsElem), svert_sum_cmp);
-
- sve_target_low_bound = sorted_verts_target;
- i_target_low_bound = 0;
- target_scan_completed = false;
-
- /* Scan source vertices, in SortVertsElem sorted array, */
- /* all the while maintaining the lower bound of possible doubles in target vertices */
- for (i_source = 0, sve_source = sorted_verts_source;
- i_source < source_num_verts;
- i_source++, sve_source++)
- {
- int best_target_vertex = -1;
- float best_dist_sq = dist * dist;
- float sve_source_sumco;
-
- /* If source has already been assigned to a target (in an earlier call, with other chunks) */
- if (doubles_map[sve_source->vertex_num] != -1) {
- continue;
- }
-
- /* If target fully scanned already, then all remaining source vertices cannot have a double */
- if (target_scan_completed) {
- doubles_map[sve_source->vertex_num] = -1;
- continue;
- }
-
- sve_source_sumco = sum_v3(sve_source->co);
-
- /* Skip all target vertices that are more than dist3 lower in terms of sumco */
- /* and advance the overall lower bound, applicable to all remaining vertices as well. */
- while ((i_target_low_bound < target_num_verts) &&
- (sve_target_low_bound->sum_co < sve_source_sumco - dist3))
- {
- i_target_low_bound++;
- sve_target_low_bound++;
- }
- /* If end of target list reached, then no more possible doubles */
- if (i_target_low_bound >= target_num_verts) {
- doubles_map[sve_source->vertex_num] = -1;
- target_scan_completed = true;
- continue;
- }
- /* Test target candidates starting at the low bound of possible doubles, ordered in terms of sumco */
- i_target = i_target_low_bound;
- sve_target = sve_target_low_bound;
-
- /* i_target will scan vertices in the [v_source_sumco - dist3; v_source_sumco + dist3] range */
-
- while ((i_target < target_num_verts) &&
- (sve_target->sum_co <= sve_source_sumco + dist3))
- {
- /* Testing distance for candidate double in target */
- /* v_target is within dist3 of v_source in terms of sumco; check real distance */
- float dist_sq;
- if ((dist_sq = len_squared_v3v3(sve_source->co, sve_target->co)) <= best_dist_sq) {
- /* Potential double found */
- best_dist_sq = dist_sq;
- best_target_vertex = sve_target->vertex_num;
-
- /* If target is already mapped, we only follow that mapping if final target remains
- * close enough from current vert (otherwise no mapping at all).
- * Note that if we later find another target closer than this one, then we check it. But if other
- * potential targets are farther, then there will be no mapping at all for this source. */
- while (best_target_vertex != -1 && !ELEM(doubles_map[best_target_vertex], -1, best_target_vertex)) {
- if (compare_len_v3v3(mverts[sve_source->vertex_num].co,
- mverts[doubles_map[best_target_vertex]].co,
- dist))
- {
- best_target_vertex = doubles_map[best_target_vertex];
- }
- else {
- best_target_vertex = -1;
- }
- }
- }
- i_target++;
- sve_target++;
- }
- /* End of candidate scan: if none found then no doubles */
- doubles_map[sve_source->vertex_num] = best_target_vertex;
- }
-
- MEM_freeN(sorted_verts_source);
- MEM_freeN(sorted_verts_target);
+ const float dist3 = ((float)M_SQRT3 + 0.00005f) * dist; /* Just above sqrt(3) */
+ int i_source, i_target, i_target_low_bound, target_end, source_end;
+ SortVertsElem *sorted_verts_target, *sorted_verts_source;
+ SortVertsElem *sve_source, *sve_target, *sve_target_low_bound;
+ bool target_scan_completed;
+
+ target_end = target_start + target_num_verts;
+ source_end = source_start + source_num_verts;
+
+ /* build array of MVerts to be tested for merging */
+ sorted_verts_target = MEM_malloc_arrayN(target_num_verts, sizeof(SortVertsElem), __func__);
+ sorted_verts_source = MEM_malloc_arrayN(source_num_verts, sizeof(SortVertsElem), __func__);
+
+ /* Copy target vertices index and cos into SortVertsElem array */
+ svert_from_mvert(sorted_verts_target, mverts + target_start, target_start, target_end);
+
+ /* Copy source vertices index and cos into SortVertsElem array */
+ svert_from_mvert(sorted_verts_source, mverts + source_start, source_start, source_end);
+
+ /* sort arrays according to sum of vertex coordinates (sumco) */
+ qsort(sorted_verts_target, target_num_verts, sizeof(SortVertsElem), svert_sum_cmp);
+ qsort(sorted_verts_source, source_num_verts, sizeof(SortVertsElem), svert_sum_cmp);
+
+ sve_target_low_bound = sorted_verts_target;
+ i_target_low_bound = 0;
+ target_scan_completed = false;
+
+ /* Scan source vertices, in SortVertsElem sorted array, */
+ /* all the while maintaining the lower bound of possible doubles in target vertices */
+ for (i_source = 0, sve_source = sorted_verts_source; i_source < source_num_verts;
+ i_source++, sve_source++) {
+ int best_target_vertex = -1;
+ float best_dist_sq = dist * dist;
+ float sve_source_sumco;
+
+ /* If source has already been assigned to a target (in an earlier call, with other chunks) */
+ if (doubles_map[sve_source->vertex_num] != -1) {
+ continue;
+ }
+
+ /* If target fully scanned already, then all remaining source vertices cannot have a double */
+ if (target_scan_completed) {
+ doubles_map[sve_source->vertex_num] = -1;
+ continue;
+ }
+
+ sve_source_sumco = sum_v3(sve_source->co);
+
+ /* Skip all target vertices that are more than dist3 lower in terms of sumco */
+ /* and advance the overall lower bound, applicable to all remaining vertices as well. */
+ while ((i_target_low_bound < target_num_verts) &&
+ (sve_target_low_bound->sum_co < sve_source_sumco - dist3)) {
+ i_target_low_bound++;
+ sve_target_low_bound++;
+ }
+ /* If end of target list reached, then no more possible doubles */
+ if (i_target_low_bound >= target_num_verts) {
+ doubles_map[sve_source->vertex_num] = -1;
+ target_scan_completed = true;
+ continue;
+ }
+ /* Test target candidates starting at the low bound of possible doubles, ordered in terms of sumco */
+ i_target = i_target_low_bound;
+ sve_target = sve_target_low_bound;
+
+ /* i_target will scan vertices in the [v_source_sumco - dist3; v_source_sumco + dist3] range */
+
+ while ((i_target < target_num_verts) && (sve_target->sum_co <= sve_source_sumco + dist3)) {
+ /* Testing distance for candidate double in target */
+ /* v_target is within dist3 of v_source in terms of sumco; check real distance */
+ float dist_sq;
+ if ((dist_sq = len_squared_v3v3(sve_source->co, sve_target->co)) <= best_dist_sq) {
+ /* Potential double found */
+ best_dist_sq = dist_sq;
+ best_target_vertex = sve_target->vertex_num;
+
+ /* If target is already mapped, we only follow that mapping if final target remains
+ * close enough from current vert (otherwise no mapping at all).
+ * Note that if we later find another target closer than this one, then we check it. But if other
+ * potential targets are farther, then there will be no mapping at all for this source. */
+ while (best_target_vertex != -1 &&
+ !ELEM(doubles_map[best_target_vertex], -1, best_target_vertex)) {
+ if (compare_len_v3v3(mverts[sve_source->vertex_num].co,
+ mverts[doubles_map[best_target_vertex]].co,
+ dist)) {
+ best_target_vertex = doubles_map[best_target_vertex];
+ }
+ else {
+ best_target_vertex = -1;
+ }
+ }
+ }
+ i_target++;
+ sve_target++;
+ }
+ /* End of candidate scan: if none found then no doubles */
+ doubles_map[sve_source->vertex_num] = best_target_vertex;
+ }
+
+ MEM_freeN(sorted_verts_source);
+ MEM_freeN(sorted_verts_target);
}
-
-static void mesh_merge_transform(
- Mesh *result, Mesh *cap_mesh, float cap_offset[4][4],
- unsigned int cap_verts_index, unsigned int cap_edges_index, int cap_loops_index, int cap_polys_index,
- int cap_nverts, int cap_nedges, int cap_nloops, int cap_npolys, int *remap, int remap_len)
+static void mesh_merge_transform(Mesh *result,
+ Mesh *cap_mesh,
+ float cap_offset[4][4],
+ unsigned int cap_verts_index,
+ unsigned int cap_edges_index,
+ int cap_loops_index,
+ int cap_polys_index,
+ int cap_nverts,
+ int cap_nedges,
+ int cap_nloops,
+ int cap_npolys,
+ int *remap,
+ int remap_len)
{
- int *index_orig;
- int i;
- MVert *mv;
- MEdge *me;
- MLoop *ml;
- MPoly *mp;
-
- CustomData_copy_data(&cap_mesh->vdata, &result->vdata, 0, cap_verts_index, cap_nverts);
- CustomData_copy_data(&cap_mesh->edata, &result->edata, 0, cap_edges_index, cap_nedges);
- CustomData_copy_data(&cap_mesh->ldata, &result->ldata, 0, cap_loops_index, cap_nloops);
- CustomData_copy_data(&cap_mesh->pdata, &result->pdata, 0, cap_polys_index, cap_npolys);
-
- mv = result->mvert + cap_verts_index;
-
- for (i = 0; i < cap_nverts; i++, mv++) {
- mul_m4_v3(cap_offset, mv->co);
- /* Reset MVert flags for caps */
- mv->flag = mv->bweight = 0;
- }
-
- /* remap the vertex groups if necessary */
- if (result->dvert != NULL) {
- BKE_object_defgroup_index_map_apply(&result->dvert[cap_verts_index], cap_nverts, remap, remap_len);
- }
-
- /* adjust cap edge vertex indices */
- me = result->medge + cap_edges_index;
- for (i = 0; i < cap_nedges; i++, me++) {
- me->v1 += cap_verts_index;
- me->v2 += cap_verts_index;
- }
-
- /* adjust cap poly loopstart indices */
- mp = result->mpoly + cap_polys_index;
- for (i = 0; i < cap_npolys; i++, mp++) {
- mp->loopstart += cap_loops_index;
- }
-
- /* adjust cap loop vertex and edge indices */
- ml = result->mloop + cap_loops_index;
- for (i = 0; i < cap_nloops; i++, ml++) {
- ml->v += cap_verts_index;
- ml->e += cap_edges_index;
- }
-
- /* set origindex */
- index_orig = CustomData_get_layer(&result->vdata, CD_ORIGINDEX);
- if (index_orig) {
- copy_vn_i(index_orig + cap_verts_index, cap_nverts, ORIGINDEX_NONE);
- }
-
- index_orig = CustomData_get_layer(&result->edata, CD_ORIGINDEX);
- if (index_orig) {
- copy_vn_i(index_orig + cap_edges_index, cap_nedges, ORIGINDEX_NONE);
- }
-
- index_orig = CustomData_get_layer(&result->pdata, CD_ORIGINDEX);
- if (index_orig) {
- copy_vn_i(index_orig + cap_polys_index, cap_npolys, ORIGINDEX_NONE);
- }
-
- index_orig = CustomData_get_layer(&result->ldata, CD_ORIGINDEX);
- if (index_orig) {
- copy_vn_i(index_orig + cap_loops_index, cap_nloops, ORIGINDEX_NONE);
- }
+ int *index_orig;
+ int i;
+ MVert *mv;
+ MEdge *me;
+ MLoop *ml;
+ MPoly *mp;
+
+ CustomData_copy_data(&cap_mesh->vdata, &result->vdata, 0, cap_verts_index, cap_nverts);
+ CustomData_copy_data(&cap_mesh->edata, &result->edata, 0, cap_edges_index, cap_nedges);
+ CustomData_copy_data(&cap_mesh->ldata, &result->ldata, 0, cap_loops_index, cap_nloops);
+ CustomData_copy_data(&cap_mesh->pdata, &result->pdata, 0, cap_polys_index, cap_npolys);
+
+ mv = result->mvert + cap_verts_index;
+
+ for (i = 0; i < cap_nverts; i++, mv++) {
+ mul_m4_v3(cap_offset, mv->co);
+ /* Reset MVert flags for caps */
+ mv->flag = mv->bweight = 0;
+ }
+
+ /* remap the vertex groups if necessary */
+ if (result->dvert != NULL) {
+ BKE_object_defgroup_index_map_apply(
+ &result->dvert[cap_verts_index], cap_nverts, remap, remap_len);
+ }
+
+ /* adjust cap edge vertex indices */
+ me = result->medge + cap_edges_index;
+ for (i = 0; i < cap_nedges; i++, me++) {
+ me->v1 += cap_verts_index;
+ me->v2 += cap_verts_index;
+ }
+
+ /* adjust cap poly loopstart indices */
+ mp = result->mpoly + cap_polys_index;
+ for (i = 0; i < cap_npolys; i++, mp++) {
+ mp->loopstart += cap_loops_index;
+ }
+
+ /* adjust cap loop vertex and edge indices */
+ ml = result->mloop + cap_loops_index;
+ for (i = 0; i < cap_nloops; i++, ml++) {
+ ml->v += cap_verts_index;
+ ml->e += cap_edges_index;
+ }
+
+ /* set origindex */
+ index_orig = CustomData_get_layer(&result->vdata, CD_ORIGINDEX);
+ if (index_orig) {
+ copy_vn_i(index_orig + cap_verts_index, cap_nverts, ORIGINDEX_NONE);
+ }
+
+ index_orig = CustomData_get_layer(&result->edata, CD_ORIGINDEX);
+ if (index_orig) {
+ copy_vn_i(index_orig + cap_edges_index, cap_nedges, ORIGINDEX_NONE);
+ }
+
+ index_orig = CustomData_get_layer(&result->pdata, CD_ORIGINDEX);
+ if (index_orig) {
+ copy_vn_i(index_orig + cap_polys_index, cap_npolys, ORIGINDEX_NONE);
+ }
+
+ index_orig = CustomData_get_layer(&result->ldata, CD_ORIGINDEX);
+ if (index_orig) {
+ copy_vn_i(index_orig + cap_loops_index, cap_nloops, ORIGINDEX_NONE);
+ }
}
-static Mesh *arrayModifier_doArray(
- ArrayModifierData *amd, const ModifierEvalContext *ctx, Mesh *mesh)
+static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh)
{
- const float eps = 1e-6f;
- const MVert *src_mvert;
- MVert *mv, *mv_prev, *result_dm_verts;
-
- MEdge *me;
- MLoop *ml;
- MPoly *mp;
- int i, j, c, count;
- float length = amd->length;
- /* offset matrix */
- float offset[4][4];
- float scale[3];
- bool offset_has_scale;
- float current_offset[4][4];
- float final_offset[4][4];
- int *full_doubles_map = NULL;
- int tot_doubles;
-
- const bool use_merge = (amd->flags & MOD_ARR_MERGE) != 0;
- const bool use_recalc_normals = (mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) || use_merge;
- const bool use_offset_ob = ((amd->offset_type & MOD_ARR_OFF_OBJ) && amd->offset_ob != NULL);
-
- int start_cap_nverts = 0, start_cap_nedges = 0, start_cap_npolys = 0, start_cap_nloops = 0;
- int end_cap_nverts = 0, end_cap_nedges = 0, end_cap_npolys = 0, end_cap_nloops = 0;
- int result_nverts = 0, result_nedges = 0, result_npolys = 0, result_nloops = 0;
- int chunk_nverts, chunk_nedges, chunk_nloops, chunk_npolys;
- int first_chunk_start, first_chunk_nverts, last_chunk_start, last_chunk_nverts;
-
- Mesh *result, *start_cap_mesh = NULL, *end_cap_mesh = NULL;
-
- int *vgroup_start_cap_remap = NULL;
- int vgroup_start_cap_remap_len = 0;
- int *vgroup_end_cap_remap = NULL;
- int vgroup_end_cap_remap_len = 0;
-
- chunk_nverts = mesh->totvert;
- chunk_nedges = mesh->totedge;
- chunk_nloops = mesh->totloop;
- chunk_npolys = mesh->totpoly;
-
- count = amd->count;
-
- Object *start_cap_ob = amd->start_cap;
- if (start_cap_ob && start_cap_ob != ctx->object && start_cap_ob->type == OB_MESH) {
- vgroup_start_cap_remap = BKE_object_defgroup_index_map_create(
- start_cap_ob, ctx->object, &vgroup_start_cap_remap_len);
-
- start_cap_mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(start_cap_ob, false);
- if (start_cap_mesh) {
- start_cap_nverts = start_cap_mesh->totvert;
- start_cap_nedges = start_cap_mesh->totedge;
- start_cap_nloops = start_cap_mesh->totloop;
- start_cap_npolys = start_cap_mesh->totpoly;
- }
- }
- Object *end_cap_ob = amd->end_cap;
- if (end_cap_ob && end_cap_ob != ctx->object && end_cap_ob->type == OB_MESH) {
- vgroup_end_cap_remap = BKE_object_defgroup_index_map_create(
- end_cap_ob, ctx->object, &vgroup_end_cap_remap_len);
-
- end_cap_mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(end_cap_ob, false);
- if (end_cap_mesh) {
- end_cap_nverts = end_cap_mesh->totvert;
- end_cap_nedges = end_cap_mesh->totedge;
- end_cap_nloops = end_cap_mesh->totloop;
- end_cap_npolys = end_cap_mesh->totpoly;
- }
- }
-
- /* Build up offset array, cumulating all settings options */
-
- unit_m4(offset);
- src_mvert = mesh->mvert;
-
- if (amd->offset_type & MOD_ARR_OFF_CONST) {
- add_v3_v3(offset[3], amd->offset);
- }
-
- if (amd->offset_type & MOD_ARR_OFF_RELATIVE) {
- float min[3], max[3];
- const MVert *src_mv;
-
- INIT_MINMAX(min, max);
- for (src_mv = src_mvert, j = chunk_nverts; j--; src_mv++) {
- minmax_v3v3_v3(min, max, src_mv->co);
- }
-
- for (j = 3; j--; ) {
- offset[3][j] += amd->scale[j] * (max[j] - min[j]);
- }
- }
-
- if (use_offset_ob) {
- float obinv[4][4];
- float result_mat[4][4];
-
- if (ctx->object)
- invert_m4_m4(obinv, ctx->object->obmat);
- else
- unit_m4(obinv);
-
- mul_m4_series(result_mat, offset, obinv, amd->offset_ob->obmat);
- copy_m4_m4(offset, result_mat);
- }
-
- /* Check if there is some scaling. If scaling, then we will not translate mapping */
- mat4_to_size(scale, offset);
- offset_has_scale = !is_one_v3(scale);
-
- if (amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob != NULL) {
- Object *curve_ob = amd->curve_ob;
- Curve *cu = curve_ob->data;
- if (cu) {
- CurveCache *curve_cache = curve_ob->runtime.curve_cache;
- if (curve_cache != NULL && curve_cache->path != NULL) {
- float scale_fac = mat4_to_scale(curve_ob->obmat);
- length = scale_fac * curve_cache->path->totdist;
- }
- }
- }
-
- /* calculate the maximum number of copies which will fit within the
- * prescribed length */
- if (amd->fit_type == MOD_ARR_FITLENGTH || amd->fit_type == MOD_ARR_FITCURVE) {
- float dist = len_v3(offset[3]);
-
- if (dist > eps) {
- /* this gives length = first copy start to last copy end
- * add a tiny offset for floating point rounding errors */
- count = (length + eps) / dist + 1;
- }
- else {
- /* if the offset has no translation, just make one copy */
- count = 1;
- }
- }
-
- if (count < 1)
- count = 1;
-
- /* The number of verts, edges, loops, polys, before eventually merging doubles */
- result_nverts = chunk_nverts * count + start_cap_nverts + end_cap_nverts;
- result_nedges = chunk_nedges * count + start_cap_nedges + end_cap_nedges;
- result_nloops = chunk_nloops * count + start_cap_nloops + end_cap_nloops;
- result_npolys = chunk_npolys * count + start_cap_npolys + end_cap_npolys;
-
- /* Initialize a result dm */
- result = BKE_mesh_new_nomain_from_template(mesh, result_nverts, result_nedges, 0, result_nloops, result_npolys);
- result_dm_verts = result->mvert;
-
- if (use_merge) {
- /* Will need full_doubles_map for handling merge */
- full_doubles_map = MEM_malloc_arrayN(result_nverts, sizeof(int), "mod array doubles map");
- copy_vn_i(full_doubles_map, result_nverts, -1);
- }
-
- /* copy customdata to original geometry */
- CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, chunk_nverts);
- CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, chunk_nedges);
- CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, chunk_nloops);
- CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, chunk_npolys);
-
- /* Subsurf for eg won't have mesh data in the custom data arrays.
- * now add mvert/medge/mpoly layers. */
- if (!CustomData_has_layer(&mesh->vdata, CD_MVERT)) {
- memcpy(result->mvert, mesh->mvert, sizeof(*result->mvert) * mesh->totvert);
- }
- if (!CustomData_has_layer(&mesh->edata, CD_MEDGE)) {
- memcpy(result->medge, mesh->medge, sizeof(*result->medge) * mesh->totedge);
- }
- if (!CustomData_has_layer(&mesh->pdata, CD_MPOLY)) {
- memcpy(result->mloop, mesh->mloop, sizeof(*result->mloop) * mesh->totloop);
- memcpy(result->mpoly, mesh->mpoly, sizeof(*result->mpoly) * mesh->totpoly);
- }
-
- /* Remember first chunk, in case of cap merge */
- first_chunk_start = 0;
- first_chunk_nverts = chunk_nverts;
-
- unit_m4(current_offset);
- for (c = 1; c < count; c++) {
- /* copy customdata to new geometry */
- CustomData_copy_data(&mesh->vdata, &result->vdata, 0, c * chunk_nverts, chunk_nverts);
- CustomData_copy_data(&mesh->edata, &result->edata, 0, c * chunk_nedges, chunk_nedges);
- CustomData_copy_data(&mesh->ldata, &result->ldata, 0, c * chunk_nloops, chunk_nloops);
- CustomData_copy_data(&mesh->pdata, &result->pdata, 0, c * chunk_npolys, chunk_npolys);
-
- mv_prev = result_dm_verts;
- mv = mv_prev + c * chunk_nverts;
-
- /* recalculate cumulative offset here */
- mul_m4_m4m4(current_offset, current_offset, offset);
-
- /* apply offset to all new verts */
- for (i = 0; i < chunk_nverts; i++, mv++, mv_prev++) {
- mul_m4_v3(current_offset, mv->co);
-
- /* We have to correct normals too, if we do not tag them as dirty! */
- if (!use_recalc_normals) {
- float no[3];
- normal_short_to_float_v3(no, mv->no);
- mul_mat3_m4_v3(current_offset, no);
- normalize_v3(no);
- normal_float_to_short_v3(mv->no, no);
- }
- }
-
- /* adjust edge vertex indices */
- me = result->medge + c * chunk_nedges;
- for (i = 0; i < chunk_nedges; i++, me++) {
- me->v1 += c * chunk_nverts;
- me->v2 += c * chunk_nverts;
- }
-
- mp = result->mpoly + c * chunk_npolys;
- for (i = 0; i < chunk_npolys; i++, mp++) {
- mp->loopstart += c * chunk_nloops;
- }
-
- /* adjust loop vertex and edge indices */
- ml = result->mloop + c * chunk_nloops;
- for (i = 0; i < chunk_nloops; i++, ml++) {
- ml->v += c * chunk_nverts;
- ml->e += c * chunk_nedges;
- }
-
- /* Handle merge between chunk n and n-1 */
- if (use_merge && (c >= 1)) {
- if (!offset_has_scale && (c >= 2)) {
- /* Mapping chunk 3 to chunk 2 is a translation of mapping 2 to 1
- * ... that is except if scaling makes the distance grow */
- int k;
- int this_chunk_index = c * chunk_nverts;
- int prev_chunk_index = (c - 1) * chunk_nverts;
- for (k = 0; k < chunk_nverts; k++, this_chunk_index++, prev_chunk_index++) {
- int target = full_doubles_map[prev_chunk_index];
- if (target != -1) {
- target += chunk_nverts; /* translate mapping */
- while (target != -1 && !ELEM(full_doubles_map[target], -1, target)) {
- /* If target is already mapped, we only follow that mapping if final target remains
- * close enough from current vert (otherwise no mapping at all). */
- if (compare_len_v3v3(result_dm_verts[this_chunk_index].co,
- result_dm_verts[full_doubles_map[target]].co,
- amd->merge_dist))
- {
- target = full_doubles_map[target];
- }
- else {
- target = -1;
- }
- }
- }
- full_doubles_map[this_chunk_index] = target;
- }
- }
- else {
- dm_mvert_map_doubles(
- full_doubles_map,
- result_dm_verts,
- (c - 1) * chunk_nverts,
- chunk_nverts,
- c * chunk_nverts,
- chunk_nverts,
- amd->merge_dist);
- }
- }
- }
-
- /* handle UVs */
- if (chunk_nloops > 0 && is_zero_v2(amd->uv_offset) == false) {
- const int totuv = CustomData_number_of_layers(&result->ldata, CD_MLOOPUV);
- for (i = 0; i < totuv; i++) {
- MLoopUV *dmloopuv = CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, i);
- dmloopuv += chunk_nloops;
- for (c = 1; c < count; c++) {
- const float uv_offset[2] = {
- amd->uv_offset[0] * (float)c,
- amd->uv_offset[1] * (float)c,
- };
- int l_index = chunk_nloops;
- for (; l_index-- != 0; dmloopuv++) {
- dmloopuv->uv[0] += uv_offset[0];
- dmloopuv->uv[1] += uv_offset[1];
- }
- }
- }
- }
-
- last_chunk_start = (count - 1) * chunk_nverts;
- last_chunk_nverts = chunk_nverts;
-
- copy_m4_m4(final_offset, current_offset);
-
- if (use_merge && (amd->flags & MOD_ARR_MERGEFINAL) && (count > 1)) {
- /* Merge first and last copies */
- dm_mvert_map_doubles(
- full_doubles_map,
- result_dm_verts,
- last_chunk_start,
- last_chunk_nverts,
- first_chunk_start,
- first_chunk_nverts,
- amd->merge_dist);
- }
-
- /* start capping */
- if (start_cap_mesh) {
- float start_offset[4][4];
- int start_cap_start = result_nverts - start_cap_nverts - end_cap_nverts;
- invert_m4_m4(start_offset, offset);
- mesh_merge_transform(
- result, start_cap_mesh, start_offset,
- result_nverts - start_cap_nverts - end_cap_nverts,
- result_nedges - start_cap_nedges - end_cap_nedges,
- result_nloops - start_cap_nloops - end_cap_nloops,
- result_npolys - start_cap_npolys - end_cap_npolys,
- start_cap_nverts, start_cap_nedges, start_cap_nloops, start_cap_npolys,
- vgroup_start_cap_remap, vgroup_start_cap_remap_len);
- /* Identify doubles with first chunk */
- if (use_merge) {
- dm_mvert_map_doubles(
- full_doubles_map,
- result_dm_verts,
- first_chunk_start,
- first_chunk_nverts,
- start_cap_start,
- start_cap_nverts,
- amd->merge_dist);
- }
- }
-
- if (end_cap_mesh) {
- float end_offset[4][4];
- int end_cap_start = result_nverts - end_cap_nverts;
- mul_m4_m4m4(end_offset, current_offset, offset);
- mesh_merge_transform(
- result, end_cap_mesh, end_offset,
- result_nverts - end_cap_nverts,
- result_nedges - end_cap_nedges,
- result_nloops - end_cap_nloops,
- result_npolys - end_cap_npolys,
- end_cap_nverts, end_cap_nedges, end_cap_nloops, end_cap_npolys,
- vgroup_end_cap_remap, vgroup_end_cap_remap_len);
- /* Identify doubles with last chunk */
- if (use_merge) {
- dm_mvert_map_doubles(
- full_doubles_map,
- result_dm_verts,
- last_chunk_start,
- last_chunk_nverts,
- end_cap_start,
- end_cap_nverts,
- amd->merge_dist);
- }
- }
- /* done capping */
-
- /* Handle merging */
- tot_doubles = 0;
- if (use_merge) {
- for (i = 0; i < result_nverts; i++) {
- int new_i = full_doubles_map[i];
- if (new_i != -1) {
- /* We have to follow chains of doubles (merge start/end especially is likely to create some),
- * those are not supported at all by BKE_mesh_merge_verts! */
- while (!ELEM(full_doubles_map[new_i], -1, new_i)) {
- new_i = full_doubles_map[new_i];
- }
- if (i == new_i) {
- full_doubles_map[i] = -1;
- }
- else {
- full_doubles_map[i] = new_i;
- tot_doubles++;
- }
- }
- }
- if (tot_doubles > 0) {
- result = BKE_mesh_merge_verts(result, full_doubles_map, tot_doubles, MESH_MERGE_VERTS_DUMP_IF_EQUAL);
- }
- MEM_freeN(full_doubles_map);
- }
-
- /* In case org dm has dirty normals, or we made some merging, mark normals as dirty in new mesh!
- * TODO: we may need to set other dirty flags as well?
- */
- if (use_recalc_normals) {
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- }
-
- if (vgroup_start_cap_remap) {
- MEM_freeN(vgroup_start_cap_remap);
- }
- if (vgroup_end_cap_remap) {
- MEM_freeN(vgroup_end_cap_remap);
- }
-
- return result;
+ const float eps = 1e-6f;
+ const MVert *src_mvert;
+ MVert *mv, *mv_prev, *result_dm_verts;
+
+ MEdge *me;
+ MLoop *ml;
+ MPoly *mp;
+ int i, j, c, count;
+ float length = amd->length;
+ /* offset matrix */
+ float offset[4][4];
+ float scale[3];
+ bool offset_has_scale;
+ float current_offset[4][4];
+ float final_offset[4][4];
+ int *full_doubles_map = NULL;
+ int tot_doubles;
+
+ const bool use_merge = (amd->flags & MOD_ARR_MERGE) != 0;
+ const bool use_recalc_normals = (mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) || use_merge;
+ const bool use_offset_ob = ((amd->offset_type & MOD_ARR_OFF_OBJ) && amd->offset_ob != NULL);
+
+ int start_cap_nverts = 0, start_cap_nedges = 0, start_cap_npolys = 0, start_cap_nloops = 0;
+ int end_cap_nverts = 0, end_cap_nedges = 0, end_cap_npolys = 0, end_cap_nloops = 0;
+ int result_nverts = 0, result_nedges = 0, result_npolys = 0, result_nloops = 0;
+ int chunk_nverts, chunk_nedges, chunk_nloops, chunk_npolys;
+ int first_chunk_start, first_chunk_nverts, last_chunk_start, last_chunk_nverts;
+
+ Mesh *result, *start_cap_mesh = NULL, *end_cap_mesh = NULL;
+
+ int *vgroup_start_cap_remap = NULL;
+ int vgroup_start_cap_remap_len = 0;
+ int *vgroup_end_cap_remap = NULL;
+ int vgroup_end_cap_remap_len = 0;
+
+ chunk_nverts = mesh->totvert;
+ chunk_nedges = mesh->totedge;
+ chunk_nloops = mesh->totloop;
+ chunk_npolys = mesh->totpoly;
+
+ count = amd->count;
+
+ Object *start_cap_ob = amd->start_cap;
+ if (start_cap_ob && start_cap_ob != ctx->object && start_cap_ob->type == OB_MESH) {
+ vgroup_start_cap_remap = BKE_object_defgroup_index_map_create(
+ start_cap_ob, ctx->object, &vgroup_start_cap_remap_len);
+
+ start_cap_mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(start_cap_ob, false);
+ if (start_cap_mesh) {
+ start_cap_nverts = start_cap_mesh->totvert;
+ start_cap_nedges = start_cap_mesh->totedge;
+ start_cap_nloops = start_cap_mesh->totloop;
+ start_cap_npolys = start_cap_mesh->totpoly;
+ }
+ }
+ Object *end_cap_ob = amd->end_cap;
+ if (end_cap_ob && end_cap_ob != ctx->object && end_cap_ob->type == OB_MESH) {
+ vgroup_end_cap_remap = BKE_object_defgroup_index_map_create(
+ end_cap_ob, ctx->object, &vgroup_end_cap_remap_len);
+
+ end_cap_mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(end_cap_ob, false);
+ if (end_cap_mesh) {
+ end_cap_nverts = end_cap_mesh->totvert;
+ end_cap_nedges = end_cap_mesh->totedge;
+ end_cap_nloops = end_cap_mesh->totloop;
+ end_cap_npolys = end_cap_mesh->totpoly;
+ }
+ }
+
+ /* Build up offset array, cumulating all settings options */
+
+ unit_m4(offset);
+ src_mvert = mesh->mvert;
+
+ if (amd->offset_type & MOD_ARR_OFF_CONST) {
+ add_v3_v3(offset[3], amd->offset);
+ }
+
+ if (amd->offset_type & MOD_ARR_OFF_RELATIVE) {
+ float min[3], max[3];
+ const MVert *src_mv;
+
+ INIT_MINMAX(min, max);
+ for (src_mv = src_mvert, j = chunk_nverts; j--; src_mv++) {
+ minmax_v3v3_v3(min, max, src_mv->co);
+ }
+
+ for (j = 3; j--;) {
+ offset[3][j] += amd->scale[j] * (max[j] - min[j]);
+ }
+ }
+
+ if (use_offset_ob) {
+ float obinv[4][4];
+ float result_mat[4][4];
+
+ if (ctx->object)
+ invert_m4_m4(obinv, ctx->object->obmat);
+ else
+ unit_m4(obinv);
+
+ mul_m4_series(result_mat, offset, obinv, amd->offset_ob->obmat);
+ copy_m4_m4(offset, result_mat);
+ }
+
+ /* Check if there is some scaling. If scaling, then we will not translate mapping */
+ mat4_to_size(scale, offset);
+ offset_has_scale = !is_one_v3(scale);
+
+ if (amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob != NULL) {
+ Object *curve_ob = amd->curve_ob;
+ Curve *cu = curve_ob->data;
+ if (cu) {
+ CurveCache *curve_cache = curve_ob->runtime.curve_cache;
+ if (curve_cache != NULL && curve_cache->path != NULL) {
+ float scale_fac = mat4_to_scale(curve_ob->obmat);
+ length = scale_fac * curve_cache->path->totdist;
+ }
+ }
+ }
+
+ /* calculate the maximum number of copies which will fit within the
+ * prescribed length */
+ if (amd->fit_type == MOD_ARR_FITLENGTH || amd->fit_type == MOD_ARR_FITCURVE) {
+ float dist = len_v3(offset[3]);
+
+ if (dist > eps) {
+ /* this gives length = first copy start to last copy end
+ * add a tiny offset for floating point rounding errors */
+ count = (length + eps) / dist + 1;
+ }
+ else {
+ /* if the offset has no translation, just make one copy */
+ count = 1;
+ }
+ }
+
+ if (count < 1)
+ count = 1;
+
+ /* The number of verts, edges, loops, polys, before eventually merging doubles */
+ result_nverts = chunk_nverts * count + start_cap_nverts + end_cap_nverts;
+ result_nedges = chunk_nedges * count + start_cap_nedges + end_cap_nedges;
+ result_nloops = chunk_nloops * count + start_cap_nloops + end_cap_nloops;
+ result_npolys = chunk_npolys * count + start_cap_npolys + end_cap_npolys;
+
+ /* Initialize a result dm */
+ result = BKE_mesh_new_nomain_from_template(
+ mesh, result_nverts, result_nedges, 0, result_nloops, result_npolys);
+ result_dm_verts = result->mvert;
+
+ if (use_merge) {
+ /* Will need full_doubles_map for handling merge */
+ full_doubles_map = MEM_malloc_arrayN(result_nverts, sizeof(int), "mod array doubles map");
+ copy_vn_i(full_doubles_map, result_nverts, -1);
+ }
+
+ /* copy customdata to original geometry */
+ CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, chunk_nverts);
+ CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, chunk_nedges);
+ CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, chunk_nloops);
+ CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, chunk_npolys);
+
+ /* Subsurf for eg won't have mesh data in the custom data arrays.
+ * now add mvert/medge/mpoly layers. */
+ if (!CustomData_has_layer(&mesh->vdata, CD_MVERT)) {
+ memcpy(result->mvert, mesh->mvert, sizeof(*result->mvert) * mesh->totvert);
+ }
+ if (!CustomData_has_layer(&mesh->edata, CD_MEDGE)) {
+ memcpy(result->medge, mesh->medge, sizeof(*result->medge) * mesh->totedge);
+ }
+ if (!CustomData_has_layer(&mesh->pdata, CD_MPOLY)) {
+ memcpy(result->mloop, mesh->mloop, sizeof(*result->mloop) * mesh->totloop);
+ memcpy(result->mpoly, mesh->mpoly, sizeof(*result->mpoly) * mesh->totpoly);
+ }
+
+ /* Remember first chunk, in case of cap merge */
+ first_chunk_start = 0;
+ first_chunk_nverts = chunk_nverts;
+
+ unit_m4(current_offset);
+ for (c = 1; c < count; c++) {
+ /* copy customdata to new geometry */
+ CustomData_copy_data(&mesh->vdata, &result->vdata, 0, c * chunk_nverts, chunk_nverts);
+ CustomData_copy_data(&mesh->edata, &result->edata, 0, c * chunk_nedges, chunk_nedges);
+ CustomData_copy_data(&mesh->ldata, &result->ldata, 0, c * chunk_nloops, chunk_nloops);
+ CustomData_copy_data(&mesh->pdata, &result->pdata, 0, c * chunk_npolys, chunk_npolys);
+
+ mv_prev = result_dm_verts;
+ mv = mv_prev + c * chunk_nverts;
+
+ /* recalculate cumulative offset here */
+ mul_m4_m4m4(current_offset, current_offset, offset);
+
+ /* apply offset to all new verts */
+ for (i = 0; i < chunk_nverts; i++, mv++, mv_prev++) {
+ mul_m4_v3(current_offset, mv->co);
+
+ /* We have to correct normals too, if we do not tag them as dirty! */
+ if (!use_recalc_normals) {
+ float no[3];
+ normal_short_to_float_v3(no, mv->no);
+ mul_mat3_m4_v3(current_offset, no);
+ normalize_v3(no);
+ normal_float_to_short_v3(mv->no, no);
+ }
+ }
+
+ /* adjust edge vertex indices */
+ me = result->medge + c * chunk_nedges;
+ for (i = 0; i < chunk_nedges; i++, me++) {
+ me->v1 += c * chunk_nverts;
+ me->v2 += c * chunk_nverts;
+ }
+
+ mp = result->mpoly + c * chunk_npolys;
+ for (i = 0; i < chunk_npolys; i++, mp++) {
+ mp->loopstart += c * chunk_nloops;
+ }
+
+ /* adjust loop vertex and edge indices */
+ ml = result->mloop + c * chunk_nloops;
+ for (i = 0; i < chunk_nloops; i++, ml++) {
+ ml->v += c * chunk_nverts;
+ ml->e += c * chunk_nedges;
+ }
+
+ /* Handle merge between chunk n and n-1 */
+ if (use_merge && (c >= 1)) {
+ if (!offset_has_scale && (c >= 2)) {
+ /* Mapping chunk 3 to chunk 2 is a translation of mapping 2 to 1
+ * ... that is except if scaling makes the distance grow */
+ int k;
+ int this_chunk_index = c * chunk_nverts;
+ int prev_chunk_index = (c - 1) * chunk_nverts;
+ for (k = 0; k < chunk_nverts; k++, this_chunk_index++, prev_chunk_index++) {
+ int target = full_doubles_map[prev_chunk_index];
+ if (target != -1) {
+ target += chunk_nverts; /* translate mapping */
+ while (target != -1 && !ELEM(full_doubles_map[target], -1, target)) {
+ /* If target is already mapped, we only follow that mapping if final target remains
+ * close enough from current vert (otherwise no mapping at all). */
+ if (compare_len_v3v3(result_dm_verts[this_chunk_index].co,
+ result_dm_verts[full_doubles_map[target]].co,
+ amd->merge_dist)) {
+ target = full_doubles_map[target];
+ }
+ else {
+ target = -1;
+ }
+ }
+ }
+ full_doubles_map[this_chunk_index] = target;
+ }
+ }
+ else {
+ dm_mvert_map_doubles(full_doubles_map,
+ result_dm_verts,
+ (c - 1) * chunk_nverts,
+ chunk_nverts,
+ c * chunk_nverts,
+ chunk_nverts,
+ amd->merge_dist);
+ }
+ }
+ }
+
+ /* handle UVs */
+ if (chunk_nloops > 0 && is_zero_v2(amd->uv_offset) == false) {
+ const int totuv = CustomData_number_of_layers(&result->ldata, CD_MLOOPUV);
+ for (i = 0; i < totuv; i++) {
+ MLoopUV *dmloopuv = CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, i);
+ dmloopuv += chunk_nloops;
+ for (c = 1; c < count; c++) {
+ const float uv_offset[2] = {
+ amd->uv_offset[0] * (float)c,
+ amd->uv_offset[1] * (float)c,
+ };
+ int l_index = chunk_nloops;
+ for (; l_index-- != 0; dmloopuv++) {
+ dmloopuv->uv[0] += uv_offset[0];
+ dmloopuv->uv[1] += uv_offset[1];
+ }
+ }
+ }
+ }
+
+ last_chunk_start = (count - 1) * chunk_nverts;
+ last_chunk_nverts = chunk_nverts;
+
+ copy_m4_m4(final_offset, current_offset);
+
+ if (use_merge && (amd->flags & MOD_ARR_MERGEFINAL) && (count > 1)) {
+ /* Merge first and last copies */
+ dm_mvert_map_doubles(full_doubles_map,
+ result_dm_verts,
+ last_chunk_start,
+ last_chunk_nverts,
+ first_chunk_start,
+ first_chunk_nverts,
+ amd->merge_dist);
+ }
+
+ /* start capping */
+ if (start_cap_mesh) {
+ float start_offset[4][4];
+ int start_cap_start = result_nverts - start_cap_nverts - end_cap_nverts;
+ invert_m4_m4(start_offset, offset);
+ mesh_merge_transform(result,
+ start_cap_mesh,
+ start_offset,
+ result_nverts - start_cap_nverts - end_cap_nverts,
+ result_nedges - start_cap_nedges - end_cap_nedges,
+ result_nloops - start_cap_nloops - end_cap_nloops,
+ result_npolys - start_cap_npolys - end_cap_npolys,
+ start_cap_nverts,
+ start_cap_nedges,
+ start_cap_nloops,
+ start_cap_npolys,
+ vgroup_start_cap_remap,
+ vgroup_start_cap_remap_len);
+ /* Identify doubles with first chunk */
+ if (use_merge) {
+ dm_mvert_map_doubles(full_doubles_map,
+ result_dm_verts,
+ first_chunk_start,
+ first_chunk_nverts,
+ start_cap_start,
+ start_cap_nverts,
+ amd->merge_dist);
+ }
+ }
+
+ if (end_cap_mesh) {
+ float end_offset[4][4];
+ int end_cap_start = result_nverts - end_cap_nverts;
+ mul_m4_m4m4(end_offset, current_offset, offset);
+ mesh_merge_transform(result,
+ end_cap_mesh,
+ end_offset,
+ result_nverts - end_cap_nverts,
+ result_nedges - end_cap_nedges,
+ result_nloops - end_cap_nloops,
+ result_npolys - end_cap_npolys,
+ end_cap_nverts,
+ end_cap_nedges,
+ end_cap_nloops,
+ end_cap_npolys,
+ vgroup_end_cap_remap,
+ vgroup_end_cap_remap_len);
+ /* Identify doubles with last chunk */
+ if (use_merge) {
+ dm_mvert_map_doubles(full_doubles_map,
+ result_dm_verts,
+ last_chunk_start,
+ last_chunk_nverts,
+ end_cap_start,
+ end_cap_nverts,
+ amd->merge_dist);
+ }
+ }
+ /* done capping */
+
+ /* Handle merging */
+ tot_doubles = 0;
+ if (use_merge) {
+ for (i = 0; i < result_nverts; i++) {
+ int new_i = full_doubles_map[i];
+ if (new_i != -1) {
+ /* We have to follow chains of doubles (merge start/end especially is likely to create some),
+ * those are not supported at all by BKE_mesh_merge_verts! */
+ while (!ELEM(full_doubles_map[new_i], -1, new_i)) {
+ new_i = full_doubles_map[new_i];
+ }
+ if (i == new_i) {
+ full_doubles_map[i] = -1;
+ }
+ else {
+ full_doubles_map[i] = new_i;
+ tot_doubles++;
+ }
+ }
+ }
+ if (tot_doubles > 0) {
+ result = BKE_mesh_merge_verts(
+ result, full_doubles_map, tot_doubles, MESH_MERGE_VERTS_DUMP_IF_EQUAL);
+ }
+ MEM_freeN(full_doubles_map);
+ }
+
+ /* In case org dm has dirty normals, or we made some merging, mark normals as dirty in new mesh!
+ * TODO: we may need to set other dirty flags as well?
+ */
+ if (use_recalc_normals) {
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ }
+
+ if (vgroup_start_cap_remap) {
+ MEM_freeN(vgroup_start_cap_remap);
+ }
+ if (vgroup_end_cap_remap) {
+ MEM_freeN(vgroup_end_cap_remap);
+ }
+
+ return result;
}
-
-static Mesh *applyModifier(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- ArrayModifierData *amd = (ArrayModifierData *) md;
- return arrayModifier_doArray(amd, ctx, mesh);
+ ArrayModifierData *amd = (ArrayModifierData *)md;
+ return arrayModifier_doArray(amd, ctx, mesh);
}
-
ModifierTypeInfo modifierType_Array = {
- /* name */ "Array",
- /* structName */ "ArrayModifierData",
- /* structSize */ sizeof(ArrayModifierData),
- /* type */ eModifierTypeType_Constructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsMapping |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_EnableInEditmode |
- eModifierTypeFlag_AcceptsCVs,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ NULL,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Array",
+ /* structName */ "ArrayModifierData",
+ /* structSize */ sizeof(ArrayModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode |
+ eModifierTypeFlag_AcceptsCVs,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c
index 567c74effe0..32a020a35ff 100644
--- a/source/blender/modifiers/intern/MOD_bevel.c
+++ b/source/blender/modifiers/intern/MOD_bevel.c
@@ -45,38 +45,40 @@
static void initData(ModifierData *md)
{
- BevelModifierData *bmd = (BevelModifierData *) md;
-
- bmd->value = 0.1f;
- bmd->res = 1;
- bmd->flags = 0;
- bmd->val_flags = MOD_BEVEL_AMT_OFFSET;
- bmd->lim_flags = 0;
- bmd->e_flags = 0;
- bmd->edge_flags = 0;
- bmd->face_str_mode = MOD_BEVEL_FACE_STRENGTH_NONE;
- bmd->miter_inner = MOD_BEVEL_MITER_SHARP;
- bmd->miter_outer = MOD_BEVEL_MITER_SHARP;
- bmd->spread = 0.1f;
- bmd->mat = -1;
- bmd->profile = 0.5f;
- bmd->bevel_angle = DEG2RADF(30.0f);
- bmd->defgrp_name[0] = '\0';
+ BevelModifierData *bmd = (BevelModifierData *)md;
+
+ bmd->value = 0.1f;
+ bmd->res = 1;
+ bmd->flags = 0;
+ bmd->val_flags = MOD_BEVEL_AMT_OFFSET;
+ bmd->lim_flags = 0;
+ bmd->e_flags = 0;
+ bmd->edge_flags = 0;
+ bmd->face_str_mode = MOD_BEVEL_FACE_STRENGTH_NONE;
+ bmd->miter_inner = MOD_BEVEL_MITER_SHARP;
+ bmd->miter_outer = MOD_BEVEL_MITER_SHARP;
+ bmd->spread = 0.1f;
+ bmd->mat = -1;
+ bmd->profile = 0.5f;
+ bmd->bevel_angle = DEG2RADF(30.0f);
+ bmd->defgrp_name[0] = '\0';
}
static void copyData(const ModifierData *md_src, ModifierData *md_dst, const int flag)
{
- modifier_copyData_generic(md_src, md_dst, flag);
+ modifier_copyData_generic(md_src, md_dst, flag);
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- BevelModifierData *bmd = (BevelModifierData *)md;
+ BevelModifierData *bmd = (BevelModifierData *)md;
- /* ask for vertexgroups if we need them */
- if (bmd->defgrp_name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ /* ask for vertexgroups if we need them */
+ if (bmd->defgrp_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
/*
@@ -84,154 +86,168 @@ static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_Me
*/
static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- Mesh *result;
- BMesh *bm;
- BMIter iter;
- BMEdge *e;
- BMVert *v;
- float weight, weight2;
- int vgroup = -1;
- MDeformVert *dvert = NULL;
- BevelModifierData *bmd = (BevelModifierData *) md;
- const float threshold = cosf(bmd->bevel_angle + 0.000000175f);
- const bool vertex_only = (bmd->flags & MOD_BEVEL_VERT) != 0;
- const bool do_clamp = !(bmd->flags & MOD_BEVEL_OVERLAP_OK);
- const int offset_type = bmd->val_flags;
- const float value = bmd->value;
- const int mat = CLAMPIS(bmd->mat, -1, ctx->object->totcol - 1);
- const bool loop_slide = (bmd->flags & MOD_BEVEL_EVEN_WIDTHS) == 0;
- const bool mark_seam = (bmd->edge_flags & MOD_BEVEL_MARK_SEAM);
- const bool mark_sharp = (bmd->edge_flags & MOD_BEVEL_MARK_SHARP);
- bool harden_normals = (bmd->flags & MOD_BEVEL_HARDEN_NORMALS);
- const int face_strength_mode = bmd->face_str_mode;
- const int miter_outer = bmd->miter_outer;
- const int miter_inner = bmd->miter_inner;
- const float spread = bmd->spread;
-
- bm = BKE_mesh_to_bmesh_ex(
- mesh,
- &(struct BMeshCreateParams){0},
- &(struct BMeshFromMeshParams){
- .calc_face_normal = true,
- .add_key_index = false,
- .use_shapekey = false,
- .active_shapekey = 0,
- /* XXX We probably can use CD_MASK_BAREMESH_ORIGDINDEX here instead (also for other modifiers cases)? */
- .cd_mask_extra = {.vmask = CD_MASK_ORIGINDEX, .emask = CD_MASK_ORIGINDEX, .pmask = CD_MASK_ORIGINDEX},
- });
-
- if ((bmd->lim_flags & MOD_BEVEL_VGROUP) && bmd->defgrp_name[0])
- MOD_get_vgroup(ctx->object, mesh, bmd->defgrp_name, &dvert, &vgroup);
-
- if (vertex_only) {
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- if (!BM_vert_is_manifold(v))
- continue;
- if (bmd->lim_flags & MOD_BEVEL_WEIGHT) {
- weight = BM_elem_float_data_get(&bm->vdata, v, CD_BWEIGHT);
- if (weight == 0.0f)
- continue;
- }
- else if (vgroup != -1) {
- weight = defvert_array_find_weight_safe(dvert, BM_elem_index_get(v), vgroup);
- /* Check is against 0.5 rather than != 0.0 because cascaded bevel modifiers will
- * interpolate weights for newly created vertices, and may cause unexpected "selection" */
- if (weight < 0.5f)
- continue;
- }
- BM_elem_flag_enable(v, BM_ELEM_TAG);
- }
- }
- else if (bmd->lim_flags & MOD_BEVEL_ANGLE) {
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- /* check for 1 edge having 2 face users */
- BMLoop *l_a, *l_b;
- if (BM_edge_loop_pair(e, &l_a, &l_b)) {
- if (dot_v3v3(l_a->f->no, l_b->f->no) < threshold) {
- BM_elem_flag_enable(e, BM_ELEM_TAG);
- BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
- BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
- }
- }
- }
- }
- else {
- /* crummy, is there a way just to operator on all? - campbell */
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_edge_is_manifold(e)) {
- if (bmd->lim_flags & MOD_BEVEL_WEIGHT) {
- weight = BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT);
- if (weight == 0.0f)
- continue;
- }
- else if (vgroup != -1) {
- weight = defvert_array_find_weight_safe(dvert, BM_elem_index_get(e->v1), vgroup);
- weight2 = defvert_array_find_weight_safe(dvert, BM_elem_index_get(e->v2), vgroup);
- if (weight < 0.5f || weight2 < 0.5f)
- continue;
- }
- BM_elem_flag_enable(e, BM_ELEM_TAG);
- BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
- BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
- }
- }
- }
-
- if (harden_normals && !(((Mesh *)ctx->object->data)->flag & ME_AUTOSMOOTH)) {
- modifier_setError(md, "Enable 'Auto Smooth' option in mesh settings for hardening");
- harden_normals = false;
- }
-
- BM_mesh_bevel(bm, value, offset_type, bmd->res, bmd->profile,
- vertex_only, bmd->lim_flags & MOD_BEVEL_WEIGHT, do_clamp,
- dvert, vgroup, mat, loop_slide, mark_seam, mark_sharp,
- harden_normals, face_strength_mode,
- miter_outer, miter_inner, spread, mesh->smoothresh);
-
- result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
-
- BLI_assert(bm->vtoolflagpool == NULL &&
- bm->etoolflagpool == NULL &&
- bm->ftoolflagpool == NULL); /* make sure we never alloc'd these */
- BM_mesh_free(bm);
-
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
-
- return result;
+ Mesh *result;
+ BMesh *bm;
+ BMIter iter;
+ BMEdge *e;
+ BMVert *v;
+ float weight, weight2;
+ int vgroup = -1;
+ MDeformVert *dvert = NULL;
+ BevelModifierData *bmd = (BevelModifierData *)md;
+ const float threshold = cosf(bmd->bevel_angle + 0.000000175f);
+ const bool vertex_only = (bmd->flags & MOD_BEVEL_VERT) != 0;
+ const bool do_clamp = !(bmd->flags & MOD_BEVEL_OVERLAP_OK);
+ const int offset_type = bmd->val_flags;
+ const float value = bmd->value;
+ const int mat = CLAMPIS(bmd->mat, -1, ctx->object->totcol - 1);
+ const bool loop_slide = (bmd->flags & MOD_BEVEL_EVEN_WIDTHS) == 0;
+ const bool mark_seam = (bmd->edge_flags & MOD_BEVEL_MARK_SEAM);
+ const bool mark_sharp = (bmd->edge_flags & MOD_BEVEL_MARK_SHARP);
+ bool harden_normals = (bmd->flags & MOD_BEVEL_HARDEN_NORMALS);
+ const int face_strength_mode = bmd->face_str_mode;
+ const int miter_outer = bmd->miter_outer;
+ const int miter_inner = bmd->miter_inner;
+ const float spread = bmd->spread;
+
+ bm = BKE_mesh_to_bmesh_ex(
+ mesh,
+ &(struct BMeshCreateParams){0},
+ &(struct BMeshFromMeshParams){
+ .calc_face_normal = true,
+ .add_key_index = false,
+ .use_shapekey = false,
+ .active_shapekey = 0,
+ /* XXX We probably can use CD_MASK_BAREMESH_ORIGDINDEX here instead (also for other modifiers cases)? */
+ .cd_mask_extra = {.vmask = CD_MASK_ORIGINDEX,
+ .emask = CD_MASK_ORIGINDEX,
+ .pmask = CD_MASK_ORIGINDEX},
+ });
+
+ if ((bmd->lim_flags & MOD_BEVEL_VGROUP) && bmd->defgrp_name[0])
+ MOD_get_vgroup(ctx->object, mesh, bmd->defgrp_name, &dvert, &vgroup);
+
+ if (vertex_only) {
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ if (!BM_vert_is_manifold(v))
+ continue;
+ if (bmd->lim_flags & MOD_BEVEL_WEIGHT) {
+ weight = BM_elem_float_data_get(&bm->vdata, v, CD_BWEIGHT);
+ if (weight == 0.0f)
+ continue;
+ }
+ else if (vgroup != -1) {
+ weight = defvert_array_find_weight_safe(dvert, BM_elem_index_get(v), vgroup);
+ /* Check is against 0.5 rather than != 0.0 because cascaded bevel modifiers will
+ * interpolate weights for newly created vertices, and may cause unexpected "selection" */
+ if (weight < 0.5f)
+ continue;
+ }
+ BM_elem_flag_enable(v, BM_ELEM_TAG);
+ }
+ }
+ else if (bmd->lim_flags & MOD_BEVEL_ANGLE) {
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ /* check for 1 edge having 2 face users */
+ BMLoop *l_a, *l_b;
+ if (BM_edge_loop_pair(e, &l_a, &l_b)) {
+ if (dot_v3v3(l_a->f->no, l_b->f->no) < threshold) {
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
+ BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
+ }
+ }
+ }
+ }
+ else {
+ /* crummy, is there a way just to operator on all? - campbell */
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_edge_is_manifold(e)) {
+ if (bmd->lim_flags & MOD_BEVEL_WEIGHT) {
+ weight = BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT);
+ if (weight == 0.0f)
+ continue;
+ }
+ else if (vgroup != -1) {
+ weight = defvert_array_find_weight_safe(dvert, BM_elem_index_get(e->v1), vgroup);
+ weight2 = defvert_array_find_weight_safe(dvert, BM_elem_index_get(e->v2), vgroup);
+ if (weight < 0.5f || weight2 < 0.5f)
+ continue;
+ }
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
+ BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
+ }
+ }
+ }
+
+ if (harden_normals && !(((Mesh *)ctx->object->data)->flag & ME_AUTOSMOOTH)) {
+ modifier_setError(md, "Enable 'Auto Smooth' option in mesh settings for hardening");
+ harden_normals = false;
+ }
+
+ BM_mesh_bevel(bm,
+ value,
+ offset_type,
+ bmd->res,
+ bmd->profile,
+ vertex_only,
+ bmd->lim_flags & MOD_BEVEL_WEIGHT,
+ do_clamp,
+ dvert,
+ vgroup,
+ mat,
+ loop_slide,
+ mark_seam,
+ mark_sharp,
+ harden_normals,
+ face_strength_mode,
+ miter_outer,
+ miter_inner,
+ spread,
+ mesh->smoothresh);
+
+ result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
+
+ BLI_assert(bm->vtoolflagpool == NULL && bm->etoolflagpool == NULL &&
+ bm->ftoolflagpool == NULL); /* make sure we never alloc'd these */
+ BM_mesh_free(bm);
+
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+
+ return result;
}
static bool dependsOnNormals(ModifierData *UNUSED(md))
{
- return true;
+ return true;
}
ModifierTypeInfo modifierType_Bevel = {
- /* name */ "Bevel",
- /* structName */ "BevelModifierData",
- /* structSize */ sizeof(BevelModifierData),
- /* type */ eModifierTypeType_Constructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_EnableInEditmode |
- eModifierTypeFlag_AcceptsCVs,
-
- /* copyData */ copyData,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Bevel",
+ /* structName */ "BevelModifierData",
+ /* structSize */ sizeof(BevelModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode |
+ eModifierTypeFlag_EnableInEditmode | eModifierTypeFlag_AcceptsCVs,
+
+ /* copyData */ copyData,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ dependsOnNormals,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c
index 8e3a19e524a..6e6f98e9889 100644
--- a/source/blender/modifiers/intern/MOD_boolean.c
+++ b/source/blender/modifiers/intern/MOD_boolean.c
@@ -35,14 +35,13 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "BKE_global.h" /* only to check G.debug */
+#include "BKE_global.h" /* only to check G.debug */
#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
-
#include "MOD_util.h"
#include "DEG_depsgraph_query.h"
@@ -60,87 +59,84 @@
static void initData(ModifierData *md)
{
- BooleanModifierData *bmd = (BooleanModifierData *)md;
+ BooleanModifierData *bmd = (BooleanModifierData *)md;
- bmd->double_threshold = 1e-6f;
- bmd->operation = eBooleanModifierOp_Difference;
+ bmd->double_threshold = 1e-6f;
+ bmd->operation = eBooleanModifierOp_Difference;
}
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(useRenderParams))
{
- BooleanModifierData *bmd = (BooleanModifierData *) md;
+ BooleanModifierData *bmd = (BooleanModifierData *)md;
- return !bmd->object;
+ return !bmd->object;
}
-static void foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- BooleanModifierData *bmd = (BooleanModifierData *) md;
+ BooleanModifierData *bmd = (BooleanModifierData *)md;
- walk(userData, ob, &bmd->object, IDWALK_CB_NOP);
+ walk(userData, ob, &bmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- BooleanModifierData *bmd = (BooleanModifierData *)md;
- if (bmd->object != NULL) {
- DEG_add_object_relation(ctx->node, bmd->object, DEG_OB_COMP_TRANSFORM, "Boolean Modifier");
- DEG_add_object_relation(ctx->node, bmd->object, DEG_OB_COMP_GEOMETRY, "Boolean Modifier");
- }
- /* We need own transformation as well. */
- DEG_add_modifier_to_transform_relation(ctx->node, "Boolean Modifier");
+ BooleanModifierData *bmd = (BooleanModifierData *)md;
+ if (bmd->object != NULL) {
+ DEG_add_object_relation(ctx->node, bmd->object, DEG_OB_COMP_TRANSFORM, "Boolean Modifier");
+ DEG_add_object_relation(ctx->node, bmd->object, DEG_OB_COMP_GEOMETRY, "Boolean Modifier");
+ }
+ /* We need own transformation as well. */
+ DEG_add_modifier_to_transform_relation(ctx->node, "Boolean Modifier");
}
static Mesh *get_quick_mesh(
- Object *ob_self, Mesh *mesh_self,
- Object *ob_other, Mesh *mesh_other,
- int operation)
+ Object *ob_self, Mesh *mesh_self, Object *ob_other, Mesh *mesh_other, int operation)
{
- Mesh *result = NULL;
+ Mesh *result = NULL;
- if (mesh_self->totpoly == 0 || mesh_other->totpoly == 0) {
- switch (operation) {
- case eBooleanModifierOp_Intersect:
- result = BKE_mesh_new_nomain(0, 0, 0, 0, 0);
- break;
+ if (mesh_self->totpoly == 0 || mesh_other->totpoly == 0) {
+ switch (operation) {
+ case eBooleanModifierOp_Intersect:
+ result = BKE_mesh_new_nomain(0, 0, 0, 0, 0);
+ break;
- case eBooleanModifierOp_Union:
- if (mesh_self->totpoly != 0) {
- result = mesh_self;
- }
- else {
- BKE_id_copy_ex(NULL, &mesh_other->id, (ID **)&result, LIB_ID_COPY_LOCALIZE);
+ case eBooleanModifierOp_Union:
+ if (mesh_self->totpoly != 0) {
+ result = mesh_self;
+ }
+ else {
+ BKE_id_copy_ex(NULL, &mesh_other->id, (ID **)&result, LIB_ID_COPY_LOCALIZE);
- float imat[4][4];
- float omat[4][4];
+ float imat[4][4];
+ float omat[4][4];
- invert_m4_m4(imat, ob_self->obmat);
- mul_m4_m4m4(omat, imat, ob_other->obmat);
+ invert_m4_m4(imat, ob_self->obmat);
+ mul_m4_m4m4(omat, imat, ob_other->obmat);
- const int mverts_len = result->totvert;
- MVert *mv = result->mvert;
+ const int mverts_len = result->totvert;
+ MVert *mv = result->mvert;
- for (int i = 0; i < mverts_len; i++, mv++) {
- mul_m4_v3(omat, mv->co);
- }
+ for (int i = 0; i < mverts_len; i++, mv++) {
+ mul_m4_v3(omat, mv->co);
+ }
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- }
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ }
- break;
+ break;
- case eBooleanModifierOp_Difference:
- result = mesh_self;
- break;
- }
- }
+ case eBooleanModifierOp_Difference:
+ result = mesh_self;
+ break;
+ }
+ }
- return result;
+ return result;
}
-
/* has no meaning for faces, do this so we can tell which face is which */
#define BM_FACE_TAG BM_ELEM_DRAW
@@ -149,210 +145,224 @@ static Mesh *get_quick_mesh(
*/
static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data))
{
- return BM_elem_flag_test(f, BM_FACE_TAG) ? 1 : 0;
+ return BM_elem_flag_test(f, BM_FACE_TAG) ? 1 : 0;
}
static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- BooleanModifierData *bmd = (BooleanModifierData *) md;
- Mesh *result = mesh;
+ BooleanModifierData *bmd = (BooleanModifierData *)md;
+ Mesh *result = mesh;
- Mesh *mesh_other;
+ Mesh *mesh_other;
- if (bmd->object == NULL) {
- return result;
- }
+ if (bmd->object == NULL) {
+ return result;
+ }
- Object *other = bmd->object;
- mesh_other = BKE_modifier_get_evaluated_mesh_from_evaluated_object(other, false);
- if (mesh_other) {
- Object *object = ctx->object;
+ Object *other = bmd->object;
+ mesh_other = BKE_modifier_get_evaluated_mesh_from_evaluated_object(other, false);
+ if (mesh_other) {
+ Object *object = ctx->object;
- /* when one of objects is empty (has got no faces) we could speed up
- * calculation a bit returning one of objects' derived meshes (or empty one)
- * Returning mesh is depended on modifiers operation (sergey) */
- result = get_quick_mesh(object, mesh, other, mesh_other, bmd->operation);
+ /* when one of objects is empty (has got no faces) we could speed up
+ * calculation a bit returning one of objects' derived meshes (or empty one)
+ * Returning mesh is depended on modifiers operation (sergey) */
+ result = get_quick_mesh(object, mesh, other, mesh_other, bmd->operation);
- if (result == NULL) {
- const bool is_flip = (is_negative_m4(object->obmat) != is_negative_m4(other->obmat));
+ if (result == NULL) {
+ const bool is_flip = (is_negative_m4(object->obmat) != is_negative_m4(other->obmat));
- BMesh *bm;
- const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh, mesh_other);
+ BMesh *bm;
+ const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh, mesh_other);
#ifdef DEBUG_TIME
- TIMEIT_START(boolean_bmesh);
+ TIMEIT_START(boolean_bmesh);
#endif
- bm = BM_mesh_create(
- &allocsize,
- &((struct BMeshCreateParams){.use_toolflags = false,}));
-
- BM_mesh_bm_from_me(bm, mesh_other, &((struct BMeshFromMeshParams){.calc_face_normal = true,}));
-
- if (UNLIKELY(is_flip)) {
- const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
- BMIter iter;
- BMFace *efa;
- BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- BM_face_normal_flip_ex(bm, efa, cd_loop_mdisp_offset, true);
- }
- }
-
- BM_mesh_bm_from_me(bm, mesh, &((struct BMeshFromMeshParams){.calc_face_normal = true,}));
-
- /* main bmesh intersection setup */
- {
- /* create tessface & intersect */
- const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
- int tottri;
- BMLoop *(*looptris)[3];
-
- looptris = MEM_malloc_arrayN(looptris_tot, sizeof(*looptris), __func__);
-
- BM_mesh_calc_tessellation_beauty(bm, looptris, &tottri);
-
- /* postpone this until after tessellating
- * so we can use the original normals before the vertex are moved */
- {
- BMIter iter;
- int i;
- const int i_verts_end = mesh_other->totvert;
- const int i_faces_end = mesh_other->totpoly;
-
- float imat[4][4];
- float omat[4][4];
-
- invert_m4_m4(imat, object->obmat);
- mul_m4_m4m4(omat, imat, other->obmat);
-
- BMVert *eve;
- i = 0;
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- mul_m4_v3(omat, eve->co);
- if (++i == i_verts_end) {
- break;
- }
- }
-
- /* we need face normals because of 'BM_face_split_edgenet'
- * we could calculate on the fly too (before calling split). */
- {
- float nmat[3][3];
- copy_m3_m4(nmat, omat);
- invert_m3(nmat);
-
- if (UNLIKELY(is_flip)) {
- negate_m3(nmat);
- }
-
- const short ob_src_totcol = other->totcol;
- short *material_remap = BLI_array_alloca(material_remap, ob_src_totcol ? ob_src_totcol : 1);
-
- /* Using original (not evaluated) object here since we are writing to it. */
- /* XXX Pretty sure comment above is fully wrong now with CoW & co ? */
- BKE_material_remap_object_calc(ctx->object, other, material_remap);
-
- BMFace *efa;
- i = 0;
- BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- mul_transposed_m3_v3(nmat, efa->no);
- normalize_v3(efa->no);
- BM_elem_flag_enable(efa, BM_FACE_TAG); /* temp tag to test which side split faces are from */
-
- /* remap material */
- if (LIKELY(efa->mat_nr < ob_src_totcol)) {
- efa->mat_nr = material_remap[efa->mat_nr];
- }
-
- if (++i == i_faces_end) {
- break;
- }
- }
- }
- }
-
- /* not needed, but normals for 'dm' will be invalid,
- * currently this is ok for 'BM_mesh_intersect' */
- // BM_mesh_normals_update(bm);
-
- bool use_separate = false;
- bool use_dissolve = true;
- bool use_island_connect = true;
-
- /* change for testing */
- if (G.debug & G_DEBUG) {
- use_separate = (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_Separate) != 0;
- use_dissolve = (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_NoDissolve) == 0;
- use_island_connect = (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_NoConnectRegions) == 0;
- }
-
- BM_mesh_intersect(
- bm,
- looptris, tottri,
- bm_face_isect_pair, NULL,
- false,
- use_separate,
- use_dissolve,
- use_island_connect,
- false,
- false,
- bmd->operation,
- bmd->double_threshold);
-
- MEM_freeN(looptris);
- }
-
- result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
-
- BM_mesh_free(bm);
-
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ bm = BM_mesh_create(&allocsize,
+ &((struct BMeshCreateParams){
+ .use_toolflags = false,
+ }));
+
+ BM_mesh_bm_from_me(bm,
+ mesh_other,
+ &((struct BMeshFromMeshParams){
+ .calc_face_normal = true,
+ }));
+
+ if (UNLIKELY(is_flip)) {
+ const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
+ BMIter iter;
+ BMFace *efa;
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ BM_face_normal_flip_ex(bm, efa, cd_loop_mdisp_offset, true);
+ }
+ }
+
+ BM_mesh_bm_from_me(bm,
+ mesh,
+ &((struct BMeshFromMeshParams){
+ .calc_face_normal = true,
+ }));
+
+ /* main bmesh intersection setup */
+ {
+ /* create tessface & intersect */
+ const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
+ int tottri;
+ BMLoop *(*looptris)[3];
+
+ looptris = MEM_malloc_arrayN(looptris_tot, sizeof(*looptris), __func__);
+
+ BM_mesh_calc_tessellation_beauty(bm, looptris, &tottri);
+
+ /* postpone this until after tessellating
+ * so we can use the original normals before the vertex are moved */
+ {
+ BMIter iter;
+ int i;
+ const int i_verts_end = mesh_other->totvert;
+ const int i_faces_end = mesh_other->totpoly;
+
+ float imat[4][4];
+ float omat[4][4];
+
+ invert_m4_m4(imat, object->obmat);
+ mul_m4_m4m4(omat, imat, other->obmat);
+
+ BMVert *eve;
+ i = 0;
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ mul_m4_v3(omat, eve->co);
+ if (++i == i_verts_end) {
+ break;
+ }
+ }
+
+ /* we need face normals because of 'BM_face_split_edgenet'
+ * we could calculate on the fly too (before calling split). */
+ {
+ float nmat[3][3];
+ copy_m3_m4(nmat, omat);
+ invert_m3(nmat);
+
+ if (UNLIKELY(is_flip)) {
+ negate_m3(nmat);
+ }
+
+ const short ob_src_totcol = other->totcol;
+ short *material_remap = BLI_array_alloca(material_remap,
+ ob_src_totcol ? ob_src_totcol : 1);
+
+ /* Using original (not evaluated) object here since we are writing to it. */
+ /* XXX Pretty sure comment above is fully wrong now with CoW & co ? */
+ BKE_material_remap_object_calc(ctx->object, other, material_remap);
+
+ BMFace *efa;
+ i = 0;
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ mul_transposed_m3_v3(nmat, efa->no);
+ normalize_v3(efa->no);
+ BM_elem_flag_enable(
+ efa, BM_FACE_TAG); /* temp tag to test which side split faces are from */
+
+ /* remap material */
+ if (LIKELY(efa->mat_nr < ob_src_totcol)) {
+ efa->mat_nr = material_remap[efa->mat_nr];
+ }
+
+ if (++i == i_faces_end) {
+ break;
+ }
+ }
+ }
+ }
+
+ /* not needed, but normals for 'dm' will be invalid,
+ * currently this is ok for 'BM_mesh_intersect' */
+ // BM_mesh_normals_update(bm);
+
+ bool use_separate = false;
+ bool use_dissolve = true;
+ bool use_island_connect = true;
+
+ /* change for testing */
+ if (G.debug & G_DEBUG) {
+ use_separate = (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_Separate) != 0;
+ use_dissolve = (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_NoDissolve) == 0;
+ use_island_connect = (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_NoConnectRegions) ==
+ 0;
+ }
+
+ BM_mesh_intersect(bm,
+ looptris,
+ tottri,
+ bm_face_isect_pair,
+ NULL,
+ false,
+ use_separate,
+ use_dissolve,
+ use_island_connect,
+ false,
+ false,
+ bmd->operation,
+ bmd->double_threshold);
+
+ MEM_freeN(looptris);
+ }
+
+ result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
+
+ BM_mesh_free(bm);
+
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
#ifdef DEBUG_TIME
- TIMEIT_END(boolean_bmesh);
+ TIMEIT_END(boolean_bmesh);
#endif
- }
+ }
- /* if new mesh returned, return it; otherwise there was
- * an error, so delete the modifier object */
- if (result == NULL)
- modifier_setError(md, "Cannot execute boolean operation");
- }
+ /* if new mesh returned, return it; otherwise there was
+ * an error, so delete the modifier object */
+ if (result == NULL)
+ modifier_setError(md, "Cannot execute boolean operation");
+ }
- return result;
+ return result;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md), CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *UNUSED(md),
+ CustomData_MeshMasks *r_cddata_masks)
{
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- r_cddata_masks->emask |= CD_MASK_MEDGE;
- r_cddata_masks->fmask |= CD_MASK_MTFACE;
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ r_cddata_masks->emask |= CD_MASK_MEDGE;
+ r_cddata_masks->fmask |= CD_MASK_MTFACE;
}
ModifierTypeInfo modifierType_Boolean = {
- /* name */ "Boolean",
- /* structName */ "BooleanModifierData",
- /* structSize */ sizeof(BooleanModifierData),
- /* type */ eModifierTypeType_Nonconstructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_UsesPointCache,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Boolean",
+ /* structName */ "BooleanModifierData",
+ /* structSize */ sizeof(BooleanModifierData),
+ /* type */ eModifierTypeType_Nonconstructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_UsesPointCache,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c
index 01478c855bb..7c8470b26d9 100644
--- a/source/blender/modifiers/intern/MOD_build.c
+++ b/source/blender/modifiers/intern/MOD_build.c
@@ -44,270 +44,260 @@
static void initData(ModifierData *md)
{
- BuildModifierData *bmd = (BuildModifierData *) md;
+ BuildModifierData *bmd = (BuildModifierData *)md;
- bmd->start = 1.0;
- bmd->length = 100.0;
+ bmd->start = 1.0;
+ bmd->length = 100.0;
}
static bool dependsOnTime(ModifierData *UNUSED(md))
{
- return true;
+ return true;
}
-static Mesh *applyModifier(
- ModifierData *md, const ModifierEvalContext *ctx,
- struct Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, struct Mesh *mesh)
{
- Mesh *result;
- BuildModifierData *bmd = (BuildModifierData *) md;
- int i, j, k;
- int numFaces_dst, numEdges_dst, numLoops_dst = 0;
- int *vertMap, *edgeMap, *faceMap;
- float frac;
- MPoly *mpoly_dst;
- MLoop *ml_dst, *ml_src /*, *mloop_dst */;
- GHashIterator gh_iter;
- /* maps vert indices in old mesh to indices in new mesh */
- GHash *vertHash = BLI_ghash_int_new("build ve apply gh");
- /* maps edge indices in new mesh to indices in old mesh */
- GHash *edgeHash = BLI_ghash_int_new("build ed apply gh");
- /* maps edge indices in old mesh to indices in new mesh */
- GHash *edgeHash2 = BLI_ghash_int_new("build ed apply gh");
-
- const int numVert_src = mesh->totvert;
- const int numEdge_src = mesh->totedge;
- const int numPoly_src = mesh->totpoly;
- MPoly *mpoly_src = mesh->mpoly;
- MLoop *mloop_src = mesh->mloop;
- MEdge *medge_src = mesh->medge;
- MVert *mvert_src = mesh->mvert;
-
- vertMap = MEM_malloc_arrayN(numVert_src, sizeof(*vertMap), "build modifier vertMap");
- edgeMap = MEM_malloc_arrayN(numEdge_src, sizeof(*edgeMap), "build modifier edgeMap");
- faceMap = MEM_malloc_arrayN(numPoly_src, sizeof(*faceMap), "build modifier faceMap");
-
- range_vn_i(vertMap, numVert_src, 0);
- range_vn_i(edgeMap, numEdge_src, 0);
- range_vn_i(faceMap, numPoly_src, 0);
-
- struct Scene *scene = DEG_get_input_scene(ctx->depsgraph);
- frac = (BKE_scene_frame_get(scene) - bmd->start) / bmd->length;
- CLAMP(frac, 0.0f, 1.0f);
- if (bmd->flag & MOD_BUILD_FLAG_REVERSE) {
- frac = 1.0f - frac;
- }
-
- numFaces_dst = numPoly_src * frac;
- numEdges_dst = numEdge_src * frac;
-
- /* if there's at least one face, build based on faces */
- if (numFaces_dst) {
- MPoly *mpoly, *mp;
- MLoop *ml, *mloop;
- uintptr_t hash_num, hash_num_alt;
-
- if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) {
- BLI_array_randomize(faceMap, sizeof(*faceMap),
- numPoly_src, bmd->seed);
- }
-
- /* get the set of all vert indices that will be in the final mesh,
- * mapped to the new indices
- */
- mpoly = mpoly_src;
- mloop = mloop_src;
- hash_num = 0;
- for (i = 0; i < numFaces_dst; i++) {
- mp = mpoly + faceMap[i];
- ml = mloop + mp->loopstart;
-
- for (j = 0; j < mp->totloop; j++, ml++) {
- void **val_p;
- if (!BLI_ghash_ensure_p(vertHash, POINTER_FROM_INT(ml->v), &val_p)) {
- *val_p = (void *)hash_num;
- hash_num++;
- }
- }
-
- numLoops_dst += mp->totloop;
- }
- BLI_assert(hash_num == BLI_ghash_len(vertHash));
-
- /* get the set of edges that will be in the new mesh (i.e. all edges
- * that have both verts in the new mesh)
- */
- hash_num = 0;
- hash_num_alt = 0;
- for (i = 0; i < numEdge_src; i++, hash_num_alt++) {
- MEdge *me = medge_src + i;
-
- if (BLI_ghash_haskey(vertHash, POINTER_FROM_INT(me->v1)) &&
- BLI_ghash_haskey(vertHash, POINTER_FROM_INT(me->v2)))
- {
- BLI_ghash_insert(edgeHash, (void *)hash_num, (void *)hash_num_alt);
- BLI_ghash_insert(edgeHash2, (void *)hash_num_alt, (void *)hash_num);
- hash_num++;
- }
- }
- BLI_assert(hash_num == BLI_ghash_len(edgeHash));
- }
- else if (numEdges_dst) {
- MEdge *medge, *me;
- uintptr_t hash_num;
-
- if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE)
- BLI_array_randomize(edgeMap, sizeof(*edgeMap),
- numEdge_src, bmd->seed);
-
- /* get the set of all vert indices that will be in the final mesh,
- * mapped to the new indices
- */
- medge = medge_src;
- hash_num = 0;
- BLI_assert(hash_num == BLI_ghash_len(vertHash));
- for (i = 0; i < numEdges_dst; i++) {
- void **val_p;
- me = medge + edgeMap[i];
-
- if (!BLI_ghash_ensure_p(vertHash, POINTER_FROM_INT(me->v1), &val_p)) {
- *val_p = (void *)hash_num;
- hash_num++;
- }
- if (!BLI_ghash_ensure_p(vertHash, POINTER_FROM_INT(me->v2), &val_p)) {
- *val_p = (void *)hash_num;
- hash_num++;
- }
- }
- BLI_assert(hash_num == BLI_ghash_len(vertHash));
-
- /* get the set of edges that will be in the new mesh */
- for (i = 0; i < numEdges_dst; i++) {
- j = BLI_ghash_len(edgeHash);
-
- BLI_ghash_insert(edgeHash, POINTER_FROM_INT(j),
- POINTER_FROM_INT(edgeMap[i]));
- BLI_ghash_insert(edgeHash2, POINTER_FROM_INT(edgeMap[i]),
- POINTER_FROM_INT(j));
- }
- }
- else {
- int numVerts = numVert_src * frac;
-
- if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) {
- BLI_array_randomize(vertMap, sizeof(*vertMap),
- numVert_src, bmd->seed);
- }
-
- /* get the set of all vert indices that will be in the final mesh,
- * mapped to the new indices
- */
- for (i = 0; i < numVerts; i++) {
- BLI_ghash_insert(vertHash, POINTER_FROM_INT(vertMap[i]), POINTER_FROM_INT(i));
- }
- }
-
- /* now we know the number of verts, edges and faces, we can create the mesh. */
- result = BKE_mesh_new_nomain_from_template(
- mesh, BLI_ghash_len(vertHash), BLI_ghash_len(edgeHash),
- 0, numLoops_dst, numFaces_dst);
-
- /* copy the vertices across */
- GHASH_ITER (gh_iter, vertHash) {
- MVert source;
- MVert *dest;
- int oldIndex = POINTER_AS_INT(BLI_ghashIterator_getKey(&gh_iter));
- int newIndex = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter));
-
- source = mvert_src[oldIndex];
- dest = &result->mvert[newIndex];
-
- CustomData_copy_data(&mesh->vdata, &result->vdata, oldIndex, newIndex, 1);
- *dest = source;
- }
-
- /* copy the edges across, remapping indices */
- for (i = 0; i < BLI_ghash_len(edgeHash); i++) {
- MEdge source;
- MEdge *dest;
- int oldIndex = POINTER_AS_INT(BLI_ghash_lookup(edgeHash, POINTER_FROM_INT(i)));
-
- source = medge_src[oldIndex];
- dest = &result->medge[i];
-
- source.v1 = POINTER_AS_INT(BLI_ghash_lookup(vertHash, POINTER_FROM_INT(source.v1)));
- source.v2 = POINTER_AS_INT(BLI_ghash_lookup(vertHash, POINTER_FROM_INT(source.v2)));
-
- CustomData_copy_data(&mesh->edata, &result->edata, oldIndex, i, 1);
- *dest = source;
- }
-
- mpoly_dst = result->mpoly;
- ml_dst = result->mloop;
-
- /* copy the faces across, remapping indices */
- k = 0;
- for (i = 0; i < numFaces_dst; i++) {
- MPoly *source;
- MPoly *dest;
-
- source = mpoly_src + faceMap[i];
- dest = mpoly_dst + i;
- CustomData_copy_data(&mesh->pdata, &result->pdata, faceMap[i], i, 1);
-
- *dest = *source;
- dest->loopstart = k;
- CustomData_copy_data(&mesh->ldata, &result->ldata, source->loopstart, dest->loopstart, dest->totloop);
-
- ml_src = mloop_src + source->loopstart;
- for (j = 0; j < source->totloop; j++, k++, ml_src++, ml_dst++) {
- ml_dst->v = POINTER_AS_INT(BLI_ghash_lookup(vertHash, POINTER_FROM_INT(ml_src->v)));
- ml_dst->e = POINTER_AS_INT(BLI_ghash_lookup(edgeHash2, POINTER_FROM_INT(ml_src->e)));
- }
- }
-
- BLI_ghash_free(vertHash, NULL, NULL);
- BLI_ghash_free(edgeHash, NULL, NULL);
- BLI_ghash_free(edgeHash2, NULL, NULL);
-
- MEM_freeN(vertMap);
- MEM_freeN(edgeMap);
- MEM_freeN(faceMap);
-
- if (mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) {
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- }
-
- /* TODO(sybren): also copy flags & tags? */
- return result;
+ Mesh *result;
+ BuildModifierData *bmd = (BuildModifierData *)md;
+ int i, j, k;
+ int numFaces_dst, numEdges_dst, numLoops_dst = 0;
+ int *vertMap, *edgeMap, *faceMap;
+ float frac;
+ MPoly *mpoly_dst;
+ MLoop *ml_dst, *ml_src /*, *mloop_dst */;
+ GHashIterator gh_iter;
+ /* maps vert indices in old mesh to indices in new mesh */
+ GHash *vertHash = BLI_ghash_int_new("build ve apply gh");
+ /* maps edge indices in new mesh to indices in old mesh */
+ GHash *edgeHash = BLI_ghash_int_new("build ed apply gh");
+ /* maps edge indices in old mesh to indices in new mesh */
+ GHash *edgeHash2 = BLI_ghash_int_new("build ed apply gh");
+
+ const int numVert_src = mesh->totvert;
+ const int numEdge_src = mesh->totedge;
+ const int numPoly_src = mesh->totpoly;
+ MPoly *mpoly_src = mesh->mpoly;
+ MLoop *mloop_src = mesh->mloop;
+ MEdge *medge_src = mesh->medge;
+ MVert *mvert_src = mesh->mvert;
+
+ vertMap = MEM_malloc_arrayN(numVert_src, sizeof(*vertMap), "build modifier vertMap");
+ edgeMap = MEM_malloc_arrayN(numEdge_src, sizeof(*edgeMap), "build modifier edgeMap");
+ faceMap = MEM_malloc_arrayN(numPoly_src, sizeof(*faceMap), "build modifier faceMap");
+
+ range_vn_i(vertMap, numVert_src, 0);
+ range_vn_i(edgeMap, numEdge_src, 0);
+ range_vn_i(faceMap, numPoly_src, 0);
+
+ struct Scene *scene = DEG_get_input_scene(ctx->depsgraph);
+ frac = (BKE_scene_frame_get(scene) - bmd->start) / bmd->length;
+ CLAMP(frac, 0.0f, 1.0f);
+ if (bmd->flag & MOD_BUILD_FLAG_REVERSE) {
+ frac = 1.0f - frac;
+ }
+
+ numFaces_dst = numPoly_src * frac;
+ numEdges_dst = numEdge_src * frac;
+
+ /* if there's at least one face, build based on faces */
+ if (numFaces_dst) {
+ MPoly *mpoly, *mp;
+ MLoop *ml, *mloop;
+ uintptr_t hash_num, hash_num_alt;
+
+ if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) {
+ BLI_array_randomize(faceMap, sizeof(*faceMap), numPoly_src, bmd->seed);
+ }
+
+ /* get the set of all vert indices that will be in the final mesh,
+ * mapped to the new indices
+ */
+ mpoly = mpoly_src;
+ mloop = mloop_src;
+ hash_num = 0;
+ for (i = 0; i < numFaces_dst; i++) {
+ mp = mpoly + faceMap[i];
+ ml = mloop + mp->loopstart;
+
+ for (j = 0; j < mp->totloop; j++, ml++) {
+ void **val_p;
+ if (!BLI_ghash_ensure_p(vertHash, POINTER_FROM_INT(ml->v), &val_p)) {
+ *val_p = (void *)hash_num;
+ hash_num++;
+ }
+ }
+
+ numLoops_dst += mp->totloop;
+ }
+ BLI_assert(hash_num == BLI_ghash_len(vertHash));
+
+ /* get the set of edges that will be in the new mesh (i.e. all edges
+ * that have both verts in the new mesh)
+ */
+ hash_num = 0;
+ hash_num_alt = 0;
+ for (i = 0; i < numEdge_src; i++, hash_num_alt++) {
+ MEdge *me = medge_src + i;
+
+ if (BLI_ghash_haskey(vertHash, POINTER_FROM_INT(me->v1)) &&
+ BLI_ghash_haskey(vertHash, POINTER_FROM_INT(me->v2))) {
+ BLI_ghash_insert(edgeHash, (void *)hash_num, (void *)hash_num_alt);
+ BLI_ghash_insert(edgeHash2, (void *)hash_num_alt, (void *)hash_num);
+ hash_num++;
+ }
+ }
+ BLI_assert(hash_num == BLI_ghash_len(edgeHash));
+ }
+ else if (numEdges_dst) {
+ MEdge *medge, *me;
+ uintptr_t hash_num;
+
+ if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE)
+ BLI_array_randomize(edgeMap, sizeof(*edgeMap), numEdge_src, bmd->seed);
+
+ /* get the set of all vert indices that will be in the final mesh,
+ * mapped to the new indices
+ */
+ medge = medge_src;
+ hash_num = 0;
+ BLI_assert(hash_num == BLI_ghash_len(vertHash));
+ for (i = 0; i < numEdges_dst; i++) {
+ void **val_p;
+ me = medge + edgeMap[i];
+
+ if (!BLI_ghash_ensure_p(vertHash, POINTER_FROM_INT(me->v1), &val_p)) {
+ *val_p = (void *)hash_num;
+ hash_num++;
+ }
+ if (!BLI_ghash_ensure_p(vertHash, POINTER_FROM_INT(me->v2), &val_p)) {
+ *val_p = (void *)hash_num;
+ hash_num++;
+ }
+ }
+ BLI_assert(hash_num == BLI_ghash_len(vertHash));
+
+ /* get the set of edges that will be in the new mesh */
+ for (i = 0; i < numEdges_dst; i++) {
+ j = BLI_ghash_len(edgeHash);
+
+ BLI_ghash_insert(edgeHash, POINTER_FROM_INT(j), POINTER_FROM_INT(edgeMap[i]));
+ BLI_ghash_insert(edgeHash2, POINTER_FROM_INT(edgeMap[i]), POINTER_FROM_INT(j));
+ }
+ }
+ else {
+ int numVerts = numVert_src * frac;
+
+ if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) {
+ BLI_array_randomize(vertMap, sizeof(*vertMap), numVert_src, bmd->seed);
+ }
+
+ /* get the set of all vert indices that will be in the final mesh,
+ * mapped to the new indices
+ */
+ for (i = 0; i < numVerts; i++) {
+ BLI_ghash_insert(vertHash, POINTER_FROM_INT(vertMap[i]), POINTER_FROM_INT(i));
+ }
+ }
+
+ /* now we know the number of verts, edges and faces, we can create the mesh. */
+ result = BKE_mesh_new_nomain_from_template(
+ mesh, BLI_ghash_len(vertHash), BLI_ghash_len(edgeHash), 0, numLoops_dst, numFaces_dst);
+
+ /* copy the vertices across */
+ GHASH_ITER (gh_iter, vertHash) {
+ MVert source;
+ MVert *dest;
+ int oldIndex = POINTER_AS_INT(BLI_ghashIterator_getKey(&gh_iter));
+ int newIndex = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter));
+
+ source = mvert_src[oldIndex];
+ dest = &result->mvert[newIndex];
+
+ CustomData_copy_data(&mesh->vdata, &result->vdata, oldIndex, newIndex, 1);
+ *dest = source;
+ }
+
+ /* copy the edges across, remapping indices */
+ for (i = 0; i < BLI_ghash_len(edgeHash); i++) {
+ MEdge source;
+ MEdge *dest;
+ int oldIndex = POINTER_AS_INT(BLI_ghash_lookup(edgeHash, POINTER_FROM_INT(i)));
+
+ source = medge_src[oldIndex];
+ dest = &result->medge[i];
+
+ source.v1 = POINTER_AS_INT(BLI_ghash_lookup(vertHash, POINTER_FROM_INT(source.v1)));
+ source.v2 = POINTER_AS_INT(BLI_ghash_lookup(vertHash, POINTER_FROM_INT(source.v2)));
+
+ CustomData_copy_data(&mesh->edata, &result->edata, oldIndex, i, 1);
+ *dest = source;
+ }
+
+ mpoly_dst = result->mpoly;
+ ml_dst = result->mloop;
+
+ /* copy the faces across, remapping indices */
+ k = 0;
+ for (i = 0; i < numFaces_dst; i++) {
+ MPoly *source;
+ MPoly *dest;
+
+ source = mpoly_src + faceMap[i];
+ dest = mpoly_dst + i;
+ CustomData_copy_data(&mesh->pdata, &result->pdata, faceMap[i], i, 1);
+
+ *dest = *source;
+ dest->loopstart = k;
+ CustomData_copy_data(
+ &mesh->ldata, &result->ldata, source->loopstart, dest->loopstart, dest->totloop);
+
+ ml_src = mloop_src + source->loopstart;
+ for (j = 0; j < source->totloop; j++, k++, ml_src++, ml_dst++) {
+ ml_dst->v = POINTER_AS_INT(BLI_ghash_lookup(vertHash, POINTER_FROM_INT(ml_src->v)));
+ ml_dst->e = POINTER_AS_INT(BLI_ghash_lookup(edgeHash2, POINTER_FROM_INT(ml_src->e)));
+ }
+ }
+
+ BLI_ghash_free(vertHash, NULL, NULL);
+ BLI_ghash_free(edgeHash, NULL, NULL);
+ BLI_ghash_free(edgeHash2, NULL, NULL);
+
+ MEM_freeN(vertMap);
+ MEM_freeN(edgeMap);
+ MEM_freeN(faceMap);
+
+ if (mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) {
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ }
+
+ /* TODO(sybren): also copy flags & tags? */
+ return result;
}
-
ModifierTypeInfo modifierType_Build = {
- /* name */ "Build",
- /* structName */ "BuildModifierData",
- /* structSize */ sizeof(BuildModifierData),
- /* type */ eModifierTypeType_Nonconstructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_AcceptsCVs,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ NULL,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Build",
+ /* structName */ "BuildModifierData",
+ /* structSize */ sizeof(BuildModifierData),
+ /* type */ eModifierTypeType_Nonconstructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c
index b8917f58234..b0a8a8c955f 100644
--- a/source/blender/modifiers/intern/MOD_cast.c
+++ b/source/blender/modifiers/intern/MOD_cast.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include "BLI_utildefines.h"
#include "BLI_math.h"
@@ -43,452 +42,468 @@
static void initData(ModifierData *md)
{
- CastModifierData *cmd = (CastModifierData *) md;
-
- cmd->fac = 0.5f;
- cmd->radius = 0.0f;
- cmd->size = 0.0f;
- cmd->flag = MOD_CAST_X | MOD_CAST_Y | MOD_CAST_Z | MOD_CAST_SIZE_FROM_RADIUS;
- cmd->type = MOD_CAST_TYPE_SPHERE;
- cmd->defgrp_name[0] = '\0';
- cmd->object = NULL;
+ CastModifierData *cmd = (CastModifierData *)md;
+
+ cmd->fac = 0.5f;
+ cmd->radius = 0.0f;
+ cmd->size = 0.0f;
+ cmd->flag = MOD_CAST_X | MOD_CAST_Y | MOD_CAST_Z | MOD_CAST_SIZE_FROM_RADIUS;
+ cmd->type = MOD_CAST_TYPE_SPHERE;
+ cmd->defgrp_name[0] = '\0';
+ cmd->object = NULL;
}
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(useRenderParams))
{
- CastModifierData *cmd = (CastModifierData *) md;
- short flag;
+ CastModifierData *cmd = (CastModifierData *)md;
+ short flag;
- flag = cmd->flag & (MOD_CAST_X | MOD_CAST_Y | MOD_CAST_Z);
+ flag = cmd->flag & (MOD_CAST_X | MOD_CAST_Y | MOD_CAST_Z);
- if ((cmd->fac == 0.0f) || flag == 0) return true;
+ if ((cmd->fac == 0.0f) || flag == 0)
+ return true;
- return false;
+ return false;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- CastModifierData *cmd = (CastModifierData *)md;
+ CastModifierData *cmd = (CastModifierData *)md;
- /* ask for vertexgroups if we need them */
- if (cmd->defgrp_name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ /* ask for vertexgroups if we need them */
+ if (cmd->defgrp_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
-static void foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- CastModifierData *cmd = (CastModifierData *) md;
+ CastModifierData *cmd = (CastModifierData *)md;
- walk(userData, ob, &cmd->object, IDWALK_CB_NOP);
+ walk(userData, ob, &cmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- CastModifierData *cmd = (CastModifierData *)md;
- if (cmd->object != NULL) {
- DEG_add_object_relation(ctx->node, cmd->object, DEG_OB_COMP_TRANSFORM, "Cast Modifier");
- DEG_add_modifier_to_transform_relation(ctx->node, "Cast Modifier");
- }
+ CastModifierData *cmd = (CastModifierData *)md;
+ if (cmd->object != NULL) {
+ DEG_add_object_relation(ctx->node, cmd->object, DEG_OB_COMP_TRANSFORM, "Cast Modifier");
+ DEG_add_modifier_to_transform_relation(ctx->node, "Cast Modifier");
+ }
}
-static void sphere_do(
- CastModifierData *cmd, const ModifierEvalContext *UNUSED(ctx),
- Object *ob, Mesh *mesh,
- float (*vertexCos)[3], int numVerts)
+static void sphere_do(CastModifierData *cmd,
+ const ModifierEvalContext *UNUSED(ctx),
+ Object *ob,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- MDeformVert *dvert = NULL;
-
- Object *ctrl_ob = NULL;
-
- int i, defgrp_index;
- bool has_radius = false;
- short flag, type;
- float len = 0.0f;
- float fac = cmd->fac;
- float facm = 1.0f - fac;
- const float fac_orig = fac;
- float vec[3], center[3] = {0.0f, 0.0f, 0.0f};
- float mat[4][4], imat[4][4];
-
- flag = cmd->flag;
- type = cmd->type; /* projection type: sphere or cylinder */
-
- if (type == MOD_CAST_TYPE_CYLINDER)
- flag &= ~MOD_CAST_Z;
-
- ctrl_ob = cmd->object;
-
- /* spherify's center is {0, 0, 0} (the ob's own center in its local
- * space), by default, but if the user defined a control object,
- * we use its location, transformed to ob's local space */
- if (ctrl_ob) {
- if (flag & MOD_CAST_USE_OB_TRANSFORM) {
- invert_m4_m4(imat, ctrl_ob->obmat);
- mul_m4_m4m4(mat, imat, ob->obmat);
- invert_m4_m4(imat, mat);
- }
-
- invert_m4_m4(ob->imat, ob->obmat);
- mul_v3_m4v3(center, ob->imat, ctrl_ob->obmat[3]);
- }
-
- /* now we check which options the user wants */
-
- /* 1) (flag was checked in the "if (ctrl_ob)" block above) */
- /* 2) cmd->radius > 0.0f: only the vertices within this radius from
- * the center of the effect should be deformed */
- if (cmd->radius > FLT_EPSILON) has_radius = 1;
-
- /* 3) if we were given a vertex group name,
- * only those vertices should be affected */
- MOD_get_vgroup(ob, mesh, cmd->defgrp_name, &dvert, &defgrp_index);
-
- if (flag & MOD_CAST_SIZE_FROM_RADIUS) {
- len = cmd->radius;
- }
- else {
- len = cmd->size;
- }
-
- if (len <= 0) {
- for (i = 0; i < numVerts; i++) {
- len += len_v3v3(center, vertexCos[i]);
- }
- len /= numVerts;
-
- if (len == 0.0f) len = 10.0f;
- }
-
- for (i = 0; i < numVerts; i++) {
- float tmp_co[3];
-
- copy_v3_v3(tmp_co, vertexCos[i]);
- if (ctrl_ob) {
- if (flag & MOD_CAST_USE_OB_TRANSFORM) {
- mul_m4_v3(mat, tmp_co);
- }
- else {
- sub_v3_v3(tmp_co, center);
- }
- }
-
- copy_v3_v3(vec, tmp_co);
-
- if (type == MOD_CAST_TYPE_CYLINDER)
- vec[2] = 0.0f;
-
- if (has_radius) {
- if (len_v3(vec) > cmd->radius) continue;
- }
-
- if (dvert) {
- const float weight = defvert_find_weight(&dvert[i], defgrp_index);
- if (weight == 0.0f) {
- continue;
- }
-
- fac = fac_orig * weight;
- facm = 1.0f - fac;
- }
-
- normalize_v3(vec);
-
- if (flag & MOD_CAST_X)
- tmp_co[0] = fac * vec[0] * len + facm * tmp_co[0];
- if (flag & MOD_CAST_Y)
- tmp_co[1] = fac * vec[1] * len + facm * tmp_co[1];
- if (flag & MOD_CAST_Z)
- tmp_co[2] = fac * vec[2] * len + facm * tmp_co[2];
-
- if (ctrl_ob) {
- if (flag & MOD_CAST_USE_OB_TRANSFORM) {
- mul_m4_v3(imat, tmp_co);
- }
- else {
- add_v3_v3(tmp_co, center);
- }
- }
-
- copy_v3_v3(vertexCos[i], tmp_co);
- }
+ MDeformVert *dvert = NULL;
+
+ Object *ctrl_ob = NULL;
+
+ int i, defgrp_index;
+ bool has_radius = false;
+ short flag, type;
+ float len = 0.0f;
+ float fac = cmd->fac;
+ float facm = 1.0f - fac;
+ const float fac_orig = fac;
+ float vec[3], center[3] = {0.0f, 0.0f, 0.0f};
+ float mat[4][4], imat[4][4];
+
+ flag = cmd->flag;
+ type = cmd->type; /* projection type: sphere or cylinder */
+
+ if (type == MOD_CAST_TYPE_CYLINDER)
+ flag &= ~MOD_CAST_Z;
+
+ ctrl_ob = cmd->object;
+
+ /* spherify's center is {0, 0, 0} (the ob's own center in its local
+ * space), by default, but if the user defined a control object,
+ * we use its location, transformed to ob's local space */
+ if (ctrl_ob) {
+ if (flag & MOD_CAST_USE_OB_TRANSFORM) {
+ invert_m4_m4(imat, ctrl_ob->obmat);
+ mul_m4_m4m4(mat, imat, ob->obmat);
+ invert_m4_m4(imat, mat);
+ }
+
+ invert_m4_m4(ob->imat, ob->obmat);
+ mul_v3_m4v3(center, ob->imat, ctrl_ob->obmat[3]);
+ }
+
+ /* now we check which options the user wants */
+
+ /* 1) (flag was checked in the "if (ctrl_ob)" block above) */
+ /* 2) cmd->radius > 0.0f: only the vertices within this radius from
+ * the center of the effect should be deformed */
+ if (cmd->radius > FLT_EPSILON)
+ has_radius = 1;
+
+ /* 3) if we were given a vertex group name,
+ * only those vertices should be affected */
+ MOD_get_vgroup(ob, mesh, cmd->defgrp_name, &dvert, &defgrp_index);
+
+ if (flag & MOD_CAST_SIZE_FROM_RADIUS) {
+ len = cmd->radius;
+ }
+ else {
+ len = cmd->size;
+ }
+
+ if (len <= 0) {
+ for (i = 0; i < numVerts; i++) {
+ len += len_v3v3(center, vertexCos[i]);
+ }
+ len /= numVerts;
+
+ if (len == 0.0f)
+ len = 10.0f;
+ }
+
+ for (i = 0; i < numVerts; i++) {
+ float tmp_co[3];
+
+ copy_v3_v3(tmp_co, vertexCos[i]);
+ if (ctrl_ob) {
+ if (flag & MOD_CAST_USE_OB_TRANSFORM) {
+ mul_m4_v3(mat, tmp_co);
+ }
+ else {
+ sub_v3_v3(tmp_co, center);
+ }
+ }
+
+ copy_v3_v3(vec, tmp_co);
+
+ if (type == MOD_CAST_TYPE_CYLINDER)
+ vec[2] = 0.0f;
+
+ if (has_radius) {
+ if (len_v3(vec) > cmd->radius)
+ continue;
+ }
+
+ if (dvert) {
+ const float weight = defvert_find_weight(&dvert[i], defgrp_index);
+ if (weight == 0.0f) {
+ continue;
+ }
+
+ fac = fac_orig * weight;
+ facm = 1.0f - fac;
+ }
+
+ normalize_v3(vec);
+
+ if (flag & MOD_CAST_X)
+ tmp_co[0] = fac * vec[0] * len + facm * tmp_co[0];
+ if (flag & MOD_CAST_Y)
+ tmp_co[1] = fac * vec[1] * len + facm * tmp_co[1];
+ if (flag & MOD_CAST_Z)
+ tmp_co[2] = fac * vec[2] * len + facm * tmp_co[2];
+
+ if (ctrl_ob) {
+ if (flag & MOD_CAST_USE_OB_TRANSFORM) {
+ mul_m4_v3(imat, tmp_co);
+ }
+ else {
+ add_v3_v3(tmp_co, center);
+ }
+ }
+
+ copy_v3_v3(vertexCos[i], tmp_co);
+ }
}
-static void cuboid_do(
- CastModifierData *cmd, const ModifierEvalContext *UNUSED(ctx),
- Object *ob, Mesh *mesh,
- float (*vertexCos)[3], int numVerts)
+static void cuboid_do(CastModifierData *cmd,
+ const ModifierEvalContext *UNUSED(ctx),
+ Object *ob,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- MDeformVert *dvert = NULL;
- Object *ctrl_ob = NULL;
-
- int i, defgrp_index;
- bool has_radius = false;
- short flag;
- float fac = cmd->fac;
- float facm = 1.0f - fac;
- const float fac_orig = fac;
- float min[3], max[3], bb[8][3];
- float center[3] = {0.0f, 0.0f, 0.0f};
- float mat[4][4], imat[4][4];
-
- flag = cmd->flag;
-
- ctrl_ob = cmd->object;
-
- /* now we check which options the user wants */
-
- /* 1) (flag was checked in the "if (ctrl_ob)" block above) */
- /* 2) cmd->radius > 0.0f: only the vertices within this radius from
- * the center of the effect should be deformed */
- if (cmd->radius > FLT_EPSILON) has_radius = 1;
-
- /* 3) if we were given a vertex group name,
- * only those vertices should be affected */
- MOD_get_vgroup(ob, mesh, cmd->defgrp_name, &dvert, &defgrp_index);
-
- if (ctrl_ob) {
- if (flag & MOD_CAST_USE_OB_TRANSFORM) {
- invert_m4_m4(imat, ctrl_ob->obmat);
- mul_m4_m4m4(mat, imat, ob->obmat);
- invert_m4_m4(imat, mat);
- }
-
- invert_m4_m4(ob->imat, ob->obmat);
- mul_v3_m4v3(center, ob->imat, ctrl_ob->obmat[3]);
- }
-
- if ((flag & MOD_CAST_SIZE_FROM_RADIUS) && has_radius) {
- for (i = 0; i < 3; i++) {
- min[i] = -cmd->radius;
- max[i] = cmd->radius;
- }
- }
- else if (!(flag & MOD_CAST_SIZE_FROM_RADIUS) && cmd->size > 0) {
- for (i = 0; i < 3; i++) {
- min[i] = -cmd->size;
- max[i] = cmd->size;
- }
- }
- else {
- /* get bound box */
- /* We can't use the object's bound box because other modifiers
- * may have changed the vertex data. */
- INIT_MINMAX(min, max);
-
- /* Cast's center is the ob's own center in its local space,
- * by default, but if the user defined a control object, we use
- * its location, transformed to ob's local space. */
- if (ctrl_ob) {
- float vec[3];
-
- /* let the center of the ctrl_ob be part of the bound box: */
- minmax_v3v3_v3(min, max, center);
-
- for (i = 0; i < numVerts; i++) {
- sub_v3_v3v3(vec, vertexCos[i], center);
- minmax_v3v3_v3(min, max, vec);
- }
- }
- else {
- for (i = 0; i < numVerts; i++) {
- minmax_v3v3_v3(min, max, vertexCos[i]);
- }
- }
-
- /* we want a symmetric bound box around the origin */
- if (fabsf(min[0]) > fabsf(max[0])) max[0] = fabsf(min[0]);
- if (fabsf(min[1]) > fabsf(max[1])) max[1] = fabsf(min[1]);
- if (fabsf(min[2]) > fabsf(max[2])) max[2] = fabsf(min[2]);
- min[0] = -max[0];
- min[1] = -max[1];
- min[2] = -max[2];
- }
-
- /* building our custom bounding box */
- bb[0][0] = bb[2][0] = bb[4][0] = bb[6][0] = min[0];
- bb[1][0] = bb[3][0] = bb[5][0] = bb[7][0] = max[0];
- bb[0][1] = bb[1][1] = bb[4][1] = bb[5][1] = min[1];
- bb[2][1] = bb[3][1] = bb[6][1] = bb[7][1] = max[1];
- bb[0][2] = bb[1][2] = bb[2][2] = bb[3][2] = min[2];
- bb[4][2] = bb[5][2] = bb[6][2] = bb[7][2] = max[2];
-
- /* ready to apply the effect, one vertex at a time */
- for (i = 0; i < numVerts; i++) {
- int octant, coord;
- float d[3], dmax, apex[3], fbb;
- float tmp_co[3];
-
- copy_v3_v3(tmp_co, vertexCos[i]);
- if (ctrl_ob) {
- if (flag & MOD_CAST_USE_OB_TRANSFORM) {
- mul_m4_v3(mat, tmp_co);
- }
- else {
- sub_v3_v3(tmp_co, center);
- }
- }
-
- if (has_radius) {
- if (fabsf(tmp_co[0]) > cmd->radius ||
- fabsf(tmp_co[1]) > cmd->radius ||
- fabsf(tmp_co[2]) > cmd->radius)
- {
- continue;
- }
- }
-
- if (dvert) {
- const float weight = defvert_find_weight(&dvert[i], defgrp_index);
- if (weight == 0.0f) {
- continue;
- }
-
- fac = fac_orig * weight;
- facm = 1.0f - fac;
- }
-
- /* The algo used to project the vertices to their
- * bounding box (bb) is pretty simple:
- * for each vertex v:
- * 1) find in which octant v is in;
- * 2) find which outer "wall" of that octant is closer to v;
- * 3) calculate factor (var fbb) to project v to that wall;
- * 4) project. */
-
- /* find in which octant this vertex is in */
- octant = 0;
- if (tmp_co[0] > 0.0f) octant += 1;
- if (tmp_co[1] > 0.0f) octant += 2;
- if (tmp_co[2] > 0.0f) octant += 4;
-
- /* apex is the bb's vertex at the chosen octant */
- copy_v3_v3(apex, bb[octant]);
-
- /* find which bb plane is closest to this vertex ... */
- d[0] = tmp_co[0] / apex[0];
- d[1] = tmp_co[1] / apex[1];
- d[2] = tmp_co[2] / apex[2];
-
- /* ... (the closest has the higher (closer to 1) d value) */
- dmax = d[0];
- coord = 0;
- if (d[1] > dmax) {
- dmax = d[1];
- coord = 1;
- }
- if (d[2] > dmax) {
- /* dmax = d[2]; */ /* commented, we don't need it */
- coord = 2;
- }
-
- /* ok, now we know which coordinate of the vertex to use */
-
- if (fabsf(tmp_co[coord]) < FLT_EPSILON) /* avoid division by zero */
- continue;
-
- /* finally, this is the factor we wanted, to project the vertex
- * to its bounding box (bb) */
- fbb = apex[coord] / tmp_co[coord];
-
- /* calculate the new vertex position */
- if (flag & MOD_CAST_X)
- tmp_co[0] = facm * tmp_co[0] + fac * tmp_co[0] * fbb;
- if (flag & MOD_CAST_Y)
- tmp_co[1] = facm * tmp_co[1] + fac * tmp_co[1] * fbb;
- if (flag & MOD_CAST_Z)
- tmp_co[2] = facm * tmp_co[2] + fac * tmp_co[2] * fbb;
-
- if (ctrl_ob) {
- if (flag & MOD_CAST_USE_OB_TRANSFORM) {
- mul_m4_v3(imat, tmp_co);
- }
- else {
- add_v3_v3(tmp_co, center);
- }
- }
-
- copy_v3_v3(vertexCos[i], tmp_co);
- }
+ MDeformVert *dvert = NULL;
+ Object *ctrl_ob = NULL;
+
+ int i, defgrp_index;
+ bool has_radius = false;
+ short flag;
+ float fac = cmd->fac;
+ float facm = 1.0f - fac;
+ const float fac_orig = fac;
+ float min[3], max[3], bb[8][3];
+ float center[3] = {0.0f, 0.0f, 0.0f};
+ float mat[4][4], imat[4][4];
+
+ flag = cmd->flag;
+
+ ctrl_ob = cmd->object;
+
+ /* now we check which options the user wants */
+
+ /* 1) (flag was checked in the "if (ctrl_ob)" block above) */
+ /* 2) cmd->radius > 0.0f: only the vertices within this radius from
+ * the center of the effect should be deformed */
+ if (cmd->radius > FLT_EPSILON)
+ has_radius = 1;
+
+ /* 3) if we were given a vertex group name,
+ * only those vertices should be affected */
+ MOD_get_vgroup(ob, mesh, cmd->defgrp_name, &dvert, &defgrp_index);
+
+ if (ctrl_ob) {
+ if (flag & MOD_CAST_USE_OB_TRANSFORM) {
+ invert_m4_m4(imat, ctrl_ob->obmat);
+ mul_m4_m4m4(mat, imat, ob->obmat);
+ invert_m4_m4(imat, mat);
+ }
+
+ invert_m4_m4(ob->imat, ob->obmat);
+ mul_v3_m4v3(center, ob->imat, ctrl_ob->obmat[3]);
+ }
+
+ if ((flag & MOD_CAST_SIZE_FROM_RADIUS) && has_radius) {
+ for (i = 0; i < 3; i++) {
+ min[i] = -cmd->radius;
+ max[i] = cmd->radius;
+ }
+ }
+ else if (!(flag & MOD_CAST_SIZE_FROM_RADIUS) && cmd->size > 0) {
+ for (i = 0; i < 3; i++) {
+ min[i] = -cmd->size;
+ max[i] = cmd->size;
+ }
+ }
+ else {
+ /* get bound box */
+ /* We can't use the object's bound box because other modifiers
+ * may have changed the vertex data. */
+ INIT_MINMAX(min, max);
+
+ /* Cast's center is the ob's own center in its local space,
+ * by default, but if the user defined a control object, we use
+ * its location, transformed to ob's local space. */
+ if (ctrl_ob) {
+ float vec[3];
+
+ /* let the center of the ctrl_ob be part of the bound box: */
+ minmax_v3v3_v3(min, max, center);
+
+ for (i = 0; i < numVerts; i++) {
+ sub_v3_v3v3(vec, vertexCos[i], center);
+ minmax_v3v3_v3(min, max, vec);
+ }
+ }
+ else {
+ for (i = 0; i < numVerts; i++) {
+ minmax_v3v3_v3(min, max, vertexCos[i]);
+ }
+ }
+
+ /* we want a symmetric bound box around the origin */
+ if (fabsf(min[0]) > fabsf(max[0]))
+ max[0] = fabsf(min[0]);
+ if (fabsf(min[1]) > fabsf(max[1]))
+ max[1] = fabsf(min[1]);
+ if (fabsf(min[2]) > fabsf(max[2]))
+ max[2] = fabsf(min[2]);
+ min[0] = -max[0];
+ min[1] = -max[1];
+ min[2] = -max[2];
+ }
+
+ /* building our custom bounding box */
+ bb[0][0] = bb[2][0] = bb[4][0] = bb[6][0] = min[0];
+ bb[1][0] = bb[3][0] = bb[5][0] = bb[7][0] = max[0];
+ bb[0][1] = bb[1][1] = bb[4][1] = bb[5][1] = min[1];
+ bb[2][1] = bb[3][1] = bb[6][1] = bb[7][1] = max[1];
+ bb[0][2] = bb[1][2] = bb[2][2] = bb[3][2] = min[2];
+ bb[4][2] = bb[5][2] = bb[6][2] = bb[7][2] = max[2];
+
+ /* ready to apply the effect, one vertex at a time */
+ for (i = 0; i < numVerts; i++) {
+ int octant, coord;
+ float d[3], dmax, apex[3], fbb;
+ float tmp_co[3];
+
+ copy_v3_v3(tmp_co, vertexCos[i]);
+ if (ctrl_ob) {
+ if (flag & MOD_CAST_USE_OB_TRANSFORM) {
+ mul_m4_v3(mat, tmp_co);
+ }
+ else {
+ sub_v3_v3(tmp_co, center);
+ }
+ }
+
+ if (has_radius) {
+ if (fabsf(tmp_co[0]) > cmd->radius || fabsf(tmp_co[1]) > cmd->radius ||
+ fabsf(tmp_co[2]) > cmd->radius) {
+ continue;
+ }
+ }
+
+ if (dvert) {
+ const float weight = defvert_find_weight(&dvert[i], defgrp_index);
+ if (weight == 0.0f) {
+ continue;
+ }
+
+ fac = fac_orig * weight;
+ facm = 1.0f - fac;
+ }
+
+ /* The algo used to project the vertices to their
+ * bounding box (bb) is pretty simple:
+ * for each vertex v:
+ * 1) find in which octant v is in;
+ * 2) find which outer "wall" of that octant is closer to v;
+ * 3) calculate factor (var fbb) to project v to that wall;
+ * 4) project. */
+
+ /* find in which octant this vertex is in */
+ octant = 0;
+ if (tmp_co[0] > 0.0f)
+ octant += 1;
+ if (tmp_co[1] > 0.0f)
+ octant += 2;
+ if (tmp_co[2] > 0.0f)
+ octant += 4;
+
+ /* apex is the bb's vertex at the chosen octant */
+ copy_v3_v3(apex, bb[octant]);
+
+ /* find which bb plane is closest to this vertex ... */
+ d[0] = tmp_co[0] / apex[0];
+ d[1] = tmp_co[1] / apex[1];
+ d[2] = tmp_co[2] / apex[2];
+
+ /* ... (the closest has the higher (closer to 1) d value) */
+ dmax = d[0];
+ coord = 0;
+ if (d[1] > dmax) {
+ dmax = d[1];
+ coord = 1;
+ }
+ if (d[2] > dmax) {
+ /* dmax = d[2]; */ /* commented, we don't need it */
+ coord = 2;
+ }
+
+ /* ok, now we know which coordinate of the vertex to use */
+
+ if (fabsf(tmp_co[coord]) < FLT_EPSILON) /* avoid division by zero */
+ continue;
+
+ /* finally, this is the factor we wanted, to project the vertex
+ * to its bounding box (bb) */
+ fbb = apex[coord] / tmp_co[coord];
+
+ /* calculate the new vertex position */
+ if (flag & MOD_CAST_X)
+ tmp_co[0] = facm * tmp_co[0] + fac * tmp_co[0] * fbb;
+ if (flag & MOD_CAST_Y)
+ tmp_co[1] = facm * tmp_co[1] + fac * tmp_co[1] * fbb;
+ if (flag & MOD_CAST_Z)
+ tmp_co[2] = facm * tmp_co[2] + fac * tmp_co[2] * fbb;
+
+ if (ctrl_ob) {
+ if (flag & MOD_CAST_USE_OB_TRANSFORM) {
+ mul_m4_v3(imat, tmp_co);
+ }
+ else {
+ add_v3_v3(tmp_co, center);
+ }
+ }
+
+ copy_v3_v3(vertexCos[i], tmp_co);
+ }
}
-static void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh,
- float (*vertexCos)[3],
- int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- CastModifierData *cmd = (CastModifierData *)md;
- Mesh *mesh_src = NULL;
-
- if (ctx->object->type == OB_MESH && cmd->defgrp_name[0] != '\0') {
- /* mesh_src is only needed for vgroups. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
- }
-
- if (cmd->type == MOD_CAST_TYPE_CUBOID) {
- cuboid_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
- }
- else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */
- sphere_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
- }
-
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ CastModifierData *cmd = (CastModifierData *)md;
+ Mesh *mesh_src = NULL;
+
+ if (ctx->object->type == OB_MESH && cmd->defgrp_name[0] != '\0') {
+ /* mesh_src is only needed for vgroups. */
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ }
+
+ if (cmd->type == MOD_CAST_TYPE_CUBOID) {
+ cuboid_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+ }
+ else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */
+ sphere_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+ }
+
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-static void deformVertsEM(
- ModifierData *md, const ModifierEvalContext *ctx,
- struct BMEditMesh *editData,
- Mesh *mesh, float (*vertexCos)[3], int numVerts)
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *editData,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- CastModifierData *cmd = (CastModifierData *)md;
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
-
- BLI_assert(mesh_src->totvert == numVerts);
-
- if (cmd->type == MOD_CAST_TYPE_CUBOID) {
- cuboid_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
- }
- else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */
- sphere_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
- }
-
- if (mesh_src != mesh) {
- BKE_id_free(NULL, mesh_src);
- }
+ CastModifierData *cmd = (CastModifierData *)md;
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, editData, mesh, NULL, numVerts, false, false);
+
+ BLI_assert(mesh_src->totvert == numVerts);
+
+ if (cmd->type == MOD_CAST_TYPE_CUBOID) {
+ cuboid_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+ }
+ else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */
+ sphere_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+ }
+
+ if (mesh_src != mesh) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-
ModifierTypeInfo modifierType_Cast = {
- /* name */ "Cast",
- /* structName */ "CastModifierData",
- /* structSize */ sizeof(CastModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_AcceptsLattice |
- eModifierTypeFlag_SupportsEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Cast",
+ /* structName */ "CastModifierData",
+ /* structSize */ sizeof(CastModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice |
+ eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c
index 8bf9d50cda7..9eeef583e44 100644
--- a/source/blender/modifiers/intern/MOD_cloth.c
+++ b/source/blender/modifiers/intern/MOD_cloth.c
@@ -52,210 +52,217 @@
static void initData(ModifierData *md)
{
- ClothModifierData *clmd = (ClothModifierData *) md;
+ ClothModifierData *clmd = (ClothModifierData *)md;
- clmd->sim_parms = MEM_callocN(sizeof(ClothSimSettings), "cloth sim parms");
- clmd->coll_parms = MEM_callocN(sizeof(ClothCollSettings), "cloth coll parms");
- clmd->point_cache = BKE_ptcache_add(&clmd->ptcaches);
+ clmd->sim_parms = MEM_callocN(sizeof(ClothSimSettings), "cloth sim parms");
+ clmd->coll_parms = MEM_callocN(sizeof(ClothCollSettings), "cloth coll parms");
+ clmd->point_cache = BKE_ptcache_add(&clmd->ptcaches);
- /* check for alloc failing */
- if (!clmd->sim_parms || !clmd->coll_parms || !clmd->point_cache)
- return;
+ /* check for alloc failing */
+ if (!clmd->sim_parms || !clmd->coll_parms || !clmd->point_cache)
+ return;
- cloth_init(clmd);
+ cloth_init(clmd);
}
-static void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh, float (*vertexCos)[3],
- int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- Mesh *mesh_src;
- ClothModifierData *clmd = (ClothModifierData *) md;
- Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
-
- /* check for alloc failing */
- if (!clmd->sim_parms || !clmd->coll_parms) {
- initData(md);
-
- if (!clmd->sim_parms || !clmd->coll_parms)
- return;
- }
-
- if (mesh == NULL) {
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, NULL, numVerts, false, false);
- }
- else {
- /* Not possible to use get_mesh() in this case as we'll modify its vertices
- * and get_mesh() would return 'mesh' directly. */
- BKE_id_copy_ex(NULL, (ID *)mesh, (ID **)&mesh_src, LIB_ID_COPY_LOCALIZE);
- }
-
- /* TODO(sergey): For now it actually duplicates logic from DerivedMesh.c
- * and needs some more generic solution. But starting experimenting with
- * this so close to the release is not that nice..
- *
- * Also hopefully new cloth system will arrive soon..
- */
- if (mesh == NULL && clmd->sim_parms->shapekey_rest) {
- KeyBlock *kb = BKE_keyblock_from_key(BKE_key_from_object(ctx->object),
- clmd->sim_parms->shapekey_rest);
- if (kb && kb->data != NULL) {
- float (*layerorco)[3];
- if (!(layerorco = CustomData_get_layer(&mesh_src->vdata, CD_CLOTH_ORCO))) {
- layerorco = CustomData_add_layer(&mesh_src->vdata, CD_CLOTH_ORCO, CD_CALLOC, NULL, mesh_src->totvert);
- }
-
- memcpy(layerorco, kb->data, sizeof(float) * 3 * numVerts);
- }
- }
-
- BKE_mesh_apply_vert_coords(mesh_src, vertexCos);
-
- clothModifier_do(clmd, ctx->depsgraph, scene, ctx->object, mesh_src, vertexCos);
-
- BKE_id_free(NULL, mesh_src);
+ Mesh *mesh_src;
+ ClothModifierData *clmd = (ClothModifierData *)md;
+ Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+
+ /* check for alloc failing */
+ if (!clmd->sim_parms || !clmd->coll_parms) {
+ initData(md);
+
+ if (!clmd->sim_parms || !clmd->coll_parms)
+ return;
+ }
+
+ if (mesh == NULL) {
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, NULL, numVerts, false, false);
+ }
+ else {
+ /* Not possible to use get_mesh() in this case as we'll modify its vertices
+ * and get_mesh() would return 'mesh' directly. */
+ BKE_id_copy_ex(NULL, (ID *)mesh, (ID **)&mesh_src, LIB_ID_COPY_LOCALIZE);
+ }
+
+ /* TODO(sergey): For now it actually duplicates logic from DerivedMesh.c
+ * and needs some more generic solution. But starting experimenting with
+ * this so close to the release is not that nice..
+ *
+ * Also hopefully new cloth system will arrive soon..
+ */
+ if (mesh == NULL && clmd->sim_parms->shapekey_rest) {
+ KeyBlock *kb = BKE_keyblock_from_key(BKE_key_from_object(ctx->object),
+ clmd->sim_parms->shapekey_rest);
+ if (kb && kb->data != NULL) {
+ float(*layerorco)[3];
+ if (!(layerorco = CustomData_get_layer(&mesh_src->vdata, CD_CLOTH_ORCO))) {
+ layerorco = CustomData_add_layer(
+ &mesh_src->vdata, CD_CLOTH_ORCO, CD_CALLOC, NULL, mesh_src->totvert);
+ }
+
+ memcpy(layerorco, kb->data, sizeof(float) * 3 * numVerts);
+ }
+ }
+
+ BKE_mesh_apply_vert_coords(mesh_src, vertexCos);
+
+ clothModifier_do(clmd, ctx->depsgraph, scene, ctx->object, mesh_src, vertexCos);
+
+ BKE_id_free(NULL, mesh_src);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- ClothModifierData *clmd = (ClothModifierData *)md;
- if (clmd != NULL) {
- DEG_add_collision_relations(ctx->node, ctx->object, clmd->coll_parms->group, eModifierType_Collision, NULL, "Cloth Collision");
- DEG_add_forcefield_relations(ctx->node, ctx->object, clmd->sim_parms->effector_weights, true, 0, "Cloth Field");
- }
- DEG_add_modifier_to_transform_relation(ctx->node, "Cloth Modifier");
+ ClothModifierData *clmd = (ClothModifierData *)md;
+ if (clmd != NULL) {
+ DEG_add_collision_relations(ctx->node,
+ ctx->object,
+ clmd->coll_parms->group,
+ eModifierType_Collision,
+ NULL,
+ "Cloth Collision");
+ DEG_add_forcefield_relations(
+ ctx->node, ctx->object, clmd->sim_parms->effector_weights, true, 0, "Cloth Field");
+ }
+ DEG_add_modifier_to_transform_relation(ctx->node, "Cloth Modifier");
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- ClothModifierData *clmd = (ClothModifierData *)md;
+ ClothModifierData *clmd = (ClothModifierData *)md;
- if (cloth_uses_vgroup(clmd)) {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ if (cloth_uses_vgroup(clmd)) {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
- if (clmd->sim_parms->shapekey_rest != 0) {
- r_cddata_masks->vmask |= CD_MASK_CLOTH_ORCO;
- }
+ if (clmd->sim_parms->shapekey_rest != 0) {
+ r_cddata_masks->vmask |= CD_MASK_CLOTH_ORCO;
+ }
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
- const ClothModifierData *clmd = (const ClothModifierData *) md;
- ClothModifierData *tclmd = (ClothModifierData *) target;
-
- if (tclmd->sim_parms) {
- if (tclmd->sim_parms->effector_weights)
- MEM_freeN(tclmd->sim_parms->effector_weights);
- MEM_freeN(tclmd->sim_parms);
- }
-
- if (tclmd->coll_parms)
- MEM_freeN(tclmd->coll_parms);
-
- BKE_ptcache_free_list(&tclmd->ptcaches);
- if (flag & LIB_ID_CREATE_NO_MAIN) {
- /* Share the cache with the original object's modifier. */
- tclmd->modifier.flag |= eModifierFlag_SharedCaches;
- tclmd->ptcaches = clmd->ptcaches;
- tclmd->point_cache = clmd->point_cache;
- }
- else {
- tclmd->point_cache = BKE_ptcache_add(&tclmd->ptcaches);
- tclmd->point_cache->step = 1;
- }
-
- tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms);
- if (clmd->sim_parms->effector_weights)
- tclmd->sim_parms->effector_weights = MEM_dupallocN(clmd->sim_parms->effector_weights);
- tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
- tclmd->clothObject = NULL;
- tclmd->hairdata = NULL;
- tclmd->solver_result = NULL;
+ const ClothModifierData *clmd = (const ClothModifierData *)md;
+ ClothModifierData *tclmd = (ClothModifierData *)target;
+
+ if (tclmd->sim_parms) {
+ if (tclmd->sim_parms->effector_weights)
+ MEM_freeN(tclmd->sim_parms->effector_weights);
+ MEM_freeN(tclmd->sim_parms);
+ }
+
+ if (tclmd->coll_parms)
+ MEM_freeN(tclmd->coll_parms);
+
+ BKE_ptcache_free_list(&tclmd->ptcaches);
+ if (flag & LIB_ID_CREATE_NO_MAIN) {
+ /* Share the cache with the original object's modifier. */
+ tclmd->modifier.flag |= eModifierFlag_SharedCaches;
+ tclmd->ptcaches = clmd->ptcaches;
+ tclmd->point_cache = clmd->point_cache;
+ }
+ else {
+ tclmd->point_cache = BKE_ptcache_add(&tclmd->ptcaches);
+ tclmd->point_cache->step = 1;
+ }
+
+ tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms);
+ if (clmd->sim_parms->effector_weights)
+ tclmd->sim_parms->effector_weights = MEM_dupallocN(clmd->sim_parms->effector_weights);
+ tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
+ tclmd->clothObject = NULL;
+ tclmd->hairdata = NULL;
+ tclmd->solver_result = NULL;
}
static bool dependsOnTime(ModifierData *UNUSED(md))
{
- return true;
+ return true;
}
static void freeData(ModifierData *md)
{
- ClothModifierData *clmd = (ClothModifierData *) md;
-
- if (clmd) {
- if (G.debug & G_DEBUG_SIMDATA) {
- printf("clothModifier_freeData\n");
- }
-
- cloth_free_modifier_extern(clmd);
-
- if (clmd->sim_parms) {
- if (clmd->sim_parms->effector_weights)
- MEM_freeN(clmd->sim_parms->effector_weights);
- MEM_freeN(clmd->sim_parms);
- }
- if (clmd->coll_parms)
- MEM_freeN(clmd->coll_parms);
-
- if (md->flag & eModifierFlag_SharedCaches) {
- BLI_listbase_clear(&clmd->ptcaches);
- }
- else {
- BKE_ptcache_free_list(&clmd->ptcaches);
- }
- clmd->point_cache = NULL;
-
- if (clmd->hairdata)
- MEM_freeN(clmd->hairdata);
-
- if (clmd->solver_result)
- MEM_freeN(clmd->solver_result);
- }
+ ClothModifierData *clmd = (ClothModifierData *)md;
+
+ if (clmd) {
+ if (G.debug & G_DEBUG_SIMDATA) {
+ printf("clothModifier_freeData\n");
+ }
+
+ cloth_free_modifier_extern(clmd);
+
+ if (clmd->sim_parms) {
+ if (clmd->sim_parms->effector_weights)
+ MEM_freeN(clmd->sim_parms->effector_weights);
+ MEM_freeN(clmd->sim_parms);
+ }
+ if (clmd->coll_parms)
+ MEM_freeN(clmd->coll_parms);
+
+ if (md->flag & eModifierFlag_SharedCaches) {
+ BLI_listbase_clear(&clmd->ptcaches);
+ }
+ else {
+ BKE_ptcache_free_list(&clmd->ptcaches);
+ }
+ clmd->point_cache = NULL;
+
+ if (clmd->hairdata)
+ MEM_freeN(clmd->hairdata);
+
+ if (clmd->solver_result)
+ MEM_freeN(clmd->solver_result);
+ }
}
-static void foreachIDLink(
- ModifierData *md, Object *ob,
- IDWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
- ClothModifierData *clmd = (ClothModifierData *) md;
+ ClothModifierData *clmd = (ClothModifierData *)md;
- if (clmd->coll_parms) {
- walk(userData, ob, (ID **)&clmd->coll_parms->group, IDWALK_CB_NOP);
- }
+ if (clmd->coll_parms) {
+ walk(userData, ob, (ID **)&clmd->coll_parms->group, IDWALK_CB_NOP);
+ }
- if (clmd->sim_parms && clmd->sim_parms->effector_weights) {
- walk(userData, ob, (ID **)&clmd->sim_parms->effector_weights->group, IDWALK_CB_NOP);
- }
+ if (clmd->sim_parms && clmd->sim_parms->effector_weights) {
+ walk(userData, ob, (ID **)&clmd->sim_parms->effector_weights->group, IDWALK_CB_NOP);
+ }
}
ModifierTypeInfo modifierType_Cloth = {
- /* name */ "Cloth",
- /* structName */ "ClothModifierData",
- /* structSize */ sizeof(ClothModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_UsesPointCache |
- eModifierTypeFlag_Single,
-
- /* copyData */ copyData,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ freeData,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ foreachIDLink,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Cloth",
+ /* structName */ "ClothModifierData",
+ /* structSize */ sizeof(ClothModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_UsesPointCache |
+ eModifierTypeFlag_Single,
+
+ /* copyData */ copyData,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ freeData,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c
index 2e56da6f100..59f4a1a93b6 100644
--- a/source/blender/modifiers/intern/MOD_collision.c
+++ b/source/blender/modifiers/intern/MOD_collision.c
@@ -47,229 +47,223 @@
static void initData(ModifierData *md)
{
- CollisionModifierData *collmd = (CollisionModifierData *) md;
-
- collmd->x = NULL;
- collmd->xnew = NULL;
- collmd->current_x = NULL;
- collmd->current_xnew = NULL;
- collmd->current_v = NULL;
- collmd->time_x = collmd->time_xnew = -1000;
- collmd->mvert_num = 0;
- collmd->tri_num = 0;
- collmd->is_static = false;
- collmd->bvhtree = NULL;
+ CollisionModifierData *collmd = (CollisionModifierData *)md;
+
+ collmd->x = NULL;
+ collmd->xnew = NULL;
+ collmd->current_x = NULL;
+ collmd->current_xnew = NULL;
+ collmd->current_v = NULL;
+ collmd->time_x = collmd->time_xnew = -1000;
+ collmd->mvert_num = 0;
+ collmd->tri_num = 0;
+ collmd->is_static = false;
+ collmd->bvhtree = NULL;
}
static void freeData(ModifierData *md)
{
- CollisionModifierData *collmd = (CollisionModifierData *) md;
-
- if (collmd) { /* Seriously? */
- if (collmd->bvhtree) {
- BLI_bvhtree_free(collmd->bvhtree);
- collmd->bvhtree = NULL;
- }
-
- MEM_SAFE_FREE(collmd->x);
- MEM_SAFE_FREE(collmd->xnew);
- MEM_SAFE_FREE(collmd->current_x);
- MEM_SAFE_FREE(collmd->current_xnew);
- MEM_SAFE_FREE(collmd->current_v);
-
- MEM_SAFE_FREE(collmd->tri);
-
- collmd->time_x = collmd->time_xnew = -1000;
- collmd->mvert_num = 0;
- collmd->tri_num = 0;
- collmd->is_static = false;
- }
+ CollisionModifierData *collmd = (CollisionModifierData *)md;
+
+ if (collmd) { /* Seriously? */
+ if (collmd->bvhtree) {
+ BLI_bvhtree_free(collmd->bvhtree);
+ collmd->bvhtree = NULL;
+ }
+
+ MEM_SAFE_FREE(collmd->x);
+ MEM_SAFE_FREE(collmd->xnew);
+ MEM_SAFE_FREE(collmd->current_x);
+ MEM_SAFE_FREE(collmd->current_xnew);
+ MEM_SAFE_FREE(collmd->current_v);
+
+ MEM_SAFE_FREE(collmd->tri);
+
+ collmd->time_x = collmd->time_xnew = -1000;
+ collmd->mvert_num = 0;
+ collmd->tri_num = 0;
+ collmd->is_static = false;
+ }
}
static bool dependsOnTime(ModifierData *UNUSED(md))
{
- return true;
+ return true;
}
-static void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh,
- float (*vertexCos)[3],
- int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- CollisionModifierData *collmd = (CollisionModifierData *) md;
- Mesh *mesh_src;
- MVert *tempVert = NULL;
- Object *ob = ctx->object;
-
- if (mesh == NULL) {
- mesh_src = MOD_deform_mesh_eval_get(ob, NULL, NULL, NULL, numVerts, false, false);
- }
- else {
- /* Not possible to use get_mesh() in this case as we'll modify its vertices
- * and get_mesh() would return 'mesh' directly. */
- BKE_id_copy_ex(NULL, (ID *)mesh, (ID **)&mesh_src, LIB_ID_COPY_LOCALIZE);
- }
-
- if (!ob->pd) {
- printf("CollisionModifier deformVerts: Should not happen!\n");
- return;
- }
-
- if (mesh_src) {
- float current_time = 0;
- unsigned int mvert_num = 0;
-
- BKE_mesh_apply_vert_coords(mesh_src, vertexCos);
- BKE_mesh_calc_normals(mesh_src);
-
- current_time = DEG_get_ctime(ctx->depsgraph);
-
- if (G.debug & G_DEBUG_SIMDATA) {
- printf("current_time %f, collmd->time_xnew %f\n", current_time, collmd->time_xnew);
- }
-
- mvert_num = mesh_src->totvert;
-
- if (current_time < collmd->time_xnew) {
- freeData((ModifierData *)collmd);
- }
- else if (current_time == collmd->time_xnew) {
- if (mvert_num != collmd->mvert_num) {
- freeData((ModifierData *)collmd);
- }
- }
-
- /* check if mesh has changed */
- if (collmd->x && (mvert_num != collmd->mvert_num))
- freeData((ModifierData *)collmd);
-
- if (collmd->time_xnew == -1000) { /* first time */
-
- collmd->x = MEM_dupallocN(mesh_src->mvert); /* frame start position */
-
- for (uint i = 0; i < mvert_num; i++) {
- /* we save global positions */
- mul_m4_v3(ob->obmat, collmd->x[i].co);
- }
-
- collmd->xnew = MEM_dupallocN(collmd->x); // frame end position
- collmd->current_x = MEM_dupallocN(collmd->x); // inter-frame
- collmd->current_xnew = MEM_dupallocN(collmd->x); // inter-frame
- collmd->current_v = MEM_dupallocN(collmd->x); // inter-frame
-
- collmd->mvert_num = mvert_num;
-
- {
- const MLoop *mloop = mesh_src->mloop;
- const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh_src);
- collmd->tri_num = BKE_mesh_runtime_looptri_len(mesh_src);
- MVertTri *tri = MEM_mallocN(sizeof(*tri) * collmd->tri_num, __func__);
- BKE_mesh_runtime_verttri_from_looptri(tri, mloop, looptri, collmd->tri_num);
- collmd->tri = tri;
- }
-
- /* create bounding box hierarchy */
- collmd->bvhtree = bvhtree_build_from_mvert(
- collmd->x,
- collmd->tri, collmd->tri_num,
- ob->pd->pdef_sboft);
-
- collmd->time_x = collmd->time_xnew = current_time;
- collmd->is_static = true;
- }
- else if (mvert_num == collmd->mvert_num) {
- /* put positions to old positions */
- tempVert = collmd->x;
- collmd->x = collmd->xnew;
- collmd->xnew = tempVert;
- collmd->time_x = collmd->time_xnew;
-
- memcpy(collmd->xnew, mesh_src->mvert, mvert_num * sizeof(MVert));
-
- bool is_static = true;
-
- for (uint i = 0; i < mvert_num; i++) {
- /* we save global positions */
- mul_m4_v3(ob->obmat, collmd->xnew[i].co);
-
- /* detect motion */
- is_static = is_static && equals_v3v3(collmd->x[i].co, collmd->xnew[i].co);
- }
-
- memcpy(collmd->current_xnew, collmd->x, mvert_num * sizeof(MVert));
- memcpy(collmd->current_x, collmd->x, mvert_num * sizeof(MVert));
-
- /* check if GUI setting has changed for bvh */
- if (collmd->bvhtree) {
- if (ob->pd->pdef_sboft != BLI_bvhtree_get_epsilon(collmd->bvhtree)) {
- BLI_bvhtree_free(collmd->bvhtree);
- collmd->bvhtree = bvhtree_build_from_mvert(
- collmd->current_x,
- collmd->tri, collmd->tri_num,
- ob->pd->pdef_sboft);
- }
- }
-
- /* happens on file load (ONLY when i decomment changes in readfile.c) */
- if (!collmd->bvhtree) {
- collmd->bvhtree = bvhtree_build_from_mvert(
- collmd->current_x,
- collmd->tri, collmd->tri_num,
- ob->pd->pdef_sboft);
- }
- else if (!collmd->is_static || !is_static) {
- /* recalc static bounding boxes */
- bvhtree_update_from_mvert(
- collmd->bvhtree,
- collmd->current_x, collmd->current_xnew,
- collmd->tri, collmd->tri_num,
- true);
- }
-
- collmd->is_static = is_static;
- collmd->time_xnew = current_time;
- }
- else if (mvert_num != collmd->mvert_num) {
- freeData((ModifierData *)collmd);
- }
- }
-
- if (mesh_src != mesh) {
- BKE_id_free(NULL, mesh_src);
- }
+ CollisionModifierData *collmd = (CollisionModifierData *)md;
+ Mesh *mesh_src;
+ MVert *tempVert = NULL;
+ Object *ob = ctx->object;
+
+ if (mesh == NULL) {
+ mesh_src = MOD_deform_mesh_eval_get(ob, NULL, NULL, NULL, numVerts, false, false);
+ }
+ else {
+ /* Not possible to use get_mesh() in this case as we'll modify its vertices
+ * and get_mesh() would return 'mesh' directly. */
+ BKE_id_copy_ex(NULL, (ID *)mesh, (ID **)&mesh_src, LIB_ID_COPY_LOCALIZE);
+ }
+
+ if (!ob->pd) {
+ printf("CollisionModifier deformVerts: Should not happen!\n");
+ return;
+ }
+
+ if (mesh_src) {
+ float current_time = 0;
+ unsigned int mvert_num = 0;
+
+ BKE_mesh_apply_vert_coords(mesh_src, vertexCos);
+ BKE_mesh_calc_normals(mesh_src);
+
+ current_time = DEG_get_ctime(ctx->depsgraph);
+
+ if (G.debug & G_DEBUG_SIMDATA) {
+ printf("current_time %f, collmd->time_xnew %f\n", current_time, collmd->time_xnew);
+ }
+
+ mvert_num = mesh_src->totvert;
+
+ if (current_time < collmd->time_xnew) {
+ freeData((ModifierData *)collmd);
+ }
+ else if (current_time == collmd->time_xnew) {
+ if (mvert_num != collmd->mvert_num) {
+ freeData((ModifierData *)collmd);
+ }
+ }
+
+ /* check if mesh has changed */
+ if (collmd->x && (mvert_num != collmd->mvert_num))
+ freeData((ModifierData *)collmd);
+
+ if (collmd->time_xnew == -1000) { /* first time */
+
+ collmd->x = MEM_dupallocN(mesh_src->mvert); /* frame start position */
+
+ for (uint i = 0; i < mvert_num; i++) {
+ /* we save global positions */
+ mul_m4_v3(ob->obmat, collmd->x[i].co);
+ }
+
+ collmd->xnew = MEM_dupallocN(collmd->x); // frame end position
+ collmd->current_x = MEM_dupallocN(collmd->x); // inter-frame
+ collmd->current_xnew = MEM_dupallocN(collmd->x); // inter-frame
+ collmd->current_v = MEM_dupallocN(collmd->x); // inter-frame
+
+ collmd->mvert_num = mvert_num;
+
+ {
+ const MLoop *mloop = mesh_src->mloop;
+ const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh_src);
+ collmd->tri_num = BKE_mesh_runtime_looptri_len(mesh_src);
+ MVertTri *tri = MEM_mallocN(sizeof(*tri) * collmd->tri_num, __func__);
+ BKE_mesh_runtime_verttri_from_looptri(tri, mloop, looptri, collmd->tri_num);
+ collmd->tri = tri;
+ }
+
+ /* create bounding box hierarchy */
+ collmd->bvhtree = bvhtree_build_from_mvert(
+ collmd->x, collmd->tri, collmd->tri_num, ob->pd->pdef_sboft);
+
+ collmd->time_x = collmd->time_xnew = current_time;
+ collmd->is_static = true;
+ }
+ else if (mvert_num == collmd->mvert_num) {
+ /* put positions to old positions */
+ tempVert = collmd->x;
+ collmd->x = collmd->xnew;
+ collmd->xnew = tempVert;
+ collmd->time_x = collmd->time_xnew;
+
+ memcpy(collmd->xnew, mesh_src->mvert, mvert_num * sizeof(MVert));
+
+ bool is_static = true;
+
+ for (uint i = 0; i < mvert_num; i++) {
+ /* we save global positions */
+ mul_m4_v3(ob->obmat, collmd->xnew[i].co);
+
+ /* detect motion */
+ is_static = is_static && equals_v3v3(collmd->x[i].co, collmd->xnew[i].co);
+ }
+
+ memcpy(collmd->current_xnew, collmd->x, mvert_num * sizeof(MVert));
+ memcpy(collmd->current_x, collmd->x, mvert_num * sizeof(MVert));
+
+ /* check if GUI setting has changed for bvh */
+ if (collmd->bvhtree) {
+ if (ob->pd->pdef_sboft != BLI_bvhtree_get_epsilon(collmd->bvhtree)) {
+ BLI_bvhtree_free(collmd->bvhtree);
+ collmd->bvhtree = bvhtree_build_from_mvert(
+ collmd->current_x, collmd->tri, collmd->tri_num, ob->pd->pdef_sboft);
+ }
+ }
+
+ /* happens on file load (ONLY when i decomment changes in readfile.c) */
+ if (!collmd->bvhtree) {
+ collmd->bvhtree = bvhtree_build_from_mvert(
+ collmd->current_x, collmd->tri, collmd->tri_num, ob->pd->pdef_sboft);
+ }
+ else if (!collmd->is_static || !is_static) {
+ /* recalc static bounding boxes */
+ bvhtree_update_from_mvert(collmd->bvhtree,
+ collmd->current_x,
+ collmd->current_xnew,
+ collmd->tri,
+ collmd->tri_num,
+ true);
+ }
+
+ collmd->is_static = is_static;
+ collmd->time_xnew = current_time;
+ }
+ else if (mvert_num != collmd->mvert_num) {
+ freeData((ModifierData *)collmd);
+ }
+ }
+
+ if (mesh_src != mesh) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
static void updateDepsgraph(ModifierData *UNUSED(md), const ModifierUpdateDepsgraphContext *ctx)
{
- DEG_add_modifier_to_transform_relation(ctx->node, "Collision Modifier");
+ DEG_add_modifier_to_transform_relation(ctx->node, "Collision Modifier");
}
ModifierTypeInfo modifierType_Collision = {
- /* name */ "Collision",
- /* structName */ "CollisionModifierData",
- /* structSize */ sizeof(CollisionModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_Single,
-
- /* copyData */ NULL,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ NULL,
- /* freeData */ freeData,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Collision",
+ /* structName */ "CollisionModifierData",
+ /* structSize */ sizeof(CollisionModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_Single,
+
+ /* copyData */ NULL,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ freeData,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c
index d9e6ed78070..2a332bc9709 100644
--- a/source/blender/modifiers/intern/MOD_correctivesmooth.c
+++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c
@@ -44,10 +44,8 @@
#include "BLI_strict_flags.h"
-
#include "DEG_depsgraph_query.h"
-
// #define DEBUG_TIME
#include "PIL_time.h"
@@ -60,345 +58,343 @@
static void initData(ModifierData *md)
{
- CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
+ CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
- csmd->bind_coords = NULL;
- csmd->bind_coords_num = 0;
+ csmd->bind_coords = NULL;
+ csmd->bind_coords_num = 0;
- csmd->lambda = 0.5f;
- csmd->repeat = 5;
- csmd->flag = 0;
- csmd->smooth_type = MOD_CORRECTIVESMOOTH_SMOOTH_SIMPLE;
+ csmd->lambda = 0.5f;
+ csmd->repeat = 5;
+ csmd->flag = 0;
+ csmd->smooth_type = MOD_CORRECTIVESMOOTH_SMOOTH_SIMPLE;
- csmd->defgrp_name[0] = '\0';
+ csmd->defgrp_name[0] = '\0';
- csmd->delta_cache = NULL;
+ csmd->delta_cache = NULL;
}
-
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
- const CorrectiveSmoothModifierData *csmd = (const CorrectiveSmoothModifierData *)md;
- CorrectiveSmoothModifierData *tcsmd = (CorrectiveSmoothModifierData *)target;
+ const CorrectiveSmoothModifierData *csmd = (const CorrectiveSmoothModifierData *)md;
+ CorrectiveSmoothModifierData *tcsmd = (CorrectiveSmoothModifierData *)target;
- modifier_copyData_generic(md, target, flag);
+ modifier_copyData_generic(md, target, flag);
- if (csmd->bind_coords) {
- tcsmd->bind_coords = MEM_dupallocN(csmd->bind_coords);
- }
+ if (csmd->bind_coords) {
+ tcsmd->bind_coords = MEM_dupallocN(csmd->bind_coords);
+ }
- tcsmd->delta_cache = NULL;
- tcsmd->delta_cache_num = 0;
+ tcsmd->delta_cache = NULL;
+ tcsmd->delta_cache_num = 0;
}
-
static void freeBind(CorrectiveSmoothModifierData *csmd)
{
- MEM_SAFE_FREE(csmd->bind_coords);
- MEM_SAFE_FREE(csmd->delta_cache);
+ MEM_SAFE_FREE(csmd->bind_coords);
+ MEM_SAFE_FREE(csmd->delta_cache);
- csmd->bind_coords_num = 0;
+ csmd->bind_coords_num = 0;
}
-
static void freeData(ModifierData *md)
{
- CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
- freeBind(csmd);
+ CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
+ freeBind(csmd);
}
-
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
+ CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
- /* ask for vertex groups if we need them */
- if (csmd->defgrp_name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ /* ask for vertex groups if we need them */
+ if (csmd->defgrp_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
-
/* check individual weights for changes and cache values */
-static void mesh_get_weights(
- MDeformVert *dvert, const int defgrp_index,
- const unsigned int numVerts, const bool use_invert_vgroup,
- float *smooth_weights)
+static void mesh_get_weights(MDeformVert *dvert,
+ const int defgrp_index,
+ const unsigned int numVerts,
+ const bool use_invert_vgroup,
+ float *smooth_weights)
{
- unsigned int i;
-
- for (i = 0; i < numVerts; i++, dvert++) {
- const float w = defvert_find_weight(dvert, defgrp_index);
-
- if (use_invert_vgroup == false) {
- smooth_weights[i] = w;
- }
- else {
- smooth_weights[i] = 1.0f - w;
- }
- }
+ unsigned int i;
+
+ for (i = 0; i < numVerts; i++, dvert++) {
+ const float w = defvert_find_weight(dvert, defgrp_index);
+
+ if (use_invert_vgroup == false) {
+ smooth_weights[i] = w;
+ }
+ else {
+ smooth_weights[i] = 1.0f - w;
+ }
+ }
}
-
static void mesh_get_boundaries(Mesh *mesh, float *smooth_weights)
{
- const MPoly *mpoly = mesh->mpoly;
- const MLoop *mloop = mesh->mloop;
- const MEdge *medge = mesh->medge;
- unsigned int mpoly_num, medge_num, i;
- unsigned short *boundaries;
-
- mpoly_num = (unsigned int)mesh->totpoly;
- medge_num = (unsigned int)mesh->totedge;
-
- boundaries = MEM_calloc_arrayN(medge_num, sizeof(*boundaries), __func__);
-
- /* count the number of adjacent faces */
- for (i = 0; i < mpoly_num; i++) {
- const MPoly *p = &mpoly[i];
- const int totloop = p->totloop;
- int j;
- for (j = 0; j < totloop; j++) {
- boundaries[mloop[p->loopstart + j].e]++;
- }
- }
-
- for (i = 0; i < medge_num; i++) {
- if (boundaries[i] == 1) {
- smooth_weights[medge[i].v1] = 0.0f;
- smooth_weights[medge[i].v2] = 0.0f;
- }
- }
-
- MEM_freeN(boundaries);
+ const MPoly *mpoly = mesh->mpoly;
+ const MLoop *mloop = mesh->mloop;
+ const MEdge *medge = mesh->medge;
+ unsigned int mpoly_num, medge_num, i;
+ unsigned short *boundaries;
+
+ mpoly_num = (unsigned int)mesh->totpoly;
+ medge_num = (unsigned int)mesh->totedge;
+
+ boundaries = MEM_calloc_arrayN(medge_num, sizeof(*boundaries), __func__);
+
+ /* count the number of adjacent faces */
+ for (i = 0; i < mpoly_num; i++) {
+ const MPoly *p = &mpoly[i];
+ const int totloop = p->totloop;
+ int j;
+ for (j = 0; j < totloop; j++) {
+ boundaries[mloop[p->loopstart + j].e]++;
+ }
+ }
+
+ for (i = 0; i < medge_num; i++) {
+ if (boundaries[i] == 1) {
+ smooth_weights[medge[i].v1] = 0.0f;
+ smooth_weights[medge[i].v2] = 0.0f;
+ }
+ }
+
+ MEM_freeN(boundaries);
}
-
/* -------------------------------------------------------------------- */
/* Simple Weighted Smoothing
*
* (average of surrounding verts)
*/
-static void smooth_iter__simple(
- CorrectiveSmoothModifierData *csmd, Mesh *mesh,
- float (*vertexCos)[3], unsigned int numVerts,
- const float *smooth_weights,
- unsigned int iterations)
+static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ unsigned int numVerts,
+ const float *smooth_weights,
+ unsigned int iterations)
{
- const float lambda = csmd->lambda;
- unsigned int i;
-
- const unsigned int numEdges = (unsigned int)mesh->totedge;
- const MEdge *edges = mesh->medge;
- float *vertex_edge_count_div;
-
- struct SmoothingData_Simple {
- float delta[3];
- } *smooth_data = MEM_calloc_arrayN(numVerts, sizeof(*smooth_data), __func__);
-
- vertex_edge_count_div = MEM_calloc_arrayN(numVerts, sizeof(float), __func__);
-
- /* calculate as floats to avoid int->float conversion in #smooth_iter */
- for (i = 0; i < numEdges; i++) {
- vertex_edge_count_div[edges[i].v1] += 1.0f;
- vertex_edge_count_div[edges[i].v2] += 1.0f;
- }
-
- /* a little confusing, but we can include 'lambda' and smoothing weight
- * here to avoid multiplying for every iteration */
- if (smooth_weights == NULL) {
- for (i = 0; i < numVerts; i++) {
- vertex_edge_count_div[i] =
- lambda * (vertex_edge_count_div[i] ? (1.0f / vertex_edge_count_div[i]) : 1.0f);
- }
- }
- else {
- for (i = 0; i < numVerts; i++) {
- vertex_edge_count_div[i] =
- smooth_weights[i] * lambda * (vertex_edge_count_div[i] ? (1.0f / vertex_edge_count_div[i]) : 1.0f);
- }
- }
-
- /* -------------------------------------------------------------------- */
- /* Main Smoothing Loop */
-
- while (iterations--) {
- for (i = 0; i < numEdges; i++) {
- struct SmoothingData_Simple *sd_v1;
- struct SmoothingData_Simple *sd_v2;
- float edge_dir[3];
-
- sub_v3_v3v3(edge_dir, vertexCos[edges[i].v2], vertexCos[edges[i].v1]);
-
- sd_v1 = &smooth_data[edges[i].v1];
- sd_v2 = &smooth_data[edges[i].v2];
-
- add_v3_v3(sd_v1->delta, edge_dir);
- sub_v3_v3(sd_v2->delta, edge_dir);
- }
-
-
- for (i = 0; i < numVerts; i++) {
- struct SmoothingData_Simple *sd = &smooth_data[i];
- madd_v3_v3fl(vertexCos[i], sd->delta, vertex_edge_count_div[i]);
- /* zero for the next iteration (saves memset on entire array) */
- memset(sd, 0, sizeof(*sd));
- }
- }
-
- MEM_freeN(vertex_edge_count_div);
- MEM_freeN(smooth_data);
+ const float lambda = csmd->lambda;
+ unsigned int i;
+
+ const unsigned int numEdges = (unsigned int)mesh->totedge;
+ const MEdge *edges = mesh->medge;
+ float *vertex_edge_count_div;
+
+ struct SmoothingData_Simple {
+ float delta[3];
+ } *smooth_data = MEM_calloc_arrayN(numVerts, sizeof(*smooth_data), __func__);
+
+ vertex_edge_count_div = MEM_calloc_arrayN(numVerts, sizeof(float), __func__);
+
+ /* calculate as floats to avoid int->float conversion in #smooth_iter */
+ for (i = 0; i < numEdges; i++) {
+ vertex_edge_count_div[edges[i].v1] += 1.0f;
+ vertex_edge_count_div[edges[i].v2] += 1.0f;
+ }
+
+ /* a little confusing, but we can include 'lambda' and smoothing weight
+ * here to avoid multiplying for every iteration */
+ if (smooth_weights == NULL) {
+ for (i = 0; i < numVerts; i++) {
+ vertex_edge_count_div[i] = lambda * (vertex_edge_count_div[i] ?
+ (1.0f / vertex_edge_count_div[i]) :
+ 1.0f);
+ }
+ }
+ else {
+ for (i = 0; i < numVerts; i++) {
+ vertex_edge_count_div[i] = smooth_weights[i] * lambda *
+ (vertex_edge_count_div[i] ? (1.0f / vertex_edge_count_div[i]) :
+ 1.0f);
+ }
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Main Smoothing Loop */
+
+ while (iterations--) {
+ for (i = 0; i < numEdges; i++) {
+ struct SmoothingData_Simple *sd_v1;
+ struct SmoothingData_Simple *sd_v2;
+ float edge_dir[3];
+
+ sub_v3_v3v3(edge_dir, vertexCos[edges[i].v2], vertexCos[edges[i].v1]);
+
+ sd_v1 = &smooth_data[edges[i].v1];
+ sd_v2 = &smooth_data[edges[i].v2];
+
+ add_v3_v3(sd_v1->delta, edge_dir);
+ sub_v3_v3(sd_v2->delta, edge_dir);
+ }
+
+ for (i = 0; i < numVerts; i++) {
+ struct SmoothingData_Simple *sd = &smooth_data[i];
+ madd_v3_v3fl(vertexCos[i], sd->delta, vertex_edge_count_div[i]);
+ /* zero for the next iteration (saves memset on entire array) */
+ memset(sd, 0, sizeof(*sd));
+ }
+ }
+
+ MEM_freeN(vertex_edge_count_div);
+ MEM_freeN(smooth_data);
}
-
/* -------------------------------------------------------------------- */
/* Edge-Length Weighted Smoothing
*/
-static void smooth_iter__length_weight(
- CorrectiveSmoothModifierData *csmd, Mesh *mesh,
- float (*vertexCos)[3], unsigned int numVerts,
- const float *smooth_weights,
- unsigned int iterations)
+static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ unsigned int numVerts,
+ const float *smooth_weights,
+ unsigned int iterations)
{
- const float eps = FLT_EPSILON * 10.0f;
- const unsigned int numEdges = (unsigned int)mesh->totedge;
- /* note: the way this smoothing method works, its approx half as strong as the simple-smooth,
- * and 2.0 rarely spikes, double the value for consistent behavior. */
- const float lambda = csmd->lambda * 2.0f;
- const MEdge *edges = mesh->medge;
- float *vertex_edge_count;
- unsigned int i;
-
- struct SmoothingData_Weighted {
- float delta[3];
- float edge_length_sum;
- } *smooth_data = MEM_calloc_arrayN(numVerts, sizeof(*smooth_data), __func__);
-
-
- /* calculate as floats to avoid int->float conversion in #smooth_iter */
- vertex_edge_count = MEM_calloc_arrayN(numVerts, sizeof(float), __func__);
- for (i = 0; i < numEdges; i++) {
- vertex_edge_count[edges[i].v1] += 1.0f;
- vertex_edge_count[edges[i].v2] += 1.0f;
- }
-
-
- /* -------------------------------------------------------------------- */
- /* Main Smoothing Loop */
-
- while (iterations--) {
- for (i = 0; i < numEdges; i++) {
- struct SmoothingData_Weighted *sd_v1;
- struct SmoothingData_Weighted *sd_v2;
- float edge_dir[3];
- float edge_dist;
-
- sub_v3_v3v3(edge_dir, vertexCos[edges[i].v2], vertexCos[edges[i].v1]);
- edge_dist = len_v3(edge_dir);
-
- /* weight by distance */
- mul_v3_fl(edge_dir, edge_dist);
-
-
- sd_v1 = &smooth_data[edges[i].v1];
- sd_v2 = &smooth_data[edges[i].v2];
-
- add_v3_v3(sd_v1->delta, edge_dir);
- sub_v3_v3(sd_v2->delta, edge_dir);
-
- sd_v1->edge_length_sum += edge_dist;
- sd_v2->edge_length_sum += edge_dist;
- }
-
- if (smooth_weights == NULL) {
- /* fast-path */
- for (i = 0; i < numVerts; i++) {
- struct SmoothingData_Weighted *sd = &smooth_data[i];
- /* divide by sum of all neighbour distances (weighted) and amount of neighbors, (mean average) */
- const float div = sd->edge_length_sum * vertex_edge_count[i];
- if (div > eps) {
+ const float eps = FLT_EPSILON * 10.0f;
+ const unsigned int numEdges = (unsigned int)mesh->totedge;
+ /* note: the way this smoothing method works, its approx half as strong as the simple-smooth,
+ * and 2.0 rarely spikes, double the value for consistent behavior. */
+ const float lambda = csmd->lambda * 2.0f;
+ const MEdge *edges = mesh->medge;
+ float *vertex_edge_count;
+ unsigned int i;
+
+ struct SmoothingData_Weighted {
+ float delta[3];
+ float edge_length_sum;
+ } *smooth_data = MEM_calloc_arrayN(numVerts, sizeof(*smooth_data), __func__);
+
+ /* calculate as floats to avoid int->float conversion in #smooth_iter */
+ vertex_edge_count = MEM_calloc_arrayN(numVerts, sizeof(float), __func__);
+ for (i = 0; i < numEdges; i++) {
+ vertex_edge_count[edges[i].v1] += 1.0f;
+ vertex_edge_count[edges[i].v2] += 1.0f;
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Main Smoothing Loop */
+
+ while (iterations--) {
+ for (i = 0; i < numEdges; i++) {
+ struct SmoothingData_Weighted *sd_v1;
+ struct SmoothingData_Weighted *sd_v2;
+ float edge_dir[3];
+ float edge_dist;
+
+ sub_v3_v3v3(edge_dir, vertexCos[edges[i].v2], vertexCos[edges[i].v1]);
+ edge_dist = len_v3(edge_dir);
+
+ /* weight by distance */
+ mul_v3_fl(edge_dir, edge_dist);
+
+ sd_v1 = &smooth_data[edges[i].v1];
+ sd_v2 = &smooth_data[edges[i].v2];
+
+ add_v3_v3(sd_v1->delta, edge_dir);
+ sub_v3_v3(sd_v2->delta, edge_dir);
+
+ sd_v1->edge_length_sum += edge_dist;
+ sd_v2->edge_length_sum += edge_dist;
+ }
+
+ if (smooth_weights == NULL) {
+ /* fast-path */
+ for (i = 0; i < numVerts; i++) {
+ struct SmoothingData_Weighted *sd = &smooth_data[i];
+ /* divide by sum of all neighbour distances (weighted) and amount of neighbors, (mean average) */
+ const float div = sd->edge_length_sum * vertex_edge_count[i];
+ if (div > eps) {
#if 0
- /* first calculate the new location */
- mul_v3_fl(sd->delta, 1.0f / div);
- /* then interpolate */
- madd_v3_v3fl(vertexCos[i], sd->delta, lambda);
+ /* first calculate the new location */
+ mul_v3_fl(sd->delta, 1.0f / div);
+ /* then interpolate */
+ madd_v3_v3fl(vertexCos[i], sd->delta, lambda);
#else
- /* do this in one step */
- madd_v3_v3fl(vertexCos[i], sd->delta, lambda / div);
+ /* do this in one step */
+ madd_v3_v3fl(vertexCos[i], sd->delta, lambda / div);
#endif
- }
- /* zero for the next iteration (saves memset on entire array) */
- memset(sd, 0, sizeof(*sd));
- }
- }
- else {
- for (i = 0; i < numVerts; i++) {
- struct SmoothingData_Weighted *sd = &smooth_data[i];
- const float div = sd->edge_length_sum * vertex_edge_count[i];
- if (div > eps) {
- const float lambda_w = lambda * smooth_weights[i];
- madd_v3_v3fl(vertexCos[i], sd->delta, lambda_w / div);
- }
-
- memset(sd, 0, sizeof(*sd));
- }
- }
- }
-
- MEM_freeN(vertex_edge_count);
- MEM_freeN(smooth_data);
+ }
+ /* zero for the next iteration (saves memset on entire array) */
+ memset(sd, 0, sizeof(*sd));
+ }
+ }
+ else {
+ for (i = 0; i < numVerts; i++) {
+ struct SmoothingData_Weighted *sd = &smooth_data[i];
+ const float div = sd->edge_length_sum * vertex_edge_count[i];
+ if (div > eps) {
+ const float lambda_w = lambda * smooth_weights[i];
+ madd_v3_v3fl(vertexCos[i], sd->delta, lambda_w / div);
+ }
+
+ memset(sd, 0, sizeof(*sd));
+ }
+ }
+ }
+
+ MEM_freeN(vertex_edge_count);
+ MEM_freeN(smooth_data);
}
-
-static void smooth_iter(
- CorrectiveSmoothModifierData *csmd, Mesh *mesh,
- float (*vertexCos)[3], unsigned int numVerts,
- const float *smooth_weights,
- unsigned int iterations)
+static void smooth_iter(CorrectiveSmoothModifierData *csmd,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ unsigned int numVerts,
+ const float *smooth_weights,
+ unsigned int iterations)
{
- switch (csmd->smooth_type) {
- case MOD_CORRECTIVESMOOTH_SMOOTH_LENGTH_WEIGHT:
- smooth_iter__length_weight(csmd, mesh, vertexCos, numVerts, smooth_weights, iterations);
- break;
-
- /* case MOD_CORRECTIVESMOOTH_SMOOTH_SIMPLE: */
- default:
- smooth_iter__simple(csmd, mesh, vertexCos, numVerts, smooth_weights, iterations);
- break;
- }
+ switch (csmd->smooth_type) {
+ case MOD_CORRECTIVESMOOTH_SMOOTH_LENGTH_WEIGHT:
+ smooth_iter__length_weight(csmd, mesh, vertexCos, numVerts, smooth_weights, iterations);
+ break;
+
+ /* case MOD_CORRECTIVESMOOTH_SMOOTH_SIMPLE: */
+ default:
+ smooth_iter__simple(csmd, mesh, vertexCos, numVerts, smooth_weights, iterations);
+ break;
+ }
}
-static void smooth_verts(
- CorrectiveSmoothModifierData *csmd, Mesh *mesh,
- MDeformVert *dvert, const int defgrp_index,
- float (*vertexCos)[3], unsigned int numVerts)
+static void smooth_verts(CorrectiveSmoothModifierData *csmd,
+ Mesh *mesh,
+ MDeformVert *dvert,
+ const int defgrp_index,
+ float (*vertexCos)[3],
+ unsigned int numVerts)
{
- float *smooth_weights = NULL;
+ float *smooth_weights = NULL;
- if (dvert || (csmd->flag & MOD_CORRECTIVESMOOTH_PIN_BOUNDARY)) {
+ if (dvert || (csmd->flag & MOD_CORRECTIVESMOOTH_PIN_BOUNDARY)) {
- smooth_weights = MEM_malloc_arrayN(numVerts, sizeof(float), __func__);
+ smooth_weights = MEM_malloc_arrayN(numVerts, sizeof(float), __func__);
- if (dvert) {
- mesh_get_weights(
- dvert, defgrp_index,
- numVerts, (csmd->flag & MOD_CORRECTIVESMOOTH_INVERT_VGROUP) != 0,
- smooth_weights);
- }
- else {
- copy_vn_fl(smooth_weights, (int)numVerts, 1.0f);
- }
+ if (dvert) {
+ mesh_get_weights(dvert,
+ defgrp_index,
+ numVerts,
+ (csmd->flag & MOD_CORRECTIVESMOOTH_INVERT_VGROUP) != 0,
+ smooth_weights);
+ }
+ else {
+ copy_vn_fl(smooth_weights, (int)numVerts, 1.0f);
+ }
- if (csmd->flag & MOD_CORRECTIVESMOOTH_PIN_BOUNDARY) {
- mesh_get_boundaries(mesh, smooth_weights);
- }
- }
+ if (csmd->flag & MOD_CORRECTIVESMOOTH_PIN_BOUNDARY) {
+ mesh_get_boundaries(mesh, smooth_weights);
+ }
+ }
- smooth_iter(csmd, mesh, vertexCos, numVerts, smooth_weights, (unsigned int)csmd->repeat);
+ smooth_iter(csmd, mesh, vertexCos, numVerts, smooth_weights, (unsigned int)csmd->repeat);
- if (smooth_weights) {
- MEM_freeN(smooth_weights);
- }
+ if (smooth_weights) {
+ MEM_freeN(smooth_weights);
+ }
}
/**
@@ -406,109 +402,102 @@ static void smooth_verts(
*/
static void calc_tangent_ortho(float ts[3][3])
{
- float v_tan_a[3], v_tan_b[3];
- float t_vec_a[3], t_vec_b[3];
+ float v_tan_a[3], v_tan_b[3];
+ float t_vec_a[3], t_vec_b[3];
- normalize_v3(ts[2]);
+ normalize_v3(ts[2]);
- copy_v3_v3(v_tan_a, ts[0]);
- copy_v3_v3(v_tan_b, ts[1]);
+ copy_v3_v3(v_tan_a, ts[0]);
+ copy_v3_v3(v_tan_b, ts[1]);
- cross_v3_v3v3(ts[1], ts[2], v_tan_a);
- mul_v3_fl(ts[1], dot_v3v3(ts[1], v_tan_b) < 0.0f ? -1.0f : 1.0f);
+ cross_v3_v3v3(ts[1], ts[2], v_tan_a);
+ mul_v3_fl(ts[1], dot_v3v3(ts[1], v_tan_b) < 0.0f ? -1.0f : 1.0f);
- /* orthognalise tangent */
- mul_v3_v3fl(t_vec_a, ts[2], dot_v3v3(ts[2], v_tan_a));
- sub_v3_v3v3(ts[0], v_tan_a, t_vec_a);
+ /* orthognalise tangent */
+ mul_v3_v3fl(t_vec_a, ts[2], dot_v3v3(ts[2], v_tan_a));
+ sub_v3_v3v3(ts[0], v_tan_a, t_vec_a);
- /* orthognalise bitangent */
- mul_v3_v3fl(t_vec_a, ts[2], dot_v3v3(ts[2], ts[1]));
- mul_v3_v3fl(t_vec_b, ts[0], dot_v3v3(ts[0], ts[1]) / dot_v3v3(v_tan_a, v_tan_a));
- sub_v3_v3(ts[1], t_vec_a);
- sub_v3_v3(ts[1], t_vec_b);
+ /* orthognalise bitangent */
+ mul_v3_v3fl(t_vec_a, ts[2], dot_v3v3(ts[2], ts[1]));
+ mul_v3_v3fl(t_vec_b, ts[0], dot_v3v3(ts[0], ts[1]) / dot_v3v3(v_tan_a, v_tan_a));
+ sub_v3_v3(ts[1], t_vec_a);
+ sub_v3_v3(ts[1], t_vec_b);
- normalize_v3(ts[0]);
- normalize_v3(ts[1]);
+ normalize_v3(ts[0]);
+ normalize_v3(ts[1]);
}
/**
* accumulate edge-vectors from all polys.
*/
-static void calc_tangent_loop_accum(
- const float v_dir_prev[3],
- const float v_dir_next[3],
- float r_tspace[3][3])
+static void calc_tangent_loop_accum(const float v_dir_prev[3],
+ const float v_dir_next[3],
+ float r_tspace[3][3])
{
- add_v3_v3v3(r_tspace[1], v_dir_prev, v_dir_next);
+ add_v3_v3v3(r_tspace[1], v_dir_prev, v_dir_next);
- if (compare_v3v3(v_dir_prev, v_dir_next, FLT_EPSILON * 10.0f) == false) {
- const float weight = fabsf(acosf(dot_v3v3(v_dir_next, v_dir_prev)));
- float nor[3];
+ if (compare_v3v3(v_dir_prev, v_dir_next, FLT_EPSILON * 10.0f) == false) {
+ const float weight = fabsf(acosf(dot_v3v3(v_dir_next, v_dir_prev)));
+ float nor[3];
- cross_v3_v3v3(nor, v_dir_prev, v_dir_next);
- normalize_v3(nor);
+ cross_v3_v3v3(nor, v_dir_prev, v_dir_next);
+ normalize_v3(nor);
- cross_v3_v3v3(r_tspace[0], r_tspace[1], nor);
+ cross_v3_v3v3(r_tspace[0], r_tspace[1], nor);
- mul_v3_fl(nor, weight);
- /* accumulate weighted normals */
- add_v3_v3(r_tspace[2], nor);
- }
+ mul_v3_fl(nor, weight);
+ /* accumulate weighted normals */
+ add_v3_v3(r_tspace[2], nor);
+ }
}
-
-static void calc_tangent_spaces(
- Mesh *mesh, float (*vertexCos)[3],
- float (*r_tangent_spaces)[3][3])
+static void calc_tangent_spaces(Mesh *mesh, float (*vertexCos)[3], float (*r_tangent_spaces)[3][3])
{
- const unsigned int mpoly_num = (unsigned int)mesh->totpoly;
+ const unsigned int mpoly_num = (unsigned int)mesh->totpoly;
#ifndef USE_TANGENT_CALC_INLINE
- const unsigned int mvert_num = (unsigned int)dm->getNumVerts(dm);
+ const unsigned int mvert_num = (unsigned int)dm->getNumVerts(dm);
#endif
- const MPoly *mpoly = mesh->mpoly;
- const MLoop *mloop = mesh->mloop;
- unsigned int i;
-
- for (i = 0; i < mpoly_num; i++) {
- const MPoly *mp = &mpoly[i];
- const MLoop *l_next = &mloop[mp->loopstart];
- const MLoop *l_term = l_next + mp->totloop;
- const MLoop *l_prev = l_term - 2;
- const MLoop *l_curr = l_term - 1;
-
- /* loop directions */
- float v_dir_prev[3], v_dir_next[3];
-
- /* needed entering the loop */
- sub_v3_v3v3(v_dir_prev, vertexCos[l_prev->v], vertexCos[l_curr->v]);
- normalize_v3(v_dir_prev);
-
- for (;
- l_next != l_term;
- l_prev = l_curr, l_curr = l_next, l_next++)
- {
- float (*ts)[3] = r_tangent_spaces[l_curr->v];
-
- /* re-use the previous value */
+ const MPoly *mpoly = mesh->mpoly;
+ const MLoop *mloop = mesh->mloop;
+ unsigned int i;
+
+ for (i = 0; i < mpoly_num; i++) {
+ const MPoly *mp = &mpoly[i];
+ const MLoop *l_next = &mloop[mp->loopstart];
+ const MLoop *l_term = l_next + mp->totloop;
+ const MLoop *l_prev = l_term - 2;
+ const MLoop *l_curr = l_term - 1;
+
+ /* loop directions */
+ float v_dir_prev[3], v_dir_next[3];
+
+ /* needed entering the loop */
+ sub_v3_v3v3(v_dir_prev, vertexCos[l_prev->v], vertexCos[l_curr->v]);
+ normalize_v3(v_dir_prev);
+
+ for (; l_next != l_term; l_prev = l_curr, l_curr = l_next, l_next++) {
+ float(*ts)[3] = r_tangent_spaces[l_curr->v];
+
+ /* re-use the previous value */
#if 0
- sub_v3_v3v3(v_dir_prev, vertexCos[l_prev->v], vertexCos[l_curr->v]);
- normalize_v3(v_dir_prev);
+ sub_v3_v3v3(v_dir_prev, vertexCos[l_prev->v], vertexCos[l_curr->v]);
+ normalize_v3(v_dir_prev);
#endif
- sub_v3_v3v3(v_dir_next, vertexCos[l_curr->v], vertexCos[l_next->v]);
- normalize_v3(v_dir_next);
+ sub_v3_v3v3(v_dir_next, vertexCos[l_curr->v], vertexCos[l_next->v]);
+ normalize_v3(v_dir_next);
- calc_tangent_loop_accum(v_dir_prev, v_dir_next, ts);
+ calc_tangent_loop_accum(v_dir_prev, v_dir_next, ts);
- copy_v3_v3(v_dir_prev, v_dir_next);
- }
- }
+ copy_v3_v3(v_dir_prev, v_dir_next);
+ }
+ }
- /* do inline */
+ /* do inline */
#ifndef USE_TANGENT_CALC_INLINE
- for (i = 0; i < mvert_num; i++) {
- float (*ts)[3] = r_tangent_spaces[i];
- calc_tangent_ortho(ts);
- }
+ for (i = 0; i < mvert_num; i++) {
+ float(*ts)[3] = r_tangent_spaces[i];
+ calc_tangent_ortho(ts);
+ }
#endif
}
@@ -516,261 +505,266 @@ static void calc_tangent_spaces(
* This calculates #CorrectiveSmoothModifierData.delta_cache
* It's not run on every update (during animation for example).
*/
-static void calc_deltas(
- CorrectiveSmoothModifierData *csmd, Mesh *mesh,
- MDeformVert *dvert, const int defgrp_index,
- const float (*rest_coords)[3], unsigned int numVerts)
+static void calc_deltas(CorrectiveSmoothModifierData *csmd,
+ Mesh *mesh,
+ MDeformVert *dvert,
+ const int defgrp_index,
+ const float (*rest_coords)[3],
+ unsigned int numVerts)
{
- float (*smooth_vertex_coords)[3] = MEM_dupallocN(rest_coords);
- float (*tangent_spaces)[3][3];
- unsigned int i;
+ float(*smooth_vertex_coords)[3] = MEM_dupallocN(rest_coords);
+ float(*tangent_spaces)[3][3];
+ unsigned int i;
- tangent_spaces = MEM_calloc_arrayN(numVerts, sizeof(float[3][3]), __func__);
+ tangent_spaces = MEM_calloc_arrayN(numVerts, sizeof(float[3][3]), __func__);
- if (csmd->delta_cache_num != numVerts) {
- MEM_SAFE_FREE(csmd->delta_cache);
- }
+ if (csmd->delta_cache_num != numVerts) {
+ MEM_SAFE_FREE(csmd->delta_cache);
+ }
- /* allocate deltas if they have not yet been allocated, otheriwse we will just write over them */
- if (!csmd->delta_cache) {
- csmd->delta_cache_num = numVerts;
- csmd->delta_cache = MEM_malloc_arrayN(numVerts, sizeof(float[3]), __func__);
- }
+ /* allocate deltas if they have not yet been allocated, otheriwse we will just write over them */
+ if (!csmd->delta_cache) {
+ csmd->delta_cache_num = numVerts;
+ csmd->delta_cache = MEM_malloc_arrayN(numVerts, sizeof(float[3]), __func__);
+ }
- smooth_verts(csmd, mesh, dvert, defgrp_index, smooth_vertex_coords, numVerts);
+ smooth_verts(csmd, mesh, dvert, defgrp_index, smooth_vertex_coords, numVerts);
- calc_tangent_spaces(mesh, smooth_vertex_coords, tangent_spaces);
+ calc_tangent_spaces(mesh, smooth_vertex_coords, tangent_spaces);
- for (i = 0; i < numVerts; i++) {
- float imat[3][3], delta[3];
+ for (i = 0; i < numVerts; i++) {
+ float imat[3][3], delta[3];
#ifdef USE_TANGENT_CALC_INLINE
- calc_tangent_ortho(tangent_spaces[i]);
+ calc_tangent_ortho(tangent_spaces[i]);
#endif
- sub_v3_v3v3(delta, rest_coords[i], smooth_vertex_coords[i]);
- if (UNLIKELY(!invert_m3_m3(imat, tangent_spaces[i]))) {
- transpose_m3_m3(imat, tangent_spaces[i]);
- }
- mul_v3_m3v3(csmd->delta_cache[i], imat, delta);
- }
+ sub_v3_v3v3(delta, rest_coords[i], smooth_vertex_coords[i]);
+ if (UNLIKELY(!invert_m3_m3(imat, tangent_spaces[i]))) {
+ transpose_m3_m3(imat, tangent_spaces[i]);
+ }
+ mul_v3_m3v3(csmd->delta_cache[i], imat, delta);
+ }
- MEM_freeN(tangent_spaces);
- MEM_freeN(smooth_vertex_coords);
+ MEM_freeN(tangent_spaces);
+ MEM_freeN(smooth_vertex_coords);
}
-
-static void correctivesmooth_modifier_do(
- ModifierData *md, Depsgraph *depsgraph, Object *ob, Mesh *mesh,
- float (*vertexCos)[3], unsigned int numVerts,
- struct BMEditMesh *em)
+static void correctivesmooth_modifier_do(ModifierData *md,
+ Depsgraph *depsgraph,
+ Object *ob,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ unsigned int numVerts,
+ struct BMEditMesh *em)
{
- CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
-
- const bool force_delta_cache_update =
- /* XXX, take care! if mesh data its self changes we need to forcefully recalculate deltas */
- ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO) &&
- (((ID *)ob->data)->recalc & ID_RECALC_ALL));
-
- bool use_only_smooth = (csmd->flag & MOD_CORRECTIVESMOOTH_ONLY_SMOOTH) != 0;
- MDeformVert *dvert = NULL;
- int defgrp_index;
-
- MOD_get_vgroup(ob, mesh, csmd->defgrp_name, &dvert, &defgrp_index);
-
- /* if rest bind_coords not are defined, set them (only run during bind) */
- if ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) &&
- /* signal to recalculate, whoever sets MUST also free bind coords */
- (csmd->bind_coords_num == (unsigned int)-1))
- {
- if (DEG_is_active(depsgraph)) {
- BLI_assert(csmd->bind_coords == NULL);
- csmd->bind_coords = MEM_dupallocN(vertexCos);
- csmd->bind_coords_num = numVerts;
- BLI_assert(csmd->bind_coords != NULL);
- /* Copy bound data to the original modifier. */
- CorrectiveSmoothModifierData *csmd_orig =
- (CorrectiveSmoothModifierData *)modifier_get_original(&csmd->modifier);
- csmd_orig->bind_coords = MEM_dupallocN(csmd->bind_coords);
- csmd_orig->bind_coords_num = csmd->bind_coords_num;
- }
- else {
- modifier_setError(md, "Attempt to bind from inactive dependency graph");
- }
- }
-
- if (UNLIKELY(use_only_smooth)) {
- smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, numVerts);
- return;
- }
-
- if ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) && (csmd->bind_coords == NULL)) {
- modifier_setError(md, "Bind data required");
- goto error;
- }
-
- /* If the number of verts has changed, the bind is invalid, so we do nothing */
- if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
- if (csmd->bind_coords_num != numVerts) {
- modifier_setError(md, "Bind vertex count mismatch: %u to %u", csmd->bind_coords_num, numVerts);
- goto error;
- }
- }
- else {
- /* MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO */
- if (ob->type != OB_MESH) {
- modifier_setError(md, "Object is not a mesh");
- goto error;
- }
- else {
- unsigned int me_numVerts = (unsigned int)((em) ? em->bm->totvert : ((Mesh *)ob->data)->totvert);
-
- if (me_numVerts != numVerts) {
- modifier_setError(md, "Original vertex count mismatch: %u to %u", me_numVerts, numVerts);
- goto error;
- }
- }
- }
-
- /* check to see if our deltas are still valid */
- if (!csmd->delta_cache || (csmd->delta_cache_num != numVerts) || force_delta_cache_update) {
- const float (*rest_coords)[3];
- bool is_rest_coords_alloc = false;
-
- if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
- /* caller needs to do sanity check here */
- csmd->bind_coords_num = numVerts;
- rest_coords = (const float (*)[3])csmd->bind_coords;
- }
- else {
- int me_numVerts;
- rest_coords = (const float (*)[3]) ((em) ?
- BKE_editmesh_vertexCos_get_orco(em, &me_numVerts) :
- BKE_mesh_vertexCos_get(ob->data, &me_numVerts));
-
- BLI_assert((unsigned int)me_numVerts == numVerts);
- is_rest_coords_alloc = true;
- }
+ CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
+
+ const bool force_delta_cache_update =
+ /* XXX, take care! if mesh data its self changes we need to forcefully recalculate deltas */
+ ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO) &&
+ (((ID *)ob->data)->recalc & ID_RECALC_ALL));
+
+ bool use_only_smooth = (csmd->flag & MOD_CORRECTIVESMOOTH_ONLY_SMOOTH) != 0;
+ MDeformVert *dvert = NULL;
+ int defgrp_index;
+
+ MOD_get_vgroup(ob, mesh, csmd->defgrp_name, &dvert, &defgrp_index);
+
+ /* if rest bind_coords not are defined, set them (only run during bind) */
+ if ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) &&
+ /* signal to recalculate, whoever sets MUST also free bind coords */
+ (csmd->bind_coords_num == (unsigned int)-1)) {
+ if (DEG_is_active(depsgraph)) {
+ BLI_assert(csmd->bind_coords == NULL);
+ csmd->bind_coords = MEM_dupallocN(vertexCos);
+ csmd->bind_coords_num = numVerts;
+ BLI_assert(csmd->bind_coords != NULL);
+ /* Copy bound data to the original modifier. */
+ CorrectiveSmoothModifierData *csmd_orig = (CorrectiveSmoothModifierData *)
+ modifier_get_original(&csmd->modifier);
+ csmd_orig->bind_coords = MEM_dupallocN(csmd->bind_coords);
+ csmd_orig->bind_coords_num = csmd->bind_coords_num;
+ }
+ else {
+ modifier_setError(md, "Attempt to bind from inactive dependency graph");
+ }
+ }
+
+ if (UNLIKELY(use_only_smooth)) {
+ smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, numVerts);
+ return;
+ }
+
+ if ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) && (csmd->bind_coords == NULL)) {
+ modifier_setError(md, "Bind data required");
+ goto error;
+ }
+
+ /* If the number of verts has changed, the bind is invalid, so we do nothing */
+ if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
+ if (csmd->bind_coords_num != numVerts) {
+ modifier_setError(
+ md, "Bind vertex count mismatch: %u to %u", csmd->bind_coords_num, numVerts);
+ goto error;
+ }
+ }
+ else {
+ /* MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO */
+ if (ob->type != OB_MESH) {
+ modifier_setError(md, "Object is not a mesh");
+ goto error;
+ }
+ else {
+ unsigned int me_numVerts = (unsigned int)((em) ? em->bm->totvert :
+ ((Mesh *)ob->data)->totvert);
+
+ if (me_numVerts != numVerts) {
+ modifier_setError(md, "Original vertex count mismatch: %u to %u", me_numVerts, numVerts);
+ goto error;
+ }
+ }
+ }
+
+ /* check to see if our deltas are still valid */
+ if (!csmd->delta_cache || (csmd->delta_cache_num != numVerts) || force_delta_cache_update) {
+ const float(*rest_coords)[3];
+ bool is_rest_coords_alloc = false;
+
+ if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
+ /* caller needs to do sanity check here */
+ csmd->bind_coords_num = numVerts;
+ rest_coords = (const float(*)[3])csmd->bind_coords;
+ }
+ else {
+ int me_numVerts;
+ rest_coords = (const float(*)[3])((em) ? BKE_editmesh_vertexCos_get_orco(em, &me_numVerts) :
+ BKE_mesh_vertexCos_get(ob->data, &me_numVerts));
+
+ BLI_assert((unsigned int)me_numVerts == numVerts);
+ is_rest_coords_alloc = true;
+ }
#ifdef DEBUG_TIME
- TIMEIT_START(corrective_smooth_deltas);
+ TIMEIT_START(corrective_smooth_deltas);
#endif
- calc_deltas(csmd, mesh, dvert, defgrp_index, rest_coords, numVerts);
+ calc_deltas(csmd, mesh, dvert, defgrp_index, rest_coords, numVerts);
#ifdef DEBUG_TIME
- TIMEIT_END(corrective_smooth_deltas);
+ TIMEIT_END(corrective_smooth_deltas);
#endif
- if (is_rest_coords_alloc) {
- MEM_freeN((void *)rest_coords);
- }
- }
-
- if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
- /* this could be a check, but at this point it _must_ be valid */
- BLI_assert(csmd->bind_coords_num == numVerts && csmd->delta_cache);
- }
+ if (is_rest_coords_alloc) {
+ MEM_freeN((void *)rest_coords);
+ }
+ }
+ if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
+ /* this could be a check, but at this point it _must_ be valid */
+ BLI_assert(csmd->bind_coords_num == numVerts && csmd->delta_cache);
+ }
#ifdef DEBUG_TIME
- TIMEIT_START(corrective_smooth);
+ TIMEIT_START(corrective_smooth);
#endif
- /* do the actual delta mush */
- smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, numVerts);
+ /* do the actual delta mush */
+ smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, numVerts);
- {
- unsigned int i;
+ {
+ unsigned int i;
- float (*tangent_spaces)[3][3];
+ float(*tangent_spaces)[3][3];
- /* calloc, since values are accumulated */
- tangent_spaces = MEM_calloc_arrayN(numVerts, sizeof(float[3][3]), __func__);
+ /* calloc, since values are accumulated */
+ tangent_spaces = MEM_calloc_arrayN(numVerts, sizeof(float[3][3]), __func__);
- calc_tangent_spaces(mesh, vertexCos, tangent_spaces);
+ calc_tangent_spaces(mesh, vertexCos, tangent_spaces);
- for (i = 0; i < numVerts; i++) {
- float delta[3];
+ for (i = 0; i < numVerts; i++) {
+ float delta[3];
#ifdef USE_TANGENT_CALC_INLINE
- calc_tangent_ortho(tangent_spaces[i]);
+ calc_tangent_ortho(tangent_spaces[i]);
#endif
- mul_v3_m3v3(delta, tangent_spaces[i], csmd->delta_cache[i]);
- add_v3_v3(vertexCos[i], delta);
- }
+ mul_v3_m3v3(delta, tangent_spaces[i], csmd->delta_cache[i]);
+ add_v3_v3(vertexCos[i], delta);
+ }
- MEM_freeN(tangent_spaces);
- }
+ MEM_freeN(tangent_spaces);
+ }
#ifdef DEBUG_TIME
- TIMEIT_END(corrective_smooth);
+ TIMEIT_END(corrective_smooth);
#endif
- return;
+ return;
- /* when the modifier fails to execute */
+ /* when the modifier fails to execute */
error:
- MEM_SAFE_FREE(
- csmd->delta_cache);
- csmd->delta_cache_num = 0;
-
+ MEM_SAFE_FREE(csmd->delta_cache);
+ csmd->delta_cache_num = 0;
}
-
-static void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh,
- float (*vertexCos)[3], int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
- correctivesmooth_modifier_do(md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (unsigned int)numVerts, NULL);
+ correctivesmooth_modifier_do(
+ md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (unsigned int)numVerts, NULL);
- if (mesh_src != mesh) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (mesh_src != mesh) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-
-static void deformVertsEM(
- ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *editData,
- Mesh *mesh, float (*vertexCos)[3], int numVerts)
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *editData,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, editData, mesh, NULL, numVerts, false, false);
- correctivesmooth_modifier_do(md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (unsigned int)numVerts, editData);
+ correctivesmooth_modifier_do(
+ md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (unsigned int)numVerts, editData);
- if (mesh_src != mesh) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (mesh_src != mesh) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-
ModifierTypeInfo modifierType_CorrectiveSmooth = {
- /* name */ "CorrectiveSmooth",
- /* structName */ "CorrectiveSmoothModifierData",
- /* structSize */ sizeof(CorrectiveSmoothModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsEditmode,
-
- /* copyData */ copyData,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ freeData,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "CorrectiveSmooth",
+ /* structName */ "CorrectiveSmoothModifierData",
+ /* structSize */ sizeof(CorrectiveSmoothModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ copyData,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ freeData,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c
index 91cedda4f48..7a07d9b28eb 100644
--- a/source/blender/modifiers/intern/MOD_curve.c
+++ b/source/blender/modifiers/intern/MOD_curve.c
@@ -45,128 +45,124 @@
static void initData(ModifierData *md)
{
- CurveModifierData *cmd = (CurveModifierData *) md;
+ CurveModifierData *cmd = (CurveModifierData *)md;
- cmd->defaxis = MOD_CURVE_POSX;
+ cmd->defaxis = MOD_CURVE_POSX;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- CurveModifierData *cmd = (CurveModifierData *)md;
+ CurveModifierData *cmd = (CurveModifierData *)md;
- /* ask for vertexgroups if we need them */
- if (cmd->name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ /* ask for vertexgroups if we need them */
+ if (cmd->name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
static bool isDisabled(const Scene *UNUSED(scene), ModifierData *md, bool UNUSED(userRenderParams))
{
- CurveModifierData *cmd = (CurveModifierData *) md;
+ CurveModifierData *cmd = (CurveModifierData *)md;
- return !cmd->object;
+ return !cmd->object;
}
-static void foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- CurveModifierData *cmd = (CurveModifierData *) md;
+ CurveModifierData *cmd = (CurveModifierData *)md;
- walk(userData, ob, &cmd->object, IDWALK_CB_NOP);
+ walk(userData, ob, &cmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- CurveModifierData *cmd = (CurveModifierData *)md;
- if (cmd->object != NULL) {
- /* TODO(sergey): Need to do the same eval_flags trick for path
- * as happening in legacy depsgraph callback.
- */
- /* TODO(sergey): Currently path is evaluated as a part of modifier stack,
- * might be changed in the future.
- */
- DEG_add_object_relation(ctx->node, cmd->object, DEG_OB_COMP_TRANSFORM, "Curve Modifier");
- DEG_add_object_relation(ctx->node, cmd->object, DEG_OB_COMP_GEOMETRY, "Curve Modifier");
- DEG_add_special_eval_flag(ctx->node, &cmd->object->id, DAG_EVAL_NEED_CURVE_PATH);
- }
-
- DEG_add_modifier_to_transform_relation(ctx->node, "Curve Modifier");
+ CurveModifierData *cmd = (CurveModifierData *)md;
+ if (cmd->object != NULL) {
+ /* TODO(sergey): Need to do the same eval_flags trick for path
+ * as happening in legacy depsgraph callback.
+ */
+ /* TODO(sergey): Currently path is evaluated as a part of modifier stack,
+ * might be changed in the future.
+ */
+ DEG_add_object_relation(ctx->node, cmd->object, DEG_OB_COMP_TRANSFORM, "Curve Modifier");
+ DEG_add_object_relation(ctx->node, cmd->object, DEG_OB_COMP_GEOMETRY, "Curve Modifier");
+ DEG_add_special_eval_flag(ctx->node, &cmd->object->id, DAG_EVAL_NEED_CURVE_PATH);
+ }
+
+ DEG_add_modifier_to_transform_relation(ctx->node, "Curve Modifier");
}
-static void deformVerts(
- ModifierData *md,
- const ModifierEvalContext *ctx,
- Mesh *mesh,
- float (*vertexCos)[3],
- int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- CurveModifierData *cmd = (CurveModifierData *) md;
- Mesh *mesh_src = NULL;
-
- if (ctx->object->type == OB_MESH && cmd->name[0] != '\0') {
- /* mesh_src is only needed for vgroups. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
- }
-
- struct MDeformVert *dvert = NULL;
- int defgrp_index = -1;
- MOD_get_vgroup(ctx->object, mesh_src, cmd->name, &dvert, &defgrp_index);
-
- /* silly that defaxis and curve_deform_verts are off by 1
- * but leave for now to save having to call do_versions */
- curve_deform_verts(cmd->object, ctx->object,
- vertexCos, numVerts, dvert, defgrp_index, cmd->defaxis - 1);
-
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ CurveModifierData *cmd = (CurveModifierData *)md;
+ Mesh *mesh_src = NULL;
+
+ if (ctx->object->type == OB_MESH && cmd->name[0] != '\0') {
+ /* mesh_src is only needed for vgroups. */
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ }
+
+ struct MDeformVert *dvert = NULL;
+ int defgrp_index = -1;
+ MOD_get_vgroup(ctx->object, mesh_src, cmd->name, &dvert, &defgrp_index);
+
+ /* silly that defaxis and curve_deform_verts are off by 1
+ * but leave for now to save having to call do_versions */
+ curve_deform_verts(
+ cmd->object, ctx->object, vertexCos, numVerts, dvert, defgrp_index, cmd->defaxis - 1);
+
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-static void deformVertsEM(
- ModifierData *md,
- const ModifierEvalContext *ctx,
- struct BMEditMesh *em,
- Mesh *mesh,
- float (*vertexCos)[3],
- int numVerts)
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *em,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false);
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false);
- deformVerts(md, ctx, mesh_src, vertexCos, numVerts);
+ deformVerts(md, ctx, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-
ModifierTypeInfo modifierType_Curve = {
- /* name */ "Curve",
- /* structName */ "CurveModifierData",
- /* structSize */ sizeof(CurveModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_AcceptsLattice |
- eModifierTypeFlag_SupportsEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Curve",
+ /* structName */ "CurveModifierData",
+ /* structSize */ sizeof(CurveModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice |
+ eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.c
index 567af7bae09..4de99ea6fe6 100644
--- a/source/blender/modifiers/intern/MOD_datatransfer.c
+++ b/source/blender/modifiers/intern/MOD_datatransfer.c
@@ -49,190 +49,212 @@
**************************************/
static void initData(ModifierData *md)
{
- DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
- int i;
+ DataTransferModifierData *dtmd = (DataTransferModifierData *)md;
+ int i;
- dtmd->ob_source = NULL;
- dtmd->data_types = 0;
+ dtmd->ob_source = NULL;
+ dtmd->data_types = 0;
- dtmd->vmap_mode = MREMAP_MODE_VERT_NEAREST;
- dtmd->emap_mode = MREMAP_MODE_EDGE_NEAREST;
- dtmd->lmap_mode = MREMAP_MODE_LOOP_NEAREST_POLYNOR;
- dtmd->pmap_mode = MREMAP_MODE_POLY_NEAREST;
+ dtmd->vmap_mode = MREMAP_MODE_VERT_NEAREST;
+ dtmd->emap_mode = MREMAP_MODE_EDGE_NEAREST;
+ dtmd->lmap_mode = MREMAP_MODE_LOOP_NEAREST_POLYNOR;
+ dtmd->pmap_mode = MREMAP_MODE_POLY_NEAREST;
- dtmd->map_max_distance = 1.0f;
- dtmd->map_ray_radius = 0.0f;
+ dtmd->map_max_distance = 1.0f;
+ dtmd->map_ray_radius = 0.0f;
- for (i = 0; i < DT_MULTILAYER_INDEX_MAX; i++) {
- dtmd->layers_select_src[i] = DT_LAYERS_ALL_SRC;
- dtmd->layers_select_dst[i] = DT_LAYERS_NAME_DST;
- }
+ for (i = 0; i < DT_MULTILAYER_INDEX_MAX; i++) {
+ dtmd->layers_select_src[i] = DT_LAYERS_ALL_SRC;
+ dtmd->layers_select_dst[i] = DT_LAYERS_NAME_DST;
+ }
- dtmd->mix_mode = CDT_MIX_TRANSFER;
- dtmd->mix_factor = 1.0f;
- dtmd->defgrp_name[0] = '\0';
+ dtmd->mix_mode = CDT_MIX_TRANSFER;
+ dtmd->mix_factor = 1.0f;
+ dtmd->defgrp_name[0] = '\0';
- dtmd->flags = MOD_DATATRANSFER_OBSRC_TRANSFORM;
+ dtmd->flags = MOD_DATATRANSFER_OBSRC_TRANSFORM;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
+ DataTransferModifierData *dtmd = (DataTransferModifierData *)md;
- if (dtmd->defgrp_name[0] != '\0') {
- /* We need vertex groups! */
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ if (dtmd->defgrp_name[0] != '\0') {
+ /* We need vertex groups! */
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
- BKE_object_data_transfer_dttypes_to_cdmask(dtmd->data_types, r_cddata_masks);
+ BKE_object_data_transfer_dttypes_to_cdmask(dtmd->data_types, r_cddata_masks);
}
static bool dependsOnNormals(ModifierData *md)
{
- DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
- int item_types = BKE_object_data_transfer_get_dttypes_item_types(dtmd->data_types);
-
- if ((item_types & ME_VERT) && (dtmd->vmap_mode & (MREMAP_USE_NORPROJ | MREMAP_USE_NORMAL))) {
- return true;
- }
- if ((item_types & ME_EDGE) && (dtmd->emap_mode & (MREMAP_USE_NORPROJ | MREMAP_USE_NORMAL))) {
- return true;
- }
- if ((item_types & ME_LOOP) && (dtmd->lmap_mode & (MREMAP_USE_NORPROJ | MREMAP_USE_NORMAL))) {
- return true;
- }
- if ((item_types & ME_POLY) && (dtmd->pmap_mode & (MREMAP_USE_NORPROJ | MREMAP_USE_NORMAL))) {
- return true;
- }
-
- return false;
+ DataTransferModifierData *dtmd = (DataTransferModifierData *)md;
+ int item_types = BKE_object_data_transfer_get_dttypes_item_types(dtmd->data_types);
+
+ if ((item_types & ME_VERT) && (dtmd->vmap_mode & (MREMAP_USE_NORPROJ | MREMAP_USE_NORMAL))) {
+ return true;
+ }
+ if ((item_types & ME_EDGE) && (dtmd->emap_mode & (MREMAP_USE_NORPROJ | MREMAP_USE_NORMAL))) {
+ return true;
+ }
+ if ((item_types & ME_LOOP) && (dtmd->lmap_mode & (MREMAP_USE_NORPROJ | MREMAP_USE_NORMAL))) {
+ return true;
+ }
+ if ((item_types & ME_POLY) && (dtmd->pmap_mode & (MREMAP_USE_NORPROJ | MREMAP_USE_NORMAL))) {
+ return true;
+ }
+
+ return false;
}
-static void foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
- walk(userData, ob, &dtmd->ob_source, IDWALK_CB_NOP);
+ DataTransferModifierData *dtmd = (DataTransferModifierData *)md;
+ walk(userData, ob, &dtmd->ob_source, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
- if (dtmd->ob_source != NULL) {
- CustomData_MeshMasks cddata_masks = {0};
- BKE_object_data_transfer_dttypes_to_cdmask(dtmd->data_types, &cddata_masks);
- BKE_mesh_remap_calc_source_cddata_masks_from_map_modes(
- dtmd->vmap_mode, dtmd->emap_mode, dtmd->lmap_mode, dtmd->pmap_mode, &cddata_masks);
-
- DEG_add_object_relation(ctx->node, dtmd->ob_source, DEG_OB_COMP_GEOMETRY, "DataTransfer Modifier");
- DEG_add_customdata_mask(ctx->node, dtmd->ob_source, &cddata_masks);
-
- if (dtmd->flags & MOD_DATATRANSFER_OBSRC_TRANSFORM) {
- DEG_add_object_relation(ctx->node, dtmd->ob_source, DEG_OB_COMP_TRANSFORM, "DataTransfer Modifier");
- DEG_add_modifier_to_transform_relation(ctx->node, "DataTransfer Modifier");
- }
- }
+ DataTransferModifierData *dtmd = (DataTransferModifierData *)md;
+ if (dtmd->ob_source != NULL) {
+ CustomData_MeshMasks cddata_masks = {0};
+ BKE_object_data_transfer_dttypes_to_cdmask(dtmd->data_types, &cddata_masks);
+ BKE_mesh_remap_calc_source_cddata_masks_from_map_modes(
+ dtmd->vmap_mode, dtmd->emap_mode, dtmd->lmap_mode, dtmd->pmap_mode, &cddata_masks);
+
+ DEG_add_object_relation(
+ ctx->node, dtmd->ob_source, DEG_OB_COMP_GEOMETRY, "DataTransfer Modifier");
+ DEG_add_customdata_mask(ctx->node, dtmd->ob_source, &cddata_masks);
+
+ if (dtmd->flags & MOD_DATATRANSFER_OBSRC_TRANSFORM) {
+ DEG_add_object_relation(
+ ctx->node, dtmd->ob_source, DEG_OB_COMP_TRANSFORM, "DataTransfer Modifier");
+ DEG_add_modifier_to_transform_relation(ctx->node, "DataTransfer Modifier");
+ }
+ }
}
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(useRenderParams))
{
- DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
- /* If no source object, bypass. */
- return (dtmd->ob_source == NULL);
+ DataTransferModifierData *dtmd = (DataTransferModifierData *)md;
+ /* If no source object, bypass. */
+ return (dtmd->ob_source == NULL);
}
#define HIGH_POLY_WARNING 10000
-#define DT_TYPES_AFFECT_MESH ( \
- DT_TYPE_BWEIGHT_VERT | \
- DT_TYPE_BWEIGHT_EDGE | DT_TYPE_CREASE | DT_TYPE_SHARP_EDGE | \
- DT_TYPE_LNOR | \
- DT_TYPE_SHARP_FACE \
-)
+#define DT_TYPES_AFFECT_MESH \
+ (DT_TYPE_BWEIGHT_VERT | DT_TYPE_BWEIGHT_EDGE | DT_TYPE_CREASE | DT_TYPE_SHARP_EDGE | \
+ DT_TYPE_LNOR | DT_TYPE_SHARP_FACE)
static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *me_mod)
{
- DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
- struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- Mesh *result = me_mod;
- ReportList reports;
-
- /* Only used to check wehther we are operating on org data or not... */
- Mesh *me = ctx->object->data;
-
- Object *ob_source = dtmd->ob_source;
-
- const bool invert_vgroup = (dtmd->flags & MOD_DATATRANSFER_INVERT_VGROUP) != 0;
-
- const float max_dist = (dtmd->flags & MOD_DATATRANSFER_MAP_MAXDIST) ? dtmd->map_max_distance : FLT_MAX;
-
- SpaceTransform space_transform_data;
- SpaceTransform *space_transform = (dtmd->flags & MOD_DATATRANSFER_OBSRC_TRANSFORM) ? &space_transform_data : NULL;
-
- if (space_transform) {
- BLI_SPACE_TRANSFORM_SETUP(space_transform, ctx->object, ob_source);
- }
-
- if (((result == me) || (me->mvert == result->mvert) || (me->medge == result->medge)) &&
- (dtmd->data_types & DT_TYPES_AFFECT_MESH))
- {
- /* We need to duplicate data here, otherwise setting custom normals, edges' shaprness, etc., could
- * modify org mesh, see T43671. */
- BKE_id_copy_ex(NULL, &me_mod->id, (ID **)&result, LIB_ID_COPY_LOCALIZE);
- }
-
- BKE_reports_init(&reports, RPT_STORE);
-
- /* Note: no islands precision for now here. */
- BKE_object_data_transfer_ex(ctx->depsgraph, scene, ob_source, ctx->object, result, dtmd->data_types, false,
- dtmd->vmap_mode, dtmd->emap_mode, dtmd->lmap_mode, dtmd->pmap_mode,
- space_transform, false, max_dist, dtmd->map_ray_radius, 0.0f,
- dtmd->layers_select_src, dtmd->layers_select_dst,
- dtmd->mix_mode, dtmd->mix_factor, dtmd->defgrp_name, invert_vgroup, &reports);
-
- if (BKE_reports_contain(&reports, RPT_ERROR)) {
- modifier_setError(md, "%s", BKE_reports_string(&reports, RPT_ERROR));
- }
- else if ((dtmd->data_types & DT_TYPE_LNOR) && !(me->flag & ME_AUTOSMOOTH)) {
- modifier_setError((ModifierData *)dtmd, "Enable 'Auto Smooth' option in mesh settings");
- }
- else if (result->totvert > HIGH_POLY_WARNING || ((Mesh *)(ob_source->data))->totvert > HIGH_POLY_WARNING) {
- modifier_setError(md, "You are using a rather high poly as source or destination, computation might be slow");
- }
-
- return result;
+ DataTransferModifierData *dtmd = (DataTransferModifierData *)md;
+ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ Mesh *result = me_mod;
+ ReportList reports;
+
+ /* Only used to check wehther we are operating on org data or not... */
+ Mesh *me = ctx->object->data;
+
+ Object *ob_source = dtmd->ob_source;
+
+ const bool invert_vgroup = (dtmd->flags & MOD_DATATRANSFER_INVERT_VGROUP) != 0;
+
+ const float max_dist = (dtmd->flags & MOD_DATATRANSFER_MAP_MAXDIST) ? dtmd->map_max_distance :
+ FLT_MAX;
+
+ SpaceTransform space_transform_data;
+ SpaceTransform *space_transform = (dtmd->flags & MOD_DATATRANSFER_OBSRC_TRANSFORM) ?
+ &space_transform_data :
+ NULL;
+
+ if (space_transform) {
+ BLI_SPACE_TRANSFORM_SETUP(space_transform, ctx->object, ob_source);
+ }
+
+ if (((result == me) || (me->mvert == result->mvert) || (me->medge == result->medge)) &&
+ (dtmd->data_types & DT_TYPES_AFFECT_MESH)) {
+ /* We need to duplicate data here, otherwise setting custom normals, edges' shaprness, etc., could
+ * modify org mesh, see T43671. */
+ BKE_id_copy_ex(NULL, &me_mod->id, (ID **)&result, LIB_ID_COPY_LOCALIZE);
+ }
+
+ BKE_reports_init(&reports, RPT_STORE);
+
+ /* Note: no islands precision for now here. */
+ BKE_object_data_transfer_ex(ctx->depsgraph,
+ scene,
+ ob_source,
+ ctx->object,
+ result,
+ dtmd->data_types,
+ false,
+ dtmd->vmap_mode,
+ dtmd->emap_mode,
+ dtmd->lmap_mode,
+ dtmd->pmap_mode,
+ space_transform,
+ false,
+ max_dist,
+ dtmd->map_ray_radius,
+ 0.0f,
+ dtmd->layers_select_src,
+ dtmd->layers_select_dst,
+ dtmd->mix_mode,
+ dtmd->mix_factor,
+ dtmd->defgrp_name,
+ invert_vgroup,
+ &reports);
+
+ if (BKE_reports_contain(&reports, RPT_ERROR)) {
+ modifier_setError(md, "%s", BKE_reports_string(&reports, RPT_ERROR));
+ }
+ else if ((dtmd->data_types & DT_TYPE_LNOR) && !(me->flag & ME_AUTOSMOOTH)) {
+ modifier_setError((ModifierData *)dtmd, "Enable 'Auto Smooth' option in mesh settings");
+ }
+ else if (result->totvert > HIGH_POLY_WARNING ||
+ ((Mesh *)(ob_source->data))->totvert > HIGH_POLY_WARNING) {
+ modifier_setError(
+ md,
+ "You are using a rather high poly as source or destination, computation might be slow");
+ }
+
+ return result;
}
#undef HIGH_POLY_WARNING
#undef DT_TYPES_AFFECT_MESH
ModifierTypeInfo modifierType_DataTransfer = {
- /* name */ "DataTransfer",
- /* structName */ "DataTransferModifierData",
- /* structSize */ sizeof(DataTransferModifierData),
- /* type */ eModifierTypeType_NonGeometrical,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsMapping |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_UsesPreview,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "DataTransfer",
+ /* structName */ "DataTransferModifierData",
+ /* structSize */ sizeof(DataTransferModifierData),
+ /* type */ eModifierTypeType_NonGeometrical,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_UsesPreview,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ dependsOnNormals,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c
index 40968f1173f..c41abfb6eb2 100644
--- a/source/blender/modifiers/intern/MOD_decimate.c
+++ b/source/blender/modifiers/intern/MOD_decimate.c
@@ -50,196 +50,195 @@
static void initData(ModifierData *md)
{
- DecimateModifierData *dmd = (DecimateModifierData *) md;
+ DecimateModifierData *dmd = (DecimateModifierData *)md;
- dmd->percent = 1.0;
- dmd->angle = DEG2RADF(5.0f);
- dmd->defgrp_factor = 1.0;
+ dmd->percent = 1.0;
+ dmd->angle = DEG2RADF(5.0f);
+ dmd->defgrp_factor = 1.0;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- DecimateModifierData *dmd = (DecimateModifierData *) md;
+ DecimateModifierData *dmd = (DecimateModifierData *)md;
- /* ask for vertexgroups if we need them */
- if (dmd->defgrp_name[0] != '\0' && (dmd->defgrp_factor > 0.0f)) {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ /* ask for vertexgroups if we need them */
+ if (dmd->defgrp_name[0] != '\0' && (dmd->defgrp_factor > 0.0f)) {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
-static DecimateModifierData *getOriginalModifierData(
- const DecimateModifierData *dmd, const ModifierEvalContext *ctx)
+static DecimateModifierData *getOriginalModifierData(const DecimateModifierData *dmd,
+ const ModifierEvalContext *ctx)
{
- Object *ob_orig = DEG_get_original_object(ctx->object);
- return (DecimateModifierData *)modifiers_findByName(ob_orig, dmd->modifier.name);
+ Object *ob_orig = DEG_get_original_object(ctx->object);
+ return (DecimateModifierData *)modifiers_findByName(ob_orig, dmd->modifier.name);
}
-static void updateFaceCount(
- const ModifierEvalContext *ctx, DecimateModifierData *dmd, int face_count)
+static void updateFaceCount(const ModifierEvalContext *ctx,
+ DecimateModifierData *dmd,
+ int face_count)
{
- dmd->face_count = face_count;
+ dmd->face_count = face_count;
- if (DEG_is_active(ctx->depsgraph)) {
- /* update for display only */
- DecimateModifierData *dmd_orig = getOriginalModifierData(dmd, ctx);
- dmd_orig->face_count = face_count;
- }
+ if (DEG_is_active(ctx->depsgraph)) {
+ /* update for display only */
+ DecimateModifierData *dmd_orig = getOriginalModifierData(dmd, ctx);
+ dmd_orig->face_count = face_count;
+ }
}
-static Mesh *applyModifier(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *meshData)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *meshData)
{
- DecimateModifierData *dmd = (DecimateModifierData *) md;
- Mesh *mesh = meshData, *result = NULL;
- BMesh *bm;
- bool calc_face_normal;
- float *vweights = NULL;
+ DecimateModifierData *dmd = (DecimateModifierData *)md;
+ Mesh *mesh = meshData, *result = NULL;
+ BMesh *bm;
+ bool calc_face_normal;
+ float *vweights = NULL;
#ifdef USE_TIMEIT
- TIMEIT_START(decim);
+ TIMEIT_START(decim);
#endif
- /* set up front so we dont show invalid info in the UI */
- updateFaceCount(ctx, dmd, mesh->totpoly);
-
- switch (dmd->mode) {
- case MOD_DECIM_MODE_COLLAPSE:
- if (dmd->percent == 1.0f) {
- return mesh;
- }
- calc_face_normal = true;
- break;
- case MOD_DECIM_MODE_UNSUBDIV:
- if (dmd->iter == 0) {
- return mesh;
- }
- calc_face_normal = false;
- break;
- case MOD_DECIM_MODE_DISSOLVE:
- if (dmd->angle == 0.0f) {
- return mesh;
- }
- calc_face_normal = true;
- break;
- default:
- return mesh;
- }
-
- if (dmd->face_count <= 3) {
- modifier_setError(md, "Modifier requires more than 3 input faces");
- return mesh;
- }
-
- if (dmd->mode == MOD_DECIM_MODE_COLLAPSE) {
- if (dmd->defgrp_name[0] && (dmd->defgrp_factor > 0.0f)) {
- MDeformVert *dvert;
- int defgrp_index;
-
- MOD_get_vgroup(ctx->object, mesh, dmd->defgrp_name, &dvert, &defgrp_index);
-
- if (dvert) {
- const unsigned int vert_tot = mesh->totvert;
- unsigned int i;
-
- vweights = MEM_malloc_arrayN(vert_tot, sizeof(float), __func__);
-
- if (dmd->flag & MOD_DECIM_FLAG_INVERT_VGROUP) {
- for (i = 0; i < vert_tot; i++) {
- vweights[i] = 1.0f - defvert_find_weight(&dvert[i], defgrp_index);
- }
- }
- else {
- for (i = 0; i < vert_tot; i++) {
- vweights[i] = defvert_find_weight(&dvert[i], defgrp_index);
- }
- }
- }
- }
- }
-
- bm = BKE_mesh_to_bmesh_ex(
- mesh,
- &(struct BMeshCreateParams){0},
- &(struct BMeshFromMeshParams){
- .calc_face_normal = calc_face_normal,
- .cd_mask_extra = {.vmask = CD_MASK_ORIGINDEX, .emask = CD_MASK_ORIGINDEX, .pmask = CD_MASK_ORIGINDEX},
- });
-
- switch (dmd->mode) {
- case MOD_DECIM_MODE_COLLAPSE:
- {
- const bool do_triangulate = (dmd->flag & MOD_DECIM_FLAG_TRIANGULATE) != 0;
- const int symmetry_axis = (dmd->flag & MOD_DECIM_FLAG_SYMMETRY) ? dmd->symmetry_axis : -1;
- const float symmetry_eps = 0.00002f;
- BM_mesh_decimate_collapse(
- bm, dmd->percent, vweights, dmd->defgrp_factor, do_triangulate,
- symmetry_axis, symmetry_eps);
- break;
- }
- case MOD_DECIM_MODE_UNSUBDIV:
- {
- BM_mesh_decimate_unsubdivide(bm, dmd->iter);
- break;
- }
- case MOD_DECIM_MODE_DISSOLVE:
- {
- const bool do_dissolve_boundaries = (dmd->flag & MOD_DECIM_FLAG_ALL_BOUNDARY_VERTS) != 0;
- BM_mesh_decimate_dissolve(bm, dmd->angle, do_dissolve_boundaries, (BMO_Delimit)dmd->delimit);
- break;
- }
- }
-
- if (vweights) {
- MEM_freeN(vweights);
- }
-
- updateFaceCount(ctx, dmd, bm->totface);
-
- result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
- BLI_assert(bm->vtoolflagpool == NULL &&
- bm->etoolflagpool == NULL &&
- bm->ftoolflagpool == NULL); /* make sure we never alloc'd these */
- BLI_assert(bm->vtable == NULL &&
- bm->etable == NULL &&
- bm->ftable == NULL);
-
- BM_mesh_free(bm);
+ /* set up front so we dont show invalid info in the UI */
+ updateFaceCount(ctx, dmd, mesh->totpoly);
+
+ switch (dmd->mode) {
+ case MOD_DECIM_MODE_COLLAPSE:
+ if (dmd->percent == 1.0f) {
+ return mesh;
+ }
+ calc_face_normal = true;
+ break;
+ case MOD_DECIM_MODE_UNSUBDIV:
+ if (dmd->iter == 0) {
+ return mesh;
+ }
+ calc_face_normal = false;
+ break;
+ case MOD_DECIM_MODE_DISSOLVE:
+ if (dmd->angle == 0.0f) {
+ return mesh;
+ }
+ calc_face_normal = true;
+ break;
+ default:
+ return mesh;
+ }
+
+ if (dmd->face_count <= 3) {
+ modifier_setError(md, "Modifier requires more than 3 input faces");
+ return mesh;
+ }
+
+ if (dmd->mode == MOD_DECIM_MODE_COLLAPSE) {
+ if (dmd->defgrp_name[0] && (dmd->defgrp_factor > 0.0f)) {
+ MDeformVert *dvert;
+ int defgrp_index;
+
+ MOD_get_vgroup(ctx->object, mesh, dmd->defgrp_name, &dvert, &defgrp_index);
+
+ if (dvert) {
+ const unsigned int vert_tot = mesh->totvert;
+ unsigned int i;
+
+ vweights = MEM_malloc_arrayN(vert_tot, sizeof(float), __func__);
+
+ if (dmd->flag & MOD_DECIM_FLAG_INVERT_VGROUP) {
+ for (i = 0; i < vert_tot; i++) {
+ vweights[i] = 1.0f - defvert_find_weight(&dvert[i], defgrp_index);
+ }
+ }
+ else {
+ for (i = 0; i < vert_tot; i++) {
+ vweights[i] = defvert_find_weight(&dvert[i], defgrp_index);
+ }
+ }
+ }
+ }
+ }
+
+ bm = BKE_mesh_to_bmesh_ex(mesh,
+ &(struct BMeshCreateParams){0},
+ &(struct BMeshFromMeshParams){
+ .calc_face_normal = calc_face_normal,
+ .cd_mask_extra = {.vmask = CD_MASK_ORIGINDEX,
+ .emask = CD_MASK_ORIGINDEX,
+ .pmask = CD_MASK_ORIGINDEX},
+ });
+
+ switch (dmd->mode) {
+ case MOD_DECIM_MODE_COLLAPSE: {
+ const bool do_triangulate = (dmd->flag & MOD_DECIM_FLAG_TRIANGULATE) != 0;
+ const int symmetry_axis = (dmd->flag & MOD_DECIM_FLAG_SYMMETRY) ? dmd->symmetry_axis : -1;
+ const float symmetry_eps = 0.00002f;
+ BM_mesh_decimate_collapse(bm,
+ dmd->percent,
+ vweights,
+ dmd->defgrp_factor,
+ do_triangulate,
+ symmetry_axis,
+ symmetry_eps);
+ break;
+ }
+ case MOD_DECIM_MODE_UNSUBDIV: {
+ BM_mesh_decimate_unsubdivide(bm, dmd->iter);
+ break;
+ }
+ case MOD_DECIM_MODE_DISSOLVE: {
+ const bool do_dissolve_boundaries = (dmd->flag & MOD_DECIM_FLAG_ALL_BOUNDARY_VERTS) != 0;
+ BM_mesh_decimate_dissolve(bm, dmd->angle, do_dissolve_boundaries, (BMO_Delimit)dmd->delimit);
+ break;
+ }
+ }
+
+ if (vweights) {
+ MEM_freeN(vweights);
+ }
+
+ updateFaceCount(ctx, dmd, bm->totface);
+
+ result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
+ BLI_assert(bm->vtoolflagpool == NULL && bm->etoolflagpool == NULL &&
+ bm->ftoolflagpool == NULL); /* make sure we never alloc'd these */
+ BLI_assert(bm->vtable == NULL && bm->etable == NULL && bm->ftable == NULL);
+
+ BM_mesh_free(bm);
#ifdef USE_TIMEIT
- TIMEIT_END(decim);
+ TIMEIT_END(decim);
#endif
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- return result;
+ return result;
}
ModifierTypeInfo modifierType_Decimate = {
- /* name */ "Decimate",
- /* structName */ "DecimateModifierData",
- /* structSize */ sizeof(DecimateModifierData),
- /* type */ eModifierTypeType_Nonconstructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_AcceptsCVs,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Decimate",
+ /* structName */ "DecimateModifierData",
+ /* structSize */ sizeof(DecimateModifierData),
+ /* type */ eModifierTypeType_Nonconstructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c
index 0060639970c..b0c633b1cdd 100644
--- a/source/blender/modifiers/intern/MOD_displace.c
+++ b/source/blender/modifiers/intern/MOD_displace.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include "BLI_utildefines.h"
#include "BLI_math.h"
@@ -51,376 +50,376 @@
#include "RE_shader_ext.h"
-
/* Displace */
static void initData(ModifierData *md)
{
- DisplaceModifierData *dmd = (DisplaceModifierData *) md;
+ DisplaceModifierData *dmd = (DisplaceModifierData *)md;
- dmd->texture = NULL;
- dmd->strength = 1;
- dmd->direction = MOD_DISP_DIR_NOR;
- dmd->midlevel = 0.5;
- dmd->space = MOD_DISP_SPACE_LOCAL;
+ dmd->texture = NULL;
+ dmd->strength = 1;
+ dmd->direction = MOD_DISP_DIR_NOR;
+ dmd->midlevel = 0.5;
+ dmd->space = MOD_DISP_SPACE_LOCAL;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- DisplaceModifierData *dmd = (DisplaceModifierData *)md;
+ DisplaceModifierData *dmd = (DisplaceModifierData *)md;
- /* ask for vertexgroups if we need them */
- if (dmd->defgrp_name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ /* ask for vertexgroups if we need them */
+ if (dmd->defgrp_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
- /* ask for UV coordinates if we need them */
- if (dmd->texmapping == MOD_DISP_MAP_UV) {
- r_cddata_masks->fmask |= CD_MASK_MTFACE;
- }
+ /* ask for UV coordinates if we need them */
+ if (dmd->texmapping == MOD_DISP_MAP_UV) {
+ r_cddata_masks->fmask |= CD_MASK_MTFACE;
+ }
- if (dmd->direction == MOD_DISP_DIR_CLNOR) {
- r_cddata_masks->lmask |= CD_MASK_CUSTOMLOOPNORMAL;
- }
+ if (dmd->direction == MOD_DISP_DIR_CLNOR) {
+ r_cddata_masks->lmask |= CD_MASK_CUSTOMLOOPNORMAL;
+ }
}
static bool dependsOnTime(ModifierData *md)
{
- DisplaceModifierData *dmd = (DisplaceModifierData *)md;
-
- if (dmd->texture) {
- return BKE_texture_dependsOnTime(dmd->texture);
- }
- else {
- return false;
- }
+ DisplaceModifierData *dmd = (DisplaceModifierData *)md;
+
+ if (dmd->texture) {
+ return BKE_texture_dependsOnTime(dmd->texture);
+ }
+ else {
+ return false;
+ }
}
static bool dependsOnNormals(ModifierData *md)
{
- DisplaceModifierData *dmd = (DisplaceModifierData *)md;
- return ELEM(dmd->direction, MOD_DISP_DIR_NOR, MOD_DISP_DIR_CLNOR);
+ DisplaceModifierData *dmd = (DisplaceModifierData *)md;
+ return ELEM(dmd->direction, MOD_DISP_DIR_NOR, MOD_DISP_DIR_CLNOR);
}
-static void foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- DisplaceModifierData *dmd = (DisplaceModifierData *) md;
+ DisplaceModifierData *dmd = (DisplaceModifierData *)md;
- walk(userData, ob, &dmd->map_object, IDWALK_CB_NOP);
+ walk(userData, ob, &dmd->map_object, IDWALK_CB_NOP);
}
-static void foreachIDLink(
- ModifierData *md, Object *ob,
- IDWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
- DisplaceModifierData *dmd = (DisplaceModifierData *) md;
+ DisplaceModifierData *dmd = (DisplaceModifierData *)md;
- walk(userData, ob, (ID **)&dmd->texture, IDWALK_CB_USER);
+ walk(userData, ob, (ID **)&dmd->texture, IDWALK_CB_USER);
- foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
+ foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
}
-static void foreachTexLink(
- ModifierData *md, Object *ob,
- TexWalkFunc walk, void *userData)
+static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
{
- walk(userData, ob, md, "texture");
+ walk(userData, ob, md, "texture");
}
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(useRenderParams))
{
- DisplaceModifierData *dmd = (DisplaceModifierData *) md;
- return ((!dmd->texture && dmd->direction == MOD_DISP_DIR_RGB_XYZ) || dmd->strength == 0.0f);
+ DisplaceModifierData *dmd = (DisplaceModifierData *)md;
+ return ((!dmd->texture && dmd->direction == MOD_DISP_DIR_RGB_XYZ) || dmd->strength == 0.0f);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- DisplaceModifierData *dmd = (DisplaceModifierData *)md;
- if (dmd->map_object != NULL && dmd->texmapping == MOD_DISP_MAP_OBJECT) {
- DEG_add_modifier_to_transform_relation(ctx->node, "Displace Modifier");
- DEG_add_object_relation(ctx->node, dmd->map_object, DEG_OB_COMP_TRANSFORM, "Displace Modifier");
- }
- if (dmd->texmapping == MOD_DISP_MAP_GLOBAL ||
- (ELEM(dmd->direction, MOD_DISP_DIR_X, MOD_DISP_DIR_Y, MOD_DISP_DIR_Z, MOD_DISP_DIR_RGB_XYZ) &&
- dmd->space == MOD_DISP_SPACE_GLOBAL))
- {
- DEG_add_modifier_to_transform_relation(ctx->node, "Displace Modifier");
- }
- if (dmd->texture != NULL) {
- DEG_add_generic_id_relation(ctx->node, &dmd->texture->id, "Displace Modifier");
- }
+ DisplaceModifierData *dmd = (DisplaceModifierData *)md;
+ if (dmd->map_object != NULL && dmd->texmapping == MOD_DISP_MAP_OBJECT) {
+ DEG_add_modifier_to_transform_relation(ctx->node, "Displace Modifier");
+ DEG_add_object_relation(
+ ctx->node, dmd->map_object, DEG_OB_COMP_TRANSFORM, "Displace Modifier");
+ }
+ if (dmd->texmapping == MOD_DISP_MAP_GLOBAL ||
+ (ELEM(
+ dmd->direction, MOD_DISP_DIR_X, MOD_DISP_DIR_Y, MOD_DISP_DIR_Z, MOD_DISP_DIR_RGB_XYZ) &&
+ dmd->space == MOD_DISP_SPACE_GLOBAL)) {
+ DEG_add_modifier_to_transform_relation(ctx->node, "Displace Modifier");
+ }
+ if (dmd->texture != NULL) {
+ DEG_add_generic_id_relation(ctx->node, &dmd->texture->id, "Displace Modifier");
+ }
}
typedef struct DisplaceUserdata {
- /*const*/ DisplaceModifierData *dmd;
- struct Scene *scene;
- struct ImagePool *pool;
- MDeformVert *dvert;
- float weight;
- int defgrp_index;
- int direction;
- bool use_global_direction;
- Tex *tex_target;
- float (*tex_co)[3];
- float (*vertexCos)[3];
- float local_mat[4][4];
- MVert *mvert;
- float (*vert_clnors)[3];
+ /*const*/ DisplaceModifierData *dmd;
+ struct Scene *scene;
+ struct ImagePool *pool;
+ MDeformVert *dvert;
+ float weight;
+ int defgrp_index;
+ int direction;
+ bool use_global_direction;
+ Tex *tex_target;
+ float (*tex_co)[3];
+ float (*vertexCos)[3];
+ float local_mat[4][4];
+ MVert *mvert;
+ float (*vert_clnors)[3];
} DisplaceUserdata;
-static void displaceModifier_do_task(
- void *__restrict userdata,
- const int iter,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+static void displaceModifier_do_task(void *__restrict userdata,
+ const int iter,
+ const ParallelRangeTLS *__restrict UNUSED(tls))
{
- DisplaceUserdata *data = (DisplaceUserdata *)userdata;
- DisplaceModifierData *dmd = data->dmd;
- MDeformVert *dvert = data->dvert;
- float weight = data->weight;
- int defgrp_index = data->defgrp_index;
- int direction = data->direction;
- bool use_global_direction = data->use_global_direction;
- float (*tex_co)[3] = data->tex_co;
- float (*vertexCos)[3] = data->vertexCos;
- MVert *mvert = data->mvert;
- float (*vert_clnors)[3] = data->vert_clnors;
-
- const float delta_fixed = 1.0f - dmd->midlevel; /* when no texture is used, we fallback to white */
-
- TexResult texres;
- float strength = dmd->strength;
- float delta;
- float local_vec[3];
-
- if (dvert) {
- weight = defvert_find_weight(dvert + iter, defgrp_index);
- if (weight == 0.0f) {
- return;
- }
- }
-
- if (data->tex_target) {
- texres.nor = NULL;
- BKE_texture_get_value_ex(data->scene, data->tex_target, tex_co[iter], &texres, data->pool, false);
- delta = texres.tin - dmd->midlevel;
- }
- else {
- delta = delta_fixed; /* (1.0f - dmd->midlevel) */ /* never changes */
- }
-
- if (dvert) {
- strength *= weight;
- }
-
- delta *= strength;
- CLAMP(delta, -10000, 10000);
-
- switch (direction) {
- case MOD_DISP_DIR_X:
- if (use_global_direction) {
- vertexCos[iter][0] += delta * data->local_mat[0][0];
- vertexCos[iter][1] += delta * data->local_mat[1][0];
- vertexCos[iter][2] += delta * data->local_mat[2][0];
- }
- else {
- vertexCos[iter][0] += delta;
- }
- break;
- case MOD_DISP_DIR_Y:
- if (use_global_direction) {
- vertexCos[iter][0] += delta * data->local_mat[0][1];
- vertexCos[iter][1] += delta * data->local_mat[1][1];
- vertexCos[iter][2] += delta * data->local_mat[2][1];
- }
- else {
- vertexCos[iter][1] += delta;
- }
- break;
- case MOD_DISP_DIR_Z:
- if (use_global_direction) {
- vertexCos[iter][0] += delta * data->local_mat[0][2];
- vertexCos[iter][1] += delta * data->local_mat[1][2];
- vertexCos[iter][2] += delta * data->local_mat[2][2];
- }
- else {
- vertexCos[iter][2] += delta;
- }
- break;
- case MOD_DISP_DIR_RGB_XYZ:
- local_vec[0] = texres.tr - dmd->midlevel;
- local_vec[1] = texres.tg - dmd->midlevel;
- local_vec[2] = texres.tb - dmd->midlevel;
- if (use_global_direction) {
- mul_transposed_mat3_m4_v3(data->local_mat, local_vec);
- }
- mul_v3_fl(local_vec, strength);
- add_v3_v3(vertexCos[iter], local_vec);
- break;
- case MOD_DISP_DIR_NOR:
- vertexCos[iter][0] += delta * (mvert[iter].no[0] / 32767.0f);
- vertexCos[iter][1] += delta * (mvert[iter].no[1] / 32767.0f);
- vertexCos[iter][2] += delta * (mvert[iter].no[2] / 32767.0f);
- break;
- case MOD_DISP_DIR_CLNOR:
- madd_v3_v3fl(vertexCos[iter], vert_clnors[iter], delta);
- break;
- }
+ DisplaceUserdata *data = (DisplaceUserdata *)userdata;
+ DisplaceModifierData *dmd = data->dmd;
+ MDeformVert *dvert = data->dvert;
+ float weight = data->weight;
+ int defgrp_index = data->defgrp_index;
+ int direction = data->direction;
+ bool use_global_direction = data->use_global_direction;
+ float(*tex_co)[3] = data->tex_co;
+ float(*vertexCos)[3] = data->vertexCos;
+ MVert *mvert = data->mvert;
+ float(*vert_clnors)[3] = data->vert_clnors;
+
+ const float delta_fixed = 1.0f -
+ dmd->midlevel; /* when no texture is used, we fallback to white */
+
+ TexResult texres;
+ float strength = dmd->strength;
+ float delta;
+ float local_vec[3];
+
+ if (dvert) {
+ weight = defvert_find_weight(dvert + iter, defgrp_index);
+ if (weight == 0.0f) {
+ return;
+ }
+ }
+
+ if (data->tex_target) {
+ texres.nor = NULL;
+ BKE_texture_get_value_ex(
+ data->scene, data->tex_target, tex_co[iter], &texres, data->pool, false);
+ delta = texres.tin - dmd->midlevel;
+ }
+ else {
+ delta = delta_fixed; /* (1.0f - dmd->midlevel) */ /* never changes */
+ }
+
+ if (dvert) {
+ strength *= weight;
+ }
+
+ delta *= strength;
+ CLAMP(delta, -10000, 10000);
+
+ switch (direction) {
+ case MOD_DISP_DIR_X:
+ if (use_global_direction) {
+ vertexCos[iter][0] += delta * data->local_mat[0][0];
+ vertexCos[iter][1] += delta * data->local_mat[1][0];
+ vertexCos[iter][2] += delta * data->local_mat[2][0];
+ }
+ else {
+ vertexCos[iter][0] += delta;
+ }
+ break;
+ case MOD_DISP_DIR_Y:
+ if (use_global_direction) {
+ vertexCos[iter][0] += delta * data->local_mat[0][1];
+ vertexCos[iter][1] += delta * data->local_mat[1][1];
+ vertexCos[iter][2] += delta * data->local_mat[2][1];
+ }
+ else {
+ vertexCos[iter][1] += delta;
+ }
+ break;
+ case MOD_DISP_DIR_Z:
+ if (use_global_direction) {
+ vertexCos[iter][0] += delta * data->local_mat[0][2];
+ vertexCos[iter][1] += delta * data->local_mat[1][2];
+ vertexCos[iter][2] += delta * data->local_mat[2][2];
+ }
+ else {
+ vertexCos[iter][2] += delta;
+ }
+ break;
+ case MOD_DISP_DIR_RGB_XYZ:
+ local_vec[0] = texres.tr - dmd->midlevel;
+ local_vec[1] = texres.tg - dmd->midlevel;
+ local_vec[2] = texres.tb - dmd->midlevel;
+ if (use_global_direction) {
+ mul_transposed_mat3_m4_v3(data->local_mat, local_vec);
+ }
+ mul_v3_fl(local_vec, strength);
+ add_v3_v3(vertexCos[iter], local_vec);
+ break;
+ case MOD_DISP_DIR_NOR:
+ vertexCos[iter][0] += delta * (mvert[iter].no[0] / 32767.0f);
+ vertexCos[iter][1] += delta * (mvert[iter].no[1] / 32767.0f);
+ vertexCos[iter][2] += delta * (mvert[iter].no[2] / 32767.0f);
+ break;
+ case MOD_DISP_DIR_CLNOR:
+ madd_v3_v3fl(vertexCos[iter], vert_clnors[iter], delta);
+ break;
+ }
}
-static void displaceModifier_do(
- DisplaceModifierData *dmd, const ModifierEvalContext *ctx,
- Mesh *mesh, float (*vertexCos)[3], const int numVerts)
+static void displaceModifier_do(DisplaceModifierData *dmd,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ const int numVerts)
{
- Object *ob = ctx->object;
- MVert *mvert;
- MDeformVert *dvert;
- int direction = dmd->direction;
- int defgrp_index;
- float (*tex_co)[3];
- float weight = 1.0f; /* init value unused but some compilers may complain */
- float (*vert_clnors)[3] = NULL;
- float local_mat[4][4] = {{0}};
- const bool use_global_direction = dmd->space == MOD_DISP_SPACE_GLOBAL;
-
- if (dmd->texture == NULL && dmd->direction == MOD_DISP_DIR_RGB_XYZ) return;
- if (dmd->strength == 0.0f) return;
-
- mvert = mesh->mvert;
- MOD_get_vgroup(ob, mesh, dmd->defgrp_name, &dvert, &defgrp_index);
-
- Tex *tex_target = dmd->texture;
- if (tex_target != NULL) {
- tex_co = MEM_calloc_arrayN((size_t)numVerts, sizeof(*tex_co),
- "displaceModifier_do tex_co");
- MOD_get_texture_coords((MappingInfoModifierData *)dmd, ctx, ob, mesh, vertexCos, tex_co);
-
- MOD_init_texture((MappingInfoModifierData *)dmd, ctx);
- }
- else {
- tex_co = NULL;
- }
-
- if (direction == MOD_DISP_DIR_CLNOR) {
- CustomData *ldata = &mesh->ldata;
-
- if (CustomData_has_layer(ldata, CD_CUSTOMLOOPNORMAL)) {
- float (*clnors)[3] = NULL;
-
- if ((mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) || !CustomData_has_layer(ldata, CD_NORMAL)) {
- BKE_mesh_calc_normals_split(mesh);
- }
-
- clnors = CustomData_get_layer(ldata, CD_NORMAL);
- vert_clnors = MEM_malloc_arrayN(numVerts, sizeof(*vert_clnors), __func__);
- BKE_mesh_normals_loop_to_vertex(numVerts, mesh->mloop, mesh->totloop,
- (const float (*)[3])clnors, vert_clnors);
- }
- else {
- direction = MOD_DISP_DIR_NOR;
- }
- }
- else if (ELEM(direction, MOD_DISP_DIR_X, MOD_DISP_DIR_Y, MOD_DISP_DIR_Z, MOD_DISP_DIR_RGB_XYZ) &&
- use_global_direction)
- {
- copy_m4_m4(local_mat, ob->obmat);
- }
-
- DisplaceUserdata data = {NULL};
- data.scene = DEG_get_evaluated_scene(ctx->depsgraph);
- data.dmd = dmd;
- data.dvert = dvert;
- data.weight = weight;
- data.defgrp_index = defgrp_index;
- data.direction = direction;
- data.use_global_direction = use_global_direction;
- data.tex_target = tex_target;
- data.tex_co = tex_co;
- data.vertexCos = vertexCos;
- copy_m4_m4(data.local_mat, local_mat);
- data.mvert = mvert;
- data.vert_clnors = vert_clnors;
- if (tex_target != NULL) {
- data.pool = BKE_image_pool_new();
- BKE_texture_fetch_images_for_pool(tex_target, data.pool);
- }
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.use_threading = (numVerts > 512);
- BLI_task_parallel_range(0, numVerts,
- &data,
- displaceModifier_do_task,
- &settings);
-
- if (data.pool != NULL) {
- BKE_image_pool_free(data.pool);
- }
-
- if (tex_co) {
- MEM_freeN(tex_co);
- }
-
- if (vert_clnors) {
- MEM_freeN(vert_clnors);
- }
+ Object *ob = ctx->object;
+ MVert *mvert;
+ MDeformVert *dvert;
+ int direction = dmd->direction;
+ int defgrp_index;
+ float(*tex_co)[3];
+ float weight = 1.0f; /* init value unused but some compilers may complain */
+ float(*vert_clnors)[3] = NULL;
+ float local_mat[4][4] = {{0}};
+ const bool use_global_direction = dmd->space == MOD_DISP_SPACE_GLOBAL;
+
+ if (dmd->texture == NULL && dmd->direction == MOD_DISP_DIR_RGB_XYZ)
+ return;
+ if (dmd->strength == 0.0f)
+ return;
+
+ mvert = mesh->mvert;
+ MOD_get_vgroup(ob, mesh, dmd->defgrp_name, &dvert, &defgrp_index);
+
+ Tex *tex_target = dmd->texture;
+ if (tex_target != NULL) {
+ tex_co = MEM_calloc_arrayN((size_t)numVerts, sizeof(*tex_co), "displaceModifier_do tex_co");
+ MOD_get_texture_coords((MappingInfoModifierData *)dmd, ctx, ob, mesh, vertexCos, tex_co);
+
+ MOD_init_texture((MappingInfoModifierData *)dmd, ctx);
+ }
+ else {
+ tex_co = NULL;
+ }
+
+ if (direction == MOD_DISP_DIR_CLNOR) {
+ CustomData *ldata = &mesh->ldata;
+
+ if (CustomData_has_layer(ldata, CD_CUSTOMLOOPNORMAL)) {
+ float(*clnors)[3] = NULL;
+
+ if ((mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) ||
+ !CustomData_has_layer(ldata, CD_NORMAL)) {
+ BKE_mesh_calc_normals_split(mesh);
+ }
+
+ clnors = CustomData_get_layer(ldata, CD_NORMAL);
+ vert_clnors = MEM_malloc_arrayN(numVerts, sizeof(*vert_clnors), __func__);
+ BKE_mesh_normals_loop_to_vertex(
+ numVerts, mesh->mloop, mesh->totloop, (const float(*)[3])clnors, vert_clnors);
+ }
+ else {
+ direction = MOD_DISP_DIR_NOR;
+ }
+ }
+ else if (ELEM(direction, MOD_DISP_DIR_X, MOD_DISP_DIR_Y, MOD_DISP_DIR_Z, MOD_DISP_DIR_RGB_XYZ) &&
+ use_global_direction) {
+ copy_m4_m4(local_mat, ob->obmat);
+ }
+
+ DisplaceUserdata data = {NULL};
+ data.scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ data.dmd = dmd;
+ data.dvert = dvert;
+ data.weight = weight;
+ data.defgrp_index = defgrp_index;
+ data.direction = direction;
+ data.use_global_direction = use_global_direction;
+ data.tex_target = tex_target;
+ data.tex_co = tex_co;
+ data.vertexCos = vertexCos;
+ copy_m4_m4(data.local_mat, local_mat);
+ data.mvert = mvert;
+ data.vert_clnors = vert_clnors;
+ if (tex_target != NULL) {
+ data.pool = BKE_image_pool_new();
+ BKE_texture_fetch_images_for_pool(tex_target, data.pool);
+ }
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.use_threading = (numVerts > 512);
+ BLI_task_parallel_range(0, numVerts, &data, displaceModifier_do_task, &settings);
+
+ if (data.pool != NULL) {
+ BKE_image_pool_free(data.pool);
+ }
+
+ if (tex_co) {
+ MEM_freeN(tex_co);
+ }
+
+ if (vert_clnors) {
+ MEM_freeN(vert_clnors);
+ }
}
-static void deformVerts(
- ModifierData *md,
- const ModifierEvalContext *ctx,
- Mesh *mesh,
- float (*vertexCos)[3],
- int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
- displaceModifier_do((DisplaceModifierData *)md, ctx, mesh_src, vertexCos, numVerts);
+ displaceModifier_do((DisplaceModifierData *)md, ctx, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-static void deformVertsEM(
- ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *editData,
- Mesh *mesh, float (*vertexCos)[3], int numVerts)
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *editData,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, editData, mesh, NULL, numVerts, false, false);
- displaceModifier_do((DisplaceModifierData *)md, ctx, mesh_src, vertexCos, numVerts);
+ displaceModifier_do((DisplaceModifierData *)md, ctx, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-
ModifierTypeInfo modifierType_Displace = {
- /* name */ "Displace",
- /* structName */ "DisplaceModifierData",
- /* structSize */ sizeof(DisplaceModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ foreachIDLink,
- /* foreachTexLink */ foreachTexLink,
- /* freeRuntimeData */ NULL,
+ /* name */ "Displace",
+ /* structName */ "DisplaceModifierData",
+ /* structSize */ sizeof(DisplaceModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ dependsOnNormals,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ foreachTexLink,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c
index badf3df6b1d..ccd71455b21 100644
--- a/source/blender/modifiers/intern/MOD_dynamicpaint.c
+++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c
@@ -43,157 +43,160 @@
static void initData(ModifierData *md)
{
- DynamicPaintModifierData *pmd = (DynamicPaintModifierData *) md;
+ DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
- pmd->canvas = NULL;
- pmd->brush = NULL;
- pmd->type = MOD_DYNAMICPAINT_TYPE_CANVAS;
+ pmd->canvas = NULL;
+ pmd->brush = NULL;
+ pmd->type = MOD_DYNAMICPAINT_TYPE_CANVAS;
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
- const DynamicPaintModifierData *pmd = (const DynamicPaintModifierData *)md;
- DynamicPaintModifierData *tpmd = (DynamicPaintModifierData *)target;
+ const DynamicPaintModifierData *pmd = (const DynamicPaintModifierData *)md;
+ DynamicPaintModifierData *tpmd = (DynamicPaintModifierData *)target;
- dynamicPaint_Modifier_copy(pmd, tpmd, flag);
+ dynamicPaint_Modifier_copy(pmd, tpmd, flag);
}
static void freeRuntimeData(void *runtime_data_v)
{
- if (runtime_data_v == NULL) {
- return;
- }
- DynamicPaintRuntime *runtime_data = (DynamicPaintRuntime *)runtime_data_v;
- dynamicPaint_Modifier_free_runtime(runtime_data);
+ if (runtime_data_v == NULL) {
+ return;
+ }
+ DynamicPaintRuntime *runtime_data = (DynamicPaintRuntime *)runtime_data_v;
+ dynamicPaint_Modifier_free_runtime(runtime_data);
}
static void freeData(ModifierData *md)
{
- DynamicPaintModifierData *pmd = (DynamicPaintModifierData *) md;
- dynamicPaint_Modifier_free(pmd);
+ DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
+ dynamicPaint_Modifier_free(pmd);
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
-
- if (pmd->canvas) {
- DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
- for (; surface; surface = surface->next) {
- /* tface */
- if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ ||
- surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE)
- {
- r_cddata_masks->lmask |= CD_MASK_MLOOPUV;
- }
- /* mcol */
- if (surface->type == MOD_DPAINT_SURFACE_T_PAINT ||
- surface->init_color_type == MOD_DPAINT_INITIAL_VERTEXCOLOR)
- {
- r_cddata_masks->lmask |= CD_MASK_MLOOPCOL;
- }
- /* CD_MDEFORMVERT */
- if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
- }
- }
+ DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
+
+ if (pmd->canvas) {
+ DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
+ for (; surface; surface = surface->next) {
+ /* tface */
+ if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ ||
+ surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE) {
+ r_cddata_masks->lmask |= CD_MASK_MLOOPUV;
+ }
+ /* mcol */
+ if (surface->type == MOD_DPAINT_SURFACE_T_PAINT ||
+ surface->init_color_type == MOD_DPAINT_INITIAL_VERTEXCOLOR) {
+ r_cddata_masks->lmask |= CD_MASK_MLOOPCOL;
+ }
+ /* CD_MDEFORMVERT */
+ if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
+ }
+ }
}
-static Mesh *applyModifier(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- DynamicPaintModifierData *pmd = (DynamicPaintModifierData *) md;
-
- /* dont apply dynamic paint on orco mesh stack */
- if (!(ctx->flag & MOD_APPLY_ORCO)) {
- Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- return dynamicPaint_Modifier_do(pmd, ctx->depsgraph, scene, ctx->object, mesh);
- }
- return mesh;
+ DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
+
+ /* dont apply dynamic paint on orco mesh stack */
+ if (!(ctx->flag & MOD_APPLY_ORCO)) {
+ Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ return dynamicPaint_Modifier_do(pmd, ctx->depsgraph, scene, ctx->object, mesh);
+ }
+ return mesh;
}
static bool is_brush_cb(Object *UNUSED(ob), ModifierData *pmd)
{
- return ((DynamicPaintModifierData *)pmd)->brush != NULL;
+ return ((DynamicPaintModifierData *)pmd)->brush != NULL;
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
- /* Add relation from canvases to all brush objects. */
- if (pmd->canvas != NULL) {
- for (DynamicPaintSurface *surface = pmd->canvas->surfaces.first; surface; surface = surface->next) {
- if (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) {
- DEG_add_forcefield_relations(ctx->node, ctx->object, surface->effector_weights, true, 0, "Dynamic Paint Field");
- }
-
- /* Actual code uses custom loop over group/scene without layer checks in dynamicPaint_doStep */
- DEG_add_collision_relations(ctx->node, ctx->object, surface->brush_group, eModifierType_DynamicPaint, is_brush_cb, "Dynamic Paint Brush");
- }
- }
+ DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
+ /* Add relation from canvases to all brush objects. */
+ if (pmd->canvas != NULL) {
+ for (DynamicPaintSurface *surface = pmd->canvas->surfaces.first; surface;
+ surface = surface->next) {
+ if (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) {
+ DEG_add_forcefield_relations(
+ ctx->node, ctx->object, surface->effector_weights, true, 0, "Dynamic Paint Field");
+ }
+
+ /* Actual code uses custom loop over group/scene without layer checks in dynamicPaint_doStep */
+ DEG_add_collision_relations(ctx->node,
+ ctx->object,
+ surface->brush_group,
+ eModifierType_DynamicPaint,
+ is_brush_cb,
+ "Dynamic Paint Brush");
+ }
+ }
}
static bool dependsOnTime(ModifierData *UNUSED(md))
{
- return true;
+ return true;
}
-static void foreachIDLink(
- ModifierData *md, Object *ob,
- IDWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
- DynamicPaintModifierData *pmd = (DynamicPaintModifierData *) md;
-
- if (pmd->canvas) {
- DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
-
- for (; surface; surface = surface->next) {
- walk(userData, ob, (ID **)&surface->brush_group, IDWALK_CB_NOP);
- walk(userData, ob, (ID **)&surface->init_texture, IDWALK_CB_USER);
- if (surface->effector_weights) {
- walk(userData, ob, (ID **)&surface->effector_weights->group, IDWALK_CB_NOP);
- }
- }
- }
+ DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
+
+ if (pmd->canvas) {
+ DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
+
+ for (; surface; surface = surface->next) {
+ walk(userData, ob, (ID **)&surface->brush_group, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&surface->init_texture, IDWALK_CB_USER);
+ if (surface->effector_weights) {
+ walk(userData, ob, (ID **)&surface->effector_weights->group, IDWALK_CB_NOP);
+ }
+ }
+ }
}
-static void foreachTexLink(
- ModifierData *UNUSED(md), Object *UNUSED(ob),
- TexWalkFunc UNUSED(walk), void *UNUSED(userData))
+static void foreachTexLink(ModifierData *UNUSED(md),
+ Object *UNUSED(ob),
+ TexWalkFunc UNUSED(walk),
+ void *UNUSED(userData))
{
- //walk(userData, ob, md, ""); /* re-enable when possible */
+ //walk(userData, ob, md, ""); /* re-enable when possible */
}
ModifierTypeInfo modifierType_DynamicPaint = {
- /* name */ "Dynamic Paint",
- /* structName */ "DynamicPaintModifierData",
- /* structSize */ sizeof(DynamicPaintModifierData),
- /* type */ eModifierTypeType_Constructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
-/* eModifierTypeFlag_SupportsMapping |*/
- eModifierTypeFlag_UsesPointCache |
- eModifierTypeFlag_Single |
- eModifierTypeFlag_UsesPreview,
-
- /* copyData */ copyData,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ freeData,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ foreachIDLink,
- /* foreachTexLink */ foreachTexLink,
- /* freeRuntimeData */ freeRuntimeData,
+ /* name */ "Dynamic Paint",
+ /* structName */ "DynamicPaintModifierData",
+ /* structSize */ sizeof(DynamicPaintModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh |
+ /* eModifierTypeFlag_SupportsMapping |*/
+ eModifierTypeFlag_UsesPointCache | eModifierTypeFlag_Single |
+ eModifierTypeFlag_UsesPreview,
+
+ /* copyData */ copyData,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ freeData,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ foreachTexLink,
+ /* freeRuntimeData */ freeRuntimeData,
};
diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c
index 751a70916ab..9c2ad13db94 100644
--- a/source/blender/modifiers/intern/MOD_edgesplit.c
+++ b/source/blender/modifiers/intern/MOD_edgesplit.c
@@ -43,124 +43,115 @@
static Mesh *doEdgeSplit(Mesh *mesh, EdgeSplitModifierData *emd)
{
- Mesh *result;
- BMesh *bm;
- BMIter iter;
- BMEdge *e;
- const float threshold = cosf(emd->split_angle + 0.000000175f);
- const bool do_split_angle = (emd->flags & MOD_EDGESPLIT_FROMANGLE) != 0 && emd->split_angle < (float)M_PI;
- const bool do_split_all = do_split_angle && emd->split_angle < FLT_EPSILON;
- const bool calc_face_normals = do_split_angle && !do_split_all;
-
- bm = BKE_mesh_to_bmesh_ex(
- mesh,
- &(struct BMeshCreateParams){0},
- &(struct BMeshFromMeshParams){
- .calc_face_normal = calc_face_normals,
- .add_key_index = false,
- .use_shapekey = false,
- .active_shapekey = 0,
- .cd_mask_extra = {.vmask = CD_MASK_ORIGINDEX, .emask = CD_MASK_ORIGINDEX, .pmask = CD_MASK_ORIGINDEX},
- });
-
- if (do_split_angle) {
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- /* check for 1 edge having 2 face users */
- BMLoop *l1, *l2;
- if ((l1 = e->l) &&
- (l2 = e->l->radial_next) != l1)
- {
- if (/* 3+ faces on this edge, always split */
- UNLIKELY(l1 != l2->radial_next) ||
- /* O° angle setting, we want to split on all edges. */
- do_split_all ||
- /* 2 face edge - check angle*/
- (dot_v3v3(l1->f->no, l2->f->no) < threshold))
- {
- BM_elem_flag_enable(e, BM_ELEM_TAG);
- }
- }
- }
- }
-
- if (emd->flags & MOD_EDGESPLIT_FROMFLAG) {
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- /* check for 2 or more edge users */
- if ((e->l) &&
- (e->l->next != e->l))
- {
- if (!BM_elem_flag_test(e, BM_ELEM_SMOOTH)) {
- BM_elem_flag_enable(e, BM_ELEM_TAG);
- }
- }
- }
- }
-
- BM_mesh_edgesplit(bm, false, true, false);
-
- /* BM_mesh_validate(bm); */ /* for troubleshooting */
-
- result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
- BM_mesh_free(bm);
-
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- return result;
+ Mesh *result;
+ BMesh *bm;
+ BMIter iter;
+ BMEdge *e;
+ const float threshold = cosf(emd->split_angle + 0.000000175f);
+ const bool do_split_angle = (emd->flags & MOD_EDGESPLIT_FROMANGLE) != 0 &&
+ emd->split_angle < (float)M_PI;
+ const bool do_split_all = do_split_angle && emd->split_angle < FLT_EPSILON;
+ const bool calc_face_normals = do_split_angle && !do_split_all;
+
+ bm = BKE_mesh_to_bmesh_ex(mesh,
+ &(struct BMeshCreateParams){0},
+ &(struct BMeshFromMeshParams){
+ .calc_face_normal = calc_face_normals,
+ .add_key_index = false,
+ .use_shapekey = false,
+ .active_shapekey = 0,
+ .cd_mask_extra = {.vmask = CD_MASK_ORIGINDEX,
+ .emask = CD_MASK_ORIGINDEX,
+ .pmask = CD_MASK_ORIGINDEX},
+ });
+
+ if (do_split_angle) {
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ /* check for 1 edge having 2 face users */
+ BMLoop *l1, *l2;
+ if ((l1 = e->l) && (l2 = e->l->radial_next) != l1) {
+ if (/* 3+ faces on this edge, always split */
+ UNLIKELY(l1 != l2->radial_next) ||
+ /* O° angle setting, we want to split on all edges. */
+ do_split_all ||
+ /* 2 face edge - check angle*/
+ (dot_v3v3(l1->f->no, l2->f->no) < threshold)) {
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ }
+ }
+ }
+ }
+
+ if (emd->flags & MOD_EDGESPLIT_FROMFLAG) {
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ /* check for 2 or more edge users */
+ if ((e->l) && (e->l->next != e->l)) {
+ if (!BM_elem_flag_test(e, BM_ELEM_SMOOTH)) {
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ }
+ }
+ }
+ }
+
+ BM_mesh_edgesplit(bm, false, true, false);
+
+ /* BM_mesh_validate(bm); */ /* for troubleshooting */
+
+ result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
+ BM_mesh_free(bm);
+
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ return result;
}
static void initData(ModifierData *md)
{
- EdgeSplitModifierData *emd = (EdgeSplitModifierData *) md;
+ EdgeSplitModifierData *emd = (EdgeSplitModifierData *)md;
- /* default to 30-degree split angle, sharpness from both angle & flag */
- emd->split_angle = DEG2RADF(30.0f);
- emd->flags = MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG;
+ /* default to 30-degree split angle, sharpness from both angle & flag */
+ emd->split_angle = DEG2RADF(30.0f);
+ emd->flags = MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG;
}
-static Mesh *applyModifier(
- ModifierData *md,
- const ModifierEvalContext *UNUSED(ctx),
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
{
- Mesh *result;
- EdgeSplitModifierData *emd = (EdgeSplitModifierData *) md;
+ Mesh *result;
+ EdgeSplitModifierData *emd = (EdgeSplitModifierData *)md;
- if (!(emd->flags & (MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG)))
- return mesh;
+ if (!(emd->flags & (MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG)))
+ return mesh;
- result = doEdgeSplit(mesh, emd);
+ result = doEdgeSplit(mesh, emd);
- return result;
+ return result;
}
-
ModifierTypeInfo modifierType_EdgeSplit = {
- /* name */ "EdgeSplit",
- /* structName */ "EdgeSplitModifierData",
- /* structSize */ sizeof(EdgeSplitModifierData),
- /* type */ eModifierTypeType_Constructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_SupportsMapping |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_EnableInEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ NULL,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "EdgeSplit",
+ /* structName */ "EdgeSplitModifierData",
+ /* structSize */ sizeof(EdgeSplitModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs |
+ eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode |
+ eModifierTypeFlag_EnableInEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c
index a8a0b963bd8..f126adbaafd 100644
--- a/source/blender/modifiers/intern/MOD_explode.c
+++ b/source/blender/modifiers/intern/MOD_explode.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include "BLI_utildefines.h"
#include "BLI_edgehash.h"
@@ -50,1055 +49,1137 @@
static void initData(ModifierData *md)
{
- ExplodeModifierData *emd = (ExplodeModifierData *) md;
+ ExplodeModifierData *emd = (ExplodeModifierData *)md;
- emd->facepa = NULL;
- emd->flag |= eExplodeFlag_Unborn + eExplodeFlag_Alive + eExplodeFlag_Dead;
+ emd->facepa = NULL;
+ emd->flag |= eExplodeFlag_Unborn + eExplodeFlag_Alive + eExplodeFlag_Dead;
}
static void freeData(ModifierData *md)
{
- ExplodeModifierData *emd = (ExplodeModifierData *) md;
+ ExplodeModifierData *emd = (ExplodeModifierData *)md;
- MEM_SAFE_FREE(emd->facepa);
+ MEM_SAFE_FREE(emd->facepa);
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
#if 0
- const ExplodeModifierData *emd = (const ExplodeModifierData *) md;
+ const ExplodeModifierData *emd = (const ExplodeModifierData *) md;
#endif
- ExplodeModifierData *temd = (ExplodeModifierData *) target;
+ ExplodeModifierData *temd = (ExplodeModifierData *)target;
- modifier_copyData_generic(md, target, flag);
+ modifier_copyData_generic(md, target, flag);
- temd->facepa = NULL;
+ temd->facepa = NULL;
}
static bool dependsOnTime(ModifierData *UNUSED(md))
{
- return true;
+ return true;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- ExplodeModifierData *emd = (ExplodeModifierData *) md;
+ ExplodeModifierData *emd = (ExplodeModifierData *)md;
- if (emd->vgroup) {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ if (emd->vgroup) {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
-static void createFacepa(
- ExplodeModifierData *emd,
- ParticleSystemModifierData *psmd,
- Mesh *mesh)
+static void createFacepa(ExplodeModifierData *emd, ParticleSystemModifierData *psmd, Mesh *mesh)
{
- ParticleSystem *psys = psmd->psys;
- MFace *fa = NULL, *mface = NULL;
- MVert *mvert = NULL;
- ParticleData *pa;
- KDTree_3d *tree;
- RNG *rng;
- float center[3], co[3];
- int *facepa = NULL, *vertpa = NULL, totvert = 0, totface = 0, totpart = 0;
- int i, p, v1, v2, v3, v4 = 0;
-
- mvert = mesh->mvert;
- mface = mesh->mface;
- totvert = mesh->totvert;
- totface = mesh->totface;
- totpart = psmd->psys->totpart;
-
- rng = BLI_rng_new_srandom(psys->seed);
-
- if (emd->facepa) {
- MEM_freeN(emd->facepa);
- }
- facepa = emd->facepa = MEM_calloc_arrayN(totface, sizeof(int), "explode_facepa");
-
- vertpa = MEM_calloc_arrayN(totvert, sizeof(int), "explode_vertpa");
-
- /* initialize all faces & verts to no particle */
- for (i = 0; i < totface; i++) {
- facepa[i] = totpart;
- }
- for (i = 0; i < totvert; i++) {
- vertpa[i] = totpart;
- }
-
- /* set protected verts */
- if (emd->vgroup) {
- MDeformVert *dvert = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT);
- if (dvert) {
- const int defgrp_index = emd->vgroup - 1;
- for (i = 0; i < totvert; i++, dvert++) {
- float val = BLI_rng_get_float(rng);
- val = (1.0f - emd->protect) * val + emd->protect * 0.5f;
- if (val < defvert_find_weight(dvert, defgrp_index))
- vertpa[i] = -1;
- }
- }
- }
-
- /* make tree of emitter locations */
- tree = BLI_kdtree_3d_new(totpart);
- for (p = 0, pa = psys->particles; p < totpart; p++, pa++) {
- psys_particle_on_emitter(psmd, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, NULL, NULL, NULL, NULL);
- BLI_kdtree_3d_insert(tree, p, co);
- }
- BLI_kdtree_3d_balance(tree);
-
- /* set face-particle-indexes to nearest particle to face center */
- for (i = 0, fa = mface; i < totface; i++, fa++) {
- add_v3_v3v3(center, mvert[fa->v1].co, mvert[fa->v2].co);
- add_v3_v3(center, mvert[fa->v3].co);
- if (fa->v4) {
- add_v3_v3(center, mvert[fa->v4].co);
- mul_v3_fl(center, 0.25);
- }
- else {
- mul_v3_fl(center, 1.0f / 3.0f);
- }
-
- p = BLI_kdtree_3d_find_nearest(tree, center, NULL);
-
- v1 = vertpa[fa->v1];
- v2 = vertpa[fa->v2];
- v3 = vertpa[fa->v3];
- if (fa->v4) {
- v4 = vertpa[fa->v4];
- }
-
- if (v1 >= 0 && v2 >= 0 && v3 >= 0 && (fa->v4 == 0 || v4 >= 0)) {
- facepa[i] = p;
- }
-
- if (v1 >= 0) {
- vertpa[fa->v1] = p;
- }
- if (v2 >= 0) {
- vertpa[fa->v2] = p;
- }
- if (v3 >= 0) {
- vertpa[fa->v3] = p;
- }
- if (fa->v4 && v4 >= 0) {
- vertpa[fa->v4] = p;
- }
- }
-
- if (vertpa) {
- MEM_freeN(vertpa);
- }
- BLI_kdtree_3d_free(tree);
-
- BLI_rng_free(rng);
+ ParticleSystem *psys = psmd->psys;
+ MFace *fa = NULL, *mface = NULL;
+ MVert *mvert = NULL;
+ ParticleData *pa;
+ KDTree_3d *tree;
+ RNG *rng;
+ float center[3], co[3];
+ int *facepa = NULL, *vertpa = NULL, totvert = 0, totface = 0, totpart = 0;
+ int i, p, v1, v2, v3, v4 = 0;
+
+ mvert = mesh->mvert;
+ mface = mesh->mface;
+ totvert = mesh->totvert;
+ totface = mesh->totface;
+ totpart = psmd->psys->totpart;
+
+ rng = BLI_rng_new_srandom(psys->seed);
+
+ if (emd->facepa) {
+ MEM_freeN(emd->facepa);
+ }
+ facepa = emd->facepa = MEM_calloc_arrayN(totface, sizeof(int), "explode_facepa");
+
+ vertpa = MEM_calloc_arrayN(totvert, sizeof(int), "explode_vertpa");
+
+ /* initialize all faces & verts to no particle */
+ for (i = 0; i < totface; i++) {
+ facepa[i] = totpart;
+ }
+ for (i = 0; i < totvert; i++) {
+ vertpa[i] = totpart;
+ }
+
+ /* set protected verts */
+ if (emd->vgroup) {
+ MDeformVert *dvert = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT);
+ if (dvert) {
+ const int defgrp_index = emd->vgroup - 1;
+ for (i = 0; i < totvert; i++, dvert++) {
+ float val = BLI_rng_get_float(rng);
+ val = (1.0f - emd->protect) * val + emd->protect * 0.5f;
+ if (val < defvert_find_weight(dvert, defgrp_index))
+ vertpa[i] = -1;
+ }
+ }
+ }
+
+ /* make tree of emitter locations */
+ tree = BLI_kdtree_3d_new(totpart);
+ for (p = 0, pa = psys->particles; p < totpart; p++, pa++) {
+ psys_particle_on_emitter(psmd,
+ psys->part->from,
+ pa->num,
+ pa->num_dmcache,
+ pa->fuv,
+ pa->foffset,
+ co,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ BLI_kdtree_3d_insert(tree, p, co);
+ }
+ BLI_kdtree_3d_balance(tree);
+
+ /* set face-particle-indexes to nearest particle to face center */
+ for (i = 0, fa = mface; i < totface; i++, fa++) {
+ add_v3_v3v3(center, mvert[fa->v1].co, mvert[fa->v2].co);
+ add_v3_v3(center, mvert[fa->v3].co);
+ if (fa->v4) {
+ add_v3_v3(center, mvert[fa->v4].co);
+ mul_v3_fl(center, 0.25);
+ }
+ else {
+ mul_v3_fl(center, 1.0f / 3.0f);
+ }
+
+ p = BLI_kdtree_3d_find_nearest(tree, center, NULL);
+
+ v1 = vertpa[fa->v1];
+ v2 = vertpa[fa->v2];
+ v3 = vertpa[fa->v3];
+ if (fa->v4) {
+ v4 = vertpa[fa->v4];
+ }
+
+ if (v1 >= 0 && v2 >= 0 && v3 >= 0 && (fa->v4 == 0 || v4 >= 0)) {
+ facepa[i] = p;
+ }
+
+ if (v1 >= 0) {
+ vertpa[fa->v1] = p;
+ }
+ if (v2 >= 0) {
+ vertpa[fa->v2] = p;
+ }
+ if (v3 >= 0) {
+ vertpa[fa->v3] = p;
+ }
+ if (fa->v4 && v4 >= 0) {
+ vertpa[fa->v4] = p;
+ }
+ }
+
+ if (vertpa) {
+ MEM_freeN(vertpa);
+ }
+ BLI_kdtree_3d_free(tree);
+
+ BLI_rng_free(rng);
}
static int edgecut_get(EdgeHash *edgehash, unsigned int v1, unsigned int v2)
{
- return POINTER_AS_INT(BLI_edgehash_lookup(edgehash, v1, v2));
+ return POINTER_AS_INT(BLI_edgehash_lookup(edgehash, v1, v2));
}
-
static const short add_faces[24] = {
- 0,
- 0, 0, 2, 0, 1, 2, 2, 0, 2, 1,
- 2, 2, 2, 2, 3, 0, 0, 0, 1, 0,
- 1, 1, 2,
+ 0, 0, 0, 2, 0, 1, 2, 2, 0, 2, 1, 2, 2, 2, 2, 3, 0, 0, 0, 1, 0, 1, 1, 2,
};
static MFace *get_dface(Mesh *mesh, Mesh *split, int cur, int i, MFace *mf)
{
- MFace *df = &split->mface[cur];
- CustomData_copy_data(&mesh->fdata, &split->fdata, i, cur, 1);
- *df = *mf;
- return df;
+ MFace *df = &split->mface[cur];
+ CustomData_copy_data(&mesh->fdata, &split->fdata, i, cur, 1);
+ *df = *mf;
+ return df;
}
-#define SET_VERTS(a, b, c, d) \
- { \
- v[0] = mf->v##a; uv[0] = a - 1; \
- v[1] = mf->v##b; uv[1] = b - 1; \
- v[2] = mf->v##c; uv[2] = c - 1; \
- v[3] = mf->v##d; uv[3] = d - 1; \
- } (void)0
+#define SET_VERTS(a, b, c, d) \
+ { \
+ v[0] = mf->v##a; \
+ uv[0] = a - 1; \
+ v[1] = mf->v##b; \
+ uv[1] = b - 1; \
+ v[2] = mf->v##c; \
+ uv[2] = c - 1; \
+ v[3] = mf->v##d; \
+ uv[3] = d - 1; \
+ } \
+ (void)0
#define GET_ES(v1, v2) edgecut_get(eh, v1, v2)
#define INT_UV(uvf, c0, c1) mid_v2_v2v2(uvf, mf->uv[c0], mf->uv[c1])
-static void remap_faces_3_6_9_12(Mesh *mesh, Mesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4)
+static void remap_faces_3_6_9_12(Mesh *mesh,
+ Mesh *split,
+ MFace *mf,
+ int *facepa,
+ int *vertpa,
+ int i,
+ EdgeHash *eh,
+ int cur,
+ int v1,
+ int v2,
+ int v3,
+ int v4)
{
- MFace *df1 = get_dface(mesh, split, cur, i, mf);
- MFace *df2 = get_dface(mesh, split, cur + 1, i, mf);
- MFace *df3 = get_dface(mesh, split, cur + 2, i, mf);
-
- facepa[cur] = vertpa[v1];
- df1->v1 = v1;
- df1->v2 = GET_ES(v1, v2);
- df1->v3 = GET_ES(v2, v3);
- df1->v4 = v3;
- df1->flag |= ME_FACE_SEL;
-
- facepa[cur + 1] = vertpa[v2];
- df2->v1 = GET_ES(v1, v2);
- df2->v2 = v2;
- df2->v3 = GET_ES(v2, v3);
- df2->v4 = 0;
- df2->flag &= ~ME_FACE_SEL;
-
- facepa[cur + 2] = vertpa[v1];
- df3->v1 = v1;
- df3->v2 = v3;
- df3->v3 = v4;
- df3->v4 = 0;
- df3->flag &= ~ME_FACE_SEL;
+ MFace *df1 = get_dface(mesh, split, cur, i, mf);
+ MFace *df2 = get_dface(mesh, split, cur + 1, i, mf);
+ MFace *df3 = get_dface(mesh, split, cur + 2, i, mf);
+
+ facepa[cur] = vertpa[v1];
+ df1->v1 = v1;
+ df1->v2 = GET_ES(v1, v2);
+ df1->v3 = GET_ES(v2, v3);
+ df1->v4 = v3;
+ df1->flag |= ME_FACE_SEL;
+
+ facepa[cur + 1] = vertpa[v2];
+ df2->v1 = GET_ES(v1, v2);
+ df2->v2 = v2;
+ df2->v3 = GET_ES(v2, v3);
+ df2->v4 = 0;
+ df2->flag &= ~ME_FACE_SEL;
+
+ facepa[cur + 2] = vertpa[v1];
+ df3->v1 = v1;
+ df3->v2 = v3;
+ df3->v3 = v4;
+ df3->v4 = 0;
+ df3->flag &= ~ME_FACE_SEL;
}
-static void remap_uvs_3_6_9_12(Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3)
+static void remap_uvs_3_6_9_12(
+ Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3)
{
- MTFace *mf, *df1, *df2, *df3;
- int l;
-
- for (l = 0; l < numlayer; l++) {
- mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
- df1 = mf + cur;
- df2 = df1 + 1;
- df3 = df1 + 2;
- mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l);
- mf += i;
-
- copy_v2_v2(df1->uv[0], mf->uv[c0]);
- INT_UV(df1->uv[1], c0, c1);
- INT_UV(df1->uv[2], c1, c2);
- copy_v2_v2(df1->uv[3], mf->uv[c2]);
-
- INT_UV(df2->uv[0], c0, c1);
- copy_v2_v2(df2->uv[1], mf->uv[c1]);
- INT_UV(df2->uv[2], c1, c2);
-
- copy_v2_v2(df3->uv[0], mf->uv[c0]);
- copy_v2_v2(df3->uv[1], mf->uv[c2]);
- copy_v2_v2(df3->uv[2], mf->uv[c3]);
- }
+ MTFace *mf, *df1, *df2, *df3;
+ int l;
+
+ for (l = 0; l < numlayer; l++) {
+ mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
+ df1 = mf + cur;
+ df2 = df1 + 1;
+ df3 = df1 + 2;
+ mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l);
+ mf += i;
+
+ copy_v2_v2(df1->uv[0], mf->uv[c0]);
+ INT_UV(df1->uv[1], c0, c1);
+ INT_UV(df1->uv[2], c1, c2);
+ copy_v2_v2(df1->uv[3], mf->uv[c2]);
+
+ INT_UV(df2->uv[0], c0, c1);
+ copy_v2_v2(df2->uv[1], mf->uv[c1]);
+ INT_UV(df2->uv[2], c1, c2);
+
+ copy_v2_v2(df3->uv[0], mf->uv[c0]);
+ copy_v2_v2(df3->uv[1], mf->uv[c2]);
+ copy_v2_v2(df3->uv[2], mf->uv[c3]);
+ }
}
-static void remap_faces_5_10(Mesh *mesh, Mesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4)
+static void remap_faces_5_10(Mesh *mesh,
+ Mesh *split,
+ MFace *mf,
+ int *facepa,
+ int *vertpa,
+ int i,
+ EdgeHash *eh,
+ int cur,
+ int v1,
+ int v2,
+ int v3,
+ int v4)
{
- MFace *df1 = get_dface(mesh, split, cur, i, mf);
- MFace *df2 = get_dface(mesh, split, cur + 1, i, mf);
-
- facepa[cur] = vertpa[v1];
- df1->v1 = v1;
- df1->v2 = v2;
- df1->v3 = GET_ES(v2, v3);
- df1->v4 = GET_ES(v1, v4);
- df1->flag |= ME_FACE_SEL;
-
- facepa[cur + 1] = vertpa[v3];
- df2->v1 = GET_ES(v1, v4);
- df2->v2 = GET_ES(v2, v3);
- df2->v3 = v3;
- df2->v4 = v4;
- df2->flag |= ME_FACE_SEL;
+ MFace *df1 = get_dface(mesh, split, cur, i, mf);
+ MFace *df2 = get_dface(mesh, split, cur + 1, i, mf);
+
+ facepa[cur] = vertpa[v1];
+ df1->v1 = v1;
+ df1->v2 = v2;
+ df1->v3 = GET_ES(v2, v3);
+ df1->v4 = GET_ES(v1, v4);
+ df1->flag |= ME_FACE_SEL;
+
+ facepa[cur + 1] = vertpa[v3];
+ df2->v1 = GET_ES(v1, v4);
+ df2->v2 = GET_ES(v2, v3);
+ df2->v3 = v3;
+ df2->v4 = v4;
+ df2->flag |= ME_FACE_SEL;
}
-static void remap_uvs_5_10(Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3)
+static void remap_uvs_5_10(
+ Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3)
{
- MTFace *mf, *df1, *df2;
- int l;
-
- for (l = 0; l < numlayer; l++) {
- mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
- df1 = mf + cur;
- df2 = df1 + 1;
- mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l);
- mf += i;
-
- copy_v2_v2(df1->uv[0], mf->uv[c0]);
- copy_v2_v2(df1->uv[1], mf->uv[c1]);
- INT_UV(df1->uv[2], c1, c2);
- INT_UV(df1->uv[3], c0, c3);
-
- INT_UV(df2->uv[0], c0, c3);
- INT_UV(df2->uv[1], c1, c2);
- copy_v2_v2(df2->uv[2], mf->uv[c2]);
- copy_v2_v2(df2->uv[3], mf->uv[c3]);
-
- }
+ MTFace *mf, *df1, *df2;
+ int l;
+
+ for (l = 0; l < numlayer; l++) {
+ mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
+ df1 = mf + cur;
+ df2 = df1 + 1;
+ mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l);
+ mf += i;
+
+ copy_v2_v2(df1->uv[0], mf->uv[c0]);
+ copy_v2_v2(df1->uv[1], mf->uv[c1]);
+ INT_UV(df1->uv[2], c1, c2);
+ INT_UV(df1->uv[3], c0, c3);
+
+ INT_UV(df2->uv[0], c0, c3);
+ INT_UV(df2->uv[1], c1, c2);
+ copy_v2_v2(df2->uv[2], mf->uv[c2]);
+ copy_v2_v2(df2->uv[3], mf->uv[c3]);
+ }
}
-static void remap_faces_15(Mesh *mesh, Mesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4)
+static void remap_faces_15(Mesh *mesh,
+ Mesh *split,
+ MFace *mf,
+ int *facepa,
+ int *vertpa,
+ int i,
+ EdgeHash *eh,
+ int cur,
+ int v1,
+ int v2,
+ int v3,
+ int v4)
{
- MFace *df1 = get_dface(mesh, split, cur, i, mf);
- MFace *df2 = get_dface(mesh, split, cur + 1, i, mf);
- MFace *df3 = get_dface(mesh, split, cur + 2, i, mf);
- MFace *df4 = get_dface(mesh, split, cur + 3, i, mf);
-
- facepa[cur] = vertpa[v1];
- df1->v1 = v1;
- df1->v2 = GET_ES(v1, v2);
- df1->v3 = GET_ES(v1, v3);
- df1->v4 = GET_ES(v1, v4);
- df1->flag |= ME_FACE_SEL;
-
- facepa[cur + 1] = vertpa[v2];
- df2->v1 = GET_ES(v1, v2);
- df2->v2 = v2;
- df2->v3 = GET_ES(v2, v3);
- df2->v4 = GET_ES(v1, v3);
- df2->flag |= ME_FACE_SEL;
-
- facepa[cur + 2] = vertpa[v3];
- df3->v1 = GET_ES(v1, v3);
- df3->v2 = GET_ES(v2, v3);
- df3->v3 = v3;
- df3->v4 = GET_ES(v3, v4);
- df3->flag |= ME_FACE_SEL;
-
- facepa[cur + 3] = vertpa[v4];
- df4->v1 = GET_ES(v1, v4);
- df4->v2 = GET_ES(v1, v3);
- df4->v3 = GET_ES(v3, v4);
- df4->v4 = v4;
- df4->flag |= ME_FACE_SEL;
+ MFace *df1 = get_dface(mesh, split, cur, i, mf);
+ MFace *df2 = get_dface(mesh, split, cur + 1, i, mf);
+ MFace *df3 = get_dface(mesh, split, cur + 2, i, mf);
+ MFace *df4 = get_dface(mesh, split, cur + 3, i, mf);
+
+ facepa[cur] = vertpa[v1];
+ df1->v1 = v1;
+ df1->v2 = GET_ES(v1, v2);
+ df1->v3 = GET_ES(v1, v3);
+ df1->v4 = GET_ES(v1, v4);
+ df1->flag |= ME_FACE_SEL;
+
+ facepa[cur + 1] = vertpa[v2];
+ df2->v1 = GET_ES(v1, v2);
+ df2->v2 = v2;
+ df2->v3 = GET_ES(v2, v3);
+ df2->v4 = GET_ES(v1, v3);
+ df2->flag |= ME_FACE_SEL;
+
+ facepa[cur + 2] = vertpa[v3];
+ df3->v1 = GET_ES(v1, v3);
+ df3->v2 = GET_ES(v2, v3);
+ df3->v3 = v3;
+ df3->v4 = GET_ES(v3, v4);
+ df3->flag |= ME_FACE_SEL;
+
+ facepa[cur + 3] = vertpa[v4];
+ df4->v1 = GET_ES(v1, v4);
+ df4->v2 = GET_ES(v1, v3);
+ df4->v3 = GET_ES(v3, v4);
+ df4->v4 = v4;
+ df4->flag |= ME_FACE_SEL;
}
-static void remap_uvs_15(Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3)
+static void remap_uvs_15(
+ Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3)
{
- MTFace *mf, *df1, *df2, *df3, *df4;
- int l;
-
- for (l = 0; l < numlayer; l++) {
- mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
- df1 = mf + cur;
- df2 = df1 + 1;
- df3 = df1 + 2;
- df4 = df1 + 3;
- mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l);
- mf += i;
-
- copy_v2_v2(df1->uv[0], mf->uv[c0]);
- INT_UV(df1->uv[1], c0, c1);
- INT_UV(df1->uv[2], c0, c2);
- INT_UV(df1->uv[3], c0, c3);
-
- INT_UV(df2->uv[0], c0, c1);
- copy_v2_v2(df2->uv[1], mf->uv[c1]);
- INT_UV(df2->uv[2], c1, c2);
- INT_UV(df2->uv[3], c0, c2);
-
- INT_UV(df3->uv[0], c0, c2);
- INT_UV(df3->uv[1], c1, c2);
- copy_v2_v2(df3->uv[2], mf->uv[c2]);
- INT_UV(df3->uv[3], c2, c3);
-
- INT_UV(df4->uv[0], c0, c3);
- INT_UV(df4->uv[1], c0, c2);
- INT_UV(df4->uv[2], c2, c3);
- copy_v2_v2(df4->uv[3], mf->uv[c3]);
- }
+ MTFace *mf, *df1, *df2, *df3, *df4;
+ int l;
+
+ for (l = 0; l < numlayer; l++) {
+ mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
+ df1 = mf + cur;
+ df2 = df1 + 1;
+ df3 = df1 + 2;
+ df4 = df1 + 3;
+ mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l);
+ mf += i;
+
+ copy_v2_v2(df1->uv[0], mf->uv[c0]);
+ INT_UV(df1->uv[1], c0, c1);
+ INT_UV(df1->uv[2], c0, c2);
+ INT_UV(df1->uv[3], c0, c3);
+
+ INT_UV(df2->uv[0], c0, c1);
+ copy_v2_v2(df2->uv[1], mf->uv[c1]);
+ INT_UV(df2->uv[2], c1, c2);
+ INT_UV(df2->uv[3], c0, c2);
+
+ INT_UV(df3->uv[0], c0, c2);
+ INT_UV(df3->uv[1], c1, c2);
+ copy_v2_v2(df3->uv[2], mf->uv[c2]);
+ INT_UV(df3->uv[3], c2, c3);
+
+ INT_UV(df4->uv[0], c0, c3);
+ INT_UV(df4->uv[1], c0, c2);
+ INT_UV(df4->uv[2], c2, c3);
+ copy_v2_v2(df4->uv[3], mf->uv[c3]);
+ }
}
-static void remap_faces_7_11_13_14(Mesh *mesh, Mesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3, int v4)
+static void remap_faces_7_11_13_14(Mesh *mesh,
+ Mesh *split,
+ MFace *mf,
+ int *facepa,
+ int *vertpa,
+ int i,
+ EdgeHash *eh,
+ int cur,
+ int v1,
+ int v2,
+ int v3,
+ int v4)
{
- MFace *df1 = get_dface(mesh, split, cur, i, mf);
- MFace *df2 = get_dface(mesh, split, cur + 1, i, mf);
- MFace *df3 = get_dface(mesh, split, cur + 2, i, mf);
-
- facepa[cur] = vertpa[v1];
- df1->v1 = v1;
- df1->v2 = GET_ES(v1, v2);
- df1->v3 = GET_ES(v2, v3);
- df1->v4 = GET_ES(v1, v4);
- df1->flag |= ME_FACE_SEL;
-
- facepa[cur + 1] = vertpa[v2];
- df2->v1 = GET_ES(v1, v2);
- df2->v2 = v2;
- df2->v3 = GET_ES(v2, v3);
- df2->v4 = 0;
- df2->flag &= ~ME_FACE_SEL;
-
- facepa[cur + 2] = vertpa[v4];
- df3->v1 = GET_ES(v1, v4);
- df3->v2 = GET_ES(v2, v3);
- df3->v3 = v3;
- df3->v4 = v4;
- df3->flag |= ME_FACE_SEL;
+ MFace *df1 = get_dface(mesh, split, cur, i, mf);
+ MFace *df2 = get_dface(mesh, split, cur + 1, i, mf);
+ MFace *df3 = get_dface(mesh, split, cur + 2, i, mf);
+
+ facepa[cur] = vertpa[v1];
+ df1->v1 = v1;
+ df1->v2 = GET_ES(v1, v2);
+ df1->v3 = GET_ES(v2, v3);
+ df1->v4 = GET_ES(v1, v4);
+ df1->flag |= ME_FACE_SEL;
+
+ facepa[cur + 1] = vertpa[v2];
+ df2->v1 = GET_ES(v1, v2);
+ df2->v2 = v2;
+ df2->v3 = GET_ES(v2, v3);
+ df2->v4 = 0;
+ df2->flag &= ~ME_FACE_SEL;
+
+ facepa[cur + 2] = vertpa[v4];
+ df3->v1 = GET_ES(v1, v4);
+ df3->v2 = GET_ES(v2, v3);
+ df3->v3 = v3;
+ df3->v4 = v4;
+ df3->flag |= ME_FACE_SEL;
}
-static void remap_uvs_7_11_13_14(Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3)
+static void remap_uvs_7_11_13_14(
+ Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3)
{
- MTFace *mf, *df1, *df2, *df3;
- int l;
-
- for (l = 0; l < numlayer; l++) {
- mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
- df1 = mf + cur;
- df2 = df1 + 1;
- df3 = df1 + 2;
- mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l);
- mf += i;
-
- copy_v2_v2(df1->uv[0], mf->uv[c0]);
- INT_UV(df1->uv[1], c0, c1);
- INT_UV(df1->uv[2], c1, c2);
- INT_UV(df1->uv[3], c0, c3);
-
- INT_UV(df2->uv[0], c0, c1);
- copy_v2_v2(df2->uv[1], mf->uv[c1]);
- INT_UV(df2->uv[2], c1, c2);
-
- INT_UV(df3->uv[0], c0, c3);
- INT_UV(df3->uv[1], c1, c2);
- copy_v2_v2(df3->uv[2], mf->uv[c2]);
- copy_v2_v2(df3->uv[3], mf->uv[c3]);
- }
+ MTFace *mf, *df1, *df2, *df3;
+ int l;
+
+ for (l = 0; l < numlayer; l++) {
+ mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
+ df1 = mf + cur;
+ df2 = df1 + 1;
+ df3 = df1 + 2;
+ mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l);
+ mf += i;
+
+ copy_v2_v2(df1->uv[0], mf->uv[c0]);
+ INT_UV(df1->uv[1], c0, c1);
+ INT_UV(df1->uv[2], c1, c2);
+ INT_UV(df1->uv[3], c0, c3);
+
+ INT_UV(df2->uv[0], c0, c1);
+ copy_v2_v2(df2->uv[1], mf->uv[c1]);
+ INT_UV(df2->uv[2], c1, c2);
+
+ INT_UV(df3->uv[0], c0, c3);
+ INT_UV(df3->uv[1], c1, c2);
+ copy_v2_v2(df3->uv[2], mf->uv[c2]);
+ copy_v2_v2(df3->uv[3], mf->uv[c3]);
+ }
}
-static void remap_faces_19_21_22(Mesh *mesh, Mesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3)
+static void remap_faces_19_21_22(Mesh *mesh,
+ Mesh *split,
+ MFace *mf,
+ int *facepa,
+ int *vertpa,
+ int i,
+ EdgeHash *eh,
+ int cur,
+ int v1,
+ int v2,
+ int v3)
{
- MFace *df1 = get_dface(mesh, split, cur, i, mf);
- MFace *df2 = get_dface(mesh, split, cur + 1, i, mf);
-
- facepa[cur] = vertpa[v1];
- df1->v1 = v1;
- df1->v2 = GET_ES(v1, v2);
- df1->v3 = GET_ES(v1, v3);
- df1->v4 = 0;
- df1->flag &= ~ME_FACE_SEL;
-
- facepa[cur + 1] = vertpa[v2];
- df2->v1 = GET_ES(v1, v2);
- df2->v2 = v2;
- df2->v3 = v3;
- df2->v4 = GET_ES(v1, v3);
- df2->flag |= ME_FACE_SEL;
+ MFace *df1 = get_dface(mesh, split, cur, i, mf);
+ MFace *df2 = get_dface(mesh, split, cur + 1, i, mf);
+
+ facepa[cur] = vertpa[v1];
+ df1->v1 = v1;
+ df1->v2 = GET_ES(v1, v2);
+ df1->v3 = GET_ES(v1, v3);
+ df1->v4 = 0;
+ df1->flag &= ~ME_FACE_SEL;
+
+ facepa[cur + 1] = vertpa[v2];
+ df2->v1 = GET_ES(v1, v2);
+ df2->v2 = v2;
+ df2->v3 = v3;
+ df2->v4 = GET_ES(v1, v3);
+ df2->flag |= ME_FACE_SEL;
}
-static void remap_uvs_19_21_22(Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2)
+static void remap_uvs_19_21_22(
+ Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2)
{
- MTFace *mf, *df1, *df2;
- int l;
-
- for (l = 0; l < numlayer; l++) {
- mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
- df1 = mf + cur;
- df2 = df1 + 1;
- mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l);
- mf += i;
-
- copy_v2_v2(df1->uv[0], mf->uv[c0]);
- INT_UV(df1->uv[1], c0, c1);
- INT_UV(df1->uv[2], c0, c2);
-
- INT_UV(df2->uv[0], c0, c1);
- copy_v2_v2(df2->uv[1], mf->uv[c1]);
- copy_v2_v2(df2->uv[2], mf->uv[c2]);
- INT_UV(df2->uv[3], c0, c2);
- }
+ MTFace *mf, *df1, *df2;
+ int l;
+
+ for (l = 0; l < numlayer; l++) {
+ mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
+ df1 = mf + cur;
+ df2 = df1 + 1;
+ mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l);
+ mf += i;
+
+ copy_v2_v2(df1->uv[0], mf->uv[c0]);
+ INT_UV(df1->uv[1], c0, c1);
+ INT_UV(df1->uv[2], c0, c2);
+
+ INT_UV(df2->uv[0], c0, c1);
+ copy_v2_v2(df2->uv[1], mf->uv[c1]);
+ copy_v2_v2(df2->uv[2], mf->uv[c2]);
+ INT_UV(df2->uv[3], c0, c2);
+ }
}
-static void remap_faces_23(Mesh *mesh, Mesh *split, MFace *mf, int *facepa, int *vertpa, int i, EdgeHash *eh, int cur, int v1, int v2, int v3)
+static void remap_faces_23(Mesh *mesh,
+ Mesh *split,
+ MFace *mf,
+ int *facepa,
+ int *vertpa,
+ int i,
+ EdgeHash *eh,
+ int cur,
+ int v1,
+ int v2,
+ int v3)
{
- MFace *df1 = get_dface(mesh, split, cur, i, mf);
- MFace *df2 = get_dface(mesh, split, cur + 1, i, mf);
- MFace *df3 = get_dface(mesh, split, cur + 2, i, mf);
-
- facepa[cur] = vertpa[v1];
- df1->v1 = v1;
- df1->v2 = GET_ES(v1, v2);
- df1->v3 = GET_ES(v2, v3);
- df1->v4 = GET_ES(v1, v3);
- df1->flag |= ME_FACE_SEL;
-
- facepa[cur + 1] = vertpa[v2];
- df2->v1 = GET_ES(v1, v2);
- df2->v2 = v2;
- df2->v3 = GET_ES(v2, v3);
- df2->v4 = 0;
- df2->flag &= ~ME_FACE_SEL;
-
- facepa[cur + 2] = vertpa[v3];
- df3->v1 = GET_ES(v1, v3);
- df3->v2 = GET_ES(v2, v3);
- df3->v3 = v3;
- df3->v4 = 0;
- df3->flag &= ~ME_FACE_SEL;
+ MFace *df1 = get_dface(mesh, split, cur, i, mf);
+ MFace *df2 = get_dface(mesh, split, cur + 1, i, mf);
+ MFace *df3 = get_dface(mesh, split, cur + 2, i, mf);
+
+ facepa[cur] = vertpa[v1];
+ df1->v1 = v1;
+ df1->v2 = GET_ES(v1, v2);
+ df1->v3 = GET_ES(v2, v3);
+ df1->v4 = GET_ES(v1, v3);
+ df1->flag |= ME_FACE_SEL;
+
+ facepa[cur + 1] = vertpa[v2];
+ df2->v1 = GET_ES(v1, v2);
+ df2->v2 = v2;
+ df2->v3 = GET_ES(v2, v3);
+ df2->v4 = 0;
+ df2->flag &= ~ME_FACE_SEL;
+
+ facepa[cur + 2] = vertpa[v3];
+ df3->v1 = GET_ES(v1, v3);
+ df3->v2 = GET_ES(v2, v3);
+ df3->v3 = v3;
+ df3->v4 = 0;
+ df3->flag &= ~ME_FACE_SEL;
}
-static void remap_uvs_23(Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2)
+static void remap_uvs_23(
+ Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2)
{
- MTFace *mf, *df1, *df2;
- int l;
-
- for (l = 0; l < numlayer; l++) {
- mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
- df1 = mf + cur;
- df2 = df1 + 1;
- mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l);
- mf += i;
-
- copy_v2_v2(df1->uv[0], mf->uv[c0]);
- INT_UV(df1->uv[1], c0, c1);
- INT_UV(df1->uv[2], c1, c2);
- INT_UV(df1->uv[3], c0, c2);
-
- INT_UV(df2->uv[0], c0, c1);
- copy_v2_v2(df2->uv[1], mf->uv[c1]);
- INT_UV(df2->uv[2], c1, c2);
-
- INT_UV(df2->uv[0], c0, c2);
- INT_UV(df2->uv[1], c1, c2);
- copy_v2_v2(df2->uv[2], mf->uv[c2]);
- }
+ MTFace *mf, *df1, *df2;
+ int l;
+
+ for (l = 0; l < numlayer; l++) {
+ mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
+ df1 = mf + cur;
+ df2 = df1 + 1;
+ mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l);
+ mf += i;
+
+ copy_v2_v2(df1->uv[0], mf->uv[c0]);
+ INT_UV(df1->uv[1], c0, c1);
+ INT_UV(df1->uv[2], c1, c2);
+ INT_UV(df1->uv[3], c0, c2);
+
+ INT_UV(df2->uv[0], c0, c1);
+ copy_v2_v2(df2->uv[1], mf->uv[c1]);
+ INT_UV(df2->uv[2], c1, c2);
+
+ INT_UV(df2->uv[0], c0, c2);
+ INT_UV(df2->uv[1], c1, c2);
+ copy_v2_v2(df2->uv[2], mf->uv[c2]);
+ }
}
static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh)
{
- Mesh *split_m;
- MFace *mf = NULL, *df1 = NULL;
- MFace *mface = mesh->mface;
- MVert *dupve, *mv;
- EdgeHash *edgehash;
- EdgeHashIterator *ehi;
- int totvert = mesh->totvert;
- int totface = mesh->totface;
-
- int *facesplit = MEM_calloc_arrayN(totface, sizeof(int), "explode_facesplit");
- int *vertpa = MEM_calloc_arrayN(totvert, sizeof(int), "explode_vertpa2");
- int *facepa = emd->facepa;
- int *fs, totesplit = 0, totfsplit = 0, curdupface = 0;
- int i, v1, v2, v3, v4, esplit,
- v[4] = {0, 0, 0, 0}, /* To quite gcc barking... */
- uv[4] = {0, 0, 0, 0}; /* To quite gcc barking... */
- int numlayer;
- unsigned int ed_v1, ed_v2;
-
- edgehash = BLI_edgehash_new(__func__);
-
- /* recreate vertpa from facepa calculation */
- for (i = 0, mf = mface; i < totface; i++, mf++) {
- vertpa[mf->v1] = facepa[i];
- vertpa[mf->v2] = facepa[i];
- vertpa[mf->v3] = facepa[i];
- if (mf->v4) {
- vertpa[mf->v4] = facepa[i];
- }
- }
-
- /* mark edges for splitting and how to split faces */
- for (i = 0, mf = mface, fs = facesplit; i < totface; i++, mf++, fs++) {
- v1 = vertpa[mf->v1];
- v2 = vertpa[mf->v2];
- v3 = vertpa[mf->v3];
-
- if (v1 != v2) {
- BLI_edgehash_reinsert(edgehash, mf->v1, mf->v2, NULL);
- (*fs) |= 1;
- }
-
- if (v2 != v3) {
- BLI_edgehash_reinsert(edgehash, mf->v2, mf->v3, NULL);
- (*fs) |= 2;
- }
-
- if (mf->v4) {
- v4 = vertpa[mf->v4];
-
- if (v3 != v4) {
- BLI_edgehash_reinsert(edgehash, mf->v3, mf->v4, NULL);
- (*fs) |= 4;
- }
-
- if (v1 != v4) {
- BLI_edgehash_reinsert(edgehash, mf->v1, mf->v4, NULL);
- (*fs) |= 8;
- }
-
- /* mark center vertex as a fake edge split */
- if (*fs == 15) {
- BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, NULL);
- }
- }
- else {
- (*fs) |= 16; /* mark face as tri */
-
- if (v1 != v3) {
- BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, NULL);
- (*fs) |= 4;
- }
- }
- }
-
- /* count splits & create indexes for new verts */
- ehi = BLI_edgehashIterator_new(edgehash);
- totesplit = totvert;
- for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
- BLI_edgehashIterator_setValue(ehi, POINTER_FROM_INT(totesplit));
- totesplit++;
- }
- BLI_edgehashIterator_free(ehi);
-
- /* count new faces due to splitting */
- for (i = 0, fs = facesplit; i < totface; i++, fs++)
- totfsplit += add_faces[*fs];
-
- split_m = BKE_mesh_new_nomain_from_template(
- mesh, totesplit, 0, totface + totfsplit, 0, 0);
-
- numlayer = CustomData_number_of_layers(&split_m->fdata, CD_MTFACE);
-
- /* copy new faces & verts (is it really this painful with custom data??) */
- for (i = 0; i < totvert; i++) {
- MVert source;
- MVert *dest;
- source = mesh->mvert[i];
- dest = &split_m->mvert[i];
-
- CustomData_copy_data(&mesh->vdata, &split_m->vdata, i, i, 1);
- *dest = source;
- }
-
- /* override original facepa (original pointer is saved in caller function) */
-
- /* BMESH_TODO, (totfsplit * 2) over allocation is used since the quads are
- * later interpreted as tri's, for this to work right I think we probably
- * have to stop using tessface - campbell */
-
- facepa = MEM_calloc_arrayN((totface + (totfsplit * 2)), sizeof(int), "explode_facepa");
- //memcpy(facepa, emd->facepa, totface*sizeof(int));
- emd->facepa = facepa;
-
- /* create new verts */
- ehi = BLI_edgehashIterator_new(edgehash);
- for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
- BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2);
- esplit = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi));
- mv = &split_m->mvert[ed_v2];
- dupve = &split_m->mvert[esplit];
-
- CustomData_copy_data(&split_m->vdata, &split_m->vdata, ed_v2, esplit, 1);
-
- *dupve = *mv;
-
- mv = &split_m->mvert[ed_v1];
-
- mid_v3_v3v3(dupve->co, dupve->co, mv->co);
- }
- BLI_edgehashIterator_free(ehi);
-
- /* create new faces */
- curdupface = 0; //=totface;
- //curdupin=totesplit;
- for (i = 0, fs = facesplit; i < totface; i++, fs++) {
- mf = &mesh->mface[i];
-
- switch (*fs) {
- case 3:
- case 10:
- case 11:
- case 15:
- SET_VERTS(1, 2, 3, 4);
- break;
- case 5:
- case 6:
- case 7:
- SET_VERTS(2, 3, 4, 1);
- break;
- case 9:
- case 13:
- SET_VERTS(4, 1, 2, 3);
- break;
- case 12:
- case 14:
- SET_VERTS(3, 4, 1, 2);
- break;
- case 21:
- case 23:
- SET_VERTS(1, 2, 3, 4);
- break;
- case 19:
- SET_VERTS(2, 3, 1, 4);
- break;
- case 22:
- SET_VERTS(3, 1, 2, 4);
- break;
- }
-
- switch (*fs) {
- case 3:
- case 6:
- case 9:
- case 12:
- remap_faces_3_6_9_12(mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
- if (numlayer) {
- remap_uvs_3_6_9_12(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
- }
- break;
- case 5:
- case 10:
- remap_faces_5_10(mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
- if (numlayer) {
- remap_uvs_5_10(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
- }
- break;
- case 15:
- remap_faces_15(mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
- if (numlayer) {
- remap_uvs_15(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
- }
- break;
- case 7:
- case 11:
- case 13:
- case 14:
- remap_faces_7_11_13_14(mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
- if (numlayer) {
- remap_uvs_7_11_13_14(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
- }
- break;
- case 19:
- case 21:
- case 22:
- remap_faces_19_21_22(mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]);
- if (numlayer) {
- remap_uvs_19_21_22(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2]);
- }
- break;
- case 23:
- remap_faces_23(mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]);
- if (numlayer) {
- remap_uvs_23(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2]);
- }
- break;
- case 0:
- case 16:
- df1 = get_dface(mesh, split_m, curdupface, i, mf);
- facepa[curdupface] = vertpa[mf->v1];
-
- if (df1->v4) {
- df1->flag |= ME_FACE_SEL;
- }
- else {
- df1->flag &= ~ME_FACE_SEL;
- }
- break;
- }
-
- curdupface += add_faces[*fs] + 1;
- }
-
- for (i = 0; i < curdupface; i++) {
- mf = &split_m->mface[i];
- test_index_face(mf, &split_m->fdata, i, ((mf->flag & ME_FACE_SEL) ? 4 : 3));
- }
-
- BLI_edgehash_free(edgehash, NULL);
- MEM_freeN(facesplit);
- MEM_freeN(vertpa);
-
- BKE_mesh_calc_edges_tessface(split_m);
- BKE_mesh_convert_mfaces_to_mpolys(split_m);
-
- return split_m;
+ Mesh *split_m;
+ MFace *mf = NULL, *df1 = NULL;
+ MFace *mface = mesh->mface;
+ MVert *dupve, *mv;
+ EdgeHash *edgehash;
+ EdgeHashIterator *ehi;
+ int totvert = mesh->totvert;
+ int totface = mesh->totface;
+
+ int *facesplit = MEM_calloc_arrayN(totface, sizeof(int), "explode_facesplit");
+ int *vertpa = MEM_calloc_arrayN(totvert, sizeof(int), "explode_vertpa2");
+ int *facepa = emd->facepa;
+ int *fs, totesplit = 0, totfsplit = 0, curdupface = 0;
+ int i, v1, v2, v3, v4, esplit, v[4] = {0, 0, 0, 0}, /* To quite gcc barking... */
+ uv[4] = {0, 0, 0, 0}; /* To quite gcc barking... */
+ int numlayer;
+ unsigned int ed_v1, ed_v2;
+
+ edgehash = BLI_edgehash_new(__func__);
+
+ /* recreate vertpa from facepa calculation */
+ for (i = 0, mf = mface; i < totface; i++, mf++) {
+ vertpa[mf->v1] = facepa[i];
+ vertpa[mf->v2] = facepa[i];
+ vertpa[mf->v3] = facepa[i];
+ if (mf->v4) {
+ vertpa[mf->v4] = facepa[i];
+ }
+ }
+
+ /* mark edges for splitting and how to split faces */
+ for (i = 0, mf = mface, fs = facesplit; i < totface; i++, mf++, fs++) {
+ v1 = vertpa[mf->v1];
+ v2 = vertpa[mf->v2];
+ v3 = vertpa[mf->v3];
+
+ if (v1 != v2) {
+ BLI_edgehash_reinsert(edgehash, mf->v1, mf->v2, NULL);
+ (*fs) |= 1;
+ }
+
+ if (v2 != v3) {
+ BLI_edgehash_reinsert(edgehash, mf->v2, mf->v3, NULL);
+ (*fs) |= 2;
+ }
+
+ if (mf->v4) {
+ v4 = vertpa[mf->v4];
+
+ if (v3 != v4) {
+ BLI_edgehash_reinsert(edgehash, mf->v3, mf->v4, NULL);
+ (*fs) |= 4;
+ }
+
+ if (v1 != v4) {
+ BLI_edgehash_reinsert(edgehash, mf->v1, mf->v4, NULL);
+ (*fs) |= 8;
+ }
+
+ /* mark center vertex as a fake edge split */
+ if (*fs == 15) {
+ BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, NULL);
+ }
+ }
+ else {
+ (*fs) |= 16; /* mark face as tri */
+
+ if (v1 != v3) {
+ BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, NULL);
+ (*fs) |= 4;
+ }
+ }
+ }
+
+ /* count splits & create indexes for new verts */
+ ehi = BLI_edgehashIterator_new(edgehash);
+ totesplit = totvert;
+ for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
+ BLI_edgehashIterator_setValue(ehi, POINTER_FROM_INT(totesplit));
+ totesplit++;
+ }
+ BLI_edgehashIterator_free(ehi);
+
+ /* count new faces due to splitting */
+ for (i = 0, fs = facesplit; i < totface; i++, fs++)
+ totfsplit += add_faces[*fs];
+
+ split_m = BKE_mesh_new_nomain_from_template(mesh, totesplit, 0, totface + totfsplit, 0, 0);
+
+ numlayer = CustomData_number_of_layers(&split_m->fdata, CD_MTFACE);
+
+ /* copy new faces & verts (is it really this painful with custom data??) */
+ for (i = 0; i < totvert; i++) {
+ MVert source;
+ MVert *dest;
+ source = mesh->mvert[i];
+ dest = &split_m->mvert[i];
+
+ CustomData_copy_data(&mesh->vdata, &split_m->vdata, i, i, 1);
+ *dest = source;
+ }
+
+ /* override original facepa (original pointer is saved in caller function) */
+
+ /* BMESH_TODO, (totfsplit * 2) over allocation is used since the quads are
+ * later interpreted as tri's, for this to work right I think we probably
+ * have to stop using tessface - campbell */
+
+ facepa = MEM_calloc_arrayN((totface + (totfsplit * 2)), sizeof(int), "explode_facepa");
+ //memcpy(facepa, emd->facepa, totface*sizeof(int));
+ emd->facepa = facepa;
+
+ /* create new verts */
+ ehi = BLI_edgehashIterator_new(edgehash);
+ for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
+ BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2);
+ esplit = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi));
+ mv = &split_m->mvert[ed_v2];
+ dupve = &split_m->mvert[esplit];
+
+ CustomData_copy_data(&split_m->vdata, &split_m->vdata, ed_v2, esplit, 1);
+
+ *dupve = *mv;
+
+ mv = &split_m->mvert[ed_v1];
+
+ mid_v3_v3v3(dupve->co, dupve->co, mv->co);
+ }
+ BLI_edgehashIterator_free(ehi);
+
+ /* create new faces */
+ curdupface = 0; //=totface;
+ //curdupin=totesplit;
+ for (i = 0, fs = facesplit; i < totface; i++, fs++) {
+ mf = &mesh->mface[i];
+
+ switch (*fs) {
+ case 3:
+ case 10:
+ case 11:
+ case 15:
+ SET_VERTS(1, 2, 3, 4);
+ break;
+ case 5:
+ case 6:
+ case 7:
+ SET_VERTS(2, 3, 4, 1);
+ break;
+ case 9:
+ case 13:
+ SET_VERTS(4, 1, 2, 3);
+ break;
+ case 12:
+ case 14:
+ SET_VERTS(3, 4, 1, 2);
+ break;
+ case 21:
+ case 23:
+ SET_VERTS(1, 2, 3, 4);
+ break;
+ case 19:
+ SET_VERTS(2, 3, 1, 4);
+ break;
+ case 22:
+ SET_VERTS(3, 1, 2, 4);
+ break;
+ }
+
+ switch (*fs) {
+ case 3:
+ case 6:
+ case 9:
+ case 12:
+ remap_faces_3_6_9_12(
+ mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
+ if (numlayer) {
+ remap_uvs_3_6_9_12(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
+ }
+ break;
+ case 5:
+ case 10:
+ remap_faces_5_10(
+ mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
+ if (numlayer) {
+ remap_uvs_5_10(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
+ }
+ break;
+ case 15:
+ remap_faces_15(
+ mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
+ if (numlayer) {
+ remap_uvs_15(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
+ }
+ break;
+ case 7:
+ case 11:
+ case 13:
+ case 14:
+ remap_faces_7_11_13_14(
+ mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
+ if (numlayer) {
+ remap_uvs_7_11_13_14(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
+ }
+ break;
+ case 19:
+ case 21:
+ case 22:
+ remap_faces_19_21_22(
+ mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]);
+ if (numlayer) {
+ remap_uvs_19_21_22(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2]);
+ }
+ break;
+ case 23:
+ remap_faces_23(
+ mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]);
+ if (numlayer) {
+ remap_uvs_23(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2]);
+ }
+ break;
+ case 0:
+ case 16:
+ df1 = get_dface(mesh, split_m, curdupface, i, mf);
+ facepa[curdupface] = vertpa[mf->v1];
+
+ if (df1->v4) {
+ df1->flag |= ME_FACE_SEL;
+ }
+ else {
+ df1->flag &= ~ME_FACE_SEL;
+ }
+ break;
+ }
+
+ curdupface += add_faces[*fs] + 1;
+ }
+
+ for (i = 0; i < curdupface; i++) {
+ mf = &split_m->mface[i];
+ test_index_face(mf, &split_m->fdata, i, ((mf->flag & ME_FACE_SEL) ? 4 : 3));
+ }
+
+ BLI_edgehash_free(edgehash, NULL);
+ MEM_freeN(facesplit);
+ MEM_freeN(vertpa);
+
+ BKE_mesh_calc_edges_tessface(split_m);
+ BKE_mesh_convert_mfaces_to_mpolys(split_m);
+
+ return split_m;
}
-static Mesh *explodeMesh(
- ExplodeModifierData *emd,
- ParticleSystemModifierData *psmd, const ModifierEvalContext *ctx, Scene *scene,
- Mesh *to_explode)
+static Mesh *explodeMesh(ExplodeModifierData *emd,
+ ParticleSystemModifierData *psmd,
+ const ModifierEvalContext *ctx,
+ Scene *scene,
+ Mesh *to_explode)
{
- Mesh *explode, *mesh = to_explode;
- MFace *mf = NULL, *mface;
- /* ParticleSettings *part=psmd->psys->part; */ /* UNUSED */
- ParticleSimulationData sim = {NULL};
- ParticleData *pa = NULL, *pars = psmd->psys->particles;
- ParticleKey state, birth;
- EdgeHash *vertpahash;
- EdgeHashIterator *ehi;
- float *vertco = NULL, imat[4][4];
- float rot[4];
- float cfra;
- /* float timestep; */
- const int *facepa = emd->facepa;
- int totdup = 0, totvert = 0, totface = 0, totpart = 0, delface = 0;
- int i, v, u;
- unsigned int ed_v1, ed_v2, mindex = 0;
- MTFace *mtface = NULL, *mtf;
-
- totface = mesh->totface;
- totvert = mesh->totvert;
- mface = mesh->mface;
- totpart = psmd->psys->totpart;
-
- sim.depsgraph = ctx->depsgraph;
- sim.scene = scene;
- sim.ob = ctx->object;
- sim.psys = psmd->psys;
- sim.psmd = psmd;
-
- /* timestep = psys_get_timestep(&sim); */
-
- cfra = BKE_scene_frame_get(scene);
-
- /* hash table for vertice <-> particle relations */
- vertpahash = BLI_edgehash_new(__func__);
-
- for (i = 0; i < totface; i++) {
- if (facepa[i] != totpart) {
- pa = pars + facepa[i];
-
- if ((pa->alive == PARS_UNBORN && (emd->flag & eExplodeFlag_Unborn) == 0) ||
- (pa->alive == PARS_ALIVE && (emd->flag & eExplodeFlag_Alive) == 0) ||
- (pa->alive == PARS_DEAD && (emd->flag & eExplodeFlag_Dead) == 0))
- {
- delface++;
- continue;
- }
- }
-
- /* do mindex + totvert to ensure the vertex index to be the first
- * with BLI_edgehashIterator_getKey */
- if (facepa[i] == totpart || cfra < (pars + facepa[i])->time) {
- mindex = totvert + totpart;
- }
- else {
- mindex = totvert + facepa[i];
- }
-
- mf = &mface[i];
-
- /* set face vertices to exist in particle group */
- BLI_edgehash_reinsert(vertpahash, mf->v1, mindex, NULL);
- BLI_edgehash_reinsert(vertpahash, mf->v2, mindex, NULL);
- BLI_edgehash_reinsert(vertpahash, mf->v3, mindex, NULL);
- if (mf->v4) {
- BLI_edgehash_reinsert(vertpahash, mf->v4, mindex, NULL);
- }
- }
-
- /* make new vertice indexes & count total vertices after duplication */
- ehi = BLI_edgehashIterator_new(vertpahash);
- for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
- BLI_edgehashIterator_setValue(ehi, POINTER_FROM_INT(totdup));
- totdup++;
- }
- BLI_edgehashIterator_free(ehi);
-
- /* the final duplicated vertices */
- explode = BKE_mesh_new_nomain_from_template(mesh, totdup, 0, totface - delface, 0, 0);
-
- mtface = CustomData_get_layer_named(&explode->fdata, CD_MTFACE, emd->uvname);
- /*dupvert = CDDM_get_verts(explode);*/
-
- /* getting back to object space */
- invert_m4_m4(imat, ctx->object->obmat);
-
- psmd->psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
-
- /* duplicate & displace vertices */
- ehi = BLI_edgehashIterator_new(vertpahash);
- for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
- MVert source;
- MVert *dest;
-
- /* get particle + vertex from hash */
- BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2);
- ed_v2 -= totvert;
- v = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi));
-
- source = mesh->mvert[ed_v1];
- dest = &explode->mvert[v];
-
- CustomData_copy_data(&mesh->vdata, &explode->vdata, ed_v1, v, 1);
-
- *dest = source;
-
- if (ed_v2 != totpart) {
- /* get particle */
- pa = pars + ed_v2;
-
- psys_get_birth_coords(&sim, pa, &birth, 0, 0);
-
- state.time = cfra;
- psys_get_particle_state(&sim, ed_v2, &state, 1);
-
- vertco = explode->mvert[v].co;
- mul_m4_v3(ctx->object->obmat, vertco);
-
- sub_v3_v3(vertco, birth.co);
-
- /* apply rotation, size & location */
- sub_qt_qtqt(rot, state.rot, birth.rot);
- mul_qt_v3(rot, vertco);
-
- if (emd->flag & eExplodeFlag_PaSize) {
- mul_v3_fl(vertco, pa->size);
- }
-
- add_v3_v3(vertco, state.co);
+ Mesh *explode, *mesh = to_explode;
+ MFace *mf = NULL, *mface;
+ /* ParticleSettings *part=psmd->psys->part; */ /* UNUSED */
+ ParticleSimulationData sim = {NULL};
+ ParticleData *pa = NULL, *pars = psmd->psys->particles;
+ ParticleKey state, birth;
+ EdgeHash *vertpahash;
+ EdgeHashIterator *ehi;
+ float *vertco = NULL, imat[4][4];
+ float rot[4];
+ float cfra;
+ /* float timestep; */
+ const int *facepa = emd->facepa;
+ int totdup = 0, totvert = 0, totface = 0, totpart = 0, delface = 0;
+ int i, v, u;
+ unsigned int ed_v1, ed_v2, mindex = 0;
+ MTFace *mtface = NULL, *mtf;
+
+ totface = mesh->totface;
+ totvert = mesh->totvert;
+ mface = mesh->mface;
+ totpart = psmd->psys->totpart;
+
+ sim.depsgraph = ctx->depsgraph;
+ sim.scene = scene;
+ sim.ob = ctx->object;
+ sim.psys = psmd->psys;
+ sim.psmd = psmd;
+
+ /* timestep = psys_get_timestep(&sim); */
+
+ cfra = BKE_scene_frame_get(scene);
+
+ /* hash table for vertice <-> particle relations */
+ vertpahash = BLI_edgehash_new(__func__);
+
+ for (i = 0; i < totface; i++) {
+ if (facepa[i] != totpart) {
+ pa = pars + facepa[i];
+
+ if ((pa->alive == PARS_UNBORN && (emd->flag & eExplodeFlag_Unborn) == 0) ||
+ (pa->alive == PARS_ALIVE && (emd->flag & eExplodeFlag_Alive) == 0) ||
+ (pa->alive == PARS_DEAD && (emd->flag & eExplodeFlag_Dead) == 0)) {
+ delface++;
+ continue;
+ }
+ }
+
+ /* do mindex + totvert to ensure the vertex index to be the first
+ * with BLI_edgehashIterator_getKey */
+ if (facepa[i] == totpart || cfra < (pars + facepa[i])->time) {
+ mindex = totvert + totpart;
+ }
+ else {
+ mindex = totvert + facepa[i];
+ }
+
+ mf = &mface[i];
+
+ /* set face vertices to exist in particle group */
+ BLI_edgehash_reinsert(vertpahash, mf->v1, mindex, NULL);
+ BLI_edgehash_reinsert(vertpahash, mf->v2, mindex, NULL);
+ BLI_edgehash_reinsert(vertpahash, mf->v3, mindex, NULL);
+ if (mf->v4) {
+ BLI_edgehash_reinsert(vertpahash, mf->v4, mindex, NULL);
+ }
+ }
+
+ /* make new vertice indexes & count total vertices after duplication */
+ ehi = BLI_edgehashIterator_new(vertpahash);
+ for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
+ BLI_edgehashIterator_setValue(ehi, POINTER_FROM_INT(totdup));
+ totdup++;
+ }
+ BLI_edgehashIterator_free(ehi);
+
+ /* the final duplicated vertices */
+ explode = BKE_mesh_new_nomain_from_template(mesh, totdup, 0, totface - delface, 0, 0);
+
+ mtface = CustomData_get_layer_named(&explode->fdata, CD_MTFACE, emd->uvname);
+ /*dupvert = CDDM_get_verts(explode);*/
+
+ /* getting back to object space */
+ invert_m4_m4(imat, ctx->object->obmat);
+
+ psmd->psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
+
+ /* duplicate & displace vertices */
+ ehi = BLI_edgehashIterator_new(vertpahash);
+ for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
+ MVert source;
+ MVert *dest;
+
+ /* get particle + vertex from hash */
+ BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2);
+ ed_v2 -= totvert;
+ v = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi));
+
+ source = mesh->mvert[ed_v1];
+ dest = &explode->mvert[v];
+
+ CustomData_copy_data(&mesh->vdata, &explode->vdata, ed_v1, v, 1);
+
+ *dest = source;
+
+ if (ed_v2 != totpart) {
+ /* get particle */
+ pa = pars + ed_v2;
+
+ psys_get_birth_coords(&sim, pa, &birth, 0, 0);
+
+ state.time = cfra;
+ psys_get_particle_state(&sim, ed_v2, &state, 1);
+
+ vertco = explode->mvert[v].co;
+ mul_m4_v3(ctx->object->obmat, vertco);
- mul_m4_v3(imat, vertco);
- }
- }
- BLI_edgehashIterator_free(ehi);
+ sub_v3_v3(vertco, birth.co);
+
+ /* apply rotation, size & location */
+ sub_qt_qtqt(rot, state.rot, birth.rot);
+ mul_qt_v3(rot, vertco);
- /*map new vertices to faces*/
- for (i = 0, u = 0; i < totface; i++) {
- MFace source;
- int orig_v4;
+ if (emd->flag & eExplodeFlag_PaSize) {
+ mul_v3_fl(vertco, pa->size);
+ }
- if (facepa[i] != totpart) {
- pa = pars + facepa[i];
+ add_v3_v3(vertco, state.co);
- if (pa->alive == PARS_UNBORN && (emd->flag & eExplodeFlag_Unborn) == 0) continue;
- if (pa->alive == PARS_ALIVE && (emd->flag & eExplodeFlag_Alive) == 0) continue;
- if (pa->alive == PARS_DEAD && (emd->flag & eExplodeFlag_Dead) == 0) continue;
- }
+ mul_m4_v3(imat, vertco);
+ }
+ }
+ BLI_edgehashIterator_free(ehi);
+
+ /*map new vertices to faces*/
+ for (i = 0, u = 0; i < totface; i++) {
+ MFace source;
+ int orig_v4;
+
+ if (facepa[i] != totpart) {
+ pa = pars + facepa[i];
+
+ if (pa->alive == PARS_UNBORN && (emd->flag & eExplodeFlag_Unborn) == 0)
+ continue;
+ if (pa->alive == PARS_ALIVE && (emd->flag & eExplodeFlag_Alive) == 0)
+ continue;
+ if (pa->alive == PARS_DEAD && (emd->flag & eExplodeFlag_Dead) == 0)
+ continue;
+ }
- source = mesh->mface[i];
- mf = &explode->mface[u];
+ source = mesh->mface[i];
+ mf = &explode->mface[u];
- orig_v4 = source.v4;
+ orig_v4 = source.v4;
- if (facepa[i] != totpart && cfra < pa->time) {
- mindex = totvert + totpart;
- }
- else {
- mindex = totvert + facepa[i];
- }
+ if (facepa[i] != totpart && cfra < pa->time) {
+ mindex = totvert + totpart;
+ }
+ else {
+ mindex = totvert + facepa[i];
+ }
- source.v1 = edgecut_get(vertpahash, source.v1, mindex);
- source.v2 = edgecut_get(vertpahash, source.v2, mindex);
- source.v3 = edgecut_get(vertpahash, source.v3, mindex);
- if (source.v4) {
- source.v4 = edgecut_get(vertpahash, source.v4, mindex);
- }
+ source.v1 = edgecut_get(vertpahash, source.v1, mindex);
+ source.v2 = edgecut_get(vertpahash, source.v2, mindex);
+ source.v3 = edgecut_get(vertpahash, source.v3, mindex);
+ if (source.v4) {
+ source.v4 = edgecut_get(vertpahash, source.v4, mindex);
+ }
- CustomData_copy_data(&mesh->fdata, &explode->fdata, i, u, 1);
+ CustomData_copy_data(&mesh->fdata, &explode->fdata, i, u, 1);
- *mf = source;
+ *mf = source;
- /* override uv channel for particle age */
- if (mtface) {
- float age = (cfra - pa->time) / pa->lifetime;
- /* Clamp to this range to avoid flipping to the other side of the coordinates. */
- CLAMP(age, 0.001f, 0.999f);
+ /* override uv channel for particle age */
+ if (mtface) {
+ float age = (cfra - pa->time) / pa->lifetime;
+ /* Clamp to this range to avoid flipping to the other side of the coordinates. */
+ CLAMP(age, 0.001f, 0.999f);
- mtf = mtface + u;
+ mtf = mtface + u;
- mtf->uv[0][0] = mtf->uv[1][0] = mtf->uv[2][0] = mtf->uv[3][0] = age;
- mtf->uv[0][1] = mtf->uv[1][1] = mtf->uv[2][1] = mtf->uv[3][1] = 0.5f;
- }
+ mtf->uv[0][0] = mtf->uv[1][0] = mtf->uv[2][0] = mtf->uv[3][0] = age;
+ mtf->uv[0][1] = mtf->uv[1][1] = mtf->uv[2][1] = mtf->uv[3][1] = 0.5f;
+ }
- test_index_face(mf, &explode->fdata, u, (orig_v4 ? 4 : 3));
- u++;
- }
+ test_index_face(mf, &explode->fdata, u, (orig_v4 ? 4 : 3));
+ u++;
+ }
- /* cleanup */
- BLI_edgehash_free(vertpahash, NULL);
+ /* cleanup */
+ BLI_edgehash_free(vertpahash, NULL);
- /* finalization */
- BKE_mesh_calc_edges_tessface(explode);
- BKE_mesh_convert_mfaces_to_mpolys(explode);
- explode->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ /* finalization */
+ BKE_mesh_calc_edges_tessface(explode);
+ BKE_mesh_convert_mfaces_to_mpolys(explode);
+ explode->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- if (psmd->psys->lattice_deform_data) {
- end_latt_deform(psmd->psys->lattice_deform_data);
- psmd->psys->lattice_deform_data = NULL;
- }
+ if (psmd->psys->lattice_deform_data) {
+ end_latt_deform(psmd->psys->lattice_deform_data);
+ psmd->psys->lattice_deform_data = NULL;
+ }
- return explode;
+ return explode;
}
static ParticleSystemModifierData *findPrecedingParticlesystem(Object *ob, ModifierData *emd)
{
- ModifierData *md;
- ParticleSystemModifierData *psmd = NULL;
-
- for (md = ob->modifiers.first; emd != md; md = md->next) {
- if (md->type == eModifierType_ParticleSystem) {
- psmd = (ParticleSystemModifierData *) md;
- }
- }
- return psmd;
+ ModifierData *md;
+ ParticleSystemModifierData *psmd = NULL;
+
+ for (md = ob->modifiers.first; emd != md; md = md->next) {
+ if (md->type == eModifierType_ParticleSystem) {
+ psmd = (ParticleSystemModifierData *)md;
+ }
+ }
+ return psmd;
}
-static Mesh *applyModifier(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- ExplodeModifierData *emd = (ExplodeModifierData *) md;
- ParticleSystemModifierData *psmd = findPrecedingParticlesystem(ctx->object, md);
-
- if (psmd) {
- ParticleSystem *psys = psmd->psys;
-
- if (psys == NULL || psys->totpart == 0) {
- return mesh;
- }
- if (psys->part == NULL || psys->particles == NULL) {
- return mesh;
- }
- if (psmd->mesh_final == NULL) {
- return mesh;
- }
-
- BKE_mesh_tessface_ensure(mesh); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
-
- /* 1. find faces to be exploded if needed */
- if (emd->facepa == NULL ||
- psmd->flag & eParticleSystemFlag_Pars ||
- emd->flag & eExplodeFlag_CalcFaces ||
- MEM_allocN_len(emd->facepa) / sizeof(int) != mesh->totface)
- {
- if (psmd->flag & eParticleSystemFlag_Pars) {
- psmd->flag &= ~eParticleSystemFlag_Pars;
- }
- if (emd->flag & eExplodeFlag_CalcFaces) {
- emd->flag &= ~eExplodeFlag_CalcFaces;
- }
- createFacepa(emd, psmd, mesh);
- }
- /* 2. create new mesh */
- Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- if (emd->flag & eExplodeFlag_EdgeCut) {
- int *facepa = emd->facepa;
- Mesh *split_m = cutEdges(emd, mesh);
- Mesh *explode = explodeMesh(emd, psmd, ctx, scene, split_m);
-
- MEM_freeN(emd->facepa);
- emd->facepa = facepa;
- BKE_id_free(NULL, split_m);
- return explode;
- }
- else {
- return explodeMesh(emd, psmd, ctx, scene, mesh);
- }
- }
- return mesh;
+ ExplodeModifierData *emd = (ExplodeModifierData *)md;
+ ParticleSystemModifierData *psmd = findPrecedingParticlesystem(ctx->object, md);
+
+ if (psmd) {
+ ParticleSystem *psys = psmd->psys;
+
+ if (psys == NULL || psys->totpart == 0) {
+ return mesh;
+ }
+ if (psys->part == NULL || psys->particles == NULL) {
+ return mesh;
+ }
+ if (psmd->mesh_final == NULL) {
+ return mesh;
+ }
+
+ BKE_mesh_tessface_ensure(mesh); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
+
+ /* 1. find faces to be exploded if needed */
+ if (emd->facepa == NULL || psmd->flag & eParticleSystemFlag_Pars ||
+ emd->flag & eExplodeFlag_CalcFaces ||
+ MEM_allocN_len(emd->facepa) / sizeof(int) != mesh->totface) {
+ if (psmd->flag & eParticleSystemFlag_Pars) {
+ psmd->flag &= ~eParticleSystemFlag_Pars;
+ }
+ if (emd->flag & eExplodeFlag_CalcFaces) {
+ emd->flag &= ~eExplodeFlag_CalcFaces;
+ }
+ createFacepa(emd, psmd, mesh);
+ }
+ /* 2. create new mesh */
+ Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ if (emd->flag & eExplodeFlag_EdgeCut) {
+ int *facepa = emd->facepa;
+ Mesh *split_m = cutEdges(emd, mesh);
+ Mesh *explode = explodeMesh(emd, psmd, ctx, scene, split_m);
+
+ MEM_freeN(emd->facepa);
+ emd->facepa = facepa;
+ BKE_id_free(NULL, split_m);
+ return explode;
+ }
+ else {
+ return explodeMesh(emd, psmd, ctx, scene, mesh);
+ }
+ }
+ return mesh;
}
ModifierTypeInfo modifierType_Explode = {
- /* name */ "Explode",
- /* structName */ "ExplodeModifierData",
- /* structSize */ sizeof(ExplodeModifierData),
- /* type */ eModifierTypeType_Constructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh,
- /* copyData */ copyData,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ freeData,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Explode",
+ /* structName */ "ExplodeModifierData",
+ /* structSize */ sizeof(ExplodeModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh,
+ /* copyData */ copyData,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ freeData,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_fluidsim.c b/source/blender/modifiers/intern/MOD_fluidsim.c
index 4377e04db84..620b21f3e0c 100644
--- a/source/blender/modifiers/intern/MOD_fluidsim.c
+++ b/source/blender/modifiers/intern/MOD_fluidsim.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include "BLI_utildefines.h"
#include "DNA_mesh_types.h"
@@ -42,117 +41,110 @@
/* Fluidsim */
static void initData(ModifierData *md)
{
- FluidsimModifierData *fluidmd = (FluidsimModifierData *) md;
+ FluidsimModifierData *fluidmd = (FluidsimModifierData *)md;
- fluidsim_init(fluidmd);
+ fluidsim_init(fluidmd);
}
static void freeData(ModifierData *md)
{
- FluidsimModifierData *fluidmd = (FluidsimModifierData *) md;
+ FluidsimModifierData *fluidmd = (FluidsimModifierData *)md;
- fluidsim_free(fluidmd);
+ fluidsim_free(fluidmd);
}
static void copyData(const ModifierData *md, ModifierData *target, const int UNUSED(flag))
{
- const FluidsimModifierData *fluidmd = (const FluidsimModifierData *) md;
- FluidsimModifierData *tfluidmd = (FluidsimModifierData *) target;
-
- /* Free any FSS that was allocated in initData() */
- if (tfluidmd->fss) {
- MEM_SAFE_FREE(tfluidmd->fss->meshVelocities);
- MEM_freeN(tfluidmd->fss);
- }
-
- if (fluidmd->fss == NULL) {
- tfluidmd->fss = NULL;
- return;
- }
-
- tfluidmd->fss = MEM_dupallocN(fluidmd->fss);
- if (tfluidmd->fss->meshVelocities != NULL) {
- tfluidmd->fss->meshVelocities = MEM_dupallocN(tfluidmd->fss->meshVelocities);
- }
+ const FluidsimModifierData *fluidmd = (const FluidsimModifierData *)md;
+ FluidsimModifierData *tfluidmd = (FluidsimModifierData *)target;
+
+ /* Free any FSS that was allocated in initData() */
+ if (tfluidmd->fss) {
+ MEM_SAFE_FREE(tfluidmd->fss->meshVelocities);
+ MEM_freeN(tfluidmd->fss);
+ }
+
+ if (fluidmd->fss == NULL) {
+ tfluidmd->fss = NULL;
+ return;
+ }
+
+ tfluidmd->fss = MEM_dupallocN(fluidmd->fss);
+ if (tfluidmd->fss->meshVelocities != NULL) {
+ tfluidmd->fss->meshVelocities = MEM_dupallocN(tfluidmd->fss->meshVelocities);
+ }
}
-
-
-static Mesh *applyModifier(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- FluidsimModifierData *fluidmd = (FluidsimModifierData *) md;
- Mesh *result = NULL;
+ FluidsimModifierData *fluidmd = (FluidsimModifierData *)md;
+ Mesh *result = NULL;
- /* check for alloc failing */
- if (!fluidmd->fss) {
- initData(md);
+ /* check for alloc failing */
+ if (!fluidmd->fss) {
+ initData(md);
- if (!fluidmd->fss) {
- return mesh;
- }
- }
+ if (!fluidmd->fss) {
+ return mesh;
+ }
+ }
- result = fluidsimModifier_do(fluidmd, ctx, mesh);
+ result = fluidsimModifier_do(fluidmd, ctx, mesh);
- return result ? result : mesh;
+ return result ? result : mesh;
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- FluidsimModifierData *fluidmd = (FluidsimModifierData *) md;
- if (fluidmd && fluidmd->fss) {
- if (fluidmd->fss->type == OB_FLUIDSIM_DOMAIN) {
- FOREACH_SCENE_OBJECT_BEGIN(ctx->scene, ob1)
- {
- if (ob1 != ctx->object) {
- FluidsimModifierData *fluidmdtmp =
- (FluidsimModifierData *)modifiers_findByType(ob1, eModifierType_Fluidsim);
-
- /* Only put dependencies from NON-DOMAIN fluids in here. */
- if (fluidmdtmp && fluidmdtmp->fss && (fluidmdtmp->fss->type != OB_FLUIDSIM_DOMAIN)) {
- DEG_add_object_relation(ctx->node, ob1, DEG_OB_COMP_TRANSFORM, "Fluidsim Object");
- }
- }
- }
- FOREACH_SCENE_OBJECT_END;
- }
- }
+ FluidsimModifierData *fluidmd = (FluidsimModifierData *)md;
+ if (fluidmd && fluidmd->fss) {
+ if (fluidmd->fss->type == OB_FLUIDSIM_DOMAIN) {
+ FOREACH_SCENE_OBJECT_BEGIN (ctx->scene, ob1) {
+ if (ob1 != ctx->object) {
+ FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(
+ ob1, eModifierType_Fluidsim);
+
+ /* Only put dependencies from NON-DOMAIN fluids in here. */
+ if (fluidmdtmp && fluidmdtmp->fss && (fluidmdtmp->fss->type != OB_FLUIDSIM_DOMAIN)) {
+ DEG_add_object_relation(ctx->node, ob1, DEG_OB_COMP_TRANSFORM, "Fluidsim Object");
+ }
+ }
+ }
+ FOREACH_SCENE_OBJECT_END;
+ }
+ }
}
static bool dependsOnTime(ModifierData *UNUSED(md))
{
- return true;
+ return true;
}
-
ModifierTypeInfo modifierType_Fluidsim = {
- /* name */ "Fluidsim",
- /* structName */ "FluidsimModifierData",
- /* structSize */ sizeof(FluidsimModifierData),
- /* type */ eModifierTypeType_Nonconstructive,
-
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_RequiresOriginalData |
- eModifierTypeFlag_Single,
-
- /* copyData */ copyData,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ NULL,
- /* freeData */ freeData,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Fluidsim",
+ /* structName */ "FluidsimModifierData",
+ /* structSize */ sizeof(FluidsimModifierData),
+ /* type */ eModifierTypeType_Nonconstructive,
+
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_RequiresOriginalData |
+ eModifierTypeFlag_Single,
+
+ /* copyData */ copyData,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ freeData,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.c b/source/blender/modifiers/intern/MOD_fluidsim_util.c
index f548eb78abd..3744c527983 100644
--- a/source/blender/modifiers/intern/MOD_fluidsim_util.c
+++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include <stddef.h>
#include <zlib.h>
@@ -56,288 +55,301 @@
// headers for fluidsim bobj meshes
#include "LBM_fluidsim.h"
-
void fluidsim_init(FluidsimModifierData *fluidmd)
{
#ifdef WITH_MOD_FLUID
- if (fluidmd) {
- FluidsimSettings *fss = MEM_callocN(sizeof(FluidsimSettings), "fluidsimsettings");
-
- fluidmd->fss = fss;
-
- if (!fss)
- return;
-
- fss->fmd = fluidmd;
- fss->type = OB_FLUIDSIM_ENABLE;
- fss->threads = 0;
- fss->show_advancedoptions = 0;
-
- fss->resolutionxyz = 65;
- fss->previewresxyz = 45;
- fss->realsize = 0.5;
- fss->guiDisplayMode = OB_FSDOM_PREVIEW;
- fss->renderDisplayMode = OB_FSDOM_FINAL;
-
- fss->viscosityValue = 1.0;
- fss->viscosityExponent = 6;
-
- fss->grav[0] = 0.0;
- fss->grav[1] = 0.0;
- fss->grav[2] = -9.81;
-
- fss->animStart = 0.0;
- fss->animEnd = 4.0;
- fss->animRate = 1.0;
- fss->gstar = 0.005; // used as normgstar
- fss->maxRefine = -1;
- /* maxRefine is set according to resolutionxyz during bake */
-
- /* fluid/inflow settings
- * fss->iniVel --> automatically set to 0 */
-
- modifier_path_init(fss->surfdataPath, sizeof(fss->surfdataPath), OB_FLUIDSIM_SURF_DIR_DEFAULT);
-
- /* first init of bounding box */
- /* no bounding box needed */
-
- /* todo - reuse default init from elbeem! */
- fss->typeFlags = OB_FSBND_PARTSLIP | OB_FSSG_NOOBS;
- fss->domainNovecgen = 0;
- fss->volumeInitType = 1; /* volume */
- fss->partSlipValue = 0.2;
-
- fss->generateTracers = 0;
- fss->generateParticles = 0.0;
- fss->surfaceSmoothing = 1.0;
- fss->surfaceSubdivs = 0.0;
- fss->particleInfSize = 0.0;
- fss->particleInfAlpha = 0.0;
-
- /* init fluid control settings */
- fss->attractforceStrength = 0.2;
- fss->attractforceRadius = 0.75;
- fss->velocityforceStrength = 0.2;
- fss->velocityforceRadius = 0.75;
- fss->cpsTimeStart = fss->animStart;
- fss->cpsTimeEnd = fss->animEnd;
- fss->cpsQuality = 10.0; // 1.0 / 10.0 => means 0.1 width
-
- /*
- * BAD TODO: this is done in buttons_object.c in the moment
- * Mesh *mesh = ob->data;
- * // calculate bounding box
- * fluid_get_bb(mesh->mvert, mesh->totvert, ob->obmat, fss->bbStart, fss->bbSize);
- */
-
- fss->meshVelocities = NULL;
-
- fss->lastgoodframe = -1;
-
- fss->flag |= OB_FLUIDSIM_ACTIVE;
-
- }
+ if (fluidmd) {
+ FluidsimSettings *fss = MEM_callocN(sizeof(FluidsimSettings), "fluidsimsettings");
+
+ fluidmd->fss = fss;
+
+ if (!fss)
+ return;
+
+ fss->fmd = fluidmd;
+ fss->type = OB_FLUIDSIM_ENABLE;
+ fss->threads = 0;
+ fss->show_advancedoptions = 0;
+
+ fss->resolutionxyz = 65;
+ fss->previewresxyz = 45;
+ fss->realsize = 0.5;
+ fss->guiDisplayMode = OB_FSDOM_PREVIEW;
+ fss->renderDisplayMode = OB_FSDOM_FINAL;
+
+ fss->viscosityValue = 1.0;
+ fss->viscosityExponent = 6;
+
+ fss->grav[0] = 0.0;
+ fss->grav[1] = 0.0;
+ fss->grav[2] = -9.81;
+
+ fss->animStart = 0.0;
+ fss->animEnd = 4.0;
+ fss->animRate = 1.0;
+ fss->gstar = 0.005; // used as normgstar
+ fss->maxRefine = -1;
+ /* maxRefine is set according to resolutionxyz during bake */
+
+ /* fluid/inflow settings
+ * fss->iniVel --> automatically set to 0 */
+
+ modifier_path_init(fss->surfdataPath, sizeof(fss->surfdataPath), OB_FLUIDSIM_SURF_DIR_DEFAULT);
+
+ /* first init of bounding box */
+ /* no bounding box needed */
+
+ /* todo - reuse default init from elbeem! */
+ fss->typeFlags = OB_FSBND_PARTSLIP | OB_FSSG_NOOBS;
+ fss->domainNovecgen = 0;
+ fss->volumeInitType = 1; /* volume */
+ fss->partSlipValue = 0.2;
+
+ fss->generateTracers = 0;
+ fss->generateParticles = 0.0;
+ fss->surfaceSmoothing = 1.0;
+ fss->surfaceSubdivs = 0.0;
+ fss->particleInfSize = 0.0;
+ fss->particleInfAlpha = 0.0;
+
+ /* init fluid control settings */
+ fss->attractforceStrength = 0.2;
+ fss->attractforceRadius = 0.75;
+ fss->velocityforceStrength = 0.2;
+ fss->velocityforceRadius = 0.75;
+ fss->cpsTimeStart = fss->animStart;
+ fss->cpsTimeEnd = fss->animEnd;
+ fss->cpsQuality = 10.0; // 1.0 / 10.0 => means 0.1 width
+
+ /*
+ * BAD TODO: this is done in buttons_object.c in the moment
+ * Mesh *mesh = ob->data;
+ * // calculate bounding box
+ * fluid_get_bb(mesh->mvert, mesh->totvert, ob->obmat, fss->bbStart, fss->bbSize);
+ */
+
+ fss->meshVelocities = NULL;
+
+ fss->lastgoodframe = -1;
+
+ fss->flag |= OB_FLUIDSIM_ACTIVE;
+ }
#else
- (void)fluidmd; /* unused */
+ (void)fluidmd; /* unused */
#endif
- return;
+ return;
}
void fluidsim_free(FluidsimModifierData *fluidmd)
{
- if (fluidmd && fluidmd->fss) {
- if (fluidmd->fss->meshVelocities) {
- MEM_freeN(fluidmd->fss->meshVelocities);
- }
- MEM_SAFE_FREE(fluidmd->fss);
- }
-
- return;
+ if (fluidmd && fluidmd->fss) {
+ if (fluidmd->fss->meshVelocities) {
+ MEM_freeN(fluidmd->fss->meshVelocities);
+ }
+ MEM_SAFE_FREE(fluidmd->fss);
+ }
+
+ return;
}
#ifdef WITH_MOD_FLUID
/* read .bobj.gz file into a fluidsimMesh struct */
static Mesh *fluidsim_read_obj(const char *filename, const MPoly *mp_example)
{
- int wri = 0, i;
- int gotBytes;
- gzFile gzf;
- int numverts = 0, numfaces = 0;
- Mesh *mesh = NULL;
- MPoly *mp;
- MLoop *ml;
- MVert *mv;
- short *normals, *no_s;
- float no[3];
-
- const short mp_mat_nr = mp_example->mat_nr;
- const char mp_flag = mp_example->flag;
-
- /* ------------------------------------------------
- * get numverts + numfaces first
- * ------------------------------------------------ */
- gzf = BLI_gzopen(filename, "rb");
- if (!gzf) {
- return NULL;
- }
-
- /* read numverts */
- gotBytes = gzread(gzf, &wri, sizeof(wri));
- numverts = wri;
-
- /* skip verts */
- gotBytes = gzseek(gzf, numverts * 3 * sizeof(float), SEEK_CUR) != -1;
-
-
- /* read number of normals */
- if (gotBytes)
- gotBytes = gzread(gzf, &wri, sizeof(wri));
-
- /* skip normals */
- gotBytes = gzseek(gzf, numverts * 3 * sizeof(float), SEEK_CUR) != -1;
-
- /* get no. of triangles */
- if (gotBytes)
- gotBytes = gzread(gzf, &wri, sizeof(wri));
- numfaces = wri;
-
- gzclose(gzf);
- /* ------------------------------------------------ */
-
- if (!numfaces || !numverts || !gotBytes)
- return NULL;
-
- gzf = BLI_gzopen(filename, "rb");
- if (!gzf) {
- return NULL;
- }
-
- mesh = BKE_mesh_new_nomain(numverts, 0, 0, numfaces * 3, numfaces);
-
- if (!mesh) {
- gzclose(gzf);
- return NULL;
- }
-
- /* read numverts */
- gotBytes = gzread(gzf, &wri, sizeof(wri));
-
- /* read vertex position from file */
- mv = mesh->mvert;
-
- for (i = 0; i < numverts; i++, mv++)
- gotBytes = gzread(gzf, mv->co, sizeof(float) * 3);
-
- /* should be the same as numverts */
- gotBytes = gzread(gzf, &wri, sizeof(wri));
- if (wri != numverts) {
- if (mesh)
- BKE_id_free(NULL, mesh);
- gzclose(gzf);
- return NULL;
- }
-
- normals = MEM_calloc_arrayN(numverts, 3 * sizeof(short), "fluid_tmp_normals");
- if (!normals) {
- if (mesh)
- BKE_id_free(NULL, mesh);
- gzclose(gzf);
- return NULL;
- }
-
- /* read normals from file (but don't save them yet) */
- for (i = numverts, no_s = normals; i > 0; i--, no_s += 3) {
- gotBytes = gzread(gzf, no, sizeof(float) * 3);
- normal_float_to_short_v3(no_s, no);
- }
-
- /* read no. of triangles */
- gotBytes = gzread(gzf, &wri, sizeof(wri));
-
- if (wri != numfaces) {
- printf("Fluidsim: error in reading data from file.\n");
- if (mesh)
- BKE_id_free(NULL, mesh);
- gzclose(gzf);
- MEM_freeN(normals);
- return NULL;
- }
-
- /* read triangles from file */
- mp = mesh->mpoly;
- ml = mesh->mloop;
- for (i = 0; i < numfaces; i++, mp++, ml += 3) {
- int face[3];
-
- gotBytes = gzread(gzf, face, sizeof(int) * 3);
-
- /* initialize from existing face */
- mp->mat_nr = mp_mat_nr;
- mp->flag = mp_flag;
-
- mp->loopstart = i * 3;
- mp->totloop = 3;
-
- ml[0].v = face[0];
- ml[1].v = face[1];
- ml[2].v = face[2];
-
- }
-
- gzclose(gzf);
-
- BKE_mesh_calc_edges(mesh, false, false);
- BKE_mesh_apply_vert_normals(mesh, (short (*)[3])normals);
- MEM_freeN(normals);
-
- // CDDM_calc_normals(result);
- return mesh;
+ int wri = 0, i;
+ int gotBytes;
+ gzFile gzf;
+ int numverts = 0, numfaces = 0;
+ Mesh *mesh = NULL;
+ MPoly *mp;
+ MLoop *ml;
+ MVert *mv;
+ short *normals, *no_s;
+ float no[3];
+
+ const short mp_mat_nr = mp_example->mat_nr;
+ const char mp_flag = mp_example->flag;
+
+ /* ------------------------------------------------
+ * get numverts + numfaces first
+ * ------------------------------------------------ */
+ gzf = BLI_gzopen(filename, "rb");
+ if (!gzf) {
+ return NULL;
+ }
+
+ /* read numverts */
+ gotBytes = gzread(gzf, &wri, sizeof(wri));
+ numverts = wri;
+
+ /* skip verts */
+ gotBytes = gzseek(gzf, numverts * 3 * sizeof(float), SEEK_CUR) != -1;
+
+ /* read number of normals */
+ if (gotBytes)
+ gotBytes = gzread(gzf, &wri, sizeof(wri));
+
+ /* skip normals */
+ gotBytes = gzseek(gzf, numverts * 3 * sizeof(float), SEEK_CUR) != -1;
+
+ /* get no. of triangles */
+ if (gotBytes)
+ gotBytes = gzread(gzf, &wri, sizeof(wri));
+ numfaces = wri;
+
+ gzclose(gzf);
+ /* ------------------------------------------------ */
+
+ if (!numfaces || !numverts || !gotBytes)
+ return NULL;
+
+ gzf = BLI_gzopen(filename, "rb");
+ if (!gzf) {
+ return NULL;
+ }
+
+ mesh = BKE_mesh_new_nomain(numverts, 0, 0, numfaces * 3, numfaces);
+
+ if (!mesh) {
+ gzclose(gzf);
+ return NULL;
+ }
+
+ /* read numverts */
+ gotBytes = gzread(gzf, &wri, sizeof(wri));
+
+ /* read vertex position from file */
+ mv = mesh->mvert;
+
+ for (i = 0; i < numverts; i++, mv++)
+ gotBytes = gzread(gzf, mv->co, sizeof(float) * 3);
+
+ /* should be the same as numverts */
+ gotBytes = gzread(gzf, &wri, sizeof(wri));
+ if (wri != numverts) {
+ if (mesh)
+ BKE_id_free(NULL, mesh);
+ gzclose(gzf);
+ return NULL;
+ }
+
+ normals = MEM_calloc_arrayN(numverts, 3 * sizeof(short), "fluid_tmp_normals");
+ if (!normals) {
+ if (mesh)
+ BKE_id_free(NULL, mesh);
+ gzclose(gzf);
+ return NULL;
+ }
+
+ /* read normals from file (but don't save them yet) */
+ for (i = numverts, no_s = normals; i > 0; i--, no_s += 3) {
+ gotBytes = gzread(gzf, no, sizeof(float) * 3);
+ normal_float_to_short_v3(no_s, no);
+ }
+
+ /* read no. of triangles */
+ gotBytes = gzread(gzf, &wri, sizeof(wri));
+
+ if (wri != numfaces) {
+ printf("Fluidsim: error in reading data from file.\n");
+ if (mesh)
+ BKE_id_free(NULL, mesh);
+ gzclose(gzf);
+ MEM_freeN(normals);
+ return NULL;
+ }
+
+ /* read triangles from file */
+ mp = mesh->mpoly;
+ ml = mesh->mloop;
+ for (i = 0; i < numfaces; i++, mp++, ml += 3) {
+ int face[3];
+
+ gotBytes = gzread(gzf, face, sizeof(int) * 3);
+
+ /* initialize from existing face */
+ mp->mat_nr = mp_mat_nr;
+ mp->flag = mp_flag;
+
+ mp->loopstart = i * 3;
+ mp->totloop = 3;
+
+ ml[0].v = face[0];
+ ml[1].v = face[1];
+ ml[2].v = face[2];
+ }
+
+ gzclose(gzf);
+
+ BKE_mesh_calc_edges(mesh, false, false);
+ BKE_mesh_apply_vert_normals(mesh, (short(*)[3])normals);
+ MEM_freeN(normals);
+
+ // CDDM_calc_normals(result);
+ return mesh;
}
-
-void fluid_get_bb(
- MVert *mvert, int totvert, float obmat[4][4],
- /*RET*/ float start[3], /*RET*/ float size[3])
+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;
- float bbex = 1.0, bbey = 1.0, bbez = 1.0;
- int i;
- float vec[3];
-
- if (totvert == 0) {
- zero_v3(start);
- zero_v3(size);
- return;
- }
-
- copy_v3_v3(vec, mvert[0].co);
- mul_m4_v3(obmat, vec);
- bbsx = vec[0]; bbsy = vec[1]; bbsz = vec[2];
- bbex = vec[0]; bbey = vec[1]; bbez = vec[2];
-
- for (i = 1; i < totvert; i++) {
- copy_v3_v3(vec, mvert[i].co);
- mul_m4_v3(obmat, vec);
-
- if (vec[0] < bbsx) { bbsx = vec[0]; }
- if (vec[1] < bbsy) { bbsy = vec[1]; }
- if (vec[2] < bbsz) { bbsz = vec[2]; }
- if (vec[0] > bbex) { bbex = vec[0]; }
- if (vec[1] > bbey) { bbey = vec[1]; }
- if (vec[2] > bbez) { bbez = vec[2]; }
- }
-
- /* return values... */
- if (start) {
- start[0] = bbsx;
- start[1] = bbsy;
- start[2] = bbsz;
- }
- if (size) {
- size[0] = bbex - bbsx;
- size[1] = bbey - bbsy;
- size[2] = bbez - bbsz;
- }
+ float bbsx = 0.0, bbsy = 0.0, bbsz = 0.0;
+ float bbex = 1.0, bbey = 1.0, bbez = 1.0;
+ int i;
+ float vec[3];
+
+ if (totvert == 0) {
+ zero_v3(start);
+ zero_v3(size);
+ return;
+ }
+
+ copy_v3_v3(vec, mvert[0].co);
+ mul_m4_v3(obmat, vec);
+ bbsx = vec[0];
+ bbsy = vec[1];
+ bbsz = vec[2];
+ bbex = vec[0];
+ bbey = vec[1];
+ bbez = vec[2];
+
+ for (i = 1; i < totvert; i++) {
+ copy_v3_v3(vec, mvert[i].co);
+ mul_m4_v3(obmat, vec);
+
+ if (vec[0] < bbsx) {
+ bbsx = vec[0];
+ }
+ if (vec[1] < bbsy) {
+ bbsy = vec[1];
+ }
+ if (vec[2] < bbsz) {
+ bbsz = vec[2];
+ }
+ if (vec[0] > bbex) {
+ bbex = vec[0];
+ }
+ if (vec[1] > bbey) {
+ bbey = vec[1];
+ }
+ if (vec[2] > bbez) {
+ bbez = vec[2];
+ }
+ }
+
+ /* return values... */
+ if (start) {
+ start[0] = bbsx;
+ start[1] = bbsy;
+ start[2] = bbsz;
+ }
+ if (size) {
+ size[0] = bbex - bbsx;
+ size[1] = bbey - bbsy;
+ size[2] = bbez - bbsz;
+ }
}
//-------------------------------------------------------------------------------
@@ -346,206 +358,209 @@ void fluid_get_bb(
void fluid_estimate_memory(Object *ob, FluidsimSettings *fss, char *value)
{
- Mesh *mesh;
+ Mesh *mesh;
- value[0] = '\0';
+ value[0] = '\0';
- if (ob->type == OB_MESH) {
- /* use mesh bounding box and object scaling */
- mesh = ob->data;
+ if (ob->type == OB_MESH) {
+ /* use mesh bounding box and object scaling */
+ mesh = ob->data;
- fluid_get_bb(mesh->mvert, mesh->totvert, ob->obmat, fss->bbStart, fss->bbSize);
- elbeemEstimateMemreq(fss->resolutionxyz, fss->bbSize[0], fss->bbSize[1], fss->bbSize[2], fss->maxRefine, value);
- }
+ fluid_get_bb(mesh->mvert, mesh->totvert, ob->obmat, fss->bbStart, fss->bbSize);
+ elbeemEstimateMemreq(
+ fss->resolutionxyz, fss->bbSize[0], fss->bbSize[1], fss->bbSize[2], fss->maxRefine, value);
+ }
}
-
/* read zipped fluidsim velocities into the co's of the fluidsimsettings normals struct */
static void fluidsim_read_vel_cache(FluidsimModifierData *fluidmd, Mesh *mesh, char *filename)
{
- int wri, i, j;
- float wrf;
- gzFile gzf;
- FluidsimSettings *fss = fluidmd->fss;
- int len = strlen(filename);
- int totvert = mesh->totvert;
- FluidVertexVelocity *velarray = NULL;
-
- /* mesh and vverts have to be valid from loading... */
-
- if (fss->meshVelocities)
- MEM_freeN(fss->meshVelocities);
-
- if (len < 7) {
- return;
- }
-
- if (fss->domainNovecgen > 0) return;
-
- fss->meshVelocities = MEM_calloc_arrayN(mesh->totvert, sizeof(FluidVertexVelocity), "Fluidsim_velocities");
- fss->totvert = totvert;
-
- velarray = fss->meshVelocities;
-
- /* .bobj.gz, correct filename
- * 87654321 */
- filename[len - 6] = 'v';
- filename[len - 5] = 'e';
- filename[len - 4] = 'l';
-
- gzf = BLI_gzopen(filename, "rb");
- if (!gzf) {
- MEM_freeN(fss->meshVelocities);
- fss->meshVelocities = NULL;
- return;
- }
-
- gzread(gzf, &wri, sizeof(wri));
- if (wri != totvert) {
- MEM_freeN(fss->meshVelocities);
- fss->meshVelocities = NULL;
- return;
- }
-
- for (i = 0; i < totvert; i++) {
- for (j = 0; j < 3; j++) {
- gzread(gzf, &wrf, sizeof(wrf));
- velarray[i].vel[j] = wrf;
- }
- }
-
- gzclose(gzf);
+ int wri, i, j;
+ float wrf;
+ gzFile gzf;
+ FluidsimSettings *fss = fluidmd->fss;
+ int len = strlen(filename);
+ int totvert = mesh->totvert;
+ FluidVertexVelocity *velarray = NULL;
+
+ /* mesh and vverts have to be valid from loading... */
+
+ if (fss->meshVelocities)
+ MEM_freeN(fss->meshVelocities);
+
+ if (len < 7) {
+ return;
+ }
+
+ if (fss->domainNovecgen > 0)
+ return;
+
+ fss->meshVelocities = MEM_calloc_arrayN(
+ mesh->totvert, sizeof(FluidVertexVelocity), "Fluidsim_velocities");
+ fss->totvert = totvert;
+
+ velarray = fss->meshVelocities;
+
+ /* .bobj.gz, correct filename
+ * 87654321 */
+ filename[len - 6] = 'v';
+ filename[len - 5] = 'e';
+ filename[len - 4] = 'l';
+
+ gzf = BLI_gzopen(filename, "rb");
+ if (!gzf) {
+ MEM_freeN(fss->meshVelocities);
+ fss->meshVelocities = NULL;
+ return;
+ }
+
+ gzread(gzf, &wri, sizeof(wri));
+ if (wri != totvert) {
+ MEM_freeN(fss->meshVelocities);
+ fss->meshVelocities = NULL;
+ return;
+ }
+
+ for (i = 0; i < totvert; i++) {
+ for (j = 0; j < 3; j++) {
+ gzread(gzf, &wrf, sizeof(wrf));
+ velarray[i].vel[j] = wrf;
+ }
+ }
+
+ gzclose(gzf);
}
static Mesh *fluidsim_read_cache(
- Object *ob, Mesh *orgmesh,
- FluidsimModifierData *fluidmd, int framenr, int useRenderParams)
+ Object *ob, Mesh *orgmesh, FluidsimModifierData *fluidmd, int framenr, int useRenderParams)
{
- int curFrame = framenr /* - 1 */ /*scene->r.sfra*/; /* start with 0 at start frame */
- /* why start with 0 as start frame?? Animations + time are frozen for frame 0 anyway. (See physics_fluid.c for that. - DG */
- /* If we start with frame 0, we need to remap all animation channels, too, because they will all be 1 frame late if using frame-1! - DG */
-
- char targetFile[FILE_MAX];
- FluidsimSettings *fss = fluidmd->fss;
- Mesh *newmesh = NULL;
- MPoly *mpoly;
- MPoly mp_example = {0};
-
- const int displaymode = useRenderParams ? fss->renderDisplayMode : fss->guiDisplayMode;
-
- switch (displaymode) {
- case OB_FSDOM_GEOM:
- /* just display original object */
- return NULL;
- case OB_FSDOM_PREVIEW:
- /* use preview mesh */
- BLI_join_dirfile(targetFile, sizeof(targetFile), fss->surfdataPath, OB_FLUIDSIM_SURF_PREVIEW_OBJ_FNAME);
- break;
- case OB_FSDOM_FINAL:
- /* use final mesh */
- BLI_join_dirfile(targetFile, sizeof(targetFile), fss->surfdataPath, OB_FLUIDSIM_SURF_FINAL_OBJ_FNAME);
- break;
- default:
- BLI_assert(!"Wrong fluidsim display type");
- return NULL;
- }
-
- /* offset baked frame */
- curFrame += fss->frameOffset;
-
- BLI_path_abs(targetFile, modifier_path_relbase_from_global(ob));
- BLI_path_frame(targetFile, curFrame, 0); // fixed #frame-no
-
- /* assign material + flags to new mesh.
- * if there's no faces in original mesh, keep materials and flags unchanged */
- mpoly = orgmesh->mpoly;
- if (mpoly) {
- mp_example = *mpoly;
- }
- /* else leave NULL'd */
-
- newmesh = fluidsim_read_obj(targetFile, &mp_example);
-
- if (!newmesh) {
- /* switch, abort background rendering when fluidsim mesh is missing */
- const char *strEnvName2 = "BLENDER_ELBEEMBOBJABORT"; // from blendercall.cpp
-
- if (G.background == 1) {
- if (BLI_getenv(strEnvName2)) {
- int elevel = atoi(BLI_getenv(strEnvName2));
- if (elevel > 0) {
- printf("Env. var %s set, fluid sim mesh '%s' not found, aborting render...\n",
- strEnvName2, targetFile);
- exit(1);
- }
- }
- }
-
- /* display org. object upon failure which is in new mesh */
- return NULL;
- }
-
- /* load vertex velocities, if they exist...
- * TODO? use generate flag as loading flag as well?
- * warning, needs original .bobj.gz mesh loading filename */
- if (displaymode == OB_FSDOM_FINAL) {
- fluidsim_read_vel_cache(fluidmd, newmesh, targetFile);
- }
- else {
- if (fss->meshVelocities)
- MEM_freeN(fss->meshVelocities);
-
- fss->meshVelocities = NULL;
- }
-
- return newmesh;
+ int curFrame = framenr /* - 1 */ /*scene->r.sfra*/; /* start with 0 at start frame */
+ /* why start with 0 as start frame?? Animations + time are frozen for frame 0 anyway. (See physics_fluid.c for that. - DG */
+ /* If we start with frame 0, we need to remap all animation channels, too, because they will all be 1 frame late if using frame-1! - DG */
+
+ char targetFile[FILE_MAX];
+ FluidsimSettings *fss = fluidmd->fss;
+ Mesh *newmesh = NULL;
+ MPoly *mpoly;
+ MPoly mp_example = {0};
+
+ const int displaymode = useRenderParams ? fss->renderDisplayMode : fss->guiDisplayMode;
+
+ switch (displaymode) {
+ case OB_FSDOM_GEOM:
+ /* just display original object */
+ return NULL;
+ case OB_FSDOM_PREVIEW:
+ /* use preview mesh */
+ BLI_join_dirfile(
+ targetFile, sizeof(targetFile), fss->surfdataPath, OB_FLUIDSIM_SURF_PREVIEW_OBJ_FNAME);
+ break;
+ case OB_FSDOM_FINAL:
+ /* use final mesh */
+ BLI_join_dirfile(
+ targetFile, sizeof(targetFile), fss->surfdataPath, OB_FLUIDSIM_SURF_FINAL_OBJ_FNAME);
+ break;
+ default:
+ BLI_assert(!"Wrong fluidsim display type");
+ return NULL;
+ }
+
+ /* offset baked frame */
+ curFrame += fss->frameOffset;
+
+ BLI_path_abs(targetFile, modifier_path_relbase_from_global(ob));
+ BLI_path_frame(targetFile, curFrame, 0); // fixed #frame-no
+
+ /* assign material + flags to new mesh.
+ * if there's no faces in original mesh, keep materials and flags unchanged */
+ mpoly = orgmesh->mpoly;
+ if (mpoly) {
+ mp_example = *mpoly;
+ }
+ /* else leave NULL'd */
+
+ newmesh = fluidsim_read_obj(targetFile, &mp_example);
+
+ if (!newmesh) {
+ /* switch, abort background rendering when fluidsim mesh is missing */
+ const char *strEnvName2 = "BLENDER_ELBEEMBOBJABORT"; // from blendercall.cpp
+
+ if (G.background == 1) {
+ if (BLI_getenv(strEnvName2)) {
+ int elevel = atoi(BLI_getenv(strEnvName2));
+ if (elevel > 0) {
+ printf("Env. var %s set, fluid sim mesh '%s' not found, aborting render...\n",
+ strEnvName2,
+ targetFile);
+ exit(1);
+ }
+ }
+ }
+
+ /* display org. object upon failure which is in new mesh */
+ return NULL;
+ }
+
+ /* load vertex velocities, if they exist...
+ * TODO? use generate flag as loading flag as well?
+ * warning, needs original .bobj.gz mesh loading filename */
+ if (displaymode == OB_FSDOM_FINAL) {
+ fluidsim_read_vel_cache(fluidmd, newmesh, targetFile);
+ }
+ else {
+ if (fss->meshVelocities)
+ MEM_freeN(fss->meshVelocities);
+
+ fss->meshVelocities = NULL;
+ }
+
+ return newmesh;
}
-#endif // WITH_MOD_FLUID
+#endif // WITH_MOD_FLUID
-Mesh *fluidsimModifier_do(
- FluidsimModifierData *fluidmd,
- const ModifierEvalContext *ctx,
- Mesh *mesh)
+Mesh *fluidsimModifier_do(FluidsimModifierData *fluidmd,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh)
{
#ifdef WITH_MOD_FLUID
- Object *ob = ctx->object;
- Depsgraph *depsgraph = ctx->depsgraph;
- const bool useRenderParams = (ctx->flag & MOD_APPLY_RENDER) != 0;
-// const bool isFinalCalc = (ctx->flag & MOD_APPLY_USECACHE) != 0;
- Mesh *result = NULL;
- int framenr;
- FluidsimSettings *fss = NULL;
+ Object *ob = ctx->object;
+ Depsgraph *depsgraph = ctx->depsgraph;
+ const bool useRenderParams = (ctx->flag & MOD_APPLY_RENDER) != 0;
+ // const bool isFinalCalc = (ctx->flag & MOD_APPLY_USECACHE) != 0;
+ Mesh *result = NULL;
+ int framenr;
+ FluidsimSettings *fss = NULL;
- framenr = (int)DEG_get_ctime(depsgraph);
+ framenr = (int)DEG_get_ctime(depsgraph);
- /* only handle fluidsim domains */
- if (fluidmd && fluidmd->fss && (fluidmd->fss->type != OB_FLUIDSIM_DOMAIN))
- return mesh;
+ /* only handle fluidsim domains */
+ if (fluidmd && fluidmd->fss && (fluidmd->fss->type != OB_FLUIDSIM_DOMAIN))
+ return mesh;
- /* sanity check */
- if (!fluidmd || !fluidmd->fss)
- return mesh;
+ /* sanity check */
+ if (!fluidmd || !fluidmd->fss)
+ return mesh;
- fss = fluidmd->fss;
+ fss = fluidmd->fss;
- /* timescale not supported yet
- * clmd->sim_parms->timescale = timescale; */
+ /* timescale not supported yet
+ * clmd->sim_parms->timescale = timescale; */
- /* support reversing of baked fluid frames here */
- if ((fss->flag & OB_FLUIDSIM_REVERSE) && (fss->lastgoodframe >= 0)) {
- framenr = fss->lastgoodframe - framenr + 1;
- CLAMP(framenr, 1, fss->lastgoodframe);
- }
+ /* support reversing of baked fluid frames here */
+ if ((fss->flag & OB_FLUIDSIM_REVERSE) && (fss->lastgoodframe >= 0)) {
+ framenr = fss->lastgoodframe - framenr + 1;
+ CLAMP(framenr, 1, fss->lastgoodframe);
+ }
- /* try to read from cache */
- /* if the frame is there, fine, otherwise don't do anything */
- if ((result = fluidsim_read_cache(ob, mesh, fluidmd, framenr, useRenderParams)))
- return result;
+ /* try to read from cache */
+ /* if the frame is there, fine, otherwise don't do anything */
+ if ((result = fluidsim_read_cache(ob, mesh, fluidmd, framenr, useRenderParams)))
+ return result;
- return mesh;
+ return mesh;
#else
- /* unused */
- UNUSED_VARS(fluidmd, ctx, mesh);
- return NULL;
+ /* unused */
+ UNUSED_VARS(fluidmd, ctx, mesh);
+ return NULL;
#endif
}
diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.h b/source/blender/modifiers/intern/MOD_fluidsim_util.h
index 7673ec7f6b0..0d2be3e7074 100644
--- a/source/blender/modifiers/intern/MOD_fluidsim_util.h
+++ b/source/blender/modifiers/intern/MOD_fluidsim_util.h
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#ifndef __MOD_FLUIDSIM_UTIL_H__
#define __MOD_FLUIDSIM_UTIL_H__
@@ -35,9 +34,8 @@ struct Scene;
void fluidsim_init(struct FluidsimModifierData *fluidmd);
void fluidsim_free(struct FluidsimModifierData *fluidmd);
-struct Mesh *fluidsimModifier_do(
- struct FluidsimModifierData *fluidmd,
- const struct ModifierEvalContext *ctx,
- struct Mesh *me);
+struct Mesh *fluidsimModifier_do(struct FluidsimModifierData *fluidmd,
+ const struct ModifierEvalContext *ctx,
+ struct Mesh *me);
#endif
diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c
index 0c15f4caa23..c12fb9c1bd8 100644
--- a/source/blender/modifiers/intern/MOD_hook.c
+++ b/source/blender/modifiers/intern/MOD_hook.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include "BLI_utildefines.h"
#include "BLI_math.h"
@@ -47,360 +46,366 @@
static void initData(ModifierData *md)
{
- HookModifierData *hmd = (HookModifierData *) md;
+ HookModifierData *hmd = (HookModifierData *)md;
- hmd->force = 1.0;
- hmd->curfalloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
- hmd->falloff_type = eHook_Falloff_Smooth;
- hmd->flag = 0;
+ hmd->force = 1.0;
+ hmd->curfalloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
+ hmd->falloff_type = eHook_Falloff_Smooth;
+ hmd->flag = 0;
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
- const HookModifierData *hmd = (const HookModifierData *) md;
- HookModifierData *thmd = (HookModifierData *) target;
+ const HookModifierData *hmd = (const HookModifierData *)md;
+ HookModifierData *thmd = (HookModifierData *)target;
- modifier_copyData_generic(md, target, flag);
+ modifier_copyData_generic(md, target, flag);
- thmd->curfalloff = curvemapping_copy(hmd->curfalloff);
+ thmd->curfalloff = curvemapping_copy(hmd->curfalloff);
- thmd->indexar = MEM_dupallocN(hmd->indexar);
+ thmd->indexar = MEM_dupallocN(hmd->indexar);
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- HookModifierData *hmd = (HookModifierData *)md;
-
- /* ask for vertexgroups if we need them */
- if (hmd->name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
- if (hmd->indexar != NULL) {
- /* TODO check which origindex are actually needed? */
- r_cddata_masks->vmask |= CD_MASK_ORIGINDEX;
- r_cddata_masks->emask |= CD_MASK_ORIGINDEX;
- r_cddata_masks->pmask |= CD_MASK_ORIGINDEX;
- }
+ HookModifierData *hmd = (HookModifierData *)md;
+
+ /* ask for vertexgroups if we need them */
+ if (hmd->name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
+ if (hmd->indexar != NULL) {
+ /* TODO check which origindex are actually needed? */
+ r_cddata_masks->vmask |= CD_MASK_ORIGINDEX;
+ r_cddata_masks->emask |= CD_MASK_ORIGINDEX;
+ r_cddata_masks->pmask |= CD_MASK_ORIGINDEX;
+ }
}
static void freeData(ModifierData *md)
{
- HookModifierData *hmd = (HookModifierData *) md;
+ HookModifierData *hmd = (HookModifierData *)md;
- curvemapping_free(hmd->curfalloff);
+ curvemapping_free(hmd->curfalloff);
- MEM_SAFE_FREE(hmd->indexar);
+ MEM_SAFE_FREE(hmd->indexar);
}
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(useRenderParams))
{
- HookModifierData *hmd = (HookModifierData *) md;
+ HookModifierData *hmd = (HookModifierData *)md;
- return !hmd->object;
+ return !hmd->object;
}
-static void foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- HookModifierData *hmd = (HookModifierData *) md;
+ HookModifierData *hmd = (HookModifierData *)md;
- walk(userData, ob, &hmd->object, IDWALK_CB_NOP);
+ walk(userData, ob, &hmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- HookModifierData *hmd = (HookModifierData *)md;
- if (hmd->object != NULL) {
- if (hmd->subtarget[0]) {
- DEG_add_bone_relation(ctx->node, hmd->object, hmd->subtarget, DEG_OB_COMP_BONE, "Hook Modifier");
- }
- DEG_add_object_relation(ctx->node, hmd->object, DEG_OB_COMP_TRANSFORM, "Hook Modifier");
- }
- /* We need own transformation as well. */
- DEG_add_modifier_to_transform_relation(ctx->node, "Hook Modifier");
+ HookModifierData *hmd = (HookModifierData *)md;
+ if (hmd->object != NULL) {
+ if (hmd->subtarget[0]) {
+ DEG_add_bone_relation(
+ ctx->node, hmd->object, hmd->subtarget, DEG_OB_COMP_BONE, "Hook Modifier");
+ }
+ DEG_add_object_relation(ctx->node, hmd->object, DEG_OB_COMP_TRANSFORM, "Hook Modifier");
+ }
+ /* We need own transformation as well. */
+ DEG_add_modifier_to_transform_relation(ctx->node, "Hook Modifier");
}
struct HookData_cb {
- float (*vertexCos)[3];
+ float (*vertexCos)[3];
- MDeformVert *dvert;
- int defgrp_index;
+ MDeformVert *dvert;
+ int defgrp_index;
- struct CurveMapping *curfalloff;
+ struct CurveMapping *curfalloff;
- char falloff_type;
- float falloff;
- float falloff_sq;
- float fac_orig;
+ char falloff_type;
+ float falloff;
+ float falloff_sq;
+ float fac_orig;
- unsigned int use_falloff : 1;
- unsigned int use_uniform : 1;
+ unsigned int use_falloff : 1;
+ unsigned int use_uniform : 1;
- float cent[3];
+ float cent[3];
- float mat_uniform[3][3];
- float mat[4][4];
+ float mat_uniform[3][3];
+ float mat[4][4];
};
-static float hook_falloff(
- const struct HookData_cb *hd,
- const float len_sq)
+static float hook_falloff(const struct HookData_cb *hd, const float len_sq)
{
- BLI_assert(hd->falloff_sq);
- if (len_sq > hd->falloff_sq) {
- return 0.0f;
- }
- else if (len_sq > 0.0f) {
- float fac;
-
- if (hd->falloff_type == eHook_Falloff_Const) {
- fac = 1.0f;
- goto finally;
- }
- else if (hd->falloff_type == eHook_Falloff_InvSquare) {
- /* avoid sqrt below */
- fac = 1.0f - (len_sq / hd->falloff_sq);
- goto finally;
- }
-
- fac = 1.0f - (sqrtf(len_sq) / hd->falloff);
-
- /* closely match PROP_SMOOTH and similar */
- switch (hd->falloff_type) {
+ BLI_assert(hd->falloff_sq);
+ if (len_sq > hd->falloff_sq) {
+ return 0.0f;
+ }
+ else if (len_sq > 0.0f) {
+ float fac;
+
+ if (hd->falloff_type == eHook_Falloff_Const) {
+ fac = 1.0f;
+ goto finally;
+ }
+ else if (hd->falloff_type == eHook_Falloff_InvSquare) {
+ /* avoid sqrt below */
+ fac = 1.0f - (len_sq / hd->falloff_sq);
+ goto finally;
+ }
+
+ fac = 1.0f - (sqrtf(len_sq) / hd->falloff);
+
+ /* closely match PROP_SMOOTH and similar */
+ switch (hd->falloff_type) {
#if 0
- case eHook_Falloff_None:
- fac = 1.0f;
- break;
+ case eHook_Falloff_None:
+ fac = 1.0f;
+ break;
#endif
- case eHook_Falloff_Curve:
- fac = curvemapping_evaluateF(hd->curfalloff, 0, fac);
- break;
- case eHook_Falloff_Sharp:
- fac = fac * fac;
- break;
- case eHook_Falloff_Smooth:
- fac = 3.0f * fac * fac - 2.0f * fac * fac * fac;
- break;
- case eHook_Falloff_Root:
- fac = sqrtf(fac);
- break;
- case eHook_Falloff_Linear:
- /* pass */
- break;
+ case eHook_Falloff_Curve:
+ fac = curvemapping_evaluateF(hd->curfalloff, 0, fac);
+ break;
+ case eHook_Falloff_Sharp:
+ fac = fac * fac;
+ break;
+ case eHook_Falloff_Smooth:
+ fac = 3.0f * fac * fac - 2.0f * fac * fac * fac;
+ break;
+ case eHook_Falloff_Root:
+ fac = sqrtf(fac);
+ break;
+ case eHook_Falloff_Linear:
+ /* pass */
+ break;
#if 0
- case eHook_Falloff_Const:
- fac = 1.0f;
- break;
+ case eHook_Falloff_Const:
+ fac = 1.0f;
+ break;
#endif
- case eHook_Falloff_Sphere:
- fac = sqrtf(2 * fac - fac * fac);
- break;
+ case eHook_Falloff_Sphere:
+ fac = sqrtf(2 * fac - fac * fac);
+ break;
#if 0
- case eHook_Falloff_InvSquare:
- fac = fac * (2.0f - fac);
- break;
+ case eHook_Falloff_InvSquare:
+ fac = fac * (2.0f - fac);
+ break;
#endif
- }
-
-finally:
- return fac * hd->fac_orig;
- }
- else {
- return hd->fac_orig;
- }
+ }
+
+ finally:
+ return fac * hd->fac_orig;
+ }
+ else {
+ return hd->fac_orig;
+ }
}
static void hook_co_apply(struct HookData_cb *hd, const int j)
{
- float *co = hd->vertexCos[j];
- float fac;
-
- if (hd->use_falloff) {
- float len_sq;
-
- if (hd->use_uniform) {
- float co_uniform[3];
- mul_v3_m3v3(co_uniform, hd->mat_uniform, co);
- len_sq = len_squared_v3v3(hd->cent, co_uniform);
- }
- else {
- len_sq = len_squared_v3v3(hd->cent, co);
- }
-
- fac = hook_falloff(hd, len_sq);
- }
- else {
- fac = hd->fac_orig;
- }
-
- if (fac) {
- if (hd->dvert) {
- fac *= defvert_find_weight(&hd->dvert[j], hd->defgrp_index);
- }
-
- if (fac) {
- float co_tmp[3];
- mul_v3_m4v3(co_tmp, hd->mat, co);
- interp_v3_v3v3(co, co, co_tmp, fac);
- }
- }
+ float *co = hd->vertexCos[j];
+ float fac;
+
+ if (hd->use_falloff) {
+ float len_sq;
+
+ if (hd->use_uniform) {
+ float co_uniform[3];
+ mul_v3_m3v3(co_uniform, hd->mat_uniform, co);
+ len_sq = len_squared_v3v3(hd->cent, co_uniform);
+ }
+ else {
+ len_sq = len_squared_v3v3(hd->cent, co);
+ }
+
+ fac = hook_falloff(hd, len_sq);
+ }
+ else {
+ fac = hd->fac_orig;
+ }
+
+ if (fac) {
+ if (hd->dvert) {
+ fac *= defvert_find_weight(&hd->dvert[j], hd->defgrp_index);
+ }
+
+ if (fac) {
+ float co_tmp[3];
+ mul_v3_m4v3(co_tmp, hd->mat, co);
+ interp_v3_v3v3(co, co, co_tmp, fac);
+ }
+ }
}
-static void deformVerts_do(
- HookModifierData *hmd, const ModifierEvalContext *UNUSED(ctx),
- Object *ob, Mesh *mesh,
- float (*vertexCos)[3], int numVerts)
+static void deformVerts_do(HookModifierData *hmd,
+ const ModifierEvalContext *UNUSED(ctx),
+ Object *ob,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- Object *ob_target = hmd->object;
- bPoseChannel *pchan = BKE_pose_channel_find_name(ob_target->pose, hmd->subtarget);
- float dmat[4][4];
- int i, *index_pt;
- struct HookData_cb hd;
-
- if (hmd->curfalloff == NULL) {
- /* should never happen, but bad lib linking could cause it */
- hmd->curfalloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
- }
-
- if (hmd->curfalloff) {
- curvemapping_initialize(hmd->curfalloff);
- }
-
- /* Generic data needed for applying per-vertex calculations (initialize all members) */
- hd.vertexCos = vertexCos;
- MOD_get_vgroup(ob, mesh, hmd->name, &hd.dvert, &hd.defgrp_index);
-
- hd.curfalloff = hmd->curfalloff;
-
- hd.falloff_type = hmd->falloff_type;
- hd.falloff = (hmd->falloff_type == eHook_Falloff_None) ? 0.0f : hmd->falloff;
- hd.falloff_sq = SQUARE(hd.falloff);
- hd.fac_orig = hmd->force;
-
- hd.use_falloff = (hd.falloff_sq != 0.0f);
- hd.use_uniform = (hmd->flag & MOD_HOOK_UNIFORM_SPACE) != 0;
-
- if (hd.use_uniform) {
- copy_m3_m4(hd.mat_uniform, hmd->parentinv);
- mul_v3_m3v3(hd.cent, hd.mat_uniform, hmd->cent);
- }
- else {
- unit_m3(hd.mat_uniform); /* unused */
- copy_v3_v3(hd.cent, hmd->cent);
- }
-
- /* get world-space matrix of target, corrected for the space the verts are in */
- if (hmd->subtarget[0] && pchan) {
- /* bone target if there's a matching pose-channel */
- mul_m4_m4m4(dmat, ob_target->obmat, pchan->pose_mat);
- }
- else {
- /* just object target */
- copy_m4_m4(dmat, ob_target->obmat);
- }
- invert_m4_m4(ob->imat, ob->obmat);
- mul_m4_series(hd.mat, ob->imat, dmat, hmd->parentinv);
- /* --- done with 'hd' init --- */
-
-
- /* Regarding index range checking below.
- *
- * This should always be true and I don't generally like
- * "paranoid" style code like this, but old files can have
- * indices that are out of range because old blender did
- * not correct them on exit editmode. - zr
- */
-
- if (hmd->force == 0.0f) {
- /* do nothing, avoid annoying checks in the loop */
- }
- else if (hmd->indexar) { /* vertex indices? */
- const int *origindex_ar;
-
- /* if mesh is present and has original index data, use it */
- if (mesh && (origindex_ar = CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX))) {
- for (i = 0, index_pt = hmd->indexar; i < hmd->totindex; i++, index_pt++) {
- if (*index_pt < numVerts) {
- int j;
-
- for (j = 0; j < numVerts; j++) {
- if (origindex_ar[j] == *index_pt) {
- hook_co_apply(&hd, j);
- }
- }
- }
- }
- }
- else { /* missing mesh or ORIGINDEX */
- for (i = 0, index_pt = hmd->indexar; i < hmd->totindex; i++, index_pt++) {
- if (*index_pt < numVerts) {
- hook_co_apply(&hd, *index_pt);
- }
- }
- }
- }
- else if (hd.dvert) { /* vertex group hook */
- for (i = 0; i < numVerts; i++) {
- hook_co_apply(&hd, i);
- }
- }
+ Object *ob_target = hmd->object;
+ bPoseChannel *pchan = BKE_pose_channel_find_name(ob_target->pose, hmd->subtarget);
+ float dmat[4][4];
+ int i, *index_pt;
+ struct HookData_cb hd;
+
+ if (hmd->curfalloff == NULL) {
+ /* should never happen, but bad lib linking could cause it */
+ hmd->curfalloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
+ }
+
+ if (hmd->curfalloff) {
+ curvemapping_initialize(hmd->curfalloff);
+ }
+
+ /* Generic data needed for applying per-vertex calculations (initialize all members) */
+ hd.vertexCos = vertexCos;
+ MOD_get_vgroup(ob, mesh, hmd->name, &hd.dvert, &hd.defgrp_index);
+
+ hd.curfalloff = hmd->curfalloff;
+
+ hd.falloff_type = hmd->falloff_type;
+ hd.falloff = (hmd->falloff_type == eHook_Falloff_None) ? 0.0f : hmd->falloff;
+ hd.falloff_sq = SQUARE(hd.falloff);
+ hd.fac_orig = hmd->force;
+
+ hd.use_falloff = (hd.falloff_sq != 0.0f);
+ hd.use_uniform = (hmd->flag & MOD_HOOK_UNIFORM_SPACE) != 0;
+
+ if (hd.use_uniform) {
+ copy_m3_m4(hd.mat_uniform, hmd->parentinv);
+ mul_v3_m3v3(hd.cent, hd.mat_uniform, hmd->cent);
+ }
+ else {
+ unit_m3(hd.mat_uniform); /* unused */
+ copy_v3_v3(hd.cent, hmd->cent);
+ }
+
+ /* get world-space matrix of target, corrected for the space the verts are in */
+ if (hmd->subtarget[0] && pchan) {
+ /* bone target if there's a matching pose-channel */
+ mul_m4_m4m4(dmat, ob_target->obmat, pchan->pose_mat);
+ }
+ else {
+ /* just object target */
+ copy_m4_m4(dmat, ob_target->obmat);
+ }
+ invert_m4_m4(ob->imat, ob->obmat);
+ mul_m4_series(hd.mat, ob->imat, dmat, hmd->parentinv);
+ /* --- done with 'hd' init --- */
+
+ /* Regarding index range checking below.
+ *
+ * This should always be true and I don't generally like
+ * "paranoid" style code like this, but old files can have
+ * indices that are out of range because old blender did
+ * not correct them on exit editmode. - zr
+ */
+
+ if (hmd->force == 0.0f) {
+ /* do nothing, avoid annoying checks in the loop */
+ }
+ else if (hmd->indexar) { /* vertex indices? */
+ const int *origindex_ar;
+
+ /* if mesh is present and has original index data, use it */
+ if (mesh && (origindex_ar = CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX))) {
+ for (i = 0, index_pt = hmd->indexar; i < hmd->totindex; i++, index_pt++) {
+ if (*index_pt < numVerts) {
+ int j;
+
+ for (j = 0; j < numVerts; j++) {
+ if (origindex_ar[j] == *index_pt) {
+ hook_co_apply(&hd, j);
+ }
+ }
+ }
+ }
+ }
+ else { /* missing mesh or ORIGINDEX */
+ for (i = 0, index_pt = hmd->indexar; i < hmd->totindex; i++, index_pt++) {
+ if (*index_pt < numVerts) {
+ hook_co_apply(&hd, *index_pt);
+ }
+ }
+ }
+ }
+ else if (hd.dvert) { /* vertex group hook */
+ for (i = 0; i < numVerts; i++) {
+ hook_co_apply(&hd, i);
+ }
+ }
}
-static void deformVerts(
- struct ModifierData *md, const struct ModifierEvalContext *ctx, struct Mesh *mesh,
- float (*vertexCos)[3], int numVerts)
+static void deformVerts(struct ModifierData *md,
+ const struct ModifierEvalContext *ctx,
+ struct Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- HookModifierData *hmd = (HookModifierData *)md;
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ HookModifierData *hmd = (HookModifierData *)md;
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
- deformVerts_do(hmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+ deformVerts_do(hmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-static void deformVertsEM(
- struct ModifierData *md, const struct ModifierEvalContext *ctx,
- struct BMEditMesh *editData,
- struct Mesh *mesh, float (*vertexCos)[3], int numVerts)
+static void deformVertsEM(struct ModifierData *md,
+ const struct ModifierEvalContext *ctx,
+ struct BMEditMesh *editData,
+ struct Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- HookModifierData *hmd = (HookModifierData *)md;
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ HookModifierData *hmd = (HookModifierData *)md;
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, editData, mesh, NULL, numVerts, false, false);
- deformVerts_do(hmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+ deformVerts_do(hmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
ModifierTypeInfo modifierType_Hook = {
- /* name */ "Hook",
- /* structName */ "HookModifierData",
- /* structSize */ sizeof(HookModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_AcceptsLattice |
- eModifierTypeFlag_SupportsEditmode,
- /* copyData */ copyData,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ freeData,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Hook",
+ /* structName */ "HookModifierData",
+ /* structSize */ sizeof(HookModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice |
+ eModifierTypeFlag_SupportsEditmode,
+ /* copyData */ copyData,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ freeData,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c
index df0ef4a7404..02682b23490 100644
--- a/source/blender/modifiers/intern/MOD_laplaciandeform.c
+++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c
@@ -44,165 +44,173 @@
#include "eigen_capi.h"
enum {
- LAPDEFORM_SYSTEM_NOT_CHANGE = 0,
- LAPDEFORM_SYSTEM_IS_DIFFERENT,
- LAPDEFORM_SYSTEM_ONLY_CHANGE_ANCHORS,
- LAPDEFORM_SYSTEM_ONLY_CHANGE_GROUP,
- LAPDEFORM_SYSTEM_ONLY_CHANGE_MESH,
- LAPDEFORM_SYSTEM_CHANGE_VERTEXES,
- LAPDEFORM_SYSTEM_CHANGE_EDGES,
- LAPDEFORM_SYSTEM_CHANGE_NOT_VALID_GROUP,
+ LAPDEFORM_SYSTEM_NOT_CHANGE = 0,
+ LAPDEFORM_SYSTEM_IS_DIFFERENT,
+ LAPDEFORM_SYSTEM_ONLY_CHANGE_ANCHORS,
+ LAPDEFORM_SYSTEM_ONLY_CHANGE_GROUP,
+ LAPDEFORM_SYSTEM_ONLY_CHANGE_MESH,
+ LAPDEFORM_SYSTEM_CHANGE_VERTEXES,
+ LAPDEFORM_SYSTEM_CHANGE_EDGES,
+ LAPDEFORM_SYSTEM_CHANGE_NOT_VALID_GROUP,
};
typedef struct LaplacianSystem {
- bool is_matrix_computed;
- bool has_solution;
- int total_verts;
- int total_edges;
- int total_tris;
- int total_anchors;
- int repeat;
- char anchor_grp_name[64]; /* Vertex Group name */
- float (*co)[3]; /* Original vertex coordinates */
- float (*no)[3]; /* Original vertex normal */
- float (*delta)[3]; /* Differential Coordinates */
- unsigned int (*tris)[3]; /* Copy of MLoopTri (tessellation triangle) v1-v3 */
- int *index_anchors; /* Static vertex index list */
- int *unit_verts; /* Unit vectors of projected edges onto the plane orthogonal to n */
- int *ringf_indices; /* Indices of faces per vertex */
- int *ringv_indices; /* Indices of neighbors(vertex) per vertex */
- LinearSolver *context; /* System for solve general implicit rotations */
- MeshElemMap *ringf_map; /* Map of faces per vertex */
- MeshElemMap *ringv_map; /* Map of vertex per vertex */
+ bool is_matrix_computed;
+ bool has_solution;
+ int total_verts;
+ int total_edges;
+ int total_tris;
+ int total_anchors;
+ int repeat;
+ char anchor_grp_name[64]; /* Vertex Group name */
+ float (*co)[3]; /* Original vertex coordinates */
+ float (*no)[3]; /* Original vertex normal */
+ float (*delta)[3]; /* Differential Coordinates */
+ unsigned int (*tris)[3]; /* Copy of MLoopTri (tessellation triangle) v1-v3 */
+ int *index_anchors; /* Static vertex index list */
+ int *unit_verts; /* Unit vectors of projected edges onto the plane orthogonal to n */
+ int *ringf_indices; /* Indices of faces per vertex */
+ int *ringv_indices; /* Indices of neighbors(vertex) per vertex */
+ LinearSolver *context; /* System for solve general implicit rotations */
+ MeshElemMap *ringf_map; /* Map of faces per vertex */
+ MeshElemMap *ringv_map; /* Map of vertex per vertex */
} LaplacianSystem;
static LaplacianSystem *newLaplacianSystem(void)
{
- LaplacianSystem *sys;
- sys = MEM_callocN(sizeof(LaplacianSystem), "DeformCache");
-
- sys->is_matrix_computed = false;
- sys->has_solution = false;
- sys->total_verts = 0;
- sys->total_edges = 0;
- sys->total_anchors = 0;
- sys->total_tris = 0;
- sys->repeat = 1;
- sys->anchor_grp_name[0] = '\0';
-
- return sys;
+ LaplacianSystem *sys;
+ sys = MEM_callocN(sizeof(LaplacianSystem), "DeformCache");
+
+ sys->is_matrix_computed = false;
+ sys->has_solution = false;
+ sys->total_verts = 0;
+ sys->total_edges = 0;
+ sys->total_anchors = 0;
+ sys->total_tris = 0;
+ sys->repeat = 1;
+ sys->anchor_grp_name[0] = '\0';
+
+ return sys;
}
-static LaplacianSystem *initLaplacianSystem(
- int totalVerts, int totalEdges, int totalTris, int totalAnchors,
- const char defgrpName[64], int iterations)
+static LaplacianSystem *initLaplacianSystem(int totalVerts,
+ int totalEdges,
+ int totalTris,
+ int totalAnchors,
+ const char defgrpName[64],
+ int iterations)
{
- LaplacianSystem *sys = newLaplacianSystem();
-
- sys->is_matrix_computed = false;
- sys->has_solution = false;
- sys->total_verts = totalVerts;
- sys->total_edges = totalEdges;
- sys->total_tris = totalTris;
- sys->total_anchors = totalAnchors;
- sys->repeat = iterations;
- BLI_strncpy(sys->anchor_grp_name, defgrpName, sizeof(sys->anchor_grp_name));
- sys->co = MEM_malloc_arrayN(totalVerts, sizeof(float[3]), "DeformCoordinates");
- sys->no = MEM_calloc_arrayN(totalVerts, sizeof(float[3]), "DeformNormals");
- sys->delta = MEM_calloc_arrayN(totalVerts, sizeof(float[3]), "DeformDeltas");
- sys->tris = MEM_malloc_arrayN(totalTris, sizeof(int[3]), "DeformFaces");
- sys->index_anchors = MEM_malloc_arrayN((totalAnchors), sizeof(int), "DeformAnchors");
- sys->unit_verts = MEM_calloc_arrayN(totalVerts, sizeof(int), "DeformUnitVerts");
- return sys;
+ LaplacianSystem *sys = newLaplacianSystem();
+
+ sys->is_matrix_computed = false;
+ sys->has_solution = false;
+ sys->total_verts = totalVerts;
+ sys->total_edges = totalEdges;
+ sys->total_tris = totalTris;
+ sys->total_anchors = totalAnchors;
+ sys->repeat = iterations;
+ BLI_strncpy(sys->anchor_grp_name, defgrpName, sizeof(sys->anchor_grp_name));
+ sys->co = MEM_malloc_arrayN(totalVerts, sizeof(float[3]), "DeformCoordinates");
+ sys->no = MEM_calloc_arrayN(totalVerts, sizeof(float[3]), "DeformNormals");
+ sys->delta = MEM_calloc_arrayN(totalVerts, sizeof(float[3]), "DeformDeltas");
+ sys->tris = MEM_malloc_arrayN(totalTris, sizeof(int[3]), "DeformFaces");
+ sys->index_anchors = MEM_malloc_arrayN((totalAnchors), sizeof(int), "DeformAnchors");
+ sys->unit_verts = MEM_calloc_arrayN(totalVerts, sizeof(int), "DeformUnitVerts");
+ return sys;
}
static void deleteLaplacianSystem(LaplacianSystem *sys)
{
- MEM_SAFE_FREE(sys->co);
- MEM_SAFE_FREE(sys->no);
- MEM_SAFE_FREE(sys->delta);
- MEM_SAFE_FREE(sys->tris);
- MEM_SAFE_FREE(sys->index_anchors);
- MEM_SAFE_FREE(sys->unit_verts);
- MEM_SAFE_FREE(sys->ringf_indices);
- MEM_SAFE_FREE(sys->ringv_indices);
- MEM_SAFE_FREE(sys->ringf_map);
- MEM_SAFE_FREE(sys->ringv_map);
-
- if (sys->context) {
- EIG_linear_solver_delete(sys->context);
- }
- MEM_SAFE_FREE(sys);
+ MEM_SAFE_FREE(sys->co);
+ MEM_SAFE_FREE(sys->no);
+ MEM_SAFE_FREE(sys->delta);
+ MEM_SAFE_FREE(sys->tris);
+ MEM_SAFE_FREE(sys->index_anchors);
+ MEM_SAFE_FREE(sys->unit_verts);
+ MEM_SAFE_FREE(sys->ringf_indices);
+ MEM_SAFE_FREE(sys->ringv_indices);
+ MEM_SAFE_FREE(sys->ringf_map);
+ MEM_SAFE_FREE(sys->ringv_map);
+
+ if (sys->context) {
+ EIG_linear_solver_delete(sys->context);
+ }
+ MEM_SAFE_FREE(sys);
}
-static void createFaceRingMap(
- const int mvert_tot, const MLoopTri *mlooptri, const int mtri_tot,
- const MLoop *mloop, MeshElemMap **r_map, int **r_indices)
+static void createFaceRingMap(const int mvert_tot,
+ const MLoopTri *mlooptri,
+ const int mtri_tot,
+ const MLoop *mloop,
+ MeshElemMap **r_map,
+ int **r_indices)
{
- int i, j, totalr = 0;
- int *indices, *index_iter;
- MeshElemMap *map = MEM_calloc_arrayN(mvert_tot, sizeof(MeshElemMap), "DeformRingMap");
- const MLoopTri *mlt;
-
- for (i = 0, mlt = mlooptri; i < mtri_tot; i++, mlt++) {
-
- for (j = 0; j < 3; j++) {
- const unsigned int v_index = mloop[mlt->tri[j]].v;
- map[v_index].count++;
- totalr++;
- }
- }
- indices = MEM_calloc_arrayN(totalr, sizeof(int), "DeformRingIndex");
- index_iter = indices;
- for (i = 0; i < mvert_tot; i++) {
- map[i].indices = index_iter;
- index_iter += map[i].count;
- map[i].count = 0;
- }
- for (i = 0, mlt = mlooptri; i < mtri_tot; i++, mlt++) {
- for (j = 0; j < 3; j++) {
- const unsigned int v_index = mloop[mlt->tri[j]].v;
- map[v_index].indices[map[v_index].count] = i;
- map[v_index].count++;
- }
- }
- *r_map = map;
- *r_indices = indices;
+ int i, j, totalr = 0;
+ int *indices, *index_iter;
+ MeshElemMap *map = MEM_calloc_arrayN(mvert_tot, sizeof(MeshElemMap), "DeformRingMap");
+ const MLoopTri *mlt;
+
+ for (i = 0, mlt = mlooptri; i < mtri_tot; i++, mlt++) {
+
+ for (j = 0; j < 3; j++) {
+ const unsigned int v_index = mloop[mlt->tri[j]].v;
+ map[v_index].count++;
+ totalr++;
+ }
+ }
+ indices = MEM_calloc_arrayN(totalr, sizeof(int), "DeformRingIndex");
+ index_iter = indices;
+ for (i = 0; i < mvert_tot; i++) {
+ map[i].indices = index_iter;
+ index_iter += map[i].count;
+ map[i].count = 0;
+ }
+ for (i = 0, mlt = mlooptri; i < mtri_tot; i++, mlt++) {
+ for (j = 0; j < 3; j++) {
+ const unsigned int v_index = mloop[mlt->tri[j]].v;
+ map[v_index].indices[map[v_index].count] = i;
+ map[v_index].count++;
+ }
+ }
+ *r_map = map;
+ *r_indices = indices;
}
-static void createVertRingMap(
- const int mvert_tot, const MEdge *medge, const int medge_tot,
- MeshElemMap **r_map, int **r_indices)
+static void createVertRingMap(const int mvert_tot,
+ const MEdge *medge,
+ const int medge_tot,
+ MeshElemMap **r_map,
+ int **r_indices)
{
- MeshElemMap *map = MEM_calloc_arrayN(mvert_tot, sizeof(MeshElemMap), "DeformNeighborsMap");
- int i, vid[2], totalr = 0;
- int *indices, *index_iter;
- const MEdge *me;
-
- for (i = 0, me = medge; i < medge_tot; i++, me++) {
- vid[0] = me->v1;
- vid[1] = me->v2;
- map[vid[0]].count++;
- map[vid[1]].count++;
- totalr += 2;
- }
- indices = MEM_calloc_arrayN(totalr, sizeof(int), "DeformNeighborsIndex");
- index_iter = indices;
- for (i = 0; i < mvert_tot; i++) {
- map[i].indices = index_iter;
- index_iter += map[i].count;
- map[i].count = 0;
- }
- for (i = 0, me = medge; i < medge_tot; i++, me++) {
- vid[0] = me->v1;
- vid[1] = me->v2;
- map[vid[0]].indices[map[vid[0]].count] = vid[1];
- map[vid[0]].count++;
- map[vid[1]].indices[map[vid[1]].count] = vid[0];
- map[vid[1]].count++;
- }
- *r_map = map;
- *r_indices = indices;
+ MeshElemMap *map = MEM_calloc_arrayN(mvert_tot, sizeof(MeshElemMap), "DeformNeighborsMap");
+ int i, vid[2], totalr = 0;
+ int *indices, *index_iter;
+ const MEdge *me;
+
+ for (i = 0, me = medge; i < medge_tot; i++, me++) {
+ vid[0] = me->v1;
+ vid[1] = me->v2;
+ map[vid[0]].count++;
+ map[vid[1]].count++;
+ totalr += 2;
+ }
+ indices = MEM_calloc_arrayN(totalr, sizeof(int), "DeformNeighborsIndex");
+ index_iter = indices;
+ for (i = 0; i < mvert_tot; i++) {
+ map[i].indices = index_iter;
+ index_iter += map[i].count;
+ map[i].count = 0;
+ }
+ for (i = 0, me = medge; i < medge_tot; i++, me++) {
+ vid[0] = me->v1;
+ vid[1] = me->v2;
+ map[vid[0]].indices[map[vid[0]].count] = vid[1];
+ map[vid[0]].count++;
+ map[vid[1]].indices[map[vid[1]].count] = vid[0];
+ map[vid[1]].count++;
+ }
+ *r_map = map;
+ *r_indices = indices;
}
/**
@@ -235,557 +243,577 @@ static void createVertRingMap(
*/
static void initLaplacianMatrix(LaplacianSystem *sys)
{
- float no[3];
- float w2, w3;
- int i = 3, j, ti;
- int idv[3];
-
- for (ti = 0; ti < sys->total_tris; ti++) {
- const unsigned int *vidt = sys->tris[ti];
- const float *co[3];
-
- co[0] = sys->co[vidt[0]];
- co[1] = sys->co[vidt[1]];
- co[2] = sys->co[vidt[2]];
-
- normal_tri_v3(no, UNPACK3(co));
- add_v3_v3(sys->no[vidt[0]], no);
- add_v3_v3(sys->no[vidt[1]], no);
- add_v3_v3(sys->no[vidt[2]], no);
-
- for (j = 0; j < 3; j++) {
- const float *v1, *v2, *v3;
-
- idv[0] = vidt[j];
- idv[1] = vidt[(j + 1) % i];
- idv[2] = vidt[(j + 2) % i];
-
- v1 = sys->co[idv[0]];
- v2 = sys->co[idv[1]];
- v3 = sys->co[idv[2]];
-
- w2 = cotangent_tri_weight_v3(v3, v1, v2);
- w3 = cotangent_tri_weight_v3(v2, v3, v1);
-
- sys->delta[idv[0]][0] += v1[0] * (w2 + w3);
- sys->delta[idv[0]][1] += v1[1] * (w2 + w3);
- sys->delta[idv[0]][2] += v1[2] * (w2 + w3);
-
- sys->delta[idv[0]][0] -= v2[0] * w2;
- sys->delta[idv[0]][1] -= v2[1] * w2;
- sys->delta[idv[0]][2] -= v2[2] * w2;
-
- sys->delta[idv[0]][0] -= v3[0] * w3;
- sys->delta[idv[0]][1] -= v3[1] * w3;
- sys->delta[idv[0]][2] -= v3[2] * w3;
-
- EIG_linear_solver_matrix_add(sys->context, idv[0], idv[1], -w2);
- EIG_linear_solver_matrix_add(sys->context, idv[0], idv[2], -w3);
- EIG_linear_solver_matrix_add(sys->context, idv[0], idv[0], w2 + w3);
- }
- }
+ float no[3];
+ float w2, w3;
+ int i = 3, j, ti;
+ int idv[3];
+
+ for (ti = 0; ti < sys->total_tris; ti++) {
+ const unsigned int *vidt = sys->tris[ti];
+ const float *co[3];
+
+ co[0] = sys->co[vidt[0]];
+ co[1] = sys->co[vidt[1]];
+ co[2] = sys->co[vidt[2]];
+
+ normal_tri_v3(no, UNPACK3(co));
+ add_v3_v3(sys->no[vidt[0]], no);
+ add_v3_v3(sys->no[vidt[1]], no);
+ add_v3_v3(sys->no[vidt[2]], no);
+
+ for (j = 0; j < 3; j++) {
+ const float *v1, *v2, *v3;
+
+ idv[0] = vidt[j];
+ idv[1] = vidt[(j + 1) % i];
+ idv[2] = vidt[(j + 2) % i];
+
+ v1 = sys->co[idv[0]];
+ v2 = sys->co[idv[1]];
+ v3 = sys->co[idv[2]];
+
+ w2 = cotangent_tri_weight_v3(v3, v1, v2);
+ w3 = cotangent_tri_weight_v3(v2, v3, v1);
+
+ sys->delta[idv[0]][0] += v1[0] * (w2 + w3);
+ sys->delta[idv[0]][1] += v1[1] * (w2 + w3);
+ sys->delta[idv[0]][2] += v1[2] * (w2 + w3);
+
+ sys->delta[idv[0]][0] -= v2[0] * w2;
+ sys->delta[idv[0]][1] -= v2[1] * w2;
+ sys->delta[idv[0]][2] -= v2[2] * w2;
+
+ sys->delta[idv[0]][0] -= v3[0] * w3;
+ sys->delta[idv[0]][1] -= v3[1] * w3;
+ sys->delta[idv[0]][2] -= v3[2] * w3;
+
+ EIG_linear_solver_matrix_add(sys->context, idv[0], idv[1], -w2);
+ EIG_linear_solver_matrix_add(sys->context, idv[0], idv[2], -w3);
+ EIG_linear_solver_matrix_add(sys->context, idv[0], idv[0], w2 + w3);
+ }
+ }
}
static void computeImplictRotations(LaplacianSystem *sys)
{
- int vid, *vidn = NULL;
- float minj, mjt, qj[3], vj[3];
- int i, j, ln;
-
- for (i = 0; i < sys->total_verts; i++) {
- normalize_v3(sys->no[i]);
- vidn = sys->ringv_map[i].indices;
- ln = sys->ringv_map[i].count;
- minj = 1000000.0f;
- for (j = 0; j < ln; j++) {
- vid = vidn[j];
- copy_v3_v3(qj, sys->co[vid]);
- sub_v3_v3v3(vj, qj, sys->co[i]);
- normalize_v3(vj);
- mjt = fabsf(dot_v3v3(vj, sys->no[i]));
- if (mjt < minj) {
- minj = mjt;
- sys->unit_verts[i] = vidn[j];
- }
- }
- }
+ int vid, *vidn = NULL;
+ float minj, mjt, qj[3], vj[3];
+ int i, j, ln;
+
+ for (i = 0; i < sys->total_verts; i++) {
+ normalize_v3(sys->no[i]);
+ vidn = sys->ringv_map[i].indices;
+ ln = sys->ringv_map[i].count;
+ minj = 1000000.0f;
+ for (j = 0; j < ln; j++) {
+ vid = vidn[j];
+ copy_v3_v3(qj, sys->co[vid]);
+ sub_v3_v3v3(vj, qj, sys->co[i]);
+ normalize_v3(vj);
+ mjt = fabsf(dot_v3v3(vj, sys->no[i]));
+ if (mjt < minj) {
+ minj = mjt;
+ sys->unit_verts[i] = vidn[j];
+ }
+ }
+ }
}
static void rotateDifferentialCoordinates(LaplacianSystem *sys)
{
- float alpha, beta, gamma;
- float pj[3], ni[3], di[3];
- float uij[3], dun[3], e2[3], pi[3], fni[3], vn[3][3];
- int i, j, num_fni, k, fi;
- int *fidn;
-
- for (i = 0; i < sys->total_verts; i++) {
- copy_v3_v3(pi, sys->co[i]);
- copy_v3_v3(ni, sys->no[i]);
- k = sys->unit_verts[i];
- copy_v3_v3(pj, sys->co[k]);
- sub_v3_v3v3(uij, pj, pi);
- mul_v3_v3fl(dun, ni, dot_v3v3(uij, ni));
- sub_v3_v3(uij, dun);
- normalize_v3(uij);
- cross_v3_v3v3(e2, ni, uij);
- copy_v3_v3(di, sys->delta[i]);
- alpha = dot_v3v3(ni, di);
- beta = dot_v3v3(uij, di);
- gamma = dot_v3v3(e2, di);
-
- pi[0] = EIG_linear_solver_variable_get(sys->context, 0, i);
- pi[1] = EIG_linear_solver_variable_get(sys->context, 1, i);
- pi[2] = EIG_linear_solver_variable_get(sys->context, 2, i);
- zero_v3(ni);
- num_fni = sys->ringf_map[i].count;
- for (fi = 0; fi < num_fni; fi++) {
- const unsigned int *vin;
- fidn = sys->ringf_map[i].indices;
- vin = sys->tris[fidn[fi]];
- for (j = 0; j < 3; j++) {
- vn[j][0] = EIG_linear_solver_variable_get(sys->context, 0, vin[j]);
- vn[j][1] = EIG_linear_solver_variable_get(sys->context, 1, vin[j]);
- vn[j][2] = EIG_linear_solver_variable_get(sys->context, 2, vin[j]);
- if (vin[j] == sys->unit_verts[i]) {
- copy_v3_v3(pj, vn[j]);
- }
- }
-
- normal_tri_v3(fni, UNPACK3(vn));
- add_v3_v3(ni, fni);
- }
-
- normalize_v3(ni);
- sub_v3_v3v3(uij, pj, pi);
- mul_v3_v3fl(dun, ni, dot_v3v3(uij, ni));
- sub_v3_v3(uij, dun);
- normalize_v3(uij);
- cross_v3_v3v3(e2, ni, uij);
- fni[0] = alpha * ni[0] + beta * uij[0] + gamma * e2[0];
- fni[1] = alpha * ni[1] + beta * uij[1] + gamma * e2[1];
- fni[2] = alpha * ni[2] + beta * uij[2] + gamma * e2[2];
-
- if (len_squared_v3(fni) > FLT_EPSILON) {
- EIG_linear_solver_right_hand_side_add(sys->context, 0, i, fni[0]);
- EIG_linear_solver_right_hand_side_add(sys->context, 1, i, fni[1]);
- EIG_linear_solver_right_hand_side_add(sys->context, 2, i, fni[2]);
- }
- else {
- EIG_linear_solver_right_hand_side_add(sys->context, 0, i, sys->delta[i][0]);
- EIG_linear_solver_right_hand_side_add(sys->context, 1, i, sys->delta[i][1]);
- EIG_linear_solver_right_hand_side_add(sys->context, 2, i, sys->delta[i][2]);
- }
- }
+ float alpha, beta, gamma;
+ float pj[3], ni[3], di[3];
+ float uij[3], dun[3], e2[3], pi[3], fni[3], vn[3][3];
+ int i, j, num_fni, k, fi;
+ int *fidn;
+
+ for (i = 0; i < sys->total_verts; i++) {
+ copy_v3_v3(pi, sys->co[i]);
+ copy_v3_v3(ni, sys->no[i]);
+ k = sys->unit_verts[i];
+ copy_v3_v3(pj, sys->co[k]);
+ sub_v3_v3v3(uij, pj, pi);
+ mul_v3_v3fl(dun, ni, dot_v3v3(uij, ni));
+ sub_v3_v3(uij, dun);
+ normalize_v3(uij);
+ cross_v3_v3v3(e2, ni, uij);
+ copy_v3_v3(di, sys->delta[i]);
+ alpha = dot_v3v3(ni, di);
+ beta = dot_v3v3(uij, di);
+ gamma = dot_v3v3(e2, di);
+
+ pi[0] = EIG_linear_solver_variable_get(sys->context, 0, i);
+ pi[1] = EIG_linear_solver_variable_get(sys->context, 1, i);
+ pi[2] = EIG_linear_solver_variable_get(sys->context, 2, i);
+ zero_v3(ni);
+ num_fni = sys->ringf_map[i].count;
+ for (fi = 0; fi < num_fni; fi++) {
+ const unsigned int *vin;
+ fidn = sys->ringf_map[i].indices;
+ vin = sys->tris[fidn[fi]];
+ for (j = 0; j < 3; j++) {
+ vn[j][0] = EIG_linear_solver_variable_get(sys->context, 0, vin[j]);
+ vn[j][1] = EIG_linear_solver_variable_get(sys->context, 1, vin[j]);
+ vn[j][2] = EIG_linear_solver_variable_get(sys->context, 2, vin[j]);
+ if (vin[j] == sys->unit_verts[i]) {
+ copy_v3_v3(pj, vn[j]);
+ }
+ }
+
+ normal_tri_v3(fni, UNPACK3(vn));
+ add_v3_v3(ni, fni);
+ }
+
+ normalize_v3(ni);
+ sub_v3_v3v3(uij, pj, pi);
+ mul_v3_v3fl(dun, ni, dot_v3v3(uij, ni));
+ sub_v3_v3(uij, dun);
+ normalize_v3(uij);
+ cross_v3_v3v3(e2, ni, uij);
+ fni[0] = alpha * ni[0] + beta * uij[0] + gamma * e2[0];
+ fni[1] = alpha * ni[1] + beta * uij[1] + gamma * e2[1];
+ fni[2] = alpha * ni[2] + beta * uij[2] + gamma * e2[2];
+
+ if (len_squared_v3(fni) > FLT_EPSILON) {
+ EIG_linear_solver_right_hand_side_add(sys->context, 0, i, fni[0]);
+ EIG_linear_solver_right_hand_side_add(sys->context, 1, i, fni[1]);
+ EIG_linear_solver_right_hand_side_add(sys->context, 2, i, fni[2]);
+ }
+ else {
+ EIG_linear_solver_right_hand_side_add(sys->context, 0, i, sys->delta[i][0]);
+ EIG_linear_solver_right_hand_side_add(sys->context, 1, i, sys->delta[i][1]);
+ EIG_linear_solver_right_hand_side_add(sys->context, 2, i, sys->delta[i][2]);
+ }
+ }
}
static void laplacianDeformPreview(LaplacianSystem *sys, float (*vertexCos)[3])
{
- int vid, i, j, n, na;
- n = sys->total_verts;
- na = sys->total_anchors;
-
- if (!sys->is_matrix_computed) {
- sys->context = EIG_linear_least_squares_solver_new(n + na, n, 3);
-
- for (i = 0; i < n; i++) {
- EIG_linear_solver_variable_set(sys->context, 0, i, sys->co[i][0]);
- EIG_linear_solver_variable_set(sys->context, 1, i, sys->co[i][1]);
- EIG_linear_solver_variable_set(sys->context, 2, i, sys->co[i][2]);
- }
- for (i = 0; i < na; i++) {
- vid = sys->index_anchors[i];
- EIG_linear_solver_variable_set(sys->context, 0, vid, vertexCos[vid][0]);
- EIG_linear_solver_variable_set(sys->context, 1, vid, vertexCos[vid][1]);
- EIG_linear_solver_variable_set(sys->context, 2, vid, vertexCos[vid][2]);
- }
-
- initLaplacianMatrix(sys);
- computeImplictRotations(sys);
-
- for (i = 0; i < n; i++) {
- EIG_linear_solver_right_hand_side_add(sys->context, 0, i, sys->delta[i][0]);
- EIG_linear_solver_right_hand_side_add(sys->context, 1, i, sys->delta[i][1]);
- EIG_linear_solver_right_hand_side_add(sys->context, 2, i, sys->delta[i][2]);
- }
- for (i = 0; i < na; i++) {
- vid = sys->index_anchors[i];
- EIG_linear_solver_right_hand_side_add(sys->context, 0, n + i, vertexCos[vid][0]);
- EIG_linear_solver_right_hand_side_add(sys->context, 1, n + i, vertexCos[vid][1]);
- EIG_linear_solver_right_hand_side_add(sys->context, 2, n + i, vertexCos[vid][2]);
- EIG_linear_solver_matrix_add(sys->context, n + i, vid, 1.0f);
- }
- if (EIG_linear_solver_solve(sys->context)) {
- sys->has_solution = true;
-
- for (j = 1; j <= sys->repeat; j++) {
- rotateDifferentialCoordinates(sys);
-
- for (i = 0; i < na; i++) {
- vid = sys->index_anchors[i];
- EIG_linear_solver_right_hand_side_add(sys->context, 0, n + i, vertexCos[vid][0]);
- EIG_linear_solver_right_hand_side_add(sys->context, 1, n + i, vertexCos[vid][1]);
- EIG_linear_solver_right_hand_side_add(sys->context, 2, n + i, vertexCos[vid][2]);
- }
-
- if (!EIG_linear_solver_solve(sys->context)) {
- sys->has_solution = false;
- break;
- }
- }
- if (sys->has_solution) {
- for (vid = 0; vid < sys->total_verts; vid++) {
- vertexCos[vid][0] = EIG_linear_solver_variable_get(sys->context, 0, vid);
- vertexCos[vid][1] = EIG_linear_solver_variable_get(sys->context, 1, vid);
- vertexCos[vid][2] = EIG_linear_solver_variable_get(sys->context, 2, vid);
- }
- }
- else {
- sys->has_solution = false;
- }
-
- }
- else {
- sys->has_solution = false;
- }
- sys->is_matrix_computed = true;
-
- }
- else if (sys->has_solution) {
- for (i = 0; i < n; i++) {
- EIG_linear_solver_right_hand_side_add(sys->context, 0, i, sys->delta[i][0]);
- EIG_linear_solver_right_hand_side_add(sys->context, 1, i, sys->delta[i][1]);
- EIG_linear_solver_right_hand_side_add(sys->context, 2, i, sys->delta[i][2]);
- }
- for (i = 0; i < na; i++) {
- vid = sys->index_anchors[i];
- EIG_linear_solver_right_hand_side_add(sys->context, 0, n + i, vertexCos[vid][0]);
- EIG_linear_solver_right_hand_side_add(sys->context, 1, n + i, vertexCos[vid][1]);
- EIG_linear_solver_right_hand_side_add(sys->context, 2, n + i, vertexCos[vid][2]);
- EIG_linear_solver_matrix_add(sys->context, n + i, vid, 1.0f);
- }
-
- if (EIG_linear_solver_solve(sys->context)) {
- sys->has_solution = true;
- for (j = 1; j <= sys->repeat; j++) {
- rotateDifferentialCoordinates(sys);
-
- for (i = 0; i < na; i++) {
- vid = sys->index_anchors[i];
- EIG_linear_solver_right_hand_side_add(sys->context, 0, n + i, vertexCos[vid][0]);
- EIG_linear_solver_right_hand_side_add(sys->context, 1, n + i, vertexCos[vid][1]);
- EIG_linear_solver_right_hand_side_add(sys->context, 2, n + i, vertexCos[vid][2]);
- }
- if (!EIG_linear_solver_solve(sys->context)) {
- sys->has_solution = false;
- break;
- }
- }
- if (sys->has_solution) {
- for (vid = 0; vid < sys->total_verts; vid++) {
- vertexCos[vid][0] = EIG_linear_solver_variable_get(sys->context, 0, vid);
- vertexCos[vid][1] = EIG_linear_solver_variable_get(sys->context, 1, vid);
- vertexCos[vid][2] = EIG_linear_solver_variable_get(sys->context, 2, vid);
- }
- }
- else {
- sys->has_solution = false;
- }
- }
- else {
- sys->has_solution = false;
- }
- }
+ int vid, i, j, n, na;
+ n = sys->total_verts;
+ na = sys->total_anchors;
+
+ if (!sys->is_matrix_computed) {
+ sys->context = EIG_linear_least_squares_solver_new(n + na, n, 3);
+
+ for (i = 0; i < n; i++) {
+ EIG_linear_solver_variable_set(sys->context, 0, i, sys->co[i][0]);
+ EIG_linear_solver_variable_set(sys->context, 1, i, sys->co[i][1]);
+ EIG_linear_solver_variable_set(sys->context, 2, i, sys->co[i][2]);
+ }
+ for (i = 0; i < na; i++) {
+ vid = sys->index_anchors[i];
+ EIG_linear_solver_variable_set(sys->context, 0, vid, vertexCos[vid][0]);
+ EIG_linear_solver_variable_set(sys->context, 1, vid, vertexCos[vid][1]);
+ EIG_linear_solver_variable_set(sys->context, 2, vid, vertexCos[vid][2]);
+ }
+
+ initLaplacianMatrix(sys);
+ computeImplictRotations(sys);
+
+ for (i = 0; i < n; i++) {
+ EIG_linear_solver_right_hand_side_add(sys->context, 0, i, sys->delta[i][0]);
+ EIG_linear_solver_right_hand_side_add(sys->context, 1, i, sys->delta[i][1]);
+ EIG_linear_solver_right_hand_side_add(sys->context, 2, i, sys->delta[i][2]);
+ }
+ for (i = 0; i < na; i++) {
+ vid = sys->index_anchors[i];
+ EIG_linear_solver_right_hand_side_add(sys->context, 0, n + i, vertexCos[vid][0]);
+ EIG_linear_solver_right_hand_side_add(sys->context, 1, n + i, vertexCos[vid][1]);
+ EIG_linear_solver_right_hand_side_add(sys->context, 2, n + i, vertexCos[vid][2]);
+ EIG_linear_solver_matrix_add(sys->context, n + i, vid, 1.0f);
+ }
+ if (EIG_linear_solver_solve(sys->context)) {
+ sys->has_solution = true;
+
+ for (j = 1; j <= sys->repeat; j++) {
+ rotateDifferentialCoordinates(sys);
+
+ for (i = 0; i < na; i++) {
+ vid = sys->index_anchors[i];
+ EIG_linear_solver_right_hand_side_add(sys->context, 0, n + i, vertexCos[vid][0]);
+ EIG_linear_solver_right_hand_side_add(sys->context, 1, n + i, vertexCos[vid][1]);
+ EIG_linear_solver_right_hand_side_add(sys->context, 2, n + i, vertexCos[vid][2]);
+ }
+
+ if (!EIG_linear_solver_solve(sys->context)) {
+ sys->has_solution = false;
+ break;
+ }
+ }
+ if (sys->has_solution) {
+ for (vid = 0; vid < sys->total_verts; vid++) {
+ vertexCos[vid][0] = EIG_linear_solver_variable_get(sys->context, 0, vid);
+ vertexCos[vid][1] = EIG_linear_solver_variable_get(sys->context, 1, vid);
+ vertexCos[vid][2] = EIG_linear_solver_variable_get(sys->context, 2, vid);
+ }
+ }
+ else {
+ sys->has_solution = false;
+ }
+ }
+ else {
+ sys->has_solution = false;
+ }
+ sys->is_matrix_computed = true;
+ }
+ else if (sys->has_solution) {
+ for (i = 0; i < n; i++) {
+ EIG_linear_solver_right_hand_side_add(sys->context, 0, i, sys->delta[i][0]);
+ EIG_linear_solver_right_hand_side_add(sys->context, 1, i, sys->delta[i][1]);
+ EIG_linear_solver_right_hand_side_add(sys->context, 2, i, sys->delta[i][2]);
+ }
+ for (i = 0; i < na; i++) {
+ vid = sys->index_anchors[i];
+ EIG_linear_solver_right_hand_side_add(sys->context, 0, n + i, vertexCos[vid][0]);
+ EIG_linear_solver_right_hand_side_add(sys->context, 1, n + i, vertexCos[vid][1]);
+ EIG_linear_solver_right_hand_side_add(sys->context, 2, n + i, vertexCos[vid][2]);
+ EIG_linear_solver_matrix_add(sys->context, n + i, vid, 1.0f);
+ }
+
+ if (EIG_linear_solver_solve(sys->context)) {
+ sys->has_solution = true;
+ for (j = 1; j <= sys->repeat; j++) {
+ rotateDifferentialCoordinates(sys);
+
+ for (i = 0; i < na; i++) {
+ vid = sys->index_anchors[i];
+ EIG_linear_solver_right_hand_side_add(sys->context, 0, n + i, vertexCos[vid][0]);
+ EIG_linear_solver_right_hand_side_add(sys->context, 1, n + i, vertexCos[vid][1]);
+ EIG_linear_solver_right_hand_side_add(sys->context, 2, n + i, vertexCos[vid][2]);
+ }
+ if (!EIG_linear_solver_solve(sys->context)) {
+ sys->has_solution = false;
+ break;
+ }
+ }
+ if (sys->has_solution) {
+ for (vid = 0; vid < sys->total_verts; vid++) {
+ vertexCos[vid][0] = EIG_linear_solver_variable_get(sys->context, 0, vid);
+ vertexCos[vid][1] = EIG_linear_solver_variable_get(sys->context, 1, vid);
+ vertexCos[vid][2] = EIG_linear_solver_variable_get(sys->context, 2, vid);
+ }
+ }
+ else {
+ sys->has_solution = false;
+ }
+ }
+ else {
+ sys->has_solution = false;
+ }
+ }
}
static bool isValidVertexGroup(LaplacianDeformModifierData *lmd, Object *ob, Mesh *mesh)
{
- int defgrp_index;
- MDeformVert *dvert = NULL;
+ int defgrp_index;
+ MDeformVert *dvert = NULL;
- MOD_get_vgroup(ob, mesh, lmd->anchor_grp_name, &dvert, &defgrp_index);
+ MOD_get_vgroup(ob, mesh, lmd->anchor_grp_name, &dvert, &defgrp_index);
- return (dvert != NULL);
+ return (dvert != NULL);
}
static void initSystem(
- LaplacianDeformModifierData *lmd, Object *ob, Mesh *mesh,
- float (*vertexCos)[3], int numVerts)
+ LaplacianDeformModifierData *lmd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int numVerts)
{
- int i;
- int defgrp_index;
- int total_anchors;
- float wpaint;
- MDeformVert *dvert = NULL;
- MDeformVert *dv = NULL;
- LaplacianSystem *sys;
-
- if (isValidVertexGroup(lmd, ob, mesh)) {
- int *index_anchors = MEM_malloc_arrayN(numVerts, sizeof(int), __func__); /* over-alloc */
- const MLoopTri *mlooptri;
- const MLoop *mloop;
-
- STACK_DECLARE(index_anchors);
-
- STACK_INIT(index_anchors, numVerts);
-
- MOD_get_vgroup(ob, mesh, lmd->anchor_grp_name, &dvert, &defgrp_index);
- BLI_assert(dvert != NULL);
- dv = dvert;
- for (i = 0; i < numVerts; i++) {
- wpaint = defvert_find_weight(dv, defgrp_index);
- dv++;
- if (wpaint > 0.0f) {
- STACK_PUSH(index_anchors, i);
- }
- }
-
- total_anchors = STACK_SIZE(index_anchors);
- lmd->cache_system = initLaplacianSystem(numVerts, mesh->totedge, BKE_mesh_runtime_looptri_len(mesh),
- total_anchors, lmd->anchor_grp_name, lmd->repeat);
- sys = (LaplacianSystem *)lmd->cache_system;
- memcpy(sys->index_anchors, index_anchors, sizeof(int) * total_anchors);
- memcpy(sys->co, vertexCos, sizeof(float[3]) * numVerts);
- MEM_freeN(index_anchors);
- lmd->vertexco = MEM_malloc_arrayN(numVerts, sizeof(float[3]), "ModDeformCoordinates");
- memcpy(lmd->vertexco, vertexCos, sizeof(float[3]) * numVerts);
- lmd->total_verts = numVerts;
-
- createFaceRingMap(
- mesh->totvert, BKE_mesh_runtime_looptri_ensure(mesh), BKE_mesh_runtime_looptri_len(mesh),
- mesh->mloop, &sys->ringf_map, &sys->ringf_indices);
- createVertRingMap(
- mesh->totvert, mesh->medge, mesh->totedge,
- &sys->ringv_map, &sys->ringv_indices);
-
-
- mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
- mloop = mesh->mloop;
-
- for (i = 0; i < sys->total_tris; i++) {
- sys->tris[i][0] = mloop[mlooptri[i].tri[0]].v;
- sys->tris[i][1] = mloop[mlooptri[i].tri[1]].v;
- sys->tris[i][2] = mloop[mlooptri[i].tri[2]].v;
- }
- }
+ int i;
+ int defgrp_index;
+ int total_anchors;
+ float wpaint;
+ MDeformVert *dvert = NULL;
+ MDeformVert *dv = NULL;
+ LaplacianSystem *sys;
+
+ if (isValidVertexGroup(lmd, ob, mesh)) {
+ int *index_anchors = MEM_malloc_arrayN(numVerts, sizeof(int), __func__); /* over-alloc */
+ const MLoopTri *mlooptri;
+ const MLoop *mloop;
+
+ STACK_DECLARE(index_anchors);
+
+ STACK_INIT(index_anchors, numVerts);
+
+ MOD_get_vgroup(ob, mesh, lmd->anchor_grp_name, &dvert, &defgrp_index);
+ BLI_assert(dvert != NULL);
+ dv = dvert;
+ for (i = 0; i < numVerts; i++) {
+ wpaint = defvert_find_weight(dv, defgrp_index);
+ dv++;
+ if (wpaint > 0.0f) {
+ STACK_PUSH(index_anchors, i);
+ }
+ }
+
+ total_anchors = STACK_SIZE(index_anchors);
+ lmd->cache_system = initLaplacianSystem(numVerts,
+ mesh->totedge,
+ BKE_mesh_runtime_looptri_len(mesh),
+ total_anchors,
+ lmd->anchor_grp_name,
+ lmd->repeat);
+ sys = (LaplacianSystem *)lmd->cache_system;
+ memcpy(sys->index_anchors, index_anchors, sizeof(int) * total_anchors);
+ memcpy(sys->co, vertexCos, sizeof(float[3]) * numVerts);
+ MEM_freeN(index_anchors);
+ lmd->vertexco = MEM_malloc_arrayN(numVerts, sizeof(float[3]), "ModDeformCoordinates");
+ memcpy(lmd->vertexco, vertexCos, sizeof(float[3]) * numVerts);
+ lmd->total_verts = numVerts;
+
+ createFaceRingMap(mesh->totvert,
+ BKE_mesh_runtime_looptri_ensure(mesh),
+ BKE_mesh_runtime_looptri_len(mesh),
+ mesh->mloop,
+ &sys->ringf_map,
+ &sys->ringf_indices);
+ createVertRingMap(
+ mesh->totvert, mesh->medge, mesh->totedge, &sys->ringv_map, &sys->ringv_indices);
+
+ mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
+ mloop = mesh->mloop;
+
+ for (i = 0; i < sys->total_tris; i++) {
+ sys->tris[i][0] = mloop[mlooptri[i].tri[0]].v;
+ sys->tris[i][1] = mloop[mlooptri[i].tri[1]].v;
+ sys->tris[i][2] = mloop[mlooptri[i].tri[2]].v;
+ }
+ }
}
-static int isSystemDifferent(LaplacianDeformModifierData *lmd, Object *ob, Mesh *mesh, int numVerts)
+static int isSystemDifferent(LaplacianDeformModifierData *lmd,
+ Object *ob,
+ Mesh *mesh,
+ int numVerts)
{
- int i;
- int defgrp_index;
- int total_anchors = 0;
- float wpaint;
- MDeformVert *dvert = NULL;
- MDeformVert *dv = NULL;
- LaplacianSystem *sys = (LaplacianSystem *)lmd->cache_system;
-
- if (sys->total_verts != numVerts) {
- return LAPDEFORM_SYSTEM_CHANGE_VERTEXES;
- }
- if (sys->total_edges != mesh->totedge) {
- return LAPDEFORM_SYSTEM_CHANGE_EDGES;
- }
- if (!STREQ(lmd->anchor_grp_name, sys->anchor_grp_name)) {
- return LAPDEFORM_SYSTEM_ONLY_CHANGE_GROUP;
- }
- MOD_get_vgroup(ob, mesh, lmd->anchor_grp_name, &dvert, &defgrp_index);
- if (!dvert) {
- return LAPDEFORM_SYSTEM_CHANGE_NOT_VALID_GROUP;
- }
- dv = dvert;
- for (i = 0; i < numVerts; i++) {
- wpaint = defvert_find_weight(dv, defgrp_index);
- dv++;
- if (wpaint > 0.0f) {
- total_anchors++;
- }
- }
- if (sys->total_anchors != total_anchors) {
- return LAPDEFORM_SYSTEM_ONLY_CHANGE_ANCHORS;
- }
-
- return LAPDEFORM_SYSTEM_NOT_CHANGE;
+ int i;
+ int defgrp_index;
+ int total_anchors = 0;
+ float wpaint;
+ MDeformVert *dvert = NULL;
+ MDeformVert *dv = NULL;
+ LaplacianSystem *sys = (LaplacianSystem *)lmd->cache_system;
+
+ if (sys->total_verts != numVerts) {
+ return LAPDEFORM_SYSTEM_CHANGE_VERTEXES;
+ }
+ if (sys->total_edges != mesh->totedge) {
+ return LAPDEFORM_SYSTEM_CHANGE_EDGES;
+ }
+ if (!STREQ(lmd->anchor_grp_name, sys->anchor_grp_name)) {
+ return LAPDEFORM_SYSTEM_ONLY_CHANGE_GROUP;
+ }
+ MOD_get_vgroup(ob, mesh, lmd->anchor_grp_name, &dvert, &defgrp_index);
+ if (!dvert) {
+ return LAPDEFORM_SYSTEM_CHANGE_NOT_VALID_GROUP;
+ }
+ dv = dvert;
+ for (i = 0; i < numVerts; i++) {
+ wpaint = defvert_find_weight(dv, defgrp_index);
+ dv++;
+ if (wpaint > 0.0f) {
+ total_anchors++;
+ }
+ }
+ if (sys->total_anchors != total_anchors) {
+ return LAPDEFORM_SYSTEM_ONLY_CHANGE_ANCHORS;
+ }
+
+ return LAPDEFORM_SYSTEM_NOT_CHANGE;
}
static void LaplacianDeformModifier_do(
- LaplacianDeformModifierData *lmd, Object *ob, Mesh *mesh,
- float (*vertexCos)[3], int numVerts)
+ LaplacianDeformModifierData *lmd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int numVerts)
{
- float (*filevertexCos)[3];
- int sysdif;
- LaplacianSystem *sys = NULL;
- filevertexCos = NULL;
- if (!(lmd->flag & MOD_LAPLACIANDEFORM_BIND)) {
- if (lmd->cache_system) {
- sys = lmd->cache_system;
- deleteLaplacianSystem(sys);
- lmd->cache_system = NULL;
- }
- lmd->total_verts = 0;
- MEM_SAFE_FREE(lmd->vertexco);
- return;
- }
- if (lmd->cache_system) {
- sysdif = isSystemDifferent(lmd, ob, mesh, numVerts);
- sys = lmd->cache_system;
- if (sysdif) {
- if (sysdif == LAPDEFORM_SYSTEM_ONLY_CHANGE_ANCHORS || sysdif == LAPDEFORM_SYSTEM_ONLY_CHANGE_GROUP) {
- filevertexCos = MEM_malloc_arrayN(numVerts, sizeof(float[3]), "TempModDeformCoordinates");
- memcpy(filevertexCos, lmd->vertexco, sizeof(float[3]) * numVerts);
- MEM_SAFE_FREE(lmd->vertexco);
- lmd->total_verts = 0;
- deleteLaplacianSystem(sys);
- lmd->cache_system = NULL;
- initSystem(lmd, ob, mesh, filevertexCos, numVerts);
- sys = lmd->cache_system; /* may have been reallocated */
- MEM_SAFE_FREE(filevertexCos);
- if (sys) {
- laplacianDeformPreview(sys, vertexCos);
- }
- }
- else {
- if (sysdif == LAPDEFORM_SYSTEM_CHANGE_VERTEXES) {
- modifier_setError(&lmd->modifier, "Vertices changed from %d to %d", lmd->total_verts, numVerts);
- }
- else if (sysdif == LAPDEFORM_SYSTEM_CHANGE_EDGES) {
- modifier_setError(&lmd->modifier, "Edges changed from %d to %d", sys->total_edges, mesh->totedge);
- }
- else if (sysdif == LAPDEFORM_SYSTEM_CHANGE_NOT_VALID_GROUP) {
- modifier_setError(&lmd->modifier, "Vertex group '%s' is not valid", sys->anchor_grp_name);
- }
- }
- }
- else {
- sys->repeat = lmd->repeat;
- laplacianDeformPreview(sys, vertexCos);
- }
- }
- else {
- if (!isValidVertexGroup(lmd, ob, mesh)) {
- modifier_setError(&lmd->modifier, "Vertex group '%s' is not valid", lmd->anchor_grp_name);
- lmd->flag &= ~MOD_LAPLACIANDEFORM_BIND;
- }
- else if (lmd->total_verts > 0 && lmd->total_verts == numVerts) {
- filevertexCos = MEM_malloc_arrayN(numVerts, sizeof(float[3]), "TempDeformCoordinates");
- memcpy(filevertexCos, lmd->vertexco, sizeof(float[3]) * numVerts);
- MEM_SAFE_FREE(lmd->vertexco);
- lmd->total_verts = 0;
- initSystem(lmd, ob, mesh, filevertexCos, numVerts);
- sys = lmd->cache_system;
- MEM_SAFE_FREE(filevertexCos);
- laplacianDeformPreview(sys, vertexCos);
- }
- else {
- initSystem(lmd, ob, mesh, vertexCos, numVerts);
- sys = lmd->cache_system;
- laplacianDeformPreview(sys, vertexCos);
- }
- }
- if (sys && sys->is_matrix_computed && !sys->has_solution) {
- modifier_setError(&lmd->modifier, "The system did not find a solution");
- }
+ float(*filevertexCos)[3];
+ int sysdif;
+ LaplacianSystem *sys = NULL;
+ filevertexCos = NULL;
+ if (!(lmd->flag & MOD_LAPLACIANDEFORM_BIND)) {
+ if (lmd->cache_system) {
+ sys = lmd->cache_system;
+ deleteLaplacianSystem(sys);
+ lmd->cache_system = NULL;
+ }
+ lmd->total_verts = 0;
+ MEM_SAFE_FREE(lmd->vertexco);
+ return;
+ }
+ if (lmd->cache_system) {
+ sysdif = isSystemDifferent(lmd, ob, mesh, numVerts);
+ sys = lmd->cache_system;
+ if (sysdif) {
+ if (sysdif == LAPDEFORM_SYSTEM_ONLY_CHANGE_ANCHORS ||
+ sysdif == LAPDEFORM_SYSTEM_ONLY_CHANGE_GROUP) {
+ filevertexCos = MEM_malloc_arrayN(numVerts, sizeof(float[3]), "TempModDeformCoordinates");
+ memcpy(filevertexCos, lmd->vertexco, sizeof(float[3]) * numVerts);
+ MEM_SAFE_FREE(lmd->vertexco);
+ lmd->total_verts = 0;
+ deleteLaplacianSystem(sys);
+ lmd->cache_system = NULL;
+ initSystem(lmd, ob, mesh, filevertexCos, numVerts);
+ sys = lmd->cache_system; /* may have been reallocated */
+ MEM_SAFE_FREE(filevertexCos);
+ if (sys) {
+ laplacianDeformPreview(sys, vertexCos);
+ }
+ }
+ else {
+ if (sysdif == LAPDEFORM_SYSTEM_CHANGE_VERTEXES) {
+ modifier_setError(
+ &lmd->modifier, "Vertices changed from %d to %d", lmd->total_verts, numVerts);
+ }
+ else if (sysdif == LAPDEFORM_SYSTEM_CHANGE_EDGES) {
+ modifier_setError(
+ &lmd->modifier, "Edges changed from %d to %d", sys->total_edges, mesh->totedge);
+ }
+ else if (sysdif == LAPDEFORM_SYSTEM_CHANGE_NOT_VALID_GROUP) {
+ modifier_setError(
+ &lmd->modifier, "Vertex group '%s' is not valid", sys->anchor_grp_name);
+ }
+ }
+ }
+ else {
+ sys->repeat = lmd->repeat;
+ laplacianDeformPreview(sys, vertexCos);
+ }
+ }
+ else {
+ if (!isValidVertexGroup(lmd, ob, mesh)) {
+ modifier_setError(&lmd->modifier, "Vertex group '%s' is not valid", lmd->anchor_grp_name);
+ lmd->flag &= ~MOD_LAPLACIANDEFORM_BIND;
+ }
+ else if (lmd->total_verts > 0 && lmd->total_verts == numVerts) {
+ filevertexCos = MEM_malloc_arrayN(numVerts, sizeof(float[3]), "TempDeformCoordinates");
+ memcpy(filevertexCos, lmd->vertexco, sizeof(float[3]) * numVerts);
+ MEM_SAFE_FREE(lmd->vertexco);
+ lmd->total_verts = 0;
+ initSystem(lmd, ob, mesh, filevertexCos, numVerts);
+ sys = lmd->cache_system;
+ MEM_SAFE_FREE(filevertexCos);
+ laplacianDeformPreview(sys, vertexCos);
+ }
+ else {
+ initSystem(lmd, ob, mesh, vertexCos, numVerts);
+ sys = lmd->cache_system;
+ laplacianDeformPreview(sys, vertexCos);
+ }
+ }
+ if (sys && sys->is_matrix_computed && !sys->has_solution) {
+ modifier_setError(&lmd->modifier, "The system did not find a solution");
+ }
}
static void initData(ModifierData *md)
{
- LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)md;
- lmd->anchor_grp_name[0] = '\0';
- lmd->total_verts = 0;
- lmd->repeat = 1;
- lmd->vertexco = NULL;
- lmd->cache_system = NULL;
- lmd->flag = 0;
+ LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)md;
+ lmd->anchor_grp_name[0] = '\0';
+ lmd->total_verts = 0;
+ lmd->repeat = 1;
+ lmd->vertexco = NULL;
+ lmd->cache_system = NULL;
+ lmd->flag = 0;
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
- const LaplacianDeformModifierData *lmd = (const LaplacianDeformModifierData *)md;
- LaplacianDeformModifierData *tlmd = (LaplacianDeformModifierData *)target;
+ const LaplacianDeformModifierData *lmd = (const LaplacianDeformModifierData *)md;
+ LaplacianDeformModifierData *tlmd = (LaplacianDeformModifierData *)target;
- modifier_copyData_generic(md, target, flag);
+ modifier_copyData_generic(md, target, flag);
- tlmd->vertexco = MEM_dupallocN(lmd->vertexco);
- tlmd->cache_system = NULL;
+ tlmd->vertexco = MEM_dupallocN(lmd->vertexco);
+ tlmd->cache_system = NULL;
}
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(useRenderParams))
{
- LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)md;
- if (lmd->anchor_grp_name[0]) return 0;
- return 1;
+ LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)md;
+ if (lmd->anchor_grp_name[0])
+ return 0;
+ return 1;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)md;
+ LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)md;
- if (lmd->anchor_grp_name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ if (lmd->anchor_grp_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
-static void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh,
- float (*vertexCos)[3], int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
- LaplacianDeformModifier_do((LaplacianDeformModifierData *)md, ctx->object, mesh_src, vertexCos, numVerts);
+ LaplacianDeformModifier_do(
+ (LaplacianDeformModifierData *)md, ctx->object, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-static void deformVertsEM(
- ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *editData,
- Mesh *mesh, float (*vertexCos)[3], int numVerts)
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *editData,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, editData, mesh, NULL, numVerts, false, false);
- LaplacianDeformModifier_do((LaplacianDeformModifierData *)md, ctx->object, mesh_src,
- vertexCos, numVerts);
+ LaplacianDeformModifier_do(
+ (LaplacianDeformModifierData *)md, ctx->object, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
static void freeData(ModifierData *md)
{
- LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)md;
- LaplacianSystem *sys = (LaplacianSystem *)lmd->cache_system;
- if (sys) {
- deleteLaplacianSystem(sys);
- }
- MEM_SAFE_FREE(lmd->vertexco);
- lmd->total_verts = 0;
+ LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)md;
+ LaplacianSystem *sys = (LaplacianSystem *)lmd->cache_system;
+ if (sys) {
+ deleteLaplacianSystem(sys);
+ }
+ MEM_SAFE_FREE(lmd->vertexco);
+ lmd->total_verts = 0;
}
ModifierTypeInfo modifierType_LaplacianDeform = {
- /* name */ "LaplacianDeform",
- /* structName */ "LaplacianDeformModifierData",
- /* structSize */ sizeof(LaplacianDeformModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
- /* copyData */ copyData,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ freeData,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "LaplacianDeform",
+ /* structName */ "LaplacianDeformModifierData",
+ /* structSize */ sizeof(LaplacianDeformModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
+ /* copyData */ copyData,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ freeData,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
index 321dfd5dae1..0dfe5f49393 100644
--- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c
+++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include "BLI_utildefines.h"
#include "BLI_math.h"
@@ -43,36 +42,43 @@
#include "eigen_capi.h"
struct BLaplacianSystem {
- float *eweights; /* Length weights per Edge */
- float (*fweights)[3]; /* Cotangent weights per face */
- float *ring_areas; /* Total area per ring*/
- float *vlengths; /* Total sum of lengths(edges) per vertice*/
- float *vweights; /* Total sum of weights per vertice*/
- int numEdges; /* Number of edges*/
- int numLoops; /* Number of edges*/
- int numPolys; /* Number of faces*/
- int numVerts; /* Number of verts*/
- short *numNeFa; /* Number of neighbors faces around vertice*/
- short *numNeEd; /* Number of neighbors Edges around vertice*/
- short *zerola; /* Is zero area or length*/
-
- /* Pointers to data*/
- float (*vertexCos)[3];
- const MPoly *mpoly;
- const MLoop *mloop;
- const MEdge *medges;
- LinearSolver *context;
-
- /*Data*/
- float min_area;
- float vert_centroid[3];
+ float *eweights; /* Length weights per Edge */
+ float (*fweights)[3]; /* Cotangent weights per face */
+ float *ring_areas; /* Total area per ring*/
+ float *vlengths; /* Total sum of lengths(edges) per vertice*/
+ float *vweights; /* Total sum of weights per vertice*/
+ int numEdges; /* Number of edges*/
+ int numLoops; /* Number of edges*/
+ int numPolys; /* Number of faces*/
+ int numVerts; /* Number of verts*/
+ short *numNeFa; /* Number of neighbors faces around vertice*/
+ short *numNeEd; /* Number of neighbors Edges around vertice*/
+ short *zerola; /* Is zero area or length*/
+
+ /* Pointers to data*/
+ float (*vertexCos)[3];
+ const MPoly *mpoly;
+ const MLoop *mloop;
+ const MEdge *medges;
+ LinearSolver *context;
+
+ /*Data*/
+ float min_area;
+ float vert_centroid[3];
};
typedef struct BLaplacianSystem LaplacianSystem;
static void required_data_mask(Object *ob, ModifierData *md, CustomData_MeshMasks *r_cddata_masks);
static bool is_disabled(const struct Scene *UNUSED(scene), ModifierData *md, bool useRenderParams);
-static float compute_volume(const float center[3], float (*vertexCos)[3], const MPoly *mpoly, int numPolys, const MLoop *mloop);
-static LaplacianSystem *init_laplacian_system(int a_numEdges, int a_numPolys, int a_numLoops, int a_numVerts);
+static float compute_volume(const float center[3],
+ float (*vertexCos)[3],
+ const MPoly *mpoly,
+ int numPolys,
+ const MLoop *mloop);
+static LaplacianSystem *init_laplacian_system(int a_numEdges,
+ int a_numPolys,
+ int a_numLoops,
+ int a_numVerts);
static void delete_laplacian_system(LaplacianSystem *sys);
static void fill_laplacian_matrix(LaplacianSystem *sys);
static void init_data(ModifierData *md);
@@ -83,473 +89,503 @@ static void validate_solution(LaplacianSystem *sys, short flag, float lambda, fl
static void delete_laplacian_system(LaplacianSystem *sys)
{
- MEM_SAFE_FREE(sys->eweights);
- MEM_SAFE_FREE(sys->fweights);
- MEM_SAFE_FREE(sys->numNeEd);
- MEM_SAFE_FREE(sys->numNeFa);
- MEM_SAFE_FREE(sys->ring_areas);
- MEM_SAFE_FREE(sys->vlengths);
- MEM_SAFE_FREE(sys->vweights);
- MEM_SAFE_FREE(sys->zerola);
-
- if (sys->context) {
- EIG_linear_solver_delete(sys->context);
- }
- sys->vertexCos = NULL;
- sys->mpoly = NULL;
- sys->mloop = NULL;
- sys->medges = NULL;
- MEM_freeN(sys);
+ MEM_SAFE_FREE(sys->eweights);
+ MEM_SAFE_FREE(sys->fweights);
+ MEM_SAFE_FREE(sys->numNeEd);
+ MEM_SAFE_FREE(sys->numNeFa);
+ MEM_SAFE_FREE(sys->ring_areas);
+ MEM_SAFE_FREE(sys->vlengths);
+ MEM_SAFE_FREE(sys->vweights);
+ MEM_SAFE_FREE(sys->zerola);
+
+ if (sys->context) {
+ EIG_linear_solver_delete(sys->context);
+ }
+ sys->vertexCos = NULL;
+ sys->mpoly = NULL;
+ sys->mloop = NULL;
+ sys->medges = NULL;
+ MEM_freeN(sys);
}
static void memset_laplacian_system(LaplacianSystem *sys, int val)
{
- memset(sys->eweights, val, sizeof(float) * sys->numEdges);
- memset(sys->fweights, val, sizeof(float[3]) * sys->numLoops);
- memset(sys->numNeEd, val, sizeof(short) * sys->numVerts);
- memset(sys->numNeFa, val, sizeof(short) * sys->numVerts);
- memset(sys->ring_areas, val, sizeof(float) * sys->numVerts);
- memset(sys->vlengths, val, sizeof(float) * sys->numVerts);
- memset(sys->vweights, val, sizeof(float) * sys->numVerts);
- memset(sys->zerola, val, sizeof(short) * sys->numVerts);
+ memset(sys->eweights, val, sizeof(float) * sys->numEdges);
+ memset(sys->fweights, val, sizeof(float[3]) * sys->numLoops);
+ memset(sys->numNeEd, val, sizeof(short) * sys->numVerts);
+ memset(sys->numNeFa, val, sizeof(short) * sys->numVerts);
+ memset(sys->ring_areas, val, sizeof(float) * sys->numVerts);
+ memset(sys->vlengths, val, sizeof(float) * sys->numVerts);
+ memset(sys->vweights, val, sizeof(float) * sys->numVerts);
+ memset(sys->zerola, val, sizeof(short) * sys->numVerts);
}
-static LaplacianSystem *init_laplacian_system(int a_numEdges, int a_numPolys, int a_numLoops, int a_numVerts)
+static LaplacianSystem *init_laplacian_system(int a_numEdges,
+ int a_numPolys,
+ int a_numLoops,
+ int a_numVerts)
{
- LaplacianSystem *sys;
- sys = MEM_callocN(sizeof(LaplacianSystem), "ModLaplSmoothSystem");
- sys->numEdges = a_numEdges;
- sys->numPolys = a_numPolys;
- sys->numLoops = a_numLoops;
- sys->numVerts = a_numVerts;
-
- sys->eweights = MEM_calloc_arrayN(sys->numEdges, sizeof(float), __func__);
- sys->fweights = MEM_calloc_arrayN(sys->numLoops, sizeof(float[3]), __func__);
- sys->numNeEd = MEM_calloc_arrayN(sys->numVerts, sizeof(short), __func__);
- sys->numNeFa = MEM_calloc_arrayN(sys->numVerts, sizeof(short), __func__);
- sys->ring_areas = MEM_calloc_arrayN(sys->numVerts, sizeof(float), __func__);
- sys->vlengths = MEM_calloc_arrayN(sys->numVerts, sizeof(float), __func__);
- sys->vweights = MEM_calloc_arrayN(sys->numVerts, sizeof(float), __func__);
- sys->zerola = MEM_calloc_arrayN(sys->numVerts, sizeof(short), __func__);
-
- return sys;
+ LaplacianSystem *sys;
+ sys = MEM_callocN(sizeof(LaplacianSystem), "ModLaplSmoothSystem");
+ sys->numEdges = a_numEdges;
+ sys->numPolys = a_numPolys;
+ sys->numLoops = a_numLoops;
+ sys->numVerts = a_numVerts;
+
+ sys->eweights = MEM_calloc_arrayN(sys->numEdges, sizeof(float), __func__);
+ sys->fweights = MEM_calloc_arrayN(sys->numLoops, sizeof(float[3]), __func__);
+ sys->numNeEd = MEM_calloc_arrayN(sys->numVerts, sizeof(short), __func__);
+ sys->numNeFa = MEM_calloc_arrayN(sys->numVerts, sizeof(short), __func__);
+ sys->ring_areas = MEM_calloc_arrayN(sys->numVerts, sizeof(float), __func__);
+ sys->vlengths = MEM_calloc_arrayN(sys->numVerts, sizeof(float), __func__);
+ sys->vweights = MEM_calloc_arrayN(sys->numVerts, sizeof(float), __func__);
+ sys->zerola = MEM_calloc_arrayN(sys->numVerts, sizeof(short), __func__);
+
+ return sys;
}
-static float compute_volume(
- const float center[3], float (*vertexCos)[3],
- const MPoly *mpoly, int numPolys, const MLoop *mloop)
+static float compute_volume(const float center[3],
+ float (*vertexCos)[3],
+ const MPoly *mpoly,
+ int numPolys,
+ const MLoop *mloop)
{
- int i;
- float vol = 0.0f;
-
- for (i = 0; i < numPolys; i++) {
- const MPoly *mp = &mpoly[i];
- const MLoop *l_first = &mloop[mp->loopstart];
- const MLoop *l_prev = l_first + 1;
- const MLoop *l_curr = l_first + 2;
- const MLoop *l_term = l_first + mp->totloop;
-
-
- for (;
- l_curr != l_term;
- l_prev = l_curr, l_curr++)
- {
- vol += volume_tetrahedron_signed_v3(
- center,
- vertexCos[l_first->v],
- vertexCos[l_prev->v],
- vertexCos[l_curr->v]);
- }
- }
-
- return fabsf(vol);
+ int i;
+ float vol = 0.0f;
+
+ for (i = 0; i < numPolys; i++) {
+ const MPoly *mp = &mpoly[i];
+ const MLoop *l_first = &mloop[mp->loopstart];
+ const MLoop *l_prev = l_first + 1;
+ const MLoop *l_curr = l_first + 2;
+ const MLoop *l_term = l_first + mp->totloop;
+
+ for (; l_curr != l_term; l_prev = l_curr, l_curr++) {
+ vol += volume_tetrahedron_signed_v3(
+ center, vertexCos[l_first->v], vertexCos[l_prev->v], vertexCos[l_curr->v]);
+ }
+ }
+
+ return fabsf(vol);
}
static void volume_preservation(LaplacianSystem *sys, float vini, float vend, short flag)
{
- float beta;
- int i;
-
- if (vend != 0.0f) {
- beta = pow(vini / vend, 1.0f / 3.0f);
- for (i = 0; i < sys->numVerts; i++) {
- if (flag & MOD_LAPLACIANSMOOTH_X) {
- sys->vertexCos[i][0] = (sys->vertexCos[i][0] - sys->vert_centroid[0]) * beta + sys->vert_centroid[0];
- }
- if (flag & MOD_LAPLACIANSMOOTH_Y) {
- sys->vertexCos[i][1] = (sys->vertexCos[i][1] - sys->vert_centroid[1]) * beta + sys->vert_centroid[1];
- }
- if (flag & MOD_LAPLACIANSMOOTH_Z) {
- sys->vertexCos[i][2] = (sys->vertexCos[i][2] - sys->vert_centroid[2]) * beta + sys->vert_centroid[2];
- }
-
- }
- }
+ float beta;
+ int i;
+
+ if (vend != 0.0f) {
+ beta = pow(vini / vend, 1.0f / 3.0f);
+ for (i = 0; i < sys->numVerts; i++) {
+ if (flag & MOD_LAPLACIANSMOOTH_X) {
+ sys->vertexCos[i][0] = (sys->vertexCos[i][0] - sys->vert_centroid[0]) * beta +
+ sys->vert_centroid[0];
+ }
+ if (flag & MOD_LAPLACIANSMOOTH_Y) {
+ sys->vertexCos[i][1] = (sys->vertexCos[i][1] - sys->vert_centroid[1]) * beta +
+ sys->vert_centroid[1];
+ }
+ if (flag & MOD_LAPLACIANSMOOTH_Z) {
+ sys->vertexCos[i][2] = (sys->vertexCos[i][2] - sys->vert_centroid[2]) * beta +
+ sys->vert_centroid[2];
+ }
+ }
+ }
}
static void init_laplacian_matrix(LaplacianSystem *sys)
{
- float *v1, *v2;
- float w1, w2, w3;
- float areaf;
- int i;
- unsigned int idv1, idv2;
-
- for (i = 0; i < sys->numEdges; i++) {
- idv1 = sys->medges[i].v1;
- idv2 = sys->medges[i].v2;
-
- v1 = sys->vertexCos[idv1];
- v2 = sys->vertexCos[idv2];
-
- sys->numNeEd[idv1] = sys->numNeEd[idv1] + 1;
- sys->numNeEd[idv2] = sys->numNeEd[idv2] + 1;
- w1 = len_v3v3(v1, v2);
- if (w1 < sys->min_area) {
- sys->zerola[idv1] = 1;
- sys->zerola[idv2] = 1;
- }
- else {
- w1 = 1.0f / w1;
- }
-
- sys->eweights[i] = w1;
- }
-
- for (i = 0; i < sys->numPolys; i++) {
- const MPoly *mp = &sys->mpoly[i];
- const MLoop *l_next = &sys->mloop[mp->loopstart];
- const MLoop *l_term = l_next + mp->totloop;
- const MLoop *l_prev = l_term - 2;
- const MLoop *l_curr = l_term - 1;
-
- for (;
- l_next != l_term;
- l_prev = l_curr, l_curr = l_next, l_next++)
- {
- const float *v_prev = sys->vertexCos[l_prev->v];
- const float *v_curr = sys->vertexCos[l_curr->v];
- const float *v_next = sys->vertexCos[l_next->v];
- const unsigned int l_curr_index = l_curr - sys->mloop;
-
- sys->numNeFa[l_curr->v] += 1;
-
- areaf = area_tri_v3(v_prev, v_curr, v_next);
-
- if (areaf < sys->min_area) {
- sys->zerola[l_curr->v] = 1;
- }
-
- sys->ring_areas[l_prev->v] += areaf;
- sys->ring_areas[l_curr->v] += areaf;
- sys->ring_areas[l_next->v] += areaf;
-
- w1 = cotangent_tri_weight_v3(v_curr, v_next, v_prev) / 2.0f;
- w2 = cotangent_tri_weight_v3(v_next, v_prev, v_curr) / 2.0f;
- w3 = cotangent_tri_weight_v3(v_prev, v_curr, v_next) / 2.0f;
-
- sys->fweights[l_curr_index][0] += w1;
- sys->fweights[l_curr_index][1] += w2;
- sys->fweights[l_curr_index][2] += w3;
-
- sys->vweights[l_curr->v] += w2 + w3;
- sys->vweights[l_next->v] += w1 + w3;
- sys->vweights[l_prev->v] += w1 + w2;
- }
- }
- for (i = 0; i < sys->numEdges; i++) {
- idv1 = sys->medges[i].v1;
- idv2 = sys->medges[i].v2;
- /* if is boundary, apply scale-dependent umbrella operator only with neighbors in boundary */
- if (sys->numNeEd[idv1] != sys->numNeFa[idv1] && sys->numNeEd[idv2] != sys->numNeFa[idv2]) {
- sys->vlengths[idv1] += sys->eweights[i];
- sys->vlengths[idv2] += sys->eweights[i];
- }
- }
-
+ float *v1, *v2;
+ float w1, w2, w3;
+ float areaf;
+ int i;
+ unsigned int idv1, idv2;
+
+ for (i = 0; i < sys->numEdges; i++) {
+ idv1 = sys->medges[i].v1;
+ idv2 = sys->medges[i].v2;
+
+ v1 = sys->vertexCos[idv1];
+ v2 = sys->vertexCos[idv2];
+
+ sys->numNeEd[idv1] = sys->numNeEd[idv1] + 1;
+ sys->numNeEd[idv2] = sys->numNeEd[idv2] + 1;
+ w1 = len_v3v3(v1, v2);
+ if (w1 < sys->min_area) {
+ sys->zerola[idv1] = 1;
+ sys->zerola[idv2] = 1;
+ }
+ else {
+ w1 = 1.0f / w1;
+ }
+
+ sys->eweights[i] = w1;
+ }
+
+ for (i = 0; i < sys->numPolys; i++) {
+ const MPoly *mp = &sys->mpoly[i];
+ const MLoop *l_next = &sys->mloop[mp->loopstart];
+ const MLoop *l_term = l_next + mp->totloop;
+ const MLoop *l_prev = l_term - 2;
+ const MLoop *l_curr = l_term - 1;
+
+ for (; l_next != l_term; l_prev = l_curr, l_curr = l_next, l_next++) {
+ const float *v_prev = sys->vertexCos[l_prev->v];
+ const float *v_curr = sys->vertexCos[l_curr->v];
+ const float *v_next = sys->vertexCos[l_next->v];
+ const unsigned int l_curr_index = l_curr - sys->mloop;
+
+ sys->numNeFa[l_curr->v] += 1;
+
+ areaf = area_tri_v3(v_prev, v_curr, v_next);
+
+ if (areaf < sys->min_area) {
+ sys->zerola[l_curr->v] = 1;
+ }
+
+ sys->ring_areas[l_prev->v] += areaf;
+ sys->ring_areas[l_curr->v] += areaf;
+ sys->ring_areas[l_next->v] += areaf;
+
+ w1 = cotangent_tri_weight_v3(v_curr, v_next, v_prev) / 2.0f;
+ w2 = cotangent_tri_weight_v3(v_next, v_prev, v_curr) / 2.0f;
+ w3 = cotangent_tri_weight_v3(v_prev, v_curr, v_next) / 2.0f;
+
+ sys->fweights[l_curr_index][0] += w1;
+ sys->fweights[l_curr_index][1] += w2;
+ sys->fweights[l_curr_index][2] += w3;
+
+ sys->vweights[l_curr->v] += w2 + w3;
+ sys->vweights[l_next->v] += w1 + w3;
+ sys->vweights[l_prev->v] += w1 + w2;
+ }
+ }
+ for (i = 0; i < sys->numEdges; i++) {
+ idv1 = sys->medges[i].v1;
+ idv2 = sys->medges[i].v2;
+ /* if is boundary, apply scale-dependent umbrella operator only with neighbors in boundary */
+ if (sys->numNeEd[idv1] != sys->numNeFa[idv1] && sys->numNeEd[idv2] != sys->numNeFa[idv2]) {
+ sys->vlengths[idv1] += sys->eweights[i];
+ sys->vlengths[idv2] += sys->eweights[i];
+ }
+ }
}
static void fill_laplacian_matrix(LaplacianSystem *sys)
{
- int i;
- unsigned int idv1, idv2;
-
- for (i = 0; i < sys->numPolys; i++) {
- const MPoly *mp = &sys->mpoly[i];
- const MLoop *l_next = &sys->mloop[mp->loopstart];
- const MLoop *l_term = l_next + mp->totloop;
- const MLoop *l_prev = l_term - 2;
- const MLoop *l_curr = l_term - 1;
-
- for (;
- l_next != l_term;
- l_prev = l_curr, l_curr = l_next, l_next++)
- {
- const unsigned int l_curr_index = l_curr - sys->mloop;
-
- /* Is ring if number of faces == number of edges around vertice*/
- if (sys->numNeEd[l_curr->v] == sys->numNeFa[l_curr->v] && sys->zerola[l_curr->v] == 0) {
- EIG_linear_solver_matrix_add(sys->context, l_curr->v, l_next->v, sys->fweights[l_curr_index][2] * sys->vweights[l_curr->v]);
- EIG_linear_solver_matrix_add(sys->context, l_curr->v, l_prev->v, sys->fweights[l_curr_index][1] * sys->vweights[l_curr->v]);
- }
- if (sys->numNeEd[l_next->v] == sys->numNeFa[l_next->v] && sys->zerola[l_next->v] == 0) {
- EIG_linear_solver_matrix_add(sys->context, l_next->v, l_curr->v, sys->fweights[l_curr_index][2] * sys->vweights[l_next->v]);
- EIG_linear_solver_matrix_add(sys->context, l_next->v, l_prev->v, sys->fweights[l_curr_index][0] * sys->vweights[l_next->v]);
- }
- if (sys->numNeEd[l_prev->v] == sys->numNeFa[l_prev->v] && sys->zerola[l_prev->v] == 0) {
- EIG_linear_solver_matrix_add(sys->context, l_prev->v, l_curr->v, sys->fweights[l_curr_index][1] * sys->vweights[l_prev->v]);
- EIG_linear_solver_matrix_add(sys->context, l_prev->v, l_next->v, sys->fweights[l_curr_index][0] * sys->vweights[l_prev->v]);
- }
- }
- }
-
- for (i = 0; i < sys->numEdges; i++) {
- idv1 = sys->medges[i].v1;
- idv2 = sys->medges[i].v2;
- /* Is boundary */
- if (sys->numNeEd[idv1] != sys->numNeFa[idv1] &&
- sys->numNeEd[idv2] != sys->numNeFa[idv2] &&
- sys->zerola[idv1] == 0 &&
- sys->zerola[idv2] == 0)
- {
- EIG_linear_solver_matrix_add(sys->context, idv1, idv2, sys->eweights[i] * sys->vlengths[idv1]);
- EIG_linear_solver_matrix_add(sys->context, idv2, idv1, sys->eweights[i] * sys->vlengths[idv2]);
- }
- }
+ int i;
+ unsigned int idv1, idv2;
+
+ for (i = 0; i < sys->numPolys; i++) {
+ const MPoly *mp = &sys->mpoly[i];
+ const MLoop *l_next = &sys->mloop[mp->loopstart];
+ const MLoop *l_term = l_next + mp->totloop;
+ const MLoop *l_prev = l_term - 2;
+ const MLoop *l_curr = l_term - 1;
+
+ for (; l_next != l_term; l_prev = l_curr, l_curr = l_next, l_next++) {
+ const unsigned int l_curr_index = l_curr - sys->mloop;
+
+ /* Is ring if number of faces == number of edges around vertice*/
+ if (sys->numNeEd[l_curr->v] == sys->numNeFa[l_curr->v] && sys->zerola[l_curr->v] == 0) {
+ EIG_linear_solver_matrix_add(sys->context,
+ l_curr->v,
+ l_next->v,
+ sys->fweights[l_curr_index][2] * sys->vweights[l_curr->v]);
+ EIG_linear_solver_matrix_add(sys->context,
+ l_curr->v,
+ l_prev->v,
+ sys->fweights[l_curr_index][1] * sys->vweights[l_curr->v]);
+ }
+ if (sys->numNeEd[l_next->v] == sys->numNeFa[l_next->v] && sys->zerola[l_next->v] == 0) {
+ EIG_linear_solver_matrix_add(sys->context,
+ l_next->v,
+ l_curr->v,
+ sys->fweights[l_curr_index][2] * sys->vweights[l_next->v]);
+ EIG_linear_solver_matrix_add(sys->context,
+ l_next->v,
+ l_prev->v,
+ sys->fweights[l_curr_index][0] * sys->vweights[l_next->v]);
+ }
+ if (sys->numNeEd[l_prev->v] == sys->numNeFa[l_prev->v] && sys->zerola[l_prev->v] == 0) {
+ EIG_linear_solver_matrix_add(sys->context,
+ l_prev->v,
+ l_curr->v,
+ sys->fweights[l_curr_index][1] * sys->vweights[l_prev->v]);
+ EIG_linear_solver_matrix_add(sys->context,
+ l_prev->v,
+ l_next->v,
+ sys->fweights[l_curr_index][0] * sys->vweights[l_prev->v]);
+ }
+ }
+ }
+
+ for (i = 0; i < sys->numEdges; i++) {
+ idv1 = sys->medges[i].v1;
+ idv2 = sys->medges[i].v2;
+ /* Is boundary */
+ if (sys->numNeEd[idv1] != sys->numNeFa[idv1] && sys->numNeEd[idv2] != sys->numNeFa[idv2] &&
+ sys->zerola[idv1] == 0 && sys->zerola[idv2] == 0) {
+ EIG_linear_solver_matrix_add(
+ sys->context, idv1, idv2, sys->eweights[i] * sys->vlengths[idv1]);
+ EIG_linear_solver_matrix_add(
+ sys->context, idv2, idv1, sys->eweights[i] * sys->vlengths[idv2]);
+ }
+ }
}
static void validate_solution(LaplacianSystem *sys, short flag, float lambda, float lambda_border)
{
- int i;
- float lam;
- float vini = 0.0f, vend = 0.0f;
-
- if (flag & MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME) {
- vini = compute_volume(sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->numPolys, sys->mloop);
- }
- for (i = 0; i < sys->numVerts; i++) {
- if (sys->zerola[i] == 0) {
- lam = sys->numNeEd[i] == sys->numNeFa[i] ? (lambda >= 0.0f ? 1.0f : -1.0f) : (lambda_border >= 0.0f ? 1.0f : -1.0f);
- if (flag & MOD_LAPLACIANSMOOTH_X) {
- sys->vertexCos[i][0] += lam * ((float)EIG_linear_solver_variable_get(sys->context, 0, i) - sys->vertexCos[i][0]);
- }
- if (flag & MOD_LAPLACIANSMOOTH_Y) {
- sys->vertexCos[i][1] += lam * ((float)EIG_linear_solver_variable_get(sys->context, 1, i) - sys->vertexCos[i][1]);
- }
- if (flag & MOD_LAPLACIANSMOOTH_Z) {
- sys->vertexCos[i][2] += lam * ((float)EIG_linear_solver_variable_get(sys->context, 2, i) - sys->vertexCos[i][2]);
- }
- }
- }
- if (flag & MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME) {
- vend = compute_volume(sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->numPolys, sys->mloop);
- volume_preservation(sys, vini, vend, flag);
- }
+ int i;
+ float lam;
+ float vini = 0.0f, vend = 0.0f;
+
+ if (flag & MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME) {
+ vini = compute_volume(
+ sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->numPolys, sys->mloop);
+ }
+ for (i = 0; i < sys->numVerts; i++) {
+ if (sys->zerola[i] == 0) {
+ lam = sys->numNeEd[i] == sys->numNeFa[i] ? (lambda >= 0.0f ? 1.0f : -1.0f) :
+ (lambda_border >= 0.0f ? 1.0f : -1.0f);
+ if (flag & MOD_LAPLACIANSMOOTH_X) {
+ sys->vertexCos[i][0] += lam * ((float)EIG_linear_solver_variable_get(sys->context, 0, i) -
+ sys->vertexCos[i][0]);
+ }
+ if (flag & MOD_LAPLACIANSMOOTH_Y) {
+ sys->vertexCos[i][1] += lam * ((float)EIG_linear_solver_variable_get(sys->context, 1, i) -
+ sys->vertexCos[i][1]);
+ }
+ if (flag & MOD_LAPLACIANSMOOTH_Z) {
+ sys->vertexCos[i][2] += lam * ((float)EIG_linear_solver_variable_get(sys->context, 2, i) -
+ sys->vertexCos[i][2]);
+ }
+ }
+ }
+ if (flag & MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME) {
+ vend = compute_volume(
+ sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->numPolys, sys->mloop);
+ volume_preservation(sys, vini, vend, flag);
+ }
}
static void laplaciansmoothModifier_do(
- LaplacianSmoothModifierData *smd, Object *ob, Mesh *mesh,
- float (*vertexCos)[3], int numVerts)
+ LaplacianSmoothModifierData *smd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int numVerts)
{
- LaplacianSystem *sys;
- MDeformVert *dvert = NULL;
- MDeformVert *dv = NULL;
- float w, wpaint;
- int i, iter;
- int defgrp_index;
-
- sys = init_laplacian_system(mesh->totedge, mesh->totpoly, mesh->totloop, numVerts);
- if (!sys) {
- return;
- }
-
- sys->mpoly = mesh->mpoly;
- sys->mloop = mesh->mloop;
- sys->medges = mesh->medge;
- sys->vertexCos = vertexCos;
- sys->min_area = 0.00001f;
- MOD_get_vgroup(ob, mesh, smd->defgrp_name, &dvert, &defgrp_index);
-
- sys->vert_centroid[0] = 0.0f;
- sys->vert_centroid[1] = 0.0f;
- sys->vert_centroid[2] = 0.0f;
- memset_laplacian_system(sys, 0);
-
- sys->context = EIG_linear_least_squares_solver_new(numVerts, numVerts, 3);
-
- init_laplacian_matrix(sys);
-
- for (iter = 0; iter < smd->repeat; iter++) {
- for (i = 0; i < numVerts; i++) {
- EIG_linear_solver_variable_set(sys->context, 0, i, vertexCos[i][0]);
- EIG_linear_solver_variable_set(sys->context, 1, i, vertexCos[i][1]);
- EIG_linear_solver_variable_set(sys->context, 2, i, vertexCos[i][2]);
- if (iter == 0) {
- add_v3_v3(sys->vert_centroid, vertexCos[i]);
- }
- }
- if (iter == 0 && numVerts > 0) {
- mul_v3_fl(sys->vert_centroid, 1.0f / (float)numVerts);
- }
-
- dv = dvert;
- for (i = 0; i < numVerts; i++) {
- EIG_linear_solver_right_hand_side_add(sys->context, 0, i, vertexCos[i][0]);
- EIG_linear_solver_right_hand_side_add(sys->context, 1, i, vertexCos[i][1]);
- EIG_linear_solver_right_hand_side_add(sys->context, 2, i, vertexCos[i][2]);
- if (iter == 0) {
- if (dv) {
- wpaint = defvert_find_weight(dv, defgrp_index);
- dv++;
- }
- else {
- wpaint = 1.0f;
- }
-
- if (sys->zerola[i] == 0) {
- if (smd->flag & MOD_LAPLACIANSMOOTH_NORMALIZED) {
- w = sys->vweights[i];
- sys->vweights[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda) * wpaint / w;
- w = sys->vlengths[i];
- sys->vlengths[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda_border) * wpaint * 2.0f / w;
- if (sys->numNeEd[i] == sys->numNeFa[i]) {
- EIG_linear_solver_matrix_add(sys->context, i, i, 1.0f + fabsf(smd->lambda) * wpaint);
- }
- else {
- EIG_linear_solver_matrix_add(sys->context, i, i, 1.0f + fabsf(smd->lambda_border) * wpaint * 2.0f);
- }
- }
- else {
- w = sys->vweights[i] * sys->ring_areas[i];
- sys->vweights[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda) * wpaint / (4.0f * w);
- w = sys->vlengths[i];
- sys->vlengths[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda_border) * wpaint * 2.0f / w;
-
- if (sys->numNeEd[i] == sys->numNeFa[i]) {
- EIG_linear_solver_matrix_add(sys->context, i, i, 1.0f + fabsf(smd->lambda) * wpaint / (4.0f * sys->ring_areas[i]));
- }
- else {
- EIG_linear_solver_matrix_add(sys->context, i, i, 1.0f + fabsf(smd->lambda_border) * wpaint * 2.0f);
- }
- }
- }
- else {
- EIG_linear_solver_matrix_add(sys->context, i, i, 1.0f);
- }
- }
- }
-
- if (iter == 0) {
- fill_laplacian_matrix(sys);
- }
-
- if (EIG_linear_solver_solve(sys->context)) {
- validate_solution(sys, smd->flag, smd->lambda, smd->lambda_border);
- }
- }
- EIG_linear_solver_delete(sys->context);
- sys->context = NULL;
-
- delete_laplacian_system(sys);
+ LaplacianSystem *sys;
+ MDeformVert *dvert = NULL;
+ MDeformVert *dv = NULL;
+ float w, wpaint;
+ int i, iter;
+ int defgrp_index;
+
+ sys = init_laplacian_system(mesh->totedge, mesh->totpoly, mesh->totloop, numVerts);
+ if (!sys) {
+ return;
+ }
+
+ sys->mpoly = mesh->mpoly;
+ sys->mloop = mesh->mloop;
+ sys->medges = mesh->medge;
+ sys->vertexCos = vertexCos;
+ sys->min_area = 0.00001f;
+ MOD_get_vgroup(ob, mesh, smd->defgrp_name, &dvert, &defgrp_index);
+
+ sys->vert_centroid[0] = 0.0f;
+ sys->vert_centroid[1] = 0.0f;
+ sys->vert_centroid[2] = 0.0f;
+ memset_laplacian_system(sys, 0);
+
+ sys->context = EIG_linear_least_squares_solver_new(numVerts, numVerts, 3);
+
+ init_laplacian_matrix(sys);
+
+ for (iter = 0; iter < smd->repeat; iter++) {
+ for (i = 0; i < numVerts; i++) {
+ EIG_linear_solver_variable_set(sys->context, 0, i, vertexCos[i][0]);
+ EIG_linear_solver_variable_set(sys->context, 1, i, vertexCos[i][1]);
+ EIG_linear_solver_variable_set(sys->context, 2, i, vertexCos[i][2]);
+ if (iter == 0) {
+ add_v3_v3(sys->vert_centroid, vertexCos[i]);
+ }
+ }
+ if (iter == 0 && numVerts > 0) {
+ mul_v3_fl(sys->vert_centroid, 1.0f / (float)numVerts);
+ }
+
+ dv = dvert;
+ for (i = 0; i < numVerts; i++) {
+ EIG_linear_solver_right_hand_side_add(sys->context, 0, i, vertexCos[i][0]);
+ EIG_linear_solver_right_hand_side_add(sys->context, 1, i, vertexCos[i][1]);
+ EIG_linear_solver_right_hand_side_add(sys->context, 2, i, vertexCos[i][2]);
+ if (iter == 0) {
+ if (dv) {
+ wpaint = defvert_find_weight(dv, defgrp_index);
+ dv++;
+ }
+ else {
+ wpaint = 1.0f;
+ }
+
+ if (sys->zerola[i] == 0) {
+ if (smd->flag & MOD_LAPLACIANSMOOTH_NORMALIZED) {
+ w = sys->vweights[i];
+ sys->vweights[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda) * wpaint / w;
+ w = sys->vlengths[i];
+ sys->vlengths[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda_border) * wpaint * 2.0f / w;
+ if (sys->numNeEd[i] == sys->numNeFa[i]) {
+ EIG_linear_solver_matrix_add(sys->context, i, i, 1.0f + fabsf(smd->lambda) * wpaint);
+ }
+ else {
+ EIG_linear_solver_matrix_add(
+ sys->context, i, i, 1.0f + fabsf(smd->lambda_border) * wpaint * 2.0f);
+ }
+ }
+ else {
+ w = sys->vweights[i] * sys->ring_areas[i];
+ sys->vweights[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda) * wpaint / (4.0f * w);
+ w = sys->vlengths[i];
+ sys->vlengths[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda_border) * wpaint * 2.0f / w;
+
+ if (sys->numNeEd[i] == sys->numNeFa[i]) {
+ EIG_linear_solver_matrix_add(sys->context,
+ i,
+ i,
+ 1.0f + fabsf(smd->lambda) * wpaint /
+ (4.0f * sys->ring_areas[i]));
+ }
+ else {
+ EIG_linear_solver_matrix_add(
+ sys->context, i, i, 1.0f + fabsf(smd->lambda_border) * wpaint * 2.0f);
+ }
+ }
+ }
+ else {
+ EIG_linear_solver_matrix_add(sys->context, i, i, 1.0f);
+ }
+ }
+ }
+
+ if (iter == 0) {
+ fill_laplacian_matrix(sys);
+ }
+
+ if (EIG_linear_solver_solve(sys->context)) {
+ validate_solution(sys, smd->flag, smd->lambda, smd->lambda_border);
+ }
+ }
+ EIG_linear_solver_delete(sys->context);
+ sys->context = NULL;
+
+ delete_laplacian_system(sys);
}
static void init_data(ModifierData *md)
{
- LaplacianSmoothModifierData *smd = (LaplacianSmoothModifierData *) md;
- smd->lambda = 0.01f;
- smd->lambda_border = 0.01f;
- smd->repeat = 1;
- smd->flag = MOD_LAPLACIANSMOOTH_X | MOD_LAPLACIANSMOOTH_Y | MOD_LAPLACIANSMOOTH_Z | MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME | MOD_LAPLACIANSMOOTH_NORMALIZED;
- smd->defgrp_name[0] = '\0';
+ LaplacianSmoothModifierData *smd = (LaplacianSmoothModifierData *)md;
+ smd->lambda = 0.01f;
+ smd->lambda_border = 0.01f;
+ smd->repeat = 1;
+ smd->flag = MOD_LAPLACIANSMOOTH_X | MOD_LAPLACIANSMOOTH_Y | MOD_LAPLACIANSMOOTH_Z |
+ MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME | MOD_LAPLACIANSMOOTH_NORMALIZED;
+ smd->defgrp_name[0] = '\0';
}
-static bool is_disabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
+static bool is_disabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(useRenderParams))
{
- LaplacianSmoothModifierData *smd = (LaplacianSmoothModifierData *) md;
- short flag;
+ LaplacianSmoothModifierData *smd = (LaplacianSmoothModifierData *)md;
+ short flag;
- flag = smd->flag & (MOD_LAPLACIANSMOOTH_X | MOD_LAPLACIANSMOOTH_Y | MOD_LAPLACIANSMOOTH_Z);
+ flag = smd->flag & (MOD_LAPLACIANSMOOTH_X | MOD_LAPLACIANSMOOTH_Y | MOD_LAPLACIANSMOOTH_Z);
- /* disable if modifier is off for X, Y and Z or if factor is 0 */
- if (flag == 0) return 1;
+ /* disable if modifier is off for X, Y and Z or if factor is 0 */
+ if (flag == 0)
+ return 1;
- return 0;
+ return 0;
}
-static void required_data_mask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void required_data_mask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- LaplacianSmoothModifierData *smd = (LaplacianSmoothModifierData *)md;
+ LaplacianSmoothModifierData *smd = (LaplacianSmoothModifierData *)md;
- /* ask for vertexgroups if we need them */
- if (smd->defgrp_name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ /* ask for vertexgroups if we need them */
+ if (smd->defgrp_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
-static void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh,
- float (*vertexCos)[3], int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- Mesh *mesh_src;
+ Mesh *mesh_src;
- if (numVerts == 0)
- return;
+ if (numVerts == 0)
+ return;
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
- laplaciansmoothModifier_do((LaplacianSmoothModifierData *)md, ctx->object, mesh_src,
- vertexCos, numVerts);
+ laplaciansmoothModifier_do(
+ (LaplacianSmoothModifierData *)md, ctx->object, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-static void deformVertsEM(
- ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *editData,
- Mesh *mesh, float (*vertexCos)[3], int numVerts)
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *editData,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- Mesh *mesh_src;
+ Mesh *mesh_src;
- if (numVerts == 0)
- return;
+ if (numVerts == 0)
+ return;
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
- laplaciansmoothModifier_do((LaplacianSmoothModifierData *)md, ctx->object, mesh_src,
- vertexCos, numVerts);
+ laplaciansmoothModifier_do(
+ (LaplacianSmoothModifierData *)md, ctx->object, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-
ModifierTypeInfo modifierType_LaplacianSmooth = {
- /* name */ "Laplacian Smooth",
- /* structName */ "LaplacianSmoothModifierData",
- /* structSize */ sizeof(LaplacianSmoothModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ init_data,
- /* requiredDataMask */ required_data_mask,
- /* freeData */ NULL,
- /* isDisabled */ is_disabled,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Laplacian Smooth",
+ /* structName */ "LaplacianSmoothModifierData",
+ /* structSize */ sizeof(LaplacianSmoothModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ init_data,
+ /* requiredDataMask */ required_data_mask,
+ /* freeData */ NULL,
+ /* isDisabled */ is_disabled,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c
index 4715d2ab073..b639e874a88 100644
--- a/source/blender/modifiers/intern/MOD_lattice.c
+++ b/source/blender/modifiers/intern/MOD_lattice.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include <string.h>
#include "BLI_utildefines.h"
@@ -43,105 +42,110 @@
static void initData(ModifierData *md)
{
- LatticeModifierData *lmd = (LatticeModifierData *) md;
- lmd->strength = 1.0f;
+ LatticeModifierData *lmd = (LatticeModifierData *)md;
+ lmd->strength = 1.0f;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- LatticeModifierData *lmd = (LatticeModifierData *)md;
+ LatticeModifierData *lmd = (LatticeModifierData *)md;
- /* ask for vertexgroups if we need them */
- if (lmd->name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ /* ask for vertexgroups if we need them */
+ if (lmd->name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(userRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(userRenderParams))
{
- LatticeModifierData *lmd = (LatticeModifierData *) md;
+ LatticeModifierData *lmd = (LatticeModifierData *)md;
- return !lmd->object;
+ return !lmd->object;
}
-static void foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- LatticeModifierData *lmd = (LatticeModifierData *) md;
+ LatticeModifierData *lmd = (LatticeModifierData *)md;
- walk(userData, ob, &lmd->object, IDWALK_CB_NOP);
+ walk(userData, ob, &lmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- LatticeModifierData *lmd = (LatticeModifierData *)md;
- if (lmd->object != NULL) {
- DEG_add_object_relation(ctx->node, lmd->object, DEG_OB_COMP_GEOMETRY, "Lattice Modifier");
- DEG_add_object_relation(ctx->node, lmd->object, DEG_OB_COMP_TRANSFORM, "Lattice Modifier");
- }
- DEG_add_modifier_to_transform_relation(ctx->node, "Lattice Modifier");
+ LatticeModifierData *lmd = (LatticeModifierData *)md;
+ if (lmd->object != NULL) {
+ DEG_add_object_relation(ctx->node, lmd->object, DEG_OB_COMP_GEOMETRY, "Lattice Modifier");
+ DEG_add_object_relation(ctx->node, lmd->object, DEG_OB_COMP_TRANSFORM, "Lattice Modifier");
+ }
+ DEG_add_modifier_to_transform_relation(ctx->node, "Lattice Modifier");
}
-static void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx,
- struct Mesh *mesh,
- float (*vertexCos)[3],
- int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- LatticeModifierData *lmd = (LatticeModifierData *) md;
- struct Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ LatticeModifierData *lmd = (LatticeModifierData *)md;
+ struct Mesh *mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, NULL, mesh, NULL, numVerts, false, false);
- MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
+ MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
- lattice_deform_verts(lmd->object, ctx->object, mesh_src,
- vertexCos, numVerts, lmd->name, lmd->strength);
+ lattice_deform_verts(
+ lmd->object, ctx->object, mesh_src, vertexCos, numVerts, lmd->name, lmd->strength);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-static void deformVertsEM(
- ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *em,
- struct Mesh *mesh, float (*vertexCos)[3], int numVerts)
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *em,
+ struct Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- struct Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false);
+ struct Mesh *mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, em, mesh, NULL, numVerts, false, false);
- deformVerts(md, ctx, mesh_src, vertexCos, numVerts);
+ deformVerts(md, ctx, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-
ModifierTypeInfo modifierType_Lattice = {
- /* name */ "Lattice",
- /* structName */ "LatticeModifierData",
- /* structSize */ sizeof(LatticeModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_AcceptsLattice |
- eModifierTypeFlag_SupportsEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Lattice",
+ /* structName */ "LatticeModifierData",
+ /* structSize */ sizeof(LatticeModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice |
+ eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c
index efb299773ef..a13e75c76de 100644
--- a/source/blender/modifiers/intern/MOD_mask.c
+++ b/source/blender/modifiers/intern/MOD_mask.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
@@ -49,329 +48,324 @@
#include "BLI_strict_flags.h"
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md), CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *UNUSED(md),
+ CustomData_MeshMasks *r_cddata_masks)
{
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
}
-static void foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- MaskModifierData *mmd = (MaskModifierData *)md;
- walk(userData, ob, &mmd->ob_arm, IDWALK_CB_NOP);
+ MaskModifierData *mmd = (MaskModifierData *)md;
+ walk(userData, ob, &mmd->ob_arm, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- MaskModifierData *mmd = (MaskModifierData *)md;
- if (mmd->ob_arm) {
- bArmature *arm = (bArmature *)mmd->ob_arm->data;
- /* Tag relationship in depsgraph, but also on the armature. */
- /* TODO(sergey): Is it a proper relation here? */
- DEG_add_object_relation(ctx->node, mmd->ob_arm, DEG_OB_COMP_TRANSFORM, "Mask Modifier");
- arm->flag |= ARM_HAS_VIZ_DEPS;
- DEG_add_modifier_to_transform_relation(ctx->node, "Mask Modifier");
- }
+ MaskModifierData *mmd = (MaskModifierData *)md;
+ if (mmd->ob_arm) {
+ bArmature *arm = (bArmature *)mmd->ob_arm->data;
+ /* Tag relationship in depsgraph, but also on the armature. */
+ /* TODO(sergey): Is it a proper relation here? */
+ DEG_add_object_relation(ctx->node, mmd->ob_arm, DEG_OB_COMP_TRANSFORM, "Mask Modifier");
+ arm->flag |= ARM_HAS_VIZ_DEPS;
+ DEG_add_modifier_to_transform_relation(ctx->node, "Mask Modifier");
+ }
}
static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- MaskModifierData *mmd = (MaskModifierData *)md;
- Object *ob = ctx->object;
- const bool found_test = (mmd->flag & MOD_MASK_INV) == 0;
- Mesh *result = NULL;
- GHash *vertHash = NULL, *edgeHash, *polyHash;
- GHashIterator gh_iter;
- MDeformVert *dvert, *dv;
- int numPolys = 0, numLoops = 0, numEdges = 0, numVerts = 0;
- int maxVerts, maxEdges, maxPolys;
- int i;
-
- const MVert *mvert_src;
- const MEdge *medge_src;
- const MPoly *mpoly_src;
- const MLoop *mloop_src;
-
- MPoly *mpoly_dst;
- MLoop *mloop_dst;
- MEdge *medge_dst;
- MVert *mvert_dst;
-
- int *loop_mapping;
-
- dvert = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT);
- if (dvert == NULL) {
- return found_test ? BKE_mesh_new_nomain_from_template(mesh, 0, 0, 0, 0, 0) : mesh;
- }
-
- /* Overview of Method:
- * 1. Get the vertices that are in the vertexgroup of interest
- * 2. Filter out unwanted geometry (i.e. not in vertexgroup), by populating mappings with new vs old indices
- * 3. Make a new mesh containing only the mapping data
- */
-
- /* get original number of verts, edges, and faces */
- maxVerts = mesh->totvert;
- maxEdges = mesh->totedge;
- maxPolys = mesh->totpoly;
-
- /* check if we can just return the original mesh
- * - must have verts and therefore verts assigned to vgroups to do anything useful
- */
- if (!(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) ||
- (maxVerts == 0) || BLI_listbase_is_empty(&ob->defbase))
- {
- return mesh;
- }
-
- /* if mode is to use selected armature bones, aggregate the bone groups */
- if (mmd->mode == MOD_MASK_MODE_ARM) { /* --- using selected bones --- */
- Object *oba = mmd->ob_arm;
- bPoseChannel *pchan;
- bDeformGroup *def;
- bool *bone_select_array;
- int bone_select_tot = 0;
- const int defbase_tot = BLI_listbase_count(&ob->defbase);
-
- /* check that there is armature object with bones to use, otherwise return original mesh */
- if (ELEM(NULL, oba, oba->pose, ob->defbase.first)) {
- return mesh;
- }
-
- /* determine whether each vertexgroup is associated with a selected bone or not
- * - each cell is a boolean saying whether bone corresponding to the ith group is selected
- * - groups that don't match a bone are treated as not existing (along with the corresponding ungrouped verts)
- */
- bone_select_array = MEM_malloc_arrayN((size_t)defbase_tot, sizeof(char), "mask array");
-
- for (i = 0, def = ob->defbase.first; def; def = def->next, i++) {
- pchan = BKE_pose_channel_find_name(oba->pose, def->name);
- if (pchan && pchan->bone && (pchan->bone->flag & BONE_SELECTED)) {
- bone_select_array[i] = true;
- bone_select_tot++;
- }
- else {
- bone_select_array[i] = false;
- }
- }
-
- /* verthash gives mapping from original vertex indices to the new indices (including selected matches only)
- * key = oldindex, value = newindex
- */
- vertHash = BLI_ghash_int_new_ex("mask vert gh", (unsigned int)maxVerts);
-
- /* add vertices which exist in vertexgroups into vertHash for filtering
- * - dv = for each vertex, what vertexgroups does it belong to
- * - dw = weight that vertex was assigned to a vertexgroup it belongs to
- */
- for (i = 0, dv = dvert; i < maxVerts; i++, dv++) {
- MDeformWeight *dw = dv->dw;
- bool found = false;
- int j;
-
- /* check the groups that vertex is assigned to, and see if it was any use */
- for (j = 0; j < dv->totweight; j++, dw++) {
- if (dw->def_nr < defbase_tot) {
- if (bone_select_array[dw->def_nr]) {
- if (dw->weight > mmd->threshold) {
- found = true;
- break;
- }
- }
- }
- }
-
- if (found_test != found) {
- continue;
- }
-
- /* add to ghash for verts (numVerts acts as counter for mapping) */
- BLI_ghash_insert(vertHash, POINTER_FROM_INT(i), POINTER_FROM_INT(numVerts));
- numVerts++;
- }
-
- /* free temp hashes */
- MEM_freeN(bone_select_array);
- }
- else { /* --- Using Nominated VertexGroup only --- */
- int defgrp_index = defgroup_name_index(ob, mmd->vgroup);
-
- /* if no vgroup (i.e. dverts) found, return the initial mesh */
- if (defgrp_index == -1) {
- return mesh;
- }
-
- /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
- vertHash = BLI_ghash_int_new_ex("mask vert2 bh", (unsigned int)maxVerts);
-
- /* add vertices which exist in vertexgroup into ghash for filtering */
- for (i = 0, dv = dvert; i < maxVerts; i++, dv++) {
- const bool found = defvert_find_weight(dv, defgrp_index) > mmd->threshold;
- if (found_test != found) {
- continue;
- }
-
- /* add to ghash for verts (numVerts acts as counter for mapping) */
- BLI_ghash_insert(vertHash, POINTER_FROM_INT(i), POINTER_FROM_INT(numVerts));
- numVerts++;
- }
- }
-
- /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
- edgeHash = BLI_ghash_int_new_ex("mask ed2 gh", (unsigned int)maxEdges);
- polyHash = BLI_ghash_int_new_ex("mask fa2 gh", (unsigned int)maxPolys);
-
- mvert_src = mesh->mvert;
- medge_src = mesh->medge;
- mpoly_src = mesh->mpoly;
- mloop_src = mesh->mloop;
-
- /* overalloc, assume all polys are seen */
- loop_mapping = MEM_malloc_arrayN((size_t)maxPolys, sizeof(int), "mask loopmap");
-
- /* loop over edges and faces, and do the same thing to
- * ensure that they only reference existing verts
- */
- for (i = 0; i < maxEdges; i++) {
- const MEdge *me = &medge_src[i];
-
- /* only add if both verts will be in new mesh */
- if (BLI_ghash_haskey(vertHash, POINTER_FROM_INT(me->v1)) &&
- BLI_ghash_haskey(vertHash, POINTER_FROM_INT(me->v2)))
- {
- BLI_ghash_insert(edgeHash, POINTER_FROM_INT(i), POINTER_FROM_INT(numEdges));
- numEdges++;
- }
- }
- for (i = 0; i < maxPolys; i++) {
- const MPoly *mp_src = &mpoly_src[i];
- const MLoop *ml_src = &mloop_src[mp_src->loopstart];
- bool ok = true;
- int j;
-
- for (j = 0; j < mp_src->totloop; j++, ml_src++) {
- if (!BLI_ghash_haskey(vertHash, POINTER_FROM_INT(ml_src->v))) {
- ok = false;
- break;
- }
- }
-
- /* all verts must be available */
- if (ok) {
- BLI_ghash_insert(polyHash, POINTER_FROM_INT(i), POINTER_FROM_INT(numPolys));
- loop_mapping[numPolys] = numLoops;
- numPolys++;
- numLoops += mp_src->totloop;
- }
- }
-
-
- /* now we know the number of verts, edges and faces,
- * we can create the new (reduced) mesh
- */
- result = BKE_mesh_new_nomain_from_template(mesh, numVerts, numEdges, 0, numLoops, numPolys);
-
- mpoly_dst = result->mpoly;
- mloop_dst = result->mloop;
- medge_dst = result->medge;
- mvert_dst = result->mvert;
-
- /* using ghash-iterators, map data into new mesh */
- /* vertices */
- GHASH_ITER (gh_iter, vertHash) {
- const MVert *v_src;
- MVert *v_dst;
- const int i_src = POINTER_AS_INT(BLI_ghashIterator_getKey(&gh_iter));
- const int i_dst = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter));
-
- v_src = &mvert_src[i_src];
- v_dst = &mvert_dst[i_dst];
-
- *v_dst = *v_src;
- CustomData_copy_data(&mesh->vdata, &result->vdata, i_src, i_dst, 1);
- }
-
- /* edges */
- GHASH_ITER (gh_iter, edgeHash) {
- const MEdge *e_src;
- MEdge *e_dst;
- const int i_src = POINTER_AS_INT(BLI_ghashIterator_getKey(&gh_iter));
- const int i_dst = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter));
-
- e_src = &medge_src[i_src];
- e_dst = &medge_dst[i_dst];
-
- CustomData_copy_data(&mesh->edata, &result->edata, i_src, i_dst, 1);
- *e_dst = *e_src;
- e_dst->v1 = POINTER_AS_UINT(BLI_ghash_lookup(vertHash, POINTER_FROM_UINT(e_src->v1)));
- e_dst->v2 = POINTER_AS_UINT(BLI_ghash_lookup(vertHash, POINTER_FROM_UINT(e_src->v2)));
- }
-
- /* faces */
- GHASH_ITER (gh_iter, polyHash) {
- const int i_src = POINTER_AS_INT(BLI_ghashIterator_getKey(&gh_iter));
- const int i_dst = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter));
- const MPoly *mp_src = &mpoly_src[i_src];
- MPoly *mp_dst = &mpoly_dst[i_dst];
- const int i_ml_src = mp_src->loopstart;
- const int i_ml_dst = loop_mapping[i_dst];
- const MLoop *ml_src = &mloop_src[i_ml_src];
- MLoop *ml_dst = &mloop_dst[i_ml_dst];
-
- CustomData_copy_data(&mesh->pdata, &result->pdata, i_src, i_dst, 1);
- CustomData_copy_data(&mesh->ldata, &result->ldata, i_ml_src, i_ml_dst, mp_src->totloop);
-
- *mp_dst = *mp_src;
- mp_dst->loopstart = i_ml_dst;
- for (i = 0; i < mp_src->totloop; i++) {
- ml_dst[i].v = POINTER_AS_UINT(BLI_ghash_lookup(vertHash, POINTER_FROM_UINT(ml_src[i].v)));
- ml_dst[i].e = POINTER_AS_UINT(BLI_ghash_lookup(edgeHash, POINTER_FROM_UINT(ml_src[i].e)));
- }
- }
-
- MEM_freeN(loop_mapping);
-
- /* why is this needed? - campbell */
- /* recalculate normals */
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
-
- /* free hashes */
- BLI_ghash_free(vertHash, NULL, NULL);
- BLI_ghash_free(edgeHash, NULL, NULL);
- BLI_ghash_free(polyHash, NULL, NULL);
-
- /* return the new mesh */
- return result;
+ MaskModifierData *mmd = (MaskModifierData *)md;
+ Object *ob = ctx->object;
+ const bool found_test = (mmd->flag & MOD_MASK_INV) == 0;
+ Mesh *result = NULL;
+ GHash *vertHash = NULL, *edgeHash, *polyHash;
+ GHashIterator gh_iter;
+ MDeformVert *dvert, *dv;
+ int numPolys = 0, numLoops = 0, numEdges = 0, numVerts = 0;
+ int maxVerts, maxEdges, maxPolys;
+ int i;
+
+ const MVert *mvert_src;
+ const MEdge *medge_src;
+ const MPoly *mpoly_src;
+ const MLoop *mloop_src;
+
+ MPoly *mpoly_dst;
+ MLoop *mloop_dst;
+ MEdge *medge_dst;
+ MVert *mvert_dst;
+
+ int *loop_mapping;
+
+ dvert = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT);
+ if (dvert == NULL) {
+ return found_test ? BKE_mesh_new_nomain_from_template(mesh, 0, 0, 0, 0, 0) : mesh;
+ }
+
+ /* Overview of Method:
+ * 1. Get the vertices that are in the vertexgroup of interest
+ * 2. Filter out unwanted geometry (i.e. not in vertexgroup), by populating mappings with new vs old indices
+ * 3. Make a new mesh containing only the mapping data
+ */
+
+ /* get original number of verts, edges, and faces */
+ maxVerts = mesh->totvert;
+ maxEdges = mesh->totedge;
+ maxPolys = mesh->totpoly;
+
+ /* check if we can just return the original mesh
+ * - must have verts and therefore verts assigned to vgroups to do anything useful
+ */
+ if (!(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) || (maxVerts == 0) ||
+ BLI_listbase_is_empty(&ob->defbase)) {
+ return mesh;
+ }
+
+ /* if mode is to use selected armature bones, aggregate the bone groups */
+ if (mmd->mode == MOD_MASK_MODE_ARM) { /* --- using selected bones --- */
+ Object *oba = mmd->ob_arm;
+ bPoseChannel *pchan;
+ bDeformGroup *def;
+ bool *bone_select_array;
+ int bone_select_tot = 0;
+ const int defbase_tot = BLI_listbase_count(&ob->defbase);
+
+ /* check that there is armature object with bones to use, otherwise return original mesh */
+ if (ELEM(NULL, oba, oba->pose, ob->defbase.first)) {
+ return mesh;
+ }
+
+ /* determine whether each vertexgroup is associated with a selected bone or not
+ * - each cell is a boolean saying whether bone corresponding to the ith group is selected
+ * - groups that don't match a bone are treated as not existing (along with the corresponding ungrouped verts)
+ */
+ bone_select_array = MEM_malloc_arrayN((size_t)defbase_tot, sizeof(char), "mask array");
+
+ for (i = 0, def = ob->defbase.first; def; def = def->next, i++) {
+ pchan = BKE_pose_channel_find_name(oba->pose, def->name);
+ if (pchan && pchan->bone && (pchan->bone->flag & BONE_SELECTED)) {
+ bone_select_array[i] = true;
+ bone_select_tot++;
+ }
+ else {
+ bone_select_array[i] = false;
+ }
+ }
+
+ /* verthash gives mapping from original vertex indices to the new indices (including selected matches only)
+ * key = oldindex, value = newindex
+ */
+ vertHash = BLI_ghash_int_new_ex("mask vert gh", (unsigned int)maxVerts);
+
+ /* add vertices which exist in vertexgroups into vertHash for filtering
+ * - dv = for each vertex, what vertexgroups does it belong to
+ * - dw = weight that vertex was assigned to a vertexgroup it belongs to
+ */
+ for (i = 0, dv = dvert; i < maxVerts; i++, dv++) {
+ MDeformWeight *dw = dv->dw;
+ bool found = false;
+ int j;
+
+ /* check the groups that vertex is assigned to, and see if it was any use */
+ for (j = 0; j < dv->totweight; j++, dw++) {
+ if (dw->def_nr < defbase_tot) {
+ if (bone_select_array[dw->def_nr]) {
+ if (dw->weight > mmd->threshold) {
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (found_test != found) {
+ continue;
+ }
+
+ /* add to ghash for verts (numVerts acts as counter for mapping) */
+ BLI_ghash_insert(vertHash, POINTER_FROM_INT(i), POINTER_FROM_INT(numVerts));
+ numVerts++;
+ }
+
+ /* free temp hashes */
+ MEM_freeN(bone_select_array);
+ }
+ else { /* --- Using Nominated VertexGroup only --- */
+ int defgrp_index = defgroup_name_index(ob, mmd->vgroup);
+
+ /* if no vgroup (i.e. dverts) found, return the initial mesh */
+ if (defgrp_index == -1) {
+ return mesh;
+ }
+
+ /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
+ vertHash = BLI_ghash_int_new_ex("mask vert2 bh", (unsigned int)maxVerts);
+
+ /* add vertices which exist in vertexgroup into ghash for filtering */
+ for (i = 0, dv = dvert; i < maxVerts; i++, dv++) {
+ const bool found = defvert_find_weight(dv, defgrp_index) > mmd->threshold;
+ if (found_test != found) {
+ continue;
+ }
+
+ /* add to ghash for verts (numVerts acts as counter for mapping) */
+ BLI_ghash_insert(vertHash, POINTER_FROM_INT(i), POINTER_FROM_INT(numVerts));
+ numVerts++;
+ }
+ }
+
+ /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
+ edgeHash = BLI_ghash_int_new_ex("mask ed2 gh", (unsigned int)maxEdges);
+ polyHash = BLI_ghash_int_new_ex("mask fa2 gh", (unsigned int)maxPolys);
+
+ mvert_src = mesh->mvert;
+ medge_src = mesh->medge;
+ mpoly_src = mesh->mpoly;
+ mloop_src = mesh->mloop;
+
+ /* overalloc, assume all polys are seen */
+ loop_mapping = MEM_malloc_arrayN((size_t)maxPolys, sizeof(int), "mask loopmap");
+
+ /* loop over edges and faces, and do the same thing to
+ * ensure that they only reference existing verts
+ */
+ for (i = 0; i < maxEdges; i++) {
+ const MEdge *me = &medge_src[i];
+
+ /* only add if both verts will be in new mesh */
+ if (BLI_ghash_haskey(vertHash, POINTER_FROM_INT(me->v1)) &&
+ BLI_ghash_haskey(vertHash, POINTER_FROM_INT(me->v2))) {
+ BLI_ghash_insert(edgeHash, POINTER_FROM_INT(i), POINTER_FROM_INT(numEdges));
+ numEdges++;
+ }
+ }
+ for (i = 0; i < maxPolys; i++) {
+ const MPoly *mp_src = &mpoly_src[i];
+ const MLoop *ml_src = &mloop_src[mp_src->loopstart];
+ bool ok = true;
+ int j;
+
+ for (j = 0; j < mp_src->totloop; j++, ml_src++) {
+ if (!BLI_ghash_haskey(vertHash, POINTER_FROM_INT(ml_src->v))) {
+ ok = false;
+ break;
+ }
+ }
+
+ /* all verts must be available */
+ if (ok) {
+ BLI_ghash_insert(polyHash, POINTER_FROM_INT(i), POINTER_FROM_INT(numPolys));
+ loop_mapping[numPolys] = numLoops;
+ numPolys++;
+ numLoops += mp_src->totloop;
+ }
+ }
+
+ /* now we know the number of verts, edges and faces,
+ * we can create the new (reduced) mesh
+ */
+ result = BKE_mesh_new_nomain_from_template(mesh, numVerts, numEdges, 0, numLoops, numPolys);
+
+ mpoly_dst = result->mpoly;
+ mloop_dst = result->mloop;
+ medge_dst = result->medge;
+ mvert_dst = result->mvert;
+
+ /* using ghash-iterators, map data into new mesh */
+ /* vertices */
+ GHASH_ITER (gh_iter, vertHash) {
+ const MVert *v_src;
+ MVert *v_dst;
+ const int i_src = POINTER_AS_INT(BLI_ghashIterator_getKey(&gh_iter));
+ const int i_dst = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter));
+
+ v_src = &mvert_src[i_src];
+ v_dst = &mvert_dst[i_dst];
+
+ *v_dst = *v_src;
+ CustomData_copy_data(&mesh->vdata, &result->vdata, i_src, i_dst, 1);
+ }
+
+ /* edges */
+ GHASH_ITER (gh_iter, edgeHash) {
+ const MEdge *e_src;
+ MEdge *e_dst;
+ const int i_src = POINTER_AS_INT(BLI_ghashIterator_getKey(&gh_iter));
+ const int i_dst = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter));
+
+ e_src = &medge_src[i_src];
+ e_dst = &medge_dst[i_dst];
+
+ CustomData_copy_data(&mesh->edata, &result->edata, i_src, i_dst, 1);
+ *e_dst = *e_src;
+ e_dst->v1 = POINTER_AS_UINT(BLI_ghash_lookup(vertHash, POINTER_FROM_UINT(e_src->v1)));
+ e_dst->v2 = POINTER_AS_UINT(BLI_ghash_lookup(vertHash, POINTER_FROM_UINT(e_src->v2)));
+ }
+
+ /* faces */
+ GHASH_ITER (gh_iter, polyHash) {
+ const int i_src = POINTER_AS_INT(BLI_ghashIterator_getKey(&gh_iter));
+ const int i_dst = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter));
+ const MPoly *mp_src = &mpoly_src[i_src];
+ MPoly *mp_dst = &mpoly_dst[i_dst];
+ const int i_ml_src = mp_src->loopstart;
+ const int i_ml_dst = loop_mapping[i_dst];
+ const MLoop *ml_src = &mloop_src[i_ml_src];
+ MLoop *ml_dst = &mloop_dst[i_ml_dst];
+
+ CustomData_copy_data(&mesh->pdata, &result->pdata, i_src, i_dst, 1);
+ CustomData_copy_data(&mesh->ldata, &result->ldata, i_ml_src, i_ml_dst, mp_src->totloop);
+
+ *mp_dst = *mp_src;
+ mp_dst->loopstart = i_ml_dst;
+ for (i = 0; i < mp_src->totloop; i++) {
+ ml_dst[i].v = POINTER_AS_UINT(BLI_ghash_lookup(vertHash, POINTER_FROM_UINT(ml_src[i].v)));
+ ml_dst[i].e = POINTER_AS_UINT(BLI_ghash_lookup(edgeHash, POINTER_FROM_UINT(ml_src[i].e)));
+ }
+ }
+
+ MEM_freeN(loop_mapping);
+
+ /* why is this needed? - campbell */
+ /* recalculate normals */
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+
+ /* free hashes */
+ BLI_ghash_free(vertHash, NULL, NULL);
+ BLI_ghash_free(edgeHash, NULL, NULL);
+ BLI_ghash_free(polyHash, NULL, NULL);
+
+ /* return the new mesh */
+ return result;
}
-
ModifierTypeInfo modifierType_Mask = {
- /* name */ "Mask",
- /* structName */ "MaskModifierData",
- /* structSize */ sizeof(MaskModifierData),
- /* type */ eModifierTypeType_Nonconstructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsMapping |
- eModifierTypeFlag_SupportsEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ NULL,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Mask",
+ /* structName */ "MaskModifierData",
+ /* structSize */ sizeof(MaskModifierData),
+ /* type */ eModifierTypeType_Nonconstructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ NULL,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c
index 74172927c9d..cf1b2daa9cd 100644
--- a/source/blender/modifiers/intern/MOD_meshcache.c
+++ b/source/blender/modifiers/intern/MOD_meshcache.c
@@ -39,276 +39,276 @@
#include "MEM_guardedalloc.h"
-#include "MOD_meshcache_util.h" /* utility functions */
+#include "MOD_meshcache_util.h" /* utility functions */
#include "MOD_modifiertypes.h"
static void initData(ModifierData *md)
{
- MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
+ MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
- mcmd->flag = 0;
- mcmd->type = MOD_MESHCACHE_TYPE_MDD;
- mcmd->interp = MOD_MESHCACHE_INTERP_LINEAR;
- mcmd->frame_scale = 1.0f;
+ mcmd->flag = 0;
+ mcmd->type = MOD_MESHCACHE_TYPE_MDD;
+ mcmd->interp = MOD_MESHCACHE_INTERP_LINEAR;
+ mcmd->frame_scale = 1.0f;
- mcmd->factor = 1.0f;
+ mcmd->factor = 1.0f;
- /* (Y, Z). Blender default */
- mcmd->forward_axis = 1;
- mcmd->up_axis = 2;
+ /* (Y, Z). Blender default */
+ mcmd->forward_axis = 1;
+ mcmd->up_axis = 2;
}
static bool dependsOnTime(ModifierData *md)
{
- MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
- return (mcmd->play_mode == MOD_MESHCACHE_PLAY_CFEA);
+ MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
+ return (mcmd->play_mode == MOD_MESHCACHE_PLAY_CFEA);
}
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(useRenderParams))
{
- MeshCacheModifierData *mcmd = (MeshCacheModifierData *) md;
+ MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
- /* leave it up to the modifier to check the file is valid on calculation */
- return (mcmd->factor <= 0.0f) || (mcmd->filepath[0] == '\0');
+ /* leave it up to the modifier to check the file is valid on calculation */
+ return (mcmd->factor <= 0.0f) || (mcmd->filepath[0] == '\0');
}
-
-static void meshcache_do(
- MeshCacheModifierData *mcmd, Scene *scene, Object *ob,
- float (*vertexCos_Real)[3], int numVerts)
+static void meshcache_do(MeshCacheModifierData *mcmd,
+ Scene *scene,
+ Object *ob,
+ float (*vertexCos_Real)[3],
+ int numVerts)
{
- const bool use_factor = mcmd->factor < 1.0f;
- float (*vertexCos_Store)[3] = (use_factor || (mcmd->deform_mode == MOD_MESHCACHE_DEFORM_INTEGRATE)) ?
- MEM_malloc_arrayN(numVerts, sizeof(*vertexCos_Store), __func__) : NULL;
- float (*vertexCos)[3] = vertexCos_Store ? vertexCos_Store : vertexCos_Real;
-
- const float fps = FPS;
-
- char filepath[FILE_MAX];
- const char *err_str = NULL;
- bool ok;
-
- float time;
-
-
- /* -------------------------------------------------------------------- */
- /* Interpret Time (the reading functions also do some of this ) */
- if (mcmd->play_mode == MOD_MESHCACHE_PLAY_CFEA) {
- const float cfra = BKE_scene_frame_get(scene);
-
- switch (mcmd->time_mode) {
- case MOD_MESHCACHE_TIME_FRAME:
- {
- time = cfra;
- break;
- }
- case MOD_MESHCACHE_TIME_SECONDS:
- {
- time = cfra / fps;
- break;
- }
- case MOD_MESHCACHE_TIME_FACTOR:
- default:
- {
- time = cfra / fps;
- break;
- }
- }
-
- /* apply offset and scale */
- time = (mcmd->frame_scale * time) - mcmd->frame_start;
- }
- else { /* if (mcmd->play_mode == MOD_MESHCACHE_PLAY_EVAL) { */
- switch (mcmd->time_mode) {
- case MOD_MESHCACHE_TIME_FRAME:
- {
- time = mcmd->eval_frame;
- break;
- }
- case MOD_MESHCACHE_TIME_SECONDS:
- {
- time = mcmd->eval_time;
- break;
- }
- case MOD_MESHCACHE_TIME_FACTOR:
- default:
- {
- time = mcmd->eval_factor;
- break;
- }
- }
- }
-
-
- /* -------------------------------------------------------------------- */
- /* Read the File (or error out when the file is bad) */
-
- /* would be nice if we could avoid doing this _every_ frame */
- BLI_strncpy(filepath, mcmd->filepath, sizeof(filepath));
- BLI_path_abs(filepath, ID_BLEND_PATH_FROM_GLOBAL((ID *)ob));
-
- switch (mcmd->type) {
- case MOD_MESHCACHE_TYPE_MDD:
- ok = MOD_meshcache_read_mdd_times(filepath, vertexCos, numVerts,
- mcmd->interp, time, fps, mcmd->time_mode, &err_str);
- break;
- case MOD_MESHCACHE_TYPE_PC2:
- ok = MOD_meshcache_read_pc2_times(filepath, vertexCos, numVerts,
- mcmd->interp, time, fps, mcmd->time_mode, &err_str);
- break;
- default:
- ok = false;
- break;
- }
-
-
- /* -------------------------------------------------------------------- */
- /* tricky shape key integration (slow!) */
- if (mcmd->deform_mode == MOD_MESHCACHE_DEFORM_INTEGRATE) {
- Mesh *me = ob->data;
-
- /* we could support any object type */
- if (UNLIKELY(ob->type != OB_MESH)) {
- modifier_setError(&mcmd->modifier, "'Integrate' only valid for Mesh objects");
- }
- else if (UNLIKELY(me->totvert != numVerts)) {
- modifier_setError(&mcmd->modifier, "'Integrate' original mesh vertex mismatch");
- }
- else if (UNLIKELY(me->totpoly == 0)) {
- modifier_setError(&mcmd->modifier, "'Integrate' requires faces");
- }
- else {
- /* the moons align! */
- int i;
-
- float (*vertexCos_Source)[3] = MEM_malloc_arrayN(numVerts, sizeof(*vertexCos_Source), __func__);
- float (*vertexCos_New)[3] = MEM_malloc_arrayN(numVerts, sizeof(*vertexCos_New), __func__);
- MVert *mv = me->mvert;
-
- for (i = 0; i < numVerts; i++, mv++) {
- copy_v3_v3(vertexCos_Source[i], mv->co);
- }
-
- BKE_mesh_calc_relative_deform(
- me->mpoly, me->totpoly,
- me->mloop, me->totvert,
-
- (const float (*)[3])vertexCos_Source, /* from the original Mesh*/
- (const float (*)[3])vertexCos_Real, /* the input we've been given (shape keys!) */
-
- (const float (*)[3])vertexCos, /* the result of this modifier */
- vertexCos_New /* the result of this function */
- );
-
- /* write the corrected locations back into the result */
- memcpy(vertexCos, vertexCos_New, sizeof(*vertexCos) * numVerts);
-
- MEM_freeN(vertexCos_Source);
- MEM_freeN(vertexCos_New);
- }
- }
-
-
- /* -------------------------------------------------------------------- */
- /* Apply the transformation matrix (if needed) */
- if (UNLIKELY(err_str)) {
- modifier_setError(&mcmd->modifier, "%s", err_str);
- }
- else if (ok) {
- bool use_matrix = false;
- float mat[3][3];
- unit_m3(mat);
-
- if (mat3_from_axis_conversion(mcmd->forward_axis, mcmd->up_axis, 1, 2, mat)) {
- use_matrix = true;
- }
-
- if (mcmd->flip_axis) {
- float tmat[3][3];
- unit_m3(tmat);
- if (mcmd->flip_axis & (1 << 0)) tmat[0][0] = -1.0f;
- if (mcmd->flip_axis & (1 << 1)) tmat[1][1] = -1.0f;
- if (mcmd->flip_axis & (1 << 2)) tmat[2][2] = -1.0f;
- mul_m3_m3m3(mat, tmat, mat);
-
- use_matrix = true;
- }
-
- if (use_matrix) {
- int i;
- for (i = 0; i < numVerts; i++) {
- mul_m3_v3(mat, vertexCos[i]);
- }
- }
- }
-
- if (vertexCos_Store) {
- if (ok) {
- if (use_factor) {
- interp_vn_vn(*vertexCos_Real, *vertexCos_Store, mcmd->factor, numVerts * 3);
- }
- else {
- memcpy(vertexCos_Real, vertexCos_Store, sizeof(*vertexCos_Store) * numVerts);
- }
- }
-
- MEM_freeN(vertexCos_Store);
- }
+ const bool use_factor = mcmd->factor < 1.0f;
+ float(*vertexCos_Store)[3] = (use_factor ||
+ (mcmd->deform_mode == MOD_MESHCACHE_DEFORM_INTEGRATE)) ?
+ MEM_malloc_arrayN(
+ numVerts, sizeof(*vertexCos_Store), __func__) :
+ NULL;
+ float(*vertexCos)[3] = vertexCos_Store ? vertexCos_Store : vertexCos_Real;
+
+ const float fps = FPS;
+
+ char filepath[FILE_MAX];
+ const char *err_str = NULL;
+ bool ok;
+
+ float time;
+
+ /* -------------------------------------------------------------------- */
+ /* Interpret Time (the reading functions also do some of this ) */
+ if (mcmd->play_mode == MOD_MESHCACHE_PLAY_CFEA) {
+ const float cfra = BKE_scene_frame_get(scene);
+
+ switch (mcmd->time_mode) {
+ case MOD_MESHCACHE_TIME_FRAME: {
+ time = cfra;
+ break;
+ }
+ case MOD_MESHCACHE_TIME_SECONDS: {
+ time = cfra / fps;
+ break;
+ }
+ case MOD_MESHCACHE_TIME_FACTOR:
+ default: {
+ time = cfra / fps;
+ break;
+ }
+ }
+
+ /* apply offset and scale */
+ time = (mcmd->frame_scale * time) - mcmd->frame_start;
+ }
+ else { /* if (mcmd->play_mode == MOD_MESHCACHE_PLAY_EVAL) { */
+ switch (mcmd->time_mode) {
+ case MOD_MESHCACHE_TIME_FRAME: {
+ time = mcmd->eval_frame;
+ break;
+ }
+ case MOD_MESHCACHE_TIME_SECONDS: {
+ time = mcmd->eval_time;
+ break;
+ }
+ case MOD_MESHCACHE_TIME_FACTOR:
+ default: {
+ time = mcmd->eval_factor;
+ break;
+ }
+ }
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Read the File (or error out when the file is bad) */
+
+ /* would be nice if we could avoid doing this _every_ frame */
+ BLI_strncpy(filepath, mcmd->filepath, sizeof(filepath));
+ BLI_path_abs(filepath, ID_BLEND_PATH_FROM_GLOBAL((ID *)ob));
+
+ switch (mcmd->type) {
+ case MOD_MESHCACHE_TYPE_MDD:
+ ok = MOD_meshcache_read_mdd_times(
+ filepath, vertexCos, numVerts, mcmd->interp, time, fps, mcmd->time_mode, &err_str);
+ break;
+ case MOD_MESHCACHE_TYPE_PC2:
+ ok = MOD_meshcache_read_pc2_times(
+ filepath, vertexCos, numVerts, mcmd->interp, time, fps, mcmd->time_mode, &err_str);
+ break;
+ default:
+ ok = false;
+ break;
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* tricky shape key integration (slow!) */
+ if (mcmd->deform_mode == MOD_MESHCACHE_DEFORM_INTEGRATE) {
+ Mesh *me = ob->data;
+
+ /* we could support any object type */
+ if (UNLIKELY(ob->type != OB_MESH)) {
+ modifier_setError(&mcmd->modifier, "'Integrate' only valid for Mesh objects");
+ }
+ else if (UNLIKELY(me->totvert != numVerts)) {
+ modifier_setError(&mcmd->modifier, "'Integrate' original mesh vertex mismatch");
+ }
+ else if (UNLIKELY(me->totpoly == 0)) {
+ modifier_setError(&mcmd->modifier, "'Integrate' requires faces");
+ }
+ else {
+ /* the moons align! */
+ int i;
+
+ float(*vertexCos_Source)[3] = MEM_malloc_arrayN(
+ numVerts, sizeof(*vertexCos_Source), __func__);
+ float(*vertexCos_New)[3] = MEM_malloc_arrayN(numVerts, sizeof(*vertexCos_New), __func__);
+ MVert *mv = me->mvert;
+
+ for (i = 0; i < numVerts; i++, mv++) {
+ copy_v3_v3(vertexCos_Source[i], mv->co);
+ }
+
+ BKE_mesh_calc_relative_deform(
+ me->mpoly,
+ me->totpoly,
+ me->mloop,
+ me->totvert,
+
+ (const float(*)[3])vertexCos_Source, /* from the original Mesh*/
+ (const float(*)[3])vertexCos_Real, /* the input we've been given (shape keys!) */
+
+ (const float(*)[3])vertexCos, /* the result of this modifier */
+ vertexCos_New /* the result of this function */
+ );
+
+ /* write the corrected locations back into the result */
+ memcpy(vertexCos, vertexCos_New, sizeof(*vertexCos) * numVerts);
+
+ MEM_freeN(vertexCos_Source);
+ MEM_freeN(vertexCos_New);
+ }
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Apply the transformation matrix (if needed) */
+ if (UNLIKELY(err_str)) {
+ modifier_setError(&mcmd->modifier, "%s", err_str);
+ }
+ else if (ok) {
+ bool use_matrix = false;
+ float mat[3][3];
+ unit_m3(mat);
+
+ if (mat3_from_axis_conversion(mcmd->forward_axis, mcmd->up_axis, 1, 2, mat)) {
+ use_matrix = true;
+ }
+
+ if (mcmd->flip_axis) {
+ float tmat[3][3];
+ unit_m3(tmat);
+ if (mcmd->flip_axis & (1 << 0))
+ tmat[0][0] = -1.0f;
+ if (mcmd->flip_axis & (1 << 1))
+ tmat[1][1] = -1.0f;
+ if (mcmd->flip_axis & (1 << 2))
+ tmat[2][2] = -1.0f;
+ mul_m3_m3m3(mat, tmat, mat);
+
+ use_matrix = true;
+ }
+
+ if (use_matrix) {
+ int i;
+ for (i = 0; i < numVerts; i++) {
+ mul_m3_v3(mat, vertexCos[i]);
+ }
+ }
+ }
+
+ if (vertexCos_Store) {
+ if (ok) {
+ if (use_factor) {
+ interp_vn_vn(*vertexCos_Real, *vertexCos_Store, mcmd->factor, numVerts * 3);
+ }
+ else {
+ memcpy(vertexCos_Real, vertexCos_Store, sizeof(*vertexCos_Store) * numVerts);
+ }
+ }
+
+ MEM_freeN(vertexCos_Store);
+ }
}
-static void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *UNUSED(mesh),
- float (*vertexCos)[3],
- int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *UNUSED(mesh),
+ float (*vertexCos)[3],
+ int numVerts)
{
- MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
- Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
+ Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- meshcache_do(mcmd, scene, ctx->object, vertexCos, numVerts);
+ meshcache_do(mcmd, scene, ctx->object, vertexCos, numVerts);
}
-static void deformVertsEM(
- ModifierData *md, const ModifierEvalContext *ctx,
- struct BMEditMesh *UNUSED(editData),
- Mesh *UNUSED(mesh),
- float (*vertexCos)[3],
- int numVerts)
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *UNUSED(editData),
+ Mesh *UNUSED(mesh),
+ float (*vertexCos)[3],
+ int numVerts)
{
- MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
- Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
+ Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- meshcache_do(mcmd, scene, ctx->object, vertexCos, numVerts);
+ meshcache_do(mcmd, scene, ctx->object, vertexCos, numVerts);
}
-
ModifierTypeInfo modifierType_MeshCache = {
- /* name */ "Mesh Cache",
- /* structName */ "MeshCacheModifierData",
- /* structSize */ sizeof(MeshCacheModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_AcceptsLattice |
- eModifierTypeFlag_SupportsEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ NULL,
- /* freeData */ NULL,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Mesh Cache",
+ /* structName */ "MeshCacheModifierData",
+ /* structSize */ sizeof(MeshCacheModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice |
+ eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_meshcache_mdd.c b/source/blender/modifiers/intern/MOD_meshcache_mdd.c
index bd99248eec4..16a118522c5 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_mdd.c
+++ b/source/blender/modifiers/intern/MOD_meshcache_mdd.c
@@ -35,272 +35,276 @@
#include "DNA_modifier_types.h"
-#include "MOD_meshcache_util.h" /* own include */
+#include "MOD_meshcache_util.h" /* own include */
typedef struct MDDHead {
- int frame_tot;
- int verts_tot;
-} MDDHead; /* frames, verts */
-
-static bool meshcache_read_mdd_head(
- FILE *fp, const int verts_tot,
- MDDHead *mdd_head,
- const char **err_str)
+ int frame_tot;
+ int verts_tot;
+} MDDHead; /* frames, verts */
+
+static bool meshcache_read_mdd_head(FILE *fp,
+ const int verts_tot,
+ MDDHead *mdd_head,
+ const char **err_str)
{
- if (!fread(mdd_head, sizeof(*mdd_head), 1, fp)) {
- *err_str = "Missing header";
- return false;
- }
+ if (!fread(mdd_head, sizeof(*mdd_head), 1, fp)) {
+ *err_str = "Missing header";
+ return false;
+ }
#ifdef __LITTLE_ENDIAN__
- BLI_endian_switch_int32_array((int *)mdd_head, 2);
+ BLI_endian_switch_int32_array((int *)mdd_head, 2);
#endif
- if (mdd_head->verts_tot != verts_tot) {
- *err_str = "Vertex count mismatch";
- return false;
- }
+ if (mdd_head->verts_tot != verts_tot) {
+ *err_str = "Vertex count mismatch";
+ return false;
+ }
- if (mdd_head->frame_tot <= 0) {
- *err_str = "Invalid frame total";
- return false;
- }
- /* intentionally dont seek back */
+ if (mdd_head->frame_tot <= 0) {
+ *err_str = "Invalid frame total";
+ return false;
+ }
+ /* intentionally dont seek back */
- return true;
+ return true;
}
/**
* Gets the index frange and factor
*/
-static bool meshcache_read_mdd_range(
- FILE *fp,
- const int verts_tot,
- const float frame, const char interp,
- int r_index_range[2], float *r_factor,
- const char **err_str)
+static bool meshcache_read_mdd_range(FILE *fp,
+ const int verts_tot,
+ const float frame,
+ const char interp,
+ int r_index_range[2],
+ float *r_factor,
+ const char **err_str)
{
- MDDHead mdd_head;
+ MDDHead mdd_head;
- /* first check interpolation and get the vert locations */
+ /* first check interpolation and get the vert locations */
- if (meshcache_read_mdd_head(fp, verts_tot, &mdd_head, err_str) == false) {
- return false;
- }
+ if (meshcache_read_mdd_head(fp, verts_tot, &mdd_head, err_str) == false) {
+ return false;
+ }
- MOD_meshcache_calc_range(frame, interp, mdd_head.frame_tot, r_index_range, r_factor);
+ MOD_meshcache_calc_range(frame, interp, mdd_head.frame_tot, r_index_range, r_factor);
- return true;
+ return true;
}
-static bool meshcache_read_mdd_range_from_time(
- FILE *fp,
- const int verts_tot,
- const float time, const float UNUSED(fps),
- float *r_frame,
- const char **err_str)
+static bool meshcache_read_mdd_range_from_time(FILE *fp,
+ const int verts_tot,
+ const float time,
+ const float UNUSED(fps),
+ float *r_frame,
+ const char **err_str)
{
- MDDHead mdd_head;
- int i;
- float f_time, f_time_prev = FLT_MAX;
- float frame;
+ MDDHead mdd_head;
+ int i;
+ float f_time, f_time_prev = FLT_MAX;
+ float frame;
- if (meshcache_read_mdd_head(fp, verts_tot, &mdd_head, err_str) == false) {
- return false;
- }
+ if (meshcache_read_mdd_head(fp, verts_tot, &mdd_head, err_str) == false) {
+ return false;
+ }
- for (i = 0; i < mdd_head.frame_tot; i++) {
- fread(&f_time, sizeof(float), 1, fp);
+ for (i = 0; i < mdd_head.frame_tot; i++) {
+ fread(&f_time, sizeof(float), 1, fp);
#ifdef __LITTLE_ENDIAN__
- BLI_endian_switch_float(&f_time);
+ BLI_endian_switch_float(&f_time);
#endif
- if (f_time >= time) {
- break;
- }
- f_time_prev = f_time;
- }
-
- if (i == mdd_head.frame_tot) {
- frame = (float)(mdd_head.frame_tot - 1);
- }
- if (UNLIKELY(f_time_prev == FLT_MAX)) {
- frame = 0.0f;
- }
- else {
- const float range = f_time - f_time_prev;
-
- if (range <= FRAME_SNAP_EPS) {
- frame = (float)i;
- }
- else {
- frame = (float)(i - 1) + ((time - f_time_prev) / range);
- }
- }
-
- *r_frame = frame;
- return true;
+ if (f_time >= time) {
+ break;
+ }
+ f_time_prev = f_time;
+ }
+
+ if (i == mdd_head.frame_tot) {
+ frame = (float)(mdd_head.frame_tot - 1);
+ }
+ if (UNLIKELY(f_time_prev == FLT_MAX)) {
+ frame = 0.0f;
+ }
+ else {
+ const float range = f_time - f_time_prev;
+
+ if (range <= FRAME_SNAP_EPS) {
+ frame = (float)i;
+ }
+ else {
+ frame = (float)(i - 1) + ((time - f_time_prev) / range);
+ }
+ }
+
+ *r_frame = frame;
+ return true;
}
-bool MOD_meshcache_read_mdd_index(
- FILE *fp,
- float (*vertexCos)[3], const int verts_tot,
- const int index, const float factor,
- const char **err_str)
+bool MOD_meshcache_read_mdd_index(FILE *fp,
+ float (*vertexCos)[3],
+ const int verts_tot,
+ const int index,
+ const float factor,
+ const char **err_str)
{
- MDDHead mdd_head;
+ MDDHead mdd_head;
- if (meshcache_read_mdd_head(fp, verts_tot, &mdd_head, err_str) == false) {
- return false;
- }
+ if (meshcache_read_mdd_head(fp, verts_tot, &mdd_head, err_str) == false) {
+ return false;
+ }
- if (fseek(fp, mdd_head.frame_tot * sizeof(int), SEEK_CUR) != 0) {
- *err_str = "Header seek failed";
- return false;
- }
+ if (fseek(fp, mdd_head.frame_tot * sizeof(int), SEEK_CUR) != 0) {
+ *err_str = "Header seek failed";
+ return false;
+ }
- if (fseek(fp, sizeof(float) * 3 * index * mdd_head.verts_tot, SEEK_CUR) != 0) {
- *err_str = "Failed to seek frame";
- return false;
- }
+ if (fseek(fp, sizeof(float) * 3 * index * mdd_head.verts_tot, SEEK_CUR) != 0) {
+ *err_str = "Failed to seek frame";
+ return false;
+ }
- if (factor >= 1.0f) {
+ if (factor >= 1.0f) {
#if 1
- float *vco = *vertexCos;
- unsigned int i;
- for (i = mdd_head.verts_tot; i != 0 ; i--, vco += 3) {
- fread(vco, sizeof(float) * 3, 1, fp);
+ float *vco = *vertexCos;
+ unsigned int i;
+ for (i = mdd_head.verts_tot; i != 0; i--, vco += 3) {
+ fread(vco, sizeof(float) * 3, 1, fp);
# ifdef __LITTLE_ENDIAN__
- BLI_endian_switch_float(vco + 0);
- BLI_endian_switch_float(vco + 1);
- BLI_endian_switch_float(vco + 2);
-# endif /* __LITTLE_ENDIAN__ */
- }
+ BLI_endian_switch_float(vco + 0);
+ BLI_endian_switch_float(vco + 1);
+ BLI_endian_switch_float(vco + 2);
+# endif /* __LITTLE_ENDIAN__ */
+ }
#else
- /* no blending */
- if (!fread(vertexCos, sizeof(float) * 3, mdd_head.verts_tot, f)) {
- *err_str = errno ? strerror(errno) : "Failed to read frame";
- return false;
- }
+ /* no blending */
+ if (!fread(vertexCos, sizeof(float) * 3, mdd_head.verts_tot, f)) {
+ *err_str = errno ? strerror(errno) : "Failed to read frame";
+ return false;
+ }
# ifdef __LITTLE_ENDIAN__
- BLI_endian_switch_float_array(vertexCos[0], mdd_head.verts_tot * 3);
+ BLI_endian_switch_float_array(vertexCos[0], mdd_head.verts_tot * 3);
# endif
#endif
- }
- else {
- const float ifactor = 1.0f - factor;
- float *vco = *vertexCos;
- unsigned int i;
- for (i = mdd_head.verts_tot; i != 0 ; i--, vco += 3) {
- float tvec[3];
- fread(tvec, sizeof(float) * 3, 1, fp);
+ }
+ else {
+ const float ifactor = 1.0f - factor;
+ float *vco = *vertexCos;
+ unsigned int i;
+ for (i = mdd_head.verts_tot; i != 0; i--, vco += 3) {
+ float tvec[3];
+ fread(tvec, sizeof(float) * 3, 1, fp);
#ifdef __LITTLE_ENDIAN__
- BLI_endian_switch_float(tvec + 0);
- BLI_endian_switch_float(tvec + 1);
- BLI_endian_switch_float(tvec + 2);
+ BLI_endian_switch_float(tvec + 0);
+ BLI_endian_switch_float(tvec + 1);
+ BLI_endian_switch_float(tvec + 2);
#endif
- vco[0] = (vco[0] * ifactor) + (tvec[0] * factor);
- vco[1] = (vco[1] * ifactor) + (tvec[1] * factor);
- vco[2] = (vco[2] * ifactor) + (tvec[2] * factor);
- }
- }
+ vco[0] = (vco[0] * ifactor) + (tvec[0] * factor);
+ vco[1] = (vco[1] * ifactor) + (tvec[1] * factor);
+ vco[2] = (vco[2] * ifactor) + (tvec[2] * factor);
+ }
+ }
- return true;
+ return true;
}
-bool MOD_meshcache_read_mdd_frame(
- FILE *fp,
- float (*vertexCos)[3], const int verts_tot, const char interp,
- const float frame,
- const char **err_str)
+bool MOD_meshcache_read_mdd_frame(FILE *fp,
+ float (*vertexCos)[3],
+ const int verts_tot,
+ const char interp,
+ const float frame,
+ const char **err_str)
{
- int index_range[2];
- float factor;
-
- if (meshcache_read_mdd_range(fp, verts_tot, frame, interp,
- index_range, &factor, /* read into these values */
- err_str) == false)
- {
- return false;
- }
-
- if (index_range[0] == index_range[1]) {
- /* read single */
- if ((fseek(fp, 0, SEEK_SET) == 0) &&
- MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str))
- {
- return true;
- }
- else {
- return false;
- }
- }
- else {
- /* read both and interpolate */
- if ((fseek(fp, 0, SEEK_SET) == 0) &&
- MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str) &&
- (fseek(fp, 0, SEEK_SET) == 0) &&
- MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[1], factor, err_str))
- {
- return true;
- }
- else {
- return false;
- }
- }
+ int index_range[2];
+ float factor;
+
+ if (meshcache_read_mdd_range(fp,
+ verts_tot,
+ frame,
+ interp,
+ index_range,
+ &factor, /* read into these values */
+ err_str) == false) {
+ return false;
+ }
+
+ if (index_range[0] == index_range[1]) {
+ /* read single */
+ if ((fseek(fp, 0, SEEK_SET) == 0) &&
+ MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ else {
+ /* read both and interpolate */
+ if ((fseek(fp, 0, SEEK_SET) == 0) &&
+ MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str) &&
+ (fseek(fp, 0, SEEK_SET) == 0) &&
+ MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[1], factor, err_str)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
}
-bool MOD_meshcache_read_mdd_times(
- const char *filepath,
- float (*vertexCos)[3], const int verts_tot, const char interp,
- const float time, const float fps, const char time_mode,
- const char **err_str)
+bool MOD_meshcache_read_mdd_times(const char *filepath,
+ float (*vertexCos)[3],
+ const int verts_tot,
+ const char interp,
+ const float time,
+ const float fps,
+ const char time_mode,
+ const char **err_str)
{
- float frame;
-
- FILE *fp = BLI_fopen(filepath, "rb");
- bool ok;
-
- if (fp == NULL) {
- *err_str = errno ? strerror(errno) : "Unknown error opening file";
- return false;
- }
-
- switch (time_mode) {
- case MOD_MESHCACHE_TIME_FRAME:
- {
- frame = time;
- break;
- }
- case MOD_MESHCACHE_TIME_SECONDS:
- {
- /* we need to find the closest time */
- if (meshcache_read_mdd_range_from_time(fp, verts_tot, time, fps, &frame, err_str) == false) {
- fclose(fp);
- return false;
- }
- rewind(fp);
- break;
- }
- case MOD_MESHCACHE_TIME_FACTOR:
- default:
- {
- MDDHead mdd_head;
- if (meshcache_read_mdd_head(fp, verts_tot, &mdd_head, err_str) == false) {
- fclose(fp);
- return false;
- }
-
- frame = CLAMPIS(time, 0.0f, 1.0f) * (float)mdd_head.frame_tot;
- rewind(fp);
- break;
- }
- }
-
- ok = MOD_meshcache_read_mdd_frame(fp, vertexCos, verts_tot, interp, frame, err_str);
-
- fclose(fp);
- return ok;
+ float frame;
+
+ FILE *fp = BLI_fopen(filepath, "rb");
+ bool ok;
+
+ if (fp == NULL) {
+ *err_str = errno ? strerror(errno) : "Unknown error opening file";
+ return false;
+ }
+
+ switch (time_mode) {
+ case MOD_MESHCACHE_TIME_FRAME: {
+ frame = time;
+ break;
+ }
+ case MOD_MESHCACHE_TIME_SECONDS: {
+ /* we need to find the closest time */
+ if (meshcache_read_mdd_range_from_time(fp, verts_tot, time, fps, &frame, err_str) == false) {
+ fclose(fp);
+ return false;
+ }
+ rewind(fp);
+ break;
+ }
+ case MOD_MESHCACHE_TIME_FACTOR:
+ default: {
+ MDDHead mdd_head;
+ if (meshcache_read_mdd_head(fp, verts_tot, &mdd_head, err_str) == false) {
+ fclose(fp);
+ return false;
+ }
+
+ frame = CLAMPIS(time, 0.0f, 1.0f) * (float)mdd_head.frame_tot;
+ rewind(fp);
+ break;
+ }
+ }
+
+ ok = MOD_meshcache_read_mdd_frame(fp, vertexCos, verts_tot, interp, frame, err_str);
+
+ fclose(fp);
+ return ok;
}
diff --git a/source/blender/modifiers/intern/MOD_meshcache_pc2.c b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
index e19a967cca7..97a8635ac9e 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_pc2.c
+++ b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
@@ -35,248 +35,251 @@
#include "DNA_modifier_types.h"
-#include "MOD_meshcache_util.h" /* own include */
+#include "MOD_meshcache_util.h" /* own include */
typedef struct PC2Head {
- char header[12]; /* 'POINTCACHE2\0' */
- int file_version; /* unused - should be 1 */
- int verts_tot;
- float start;
- float sampling;
- int frame_tot;
-} PC2Head; /* frames, verts */
-
-static bool meshcache_read_pc2_head(
- FILE *fp, const int verts_tot,
- PC2Head *pc2_head,
- const char **err_str)
+ char header[12]; /* 'POINTCACHE2\0' */
+ int file_version; /* unused - should be 1 */
+ int verts_tot;
+ float start;
+ float sampling;
+ int frame_tot;
+} PC2Head; /* frames, verts */
+
+static bool meshcache_read_pc2_head(FILE *fp,
+ const int verts_tot,
+ PC2Head *pc2_head,
+ const char **err_str)
{
- if (!fread(pc2_head, sizeof(*pc2_head), 1, fp)) {
- *err_str = "Missing header";
- return false;
- }
+ if (!fread(pc2_head, sizeof(*pc2_head), 1, fp)) {
+ *err_str = "Missing header";
+ return false;
+ }
- if (!STREQ(pc2_head->header, "POINTCACHE2")) {
- *err_str = "Invalid header";
- return false;
- }
+ if (!STREQ(pc2_head->header, "POINTCACHE2")) {
+ *err_str = "Invalid header";
+ return false;
+ }
#ifdef __BIG_ENDIAN__
- BLI_endian_switch_int32_array(&pc2_head->file_version, (sizeof(*pc2_head) - sizeof(pc2_head->header)) / sizeof(int));
+ BLI_endian_switch_int32_array(&pc2_head->file_version,
+ (sizeof(*pc2_head) - sizeof(pc2_head->header)) / sizeof(int));
#endif
- if (pc2_head->verts_tot != verts_tot) {
- *err_str = "Vertex count mismatch";
- return false;
- }
+ if (pc2_head->verts_tot != verts_tot) {
+ *err_str = "Vertex count mismatch";
+ return false;
+ }
- if (pc2_head->frame_tot <= 0) {
- *err_str = "Invalid frame total";
- return false;
- }
- /* intentionally dont seek back */
+ if (pc2_head->frame_tot <= 0) {
+ *err_str = "Invalid frame total";
+ return false;
+ }
+ /* intentionally dont seek back */
- return true;
+ return true;
}
-
/**
* Gets the index frange and factor
*
* currently same as for MDD
*/
-static bool meshcache_read_pc2_range(
- FILE *fp,
- const int verts_tot,
- const float frame, const char interp,
- int r_index_range[2], float *r_factor,
- const char **err_str)
+static bool meshcache_read_pc2_range(FILE *fp,
+ const int verts_tot,
+ const float frame,
+ const char interp,
+ int r_index_range[2],
+ float *r_factor,
+ const char **err_str)
{
- PC2Head pc2_head;
+ PC2Head pc2_head;
- /* first check interpolation and get the vert locations */
+ /* first check interpolation and get the vert locations */
- if (meshcache_read_pc2_head(fp, verts_tot, &pc2_head, err_str) == false) {
- return false;
- }
+ if (meshcache_read_pc2_head(fp, verts_tot, &pc2_head, err_str) == false) {
+ return false;
+ }
- MOD_meshcache_calc_range(frame, interp, pc2_head.frame_tot, r_index_range, r_factor);
+ MOD_meshcache_calc_range(frame, interp, pc2_head.frame_tot, r_index_range, r_factor);
- return true;
+ return true;
}
-static bool meshcache_read_pc2_range_from_time(
- FILE *fp,
- const int verts_tot,
- const float time, const float fps,
- float *r_frame,
- const char **err_str)
+static bool meshcache_read_pc2_range_from_time(FILE *fp,
+ const int verts_tot,
+ const float time,
+ const float fps,
+ float *r_frame,
+ const char **err_str)
{
- PC2Head pc2_head;
- float frame;
+ PC2Head pc2_head;
+ float frame;
- if (meshcache_read_pc2_head(fp, verts_tot, &pc2_head, err_str) == false) {
- return false;
- }
+ if (meshcache_read_pc2_head(fp, verts_tot, &pc2_head, err_str) == false) {
+ return false;
+ }
- frame = ((time / fps) - pc2_head.start) / pc2_head.sampling;
+ frame = ((time / fps) - pc2_head.start) / pc2_head.sampling;
- if (frame >= pc2_head.frame_tot) {
- frame = (float)(pc2_head.frame_tot - 1);
- }
- else if (frame < 0.0f) {
- frame = 0.0f;
- }
+ if (frame >= pc2_head.frame_tot) {
+ frame = (float)(pc2_head.frame_tot - 1);
+ }
+ else if (frame < 0.0f) {
+ frame = 0.0f;
+ }
- *r_frame = frame;
- return true;
+ *r_frame = frame;
+ return true;
}
-bool MOD_meshcache_read_pc2_index(
- FILE *fp,
- float (*vertexCos)[3], const int verts_tot,
- const int index, const float factor,
- const char **err_str)
+bool MOD_meshcache_read_pc2_index(FILE *fp,
+ float (*vertexCos)[3],
+ const int verts_tot,
+ const int index,
+ const float factor,
+ const char **err_str)
{
- PC2Head pc2_head;
-
- if (meshcache_read_pc2_head(fp, verts_tot, &pc2_head, err_str) == false) {
- return false;
- }
-
- if (fseek(fp, sizeof(float) * 3 * index * pc2_head.verts_tot, SEEK_CUR) != 0) {
- *err_str = "Failed to seek frame";
- return false;
- }
-
- if (factor >= 1.0f) {
- float *vco = *vertexCos;
- unsigned int i;
- for (i = pc2_head.verts_tot; i != 0 ; i--, vco += 3) {
- fread(vco, sizeof(float) * 3, 1, fp);
-
-# ifdef __BIG_ENDIAN__
- BLI_endian_switch_float(vco + 0);
- BLI_endian_switch_float(vco + 1);
- BLI_endian_switch_float(vco + 2);
-# endif /* __BIG_ENDIAN__ */
- }
- }
- else {
- const float ifactor = 1.0f - factor;
- float *vco = *vertexCos;
- unsigned int i;
- for (i = pc2_head.verts_tot; i != 0 ; i--, vco += 3) {
- float tvec[3];
- fread(tvec, sizeof(float) * 3, 1, fp);
+ PC2Head pc2_head;
+
+ if (meshcache_read_pc2_head(fp, verts_tot, &pc2_head, err_str) == false) {
+ return false;
+ }
+
+ if (fseek(fp, sizeof(float) * 3 * index * pc2_head.verts_tot, SEEK_CUR) != 0) {
+ *err_str = "Failed to seek frame";
+ return false;
+ }
+
+ if (factor >= 1.0f) {
+ float *vco = *vertexCos;
+ unsigned int i;
+ for (i = pc2_head.verts_tot; i != 0; i--, vco += 3) {
+ fread(vco, sizeof(float) * 3, 1, fp);
#ifdef __BIG_ENDIAN__
- BLI_endian_switch_float(tvec + 0);
- BLI_endian_switch_float(tvec + 1);
- BLI_endian_switch_float(tvec + 2);
-#endif /* __BIG_ENDIAN__ */
-
- vco[0] = (vco[0] * ifactor) + (tvec[0] * factor);
- vco[1] = (vco[1] * ifactor) + (tvec[1] * factor);
- vco[2] = (vco[2] * ifactor) + (tvec[2] * factor);
- }
- }
-
- return true;
-}
+ BLI_endian_switch_float(vco + 0);
+ BLI_endian_switch_float(vco + 1);
+ BLI_endian_switch_float(vco + 2);
+#endif /* __BIG_ENDIAN__ */
+ }
+ }
+ else {
+ const float ifactor = 1.0f - factor;
+ float *vco = *vertexCos;
+ unsigned int i;
+ for (i = pc2_head.verts_tot; i != 0; i--, vco += 3) {
+ float tvec[3];
+ fread(tvec, sizeof(float) * 3, 1, fp);
+#ifdef __BIG_ENDIAN__
+ BLI_endian_switch_float(tvec + 0);
+ BLI_endian_switch_float(tvec + 1);
+ BLI_endian_switch_float(tvec + 2);
+#endif /* __BIG_ENDIAN__ */
+
+ vco[0] = (vco[0] * ifactor) + (tvec[0] * factor);
+ vco[1] = (vco[1] * ifactor) + (tvec[1] * factor);
+ vco[2] = (vco[2] * ifactor) + (tvec[2] * factor);
+ }
+ }
+
+ return true;
+}
-bool MOD_meshcache_read_pc2_frame(
- FILE *fp,
- float (*vertexCos)[3], const int verts_tot, const char interp,
- const float frame,
- const char **err_str)
+bool MOD_meshcache_read_pc2_frame(FILE *fp,
+ float (*vertexCos)[3],
+ const int verts_tot,
+ const char interp,
+ const float frame,
+ const char **err_str)
{
- int index_range[2];
- float factor;
-
- if (meshcache_read_pc2_range(fp, verts_tot, frame, interp,
- index_range, &factor, /* read into these values */
- err_str) == false)
- {
- return false;
- }
-
- if (index_range[0] == index_range[1]) {
- /* read single */
- if ((fseek(fp, 0, SEEK_SET) == 0) &&
- MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str))
- {
- return true;
- }
- else {
- return false;
- }
- }
- else {
- /* read both and interpolate */
- if ((fseek(fp, 0, SEEK_SET) == 0) &&
- MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str) &&
- (fseek(fp, 0, SEEK_SET) == 0) &&
- MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[1], factor, err_str))
- {
- return true;
- }
- else {
- return false;
- }
- }
+ int index_range[2];
+ float factor;
+
+ if (meshcache_read_pc2_range(fp,
+ verts_tot,
+ frame,
+ interp,
+ index_range,
+ &factor, /* read into these values */
+ err_str) == false) {
+ return false;
+ }
+
+ if (index_range[0] == index_range[1]) {
+ /* read single */
+ if ((fseek(fp, 0, SEEK_SET) == 0) &&
+ MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ else {
+ /* read both and interpolate */
+ if ((fseek(fp, 0, SEEK_SET) == 0) &&
+ MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str) &&
+ (fseek(fp, 0, SEEK_SET) == 0) &&
+ MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[1], factor, err_str)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
}
-bool MOD_meshcache_read_pc2_times(
- const char *filepath,
- float (*vertexCos)[3], const int verts_tot, const char interp,
- const float time, const float fps, const char time_mode,
- const char **err_str)
+bool MOD_meshcache_read_pc2_times(const char *filepath,
+ float (*vertexCos)[3],
+ const int verts_tot,
+ const char interp,
+ const float time,
+ const float fps,
+ const char time_mode,
+ const char **err_str)
{
- float frame;
-
- FILE *fp = BLI_fopen(filepath, "rb");
- bool ok;
-
- if (fp == NULL) {
- *err_str = errno ? strerror(errno) : "Unknown error opening file";
- return false;
- }
-
- switch (time_mode) {
- case MOD_MESHCACHE_TIME_FRAME:
- {
- frame = time;
- break;
- }
- case MOD_MESHCACHE_TIME_SECONDS:
- {
- /* we need to find the closest time */
- if (meshcache_read_pc2_range_from_time(fp, verts_tot, time, fps, &frame, err_str) == false) {
- fclose(fp);
- return false;
- }
- rewind(fp);
- break;
- }
- case MOD_MESHCACHE_TIME_FACTOR:
- default:
- {
- PC2Head pc2_head;
- if (meshcache_read_pc2_head(fp, verts_tot, &pc2_head, err_str) == false) {
- fclose(fp);
- return false;
- }
-
- frame = CLAMPIS(time, 0.0f, 1.0f) * (float)pc2_head.frame_tot;
- rewind(fp);
- break;
- }
- }
-
- ok = MOD_meshcache_read_pc2_frame(fp, vertexCos, verts_tot, interp, frame, err_str);
-
- fclose(fp);
- return ok;
+ float frame;
+
+ FILE *fp = BLI_fopen(filepath, "rb");
+ bool ok;
+
+ if (fp == NULL) {
+ *err_str = errno ? strerror(errno) : "Unknown error opening file";
+ return false;
+ }
+
+ switch (time_mode) {
+ case MOD_MESHCACHE_TIME_FRAME: {
+ frame = time;
+ break;
+ }
+ case MOD_MESHCACHE_TIME_SECONDS: {
+ /* we need to find the closest time */
+ if (meshcache_read_pc2_range_from_time(fp, verts_tot, time, fps, &frame, err_str) == false) {
+ fclose(fp);
+ return false;
+ }
+ rewind(fp);
+ break;
+ }
+ case MOD_MESHCACHE_TIME_FACTOR:
+ default: {
+ PC2Head pc2_head;
+ if (meshcache_read_pc2_head(fp, verts_tot, &pc2_head, err_str) == false) {
+ fclose(fp);
+ return false;
+ }
+
+ frame = CLAMPIS(time, 0.0f, 1.0f) * (float)pc2_head.frame_tot;
+ rewind(fp);
+ break;
+ }
+ }
+
+ ok = MOD_meshcache_read_pc2_frame(fp, vertexCos, verts_tot, interp, frame, err_str);
+
+ fclose(fp);
+ return ok;
}
diff --git a/source/blender/modifiers/intern/MOD_meshcache_util.c b/source/blender/modifiers/intern/MOD_meshcache_util.c
index 2db46af1188..0027ce5f7e2 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_util.c
+++ b/source/blender/modifiers/intern/MOD_meshcache_util.c
@@ -26,42 +26,39 @@
#include "MOD_meshcache_util.h"
-void MOD_meshcache_calc_range(
- const float frame, const char interp,
- const int frame_tot,
- int r_index_range[2], float *r_factor)
+void MOD_meshcache_calc_range(const float frame,
+ const char interp,
+ const int frame_tot,
+ int r_index_range[2],
+ float *r_factor)
{
- if (interp == MOD_MESHCACHE_INTERP_NONE) {
- r_index_range[0] = r_index_range[1] = max_ii(0, min_ii(frame_tot - 1, round_fl_to_int(frame)));
- *r_factor = 1.0f; /* dummy */
- }
- else {
- const float tframe = floorf(frame);
- const float range = frame - tframe;
- r_index_range[0] = (int)tframe;
- if (range <= FRAME_SNAP_EPS) {
- /* we're close enough not to need blending */
- r_index_range[1] = r_index_range[0];
- *r_factor = 1.0f; /* dummy */
- }
- else {
- /* blend between 2 frames */
- r_index_range[1] = r_index_range[0] + 1;
- *r_factor = range;
- }
+ if (interp == MOD_MESHCACHE_INTERP_NONE) {
+ r_index_range[0] = r_index_range[1] = max_ii(0, min_ii(frame_tot - 1, round_fl_to_int(frame)));
+ *r_factor = 1.0f; /* dummy */
+ }
+ else {
+ const float tframe = floorf(frame);
+ const float range = frame - tframe;
+ r_index_range[0] = (int)tframe;
+ if (range <= FRAME_SNAP_EPS) {
+ /* we're close enough not to need blending */
+ r_index_range[1] = r_index_range[0];
+ *r_factor = 1.0f; /* dummy */
+ }
+ else {
+ /* blend between 2 frames */
+ r_index_range[1] = r_index_range[0] + 1;
+ *r_factor = range;
+ }
- /* clamp */
- if ((r_index_range[0] >= frame_tot) ||
- (r_index_range[1] >= frame_tot))
- {
- r_index_range[0] = r_index_range[1] = frame_tot - 1;
- *r_factor = 1.0f; /* dummy */
- }
- else if ((r_index_range[0] < 0) ||
- (r_index_range[1] < 0))
- {
- r_index_range[0] = r_index_range[1] = 0;
- *r_factor = 1.0f; /* dummy */
- }
- }
+ /* clamp */
+ if ((r_index_range[0] >= frame_tot) || (r_index_range[1] >= frame_tot)) {
+ r_index_range[0] = r_index_range[1] = frame_tot - 1;
+ *r_factor = 1.0f; /* dummy */
+ }
+ else if ((r_index_range[0] < 0) || (r_index_range[1] < 0)) {
+ r_index_range[0] = r_index_range[1] = 0;
+ *r_factor = 1.0f; /* dummy */
+ }
+ }
}
diff --git a/source/blender/modifiers/intern/MOD_meshcache_util.h b/source/blender/modifiers/intern/MOD_meshcache_util.h
index a177ea467e7..0a6c0e73632 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_util.h
+++ b/source/blender/modifiers/intern/MOD_meshcache_util.h
@@ -21,47 +21,57 @@
#ifndef __MOD_MESHCACHE_UTIL_H__
#define __MOD_MESHCACHE_UTIL_H__
-
/* MOD_meshcache_mdd.c */
-bool MOD_meshcache_read_mdd_index(
- FILE *fp,
- float (*vertexCos)[3], const int vertex_tot,
- const int index, const float factor,
- const char **err_str);
-bool MOD_meshcache_read_mdd_frame(
- FILE *fp,
- float (*vertexCos)[3], const int verts_tot, const char interp,
- const float frame,
- const char **err_str);
-bool MOD_meshcache_read_mdd_times(
- const char *filepath,
- float (*vertexCos)[3], const int verts_tot, const char interp,
- const float time, const float fps, const char time_mode,
- const char **err_str);
+bool MOD_meshcache_read_mdd_index(FILE *fp,
+ float (*vertexCos)[3],
+ const int vertex_tot,
+ const int index,
+ const float factor,
+ const char **err_str);
+bool MOD_meshcache_read_mdd_frame(FILE *fp,
+ float (*vertexCos)[3],
+ const int verts_tot,
+ const char interp,
+ const float frame,
+ const char **err_str);
+bool MOD_meshcache_read_mdd_times(const char *filepath,
+ float (*vertexCos)[3],
+ const int verts_tot,
+ const char interp,
+ const float time,
+ const float fps,
+ const char time_mode,
+ const char **err_str);
/* MOD_meshcache_pc2.c */
-bool MOD_meshcache_read_pc2_index(
- FILE *fp,
- float (*vertexCos)[3], const int verts_tot,
- const int index, const float factor,
- const char **err_str);
-bool MOD_meshcache_read_pc2_frame(
- FILE *fp,
- float (*vertexCos)[3], const int verts_tot, const char interp,
- const float frame,
- const char **err_str);
-bool MOD_meshcache_read_pc2_times(
- const char *filepath,
- float (*vertexCos)[3], const int verts_tot, const char interp,
- const float time, const float fps, const char time_mode,
- const char **err_str);
+bool MOD_meshcache_read_pc2_index(FILE *fp,
+ float (*vertexCos)[3],
+ const int verts_tot,
+ const int index,
+ const float factor,
+ const char **err_str);
+bool MOD_meshcache_read_pc2_frame(FILE *fp,
+ float (*vertexCos)[3],
+ const int verts_tot,
+ const char interp,
+ const float frame,
+ const char **err_str);
+bool MOD_meshcache_read_pc2_times(const char *filepath,
+ float (*vertexCos)[3],
+ const int verts_tot,
+ const char interp,
+ const float time,
+ const float fps,
+ const char time_mode,
+ const char **err_str);
/* MOD_meshcache_util.c */
-void MOD_meshcache_calc_range(
- const float frame, const char interp,
- const int frame_tot,
- int r_index_range[2], float *r_factor);
+void MOD_meshcache_calc_range(const float frame,
+ const char interp,
+ const int frame_tot,
+ int r_index_range[2],
+ float *r_factor);
#define FRAME_SNAP_EPS 0.0001f
-#endif /* __MOD_MESHCACHE_UTIL_H__ */
+#endif /* __MOD_MESHCACHE_UTIL_H__ */
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c
index 7ae03cc43f3..9238057f032 100644
--- a/source/blender/modifiers/intern/MOD_meshdeform.c
+++ b/source/blender/modifiers/intern/MOD_meshdeform.c
@@ -53,466 +53,500 @@
static void initData(ModifierData *md)
{
- MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
+ MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
- mmd->gridsize = 5;
+ mmd->gridsize = 5;
}
static void freeData(ModifierData *md)
{
- MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
-
- if (mmd->bindinfluences) MEM_freeN(mmd->bindinfluences);
- if (mmd->bindoffsets) MEM_freeN(mmd->bindoffsets);
- if (mmd->bindcagecos) MEM_freeN(mmd->bindcagecos);
- if (mmd->dyngrid) MEM_freeN(mmd->dyngrid);
- if (mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
- if (mmd->dynverts) MEM_freeN(mmd->dynverts);
- if (mmd->bindweights) MEM_freeN(mmd->bindweights); /* deprecated */
- if (mmd->bindcos) MEM_freeN(mmd->bindcos); /* deprecated */
+ MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
+
+ if (mmd->bindinfluences)
+ MEM_freeN(mmd->bindinfluences);
+ if (mmd->bindoffsets)
+ MEM_freeN(mmd->bindoffsets);
+ if (mmd->bindcagecos)
+ MEM_freeN(mmd->bindcagecos);
+ if (mmd->dyngrid)
+ MEM_freeN(mmd->dyngrid);
+ if (mmd->dyninfluences)
+ MEM_freeN(mmd->dyninfluences);
+ if (mmd->dynverts)
+ MEM_freeN(mmd->dynverts);
+ if (mmd->bindweights)
+ MEM_freeN(mmd->bindweights); /* deprecated */
+ if (mmd->bindcos)
+ MEM_freeN(mmd->bindcos); /* deprecated */
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
- const MeshDeformModifierData *mmd = (const MeshDeformModifierData *) md;
- MeshDeformModifierData *tmmd = (MeshDeformModifierData *) target;
-
- modifier_copyData_generic(md, target, flag);
-
- if (mmd->bindinfluences) tmmd->bindinfluences = MEM_dupallocN(mmd->bindinfluences);
- if (mmd->bindoffsets) tmmd->bindoffsets = MEM_dupallocN(mmd->bindoffsets);
- if (mmd->bindcagecos) tmmd->bindcagecos = MEM_dupallocN(mmd->bindcagecos);
- if (mmd->dyngrid) tmmd->dyngrid = MEM_dupallocN(mmd->dyngrid);
- if (mmd->dyninfluences) tmmd->dyninfluences = MEM_dupallocN(mmd->dyninfluences);
- if (mmd->dynverts) tmmd->dynverts = MEM_dupallocN(mmd->dynverts);
- if (mmd->bindweights) tmmd->bindweights = MEM_dupallocN(mmd->bindweights); /* deprecated */
- if (mmd->bindcos) tmmd->bindcos = MEM_dupallocN(mmd->bindcos); /* deprecated */
+ const MeshDeformModifierData *mmd = (const MeshDeformModifierData *)md;
+ MeshDeformModifierData *tmmd = (MeshDeformModifierData *)target;
+
+ modifier_copyData_generic(md, target, flag);
+
+ if (mmd->bindinfluences)
+ tmmd->bindinfluences = MEM_dupallocN(mmd->bindinfluences);
+ if (mmd->bindoffsets)
+ tmmd->bindoffsets = MEM_dupallocN(mmd->bindoffsets);
+ if (mmd->bindcagecos)
+ tmmd->bindcagecos = MEM_dupallocN(mmd->bindcagecos);
+ if (mmd->dyngrid)
+ tmmd->dyngrid = MEM_dupallocN(mmd->dyngrid);
+ if (mmd->dyninfluences)
+ tmmd->dyninfluences = MEM_dupallocN(mmd->dyninfluences);
+ if (mmd->dynverts)
+ tmmd->dynverts = MEM_dupallocN(mmd->dynverts);
+ if (mmd->bindweights)
+ tmmd->bindweights = MEM_dupallocN(mmd->bindweights); /* deprecated */
+ if (mmd->bindcos)
+ tmmd->bindcos = MEM_dupallocN(mmd->bindcos); /* deprecated */
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
+ MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
- /* ask for vertexgroups if we need them */
- if (mmd->defgrp_name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ /* ask for vertexgroups if we need them */
+ if (mmd->defgrp_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(useRenderParams))
{
- MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
+ MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
- return !mmd->object;
+ return !mmd->object;
}
-static void foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
+ MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
- walk(userData, ob, &mmd->object, IDWALK_CB_NOP);
+ walk(userData, ob, &mmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
- if (mmd->object != NULL) {
- /* TODO(sergey): Do we need transform component here? */
- DEG_add_object_relation(ctx->node, mmd->object, DEG_OB_COMP_GEOMETRY, "Mesh Deform Modifier");
- }
+ MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
+ if (mmd->object != NULL) {
+ /* TODO(sergey): Do we need transform component here? */
+ DEG_add_object_relation(ctx->node, mmd->object, DEG_OB_COMP_GEOMETRY, "Mesh Deform Modifier");
+ }
}
static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float (*dco)[3], float vec[3])
{
- MDefCell *cell;
- MDefInfluence *inf;
- float gridvec[3], dvec[3], ivec[3], wx, wy, wz;
- float weight, cageweight, totweight, *cageco;
- int i, j, a, x, y, z, size;
+ MDefCell *cell;
+ MDefInfluence *inf;
+ float gridvec[3], dvec[3], ivec[3], wx, wy, wz;
+ float weight, cageweight, totweight, *cageco;
+ int i, j, a, x, y, z, size;
#ifdef __SSE2__
- __m128 co = _mm_setzero_ps();
+ __m128 co = _mm_setzero_ps();
#else
- float co[3] = {0.0f, 0.0f, 0.0f};
+ float co[3] = {0.0f, 0.0f, 0.0f};
#endif
- totweight = 0.0f;
- size = mmd->dyngridsize;
-
- for (i = 0; i < 3; i++) {
- gridvec[i] = (vec[i] - mmd->dyncellmin[i] - mmd->dyncellwidth * 0.5f) / mmd->dyncellwidth;
- ivec[i] = (int)gridvec[i];
- dvec[i] = gridvec[i] - ivec[i];
- }
-
- for (i = 0; i < 8; i++) {
- if (i & 1) { x = ivec[0] + 1; wx = dvec[0]; }
- else { x = ivec[0]; wx = 1.0f - dvec[0]; }
-
- if (i & 2) { y = ivec[1] + 1; wy = dvec[1]; }
- else { y = ivec[1]; wy = 1.0f - dvec[1]; }
-
- if (i & 4) { z = ivec[2] + 1; wz = dvec[2]; }
- else { z = ivec[2]; wz = 1.0f - dvec[2]; }
-
- CLAMP(x, 0, size - 1);
- CLAMP(y, 0, size - 1);
- CLAMP(z, 0, size - 1);
-
- a = x + y * size + z * size * size;
- weight = wx * wy * wz;
-
- cell = &mmd->dyngrid[a];
- inf = mmd->dyninfluences + cell->offset;
- for (j = 0; j < cell->totinfluence; j++, inf++) {
- cageco = dco[inf->vertex];
- cageweight = weight * inf->weight;
+ totweight = 0.0f;
+ size = mmd->dyngridsize;
+
+ for (i = 0; i < 3; i++) {
+ gridvec[i] = (vec[i] - mmd->dyncellmin[i] - mmd->dyncellwidth * 0.5f) / mmd->dyncellwidth;
+ ivec[i] = (int)gridvec[i];
+ dvec[i] = gridvec[i] - ivec[i];
+ }
+
+ for (i = 0; i < 8; i++) {
+ if (i & 1) {
+ x = ivec[0] + 1;
+ wx = dvec[0];
+ }
+ else {
+ x = ivec[0];
+ wx = 1.0f - dvec[0];
+ }
+
+ if (i & 2) {
+ y = ivec[1] + 1;
+ wy = dvec[1];
+ }
+ else {
+ y = ivec[1];
+ wy = 1.0f - dvec[1];
+ }
+
+ if (i & 4) {
+ z = ivec[2] + 1;
+ wz = dvec[2];
+ }
+ else {
+ z = ivec[2];
+ wz = 1.0f - dvec[2];
+ }
+
+ CLAMP(x, 0, size - 1);
+ CLAMP(y, 0, size - 1);
+ CLAMP(z, 0, size - 1);
+
+ a = x + y * size + z * size * size;
+ weight = wx * wy * wz;
+
+ cell = &mmd->dyngrid[a];
+ inf = mmd->dyninfluences + cell->offset;
+ for (j = 0; j < cell->totinfluence; j++, inf++) {
+ cageco = dco[inf->vertex];
+ cageweight = weight * inf->weight;
#ifdef __SSE2__
- {
- __m128 cageweight_r = _mm_set1_ps(cageweight);
- /* This will load one extra element, this is ok because
- * we ignore that part of register anyway.
- */
- __m128 cageco_r = _mm_loadu_ps(cageco);
- co = _mm_add_ps(co,
- _mm_mul_ps(cageco_r, cageweight_r));
- }
+ {
+ __m128 cageweight_r = _mm_set1_ps(cageweight);
+ /* This will load one extra element, this is ok because
+ * we ignore that part of register anyway.
+ */
+ __m128 cageco_r = _mm_loadu_ps(cageco);
+ co = _mm_add_ps(co, _mm_mul_ps(cageco_r, cageweight_r));
+ }
#else
- co[0] += cageweight * cageco[0];
- co[1] += cageweight * cageco[1];
- co[2] += cageweight * cageco[2];
+ co[0] += cageweight * cageco[0];
+ co[1] += cageweight * cageco[1];
+ co[2] += cageweight * cageco[2];
#endif
- totweight += cageweight;
- }
- }
+ totweight += cageweight;
+ }
+ }
#ifdef __SSE2__
- copy_v3_v3(vec, (float *)&co);
+ copy_v3_v3(vec, (float *)&co);
#else
- copy_v3_v3(vec, co);
+ copy_v3_v3(vec, co);
#endif
- return totweight;
+ return totweight;
}
typedef struct MeshdeformUserdata {
- /*const*/ MeshDeformModifierData *mmd;
- const MDeformVert *dvert;
- /*const*/ float (*dco)[3];
- int defgrp_index;
- float (*vertexCos)[3];
- float (*cagemat)[4];
- float (*icagemat)[3];
+ /*const*/ MeshDeformModifierData *mmd;
+ const MDeformVert *dvert;
+ /*const*/ float (*dco)[3];
+ int defgrp_index;
+ float (*vertexCos)[3];
+ float (*cagemat)[4];
+ float (*icagemat)[3];
} MeshdeformUserdata;
-static void meshdeform_vert_task(
- void *__restrict userdata,
- const int iter,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+static void meshdeform_vert_task(void *__restrict userdata,
+ const int iter,
+ const ParallelRangeTLS *__restrict UNUSED(tls))
{
- MeshdeformUserdata *data = userdata;
- /*const*/ MeshDeformModifierData *mmd = data->mmd;
- const MDeformVert *dvert = data->dvert;
- const int defgrp_index = data->defgrp_index;
- const int *offsets = mmd->bindoffsets;
- const MDefInfluence *__restrict influences = mmd->bindinfluences;
- /*const*/ float (*__restrict dco)[3] = data->dco;
- float (*vertexCos)[3] = data->vertexCos;
- float co[3];
- float weight, totweight, fac = 1.0f;
-
- if (mmd->flag & MOD_MDEF_DYNAMIC_BIND)
- if (!mmd->dynverts[iter])
- return;
-
- if (dvert) {
- fac = defvert_find_weight(&dvert[iter], defgrp_index);
-
- if (mmd->flag & MOD_MDEF_INVERT_VGROUP) {
- fac = 1.0f - fac;
- }
-
- if (fac <= 0.0f) {
- return;
- }
- }
-
- if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) {
- /* transform coordinate into cage's local space */
- mul_v3_m4v3(co, data->cagemat, vertexCos[iter]);
- totweight = meshdeform_dynamic_bind(mmd, dco, co);
- }
- else {
- totweight = 0.0f;
- zero_v3(co);
- int start = offsets[iter];
- int end = offsets[iter + 1];
-
- for (int a = start; a < end; a++) {
- weight = influences[a].weight;
- madd_v3_v3fl(co, dco[influences[a].vertex], weight);
- totweight += weight;
- }
- }
-
- if (totweight > 0.0f) {
- mul_v3_fl(co, fac / totweight);
- mul_m3_v3(data->icagemat, co);
- if (G.debug_value != 527)
- add_v3_v3(vertexCos[iter], co);
- else
- copy_v3_v3(vertexCos[iter], co);
- }
+ MeshdeformUserdata *data = userdata;
+ /*const*/ MeshDeformModifierData *mmd = data->mmd;
+ const MDeformVert *dvert = data->dvert;
+ const int defgrp_index = data->defgrp_index;
+ const int *offsets = mmd->bindoffsets;
+ const MDefInfluence *__restrict influences = mmd->bindinfluences;
+ /*const*/ float(*__restrict dco)[3] = data->dco;
+ float(*vertexCos)[3] = data->vertexCos;
+ float co[3];
+ float weight, totweight, fac = 1.0f;
+
+ if (mmd->flag & MOD_MDEF_DYNAMIC_BIND)
+ if (!mmd->dynverts[iter])
+ return;
+
+ if (dvert) {
+ fac = defvert_find_weight(&dvert[iter], defgrp_index);
+
+ if (mmd->flag & MOD_MDEF_INVERT_VGROUP) {
+ fac = 1.0f - fac;
+ }
+
+ if (fac <= 0.0f) {
+ return;
+ }
+ }
+
+ if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) {
+ /* transform coordinate into cage's local space */
+ mul_v3_m4v3(co, data->cagemat, vertexCos[iter]);
+ totweight = meshdeform_dynamic_bind(mmd, dco, co);
+ }
+ else {
+ totweight = 0.0f;
+ zero_v3(co);
+ int start = offsets[iter];
+ int end = offsets[iter + 1];
+
+ for (int a = start; a < end; a++) {
+ weight = influences[a].weight;
+ madd_v3_v3fl(co, dco[influences[a].vertex], weight);
+ totweight += weight;
+ }
+ }
+
+ if (totweight > 0.0f) {
+ mul_v3_fl(co, fac / totweight);
+ mul_m3_v3(data->icagemat, co);
+ if (G.debug_value != 527)
+ add_v3_v3(vertexCos[iter], co);
+ else
+ copy_v3_v3(vertexCos[iter], co);
+ }
}
-static void meshdeformModifier_do(
- ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh,
- float (*vertexCos)[3], int numVerts)
+static void meshdeformModifier_do(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
- Object *ob = ctx->object;
-
- Mesh *cagemesh;
- MDeformVert *dvert = NULL;
- float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
- float co[3], (*dco)[3] = NULL, (*bindcagecos)[3];
- int a, totvert, totcagevert, defgrp_index;
- float (*cagecos)[3] = NULL;
- MeshdeformUserdata data;
-
- static int recursive_bind_sentinel = 0;
-
- if (mmd->object == NULL || (mmd->bindcagecos == NULL && mmd->bindfunc == NULL))
- return;
-
- /* Get cage mesh.
- *
- * Only do this is the target object is in edit mode by itself, meaning
- * we don't allow linked edit meshes here.
- * This is because editbmesh_get_mesh_cage_and_final() might easily
- * conflict with the thread which evaluates object which is in the edit
- * mode for this mesh.
- *
- * We'll support this case once granular dependency graph is landed.
- */
- Object *ob_target = mmd->object;
- cagemesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob_target, false);
- if (cagemesh == NULL) {
- modifier_setError(md, "Cannot get mesh from cage object");
- return;
- }
-
- /* compute matrices to go in and out of cage object space */
- invert_m4_m4(imat, ob_target->obmat);
- mul_m4_m4m4(cagemat, imat, ob->obmat);
- mul_m4_m4m4(cmat, mmd->bindmat, cagemat);
- invert_m4_m4(iobmat, cmat);
- copy_m3_m4(icagemat, iobmat);
-
- /* bind weights if needed */
- if (!mmd->bindcagecos) {
- /* progress bar redraw can make this recursive .. */
- if (!DEG_is_active(ctx->depsgraph)) {
- modifier_setError(md, "Attempt to bind from inactive dependency graph");
- goto finally;
- }
- if (!recursive_bind_sentinel) {
- recursive_bind_sentinel = 1;
- mmd->bindfunc(mmd, cagemesh, (float *)vertexCos, numVerts, cagemat);
- recursive_bind_sentinel = 0;
- }
-
- goto finally;
- }
-
- /* verify we have compatible weights */
- totvert = numVerts;
- totcagevert = cagemesh->totvert;
-
- if (mmd->totvert != totvert) {
- modifier_setError(md, "Verts changed from %d to %d", mmd->totvert, totvert);
- goto finally;
- }
- else if (mmd->totcagevert != totcagevert) {
- modifier_setError(md, "Cage verts changed from %d to %d", mmd->totcagevert, totcagevert);
- goto finally;
- }
- else if (mmd->bindcagecos == NULL) {
- modifier_setError(md, "Bind data missing");
- goto finally;
- }
-
- /* setup deformation data */
- cagecos = BKE_mesh_vertexCos_get(cagemesh, NULL);
- bindcagecos = (float(*)[3])mmd->bindcagecos;
-
- /* We allocate 1 element extra to make it possible to
- * load the values to SSE registers, which are float4.
- */
- dco = MEM_calloc_arrayN((totcagevert + 1), sizeof(*dco), "MDefDco");
- zero_v3(dco[totcagevert]);
- for (a = 0; a < totcagevert; a++) {
- /* get cage vertex in world space with binding transform */
- copy_v3_v3(co, cagecos[a]);
-
- if (G.debug_value != 527) {
- mul_m4_v3(mmd->bindmat, co);
- /* compute difference with world space bind coord */
- sub_v3_v3v3(dco[a], co, bindcagecos[a]);
- }
- else {
- copy_v3_v3(dco[a], co);
- }
- }
-
- MOD_get_vgroup(ob, mesh, mmd->defgrp_name, &dvert, &defgrp_index);
-
- /* Initialize data to be pass to the for body function. */
- data.mmd = mmd;
- data.dvert = dvert;
- data.dco = dco;
- data.defgrp_index = defgrp_index;
- data.vertexCos = vertexCos;
- data.cagemat = cagemat;
- data.icagemat = icagemat;
-
- /* Do deformation. */
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.min_iter_per_thread = 16;
- BLI_task_parallel_range(0, totvert,
- &data,
- meshdeform_vert_task,
- &settings);
+ MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
+ Object *ob = ctx->object;
+
+ Mesh *cagemesh;
+ MDeformVert *dvert = NULL;
+ float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
+ float co[3], (*dco)[3] = NULL, (*bindcagecos)[3];
+ int a, totvert, totcagevert, defgrp_index;
+ float(*cagecos)[3] = NULL;
+ MeshdeformUserdata data;
+
+ static int recursive_bind_sentinel = 0;
+
+ if (mmd->object == NULL || (mmd->bindcagecos == NULL && mmd->bindfunc == NULL))
+ return;
+
+ /* Get cage mesh.
+ *
+ * Only do this is the target object is in edit mode by itself, meaning
+ * we don't allow linked edit meshes here.
+ * This is because editbmesh_get_mesh_cage_and_final() might easily
+ * conflict with the thread which evaluates object which is in the edit
+ * mode for this mesh.
+ *
+ * We'll support this case once granular dependency graph is landed.
+ */
+ Object *ob_target = mmd->object;
+ cagemesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob_target, false);
+ if (cagemesh == NULL) {
+ modifier_setError(md, "Cannot get mesh from cage object");
+ return;
+ }
+
+ /* compute matrices to go in and out of cage object space */
+ invert_m4_m4(imat, ob_target->obmat);
+ mul_m4_m4m4(cagemat, imat, ob->obmat);
+ mul_m4_m4m4(cmat, mmd->bindmat, cagemat);
+ invert_m4_m4(iobmat, cmat);
+ copy_m3_m4(icagemat, iobmat);
+
+ /* bind weights if needed */
+ if (!mmd->bindcagecos) {
+ /* progress bar redraw can make this recursive .. */
+ if (!DEG_is_active(ctx->depsgraph)) {
+ modifier_setError(md, "Attempt to bind from inactive dependency graph");
+ goto finally;
+ }
+ if (!recursive_bind_sentinel) {
+ recursive_bind_sentinel = 1;
+ mmd->bindfunc(mmd, cagemesh, (float *)vertexCos, numVerts, cagemat);
+ recursive_bind_sentinel = 0;
+ }
+
+ goto finally;
+ }
+
+ /* verify we have compatible weights */
+ totvert = numVerts;
+ totcagevert = cagemesh->totvert;
+
+ if (mmd->totvert != totvert) {
+ modifier_setError(md, "Verts changed from %d to %d", mmd->totvert, totvert);
+ goto finally;
+ }
+ else if (mmd->totcagevert != totcagevert) {
+ modifier_setError(md, "Cage verts changed from %d to %d", mmd->totcagevert, totcagevert);
+ goto finally;
+ }
+ else if (mmd->bindcagecos == NULL) {
+ modifier_setError(md, "Bind data missing");
+ goto finally;
+ }
+
+ /* setup deformation data */
+ cagecos = BKE_mesh_vertexCos_get(cagemesh, NULL);
+ bindcagecos = (float(*)[3])mmd->bindcagecos;
+
+ /* We allocate 1 element extra to make it possible to
+ * load the values to SSE registers, which are float4.
+ */
+ dco = MEM_calloc_arrayN((totcagevert + 1), sizeof(*dco), "MDefDco");
+ zero_v3(dco[totcagevert]);
+ for (a = 0; a < totcagevert; a++) {
+ /* get cage vertex in world space with binding transform */
+ copy_v3_v3(co, cagecos[a]);
+
+ if (G.debug_value != 527) {
+ mul_m4_v3(mmd->bindmat, co);
+ /* compute difference with world space bind coord */
+ sub_v3_v3v3(dco[a], co, bindcagecos[a]);
+ }
+ else {
+ copy_v3_v3(dco[a], co);
+ }
+ }
+
+ MOD_get_vgroup(ob, mesh, mmd->defgrp_name, &dvert, &defgrp_index);
+
+ /* Initialize data to be pass to the for body function. */
+ data.mmd = mmd;
+ data.dvert = dvert;
+ data.dco = dco;
+ data.defgrp_index = defgrp_index;
+ data.vertexCos = vertexCos;
+ data.cagemat = cagemat;
+ data.icagemat = icagemat;
+
+ /* Do deformation. */
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.min_iter_per_thread = 16;
+ BLI_task_parallel_range(0, totvert, &data, meshdeform_vert_task, &settings);
finally:
- MEM_SAFE_FREE(dco);
- MEM_SAFE_FREE(cagecos);
+ MEM_SAFE_FREE(dco);
+ MEM_SAFE_FREE(cagecos);
}
-static void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh,
- float (*vertexCos)[3],
- int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
- MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
+ MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
- meshdeformModifier_do(md, ctx, mesh_src, vertexCos, numVerts);
+ meshdeformModifier_do(md, ctx, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-static void deformVertsEM(
- ModifierData *md, const ModifierEvalContext *ctx,
- struct BMEditMesh *editData,
- Mesh *mesh,
- float (*vertexCos)[3],
- int numVerts)
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *editData,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, editData, mesh, NULL, numVerts, false, false);
- meshdeformModifier_do(md, ctx, mesh_src, vertexCos, numVerts);
+ meshdeformModifier_do(md, ctx, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
#define MESHDEFORM_MIN_INFLUENCE 0.00001f
void modifier_mdef_compact_influences(ModifierData *md)
{
- MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
- float weight, *weights, totweight;
- int totinfluence, totvert, totcagevert, a, b;
-
- weights = mmd->bindweights;
- if (!weights)
- return;
-
- totvert = mmd->totvert;
- totcagevert = mmd->totcagevert;
-
- /* count number of influences above threshold */
- for (b = 0; b < totvert; b++) {
- for (a = 0; a < totcagevert; a++) {
- weight = weights[a + b * totcagevert];
-
- if (weight > MESHDEFORM_MIN_INFLUENCE)
- mmd->totinfluence++;
- }
- }
-
- /* allocate bind influences */
- mmd->bindinfluences = MEM_calloc_arrayN(mmd->totinfluence, sizeof(MDefInfluence), "MDefBindInfluence");
- mmd->bindoffsets = MEM_calloc_arrayN((totvert + 1), sizeof(int), "MDefBindOffset");
-
- /* write influences */
- totinfluence = 0;
-
- for (b = 0; b < totvert; b++) {
- mmd->bindoffsets[b] = totinfluence;
- totweight = 0.0f;
-
- /* sum total weight */
- for (a = 0; a < totcagevert; a++) {
- weight = weights[a + b * totcagevert];
-
- if (weight > MESHDEFORM_MIN_INFLUENCE)
- totweight += weight;
- }
-
- /* assign weights normalized */
- for (a = 0; a < totcagevert; a++) {
- weight = weights[a + b * totcagevert];
-
- if (weight > MESHDEFORM_MIN_INFLUENCE) {
- mmd->bindinfluences[totinfluence].weight = weight / totweight;
- mmd->bindinfluences[totinfluence].vertex = a;
- totinfluence++;
- }
- }
- }
-
- mmd->bindoffsets[b] = totinfluence;
-
- /* free */
- MEM_freeN(mmd->bindweights);
- mmd->bindweights = NULL;
+ MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
+ float weight, *weights, totweight;
+ int totinfluence, totvert, totcagevert, a, b;
+
+ weights = mmd->bindweights;
+ if (!weights)
+ return;
+
+ totvert = mmd->totvert;
+ totcagevert = mmd->totcagevert;
+
+ /* count number of influences above threshold */
+ for (b = 0; b < totvert; b++) {
+ for (a = 0; a < totcagevert; a++) {
+ weight = weights[a + b * totcagevert];
+
+ if (weight > MESHDEFORM_MIN_INFLUENCE)
+ mmd->totinfluence++;
+ }
+ }
+
+ /* allocate bind influences */
+ mmd->bindinfluences = MEM_calloc_arrayN(
+ mmd->totinfluence, sizeof(MDefInfluence), "MDefBindInfluence");
+ mmd->bindoffsets = MEM_calloc_arrayN((totvert + 1), sizeof(int), "MDefBindOffset");
+
+ /* write influences */
+ totinfluence = 0;
+
+ for (b = 0; b < totvert; b++) {
+ mmd->bindoffsets[b] = totinfluence;
+ totweight = 0.0f;
+
+ /* sum total weight */
+ for (a = 0; a < totcagevert; a++) {
+ weight = weights[a + b * totcagevert];
+
+ if (weight > MESHDEFORM_MIN_INFLUENCE)
+ totweight += weight;
+ }
+
+ /* assign weights normalized */
+ for (a = 0; a < totcagevert; a++) {
+ weight = weights[a + b * totcagevert];
+
+ if (weight > MESHDEFORM_MIN_INFLUENCE) {
+ mmd->bindinfluences[totinfluence].weight = weight / totweight;
+ mmd->bindinfluences[totinfluence].vertex = a;
+ totinfluence++;
+ }
+ }
+ }
+
+ mmd->bindoffsets[b] = totinfluence;
+
+ /* free */
+ MEM_freeN(mmd->bindweights);
+ mmd->bindweights = NULL;
}
ModifierTypeInfo modifierType_MeshDeform = {
- /* name */ "MeshDeform",
- /* structName */ "MeshDeformModifierData",
- /* structSize */ sizeof(MeshDeformModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_AcceptsLattice |
- eModifierTypeFlag_SupportsEditmode,
-
- /* copyData */ copyData,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ freeData,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "MeshDeform",
+ /* structName */ "MeshDeformModifierData",
+ /* structSize */ sizeof(MeshDeformModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice |
+ eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ copyData,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ freeData,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c
index 3b092bc7a76..7710082150b 100644
--- a/source/blender/modifiers/intern/MOD_meshsequencecache.c
+++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c
@@ -42,168 +42,158 @@
static void initData(ModifierData *md)
{
- MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md;
+ MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md;
- mcmd->cache_file = NULL;
- mcmd->object_path[0] = '\0';
- mcmd->read_flag = MOD_MESHSEQ_READ_ALL;
+ mcmd->cache_file = NULL;
+ mcmd->object_path[0] = '\0';
+ mcmd->read_flag = MOD_MESHSEQ_READ_ALL;
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
#if 0
- const MeshSeqCacheModifierData *mcmd = (const MeshSeqCacheModifierData *)md;
+ const MeshSeqCacheModifierData *mcmd = (const MeshSeqCacheModifierData *)md;
#endif
- MeshSeqCacheModifierData *tmcmd = (MeshSeqCacheModifierData *)target;
+ MeshSeqCacheModifierData *tmcmd = (MeshSeqCacheModifierData *)target;
- modifier_copyData_generic(md, target, flag);
+ modifier_copyData_generic(md, target, flag);
- tmcmd->reader = NULL;
+ tmcmd->reader = NULL;
}
static void freeData(ModifierData *md)
{
- MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *) md;
+ MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md;
- if (mcmd->reader) {
+ if (mcmd->reader) {
#ifdef WITH_ALEMBIC
- CacheReader_free(mcmd->reader);
+ CacheReader_free(mcmd->reader);
#endif
- mcmd->reader = NULL;
- }
+ mcmd->reader = NULL;
+ }
}
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(useRenderParams))
{
- MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *) md;
+ MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md;
- /* leave it up to the modifier to check the file is valid on calculation */
- return (mcmd->cache_file == NULL) || (mcmd->object_path[0] == '\0');
+ /* leave it up to the modifier to check the file is valid on calculation */
+ return (mcmd->cache_file == NULL) || (mcmd->object_path[0] == '\0');
}
-static Mesh *applyModifier(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
#ifdef WITH_ALEMBIC
- MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *) md;
-
- /* Only used to check whether we are operating on org data or not... */
- Mesh *me = (ctx->object->type == OB_MESH) ? ctx->object->data : NULL;
- Mesh *org_mesh = mesh;
-
- Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- const float frame = DEG_get_ctime(ctx->depsgraph);
- const float time = BKE_cachefile_time_offset(mcmd->cache_file, frame, FPS);
- const char *err_str = NULL;
-
- CacheFile *cache_file = (CacheFile *)DEG_get_original_id(&mcmd->cache_file->id);
-
- BKE_cachefile_ensure_handle(G.main, cache_file);
-
- if (!mcmd->reader) {
- mcmd->reader = CacheReader_open_alembic_object(cache_file->handle,
- NULL,
- ctx->object,
- mcmd->object_path);
- if (!mcmd->reader) {
- modifier_setError(md, "Could not create Alembic reader for file %s", cache_file->filepath);
- return mesh;
- }
- }
-
- if (me != NULL) {
- MVert *mvert = mesh->mvert;
- MEdge *medge = mesh->medge;
- MPoly *mpoly = mesh->mpoly;
- if ((me->mvert == mvert) || (me->medge == medge) || (me->mpoly == mpoly)) {
- /* We need to duplicate data here, otherwise we'll modify org mesh, see T51701. */
- BKE_id_copy_ex(NULL, &mesh->id, (ID **)&mesh,
- LIB_ID_CREATE_NO_MAIN |
- LIB_ID_CREATE_NO_USER_REFCOUNT |
- LIB_ID_CREATE_NO_DEG_TAG |
- LIB_ID_COPY_NO_PREVIEW);
- }
- }
-
- Mesh *result = ABC_read_mesh(mcmd->reader,
- ctx->object,
- mesh,
- time,
- &err_str,
- mcmd->read_flag);
-
- if (err_str) {
- modifier_setError(md, "%s", err_str);
- }
-
- if (!ELEM(result, NULL, mesh) && (mesh != org_mesh)) {
- BKE_id_free(NULL, mesh);
- mesh = org_mesh;
- }
-
- return result ? result : mesh;
+ MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md;
+
+ /* Only used to check whether we are operating on org data or not... */
+ Mesh *me = (ctx->object->type == OB_MESH) ? ctx->object->data : NULL;
+ Mesh *org_mesh = mesh;
+
+ Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ const float frame = DEG_get_ctime(ctx->depsgraph);
+ const float time = BKE_cachefile_time_offset(mcmd->cache_file, frame, FPS);
+ const char *err_str = NULL;
+
+ CacheFile *cache_file = (CacheFile *)DEG_get_original_id(&mcmd->cache_file->id);
+
+ BKE_cachefile_ensure_handle(G.main, cache_file);
+
+ if (!mcmd->reader) {
+ mcmd->reader = CacheReader_open_alembic_object(
+ cache_file->handle, NULL, ctx->object, mcmd->object_path);
+ if (!mcmd->reader) {
+ modifier_setError(md, "Could not create Alembic reader for file %s", cache_file->filepath);
+ return mesh;
+ }
+ }
+
+ if (me != NULL) {
+ MVert *mvert = mesh->mvert;
+ MEdge *medge = mesh->medge;
+ MPoly *mpoly = mesh->mpoly;
+ if ((me->mvert == mvert) || (me->medge == medge) || (me->mpoly == mpoly)) {
+ /* We need to duplicate data here, otherwise we'll modify org mesh, see T51701. */
+ BKE_id_copy_ex(NULL,
+ &mesh->id,
+ (ID **)&mesh,
+ LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT |
+ LIB_ID_CREATE_NO_DEG_TAG | LIB_ID_COPY_NO_PREVIEW);
+ }
+ }
+
+ Mesh *result = ABC_read_mesh(mcmd->reader, ctx->object, mesh, time, &err_str, mcmd->read_flag);
+
+ if (err_str) {
+ modifier_setError(md, "%s", err_str);
+ }
+
+ if (!ELEM(result, NULL, mesh) && (mesh != org_mesh)) {
+ BKE_id_free(NULL, mesh);
+ mesh = org_mesh;
+ }
+
+ return result ? result : mesh;
#else
- UNUSED_VARS(ctx, md);
- return mesh;
+ UNUSED_VARS(ctx, md);
+ return mesh;
#endif
}
static bool dependsOnTime(ModifierData *md)
{
#ifdef WITH_ALEMBIC
- MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *) md;
- return (mcmd->cache_file != NULL);
+ MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md;
+ return (mcmd->cache_file != NULL);
#else
- UNUSED_VARS(md);
- return false;
+ UNUSED_VARS(md);
+ return false;
#endif
}
-static void foreachIDLink(
- ModifierData *md, Object *ob,
- IDWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
- MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *) md;
+ MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md;
- walk(userData, ob, (ID **)&mcmd->cache_file, IDWALK_CB_USER);
+ walk(userData, ob, (ID **)&mcmd->cache_file, IDWALK_CB_USER);
}
-
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *) md;
+ MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md;
- if (mcmd->cache_file != NULL) {
- DEG_add_object_cache_relation(ctx->node, mcmd->cache_file, DEG_OB_COMP_CACHE, "Mesh Cache File");
- }
+ if (mcmd->cache_file != NULL) {
+ DEG_add_object_cache_relation(
+ ctx->node, mcmd->cache_file, DEG_OB_COMP_CACHE, "Mesh Cache File");
+ }
}
ModifierTypeInfo modifierType_MeshSequenceCache = {
- /* name */ "Mesh Sequence Cache",
- /* structName */ "MeshSeqCacheModifierData",
- /* structSize */ sizeof(MeshSeqCacheModifierData),
- /* type */ eModifierTypeType_Constructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_AcceptsCVs,
-
- /* copyData */ copyData,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ NULL,
- /* freeData */ freeData,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ foreachIDLink,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Mesh Sequence Cache",
+ /* structName */ "MeshSeqCacheModifierData",
+ /* structSize */ sizeof(MeshSeqCacheModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs,
+
+ /* copyData */ copyData,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ freeData,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c
index 5fb4c66471f..39b86ca48fd 100644
--- a/source/blender/modifiers/intern/MOD_mirror.c
+++ b/source/blender/modifiers/intern/MOD_mirror.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include "BLI_math.h"
#include "DNA_mesh_types.h"
@@ -46,407 +45,402 @@
static void initData(ModifierData *md)
{
- MirrorModifierData *mmd = (MirrorModifierData *) md;
+ MirrorModifierData *mmd = (MirrorModifierData *)md;
- mmd->flag |= (MOD_MIR_AXIS_X | MOD_MIR_VGROUP);
- mmd->tolerance = 0.001;
- mmd->mirror_ob = NULL;
+ mmd->flag |= (MOD_MIR_AXIS_X | MOD_MIR_VGROUP);
+ mmd->tolerance = 0.001;
+ mmd->mirror_ob = NULL;
}
-static void foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- MirrorModifierData *mmd = (MirrorModifierData *) md;
+ MirrorModifierData *mmd = (MirrorModifierData *)md;
- walk(userData, ob, &mmd->mirror_ob, IDWALK_CB_NOP);
+ walk(userData, ob, &mmd->mirror_ob, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- MirrorModifierData *mmd = (MirrorModifierData *)md;
- if (mmd->mirror_ob != NULL) {
- DEG_add_object_relation(ctx->node, mmd->mirror_ob, DEG_OB_COMP_TRANSFORM, "Mirror Modifier");
- DEG_add_modifier_to_transform_relation(ctx->node, "Mirror Modifier");
- }
+ MirrorModifierData *mmd = (MirrorModifierData *)md;
+ if (mmd->mirror_ob != NULL) {
+ DEG_add_object_relation(ctx->node, mmd->mirror_ob, DEG_OB_COMP_TRANSFORM, "Mirror Modifier");
+ DEG_add_modifier_to_transform_relation(ctx->node, "Mirror Modifier");
+ }
}
static Mesh *doBiscetOnMirrorPlane(
- MirrorModifierData *mmd,
- const Mesh *mesh,
- int axis,
- float plane_co[3],
- float plane_no[3])
+ MirrorModifierData *mmd, const Mesh *mesh, int axis, float plane_co[3], float plane_no[3])
{
- bool do_bisect_flip_axis = (
- (axis == 0 && mmd->flag & MOD_MIR_BISECT_FLIP_AXIS_X) ||
- (axis == 1 && mmd->flag & MOD_MIR_BISECT_FLIP_AXIS_Y) ||
- (axis == 2 && mmd->flag & MOD_MIR_BISECT_FLIP_AXIS_Z));
-
- const float bisect_distance = 0.001f;
-
- Mesh *result;
- BMesh *bm;
- BMIter viter;
- BMVert *v, *v_next;
-
- bm = BKE_mesh_to_bmesh_ex(
- mesh,
- &(struct BMeshCreateParams){0},
- &(struct BMeshFromMeshParams){
- .calc_face_normal = true,
- .cd_mask_extra = {.vmask = CD_MASK_ORIGINDEX, .emask = CD_MASK_ORIGINDEX, .pmask = CD_MASK_ORIGINDEX},
- });
-
- /* Define bisecting plane (aka mirror plane). */
- float plane[4];
- if (!do_bisect_flip_axis) {
- /* That reversed condition is a tad weird, but for some reason that's how you keep
- * the part of the mesh which is on the non-mirrored side when flip option is disabled,
- * think that that is the expected behavior. */
- negate_v3(plane_no);
- }
- plane_from_point_normal_v3(plane, plane_co, plane_no);
-
- BM_mesh_bisect_plane(bm, plane, false, false, 0, 0, bisect_distance);
-
- /* Plane definitions for vert killing. */
- float plane_offset[4];
- copy_v3_v3(plane_offset, plane);
- plane_offset[3] = plane[3] - bisect_distance;
-
- /* Delete verts across the mirror plane. */
- BM_ITER_MESH_MUTABLE(v, v_next, &viter, bm, BM_VERTS_OF_MESH) {
- if (plane_point_side_v3(plane_offset, v->co) > 0.0f) {
- BM_vert_kill(bm, v);
- }
- }
-
- result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
- BM_mesh_free(bm);
-
- return result;
+ bool do_bisect_flip_axis = ((axis == 0 && mmd->flag & MOD_MIR_BISECT_FLIP_AXIS_X) ||
+ (axis == 1 && mmd->flag & MOD_MIR_BISECT_FLIP_AXIS_Y) ||
+ (axis == 2 && mmd->flag & MOD_MIR_BISECT_FLIP_AXIS_Z));
+
+ const float bisect_distance = 0.001f;
+
+ Mesh *result;
+ BMesh *bm;
+ BMIter viter;
+ BMVert *v, *v_next;
+
+ bm = BKE_mesh_to_bmesh_ex(mesh,
+ &(struct BMeshCreateParams){0},
+ &(struct BMeshFromMeshParams){
+ .calc_face_normal = true,
+ .cd_mask_extra = {.vmask = CD_MASK_ORIGINDEX,
+ .emask = CD_MASK_ORIGINDEX,
+ .pmask = CD_MASK_ORIGINDEX},
+ });
+
+ /* Define bisecting plane (aka mirror plane). */
+ float plane[4];
+ if (!do_bisect_flip_axis) {
+ /* That reversed condition is a tad weird, but for some reason that's how you keep
+ * the part of the mesh which is on the non-mirrored side when flip option is disabled,
+ * think that that is the expected behavior. */
+ negate_v3(plane_no);
+ }
+ plane_from_point_normal_v3(plane, plane_co, plane_no);
+
+ BM_mesh_bisect_plane(bm, plane, false, false, 0, 0, bisect_distance);
+
+ /* Plane definitions for vert killing. */
+ float plane_offset[4];
+ copy_v3_v3(plane_offset, plane);
+ plane_offset[3] = plane[3] - bisect_distance;
+
+ /* Delete verts across the mirror plane. */
+ BM_ITER_MESH_MUTABLE (v, v_next, &viter, bm, BM_VERTS_OF_MESH) {
+ if (plane_point_side_v3(plane_offset, v->co) > 0.0f) {
+ BM_vert_kill(bm, v);
+ }
+ }
+
+ result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
+ BM_mesh_free(bm);
+
+ return result;
}
-static Mesh *doMirrorOnAxis(
- MirrorModifierData *mmd,
- const ModifierEvalContext *UNUSED(ctx),
- Object *ob,
- const Mesh *mesh,
- int axis)
+static Mesh *doMirrorOnAxis(MirrorModifierData *mmd,
+ const ModifierEvalContext *UNUSED(ctx),
+ Object *ob,
+ const Mesh *mesh,
+ int axis)
{
- const float tolerance_sq = mmd->tolerance * mmd->tolerance;
- const bool do_vtargetmap = (mmd->flag & MOD_MIR_NO_MERGE) == 0;
- int tot_vtargetmap = 0; /* total merge vertices */
-
- const bool do_bisect = (
- (axis == 0 && mmd->flag & MOD_MIR_BISECT_AXIS_X) ||
- (axis == 1 && mmd->flag & MOD_MIR_BISECT_AXIS_Y) ||
- (axis == 2 && mmd->flag & MOD_MIR_BISECT_AXIS_Z));
-
- Mesh *result;
- MVert *mv, *mv_prev;
- MEdge *me;
- MLoop *ml;
- MPoly *mp;
- float mtx[4][4];
- float plane_co[3], plane_no[3];
- int i;
- int a, totshape;
- int *vtargetmap = NULL, *vtmap_a = NULL, *vtmap_b = NULL;
-
- /* mtx is the mirror transformation */
- unit_m4(mtx);
- mtx[axis][axis] = -1.0f;
-
- Object *mirror_ob = mmd->mirror_ob;
- if (mirror_ob != NULL) {
- float tmp[4][4];
- float itmp[4][4];
-
- /* tmp is a transform from coords relative to the object's own origin,
- * to coords relative to the mirror object origin */
- invert_m4_m4(tmp, mirror_ob->obmat);
- mul_m4_m4m4(tmp, tmp, ob->obmat);
-
- /* itmp is the reverse transform back to origin-relative coordinates */
- invert_m4_m4(itmp, tmp);
-
- /* combine matrices to get a single matrix that translates coordinates into
- * mirror-object-relative space, does the mirror, and translates back to
- * origin-relative space */
- mul_m4_series(mtx, itmp, mtx, tmp);
-
- if (do_bisect) {
- copy_v3_v3(plane_co, itmp[3]);
- copy_v3_v3(plane_no, itmp[axis]);
- }
- }
- else if (do_bisect) {
- copy_v3_v3(plane_co, mtx[3]);
- /* Need to negate here, since that axis is inverted (for mirror transform). */
- negate_v3_v3(plane_no, mtx[axis]);
- }
-
- Mesh *mesh_bisect = NULL;
- if (do_bisect) {
- mesh_bisect = doBiscetOnMirrorPlane(mmd, mesh, axis, plane_co, plane_no);
- mesh = mesh_bisect;
- }
-
- const int maxVerts = mesh->totvert;
- const int maxEdges = mesh->totedge;
- const int maxLoops = mesh->totloop;
- const int maxPolys = mesh->totpoly;
-
- result = BKE_mesh_new_nomain_from_template(
- mesh, maxVerts * 2, maxEdges * 2, 0, maxLoops * 2, maxPolys * 2);
-
- /*copy customdata to original geometry*/
- CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, maxVerts);
- CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, maxEdges);
- CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, maxLoops);
- CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, maxPolys);
-
- /* Subsurf for eg won't have mesh data in the custom data arrays.
- * now add mvert/medge/mpoly layers. */
- if (!CustomData_has_layer(&mesh->vdata, CD_MVERT)) {
- memcpy(result->mvert, mesh->mvert, sizeof(*result->mvert) * mesh->totvert);
- }
- if (!CustomData_has_layer(&mesh->edata, CD_MEDGE)) {
- memcpy(result->medge, mesh->medge, sizeof(*result->medge) * mesh->totedge);
- }
- if (!CustomData_has_layer(&mesh->pdata, CD_MPOLY)) {
- memcpy(result->mloop, mesh->mloop, sizeof(*result->mloop) * mesh->totloop);
- memcpy(result->mpoly, mesh->mpoly, sizeof(*result->mpoly) * mesh->totpoly);
- }
-
- /* copy customdata to new geometry,
- * copy from its self because this data may have been created in the checks above */
- CustomData_copy_data(&result->vdata, &result->vdata, 0, maxVerts, maxVerts);
- CustomData_copy_data(&result->edata, &result->edata, 0, maxEdges, maxEdges);
- /* loops are copied later */
- CustomData_copy_data(&result->pdata, &result->pdata, 0, maxPolys, maxPolys);
-
- if (do_vtargetmap) {
- /* second half is filled with -1 */
- vtargetmap = MEM_malloc_arrayN(maxVerts, 2 * sizeof(int), "MOD_mirror tarmap");
-
- vtmap_a = vtargetmap;
- vtmap_b = vtargetmap + maxVerts;
- }
-
- /* mirror vertex coordinates */
- mv_prev = result->mvert;
- mv = mv_prev + maxVerts;
- for (i = 0; i < maxVerts; i++, mv++, mv_prev++) {
- mul_m4_v3(mtx, mv->co);
-
- if (do_vtargetmap) {
- /* compare location of the original and mirrored vertex, to see if they
- * should be mapped for merging */
- if (UNLIKELY(len_squared_v3v3(mv_prev->co, mv->co) < tolerance_sq)) {
- *vtmap_a = maxVerts + i;
- tot_vtargetmap++;
-
- /* average location */
- mid_v3_v3v3(mv->co, mv_prev->co, mv->co);
- copy_v3_v3(mv_prev->co, mv->co);
- }
- else {
- *vtmap_a = -1;
- }
-
- *vtmap_b = -1; /* fill here to avoid 2x loops */
-
- vtmap_a++;
- vtmap_b++;
- }
- }
-
- /* handle shape keys */
- totshape = CustomData_number_of_layers(&result->vdata, CD_SHAPEKEY);
- for (a = 0; a < totshape; a++) {
- float (*cos)[3] = CustomData_get_layer_n(&result->vdata, CD_SHAPEKEY, a);
- for (i = maxVerts; i < result->totvert; i++) {
- mul_m4_v3(mtx, cos[i]);
- }
- }
-
- /* adjust mirrored edge vertex indices */
- me = result->medge + maxEdges;
- for (i = 0; i < maxEdges; i++, me++) {
- me->v1 += maxVerts;
- me->v2 += maxVerts;
- }
-
- /* adjust mirrored poly loopstart indices, and reverse loop order (normals) */
- mp = result->mpoly + maxPolys;
- ml = result->mloop;
- for (i = 0; i < maxPolys; i++, mp++) {
- MLoop *ml2;
- int j, e;
-
- /* reverse the loop, but we keep the first vertex in the face the same,
- * to ensure that quads are split the same way as on the other side */
- CustomData_copy_data(&result->ldata, &result->ldata, mp->loopstart, mp->loopstart + maxLoops, 1);
-
- for (j = 1; j < mp->totloop; j++)
- CustomData_copy_data(&result->ldata, &result->ldata,
- mp->loopstart + j,
- mp->loopstart + maxLoops + mp->totloop - j,
- 1);
-
- ml2 = ml + mp->loopstart + maxLoops;
- e = ml2[0].e;
- for (j = 0; j < mp->totloop - 1; j++) {
- ml2[j].e = ml2[j + 1].e;
- }
- ml2[mp->totloop - 1].e = e;
-
- mp->loopstart += maxLoops;
- }
-
- /* adjust mirrored loop vertex and edge indices */
- ml = result->mloop + maxLoops;
- for (i = 0; i < maxLoops; i++, ml++) {
- ml->v += maxVerts;
- ml->e += maxEdges;
- }
-
- /* handle uvs,
- * let tessface recalc handle updating the MTFace data */
- if (mmd->flag & (MOD_MIR_MIRROR_U | MOD_MIR_MIRROR_V) || (is_zero_v2(mmd->uv_offset_copy) == false)) {
- const bool do_mirr_u = (mmd->flag & MOD_MIR_MIRROR_U) != 0;
- const bool do_mirr_v = (mmd->flag & MOD_MIR_MIRROR_V) != 0;
-
- const int totuv = CustomData_number_of_layers(&result->ldata, CD_MLOOPUV);
-
- for (a = 0; a < totuv; a++) {
- MLoopUV *dmloopuv = CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, a);
- int j = maxLoops;
- dmloopuv += j; /* second set of loops only */
- for (; j-- > 0; dmloopuv++) {
- if (do_mirr_u) dmloopuv->uv[0] = 1.0f - dmloopuv->uv[0] + mmd->uv_offset[0];
- if (do_mirr_v) dmloopuv->uv[1] = 1.0f - dmloopuv->uv[1] + mmd->uv_offset[1];
- dmloopuv->uv[0] += mmd->uv_offset_copy[0];
- dmloopuv->uv[1] += mmd->uv_offset_copy[1];
- }
- }
- }
-
- /* handle vgroup stuff */
- if ((mmd->flag & MOD_MIR_VGROUP) && CustomData_has_layer(&result->vdata, CD_MDEFORMVERT)) {
- MDeformVert *dvert = (MDeformVert *) CustomData_get_layer(&result->vdata, CD_MDEFORMVERT) + maxVerts;
- int *flip_map = NULL, flip_map_len = 0;
-
- flip_map = defgroup_flip_map(ob, &flip_map_len, false);
-
- if (flip_map) {
- for (i = 0; i < maxVerts; dvert++, i++) {
- /* merged vertices get both groups, others get flipped */
- if (do_vtargetmap && (vtargetmap[i] != -1))
- defvert_flip_merged(dvert, flip_map, flip_map_len);
- else
- defvert_flip(dvert, flip_map, flip_map_len);
- }
-
- MEM_freeN(flip_map);
- }
- }
-
- if (do_vtargetmap) {
- /* slow - so only call if one or more merge verts are found,
- * users may leave this on and not realize there is nothing to merge - campbell */
- if (tot_vtargetmap) {
- result = BKE_mesh_merge_verts(result, vtargetmap, tot_vtargetmap, MESH_MERGE_VERTS_DUMP_IF_MAPPED);
- }
- MEM_freeN(vtargetmap);
- }
-
- if (mesh_bisect != NULL) {
- BKE_id_free(NULL, mesh_bisect);
- }
-
- return result;
+ const float tolerance_sq = mmd->tolerance * mmd->tolerance;
+ const bool do_vtargetmap = (mmd->flag & MOD_MIR_NO_MERGE) == 0;
+ int tot_vtargetmap = 0; /* total merge vertices */
+
+ const bool do_bisect = ((axis == 0 && mmd->flag & MOD_MIR_BISECT_AXIS_X) ||
+ (axis == 1 && mmd->flag & MOD_MIR_BISECT_AXIS_Y) ||
+ (axis == 2 && mmd->flag & MOD_MIR_BISECT_AXIS_Z));
+
+ Mesh *result;
+ MVert *mv, *mv_prev;
+ MEdge *me;
+ MLoop *ml;
+ MPoly *mp;
+ float mtx[4][4];
+ float plane_co[3], plane_no[3];
+ int i;
+ int a, totshape;
+ int *vtargetmap = NULL, *vtmap_a = NULL, *vtmap_b = NULL;
+
+ /* mtx is the mirror transformation */
+ unit_m4(mtx);
+ mtx[axis][axis] = -1.0f;
+
+ Object *mirror_ob = mmd->mirror_ob;
+ if (mirror_ob != NULL) {
+ float tmp[4][4];
+ float itmp[4][4];
+
+ /* tmp is a transform from coords relative to the object's own origin,
+ * to coords relative to the mirror object origin */
+ invert_m4_m4(tmp, mirror_ob->obmat);
+ mul_m4_m4m4(tmp, tmp, ob->obmat);
+
+ /* itmp is the reverse transform back to origin-relative coordinates */
+ invert_m4_m4(itmp, tmp);
+
+ /* combine matrices to get a single matrix that translates coordinates into
+ * mirror-object-relative space, does the mirror, and translates back to
+ * origin-relative space */
+ mul_m4_series(mtx, itmp, mtx, tmp);
+
+ if (do_bisect) {
+ copy_v3_v3(plane_co, itmp[3]);
+ copy_v3_v3(plane_no, itmp[axis]);
+ }
+ }
+ else if (do_bisect) {
+ copy_v3_v3(plane_co, mtx[3]);
+ /* Need to negate here, since that axis is inverted (for mirror transform). */
+ negate_v3_v3(plane_no, mtx[axis]);
+ }
+
+ Mesh *mesh_bisect = NULL;
+ if (do_bisect) {
+ mesh_bisect = doBiscetOnMirrorPlane(mmd, mesh, axis, plane_co, plane_no);
+ mesh = mesh_bisect;
+ }
+
+ const int maxVerts = mesh->totvert;
+ const int maxEdges = mesh->totedge;
+ const int maxLoops = mesh->totloop;
+ const int maxPolys = mesh->totpoly;
+
+ result = BKE_mesh_new_nomain_from_template(
+ mesh, maxVerts * 2, maxEdges * 2, 0, maxLoops * 2, maxPolys * 2);
+
+ /*copy customdata to original geometry*/
+ CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, maxVerts);
+ CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, maxEdges);
+ CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, maxLoops);
+ CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, maxPolys);
+
+ /* Subsurf for eg won't have mesh data in the custom data arrays.
+ * now add mvert/medge/mpoly layers. */
+ if (!CustomData_has_layer(&mesh->vdata, CD_MVERT)) {
+ memcpy(result->mvert, mesh->mvert, sizeof(*result->mvert) * mesh->totvert);
+ }
+ if (!CustomData_has_layer(&mesh->edata, CD_MEDGE)) {
+ memcpy(result->medge, mesh->medge, sizeof(*result->medge) * mesh->totedge);
+ }
+ if (!CustomData_has_layer(&mesh->pdata, CD_MPOLY)) {
+ memcpy(result->mloop, mesh->mloop, sizeof(*result->mloop) * mesh->totloop);
+ memcpy(result->mpoly, mesh->mpoly, sizeof(*result->mpoly) * mesh->totpoly);
+ }
+
+ /* copy customdata to new geometry,
+ * copy from its self because this data may have been created in the checks above */
+ CustomData_copy_data(&result->vdata, &result->vdata, 0, maxVerts, maxVerts);
+ CustomData_copy_data(&result->edata, &result->edata, 0, maxEdges, maxEdges);
+ /* loops are copied later */
+ CustomData_copy_data(&result->pdata, &result->pdata, 0, maxPolys, maxPolys);
+
+ if (do_vtargetmap) {
+ /* second half is filled with -1 */
+ vtargetmap = MEM_malloc_arrayN(maxVerts, 2 * sizeof(int), "MOD_mirror tarmap");
+
+ vtmap_a = vtargetmap;
+ vtmap_b = vtargetmap + maxVerts;
+ }
+
+ /* mirror vertex coordinates */
+ mv_prev = result->mvert;
+ mv = mv_prev + maxVerts;
+ for (i = 0; i < maxVerts; i++, mv++, mv_prev++) {
+ mul_m4_v3(mtx, mv->co);
+
+ if (do_vtargetmap) {
+ /* compare location of the original and mirrored vertex, to see if they
+ * should be mapped for merging */
+ if (UNLIKELY(len_squared_v3v3(mv_prev->co, mv->co) < tolerance_sq)) {
+ *vtmap_a = maxVerts + i;
+ tot_vtargetmap++;
+
+ /* average location */
+ mid_v3_v3v3(mv->co, mv_prev->co, mv->co);
+ copy_v3_v3(mv_prev->co, mv->co);
+ }
+ else {
+ *vtmap_a = -1;
+ }
+
+ *vtmap_b = -1; /* fill here to avoid 2x loops */
+
+ vtmap_a++;
+ vtmap_b++;
+ }
+ }
+
+ /* handle shape keys */
+ totshape = CustomData_number_of_layers(&result->vdata, CD_SHAPEKEY);
+ for (a = 0; a < totshape; a++) {
+ float(*cos)[3] = CustomData_get_layer_n(&result->vdata, CD_SHAPEKEY, a);
+ for (i = maxVerts; i < result->totvert; i++) {
+ mul_m4_v3(mtx, cos[i]);
+ }
+ }
+
+ /* adjust mirrored edge vertex indices */
+ me = result->medge + maxEdges;
+ for (i = 0; i < maxEdges; i++, me++) {
+ me->v1 += maxVerts;
+ me->v2 += maxVerts;
+ }
+
+ /* adjust mirrored poly loopstart indices, and reverse loop order (normals) */
+ mp = result->mpoly + maxPolys;
+ ml = result->mloop;
+ for (i = 0; i < maxPolys; i++, mp++) {
+ MLoop *ml2;
+ int j, e;
+
+ /* reverse the loop, but we keep the first vertex in the face the same,
+ * to ensure that quads are split the same way as on the other side */
+ CustomData_copy_data(
+ &result->ldata, &result->ldata, mp->loopstart, mp->loopstart + maxLoops, 1);
+
+ for (j = 1; j < mp->totloop; j++)
+ CustomData_copy_data(&result->ldata,
+ &result->ldata,
+ mp->loopstart + j,
+ mp->loopstart + maxLoops + mp->totloop - j,
+ 1);
+
+ ml2 = ml + mp->loopstart + maxLoops;
+ e = ml2[0].e;
+ for (j = 0; j < mp->totloop - 1; j++) {
+ ml2[j].e = ml2[j + 1].e;
+ }
+ ml2[mp->totloop - 1].e = e;
+
+ mp->loopstart += maxLoops;
+ }
+
+ /* adjust mirrored loop vertex and edge indices */
+ ml = result->mloop + maxLoops;
+ for (i = 0; i < maxLoops; i++, ml++) {
+ ml->v += maxVerts;
+ ml->e += maxEdges;
+ }
+
+ /* handle uvs,
+ * let tessface recalc handle updating the MTFace data */
+ if (mmd->flag & (MOD_MIR_MIRROR_U | MOD_MIR_MIRROR_V) ||
+ (is_zero_v2(mmd->uv_offset_copy) == false)) {
+ const bool do_mirr_u = (mmd->flag & MOD_MIR_MIRROR_U) != 0;
+ const bool do_mirr_v = (mmd->flag & MOD_MIR_MIRROR_V) != 0;
+
+ const int totuv = CustomData_number_of_layers(&result->ldata, CD_MLOOPUV);
+
+ for (a = 0; a < totuv; a++) {
+ MLoopUV *dmloopuv = CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, a);
+ int j = maxLoops;
+ dmloopuv += j; /* second set of loops only */
+ for (; j-- > 0; dmloopuv++) {
+ if (do_mirr_u)
+ dmloopuv->uv[0] = 1.0f - dmloopuv->uv[0] + mmd->uv_offset[0];
+ if (do_mirr_v)
+ dmloopuv->uv[1] = 1.0f - dmloopuv->uv[1] + mmd->uv_offset[1];
+ dmloopuv->uv[0] += mmd->uv_offset_copy[0];
+ dmloopuv->uv[1] += mmd->uv_offset_copy[1];
+ }
+ }
+ }
+
+ /* handle vgroup stuff */
+ if ((mmd->flag & MOD_MIR_VGROUP) && CustomData_has_layer(&result->vdata, CD_MDEFORMVERT)) {
+ MDeformVert *dvert = (MDeformVert *)CustomData_get_layer(&result->vdata, CD_MDEFORMVERT) +
+ maxVerts;
+ int *flip_map = NULL, flip_map_len = 0;
+
+ flip_map = defgroup_flip_map(ob, &flip_map_len, false);
+
+ if (flip_map) {
+ for (i = 0; i < maxVerts; dvert++, i++) {
+ /* merged vertices get both groups, others get flipped */
+ if (do_vtargetmap && (vtargetmap[i] != -1))
+ defvert_flip_merged(dvert, flip_map, flip_map_len);
+ else
+ defvert_flip(dvert, flip_map, flip_map_len);
+ }
+
+ MEM_freeN(flip_map);
+ }
+ }
+
+ if (do_vtargetmap) {
+ /* slow - so only call if one or more merge verts are found,
+ * users may leave this on and not realize there is nothing to merge - campbell */
+ if (tot_vtargetmap) {
+ result = BKE_mesh_merge_verts(
+ result, vtargetmap, tot_vtargetmap, MESH_MERGE_VERTS_DUMP_IF_MAPPED);
+ }
+ MEM_freeN(vtargetmap);
+ }
+
+ if (mesh_bisect != NULL) {
+ BKE_id_free(NULL, mesh_bisect);
+ }
+
+ return result;
}
-static Mesh *mirrorModifier__doMirror(
- MirrorModifierData *mmd, const ModifierEvalContext *ctx,
- Object *ob, Mesh *mesh)
+static Mesh *mirrorModifier__doMirror(MirrorModifierData *mmd,
+ const ModifierEvalContext *ctx,
+ Object *ob,
+ Mesh *mesh)
{
- Mesh *result = mesh;
-
- /* check which axes have been toggled and mirror accordingly */
- if (mmd->flag & MOD_MIR_AXIS_X) {
- result = doMirrorOnAxis(mmd, ctx, ob, result, 0);
- }
- if (mmd->flag & MOD_MIR_AXIS_Y) {
- Mesh *tmp = result;
- result = doMirrorOnAxis(mmd, ctx, ob, result, 1);
- if (tmp != mesh) {
- /* free intermediate results */
- BKE_id_free(NULL, tmp);
- }
- }
- if (mmd->flag & MOD_MIR_AXIS_Z) {
- Mesh *tmp = result;
- result = doMirrorOnAxis(mmd, ctx, ob, result, 2);
- if (tmp != mesh) {
- /* free intermediate results */
- BKE_id_free(NULL, tmp);
- }
- }
-
- return result;
+ Mesh *result = mesh;
+
+ /* check which axes have been toggled and mirror accordingly */
+ if (mmd->flag & MOD_MIR_AXIS_X) {
+ result = doMirrorOnAxis(mmd, ctx, ob, result, 0);
+ }
+ if (mmd->flag & MOD_MIR_AXIS_Y) {
+ Mesh *tmp = result;
+ result = doMirrorOnAxis(mmd, ctx, ob, result, 1);
+ if (tmp != mesh) {
+ /* free intermediate results */
+ BKE_id_free(NULL, tmp);
+ }
+ }
+ if (mmd->flag & MOD_MIR_AXIS_Z) {
+ Mesh *tmp = result;
+ result = doMirrorOnAxis(mmd, ctx, ob, result, 2);
+ if (tmp != mesh) {
+ /* free intermediate results */
+ BKE_id_free(NULL, tmp);
+ }
+ }
+
+ return result;
}
-static Mesh *applyModifier(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- Mesh *result;
- MirrorModifierData *mmd = (MirrorModifierData *) md;
+ Mesh *result;
+ MirrorModifierData *mmd = (MirrorModifierData *)md;
- result = mirrorModifier__doMirror(mmd, ctx, ctx->object, mesh);
+ result = mirrorModifier__doMirror(mmd, ctx, ctx->object, mesh);
- if (result != mesh) {
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- }
- return result;
+ if (result != mesh) {
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ }
+ return result;
}
-
ModifierTypeInfo modifierType_Mirror = {
- /* name */ "Mirror",
- /* structName */ "MirrorModifierData",
- /* structSize */ sizeof(MirrorModifierData),
- /* type */ eModifierTypeType_Constructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsMapping |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_EnableInEditmode |
- eModifierTypeFlag_AcceptsCVs |
- /* this is only the case when 'MOD_MIR_VGROUP' is used */
- eModifierTypeFlag_UsesPreview,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ NULL,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Mirror",
+ /* structName */ "MirrorModifierData",
+ /* structSize */ sizeof(MirrorModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode |
+ eModifierTypeFlag_AcceptsCVs |
+ /* this is only the case when 'MOD_MIR_VGROUP' is used */
+ eModifierTypeFlag_UsesPreview,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c
index a8760d05834..6e5426bbf40 100644
--- a/source/blender/modifiers/intern/MOD_multires.c
+++ b/source/blender/modifiers/intern/MOD_multires.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include <stddef.h>
#include "MEM_guardedalloc.h"
@@ -47,55 +46,54 @@
#include "MOD_modifiertypes.h"
typedef struct MultiresRuntimeData {
- /* Cached subdivision surface descriptor, with topology and settings. */
- struct Subdiv *subdiv;
+ /* Cached subdivision surface descriptor, with topology and settings. */
+ struct Subdiv *subdiv;
} MultiresRuntimeData;
static void initData(ModifierData *md)
{
- MultiresModifierData *mmd = (MultiresModifierData *)md;
-
- mmd->lvl = 0;
- mmd->sculptlvl = 0;
- mmd->renderlvl = 0;
- mmd->totlvl = 0;
- mmd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
- mmd->quality = 3;
- mmd->flags |= eMultiresModifierFlag_UseCrease;
+ MultiresModifierData *mmd = (MultiresModifierData *)md;
+
+ mmd->lvl = 0;
+ mmd->sculptlvl = 0;
+ mmd->renderlvl = 0;
+ mmd->totlvl = 0;
+ mmd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
+ mmd->quality = 3;
+ mmd->flags |= eMultiresModifierFlag_UseCrease;
}
static void copyData(const ModifierData *md_src, ModifierData *md_dst, const int flag)
{
- modifier_copyData_generic(md_src, md_dst, flag);
+ modifier_copyData_generic(md_src, md_dst, flag);
}
static void freeRuntimeData(void *runtime_data_v)
{
- if (runtime_data_v == NULL) {
- return;
- }
- MultiresRuntimeData *runtime_data = (MultiresRuntimeData *)runtime_data_v;
- if (runtime_data->subdiv != NULL) {
- BKE_subdiv_free(runtime_data->subdiv);
- }
- MEM_freeN(runtime_data);
+ if (runtime_data_v == NULL) {
+ return;
+ }
+ MultiresRuntimeData *runtime_data = (MultiresRuntimeData *)runtime_data_v;
+ if (runtime_data->subdiv != NULL) {
+ BKE_subdiv_free(runtime_data->subdiv);
+ }
+ MEM_freeN(runtime_data);
}
static void freeData(ModifierData *md)
{
- MultiresModifierData *mmd = (MultiresModifierData *) md;
- freeRuntimeData(mmd->modifier.runtime);
+ MultiresModifierData *mmd = (MultiresModifierData *)md;
+ freeRuntimeData(mmd->modifier.runtime);
}
static MultiresRuntimeData *multires_ensure_runtime(MultiresModifierData *mmd)
{
- MultiresRuntimeData *runtime_data =
- (MultiresRuntimeData *)mmd->modifier.runtime;
- if (runtime_data == NULL) {
- runtime_data = MEM_callocN(sizeof(*runtime_data), "subsurf runtime");
- mmd->modifier.runtime = runtime_data;
- }
- return runtime_data;
+ MultiresRuntimeData *runtime_data = (MultiresRuntimeData *)mmd->modifier.runtime;
+ if (runtime_data == NULL) {
+ runtime_data = MEM_callocN(sizeof(*runtime_data), "subsurf runtime");
+ mmd->modifier.runtime = runtime_data;
+ }
+ return runtime_data;
}
/* Main goal of this function is to give usable subdivision surface descriptor
@@ -104,12 +102,10 @@ static Subdiv *subdiv_descriptor_ensure(MultiresModifierData *mmd,
const SubdivSettings *subdiv_settings,
const Mesh *mesh)
{
- MultiresRuntimeData *runtime_data =
- (MultiresRuntimeData *)mmd->modifier.runtime;
- Subdiv *subdiv = BKE_subdiv_update_from_mesh(
- runtime_data->subdiv, subdiv_settings, mesh);
- runtime_data->subdiv = subdiv;
- return subdiv;
+ MultiresRuntimeData *runtime_data = (MultiresRuntimeData *)mmd->modifier.runtime;
+ Subdiv *subdiv = BKE_subdiv_update_from_mesh(runtime_data->subdiv, subdiv_settings, mesh);
+ runtime_data->subdiv = subdiv;
+ return subdiv;
}
/* Subdivide into fully qualified mesh. */
@@ -119,20 +115,20 @@ static Mesh *multires_as_mesh(MultiresModifierData *mmd,
Mesh *mesh,
Subdiv *subdiv)
{
- Mesh *result = mesh;
- const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER);
- const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY);
- const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- Object *object = ctx->object;
- SubdivToMeshSettings mesh_settings;
- BKE_multires_subdiv_mesh_settings_init(
- &mesh_settings, scene, object, mmd, use_render_params, ignore_simplify);
- if (mesh_settings.resolution < 3) {
- return result;
- }
- BKE_subdiv_displacement_attach_from_multires(subdiv, mesh, mmd);
- result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh);
- return result;
+ Mesh *result = mesh;
+ const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER);
+ const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY);
+ const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ Object *object = ctx->object;
+ SubdivToMeshSettings mesh_settings;
+ BKE_multires_subdiv_mesh_settings_init(
+ &mesh_settings, scene, object, mmd, use_render_params, ignore_simplify);
+ if (mesh_settings.resolution < 3) {
+ return result;
+ }
+ BKE_subdiv_displacement_attach_from_multires(subdiv, mesh, mmd);
+ result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh);
+ return result;
}
/* Subdivide into CCG. */
@@ -142,17 +138,15 @@ static void multires_ccg_settings_init(SubdivToCCGSettings *settings,
const ModifierEvalContext *ctx,
Mesh *mesh)
{
- const bool has_mask =
- CustomData_has_layer(&mesh->ldata, CD_GRID_PAINT_MASK);
- const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER);
- const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY);
- const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- Object *object = ctx->object;
- const int level = multires_get_level(
- scene, object, mmd, use_render_params, ignore_simplify);
- settings->resolution = (1 << level) + 1;
- settings->need_normal = true;
- settings->need_mask = has_mask;
+ const bool has_mask = CustomData_has_layer(&mesh->ldata, CD_GRID_PAINT_MASK);
+ const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER);
+ const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY);
+ const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ Object *object = ctx->object;
+ const int level = multires_get_level(scene, object, mmd, use_render_params, ignore_simplify);
+ settings->resolution = (1 << level) + 1;
+ settings->need_normal = true;
+ settings->need_mask = has_mask;
}
static Mesh *multires_as_ccg(MultiresModifierData *mmd,
@@ -160,93 +154,90 @@ static Mesh *multires_as_ccg(MultiresModifierData *mmd,
Mesh *mesh,
Subdiv *subdiv)
{
- Mesh *result = mesh;
- SubdivToCCGSettings ccg_settings;
- multires_ccg_settings_init(&ccg_settings, mmd, ctx, mesh);
- if (ccg_settings.resolution < 3) {
- return result;
- }
- BKE_subdiv_displacement_attach_from_multires(subdiv, mesh, mmd);
- result = BKE_subdiv_to_ccg_mesh(subdiv, &ccg_settings, mesh);
- return result;
+ Mesh *result = mesh;
+ SubdivToCCGSettings ccg_settings;
+ multires_ccg_settings_init(&ccg_settings, mmd, ctx, mesh);
+ if (ccg_settings.resolution < 3) {
+ return result;
+ }
+ BKE_subdiv_displacement_attach_from_multires(subdiv, mesh, mmd);
+ result = BKE_subdiv_to_ccg_mesh(subdiv, &ccg_settings, mesh);
+ return result;
}
-static Mesh *applyModifier(ModifierData *md,
- const ModifierEvalContext *ctx,
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- Mesh *result = mesh;
- MultiresModifierData *mmd = (MultiresModifierData *)md;
- SubdivSettings subdiv_settings;
- BKE_multires_subdiv_settings_init(&subdiv_settings, mmd);
- if (subdiv_settings.level == 0) {
- return result;
- }
- BKE_subdiv_settings_validate_for_mesh(&subdiv_settings, mesh);
- MultiresRuntimeData *runtime_data = multires_ensure_runtime(mmd);
- Subdiv *subdiv = subdiv_descriptor_ensure(mmd, &subdiv_settings, mesh);
- if (subdiv == NULL) {
- /* Happens on bad topology, ut also on empty input mesh. */
- return result;
- }
- /* NOTE: Orco needs final coordinates on CPU side, which are expected to be
- * accessible via MVert. For this reason we do not evaluate multires to
- * grids when orco is requested. */
- const bool for_orco = (ctx->flag & MOD_APPLY_ORCO) != 0;
- if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco) {
- /* NOTE: CCG takes ownership over Subdiv. */
- result = multires_as_ccg(mmd, ctx, mesh, subdiv);
- result->runtime.subdiv_ccg_tot_level = mmd->totlvl;
- /* TODO(sergey): Usually it is sculpt stroke's update variants which
- * takes care of this, but is possible that we need this before the
- * stroke: i.e. when exiting blender right after stroke is done.
- * Annoying and not so much black-boxed as far as sculpting goes, and
- * surely there is a better way of solving this. */
- if (ctx->object->sculpt != NULL) {
- ctx->object->sculpt->subdiv_ccg = result->runtime.subdiv_ccg;
- }
- /* NOTE: CCG becomes an owner of Subdiv descriptor, so can not share
- * this pointer. Not sure if it's needed, but might have a second look
- * on the ownership model here. */
- runtime_data->subdiv = NULL;
- // BKE_subdiv_stats_print(&subdiv->stats);
- }
- else {
- result = multires_as_mesh(mmd, ctx, mesh, subdiv);
- // BKE_subdiv_stats_print(&subdiv->stats);
- if (subdiv != runtime_data->subdiv) {
- BKE_subdiv_free(subdiv);
- }
- }
- return result;
+ Mesh *result = mesh;
+ MultiresModifierData *mmd = (MultiresModifierData *)md;
+ SubdivSettings subdiv_settings;
+ BKE_multires_subdiv_settings_init(&subdiv_settings, mmd);
+ if (subdiv_settings.level == 0) {
+ return result;
+ }
+ BKE_subdiv_settings_validate_for_mesh(&subdiv_settings, mesh);
+ MultiresRuntimeData *runtime_data = multires_ensure_runtime(mmd);
+ Subdiv *subdiv = subdiv_descriptor_ensure(mmd, &subdiv_settings, mesh);
+ if (subdiv == NULL) {
+ /* Happens on bad topology, ut also on empty input mesh. */
+ return result;
+ }
+ /* NOTE: Orco needs final coordinates on CPU side, which are expected to be
+ * accessible via MVert. For this reason we do not evaluate multires to
+ * grids when orco is requested. */
+ const bool for_orco = (ctx->flag & MOD_APPLY_ORCO) != 0;
+ if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco) {
+ /* NOTE: CCG takes ownership over Subdiv. */
+ result = multires_as_ccg(mmd, ctx, mesh, subdiv);
+ result->runtime.subdiv_ccg_tot_level = mmd->totlvl;
+ /* TODO(sergey): Usually it is sculpt stroke's update variants which
+ * takes care of this, but is possible that we need this before the
+ * stroke: i.e. when exiting blender right after stroke is done.
+ * Annoying and not so much black-boxed as far as sculpting goes, and
+ * surely there is a better way of solving this. */
+ if (ctx->object->sculpt != NULL) {
+ ctx->object->sculpt->subdiv_ccg = result->runtime.subdiv_ccg;
+ }
+ /* NOTE: CCG becomes an owner of Subdiv descriptor, so can not share
+ * this pointer. Not sure if it's needed, but might have a second look
+ * on the ownership model here. */
+ runtime_data->subdiv = NULL;
+ // BKE_subdiv_stats_print(&subdiv->stats);
+ }
+ else {
+ result = multires_as_mesh(mmd, ctx, mesh, subdiv);
+ // BKE_subdiv_stats_print(&subdiv->stats);
+ if (subdiv != runtime_data->subdiv) {
+ BKE_subdiv_free(subdiv);
+ }
+ }
+ return result;
}
ModifierTypeInfo modifierType_Multires = {
- /* name */ "Multires",
- /* structName */ "MultiresModifierData",
- /* structSize */ sizeof(MultiresModifierData),
- /* type */ eModifierTypeType_Constructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsMapping |
- eModifierTypeFlag_RequiresOriginalData,
-
- /* copyData */ copyData,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ NULL,
- /* freeData */ freeData,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ freeRuntimeData,
+ /* name */ "Multires",
+ /* structName */ "MultiresModifierData",
+ /* structSize */ sizeof(MultiresModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_RequiresOriginalData,
+
+ /* copyData */ copyData,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ freeData,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ freeRuntimeData,
};
diff --git a/source/blender/modifiers/intern/MOD_none.c b/source/blender/modifiers/intern/MOD_none.c
index 749c329b3b6..9be422afab9 100644
--- a/source/blender/modifiers/intern/MOD_none.c
+++ b/source/blender/modifiers/intern/MOD_none.c
@@ -31,36 +31,37 @@
* no other functions will be called
*/
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *UNUSED(md), bool UNUSED(userRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *UNUSED(md),
+ bool UNUSED(userRenderParams))
{
- return true;
+ return true;
}
ModifierTypeInfo modifierType_None = {
- /* name */ "None",
- /* structName */ "ModifierData",
- /* structSize */ sizeof(ModifierData),
- /* type */ eModifierTypeType_None,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_AcceptsCVs,
+ /* name */ "None",
+ /* structName */ "ModifierData",
+ /* structSize */ sizeof(ModifierData),
+ /* type */ eModifierTypeType_None,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs,
- /* copyData */ NULL,
+ /* copyData */ NULL,
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
- /* initData */ NULL,
- /* requiredDataMask */ NULL,
- /* freeData */ NULL,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* initData */ NULL,
+ /* requiredDataMask */ NULL,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c
index 2a8bca895be..0c5b260eadc 100644
--- a/source/blender/modifiers/intern/MOD_normal_edit.c
+++ b/source/blender/modifiers/intern/MOD_normal_edit.c
@@ -40,537 +40,672 @@
#include "MOD_util.h"
-
-static void generate_vert_coordinates(
- Mesh *mesh, Object *ob, Object *ob_center, const float offset[3],
- const int num_verts, float (*r_cos)[3], float r_size[3])
+static void generate_vert_coordinates(Mesh *mesh,
+ Object *ob,
+ Object *ob_center,
+ const float offset[3],
+ const int num_verts,
+ float (*r_cos)[3],
+ float r_size[3])
{
- float min_co[3], max_co[3];
- float diff[3];
- bool do_diff = false;
-
- INIT_MINMAX(min_co, max_co);
-
- MVert *mv = mesh->mvert;
- for (int i = 0; i < mesh->totvert; i++, mv++) {
- copy_v3_v3(r_cos[i], mv->co);
- if (r_size != NULL && ob_center == NULL) {
- minmax_v3v3_v3(min_co, max_co, r_cos[i]);
- }
- }
-
- /* Get size (i.e. deformation of the spheroid generating normals), either from target object, or own geometry. */
- if (r_size != NULL) {
- if (ob_center != NULL) {
- /* Using 'scale' as 'size' here. The input object is typically an empty
- * who's scale is used to define an ellipsoid instead of a simple sphere. */
-
- /* Not we are not interested in signs here - they are even troublesome actually, due to security clamping! */
- abs_v3_v3(r_size, ob_center->scale);
- }
- else {
- /* Set size. */
- sub_v3_v3v3(r_size, max_co, min_co);
- }
-
- /* Error checks - we do not want one or more of our sizes to be null! */
- if (is_zero_v3(r_size)) {
- r_size[0] = r_size[1] = r_size[2] = 1.0f;
- }
- else {
- CLAMP_MIN(r_size[0], FLT_EPSILON);
- CLAMP_MIN(r_size[1], FLT_EPSILON);
- CLAMP_MIN(r_size[2], FLT_EPSILON);
- }
- }
-
- if (ob_center != NULL) {
- float inv_obmat[4][4];
-
- /* Translate our coordinates so that center of ob_center is at (0, 0, 0). */
- /* Get ob_center (world) coordinates in ob local coordinates.
- * No need to take into account ob_center's space here, see T44027. */
- invert_m4_m4(inv_obmat, ob->obmat);
- mul_v3_m4v3(diff, inv_obmat, ob_center->obmat[3]);
- negate_v3(diff);
-
- do_diff = true;
- }
- else if (offset != NULL && !is_zero_v3(offset)) {
- negate_v3_v3(diff, offset);
-
- do_diff = true;
- }
- /* Else, no need to change coordinates! */
-
- if (do_diff) {
- int i = num_verts;
- while (i--) {
- add_v3_v3(r_cos[i], diff);
- }
- }
+ float min_co[3], max_co[3];
+ float diff[3];
+ bool do_diff = false;
+
+ INIT_MINMAX(min_co, max_co);
+
+ MVert *mv = mesh->mvert;
+ for (int i = 0; i < mesh->totvert; i++, mv++) {
+ copy_v3_v3(r_cos[i], mv->co);
+ if (r_size != NULL && ob_center == NULL) {
+ minmax_v3v3_v3(min_co, max_co, r_cos[i]);
+ }
+ }
+
+ /* Get size (i.e. deformation of the spheroid generating normals), either from target object, or own geometry. */
+ if (r_size != NULL) {
+ if (ob_center != NULL) {
+ /* Using 'scale' as 'size' here. The input object is typically an empty
+ * who's scale is used to define an ellipsoid instead of a simple sphere. */
+
+ /* Not we are not interested in signs here - they are even troublesome actually, due to security clamping! */
+ abs_v3_v3(r_size, ob_center->scale);
+ }
+ else {
+ /* Set size. */
+ sub_v3_v3v3(r_size, max_co, min_co);
+ }
+
+ /* Error checks - we do not want one or more of our sizes to be null! */
+ if (is_zero_v3(r_size)) {
+ r_size[0] = r_size[1] = r_size[2] = 1.0f;
+ }
+ else {
+ CLAMP_MIN(r_size[0], FLT_EPSILON);
+ CLAMP_MIN(r_size[1], FLT_EPSILON);
+ CLAMP_MIN(r_size[2], FLT_EPSILON);
+ }
+ }
+
+ if (ob_center != NULL) {
+ float inv_obmat[4][4];
+
+ /* Translate our coordinates so that center of ob_center is at (0, 0, 0). */
+ /* Get ob_center (world) coordinates in ob local coordinates.
+ * No need to take into account ob_center's space here, see T44027. */
+ invert_m4_m4(inv_obmat, ob->obmat);
+ mul_v3_m4v3(diff, inv_obmat, ob_center->obmat[3]);
+ negate_v3(diff);
+
+ do_diff = true;
+ }
+ else if (offset != NULL && !is_zero_v3(offset)) {
+ negate_v3_v3(diff, offset);
+
+ do_diff = true;
+ }
+ /* Else, no need to change coordinates! */
+
+ if (do_diff) {
+ int i = num_verts;
+ while (i--) {
+ add_v3_v3(r_cos[i], diff);
+ }
+ }
}
/* Note this modifies nos_new in-place. */
-static void mix_normals(
- const float mix_factor, MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup,
- const float mix_limit, const short mix_mode,
- const int num_verts, MLoop *mloop, float (*nos_old)[3], float (*nos_new)[3], const int num_loops)
+static void mix_normals(const float mix_factor,
+ MDeformVert *dvert,
+ const int defgrp_index,
+ const bool use_invert_vgroup,
+ const float mix_limit,
+ const short mix_mode,
+ const int num_verts,
+ MLoop *mloop,
+ float (*nos_old)[3],
+ float (*nos_new)[3],
+ const int num_loops)
{
- /* Mix with org normals... */
- float *facs = NULL, *wfac;
- float (*no_new)[3], (*no_old)[3];
- int i;
-
- if (dvert) {
- facs = MEM_malloc_arrayN((size_t)num_loops, sizeof(*facs), __func__);
- BKE_defvert_extract_vgroup_to_loopweights(
- dvert, defgrp_index, num_verts, mloop, num_loops, facs, use_invert_vgroup);
- }
-
- for (i = num_loops, no_new = nos_new, no_old = nos_old, wfac = facs; i--; no_new++, no_old++, wfac++) {
- const float fac = facs ? *wfac * mix_factor : mix_factor;
-
- switch (mix_mode) {
- case MOD_NORMALEDIT_MIX_ADD:
- add_v3_v3(*no_new, *no_old);
- normalize_v3(*no_new);
- break;
- case MOD_NORMALEDIT_MIX_SUB:
- sub_v3_v3(*no_new, *no_old);
- normalize_v3(*no_new);
- break;
- case MOD_NORMALEDIT_MIX_MUL:
- mul_v3_v3(*no_new, *no_old);
- normalize_v3(*no_new);
- break;
- case MOD_NORMALEDIT_MIX_COPY:
- break;
- }
-
- interp_v3_v3v3_slerp_safe(
- *no_new, *no_old, *no_new,
- (mix_limit < (float)M_PI) ? min_ff(fac, mix_limit / angle_v3v3(*no_new, *no_old)) : fac);
- }
-
- MEM_SAFE_FREE(facs);
+ /* Mix with org normals... */
+ float *facs = NULL, *wfac;
+ float(*no_new)[3], (*no_old)[3];
+ int i;
+
+ if (dvert) {
+ facs = MEM_malloc_arrayN((size_t)num_loops, sizeof(*facs), __func__);
+ BKE_defvert_extract_vgroup_to_loopweights(
+ dvert, defgrp_index, num_verts, mloop, num_loops, facs, use_invert_vgroup);
+ }
+
+ for (i = num_loops, no_new = nos_new, no_old = nos_old, wfac = facs; i--;
+ no_new++, no_old++, wfac++) {
+ const float fac = facs ? *wfac * mix_factor : mix_factor;
+
+ switch (mix_mode) {
+ case MOD_NORMALEDIT_MIX_ADD:
+ add_v3_v3(*no_new, *no_old);
+ normalize_v3(*no_new);
+ break;
+ case MOD_NORMALEDIT_MIX_SUB:
+ sub_v3_v3(*no_new, *no_old);
+ normalize_v3(*no_new);
+ break;
+ case MOD_NORMALEDIT_MIX_MUL:
+ mul_v3_v3(*no_new, *no_old);
+ normalize_v3(*no_new);
+ break;
+ case MOD_NORMALEDIT_MIX_COPY:
+ break;
+ }
+
+ interp_v3_v3v3_slerp_safe(
+ *no_new,
+ *no_old,
+ *no_new,
+ (mix_limit < (float)M_PI) ? min_ff(fac, mix_limit / angle_v3v3(*no_new, *no_old)) : fac);
+ }
+
+ MEM_SAFE_FREE(facs);
}
/* Check poly normals and new loop normals are compatible, otherwise flip polygons
* (and invert matching poly normals). */
-static bool polygons_check_flip(
- MLoop *mloop, float (*nos)[3], CustomData *ldata,
- MPoly *mpoly, float (*polynors)[3], const int num_polys)
+static bool polygons_check_flip(MLoop *mloop,
+ float (*nos)[3],
+ CustomData *ldata,
+ MPoly *mpoly,
+ float (*polynors)[3],
+ const int num_polys)
{
- MPoly *mp;
- MDisps *mdisp = CustomData_get_layer(ldata, CD_MDISPS);
- int i;
- bool flipped = false;
-
- for (i = 0, mp = mpoly; i < num_polys; i++, mp++) {
- float norsum[3] = {0.0f};
- float (*no)[3];
- int j;
-
- for (j = 0, no = &nos[mp->loopstart]; j < mp->totloop; j++, no++) {
- add_v3_v3(norsum, *no);
- }
-
- if (!normalize_v3(norsum)) {
- continue;
- }
-
- /* If average of new loop normals is opposed to polygon normal, flip polygon. */
- if (dot_v3v3(polynors[i], norsum) < 0.0f) {
- BKE_mesh_polygon_flip_ex(mp, mloop, ldata, nos, mdisp, true);
- negate_v3(polynors[i]);
- flipped = true;
- }
- }
-
- return flipped;
+ MPoly *mp;
+ MDisps *mdisp = CustomData_get_layer(ldata, CD_MDISPS);
+ int i;
+ bool flipped = false;
+
+ for (i = 0, mp = mpoly; i < num_polys; i++, mp++) {
+ float norsum[3] = {0.0f};
+ float(*no)[3];
+ int j;
+
+ for (j = 0, no = &nos[mp->loopstart]; j < mp->totloop; j++, no++) {
+ add_v3_v3(norsum, *no);
+ }
+
+ if (!normalize_v3(norsum)) {
+ continue;
+ }
+
+ /* If average of new loop normals is opposed to polygon normal, flip polygon. */
+ if (dot_v3v3(polynors[i], norsum) < 0.0f) {
+ BKE_mesh_polygon_flip_ex(mp, mloop, ldata, nos, mdisp, true);
+ negate_v3(polynors[i]);
+ flipped = true;
+ }
+ }
+
+ return flipped;
}
-static void normalEditModifier_do_radial(
- NormalEditModifierData *enmd, const ModifierEvalContext *UNUSED(ctx),
- Object *ob, Mesh *mesh,
- short (*clnors)[2], float (*loopnors)[3], float (*polynors)[3],
- const short mix_mode, const float mix_factor, const float mix_limit,
- MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup,
- MVert *mvert, const int num_verts, MEdge *medge, const int num_edges,
- MLoop *mloop, const int num_loops, MPoly *mpoly, const int num_polys)
+static void normalEditModifier_do_radial(NormalEditModifierData *enmd,
+ const ModifierEvalContext *UNUSED(ctx),
+ Object *ob,
+ Mesh *mesh,
+ short (*clnors)[2],
+ float (*loopnors)[3],
+ float (*polynors)[3],
+ const short mix_mode,
+ const float mix_factor,
+ const float mix_limit,
+ MDeformVert *dvert,
+ const int defgrp_index,
+ const bool use_invert_vgroup,
+ MVert *mvert,
+ const int num_verts,
+ MEdge *medge,
+ const int num_edges,
+ MLoop *mloop,
+ const int num_loops,
+ MPoly *mpoly,
+ const int num_polys)
{
- Object *ob_target = enmd->target;
-
- const bool do_polynors_fix = (enmd->flag & MOD_NORMALEDIT_NO_POLYNORS_FIX) == 0;
- int i;
-
- float (*cos)[3] = MEM_malloc_arrayN((size_t)num_verts, sizeof(*cos), __func__);
- float (*nos)[3] = MEM_malloc_arrayN((size_t)num_loops, sizeof(*nos), __func__);
- float size[3];
-
- BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)num_verts, __func__);
-
- generate_vert_coordinates(mesh, ob, ob_target, enmd->offset, num_verts, cos, size);
-
- /**
- * size gives us our spheroid coefficients ``(A, B, C)``.
- * Then, we want to find out for each vert its (a, b, c) triple (proportional to (A, B, C) one).
- *
- * Ellipsoid basic equation: ``(x^2/a^2) + (y^2/b^2) + (z^2/c^2) = 1.``
- * Since we want to find (a, b, c) matching this equation and proportional to (A, B, C), we can do:
- * <pre>
- * m = B / A
- * n = C / A
- * </pre>
- *
- * hence:
- * <pre>
- * (x^2/a^2) + (y^2/b^2) + (z^2/c^2) = 1
- * -> b^2*c^2*x^2 + a^2*c^2*y^2 + a^2*b^2*z^2 = a^2*b^2*c^2
- * b = ma
- * c = na
- * -> m^2*a^2*n^2*a^2*x^2 + a^2*n^2*a^2*y^2 + a^2*m^2*a^2*z^2 = a^2*m^2*a^2*n^2*a^2
- * -> m^2*n^2*a^4*x^2 + n^2*a^4*y^2 + m^2*a^4*z^2 = m^2*n^2*a^6
- * -> a^2 = (m^2*n^2*x^2 + n^2y^2 + m^2z^2) / (m^2*n^2) = x^2 + (y^2 / m^2) + (z^2 / n^2)
- * -> b^2 = (m^2*n^2*x^2 + n^2y^2 + m^2z^2) / (n^2) = (m^2 * x^2) + y^2 + (m^2 * z^2 / n^2)
- * -> c^2 = (m^2*n^2*x^2 + n^2y^2 + m^2z^2) / (m^2) = (n^2 * x^2) + (n^2 * y^2 / m^2) + z^2
- * </pre>
- *
- * All we have to do now is compute normal of the spheroid at that point:
- * <pre>
- * n = (x / a^2, y / b^2, z / c^2)
- * </pre>
- * And we are done!
- */
- {
- const float a = size[0], b = size[1], c = size[2];
- const float m2 = (b * b) / (a * a);
- const float n2 = (c * c) / (a * a);
-
- MLoop *ml;
- float (*no)[3];
-
- /* We reuse cos to now store the ellipsoid-normal of the verts! */
- for (i = num_loops, ml = mloop, no = nos; i-- ; ml++, no++) {
- const int vidx = ml->v;
- float *co = cos[vidx];
-
- if (!BLI_BITMAP_TEST(done_verts, vidx)) {
- const float x2 = co[0] * co[0];
- const float y2 = co[1] * co[1];
- const float z2 = co[2] * co[2];
- const float a2 = x2 + (y2 / m2) + (z2 / n2);
- const float b2 = (m2 * x2) + y2 + (m2 * z2 / n2);
- const float c2 = (n2 * x2) + (n2 * y2 / m2) + z2;
-
- co[0] /= a2;
- co[1] /= b2;
- co[2] /= c2;
- normalize_v3(co);
-
- BLI_BITMAP_ENABLE(done_verts, vidx);
- }
- copy_v3_v3(*no, co);
- }
- }
-
- if (loopnors) {
- mix_normals(mix_factor, dvert, defgrp_index, use_invert_vgroup,
- mix_limit, mix_mode, num_verts, mloop, loopnors, nos, num_loops);
- }
-
- if (do_polynors_fix && polygons_check_flip(mloop, nos, &mesh->ldata, mpoly, polynors, num_polys)) {
- /* XXX TODO is this still needed? */
- // mesh->dirty |= DM_DIRTY_TESS_CDLAYERS;
- /* We need to recompute vertex normals! */
- BKE_mesh_calc_normals(mesh);
- }
-
- BKE_mesh_normals_loop_custom_set(mvert, num_verts, medge, num_edges, mloop, nos, num_loops,
- mpoly, (const float(*)[3])polynors, num_polys, clnors);
-
- MEM_freeN(cos);
- MEM_freeN(nos);
- MEM_freeN(done_verts);
+ Object *ob_target = enmd->target;
+
+ const bool do_polynors_fix = (enmd->flag & MOD_NORMALEDIT_NO_POLYNORS_FIX) == 0;
+ int i;
+
+ float(*cos)[3] = MEM_malloc_arrayN((size_t)num_verts, sizeof(*cos), __func__);
+ float(*nos)[3] = MEM_malloc_arrayN((size_t)num_loops, sizeof(*nos), __func__);
+ float size[3];
+
+ BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)num_verts, __func__);
+
+ generate_vert_coordinates(mesh, ob, ob_target, enmd->offset, num_verts, cos, size);
+
+ /**
+ * size gives us our spheroid coefficients ``(A, B, C)``.
+ * Then, we want to find out for each vert its (a, b, c) triple (proportional to (A, B, C) one).
+ *
+ * Ellipsoid basic equation: ``(x^2/a^2) + (y^2/b^2) + (z^2/c^2) = 1.``
+ * Since we want to find (a, b, c) matching this equation and proportional to (A, B, C), we can do:
+ * <pre>
+ * m = B / A
+ * n = C / A
+ * </pre>
+ *
+ * hence:
+ * <pre>
+ * (x^2/a^2) + (y^2/b^2) + (z^2/c^2) = 1
+ * -> b^2*c^2*x^2 + a^2*c^2*y^2 + a^2*b^2*z^2 = a^2*b^2*c^2
+ * b = ma
+ * c = na
+ * -> m^2*a^2*n^2*a^2*x^2 + a^2*n^2*a^2*y^2 + a^2*m^2*a^2*z^2 = a^2*m^2*a^2*n^2*a^2
+ * -> m^2*n^2*a^4*x^2 + n^2*a^4*y^2 + m^2*a^4*z^2 = m^2*n^2*a^6
+ * -> a^2 = (m^2*n^2*x^2 + n^2y^2 + m^2z^2) / (m^2*n^2) = x^2 + (y^2 / m^2) + (z^2 / n^2)
+ * -> b^2 = (m^2*n^2*x^2 + n^2y^2 + m^2z^2) / (n^2) = (m^2 * x^2) + y^2 + (m^2 * z^2 / n^2)
+ * -> c^2 = (m^2*n^2*x^2 + n^2y^2 + m^2z^2) / (m^2) = (n^2 * x^2) + (n^2 * y^2 / m^2) + z^2
+ * </pre>
+ *
+ * All we have to do now is compute normal of the spheroid at that point:
+ * <pre>
+ * n = (x / a^2, y / b^2, z / c^2)
+ * </pre>
+ * And we are done!
+ */
+ {
+ const float a = size[0], b = size[1], c = size[2];
+ const float m2 = (b * b) / (a * a);
+ const float n2 = (c * c) / (a * a);
+
+ MLoop *ml;
+ float(*no)[3];
+
+ /* We reuse cos to now store the ellipsoid-normal of the verts! */
+ for (i = num_loops, ml = mloop, no = nos; i--; ml++, no++) {
+ const int vidx = ml->v;
+ float *co = cos[vidx];
+
+ if (!BLI_BITMAP_TEST(done_verts, vidx)) {
+ const float x2 = co[0] * co[0];
+ const float y2 = co[1] * co[1];
+ const float z2 = co[2] * co[2];
+ const float a2 = x2 + (y2 / m2) + (z2 / n2);
+ const float b2 = (m2 * x2) + y2 + (m2 * z2 / n2);
+ const float c2 = (n2 * x2) + (n2 * y2 / m2) + z2;
+
+ co[0] /= a2;
+ co[1] /= b2;
+ co[2] /= c2;
+ normalize_v3(co);
+
+ BLI_BITMAP_ENABLE(done_verts, vidx);
+ }
+ copy_v3_v3(*no, co);
+ }
+ }
+
+ if (loopnors) {
+ mix_normals(mix_factor,
+ dvert,
+ defgrp_index,
+ use_invert_vgroup,
+ mix_limit,
+ mix_mode,
+ num_verts,
+ mloop,
+ loopnors,
+ nos,
+ num_loops);
+ }
+
+ if (do_polynors_fix &&
+ polygons_check_flip(mloop, nos, &mesh->ldata, mpoly, polynors, num_polys)) {
+ /* XXX TODO is this still needed? */
+ // mesh->dirty |= DM_DIRTY_TESS_CDLAYERS;
+ /* We need to recompute vertex normals! */
+ BKE_mesh_calc_normals(mesh);
+ }
+
+ BKE_mesh_normals_loop_custom_set(mvert,
+ num_verts,
+ medge,
+ num_edges,
+ mloop,
+ nos,
+ num_loops,
+ mpoly,
+ (const float(*)[3])polynors,
+ num_polys,
+ clnors);
+
+ MEM_freeN(cos);
+ MEM_freeN(nos);
+ MEM_freeN(done_verts);
}
-static void normalEditModifier_do_directional(
- NormalEditModifierData *enmd, const ModifierEvalContext *UNUSED(ctx),
- Object *ob, Mesh *mesh,
- short (*clnors)[2], float (*loopnors)[3], float (*polynors)[3],
- const short mix_mode, const float mix_factor, const float mix_limit,
- MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup,
- MVert *mvert, const int num_verts, MEdge *medge, const int num_edges,
- MLoop *mloop, const int num_loops, MPoly *mpoly, const int num_polys)
+static void normalEditModifier_do_directional(NormalEditModifierData *enmd,
+ const ModifierEvalContext *UNUSED(ctx),
+ Object *ob,
+ Mesh *mesh,
+ short (*clnors)[2],
+ float (*loopnors)[3],
+ float (*polynors)[3],
+ const short mix_mode,
+ const float mix_factor,
+ const float mix_limit,
+ MDeformVert *dvert,
+ const int defgrp_index,
+ const bool use_invert_vgroup,
+ MVert *mvert,
+ const int num_verts,
+ MEdge *medge,
+ const int num_edges,
+ MLoop *mloop,
+ const int num_loops,
+ MPoly *mpoly,
+ const int num_polys)
{
- Object *ob_target = enmd->target;
-
- const bool do_polynors_fix = (enmd->flag & MOD_NORMALEDIT_NO_POLYNORS_FIX) == 0;
- const bool use_parallel_normals = (enmd->flag & MOD_NORMALEDIT_USE_DIRECTION_PARALLEL) != 0;
-
- float (*nos)[3] = MEM_malloc_arrayN((size_t)num_loops, sizeof(*nos), __func__);
-
- float target_co[3];
- int i;
-
- /* Get target's center coordinates in ob local coordinates. */
- float mat[4][4];
-
- invert_m4_m4(mat, ob->obmat);
- mul_m4_m4m4(mat, mat, ob_target->obmat);
- copy_v3_v3(target_co, mat[3]);
-
- if (use_parallel_normals) {
- float no[3];
-
- sub_v3_v3v3(no, target_co, enmd->offset);
- normalize_v3(no);
-
- for (i = num_loops; i--; ) {
- copy_v3_v3(nos[i], no);
- }
- }
- else {
- float (*cos)[3] = MEM_malloc_arrayN((size_t)num_verts, sizeof(*cos), __func__);
- generate_vert_coordinates(mesh, ob, ob_target, NULL, num_verts, cos, NULL);
+ Object *ob_target = enmd->target;
+
+ const bool do_polynors_fix = (enmd->flag & MOD_NORMALEDIT_NO_POLYNORS_FIX) == 0;
+ const bool use_parallel_normals = (enmd->flag & MOD_NORMALEDIT_USE_DIRECTION_PARALLEL) != 0;
+
+ float(*nos)[3] = MEM_malloc_arrayN((size_t)num_loops, sizeof(*nos), __func__);
+
+ float target_co[3];
+ int i;
+
+ /* Get target's center coordinates in ob local coordinates. */
+ float mat[4][4];
+
+ invert_m4_m4(mat, ob->obmat);
+ mul_m4_m4m4(mat, mat, ob_target->obmat);
+ copy_v3_v3(target_co, mat[3]);
+
+ if (use_parallel_normals) {
+ float no[3];
+
+ sub_v3_v3v3(no, target_co, enmd->offset);
+ normalize_v3(no);
+
+ for (i = num_loops; i--;) {
+ copy_v3_v3(nos[i], no);
+ }
+ }
+ else {
+ float(*cos)[3] = MEM_malloc_arrayN((size_t)num_verts, sizeof(*cos), __func__);
+ generate_vert_coordinates(mesh, ob, ob_target, NULL, num_verts, cos, NULL);
+
+ BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)num_verts, __func__);
+ MLoop *ml;
+ float(*no)[3];
+
+ /* We reuse cos to now store the 'to target' normal of the verts! */
+ for (i = num_loops, no = nos, ml = mloop; i--; no++, ml++) {
+ const int vidx = ml->v;
+ float *co = cos[vidx];
+
+ if (!BLI_BITMAP_TEST(done_verts, vidx)) {
+ sub_v3_v3v3(co, target_co, co);
+ normalize_v3(co);
+
+ BLI_BITMAP_ENABLE(done_verts, vidx);
+ }
+
+ copy_v3_v3(*no, co);
+ }
+
+ MEM_freeN(done_verts);
+ MEM_freeN(cos);
+ }
+
+ if (loopnors) {
+ mix_normals(mix_factor,
+ dvert,
+ defgrp_index,
+ use_invert_vgroup,
+ mix_limit,
+ mix_mode,
+ num_verts,
+ mloop,
+ loopnors,
+ nos,
+ num_loops);
+ }
+
+ if (do_polynors_fix &&
+ polygons_check_flip(mloop, nos, &mesh->ldata, mpoly, polynors, num_polys)) {
+ mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ }
+
+ BKE_mesh_normals_loop_custom_set(mvert,
+ num_verts,
+ medge,
+ num_edges,
+ mloop,
+ nos,
+ num_loops,
+ mpoly,
+ (const float(*)[3])polynors,
+ num_polys,
+ clnors);
+
+ MEM_freeN(nos);
+}
- BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)num_verts, __func__);
- MLoop *ml;
- float (*no)[3];
+static bool is_valid_target(NormalEditModifierData *enmd)
+{
+ if (enmd->mode == MOD_NORMALEDIT_MODE_RADIAL) {
+ return true;
+ }
+ else if ((enmd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) && enmd->target) {
+ return true;
+ }
+ modifier_setError((ModifierData *)enmd, "Invalid target settings");
+ return false;
+}
- /* We reuse cos to now store the 'to target' normal of the verts! */
- for (i = num_loops, no = nos, ml = mloop; i--; no++, ml++) {
- const int vidx = ml->v;
- float *co = cos[vidx];
+static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
+ const ModifierEvalContext *ctx,
+ Object *ob,
+ Mesh *mesh)
+{
+ const bool use_invert_vgroup = ((enmd->flag & MOD_NORMALEDIT_INVERT_VGROUP) != 0);
+ const bool use_current_clnors = !((enmd->mix_mode == MOD_NORMALEDIT_MIX_COPY) &&
+ (enmd->mix_factor == 1.0f) && (enmd->defgrp_name[0] == '\0') &&
+ (enmd->mix_limit == (float)M_PI));
+
+ /* Do not run that modifier at all if autosmooth is disabled! */
+ if (!is_valid_target(enmd) || mesh->totloop == 0) {
+ return mesh;
+ }
+
+ /* XXX TODO ARG GRRR XYQWNMPRXTYY
+ * Once we fully switch to Mesh evaluation of modifiers, we can expect to get that flag from the COW copy.
+ * But for now, it is lost in the DM intermediate step, so we need to directly check orig object's data. */
+#if 0
+ if (!(mesh->flag & ME_AUTOSMOOTH)) {
+#else
+ if (!(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH)) {
+#endif
+ modifier_setError((ModifierData *)enmd, "Enable 'Auto Smooth' option in mesh settings");
+ return mesh;
+}
- if (!BLI_BITMAP_TEST(done_verts, vidx)) {
- sub_v3_v3v3(co, target_co, co);
- normalize_v3(co);
+Mesh *result;
+if (mesh->medge == ((Mesh *)ob->data)->medge) {
+ /* We need to duplicate data here, otherwise setting custom normals (which may also affect sharp edges) could
+ * modify org mesh, see T43671. */
+ BKE_id_copy_ex(NULL, &mesh->id, (ID **)&result, LIB_ID_COPY_LOCALIZE);
+}
+else {
+ result = mesh;
+}
- BLI_BITMAP_ENABLE(done_verts, vidx);
- }
+const int num_verts = result->totvert;
+const int num_edges = result->totedge;
+const int num_loops = result->totloop;
+const int num_polys = result->totpoly;
+MVert *mvert = result->mvert;
+MEdge *medge = result->medge;
+MLoop *mloop = result->mloop;
+MPoly *mpoly = result->mpoly;
- copy_v3_v3(*no, co);
- }
+int defgrp_index;
+MDeformVert *dvert;
- MEM_freeN(done_verts);
- MEM_freeN(cos);
- }
+float (*loopnors)[3] = NULL;
+short (*clnors)[2] = NULL;
- if (loopnors) {
- mix_normals(mix_factor, dvert, defgrp_index, use_invert_vgroup,
- mix_limit, mix_mode, num_verts, mloop, loopnors, nos, num_loops);
- }
+float (*polynors)[3];
- if (do_polynors_fix && polygons_check_flip(mloop, nos, &mesh->ldata, mpoly, polynors, num_polys)) {
- mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- }
+CustomData *ldata = &result->ldata;
+if (CustomData_has_layer(ldata, CD_NORMAL)) {
+ loopnors = CustomData_get_layer(ldata, CD_NORMAL);
+}
+else {
+ loopnors = CustomData_add_layer(ldata, CD_NORMAL, CD_CALLOC, NULL, num_loops);
+}
- BKE_mesh_normals_loop_custom_set(mvert, num_verts, medge, num_edges, mloop, nos, num_loops,
- mpoly, (const float(*)[3])polynors, num_polys, clnors);
+/* Compute poly (always needed) and vert normals. */
+CustomData *pdata = &result->pdata;
+polynors = CustomData_get_layer(pdata, CD_NORMAL);
+if (!polynors) {
+ polynors = CustomData_add_layer(pdata, CD_NORMAL, CD_CALLOC, NULL, num_polys);
+}
+BKE_mesh_calc_normals_poly(mvert,
+ NULL,
+ num_verts,
+ mloop,
+ mpoly,
+ num_loops,
+ num_polys,
+ polynors,
+ (result->runtime.cd_dirty_vert & CD_MASK_NORMAL) ? false : true);
+
+result->runtime.cd_dirty_vert &= ~CD_MASK_NORMAL;
+
+if (use_current_clnors) {
+ clnors = CustomData_duplicate_referenced_layer(ldata, CD_CUSTOMLOOPNORMAL, num_loops);
+
+ BKE_mesh_normals_loop_split(mvert,
+ num_verts,
+ medge,
+ num_edges,
+ mloop,
+ loopnors,
+ num_loops,
+ mpoly,
+ (const float(*)[3])polynors,
+ num_polys,
+ true,
+ result->smoothresh,
+ NULL,
+ clnors,
+ NULL);
+}
- MEM_freeN(nos);
+if (!clnors) {
+ clnors = CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, num_loops);
}
-static bool is_valid_target(NormalEditModifierData *enmd)
-{
- if (enmd->mode == MOD_NORMALEDIT_MODE_RADIAL) {
- return true;
- }
- else if ((enmd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) && enmd->target) {
- return true;
- }
- modifier_setError((ModifierData *)enmd, "Invalid target settings");
- return false;
+MOD_get_vgroup(ob, result, enmd->defgrp_name, &dvert, &defgrp_index);
+
+if (enmd->mode == MOD_NORMALEDIT_MODE_RADIAL) {
+ normalEditModifier_do_radial(enmd,
+ ctx,
+ ob,
+ result,
+ clnors,
+ loopnors,
+ polynors,
+ enmd->mix_mode,
+ enmd->mix_factor,
+ enmd->mix_limit,
+ dvert,
+ defgrp_index,
+ use_invert_vgroup,
+ mvert,
+ num_verts,
+ medge,
+ num_edges,
+ mloop,
+ num_loops,
+ mpoly,
+ num_polys);
+}
+else if (enmd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) {
+ normalEditModifier_do_directional(enmd,
+ ctx,
+ ob,
+ result,
+ clnors,
+ loopnors,
+ polynors,
+ enmd->mix_mode,
+ enmd->mix_factor,
+ enmd->mix_limit,
+ dvert,
+ defgrp_index,
+ use_invert_vgroup,
+ mvert,
+ num_verts,
+ medge,
+ num_edges,
+ mloop,
+ num_loops,
+ mpoly,
+ num_polys);
}
-static Mesh *normalEditModifier_do(
- NormalEditModifierData *enmd, const ModifierEvalContext *ctx, Object *ob, Mesh *mesh)
-{
- const bool use_invert_vgroup = ((enmd->flag & MOD_NORMALEDIT_INVERT_VGROUP) != 0);
- const bool use_current_clnors = !((enmd->mix_mode == MOD_NORMALEDIT_MIX_COPY) &&
- (enmd->mix_factor == 1.0f) &&
- (enmd->defgrp_name[0] == '\0') &&
- (enmd->mix_limit == (float)M_PI));
-
- /* Do not run that modifier at all if autosmooth is disabled! */
- if (!is_valid_target(enmd) || mesh->totloop == 0) {
- return mesh;
- }
-
- /* XXX TODO ARG GRRR XYQWNMPRXTYY
- * Once we fully switch to Mesh evaluation of modifiers, we can expect to get that flag from the COW copy.
- * But for now, it is lost in the DM intermediate step, so we need to directly check orig object's data. */
-#if 0
- if (!(mesh->flag & ME_AUTOSMOOTH)) {
-#else
- if (!(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH)) {
-#endif
- modifier_setError((ModifierData *)enmd, "Enable 'Auto Smooth' option in mesh settings");
- return mesh;
- }
-
- Mesh *result;
- if (mesh->medge == ((Mesh *)ob->data)->medge) {
- /* We need to duplicate data here, otherwise setting custom normals (which may also affect sharp edges) could
- * modify org mesh, see T43671. */
- BKE_id_copy_ex(NULL, &mesh->id, (ID **)&result, LIB_ID_COPY_LOCALIZE);
- }
- else {
- result = mesh;
- }
-
- const int num_verts = result->totvert;
- const int num_edges = result->totedge;
- const int num_loops = result->totloop;
- const int num_polys = result->totpoly;
- MVert *mvert = result->mvert;
- MEdge *medge = result->medge;
- MLoop *mloop = result->mloop;
- MPoly *mpoly = result->mpoly;
-
- int defgrp_index;
- MDeformVert *dvert;
-
- float (*loopnors)[3] = NULL;
- short (*clnors)[2] = NULL;
-
- float (*polynors)[3];
-
- CustomData *ldata = &result->ldata;
- if (CustomData_has_layer(ldata, CD_NORMAL)) {
- loopnors = CustomData_get_layer(ldata, CD_NORMAL);
- }
- else {
- loopnors = CustomData_add_layer(ldata, CD_NORMAL, CD_CALLOC, NULL, num_loops);
- }
-
- /* Compute poly (always needed) and vert normals. */
- CustomData *pdata = &result->pdata;
- polynors = CustomData_get_layer(pdata, CD_NORMAL);
- if (!polynors) {
- polynors = CustomData_add_layer(pdata, CD_NORMAL, CD_CALLOC, NULL, num_polys);
- }
- BKE_mesh_calc_normals_poly(mvert, NULL, num_verts, mloop, mpoly, num_loops, num_polys, polynors,
- (result->runtime.cd_dirty_vert & CD_MASK_NORMAL) ? false : true);
-
- result->runtime.cd_dirty_vert &= ~CD_MASK_NORMAL;
-
- if (use_current_clnors) {
- clnors = CustomData_duplicate_referenced_layer(ldata, CD_CUSTOMLOOPNORMAL, num_loops);
-
- BKE_mesh_normals_loop_split(mvert, num_verts, medge, num_edges, mloop, loopnors, num_loops,
- mpoly, (const float (*)[3])polynors, num_polys,
- true, result->smoothresh,
- NULL, clnors, NULL);
- }
-
- if (!clnors) {
- clnors = CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, num_loops);
- }
-
- MOD_get_vgroup(ob, result, enmd->defgrp_name, &dvert, &defgrp_index);
-
- if (enmd->mode == MOD_NORMALEDIT_MODE_RADIAL) {
- normalEditModifier_do_radial(
- enmd, ctx, ob, result, clnors, loopnors, polynors,
- enmd->mix_mode, enmd->mix_factor, enmd->mix_limit, dvert, defgrp_index, use_invert_vgroup,
- mvert, num_verts, medge, num_edges, mloop, num_loops, mpoly, num_polys);
- }
- else if (enmd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) {
- normalEditModifier_do_directional(
- enmd, ctx, ob, result, clnors, loopnors, polynors,
- enmd->mix_mode, enmd->mix_factor, enmd->mix_limit, dvert, defgrp_index, use_invert_vgroup,
- mvert, num_verts, medge, num_edges, mloop, num_loops, mpoly, num_polys);
- }
-
- return result;
+return result;
}
static void initData(ModifierData *md)
{
- NormalEditModifierData *enmd = (NormalEditModifierData *)md;
+ NormalEditModifierData *enmd = (NormalEditModifierData *)md;
- enmd->mode = MOD_NORMALEDIT_MODE_RADIAL;
+ enmd->mode = MOD_NORMALEDIT_MODE_RADIAL;
- enmd->mix_mode = MOD_NORMALEDIT_MIX_COPY;
- enmd->mix_factor = 1.0f;
- enmd->mix_limit = M_PI;
+ enmd->mix_mode = MOD_NORMALEDIT_MIX_COPY;
+ enmd->mix_factor = 1.0f;
+ enmd->mix_limit = M_PI;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- NormalEditModifierData *enmd = (NormalEditModifierData *)md;
+ NormalEditModifierData *enmd = (NormalEditModifierData *)md;
- r_cddata_masks->lmask |= CD_MASK_CUSTOMLOOPNORMAL;
+ r_cddata_masks->lmask |= CD_MASK_CUSTOMLOOPNORMAL;
- /* Ask for vertexgroups if we need them. */
- if (enmd->defgrp_name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ /* Ask for vertexgroups if we need them. */
+ if (enmd->defgrp_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
static bool dependsOnNormals(ModifierData *UNUSED(md))
{
- return true;
+ return true;
}
static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- NormalEditModifierData *enmd = (NormalEditModifierData *) md;
+ NormalEditModifierData *enmd = (NormalEditModifierData *)md;
- walk(userData, ob, &enmd->target, IDWALK_CB_NOP);
+ walk(userData, ob, &enmd->target, IDWALK_CB_NOP);
}
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(useRenderParams))
{
- NormalEditModifierData *enmd = (NormalEditModifierData *)md;
+ NormalEditModifierData *enmd = (NormalEditModifierData *)md;
- return !is_valid_target(enmd);
+ return !is_valid_target(enmd);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- NormalEditModifierData *enmd = (NormalEditModifierData *) md;
- if (enmd->target) {
- DEG_add_object_relation(ctx->node, enmd->target, DEG_OB_COMP_TRANSFORM, "NormalEdit Modifier");
- DEG_add_modifier_to_transform_relation(ctx->node, "NormalEdit Modifier");
- }
+ NormalEditModifierData *enmd = (NormalEditModifierData *)md;
+ if (enmd->target) {
+ DEG_add_object_relation(ctx->node, enmd->target, DEG_OB_COMP_TRANSFORM, "NormalEdit Modifier");
+ DEG_add_modifier_to_transform_relation(ctx->node, "NormalEdit Modifier");
+ }
}
static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- return normalEditModifier_do((NormalEditModifierData *)md, ctx, ctx->object, mesh);
+ return normalEditModifier_do((NormalEditModifierData *)md, ctx, ctx->object, mesh);
}
ModifierTypeInfo modifierType_NormalEdit = {
- /* name */ "Set Split Normals",
- /* structName */ "NormalEditModifierData",
- /* structSize */ sizeof(NormalEditModifierData),
- /* type */ eModifierTypeType_Constructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsMapping |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_EnableInEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Set Split Normals",
+ /* structName */ "NormalEditModifierData",
+ /* structSize */ sizeof(NormalEditModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ dependsOnNormals,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c
index 5379321239c..983ea7b4309 100644
--- a/source/blender/modifiers/intern/MOD_ocean.c
+++ b/source/blender/modifiers/intern/MOD_ocean.c
@@ -46,471 +46,472 @@
#ifdef WITH_OCEANSIM
static void init_cache_data(Object *ob, struct OceanModifierData *omd)
{
- const char *relbase = modifier_path_relbase_from_global(ob);
-
- omd->oceancache = BKE_ocean_init_cache(omd->cachepath, relbase,
- omd->bakestart, omd->bakeend, omd->wave_scale,
- omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution);
+ const char *relbase = modifier_path_relbase_from_global(ob);
+
+ omd->oceancache = BKE_ocean_init_cache(omd->cachepath,
+ relbase,
+ omd->bakestart,
+ omd->bakeend,
+ omd->wave_scale,
+ omd->chop_amount,
+ omd->foam_coverage,
+ omd->foam_fade,
+ omd->resolution);
}
static void simulate_ocean_modifier(struct OceanModifierData *omd)
{
- BKE_ocean_simulate(omd->ocean, omd->time, omd->wave_scale, omd->chop_amount);
+ BKE_ocean_simulate(omd->ocean, omd->time, omd->wave_scale, omd->chop_amount);
}
#endif /* WITH_OCEANSIM */
-
-
/* Modifier Code */
static void initData(ModifierData *md)
{
#ifdef WITH_OCEANSIM
- OceanModifierData *omd = (OceanModifierData *) md;
+ OceanModifierData *omd = (OceanModifierData *)md;
- omd->resolution = 7;
- omd->spatial_size = 50;
+ omd->resolution = 7;
+ omd->spatial_size = 50;
- omd->wave_alignment = 0.0;
- omd->wind_velocity = 30.0;
+ omd->wave_alignment = 0.0;
+ omd->wind_velocity = 30.0;
- omd->damp = 0.5;
- omd->smallest_wave = 0.01;
- omd->wave_direction = 0.0;
- omd->depth = 200.0;
+ omd->damp = 0.5;
+ omd->smallest_wave = 0.01;
+ omd->wave_direction = 0.0;
+ omd->depth = 200.0;
- omd->wave_scale = 1.0;
+ omd->wave_scale = 1.0;
- omd->chop_amount = 1.0;
+ omd->chop_amount = 1.0;
- omd->foam_coverage = 0.0;
+ omd->foam_coverage = 0.0;
- omd->seed = 0;
- omd->time = 1.0;
+ omd->seed = 0;
+ omd->time = 1.0;
- omd->size = 1.0;
- omd->repeat_x = 1;
- omd->repeat_y = 1;
+ omd->size = 1.0;
+ omd->repeat_x = 1;
+ omd->repeat_y = 1;
- modifier_path_init(omd->cachepath, sizeof(omd->cachepath), "cache_ocean");
+ modifier_path_init(omd->cachepath, sizeof(omd->cachepath), "cache_ocean");
- omd->cached = 0;
- omd->bakestart = 1;
- omd->bakeend = 250;
- omd->oceancache = NULL;
- omd->foam_fade = 0.98;
- omd->foamlayername[0] = '\0'; /* layer name empty by default */
+ omd->cached = 0;
+ omd->bakestart = 1;
+ omd->bakeend = 250;
+ omd->oceancache = NULL;
+ omd->foam_fade = 0.98;
+ omd->foamlayername[0] = '\0'; /* layer name empty by default */
- omd->ocean = BKE_ocean_add();
- BKE_ocean_init_from_modifier(omd->ocean, omd);
- simulate_ocean_modifier(omd);
+ omd->ocean = BKE_ocean_add();
+ BKE_ocean_init_from_modifier(omd->ocean, omd);
+ simulate_ocean_modifier(omd);
#else /* WITH_OCEANSIM */
- /* unused */
- (void)md;
+ /* unused */
+ (void)md;
#endif /* WITH_OCEANSIM */
}
static void freeData(ModifierData *md)
{
#ifdef WITH_OCEANSIM
- OceanModifierData *omd = (OceanModifierData *) md;
-
- BKE_ocean_free(omd->ocean);
- if (omd->oceancache)
- BKE_ocean_free_cache(omd->oceancache);
-#else /* WITH_OCEANSIM */
- /* unused */
- (void)md;
+ OceanModifierData *omd = (OceanModifierData *)md;
+
+ BKE_ocean_free(omd->ocean);
+ if (omd->oceancache)
+ BKE_ocean_free_cache(omd->oceancache);
+#else /* WITH_OCEANSIM */
+ /* unused */
+ (void)md;
#endif /* WITH_OCEANSIM */
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
#ifdef WITH_OCEANSIM
-#if 0
- const OceanModifierData *omd = (const OceanModifierData *) md;
-#endif
- OceanModifierData *tomd = (OceanModifierData *) target;
-
- modifier_copyData_generic(md, target, flag);
-
- /* The oceancache object will be recreated for this copy
- * automatically when cached=true */
- tomd->oceancache = NULL;
-
- tomd->ocean = BKE_ocean_add();
- BKE_ocean_init_from_modifier(tomd->ocean, tomd);
- simulate_ocean_modifier(tomd);
-#else /* WITH_OCEANSIM */
- /* unused */
- (void)md;
- (void)target;
- (void)flag;
+# if 0
+ const OceanModifierData *omd = (const OceanModifierData *) md;
+# endif
+ OceanModifierData *tomd = (OceanModifierData *)target;
+
+ modifier_copyData_generic(md, target, flag);
+
+ /* The oceancache object will be recreated for this copy
+ * automatically when cached=true */
+ tomd->oceancache = NULL;
+
+ tomd->ocean = BKE_ocean_add();
+ BKE_ocean_init_from_modifier(tomd->ocean, tomd);
+ simulate_ocean_modifier(tomd);
+#else /* WITH_OCEANSIM */
+ /* unused */
+ (void)md;
+ (void)target;
+ (void)flag;
#endif /* WITH_OCEANSIM */
}
#ifdef WITH_OCEANSIM
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- OceanModifierData *omd = (OceanModifierData *)md;
+ OceanModifierData *omd = (OceanModifierData *)md;
- if (omd->flag & MOD_OCEAN_GENERATE_FOAM) {
- r_cddata_masks->fmask |= CD_MASK_MCOL; /* XXX Should be loop cddata I guess? */
- }
+ if (omd->flag & MOD_OCEAN_GENERATE_FOAM) {
+ r_cddata_masks->fmask |= CD_MASK_MCOL; /* XXX Should be loop cddata I guess? */
+ }
}
-#else /* WITH_OCEANSIM */
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md), CustomData_MeshMasks *UNUSED(r_cddata_masks))
+#else /* WITH_OCEANSIM */
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *UNUSED(md),
+ CustomData_MeshMasks *UNUSED(r_cddata_masks))
{
}
#endif /* WITH_OCEANSIM */
static bool dependsOnNormals(ModifierData *md)
{
- OceanModifierData *omd = (OceanModifierData *)md;
- return (omd->geometry_mode != MOD_OCEAN_GEOM_GENERATE);
+ OceanModifierData *omd = (OceanModifierData *)md;
+ return (omd->geometry_mode != MOD_OCEAN_GEOM_GENERATE);
}
#ifdef WITH_OCEANSIM
typedef struct GenerateOceanGeometryData {
- MVert *mverts;
- MPoly *mpolys;
- MLoop *mloops;
- MLoopUV *mloopuvs;
-
- int res_x, res_y;
- int rx, ry;
- float ox, oy;
- float sx, sy;
- float ix, iy;
+ MVert *mverts;
+ MPoly *mpolys;
+ MLoop *mloops;
+ MLoopUV *mloopuvs;
+
+ int res_x, res_y;
+ int rx, ry;
+ float ox, oy;
+ float sx, sy;
+ float ix, iy;
} GenerateOceanGeometryData;
-static void generate_ocean_geometry_vertices(
- void *__restrict userdata,
- const int y,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+static void generate_ocean_geometry_vertices(void *__restrict userdata,
+ const int y,
+ const ParallelRangeTLS *__restrict UNUSED(tls))
{
- GenerateOceanGeometryData *gogd = userdata;
- int x;
-
- for (x = 0; x <= gogd->res_x; x++) {
- const int i = y * (gogd->res_x + 1) + x;
- float *co = gogd->mverts[i].co;
- co[0] = gogd->ox + (x * gogd->sx);
- co[1] = gogd->oy + (y * gogd->sy);
- co[2] = 0.0f;
- }
+ GenerateOceanGeometryData *gogd = userdata;
+ int x;
+
+ for (x = 0; x <= gogd->res_x; x++) {
+ const int i = y * (gogd->res_x + 1) + x;
+ float *co = gogd->mverts[i].co;
+ co[0] = gogd->ox + (x * gogd->sx);
+ co[1] = gogd->oy + (y * gogd->sy);
+ co[2] = 0.0f;
+ }
}
-static void generate_ocean_geometry_polygons(
- void *__restrict userdata,
- const int y,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+static void generate_ocean_geometry_polygons(void *__restrict userdata,
+ const int y,
+ const ParallelRangeTLS *__restrict UNUSED(tls))
{
- GenerateOceanGeometryData *gogd = userdata;
- int x;
-
- for (x = 0; x < gogd->res_x; x++) {
- const int fi = y * gogd->res_x + x;
- const int vi = y * (gogd->res_x + 1) + x;
- MPoly *mp = &gogd->mpolys[fi];
- MLoop *ml = &gogd->mloops[fi * 4];
-
- ml->v = vi;
- ml++;
- ml->v = vi + 1;
- ml++;
- ml->v = vi + 1 + gogd->res_x + 1;
- ml++;
- ml->v = vi + gogd->res_x + 1;
- ml++;
-
- mp->loopstart = fi * 4;
- mp->totloop = 4;
-
- mp->flag |= ME_SMOOTH;
- }
+ GenerateOceanGeometryData *gogd = userdata;
+ int x;
+
+ for (x = 0; x < gogd->res_x; x++) {
+ const int fi = y * gogd->res_x + x;
+ const int vi = y * (gogd->res_x + 1) + x;
+ MPoly *mp = &gogd->mpolys[fi];
+ MLoop *ml = &gogd->mloops[fi * 4];
+
+ ml->v = vi;
+ ml++;
+ ml->v = vi + 1;
+ ml++;
+ ml->v = vi + 1 + gogd->res_x + 1;
+ ml++;
+ ml->v = vi + gogd->res_x + 1;
+ ml++;
+
+ mp->loopstart = fi * 4;
+ mp->totloop = 4;
+
+ mp->flag |= ME_SMOOTH;
+ }
}
-static void generate_ocean_geometry_uvs(
- void *__restrict userdata,
- const int y,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+static void generate_ocean_geometry_uvs(void *__restrict userdata,
+ const int y,
+ const ParallelRangeTLS *__restrict UNUSED(tls))
{
- GenerateOceanGeometryData *gogd = userdata;
- int x;
+ GenerateOceanGeometryData *gogd = userdata;
+ int x;
- for (x = 0; x < gogd->res_x; x++) {
- const int i = y * gogd->res_x + x;
- MLoopUV *luv = &gogd->mloopuvs[i * 4];
+ for (x = 0; x < gogd->res_x; x++) {
+ const int i = y * gogd->res_x + x;
+ MLoopUV *luv = &gogd->mloopuvs[i * 4];
- luv->uv[0] = x * gogd->ix;
- luv->uv[1] = y * gogd->iy;
- luv++;
+ luv->uv[0] = x * gogd->ix;
+ luv->uv[1] = y * gogd->iy;
+ luv++;
- luv->uv[0] = (x + 1) * gogd->ix;
- luv->uv[1] = y * gogd->iy;
- luv++;
+ luv->uv[0] = (x + 1) * gogd->ix;
+ luv->uv[1] = y * gogd->iy;
+ luv++;
- luv->uv[0] = (x + 1) * gogd->ix;
- luv->uv[1] = (y + 1) * gogd->iy;
- luv++;
+ luv->uv[0] = (x + 1) * gogd->ix;
+ luv->uv[1] = (y + 1) * gogd->iy;
+ luv++;
- luv->uv[0] = x * gogd->ix;
- luv->uv[1] = (y + 1) * gogd->iy;
- luv++;
- }
+ luv->uv[0] = x * gogd->ix;
+ luv->uv[1] = (y + 1) * gogd->iy;
+ luv++;
+ }
}
static Mesh *generate_ocean_geometry(OceanModifierData *omd)
{
- Mesh *result;
+ Mesh *result;
- GenerateOceanGeometryData gogd;
+ GenerateOceanGeometryData gogd;
- int num_verts;
- int num_polys;
+ int num_verts;
+ int num_polys;
- const bool use_threading = omd->resolution > 4;
+ const bool use_threading = omd->resolution > 4;
- gogd.rx = omd->resolution * omd->resolution;
- gogd.ry = omd->resolution * omd->resolution;
- gogd.res_x = gogd.rx * omd->repeat_x;
- gogd.res_y = gogd.ry * omd->repeat_y;
+ gogd.rx = omd->resolution * omd->resolution;
+ gogd.ry = omd->resolution * omd->resolution;
+ gogd.res_x = gogd.rx * omd->repeat_x;
+ gogd.res_y = gogd.ry * omd->repeat_y;
- num_verts = (gogd.res_x + 1) * (gogd.res_y + 1);
- num_polys = gogd.res_x * gogd.res_y;
+ num_verts = (gogd.res_x + 1) * (gogd.res_y + 1);
+ num_polys = gogd.res_x * gogd.res_y;
- gogd.sx = omd->size * omd->spatial_size;
- gogd.sy = omd->size * omd->spatial_size;
- gogd.ox = -gogd.sx / 2.0f;
- gogd.oy = -gogd.sy / 2.0f;
+ gogd.sx = omd->size * omd->spatial_size;
+ gogd.sy = omd->size * omd->spatial_size;
+ gogd.ox = -gogd.sx / 2.0f;
+ gogd.oy = -gogd.sy / 2.0f;
- gogd.sx /= gogd.rx;
- gogd.sy /= gogd.ry;
+ gogd.sx /= gogd.rx;
+ gogd.sy /= gogd.ry;
- result = BKE_mesh_new_nomain(num_verts, 0, 0, num_polys * 4, num_polys);
+ result = BKE_mesh_new_nomain(num_verts, 0, 0, num_polys * 4, num_polys);
- gogd.mverts = result->mvert;
- gogd.mpolys = result->mpoly;
- gogd.mloops = result->mloop;
+ gogd.mverts = result->mvert;
+ gogd.mpolys = result->mpoly;
+ gogd.mloops = result->mloop;
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.use_threading = use_threading;
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.use_threading = use_threading;
- /* create vertices */
- BLI_task_parallel_range(0, gogd.res_y + 1, &gogd, generate_ocean_geometry_vertices, &settings);
+ /* create vertices */
+ BLI_task_parallel_range(0, gogd.res_y + 1, &gogd, generate_ocean_geometry_vertices, &settings);
- /* create faces */
- BLI_task_parallel_range(0, gogd.res_y, &gogd, generate_ocean_geometry_polygons, &settings);
+ /* create faces */
+ BLI_task_parallel_range(0, gogd.res_y, &gogd, generate_ocean_geometry_polygons, &settings);
- BKE_mesh_calc_edges(result, false, false);
+ BKE_mesh_calc_edges(result, false, false);
- /* add uvs */
- if (CustomData_number_of_layers(&result->ldata, CD_MLOOPUV) < MAX_MTFACE) {
- gogd.mloopuvs = CustomData_add_layer(&result->ldata, CD_MLOOPUV, CD_CALLOC, NULL, num_polys * 4);
+ /* add uvs */
+ if (CustomData_number_of_layers(&result->ldata, CD_MLOOPUV) < MAX_MTFACE) {
+ gogd.mloopuvs = CustomData_add_layer(
+ &result->ldata, CD_MLOOPUV, CD_CALLOC, NULL, num_polys * 4);
- if (gogd.mloopuvs) { /* unlikely to fail */
- gogd.ix = 1.0 / gogd.rx;
- gogd.iy = 1.0 / gogd.ry;
+ if (gogd.mloopuvs) { /* unlikely to fail */
+ gogd.ix = 1.0 / gogd.rx;
+ gogd.iy = 1.0 / gogd.ry;
- BLI_task_parallel_range(0, gogd.res_y, &gogd, generate_ocean_geometry_uvs, &settings);
- }
- }
+ BLI_task_parallel_range(0, gogd.res_y, &gogd, generate_ocean_geometry_uvs, &settings);
+ }
+ }
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- return result;
+ return result;
}
static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- OceanModifierData *omd = (OceanModifierData *) md;
- int cfra_scene = (int)DEG_get_ctime(ctx->depsgraph);
- Object *ob = ctx->object;
- bool allocated_ocean = false;
-
- Mesh *result = NULL;
- OceanResult ocr;
-
- MVert *mverts;
-
- int cfra_for_cache;
- int i, j;
-
- /* use cached & inverted value for speed
- * expanded this would read...
- *
- * (axis / (omd->size * omd->spatial_size)) + 0.5f) */
-#define OCEAN_CO(_size_co_inv, _v) ((_v * _size_co_inv) + 0.5f)
-
- const float size_co_inv = 1.0f / (omd->size * omd->spatial_size);
-
- /* can happen in when size is small, avoid bad array lookups later and quit now */
- if (!isfinite(size_co_inv)) {
- return mesh;
- }
-
- /* do ocean simulation */
- if (omd->cached == true) {
- if (!omd->oceancache) {
- init_cache_data(ob, omd);
- }
- BKE_ocean_simulate_cache(omd->oceancache, cfra_scene);
- }
- else {
- /* omd->ocean is NULL on an original object (in contrast to an evaluated one).
- * We can create a new one, but we have to free it as well once we're done.
- * This function is only called on an original object when applying the modifier
- * using the 'Apply Modifier' button, and thus it is not called frequently for
- * simulation. */
- allocated_ocean |= BKE_ocean_ensure(omd);
- simulate_ocean_modifier(omd);
- }
-
- if (omd->geometry_mode == MOD_OCEAN_GEOM_GENERATE) {
- result = generate_ocean_geometry(omd);
- BKE_mesh_ensure_normals(result);
- }
- else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) {
- BKE_id_copy_ex(NULL, &mesh->id, (ID **)&result, LIB_ID_COPY_LOCALIZE);
- }
-
- cfra_for_cache = cfra_scene;
- CLAMP(cfra_for_cache, omd->bakestart, omd->bakeend);
- cfra_for_cache -= omd->bakestart; /* shift to 0 based */
-
- mverts = result->mvert;
-
- /* add vcols before displacement - allows lookup based on position */
-
- if (omd->flag & MOD_OCEAN_GENERATE_FOAM) {
- if (CustomData_number_of_layers(&result->ldata, CD_MLOOPCOL) < MAX_MCOL) {
- const int num_polys = result->totpoly;
- const int num_loops = result->totloop;
- MLoop *mloops = result->mloop;
- MLoopCol *mloopcols = CustomData_add_layer_named(
- &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, num_loops, omd->foamlayername);
-
- if (mloopcols) { /* unlikely to fail */
- MPoly *mpolys = result->mpoly;
- MPoly *mp;
-
- for (i = 0, mp = mpolys; i < num_polys; i++, mp++) {
- MLoop *ml = &mloops[mp->loopstart];
- MLoopCol *mlcol = &mloopcols[mp->loopstart];
-
- for (j = mp->totloop; j--; ml++, mlcol++) {
- const float *vco = mverts[ml->v].co;
- const float u = OCEAN_CO(size_co_inv, vco[0]);
- const float v = OCEAN_CO(size_co_inv, vco[1]);
- float foam;
-
- if (omd->oceancache && omd->cached == true) {
- BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra_for_cache, u, v);
- foam = ocr.foam;
- CLAMP(foam, 0.0f, 1.0f);
- }
- else {
- BKE_ocean_eval_uv(omd->ocean, &ocr, u, v);
- foam = BKE_ocean_jminus_to_foam(ocr.Jminus, omd->foam_coverage);
- }
-
- mlcol->r = mlcol->g = mlcol->b = (char)(foam * 255);
- /* This needs to be set (render engine uses) */
- mlcol->a = 255;
- }
- }
- }
- }
- }
-
-
- /* displace the geometry */
-
- /* Note: tried to parallelized that one and previous foam loop, but gives 20% slower results... odd. */
- {
- const int num_verts = result->totvert;
-
- for (i = 0; i < num_verts; i++) {
- float *vco = mverts[i].co;
- const float u = OCEAN_CO(size_co_inv, vco[0]);
- const float v = OCEAN_CO(size_co_inv, vco[1]);
-
- if (omd->oceancache && omd->cached == true) {
- BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra_for_cache, u, v);
- }
- else {
- BKE_ocean_eval_uv(omd->ocean, &ocr, u, v);
- }
-
- vco[2] += ocr.disp[1];
-
- if (omd->chop_amount > 0.0f) {
- vco[0] += ocr.disp[0];
- vco[1] += ocr.disp[2];
- }
- }
- }
-
- if (allocated_ocean) {
- BKE_ocean_free(omd->ocean);
- omd->ocean = NULL;
- }
-
-#undef OCEAN_CO
-
- return result;
+ OceanModifierData *omd = (OceanModifierData *)md;
+ int cfra_scene = (int)DEG_get_ctime(ctx->depsgraph);
+ Object *ob = ctx->object;
+ bool allocated_ocean = false;
+
+ Mesh *result = NULL;
+ OceanResult ocr;
+
+ MVert *mverts;
+
+ int cfra_for_cache;
+ int i, j;
+
+ /* use cached & inverted value for speed
+ * expanded this would read...
+ *
+ * (axis / (omd->size * omd->spatial_size)) + 0.5f) */
+# define OCEAN_CO(_size_co_inv, _v) ((_v * _size_co_inv) + 0.5f)
+
+ const float size_co_inv = 1.0f / (omd->size * omd->spatial_size);
+
+ /* can happen in when size is small, avoid bad array lookups later and quit now */
+ if (!isfinite(size_co_inv)) {
+ return mesh;
+ }
+
+ /* do ocean simulation */
+ if (omd->cached == true) {
+ if (!omd->oceancache) {
+ init_cache_data(ob, omd);
+ }
+ BKE_ocean_simulate_cache(omd->oceancache, cfra_scene);
+ }
+ else {
+ /* omd->ocean is NULL on an original object (in contrast to an evaluated one).
+ * We can create a new one, but we have to free it as well once we're done.
+ * This function is only called on an original object when applying the modifier
+ * using the 'Apply Modifier' button, and thus it is not called frequently for
+ * simulation. */
+ allocated_ocean |= BKE_ocean_ensure(omd);
+ simulate_ocean_modifier(omd);
+ }
+
+ if (omd->geometry_mode == MOD_OCEAN_GEOM_GENERATE) {
+ result = generate_ocean_geometry(omd);
+ BKE_mesh_ensure_normals(result);
+ }
+ else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) {
+ BKE_id_copy_ex(NULL, &mesh->id, (ID **)&result, LIB_ID_COPY_LOCALIZE);
+ }
+
+ cfra_for_cache = cfra_scene;
+ CLAMP(cfra_for_cache, omd->bakestart, omd->bakeend);
+ cfra_for_cache -= omd->bakestart; /* shift to 0 based */
+
+ mverts = result->mvert;
+
+ /* add vcols before displacement - allows lookup based on position */
+
+ if (omd->flag & MOD_OCEAN_GENERATE_FOAM) {
+ if (CustomData_number_of_layers(&result->ldata, CD_MLOOPCOL) < MAX_MCOL) {
+ const int num_polys = result->totpoly;
+ const int num_loops = result->totloop;
+ MLoop *mloops = result->mloop;
+ MLoopCol *mloopcols = CustomData_add_layer_named(
+ &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, num_loops, omd->foamlayername);
+
+ if (mloopcols) { /* unlikely to fail */
+ MPoly *mpolys = result->mpoly;
+ MPoly *mp;
+
+ for (i = 0, mp = mpolys; i < num_polys; i++, mp++) {
+ MLoop *ml = &mloops[mp->loopstart];
+ MLoopCol *mlcol = &mloopcols[mp->loopstart];
+
+ for (j = mp->totloop; j--; ml++, mlcol++) {
+ const float *vco = mverts[ml->v].co;
+ const float u = OCEAN_CO(size_co_inv, vco[0]);
+ const float v = OCEAN_CO(size_co_inv, vco[1]);
+ float foam;
+
+ if (omd->oceancache && omd->cached == true) {
+ BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra_for_cache, u, v);
+ foam = ocr.foam;
+ CLAMP(foam, 0.0f, 1.0f);
+ }
+ else {
+ BKE_ocean_eval_uv(omd->ocean, &ocr, u, v);
+ foam = BKE_ocean_jminus_to_foam(ocr.Jminus, omd->foam_coverage);
+ }
+
+ mlcol->r = mlcol->g = mlcol->b = (char)(foam * 255);
+ /* This needs to be set (render engine uses) */
+ mlcol->a = 255;
+ }
+ }
+ }
+ }
+ }
+
+ /* displace the geometry */
+
+ /* Note: tried to parallelized that one and previous foam loop, but gives 20% slower results... odd. */
+ {
+ const int num_verts = result->totvert;
+
+ for (i = 0; i < num_verts; i++) {
+ float *vco = mverts[i].co;
+ const float u = OCEAN_CO(size_co_inv, vco[0]);
+ const float v = OCEAN_CO(size_co_inv, vco[1]);
+
+ if (omd->oceancache && omd->cached == true) {
+ BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra_for_cache, u, v);
+ }
+ else {
+ BKE_ocean_eval_uv(omd->ocean, &ocr, u, v);
+ }
+
+ vco[2] += ocr.disp[1];
+
+ if (omd->chop_amount > 0.0f) {
+ vco[0] += ocr.disp[0];
+ vco[1] += ocr.disp[2];
+ }
+ }
+ }
+
+ if (allocated_ocean) {
+ BKE_ocean_free(omd->ocean);
+ omd->ocean = NULL;
+ }
+
+# undef OCEAN_CO
+
+ return result;
}
#else /* WITH_OCEANSIM */
static Mesh *doOcean(ModifierData *UNUSED(md), const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
{
- return mesh;
+ return mesh;
}
#endif /* WITH_OCEANSIM */
-static Mesh *applyModifier(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- Mesh *result;
+ Mesh *result;
- result = doOcean(md, ctx, mesh);
+ result = doOcean(md, ctx, mesh);
- if (result != mesh)
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ if (result != mesh)
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- return result;
+ return result;
}
-
ModifierTypeInfo modifierType_Ocean = {
- /* name */ "Ocean",
- /* structName */ "OceanModifierData",
- /* structSize */ sizeof(OceanModifierData),
- /* type */ eModifierTypeType_Constructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_EnableInEditmode,
-
- /* copyData */ copyData,
- /* deformMatrices_DM */ NULL,
-
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ freeData,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Ocean",
+ /* structName */ "OceanModifierData",
+ /* structSize */ sizeof(OceanModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode |
+ eModifierTypeFlag_EnableInEditmode,
+
+ /* copyData */ copyData,
+ /* deformMatrices_DM */ NULL,
+
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ freeData,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ dependsOnNormals,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c
index 189255a7dd1..718c1e6a038 100644
--- a/source/blender/modifiers/intern/MOD_particleinstance.c
+++ b/source/blender/modifiers/intern/MOD_particleinstance.c
@@ -48,497 +48,502 @@
static void initData(ModifierData *md)
{
- ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *) md;
-
- pimd->flag = eParticleInstanceFlag_Parents | eParticleInstanceFlag_Unborn |
- eParticleInstanceFlag_Alive | eParticleInstanceFlag_Dead;
- pimd->psys = 1;
- pimd->position = 1.0f;
- pimd->axis = 2;
- pimd->space = eParticleInstanceSpace_World;
- pimd->particle_amount = 1.0f;
- pimd->particle_offset = 0.0f;
-
- STRNCPY(pimd->index_layer_name, "");
- STRNCPY(pimd->value_layer_name, "");
+ ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
+
+ pimd->flag = eParticleInstanceFlag_Parents | eParticleInstanceFlag_Unborn |
+ eParticleInstanceFlag_Alive | eParticleInstanceFlag_Dead;
+ pimd->psys = 1;
+ pimd->position = 1.0f;
+ pimd->axis = 2;
+ pimd->space = eParticleInstanceSpace_World;
+ pimd->particle_amount = 1.0f;
+ pimd->particle_offset = 0.0f;
+
+ STRNCPY(pimd->index_layer_name, "");
+ STRNCPY(pimd->value_layer_name, "");
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
+ ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
- if (pimd->index_layer_name[0] != '\0' ||
- pimd->value_layer_name[0] != '\0')
- {
- r_cddata_masks->lmask |= CD_MASK_MLOOPCOL;
- }
+ if (pimd->index_layer_name[0] != '\0' || pimd->value_layer_name[0] != '\0') {
+ r_cddata_masks->lmask |= CD_MASK_MLOOPCOL;
+ }
}
static bool isDisabled(const struct Scene *scene, ModifierData *md, bool useRenderParams)
{
- ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
- ParticleSystem *psys;
- ModifierData *ob_md;
-
- if (!pimd->ob)
- return true;
-
- psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1);
- if (psys == NULL)
- return true;
-
- /* If the psys modifier is disabled we cannot use its data.
- * First look up the psys modifier from the object, then check if it is enabled.
- */
- for (ob_md = pimd->ob->modifiers.first; ob_md; ob_md = ob_md->next) {
- if (ob_md->type == eModifierType_ParticleSystem) {
- ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)ob_md;
- if (psmd->psys == psys) {
- int required_mode;
-
- if (useRenderParams) required_mode = eModifierMode_Render;
- else required_mode = eModifierMode_Realtime;
-
- if (!modifier_isEnabled(scene, ob_md, required_mode))
- return true;
-
- break;
- }
- }
- }
-
- return false;
+ ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
+ ParticleSystem *psys;
+ ModifierData *ob_md;
+
+ if (!pimd->ob)
+ return true;
+
+ psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1);
+ if (psys == NULL)
+ return true;
+
+ /* If the psys modifier is disabled we cannot use its data.
+ * First look up the psys modifier from the object, then check if it is enabled.
+ */
+ for (ob_md = pimd->ob->modifiers.first; ob_md; ob_md = ob_md->next) {
+ if (ob_md->type == eModifierType_ParticleSystem) {
+ ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)ob_md;
+ if (psmd->psys == psys) {
+ int required_mode;
+
+ if (useRenderParams)
+ required_mode = eModifierMode_Render;
+ else
+ required_mode = eModifierMode_Realtime;
+
+ if (!modifier_isEnabled(scene, ob_md, required_mode))
+ return true;
+
+ break;
+ }
+ }
+ }
+
+ return false;
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *) md;
- if (pimd->ob != NULL) {
- DEG_add_object_relation(ctx->node, pimd->ob, DEG_OB_COMP_TRANSFORM, "Particle Instance Modifier");
- DEG_add_object_relation(ctx->node, pimd->ob, DEG_OB_COMP_GEOMETRY, "Particle Instance Modifier");
- }
+ ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
+ if (pimd->ob != NULL) {
+ DEG_add_object_relation(
+ ctx->node, pimd->ob, DEG_OB_COMP_TRANSFORM, "Particle Instance Modifier");
+ DEG_add_object_relation(
+ ctx->node, pimd->ob, DEG_OB_COMP_GEOMETRY, "Particle Instance Modifier");
+ }
}
-static void foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *) md;
+ ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
- walk(userData, ob, &pimd->ob, IDWALK_CB_NOP);
+ walk(userData, ob, &pimd->ob, IDWALK_CB_NOP);
}
static bool particle_skip(ParticleInstanceModifierData *pimd, ParticleSystem *psys, int p)
{
- const bool between = (psys->part->childtype == PART_CHILD_FACES);
- ParticleData *pa;
- int totpart, randp, minp, maxp;
-
- if (p >= psys->totpart) {
- ChildParticle *cpa = psys->child + (p - psys->totpart);
- pa = psys->particles + (between ? cpa->pa[0] : cpa->parent);
- }
- else {
- pa = psys->particles + p;
- }
-
- if (pa) {
- if (pa->alive == PARS_UNBORN && (pimd->flag & eParticleInstanceFlag_Unborn) == 0) return true;
- if (pa->alive == PARS_ALIVE && (pimd->flag & eParticleInstanceFlag_Alive) == 0) return true;
- if (pa->alive == PARS_DEAD && (pimd->flag & eParticleInstanceFlag_Dead) == 0) return true;
- }
-
- if (pimd->particle_amount == 1.0f) {
- /* Early output, all particles are to be instanced. */
- return false;
- }
-
- /* Randomly skip particles based on desired amount of visible particles. */
-
- totpart = psys->totpart + psys->totchild;
-
- /* TODO make randomization optional? */
- randp = (int)(psys_frand(psys, 3578 + p) * totpart) % totpart;
-
- minp = (int)(totpart * pimd->particle_offset) % (totpart + 1);
- maxp = (int)(totpart * (pimd->particle_offset + pimd->particle_amount)) % (totpart + 1);
-
- if (maxp > minp) {
- return randp < minp || randp >= maxp;
- }
- else if (maxp < minp) {
- return randp < minp && randp >= maxp;
- }
- else {
- return true;
- }
-
- return false;
+ const bool between = (psys->part->childtype == PART_CHILD_FACES);
+ ParticleData *pa;
+ int totpart, randp, minp, maxp;
+
+ if (p >= psys->totpart) {
+ ChildParticle *cpa = psys->child + (p - psys->totpart);
+ pa = psys->particles + (between ? cpa->pa[0] : cpa->parent);
+ }
+ else {
+ pa = psys->particles + p;
+ }
+
+ if (pa) {
+ if (pa->alive == PARS_UNBORN && (pimd->flag & eParticleInstanceFlag_Unborn) == 0)
+ return true;
+ if (pa->alive == PARS_ALIVE && (pimd->flag & eParticleInstanceFlag_Alive) == 0)
+ return true;
+ if (pa->alive == PARS_DEAD && (pimd->flag & eParticleInstanceFlag_Dead) == 0)
+ return true;
+ }
+
+ if (pimd->particle_amount == 1.0f) {
+ /* Early output, all particles are to be instanced. */
+ return false;
+ }
+
+ /* Randomly skip particles based on desired amount of visible particles. */
+
+ totpart = psys->totpart + psys->totchild;
+
+ /* TODO make randomization optional? */
+ randp = (int)(psys_frand(psys, 3578 + p) * totpart) % totpart;
+
+ minp = (int)(totpart * pimd->particle_offset) % (totpart + 1);
+ maxp = (int)(totpart * (pimd->particle_offset + pimd->particle_amount)) % (totpart + 1);
+
+ if (maxp > minp) {
+ return randp < minp || randp >= maxp;
+ }
+ else if (maxp < minp) {
+ return randp < minp && randp >= maxp;
+ }
+ else {
+ return true;
+ }
+
+ return false;
}
static void store_float_in_vcol(MLoopCol *vcol, float float_value)
{
- const uchar value = unit_float_to_uchar_clamp(float_value);
- vcol->r = vcol->g = vcol->b = value;
- vcol->a = 1.0f;
+ const uchar value = unit_float_to_uchar_clamp(float_value);
+ vcol->r = vcol->g = vcol->b = value;
+ vcol->a = 1.0f;
}
-static Mesh *applyModifier(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- Mesh *result;
- ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *) md;
- struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- ParticleSimulationData sim;
- ParticleSystem *psys = NULL;
- ParticleData *pa = NULL;
- MPoly *mpoly, *orig_mpoly;
- MLoop *mloop, *orig_mloop;
- MVert *mvert, *orig_mvert;
- int totvert, totpoly, totloop, totedge;
- int maxvert, maxpoly, maxloop, maxedge, part_end = 0, part_start;
- int k, p, p_skip;
- short track = ctx->object->trackflag % 3, trackneg, axis = pimd->axis;
- float max_co = 0.0, min_co = 0.0, temp_co[3];
- float *size = NULL;
- float spacemat[4][4];
- const bool use_parents = pimd->flag & eParticleInstanceFlag_Parents;
- const bool use_children = pimd->flag & eParticleInstanceFlag_Children;
- bool between;
-
- trackneg = ((ctx->object->trackflag > 2) ? 1 : 0);
-
- if (pimd->ob == ctx->object) {
- pimd->ob = NULL;
- return mesh;
- }
-
- if (pimd->ob) {
- psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1);
- if (psys == NULL || psys->totpart == 0)
- return mesh;
- }
- else {
- return mesh;
- }
-
- part_start = use_parents ? 0 : psys->totpart;
-
- part_end = 0;
- if (use_parents)
- part_end += psys->totpart;
- if (use_children)
- part_end += psys->totchild;
-
- if (part_end == 0)
- return mesh;
-
- sim.depsgraph = ctx->depsgraph;
- sim.scene = scene;
- sim.ob = pimd->ob;
- sim.psys = psys;
- sim.psmd = psys_get_modifier(pimd->ob, psys);
- between = (psys->part->childtype == PART_CHILD_FACES);
-
- if (pimd->flag & eParticleInstanceFlag_UseSize) {
- float *si;
- si = size = MEM_calloc_arrayN(part_end, sizeof(float), "particle size array");
-
- if (pimd->flag & eParticleInstanceFlag_Parents) {
- for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++, si++)
- *si = pa->size;
- }
-
- if (pimd->flag & eParticleInstanceFlag_Children) {
- ChildParticle *cpa = psys->child;
-
- for (p = 0; p < psys->totchild; p++, cpa++, si++) {
- *si = psys_get_child_size(psys, cpa, 0.0f, NULL);
- }
- }
- }
-
- switch (pimd->space) {
- case eParticleInstanceSpace_World:
- /* particle states are in world space already */
- unit_m4(spacemat);
- break;
- case eParticleInstanceSpace_Local:
- /* get particle states in the particle object's local space */
- invert_m4_m4(spacemat, pimd->ob->obmat);
- break;
- default:
- /* should not happen */
- BLI_assert(false);
- break;
- }
-
- totvert = mesh->totvert;
- totpoly = mesh->totpoly;
- totloop = mesh->totloop;
- totedge = mesh->totedge;
-
- /* count particles */
- maxvert = 0;
- maxpoly = 0;
- maxloop = 0;
- maxedge = 0;
-
- for (p = part_start; p < part_end; p++) {
- if (particle_skip(pimd, psys, p))
- continue;
-
- maxvert += totvert;
- maxpoly += totpoly;
- maxloop += totloop;
- maxedge += totedge;
- }
-
- psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
-
- if (psys->flag & (PSYS_HAIR_DONE | PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) {
- float min[3], max[3];
- INIT_MINMAX(min, max);
- BKE_mesh_minmax(mesh, min, max);
- min_co = min[track];
- max_co = max[track];
- }
-
- result = BKE_mesh_new_nomain_from_template(mesh, maxvert, maxedge, 0, maxloop, maxpoly);
-
- mvert = result->mvert;
- orig_mvert = mesh->mvert;
- mpoly = result->mpoly;
- orig_mpoly = mesh->mpoly;
- mloop = result->mloop;
- orig_mloop = mesh->mloop;
-
- MLoopCol *mloopcols_index = CustomData_get_layer_named(&result->ldata, CD_MLOOPCOL, pimd->index_layer_name);
- MLoopCol *mloopcols_value = CustomData_get_layer_named(&result->ldata, CD_MLOOPCOL, pimd->value_layer_name);
- int *vert_part_index = NULL;
- float *vert_part_value = NULL;
- if (mloopcols_index != NULL) {
- vert_part_index = MEM_calloc_arrayN(maxvert, sizeof(int), "vertex part index array");
- }
- if (mloopcols_value) {
- vert_part_value = MEM_calloc_arrayN(maxvert, sizeof(float), "vertex part value array");
- }
-
- for (p = part_start, p_skip = 0; p < part_end; p++) {
- float prev_dir[3];
- float frame[4]; /* frame orientation quaternion */
- float p_random = psys_frand(psys, 77091 + 283 * p);
-
- /* skip particle? */
- if (particle_skip(pimd, psys, p))
- continue;
-
- /* set vertices coordinates */
- for (k = 0; k < totvert; k++) {
- ParticleKey state;
- MVert *inMV;
- int vindex = p_skip * totvert + k;
- MVert *mv = mvert + vindex;
-
- inMV = orig_mvert + k;
- CustomData_copy_data(&mesh->vdata, &result->vdata, k, p_skip * totvert + k, 1);
- *mv = *inMV;
-
- if (vert_part_index != NULL) {
- vert_part_index[vindex] = p;
- }
- if (vert_part_value != NULL) {
- vert_part_value[vindex] = p_random;
- }
-
- /*change orientation based on object trackflag*/
- copy_v3_v3(temp_co, mv->co);
- mv->co[axis] = temp_co[track];
- mv->co[(axis + 1) % 3] = temp_co[(track + 1) % 3];
- mv->co[(axis + 2) % 3] = temp_co[(track + 2) % 3];
-
- /* get particle state */
- if ((psys->flag & (PSYS_HAIR_DONE | PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) &&
- (pimd->flag & eParticleInstanceFlag_Path))
- {
- float ran = 0.0f;
- if (pimd->random_position != 0.0f) {
- ran = pimd->random_position * BLI_hash_frand(psys->seed + p);
- }
-
- if (pimd->flag & eParticleInstanceFlag_KeepShape) {
- state.time = pimd->position * (1.0f - ran);
- }
- else {
- state.time = (mv->co[axis] - min_co) / (max_co - min_co) * pimd->position * (1.0f - ran);
-
- if (trackneg)
- state.time = 1.0f - state.time;
-
- mv->co[axis] = 0.0;
- }
-
- psys_get_particle_on_path(&sim, p, &state, 1);
-
- normalize_v3(state.vel);
-
- /* Incrementally Rotating Frame (Bishop Frame) */
- if (k == 0) {
- float hairmat[4][4];
- float mat[3][3];
-
- if (p < psys->totpart)
- pa = psys->particles + p;
- else {
- ChildParticle *cpa = psys->child + (p - psys->totpart);
- pa = psys->particles + (between ? cpa->pa[0] : cpa->parent);
- }
- psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, sim.psys->part->from, pa, hairmat);
- copy_m3_m4(mat, hairmat);
- /* to quaternion */
- mat3_to_quat(frame, mat);
-
- if (pimd->rotation > 0.0f || pimd->random_rotation > 0.0f) {
- float angle = 2.0f * M_PI * (pimd->rotation + pimd->random_rotation * (psys_frand(psys, 19957323 + p) - 0.5f));
- float eul[3] = { 0.0f, 0.0f, angle };
- float rot[4];
-
- eul_to_quat(rot, eul);
- mul_qt_qtqt(frame, frame, rot);
- }
-
- /* note: direction is same as normal vector currently,
- * but best to keep this separate so the frame can be
- * rotated later if necessary
- */
- copy_v3_v3(prev_dir, state.vel);
- }
- else {
- float rot[4];
-
- /* incrementally rotate along bend direction */
- rotation_between_vecs_to_quat(rot, prev_dir, state.vel);
- mul_qt_qtqt(frame, rot, frame);
-
- copy_v3_v3(prev_dir, state.vel);
- }
-
- copy_qt_qt(state.rot, frame);
+ Mesh *result;
+ ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
+ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ ParticleSimulationData sim;
+ ParticleSystem *psys = NULL;
+ ParticleData *pa = NULL;
+ MPoly *mpoly, *orig_mpoly;
+ MLoop *mloop, *orig_mloop;
+ MVert *mvert, *orig_mvert;
+ int totvert, totpoly, totloop, totedge;
+ int maxvert, maxpoly, maxloop, maxedge, part_end = 0, part_start;
+ int k, p, p_skip;
+ short track = ctx->object->trackflag % 3, trackneg, axis = pimd->axis;
+ float max_co = 0.0, min_co = 0.0, temp_co[3];
+ float *size = NULL;
+ float spacemat[4][4];
+ const bool use_parents = pimd->flag & eParticleInstanceFlag_Parents;
+ const bool use_children = pimd->flag & eParticleInstanceFlag_Children;
+ bool between;
+
+ trackneg = ((ctx->object->trackflag > 2) ? 1 : 0);
+
+ if (pimd->ob == ctx->object) {
+ pimd->ob = NULL;
+ return mesh;
+ }
+
+ if (pimd->ob) {
+ psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1);
+ if (psys == NULL || psys->totpart == 0)
+ return mesh;
+ }
+ else {
+ return mesh;
+ }
+
+ part_start = use_parents ? 0 : psys->totpart;
+
+ part_end = 0;
+ if (use_parents)
+ part_end += psys->totpart;
+ if (use_children)
+ part_end += psys->totchild;
+
+ if (part_end == 0)
+ return mesh;
+
+ sim.depsgraph = ctx->depsgraph;
+ sim.scene = scene;
+ sim.ob = pimd->ob;
+ sim.psys = psys;
+ sim.psmd = psys_get_modifier(pimd->ob, psys);
+ between = (psys->part->childtype == PART_CHILD_FACES);
+
+ if (pimd->flag & eParticleInstanceFlag_UseSize) {
+ float *si;
+ si = size = MEM_calloc_arrayN(part_end, sizeof(float), "particle size array");
+
+ if (pimd->flag & eParticleInstanceFlag_Parents) {
+ for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++, si++)
+ *si = pa->size;
+ }
+
+ if (pimd->flag & eParticleInstanceFlag_Children) {
+ ChildParticle *cpa = psys->child;
+
+ for (p = 0; p < psys->totchild; p++, cpa++, si++) {
+ *si = psys_get_child_size(psys, cpa, 0.0f, NULL);
+ }
+ }
+ }
+
+ switch (pimd->space) {
+ case eParticleInstanceSpace_World:
+ /* particle states are in world space already */
+ unit_m4(spacemat);
+ break;
+ case eParticleInstanceSpace_Local:
+ /* get particle states in the particle object's local space */
+ invert_m4_m4(spacemat, pimd->ob->obmat);
+ break;
+ default:
+ /* should not happen */
+ BLI_assert(false);
+ break;
+ }
+
+ totvert = mesh->totvert;
+ totpoly = mesh->totpoly;
+ totloop = mesh->totloop;
+ totedge = mesh->totedge;
+
+ /* count particles */
+ maxvert = 0;
+ maxpoly = 0;
+ maxloop = 0;
+ maxedge = 0;
+
+ for (p = part_start; p < part_end; p++) {
+ if (particle_skip(pimd, psys, p))
+ continue;
+
+ maxvert += totvert;
+ maxpoly += totpoly;
+ maxloop += totloop;
+ maxedge += totedge;
+ }
+
+ psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
+
+ if (psys->flag & (PSYS_HAIR_DONE | PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) {
+ float min[3], max[3];
+ INIT_MINMAX(min, max);
+ BKE_mesh_minmax(mesh, min, max);
+ min_co = min[track];
+ max_co = max[track];
+ }
+
+ result = BKE_mesh_new_nomain_from_template(mesh, maxvert, maxedge, 0, maxloop, maxpoly);
+
+ mvert = result->mvert;
+ orig_mvert = mesh->mvert;
+ mpoly = result->mpoly;
+ orig_mpoly = mesh->mpoly;
+ mloop = result->mloop;
+ orig_mloop = mesh->mloop;
+
+ MLoopCol *mloopcols_index = CustomData_get_layer_named(
+ &result->ldata, CD_MLOOPCOL, pimd->index_layer_name);
+ MLoopCol *mloopcols_value = CustomData_get_layer_named(
+ &result->ldata, CD_MLOOPCOL, pimd->value_layer_name);
+ int *vert_part_index = NULL;
+ float *vert_part_value = NULL;
+ if (mloopcols_index != NULL) {
+ vert_part_index = MEM_calloc_arrayN(maxvert, sizeof(int), "vertex part index array");
+ }
+ if (mloopcols_value) {
+ vert_part_value = MEM_calloc_arrayN(maxvert, sizeof(float), "vertex part value array");
+ }
+
+ for (p = part_start, p_skip = 0; p < part_end; p++) {
+ float prev_dir[3];
+ float frame[4]; /* frame orientation quaternion */
+ float p_random = psys_frand(psys, 77091 + 283 * p);
+
+ /* skip particle? */
+ if (particle_skip(pimd, psys, p))
+ continue;
+
+ /* set vertices coordinates */
+ for (k = 0; k < totvert; k++) {
+ ParticleKey state;
+ MVert *inMV;
+ int vindex = p_skip * totvert + k;
+ MVert *mv = mvert + vindex;
+
+ inMV = orig_mvert + k;
+ CustomData_copy_data(&mesh->vdata, &result->vdata, k, p_skip * totvert + k, 1);
+ *mv = *inMV;
+
+ if (vert_part_index != NULL) {
+ vert_part_index[vindex] = p;
+ }
+ if (vert_part_value != NULL) {
+ vert_part_value[vindex] = p_random;
+ }
+
+ /*change orientation based on object trackflag*/
+ copy_v3_v3(temp_co, mv->co);
+ mv->co[axis] = temp_co[track];
+ mv->co[(axis + 1) % 3] = temp_co[(track + 1) % 3];
+ mv->co[(axis + 2) % 3] = temp_co[(track + 2) % 3];
+
+ /* get particle state */
+ if ((psys->flag & (PSYS_HAIR_DONE | PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) &&
+ (pimd->flag & eParticleInstanceFlag_Path)) {
+ float ran = 0.0f;
+ if (pimd->random_position != 0.0f) {
+ ran = pimd->random_position * BLI_hash_frand(psys->seed + p);
+ }
+
+ if (pimd->flag & eParticleInstanceFlag_KeepShape) {
+ state.time = pimd->position * (1.0f - ran);
+ }
+ else {
+ state.time = (mv->co[axis] - min_co) / (max_co - min_co) * pimd->position * (1.0f - ran);
+
+ if (trackneg)
+ state.time = 1.0f - state.time;
+
+ mv->co[axis] = 0.0;
+ }
+
+ psys_get_particle_on_path(&sim, p, &state, 1);
+
+ normalize_v3(state.vel);
+
+ /* Incrementally Rotating Frame (Bishop Frame) */
+ if (k == 0) {
+ float hairmat[4][4];
+ float mat[3][3];
+
+ if (p < psys->totpart)
+ pa = psys->particles + p;
+ else {
+ ChildParticle *cpa = psys->child + (p - psys->totpart);
+ pa = psys->particles + (between ? cpa->pa[0] : cpa->parent);
+ }
+ psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, sim.psys->part->from, pa, hairmat);
+ copy_m3_m4(mat, hairmat);
+ /* to quaternion */
+ mat3_to_quat(frame, mat);
+
+ if (pimd->rotation > 0.0f || pimd->random_rotation > 0.0f) {
+ float angle = 2.0f * M_PI *
+ (pimd->rotation +
+ pimd->random_rotation * (psys_frand(psys, 19957323 + p) - 0.5f));
+ float eul[3] = {0.0f, 0.0f, angle};
+ float rot[4];
+
+ eul_to_quat(rot, eul);
+ mul_qt_qtqt(frame, frame, rot);
+ }
+
+ /* note: direction is same as normal vector currently,
+ * but best to keep this separate so the frame can be
+ * rotated later if necessary
+ */
+ copy_v3_v3(prev_dir, state.vel);
+ }
+ else {
+ float rot[4];
+
+ /* incrementally rotate along bend direction */
+ rotation_between_vecs_to_quat(rot, prev_dir, state.vel);
+ mul_qt_qtqt(frame, rot, frame);
+
+ copy_v3_v3(prev_dir, state.vel);
+ }
+
+ copy_qt_qt(state.rot, frame);
#if 0
- /* Absolute Frame (Frenet Frame) */
- if (state.vel[axis] < -0.9999f || state.vel[axis] > 0.9999f) {
- unit_qt(state.rot);
- }
- else {
- float cross[3];
- float temp[3] = {0.0f, 0.0f, 0.0f};
- temp[axis] = 1.0f;
-
- cross_v3_v3v3(cross, temp, state.vel);
-
- /* state.vel[axis] is the only component surviving from a dot product with the axis */
- axis_angle_to_quat(state.rot, cross, saacos(state.vel[axis]));
- }
+ /* Absolute Frame (Frenet Frame) */
+ if (state.vel[axis] < -0.9999f || state.vel[axis] > 0.9999f) {
+ unit_qt(state.rot);
+ }
+ else {
+ float cross[3];
+ float temp[3] = {0.0f, 0.0f, 0.0f};
+ temp[axis] = 1.0f;
+
+ cross_v3_v3v3(cross, temp, state.vel);
+
+ /* state.vel[axis] is the only component surviving from a dot product with the axis */
+ axis_angle_to_quat(state.rot, cross, saacos(state.vel[axis]));
+ }
#endif
- }
- else {
- state.time = -1.0;
- psys_get_particle_state(&sim, p, &state, 1);
- }
-
- mul_qt_v3(state.rot, mv->co);
- if (pimd->flag & eParticleInstanceFlag_UseSize)
- mul_v3_fl(mv->co, size[p]);
- add_v3_v3(mv->co, state.co);
-
- mul_m4_v3(spacemat, mv->co);
- }
-
- /* create edges and adjust edge vertex indices*/
- CustomData_copy_data(&mesh->edata, &result->edata, 0, p_skip * totedge, totedge);
- MEdge *me = &result->medge[p_skip * totedge];
- for (k = 0; k < totedge; k++, me++) {
- me->v1 += p_skip * totvert;
- me->v2 += p_skip * totvert;
- }
-
- /* create polys and loops */
- for (k = 0; k < totpoly; k++) {
-
- MPoly *inMP = orig_mpoly + k;
- MPoly *mp = mpoly + p_skip * totpoly + k;
-
- CustomData_copy_data(&mesh->pdata, &result->pdata, k, p_skip * totpoly + k, 1);
- *mp = *inMP;
- mp->loopstart += p_skip * totloop;
-
- {
- MLoop *inML = orig_mloop + inMP->loopstart;
- MLoop *ml = mloop + mp->loopstart;
- int j = mp->totloop;
-
- CustomData_copy_data(&mesh->ldata, &result->ldata, inMP->loopstart, mp->loopstart, j);
- for (; j; j--, ml++, inML++) {
- ml->v = inML->v + (p_skip * totvert);
- ml->e = inML->e + (p_skip * totedge);
- const int ml_index = (ml - mloop);
- if (mloopcols_index != NULL) {
- const int part_index = vert_part_index[ml->v];
- store_float_in_vcol(&mloopcols_index[ml_index], (float)part_index / (float)(psys->totpart - 1));
- }
- if (mloopcols_value != NULL) {
- const float part_value = vert_part_value[ml->v];
- store_float_in_vcol(&mloopcols_value[ml_index], part_value);
- }
- }
- }
- }
- p_skip++;
- }
-
- if (psys->lattice_deform_data) {
- end_latt_deform(psys->lattice_deform_data);
- psys->lattice_deform_data = NULL;
- }
-
- if (size)
- MEM_freeN(size);
-
- MEM_SAFE_FREE(vert_part_index);
- MEM_SAFE_FREE(vert_part_value);
-
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
-
- return result;
+ }
+ else {
+ state.time = -1.0;
+ psys_get_particle_state(&sim, p, &state, 1);
+ }
+
+ mul_qt_v3(state.rot, mv->co);
+ if (pimd->flag & eParticleInstanceFlag_UseSize)
+ mul_v3_fl(mv->co, size[p]);
+ add_v3_v3(mv->co, state.co);
+
+ mul_m4_v3(spacemat, mv->co);
+ }
+
+ /* create edges and adjust edge vertex indices*/
+ CustomData_copy_data(&mesh->edata, &result->edata, 0, p_skip * totedge, totedge);
+ MEdge *me = &result->medge[p_skip * totedge];
+ for (k = 0; k < totedge; k++, me++) {
+ me->v1 += p_skip * totvert;
+ me->v2 += p_skip * totvert;
+ }
+
+ /* create polys and loops */
+ for (k = 0; k < totpoly; k++) {
+
+ MPoly *inMP = orig_mpoly + k;
+ MPoly *mp = mpoly + p_skip * totpoly + k;
+
+ CustomData_copy_data(&mesh->pdata, &result->pdata, k, p_skip * totpoly + k, 1);
+ *mp = *inMP;
+ mp->loopstart += p_skip * totloop;
+
+ {
+ MLoop *inML = orig_mloop + inMP->loopstart;
+ MLoop *ml = mloop + mp->loopstart;
+ int j = mp->totloop;
+
+ CustomData_copy_data(&mesh->ldata, &result->ldata, inMP->loopstart, mp->loopstart, j);
+ for (; j; j--, ml++, inML++) {
+ ml->v = inML->v + (p_skip * totvert);
+ ml->e = inML->e + (p_skip * totedge);
+ const int ml_index = (ml - mloop);
+ if (mloopcols_index != NULL) {
+ const int part_index = vert_part_index[ml->v];
+ store_float_in_vcol(&mloopcols_index[ml_index],
+ (float)part_index / (float)(psys->totpart - 1));
+ }
+ if (mloopcols_value != NULL) {
+ const float part_value = vert_part_value[ml->v];
+ store_float_in_vcol(&mloopcols_value[ml_index], part_value);
+ }
+ }
+ }
+ }
+ p_skip++;
+ }
+
+ if (psys->lattice_deform_data) {
+ end_latt_deform(psys->lattice_deform_data);
+ psys->lattice_deform_data = NULL;
+ }
+
+ if (size)
+ MEM_freeN(size);
+
+ MEM_SAFE_FREE(vert_part_index);
+ MEM_SAFE_FREE(vert_part_value);
+
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+
+ return result;
}
ModifierTypeInfo modifierType_ParticleInstance = {
- /* name */ "ParticleInstance",
- /* structName */ "ParticleInstanceModifierData",
- /* structSize */ sizeof(ParticleInstanceModifierData),
- /* type */ eModifierTypeType_Constructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsMapping |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_EnableInEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "ParticleInstance",
+ /* structName */ "ParticleInstanceModifierData",
+ /* structSize */ sizeof(ParticleInstanceModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c
index 5b3e104072c..547e5facbbe 100644
--- a/source/blender/modifiers/intern/MOD_particlesystem.c
+++ b/source/blender/modifiers/intern/MOD_particlesystem.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include <stddef.h>
#include "BLI_utildefines.h"
@@ -41,174 +40,175 @@
static void initData(ModifierData *md)
{
- ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
- psmd->psys = NULL;
- psmd->mesh_final = NULL;
- psmd->mesh_original = NULL;
- psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0;
+ ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
+ psmd->psys = NULL;
+ psmd->mesh_final = NULL;
+ psmd->mesh_original = NULL;
+ psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0;
}
static void freeData(ModifierData *md)
{
- ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
-
- if (psmd->mesh_final) {
- BKE_id_free(NULL, psmd->mesh_final);
- psmd->mesh_final = NULL;
- if (psmd->mesh_original) {
- BKE_id_free(NULL, psmd->mesh_original);
- psmd->mesh_original = NULL;
- }
- }
- psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0;
-
- /* ED_object_modifier_remove may have freed this first before calling
- * modifier_free (which calls this function) */
- if (psmd->psys)
- psmd->psys->flag |= PSYS_DELETE;
+ ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
+
+ if (psmd->mesh_final) {
+ BKE_id_free(NULL, psmd->mesh_final);
+ psmd->mesh_final = NULL;
+ if (psmd->mesh_original) {
+ BKE_id_free(NULL, psmd->mesh_original);
+ psmd->mesh_original = NULL;
+ }
+ }
+ psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0;
+
+ /* ED_object_modifier_remove may have freed this first before calling
+ * modifier_free (which calls this function) */
+ if (psmd->psys)
+ psmd->psys->flag |= PSYS_DELETE;
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
#if 0
- const ParticleSystemModifierData *psmd = (const ParticleSystemModifierData *) md;
+ const ParticleSystemModifierData *psmd = (const ParticleSystemModifierData *) md;
#endif
- ParticleSystemModifierData *tpsmd = (ParticleSystemModifierData *) target;
+ ParticleSystemModifierData *tpsmd = (ParticleSystemModifierData *)target;
- modifier_copyData_generic(md, target, flag);
+ modifier_copyData_generic(md, target, flag);
- tpsmd->mesh_final = NULL;
- tpsmd->mesh_original = NULL;
- tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0;
+ tpsmd->mesh_final = NULL;
+ tpsmd->mesh_original = NULL;
+ tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
+ ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
- psys_emitter_customdata_mask(psmd->psys, r_cddata_masks);
+ psys_emitter_customdata_mask(psmd->psys, r_cddata_masks);
}
/* saves the current emitter state for a particle system and calculates particles */
-static void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh,
- float (*vertexCos)[3],
- int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- Mesh *mesh_src = mesh;
- ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
- ParticleSystem *psys = NULL;
- /* float cfra = BKE_scene_frame_get(md->scene); */ /* UNUSED */
-
- if (ctx->object->particlesystem.first)
- psys = psmd->psys;
- else
- return;
-
- if (!psys_check_enabled(ctx->object, psys, (ctx->flag & MOD_APPLY_RENDER) != 0))
- return;
-
- if (mesh_src == NULL) {
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, vertexCos, numVerts, false, true);
- if (mesh_src == NULL) {
- return;
- }
- }
-
- /* clear old dm */
- bool had_mesh_final = (psmd->mesh_final != NULL);
- if (psmd->mesh_final) {
- BKE_id_free(NULL, psmd->mesh_final);
- psmd->mesh_final = NULL;
- if (psmd->mesh_original) {
- BKE_id_free(NULL, psmd->mesh_original);
- psmd->mesh_original = NULL;
- }
- }
- else if (psmd->flag & eParticleSystemFlag_file_loaded) {
- /* in file read mesh just wasn't saved in file so no need to reset everything */
- psmd->flag &= ~eParticleSystemFlag_file_loaded;
- if (psys->particles == NULL) {
- psys->recalc |= ID_RECALC_PSYS_RESET;
- }
- /* TODO(sergey): This is not how particles were working prior to copy on
- * write, but now evaluation is similar to case when one duplicates the
- * object. In that case particles were doing reset here. */
- psys->recalc |= ID_RECALC_PSYS_RESET;
- }
-
- /* make new mesh */
- psmd->mesh_final = BKE_mesh_copy_for_eval(mesh_src, false);
- BKE_mesh_apply_vert_coords(psmd->mesh_final, vertexCos);
- BKE_mesh_calc_normals(psmd->mesh_final);
-
- BKE_mesh_tessface_ensure(psmd->mesh_final);
-
- if (!psmd->mesh_final->runtime.deformed_only) {
- /* Get the original mesh from the object, this is what the particles
- * are attached to so in case of non-deform modifiers we need to remap
- * them to the final mesh (typically subdivision surfaces). */
- Mesh *mesh_original = NULL;
-
- if (ctx->object->type == OB_MESH) {
- BMEditMesh *em = BKE_editmesh_from_object(ctx->object);
-
- if (em) {
- /* In edit mode get directly from the edit mesh. */
- psmd->mesh_original = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL);
- }
- else {
- /* Otherwise get regular mesh. */
- mesh_original = ctx->object->data;
- }
- }
- else {
- mesh_original = mesh_src;
- }
-
- if (mesh_original) {
- /* Make a persistent copy of the mesh. We don't actually need
- * all this data, just some topology for remapping. Could be
- * optimized once. */
- psmd->mesh_original = BKE_mesh_copy_for_eval(mesh_original, false);
- }
-
- BKE_mesh_tessface_ensure(psmd->mesh_original);
- }
-
- if (mesh_src != psmd->mesh_final && mesh_src != mesh) {
- BKE_id_free(NULL, mesh_src);
- }
-
- /* Report change in mesh structure.
- * This is an unreliable check for the topology check, but allows some
- * handy configuration like emitting particles from inside particle
- * instance. */
- if (had_mesh_final &&
- (psmd->mesh_final->totvert != psmd->totdmvert ||
- psmd->mesh_final->totedge != psmd->totdmedge ||
- psmd->mesh_final->totface != psmd->totdmface))
- {
- psys->recalc |= ID_RECALC_PSYS_RESET;
- psmd->totdmvert = psmd->mesh_final->totvert;
- psmd->totdmedge = psmd->mesh_final->totedge;
- psmd->totdmface = psmd->mesh_final->totface;
- }
-
- if (!(ctx->object->transflag & OB_NO_PSYS_UPDATE)) {
- struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- psmd->flag &= ~eParticleSystemFlag_psys_updated;
- particle_system_update(ctx->depsgraph, scene, ctx->object, psys, (ctx->flag & MOD_APPLY_RENDER) != 0);
- psmd->flag |= eParticleSystemFlag_psys_updated;
- }
-
- if (DEG_is_active(ctx->depsgraph)) {
- Object *object_orig = DEG_get_original_object(ctx->object);
- ModifierData *md_orig = modifiers_findByName(object_orig, psmd->modifier.name);
- BLI_assert(md_orig != NULL);
- ParticleSystemModifierData *psmd_orig = (ParticleSystemModifierData *) md_orig;
- psmd_orig->flag = psmd->flag;
- }
+ Mesh *mesh_src = mesh;
+ ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
+ ParticleSystem *psys = NULL;
+ /* float cfra = BKE_scene_frame_get(md->scene); */ /* UNUSED */
+
+ if (ctx->object->particlesystem.first)
+ psys = psmd->psys;
+ else
+ return;
+
+ if (!psys_check_enabled(ctx->object, psys, (ctx->flag & MOD_APPLY_RENDER) != 0))
+ return;
+
+ if (mesh_src == NULL) {
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, vertexCos, numVerts, false, true);
+ if (mesh_src == NULL) {
+ return;
+ }
+ }
+
+ /* clear old dm */
+ bool had_mesh_final = (psmd->mesh_final != NULL);
+ if (psmd->mesh_final) {
+ BKE_id_free(NULL, psmd->mesh_final);
+ psmd->mesh_final = NULL;
+ if (psmd->mesh_original) {
+ BKE_id_free(NULL, psmd->mesh_original);
+ psmd->mesh_original = NULL;
+ }
+ }
+ else if (psmd->flag & eParticleSystemFlag_file_loaded) {
+ /* in file read mesh just wasn't saved in file so no need to reset everything */
+ psmd->flag &= ~eParticleSystemFlag_file_loaded;
+ if (psys->particles == NULL) {
+ psys->recalc |= ID_RECALC_PSYS_RESET;
+ }
+ /* TODO(sergey): This is not how particles were working prior to copy on
+ * write, but now evaluation is similar to case when one duplicates the
+ * object. In that case particles were doing reset here. */
+ psys->recalc |= ID_RECALC_PSYS_RESET;
+ }
+
+ /* make new mesh */
+ psmd->mesh_final = BKE_mesh_copy_for_eval(mesh_src, false);
+ BKE_mesh_apply_vert_coords(psmd->mesh_final, vertexCos);
+ BKE_mesh_calc_normals(psmd->mesh_final);
+
+ BKE_mesh_tessface_ensure(psmd->mesh_final);
+
+ if (!psmd->mesh_final->runtime.deformed_only) {
+ /* Get the original mesh from the object, this is what the particles
+ * are attached to so in case of non-deform modifiers we need to remap
+ * them to the final mesh (typically subdivision surfaces). */
+ Mesh *mesh_original = NULL;
+
+ if (ctx->object->type == OB_MESH) {
+ BMEditMesh *em = BKE_editmesh_from_object(ctx->object);
+
+ if (em) {
+ /* In edit mode get directly from the edit mesh. */
+ psmd->mesh_original = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL);
+ }
+ else {
+ /* Otherwise get regular mesh. */
+ mesh_original = ctx->object->data;
+ }
+ }
+ else {
+ mesh_original = mesh_src;
+ }
+
+ if (mesh_original) {
+ /* Make a persistent copy of the mesh. We don't actually need
+ * all this data, just some topology for remapping. Could be
+ * optimized once. */
+ psmd->mesh_original = BKE_mesh_copy_for_eval(mesh_original, false);
+ }
+
+ BKE_mesh_tessface_ensure(psmd->mesh_original);
+ }
+
+ if (mesh_src != psmd->mesh_final && mesh_src != mesh) {
+ BKE_id_free(NULL, mesh_src);
+ }
+
+ /* Report change in mesh structure.
+ * This is an unreliable check for the topology check, but allows some
+ * handy configuration like emitting particles from inside particle
+ * instance. */
+ if (had_mesh_final && (psmd->mesh_final->totvert != psmd->totdmvert ||
+ psmd->mesh_final->totedge != psmd->totdmedge ||
+ psmd->mesh_final->totface != psmd->totdmface)) {
+ psys->recalc |= ID_RECALC_PSYS_RESET;
+ psmd->totdmvert = psmd->mesh_final->totvert;
+ psmd->totdmedge = psmd->mesh_final->totedge;
+ psmd->totdmface = psmd->mesh_final->totface;
+ }
+
+ if (!(ctx->object->transflag & OB_NO_PSYS_UPDATE)) {
+ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ psmd->flag &= ~eParticleSystemFlag_psys_updated;
+ particle_system_update(
+ ctx->depsgraph, scene, ctx->object, psys, (ctx->flag & MOD_APPLY_RENDER) != 0);
+ psmd->flag |= eParticleSystemFlag_psys_updated;
+ }
+
+ if (DEG_is_active(ctx->depsgraph)) {
+ Object *object_orig = DEG_get_original_object(ctx->object);
+ ModifierData *md_orig = modifiers_findByName(object_orig, psmd->modifier.name);
+ BLI_assert(md_orig != NULL);
+ ParticleSystemModifierData *psmd_orig = (ParticleSystemModifierData *)md_orig;
+ psmd_orig->flag = psmd->flag;
+ }
}
/* disabled particles in editmode for now, until support for proper evaluated mesh
@@ -218,49 +218,48 @@ static void deformVertsEM(
ModifierData *md, Object *ob, BMEditMesh *editData,
Mesh *mesh, float (*vertexCos)[3], int numVerts)
{
- const bool do_temp_mesh = (mesh == NULL);
- if (do_temp_mesh) {
- mesh = BKE_id_new_nomain(ID_ME, ((ID *)ob->data)->name);
- BM_mesh_bm_to_me(NULL, editData->bm, mesh, &((BMeshToMeshParams){0}));
- }
+ const bool do_temp_mesh = (mesh == NULL);
+ if (do_temp_mesh) {
+ mesh = BKE_id_new_nomain(ID_ME, ((ID *)ob->data)->name);
+ BM_mesh_bm_to_me(NULL, editData->bm, mesh, &((BMeshToMeshParams){0}));
+ }
- deformVerts(md, ob, mesh, vertexCos, numVerts);
+ deformVerts(md, ob, mesh, vertexCos, numVerts);
- if (derivedData) {
- BKE_id_free(NULL, mesh);
- }
+ if (derivedData) {
+ BKE_id_free(NULL, mesh);
+ }
}
#endif
-
ModifierTypeInfo modifierType_ParticleSystem = {
- /* name */ "ParticleSystem",
- /* structName */ "ParticleSystemModifierData",
- /* structSize */ sizeof(ParticleSystemModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsMapping |
- eModifierTypeFlag_UsesPointCache /* |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_EnableInEditmode */,
-
- /* copyData */ copyData,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ freeData,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "ParticleSystem",
+ /* structName */ "ParticleSystemModifierData",
+ /* structSize */ sizeof(ParticleSystemModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_UsesPointCache /* |
+ eModifierTypeFlag_SupportsEditmode |
+ eModifierTypeFlag_EnableInEditmode */
+ ,
+
+ /* copyData */ copyData,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ freeData,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c
index 345ee6477ac..daf9a615f3f 100644
--- a/source/blender/modifiers/intern/MOD_remesh.c
+++ b/source/blender/modifiers/intern/MOD_remesh.c
@@ -48,188 +48,181 @@
static void initData(ModifierData *md)
{
- RemeshModifierData *rmd = (RemeshModifierData *) md;
-
- rmd->scale = 0.9;
- rmd->depth = 4;
- rmd->hermite_num = 1;
- rmd->flag = MOD_REMESH_FLOOD_FILL;
- rmd->mode = MOD_REMESH_SHARP_FEATURES;
- rmd->threshold = 1;
+ RemeshModifierData *rmd = (RemeshModifierData *)md;
+
+ rmd->scale = 0.9;
+ rmd->depth = 4;
+ rmd->hermite_num = 1;
+ rmd->flag = MOD_REMESH_FLOOD_FILL;
+ rmd->mode = MOD_REMESH_SHARP_FEATURES;
+ rmd->threshold = 1;
}
#ifdef WITH_MOD_REMESH
static void init_dualcon_mesh(DualConInput *input, Mesh *mesh)
{
- memset(input, 0, sizeof(DualConInput));
+ memset(input, 0, sizeof(DualConInput));
- input->co = (void *)mesh->mvert;
- input->co_stride = sizeof(MVert);
- input->totco = mesh->totvert;
+ input->co = (void *)mesh->mvert;
+ input->co_stride = sizeof(MVert);
+ input->totco = mesh->totvert;
- input->mloop = (void *)mesh->mloop;
- input->loop_stride = sizeof(MLoop);
+ input->mloop = (void *)mesh->mloop;
+ input->loop_stride = sizeof(MLoop);
- BKE_mesh_runtime_looptri_ensure(mesh);
- input->looptri = (void *)mesh->runtime.looptris.array;
- input->tri_stride = sizeof(MLoopTri);
- input->tottri = mesh->runtime.looptris.len;
+ BKE_mesh_runtime_looptri_ensure(mesh);
+ input->looptri = (void *)mesh->runtime.looptris.array;
+ input->tri_stride = sizeof(MLoopTri);
+ input->tottri = mesh->runtime.looptris.len;
- INIT_MINMAX(input->min, input->max);
- BKE_mesh_minmax(mesh, input->min, input->max);
+ INIT_MINMAX(input->min, input->max);
+ BKE_mesh_minmax(mesh, input->min, input->max);
}
/* simple structure to hold the output: a CDDM and two counters to
* keep track of the current elements */
typedef struct {
- Mesh *mesh;
- int curvert, curface;
+ Mesh *mesh;
+ int curvert, curface;
} DualConOutput;
/* allocate and initialize a DualConOutput */
static void *dualcon_alloc_output(int totvert, int totquad)
{
- DualConOutput *output;
+ DualConOutput *output;
- if (!(output = MEM_callocN(sizeof(DualConOutput),
- "DualConOutput")))
- {
- return NULL;
- }
+ if (!(output = MEM_callocN(sizeof(DualConOutput), "DualConOutput"))) {
+ return NULL;
+ }
- output->mesh = BKE_mesh_new_nomain(totvert, 0, 0, 4 * totquad, totquad);
- return output;
+ output->mesh = BKE_mesh_new_nomain(totvert, 0, 0, 4 * totquad, totquad);
+ return output;
}
static void dualcon_add_vert(void *output_v, const float co[3])
{
- DualConOutput *output = output_v;
- Mesh *mesh = output->mesh;
+ DualConOutput *output = output_v;
+ Mesh *mesh = output->mesh;
- assert(output->curvert < mesh->totvert);
+ assert(output->curvert < mesh->totvert);
- copy_v3_v3(mesh->mvert[output->curvert].co, co);
- output->curvert++;
+ copy_v3_v3(mesh->mvert[output->curvert].co, co);
+ output->curvert++;
}
static void dualcon_add_quad(void *output_v, const int vert_indices[4])
{
- DualConOutput *output = output_v;
- Mesh *mesh = output->mesh;
- MLoop *mloop;
- MPoly *cur_poly;
- int i;
+ DualConOutput *output = output_v;
+ Mesh *mesh = output->mesh;
+ MLoop *mloop;
+ MPoly *cur_poly;
+ int i;
- assert(output->curface < mesh->totpoly);
+ assert(output->curface < mesh->totpoly);
- mloop = mesh->mloop;
- cur_poly = &mesh->mpoly[output->curface];
+ mloop = mesh->mloop;
+ cur_poly = &mesh->mpoly[output->curface];
- cur_poly->loopstart = output->curface * 4;
- cur_poly->totloop = 4;
- for (i = 0; i < 4; i++)
- mloop[output->curface * 4 + i].v = vert_indices[i];
+ cur_poly->loopstart = output->curface * 4;
+ cur_poly->totloop = 4;
+ for (i = 0; i < 4; i++)
+ mloop[output->curface * 4 + i].v = vert_indices[i];
- output->curface++;
+ output->curface++;
}
-static Mesh *applyModifier(
- ModifierData *md,
- const ModifierEvalContext *UNUSED(ctx),
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
{
- RemeshModifierData *rmd;
- DualConOutput *output;
- DualConInput input;
- Mesh *result;
- DualConFlags flags = 0;
- DualConMode mode = 0;
-
- rmd = (RemeshModifierData *)md;
-
- init_dualcon_mesh(&input, mesh);
-
- if (rmd->flag & MOD_REMESH_FLOOD_FILL)
- flags |= DUALCON_FLOOD_FILL;
-
- switch (rmd->mode) {
- case MOD_REMESH_CENTROID:
- mode = DUALCON_CENTROID;
- break;
- case MOD_REMESH_MASS_POINT:
- mode = DUALCON_MASS_POINT;
- break;
- case MOD_REMESH_SHARP_FEATURES:
- mode = DUALCON_SHARP_FEATURES;
- break;
- }
-
- output = dualcon(&input,
- dualcon_alloc_output,
- dualcon_add_vert,
- dualcon_add_quad,
- flags,
- mode,
- rmd->threshold,
- rmd->hermite_num,
- rmd->scale,
- rmd->depth);
- result = output->mesh;
- MEM_freeN(output);
-
- if (rmd->flag & MOD_REMESH_SMOOTH_SHADING) {
- MPoly *mpoly = result->mpoly;
- int i, totpoly = result->totpoly;
-
- /* Apply smooth shading to output faces */
- for (i = 0; i < totpoly; i++) {
- mpoly[i].flag |= ME_SMOOTH;
- }
- }
-
- BKE_mesh_calc_edges(result, true, false);
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- return result;
+ RemeshModifierData *rmd;
+ DualConOutput *output;
+ DualConInput input;
+ Mesh *result;
+ DualConFlags flags = 0;
+ DualConMode mode = 0;
+
+ rmd = (RemeshModifierData *)md;
+
+ init_dualcon_mesh(&input, mesh);
+
+ if (rmd->flag & MOD_REMESH_FLOOD_FILL)
+ flags |= DUALCON_FLOOD_FILL;
+
+ switch (rmd->mode) {
+ case MOD_REMESH_CENTROID:
+ mode = DUALCON_CENTROID;
+ break;
+ case MOD_REMESH_MASS_POINT:
+ mode = DUALCON_MASS_POINT;
+ break;
+ case MOD_REMESH_SHARP_FEATURES:
+ mode = DUALCON_SHARP_FEATURES;
+ break;
+ }
+
+ output = dualcon(&input,
+ dualcon_alloc_output,
+ dualcon_add_vert,
+ dualcon_add_quad,
+ flags,
+ mode,
+ rmd->threshold,
+ rmd->hermite_num,
+ rmd->scale,
+ rmd->depth);
+ result = output->mesh;
+ MEM_freeN(output);
+
+ if (rmd->flag & MOD_REMESH_SMOOTH_SHADING) {
+ MPoly *mpoly = result->mpoly;
+ int i, totpoly = result->totpoly;
+
+ /* Apply smooth shading to output faces */
+ for (i = 0; i < totpoly; i++) {
+ mpoly[i].flag |= ME_SMOOTH;
+ }
+ }
+
+ BKE_mesh_calc_edges(result, true, false);
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ return result;
}
#else /* !WITH_MOD_REMESH */
-static Mesh *applyModifier(
- ModifierData *UNUSED(md),
- const ModifierEvalContext *UNUSED(ctx),
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *UNUSED(md),
+ const ModifierEvalContext *UNUSED(ctx),
+ Mesh *mesh)
{
- return mesh;
+ return mesh;
}
#endif /* !WITH_MOD_REMESH */
ModifierTypeInfo modifierType_Remesh = {
- /* name */ "Remesh",
- /* structName */ "RemeshModifierData",
- /* structSize */ sizeof(RemeshModifierData),
- /* type */ eModifierTypeType_Nonconstructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_SupportsEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ NULL,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Remesh",
+ /* structName */ "RemeshModifierData",
+ /* structSize */ sizeof(RemeshModifierData),
+ /* type */ eModifierTypeType_Nonconstructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs |
+ eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c
index 8e881fd09f0..e2917e2f82a 100644
--- a/source/blender/modifiers/intern/MOD_screw.c
+++ b/source/blender/modifiers/intern/MOD_screw.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
/* Screw modifier: revolves the edges about an axis */
#include <limits.h>
@@ -47,1109 +46,1117 @@
/* used for gathering edge connectivity */
typedef struct ScrewVertConnect {
- float dist; /* distance from the center axis */
- float co[3]; /* location relative to the transformed axis */
- float no[3]; /* calc normal of the vertex */
- unsigned int v[2]; /* 2 verts on either side of this one */
- MEdge *e[2]; /* edges on either side, a bit of a waste since each edge ref's 2 edges */
- char flag;
+ float dist; /* distance from the center axis */
+ float co[3]; /* location relative to the transformed axis */
+ float no[3]; /* calc normal of the vertex */
+ unsigned int v[2]; /* 2 verts on either side of this one */
+ MEdge *e[2]; /* edges on either side, a bit of a waste since each edge ref's 2 edges */
+ char flag;
} ScrewVertConnect;
typedef struct ScrewVertIter {
- ScrewVertConnect *v_array;
- ScrewVertConnect *v_poin;
- unsigned int v, v_other;
- MEdge *e;
+ ScrewVertConnect *v_array;
+ ScrewVertConnect *v_poin;
+ unsigned int v, v_other;
+ MEdge *e;
} ScrewVertIter;
#define SV_UNUSED (UINT_MAX)
-#define SV_INVALID ((UINT_MAX) - 1)
+#define SV_INVALID ((UINT_MAX)-1)
#define SV_IS_VALID(v) ((v) < SV_INVALID)
-static void screwvert_iter_init(ScrewVertIter *iter, ScrewVertConnect *array, unsigned int v_init, unsigned int dir)
+static void screwvert_iter_init(ScrewVertIter *iter,
+ ScrewVertConnect *array,
+ unsigned int v_init,
+ unsigned int dir)
{
- iter->v_array = array;
- iter->v = v_init;
-
- if (SV_IS_VALID(v_init)) {
- iter->v_poin = &array[v_init];
- iter->v_other = iter->v_poin->v[dir];
- iter->e = iter->v_poin->e[!dir];
- }
- else {
- iter->v_poin = NULL;
- iter->e = NULL;
- }
+ iter->v_array = array;
+ iter->v = v_init;
+
+ if (SV_IS_VALID(v_init)) {
+ iter->v_poin = &array[v_init];
+ iter->v_other = iter->v_poin->v[dir];
+ iter->e = iter->v_poin->e[!dir];
+ }
+ else {
+ iter->v_poin = NULL;
+ iter->e = NULL;
+ }
}
-
static void screwvert_iter_step(ScrewVertIter *iter)
{
- if (iter->v_poin->v[0] == iter->v_other) {
- iter->v_other = iter->v;
- iter->v = iter->v_poin->v[1];
- }
- else if (iter->v_poin->v[1] == iter->v_other) {
- iter->v_other = iter->v;
- iter->v = iter->v_poin->v[0];
- }
- if (SV_IS_VALID(iter->v)) {
- iter->v_poin = &iter->v_array[iter->v];
- iter->e = iter->v_poin->e[(iter->v_poin->e[0] == iter->e)];
- }
- else {
- iter->e = NULL;
- iter->v_poin = NULL;
- }
+ if (iter->v_poin->v[0] == iter->v_other) {
+ iter->v_other = iter->v;
+ iter->v = iter->v_poin->v[1];
+ }
+ else if (iter->v_poin->v[1] == iter->v_other) {
+ iter->v_other = iter->v;
+ iter->v = iter->v_poin->v[0];
+ }
+ if (SV_IS_VALID(iter->v)) {
+ iter->v_poin = &iter->v_array[iter->v];
+ iter->e = iter->v_poin->e[(iter->v_poin->e[0] == iter->e)];
+ }
+ else {
+ iter->e = NULL;
+ iter->v_poin = NULL;
+ }
}
-static Mesh *mesh_remove_doubles_on_axis(
- Mesh *result, MVert *mvert_new, const uint totvert, const uint step_tot,
- const float axis_vec[3], const float axis_offset[3], const float merge_threshold)
+static Mesh *mesh_remove_doubles_on_axis(Mesh *result,
+ MVert *mvert_new,
+ const uint totvert,
+ const uint step_tot,
+ const float axis_vec[3],
+ const float axis_offset[3],
+ const float merge_threshold)
{
- const float merge_threshold_sq = SQUARE(merge_threshold);
- const bool use_offset = axis_offset != NULL;
- uint tot_doubles = 0;
- for (uint i = 0; i < totvert; i += 1) {
- float axis_co[3];
- if (use_offset) {
- float offset_co[3];
- sub_v3_v3v3(offset_co, mvert_new[i].co, axis_offset);
- project_v3_v3v3_normalized(axis_co, offset_co, axis_vec);
- add_v3_v3(axis_co, axis_offset);
- }
- else {
- project_v3_v3v3_normalized(axis_co, mvert_new[i].co, axis_vec);
- }
- const float dist_sq = len_squared_v3v3(axis_co, mvert_new[i].co);
- if (dist_sq <= merge_threshold_sq) {
- mvert_new[i].flag |= ME_VERT_TMP_TAG;
- tot_doubles += 1;
- copy_v3_v3(mvert_new[i].co, axis_co);
- }
- }
-
- if (tot_doubles != 0) {
- uint tot = totvert * step_tot;
- int *full_doubles_map = MEM_malloc_arrayN(tot, sizeof(int), __func__);
- copy_vn_i(full_doubles_map, (int)tot, -1);
-
- uint tot_doubles_left = tot_doubles;
- for (uint i = 0; i < totvert; i += 1) {
- if (mvert_new[i].flag & ME_VERT_TMP_TAG) {
- int *doubles_map = &full_doubles_map[totvert + i] ;
- for (uint step = 1; step < step_tot; step += 1) {
- *doubles_map = (int)i;
- doubles_map += totvert;
- }
- tot_doubles_left -= 1;
- if (tot_doubles_left == 0) {
- break;
- }
- }
- }
- result = BKE_mesh_merge_verts(result, full_doubles_map, (int)(tot_doubles * (step_tot - 1)), MESH_MERGE_VERTS_DUMP_IF_MAPPED);
- MEM_freeN(full_doubles_map);
- }
- return result;
+ const float merge_threshold_sq = SQUARE(merge_threshold);
+ const bool use_offset = axis_offset != NULL;
+ uint tot_doubles = 0;
+ for (uint i = 0; i < totvert; i += 1) {
+ float axis_co[3];
+ if (use_offset) {
+ float offset_co[3];
+ sub_v3_v3v3(offset_co, mvert_new[i].co, axis_offset);
+ project_v3_v3v3_normalized(axis_co, offset_co, axis_vec);
+ add_v3_v3(axis_co, axis_offset);
+ }
+ else {
+ project_v3_v3v3_normalized(axis_co, mvert_new[i].co, axis_vec);
+ }
+ const float dist_sq = len_squared_v3v3(axis_co, mvert_new[i].co);
+ if (dist_sq <= merge_threshold_sq) {
+ mvert_new[i].flag |= ME_VERT_TMP_TAG;
+ tot_doubles += 1;
+ copy_v3_v3(mvert_new[i].co, axis_co);
+ }
+ }
+
+ if (tot_doubles != 0) {
+ uint tot = totvert * step_tot;
+ int *full_doubles_map = MEM_malloc_arrayN(tot, sizeof(int), __func__);
+ copy_vn_i(full_doubles_map, (int)tot, -1);
+
+ uint tot_doubles_left = tot_doubles;
+ for (uint i = 0; i < totvert; i += 1) {
+ if (mvert_new[i].flag & ME_VERT_TMP_TAG) {
+ int *doubles_map = &full_doubles_map[totvert + i];
+ for (uint step = 1; step < step_tot; step += 1) {
+ *doubles_map = (int)i;
+ doubles_map += totvert;
+ }
+ tot_doubles_left -= 1;
+ if (tot_doubles_left == 0) {
+ break;
+ }
+ }
+ }
+ result = BKE_mesh_merge_verts(result,
+ full_doubles_map,
+ (int)(tot_doubles * (step_tot - 1)),
+ MESH_MERGE_VERTS_DUMP_IF_MAPPED);
+ MEM_freeN(full_doubles_map);
+ }
+ return result;
}
static void initData(ModifierData *md)
{
- ScrewModifierData *ltmd = (ScrewModifierData *) md;
- ltmd->ob_axis = NULL;
- ltmd->angle = (float)(M_PI * 2.0);
- ltmd->axis = 2;
- ltmd->flag = MOD_SCREW_SMOOTH_SHADING;
- ltmd->steps = 16;
- ltmd->render_steps = 16;
- ltmd->iter = 1;
- ltmd->merge_dist = 0.01f;
+ ScrewModifierData *ltmd = (ScrewModifierData *)md;
+ ltmd->ob_axis = NULL;
+ ltmd->angle = (float)(M_PI * 2.0);
+ ltmd->axis = 2;
+ ltmd->flag = MOD_SCREW_SMOOTH_SHADING;
+ ltmd->steps = 16;
+ ltmd->render_steps = 16;
+ ltmd->iter = 1;
+ ltmd->merge_dist = 0.01f;
}
-static Mesh *applyModifier(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *meshData)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *meshData)
{
- Mesh *mesh = meshData;
- Mesh *result;
- ScrewModifierData *ltmd = (ScrewModifierData *) md;
- const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER) != 0;
-
- int *origindex;
- int mpoly_index = 0;
- unsigned int step;
- unsigned int i, j;
- unsigned int i1, i2;
- unsigned int step_tot = use_render_params ? ltmd->render_steps : ltmd->steps;
- const bool do_flip = (ltmd->flag & MOD_SCREW_NORMAL_FLIP) != 0;
-
- const int quad_ord[4] = {
- do_flip ? 3 : 0,
- do_flip ? 2 : 1,
- do_flip ? 1 : 2,
- do_flip ? 0 : 3,
- };
- const int quad_ord_ofs[4] = {
- do_flip ? 2 : 0,
- 1,
- do_flip ? 0 : 2,
- 3,
- };
-
- unsigned int maxVerts = 0, maxEdges = 0, maxPolys = 0;
- const unsigned int totvert = (unsigned int)mesh->totvert;
- const unsigned int totedge = (unsigned int)mesh->totedge;
- const unsigned int totpoly = (unsigned int)mesh->totpoly;
-
- unsigned int *edge_poly_map = NULL; /* orig edge to orig poly */
- unsigned int *vert_loop_map = NULL; /* orig vert to orig loop */
-
- /* UV Coords */
- const unsigned int mloopuv_layers_tot = (unsigned int)CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV);
- MLoopUV **mloopuv_layers = BLI_array_alloca(mloopuv_layers, mloopuv_layers_tot);
- float uv_u_scale;
- float uv_v_minmax[2] = {FLT_MAX, -FLT_MAX};
- float uv_v_range_inv;
- float uv_axis_plane[4];
-
- char axis_char = 'X';
- bool close;
- float angle = ltmd->angle;
- float screw_ofs = ltmd->screw_ofs;
- float axis_vec[3] = {0.0f, 0.0f, 0.0f};
- float tmp_vec1[3], tmp_vec2[3];
- float mat3[3][3];
- /* transform the coords by an object relative to this objects transformation */
- float mtx_tx[4][4];
- float mtx_tx_inv[4][4]; /* inverted */
- float mtx_tmp_a[4][4];
-
- unsigned int vc_tot_linked = 0;
- short other_axis_1, other_axis_2;
- const float *tmpf1, *tmpf2;
-
- unsigned int edge_offset;
-
- MPoly *mpoly_orig, *mpoly_new, *mp_new;
- MLoop *mloop_orig, *mloop_new, *ml_new;
- MEdge *medge_orig, *med_orig, *med_new, *med_new_firstloop, *medge_new;
- MVert *mvert_new, *mvert_orig, *mv_orig, *mv_new, *mv_new_base;
-
- Object *ob_axis = ltmd->ob_axis;
-
- ScrewVertConnect *vc, *vc_tmp, *vert_connect = NULL;
-
- const char mpoly_flag = (ltmd->flag & MOD_SCREW_SMOOTH_SHADING) ? ME_SMOOTH : 0;
-
- /* don't do anything? */
- if (!totvert)
- return BKE_mesh_new_nomain_from_template(mesh, 0, 0, 0, 0, 0);
-
- switch (ltmd->axis) {
- case 0:
- other_axis_1 = 1;
- other_axis_2 = 2;
- break;
- case 1:
- other_axis_1 = 0;
- other_axis_2 = 2;
- break;
- default: /* 2, use default to quiet warnings */
- other_axis_1 = 0;
- other_axis_2 = 1;
- break;
- }
-
- axis_vec[ltmd->axis] = 1.0f;
-
- if (ob_axis != NULL) {
- /* calc the matrix relative to the axis object */
- invert_m4_m4(mtx_tmp_a, ctx->object->obmat);
- copy_m4_m4(mtx_tx_inv, ob_axis->obmat);
- mul_m4_m4m4(mtx_tx, mtx_tmp_a, mtx_tx_inv);
-
- /* calc the axis vec */
- mul_mat3_m4_v3(mtx_tx, axis_vec); /* only rotation component */
- normalize_v3(axis_vec);
-
- /* screw */
- if (ltmd->flag & MOD_SCREW_OBJECT_OFFSET) {
- /* find the offset along this axis relative to this objects matrix */
- float totlen = len_v3(mtx_tx[3]);
-
- if (totlen != 0.0f) {
- float zero[3] = {0.0f, 0.0f, 0.0f};
- float cp[3];
- screw_ofs = closest_to_line_v3(cp, mtx_tx[3], zero, axis_vec);
- }
- else {
- screw_ofs = 0.0f;
- }
- }
-
- /* angle */
-
-#if 0 /* can't include this, not predictable enough, though quite fun. */
- if (ltmd->flag & MOD_SCREW_OBJECT_ANGLE) {
- float mtx3_tx[3][3];
- copy_m3_m4(mtx3_tx, mtx_tx);
-
- float vec[3] = {0, 1, 0};
- float cross1[3];
- float cross2[3];
- cross_v3_v3v3(cross1, vec, axis_vec);
-
- mul_v3_m3v3(cross2, mtx3_tx, cross1);
- {
- float c1[3];
- float c2[3];
- float axis_tmp[3];
-
- cross_v3_v3v3(c1, cross2, axis_vec);
- cross_v3_v3v3(c2, axis_vec, c1);
-
-
- angle = angle_v3v3(cross1, c2);
-
- cross_v3_v3v3(axis_tmp, cross1, c2);
- normalize_v3(axis_tmp);
-
- if (len_v3v3(axis_tmp, axis_vec) > 1.0f)
- angle = -angle;
-
- }
- }
+ Mesh *mesh = meshData;
+ Mesh *result;
+ ScrewModifierData *ltmd = (ScrewModifierData *)md;
+ const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER) != 0;
+
+ int *origindex;
+ int mpoly_index = 0;
+ unsigned int step;
+ unsigned int i, j;
+ unsigned int i1, i2;
+ unsigned int step_tot = use_render_params ? ltmd->render_steps : ltmd->steps;
+ const bool do_flip = (ltmd->flag & MOD_SCREW_NORMAL_FLIP) != 0;
+
+ const int quad_ord[4] = {
+ do_flip ? 3 : 0,
+ do_flip ? 2 : 1,
+ do_flip ? 1 : 2,
+ do_flip ? 0 : 3,
+ };
+ const int quad_ord_ofs[4] = {
+ do_flip ? 2 : 0,
+ 1,
+ do_flip ? 0 : 2,
+ 3,
+ };
+
+ unsigned int maxVerts = 0, maxEdges = 0, maxPolys = 0;
+ const unsigned int totvert = (unsigned int)mesh->totvert;
+ const unsigned int totedge = (unsigned int)mesh->totedge;
+ const unsigned int totpoly = (unsigned int)mesh->totpoly;
+
+ unsigned int *edge_poly_map = NULL; /* orig edge to orig poly */
+ unsigned int *vert_loop_map = NULL; /* orig vert to orig loop */
+
+ /* UV Coords */
+ const unsigned int mloopuv_layers_tot = (unsigned int)CustomData_number_of_layers(&mesh->ldata,
+ CD_MLOOPUV);
+ MLoopUV **mloopuv_layers = BLI_array_alloca(mloopuv_layers, mloopuv_layers_tot);
+ float uv_u_scale;
+ float uv_v_minmax[2] = {FLT_MAX, -FLT_MAX};
+ float uv_v_range_inv;
+ float uv_axis_plane[4];
+
+ char axis_char = 'X';
+ bool close;
+ float angle = ltmd->angle;
+ float screw_ofs = ltmd->screw_ofs;
+ float axis_vec[3] = {0.0f, 0.0f, 0.0f};
+ float tmp_vec1[3], tmp_vec2[3];
+ float mat3[3][3];
+ /* transform the coords by an object relative to this objects transformation */
+ float mtx_tx[4][4];
+ float mtx_tx_inv[4][4]; /* inverted */
+ float mtx_tmp_a[4][4];
+
+ unsigned int vc_tot_linked = 0;
+ short other_axis_1, other_axis_2;
+ const float *tmpf1, *tmpf2;
+
+ unsigned int edge_offset;
+
+ MPoly *mpoly_orig, *mpoly_new, *mp_new;
+ MLoop *mloop_orig, *mloop_new, *ml_new;
+ MEdge *medge_orig, *med_orig, *med_new, *med_new_firstloop, *medge_new;
+ MVert *mvert_new, *mvert_orig, *mv_orig, *mv_new, *mv_new_base;
+
+ Object *ob_axis = ltmd->ob_axis;
+
+ ScrewVertConnect *vc, *vc_tmp, *vert_connect = NULL;
+
+ const char mpoly_flag = (ltmd->flag & MOD_SCREW_SMOOTH_SHADING) ? ME_SMOOTH : 0;
+
+ /* don't do anything? */
+ if (!totvert)
+ return BKE_mesh_new_nomain_from_template(mesh, 0, 0, 0, 0, 0);
+
+ switch (ltmd->axis) {
+ case 0:
+ other_axis_1 = 1;
+ other_axis_2 = 2;
+ break;
+ case 1:
+ other_axis_1 = 0;
+ other_axis_2 = 2;
+ break;
+ default: /* 2, use default to quiet warnings */
+ other_axis_1 = 0;
+ other_axis_2 = 1;
+ break;
+ }
+
+ axis_vec[ltmd->axis] = 1.0f;
+
+ if (ob_axis != NULL) {
+ /* calc the matrix relative to the axis object */
+ invert_m4_m4(mtx_tmp_a, ctx->object->obmat);
+ copy_m4_m4(mtx_tx_inv, ob_axis->obmat);
+ mul_m4_m4m4(mtx_tx, mtx_tmp_a, mtx_tx_inv);
+
+ /* calc the axis vec */
+ mul_mat3_m4_v3(mtx_tx, axis_vec); /* only rotation component */
+ normalize_v3(axis_vec);
+
+ /* screw */
+ if (ltmd->flag & MOD_SCREW_OBJECT_OFFSET) {
+ /* find the offset along this axis relative to this objects matrix */
+ float totlen = len_v3(mtx_tx[3]);
+
+ if (totlen != 0.0f) {
+ float zero[3] = {0.0f, 0.0f, 0.0f};
+ float cp[3];
+ screw_ofs = closest_to_line_v3(cp, mtx_tx[3], zero, axis_vec);
+ }
+ else {
+ screw_ofs = 0.0f;
+ }
+ }
+
+ /* angle */
+
+#if 0 /* can't include this, not predictable enough, though quite fun. */
+ if (ltmd->flag & MOD_SCREW_OBJECT_ANGLE) {
+ float mtx3_tx[3][3];
+ copy_m3_m4(mtx3_tx, mtx_tx);
+
+ float vec[3] = {0, 1, 0};
+ float cross1[3];
+ float cross2[3];
+ cross_v3_v3v3(cross1, vec, axis_vec);
+
+ mul_v3_m3v3(cross2, mtx3_tx, cross1);
+ {
+ float c1[3];
+ float c2[3];
+ float axis_tmp[3];
+
+ cross_v3_v3v3(c1, cross2, axis_vec);
+ cross_v3_v3v3(c2, axis_vec, c1);
+
+
+ angle = angle_v3v3(cross1, c2);
+
+ cross_v3_v3v3(axis_tmp, cross1, c2);
+ normalize_v3(axis_tmp);
+
+ if (len_v3v3(axis_tmp, axis_vec) > 1.0f)
+ angle = -angle;
+
+ }
+ }
#endif
- }
- else {
- /* exis char is used by i_rotate*/
- axis_char = (char)(axis_char + ltmd->axis); /* 'X' + axis */
-
- /* useful to be able to use the axis vec in some cases still */
- zero_v3(axis_vec);
- axis_vec[ltmd->axis] = 1.0f;
- }
-
- /* apply the multiplier */
- angle *= (float)ltmd->iter;
- screw_ofs *= (float)ltmd->iter;
- uv_u_scale = 1.0f / (float)(step_tot);
-
- /* multiplying the steps is a bit tricky, this works best */
- step_tot = ((step_tot + 1) * ltmd->iter) - (ltmd->iter - 1);
-
- /* will the screw be closed?
- * Note! smaller then FLT_EPSILON * 100 gives problems with float precision so its never closed. */
- if (fabsf(screw_ofs) <= (FLT_EPSILON * 100.0f) &&
- fabsf(fabsf(angle) - ((float)M_PI * 2.0f)) <= (FLT_EPSILON * 100.0f))
- {
- close = 1;
- step_tot--;
- if (step_tot < 3) step_tot = 3;
-
- maxVerts = totvert * step_tot; /* -1 because we're joining back up */
- maxEdges = (totvert * step_tot) + /* these are the edges between new verts */
- (totedge * step_tot); /* -1 because vert edges join */
- maxPolys = totedge * step_tot;
-
- screw_ofs = 0.0f;
- }
- else {
- close = 0;
- if (step_tot < 3) step_tot = 3;
-
- maxVerts = totvert * step_tot; /* -1 because we're joining back up */
- maxEdges = (totvert * (step_tot - 1)) + /* these are the edges between new verts */
- (totedge * step_tot); /* -1 because vert edges join */
- maxPolys = totedge * (step_tot - 1);
- }
-
- if ((ltmd->flag & MOD_SCREW_UV_STRETCH_U) == 0) {
- uv_u_scale = (uv_u_scale / (float)ltmd->iter) * (angle / ((float)M_PI * 2.0f));
- }
-
- result = BKE_mesh_new_nomain_from_template(mesh, (int)maxVerts, (int)maxEdges, 0, (int)maxPolys * 4, (int)maxPolys);
-
- /* copy verts from mesh */
- mvert_orig = mesh->mvert;
- medge_orig = mesh->medge;
-
- mvert_new = result->mvert;
- mpoly_new = result->mpoly;
- mloop_new = result->mloop;
- medge_new = result->medge;
-
- if (!CustomData_has_layer(&result->pdata, CD_ORIGINDEX)) {
- CustomData_add_layer(&result->pdata, CD_ORIGINDEX, CD_CALLOC, NULL, (int)maxPolys);
- }
-
- origindex = CustomData_get_layer(&result->pdata, CD_ORIGINDEX);
-
- CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)totvert);
-
- if (mloopuv_layers_tot) {
- float zero_co[3] = {0};
- plane_from_point_normal_v3(uv_axis_plane, zero_co, axis_vec);
- }
-
- if (mloopuv_layers_tot) {
- unsigned int uv_lay;
- for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) {
- mloopuv_layers[uv_lay] = CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, (int)uv_lay);
- }
-
- if (ltmd->flag & MOD_SCREW_UV_STRETCH_V) {
- for (i = 0, mv_orig = mvert_orig; i < totvert; i++, mv_orig++) {
- const float v = dist_signed_squared_to_plane_v3(mv_orig->co, uv_axis_plane);
- uv_v_minmax[0] = min_ff(v, uv_v_minmax[0]);
- uv_v_minmax[1] = max_ff(v, uv_v_minmax[1]);
- }
- uv_v_minmax[0] = sqrtf_signed(uv_v_minmax[0]);
- uv_v_minmax[1] = sqrtf_signed(uv_v_minmax[1]);
- }
-
- uv_v_range_inv = uv_v_minmax[1] - uv_v_minmax[0];
- uv_v_range_inv = uv_v_range_inv ? 1.0f / uv_v_range_inv : 0.0f;
- }
-
- /* Set the locations of the first set of verts */
-
- mv_new = mvert_new;
- mv_orig = mvert_orig;
-
- /* Copy the first set of edges */
- med_orig = medge_orig;
- med_new = medge_new;
- for (i = 0; i < totedge; i++, med_orig++, med_new++) {
- med_new->v1 = med_orig->v1;
- med_new->v2 = med_orig->v2;
- med_new->crease = med_orig->crease;
- med_new->flag = med_orig->flag & ~ME_LOOSEEDGE;
- }
-
- /* build polygon -> edge map */
- if (totpoly) {
- MPoly *mp_orig;
-
- mpoly_orig = mesh->mpoly;
- mloop_orig = mesh->mloop;
- edge_poly_map = MEM_malloc_arrayN(totedge, sizeof(*edge_poly_map), __func__);
- memset(edge_poly_map, 0xff, sizeof(*edge_poly_map) * totedge);
-
- vert_loop_map = MEM_malloc_arrayN(totvert, sizeof(*vert_loop_map), __func__);
- memset(vert_loop_map, 0xff, sizeof(*vert_loop_map) * totvert);
-
- for (i = 0, mp_orig = mpoly_orig; i < totpoly; i++, mp_orig++) {
- unsigned int loopstart = (unsigned int)mp_orig->loopstart;
- unsigned int loopend = loopstart + (unsigned int)mp_orig->totloop;
-
- MLoop *ml_orig = &mloop_orig[loopstart];
- unsigned int k;
- for (k = loopstart; k < loopend; k++, ml_orig++) {
- edge_poly_map[ml_orig->e] = i;
- vert_loop_map[ml_orig->v] = k;
-
- /* also order edges based on faces */
- if (medge_new[ml_orig->e].v1 != ml_orig->v) {
- SWAP(unsigned int, medge_new[ml_orig->e].v1, medge_new[ml_orig->e].v2);
- }
- }
- }
- }
-
- if (ltmd->flag & MOD_SCREW_NORMAL_CALC) {
- /*
- * Normal Calculation (for face flipping)
- * Sort edge verts for correct face flipping
- * NOT REALLY NEEDED but face flipping is nice.
- *
- * */
-
-
- /* Notice!
- *
- * Since we are only ordering the edges here it can avoid mallocing the
- * extra space by abusing the vert array before its filled with new verts.
- * The new array for vert_connect must be at least sizeof(ScrewVertConnect) * totvert
- * and the size of our resulting meshes array is sizeof(MVert) * totvert * 3
- * so its safe to use the second 2 thrids of MVert the array for vert_connect,
- * just make sure ScrewVertConnect struct is no more than twice as big as MVert,
- * at the moment there is no chance of that being a problem,
- * unless MVert becomes half its current size.
- *
- * once the edges are ordered, vert_connect is not needed and it can be used for verts
- *
- * This makes the modifier faster with one less alloc.
- */
-
- vert_connect = MEM_malloc_arrayN(totvert, sizeof(ScrewVertConnect), "ScrewVertConnect");
- //vert_connect = (ScrewVertConnect *) &medge_new[totvert]; /* skip the first slice of verts */
- vc = vert_connect;
-
- /* Copy Vert Locations */
- /* - We can do this in a later loop - only do here if no normal calc */
- if (!totedge) {
- for (i = 0; i < totvert; i++, mv_orig++, mv_new++) {
- copy_v3_v3(mv_new->co, mv_orig->co);
- normalize_v3_v3(vc->no, mv_new->co); /* no edges- this is really a dummy normal */
- }
- }
- else {
- /*printf("\n\n\n\n\nStarting Modifier\n");*/
- /* set edge users */
- med_new = medge_new;
- mv_new = mvert_new;
-
- if (ob_axis != NULL) {
- /*mtx_tx is initialized early on */
- for (i = 0; i < totvert; i++, mv_new++, mv_orig++, vc++) {
- vc->co[0] = mv_new->co[0] = mv_orig->co[0];
- vc->co[1] = mv_new->co[1] = mv_orig->co[1];
- vc->co[2] = mv_new->co[2] = mv_orig->co[2];
-
- vc->flag = 0;
- vc->e[0] = vc->e[1] = NULL;
- vc->v[0] = vc->v[1] = SV_UNUSED;
-
- mul_m4_v3(mtx_tx, vc->co);
- /* length in 2d, don't sqrt because this is only for comparison */
- vc->dist = vc->co[other_axis_1] * vc->co[other_axis_1] +
- vc->co[other_axis_2] * vc->co[other_axis_2];
-
- /* printf("location %f %f %f -- %f\n", vc->co[0], vc->co[1], vc->co[2], vc->dist);*/
- }
- }
- else {
- for (i = 0; i < totvert; i++, mv_new++, mv_orig++, vc++) {
- vc->co[0] = mv_new->co[0] = mv_orig->co[0];
- vc->co[1] = mv_new->co[1] = mv_orig->co[1];
- vc->co[2] = mv_new->co[2] = mv_orig->co[2];
-
- vc->flag = 0;
- vc->e[0] = vc->e[1] = NULL;
- vc->v[0] = vc->v[1] = SV_UNUSED;
-
- /* length in 2d, don't sqrt because this is only for comparison */
- vc->dist = vc->co[other_axis_1] * vc->co[other_axis_1] +
- vc->co[other_axis_2] * vc->co[other_axis_2];
-
- /* printf("location %f %f %f -- %f\n", vc->co[0], vc->co[1], vc->co[2], vc->dist);*/
- }
- }
-
- /* this loop builds connectivity info for verts */
- for (i = 0; i < totedge; i++, med_new++) {
- vc = &vert_connect[med_new->v1];
-
- if (vc->v[0] == SV_UNUSED) { /* unused */
- vc->v[0] = med_new->v2;
- vc->e[0] = med_new;
- }
- else if (vc->v[1] == SV_UNUSED) {
- vc->v[1] = med_new->v2;
- vc->e[1] = med_new;
- }
- else {
- vc->v[0] = vc->v[1] = SV_INVALID; /* error value - don't use, 3 edges on vert */
- }
-
- vc = &vert_connect[med_new->v2];
-
- /* same as above but swap v1/2 */
- if (vc->v[0] == SV_UNUSED) { /* unused */
- vc->v[0] = med_new->v1;
- vc->e[0] = med_new;
- }
- else if (vc->v[1] == SV_UNUSED) {
- vc->v[1] = med_new->v1;
- vc->e[1] = med_new;
- }
- else {
- vc->v[0] = vc->v[1] = SV_INVALID; /* error value - don't use, 3 edges on vert */
- }
- }
-
- /* find the first vert */
- vc = vert_connect;
- for (i = 0; i < totvert; i++, vc++) {
- /* Now do search for connected verts, order all edges and flip them
- * so resulting faces are flipped the right way */
- vc_tot_linked = 0; /* count the number of linked verts for this loop */
- if (vc->flag == 0) {
- unsigned int v_best = SV_UNUSED, ed_loop_closed = 0; /* vert and vert new */
- ScrewVertIter lt_iter;
- float fl = -1.0f;
-
- /* compiler complains if not initialized, but it should be initialized below */
- bool ed_loop_flip = false;
-
- /*printf("Loop on connected vert: %i\n", i);*/
-
- for (j = 0; j < 2; j++) {
- /*printf("\tSide: %i\n", j);*/
- screwvert_iter_init(&lt_iter, vert_connect, i, j);
- if (j == 1) {
- screwvert_iter_step(&lt_iter);
- }
- while (lt_iter.v_poin) {
- /*printf("\t\tVERT: %i\n", lt_iter.v);*/
- if (lt_iter.v_poin->flag) {
- /*printf("\t\t\tBreaking Found end\n");*/
- //endpoints[0] = endpoints[1] = SV_UNUSED;
- ed_loop_closed = 1; /* circle */
- break;
- }
- lt_iter.v_poin->flag = 1;
- vc_tot_linked++;
- /*printf("Testing 2 floats %f : %f\n", fl, lt_iter.v_poin->dist);*/
- if (fl <= lt_iter.v_poin->dist) {
- fl = lt_iter.v_poin->dist;
- v_best = lt_iter.v;
- /*printf("\t\t\tVERT BEST: %i\n", v_best);*/
- }
- screwvert_iter_step(&lt_iter);
- if (!lt_iter.v_poin) {
- /*printf("\t\t\tFound End Also Num %i\n", j);*/
- /*endpoints[j] = lt_iter.v_other;*/ /* other is still valid */
- break;
- }
- }
- }
-
- /* now we have a collection of used edges. flip their edges the right way*/
- /*if (v_best != SV_UNUSED) - */
-
- /*printf("Done Looking - vc_tot_linked: %i\n", vc_tot_linked);*/
-
- if (vc_tot_linked > 1) {
- float vf_1, vf_2, vf_best;
-
- vc_tmp = &vert_connect[v_best];
-
- tmpf1 = vert_connect[vc_tmp->v[0]].co;
- tmpf2 = vert_connect[vc_tmp->v[1]].co;
-
-
- /* edge connects on each side! */
- if (SV_IS_VALID(vc_tmp->v[0]) && SV_IS_VALID(vc_tmp->v[1])) {
- /*printf("Verts on each side (%i %i)\n", vc_tmp->v[0], vc_tmp->v[1]);*/
- /* find out which is higher */
-
- vf_1 = tmpf1[ltmd->axis];
- vf_2 = tmpf2[ltmd->axis];
- vf_best = vc_tmp->co[ltmd->axis];
-
- if (vf_1 < vf_best && vf_best < vf_2) {
- ed_loop_flip = 0;
- }
- else if (vf_1 > vf_best && vf_best > vf_2) {
- ed_loop_flip = 1;
- }
- else {
- /* not so simple to work out which edge is higher */
- sub_v3_v3v3(tmp_vec1, tmpf1, vc_tmp->co);
- sub_v3_v3v3(tmp_vec2, tmpf2, vc_tmp->co);
- normalize_v3(tmp_vec1);
- normalize_v3(tmp_vec2);
-
- if (tmp_vec1[ltmd->axis] < tmp_vec2[ltmd->axis]) {
- ed_loop_flip = 1;
- }
- else {
- ed_loop_flip = 0;
- }
- }
- }
- else if (SV_IS_VALID(vc_tmp->v[0])) { /*vertex only connected on 1 side */
- /*printf("Verts on ONE side (%i %i)\n", vc_tmp->v[0], vc_tmp->v[1]);*/
- if (tmpf1[ltmd->axis] < vc_tmp->co[ltmd->axis]) { /* best is above */
- ed_loop_flip = 1;
- }
- else { /* best is below or even... in even case we can't know what to do. */
- ed_loop_flip = 0;
- }
-
- }
+ }
+ else {
+ /* exis char is used by i_rotate*/
+ axis_char = (char)(axis_char + ltmd->axis); /* 'X' + axis */
+
+ /* useful to be able to use the axis vec in some cases still */
+ zero_v3(axis_vec);
+ axis_vec[ltmd->axis] = 1.0f;
+ }
+
+ /* apply the multiplier */
+ angle *= (float)ltmd->iter;
+ screw_ofs *= (float)ltmd->iter;
+ uv_u_scale = 1.0f / (float)(step_tot);
+
+ /* multiplying the steps is a bit tricky, this works best */
+ step_tot = ((step_tot + 1) * ltmd->iter) - (ltmd->iter - 1);
+
+ /* will the screw be closed?
+ * Note! smaller then FLT_EPSILON * 100 gives problems with float precision so its never closed. */
+ if (fabsf(screw_ofs) <= (FLT_EPSILON * 100.0f) &&
+ fabsf(fabsf(angle) - ((float)M_PI * 2.0f)) <= (FLT_EPSILON * 100.0f)) {
+ close = 1;
+ step_tot--;
+ if (step_tot < 3)
+ step_tot = 3;
+
+ maxVerts = totvert * step_tot; /* -1 because we're joining back up */
+ maxEdges = (totvert * step_tot) + /* these are the edges between new verts */
+ (totedge * step_tot); /* -1 because vert edges join */
+ maxPolys = totedge * step_tot;
+
+ screw_ofs = 0.0f;
+ }
+ else {
+ close = 0;
+ if (step_tot < 3)
+ step_tot = 3;
+
+ maxVerts = totvert * step_tot; /* -1 because we're joining back up */
+ maxEdges = (totvert * (step_tot - 1)) + /* these are the edges between new verts */
+ (totedge * step_tot); /* -1 because vert edges join */
+ maxPolys = totedge * (step_tot - 1);
+ }
+
+ if ((ltmd->flag & MOD_SCREW_UV_STRETCH_U) == 0) {
+ uv_u_scale = (uv_u_scale / (float)ltmd->iter) * (angle / ((float)M_PI * 2.0f));
+ }
+
+ result = BKE_mesh_new_nomain_from_template(
+ mesh, (int)maxVerts, (int)maxEdges, 0, (int)maxPolys * 4, (int)maxPolys);
+
+ /* copy verts from mesh */
+ mvert_orig = mesh->mvert;
+ medge_orig = mesh->medge;
+
+ mvert_new = result->mvert;
+ mpoly_new = result->mpoly;
+ mloop_new = result->mloop;
+ medge_new = result->medge;
+
+ if (!CustomData_has_layer(&result->pdata, CD_ORIGINDEX)) {
+ CustomData_add_layer(&result->pdata, CD_ORIGINDEX, CD_CALLOC, NULL, (int)maxPolys);
+ }
+
+ origindex = CustomData_get_layer(&result->pdata, CD_ORIGINDEX);
+
+ CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)totvert);
+
+ if (mloopuv_layers_tot) {
+ float zero_co[3] = {0};
+ plane_from_point_normal_v3(uv_axis_plane, zero_co, axis_vec);
+ }
+
+ if (mloopuv_layers_tot) {
+ unsigned int uv_lay;
+ for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) {
+ mloopuv_layers[uv_lay] = CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, (int)uv_lay);
+ }
+
+ if (ltmd->flag & MOD_SCREW_UV_STRETCH_V) {
+ for (i = 0, mv_orig = mvert_orig; i < totvert; i++, mv_orig++) {
+ const float v = dist_signed_squared_to_plane_v3(mv_orig->co, uv_axis_plane);
+ uv_v_minmax[0] = min_ff(v, uv_v_minmax[0]);
+ uv_v_minmax[1] = max_ff(v, uv_v_minmax[1]);
+ }
+ uv_v_minmax[0] = sqrtf_signed(uv_v_minmax[0]);
+ uv_v_minmax[1] = sqrtf_signed(uv_v_minmax[1]);
+ }
+
+ uv_v_range_inv = uv_v_minmax[1] - uv_v_minmax[0];
+ uv_v_range_inv = uv_v_range_inv ? 1.0f / uv_v_range_inv : 0.0f;
+ }
+
+ /* Set the locations of the first set of verts */
+
+ mv_new = mvert_new;
+ mv_orig = mvert_orig;
+
+ /* Copy the first set of edges */
+ med_orig = medge_orig;
+ med_new = medge_new;
+ for (i = 0; i < totedge; i++, med_orig++, med_new++) {
+ med_new->v1 = med_orig->v1;
+ med_new->v2 = med_orig->v2;
+ med_new->crease = med_orig->crease;
+ med_new->flag = med_orig->flag & ~ME_LOOSEEDGE;
+ }
+
+ /* build polygon -> edge map */
+ if (totpoly) {
+ MPoly *mp_orig;
+
+ mpoly_orig = mesh->mpoly;
+ mloop_orig = mesh->mloop;
+ edge_poly_map = MEM_malloc_arrayN(totedge, sizeof(*edge_poly_map), __func__);
+ memset(edge_poly_map, 0xff, sizeof(*edge_poly_map) * totedge);
+
+ vert_loop_map = MEM_malloc_arrayN(totvert, sizeof(*vert_loop_map), __func__);
+ memset(vert_loop_map, 0xff, sizeof(*vert_loop_map) * totvert);
+
+ for (i = 0, mp_orig = mpoly_orig; i < totpoly; i++, mp_orig++) {
+ unsigned int loopstart = (unsigned int)mp_orig->loopstart;
+ unsigned int loopend = loopstart + (unsigned int)mp_orig->totloop;
+
+ MLoop *ml_orig = &mloop_orig[loopstart];
+ unsigned int k;
+ for (k = loopstart; k < loopend; k++, ml_orig++) {
+ edge_poly_map[ml_orig->e] = i;
+ vert_loop_map[ml_orig->v] = k;
+
+ /* also order edges based on faces */
+ if (medge_new[ml_orig->e].v1 != ml_orig->v) {
+ SWAP(unsigned int, medge_new[ml_orig->e].v1, medge_new[ml_orig->e].v2);
+ }
+ }
+ }
+ }
+
+ if (ltmd->flag & MOD_SCREW_NORMAL_CALC) {
+ /*
+ * Normal Calculation (for face flipping)
+ * Sort edge verts for correct face flipping
+ * NOT REALLY NEEDED but face flipping is nice.
+ *
+ * */
+
+ /* Notice!
+ *
+ * Since we are only ordering the edges here it can avoid mallocing the
+ * extra space by abusing the vert array before its filled with new verts.
+ * The new array for vert_connect must be at least sizeof(ScrewVertConnect) * totvert
+ * and the size of our resulting meshes array is sizeof(MVert) * totvert * 3
+ * so its safe to use the second 2 thrids of MVert the array for vert_connect,
+ * just make sure ScrewVertConnect struct is no more than twice as big as MVert,
+ * at the moment there is no chance of that being a problem,
+ * unless MVert becomes half its current size.
+ *
+ * once the edges are ordered, vert_connect is not needed and it can be used for verts
+ *
+ * This makes the modifier faster with one less alloc.
+ */
+
+ vert_connect = MEM_malloc_arrayN(totvert, sizeof(ScrewVertConnect), "ScrewVertConnect");
+ //vert_connect = (ScrewVertConnect *) &medge_new[totvert]; /* skip the first slice of verts */
+ vc = vert_connect;
+
+ /* Copy Vert Locations */
+ /* - We can do this in a later loop - only do here if no normal calc */
+ if (!totedge) {
+ for (i = 0; i < totvert; i++, mv_orig++, mv_new++) {
+ copy_v3_v3(mv_new->co, mv_orig->co);
+ normalize_v3_v3(vc->no, mv_new->co); /* no edges- this is really a dummy normal */
+ }
+ }
+ else {
+ /*printf("\n\n\n\n\nStarting Modifier\n");*/
+ /* set edge users */
+ med_new = medge_new;
+ mv_new = mvert_new;
+
+ if (ob_axis != NULL) {
+ /*mtx_tx is initialized early on */
+ for (i = 0; i < totvert; i++, mv_new++, mv_orig++, vc++) {
+ vc->co[0] = mv_new->co[0] = mv_orig->co[0];
+ vc->co[1] = mv_new->co[1] = mv_orig->co[1];
+ vc->co[2] = mv_new->co[2] = mv_orig->co[2];
+
+ vc->flag = 0;
+ vc->e[0] = vc->e[1] = NULL;
+ vc->v[0] = vc->v[1] = SV_UNUSED;
+
+ mul_m4_v3(mtx_tx, vc->co);
+ /* length in 2d, don't sqrt because this is only for comparison */
+ vc->dist = vc->co[other_axis_1] * vc->co[other_axis_1] +
+ vc->co[other_axis_2] * vc->co[other_axis_2];
+
+ /* printf("location %f %f %f -- %f\n", vc->co[0], vc->co[1], vc->co[2], vc->dist);*/
+ }
+ }
+ else {
+ for (i = 0; i < totvert; i++, mv_new++, mv_orig++, vc++) {
+ vc->co[0] = mv_new->co[0] = mv_orig->co[0];
+ vc->co[1] = mv_new->co[1] = mv_orig->co[1];
+ vc->co[2] = mv_new->co[2] = mv_orig->co[2];
+
+ vc->flag = 0;
+ vc->e[0] = vc->e[1] = NULL;
+ vc->v[0] = vc->v[1] = SV_UNUSED;
+
+ /* length in 2d, don't sqrt because this is only for comparison */
+ vc->dist = vc->co[other_axis_1] * vc->co[other_axis_1] +
+ vc->co[other_axis_2] * vc->co[other_axis_2];
+
+ /* printf("location %f %f %f -- %f\n", vc->co[0], vc->co[1], vc->co[2], vc->dist);*/
+ }
+ }
+
+ /* this loop builds connectivity info for verts */
+ for (i = 0; i < totedge; i++, med_new++) {
+ vc = &vert_connect[med_new->v1];
+
+ if (vc->v[0] == SV_UNUSED) { /* unused */
+ vc->v[0] = med_new->v2;
+ vc->e[0] = med_new;
+ }
+ else if (vc->v[1] == SV_UNUSED) {
+ vc->v[1] = med_new->v2;
+ vc->e[1] = med_new;
+ }
+ else {
+ vc->v[0] = vc->v[1] = SV_INVALID; /* error value - don't use, 3 edges on vert */
+ }
+
+ vc = &vert_connect[med_new->v2];
+
+ /* same as above but swap v1/2 */
+ if (vc->v[0] == SV_UNUSED) { /* unused */
+ vc->v[0] = med_new->v1;
+ vc->e[0] = med_new;
+ }
+ else if (vc->v[1] == SV_UNUSED) {
+ vc->v[1] = med_new->v1;
+ vc->e[1] = med_new;
+ }
+ else {
+ vc->v[0] = vc->v[1] = SV_INVALID; /* error value - don't use, 3 edges on vert */
+ }
+ }
+
+ /* find the first vert */
+ vc = vert_connect;
+ for (i = 0; i < totvert; i++, vc++) {
+ /* Now do search for connected verts, order all edges and flip them
+ * so resulting faces are flipped the right way */
+ vc_tot_linked = 0; /* count the number of linked verts for this loop */
+ if (vc->flag == 0) {
+ unsigned int v_best = SV_UNUSED, ed_loop_closed = 0; /* vert and vert new */
+ ScrewVertIter lt_iter;
+ float fl = -1.0f;
+
+ /* compiler complains if not initialized, but it should be initialized below */
+ bool ed_loop_flip = false;
+
+ /*printf("Loop on connected vert: %i\n", i);*/
+
+ for (j = 0; j < 2; j++) {
+ /*printf("\tSide: %i\n", j);*/
+ screwvert_iter_init(&lt_iter, vert_connect, i, j);
+ if (j == 1) {
+ screwvert_iter_step(&lt_iter);
+ }
+ while (lt_iter.v_poin) {
+ /*printf("\t\tVERT: %i\n", lt_iter.v);*/
+ if (lt_iter.v_poin->flag) {
+ /*printf("\t\t\tBreaking Found end\n");*/
+ //endpoints[0] = endpoints[1] = SV_UNUSED;
+ ed_loop_closed = 1; /* circle */
+ break;
+ }
+ lt_iter.v_poin->flag = 1;
+ vc_tot_linked++;
+ /*printf("Testing 2 floats %f : %f\n", fl, lt_iter.v_poin->dist);*/
+ if (fl <= lt_iter.v_poin->dist) {
+ fl = lt_iter.v_poin->dist;
+ v_best = lt_iter.v;
+ /*printf("\t\t\tVERT BEST: %i\n", v_best);*/
+ }
+ screwvert_iter_step(&lt_iter);
+ if (!lt_iter.v_poin) {
+ /*printf("\t\t\tFound End Also Num %i\n", j);*/
+ /*endpoints[j] = lt_iter.v_other;*/ /* other is still valid */
+ break;
+ }
+ }
+ }
+
+ /* now we have a collection of used edges. flip their edges the right way*/
+ /*if (v_best != SV_UNUSED) - */
+
+ /*printf("Done Looking - vc_tot_linked: %i\n", vc_tot_linked);*/
+
+ if (vc_tot_linked > 1) {
+ float vf_1, vf_2, vf_best;
+
+ vc_tmp = &vert_connect[v_best];
+
+ tmpf1 = vert_connect[vc_tmp->v[0]].co;
+ tmpf2 = vert_connect[vc_tmp->v[1]].co;
+
+ /* edge connects on each side! */
+ if (SV_IS_VALID(vc_tmp->v[0]) && SV_IS_VALID(vc_tmp->v[1])) {
+ /*printf("Verts on each side (%i %i)\n", vc_tmp->v[0], vc_tmp->v[1]);*/
+ /* find out which is higher */
+
+ vf_1 = tmpf1[ltmd->axis];
+ vf_2 = tmpf2[ltmd->axis];
+ vf_best = vc_tmp->co[ltmd->axis];
+
+ if (vf_1 < vf_best && vf_best < vf_2) {
+ ed_loop_flip = 0;
+ }
+ else if (vf_1 > vf_best && vf_best > vf_2) {
+ ed_loop_flip = 1;
+ }
+ else {
+ /* not so simple to work out which edge is higher */
+ sub_v3_v3v3(tmp_vec1, tmpf1, vc_tmp->co);
+ sub_v3_v3v3(tmp_vec2, tmpf2, vc_tmp->co);
+ normalize_v3(tmp_vec1);
+ normalize_v3(tmp_vec2);
+
+ if (tmp_vec1[ltmd->axis] < tmp_vec2[ltmd->axis]) {
+ ed_loop_flip = 1;
+ }
+ else {
+ ed_loop_flip = 0;
+ }
+ }
+ }
+ else if (SV_IS_VALID(vc_tmp->v[0])) { /*vertex only connected on 1 side */
+ /*printf("Verts on ONE side (%i %i)\n", vc_tmp->v[0], vc_tmp->v[1]);*/
+ if (tmpf1[ltmd->axis] < vc_tmp->co[ltmd->axis]) { /* best is above */
+ ed_loop_flip = 1;
+ }
+ else { /* best is below or even... in even case we can't know what to do. */
+ ed_loop_flip = 0;
+ }
+ }
#if 0
- else {
- printf("No Connected ___\n");
- }
+ else {
+ printf("No Connected ___\n");
+ }
#endif
- /*printf("flip direction %i\n", ed_loop_flip);*/
-
+ /*printf("flip direction %i\n", ed_loop_flip);*/
- /* switch the flip option if set
- * note: flip is now done at face level so copying vgroup slizes is easier */
+ /* switch the flip option if set
+ * note: flip is now done at face level so copying vgroup slizes is easier */
#if 0
- if (do_flip)
- ed_loop_flip = !ed_loop_flip;
+ if (do_flip)
+ ed_loop_flip = !ed_loop_flip;
#endif
- if (angle < 0.0f)
- ed_loop_flip = !ed_loop_flip;
-
- /* if its closed, we only need 1 loop */
- for (j = ed_loop_closed; j < 2; j++) {
- /*printf("Ordering Side J %i\n", j);*/
-
- screwvert_iter_init(&lt_iter, vert_connect, v_best, j);
- /*printf("\n\nStarting - Loop\n");*/
- lt_iter.v_poin->flag = 1; /* so a non loop will traverse the other side */
-
-
- /* If this is the vert off the best vert and
- * the best vert has 2 edges connected too it
- * then swap the flip direction */
- if (j == 1 && SV_IS_VALID(vc_tmp->v[0]) && SV_IS_VALID(vc_tmp->v[1]))
- ed_loop_flip = !ed_loop_flip;
-
- while (lt_iter.v_poin && lt_iter.v_poin->flag != 2) {
- /*printf("\tOrdering Vert V %i\n", lt_iter.v);*/
-
- lt_iter.v_poin->flag = 2;
- if (lt_iter.e) {
- if (lt_iter.v == lt_iter.e->v1) {
- if (ed_loop_flip == 0) {
- /*printf("\t\t\tFlipping 0\n");*/
- SWAP(unsigned int, lt_iter.e->v1, lt_iter.e->v2);
- }
- /* else {
- printf("\t\t\tFlipping Not 0\n");
- }*/
- }
- else if (lt_iter.v == lt_iter.e->v2) {
- if (ed_loop_flip == 1) {
- /*printf("\t\t\tFlipping 1\n");*/
- SWAP(unsigned int, lt_iter.e->v1, lt_iter.e->v2);
- }
- /* else {
- printf("\t\t\tFlipping Not 1\n");
- }*/
- }
- /* else {
- printf("\t\tIncorrect edge topology");
- }*/
- }
- /* else {
- printf("\t\tNo Edge at this point\n");
- }*/
- screwvert_iter_step(&lt_iter);
- }
- }
- }
- }
-
- /* *VERTEX NORMALS*
- * we know the surrounding edges are ordered correctly now
- * so its safe to create vertex normals.
- *
- * calculate vertex normals that can be propagated on lathing
- * use edge connectivity work this out */
- if (SV_IS_VALID(vc->v[0])) {
- if (SV_IS_VALID(vc->v[1])) {
- /* 2 edges connedted */
- /* make 2 connecting vert locations relative to the middle vert */
- sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co);
- sub_v3_v3v3(tmp_vec2, mvert_new[vc->v[1]].co, mvert_new[i].co);
- /* normalize so both edges have the same influence, no matter their length */
- normalize_v3(tmp_vec1);
- normalize_v3(tmp_vec2);
-
- /* vc_no_tmp1 - this line is the average direction of both connecting edges
- *
- * Use the edge order to make the subtraction, flip the normal the right way
- * edge should be there but check just in case... */
- if (vc->e[0]->v1 == i) {
- sub_v3_v3(tmp_vec1, tmp_vec2);
- }
- else {
- sub_v3_v3v3(tmp_vec1, tmp_vec2, tmp_vec1);
- }
- }
- else {
- /* only 1 edge connected - same as above except
- * don't need to average edge direction */
- if (vc->e[0]->v2 == i) {
- sub_v3_v3v3(tmp_vec1, mvert_new[i].co, mvert_new[vc->v[0]].co);
- }
- else {
- sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co);
- }
- }
-
- /* tmp_vec2 - is a line 90d from the pivot to the vec
- * This is used so the resulting normal points directly away from the middle */
- cross_v3_v3v3(tmp_vec2, axis_vec, vc->co);
-
- if (UNLIKELY(is_zero_v3(tmp_vec2))) {
- /* we're _on_ the axis, so copy it based on our winding */
- if (vc->e[0]->v2 == i) {
- negate_v3_v3(vc->no, axis_vec);
- }
- else {
- copy_v3_v3(vc->no, axis_vec);
- }
- }
- else {
- /* edge average vector and right angle to the pivot make the normal */
- cross_v3_v3v3(vc->no, tmp_vec1, tmp_vec2);
- }
-
- }
- else {
- copy_v3_v3(vc->no, vc->co);
- }
-
- /* we won't be looping on this data again so copy normals here */
- if ((angle < 0.0f) != do_flip)
- negate_v3(vc->no);
-
- normalize_v3(vc->no);
- normal_float_to_short_v3(mvert_new[i].no, vc->no);
-
- /* Done with normals */
- }
- }
- }
- else {
- mv_orig = mvert_orig;
- mv_new = mvert_new;
-
- for (i = 0; i < totvert; i++, mv_new++, mv_orig++) {
- copy_v3_v3(mv_new->co, mv_orig->co);
- }
- }
- /* done with edge connectivity based normal flipping */
-
- /* Add Faces */
- for (step = 1; step < step_tot; step++) {
- const unsigned int varray_stride = totvert * step;
- float step_angle;
- float nor_tx[3];
- float mat[4][4];
- /* Rotation Matrix */
- step_angle = (angle / (float)(step_tot - (!close))) * (float)step;
-
- if (ob_axis != NULL) {
- axis_angle_normalized_to_mat3(mat3, axis_vec, step_angle);
- }
- else {
- axis_angle_to_mat3_single(mat3, axis_char, step_angle);
- }
- copy_m4_m3(mat, mat3);
-
- if (screw_ofs)
- madd_v3_v3fl(mat[3], axis_vec, screw_ofs * ((float)step / (float)(step_tot - 1)));
-
- /* copy a slice */
- CustomData_copy_data(&mesh->vdata, &result->vdata, 0, (int)varray_stride, (int)totvert);
-
- mv_new_base = mvert_new;
- mv_new = &mvert_new[varray_stride]; /* advance to the next slice */
-
- for (j = 0; j < totvert; j++, mv_new_base++, mv_new++) {
- /* set normal */
- if (vert_connect) {
- mul_v3_m3v3(nor_tx, mat3, vert_connect[j].no);
-
- /* set the normal now its transformed */
- normal_float_to_short_v3(mv_new->no, nor_tx);
- }
-
- /* set location */
- copy_v3_v3(mv_new->co, mv_new_base->co);
-
- /* only need to set these if using non cleared memory */
- /*mv_new->mat_nr = mv_new->flag = 0;*/
-
- if (ob_axis != NULL) {
- sub_v3_v3(mv_new->co, mtx_tx[3]);
-
- mul_m4_v3(mat, mv_new->co);
-
- add_v3_v3(mv_new->co, mtx_tx[3]);
- }
- else {
- mul_m4_v3(mat, mv_new->co);
- }
-
- /* add the new edge */
- med_new->v1 = varray_stride + j;
- med_new->v2 = med_new->v1 - totvert;
- med_new->flag = ME_EDGEDRAW | ME_EDGERENDER;
- med_new++;
- }
- }
-
- /* we can avoid if using vert alloc trick */
- if (vert_connect) {
- MEM_freeN(vert_connect);
- vert_connect = NULL;
- }
-
- if (close) {
- /* last loop of edges, previous loop doesn't account for the last set of edges */
- const unsigned int varray_stride = (step_tot - 1) * totvert;
-
- for (i = 0; i < totvert; i++) {
- med_new->v1 = i;
- med_new->v2 = varray_stride + i;
- med_new->flag = ME_EDGEDRAW | ME_EDGERENDER;
- med_new++;
- }
- }
-
- mp_new = mpoly_new;
- ml_new = mloop_new;
- med_new_firstloop = medge_new;
-
- /* more of an offset in this case */
- edge_offset = totedge + (totvert * (step_tot - (close ? 0 : 1)));
-
- for (i = 0; i < totedge; i++, med_new_firstloop++) {
- const unsigned int step_last = step_tot - (close ? 1 : 2);
- const unsigned int mpoly_index_orig = totpoly ? edge_poly_map[i] : UINT_MAX;
- const bool has_mpoly_orig = (mpoly_index_orig != UINT_MAX);
- float uv_v_offset_a, uv_v_offset_b;
-
- const unsigned int mloop_index_orig[2] = {
- vert_loop_map ? vert_loop_map[medge_new[i].v1] : UINT_MAX,
- vert_loop_map ? vert_loop_map[medge_new[i].v2] : UINT_MAX,
- };
- const bool has_mloop_orig = mloop_index_orig[0] != UINT_MAX;
-
- short mat_nr;
-
- /* for each edge, make a cylinder of quads */
- i1 = med_new_firstloop->v1;
- i2 = med_new_firstloop->v2;
-
- if (has_mpoly_orig) {
- mat_nr = mpoly_orig[mpoly_index_orig].mat_nr;
- }
- else {
- mat_nr = 0;
- }
-
- if (has_mloop_orig == false && mloopuv_layers_tot) {
- uv_v_offset_a = dist_signed_to_plane_v3(mvert_new[medge_new[i].v1].co, uv_axis_plane);
- uv_v_offset_b = dist_signed_to_plane_v3(mvert_new[medge_new[i].v2].co, uv_axis_plane);
-
- if (ltmd->flag & MOD_SCREW_UV_STRETCH_V) {
- uv_v_offset_a = (uv_v_offset_a - uv_v_minmax[0]) * uv_v_range_inv;
- uv_v_offset_b = (uv_v_offset_b - uv_v_minmax[0]) * uv_v_range_inv;
- }
- }
-
- for (step = 0; step <= step_last; step++) {
-
- /* Polygon */
- if (has_mpoly_orig) {
- CustomData_copy_data(&mesh->pdata, &result->pdata, (int)mpoly_index_orig, (int)mpoly_index, 1);
- origindex[mpoly_index] = (int)mpoly_index_orig;
- }
- else {
- origindex[mpoly_index] = ORIGINDEX_NONE;
- mp_new->flag = mpoly_flag;
- mp_new->mat_nr = mat_nr;
- }
- mp_new->loopstart = mpoly_index * 4;
- mp_new->totloop = 4;
-
-
- /* Loop-Custom-Data */
- if (has_mloop_orig) {
- int l_index = (int)(ml_new - mloop_new);
-
- CustomData_copy_data(&mesh->ldata, &result->ldata, (int)mloop_index_orig[0], l_index + 0, 1);
- CustomData_copy_data(&mesh->ldata, &result->ldata, (int)mloop_index_orig[1], l_index + 1, 1);
- CustomData_copy_data(&mesh->ldata, &result->ldata, (int)mloop_index_orig[1], l_index + 2, 1);
- CustomData_copy_data(&mesh->ldata, &result->ldata, (int)mloop_index_orig[0], l_index + 3, 1);
-
- if (mloopuv_layers_tot) {
- unsigned int uv_lay;
- const float uv_u_offset_a = (float)(step) * uv_u_scale;
- const float uv_u_offset_b = (float)(step + 1) * uv_u_scale;
- for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) {
- MLoopUV *mluv = &mloopuv_layers[uv_lay][l_index];
-
- mluv[quad_ord[0]].uv[0] += uv_u_offset_a;
- mluv[quad_ord[1]].uv[0] += uv_u_offset_a;
- mluv[quad_ord[2]].uv[0] += uv_u_offset_b;
- mluv[quad_ord[3]].uv[0] += uv_u_offset_b;
- }
- }
- }
- else {
- if (mloopuv_layers_tot) {
- int l_index = (int)(ml_new - mloop_new);
-
- unsigned int uv_lay;
- const float uv_u_offset_a = (float)(step) * uv_u_scale;
- const float uv_u_offset_b = (float)(step + 1) * uv_u_scale;
- for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) {
- MLoopUV *mluv = &mloopuv_layers[uv_lay][l_index];
-
- copy_v2_fl2(mluv[quad_ord[0]].uv, uv_u_offset_a, uv_v_offset_a);
- copy_v2_fl2(mluv[quad_ord[1]].uv, uv_u_offset_a, uv_v_offset_b);
- copy_v2_fl2(mluv[quad_ord[2]].uv, uv_u_offset_b, uv_v_offset_b);
- copy_v2_fl2(mluv[quad_ord[3]].uv, uv_u_offset_b, uv_v_offset_a);
- }
- }
- }
-
- /* Loop-Data */
- if (!(close && step == step_last)) {
- /* regular segments */
- ml_new[quad_ord[0]].v = i1;
- ml_new[quad_ord[1]].v = i2;
- ml_new[quad_ord[2]].v = i2 + totvert;
- ml_new[quad_ord[3]].v = i1 + totvert;
-
- ml_new[quad_ord_ofs[0]].e = step == 0 ? i : (edge_offset + step + (i * (step_tot - 1))) - 1;
- ml_new[quad_ord_ofs[1]].e = totedge + i2;
- ml_new[quad_ord_ofs[2]].e = edge_offset + step + (i * (step_tot - 1));
- ml_new[quad_ord_ofs[3]].e = totedge + i1;
-
-
- /* new vertical edge */
- if (step) { /* The first set is already done */
- med_new->v1 = i1;
- med_new->v2 = i2;
- med_new->flag = med_new_firstloop->flag;
- med_new->crease = med_new_firstloop->crease;
- med_new++;
- }
- i1 += totvert;
- i2 += totvert;
- }
- else {
- /* last segment */
- ml_new[quad_ord[0]].v = i1;
- ml_new[quad_ord[1]].v = i2;
- ml_new[quad_ord[2]].v = med_new_firstloop->v2;
- ml_new[quad_ord[3]].v = med_new_firstloop->v1;
-
- ml_new[quad_ord_ofs[0]].e = (edge_offset + step + (i * (step_tot - 1))) - 1;
- ml_new[quad_ord_ofs[1]].e = totedge + i2;
- ml_new[quad_ord_ofs[2]].e = i;
- ml_new[quad_ord_ofs[3]].e = totedge + i1;
- }
-
- mp_new++;
- ml_new += 4;
- mpoly_index++;
- }
-
- /* new vertical edge */
- med_new->v1 = i1;
- med_new->v2 = i2;
- med_new->flag = med_new_firstloop->flag & ~ME_LOOSEEDGE;
- med_new->crease = med_new_firstloop->crease;
- med_new++;
- }
-
- /* validate loop edges */
+ if (angle < 0.0f)
+ ed_loop_flip = !ed_loop_flip;
+
+ /* if its closed, we only need 1 loop */
+ for (j = ed_loop_closed; j < 2; j++) {
+ /*printf("Ordering Side J %i\n", j);*/
+
+ screwvert_iter_init(&lt_iter, vert_connect, v_best, j);
+ /*printf("\n\nStarting - Loop\n");*/
+ lt_iter.v_poin->flag = 1; /* so a non loop will traverse the other side */
+
+ /* If this is the vert off the best vert and
+ * the best vert has 2 edges connected too it
+ * then swap the flip direction */
+ if (j == 1 && SV_IS_VALID(vc_tmp->v[0]) && SV_IS_VALID(vc_tmp->v[1]))
+ ed_loop_flip = !ed_loop_flip;
+
+ while (lt_iter.v_poin && lt_iter.v_poin->flag != 2) {
+ /*printf("\tOrdering Vert V %i\n", lt_iter.v);*/
+
+ lt_iter.v_poin->flag = 2;
+ if (lt_iter.e) {
+ if (lt_iter.v == lt_iter.e->v1) {
+ if (ed_loop_flip == 0) {
+ /*printf("\t\t\tFlipping 0\n");*/
+ SWAP(unsigned int, lt_iter.e->v1, lt_iter.e->v2);
+ }
+ /* else {
+ printf("\t\t\tFlipping Not 0\n");
+ }*/
+ }
+ else if (lt_iter.v == lt_iter.e->v2) {
+ if (ed_loop_flip == 1) {
+ /*printf("\t\t\tFlipping 1\n");*/
+ SWAP(unsigned int, lt_iter.e->v1, lt_iter.e->v2);
+ }
+ /* else {
+ printf("\t\t\tFlipping Not 1\n");
+ }*/
+ }
+ /* else {
+ printf("\t\tIncorrect edge topology");
+ }*/
+ }
+ /* else {
+ printf("\t\tNo Edge at this point\n");
+ }*/
+ screwvert_iter_step(&lt_iter);
+ }
+ }
+ }
+ }
+
+ /* *VERTEX NORMALS*
+ * we know the surrounding edges are ordered correctly now
+ * so its safe to create vertex normals.
+ *
+ * calculate vertex normals that can be propagated on lathing
+ * use edge connectivity work this out */
+ if (SV_IS_VALID(vc->v[0])) {
+ if (SV_IS_VALID(vc->v[1])) {
+ /* 2 edges connedted */
+ /* make 2 connecting vert locations relative to the middle vert */
+ sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co);
+ sub_v3_v3v3(tmp_vec2, mvert_new[vc->v[1]].co, mvert_new[i].co);
+ /* normalize so both edges have the same influence, no matter their length */
+ normalize_v3(tmp_vec1);
+ normalize_v3(tmp_vec2);
+
+ /* vc_no_tmp1 - this line is the average direction of both connecting edges
+ *
+ * Use the edge order to make the subtraction, flip the normal the right way
+ * edge should be there but check just in case... */
+ if (vc->e[0]->v1 == i) {
+ sub_v3_v3(tmp_vec1, tmp_vec2);
+ }
+ else {
+ sub_v3_v3v3(tmp_vec1, tmp_vec2, tmp_vec1);
+ }
+ }
+ else {
+ /* only 1 edge connected - same as above except
+ * don't need to average edge direction */
+ if (vc->e[0]->v2 == i) {
+ sub_v3_v3v3(tmp_vec1, mvert_new[i].co, mvert_new[vc->v[0]].co);
+ }
+ else {
+ sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co);
+ }
+ }
+
+ /* tmp_vec2 - is a line 90d from the pivot to the vec
+ * This is used so the resulting normal points directly away from the middle */
+ cross_v3_v3v3(tmp_vec2, axis_vec, vc->co);
+
+ if (UNLIKELY(is_zero_v3(tmp_vec2))) {
+ /* we're _on_ the axis, so copy it based on our winding */
+ if (vc->e[0]->v2 == i) {
+ negate_v3_v3(vc->no, axis_vec);
+ }
+ else {
+ copy_v3_v3(vc->no, axis_vec);
+ }
+ }
+ else {
+ /* edge average vector and right angle to the pivot make the normal */
+ cross_v3_v3v3(vc->no, tmp_vec1, tmp_vec2);
+ }
+ }
+ else {
+ copy_v3_v3(vc->no, vc->co);
+ }
+
+ /* we won't be looping on this data again so copy normals here */
+ if ((angle < 0.0f) != do_flip)
+ negate_v3(vc->no);
+
+ normalize_v3(vc->no);
+ normal_float_to_short_v3(mvert_new[i].no, vc->no);
+
+ /* Done with normals */
+ }
+ }
+ }
+ else {
+ mv_orig = mvert_orig;
+ mv_new = mvert_new;
+
+ for (i = 0; i < totvert; i++, mv_new++, mv_orig++) {
+ copy_v3_v3(mv_new->co, mv_orig->co);
+ }
+ }
+ /* done with edge connectivity based normal flipping */
+
+ /* Add Faces */
+ for (step = 1; step < step_tot; step++) {
+ const unsigned int varray_stride = totvert * step;
+ float step_angle;
+ float nor_tx[3];
+ float mat[4][4];
+ /* Rotation Matrix */
+ step_angle = (angle / (float)(step_tot - (!close))) * (float)step;
+
+ if (ob_axis != NULL) {
+ axis_angle_normalized_to_mat3(mat3, axis_vec, step_angle);
+ }
+ else {
+ axis_angle_to_mat3_single(mat3, axis_char, step_angle);
+ }
+ copy_m4_m3(mat, mat3);
+
+ if (screw_ofs)
+ madd_v3_v3fl(mat[3], axis_vec, screw_ofs * ((float)step / (float)(step_tot - 1)));
+
+ /* copy a slice */
+ CustomData_copy_data(&mesh->vdata, &result->vdata, 0, (int)varray_stride, (int)totvert);
+
+ mv_new_base = mvert_new;
+ mv_new = &mvert_new[varray_stride]; /* advance to the next slice */
+
+ for (j = 0; j < totvert; j++, mv_new_base++, mv_new++) {
+ /* set normal */
+ if (vert_connect) {
+ mul_v3_m3v3(nor_tx, mat3, vert_connect[j].no);
+
+ /* set the normal now its transformed */
+ normal_float_to_short_v3(mv_new->no, nor_tx);
+ }
+
+ /* set location */
+ copy_v3_v3(mv_new->co, mv_new_base->co);
+
+ /* only need to set these if using non cleared memory */
+ /*mv_new->mat_nr = mv_new->flag = 0;*/
+
+ if (ob_axis != NULL) {
+ sub_v3_v3(mv_new->co, mtx_tx[3]);
+
+ mul_m4_v3(mat, mv_new->co);
+
+ add_v3_v3(mv_new->co, mtx_tx[3]);
+ }
+ else {
+ mul_m4_v3(mat, mv_new->co);
+ }
+
+ /* add the new edge */
+ med_new->v1 = varray_stride + j;
+ med_new->v2 = med_new->v1 - totvert;
+ med_new->flag = ME_EDGEDRAW | ME_EDGERENDER;
+ med_new++;
+ }
+ }
+
+ /* we can avoid if using vert alloc trick */
+ if (vert_connect) {
+ MEM_freeN(vert_connect);
+ vert_connect = NULL;
+ }
+
+ if (close) {
+ /* last loop of edges, previous loop doesn't account for the last set of edges */
+ const unsigned int varray_stride = (step_tot - 1) * totvert;
+
+ for (i = 0; i < totvert; i++) {
+ med_new->v1 = i;
+ med_new->v2 = varray_stride + i;
+ med_new->flag = ME_EDGEDRAW | ME_EDGERENDER;
+ med_new++;
+ }
+ }
+
+ mp_new = mpoly_new;
+ ml_new = mloop_new;
+ med_new_firstloop = medge_new;
+
+ /* more of an offset in this case */
+ edge_offset = totedge + (totvert * (step_tot - (close ? 0 : 1)));
+
+ for (i = 0; i < totedge; i++, med_new_firstloop++) {
+ const unsigned int step_last = step_tot - (close ? 1 : 2);
+ const unsigned int mpoly_index_orig = totpoly ? edge_poly_map[i] : UINT_MAX;
+ const bool has_mpoly_orig = (mpoly_index_orig != UINT_MAX);
+ float uv_v_offset_a, uv_v_offset_b;
+
+ const unsigned int mloop_index_orig[2] = {
+ vert_loop_map ? vert_loop_map[medge_new[i].v1] : UINT_MAX,
+ vert_loop_map ? vert_loop_map[medge_new[i].v2] : UINT_MAX,
+ };
+ const bool has_mloop_orig = mloop_index_orig[0] != UINT_MAX;
+
+ short mat_nr;
+
+ /* for each edge, make a cylinder of quads */
+ i1 = med_new_firstloop->v1;
+ i2 = med_new_firstloop->v2;
+
+ if (has_mpoly_orig) {
+ mat_nr = mpoly_orig[mpoly_index_orig].mat_nr;
+ }
+ else {
+ mat_nr = 0;
+ }
+
+ if (has_mloop_orig == false && mloopuv_layers_tot) {
+ uv_v_offset_a = dist_signed_to_plane_v3(mvert_new[medge_new[i].v1].co, uv_axis_plane);
+ uv_v_offset_b = dist_signed_to_plane_v3(mvert_new[medge_new[i].v2].co, uv_axis_plane);
+
+ if (ltmd->flag & MOD_SCREW_UV_STRETCH_V) {
+ uv_v_offset_a = (uv_v_offset_a - uv_v_minmax[0]) * uv_v_range_inv;
+ uv_v_offset_b = (uv_v_offset_b - uv_v_minmax[0]) * uv_v_range_inv;
+ }
+ }
+
+ for (step = 0; step <= step_last; step++) {
+
+ /* Polygon */
+ if (has_mpoly_orig) {
+ CustomData_copy_data(
+ &mesh->pdata, &result->pdata, (int)mpoly_index_orig, (int)mpoly_index, 1);
+ origindex[mpoly_index] = (int)mpoly_index_orig;
+ }
+ else {
+ origindex[mpoly_index] = ORIGINDEX_NONE;
+ mp_new->flag = mpoly_flag;
+ mp_new->mat_nr = mat_nr;
+ }
+ mp_new->loopstart = mpoly_index * 4;
+ mp_new->totloop = 4;
+
+ /* Loop-Custom-Data */
+ if (has_mloop_orig) {
+ int l_index = (int)(ml_new - mloop_new);
+
+ CustomData_copy_data(
+ &mesh->ldata, &result->ldata, (int)mloop_index_orig[0], l_index + 0, 1);
+ CustomData_copy_data(
+ &mesh->ldata, &result->ldata, (int)mloop_index_orig[1], l_index + 1, 1);
+ CustomData_copy_data(
+ &mesh->ldata, &result->ldata, (int)mloop_index_orig[1], l_index + 2, 1);
+ CustomData_copy_data(
+ &mesh->ldata, &result->ldata, (int)mloop_index_orig[0], l_index + 3, 1);
+
+ if (mloopuv_layers_tot) {
+ unsigned int uv_lay;
+ const float uv_u_offset_a = (float)(step)*uv_u_scale;
+ const float uv_u_offset_b = (float)(step + 1) * uv_u_scale;
+ for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) {
+ MLoopUV *mluv = &mloopuv_layers[uv_lay][l_index];
+
+ mluv[quad_ord[0]].uv[0] += uv_u_offset_a;
+ mluv[quad_ord[1]].uv[0] += uv_u_offset_a;
+ mluv[quad_ord[2]].uv[0] += uv_u_offset_b;
+ mluv[quad_ord[3]].uv[0] += uv_u_offset_b;
+ }
+ }
+ }
+ else {
+ if (mloopuv_layers_tot) {
+ int l_index = (int)(ml_new - mloop_new);
+
+ unsigned int uv_lay;
+ const float uv_u_offset_a = (float)(step)*uv_u_scale;
+ const float uv_u_offset_b = (float)(step + 1) * uv_u_scale;
+ for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) {
+ MLoopUV *mluv = &mloopuv_layers[uv_lay][l_index];
+
+ copy_v2_fl2(mluv[quad_ord[0]].uv, uv_u_offset_a, uv_v_offset_a);
+ copy_v2_fl2(mluv[quad_ord[1]].uv, uv_u_offset_a, uv_v_offset_b);
+ copy_v2_fl2(mluv[quad_ord[2]].uv, uv_u_offset_b, uv_v_offset_b);
+ copy_v2_fl2(mluv[quad_ord[3]].uv, uv_u_offset_b, uv_v_offset_a);
+ }
+ }
+ }
+
+ /* Loop-Data */
+ if (!(close && step == step_last)) {
+ /* regular segments */
+ ml_new[quad_ord[0]].v = i1;
+ ml_new[quad_ord[1]].v = i2;
+ ml_new[quad_ord[2]].v = i2 + totvert;
+ ml_new[quad_ord[3]].v = i1 + totvert;
+
+ ml_new[quad_ord_ofs[0]].e = step == 0 ? i :
+ (edge_offset + step + (i * (step_tot - 1))) - 1;
+ ml_new[quad_ord_ofs[1]].e = totedge + i2;
+ ml_new[quad_ord_ofs[2]].e = edge_offset + step + (i * (step_tot - 1));
+ ml_new[quad_ord_ofs[3]].e = totedge + i1;
+
+ /* new vertical edge */
+ if (step) { /* The first set is already done */
+ med_new->v1 = i1;
+ med_new->v2 = i2;
+ med_new->flag = med_new_firstloop->flag;
+ med_new->crease = med_new_firstloop->crease;
+ med_new++;
+ }
+ i1 += totvert;
+ i2 += totvert;
+ }
+ else {
+ /* last segment */
+ ml_new[quad_ord[0]].v = i1;
+ ml_new[quad_ord[1]].v = i2;
+ ml_new[quad_ord[2]].v = med_new_firstloop->v2;
+ ml_new[quad_ord[3]].v = med_new_firstloop->v1;
+
+ ml_new[quad_ord_ofs[0]].e = (edge_offset + step + (i * (step_tot - 1))) - 1;
+ ml_new[quad_ord_ofs[1]].e = totedge + i2;
+ ml_new[quad_ord_ofs[2]].e = i;
+ ml_new[quad_ord_ofs[3]].e = totedge + i1;
+ }
+
+ mp_new++;
+ ml_new += 4;
+ mpoly_index++;
+ }
+
+ /* new vertical edge */
+ med_new->v1 = i1;
+ med_new->v2 = i2;
+ med_new->flag = med_new_firstloop->flag & ~ME_LOOSEEDGE;
+ med_new->crease = med_new_firstloop->crease;
+ med_new++;
+ }
+
+ /* validate loop edges */
#if 0
- {
- unsigned i = 0;
- printf("\n");
- for (; i < maxPolys * 4; i += 4) {
- unsigned int ii;
- ml_new = mloop_new + i;
- ii = findEd(medge_new, maxEdges, ml_new[0].v, ml_new[1].v);
- printf("%d %d -- ", ii, ml_new[0].e);
- ml_new[0].e = ii;
-
- ii = findEd(medge_new, maxEdges, ml_new[1].v, ml_new[2].v);
- printf("%d %d -- ", ii, ml_new[1].e);
- ml_new[1].e = ii;
-
- ii = findEd(medge_new, maxEdges, ml_new[2].v, ml_new[3].v);
- printf("%d %d -- ", ii, ml_new[2].e);
- ml_new[2].e = ii;
-
- ii = findEd(medge_new, maxEdges, ml_new[3].v, ml_new[0].v);
- printf("%d %d\n", ii, ml_new[3].e);
- ml_new[3].e = ii;
-
- }
- }
+ {
+ unsigned i = 0;
+ printf("\n");
+ for (; i < maxPolys * 4; i += 4) {
+ unsigned int ii;
+ ml_new = mloop_new + i;
+ ii = findEd(medge_new, maxEdges, ml_new[0].v, ml_new[1].v);
+ printf("%d %d -- ", ii, ml_new[0].e);
+ ml_new[0].e = ii;
+
+ ii = findEd(medge_new, maxEdges, ml_new[1].v, ml_new[2].v);
+ printf("%d %d -- ", ii, ml_new[1].e);
+ ml_new[1].e = ii;
+
+ ii = findEd(medge_new, maxEdges, ml_new[2].v, ml_new[3].v);
+ printf("%d %d -- ", ii, ml_new[2].e);
+ ml_new[2].e = ii;
+
+ ii = findEd(medge_new, maxEdges, ml_new[3].v, ml_new[0].v);
+ printf("%d %d\n", ii, ml_new[3].e);
+ ml_new[3].e = ii;
+
+ }
+ }
#endif
- if (edge_poly_map) {
- MEM_freeN(edge_poly_map);
- }
-
- if (vert_loop_map) {
- MEM_freeN(vert_loop_map);
- }
-
- if ((ltmd->flag & MOD_SCREW_MERGE) && (screw_ofs == 0.0f)) {
- Mesh *result_prev = result;
- result = mesh_remove_doubles_on_axis(
- result, mvert_new, totvert, step_tot,
- axis_vec, ob_axis != NULL ? mtx_tx[3] : NULL, ltmd->merge_dist);
- if (result != result_prev) {
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- }
- }
-
- if ((ltmd->flag & MOD_SCREW_NORMAL_CALC) == 0) {
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- }
-
- return result;
+ if (edge_poly_map) {
+ MEM_freeN(edge_poly_map);
+ }
+
+ if (vert_loop_map) {
+ MEM_freeN(vert_loop_map);
+ }
+
+ if ((ltmd->flag & MOD_SCREW_MERGE) && (screw_ofs == 0.0f)) {
+ Mesh *result_prev = result;
+ result = mesh_remove_doubles_on_axis(result,
+ mvert_new,
+ totvert,
+ step_tot,
+ axis_vec,
+ ob_axis != NULL ? mtx_tx[3] : NULL,
+ ltmd->merge_dist);
+ if (result != result_prev) {
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ }
+ }
+
+ if ((ltmd->flag & MOD_SCREW_NORMAL_CALC) == 0) {
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ }
+
+ return result;
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- ScrewModifierData *ltmd = (ScrewModifierData *)md;
- if (ltmd->ob_axis != NULL) {
- DEG_add_object_relation(ctx->node, ltmd->ob_axis, DEG_OB_COMP_TRANSFORM, "Screw Modifier");
- DEG_add_modifier_to_transform_relation(ctx->node, "Screw Modifier");
- }
+ ScrewModifierData *ltmd = (ScrewModifierData *)md;
+ if (ltmd->ob_axis != NULL) {
+ DEG_add_object_relation(ctx->node, ltmd->ob_axis, DEG_OB_COMP_TRANSFORM, "Screw Modifier");
+ DEG_add_modifier_to_transform_relation(ctx->node, "Screw Modifier");
+ }
}
-static void foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- ScrewModifierData *ltmd = (ScrewModifierData *) md;
+ ScrewModifierData *ltmd = (ScrewModifierData *)md;
- walk(userData, ob, &ltmd->ob_axis, IDWALK_CB_NOP);
+ walk(userData, ob, &ltmd->ob_axis, IDWALK_CB_NOP);
}
ModifierTypeInfo modifierType_Screw = {
- /* name */ "Screw",
- /* structName */ "ScrewModifierData",
- /* structSize */ sizeof(ScrewModifierData),
- /* type */ eModifierTypeType_Constructive,
-
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_EnableInEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ NULL,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Screw",
+ /* structName */ "ScrewModifierData",
+ /* structSize */ sizeof(ScrewModifierData),
+ /* type */ eModifierTypeType_Constructive,
+
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs |
+ eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_shapekey.c b/source/blender/modifiers/intern/MOD_shapekey.c
index dd5f53c408a..5667a74bce6 100644
--- a/source/blender/modifiers/intern/MOD_shapekey.c
+++ b/source/blender/modifiers/intern/MOD_shapekey.c
@@ -33,109 +33,110 @@
#include "MOD_modifiertypes.h"
-static void deformVerts(
- ModifierData *UNUSED(md), const ModifierEvalContext *ctx,
- Mesh *UNUSED(mesh),
- float (*vertexCos)[3],
- int numVerts)
+static void deformVerts(ModifierData *UNUSED(md),
+ const ModifierEvalContext *ctx,
+ Mesh *UNUSED(mesh),
+ float (*vertexCos)[3],
+ int numVerts)
{
- Key *key = BKE_key_from_object(ctx->object);
+ Key *key = BKE_key_from_object(ctx->object);
- if (key && key->block.first) {
- int deformedVerts_tot;
- BKE_key_evaluate_object_ex(
- ctx->object, &deformedVerts_tot,
- (float *)vertexCos, sizeof(*vertexCos) * numVerts);
-
- }
+ if (key && key->block.first) {
+ int deformedVerts_tot;
+ BKE_key_evaluate_object_ex(
+ ctx->object, &deformedVerts_tot, (float *)vertexCos, sizeof(*vertexCos) * numVerts);
+ }
}
-static void deformMatrices(
- ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh,
- float (*vertexCos)[3], float (*defMats)[3][3], int numVerts)
+static void deformMatrices(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ float (*defMats)[3][3],
+ int numVerts)
{
- Key *key = BKE_key_from_object(ctx->object);
- KeyBlock *kb = BKE_keyblock_from_object(ctx->object);
- float scale[3][3];
+ Key *key = BKE_key_from_object(ctx->object);
+ KeyBlock *kb = BKE_keyblock_from_object(ctx->object);
+ float scale[3][3];
- (void)vertexCos; /* unused */
+ (void)vertexCos; /* unused */
- if (kb && kb->totelem == numVerts && kb != key->refkey) {
- int a;
+ if (kb && kb->totelem == numVerts && kb != key->refkey) {
+ int a;
- if (ctx->object->shapeflag & OB_SHAPE_LOCK) scale_m3_fl(scale, 1);
- else scale_m3_fl(scale, kb->curval);
+ if (ctx->object->shapeflag & OB_SHAPE_LOCK)
+ scale_m3_fl(scale, 1);
+ else
+ scale_m3_fl(scale, kb->curval);
- for (a = 0; a < numVerts; a++)
- copy_m3_m3(defMats[a], scale);
- }
+ for (a = 0; a < numVerts; a++)
+ copy_m3_m3(defMats[a], scale);
+ }
- deformVerts(md, ctx, mesh, vertexCos, numVerts);
+ deformVerts(md, ctx, mesh, vertexCos, numVerts);
}
-static void deformVertsEM(
- ModifierData *md, const ModifierEvalContext *ctx,
- struct BMEditMesh *UNUSED(editData),
- Mesh *mesh,
- float (*vertexCos)[3],
- int numVerts)
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *UNUSED(editData),
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- Key *key = BKE_key_from_object(ctx->object);
+ Key *key = BKE_key_from_object(ctx->object);
- if (key && key->type == KEY_RELATIVE)
- deformVerts(md, ctx, mesh, vertexCos, numVerts);
+ if (key && key->type == KEY_RELATIVE)
+ deformVerts(md, ctx, mesh, vertexCos, numVerts);
}
-static void deformMatricesEM(
- ModifierData *UNUSED(md), const ModifierEvalContext *ctx,
- struct BMEditMesh *UNUSED(editData),
- Mesh *UNUSED(mesh),
- float (*vertexCos)[3],
- float (*defMats)[3][3],
- int numVerts)
+static void deformMatricesEM(ModifierData *UNUSED(md),
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *UNUSED(editData),
+ Mesh *UNUSED(mesh),
+ float (*vertexCos)[3],
+ float (*defMats)[3][3],
+ int numVerts)
{
- Key *key = BKE_key_from_object(ctx->object);
- KeyBlock *kb = BKE_keyblock_from_object(ctx->object);
- float scale[3][3];
+ Key *key = BKE_key_from_object(ctx->object);
+ KeyBlock *kb = BKE_keyblock_from_object(ctx->object);
+ float scale[3][3];
- (void)vertexCos; /* unused */
+ (void)vertexCos; /* unused */
- if (kb && kb->totelem == numVerts && kb != key->refkey) {
- int a;
- scale_m3_fl(scale, kb->curval);
+ if (kb && kb->totelem == numVerts && kb != key->refkey) {
+ int a;
+ scale_m3_fl(scale, kb->curval);
- for (a = 0; a < numVerts; a++)
- copy_m3_m3(defMats[a], scale);
- }
+ for (a = 0; a < numVerts; a++)
+ copy_m3_m3(defMats[a], scale);
+ }
}
-
ModifierTypeInfo modifierType_ShapeKey = {
- /* name */ "ShapeKey",
- /* structName */ "ShapeKeyModifierData",
- /* structSize */ sizeof(ShapeKeyModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_AcceptsLattice |
- eModifierTypeFlag_SupportsEditmode,
-
- /* copyData */ NULL,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ deformMatrices,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ deformMatricesEM,
- /* applyModifier */ NULL,
-
- /* initData */ NULL,
- /* requiredDataMask */ NULL,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "ShapeKey",
+ /* structName */ "ShapeKeyModifierData",
+ /* structSize */ sizeof(ShapeKeyModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice |
+ eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ NULL,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ deformMatrices,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ deformMatricesEM,
+ /* applyModifier */ NULL,
+
+ /* initData */ NULL,
+ /* requiredDataMask */ NULL,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c
index 73e99738458..3b4d6251c0a 100644
--- a/source/blender/modifiers/intern/MOD_shrinkwrap.c
+++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include <string.h>
#include "BLI_utildefines.h"
@@ -42,162 +41,169 @@
static bool dependsOnNormals(ModifierData *md);
-
static void initData(ModifierData *md)
{
- ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *) md;
- smd->shrinkType = MOD_SHRINKWRAP_NEAREST_SURFACE;
- smd->shrinkOpts = MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR;
- smd->keepDist = 0.0f;
+ ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
+ smd->shrinkType = MOD_SHRINKWRAP_NEAREST_SURFACE;
+ smd->shrinkOpts = MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR;
+ smd->keepDist = 0.0f;
- smd->target = NULL;
- smd->auxTarget = NULL;
+ smd->target = NULL;
+ smd->auxTarget = NULL;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
-
- /* ask for vertexgroups if we need them */
- if (smd->vgroup_name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
-
- if ((smd->shrinkType == MOD_SHRINKWRAP_PROJECT) &&
- (smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL))
- {
- r_cddata_masks->vmask |= CD_MASK_MVERT; /* XXX Really? These should always be present, always... */
- }
+ ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
+
+ /* ask for vertexgroups if we need them */
+ if (smd->vgroup_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
+
+ if ((smd->shrinkType == MOD_SHRINKWRAP_PROJECT) &&
+ (smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL)) {
+ r_cddata_masks->vmask |=
+ CD_MASK_MVERT; /* XXX Really? These should always be present, always... */
+ }
}
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(useRenderParams))
{
- ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *) md;
- return !smd->target;
+ ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
+ return !smd->target;
}
-
static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *) md;
+ ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
- walk(userData, ob, &smd->target, IDWALK_CB_NOP);
- walk(userData, ob, &smd->auxTarget, IDWALK_CB_NOP);
+ walk(userData, ob, &smd->target, IDWALK_CB_NOP);
+ walk(userData, ob, &smd->auxTarget, IDWALK_CB_NOP);
}
-static void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh,
- float (*vertexCos)[3],
- int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- ShrinkwrapModifierData *swmd = (ShrinkwrapModifierData *)md;
- struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- Mesh *mesh_src = NULL;
+ ShrinkwrapModifierData *swmd = (ShrinkwrapModifierData *)md;
+ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ Mesh *mesh_src = NULL;
- if (ctx->object->type == OB_MESH) {
- /* mesh_src is only needed for vgroups. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
- }
+ if (ctx->object->type == OB_MESH) {
+ /* mesh_src is only needed for vgroups. */
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ }
- struct MDeformVert *dvert = NULL;
- int defgrp_index = -1;
- MOD_get_vgroup(ctx->object, mesh_src, swmd->vgroup_name, &dvert, &defgrp_index);
+ struct MDeformVert *dvert = NULL;
+ int defgrp_index = -1;
+ MOD_get_vgroup(ctx->object, mesh_src, swmd->vgroup_name, &dvert, &defgrp_index);
- shrinkwrapModifier_deform(swmd, ctx, scene, ctx->object, mesh_src, dvert, defgrp_index, vertexCos, numVerts);
+ shrinkwrapModifier_deform(
+ swmd, ctx, scene, ctx->object, mesh_src, dvert, defgrp_index, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-static void deformVertsEM(
- ModifierData *md, const ModifierEvalContext *ctx,
- struct BMEditMesh *editData, Mesh *mesh,
- float (*vertexCos)[3], int numVerts)
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *editData,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- ShrinkwrapModifierData *swmd = (ShrinkwrapModifierData *)md;
- struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ ShrinkwrapModifierData *swmd = (ShrinkwrapModifierData *)md;
+ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, editData, mesh, NULL, numVerts, false, false);
- struct MDeformVert *dvert = NULL;
- int defgrp_index = -1;
- MOD_get_vgroup(ctx->object, mesh_src, swmd->vgroup_name, &dvert, &defgrp_index);
+ struct MDeformVert *dvert = NULL;
+ int defgrp_index = -1;
+ MOD_get_vgroup(ctx->object, mesh_src, swmd->vgroup_name, &dvert, &defgrp_index);
- shrinkwrapModifier_deform(swmd, ctx, scene, ctx->object, mesh_src, dvert, defgrp_index, vertexCos, numVerts);
+ shrinkwrapModifier_deform(
+ swmd, ctx, scene, ctx->object, mesh_src, dvert, defgrp_index, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
- CustomData_MeshMasks mask = {0};
-
- if (BKE_shrinkwrap_needs_normals(smd->shrinkType, smd->shrinkMode)) {
- mask.vmask |= CD_MASK_NORMAL;
- mask.lmask |= CD_MASK_NORMAL | CD_MASK_CUSTOMLOOPNORMAL;
- }
-
- if (smd->target != NULL) {
- DEG_add_object_relation(ctx->node, smd->target, DEG_OB_COMP_TRANSFORM, "Shrinkwrap Modifier");
- DEG_add_object_relation(ctx->node, smd->target, DEG_OB_COMP_GEOMETRY, "Shrinkwrap Modifier");
- DEG_add_customdata_mask(ctx->node, smd->target, &mask);
- if (smd->shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) {
- DEG_add_special_eval_flag(ctx->node, &smd->target->id, DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY);
- }
- }
- if (smd->auxTarget != NULL) {
- DEG_add_object_relation(ctx->node, smd->auxTarget, DEG_OB_COMP_TRANSFORM, "Shrinkwrap Modifier");
- DEG_add_object_relation(ctx->node, smd->auxTarget, DEG_OB_COMP_GEOMETRY, "Shrinkwrap Modifier");
- DEG_add_customdata_mask(ctx->node, smd->auxTarget, &mask);
- if (smd->shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) {
- DEG_add_special_eval_flag(ctx->node, &smd->auxTarget->id, DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY);
- }
- }
- DEG_add_modifier_to_transform_relation(ctx->node, "Shrinkwrap Modifier");
+ ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
+ CustomData_MeshMasks mask = {0};
+
+ if (BKE_shrinkwrap_needs_normals(smd->shrinkType, smd->shrinkMode)) {
+ mask.vmask |= CD_MASK_NORMAL;
+ mask.lmask |= CD_MASK_NORMAL | CD_MASK_CUSTOMLOOPNORMAL;
+ }
+
+ if (smd->target != NULL) {
+ DEG_add_object_relation(ctx->node, smd->target, DEG_OB_COMP_TRANSFORM, "Shrinkwrap Modifier");
+ DEG_add_object_relation(ctx->node, smd->target, DEG_OB_COMP_GEOMETRY, "Shrinkwrap Modifier");
+ DEG_add_customdata_mask(ctx->node, smd->target, &mask);
+ if (smd->shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) {
+ DEG_add_special_eval_flag(ctx->node, &smd->target->id, DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY);
+ }
+ }
+ if (smd->auxTarget != NULL) {
+ DEG_add_object_relation(
+ ctx->node, smd->auxTarget, DEG_OB_COMP_TRANSFORM, "Shrinkwrap Modifier");
+ DEG_add_object_relation(
+ ctx->node, smd->auxTarget, DEG_OB_COMP_GEOMETRY, "Shrinkwrap Modifier");
+ DEG_add_customdata_mask(ctx->node, smd->auxTarget, &mask);
+ if (smd->shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) {
+ DEG_add_special_eval_flag(ctx->node, &smd->auxTarget->id, DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY);
+ }
+ }
+ DEG_add_modifier_to_transform_relation(ctx->node, "Shrinkwrap Modifier");
}
static bool dependsOnNormals(ModifierData *md)
{
- ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
+ ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
- if (smd->target && smd->shrinkType == MOD_SHRINKWRAP_PROJECT)
- return (smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL);
+ if (smd->target && smd->shrinkType == MOD_SHRINKWRAP_PROJECT)
+ return (smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL);
- return false;
+ return false;
}
ModifierTypeInfo modifierType_Shrinkwrap = {
- /* name */ "Shrinkwrap",
- /* structName */ "ShrinkwrapModifierData",
- /* structSize */ sizeof(ShrinkwrapModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_AcceptsLattice |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_EnableInEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Shrinkwrap",
+ /* structName */ "ShrinkwrapModifierData",
+ /* structSize */ sizeof(ShrinkwrapModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs |
+ eModifierTypeFlag_AcceptsLattice | eModifierTypeFlag_SupportsEditmode |
+ eModifierTypeFlag_EnableInEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ dependsOnNormals,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c
index 0ebeb1cd761..2434bd514f4 100644
--- a/source/blender/modifiers/intern/MOD_simpledeform.c
+++ b/source/blender/modifiers/intern/MOD_simpledeform.c
@@ -49,401 +49,428 @@
* exists because the deformations (excluding bend) are based on the Z axis.
* Having this helps avoid long, drawn out switches. */
static const uint axis_map_table[3][3] = {
- {1, 2, 0},
- {2, 0, 1},
- {0, 1, 2},
+ {1, 2, 0},
+ {2, 0, 1},
+ {0, 1, 2},
};
BLI_INLINE void copy_v3_v3_map(float a[3], const float b[3], const uint map[3])
{
- a[0] = b[map[0]];
- a[1] = b[map[1]];
- a[2] = b[map[2]];
+ a[0] = b[map[0]];
+ a[1] = b[map[1]];
+ a[2] = b[map[2]];
}
BLI_INLINE void copy_v3_v3_unmap(float a[3], const float b[3], const uint map[3])
{
- a[map[0]] = b[0];
- a[map[1]] = b[1];
- a[map[2]] = b[2];
+ a[map[0]] = b[0];
+ a[map[1]] = b[1];
+ a[map[2]] = b[2];
}
/* Clamps/Limits the given coordinate to: limits[0] <= co[axis] <= limits[1]
* The amount of clamp is saved on dcut */
static void axis_limit(const int axis, const float limits[2], float co[3], float dcut[3])
{
- float val = co[axis];
- if (limits[0] > val) val = limits[0];
- if (limits[1] < val) val = limits[1];
-
- dcut[axis] = co[axis] - val;
- co[axis] = val;
+ float val = co[axis];
+ if (limits[0] > val)
+ val = limits[0];
+ if (limits[1] < val)
+ val = limits[1];
+
+ dcut[axis] = co[axis] - val;
+ co[axis] = val;
}
-static void simpleDeform_taper(const float factor, const int UNUSED(axis), const float dcut[3], float r_co[3])
+static void simpleDeform_taper(const float factor,
+ const int UNUSED(axis),
+ const float dcut[3],
+ float r_co[3])
{
- float x = r_co[0], y = r_co[1], z = r_co[2];
- float scale = z * factor;
+ float x = r_co[0], y = r_co[1], z = r_co[2];
+ float scale = z * factor;
- r_co[0] = x + x * scale;
- r_co[1] = y + y * scale;
- r_co[2] = z;
+ r_co[0] = x + x * scale;
+ r_co[1] = y + y * scale;
+ r_co[2] = z;
- add_v3_v3(r_co, dcut);
+ add_v3_v3(r_co, dcut);
}
-static void simpleDeform_stretch(const float factor, const int UNUSED(axis), const float dcut[3], float r_co[3])
+static void simpleDeform_stretch(const float factor,
+ const int UNUSED(axis),
+ const float dcut[3],
+ float r_co[3])
{
- float x = r_co[0], y = r_co[1], z = r_co[2];
- float scale;
+ float x = r_co[0], y = r_co[1], z = r_co[2];
+ float scale;
- scale = (z * z * factor - factor + 1.0f);
+ scale = (z * z * factor - factor + 1.0f);
- r_co[0] = x * scale;
- r_co[1] = y * scale;
- r_co[2] = z * (1.0f + factor);
+ r_co[0] = x * scale;
+ r_co[1] = y * scale;
+ r_co[2] = z * (1.0f + factor);
- add_v3_v3(r_co, dcut);
+ add_v3_v3(r_co, dcut);
}
-static void simpleDeform_twist(const float factor, const int UNUSED(axis), const float *dcut, float r_co[3])
+static void simpleDeform_twist(const float factor,
+ const int UNUSED(axis),
+ const float *dcut,
+ float r_co[3])
{
- float x = r_co[0], y = r_co[1], z = r_co[2];
- float theta, sint, cost;
+ float x = r_co[0], y = r_co[1], z = r_co[2];
+ float theta, sint, cost;
- theta = z * factor;
- sint = sinf(theta);
- cost = cosf(theta);
+ theta = z * factor;
+ sint = sinf(theta);
+ cost = cosf(theta);
- r_co[0] = x * cost - y * sint;
- r_co[1] = x * sint + y * cost;
- r_co[2] = z;
+ r_co[0] = x * cost - y * sint;
+ r_co[1] = x * sint + y * cost;
+ r_co[2] = z;
- add_v3_v3(r_co, dcut);
+ add_v3_v3(r_co, dcut);
}
-static void simpleDeform_bend(const float factor, const int axis, const float dcut[3], float r_co[3])
+static void simpleDeform_bend(const float factor,
+ const int axis,
+ const float dcut[3],
+ float r_co[3])
{
- float x = r_co[0], y = r_co[1], z = r_co[2];
- float theta, sint, cost;
-
- BLI_assert(!(fabsf(factor) < BEND_EPS));
-
- switch (axis) {
- case 0:
- ATTR_FALLTHROUGH;
- case 1:
- theta = z * factor;
- break;
- default:
- theta = x * factor;
- }
- sint = sinf(theta);
- cost = cosf(theta);
-
- switch (axis) {
- case 0:
- r_co[0] = x;
- r_co[1] = (y - 1.0f / factor) * cost + 1.0f / factor;
- r_co[2] = -(y - 1.0f / factor) * sint;
- {
- r_co[0] += dcut[0];
- r_co[1] += sint * dcut[2];
- r_co[2] += cost * dcut[2];
- }
- break;
- case 1:
- r_co[0] = (x - 1.0f / factor) * cost + 1.0f / factor;
- r_co[1] = y;
- r_co[2] = -(x - 1.0f / factor) * sint;
- {
- r_co[0] += sint * dcut[2];
- r_co[1] += dcut[1];
- r_co[2] += cost * dcut[2];
- }
- break;
- default:
- r_co[0] = -(y - 1.0f / factor) * sint;
- r_co[1] = (y - 1.0f / factor) * cost + 1.0f / factor;
- r_co[2] = z;
- {
- r_co[0] += cost * dcut[0];
- r_co[1] += sint * dcut[0];
- r_co[2] += dcut[2];
- }
- }
-
+ float x = r_co[0], y = r_co[1], z = r_co[2];
+ float theta, sint, cost;
+
+ BLI_assert(!(fabsf(factor) < BEND_EPS));
+
+ switch (axis) {
+ case 0:
+ ATTR_FALLTHROUGH;
+ case 1:
+ theta = z * factor;
+ break;
+ default:
+ theta = x * factor;
+ }
+ sint = sinf(theta);
+ cost = cosf(theta);
+
+ switch (axis) {
+ case 0:
+ r_co[0] = x;
+ r_co[1] = (y - 1.0f / factor) * cost + 1.0f / factor;
+ r_co[2] = -(y - 1.0f / factor) * sint;
+ {
+ r_co[0] += dcut[0];
+ r_co[1] += sint * dcut[2];
+ r_co[2] += cost * dcut[2];
+ }
+ break;
+ case 1:
+ r_co[0] = (x - 1.0f / factor) * cost + 1.0f / factor;
+ r_co[1] = y;
+ r_co[2] = -(x - 1.0f / factor) * sint;
+ {
+ r_co[0] += sint * dcut[2];
+ r_co[1] += dcut[1];
+ r_co[2] += cost * dcut[2];
+ }
+ break;
+ default:
+ r_co[0] = -(y - 1.0f / factor) * sint;
+ r_co[1] = (y - 1.0f / factor) * cost + 1.0f / factor;
+ r_co[2] = z;
+ {
+ r_co[0] += cost * dcut[0];
+ r_co[1] += sint * dcut[0];
+ r_co[2] += dcut[2];
+ }
+ }
}
-
/* simple deform modifier */
-static void SimpleDeformModifier_do(
- SimpleDeformModifierData *smd, const ModifierEvalContext *UNUSED(ctx),
- struct Object *ob, struct Mesh *mesh,
- float (*vertexCos)[3], int numVerts)
+static void SimpleDeformModifier_do(SimpleDeformModifierData *smd,
+ const ModifierEvalContext *UNUSED(ctx),
+ struct Object *ob,
+ struct Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- const float base_limit[2] = {0.0f, 0.0f};
- int i;
- float smd_limit[2], smd_factor;
- SpaceTransform *transf = NULL, tmp_transf;
- void (*simpleDeform_callback)(const float factor, const int axis, const float dcut[3], float co[3]) = NULL; /* Mode callback */
- int vgroup;
- MDeformVert *dvert;
-
- /* This is historically the lock axis, _not_ the deform axis as the name would imply */
- const int deform_axis = smd->deform_axis;
- int lock_axis = smd->axis;
- if (smd->mode == MOD_SIMPLEDEFORM_MODE_BEND) { /* Bend mode shouldn't have any lock axis */
- lock_axis = 0;
- }
- else {
- /* Don't lock axis if it is the chosen deform axis, as this flattens
- * the geometry */
- if (deform_axis == 0) {
- lock_axis &= ~MOD_SIMPLEDEFORM_LOCK_AXIS_X;
- }
- if (deform_axis == 1) {
- lock_axis &= ~MOD_SIMPLEDEFORM_LOCK_AXIS_Y;
- }
- if (deform_axis == 2) {
- lock_axis &= ~MOD_SIMPLEDEFORM_LOCK_AXIS_Z;
- }
- }
-
-
- /* Safe-check */
- if (smd->origin == ob) smd->origin = NULL; /* No self references */
-
- if (smd->limit[0] < 0.0f) smd->limit[0] = 0.0f;
- if (smd->limit[0] > 1.0f) smd->limit[0] = 1.0f;
-
- smd->limit[0] = min_ff(smd->limit[0], smd->limit[1]); /* Upper limit >= than lower limit */
-
- /* Calculate matrixs do convert between coordinate spaces */
- if (smd->origin != NULL) {
- transf = &tmp_transf;
- BLI_SPACE_TRANSFORM_SETUP(transf, ob, smd->origin);
- }
-
- /* Update limits if needed */
- int limit_axis = deform_axis;
- if (smd->mode == MOD_SIMPLEDEFORM_MODE_BEND) {
- /* Bend is a special case. */
- switch (deform_axis) {
- case 0:
- ATTR_FALLTHROUGH;
- case 1:
- limit_axis = 2;
- break;
- default:
- limit_axis = 0;
- }
- }
-
- {
- float lower = FLT_MAX;
- float upper = -FLT_MAX;
-
- for (i = 0; i < numVerts; i++) {
- float tmp[3];
- copy_v3_v3(tmp, vertexCos[i]);
-
- if (transf) {
- BLI_space_transform_apply(transf, tmp);
- }
-
- lower = min_ff(lower, tmp[limit_axis]);
- upper = max_ff(upper, tmp[limit_axis]);
- }
-
-
- /* SMD values are normalized to the BV, calculate the absolute values */
- smd_limit[1] = lower + (upper - lower) * smd->limit[1];
- smd_limit[0] = lower + (upper - lower) * smd->limit[0];
-
- smd_factor = smd->factor / max_ff(FLT_EPSILON, smd_limit[1] - smd_limit[0]);
- }
-
- switch (smd->mode) {
- case MOD_SIMPLEDEFORM_MODE_TWIST: simpleDeform_callback = simpleDeform_twist; break;
- case MOD_SIMPLEDEFORM_MODE_BEND: simpleDeform_callback = simpleDeform_bend; break;
- case MOD_SIMPLEDEFORM_MODE_TAPER: simpleDeform_callback = simpleDeform_taper; break;
- case MOD_SIMPLEDEFORM_MODE_STRETCH: simpleDeform_callback = simpleDeform_stretch; break;
- default:
- return; /* No simpledeform mode? */
- }
-
- if (smd->mode == MOD_SIMPLEDEFORM_MODE_BEND) {
- if (fabsf(smd_factor) < BEND_EPS) {
- return;
- }
- }
-
- MOD_get_vgroup(ob, mesh, smd->vgroup_name, &dvert, &vgroup);
- const bool invert_vgroup = (smd->flag & MOD_SIMPLEDEFORM_FLAG_INVERT_VGROUP) != 0;
- const uint *axis_map = axis_map_table[(smd->mode != MOD_SIMPLEDEFORM_MODE_BEND) ? deform_axis : 2];
-
- for (i = 0; i < numVerts; i++) {
- float weight = defvert_array_find_weight_safe(dvert, i, vgroup);
-
- if (invert_vgroup) {
- weight = 1.0f - weight;
- }
-
- if (weight != 0.0f) {
- float co[3], dcut[3] = {0.0f, 0.0f, 0.0f};
-
- if (transf) {
- BLI_space_transform_apply(transf, vertexCos[i]);
- }
-
- copy_v3_v3(co, vertexCos[i]);
-
- /* Apply axis limits, and axis mappings */
- if (lock_axis & MOD_SIMPLEDEFORM_LOCK_AXIS_X) {
- axis_limit(0, base_limit, co, dcut);
- }
- if (lock_axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Y) {
- axis_limit(1, base_limit, co, dcut);
- }
- if (lock_axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Z) {
- axis_limit(2, base_limit, co, dcut);
- }
- axis_limit(limit_axis, smd_limit, co, dcut);
-
- /* apply the deform to a mapped copy of the vertex, and then re-map it back. */
- float co_remap[3];
- float dcut_remap[3];
- copy_v3_v3_map(co_remap, co, axis_map);
- copy_v3_v3_map(dcut_remap, dcut, axis_map);
- simpleDeform_callback(smd_factor, deform_axis, dcut_remap, co_remap); /* apply deform */
- copy_v3_v3_unmap(co, co_remap, axis_map);
-
- interp_v3_v3v3(vertexCos[i], vertexCos[i], co, weight); /* Use vertex weight has coef of linear interpolation */
-
- if (transf) {
- BLI_space_transform_invert(transf, vertexCos[i]);
- }
- }
- }
+ const float base_limit[2] = {0.0f, 0.0f};
+ int i;
+ float smd_limit[2], smd_factor;
+ SpaceTransform *transf = NULL, tmp_transf;
+ void (*simpleDeform_callback)(const float factor,
+ const int axis,
+ const float dcut[3],
+ float co[3]) = NULL; /* Mode callback */
+ int vgroup;
+ MDeformVert *dvert;
+
+ /* This is historically the lock axis, _not_ the deform axis as the name would imply */
+ const int deform_axis = smd->deform_axis;
+ int lock_axis = smd->axis;
+ if (smd->mode == MOD_SIMPLEDEFORM_MODE_BEND) { /* Bend mode shouldn't have any lock axis */
+ lock_axis = 0;
+ }
+ else {
+ /* Don't lock axis if it is the chosen deform axis, as this flattens
+ * the geometry */
+ if (deform_axis == 0) {
+ lock_axis &= ~MOD_SIMPLEDEFORM_LOCK_AXIS_X;
+ }
+ if (deform_axis == 1) {
+ lock_axis &= ~MOD_SIMPLEDEFORM_LOCK_AXIS_Y;
+ }
+ if (deform_axis == 2) {
+ lock_axis &= ~MOD_SIMPLEDEFORM_LOCK_AXIS_Z;
+ }
+ }
+
+ /* Safe-check */
+ if (smd->origin == ob)
+ smd->origin = NULL; /* No self references */
+
+ if (smd->limit[0] < 0.0f)
+ smd->limit[0] = 0.0f;
+ if (smd->limit[0] > 1.0f)
+ smd->limit[0] = 1.0f;
+
+ smd->limit[0] = min_ff(smd->limit[0], smd->limit[1]); /* Upper limit >= than lower limit */
+
+ /* Calculate matrixs do convert between coordinate spaces */
+ if (smd->origin != NULL) {
+ transf = &tmp_transf;
+ BLI_SPACE_TRANSFORM_SETUP(transf, ob, smd->origin);
+ }
+
+ /* Update limits if needed */
+ int limit_axis = deform_axis;
+ if (smd->mode == MOD_SIMPLEDEFORM_MODE_BEND) {
+ /* Bend is a special case. */
+ switch (deform_axis) {
+ case 0:
+ ATTR_FALLTHROUGH;
+ case 1:
+ limit_axis = 2;
+ break;
+ default:
+ limit_axis = 0;
+ }
+ }
+
+ {
+ float lower = FLT_MAX;
+ float upper = -FLT_MAX;
+
+ for (i = 0; i < numVerts; i++) {
+ float tmp[3];
+ copy_v3_v3(tmp, vertexCos[i]);
+
+ if (transf) {
+ BLI_space_transform_apply(transf, tmp);
+ }
+
+ lower = min_ff(lower, tmp[limit_axis]);
+ upper = max_ff(upper, tmp[limit_axis]);
+ }
+
+ /* SMD values are normalized to the BV, calculate the absolute values */
+ smd_limit[1] = lower + (upper - lower) * smd->limit[1];
+ smd_limit[0] = lower + (upper - lower) * smd->limit[0];
+
+ smd_factor = smd->factor / max_ff(FLT_EPSILON, smd_limit[1] - smd_limit[0]);
+ }
+
+ switch (smd->mode) {
+ case MOD_SIMPLEDEFORM_MODE_TWIST:
+ simpleDeform_callback = simpleDeform_twist;
+ break;
+ case MOD_SIMPLEDEFORM_MODE_BEND:
+ simpleDeform_callback = simpleDeform_bend;
+ break;
+ case MOD_SIMPLEDEFORM_MODE_TAPER:
+ simpleDeform_callback = simpleDeform_taper;
+ break;
+ case MOD_SIMPLEDEFORM_MODE_STRETCH:
+ simpleDeform_callback = simpleDeform_stretch;
+ break;
+ default:
+ return; /* No simpledeform mode? */
+ }
+
+ if (smd->mode == MOD_SIMPLEDEFORM_MODE_BEND) {
+ if (fabsf(smd_factor) < BEND_EPS) {
+ return;
+ }
+ }
+
+ MOD_get_vgroup(ob, mesh, smd->vgroup_name, &dvert, &vgroup);
+ const bool invert_vgroup = (smd->flag & MOD_SIMPLEDEFORM_FLAG_INVERT_VGROUP) != 0;
+ const uint *axis_map =
+ axis_map_table[(smd->mode != MOD_SIMPLEDEFORM_MODE_BEND) ? deform_axis : 2];
+
+ for (i = 0; i < numVerts; i++) {
+ float weight = defvert_array_find_weight_safe(dvert, i, vgroup);
+
+ if (invert_vgroup) {
+ weight = 1.0f - weight;
+ }
+
+ if (weight != 0.0f) {
+ float co[3], dcut[3] = {0.0f, 0.0f, 0.0f};
+
+ if (transf) {
+ BLI_space_transform_apply(transf, vertexCos[i]);
+ }
+
+ copy_v3_v3(co, vertexCos[i]);
+
+ /* Apply axis limits, and axis mappings */
+ if (lock_axis & MOD_SIMPLEDEFORM_LOCK_AXIS_X) {
+ axis_limit(0, base_limit, co, dcut);
+ }
+ if (lock_axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Y) {
+ axis_limit(1, base_limit, co, dcut);
+ }
+ if (lock_axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Z) {
+ axis_limit(2, base_limit, co, dcut);
+ }
+ axis_limit(limit_axis, smd_limit, co, dcut);
+
+ /* apply the deform to a mapped copy of the vertex, and then re-map it back. */
+ float co_remap[3];
+ float dcut_remap[3];
+ copy_v3_v3_map(co_remap, co, axis_map);
+ copy_v3_v3_map(dcut_remap, dcut, axis_map);
+ simpleDeform_callback(smd_factor, deform_axis, dcut_remap, co_remap); /* apply deform */
+ copy_v3_v3_unmap(co, co_remap, axis_map);
+
+ interp_v3_v3v3(vertexCos[i],
+ vertexCos[i],
+ co,
+ weight); /* Use vertex weight has coef of linear interpolation */
+
+ if (transf) {
+ BLI_space_transform_invert(transf, vertexCos[i]);
+ }
+ }
+ }
}
-
/* SimpleDeform */
static void initData(ModifierData *md)
{
- SimpleDeformModifierData *smd = (SimpleDeformModifierData *) md;
+ SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
- smd->mode = MOD_SIMPLEDEFORM_MODE_TWIST;
- smd->axis = 0;
- smd->deform_axis = 0;
+ smd->mode = MOD_SIMPLEDEFORM_MODE_TWIST;
+ smd->axis = 0;
+ smd->deform_axis = 0;
- smd->origin = NULL;
- smd->factor = DEG2RADF(45.0f);
- smd->limit[0] = 0.0f;
- smd->limit[1] = 1.0f;
+ smd->origin = NULL;
+ smd->factor = DEG2RADF(45.0f);
+ smd->limit[0] = 0.0f;
+ smd->limit[1] = 1.0f;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
+ SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
- /* ask for vertexgroups if we need them */
- if (smd->vgroup_name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ /* ask for vertexgroups if we need them */
+ if (smd->vgroup_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
-static void foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
- walk(userData, ob, &smd->origin, IDWALK_CB_NOP);
+ SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
+ walk(userData, ob, &smd->origin, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
- if (smd->origin != NULL) {
- DEG_add_object_relation(ctx->node, smd->origin, DEG_OB_COMP_TRANSFORM, "SimpleDeform Modifier");
- DEG_add_modifier_to_transform_relation(ctx->node, "SimpleDeform Modifier");
- }
+ SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
+ if (smd->origin != NULL) {
+ DEG_add_object_relation(
+ ctx->node, smd->origin, DEG_OB_COMP_TRANSFORM, "SimpleDeform Modifier");
+ DEG_add_modifier_to_transform_relation(ctx->node, "SimpleDeform Modifier");
+ }
}
-static void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx,
- struct Mesh *mesh,
- float (*vertexCos)[3],
- int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- SimpleDeformModifierData *sdmd = (SimpleDeformModifierData *)md;
- Mesh *mesh_src = NULL;
+ SimpleDeformModifierData *sdmd = (SimpleDeformModifierData *)md;
+ Mesh *mesh_src = NULL;
- if (ctx->object->type == OB_MESH && sdmd->vgroup_name[0] != '\0') {
- /* mesh_src is only needed for vgroups. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
- }
+ if (ctx->object->type == OB_MESH && sdmd->vgroup_name[0] != '\0') {
+ /* mesh_src is only needed for vgroups. */
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ }
- SimpleDeformModifier_do(sdmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+ SimpleDeformModifier_do(sdmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-static void deformVertsEM(
- ModifierData *md, const ModifierEvalContext *ctx,
- struct BMEditMesh *editData,
- struct Mesh *mesh,
- float (*vertexCos)[3],
- int numVerts)
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *editData,
+ struct Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- SimpleDeformModifierData *sdmd = (SimpleDeformModifierData *)md;
- Mesh *mesh_src = NULL;
+ SimpleDeformModifierData *sdmd = (SimpleDeformModifierData *)md;
+ Mesh *mesh_src = NULL;
- if (ctx->object->type == OB_MESH && sdmd->vgroup_name[0] != '\0') {
- /* mesh_src is only needed for vgroups. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
- }
+ if (ctx->object->type == OB_MESH && sdmd->vgroup_name[0] != '\0') {
+ /* mesh_src is only needed for vgroups. */
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ }
- SimpleDeformModifier_do(sdmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+ SimpleDeformModifier_do(sdmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-
ModifierTypeInfo modifierType_SimpleDeform = {
- /* name */ "SimpleDeform",
- /* structName */ "SimpleDeformModifierData",
- /* structSize */ sizeof(SimpleDeformModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
-
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_AcceptsLattice |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_EnableInEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "SimpleDeform",
+ /* structName */ "SimpleDeformModifierData",
+ /* structSize */ sizeof(SimpleDeformModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs |
+ eModifierTypeFlag_AcceptsLattice | eModifierTypeFlag_SupportsEditmode |
+ eModifierTypeFlag_EnableInEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index dab2d72133b..ffef1197491 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -76,262 +76,249 @@
#include "bmesh.h"
typedef struct {
- float mat[3][3];
- /* Vert that edge is pointing away from, no relation to
- * MEdge.v1 */
- int origin;
+ float mat[3][3];
+ /* Vert that edge is pointing away from, no relation to
+ * MEdge.v1 */
+ int origin;
} EMat;
typedef enum {
- CAP_START = 1,
- CAP_END = 2,
- SEAM_FRAME = 4,
- ROOT = 8,
+ CAP_START = 1,
+ CAP_END = 2,
+ SEAM_FRAME = 4,
+ ROOT = 8,
} SkinNodeFlag;
typedef struct Frame {
- /* Index in the MVert array */
- BMVert *verts[4];
- /* Location of each corner */
- float co[4][3];
- /* Indicates which corners have been merged with another
- * frame's corner (so they share an MVert index) */
- struct {
- /* Merge to target frame/corner (no merge if frame is null) */
- struct Frame *frame;
- int corner;
- /* checked to avoid chaining.
- * (merging when we're already been referenced), see T39775 */
- unsigned int is_target : 1;
- } merge[4];
-
- /* For hull frames, whether each vertex is detached or not */
- bool inside_hull[4];
- /* Whether any part of the frame (corner or edge) is detached */
- bool detached;
+ /* Index in the MVert array */
+ BMVert *verts[4];
+ /* Location of each corner */
+ float co[4][3];
+ /* Indicates which corners have been merged with another
+ * frame's corner (so they share an MVert index) */
+ struct {
+ /* Merge to target frame/corner (no merge if frame is null) */
+ struct Frame *frame;
+ int corner;
+ /* checked to avoid chaining.
+ * (merging when we're already been referenced), see T39775 */
+ unsigned int is_target : 1;
+ } merge[4];
+
+ /* For hull frames, whether each vertex is detached or not */
+ bool inside_hull[4];
+ /* Whether any part of the frame (corner or edge) is detached */
+ bool detached;
} Frame;
#define MAX_SKIN_NODE_FRAMES 2
typedef struct {
- Frame frames[MAX_SKIN_NODE_FRAMES];
- int totframe;
+ Frame frames[MAX_SKIN_NODE_FRAMES];
+ int totframe;
- SkinNodeFlag flag;
+ SkinNodeFlag flag;
- /* Used for hulling a loop seam */
- int seam_edges[2];
+ /* Used for hulling a loop seam */
+ int seam_edges[2];
} SkinNode;
typedef struct {
- BMesh *bm;
- SkinModifierData *smd;
- int mat_nr;
+ BMesh *bm;
+ SkinModifierData *smd;
+ int mat_nr;
} SkinOutput;
-static void add_poly(
- SkinOutput *so,
- BMVert *v1,
- BMVert *v2,
- BMVert *v3,
- BMVert *v4);
+static void add_poly(SkinOutput *so, BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4);
/***************************** Convex Hull ****************************/
-static bool is_quad_symmetric(
- BMVert *quad[4],
- const SkinModifierData *smd)
+static bool is_quad_symmetric(BMVert *quad[4], const SkinModifierData *smd)
{
- const float threshold = 0.0001f;
- const float threshold_squared = threshold * threshold;
- int axis;
-
- for (axis = 0; axis < 3; axis++) {
- if (smd->symmetry_axes & (1 << axis)) {
- float a[3];
-
- copy_v3_v3(a, quad[0]->co);
- a[axis] = -a[axis];
-
- if (len_squared_v3v3(a, quad[1]->co) < threshold_squared) {
- copy_v3_v3(a, quad[2]->co);
- a[axis] = -a[axis];
- if (len_squared_v3v3(a, quad[3]->co) < threshold_squared)
- return 1;
- }
- else if (len_squared_v3v3(a, quad[3]->co) < threshold_squared) {
- copy_v3_v3(a, quad[2]->co);
- a[axis] = -a[axis];
- if (len_squared_v3v3(a, quad[1]->co) < threshold_squared)
- return 1;
- }
- }
- }
-
- return 0;
+ const float threshold = 0.0001f;
+ const float threshold_squared = threshold * threshold;
+ int axis;
+
+ for (axis = 0; axis < 3; axis++) {
+ if (smd->symmetry_axes & (1 << axis)) {
+ float a[3];
+
+ copy_v3_v3(a, quad[0]->co);
+ a[axis] = -a[axis];
+
+ if (len_squared_v3v3(a, quad[1]->co) < threshold_squared) {
+ copy_v3_v3(a, quad[2]->co);
+ a[axis] = -a[axis];
+ if (len_squared_v3v3(a, quad[3]->co) < threshold_squared)
+ return 1;
+ }
+ else if (len_squared_v3v3(a, quad[3]->co) < threshold_squared) {
+ copy_v3_v3(a, quad[2]->co);
+ a[axis] = -a[axis];
+ if (len_squared_v3v3(a, quad[1]->co) < threshold_squared)
+ return 1;
+ }
+ }
+ }
+
+ return 0;
}
/* Returns true if the quad crosses the plane of symmetry, false otherwise */
-static bool quad_crosses_symmetry_plane(
- BMVert *quad[4],
- const SkinModifierData *smd)
+static bool quad_crosses_symmetry_plane(BMVert *quad[4], const SkinModifierData *smd)
{
- int axis;
-
- for (axis = 0; axis < 3; axis++) {
- if (smd->symmetry_axes & (1 << axis)) {
- bool left = false, right = false;
- int i;
-
- for (i = 0; i < 4; i++) {
- if (quad[i]->co[axis] < 0.0f)
- left = true;
- else if (quad[i]->co[axis] > 0.0f)
- right = true;
-
- if (left && right)
- return true;
- }
- }
- }
-
- return false;
+ int axis;
+
+ for (axis = 0; axis < 3; axis++) {
+ if (smd->symmetry_axes & (1 << axis)) {
+ bool left = false, right = false;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (quad[i]->co[axis] < 0.0f)
+ left = true;
+ else if (quad[i]->co[axis] > 0.0f)
+ right = true;
+
+ if (left && right)
+ return true;
+ }
+ }
+ }
+
+ return false;
}
/* Returns true if the frame is filled by precisely two faces (and
* outputs those faces to fill_faces), otherwise returns false. */
-static bool skin_frame_find_contained_faces(
- const Frame *frame,
- BMFace *fill_faces[2])
+static bool skin_frame_find_contained_faces(const Frame *frame, BMFace *fill_faces[2])
{
- BMEdge *diag;
+ BMEdge *diag;
- /* See if the frame is bisected by a diagonal edge */
- diag = BM_edge_exists(frame->verts[0], frame->verts[2]);
- if (!diag)
- diag = BM_edge_exists(frame->verts[1], frame->verts[3]);
+ /* See if the frame is bisected by a diagonal edge */
+ diag = BM_edge_exists(frame->verts[0], frame->verts[2]);
+ if (!diag)
+ diag = BM_edge_exists(frame->verts[1], frame->verts[3]);
- if (diag)
- return BM_edge_face_pair(diag, &fill_faces[0], &fill_faces[1]);
- else
- return false;
+ if (diag)
+ return BM_edge_face_pair(diag, &fill_faces[0], &fill_faces[1]);
+ else
+ return false;
}
/* Returns true if hull is successfully built, false otherwise */
static bool build_hull(SkinOutput *so, Frame **frames, int totframe)
{
#ifdef WITH_BULLET
- BMesh *bm = so->bm;
- BMOperator op;
- BMIter iter;
- BMOIter oiter;
- BMVert *v;
- BMFace *f;
- BMEdge *e;
- int i, j;
-
- BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false);
-
- for (i = 0; i < totframe; i++) {
- for (j = 0; j < 4; j++) {
- BM_elem_flag_enable(frames[i]->verts[j], BM_ELEM_TAG);
- }
- }
-
- /* Deselect all faces so that only new hull output faces are
- * selected after the operator is run */
- BM_mesh_elem_hflag_disable_all(bm, BM_ALL_NOLOOP, BM_ELEM_SELECT, false);
-
- BMO_op_initf(bm, &op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
- "convex_hull input=%hv", BM_ELEM_TAG);
- BMO_op_exec(bm, &op);
-
- if (BMO_error_occurred(bm)) {
- BMO_op_finish(bm, &op);
- return false;
- }
-
- /* Apply face attributes to hull output */
- BMO_ITER (f, &oiter, op.slots_out, "geom.out", BM_FACE) {
- BM_face_normal_update(f);
- if (so->smd->flag & MOD_SKIN_SMOOTH_SHADING)
- BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
- f->mat_nr = so->mat_nr;
- }
-
- /* Mark interior frames */
- BMO_ITER (v, &oiter, op.slots_out, "geom_interior.out", BM_VERT) {
- for (i = 0; i < totframe; i++) {
- Frame *frame = frames[i];
-
- if (!frame->detached) {
- for (j = 0; j < 4; j++) {
- if (frame->verts[j] == v) {
- frame->inside_hull[j] = true;
- frame->detached = true;
- break;
- }
- }
- }
- }
- }
-
- /* Also mark frames as interior if an edge is not in the hull */
- for (i = 0; i < totframe; i++) {
- Frame *frame = frames[i];
-
- if (!frame->detached &&
- (!BM_edge_exists(frame->verts[0], frame->verts[1]) ||
- !BM_edge_exists(frame->verts[1], frame->verts[2]) ||
- !BM_edge_exists(frame->verts[2], frame->verts[3]) ||
- !BM_edge_exists(frame->verts[3], frame->verts[0])))
- {
- frame->detached = true;
- }
- }
-
- /* Remove triangles that would fill the original frames -- skip if
- * frame is partially detached */
- BM_mesh_elem_hflag_disable_all(bm, BM_ALL_NOLOOP, BM_ELEM_TAG, false);
- for (i = 0; i < totframe; i++) {
- Frame *frame = frames[i];
- if (!frame->detached) {
- BMFace *fill_faces[2];
-
- /* Check if the frame is filled by precisely two
- * triangles. If so, delete the triangles and their shared
- * edge. Otherwise, give up and mark the frame as
- * detached. */
- if (skin_frame_find_contained_faces(frame, fill_faces)) {
- BM_elem_flag_enable(fill_faces[0], BM_ELEM_TAG);
- BM_elem_flag_enable(fill_faces[1], BM_ELEM_TAG);
- }
- else
- frame->detached = true;
- }
- }
-
- /* Check if removing triangles above will create wire triangles,
- * mark them too */
- BMO_ITER (e, &oiter, op.slots_out, "geom.out", BM_EDGE) {
- bool is_wire = true;
- BM_ITER_ELEM (f, &iter, e, BM_FACES_OF_EDGE) {
- if (!BM_elem_flag_test(f, BM_ELEM_TAG)) {
- is_wire = false;
- break;
- }
- }
- if (is_wire)
- BM_elem_flag_enable(e, BM_ELEM_TAG);
- }
-
- BMO_op_finish(bm, &op);
-
- BM_mesh_delete_hflag_tagged(bm, BM_ELEM_TAG, BM_EDGE | BM_FACE);
-
- return true;
+ BMesh *bm = so->bm;
+ BMOperator op;
+ BMIter iter;
+ BMOIter oiter;
+ BMVert *v;
+ BMFace *f;
+ BMEdge *e;
+ int i, j;
+
+ BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false);
+
+ for (i = 0; i < totframe; i++) {
+ for (j = 0; j < 4; j++) {
+ BM_elem_flag_enable(frames[i]->verts[j], BM_ELEM_TAG);
+ }
+ }
+
+ /* Deselect all faces so that only new hull output faces are
+ * selected after the operator is run */
+ BM_mesh_elem_hflag_disable_all(bm, BM_ALL_NOLOOP, BM_ELEM_SELECT, false);
+
+ BMO_op_initf(
+ bm, &op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE), "convex_hull input=%hv", BM_ELEM_TAG);
+ BMO_op_exec(bm, &op);
+
+ if (BMO_error_occurred(bm)) {
+ BMO_op_finish(bm, &op);
+ return false;
+ }
+
+ /* Apply face attributes to hull output */
+ BMO_ITER (f, &oiter, op.slots_out, "geom.out", BM_FACE) {
+ BM_face_normal_update(f);
+ if (so->smd->flag & MOD_SKIN_SMOOTH_SHADING)
+ BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
+ f->mat_nr = so->mat_nr;
+ }
+
+ /* Mark interior frames */
+ BMO_ITER (v, &oiter, op.slots_out, "geom_interior.out", BM_VERT) {
+ for (i = 0; i < totframe; i++) {
+ Frame *frame = frames[i];
+
+ if (!frame->detached) {
+ for (j = 0; j < 4; j++) {
+ if (frame->verts[j] == v) {
+ frame->inside_hull[j] = true;
+ frame->detached = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* Also mark frames as interior if an edge is not in the hull */
+ for (i = 0; i < totframe; i++) {
+ Frame *frame = frames[i];
+
+ if (!frame->detached && (!BM_edge_exists(frame->verts[0], frame->verts[1]) ||
+ !BM_edge_exists(frame->verts[1], frame->verts[2]) ||
+ !BM_edge_exists(frame->verts[2], frame->verts[3]) ||
+ !BM_edge_exists(frame->verts[3], frame->verts[0]))) {
+ frame->detached = true;
+ }
+ }
+
+ /* Remove triangles that would fill the original frames -- skip if
+ * frame is partially detached */
+ BM_mesh_elem_hflag_disable_all(bm, BM_ALL_NOLOOP, BM_ELEM_TAG, false);
+ for (i = 0; i < totframe; i++) {
+ Frame *frame = frames[i];
+ if (!frame->detached) {
+ BMFace *fill_faces[2];
+
+ /* Check if the frame is filled by precisely two
+ * triangles. If so, delete the triangles and their shared
+ * edge. Otherwise, give up and mark the frame as
+ * detached. */
+ if (skin_frame_find_contained_faces(frame, fill_faces)) {
+ BM_elem_flag_enable(fill_faces[0], BM_ELEM_TAG);
+ BM_elem_flag_enable(fill_faces[1], BM_ELEM_TAG);
+ }
+ else
+ frame->detached = true;
+ }
+ }
+
+ /* Check if removing triangles above will create wire triangles,
+ * mark them too */
+ BMO_ITER (e, &oiter, op.slots_out, "geom.out", BM_EDGE) {
+ bool is_wire = true;
+ BM_ITER_ELEM (f, &iter, e, BM_FACES_OF_EDGE) {
+ if (!BM_elem_flag_test(f, BM_ELEM_TAG)) {
+ is_wire = false;
+ break;
+ }
+ }
+ if (is_wire)
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ }
+
+ BMO_op_finish(bm, &op);
+
+ BM_mesh_delete_hflag_tagged(bm, BM_ELEM_TAG, BM_EDGE | BM_FACE);
+
+ return true;
#else
- UNUSED_VARS(so, frames, totframe, skin_frame_find_contained_faces);
- return false;
+ UNUSED_VARS(so, frames, totframe, skin_frame_find_contained_faces);
+ return false;
#endif
}
@@ -339,428 +326,421 @@ static bool build_hull(SkinOutput *so, Frame **frames, int totframe)
* just the average of two adjacent edge lengths) */
static float frame_len(const Frame *frame)
{
- return (len_v3v3(frame->co[0], frame->co[1]) +
- len_v3v3(frame->co[1], frame->co[2])) * 0.5f;
+ return (len_v3v3(frame->co[0], frame->co[1]) + len_v3v3(frame->co[1], frame->co[2])) * 0.5f;
}
static void merge_frame_corners(Frame **frames, int totframe)
{
- float dist, side_a, side_b, thresh, mid[3];
- int i, j, k, l;
-
- for (i = 0; i < totframe; i++) {
- side_a = frame_len(frames[i]);
-
- /* For each corner of each frame... */
- for (j = 0; j < 4; j++) {
-
- /* Ensure the merge target is not itself a merge target */
- if (frames[i]->merge[j].frame)
- continue;
-
- for (k = i + 1; k < totframe; k++) {
- BLI_assert(frames[i] != frames[k]);
-
- side_b = frame_len(frames[k]);
- thresh = min_ff(side_a, side_b) / 2.0f;
-
- /* Compare with each corner of all other frames... */
- for (l = 0; l < 4; l++) {
- if (frames[k]->merge[l].frame || frames[k]->merge[l].is_target)
- continue;
-
- /* Some additional concerns that could be checked
- * further:
- *
- * + Vertex coords are being used for the
- * edge-length test, but are also being
- * modified, might cause symmetry problems.
- *
- * + A frame could be merged diagonally across
- * another, would generate a weird (bad) T
- * junction
- */
-
- /* Check if corners are near each other, where
- * 'near' is based in the frames' minimum side
- * length */
- dist = len_v3v3(frames[i]->co[j],
- frames[k]->co[l]);
- if (dist < thresh) {
- mid_v3_v3v3(mid,
- frames[i]->co[j],
- frames[k]->co[l]);
-
- copy_v3_v3(frames[i]->co[j], mid);
- copy_v3_v3(frames[k]->co[l], mid);
-
- frames[k]->merge[l].frame = frames[i];
- frames[k]->merge[l].corner = j;
- frames[i]->merge[j].is_target = true;
-
- /* Can't merge another corner into the same
- * frame corner, so move on to frame k+1 */
- break;
- }
- }
- }
- }
- }
+ float dist, side_a, side_b, thresh, mid[3];
+ int i, j, k, l;
+
+ for (i = 0; i < totframe; i++) {
+ side_a = frame_len(frames[i]);
+
+ /* For each corner of each frame... */
+ for (j = 0; j < 4; j++) {
+
+ /* Ensure the merge target is not itself a merge target */
+ if (frames[i]->merge[j].frame)
+ continue;
+
+ for (k = i + 1; k < totframe; k++) {
+ BLI_assert(frames[i] != frames[k]);
+
+ side_b = frame_len(frames[k]);
+ thresh = min_ff(side_a, side_b) / 2.0f;
+
+ /* Compare with each corner of all other frames... */
+ for (l = 0; l < 4; l++) {
+ if (frames[k]->merge[l].frame || frames[k]->merge[l].is_target)
+ continue;
+
+ /* Some additional concerns that could be checked
+ * further:
+ *
+ * + Vertex coords are being used for the
+ * edge-length test, but are also being
+ * modified, might cause symmetry problems.
+ *
+ * + A frame could be merged diagonally across
+ * another, would generate a weird (bad) T
+ * junction
+ */
+
+ /* Check if corners are near each other, where
+ * 'near' is based in the frames' minimum side
+ * length */
+ dist = len_v3v3(frames[i]->co[j], frames[k]->co[l]);
+ if (dist < thresh) {
+ mid_v3_v3v3(mid, frames[i]->co[j], frames[k]->co[l]);
+
+ copy_v3_v3(frames[i]->co[j], mid);
+ copy_v3_v3(frames[k]->co[l], mid);
+
+ frames[k]->merge[l].frame = frames[i];
+ frames[k]->merge[l].corner = j;
+ frames[i]->merge[j].is_target = true;
+
+ /* Can't merge another corner into the same
+ * frame corner, so move on to frame k+1 */
+ break;
+ }
+ }
+ }
+ }
+ }
}
static Frame **collect_hull_frames(
- int v, SkinNode *frames,
- const MeshElemMap *emap, const MEdge *medge,
- int *tothullframe)
+ int v, SkinNode *frames, const MeshElemMap *emap, const MEdge *medge, int *tothullframe)
{
- SkinNode *f;
- Frame **hull_frames;
- int nbr, i;
-
- (*tothullframe) = emap[v].count;
- hull_frames = MEM_calloc_arrayN((*tothullframe), sizeof(Frame *),
- "hull_from_frames.hull_frames");
- i = 0;
- for (nbr = 0; nbr < emap[v].count; nbr++) {
- const MEdge *e = &medge[emap[v].indices[nbr]];
- f = &frames[BKE_mesh_edge_other_vert(e, v)];
- /* Can't have adjacent branch nodes yet */
- if (f->totframe)
- hull_frames[i++] = &f->frames[0];
- else
- (*tothullframe)--;
- }
-
- return hull_frames;
+ SkinNode *f;
+ Frame **hull_frames;
+ int nbr, i;
+
+ (*tothullframe) = emap[v].count;
+ hull_frames = MEM_calloc_arrayN(
+ (*tothullframe), sizeof(Frame *), "hull_from_frames.hull_frames");
+ i = 0;
+ for (nbr = 0; nbr < emap[v].count; nbr++) {
+ const MEdge *e = &medge[emap[v].indices[nbr]];
+ f = &frames[BKE_mesh_edge_other_vert(e, v)];
+ /* Can't have adjacent branch nodes yet */
+ if (f->totframe)
+ hull_frames[i++] = &f->frames[0];
+ else
+ (*tothullframe)--;
+ }
+
+ return hull_frames;
}
-
/**************************** Create Frames ***************************/
static void node_frames_init(SkinNode *nf, int totframe)
{
- int i;
+ int i;
- nf->totframe = totframe;
- memset(nf->frames, 0, sizeof(nf->frames));
+ nf->totframe = totframe;
+ memset(nf->frames, 0, sizeof(nf->frames));
- nf->flag = 0;
- for (i = 0; i < 2; i++)
- nf->seam_edges[i] = -1;
+ nf->flag = 0;
+ for (i = 0; i < 2; i++)
+ nf->seam_edges[i] = -1;
}
static void create_frame(
- Frame *frame, const float co[3],
- const float radius[2],
- float mat[3][3], float offset)
+ Frame *frame, const float co[3], const float radius[2], float mat[3][3], float offset)
{
- float rx[3], ry[3], rz[3];
- int i;
+ float rx[3], ry[3], rz[3];
+ int i;
- mul_v3_v3fl(ry, mat[1], radius[0]);
- mul_v3_v3fl(rz, mat[2], radius[1]);
+ mul_v3_v3fl(ry, mat[1], radius[0]);
+ mul_v3_v3fl(rz, mat[2], radius[1]);
- add_v3_v3v3(frame->co[3], co, ry);
- add_v3_v3v3(frame->co[3], frame->co[3], rz);
+ add_v3_v3v3(frame->co[3], co, ry);
+ add_v3_v3v3(frame->co[3], frame->co[3], rz);
- sub_v3_v3v3(frame->co[2], co, ry);
- add_v3_v3v3(frame->co[2], frame->co[2], rz);
+ sub_v3_v3v3(frame->co[2], co, ry);
+ add_v3_v3v3(frame->co[2], frame->co[2], rz);
- sub_v3_v3v3(frame->co[1], co, ry);
- sub_v3_v3v3(frame->co[1], frame->co[1], rz);
+ sub_v3_v3v3(frame->co[1], co, ry);
+ sub_v3_v3v3(frame->co[1], frame->co[1], rz);
- add_v3_v3v3(frame->co[0], co, ry);
- sub_v3_v3v3(frame->co[0], frame->co[0], rz);
+ add_v3_v3v3(frame->co[0], co, ry);
+ sub_v3_v3v3(frame->co[0], frame->co[0], rz);
- mul_v3_v3fl(rx, mat[0], offset);
- for (i = 0; i < 4; i++)
- add_v3_v3v3(frame->co[i], frame->co[i], rx);
+ mul_v3_v3fl(rx, mat[0], offset);
+ for (i = 0; i < 4; i++)
+ add_v3_v3v3(frame->co[i], frame->co[i], rx);
}
static float half_v2(const float v[2])
{
- return (v[0] + v[1]) * 0.5f;
+ return (v[0] + v[1]) * 0.5f;
}
-static void end_node_frames(
- int v, SkinNode *skin_nodes, const MVert *mvert,
- const MVertSkin *nodes, const MeshElemMap *emap,
- EMat *emat)
+static void end_node_frames(int v,
+ SkinNode *skin_nodes,
+ const MVert *mvert,
+ const MVertSkin *nodes,
+ const MeshElemMap *emap,
+ EMat *emat)
{
- const float *rad = nodes[v].radius;
- float mat[3][3];
-
- if (emap[v].count == 0) {
- float avg = half_v2(rad);
-
- /* For solitary nodes, just build a box (two frames) */
- node_frames_init(&skin_nodes[v], 2);
- skin_nodes[v].flag |= (CAP_START | CAP_END);
-
- /* Hardcoded basis */
- zero_m3(mat);
- mat[0][2] = mat[1][0] = mat[2][1] = 1;
-
- /* Caps */
- create_frame(&skin_nodes[v].frames[0], mvert[v].co, rad, mat, avg);
- create_frame(&skin_nodes[v].frames[1], mvert[v].co, rad, mat, -avg);
- }
- else {
- /* For nodes with an incoming edge, create a single (capped) frame */
- node_frames_init(&skin_nodes[v], 1);
- skin_nodes[v].flag |= CAP_START;
-
- /* Use incoming edge for orientation */
- copy_m3_m3(mat, emat[emap[v].indices[0]].mat);
- if (emat[emap[v].indices[0]].origin != v)
- negate_v3(mat[0]);
-
- /* End frame */
- create_frame(&skin_nodes[v].frames[0], mvert[v].co, rad, mat, 0);
- }
-
- if (nodes[v].flag & MVERT_SKIN_ROOT)
- skin_nodes[v].flag |= ROOT;
+ const float *rad = nodes[v].radius;
+ float mat[3][3];
+
+ if (emap[v].count == 0) {
+ float avg = half_v2(rad);
+
+ /* For solitary nodes, just build a box (two frames) */
+ node_frames_init(&skin_nodes[v], 2);
+ skin_nodes[v].flag |= (CAP_START | CAP_END);
+
+ /* Hardcoded basis */
+ zero_m3(mat);
+ mat[0][2] = mat[1][0] = mat[2][1] = 1;
+
+ /* Caps */
+ create_frame(&skin_nodes[v].frames[0], mvert[v].co, rad, mat, avg);
+ create_frame(&skin_nodes[v].frames[1], mvert[v].co, rad, mat, -avg);
+ }
+ else {
+ /* For nodes with an incoming edge, create a single (capped) frame */
+ node_frames_init(&skin_nodes[v], 1);
+ skin_nodes[v].flag |= CAP_START;
+
+ /* Use incoming edge for orientation */
+ copy_m3_m3(mat, emat[emap[v].indices[0]].mat);
+ if (emat[emap[v].indices[0]].origin != v)
+ negate_v3(mat[0]);
+
+ /* End frame */
+ create_frame(&skin_nodes[v].frames[0], mvert[v].co, rad, mat, 0);
+ }
+
+ if (nodes[v].flag & MVERT_SKIN_ROOT)
+ skin_nodes[v].flag |= ROOT;
}
/* Returns 1 for seam, 0 otherwise */
static int connection_node_mat(float mat[3][3], int v, const MeshElemMap *emap, EMat *emat)
{
- float axis[3], angle, ine[3][3], oute[3][3];
- EMat *e1, *e2;
-
- e1 = &emat[emap[v].indices[0]];
- e2 = &emat[emap[v].indices[1]];
-
- if (e1->origin != v && e2->origin == v) {
- copy_m3_m3(ine, e1->mat);
- copy_m3_m3(oute, e2->mat);
- }
- else if (e1->origin == v && e2->origin != v) {
- copy_m3_m3(ine, e2->mat);
- copy_m3_m3(oute, e1->mat);
- }
- else
- return 1;
-
- /* Get axis and angle to rotate frame by */
- angle = angle_normalized_v3v3(ine[0], oute[0]) / 2.0f;
- cross_v3_v3v3(axis, ine[0], oute[0]);
- normalize_v3(axis);
-
- /* Build frame matrix (don't care about X axis here) */
- copy_v3_v3(mat[0], ine[0]);
- rotate_normalized_v3_v3v3fl(mat[1], ine[1], axis, angle);
- rotate_normalized_v3_v3v3fl(mat[2], ine[2], axis, angle);
-
- return 0;
+ float axis[3], angle, ine[3][3], oute[3][3];
+ EMat *e1, *e2;
+
+ e1 = &emat[emap[v].indices[0]];
+ e2 = &emat[emap[v].indices[1]];
+
+ if (e1->origin != v && e2->origin == v) {
+ copy_m3_m3(ine, e1->mat);
+ copy_m3_m3(oute, e2->mat);
+ }
+ else if (e1->origin == v && e2->origin != v) {
+ copy_m3_m3(ine, e2->mat);
+ copy_m3_m3(oute, e1->mat);
+ }
+ else
+ return 1;
+
+ /* Get axis and angle to rotate frame by */
+ angle = angle_normalized_v3v3(ine[0], oute[0]) / 2.0f;
+ cross_v3_v3v3(axis, ine[0], oute[0]);
+ normalize_v3(axis);
+
+ /* Build frame matrix (don't care about X axis here) */
+ copy_v3_v3(mat[0], ine[0]);
+ rotate_normalized_v3_v3v3fl(mat[1], ine[1], axis, angle);
+ rotate_normalized_v3_v3v3fl(mat[2], ine[2], axis, angle);
+
+ return 0;
}
-static void connection_node_frames(
- int v, SkinNode *skin_nodes, const MVert *mvert,
- const MVertSkin *nodes, const MeshElemMap *emap,
- EMat *emat)
+static void connection_node_frames(int v,
+ SkinNode *skin_nodes,
+ const MVert *mvert,
+ const MVertSkin *nodes,
+ const MeshElemMap *emap,
+ EMat *emat)
{
- const float *rad = nodes[v].radius;
- float mat[3][3];
- EMat *e1, *e2;
-
- if (connection_node_mat(mat, v, emap, emat)) {
- float avg = half_v2(rad);
-
- /* Get edges */
- e1 = &emat[emap[v].indices[0]];
- e2 = &emat[emap[v].indices[1]];
-
- /* Handle seam separately to avoid twisting */
- /* Create two frames, will be hulled to neighbors later */
- node_frames_init(&skin_nodes[v], 2);
- skin_nodes[v].flag |= SEAM_FRAME;
-
- copy_m3_m3(mat, e1->mat);
- if (e1->origin != v) negate_v3(mat[0]);
- create_frame(&skin_nodes[v].frames[0], mvert[v].co, rad, mat, avg);
- skin_nodes[v].seam_edges[0] = emap[v].indices[0];
-
- copy_m3_m3(mat, e2->mat);
- if (e2->origin != v) negate_v3(mat[0]);
- create_frame(&skin_nodes[v].frames[1], mvert[v].co, rad, mat, avg);
- skin_nodes[v].seam_edges[1] = emap[v].indices[1];
-
- return;
- }
-
- /* Build regular frame */
- node_frames_init(&skin_nodes[v], 1);
- create_frame(&skin_nodes[v].frames[0], mvert[v].co, rad, mat, 0);
+ const float *rad = nodes[v].radius;
+ float mat[3][3];
+ EMat *e1, *e2;
+
+ if (connection_node_mat(mat, v, emap, emat)) {
+ float avg = half_v2(rad);
+
+ /* Get edges */
+ e1 = &emat[emap[v].indices[0]];
+ e2 = &emat[emap[v].indices[1]];
+
+ /* Handle seam separately to avoid twisting */
+ /* Create two frames, will be hulled to neighbors later */
+ node_frames_init(&skin_nodes[v], 2);
+ skin_nodes[v].flag |= SEAM_FRAME;
+
+ copy_m3_m3(mat, e1->mat);
+ if (e1->origin != v)
+ negate_v3(mat[0]);
+ create_frame(&skin_nodes[v].frames[0], mvert[v].co, rad, mat, avg);
+ skin_nodes[v].seam_edges[0] = emap[v].indices[0];
+
+ copy_m3_m3(mat, e2->mat);
+ if (e2->origin != v)
+ negate_v3(mat[0]);
+ create_frame(&skin_nodes[v].frames[1], mvert[v].co, rad, mat, avg);
+ skin_nodes[v].seam_edges[1] = emap[v].indices[1];
+
+ return;
+ }
+
+ /* Build regular frame */
+ node_frames_init(&skin_nodes[v], 1);
+ create_frame(&skin_nodes[v].frames[0], mvert[v].co, rad, mat, 0);
}
static SkinNode *build_frames(
- const MVert *mvert, int totvert,
- const MVertSkin *nodes, const MeshElemMap *emap,
- EMat *emat)
+ const MVert *mvert, int totvert, const MVertSkin *nodes, const MeshElemMap *emap, EMat *emat)
{
- SkinNode *skin_nodes;
- int v;
-
- skin_nodes = MEM_calloc_arrayN(totvert, sizeof(SkinNode), "build_frames.skin_nodes");
-
- for (v = 0; v < totvert; v++) {
- if (emap[v].count <= 1)
- end_node_frames(v, skin_nodes, mvert, nodes, emap, emat);
- else if (emap[v].count == 2)
- connection_node_frames(v, skin_nodes, mvert, nodes, emap, emat);
- else {
- /* Branch node generates no frames */
- }
- }
-
- return skin_nodes;
+ SkinNode *skin_nodes;
+ int v;
+
+ skin_nodes = MEM_calloc_arrayN(totvert, sizeof(SkinNode), "build_frames.skin_nodes");
+
+ for (v = 0; v < totvert; v++) {
+ if (emap[v].count <= 1)
+ end_node_frames(v, skin_nodes, mvert, nodes, emap, emat);
+ else if (emap[v].count == 2)
+ connection_node_frames(v, skin_nodes, mvert, nodes, emap, emat);
+ else {
+ /* Branch node generates no frames */
+ }
+ }
+
+ return skin_nodes;
}
/**************************** Edge Matrices ***************************/
static void calc_edge_mat(float mat[3][3], const float a[3], const float b[3])
{
- const float z_up[3] = {0, 0, 1};
- float dot;
-
- /* X = edge direction */
- sub_v3_v3v3(mat[0], b, a);
- normalize_v3(mat[0]);
-
- dot = dot_v3v3(mat[0], z_up);
- if (dot > -1 + FLT_EPSILON && dot < 1 - FLT_EPSILON) {
- /* Y = Z cross x */
- cross_v3_v3v3(mat[1], z_up, mat[0]);
- normalize_v3(mat[1]);
-
- /* Z = x cross y */
- cross_v3_v3v3(mat[2], mat[0], mat[1]);
- normalize_v3(mat[2]);
- }
- else {
- mat[1][0] = 1;
- mat[1][1] = 0;
- mat[1][2] = 0;
- mat[2][0] = 0;
- mat[2][1] = 1;
- mat[2][2] = 0;
- }
+ const float z_up[3] = {0, 0, 1};
+ float dot;
+
+ /* X = edge direction */
+ sub_v3_v3v3(mat[0], b, a);
+ normalize_v3(mat[0]);
+
+ dot = dot_v3v3(mat[0], z_up);
+ if (dot > -1 + FLT_EPSILON && dot < 1 - FLT_EPSILON) {
+ /* Y = Z cross x */
+ cross_v3_v3v3(mat[1], z_up, mat[0]);
+ normalize_v3(mat[1]);
+
+ /* Z = x cross y */
+ cross_v3_v3v3(mat[2], mat[0], mat[1]);
+ normalize_v3(mat[2]);
+ }
+ else {
+ mat[1][0] = 1;
+ mat[1][1] = 0;
+ mat[1][2] = 0;
+ mat[2][0] = 0;
+ mat[2][1] = 1;
+ mat[2][2] = 0;
+ }
}
typedef struct {
- float mat[3][3];
- int parent_v;
- int e;
+ float mat[3][3];
+ int parent_v;
+ int e;
} EdgeStackElem;
-static void build_emats_stack(
- BLI_Stack *stack, BLI_bitmap *visited_e, EMat *emat,
- const MeshElemMap *emap, const MEdge *medge,
- const MVertSkin *vs, const MVert *mvert)
+static void build_emats_stack(BLI_Stack *stack,
+ BLI_bitmap *visited_e,
+ EMat *emat,
+ const MeshElemMap *emap,
+ const MEdge *medge,
+ const MVertSkin *vs,
+ const MVert *mvert)
{
- EdgeStackElem stack_elem;
- float axis[3], angle;
- int i, e, v, parent_v, parent_is_branch;
-
- BLI_stack_pop(stack, &stack_elem);
- parent_v = stack_elem.parent_v;
- e = stack_elem.e;
-
- /* Skip if edge already visited */
- if (BLI_BITMAP_TEST(visited_e, e))
- return;
-
- /* Mark edge as visited */
- BLI_BITMAP_ENABLE(visited_e, e);
-
- /* Process edge */
-
- parent_is_branch = ((emap[parent_v].count > 2) ||
- (vs[parent_v].flag & MVERT_SKIN_ROOT));
-
- v = BKE_mesh_edge_other_vert(&medge[e], parent_v);
- emat[e].origin = parent_v;
-
- /* If parent is a branch node, start a new edge chain */
- if (parent_is_branch) {
- calc_edge_mat(emat[e].mat, mvert[parent_v].co,
- mvert[v].co);
- }
- else {
- /* Build edge matrix guided by parent matrix */
- sub_v3_v3v3(emat[e].mat[0], mvert[v].co, mvert[parent_v].co);
- normalize_v3(emat[e].mat[0]);
- angle = angle_normalized_v3v3(stack_elem.mat[0], emat[e].mat[0]);
- cross_v3_v3v3(axis, stack_elem.mat[0], emat[e].mat[0]);
- normalize_v3(axis);
- rotate_normalized_v3_v3v3fl(emat[e].mat[1], stack_elem.mat[1], axis, angle);
- rotate_normalized_v3_v3v3fl(emat[e].mat[2], stack_elem.mat[2], axis, angle);
- }
-
- /* Add neighbors to stack */
- for (i = 0; i < emap[v].count; i++) {
- /* Add neighbors to stack */
- copy_m3_m3(stack_elem.mat, emat[e].mat);
- stack_elem.e = emap[v].indices[i];
- stack_elem.parent_v = v;
- BLI_stack_push(stack, &stack_elem);
- }
+ EdgeStackElem stack_elem;
+ float axis[3], angle;
+ int i, e, v, parent_v, parent_is_branch;
+
+ BLI_stack_pop(stack, &stack_elem);
+ parent_v = stack_elem.parent_v;
+ e = stack_elem.e;
+
+ /* Skip if edge already visited */
+ if (BLI_BITMAP_TEST(visited_e, e))
+ return;
+
+ /* Mark edge as visited */
+ BLI_BITMAP_ENABLE(visited_e, e);
+
+ /* Process edge */
+
+ parent_is_branch = ((emap[parent_v].count > 2) || (vs[parent_v].flag & MVERT_SKIN_ROOT));
+
+ v = BKE_mesh_edge_other_vert(&medge[e], parent_v);
+ emat[e].origin = parent_v;
+
+ /* If parent is a branch node, start a new edge chain */
+ if (parent_is_branch) {
+ calc_edge_mat(emat[e].mat, mvert[parent_v].co, mvert[v].co);
+ }
+ else {
+ /* Build edge matrix guided by parent matrix */
+ sub_v3_v3v3(emat[e].mat[0], mvert[v].co, mvert[parent_v].co);
+ normalize_v3(emat[e].mat[0]);
+ angle = angle_normalized_v3v3(stack_elem.mat[0], emat[e].mat[0]);
+ cross_v3_v3v3(axis, stack_elem.mat[0], emat[e].mat[0]);
+ normalize_v3(axis);
+ rotate_normalized_v3_v3v3fl(emat[e].mat[1], stack_elem.mat[1], axis, angle);
+ rotate_normalized_v3_v3v3fl(emat[e].mat[2], stack_elem.mat[2], axis, angle);
+ }
+
+ /* Add neighbors to stack */
+ for (i = 0; i < emap[v].count; i++) {
+ /* Add neighbors to stack */
+ copy_m3_m3(stack_elem.mat, emat[e].mat);
+ stack_elem.e = emap[v].indices[i];
+ stack_elem.parent_v = v;
+ BLI_stack_push(stack, &stack_elem);
+ }
}
-static EMat *build_edge_mats(
- const MVertSkin *vs,
- const MVert *mvert,
- int totvert,
- const MEdge *medge,
- const MeshElemMap *emap,
- int totedge,
- bool *has_valid_root)
+static EMat *build_edge_mats(const MVertSkin *vs,
+ const MVert *mvert,
+ int totvert,
+ const MEdge *medge,
+ const MeshElemMap *emap,
+ int totedge,
+ bool *has_valid_root)
{
- BLI_Stack *stack;
- EMat *emat;
- EdgeStackElem stack_elem;
- BLI_bitmap *visited_e;
- int i, v;
-
- stack = BLI_stack_new(sizeof(stack_elem), "build_edge_mats.stack");
-
- visited_e = BLI_BITMAP_NEW(totedge, "build_edge_mats.visited_e");
- emat = MEM_calloc_arrayN(totedge, sizeof(EMat), "build_edge_mats.emat");
-
- /* Edge matrices are built from the root nodes, add all roots with
- * children to the stack */
- for (v = 0; v < totvert; v++) {
- if (vs[v].flag & MVERT_SKIN_ROOT) {
- if (emap[v].count >= 1) {
- const MEdge *e = &medge[emap[v].indices[0]];
- calc_edge_mat(stack_elem.mat, mvert[v].co,
- mvert[BKE_mesh_edge_other_vert(e, v)].co);
- stack_elem.parent_v = v;
-
- /* Add adjacent edges to stack */
- for (i = 0; i < emap[v].count; i++) {
- stack_elem.e = emap[v].indices[i];
- BLI_stack_push(stack, &stack_elem);
- }
-
- *has_valid_root = true;
- }
- }
- }
-
- while (!BLI_stack_is_empty(stack)) {
- build_emats_stack(stack, visited_e, emat, emap, medge, vs, mvert);
- }
-
- MEM_freeN(visited_e);
- BLI_stack_free(stack);
-
- return emat;
+ BLI_Stack *stack;
+ EMat *emat;
+ EdgeStackElem stack_elem;
+ BLI_bitmap *visited_e;
+ int i, v;
+
+ stack = BLI_stack_new(sizeof(stack_elem), "build_edge_mats.stack");
+
+ visited_e = BLI_BITMAP_NEW(totedge, "build_edge_mats.visited_e");
+ emat = MEM_calloc_arrayN(totedge, sizeof(EMat), "build_edge_mats.emat");
+
+ /* Edge matrices are built from the root nodes, add all roots with
+ * children to the stack */
+ for (v = 0; v < totvert; v++) {
+ if (vs[v].flag & MVERT_SKIN_ROOT) {
+ if (emap[v].count >= 1) {
+ const MEdge *e = &medge[emap[v].indices[0]];
+ calc_edge_mat(stack_elem.mat, mvert[v].co, mvert[BKE_mesh_edge_other_vert(e, v)].co);
+ stack_elem.parent_v = v;
+
+ /* Add adjacent edges to stack */
+ for (i = 0; i < emap[v].count; i++) {
+ stack_elem.e = emap[v].indices[i];
+ BLI_stack_push(stack, &stack_elem);
+ }
+
+ *has_valid_root = true;
+ }
+ }
+ }
+
+ while (!BLI_stack_is_empty(stack)) {
+ build_emats_stack(stack, visited_e, emat, emap, medge, vs, mvert);
+ }
+
+ MEM_freeN(visited_e);
+ BLI_stack_free(stack);
+
+ return emat;
}
-
/************************** Input Subdivision *************************/
/* Returns number of edge subdivisions, taking into account the radius
@@ -768,54 +748,54 @@ static EMat *build_edge_mats(
* nodes, at least two intermediate frames are required. (This avoids
* having any special cases for dealing with sharing a frame between
* two hulls.) */
-static int calc_edge_subdivisions(
- const MVert *mvert, const MVertSkin *nodes,
- const MEdge *e, const int *degree)
+static int calc_edge_subdivisions(const MVert *mvert,
+ const MVertSkin *nodes,
+ const MEdge *e,
+ const int *degree)
{
- /* prevent memory errors [#38003] */
+ /* prevent memory errors [#38003] */
#define NUM_SUBDIVISIONS_MAX 128
- const MVertSkin *evs[2] = {&nodes[e->v1], &nodes[e->v2]};
- float avg_radius;
- const bool v1_branch = degree[e->v1] > 2;
- const bool v2_branch = degree[e->v2] > 2;
- int num_subdivisions;
-
- /* If either end is a branch node marked 'loose', don't subdivide
- * the edge (or subdivide just twice if both are branches) */
- if ((v1_branch && (evs[0]->flag & MVERT_SKIN_LOOSE)) ||
- (v2_branch && (evs[1]->flag & MVERT_SKIN_LOOSE)))
- {
- if (v1_branch && v2_branch)
- return 2;
- else
- return 0;
- }
-
- avg_radius = half_v2(evs[0]->radius) + half_v2(evs[1]->radius);
-
- if (avg_radius != 0.0f) {
- /* possible (but unlikely) that we overflow INT_MAX */
- float num_subdivisions_fl;
- const float edge_len = len_v3v3(mvert[e->v1].co, mvert[e->v2].co);
- num_subdivisions_fl = (edge_len / avg_radius);
- if (num_subdivisions_fl < NUM_SUBDIVISIONS_MAX) {
- num_subdivisions = (int)num_subdivisions_fl;
- }
- else {
- num_subdivisions = NUM_SUBDIVISIONS_MAX;
- }
- }
- else {
- num_subdivisions = 0;
- }
-
- /* If both ends are branch nodes, two intermediate nodes are
- * required */
- if (num_subdivisions < 2 && v1_branch && v2_branch)
- num_subdivisions = 2;
-
- return num_subdivisions;
+ const MVertSkin *evs[2] = {&nodes[e->v1], &nodes[e->v2]};
+ float avg_radius;
+ const bool v1_branch = degree[e->v1] > 2;
+ const bool v2_branch = degree[e->v2] > 2;
+ int num_subdivisions;
+
+ /* If either end is a branch node marked 'loose', don't subdivide
+ * the edge (or subdivide just twice if both are branches) */
+ if ((v1_branch && (evs[0]->flag & MVERT_SKIN_LOOSE)) ||
+ (v2_branch && (evs[1]->flag & MVERT_SKIN_LOOSE))) {
+ if (v1_branch && v2_branch)
+ return 2;
+ else
+ return 0;
+ }
+
+ avg_radius = half_v2(evs[0]->radius) + half_v2(evs[1]->radius);
+
+ if (avg_radius != 0.0f) {
+ /* possible (but unlikely) that we overflow INT_MAX */
+ float num_subdivisions_fl;
+ const float edge_len = len_v3v3(mvert[e->v1].co, mvert[e->v2].co);
+ num_subdivisions_fl = (edge_len / avg_radius);
+ if (num_subdivisions_fl < NUM_SUBDIVISIONS_MAX) {
+ num_subdivisions = (int)num_subdivisions_fl;
+ }
+ else {
+ num_subdivisions = NUM_SUBDIVISIONS_MAX;
+ }
+ }
+ else {
+ num_subdivisions = 0;
+ }
+
+ /* If both ends are branch nodes, two intermediate nodes are
+ * required */
+ if (num_subdivisions < 2 && v1_branch && v2_branch)
+ num_subdivisions = 2;
+
+ return num_subdivisions;
#undef NUM_SUBDIVISIONS_MAX
}
@@ -824,258 +804,235 @@ static int calc_edge_subdivisions(
* reasonably close. */
static Mesh *subdivide_base(Mesh *orig)
{
- Mesh *result;
- MVertSkin *orignode, *outnode;
- MVert *origvert, *outvert;
- MEdge *origedge, *outedge, *e;
- MDeformVert *origdvert, *outdvert;
- int totorigvert, totorigedge;
- int totsubd, *degree, *edge_subd;
- int i, j, k, u, v;
- float radrat;
-
- orignode = CustomData_get_layer(&orig->vdata, CD_MVERT_SKIN);
- origvert = orig->mvert;
- origedge = orig->medge;
- origdvert = orig->dvert;
- totorigvert = orig->totvert;
- totorigedge = orig->totedge;
-
- /* Get degree of all vertices */
- degree = MEM_calloc_arrayN(totorigvert, sizeof(int), "degree");
- for (i = 0; i < totorigedge; i++) {
- degree[origedge[i].v1]++;
- degree[origedge[i].v2]++;
- }
-
- /* Per edge, store how many subdivisions are needed */
- edge_subd = MEM_calloc_arrayN(totorigedge, sizeof(int), "edge_subd");
- for (i = 0, totsubd = 0; i < totorigedge; i++) {
- edge_subd[i] += calc_edge_subdivisions(origvert, orignode,
- &origedge[i], degree);
- BLI_assert(edge_subd[i] >= 0);
- totsubd += edge_subd[i];
- }
-
- MEM_freeN(degree);
-
- /* Allocate output mesh */
- result = BKE_mesh_new_nomain_from_template(
- orig,
- totorigvert + totsubd,
- totorigedge + totsubd,
- 0, 0, 0);
-
- outvert = result->mvert;
- outedge = result->medge;
- outnode = CustomData_get_layer(&result->vdata, CD_MVERT_SKIN);
- outdvert = result->dvert;
-
- /* Copy original vertex data */
- CustomData_copy_data(&orig->vdata,
- &result->vdata,
- 0, 0, totorigvert);
-
- /* Subdivide edges */
- for (i = 0, v = totorigvert; i < totorigedge; i++) {
- struct {
- /* Vertex group number */
- int def_nr;
- float w1, w2;
- } *vgroups = NULL, *vg;
- int totvgroup = 0;
-
- e = &origedge[i];
-
- if (origdvert) {
- const MDeformVert *dv1 = &origdvert[e->v1];
- const MDeformVert *dv2 = &origdvert[e->v2];
- vgroups = MEM_calloc_arrayN(dv1->totweight, sizeof(*vgroups), "vgroup");
-
- /* Only want vertex groups used by both vertices */
- for (j = 0; j < dv1->totweight; j++) {
- vg = NULL;
- for (k = 0; k < dv2->totweight; k++) {
- if (dv1->dw[j].def_nr == dv2->dw[k].def_nr) {
- vg = &vgroups[totvgroup];
- totvgroup++;
- break;
- }
- }
-
- if (vg) {
- vg->def_nr = dv1->dw[j].def_nr;
- vg->w1 = dv1->dw[j].weight;
- vg->w2 = dv2->dw[k].weight;
- }
- }
- }
-
- u = e->v1;
- radrat = (half_v2(outnode[e->v2].radius) /
- half_v2(outnode[e->v1].radius));
- radrat = (radrat + 1) / 2;
-
- /* Add vertices and edge segments */
- for (j = 0; j < edge_subd[i]; j++, v++, outedge++) {
- float r = (j + 1) / (float)(edge_subd[i] + 1);
- float t = powf(r, radrat);
-
- /* Interpolate vertex coord */
- interp_v3_v3v3(outvert[v].co, outvert[e->v1].co,
- outvert[e->v2].co, t);
-
- /* Interpolate skin radii */
- interp_v3_v3v3(outnode[v].radius,
- orignode[e->v1].radius,
- orignode[e->v2].radius, t);
-
- /* Interpolate vertex group weights */
- for (k = 0; k < totvgroup; k++) {
- float weight;
-
- vg = &vgroups[k];
- weight = interpf(vg->w2, vg->w1, t);
-
- if (weight > 0)
- defvert_add_index_notest(&outdvert[v], vg->def_nr, weight);
- }
-
- outedge->v1 = u;
- outedge->v2 = v;
- u = v;
- }
-
- if (vgroups)
- MEM_freeN(vgroups);
-
- /* Link up to final vertex */
- outedge->v1 = u;
- outedge->v2 = e->v2;
- outedge++;
- }
-
- MEM_freeN(edge_subd);
-
- return result;
+ Mesh *result;
+ MVertSkin *orignode, *outnode;
+ MVert *origvert, *outvert;
+ MEdge *origedge, *outedge, *e;
+ MDeformVert *origdvert, *outdvert;
+ int totorigvert, totorigedge;
+ int totsubd, *degree, *edge_subd;
+ int i, j, k, u, v;
+ float radrat;
+
+ orignode = CustomData_get_layer(&orig->vdata, CD_MVERT_SKIN);
+ origvert = orig->mvert;
+ origedge = orig->medge;
+ origdvert = orig->dvert;
+ totorigvert = orig->totvert;
+ totorigedge = orig->totedge;
+
+ /* Get degree of all vertices */
+ degree = MEM_calloc_arrayN(totorigvert, sizeof(int), "degree");
+ for (i = 0; i < totorigedge; i++) {
+ degree[origedge[i].v1]++;
+ degree[origedge[i].v2]++;
+ }
+
+ /* Per edge, store how many subdivisions are needed */
+ edge_subd = MEM_calloc_arrayN(totorigedge, sizeof(int), "edge_subd");
+ for (i = 0, totsubd = 0; i < totorigedge; i++) {
+ edge_subd[i] += calc_edge_subdivisions(origvert, orignode, &origedge[i], degree);
+ BLI_assert(edge_subd[i] >= 0);
+ totsubd += edge_subd[i];
+ }
+
+ MEM_freeN(degree);
+
+ /* Allocate output mesh */
+ result = BKE_mesh_new_nomain_from_template(
+ orig, totorigvert + totsubd, totorigedge + totsubd, 0, 0, 0);
+
+ outvert = result->mvert;
+ outedge = result->medge;
+ outnode = CustomData_get_layer(&result->vdata, CD_MVERT_SKIN);
+ outdvert = result->dvert;
+
+ /* Copy original vertex data */
+ CustomData_copy_data(&orig->vdata, &result->vdata, 0, 0, totorigvert);
+
+ /* Subdivide edges */
+ for (i = 0, v = totorigvert; i < totorigedge; i++) {
+ struct {
+ /* Vertex group number */
+ int def_nr;
+ float w1, w2;
+ } *vgroups = NULL, *vg;
+ int totvgroup = 0;
+
+ e = &origedge[i];
+
+ if (origdvert) {
+ const MDeformVert *dv1 = &origdvert[e->v1];
+ const MDeformVert *dv2 = &origdvert[e->v2];
+ vgroups = MEM_calloc_arrayN(dv1->totweight, sizeof(*vgroups), "vgroup");
+
+ /* Only want vertex groups used by both vertices */
+ for (j = 0; j < dv1->totweight; j++) {
+ vg = NULL;
+ for (k = 0; k < dv2->totweight; k++) {
+ if (dv1->dw[j].def_nr == dv2->dw[k].def_nr) {
+ vg = &vgroups[totvgroup];
+ totvgroup++;
+ break;
+ }
+ }
+
+ if (vg) {
+ vg->def_nr = dv1->dw[j].def_nr;
+ vg->w1 = dv1->dw[j].weight;
+ vg->w2 = dv2->dw[k].weight;
+ }
+ }
+ }
+
+ u = e->v1;
+ radrat = (half_v2(outnode[e->v2].radius) / half_v2(outnode[e->v1].radius));
+ radrat = (radrat + 1) / 2;
+
+ /* Add vertices and edge segments */
+ for (j = 0; j < edge_subd[i]; j++, v++, outedge++) {
+ float r = (j + 1) / (float)(edge_subd[i] + 1);
+ float t = powf(r, radrat);
+
+ /* Interpolate vertex coord */
+ interp_v3_v3v3(outvert[v].co, outvert[e->v1].co, outvert[e->v2].co, t);
+
+ /* Interpolate skin radii */
+ interp_v3_v3v3(outnode[v].radius, orignode[e->v1].radius, orignode[e->v2].radius, t);
+
+ /* Interpolate vertex group weights */
+ for (k = 0; k < totvgroup; k++) {
+ float weight;
+
+ vg = &vgroups[k];
+ weight = interpf(vg->w2, vg->w1, t);
+
+ if (weight > 0)
+ defvert_add_index_notest(&outdvert[v], vg->def_nr, weight);
+ }
+
+ outedge->v1 = u;
+ outedge->v2 = v;
+ u = v;
+ }
+
+ if (vgroups)
+ MEM_freeN(vgroups);
+
+ /* Link up to final vertex */
+ outedge->v1 = u;
+ outedge->v2 = e->v2;
+ outedge++;
+ }
+
+ MEM_freeN(edge_subd);
+
+ return result;
}
/******************************* Output *******************************/
/* Can be either quad or triangle */
-static void add_poly(
- SkinOutput *so,
- BMVert *v1,
- BMVert *v2,
- BMVert *v3,
- BMVert *v4)
+static void add_poly(SkinOutput *so, BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4)
{
- BMVert *verts[4] = {v1, v2, v3, v4};
- BMFace *f;
-
- BLI_assert(v1 != v2 && v1 != v3 && v1 != v4);
- BLI_assert(v2 != v3 && v2 != v4);
- BLI_assert(v3 != v4);
- BLI_assert(v1 && v2 && v3);
-
- f = BM_face_create_verts(so->bm, verts, v4 ? 4 : 3, NULL, BM_CREATE_NO_DOUBLE, true);
- BM_face_normal_update(f);
- if (so->smd->flag & MOD_SKIN_SMOOTH_SHADING)
- BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
- f->mat_nr = so->mat_nr;
+ BMVert *verts[4] = {v1, v2, v3, v4};
+ BMFace *f;
+
+ BLI_assert(v1 != v2 && v1 != v3 && v1 != v4);
+ BLI_assert(v2 != v3 && v2 != v4);
+ BLI_assert(v3 != v4);
+ BLI_assert(v1 && v2 && v3);
+
+ f = BM_face_create_verts(so->bm, verts, v4 ? 4 : 3, NULL, BM_CREATE_NO_DOUBLE, true);
+ BM_face_normal_update(f);
+ if (so->smd->flag & MOD_SKIN_SMOOTH_SHADING)
+ BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
+ f->mat_nr = so->mat_nr;
}
-static void connect_frames(
- SkinOutput *so,
- BMVert *frame1[4],
- BMVert *frame2[4])
+static void connect_frames(SkinOutput *so, BMVert *frame1[4], BMVert *frame2[4])
{
- BMVert *q[4][4] = {{frame2[0], frame2[1], frame1[1], frame1[0]},
- {frame2[1], frame2[2], frame1[2], frame1[1]},
- {frame2[2], frame2[3], frame1[3], frame1[2]},
- {frame2[3], frame2[0], frame1[0], frame1[3]}};
- int i;
- bool swap;
-
- /* Check if frame normals need swap */
+ BMVert *q[4][4] = {{frame2[0], frame2[1], frame1[1], frame1[0]},
+ {frame2[1], frame2[2], frame1[2], frame1[1]},
+ {frame2[2], frame2[3], frame1[3], frame1[2]},
+ {frame2[3], frame2[0], frame1[0], frame1[3]}};
+ int i;
+ bool swap;
+
+ /* Check if frame normals need swap */
#if 0
- {
- /* simple method, works mostly */
- float p[3], no[3];
- sub_v3_v3v3(p, q[3][0]->co, q[0][0]->co);
- normal_quad_v3(no,
- q[0][0]->co, q[0][1]->co,
- q[0][2]->co, q[0][3]->co);
- swap = dot_v3v3(no, p) > 0;
- }
+ {
+ /* simple method, works mostly */
+ float p[3], no[3];
+ sub_v3_v3v3(p, q[3][0]->co, q[0][0]->co);
+ normal_quad_v3(no,
+ q[0][0]->co, q[0][1]->co,
+ q[0][2]->co, q[0][3]->co);
+ swap = dot_v3v3(no, p) > 0;
+ }
#else
- {
- /* comprehensive method, accumulate flipping of all faces */
- float cent_sides[4][3];
- float cent[3];
- float dot = 0.0f;
-
- for (i = 0; i < 4; i++) {
- mid_v3_v3v3v3v3(cent_sides[i], UNPACK4_EX(, q[i], ->co));
- }
- mid_v3_v3v3v3v3(cent, UNPACK4(cent_sides));
-
- for (i = 0; i < 4; i++) {
- float p[3], no[3];
- normal_quad_v3(no, UNPACK4_EX(, q[i], ->co));
- sub_v3_v3v3(p, cent, cent_sides[i]);
- dot += dot_v3v3(no, p);
- }
-
- swap = dot > 0;
- }
+ {
+ /* comprehensive method, accumulate flipping of all faces */
+ float cent_sides[4][3];
+ float cent[3];
+ float dot = 0.0f;
+
+ for (i = 0; i < 4; i++) {
+ mid_v3_v3v3v3v3(cent_sides[i], UNPACK4_EX(, q[i], ->co));
+ }
+ mid_v3_v3v3v3v3(cent, UNPACK4(cent_sides));
+
+ for (i = 0; i < 4; i++) {
+ float p[3], no[3];
+ normal_quad_v3(no, UNPACK4_EX(, q[i], ->co));
+ sub_v3_v3v3(p, cent, cent_sides[i]);
+ dot += dot_v3v3(no, p);
+ }
+
+ swap = dot > 0;
+ }
#endif
- for (i = 0; i < 4; i++) {
- if (swap)
- add_poly(so, q[i][3], q[i][2], q[i][1], q[i][0]);
- else
- add_poly(so, q[i][0], q[i][1], q[i][2], q[i][3]);
- }
+ for (i = 0; i < 4; i++) {
+ if (swap)
+ add_poly(so, q[i][3], q[i][2], q[i][1], q[i][0]);
+ else
+ add_poly(so, q[i][0], q[i][1], q[i][2], q[i][3]);
+ }
}
-static void output_frames(
- BMesh *bm,
- SkinNode *sn,
- const MDeformVert *input_dvert)
+static void output_frames(BMesh *bm, SkinNode *sn, const MDeformVert *input_dvert)
{
- Frame *f;
- int i, j;
-
- /* Output all frame verts */
- for (i = 0; i < sn->totframe; i++) {
- f = &sn->frames[i];
- for (j = 0; j < 4; j++) {
- if (!f->merge[j].frame) {
- BMVert *v = f->verts[j] = BM_vert_create(bm, f->co[j], NULL, BM_CREATE_NOP);
-
- if (input_dvert) {
- MDeformVert *dv;
- dv = CustomData_bmesh_get(&bm->vdata,
- v->head.data,
- CD_MDEFORMVERT);
-
- BLI_assert(dv->totweight == 0);
- defvert_copy(dv, input_dvert);
- }
- }
- }
- }
+ Frame *f;
+ int i, j;
+
+ /* Output all frame verts */
+ for (i = 0; i < sn->totframe; i++) {
+ f = &sn->frames[i];
+ for (j = 0; j < 4; j++) {
+ if (!f->merge[j].frame) {
+ BMVert *v = f->verts[j] = BM_vert_create(bm, f->co[j], NULL, BM_CREATE_NOP);
+
+ if (input_dvert) {
+ MDeformVert *dv;
+ dv = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_MDEFORMVERT);
+
+ BLI_assert(dv->totweight == 0);
+ defvert_copy(dv, input_dvert);
+ }
+ }
+ }
+ }
}
#define PRINT_HOLE_INFO 0
static void calc_frame_center(float center[3], const Frame *frame)
{
- add_v3_v3v3(center, frame->verts[0]->co, frame->verts[1]->co);
- add_v3_v3(center, frame->verts[2]->co);
- add_v3_v3(center, frame->verts[3]->co);
- mul_v3_fl(center, 0.25f);
+ add_v3_v3v3(center, frame->verts[0]->co, frame->verts[1]->co);
+ add_v3_v3(center, frame->verts[2]->co);
+ add_v3_v3(center, frame->verts[3]->co);
+ mul_v3_fl(center, 0.25f);
}
/* Does crappy fan triangulation of poly, may not be so accurate for
@@ -1085,32 +1042,30 @@ static int isect_ray_poly(const float ray_start[3],
BMFace *f,
float *r_lambda)
{
- BMVert *v, *v_first = NULL, *v_prev = NULL;
- BMIter iter;
- float best_dist = FLT_MAX;
- bool hit = false;
-
- BM_ITER_ELEM (v, &iter, f, BM_VERTS_OF_FACE) {
- if (!v_first)
- v_first = v;
- else if (v_prev != v_first) {
- float dist;
- bool curhit;
-
- curhit = isect_ray_tri_v3(ray_start, ray_dir,
- v_first->co, v_prev->co, v->co,
- &dist, NULL);
- if (curhit && dist < best_dist) {
- hit = true;
- best_dist = dist;
- }
- }
-
- v_prev = v;
- }
-
- *r_lambda = best_dist;
- return hit;
+ BMVert *v, *v_first = NULL, *v_prev = NULL;
+ BMIter iter;
+ float best_dist = FLT_MAX;
+ bool hit = false;
+
+ BM_ITER_ELEM (v, &iter, f, BM_VERTS_OF_FACE) {
+ if (!v_first)
+ v_first = v;
+ else if (v_prev != v_first) {
+ float dist;
+ bool curhit;
+
+ curhit = isect_ray_tri_v3(ray_start, ray_dir, v_first->co, v_prev->co, v->co, &dist, NULL);
+ if (curhit && dist < best_dist) {
+ hit = true;
+ best_dist = dist;
+ }
+ }
+
+ v_prev = v;
+ }
+
+ *r_lambda = best_dist;
+ return hit;
}
/* Reduce the face down to 'n' corners by collapsing the edges;
@@ -1118,237 +1073,238 @@ static int isect_ray_poly(const float ray_start[3],
*
* The orig_verts should contain the vertices of 'f'
*/
-static BMFace *collapse_face_corners(BMesh *bm, BMFace *f, int n,
- BMVert **orig_verts)
+static BMFace *collapse_face_corners(BMesh *bm, BMFace *f, int n, BMVert **orig_verts)
{
- int orig_len = f->len;
-
- BLI_assert(n >= 3);
- BLI_assert(f->len > n);
- if (f->len <= n)
- return f;
-
- /* Collapse shortest edge for now */
- while (f->len > n) {
- BMFace *vf;
- BMEdge *shortest_edge;
- BMVert *v_safe, *v_merge;
- BMOperator op;
- BMIter iter;
- int i;
- BMOpSlot *slot_targetmap;
-
- shortest_edge = BM_face_find_shortest_loop(f)->e;
- BMO_op_initf(bm, &op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE), "weld_verts");
-
- slot_targetmap = BMO_slot_get(op.slots_in, "targetmap");
-
- /* Note: could probably calculate merges in one go to be
- * faster */
-
- v_safe = shortest_edge->v1;
- v_merge = shortest_edge->v2;
- mid_v3_v3v3(v_safe->co, v_safe->co, v_merge->co);
- BMO_slot_map_elem_insert(&op, slot_targetmap, v_merge, v_safe);
- BMO_op_exec(bm, &op);
- BMO_op_finish(bm, &op);
-
- /* Find the new face */
- f = NULL;
- BM_ITER_ELEM (vf, &iter, v_safe, BM_FACES_OF_VERT) {
- bool wrong_face = false;
-
- for (i = 0; i < orig_len; i++) {
- if (orig_verts[i] == v_merge) {
- orig_verts[i] = NULL;
- }
- else if (orig_verts[i] &&
- !BM_vert_in_face(orig_verts[i], vf))
- {
- wrong_face = true;
- break;
- }
- }
-
- if (!wrong_face) {
- f = vf;
- break;
- }
- }
-
- BLI_assert(f);
- }
-
- return f;
+ int orig_len = f->len;
+
+ BLI_assert(n >= 3);
+ BLI_assert(f->len > n);
+ if (f->len <= n)
+ return f;
+
+ /* Collapse shortest edge for now */
+ while (f->len > n) {
+ BMFace *vf;
+ BMEdge *shortest_edge;
+ BMVert *v_safe, *v_merge;
+ BMOperator op;
+ BMIter iter;
+ int i;
+ BMOpSlot *slot_targetmap;
+
+ shortest_edge = BM_face_find_shortest_loop(f)->e;
+ BMO_op_initf(bm, &op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE), "weld_verts");
+
+ slot_targetmap = BMO_slot_get(op.slots_in, "targetmap");
+
+ /* Note: could probably calculate merges in one go to be
+ * faster */
+
+ v_safe = shortest_edge->v1;
+ v_merge = shortest_edge->v2;
+ mid_v3_v3v3(v_safe->co, v_safe->co, v_merge->co);
+ BMO_slot_map_elem_insert(&op, slot_targetmap, v_merge, v_safe);
+ BMO_op_exec(bm, &op);
+ BMO_op_finish(bm, &op);
+
+ /* Find the new face */
+ f = NULL;
+ BM_ITER_ELEM (vf, &iter, v_safe, BM_FACES_OF_VERT) {
+ bool wrong_face = false;
+
+ for (i = 0; i < orig_len; i++) {
+ if (orig_verts[i] == v_merge) {
+ orig_verts[i] = NULL;
+ }
+ else if (orig_verts[i] && !BM_vert_in_face(orig_verts[i], vf)) {
+ wrong_face = true;
+ break;
+ }
+ }
+
+ if (!wrong_face) {
+ f = vf;
+ break;
+ }
+ }
+
+ BLI_assert(f);
+ }
+
+ return f;
}
/* Choose a good face to merge the frame with, used in case the frame
* is completely inside the hull. */
static BMFace *skin_hole_target_face(BMesh *bm, Frame *frame)
{
- BMFace *f, *isect_target_face, *center_target_face;
- BMIter iter;
- float frame_center[3];
- float frame_normal[3];
- float best_isect_dist = FLT_MAX;
- float best_center_dist = FLT_MAX;
-
- calc_frame_center(frame_center, frame);
- normal_quad_v3(frame_normal, frame->verts[3]->co,
- frame->verts[2]->co, frame->verts[1]->co,
- frame->verts[0]->co);
-
- /* Use a line intersection test and nearest center test against
- * all faces */
- isect_target_face = center_target_face = NULL;
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- float dist, poly_center[3];
- int hit;
-
- /* Intersection test */
- hit = isect_ray_poly(frame_center, frame_normal, f, &dist);
- if (hit && dist < best_isect_dist) {
- isect_target_face = f;
- best_isect_dist = dist;
- }
-
- /* Nearest test */
- BM_face_calc_center_median(f, poly_center);
- dist = len_v3v3(frame_center, poly_center);
- if (dist < best_center_dist) {
- center_target_face = f;
- best_center_dist = dist;
- }
- }
-
- f = isect_target_face;
- if (!f || best_center_dist < best_isect_dist / 2)
- f = center_target_face;
-
- /* This case is unlikely now, but could still happen. Should look
- * into splitting edges to make new faces. */
+ BMFace *f, *isect_target_face, *center_target_face;
+ BMIter iter;
+ float frame_center[3];
+ float frame_normal[3];
+ float best_isect_dist = FLT_MAX;
+ float best_center_dist = FLT_MAX;
+
+ calc_frame_center(frame_center, frame);
+ normal_quad_v3(frame_normal,
+ frame->verts[3]->co,
+ frame->verts[2]->co,
+ frame->verts[1]->co,
+ frame->verts[0]->co);
+
+ /* Use a line intersection test and nearest center test against
+ * all faces */
+ isect_target_face = center_target_face = NULL;
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ float dist, poly_center[3];
+ int hit;
+
+ /* Intersection test */
+ hit = isect_ray_poly(frame_center, frame_normal, f, &dist);
+ if (hit && dist < best_isect_dist) {
+ isect_target_face = f;
+ best_isect_dist = dist;
+ }
+
+ /* Nearest test */
+ BM_face_calc_center_median(f, poly_center);
+ dist = len_v3v3(frame_center, poly_center);
+ if (dist < best_center_dist) {
+ center_target_face = f;
+ best_center_dist = dist;
+ }
+ }
+
+ f = isect_target_face;
+ if (!f || best_center_dist < best_isect_dist / 2)
+ f = center_target_face;
+
+ /* This case is unlikely now, but could still happen. Should look
+ * into splitting edges to make new faces. */
#if PRINT_HOLE_INFO
- if (!f) {
- printf("no good face found\n");
- }
+ if (!f) {
+ printf("no good face found\n");
+ }
#endif
- return f;
+ return f;
}
/* Use edge-length heuristic to choose from eight possible polygon bridges */
-static void skin_choose_quad_bridge_order(BMVert *a[4], BMVert *b[4],
- int best_order[4])
+static void skin_choose_quad_bridge_order(BMVert *a[4], BMVert *b[4], int best_order[4])
{
- int orders[8][4];
- float shortest_len;
- int i, j;
-
- /* Enumerate all valid orderings */
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- orders[i][j] = (j + i) % 4;
- orders[i + 4][j] = 3 - ((j + i) % 4);
- }
- }
-
- shortest_len = FLT_MAX;
- for (i = 0; i < 8; i++) {
- float len = 0;
-
- /* Get total edge length for this configuration */
- for (j = 0; j < 4; j++)
- len += len_squared_v3v3(a[j]->co, b[orders[i][j]]->co);
-
- if (len < shortest_len) {
- shortest_len = len;
- memcpy(best_order, orders[i], sizeof(int) * 4);
- }
- }
+ int orders[8][4];
+ float shortest_len;
+ int i, j;
+
+ /* Enumerate all valid orderings */
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ orders[i][j] = (j + i) % 4;
+ orders[i + 4][j] = 3 - ((j + i) % 4);
+ }
+ }
+
+ shortest_len = FLT_MAX;
+ for (i = 0; i < 8; i++) {
+ float len = 0;
+
+ /* Get total edge length for this configuration */
+ for (j = 0; j < 4; j++)
+ len += len_squared_v3v3(a[j]->co, b[orders[i][j]]->co);
+
+ if (len < shortest_len) {
+ shortest_len = len;
+ memcpy(best_order, orders[i], sizeof(int) * 4);
+ }
+ }
}
static void skin_fix_hole_no_good_verts(BMesh *bm, Frame *frame, BMFace *split_face)
{
- BMFace *f;
- BMVert *verts[4];
- BMVert **vert_buf = NULL;
- BLI_array_declare(vert_buf);
- BMOIter oiter;
- BMOperator op;
- int i, best_order[4];
- BMOpSlot *slot_targetmap;
-
- BLI_assert(split_face->len >= 3);
-
- /* Extrude the split face */
- BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
- BM_elem_flag_enable(split_face, BM_ELEM_TAG);
- BMO_op_initf(bm, &op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
- "extrude_discrete_faces faces=%hf", BM_ELEM_TAG);
- BMO_op_exec(bm, &op);
-
- /* Update split face (should only be one new face created
- * during extrusion) */
- split_face = NULL;
- BMO_ITER (f, &oiter, op.slots_out, "faces.out", BM_FACE) {
- BLI_assert(!split_face);
- split_face = f;
- }
-
- BMO_op_finish(bm, &op);
-
- if (split_face->len == 3) {
- BMEdge *longest_edge;
-
- /* Need at least four ring edges, so subdivide longest edge if
- * face is a triangle */
- longest_edge = BM_face_find_longest_loop(split_face)->e;
-
- BM_mesh_elem_hflag_disable_all(bm, BM_EDGE, BM_ELEM_TAG, false);
- BM_elem_flag_enable(longest_edge, BM_ELEM_TAG);
-
- BMO_op_callf(bm, BMO_FLAG_DEFAULTS,
- "subdivide_edges edges=%he cuts=%i quad_corner_type=%i",
- BM_ELEM_TAG, 1, SUBD_CORNER_STRAIGHT_CUT);
- }
- else if (split_face->len > 4) {
- /* Maintain a dynamic vert array containing the split_face's
- * vertices, avoids frequent allocs in collapse_face_corners() */
- if (BLI_array_len(vert_buf) < split_face->len) {
- BLI_array_grow_items(vert_buf, (split_face->len -
- BLI_array_len(vert_buf)));
- }
-
- /* Get split face's verts */
- BM_iter_as_array(bm, BM_VERTS_OF_FACE, split_face,
- (void **)vert_buf, split_face->len);
-
- /* Earlier edge split operations may have turned some quads
- * into higher-degree faces */
- split_face = collapse_face_corners(bm, split_face, 4, vert_buf);
- }
-
- /* Done with dynamic array, split_face must now be a quad */
- BLI_array_free(vert_buf);
- BLI_assert(split_face->len == 4);
- if (split_face->len != 4)
- return;
-
- /* Get split face's verts */
- // BM_iter_as_array(bm, BM_VERTS_OF_FACE, split_face, (void **)verts, 4);
- BM_face_as_array_vert_quad(split_face, verts);
- skin_choose_quad_bridge_order(verts, frame->verts, best_order);
-
- /* Delete split face and merge */
- BM_face_kill(bm, split_face);
- BMO_op_init(bm, &op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
- "weld_verts");
- slot_targetmap = BMO_slot_get(op.slots_in, "targetmap");
- for (i = 0; i < 4; i++) {
- BMO_slot_map_elem_insert(&op, slot_targetmap, verts[i], frame->verts[best_order[i]]);
- }
- BMO_op_exec(bm, &op);
- BMO_op_finish(bm, &op);
+ BMFace *f;
+ BMVert *verts[4];
+ BMVert **vert_buf = NULL;
+ BLI_array_declare(vert_buf);
+ BMOIter oiter;
+ BMOperator op;
+ int i, best_order[4];
+ BMOpSlot *slot_targetmap;
+
+ BLI_assert(split_face->len >= 3);
+
+ /* Extrude the split face */
+ BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
+ BM_elem_flag_enable(split_face, BM_ELEM_TAG);
+ BMO_op_initf(bm,
+ &op,
+ (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
+ "extrude_discrete_faces faces=%hf",
+ BM_ELEM_TAG);
+ BMO_op_exec(bm, &op);
+
+ /* Update split face (should only be one new face created
+ * during extrusion) */
+ split_face = NULL;
+ BMO_ITER (f, &oiter, op.slots_out, "faces.out", BM_FACE) {
+ BLI_assert(!split_face);
+ split_face = f;
+ }
+
+ BMO_op_finish(bm, &op);
+
+ if (split_face->len == 3) {
+ BMEdge *longest_edge;
+
+ /* Need at least four ring edges, so subdivide longest edge if
+ * face is a triangle */
+ longest_edge = BM_face_find_longest_loop(split_face)->e;
+
+ BM_mesh_elem_hflag_disable_all(bm, BM_EDGE, BM_ELEM_TAG, false);
+ BM_elem_flag_enable(longest_edge, BM_ELEM_TAG);
+
+ BMO_op_callf(bm,
+ BMO_FLAG_DEFAULTS,
+ "subdivide_edges edges=%he cuts=%i quad_corner_type=%i",
+ BM_ELEM_TAG,
+ 1,
+ SUBD_CORNER_STRAIGHT_CUT);
+ }
+ else if (split_face->len > 4) {
+ /* Maintain a dynamic vert array containing the split_face's
+ * vertices, avoids frequent allocs in collapse_face_corners() */
+ if (BLI_array_len(vert_buf) < split_face->len) {
+ BLI_array_grow_items(vert_buf, (split_face->len - BLI_array_len(vert_buf)));
+ }
+
+ /* Get split face's verts */
+ BM_iter_as_array(bm, BM_VERTS_OF_FACE, split_face, (void **)vert_buf, split_face->len);
+
+ /* Earlier edge split operations may have turned some quads
+ * into higher-degree faces */
+ split_face = collapse_face_corners(bm, split_face, 4, vert_buf);
+ }
+
+ /* Done with dynamic array, split_face must now be a quad */
+ BLI_array_free(vert_buf);
+ BLI_assert(split_face->len == 4);
+ if (split_face->len != 4)
+ return;
+
+ /* Get split face's verts */
+ // BM_iter_as_array(bm, BM_VERTS_OF_FACE, split_face, (void **)verts, 4);
+ BM_face_as_array_vert_quad(split_face, verts);
+ skin_choose_quad_bridge_order(verts, frame->verts, best_order);
+
+ /* Delete split face and merge */
+ BM_face_kill(bm, split_face);
+ BMO_op_init(bm, &op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE), "weld_verts");
+ slot_targetmap = BMO_slot_get(op.slots_in, "targetmap");
+ for (i = 0; i < 4; i++) {
+ BMO_slot_map_elem_insert(&op, slot_targetmap, verts[i], frame->verts[best_order[i]]);
+ }
+ BMO_op_exec(bm, &op);
+ BMO_op_finish(bm, &op);
}
/* If the frame has some vertices that are inside the hull (detached)
@@ -1356,473 +1312,451 @@ static void skin_fix_hole_no_good_verts(BMesh *bm, Frame *frame, BMFace *split_f
* whole frame off the hull. */
static void skin_hole_detach_partially_attached_frame(BMesh *bm, Frame *frame)
{
- int i, attached[4], totattached = 0;
-
- /* Get/count attached frame corners */
- for (i = 0; i < 4; i++) {
- if (!frame->inside_hull[i])
- attached[totattached++] = i;
- }
-
- /* Detach everything */
- for (i = 0; i < totattached; i++) {
- BMVert **av = &frame->verts[attached[i]];
- (*av) = BM_vert_create(bm, (*av)->co, *av, BM_CREATE_NOP);
- }
+ int i, attached[4], totattached = 0;
+
+ /* Get/count attached frame corners */
+ for (i = 0; i < 4; i++) {
+ if (!frame->inside_hull[i])
+ attached[totattached++] = i;
+ }
+
+ /* Detach everything */
+ for (i = 0; i < totattached; i++) {
+ BMVert **av = &frame->verts[attached[i]];
+ (*av) = BM_vert_create(bm, (*av)->co, *av, BM_CREATE_NOP);
+ }
}
-
static void quad_from_tris(BMEdge *e, BMFace *adj[2], BMVert *ndx[4])
{
- BMVert *tri[2][3];
- BMVert *opp = NULL;
- int i, j;
+ BMVert *tri[2][3];
+ BMVert *opp = NULL;
+ int i, j;
- BLI_assert(adj[0]->len == 3 && adj[1]->len == 3);
+ BLI_assert(adj[0]->len == 3 && adj[1]->len == 3);
#if 0
- BM_iter_as_array(bm, BM_VERTS_OF_FACE, adj[0], (void **)tri[0], 3);
- BM_iter_as_array(bm, BM_VERTS_OF_FACE, adj[1], (void **)tri[1], 3);
+ BM_iter_as_array(bm, BM_VERTS_OF_FACE, adj[0], (void **)tri[0], 3);
+ BM_iter_as_array(bm, BM_VERTS_OF_FACE, adj[1], (void **)tri[1], 3);
#else
- BM_face_as_array_vert_tri(adj[0], tri[0]);
- BM_face_as_array_vert_tri(adj[1], tri[1]);
+ BM_face_as_array_vert_tri(adj[0], tri[0]);
+ BM_face_as_array_vert_tri(adj[1], tri[1]);
#endif
- /* Find what the second tri has that the first doesn't */
- for (i = 0; i < 3; i++) {
- if (tri[1][i] != tri[0][0] &&
- tri[1][i] != tri[0][1] &&
- tri[1][i] != tri[0][2])
- {
- opp = tri[1][i];
- break;
- }
- }
- BLI_assert(opp);
-
- for (i = 0, j = 0; i < 3; i++, j++) {
- ndx[j] = tri[0][i];
- /* When the triangle edge cuts across our quad-to-be,
- * throw in the second triangle's vertex */
- if ((tri[0][i] == e->v1 || tri[0][i] == e->v2) &&
- (tri[0][(i + 1) % 3] == e->v1 || tri[0][(i + 1) % 3] == e->v2))
- {
- j++;
- ndx[j] = opp;
- }
- }
+ /* Find what the second tri has that the first doesn't */
+ for (i = 0; i < 3; i++) {
+ if (tri[1][i] != tri[0][0] && tri[1][i] != tri[0][1] && tri[1][i] != tri[0][2]) {
+ opp = tri[1][i];
+ break;
+ }
+ }
+ BLI_assert(opp);
+
+ for (i = 0, j = 0; i < 3; i++, j++) {
+ ndx[j] = tri[0][i];
+ /* When the triangle edge cuts across our quad-to-be,
+ * throw in the second triangle's vertex */
+ if ((tri[0][i] == e->v1 || tri[0][i] == e->v2) &&
+ (tri[0][(i + 1) % 3] == e->v1 || tri[0][(i + 1) % 3] == e->v2)) {
+ j++;
+ ndx[j] = opp;
+ }
+ }
}
static void add_quad_from_tris(SkinOutput *so, BMEdge *e, BMFace *adj[2])
{
- BMVert *quad[4];
+ BMVert *quad[4];
- quad_from_tris(e, adj, quad);
+ quad_from_tris(e, adj, quad);
- add_poly(so, quad[0], quad[1], quad[2], quad[3]);
+ add_poly(so, quad[0], quad[1], quad[2], quad[3]);
}
static void hull_merge_triangles(SkinOutput *so, const SkinModifierData *smd)
{
- BMIter iter;
- BMEdge *e;
- HeapSimple *heap;
- float score;
-
- heap = BLI_heapsimple_new();
-
- BM_mesh_elem_hflag_disable_all(so->bm, BM_FACE, BM_ELEM_TAG, false);
-
- /* Build heap */
- BM_ITER_MESH (e, &iter, so->bm, BM_EDGES_OF_MESH) {
- BMFace *adj[2];
-
- /* Only care if the edge is used by exactly two triangles */
- if (BM_edge_face_pair(e, &adj[0], &adj[1])) {
- if (adj[0]->len == 3 && adj[1]->len == 3) {
- BMVert *quad[4];
-
- BLI_assert(BM_face_is_normal_valid(adj[0]));
- BLI_assert(BM_face_is_normal_valid(adj[1]));
-
- /* Construct quad using the two triangles adjacent to
- * the edge */
- quad_from_tris(e, adj, quad);
-
- /* Calculate a score for the quad, higher score for
- * triangles being closer to coplanar */
- score = ((BM_face_calc_area(adj[0]) +
- BM_face_calc_area(adj[1])) *
- dot_v3v3(adj[0]->no, adj[1]->no));
-
- /* Check if quad crosses the axis of symmetry */
- if (quad_crosses_symmetry_plane(quad, smd)) {
- /* Increase score if the triangles form a
- * symmetric quad, otherwise don't use it */
- if (is_quad_symmetric(quad, smd))
- score *= 10;
- else
- continue;
- }
-
- /* Don't use the quad if it's concave */
- if (!is_quad_convex_v3(quad[0]->co, quad[1]->co,
- quad[2]->co, quad[3]->co))
- {
- continue;
- }
-
- BLI_heapsimple_insert(heap, -score, e);
- }
- }
- }
-
- while (!BLI_heapsimple_is_empty(heap)) {
- BMFace *adj[2];
-
- e = BLI_heapsimple_pop_min(heap);
-
- if (BM_edge_face_pair(e, &adj[0], &adj[1])) {
- /* If both triangles still free, and if they don't already
- * share a border with another face, output as a quad */
- if (!BM_elem_flag_test(adj[0], BM_ELEM_TAG) &&
- !BM_elem_flag_test(adj[1], BM_ELEM_TAG) &&
- !BM_face_share_face_check(adj[0], adj[1]))
- {
- add_quad_from_tris(so, e, adj);
- BM_elem_flag_enable(adj[0], BM_ELEM_TAG);
- BM_elem_flag_enable(adj[1], BM_ELEM_TAG);
- BM_elem_flag_enable(e, BM_ELEM_TAG);
- }
- }
- }
-
- BLI_heapsimple_free(heap, NULL);
-
- BM_mesh_delete_hflag_tagged(so->bm, BM_ELEM_TAG, BM_EDGE | BM_FACE);
-
+ BMIter iter;
+ BMEdge *e;
+ HeapSimple *heap;
+ float score;
+
+ heap = BLI_heapsimple_new();
+
+ BM_mesh_elem_hflag_disable_all(so->bm, BM_FACE, BM_ELEM_TAG, false);
+
+ /* Build heap */
+ BM_ITER_MESH (e, &iter, so->bm, BM_EDGES_OF_MESH) {
+ BMFace *adj[2];
+
+ /* Only care if the edge is used by exactly two triangles */
+ if (BM_edge_face_pair(e, &adj[0], &adj[1])) {
+ if (adj[0]->len == 3 && adj[1]->len == 3) {
+ BMVert *quad[4];
+
+ BLI_assert(BM_face_is_normal_valid(adj[0]));
+ BLI_assert(BM_face_is_normal_valid(adj[1]));
+
+ /* Construct quad using the two triangles adjacent to
+ * the edge */
+ quad_from_tris(e, adj, quad);
+
+ /* Calculate a score for the quad, higher score for
+ * triangles being closer to coplanar */
+ score = ((BM_face_calc_area(adj[0]) + BM_face_calc_area(adj[1])) *
+ dot_v3v3(adj[0]->no, adj[1]->no));
+
+ /* Check if quad crosses the axis of symmetry */
+ if (quad_crosses_symmetry_plane(quad, smd)) {
+ /* Increase score if the triangles form a
+ * symmetric quad, otherwise don't use it */
+ if (is_quad_symmetric(quad, smd))
+ score *= 10;
+ else
+ continue;
+ }
+
+ /* Don't use the quad if it's concave */
+ if (!is_quad_convex_v3(quad[0]->co, quad[1]->co, quad[2]->co, quad[3]->co)) {
+ continue;
+ }
+
+ BLI_heapsimple_insert(heap, -score, e);
+ }
+ }
+ }
+
+ while (!BLI_heapsimple_is_empty(heap)) {
+ BMFace *adj[2];
+
+ e = BLI_heapsimple_pop_min(heap);
+
+ if (BM_edge_face_pair(e, &adj[0], &adj[1])) {
+ /* If both triangles still free, and if they don't already
+ * share a border with another face, output as a quad */
+ if (!BM_elem_flag_test(adj[0], BM_ELEM_TAG) && !BM_elem_flag_test(adj[1], BM_ELEM_TAG) &&
+ !BM_face_share_face_check(adj[0], adj[1])) {
+ add_quad_from_tris(so, e, adj);
+ BM_elem_flag_enable(adj[0], BM_ELEM_TAG);
+ BM_elem_flag_enable(adj[1], BM_ELEM_TAG);
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ }
+ }
+ }
+
+ BLI_heapsimple_free(heap, NULL);
+
+ BM_mesh_delete_hflag_tagged(so->bm, BM_ELEM_TAG, BM_EDGE | BM_FACE);
}
-static void skin_merge_close_frame_verts(SkinNode *skin_nodes, int totvert,
+static void skin_merge_close_frame_verts(SkinNode *skin_nodes,
+ int totvert,
const MeshElemMap *emap,
const MEdge *medge)
{
- Frame **hull_frames;
- int v, tothullframe;
-
- for (v = 0; v < totvert; v++) {
- /* Only check branch nodes */
- if (!skin_nodes[v].totframe) {
- hull_frames = collect_hull_frames(v, skin_nodes,
- emap, medge,
- &tothullframe);
- merge_frame_corners(hull_frames, tothullframe);
- MEM_freeN(hull_frames);
- }
- }
+ Frame **hull_frames;
+ int v, tothullframe;
+
+ for (v = 0; v < totvert; v++) {
+ /* Only check branch nodes */
+ if (!skin_nodes[v].totframe) {
+ hull_frames = collect_hull_frames(v, skin_nodes, emap, medge, &tothullframe);
+ merge_frame_corners(hull_frames, tothullframe);
+ MEM_freeN(hull_frames);
+ }
+ }
}
static void skin_update_merged_vertices(SkinNode *skin_nodes, int totvert)
{
- int v;
+ int v;
- for (v = 0; v < totvert; ++v) {
- SkinNode *sn = &skin_nodes[v];
- int i, j;
+ for (v = 0; v < totvert; ++v) {
+ SkinNode *sn = &skin_nodes[v];
+ int i, j;
- for (i = 0; i < sn->totframe; i++) {
- Frame *f = &sn->frames[i];
+ for (i = 0; i < sn->totframe; i++) {
+ Frame *f = &sn->frames[i];
- for (j = 0; j < 4; j++) {
- if (f->merge[j].frame) {
- /* Merge chaining not allowed */
- BLI_assert(!f->merge[j].frame->merge[f->merge[j].corner].frame);
+ for (j = 0; j < 4; j++) {
+ if (f->merge[j].frame) {
+ /* Merge chaining not allowed */
+ BLI_assert(!f->merge[j].frame->merge[f->merge[j].corner].frame);
- f->verts[j] = f->merge[j].frame->verts[f->merge[j].corner];
- }
- }
- }
- }
+ f->verts[j] = f->merge[j].frame->verts[f->merge[j].corner];
+ }
+ }
+ }
+ }
}
-static void skin_fix_hull_topology(BMesh *bm, SkinNode *skin_nodes,
- int totvert)
+static void skin_fix_hull_topology(BMesh *bm, SkinNode *skin_nodes, int totvert)
{
- int v;
+ int v;
- for (v = 0; v < totvert; v++) {
- SkinNode *sn = &skin_nodes[v];
- int j;
+ for (v = 0; v < totvert; v++) {
+ SkinNode *sn = &skin_nodes[v];
+ int j;
- for (j = 0; j < sn->totframe; j++) {
- Frame *f = &sn->frames[j];
+ for (j = 0; j < sn->totframe; j++) {
+ Frame *f = &sn->frames[j];
- if (f->detached) {
- BMFace *target_face;
+ if (f->detached) {
+ BMFace *target_face;
- skin_hole_detach_partially_attached_frame(bm, f);
+ skin_hole_detach_partially_attached_frame(bm, f);
- target_face = skin_hole_target_face(bm, f);
- if (target_face)
- skin_fix_hole_no_good_verts(bm, f, target_face);
- }
- }
- }
+ target_face = skin_hole_target_face(bm, f);
+ if (target_face)
+ skin_fix_hole_no_good_verts(bm, f, target_face);
+ }
+ }
+ }
}
-static void skin_output_end_nodes(SkinOutput *so, SkinNode *skin_nodes,
- int totvert)
+static void skin_output_end_nodes(SkinOutput *so, SkinNode *skin_nodes, int totvert)
{
- int v;
-
- for (v = 0; v < totvert; ++v) {
- SkinNode *sn = &skin_nodes[v];
- /* Assuming here just two frames */
- if (sn->flag & SEAM_FRAME) {
- BMVert *v_order[4];
- int i, order[4];
-
- skin_choose_quad_bridge_order(sn->frames[0].verts,
- sn->frames[1].verts,
- order);
- for (i = 0; i < 4; i++)
- v_order[i] = sn->frames[1].verts[order[i]];
- connect_frames(so, sn->frames[0].verts, v_order);
- }
- else if (sn->totframe == 2) {
- connect_frames(so,
- sn->frames[0].verts,
- sn->frames[1].verts);
- }
-
- if (sn->flag & CAP_START) {
- if (sn->flag & ROOT) {
- add_poly(so,
- sn->frames[0].verts[0],
- sn->frames[0].verts[1],
- sn->frames[0].verts[2],
- sn->frames[0].verts[3]);
- }
- else {
- add_poly(so,
- sn->frames[0].verts[3],
- sn->frames[0].verts[2],
- sn->frames[0].verts[1],
- sn->frames[0].verts[0]);
- }
- }
- if (sn->flag & CAP_END) {
- add_poly(so,
- sn->frames[1].verts[0],
- sn->frames[1].verts[1],
- sn->frames[1].verts[2],
- sn->frames[1].verts[3]);
- }
- }
+ int v;
+
+ for (v = 0; v < totvert; ++v) {
+ SkinNode *sn = &skin_nodes[v];
+ /* Assuming here just two frames */
+ if (sn->flag & SEAM_FRAME) {
+ BMVert *v_order[4];
+ int i, order[4];
+
+ skin_choose_quad_bridge_order(sn->frames[0].verts, sn->frames[1].verts, order);
+ for (i = 0; i < 4; i++)
+ v_order[i] = sn->frames[1].verts[order[i]];
+ connect_frames(so, sn->frames[0].verts, v_order);
+ }
+ else if (sn->totframe == 2) {
+ connect_frames(so, sn->frames[0].verts, sn->frames[1].verts);
+ }
+
+ if (sn->flag & CAP_START) {
+ if (sn->flag & ROOT) {
+ add_poly(so,
+ sn->frames[0].verts[0],
+ sn->frames[0].verts[1],
+ sn->frames[0].verts[2],
+ sn->frames[0].verts[3]);
+ }
+ else {
+ add_poly(so,
+ sn->frames[0].verts[3],
+ sn->frames[0].verts[2],
+ sn->frames[0].verts[1],
+ sn->frames[0].verts[0]);
+ }
+ }
+ if (sn->flag & CAP_END) {
+ add_poly(so,
+ sn->frames[1].verts[0],
+ sn->frames[1].verts[1],
+ sn->frames[1].verts[2],
+ sn->frames[1].verts[3]);
+ }
+ }
}
-static void skin_output_connections(SkinOutput *so, SkinNode *skin_nodes,
+static void skin_output_connections(SkinOutput *so,
+ SkinNode *skin_nodes,
const MEdge *medge,
int totedge)
{
- int e;
-
- for (e = 0; e < totedge; e++) {
- SkinNode *a, *b;
- a = &skin_nodes[medge[e].v1];
- b = &skin_nodes[medge[e].v2];
-
- if (a->totframe && b->totframe) {
- if ((a->flag & SEAM_FRAME) || (b->flag & SEAM_FRAME)) {
- Frame *fr[2] = {&a->frames[0], &b->frames[0]};
- BMVert *v_order[4];
- int i, order[4];
-
- if ((a->flag & SEAM_FRAME) && (e != a->seam_edges[0]))
- fr[0]++;
- if ((b->flag & SEAM_FRAME) && (e != b->seam_edges[0]))
- fr[1]++;
-
- skin_choose_quad_bridge_order(fr[0]->verts, fr[1]->verts, order);
- for (i = 0; i < 4; i++)
- v_order[i] = fr[1]->verts[order[i]];
- connect_frames(so, fr[0]->verts, v_order);
- }
- else {
- connect_frames(so,
- a->frames[0].verts,
- b->frames[0].verts);
- }
- }
- }
+ int e;
+
+ for (e = 0; e < totedge; e++) {
+ SkinNode *a, *b;
+ a = &skin_nodes[medge[e].v1];
+ b = &skin_nodes[medge[e].v2];
+
+ if (a->totframe && b->totframe) {
+ if ((a->flag & SEAM_FRAME) || (b->flag & SEAM_FRAME)) {
+ Frame *fr[2] = {&a->frames[0], &b->frames[0]};
+ BMVert *v_order[4];
+ int i, order[4];
+
+ if ((a->flag & SEAM_FRAME) && (e != a->seam_edges[0]))
+ fr[0]++;
+ if ((b->flag & SEAM_FRAME) && (e != b->seam_edges[0]))
+ fr[1]++;
+
+ skin_choose_quad_bridge_order(fr[0]->verts, fr[1]->verts, order);
+ for (i = 0; i < 4; i++)
+ v_order[i] = fr[1]->verts[order[i]];
+ connect_frames(so, fr[0]->verts, v_order);
+ }
+ else {
+ connect_frames(so, a->frames[0].verts, b->frames[0].verts);
+ }
+ }
+ }
}
-static void skin_smooth_hulls(BMesh *bm, SkinNode *skin_nodes,
- int totvert, const SkinModifierData *smd)
+static void skin_smooth_hulls(BMesh *bm,
+ SkinNode *skin_nodes,
+ int totvert,
+ const SkinModifierData *smd)
{
- BMIter iter, eiter;
- BMVert *v;
- int i, j, k, skey;
-
- if (smd->branch_smoothing == 0)
- return;
-
- /* Mark all frame vertices */
- BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false);
- for (i = 0; i < totvert; i++) {
- for (j = 0; j < skin_nodes[i].totframe; j++) {
- Frame *frame = &skin_nodes[i].frames[j];
-
- for (k = 0; k < 4; k++)
- BM_elem_flag_enable(frame->verts[k], BM_ELEM_TAG);
- }
- }
-
- /* Add temporary shapekey layer to store original coordinates */
- BM_data_layer_add(bm, &bm->vdata, CD_SHAPEKEY);
- skey = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY) - 1;
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- copy_v3_v3(CustomData_bmesh_get_n(&bm->vdata, v->head.data,
- CD_SHAPEKEY, skey), v->co);
- }
-
- /* Smooth vertices, weight unmarked vertices more strongly (helps
- * to smooth frame vertices, but don't want to alter them too
- * much) */
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- BMEdge *e;
- float avg[3];
- float weight = smd->branch_smoothing;
- int totv = 1;
-
- if (BM_elem_flag_test(v, BM_ELEM_TAG))
- weight *= 0.5f;
-
- copy_v3_v3(avg, v->co);
- BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
- BMVert *other = BM_edge_other_vert(e, v);
-
- add_v3_v3(avg, CustomData_bmesh_get_n(&bm->vdata,
- other->head.data,
- CD_SHAPEKEY, skey));
- totv++;
- }
-
- if (totv > 1) {
- mul_v3_fl(avg, 1.0f / (float)totv);
- interp_v3_v3v3(v->co, v->co, avg, weight);
- }
- }
-
- /* Done with original coordinates */
- BM_data_layer_free_n(bm, &bm->vdata, CD_SHAPEKEY, skey);
+ BMIter iter, eiter;
+ BMVert *v;
+ int i, j, k, skey;
+
+ if (smd->branch_smoothing == 0)
+ return;
+
+ /* Mark all frame vertices */
+ BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false);
+ for (i = 0; i < totvert; i++) {
+ for (j = 0; j < skin_nodes[i].totframe; j++) {
+ Frame *frame = &skin_nodes[i].frames[j];
+
+ for (k = 0; k < 4; k++)
+ BM_elem_flag_enable(frame->verts[k], BM_ELEM_TAG);
+ }
+ }
+
+ /* Add temporary shapekey layer to store original coordinates */
+ BM_data_layer_add(bm, &bm->vdata, CD_SHAPEKEY);
+ skey = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY) - 1;
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ copy_v3_v3(CustomData_bmesh_get_n(&bm->vdata, v->head.data, CD_SHAPEKEY, skey), v->co);
+ }
+
+ /* Smooth vertices, weight unmarked vertices more strongly (helps
+ * to smooth frame vertices, but don't want to alter them too
+ * much) */
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ BMEdge *e;
+ float avg[3];
+ float weight = smd->branch_smoothing;
+ int totv = 1;
+
+ if (BM_elem_flag_test(v, BM_ELEM_TAG))
+ weight *= 0.5f;
+
+ copy_v3_v3(avg, v->co);
+ BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
+ BMVert *other = BM_edge_other_vert(e, v);
+
+ add_v3_v3(avg, CustomData_bmesh_get_n(&bm->vdata, other->head.data, CD_SHAPEKEY, skey));
+ totv++;
+ }
+
+ if (totv > 1) {
+ mul_v3_fl(avg, 1.0f / (float)totv);
+ interp_v3_v3v3(v->co, v->co, avg, weight);
+ }
+ }
+
+ /* Done with original coordinates */
+ BM_data_layer_free_n(bm, &bm->vdata, CD_SHAPEKEY, skey);
}
/* Returns true if all hulls are successfully built, false otherwise */
-static bool skin_output_branch_hulls(SkinOutput *so, SkinNode *skin_nodes,
- int totvert, const MeshElemMap *emap,
- const MEdge *medge)
+static bool skin_output_branch_hulls(
+ SkinOutput *so, SkinNode *skin_nodes, int totvert, const MeshElemMap *emap, const MEdge *medge)
{
- bool result = true;
- int v;
+ bool result = true;
+ int v;
- for (v = 0; v < totvert; v++) {
- SkinNode *sn = &skin_nodes[v];
+ for (v = 0; v < totvert; v++) {
+ SkinNode *sn = &skin_nodes[v];
- /* Branch node hulls */
- if (!sn->totframe) {
- Frame **hull_frames;
- int tothullframe;
+ /* Branch node hulls */
+ if (!sn->totframe) {
+ Frame **hull_frames;
+ int tothullframe;
- hull_frames = collect_hull_frames(v, skin_nodes,
- emap, medge,
- &tothullframe);
- if (!build_hull(so, hull_frames, tothullframe))
- result = false;
+ hull_frames = collect_hull_frames(v, skin_nodes, emap, medge, &tothullframe);
+ if (!build_hull(so, hull_frames, tothullframe))
+ result = false;
- MEM_freeN(hull_frames);
- }
- }
+ MEM_freeN(hull_frames);
+ }
+ }
- return result;
+ return result;
}
static BMesh *build_skin(SkinNode *skin_nodes,
- int totvert, const MeshElemMap *emap,
- const MEdge *medge, int totedge,
+ int totvert,
+ const MeshElemMap *emap,
+ const MEdge *medge,
+ int totedge,
const MDeformVert *input_dvert,
SkinModifierData *smd)
{
- SkinOutput so;
- int v;
-
- so.smd = smd;
- so.bm = BM_mesh_create(
- &bm_mesh_allocsize_default,
- &((struct BMeshCreateParams){.use_toolflags = true,}));
- so.mat_nr = 0;
-
- /* BMESH_TODO: bumping up the stack level (see MOD_array.c) */
- BM_mesh_elem_toolflags_ensure(so.bm);
- BMO_push(so.bm, NULL);
- bmesh_edit_begin(so.bm, 0);
-
- if (input_dvert)
- BM_data_layer_add(so.bm, &so.bm->vdata, CD_MDEFORMVERT);
-
- /* Check for mergeable frame corners around hulls before
- * outputting vertices */
- skin_merge_close_frame_verts(skin_nodes, totvert, emap, medge);
-
- /* Write out all frame vertices to the mesh */
- for (v = 0; v < totvert; ++v) {
- if (skin_nodes[v].totframe)
- output_frames(so.bm, &skin_nodes[v],
- input_dvert ? &input_dvert[v] : NULL);
- }
-
- /* Update vertex pointers for merged frame corners */
- skin_update_merged_vertices(skin_nodes, totvert);
-
- if (!skin_output_branch_hulls(&so, skin_nodes, totvert, emap, medge))
- modifier_setError(&smd->modifier, "Hull error");
-
- /* Merge triangles here in the hope of providing better target
- * faces for skin_fix_hull_topology() to connect to */
- hull_merge_triangles(&so, smd);
-
- /* Using convex hulls may not generate a nice manifold mesh. Two
- * problems can occur: an input frame's edges may be inside the
- * hull, and/or an input frame's vertices may be inside the hull.
- *
- * General fix to produce manifold mesh: for any frame that is
- * partially detached, first detach it fully, then find a suitable
- * existing face to merge with. (Note that we do this after
- * creating all hull faces, but before creating any other
- * faces.
- */
- skin_fix_hull_topology(so.bm, skin_nodes, totvert);
-
- skin_smooth_hulls(so.bm, skin_nodes, totvert, smd);
-
- skin_output_end_nodes(&so, skin_nodes, totvert);
- skin_output_connections(&so, skin_nodes, medge, totedge);
- hull_merge_triangles(&so, smd);
-
- bmesh_edit_end(so.bm, 0);
- BMO_pop(so.bm);
-
- return so.bm;
+ SkinOutput so;
+ int v;
+
+ so.smd = smd;
+ so.bm = BM_mesh_create(&bm_mesh_allocsize_default,
+ &((struct BMeshCreateParams){
+ .use_toolflags = true,
+ }));
+ so.mat_nr = 0;
+
+ /* BMESH_TODO: bumping up the stack level (see MOD_array.c) */
+ BM_mesh_elem_toolflags_ensure(so.bm);
+ BMO_push(so.bm, NULL);
+ bmesh_edit_begin(so.bm, 0);
+
+ if (input_dvert)
+ BM_data_layer_add(so.bm, &so.bm->vdata, CD_MDEFORMVERT);
+
+ /* Check for mergeable frame corners around hulls before
+ * outputting vertices */
+ skin_merge_close_frame_verts(skin_nodes, totvert, emap, medge);
+
+ /* Write out all frame vertices to the mesh */
+ for (v = 0; v < totvert; ++v) {
+ if (skin_nodes[v].totframe)
+ output_frames(so.bm, &skin_nodes[v], input_dvert ? &input_dvert[v] : NULL);
+ }
+
+ /* Update vertex pointers for merged frame corners */
+ skin_update_merged_vertices(skin_nodes, totvert);
+
+ if (!skin_output_branch_hulls(&so, skin_nodes, totvert, emap, medge))
+ modifier_setError(&smd->modifier, "Hull error");
+
+ /* Merge triangles here in the hope of providing better target
+ * faces for skin_fix_hull_topology() to connect to */
+ hull_merge_triangles(&so, smd);
+
+ /* Using convex hulls may not generate a nice manifold mesh. Two
+ * problems can occur: an input frame's edges may be inside the
+ * hull, and/or an input frame's vertices may be inside the hull.
+ *
+ * General fix to produce manifold mesh: for any frame that is
+ * partially detached, first detach it fully, then find a suitable
+ * existing face to merge with. (Note that we do this after
+ * creating all hull faces, but before creating any other
+ * faces.
+ */
+ skin_fix_hull_topology(so.bm, skin_nodes, totvert);
+
+ skin_smooth_hulls(so.bm, skin_nodes, totvert, smd);
+
+ skin_output_end_nodes(&so, skin_nodes, totvert);
+ skin_output_connections(&so, skin_nodes, medge, totedge);
+ hull_merge_triangles(&so, smd);
+
+ bmesh_edit_end(so.bm, 0);
+ BMO_pop(so.bm);
+
+ return so.bm;
}
static void skin_set_orig_indices(Mesh *mesh)
{
- int *orig, totpoly;
+ int *orig, totpoly;
- totpoly = mesh->totpoly;
- orig = CustomData_add_layer(&mesh->pdata, CD_ORIGINDEX,
- CD_CALLOC, NULL, totpoly);
- copy_vn_i(orig, totpoly, ORIGINDEX_NONE);
+ totpoly = mesh->totpoly;
+ orig = CustomData_add_layer(&mesh->pdata, CD_ORIGINDEX, CD_CALLOC, NULL, totpoly);
+ copy_vn_i(orig, totpoly, ORIGINDEX_NONE);
}
/*
@@ -1831,129 +1765,129 @@ static void skin_set_orig_indices(Mesh *mesh)
* 2) Generate node frames
* 3) Output vertices and polygons from frames, connections, and hulls
*/
-static Mesh *base_skin(Mesh *origmesh,
- SkinModifierData *smd)
+static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd)
{
- Mesh *result;
- MVertSkin *nodes;
- BMesh *bm;
- EMat *emat;
- SkinNode *skin_nodes;
- MeshElemMap *emap;
- int *emapmem;
- MVert *mvert;
- MEdge *medge;
- MDeformVert *dvert;
- int totvert, totedge;
- bool has_valid_root = false;
+ Mesh *result;
+ MVertSkin *nodes;
+ BMesh *bm;
+ EMat *emat;
+ SkinNode *skin_nodes;
+ MeshElemMap *emap;
+ int *emapmem;
+ MVert *mvert;
+ MEdge *medge;
+ MDeformVert *dvert;
+ int totvert, totedge;
+ bool has_valid_root = false;
- nodes = CustomData_get_layer(&origmesh->vdata, CD_MVERT_SKIN);
+ nodes = CustomData_get_layer(&origmesh->vdata, CD_MVERT_SKIN);
- mvert = origmesh->mvert;
- dvert = origmesh->dvert;
- medge = origmesh->medge;
- totvert = origmesh->totvert;
- totedge = origmesh->totedge;
+ mvert = origmesh->mvert;
+ dvert = origmesh->dvert;
+ medge = origmesh->medge;
+ totvert = origmesh->totvert;
+ totedge = origmesh->totedge;
- BKE_mesh_vert_edge_map_create(&emap, &emapmem, medge, totvert, totedge);
+ BKE_mesh_vert_edge_map_create(&emap, &emapmem, medge, totvert, totedge);
- emat = build_edge_mats(nodes, mvert, totvert, medge, emap, totedge, &has_valid_root);
- skin_nodes = build_frames(mvert, totvert, nodes, emap, emat);
- MEM_freeN(emat);
- emat = NULL;
+ emat = build_edge_mats(nodes, mvert, totvert, medge, emap, totedge, &has_valid_root);
+ skin_nodes = build_frames(mvert, totvert, nodes, emap, emat);
+ MEM_freeN(emat);
+ emat = NULL;
- bm = build_skin(skin_nodes, totvert, emap, medge, totedge, dvert, smd);
+ bm = build_skin(skin_nodes, totvert, emap, medge, totedge, dvert, smd);
- MEM_freeN(skin_nodes);
- MEM_freeN(emap);
- MEM_freeN(emapmem);
+ MEM_freeN(skin_nodes);
+ MEM_freeN(emap);
+ MEM_freeN(emapmem);
- if (!has_valid_root) {
- modifier_setError(&smd->modifier, "No valid root vertex found (you need one per mesh island you want to skin)");
- }
+ if (!has_valid_root) {
+ modifier_setError(
+ &smd->modifier,
+ "No valid root vertex found (you need one per mesh island you want to skin)");
+ }
- if (!bm)
- return NULL;
+ if (!bm)
+ return NULL;
- result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
- BM_mesh_free(bm);
+ result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
+ BM_mesh_free(bm);
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- skin_set_orig_indices(result);
+ skin_set_orig_indices(result);
- return result;
+ return result;
}
static Mesh *final_skin(SkinModifierData *smd, Mesh *mesh)
{
- Mesh *result;
+ Mesh *result;
- /* Skin node layer is required */
- if (!CustomData_get_layer(&mesh->vdata, CD_MVERT_SKIN))
- return mesh;
+ /* Skin node layer is required */
+ if (!CustomData_get_layer(&mesh->vdata, CD_MVERT_SKIN))
+ return mesh;
- mesh = subdivide_base(mesh);
- result = base_skin(mesh, smd);
+ mesh = subdivide_base(mesh);
+ result = base_skin(mesh, smd);
- BKE_id_free(NULL, mesh);
- return result;
+ BKE_id_free(NULL, mesh);
+ return result;
}
-
/**************************** Skin Modifier ***************************/
static void initData(ModifierData *md)
{
- SkinModifierData *smd = (SkinModifierData *) md;
+ SkinModifierData *smd = (SkinModifierData *)md;
- /* Enable in editmode by default */
- md->mode |= eModifierMode_Editmode;
+ /* Enable in editmode by default */
+ md->mode |= eModifierMode_Editmode;
- smd->branch_smoothing = 0;
- smd->flag = 0;
- smd->symmetry_axes = MOD_SKIN_SYMM_X;
+ smd->branch_smoothing = 0;
+ smd->flag = 0;
+ smd->symmetry_axes = MOD_SKIN_SYMM_X;
}
-static Mesh *applyModifier(ModifierData *md,
- const ModifierEvalContext *UNUSED(ctx),
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
{
- Mesh *result;
+ Mesh *result;
- if (!(result = final_skin((SkinModifierData *)md, mesh)))
- return mesh;
- return result;
+ if (!(result = final_skin((SkinModifierData *)md, mesh)))
+ return mesh;
+ return result;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md), CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *UNUSED(md),
+ CustomData_MeshMasks *r_cddata_masks)
{
- r_cddata_masks->vmask |= CD_MASK_MVERT_SKIN | CD_MASK_MDEFORMVERT;
+ r_cddata_masks->vmask |= CD_MASK_MVERT_SKIN | CD_MASK_MDEFORMVERT;
}
ModifierTypeInfo modifierType_Skin = {
- /* name */ "Skin",
- /* structName */ "SkinModifierData",
- /* structSize */ sizeof(SkinModifierData),
- /* type */ eModifierTypeType_Constructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Skin",
+ /* structName */ "SkinModifierData",
+ /* structSize */ sizeof(SkinModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_smoke.c b/source/blender/modifiers/intern/MOD_smoke.c
index 8a0a8e227ae..60d4c1a01c3 100644
--- a/source/blender/modifiers/intern/MOD_smoke.c
+++ b/source/blender/modifiers/intern/MOD_smoke.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include <stddef.h>
#include "MEM_guardedalloc.h"
@@ -50,136 +49,148 @@
static void initData(ModifierData *md)
{
- SmokeModifierData *smd = (SmokeModifierData *) md;
+ SmokeModifierData *smd = (SmokeModifierData *)md;
- smd->domain = NULL;
- smd->flow = NULL;
- smd->coll = NULL;
- smd->type = 0;
- smd->time = -1;
+ smd->domain = NULL;
+ smd->flow = NULL;
+ smd->coll = NULL;
+ smd->type = 0;
+ smd->time = -1;
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
- const SmokeModifierData *smd = (const SmokeModifierData *)md;
- SmokeModifierData *tsmd = (SmokeModifierData *)target;
+ const SmokeModifierData *smd = (const SmokeModifierData *)md;
+ SmokeModifierData *tsmd = (SmokeModifierData *)target;
- smokeModifier_free(tsmd);
- smokeModifier_copy(smd, tsmd, flag);
+ smokeModifier_free(tsmd);
+ smokeModifier_copy(smd, tsmd, flag);
}
static void freeData(ModifierData *md)
{
- SmokeModifierData *smd = (SmokeModifierData *) md;
+ SmokeModifierData *smd = (SmokeModifierData *)md;
- smokeModifier_free(smd);
+ smokeModifier_free(smd);
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- SmokeModifierData *smd = (SmokeModifierData *)md;
-
- if (smd && (smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) {
- if (smd->flow->source == MOD_SMOKE_FLOW_SOURCE_MESH) {
- /* vertex groups */
- if (smd->flow->vgroup_density)
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- /* uv layer */
- if (smd->flow->texture_type == MOD_SMOKE_FLOW_TEXTURE_MAP_UV)
- r_cddata_masks->fmask |= CD_MASK_MTFACE;
- }
- }
+ SmokeModifierData *smd = (SmokeModifierData *)md;
+
+ if (smd && (smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) {
+ if (smd->flow->source == MOD_SMOKE_FLOW_SOURCE_MESH) {
+ /* vertex groups */
+ if (smd->flow->vgroup_density)
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ /* uv layer */
+ if (smd->flow->texture_type == MOD_SMOKE_FLOW_TEXTURE_MAP_UV)
+ r_cddata_masks->fmask |= CD_MASK_MTFACE;
+ }
+ }
}
-static Mesh *applyModifier(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *me)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *me)
{
- SmokeModifierData *smd = (SmokeModifierData *) md;
+ SmokeModifierData *smd = (SmokeModifierData *)md;
- if (ctx->flag & MOD_APPLY_ORCO) {
- return me;
- }
+ if (ctx->flag & MOD_APPLY_ORCO) {
+ return me;
+ }
- Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- return smokeModifier_do(smd, ctx->depsgraph, scene, ctx->object, me);
+ Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ return smokeModifier_do(smd, ctx->depsgraph, scene, ctx->object, me);
}
static bool dependsOnTime(ModifierData *UNUSED(md))
{
- return true;
+ return true;
}
static bool is_flow_cb(Object *UNUSED(ob), ModifierData *md)
{
- SmokeModifierData *smd = (SmokeModifierData *) md;
- return (smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow;
+ SmokeModifierData *smd = (SmokeModifierData *)md;
+ return (smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow;
}
static bool is_coll_cb(Object *UNUSED(ob), ModifierData *md)
{
- SmokeModifierData *smd = (SmokeModifierData *) md;
- return (smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll;
+ SmokeModifierData *smd = (SmokeModifierData *)md;
+ return (smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll;
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- SmokeModifierData *smd = (SmokeModifierData *)md;
-
- if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) {
- DEG_add_collision_relations(ctx->node, ctx->object, smd->domain->fluid_group, eModifierType_Smoke, is_flow_cb, "Smoke Flow");
- DEG_add_collision_relations(ctx->node, ctx->object, smd->domain->coll_group, eModifierType_Smoke, is_coll_cb, "Smoke Coll");
- DEG_add_forcefield_relations(ctx->node, ctx->object, smd->domain->effector_weights, true, PFIELD_SMOKEFLOW, "Smoke Force Field");
- }
+ SmokeModifierData *smd = (SmokeModifierData *)md;
+
+ if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) {
+ DEG_add_collision_relations(ctx->node,
+ ctx->object,
+ smd->domain->fluid_group,
+ eModifierType_Smoke,
+ is_flow_cb,
+ "Smoke Flow");
+ DEG_add_collision_relations(ctx->node,
+ ctx->object,
+ smd->domain->coll_group,
+ eModifierType_Smoke,
+ is_coll_cb,
+ "Smoke Coll");
+ DEG_add_forcefield_relations(ctx->node,
+ ctx->object,
+ smd->domain->effector_weights,
+ true,
+ PFIELD_SMOKEFLOW,
+ "Smoke Force Field");
+ }
}
-static void foreachIDLink(
- ModifierData *md, Object *ob,
- IDWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
- SmokeModifierData *smd = (SmokeModifierData *) md;
+ SmokeModifierData *smd = (SmokeModifierData *)md;
- if (smd->type == MOD_SMOKE_TYPE_DOMAIN && smd->domain) {
- walk(userData, ob, (ID **)&smd->domain->coll_group, IDWALK_CB_NOP);
- walk(userData, ob, (ID **)&smd->domain->fluid_group, IDWALK_CB_NOP);
- walk(userData, ob, (ID **)&smd->domain->eff_group, IDWALK_CB_NOP);
+ if (smd->type == MOD_SMOKE_TYPE_DOMAIN && smd->domain) {
+ walk(userData, ob, (ID **)&smd->domain->coll_group, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&smd->domain->fluid_group, IDWALK_CB_NOP);
+ walk(userData, ob, (ID **)&smd->domain->eff_group, IDWALK_CB_NOP);
- if (smd->domain->effector_weights) {
- walk(userData, ob, (ID **)&smd->domain->effector_weights->group, IDWALK_CB_NOP);
- }
- }
+ if (smd->domain->effector_weights) {
+ walk(userData, ob, (ID **)&smd->domain->effector_weights->group, IDWALK_CB_NOP);
+ }
+ }
- if (smd->type == MOD_SMOKE_TYPE_FLOW && smd->flow) {
- walk(userData, ob, (ID **)&smd->flow->noise_texture, IDWALK_CB_USER);
- }
+ if (smd->type == MOD_SMOKE_TYPE_FLOW && smd->flow) {
+ walk(userData, ob, (ID **)&smd->flow->noise_texture, IDWALK_CB_USER);
+ }
}
ModifierTypeInfo modifierType_Smoke = {
- /* name */ "Smoke",
- /* structName */ "SmokeModifierData",
- /* structSize */ sizeof(SmokeModifierData),
- /* type */ eModifierTypeType_Constructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_UsesPointCache |
- eModifierTypeFlag_Single,
-
- /* copyData */ copyData,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ freeData,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ foreachIDLink,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Smoke",
+ /* structName */ "SmokeModifierData",
+ /* structSize */ sizeof(SmokeModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_UsesPointCache |
+ eModifierTypeFlag_Single,
+
+ /* copyData */ copyData,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ freeData,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c
index 685a4837d32..08430d0e8f1 100644
--- a/source/blender/modifiers/intern/MOD_smooth.c
+++ b/source/blender/modifiers/intern/MOD_smooth.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
@@ -40,225 +39,230 @@
#include "MOD_modifiertypes.h"
#include "MOD_util.h"
-
static void initData(ModifierData *md)
{
- SmoothModifierData *smd = (SmoothModifierData *) md;
+ SmoothModifierData *smd = (SmoothModifierData *)md;
- smd->fac = 0.5f;
- smd->repeat = 1;
- smd->flag = MOD_SMOOTH_X | MOD_SMOOTH_Y | MOD_SMOOTH_Z;
- smd->defgrp_name[0] = '\0';
+ smd->fac = 0.5f;
+ smd->repeat = 1;
+ smd->flag = MOD_SMOOTH_X | MOD_SMOOTH_Y | MOD_SMOOTH_Z;
+ smd->defgrp_name[0] = '\0';
}
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(useRenderParams))
{
- SmoothModifierData *smd = (SmoothModifierData *) md;
- short flag;
+ SmoothModifierData *smd = (SmoothModifierData *)md;
+ short flag;
- flag = smd->flag & (MOD_SMOOTH_X | MOD_SMOOTH_Y | MOD_SMOOTH_Z);
+ flag = smd->flag & (MOD_SMOOTH_X | MOD_SMOOTH_Y | MOD_SMOOTH_Z);
- /* disable if modifier is off for X, Y and Z or if factor is 0 */
- if ((smd->fac == 0.0f) || flag == 0) return 1;
+ /* disable if modifier is off for X, Y and Z or if factor is 0 */
+ if ((smd->fac == 0.0f) || flag == 0)
+ return 1;
- return 0;
+ return 0;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- SmoothModifierData *smd = (SmoothModifierData *)md;
+ SmoothModifierData *smd = (SmoothModifierData *)md;
- /* ask for vertexgroups if we need them */
- if (smd->defgrp_name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ /* ask for vertexgroups if we need them */
+ if (smd->defgrp_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
static void smoothModifier_do(
- SmoothModifierData *smd, Object *ob, Mesh *mesh,
- float (*vertexCos)[3], int numVerts)
+ SmoothModifierData *smd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int numVerts)
{
- MDeformVert *dvert = NULL;
- MEdge *medges = NULL;
-
- int i, j, numDMEdges, defgrp_index;
- unsigned char *uctmp;
- float *ftmp, fac, facm;
-
- ftmp = (float *)MEM_calloc_arrayN(numVerts, 3 * sizeof(float),
- "smoothmodifier_f");
- if (!ftmp) return;
- uctmp = (unsigned char *)MEM_calloc_arrayN(numVerts, sizeof(unsigned char),
- "smoothmodifier_uc");
- if (!uctmp) {
- if (ftmp) MEM_freeN(ftmp);
- return;
- }
-
- fac = smd->fac;
- facm = 1 - fac;
-
- if (mesh != NULL) {
- medges = mesh->medge;
- numDMEdges = mesh->totedge;
- }
- else {
- medges = NULL;
- numDMEdges = 0;
- }
-
- MOD_get_vgroup(ob, mesh, smd->defgrp_name, &dvert, &defgrp_index);
-
- /* NOTICE: this can be optimized a little bit by moving the
- * if (dvert) out of the loop, if needed */
- for (j = 0; j < smd->repeat; j++) {
- for (i = 0; i < numDMEdges; i++) {
- float fvec[3];
- float *v1, *v2;
- unsigned int idx1, idx2;
-
- idx1 = medges[i].v1;
- idx2 = medges[i].v2;
-
- v1 = vertexCos[idx1];
- v2 = vertexCos[idx2];
-
- mid_v3_v3v3(fvec, v1, v2);
-
- v1 = &ftmp[idx1 * 3];
- v2 = &ftmp[idx2 * 3];
-
- if (uctmp[idx1] < 255) {
- uctmp[idx1]++;
- add_v3_v3(v1, fvec);
- }
- if (uctmp[idx2] < 255) {
- uctmp[idx2]++;
- add_v3_v3(v2, fvec);
- }
- }
-
- if (dvert) {
- MDeformVert *dv = dvert;
- for (i = 0; i < numVerts; i++, dv++) {
- float f, fm, facw, *fp, *v;
- short flag = smd->flag;
-
- v = vertexCos[i];
- fp = &ftmp[i * 3];
-
-
- f = defvert_find_weight(dv, defgrp_index);
- if (f <= 0.0f) continue;
-
- f *= fac;
- fm = 1.0f - f;
-
- /* fp is the sum of uctmp[i] verts, so must be averaged */
- facw = 0.0f;
- if (uctmp[i])
- facw = f / (float)uctmp[i];
-
- if (flag & MOD_SMOOTH_X)
- v[0] = fm * v[0] + facw * fp[0];
- if (flag & MOD_SMOOTH_Y)
- v[1] = fm * v[1] + facw * fp[1];
- if (flag & MOD_SMOOTH_Z)
- v[2] = fm * v[2] + facw * fp[2];
- }
- }
- else { /* no vertex group */
- for (i = 0; i < numVerts; i++) {
- float facw, *fp, *v;
- short flag = smd->flag;
-
- v = vertexCos[i];
- fp = &ftmp[i * 3];
-
- /* fp is the sum of uctmp[i] verts, so must be averaged */
- facw = 0.0f;
- if (uctmp[i])
- facw = fac / (float)uctmp[i];
-
- if (flag & MOD_SMOOTH_X)
- v[0] = facm * v[0] + facw * fp[0];
- if (flag & MOD_SMOOTH_Y)
- v[1] = facm * v[1] + facw * fp[1];
- if (flag & MOD_SMOOTH_Z)
- v[2] = facm * v[2] + facw * fp[2];
- }
-
- }
-
- memset(ftmp, 0, 3 * sizeof(float) * numVerts);
- memset(uctmp, 0, sizeof(unsigned char) * numVerts);
- }
-
- MEM_freeN(ftmp);
- MEM_freeN(uctmp);
+ MDeformVert *dvert = NULL;
+ MEdge *medges = NULL;
+
+ int i, j, numDMEdges, defgrp_index;
+ unsigned char *uctmp;
+ float *ftmp, fac, facm;
+
+ ftmp = (float *)MEM_calloc_arrayN(numVerts, 3 * sizeof(float), "smoothmodifier_f");
+ if (!ftmp)
+ return;
+ uctmp = (unsigned char *)MEM_calloc_arrayN(numVerts, sizeof(unsigned char), "smoothmodifier_uc");
+ if (!uctmp) {
+ if (ftmp)
+ MEM_freeN(ftmp);
+ return;
+ }
+
+ fac = smd->fac;
+ facm = 1 - fac;
+
+ if (mesh != NULL) {
+ medges = mesh->medge;
+ numDMEdges = mesh->totedge;
+ }
+ else {
+ medges = NULL;
+ numDMEdges = 0;
+ }
+
+ MOD_get_vgroup(ob, mesh, smd->defgrp_name, &dvert, &defgrp_index);
+
+ /* NOTICE: this can be optimized a little bit by moving the
+ * if (dvert) out of the loop, if needed */
+ for (j = 0; j < smd->repeat; j++) {
+ for (i = 0; i < numDMEdges; i++) {
+ float fvec[3];
+ float *v1, *v2;
+ unsigned int idx1, idx2;
+
+ idx1 = medges[i].v1;
+ idx2 = medges[i].v2;
+
+ v1 = vertexCos[idx1];
+ v2 = vertexCos[idx2];
+
+ mid_v3_v3v3(fvec, v1, v2);
+
+ v1 = &ftmp[idx1 * 3];
+ v2 = &ftmp[idx2 * 3];
+
+ if (uctmp[idx1] < 255) {
+ uctmp[idx1]++;
+ add_v3_v3(v1, fvec);
+ }
+ if (uctmp[idx2] < 255) {
+ uctmp[idx2]++;
+ add_v3_v3(v2, fvec);
+ }
+ }
+
+ if (dvert) {
+ MDeformVert *dv = dvert;
+ for (i = 0; i < numVerts; i++, dv++) {
+ float f, fm, facw, *fp, *v;
+ short flag = smd->flag;
+
+ v = vertexCos[i];
+ fp = &ftmp[i * 3];
+
+ f = defvert_find_weight(dv, defgrp_index);
+ if (f <= 0.0f)
+ continue;
+
+ f *= fac;
+ fm = 1.0f - f;
+
+ /* fp is the sum of uctmp[i] verts, so must be averaged */
+ facw = 0.0f;
+ if (uctmp[i])
+ facw = f / (float)uctmp[i];
+
+ if (flag & MOD_SMOOTH_X)
+ v[0] = fm * v[0] + facw * fp[0];
+ if (flag & MOD_SMOOTH_Y)
+ v[1] = fm * v[1] + facw * fp[1];
+ if (flag & MOD_SMOOTH_Z)
+ v[2] = fm * v[2] + facw * fp[2];
+ }
+ }
+ else { /* no vertex group */
+ for (i = 0; i < numVerts; i++) {
+ float facw, *fp, *v;
+ short flag = smd->flag;
+
+ v = vertexCos[i];
+ fp = &ftmp[i * 3];
+
+ /* fp is the sum of uctmp[i] verts, so must be averaged */
+ facw = 0.0f;
+ if (uctmp[i])
+ facw = fac / (float)uctmp[i];
+
+ if (flag & MOD_SMOOTH_X)
+ v[0] = facm * v[0] + facw * fp[0];
+ if (flag & MOD_SMOOTH_Y)
+ v[1] = facm * v[1] + facw * fp[1];
+ if (flag & MOD_SMOOTH_Z)
+ v[2] = facm * v[2] + facw * fp[2];
+ }
+ }
+
+ memset(ftmp, 0, 3 * sizeof(float) * numVerts);
+ memset(uctmp, 0, sizeof(unsigned char) * numVerts);
+ }
+
+ MEM_freeN(ftmp);
+ MEM_freeN(uctmp);
}
-static void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh,
- float (*vertexCos)[3], int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- SmoothModifierData *smd = (SmoothModifierData *)md;
- Mesh *mesh_src = NULL;
+ SmoothModifierData *smd = (SmoothModifierData *)md;
+ Mesh *mesh_src = NULL;
- /* mesh_src is needed for vgroups, and taking edges into account. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ /* mesh_src is needed for vgroups, and taking edges into account. */
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
- smoothModifier_do(smd, ctx->object, mesh_src, vertexCos, numVerts);
+ smoothModifier_do(smd, ctx->object, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-static void deformVertsEM(
- ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *editData,
- Mesh *mesh, float (*vertexCos)[3], int numVerts)
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *editData,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- SmoothModifierData *smd = (SmoothModifierData *)md;
- Mesh *mesh_src = NULL;
+ SmoothModifierData *smd = (SmoothModifierData *)md;
+ Mesh *mesh_src = NULL;
- /* mesh_src is needed for vgroups, and taking edges into account. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ /* mesh_src is needed for vgroups, and taking edges into account. */
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
- smoothModifier_do(smd, ctx->object, mesh_src, vertexCos, numVerts);
+ smoothModifier_do(smd, ctx->object, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-
ModifierTypeInfo modifierType_Smooth = {
- /* name */ "Smooth",
- /* structName */ "SmoothModifierData",
- /* structSize */ sizeof(SmoothModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_SupportsEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Smooth",
+ /* structName */ "SmoothModifierData",
+ /* structSize */ sizeof(SmoothModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs |
+ eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_softbody.c b/source/blender/modifiers/intern/MOD_softbody.c
index 2ff50ee3977..48ccd9b83ed 100644
--- a/source/blender/modifiers/intern/MOD_softbody.c
+++ b/source/blender/modifiers/intern/MOD_softbody.c
@@ -40,57 +40,62 @@
#include "MOD_modifiertypes.h"
-static void deformVerts(
- ModifierData *UNUSED(md), const ModifierEvalContext *ctx,
- Mesh *UNUSED(derivedData),
- float (*vertexCos)[3],
- int numVerts)
+static void deformVerts(ModifierData *UNUSED(md),
+ const ModifierEvalContext *ctx,
+ Mesh *UNUSED(derivedData),
+ float (*vertexCos)[3],
+ int numVerts)
{
- Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- sbObjectStep(ctx->depsgraph, scene, ctx->object, DEG_get_ctime(ctx->depsgraph), vertexCos, numVerts);
+ Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ sbObjectStep(
+ ctx->depsgraph, scene, ctx->object, DEG_get_ctime(ctx->depsgraph), vertexCos, numVerts);
}
static bool dependsOnTime(ModifierData *UNUSED(md))
{
- return true;
+ return true;
}
static void updateDepsgraph(ModifierData *UNUSED(md), const ModifierUpdateDepsgraphContext *ctx)
{
- if (ctx->object->soft) {
- /* Actual code uses ccd_build_deflector_hash */
- DEG_add_collision_relations(ctx->node, ctx->object, ctx->object->soft->collision_group, eModifierType_Collision, NULL, "Softbody Collision");
- DEG_add_forcefield_relations(ctx->node, ctx->object, ctx->object->soft->effector_weights, true, 0, "Softbody Field");
- }
+ if (ctx->object->soft) {
+ /* Actual code uses ccd_build_deflector_hash */
+ DEG_add_collision_relations(ctx->node,
+ ctx->object,
+ ctx->object->soft->collision_group,
+ eModifierType_Collision,
+ NULL,
+ "Softbody Collision");
+ DEG_add_forcefield_relations(
+ ctx->node, ctx->object, ctx->object->soft->effector_weights, true, 0, "Softbody Field");
+ }
}
ModifierTypeInfo modifierType_Softbody = {
- /* name */ "Softbody",
- /* structName */ "SoftbodyModifierData",
- /* structSize */ sizeof(SoftbodyModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_AcceptsLattice |
- eModifierTypeFlag_RequiresOriginalData |
- eModifierTypeFlag_Single,
+ /* name */ "Softbody",
+ /* structName */ "SoftbodyModifierData",
+ /* structSize */ sizeof(SoftbodyModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice |
+ eModifierTypeFlag_RequiresOriginalData | eModifierTypeFlag_Single,
- /* copyData */ NULL,
+ /* copyData */ NULL,
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
- /* initData */ NULL,
- /* requiredDataMask */ NULL,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* initData */ NULL,
+ /* requiredDataMask */ NULL,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index e8a7d8217ed..9fb2e728dd9 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -50,13 +50,13 @@
/* could be exposed for other functions to use */
typedef struct EdgeFaceRef {
- int p1; /* init as -1 */
- int p2;
+ int p1; /* init as -1 */
+ int p2;
} EdgeFaceRef;
BLI_INLINE bool edgeref_is_init(const EdgeFaceRef *edge_ref)
{
- return !((edge_ref->p1 == 0) && (edge_ref->p2 == 0));
+ return !((edge_ref->p1 == 0) && (edge_ref->p2 == 0));
}
/**
@@ -66,912 +66,934 @@ BLI_INLINE bool edgeref_is_init(const EdgeFaceRef *edge_ref)
*/
static void mesh_calc_hq_normal(Mesh *mesh, float (*poly_nors)[3], float (*r_vert_nors)[3])
{
- int i, numVerts, numEdges, numPolys;
- MPoly *mpoly, *mp;
- MLoop *mloop, *ml;
- MEdge *medge, *ed;
- MVert *mvert, *mv;
-
- numVerts = mesh->totvert;
- numEdges = mesh->totedge;
- numPolys = mesh->totpoly;
- mpoly = mesh->mpoly;
- medge = mesh->medge;
- mvert = mesh->mvert;
- mloop = mesh->mloop;
-
- /* we don't want to overwrite any referenced layers */
-
- /* Doesn't work here! */
+ int i, numVerts, numEdges, numPolys;
+ MPoly *mpoly, *mp;
+ MLoop *mloop, *ml;
+ MEdge *medge, *ed;
+ MVert *mvert, *mv;
+
+ numVerts = mesh->totvert;
+ numEdges = mesh->totedge;
+ numPolys = mesh->totpoly;
+ mpoly = mesh->mpoly;
+ medge = mesh->medge;
+ mvert = mesh->mvert;
+ mloop = mesh->mloop;
+
+ /* we don't want to overwrite any referenced layers */
+
+ /* Doesn't work here! */
#if 0
- mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, numVerts);
- cddm->mvert = mv;
+ mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, numVerts);
+ cddm->mvert = mv;
#endif
- mv = mvert;
- mp = mpoly;
-
- {
- EdgeFaceRef *edge_ref_array = MEM_calloc_arrayN((size_t)numEdges, sizeof(EdgeFaceRef), "Edge Connectivity");
- EdgeFaceRef *edge_ref;
- float edge_normal[3];
-
- /* Add an edge reference if it's not there, pointing back to the face index. */
- for (i = 0; i < numPolys; i++, mp++) {
- int j;
-
- ml = mloop + mp->loopstart;
-
- for (j = 0; j < mp->totloop; j++, ml++) {
- /* --- add edge ref to face --- */
- edge_ref = &edge_ref_array[ml->e];
- if (!edgeref_is_init(edge_ref)) {
- edge_ref->p1 = i;
- edge_ref->p2 = -1;
- }
- else if ((edge_ref->p1 != -1) && (edge_ref->p2 == -1)) {
- edge_ref->p2 = i;
- }
- else {
- /* 3+ faces using an edge, we can't handle this usefully */
- edge_ref->p1 = edge_ref->p2 = -1;
+ mv = mvert;
+ mp = mpoly;
+
+ {
+ EdgeFaceRef *edge_ref_array = MEM_calloc_arrayN(
+ (size_t)numEdges, sizeof(EdgeFaceRef), "Edge Connectivity");
+ EdgeFaceRef *edge_ref;
+ float edge_normal[3];
+
+ /* Add an edge reference if it's not there, pointing back to the face index. */
+ for (i = 0; i < numPolys; i++, mp++) {
+ int j;
+
+ ml = mloop + mp->loopstart;
+
+ for (j = 0; j < mp->totloop; j++, ml++) {
+ /* --- add edge ref to face --- */
+ edge_ref = &edge_ref_array[ml->e];
+ if (!edgeref_is_init(edge_ref)) {
+ edge_ref->p1 = i;
+ edge_ref->p2 = -1;
+ }
+ else if ((edge_ref->p1 != -1) && (edge_ref->p2 == -1)) {
+ edge_ref->p2 = i;
+ }
+ else {
+ /* 3+ faces using an edge, we can't handle this usefully */
+ edge_ref->p1 = edge_ref->p2 = -1;
#ifdef USE_NONMANIFOLD_WORKAROUND
- medge[ml->e].flag |= ME_EDGE_TMP_TAG;
+ medge[ml->e].flag |= ME_EDGE_TMP_TAG;
#endif
- }
- /* --- done --- */
- }
- }
-
- for (i = 0, ed = medge, edge_ref = edge_ref_array; i < numEdges; i++, ed++, edge_ref++) {
- /* Get the edge vert indices, and edge value (the face indices that use it) */
-
- if (edgeref_is_init(edge_ref) && (edge_ref->p1 != -1)) {
- if (edge_ref->p2 != -1) {
- /* We have 2 faces using this edge, calculate the edges normal
- * using the angle between the 2 faces as a weighting */
+ }
+ /* --- done --- */
+ }
+ }
+
+ for (i = 0, ed = medge, edge_ref = edge_ref_array; i < numEdges; i++, ed++, edge_ref++) {
+ /* Get the edge vert indices, and edge value (the face indices that use it) */
+
+ if (edgeref_is_init(edge_ref) && (edge_ref->p1 != -1)) {
+ if (edge_ref->p2 != -1) {
+ /* We have 2 faces using this edge, calculate the edges normal
+ * using the angle between the 2 faces as a weighting */
#if 0
- add_v3_v3v3(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]);
- normalize_v3_length(
- edge_normal,
- angle_normalized_v3v3(face_nors[edge_ref->f1], face_nors[edge_ref->f2]));
+ add_v3_v3v3(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]);
+ normalize_v3_length(
+ edge_normal,
+ angle_normalized_v3v3(face_nors[edge_ref->f1], face_nors[edge_ref->f2]));
#else
- mid_v3_v3v3_angle_weighted(edge_normal, poly_nors[edge_ref->p1], poly_nors[edge_ref->p2]);
+ mid_v3_v3v3_angle_weighted(
+ edge_normal, poly_nors[edge_ref->p1], poly_nors[edge_ref->p2]);
#endif
- }
- else {
- /* only one face attached to that edge */
- /* an edge without another attached- the weight on this is undefined */
- copy_v3_v3(edge_normal, poly_nors[edge_ref->p1]);
- }
- add_v3_v3(r_vert_nors[ed->v1], edge_normal);
- add_v3_v3(r_vert_nors[ed->v2], edge_normal);
- }
- }
- MEM_freeN(edge_ref_array);
- }
-
- /* normalize vertex normals and assign */
- for (i = 0; i < numVerts; i++, mv++) {
- if (normalize_v3(r_vert_nors[i]) == 0.0f) {
- normal_short_to_float_v3(r_vert_nors[i], mv->no);
- }
- }
+ }
+ else {
+ /* only one face attached to that edge */
+ /* an edge without another attached- the weight on this is undefined */
+ copy_v3_v3(edge_normal, poly_nors[edge_ref->p1]);
+ }
+ add_v3_v3(r_vert_nors[ed->v1], edge_normal);
+ add_v3_v3(r_vert_nors[ed->v2], edge_normal);
+ }
+ }
+ MEM_freeN(edge_ref_array);
+ }
+
+ /* normalize vertex normals and assign */
+ for (i = 0; i < numVerts; i++, mv++) {
+ if (normalize_v3(r_vert_nors[i]) == 0.0f) {
+ normal_short_to_float_v3(r_vert_nors[i], mv->no);
+ }
+ }
}
static void initData(ModifierData *md)
{
- SolidifyModifierData *smd = (SolidifyModifierData *) md;
- smd->offset = 0.01f;
- smd->offset_fac = -1.0f;
- smd->flag = MOD_SOLIDIFY_RIM;
+ SolidifyModifierData *smd = (SolidifyModifierData *)md;
+ smd->offset = 0.01f;
+ smd->offset_fac = -1.0f;
+ smd->flag = MOD_SOLIDIFY_RIM;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- SolidifyModifierData *smd = (SolidifyModifierData *) md;
+ SolidifyModifierData *smd = (SolidifyModifierData *)md;
- /* ask for vertexgroups if we need them */
- if (smd->defgrp_name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ /* ask for vertexgroups if we need them */
+ if (smd->defgrp_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
/* specific function for solidify - define locally */
BLI_INLINE void madd_v3v3short_fl(float r[3], const short a[3], const float f)
{
- r[0] += (float)a[0] * f;
- r[1] += (float)a[1] * f;
- r[2] += (float)a[2] * f;
+ r[0] += (float)a[0] * f;
+ r[1] += (float)a[1] * f;
+ r[2] += (float)a[2] * f;
}
-static Mesh *applyModifier(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- Mesh *result;
- const SolidifyModifierData *smd = (SolidifyModifierData *) md;
-
- MVert *mv, *mvert, *orig_mvert;
- MEdge *ed, *medge, *orig_medge;
- MLoop *ml, *mloop, *orig_mloop;
- MPoly *mp, *mpoly, *orig_mpoly;
- const unsigned int numVerts = (unsigned int)mesh->totvert;
- const unsigned int numEdges = (unsigned int)mesh->totedge;
- const unsigned int numPolys = (unsigned int)mesh->totpoly;
- const unsigned int numLoops = (unsigned int)mesh->totloop;
- unsigned int newLoops = 0, newPolys = 0, newEdges = 0, newVerts = 0, rimVerts = 0;
-
- /* only use material offsets if we have 2 or more materials */
- const short mat_nr_max = ctx->object->totcol > 1 ? ctx->object->totcol - 1 : 0;
- const short mat_ofs = mat_nr_max ? smd->mat_ofs : 0;
- const short mat_ofs_rim = mat_nr_max ? smd->mat_ofs_rim : 0;
-
- /* use for edges */
- /* over-alloc new_vert_arr, old_vert_arr */
- unsigned int *new_vert_arr = NULL;
- STACK_DECLARE(new_vert_arr);
-
- unsigned int *new_edge_arr = NULL;
- STACK_DECLARE(new_edge_arr);
-
- unsigned int *old_vert_arr = MEM_calloc_arrayN(numVerts, sizeof(*old_vert_arr), "old_vert_arr in solidify");
-
- unsigned int *edge_users = NULL;
- char *edge_order = NULL;
-
- float (*vert_nors)[3] = NULL;
- float (*poly_nors)[3] = NULL;
-
- const bool need_poly_normals = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) || (smd->flag & MOD_SOLIDIFY_EVEN);
-
- const float ofs_orig = -(((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset);
- const float ofs_new = smd->offset + ofs_orig;
- const float offset_fac_vg = smd->offset_fac_vg;
- const float offset_fac_vg_inv = 1.0f - smd->offset_fac_vg;
- const bool do_flip = (smd->flag & MOD_SOLIDIFY_FLIP) != 0;
- const bool do_clamp = (smd->offset_clamp != 0.0f);
- const bool do_shell = ((smd->flag & MOD_SOLIDIFY_RIM) && (smd->flag & MOD_SOLIDIFY_NOSHELL)) == 0;
-
- /* weights */
- MDeformVert *dvert;
- const bool defgrp_invert = (smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0;
- int defgrp_index;
-
- /* array size is doubled in case of using a shell */
- const unsigned int stride = do_shell ? 2 : 1;
-
- MOD_get_vgroup(ctx->object, mesh, smd->defgrp_name, &dvert, &defgrp_index);
-
- orig_mvert = mesh->mvert;
- orig_medge = mesh->medge;
- orig_mloop = mesh->mloop;
- orig_mpoly = mesh->mpoly;
-
- if (need_poly_normals) {
- /* calculate only face normals */
- poly_nors = MEM_malloc_arrayN(numPolys, sizeof(*poly_nors), __func__);
- BKE_mesh_calc_normals_poly(
- orig_mvert, NULL, (int)numVerts,
- orig_mloop, orig_mpoly,
- (int)numLoops, (int)numPolys,
- poly_nors, true);
- }
-
- STACK_INIT(new_vert_arr, numVerts * 2);
- STACK_INIT(new_edge_arr, numEdges * 2);
-
- if (smd->flag & MOD_SOLIDIFY_RIM) {
- BLI_bitmap *orig_mvert_tag = BLI_BITMAP_NEW(numVerts, __func__);
- unsigned int eidx;
- unsigned int i;
+ Mesh *result;
+ const SolidifyModifierData *smd = (SolidifyModifierData *)md;
+
+ MVert *mv, *mvert, *orig_mvert;
+ MEdge *ed, *medge, *orig_medge;
+ MLoop *ml, *mloop, *orig_mloop;
+ MPoly *mp, *mpoly, *orig_mpoly;
+ const unsigned int numVerts = (unsigned int)mesh->totvert;
+ const unsigned int numEdges = (unsigned int)mesh->totedge;
+ const unsigned int numPolys = (unsigned int)mesh->totpoly;
+ const unsigned int numLoops = (unsigned int)mesh->totloop;
+ unsigned int newLoops = 0, newPolys = 0, newEdges = 0, newVerts = 0, rimVerts = 0;
+
+ /* only use material offsets if we have 2 or more materials */
+ const short mat_nr_max = ctx->object->totcol > 1 ? ctx->object->totcol - 1 : 0;
+ const short mat_ofs = mat_nr_max ? smd->mat_ofs : 0;
+ const short mat_ofs_rim = mat_nr_max ? smd->mat_ofs_rim : 0;
+
+ /* use for edges */
+ /* over-alloc new_vert_arr, old_vert_arr */
+ unsigned int *new_vert_arr = NULL;
+ STACK_DECLARE(new_vert_arr);
+
+ unsigned int *new_edge_arr = NULL;
+ STACK_DECLARE(new_edge_arr);
+
+ unsigned int *old_vert_arr = MEM_calloc_arrayN(
+ numVerts, sizeof(*old_vert_arr), "old_vert_arr in solidify");
+
+ unsigned int *edge_users = NULL;
+ char *edge_order = NULL;
+
+ float(*vert_nors)[3] = NULL;
+ float(*poly_nors)[3] = NULL;
+
+ const bool need_poly_normals = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) ||
+ (smd->flag & MOD_SOLIDIFY_EVEN);
+
+ const float ofs_orig = -(((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset);
+ const float ofs_new = smd->offset + ofs_orig;
+ const float offset_fac_vg = smd->offset_fac_vg;
+ const float offset_fac_vg_inv = 1.0f - smd->offset_fac_vg;
+ const bool do_flip = (smd->flag & MOD_SOLIDIFY_FLIP) != 0;
+ const bool do_clamp = (smd->offset_clamp != 0.0f);
+ const bool do_shell = ((smd->flag & MOD_SOLIDIFY_RIM) && (smd->flag & MOD_SOLIDIFY_NOSHELL)) ==
+ 0;
+
+ /* weights */
+ MDeformVert *dvert;
+ const bool defgrp_invert = (smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0;
+ int defgrp_index;
+
+ /* array size is doubled in case of using a shell */
+ const unsigned int stride = do_shell ? 2 : 1;
+
+ MOD_get_vgroup(ctx->object, mesh, smd->defgrp_name, &dvert, &defgrp_index);
+
+ orig_mvert = mesh->mvert;
+ orig_medge = mesh->medge;
+ orig_mloop = mesh->mloop;
+ orig_mpoly = mesh->mpoly;
+
+ if (need_poly_normals) {
+ /* calculate only face normals */
+ poly_nors = MEM_malloc_arrayN(numPolys, sizeof(*poly_nors), __func__);
+ BKE_mesh_calc_normals_poly(orig_mvert,
+ NULL,
+ (int)numVerts,
+ orig_mloop,
+ orig_mpoly,
+ (int)numLoops,
+ (int)numPolys,
+ poly_nors,
+ true);
+ }
+
+ STACK_INIT(new_vert_arr, numVerts * 2);
+ STACK_INIT(new_edge_arr, numEdges * 2);
+
+ if (smd->flag & MOD_SOLIDIFY_RIM) {
+ BLI_bitmap *orig_mvert_tag = BLI_BITMAP_NEW(numVerts, __func__);
+ unsigned int eidx;
+ unsigned int i;
#define INVALID_UNUSED ((unsigned int)-1)
#define INVALID_PAIR ((unsigned int)-2)
- new_vert_arr = MEM_malloc_arrayN(numVerts, 2 * sizeof(*new_vert_arr), __func__);
- new_edge_arr = MEM_malloc_arrayN(((numEdges * 2) + numVerts), sizeof(*new_edge_arr), __func__);
+ new_vert_arr = MEM_malloc_arrayN(numVerts, 2 * sizeof(*new_vert_arr), __func__);
+ new_edge_arr = MEM_malloc_arrayN(((numEdges * 2) + numVerts), sizeof(*new_edge_arr), __func__);
- edge_users = MEM_malloc_arrayN(numEdges, sizeof(*edge_users), "solid_mod edges");
- edge_order = MEM_malloc_arrayN(numEdges, sizeof(*edge_order), "solid_mod eorder");
+ edge_users = MEM_malloc_arrayN(numEdges, sizeof(*edge_users), "solid_mod edges");
+ edge_order = MEM_malloc_arrayN(numEdges, sizeof(*edge_order), "solid_mod eorder");
-
- /* save doing 2 loops here... */
+ /* save doing 2 loops here... */
#if 0
- copy_vn_i(edge_users, numEdges, INVALID_UNUSED);
+ copy_vn_i(edge_users, numEdges, INVALID_UNUSED);
#endif
- for (eidx = 0, ed = orig_medge; eidx < numEdges; eidx++, ed++) {
- edge_users[eidx] = INVALID_UNUSED;
- }
-
- for (i = 0, mp = orig_mpoly; i < numPolys; i++, mp++) {
- MLoop *ml_prev;
- int j;
-
- ml = orig_mloop + mp->loopstart;
- ml_prev = ml + (mp->totloop - 1);
-
- for (j = 0; j < mp->totloop; j++, ml++) {
- /* add edge user */
- eidx = ml_prev->e;
- if (edge_users[eidx] == INVALID_UNUSED) {
- ed = orig_medge + eidx;
- BLI_assert(ELEM(ml_prev->v, ed->v1, ed->v2) &&
- ELEM(ml->v, ed->v1, ed->v2));
- edge_users[eidx] = (ml_prev->v > ml->v) == (ed->v1 < ed->v2) ? i : (i + numPolys);
- edge_order[eidx] = j;
- }
- else {
- edge_users[eidx] = INVALID_PAIR;
- }
- ml_prev = ml;
- }
- }
-
- for (eidx = 0, ed = orig_medge; eidx < numEdges; eidx++, ed++) {
- if (!ELEM(edge_users[eidx], INVALID_UNUSED, INVALID_PAIR)) {
- BLI_BITMAP_ENABLE(orig_mvert_tag, ed->v1);
- BLI_BITMAP_ENABLE(orig_mvert_tag, ed->v2);
- STACK_PUSH(new_edge_arr, eidx);
- newPolys++;
- newLoops += 4;
- }
- }
-
- for (i = 0; i < numVerts; i++) {
- if (BLI_BITMAP_TEST(orig_mvert_tag, i)) {
- old_vert_arr[i] = STACK_SIZE(new_vert_arr);
- STACK_PUSH(new_vert_arr, i);
- rimVerts++;
- }
- else {
- old_vert_arr[i] = INVALID_UNUSED;
- }
- }
-
- MEM_freeN(orig_mvert_tag);
- }
-
- if (do_shell == false) {
- /* only add rim vertices */
- newVerts = rimVerts;
- /* each extruded face needs an opposite edge */
- newEdges = newPolys;
- }
- else {
- /* (stride == 2) in this case, so no need to add newVerts/newEdges */
- BLI_assert(newVerts == 0);
- BLI_assert(newEdges == 0);
- }
-
- if (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) {
- vert_nors = MEM_calloc_arrayN(numVerts, 3 * sizeof(float), "mod_solid_vno_hq");
- mesh_calc_hq_normal(mesh, poly_nors, vert_nors);
- }
-
- result = BKE_mesh_new_nomain_from_template(
- mesh,
- (int)((numVerts * stride) + newVerts),
- (int)((numEdges * stride) + newEdges + rimVerts), 0,
- (int)((numLoops * stride) + newLoops),
- (int)((numPolys * stride) + newPolys));
-
- mpoly = result->mpoly;
- mloop = result->mloop;
- medge = result->medge;
- mvert = result->mvert;
-
- if (do_shell) {
- CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)numVerts);
- CustomData_copy_data(&mesh->vdata, &result->vdata, 0, (int)numVerts, (int)numVerts);
-
- CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, (int)numEdges);
- CustomData_copy_data(&mesh->edata, &result->edata, 0, (int)numEdges, (int)numEdges);
-
- CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, (int)numLoops);
- /* DO NOT copy here the 'copied' part of loop data, we want to reverse loops
- * (so that winding of copied face get reversed, so that normals get reversed
- * and point in expected direction...).
- * If we also copy data here, then this data get overwritten (and allocated memory becomes memleak). */
-
- CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)numPolys);
- CustomData_copy_data(&mesh->pdata, &result->pdata, 0, (int)numPolys, (int)numPolys);
- }
- else {
- int i, j;
- CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)numVerts);
- for (i = 0, j = (int)numVerts; i < numVerts; i++) {
- if (old_vert_arr[i] != INVALID_UNUSED) {
- CustomData_copy_data(&mesh->vdata, &result->vdata, i, j, 1);
- j++;
- }
- }
-
- CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, (int)numEdges);
-
- for (i = 0, j = (int)numEdges; i < numEdges; i++) {
- if (!ELEM(edge_users[i], INVALID_UNUSED, INVALID_PAIR)) {
- MEdge *ed_src, *ed_dst;
- CustomData_copy_data(&mesh->edata, &result->edata, i, j, 1);
-
- ed_src = &medge[i];
- ed_dst = &medge[j];
- ed_dst->v1 = old_vert_arr[ed_src->v1] + numVerts;
- ed_dst->v2 = old_vert_arr[ed_src->v2] + numVerts;
- j++;
- }
- }
-
- /* will be created later */
- CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, (int)numLoops);
- CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)numPolys);
- }
+ for (eidx = 0, ed = orig_medge; eidx < numEdges; eidx++, ed++) {
+ edge_users[eidx] = INVALID_UNUSED;
+ }
+
+ for (i = 0, mp = orig_mpoly; i < numPolys; i++, mp++) {
+ MLoop *ml_prev;
+ int j;
+
+ ml = orig_mloop + mp->loopstart;
+ ml_prev = ml + (mp->totloop - 1);
+
+ for (j = 0; j < mp->totloop; j++, ml++) {
+ /* add edge user */
+ eidx = ml_prev->e;
+ if (edge_users[eidx] == INVALID_UNUSED) {
+ ed = orig_medge + eidx;
+ BLI_assert(ELEM(ml_prev->v, ed->v1, ed->v2) && ELEM(ml->v, ed->v1, ed->v2));
+ edge_users[eidx] = (ml_prev->v > ml->v) == (ed->v1 < ed->v2) ? i : (i + numPolys);
+ edge_order[eidx] = j;
+ }
+ else {
+ edge_users[eidx] = INVALID_PAIR;
+ }
+ ml_prev = ml;
+ }
+ }
+
+ for (eidx = 0, ed = orig_medge; eidx < numEdges; eidx++, ed++) {
+ if (!ELEM(edge_users[eidx], INVALID_UNUSED, INVALID_PAIR)) {
+ BLI_BITMAP_ENABLE(orig_mvert_tag, ed->v1);
+ BLI_BITMAP_ENABLE(orig_mvert_tag, ed->v2);
+ STACK_PUSH(new_edge_arr, eidx);
+ newPolys++;
+ newLoops += 4;
+ }
+ }
+
+ for (i = 0; i < numVerts; i++) {
+ if (BLI_BITMAP_TEST(orig_mvert_tag, i)) {
+ old_vert_arr[i] = STACK_SIZE(new_vert_arr);
+ STACK_PUSH(new_vert_arr, i);
+ rimVerts++;
+ }
+ else {
+ old_vert_arr[i] = INVALID_UNUSED;
+ }
+ }
+
+ MEM_freeN(orig_mvert_tag);
+ }
+
+ if (do_shell == false) {
+ /* only add rim vertices */
+ newVerts = rimVerts;
+ /* each extruded face needs an opposite edge */
+ newEdges = newPolys;
+ }
+ else {
+ /* (stride == 2) in this case, so no need to add newVerts/newEdges */
+ BLI_assert(newVerts == 0);
+ BLI_assert(newEdges == 0);
+ }
+
+ if (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) {
+ vert_nors = MEM_calloc_arrayN(numVerts, 3 * sizeof(float), "mod_solid_vno_hq");
+ mesh_calc_hq_normal(mesh, poly_nors, vert_nors);
+ }
+
+ result = BKE_mesh_new_nomain_from_template(mesh,
+ (int)((numVerts * stride) + newVerts),
+ (int)((numEdges * stride) + newEdges + rimVerts),
+ 0,
+ (int)((numLoops * stride) + newLoops),
+ (int)((numPolys * stride) + newPolys));
+
+ mpoly = result->mpoly;
+ mloop = result->mloop;
+ medge = result->medge;
+ mvert = result->mvert;
+
+ if (do_shell) {
+ CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)numVerts);
+ CustomData_copy_data(&mesh->vdata, &result->vdata, 0, (int)numVerts, (int)numVerts);
+
+ CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, (int)numEdges);
+ CustomData_copy_data(&mesh->edata, &result->edata, 0, (int)numEdges, (int)numEdges);
+
+ CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, (int)numLoops);
+ /* DO NOT copy here the 'copied' part of loop data, we want to reverse loops
+ * (so that winding of copied face get reversed, so that normals get reversed
+ * and point in expected direction...).
+ * If we also copy data here, then this data get overwritten (and allocated memory becomes memleak). */
+
+ CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)numPolys);
+ CustomData_copy_data(&mesh->pdata, &result->pdata, 0, (int)numPolys, (int)numPolys);
+ }
+ else {
+ int i, j;
+ CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)numVerts);
+ for (i = 0, j = (int)numVerts; i < numVerts; i++) {
+ if (old_vert_arr[i] != INVALID_UNUSED) {
+ CustomData_copy_data(&mesh->vdata, &result->vdata, i, j, 1);
+ j++;
+ }
+ }
+
+ CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, (int)numEdges);
+
+ for (i = 0, j = (int)numEdges; i < numEdges; i++) {
+ if (!ELEM(edge_users[i], INVALID_UNUSED, INVALID_PAIR)) {
+ MEdge *ed_src, *ed_dst;
+ CustomData_copy_data(&mesh->edata, &result->edata, i, j, 1);
+
+ ed_src = &medge[i];
+ ed_dst = &medge[j];
+ ed_dst->v1 = old_vert_arr[ed_src->v1] + numVerts;
+ ed_dst->v2 = old_vert_arr[ed_src->v2] + numVerts;
+ j++;
+ }
+ }
+
+ /* will be created later */
+ CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, (int)numLoops);
+ CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)numPolys);
+ }
#undef INVALID_UNUSED
#undef INVALID_PAIR
-
- /* initializes: (i_end, do_shell_align, mv) */
+ /* initializes: (i_end, do_shell_align, mv) */
#define INIT_VERT_ARRAY_OFFSETS(test) \
- if (((ofs_new >= ofs_orig) == do_flip) == test) { \
- i_end = numVerts; \
- do_shell_align = true; \
- mv = mvert; \
- } \
- else { \
- if (do_shell) { \
- i_end = numVerts; \
- do_shell_align = true; \
- } \
- else { \
- i_end = newVerts ; \
- do_shell_align = false; \
- } \
- mv = &mvert[numVerts]; \
- } (void)0
-
-
- /* flip normals */
-
- if (do_shell) {
- unsigned int i;
-
- mp = mpoly + numPolys;
- for (i = 0; i < mesh->totpoly; i++, mp++) {
- const int loop_end = mp->totloop - 1;
- MLoop *ml2;
- unsigned int e;
- int j;
-
- /* reverses the loop direction (MLoop.v as well as custom-data)
- * MLoop.e also needs to be corrected too, done in a separate loop below. */
- ml2 = mloop + mp->loopstart + mesh->totloop;
+ if (((ofs_new >= ofs_orig) == do_flip) == test) { \
+ i_end = numVerts; \
+ do_shell_align = true; \
+ mv = mvert; \
+ } \
+ else { \
+ if (do_shell) { \
+ i_end = numVerts; \
+ do_shell_align = true; \
+ } \
+ else { \
+ i_end = newVerts; \
+ do_shell_align = false; \
+ } \
+ mv = &mvert[numVerts]; \
+ } \
+ (void)0
+
+ /* flip normals */
+
+ if (do_shell) {
+ unsigned int i;
+
+ mp = mpoly + numPolys;
+ for (i = 0; i < mesh->totpoly; i++, mp++) {
+ const int loop_end = mp->totloop - 1;
+ MLoop *ml2;
+ unsigned int e;
+ int j;
+
+ /* reverses the loop direction (MLoop.v as well as custom-data)
+ * MLoop.e also needs to be corrected too, done in a separate loop below. */
+ ml2 = mloop + mp->loopstart + mesh->totloop;
#if 0
- for (j = 0; j < mp->totloop; j++) {
- CustomData_copy_data(&mesh->ldata, &result->ldata, mp->loopstart + j,
- mp->loopstart + (loop_end - j) + mesh->totloop, 1);
- }
+ for (j = 0; j < mp->totloop; j++) {
+ CustomData_copy_data(&mesh->ldata, &result->ldata, mp->loopstart + j,
+ mp->loopstart + (loop_end - j) + mesh->totloop, 1);
+ }
#else
- /* slightly more involved, keep the first vertex the same for the copy,
- * ensures the diagonals in the new face match the original. */
- j = 0;
- for (int j_prev = loop_end; j < mp->totloop; j_prev = j++) {
- CustomData_copy_data(&mesh->ldata, &result->ldata, mp->loopstart + j,
- mp->loopstart + (loop_end - j_prev) + mesh->totloop, 1);
- }
+ /* slightly more involved, keep the first vertex the same for the copy,
+ * ensures the diagonals in the new face match the original. */
+ j = 0;
+ for (int j_prev = loop_end; j < mp->totloop; j_prev = j++) {
+ CustomData_copy_data(&mesh->ldata,
+ &result->ldata,
+ mp->loopstart + j,
+ mp->loopstart + (loop_end - j_prev) + mesh->totloop,
+ 1);
+ }
#endif
- if (mat_ofs) {
- mp->mat_nr += mat_ofs;
- CLAMP(mp->mat_nr, 0, mat_nr_max);
- }
-
- e = ml2[0].e;
- for (j = 0; j < loop_end; j++) {
- ml2[j].e = ml2[j + 1].e;
- }
- ml2[loop_end].e = e;
-
- mp->loopstart += mesh->totloop;
-
- for (j = 0; j < mp->totloop; j++) {
- ml2[j].e += numEdges;
- ml2[j].v += numVerts;
- }
- }
-
- for (i = 0, ed = medge + numEdges; i < numEdges; i++, ed++) {
- ed->v1 += numVerts;
- ed->v2 += numVerts;
- }
- }
-
- /* note, copied vertex layers don't have flipped normals yet. do this after applying offset */
- if ((smd->flag & MOD_SOLIDIFY_EVEN) == 0) {
- /* no even thickness, very simple */
- float scalar_short;
- float scalar_short_vgroup;
-
- /* for clamping */
- float *vert_lens = NULL;
- const float offset = fabsf(smd->offset) * smd->offset_clamp;
- const float offset_sq = offset * offset;
-
- if (do_clamp) {
- unsigned int i;
-
- vert_lens = MEM_malloc_arrayN(numVerts, sizeof(float), "vert_lens");
- copy_vn_fl(vert_lens, (int)numVerts, FLT_MAX);
- for (i = 0; i < numEdges; i++) {
- const float ed_len_sq = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co);
- vert_lens[medge[i].v1] = min_ff(vert_lens[medge[i].v1], ed_len_sq);
- vert_lens[medge[i].v2] = min_ff(vert_lens[medge[i].v2], ed_len_sq);
- }
- }
-
- if (ofs_new != 0.0f) {
- unsigned int i_orig, i_end;
- bool do_shell_align;
-
- scalar_short = scalar_short_vgroup = ofs_new / 32767.0f;
-
- INIT_VERT_ARRAY_OFFSETS(false);
-
- for (i_orig = 0; i_orig < i_end; i_orig++, mv++) {
- const unsigned int i = do_shell_align ? i_orig : new_vert_arr[i_orig];
- if (dvert) {
- MDeformVert *dv = &dvert[i];
- if (defgrp_invert) scalar_short_vgroup = 1.0f - defvert_find_weight(dv, defgrp_index);
- else scalar_short_vgroup = defvert_find_weight(dv, defgrp_index);
- scalar_short_vgroup = (offset_fac_vg + (scalar_short_vgroup * offset_fac_vg_inv)) * scalar_short;
- }
- if (do_clamp) {
- /* always reset becaise we may have set before */
- if (dvert == NULL) {
- scalar_short_vgroup = scalar_short;
- }
- if (vert_lens[i] < offset_sq) {
- float scalar = sqrtf(vert_lens[i]) / offset;
- scalar_short_vgroup *= scalar;
- }
- }
- madd_v3v3short_fl(mv->co, mv->no, scalar_short_vgroup);
- }
- }
-
- if (ofs_orig != 0.0f) {
- unsigned int i_orig, i_end;
- bool do_shell_align;
-
- scalar_short = scalar_short_vgroup = ofs_orig / 32767.0f;
-
- /* as above but swapped */
- INIT_VERT_ARRAY_OFFSETS(true);
-
- for (i_orig = 0; i_orig < i_end; i_orig++, mv++) {
- const unsigned int i = do_shell_align ? i_orig : new_vert_arr[i_orig];
- if (dvert) {
- MDeformVert *dv = &dvert[i];
- if (defgrp_invert) scalar_short_vgroup = 1.0f - defvert_find_weight(dv, defgrp_index);
- else scalar_short_vgroup = defvert_find_weight(dv, defgrp_index);
- scalar_short_vgroup = (offset_fac_vg + (scalar_short_vgroup * offset_fac_vg_inv)) * scalar_short;
- }
- if (do_clamp) {
- /* always reset becaise we may have set before */
- if (dvert == NULL) {
- scalar_short_vgroup = scalar_short;
- }
- if (vert_lens[i] < offset_sq) {
- float scalar = sqrtf(vert_lens[i]) / offset;
- scalar_short_vgroup *= scalar;
- }
- }
- madd_v3v3short_fl(mv->co, mv->no, scalar_short_vgroup);
- }
- }
-
- if (do_clamp) {
- MEM_freeN(vert_lens);
- }
- }
- else {
+ if (mat_ofs) {
+ mp->mat_nr += mat_ofs;
+ CLAMP(mp->mat_nr, 0, mat_nr_max);
+ }
+
+ e = ml2[0].e;
+ for (j = 0; j < loop_end; j++) {
+ ml2[j].e = ml2[j + 1].e;
+ }
+ ml2[loop_end].e = e;
+
+ mp->loopstart += mesh->totloop;
+
+ for (j = 0; j < mp->totloop; j++) {
+ ml2[j].e += numEdges;
+ ml2[j].v += numVerts;
+ }
+ }
+
+ for (i = 0, ed = medge + numEdges; i < numEdges; i++, ed++) {
+ ed->v1 += numVerts;
+ ed->v2 += numVerts;
+ }
+ }
+
+ /* note, copied vertex layers don't have flipped normals yet. do this after applying offset */
+ if ((smd->flag & MOD_SOLIDIFY_EVEN) == 0) {
+ /* no even thickness, very simple */
+ float scalar_short;
+ float scalar_short_vgroup;
+
+ /* for clamping */
+ float *vert_lens = NULL;
+ const float offset = fabsf(smd->offset) * smd->offset_clamp;
+ const float offset_sq = offset * offset;
+
+ if (do_clamp) {
+ unsigned int i;
+
+ vert_lens = MEM_malloc_arrayN(numVerts, sizeof(float), "vert_lens");
+ copy_vn_fl(vert_lens, (int)numVerts, FLT_MAX);
+ for (i = 0; i < numEdges; i++) {
+ const float ed_len_sq = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co);
+ vert_lens[medge[i].v1] = min_ff(vert_lens[medge[i].v1], ed_len_sq);
+ vert_lens[medge[i].v2] = min_ff(vert_lens[medge[i].v2], ed_len_sq);
+ }
+ }
+
+ if (ofs_new != 0.0f) {
+ unsigned int i_orig, i_end;
+ bool do_shell_align;
+
+ scalar_short = scalar_short_vgroup = ofs_new / 32767.0f;
+
+ INIT_VERT_ARRAY_OFFSETS(false);
+
+ for (i_orig = 0; i_orig < i_end; i_orig++, mv++) {
+ const unsigned int i = do_shell_align ? i_orig : new_vert_arr[i_orig];
+ if (dvert) {
+ MDeformVert *dv = &dvert[i];
+ if (defgrp_invert)
+ scalar_short_vgroup = 1.0f - defvert_find_weight(dv, defgrp_index);
+ else
+ scalar_short_vgroup = defvert_find_weight(dv, defgrp_index);
+ scalar_short_vgroup = (offset_fac_vg + (scalar_short_vgroup * offset_fac_vg_inv)) *
+ scalar_short;
+ }
+ if (do_clamp) {
+ /* always reset becaise we may have set before */
+ if (dvert == NULL) {
+ scalar_short_vgroup = scalar_short;
+ }
+ if (vert_lens[i] < offset_sq) {
+ float scalar = sqrtf(vert_lens[i]) / offset;
+ scalar_short_vgroup *= scalar;
+ }
+ }
+ madd_v3v3short_fl(mv->co, mv->no, scalar_short_vgroup);
+ }
+ }
+
+ if (ofs_orig != 0.0f) {
+ unsigned int i_orig, i_end;
+ bool do_shell_align;
+
+ scalar_short = scalar_short_vgroup = ofs_orig / 32767.0f;
+
+ /* as above but swapped */
+ INIT_VERT_ARRAY_OFFSETS(true);
+
+ for (i_orig = 0; i_orig < i_end; i_orig++, mv++) {
+ const unsigned int i = do_shell_align ? i_orig : new_vert_arr[i_orig];
+ if (dvert) {
+ MDeformVert *dv = &dvert[i];
+ if (defgrp_invert)
+ scalar_short_vgroup = 1.0f - defvert_find_weight(dv, defgrp_index);
+ else
+ scalar_short_vgroup = defvert_find_weight(dv, defgrp_index);
+ scalar_short_vgroup = (offset_fac_vg + (scalar_short_vgroup * offset_fac_vg_inv)) *
+ scalar_short;
+ }
+ if (do_clamp) {
+ /* always reset becaise we may have set before */
+ if (dvert == NULL) {
+ scalar_short_vgroup = scalar_short;
+ }
+ if (vert_lens[i] < offset_sq) {
+ float scalar = sqrtf(vert_lens[i]) / offset;
+ scalar_short_vgroup *= scalar;
+ }
+ }
+ madd_v3v3short_fl(mv->co, mv->no, scalar_short_vgroup);
+ }
+ }
+
+ if (do_clamp) {
+ MEM_freeN(vert_lens);
+ }
+ }
+ else {
#ifdef USE_NONMANIFOLD_WORKAROUND
- const bool check_non_manifold = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) != 0;
+ const bool check_non_manifold = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) != 0;
#endif
- /* same as EM_solidify() in editmesh_lib.c */
- float *vert_angles = MEM_calloc_arrayN(numVerts, 2 * sizeof(float), "mod_solid_pair"); /* 2 in 1 */
- float *vert_accum = vert_angles + numVerts;
- unsigned int vidx;
- unsigned int i;
-
- if (vert_nors == NULL) {
- vert_nors = MEM_malloc_arrayN(numVerts, 3 * sizeof(float), "mod_solid_vno");
- for (i = 0, mv = mvert; i < numVerts; i++, mv++) {
- normal_short_to_float_v3(vert_nors[i], mv->no);
- }
- }
-
- for (i = 0, mp = mpoly; i < numPolys; i++, mp++) {
- /* #BKE_mesh_calc_poly_angles logic is inlined here */
- float nor_prev[3];
- float nor_next[3];
-
- int i_curr = mp->totloop - 1;
- int i_next = 0;
-
- ml = &mloop[mp->loopstart];
-
- sub_v3_v3v3(nor_prev, mvert[ml[i_curr - 1].v].co, mvert[ml[i_curr].v].co);
- normalize_v3(nor_prev);
-
- while (i_next < mp->totloop) {
- float angle;
- sub_v3_v3v3(nor_next, mvert[ml[i_curr].v].co, mvert[ml[i_next].v].co);
- normalize_v3(nor_next);
- angle = angle_normalized_v3v3(nor_prev, nor_next);
-
-
- /* --- not related to angle calc --- */
- if (angle < FLT_EPSILON) {
- angle = FLT_EPSILON;
- }
-
- vidx = ml[i_curr].v;
- vert_accum[vidx] += angle;
+ /* same as EM_solidify() in editmesh_lib.c */
+ float *vert_angles = MEM_calloc_arrayN(
+ numVerts, 2 * sizeof(float), "mod_solid_pair"); /* 2 in 1 */
+ float *vert_accum = vert_angles + numVerts;
+ unsigned int vidx;
+ unsigned int i;
+
+ if (vert_nors == NULL) {
+ vert_nors = MEM_malloc_arrayN(numVerts, 3 * sizeof(float), "mod_solid_vno");
+ for (i = 0, mv = mvert; i < numVerts; i++, mv++) {
+ normal_short_to_float_v3(vert_nors[i], mv->no);
+ }
+ }
+
+ for (i = 0, mp = mpoly; i < numPolys; i++, mp++) {
+ /* #BKE_mesh_calc_poly_angles logic is inlined here */
+ float nor_prev[3];
+ float nor_next[3];
+
+ int i_curr = mp->totloop - 1;
+ int i_next = 0;
+
+ ml = &mloop[mp->loopstart];
+
+ sub_v3_v3v3(nor_prev, mvert[ml[i_curr - 1].v].co, mvert[ml[i_curr].v].co);
+ normalize_v3(nor_prev);
+
+ while (i_next < mp->totloop) {
+ float angle;
+ sub_v3_v3v3(nor_next, mvert[ml[i_curr].v].co, mvert[ml[i_next].v].co);
+ normalize_v3(nor_next);
+ angle = angle_normalized_v3v3(nor_prev, nor_next);
+
+ /* --- not related to angle calc --- */
+ if (angle < FLT_EPSILON) {
+ angle = FLT_EPSILON;
+ }
+
+ vidx = ml[i_curr].v;
+ vert_accum[vidx] += angle;
#ifdef USE_NONMANIFOLD_WORKAROUND
- /* skip 3+ face user edges */
- if ((check_non_manifold == false) ||
- LIKELY(((orig_medge[ml[i_curr].e].flag & ME_EDGE_TMP_TAG) == 0) &&
- ((orig_medge[ml[i_next].e].flag & ME_EDGE_TMP_TAG) == 0)))
- {
- vert_angles[vidx] += shell_v3v3_normalized_to_dist(vert_nors[vidx], poly_nors[i]) * angle;
- }
- else {
- vert_angles[vidx] += angle;
- }
+ /* skip 3+ face user edges */
+ if ((check_non_manifold == false) ||
+ LIKELY(((orig_medge[ml[i_curr].e].flag & ME_EDGE_TMP_TAG) == 0) &&
+ ((orig_medge[ml[i_next].e].flag & ME_EDGE_TMP_TAG) == 0))) {
+ vert_angles[vidx] += shell_v3v3_normalized_to_dist(vert_nors[vidx], poly_nors[i]) *
+ angle;
+ }
+ else {
+ vert_angles[vidx] += angle;
+ }
#else
- vert_angles[vidx] += shell_v3v3_normalized_to_dist(vert_nors[vidx], poly_nors[i]) * angle;
+ vert_angles[vidx] += shell_v3v3_normalized_to_dist(vert_nors[vidx], poly_nors[i]) * angle;
#endif
- /* --- end non-angle-calc section --- */
-
-
- /* step */
- copy_v3_v3(nor_prev, nor_next);
- i_curr = i_next;
- i_next++;
- }
- }
-
- /* vertex group support */
- if (dvert) {
- MDeformVert *dv = dvert;
- float scalar;
-
- if (defgrp_invert) {
- for (i = 0; i < numVerts; i++, dv++) {
- scalar = 1.0f - defvert_find_weight(dv, defgrp_index);
- scalar = offset_fac_vg + (scalar * offset_fac_vg_inv);
- vert_angles[i] *= scalar;
- }
- }
- else {
- for (i = 0; i < numVerts; i++, dv++) {
- scalar = defvert_find_weight(dv, defgrp_index);
- scalar = offset_fac_vg + (scalar * offset_fac_vg_inv);
- vert_angles[i] *= scalar;
- }
- }
- }
-
- if (do_clamp) {
- float *vert_lens_sq = MEM_malloc_arrayN(numVerts, sizeof(float), "vert_lens");
- const float offset = fabsf(smd->offset) * smd->offset_clamp;
- const float offset_sq = offset * offset;
- copy_vn_fl(vert_lens_sq, (int)numVerts, FLT_MAX);
- for (i = 0; i < numEdges; i++) {
- const float ed_len = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co);
- vert_lens_sq[medge[i].v1] = min_ff(vert_lens_sq[medge[i].v1], ed_len);
- vert_lens_sq[medge[i].v2] = min_ff(vert_lens_sq[medge[i].v2], ed_len);
- }
- for (i = 0; i < numVerts; i++) {
- if (vert_lens_sq[i] < offset_sq) {
- float scalar = sqrtf(vert_lens_sq[i]) / offset;
- vert_angles[i] *= scalar;
- }
- }
- MEM_freeN(vert_lens_sq);
- }
-
- if (ofs_new != 0.0f) {
- unsigned int i_orig, i_end;
- bool do_shell_align;
-
- INIT_VERT_ARRAY_OFFSETS(false);
-
- for (i_orig = 0; i_orig < i_end; i_orig++, mv++) {
- const unsigned int i_other = do_shell_align ? i_orig : new_vert_arr[i_orig];
- if (vert_accum[i_other]) { /* zero if unselected */
- madd_v3_v3fl(mv->co, vert_nors[i_other], ofs_new * (vert_angles[i_other] / vert_accum[i_other]));
- }
- }
- }
-
- if (ofs_orig != 0.0f) {
- unsigned int i_orig, i_end;
- bool do_shell_align;
-
- /* same as above but swapped, intentional use of 'ofs_new' */
- INIT_VERT_ARRAY_OFFSETS(true);
-
- for (i_orig = 0; i_orig < i_end; i_orig++, mv++) {
- const unsigned int i_other = do_shell_align ? i_orig : new_vert_arr[i_orig];
- if (vert_accum[i_other]) { /* zero if unselected */
- madd_v3_v3fl(mv->co, vert_nors[i_other], ofs_orig * (vert_angles[i_other] / vert_accum[i_other]));
- }
- }
- }
-
- MEM_freeN(vert_angles);
- }
-
- if (vert_nors)
- MEM_freeN(vert_nors);
-
- /* must recalculate normals with vgroups since they can displace unevenly [#26888] */
- if ((mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) || (smd->flag & MOD_SOLIDIFY_RIM) || dvert) {
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- }
- else if (do_shell) {
- unsigned int i;
- /* flip vertex normals for copied verts */
- mv = mvert + numVerts;
- for (i = 0; i < numVerts; i++, mv++) {
- negate_v3_short(mv->no);
- }
- }
-
- if (smd->flag & MOD_SOLIDIFY_RIM) {
- unsigned int i;
-
- /* bugger, need to re-calculate the normals for the new edge faces.
- * This could be done in many ways, but probably the quickest way
- * is to calculate the average normals for side faces only.
- * Then blend them with the normals of the edge verts.
- *
- * at the moment its easiest to allocate an entire array for every vertex,
- * even though we only need edge verts - campbell
- */
+ /* --- end non-angle-calc section --- */
+
+ /* step */
+ copy_v3_v3(nor_prev, nor_next);
+ i_curr = i_next;
+ i_next++;
+ }
+ }
+
+ /* vertex group support */
+ if (dvert) {
+ MDeformVert *dv = dvert;
+ float scalar;
+
+ if (defgrp_invert) {
+ for (i = 0; i < numVerts; i++, dv++) {
+ scalar = 1.0f - defvert_find_weight(dv, defgrp_index);
+ scalar = offset_fac_vg + (scalar * offset_fac_vg_inv);
+ vert_angles[i] *= scalar;
+ }
+ }
+ else {
+ for (i = 0; i < numVerts; i++, dv++) {
+ scalar = defvert_find_weight(dv, defgrp_index);
+ scalar = offset_fac_vg + (scalar * offset_fac_vg_inv);
+ vert_angles[i] *= scalar;
+ }
+ }
+ }
+
+ if (do_clamp) {
+ float *vert_lens_sq = MEM_malloc_arrayN(numVerts, sizeof(float), "vert_lens");
+ const float offset = fabsf(smd->offset) * smd->offset_clamp;
+ const float offset_sq = offset * offset;
+ copy_vn_fl(vert_lens_sq, (int)numVerts, FLT_MAX);
+ for (i = 0; i < numEdges; i++) {
+ const float ed_len = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co);
+ vert_lens_sq[medge[i].v1] = min_ff(vert_lens_sq[medge[i].v1], ed_len);
+ vert_lens_sq[medge[i].v2] = min_ff(vert_lens_sq[medge[i].v2], ed_len);
+ }
+ for (i = 0; i < numVerts; i++) {
+ if (vert_lens_sq[i] < offset_sq) {
+ float scalar = sqrtf(vert_lens_sq[i]) / offset;
+ vert_angles[i] *= scalar;
+ }
+ }
+ MEM_freeN(vert_lens_sq);
+ }
+
+ if (ofs_new != 0.0f) {
+ unsigned int i_orig, i_end;
+ bool do_shell_align;
+
+ INIT_VERT_ARRAY_OFFSETS(false);
+
+ for (i_orig = 0; i_orig < i_end; i_orig++, mv++) {
+ const unsigned int i_other = do_shell_align ? i_orig : new_vert_arr[i_orig];
+ if (vert_accum[i_other]) { /* zero if unselected */
+ madd_v3_v3fl(
+ mv->co, vert_nors[i_other], ofs_new * (vert_angles[i_other] / vert_accum[i_other]));
+ }
+ }
+ }
+
+ if (ofs_orig != 0.0f) {
+ unsigned int i_orig, i_end;
+ bool do_shell_align;
+
+ /* same as above but swapped, intentional use of 'ofs_new' */
+ INIT_VERT_ARRAY_OFFSETS(true);
+
+ for (i_orig = 0; i_orig < i_end; i_orig++, mv++) {
+ const unsigned int i_other = do_shell_align ? i_orig : new_vert_arr[i_orig];
+ if (vert_accum[i_other]) { /* zero if unselected */
+ madd_v3_v3fl(
+ mv->co, vert_nors[i_other], ofs_orig * (vert_angles[i_other] / vert_accum[i_other]));
+ }
+ }
+ }
+
+ MEM_freeN(vert_angles);
+ }
+
+ if (vert_nors)
+ MEM_freeN(vert_nors);
+
+ /* must recalculate normals with vgroups since they can displace unevenly [#26888] */
+ if ((mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) || (smd->flag & MOD_SOLIDIFY_RIM) || dvert) {
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ }
+ else if (do_shell) {
+ unsigned int i;
+ /* flip vertex normals for copied verts */
+ mv = mvert + numVerts;
+ for (i = 0; i < numVerts; i++, mv++) {
+ negate_v3_short(mv->no);
+ }
+ }
+
+ if (smd->flag & MOD_SOLIDIFY_RIM) {
+ unsigned int i;
+
+ /* bugger, need to re-calculate the normals for the new edge faces.
+ * This could be done in many ways, but probably the quickest way
+ * is to calculate the average normals for side faces only.
+ * Then blend them with the normals of the edge verts.
+ *
+ * at the moment its easiest to allocate an entire array for every vertex,
+ * even though we only need edge verts - campbell
+ */
#define SOLIDIFY_SIDE_NORMALS
#ifdef SOLIDIFY_SIDE_NORMALS
- /* Note that, due to the code setting cd_dirty_vert a few lines above,
- * do_side_normals is always false. - Sybren */
- const bool do_side_normals = !(result->runtime.cd_dirty_vert & CD_MASK_NORMAL);
- /* annoying to allocate these since we only need the edge verts, */
- float (*edge_vert_nos)[3] = do_side_normals ? MEM_calloc_arrayN(numVerts, 3 * sizeof(float), __func__) : NULL;
- float nor[3];
+ /* Note that, due to the code setting cd_dirty_vert a few lines above,
+ * do_side_normals is always false. - Sybren */
+ const bool do_side_normals = !(result->runtime.cd_dirty_vert & CD_MASK_NORMAL);
+ /* annoying to allocate these since we only need the edge verts, */
+ float(*edge_vert_nos)[3] = do_side_normals ?
+ MEM_calloc_arrayN(numVerts, 3 * sizeof(float), __func__) :
+ NULL;
+ float nor[3];
#endif
- const unsigned char crease_rim = smd->crease_rim * 255.0f;
- const unsigned char crease_outer = smd->crease_outer * 255.0f;
- const unsigned char crease_inner = smd->crease_inner * 255.0f;
-
- int *origindex_edge;
- int *orig_ed;
- unsigned int j;
-
- if (crease_rim || crease_outer || crease_inner) {
- result->cd_flag |= ME_CDFLAG_EDGE_CREASE;
- }
-
- /* add faces & edges */
- origindex_edge = CustomData_get_layer(&result->edata, CD_ORIGINDEX);
- orig_ed = (origindex_edge) ? &origindex_edge[(numEdges * stride) + newEdges] : NULL;
- ed = &medge[(numEdges * stride) + newEdges]; /* start after copied edges */
- for (i = 0; i < rimVerts; i++, ed++) {
- ed->v1 = new_vert_arr[i];
- ed->v2 = (do_shell ? new_vert_arr[i] : i) + numVerts;
- ed->flag |= ME_EDGEDRAW | ME_EDGERENDER;
-
- if (orig_ed) {
- *orig_ed = ORIGINDEX_NONE;
- orig_ed++;
- }
-
- if (crease_rim) {
- ed->crease = crease_rim;
- }
- }
-
- /* faces */
- mp = mpoly + (numPolys * stride);
- ml = mloop + (numLoops * stride);
- j = 0;
- for (i = 0; i < newPolys; i++, mp++) {
- unsigned int eidx = new_edge_arr[i];
- unsigned int pidx = edge_users[eidx];
- int k1, k2;
- bool flip;
-
- if (pidx >= numPolys) {
- pidx -= numPolys;
- flip = true;
- }
- else {
- flip = false;
- }
-
- ed = medge + eidx;
-
- /* copy most of the face settings */
- CustomData_copy_data(&mesh->pdata, &result->pdata, (int)pidx, (int)((numPolys * stride) + i), 1);
- mp->loopstart = (int)(j + (numLoops * stride));
- mp->flag = mpoly[pidx].flag;
-
- /* notice we use 'mp->totloop' which is later overwritten,
- * we could lookup the original face but there's no point since this is a copy
- * and will have the same value, just take care when changing order of assignment */
- k1 = mpoly[pidx].loopstart + (((edge_order[eidx] - 1) + mp->totloop) % mp->totloop); /* prev loop */
- k2 = mpoly[pidx].loopstart + (edge_order[eidx]);
-
- mp->totloop = 4;
-
- CustomData_copy_data(&mesh->ldata, &result->ldata, k2, (int)((numLoops * stride) + j + 0), 1);
- CustomData_copy_data(&mesh->ldata, &result->ldata, k1, (int)((numLoops * stride) + j + 1), 1);
- CustomData_copy_data(&mesh->ldata, &result->ldata, k1, (int)((numLoops * stride) + j + 2), 1);
- CustomData_copy_data(&mesh->ldata, &result->ldata, k2, (int)((numLoops * stride) + j + 3), 1);
-
- if (flip == false) {
- ml[j].v = ed->v1;
- ml[j++].e = eidx;
-
- ml[j].v = ed->v2;
- ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v2] + newEdges;
-
- ml[j].v = (do_shell ? ed->v2 : old_vert_arr[ed->v2]) + numVerts;
- ml[j++].e = (do_shell ? eidx : i) + numEdges;
-
- ml[j].v = (do_shell ? ed->v1 : old_vert_arr[ed->v1]) + numVerts;
- ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v1] + newEdges;
- }
- else {
- ml[j].v = ed->v2;
- ml[j++].e = eidx;
-
- ml[j].v = ed->v1;
- ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v1] + newEdges;
-
- ml[j].v = (do_shell ? ed->v1 : old_vert_arr[ed->v1]) + numVerts;
- ml[j++].e = (do_shell ? eidx : i) + numEdges;
-
- ml[j].v = (do_shell ? ed->v2 : old_vert_arr[ed->v2]) + numVerts;
- ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v2] + newEdges;
- }
-
- if (origindex_edge) {
- origindex_edge[ml[j - 3].e] = ORIGINDEX_NONE;
- origindex_edge[ml[j - 1].e] = ORIGINDEX_NONE;
- }
-
- /* use the next material index if option enabled */
- if (mat_ofs_rim) {
- mp->mat_nr += mat_ofs_rim;
- CLAMP(mp->mat_nr, 0, mat_nr_max);
- }
- if (crease_outer) {
- /* crease += crease_outer; without wrapping */
- char *cr = &(ed->crease);
- int tcr = *cr + crease_outer;
- *cr = tcr > 255 ? 255 : tcr;
- }
-
- if (crease_inner) {
- /* crease += crease_inner; without wrapping */
- char *cr = &(medge[numEdges + (do_shell ? eidx : i)].crease);
- int tcr = *cr + crease_inner;
- *cr = tcr > 255 ? 255 : tcr;
- }
+ const unsigned char crease_rim = smd->crease_rim * 255.0f;
+ const unsigned char crease_outer = smd->crease_outer * 255.0f;
+ const unsigned char crease_inner = smd->crease_inner * 255.0f;
+
+ int *origindex_edge;
+ int *orig_ed;
+ unsigned int j;
+
+ if (crease_rim || crease_outer || crease_inner) {
+ result->cd_flag |= ME_CDFLAG_EDGE_CREASE;
+ }
+
+ /* add faces & edges */
+ origindex_edge = CustomData_get_layer(&result->edata, CD_ORIGINDEX);
+ orig_ed = (origindex_edge) ? &origindex_edge[(numEdges * stride) + newEdges] : NULL;
+ ed = &medge[(numEdges * stride) + newEdges]; /* start after copied edges */
+ for (i = 0; i < rimVerts; i++, ed++) {
+ ed->v1 = new_vert_arr[i];
+ ed->v2 = (do_shell ? new_vert_arr[i] : i) + numVerts;
+ ed->flag |= ME_EDGEDRAW | ME_EDGERENDER;
+
+ if (orig_ed) {
+ *orig_ed = ORIGINDEX_NONE;
+ orig_ed++;
+ }
+
+ if (crease_rim) {
+ ed->crease = crease_rim;
+ }
+ }
+
+ /* faces */
+ mp = mpoly + (numPolys * stride);
+ ml = mloop + (numLoops * stride);
+ j = 0;
+ for (i = 0; i < newPolys; i++, mp++) {
+ unsigned int eidx = new_edge_arr[i];
+ unsigned int pidx = edge_users[eidx];
+ int k1, k2;
+ bool flip;
+
+ if (pidx >= numPolys) {
+ pidx -= numPolys;
+ flip = true;
+ }
+ else {
+ flip = false;
+ }
+
+ ed = medge + eidx;
+
+ /* copy most of the face settings */
+ CustomData_copy_data(
+ &mesh->pdata, &result->pdata, (int)pidx, (int)((numPolys * stride) + i), 1);
+ mp->loopstart = (int)(j + (numLoops * stride));
+ mp->flag = mpoly[pidx].flag;
+
+ /* notice we use 'mp->totloop' which is later overwritten,
+ * we could lookup the original face but there's no point since this is a copy
+ * and will have the same value, just take care when changing order of assignment */
+ k1 = mpoly[pidx].loopstart +
+ (((edge_order[eidx] - 1) + mp->totloop) % mp->totloop); /* prev loop */
+ k2 = mpoly[pidx].loopstart + (edge_order[eidx]);
+
+ mp->totloop = 4;
+
+ CustomData_copy_data(
+ &mesh->ldata, &result->ldata, k2, (int)((numLoops * stride) + j + 0), 1);
+ CustomData_copy_data(
+ &mesh->ldata, &result->ldata, k1, (int)((numLoops * stride) + j + 1), 1);
+ CustomData_copy_data(
+ &mesh->ldata, &result->ldata, k1, (int)((numLoops * stride) + j + 2), 1);
+ CustomData_copy_data(
+ &mesh->ldata, &result->ldata, k2, (int)((numLoops * stride) + j + 3), 1);
+
+ if (flip == false) {
+ ml[j].v = ed->v1;
+ ml[j++].e = eidx;
+
+ ml[j].v = ed->v2;
+ ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v2] + newEdges;
+
+ ml[j].v = (do_shell ? ed->v2 : old_vert_arr[ed->v2]) + numVerts;
+ ml[j++].e = (do_shell ? eidx : i) + numEdges;
+
+ ml[j].v = (do_shell ? ed->v1 : old_vert_arr[ed->v1]) + numVerts;
+ ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v1] + newEdges;
+ }
+ else {
+ ml[j].v = ed->v2;
+ ml[j++].e = eidx;
+
+ ml[j].v = ed->v1;
+ ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v1] + newEdges;
+
+ ml[j].v = (do_shell ? ed->v1 : old_vert_arr[ed->v1]) + numVerts;
+ ml[j++].e = (do_shell ? eidx : i) + numEdges;
+
+ ml[j].v = (do_shell ? ed->v2 : old_vert_arr[ed->v2]) + numVerts;
+ ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v2] + newEdges;
+ }
+
+ if (origindex_edge) {
+ origindex_edge[ml[j - 3].e] = ORIGINDEX_NONE;
+ origindex_edge[ml[j - 1].e] = ORIGINDEX_NONE;
+ }
+
+ /* use the next material index if option enabled */
+ if (mat_ofs_rim) {
+ mp->mat_nr += mat_ofs_rim;
+ CLAMP(mp->mat_nr, 0, mat_nr_max);
+ }
+ if (crease_outer) {
+ /* crease += crease_outer; without wrapping */
+ char *cr = &(ed->crease);
+ int tcr = *cr + crease_outer;
+ *cr = tcr > 255 ? 255 : tcr;
+ }
+
+ if (crease_inner) {
+ /* crease += crease_inner; without wrapping */
+ char *cr = &(medge[numEdges + (do_shell ? eidx : i)].crease);
+ int tcr = *cr + crease_inner;
+ *cr = tcr > 255 ? 255 : tcr;
+ }
#ifdef SOLIDIFY_SIDE_NORMALS
- if (do_side_normals) {
- normal_quad_v3(nor,
- mvert[ml[j - 4].v].co,
- mvert[ml[j - 3].v].co,
- mvert[ml[j - 2].v].co,
- mvert[ml[j - 1].v].co);
-
- add_v3_v3(edge_vert_nos[ed->v1], nor);
- add_v3_v3(edge_vert_nos[ed->v2], nor);
- }
+ if (do_side_normals) {
+ normal_quad_v3(nor,
+ mvert[ml[j - 4].v].co,
+ mvert[ml[j - 3].v].co,
+ mvert[ml[j - 2].v].co,
+ mvert[ml[j - 1].v].co);
+
+ add_v3_v3(edge_vert_nos[ed->v1], nor);
+ add_v3_v3(edge_vert_nos[ed->v2], nor);
+ }
#endif
- }
+ }
#ifdef SOLIDIFY_SIDE_NORMALS
- if (do_side_normals) {
- const MEdge *ed_orig = medge;
- ed = medge + (numEdges * stride);
- for (i = 0; i < rimVerts; i++, ed++, ed_orig++) {
- float nor_cpy[3];
- short *nor_short;
- int k;
-
- /* note, only the first vertex (lower half of the index) is calculated */
- BLI_assert(ed->v1 < numVerts);
- normalize_v3_v3(nor_cpy, edge_vert_nos[ed_orig->v1]);
-
- for (k = 0; k < 2; k++) { /* loop over both verts of the edge */
- nor_short = mvert[*(&ed->v1 + k)].no;
- normal_short_to_float_v3(nor, nor_short);
- add_v3_v3(nor, nor_cpy);
- normalize_v3(nor);
- normal_float_to_short_v3(nor_short, nor);
- }
- }
-
- MEM_freeN(edge_vert_nos);
- }
+ if (do_side_normals) {
+ const MEdge *ed_orig = medge;
+ ed = medge + (numEdges * stride);
+ for (i = 0; i < rimVerts; i++, ed++, ed_orig++) {
+ float nor_cpy[3];
+ short *nor_short;
+ int k;
+
+ /* note, only the first vertex (lower half of the index) is calculated */
+ BLI_assert(ed->v1 < numVerts);
+ normalize_v3_v3(nor_cpy, edge_vert_nos[ed_orig->v1]);
+
+ for (k = 0; k < 2; k++) { /* loop over both verts of the edge */
+ nor_short = mvert[*(&ed->v1 + k)].no;
+ normal_short_to_float_v3(nor, nor_short);
+ add_v3_v3(nor, nor_cpy);
+ normalize_v3(nor);
+ normal_float_to_short_v3(nor_short, nor);
+ }
+ }
+
+ MEM_freeN(edge_vert_nos);
+ }
#endif
- MEM_freeN(new_vert_arr);
- MEM_freeN(new_edge_arr);
+ MEM_freeN(new_vert_arr);
+ MEM_freeN(new_edge_arr);
- MEM_freeN(edge_users);
- MEM_freeN(edge_order);
- }
+ MEM_freeN(edge_users);
+ MEM_freeN(edge_order);
+ }
- if (old_vert_arr)
- MEM_freeN(old_vert_arr);
+ if (old_vert_arr)
+ MEM_freeN(old_vert_arr);
- if (poly_nors)
- MEM_freeN(poly_nors);
+ if (poly_nors)
+ MEM_freeN(poly_nors);
- if (numPolys == 0 && numEdges != 0) {
- modifier_setError(md, "Faces needed for useful output");
- }
+ if (numPolys == 0 && numEdges != 0) {
+ modifier_setError(md, "Faces needed for useful output");
+ }
- return result;
+ return result;
}
#undef SOLIDIFY_SIDE_NORMALS
static bool dependsOnNormals(ModifierData *UNUSED(md))
{
- /* even when we calculate our own normals,
- * the vertex normals are used as a fallback */
- return true;
+ /* even when we calculate our own normals,
+ * the vertex normals are used as a fallback */
+ return true;
}
ModifierTypeInfo modifierType_Solidify = {
- /* name */ "Solidify",
- /* structName */ "SolidifyModifierData",
- /* structSize */ sizeof(SolidifyModifierData),
- /* type */ eModifierTypeType_Constructive,
-
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_SupportsMapping |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_EnableInEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Solidify",
+ /* structName */ "SolidifyModifierData",
+ /* structSize */ sizeof(SolidifyModifierData),
+ /* type */ eModifierTypeType_Constructive,
+
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs |
+ eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode |
+ eModifierTypeFlag_EnableInEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ dependsOnNormals,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c
index 74bf6b7e976..c03b1761251 100644
--- a/source/blender/modifiers/intern/MOD_subsurf.c
+++ b/source/blender/modifiers/intern/MOD_subsurf.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include <stddef.h>
#include "MEM_guardedalloc.h"
@@ -47,90 +46,86 @@
#include "intern/CCGSubSurf.h"
typedef struct SubsurfRuntimeData {
- /* Cached subdivision surface descriptor, with topology and settings. */
- struct Subdiv *subdiv;
+ /* Cached subdivision surface descriptor, with topology and settings. */
+ struct Subdiv *subdiv;
} SubsurfRuntimeData;
static void initData(ModifierData *md)
{
- SubsurfModifierData *smd = (SubsurfModifierData *) md;
+ SubsurfModifierData *smd = (SubsurfModifierData *)md;
- smd->levels = 1;
- smd->renderLevels = 2;
- smd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
- smd->quality = 3;
- smd->flags |= eSubsurfModifierFlag_UseCrease;
+ smd->levels = 1;
+ smd->renderLevels = 2;
+ smd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
+ smd->quality = 3;
+ smd->flags |= eSubsurfModifierFlag_UseCrease;
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
#if 0
- const SubsurfModifierData *smd = (const SubsurfModifierData *) md;
+ const SubsurfModifierData *smd = (const SubsurfModifierData *) md;
#endif
- SubsurfModifierData *tsmd = (SubsurfModifierData *) target;
+ SubsurfModifierData *tsmd = (SubsurfModifierData *)target;
- modifier_copyData_generic(md, target, flag);
+ modifier_copyData_generic(md, target, flag);
- tsmd->emCache = tsmd->mCache = NULL;
+ tsmd->emCache = tsmd->mCache = NULL;
}
static void freeRuntimeData(void *runtime_data_v)
{
- if (runtime_data_v == NULL) {
- return;
- }
- SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)runtime_data_v;
- if (runtime_data->subdiv != NULL) {
- BKE_subdiv_free(runtime_data->subdiv);
- }
- MEM_freeN(runtime_data);
+ if (runtime_data_v == NULL) {
+ return;
+ }
+ SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)runtime_data_v;
+ if (runtime_data->subdiv != NULL) {
+ BKE_subdiv_free(runtime_data->subdiv);
+ }
+ MEM_freeN(runtime_data);
}
static void freeData(ModifierData *md)
{
- SubsurfModifierData *smd = (SubsurfModifierData *) md;
-
- if (smd->mCache) {
- ccgSubSurf_free(smd->mCache);
- smd->mCache = NULL;
- }
- if (smd->emCache) {
- ccgSubSurf_free(smd->emCache);
- smd->emCache = NULL;
- }
- freeRuntimeData(smd->modifier.runtime);
+ SubsurfModifierData *smd = (SubsurfModifierData *)md;
+
+ if (smd->mCache) {
+ ccgSubSurf_free(smd->mCache);
+ smd->mCache = NULL;
+ }
+ if (smd->emCache) {
+ ccgSubSurf_free(smd->emCache);
+ smd->emCache = NULL;
+ }
+ freeRuntimeData(smd->modifier.runtime);
}
static bool isDisabled(const Scene *scene, ModifierData *md, bool useRenderParams)
{
- SubsurfModifierData *smd = (SubsurfModifierData *) md;
- int levels = (useRenderParams) ? smd->renderLevels : smd->levels;
+ SubsurfModifierData *smd = (SubsurfModifierData *)md;
+ int levels = (useRenderParams) ? smd->renderLevels : smd->levels;
- return get_render_subsurf_level(&scene->r, levels, useRenderParams != 0) == 0;
+ return get_render_subsurf_level(&scene->r, levels, useRenderParams != 0) == 0;
}
static int subdiv_levels_for_modifier_get(const SubsurfModifierData *smd,
const ModifierEvalContext *ctx)
{
- Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER);
- const int requested_levels = (use_render_params) ? smd->renderLevels
- : smd->levels;
- return get_render_subsurf_level(&scene->r,
- requested_levels,
- use_render_params);
+ Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER);
+ const int requested_levels = (use_render_params) ? smd->renderLevels : smd->levels;
+ return get_render_subsurf_level(&scene->r, requested_levels, use_render_params);
}
-static void subdiv_settings_init(SubdivSettings *settings,
- const SubsurfModifierData *smd)
+static void subdiv_settings_init(SubdivSettings *settings, const SubsurfModifierData *smd)
{
- settings->is_simple = (smd->subdivType == SUBSURF_TYPE_SIMPLE);
- settings->is_adaptive = true;
- settings->level = settings->is_simple ? 1 : smd->quality;
- settings->use_creases = (smd->flags & eSubsurfModifierFlag_UseCrease);
- settings->vtx_boundary_interpolation = SUBDIV_VTX_BOUNDARY_EDGE_ONLY;
- settings->fvar_linear_interpolation =
- BKE_subdiv_fvar_interpolation_from_uv_smooth(smd->uv_smooth);
+ settings->is_simple = (smd->subdivType == SUBSURF_TYPE_SIMPLE);
+ settings->is_adaptive = true;
+ settings->level = settings->is_simple ? 1 : smd->quality;
+ settings->use_creases = (smd->flags & eSubsurfModifierFlag_UseCrease);
+ settings->vtx_boundary_interpolation = SUBDIV_VTX_BOUNDARY_EDGE_ONLY;
+ settings->fvar_linear_interpolation = BKE_subdiv_fvar_interpolation_from_uv_smooth(
+ smd->uv_smooth);
}
/* Main goal of this function is to give usable subdivision surface descriptor
@@ -139,12 +134,10 @@ static Subdiv *subdiv_descriptor_ensure(SubsurfModifierData *smd,
const SubdivSettings *subdiv_settings,
const Mesh *mesh)
{
- SubsurfRuntimeData *runtime_data =
- (SubsurfRuntimeData *)smd->modifier.runtime;
- Subdiv *subdiv = BKE_subdiv_update_from_mesh(
- runtime_data->subdiv, subdiv_settings, mesh);
- runtime_data->subdiv = subdiv;
- return subdiv;
+ SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)smd->modifier.runtime;
+ Subdiv *subdiv = BKE_subdiv_update_from_mesh(runtime_data->subdiv, subdiv_settings, mesh);
+ runtime_data->subdiv = subdiv;
+ return subdiv;
}
/* Subdivide into fully qualified mesh. */
@@ -153,10 +146,9 @@ static void subdiv_mesh_settings_init(SubdivToMeshSettings *settings,
const SubsurfModifierData *smd,
const ModifierEvalContext *ctx)
{
- const int level = subdiv_levels_for_modifier_get(smd, ctx);
- settings->resolution = (1 << level) + 1;
- settings->use_optimal_display =
- (smd->flags & eSubsurfModifierFlag_ControlEdges);
+ const int level = subdiv_levels_for_modifier_get(smd, ctx);
+ settings->resolution = (1 << level) + 1;
+ settings->use_optimal_display = (smd->flags & eSubsurfModifierFlag_ControlEdges);
}
static Mesh *subdiv_as_mesh(SubsurfModifierData *smd,
@@ -164,14 +156,14 @@ static Mesh *subdiv_as_mesh(SubsurfModifierData *smd,
Mesh *mesh,
Subdiv *subdiv)
{
- Mesh *result = mesh;
- SubdivToMeshSettings mesh_settings;
- subdiv_mesh_settings_init(&mesh_settings, smd, ctx);
- if (mesh_settings.resolution < 3) {
- return result;
- }
- result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh);
- return result;
+ Mesh *result = mesh;
+ SubdivToMeshSettings mesh_settings;
+ subdiv_mesh_settings_init(&mesh_settings, smd, ctx);
+ if (mesh_settings.resolution < 3) {
+ return result;
+ }
+ result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh);
+ return result;
}
/* Subdivide into CCG. */
@@ -180,101 +172,96 @@ static void subdiv_ccg_settings_init(SubdivToCCGSettings *settings,
const SubsurfModifierData *smd,
const ModifierEvalContext *ctx)
{
- const int level = subdiv_levels_for_modifier_get(smd, ctx);
- settings->resolution = (1 << level) + 1;
- settings->need_normal = true;
- settings->need_mask = false;
+ const int level = subdiv_levels_for_modifier_get(smd, ctx);
+ settings->resolution = (1 << level) + 1;
+ settings->need_normal = true;
+ settings->need_mask = false;
}
static Mesh *subdiv_as_ccg(SubsurfModifierData *smd,
- const ModifierEvalContext *ctx,
- Mesh *mesh,
- Subdiv *subdiv)
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ Subdiv *subdiv)
{
- Mesh *result = mesh;
- SubdivToCCGSettings ccg_settings;
- subdiv_ccg_settings_init(&ccg_settings, smd, ctx);
- if (ccg_settings.resolution < 3) {
- return result;
- }
- result = BKE_subdiv_to_ccg_mesh(subdiv, &ccg_settings, mesh);
- return result;
+ Mesh *result = mesh;
+ SubdivToCCGSettings ccg_settings;
+ subdiv_ccg_settings_init(&ccg_settings, smd, ctx);
+ if (ccg_settings.resolution < 3) {
+ return result;
+ }
+ result = BKE_subdiv_to_ccg_mesh(subdiv, &ccg_settings, mesh);
+ return result;
}
static SubsurfRuntimeData *subsurf_ensure_runtime(SubsurfModifierData *smd)
{
- SubsurfRuntimeData *runtime_data =
- (SubsurfRuntimeData *)smd->modifier.runtime;
- if (runtime_data == NULL) {
- runtime_data = MEM_callocN(sizeof(*runtime_data), "subsurf runtime");
- smd->modifier.runtime = runtime_data;
- }
- return runtime_data;
+ SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)smd->modifier.runtime;
+ if (runtime_data == NULL) {
+ runtime_data = MEM_callocN(sizeof(*runtime_data), "subsurf runtime");
+ smd->modifier.runtime = runtime_data;
+ }
+ return runtime_data;
}
/* Modifier itself. */
-static Mesh *applyModifier(ModifierData *md,
- const ModifierEvalContext *ctx,
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- Mesh *result = mesh;
- SubsurfModifierData *smd = (SubsurfModifierData *) md;
- SubdivSettings subdiv_settings;
- subdiv_settings_init(&subdiv_settings, smd);
- if (subdiv_settings.level == 0) {
- return result;
- }
- BKE_subdiv_settings_validate_for_mesh(&subdiv_settings, mesh);
- SubsurfRuntimeData *runtime_data = subsurf_ensure_runtime(smd);
- Subdiv *subdiv = subdiv_descriptor_ensure(smd, &subdiv_settings, mesh);
- if (subdiv == NULL) {
- /* Happens on bad topology, but also on empty input mesh. */
- return result;
- }
- /* TODO(sergey): Decide whether we ever want to use CCG for subsurf,
- * maybe when it is a last modifier in the stack? */
- if (true) {
- result = subdiv_as_mesh(smd, ctx, mesh, subdiv);
- }
- else {
- result = subdiv_as_ccg(smd, ctx, mesh, subdiv);
- }
- // BKE_subdiv_stats_print(&subdiv->stats);
- if (subdiv != runtime_data->subdiv) {
- BKE_subdiv_free(subdiv);
- }
- return result;
+ Mesh *result = mesh;
+ SubsurfModifierData *smd = (SubsurfModifierData *)md;
+ SubdivSettings subdiv_settings;
+ subdiv_settings_init(&subdiv_settings, smd);
+ if (subdiv_settings.level == 0) {
+ return result;
+ }
+ BKE_subdiv_settings_validate_for_mesh(&subdiv_settings, mesh);
+ SubsurfRuntimeData *runtime_data = subsurf_ensure_runtime(smd);
+ Subdiv *subdiv = subdiv_descriptor_ensure(smd, &subdiv_settings, mesh);
+ if (subdiv == NULL) {
+ /* Happens on bad topology, but also on empty input mesh. */
+ return result;
+ }
+ /* TODO(sergey): Decide whether we ever want to use CCG for subsurf,
+ * maybe when it is a last modifier in the stack? */
+ if (true) {
+ result = subdiv_as_mesh(smd, ctx, mesh, subdiv);
+ }
+ else {
+ result = subdiv_as_ccg(smd, ctx, mesh, subdiv);
+ }
+ // BKE_subdiv_stats_print(&subdiv->stats);
+ if (subdiv != runtime_data->subdiv) {
+ BKE_subdiv_free(subdiv);
+ }
+ return result;
}
ModifierTypeInfo modifierType_Subsurf = {
- /* name */ "Subdivision",
- /* structName */ "SubsurfModifierData",
- /* structSize */ sizeof(SubsurfModifierData),
- /* type */ eModifierTypeType_Constructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsMapping |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_EnableInEditmode |
- eModifierTypeFlag_AcceptsCVs,
-
- /* copyData */ copyData,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ NULL,
- /* freeData */ freeData,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ freeRuntimeData,
+ /* name */ "Subdivision",
+ /* structName */ "SubsurfModifierData",
+ /* structSize */ sizeof(SubsurfModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode |
+ eModifierTypeFlag_AcceptsCVs,
+
+ /* copyData */ copyData,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ freeData,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ freeRuntimeData,
};
diff --git a/source/blender/modifiers/intern/MOD_surface.c b/source/blender/modifiers/intern/MOD_surface.c
index c0fbb4d9ac3..02678879e89 100644
--- a/source/blender/modifiers/intern/MOD_surface.c
+++ b/source/blender/modifiers/intern/MOD_surface.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include "BLI_utildefines.h"
#include "BLI_math.h"
@@ -43,173 +42,167 @@
#include "MEM_guardedalloc.h"
-
static void initData(ModifierData *md)
{
- SurfaceModifierData *surmd = (SurfaceModifierData *) md;
+ SurfaceModifierData *surmd = (SurfaceModifierData *)md;
- surmd->bvhtree = NULL;
- surmd->mesh = NULL;
- surmd->x = NULL;
- surmd->v = NULL;
+ surmd->bvhtree = NULL;
+ surmd->mesh = NULL;
+ surmd->x = NULL;
+ surmd->v = NULL;
}
static void copyData(const ModifierData *md_src, ModifierData *md_dst, const int flag)
{
- SurfaceModifierData *surmd_dst = (SurfaceModifierData *)md_dst;
+ SurfaceModifierData *surmd_dst = (SurfaceModifierData *)md_dst;
- modifier_copyData_generic(md_src, md_dst, flag);
+ modifier_copyData_generic(md_src, md_dst, flag);
- surmd_dst->bvhtree = NULL;
- surmd_dst->mesh = NULL;
- surmd_dst->x = NULL;
- surmd_dst->v = NULL;
+ surmd_dst->bvhtree = NULL;
+ surmd_dst->mesh = NULL;
+ surmd_dst->x = NULL;
+ surmd_dst->v = NULL;
}
static void freeData(ModifierData *md)
{
- SurfaceModifierData *surmd = (SurfaceModifierData *) md;
+ SurfaceModifierData *surmd = (SurfaceModifierData *)md;
- if (surmd) {
- if (surmd->bvhtree) {
- free_bvhtree_from_mesh(surmd->bvhtree);
- MEM_SAFE_FREE(surmd->bvhtree);
- }
+ if (surmd) {
+ if (surmd->bvhtree) {
+ free_bvhtree_from_mesh(surmd->bvhtree);
+ MEM_SAFE_FREE(surmd->bvhtree);
+ }
- if (surmd->mesh) {
- BKE_id_free(NULL, surmd->mesh);
- surmd->mesh = NULL;
- }
+ if (surmd->mesh) {
+ BKE_id_free(NULL, surmd->mesh);
+ surmd->mesh = NULL;
+ }
- MEM_SAFE_FREE(surmd->x);
+ MEM_SAFE_FREE(surmd->x);
- MEM_SAFE_FREE(surmd->v);
- }
+ MEM_SAFE_FREE(surmd->v);
+ }
}
static bool dependsOnTime(ModifierData *UNUSED(md))
{
- return true;
+ return true;
}
-static void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh,
- float (*vertexCos)[3],
- int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- SurfaceModifierData *surmd = (SurfaceModifierData *) md;
- const int cfra = (int)DEG_get_ctime(ctx->depsgraph);
-
- /* Free mesh and BVH cache. */
- if (surmd->bvhtree) {
- free_bvhtree_from_mesh(surmd->bvhtree);
- MEM_SAFE_FREE(surmd->bvhtree);
- }
-
- if (surmd->mesh) {
- BKE_id_free(NULL, surmd->mesh);
- surmd->mesh = NULL;
- }
-
- if (mesh) {
- /* Not possible to use get_mesh() in this case as we'll modify its vertices
- * and get_mesh() would return 'mesh' directly. */
- BKE_id_copy_ex(NULL, (ID *)mesh, (ID **)&surmd->mesh, LIB_ID_COPY_LOCALIZE);
- }
- else {
- surmd->mesh = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, NULL, numVerts, false, false);
- }
-
- if (!ctx->object->pd) {
- printf("SurfaceModifier deformVerts: Should not happen!\n");
- return;
- }
-
- if (surmd->mesh) {
- unsigned int numverts = 0, i = 0;
- int init = 0;
- float *vec;
- MVert *x, *v;
-
- BKE_mesh_apply_vert_coords(surmd->mesh, vertexCos);
- BKE_mesh_calc_normals(surmd->mesh);
-
- numverts = surmd->mesh->totvert;
-
- if (numverts != surmd->numverts ||
- surmd->x == NULL ||
- surmd->v == NULL ||
- cfra != surmd->cfra + 1)
- {
- if (surmd->x) {
- MEM_freeN(surmd->x);
- surmd->x = NULL;
- }
- if (surmd->v) {
- MEM_freeN(surmd->v);
- surmd->v = NULL;
- }
-
- surmd->x = MEM_calloc_arrayN(numverts, sizeof(MVert), "MVert");
- surmd->v = MEM_calloc_arrayN(numverts, sizeof(MVert), "MVert");
-
- surmd->numverts = numverts;
-
- init = 1;
- }
-
- /* convert to global coordinates and calculate velocity */
- for (i = 0, x = surmd->x, v = surmd->v; i < numverts; i++, x++, v++) {
- vec = surmd->mesh->mvert[i].co;
- mul_m4_v3(ctx->object->obmat, vec);
-
- if (init)
- v->co[0] = v->co[1] = v->co[2] = 0.0f;
- else
- sub_v3_v3v3(v->co, vec, x->co);
-
- copy_v3_v3(x->co, vec);
- }
-
- surmd->cfra = cfra;
-
- surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh");
-
- if (surmd->mesh->totpoly)
- BKE_bvhtree_from_mesh_get(surmd->bvhtree, surmd->mesh, BVHTREE_FROM_LOOPTRI, 2);
- else
- BKE_bvhtree_from_mesh_get(surmd->bvhtree, surmd->mesh, BVHTREE_FROM_EDGES, 2);
- }
+ SurfaceModifierData *surmd = (SurfaceModifierData *)md;
+ const int cfra = (int)DEG_get_ctime(ctx->depsgraph);
+
+ /* Free mesh and BVH cache. */
+ if (surmd->bvhtree) {
+ free_bvhtree_from_mesh(surmd->bvhtree);
+ MEM_SAFE_FREE(surmd->bvhtree);
+ }
+
+ if (surmd->mesh) {
+ BKE_id_free(NULL, surmd->mesh);
+ surmd->mesh = NULL;
+ }
+
+ if (mesh) {
+ /* Not possible to use get_mesh() in this case as we'll modify its vertices
+ * and get_mesh() would return 'mesh' directly. */
+ BKE_id_copy_ex(NULL, (ID *)mesh, (ID **)&surmd->mesh, LIB_ID_COPY_LOCALIZE);
+ }
+ else {
+ surmd->mesh = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, NULL, numVerts, false, false);
+ }
+
+ if (!ctx->object->pd) {
+ printf("SurfaceModifier deformVerts: Should not happen!\n");
+ return;
+ }
+
+ if (surmd->mesh) {
+ unsigned int numverts = 0, i = 0;
+ int init = 0;
+ float *vec;
+ MVert *x, *v;
+
+ BKE_mesh_apply_vert_coords(surmd->mesh, vertexCos);
+ BKE_mesh_calc_normals(surmd->mesh);
+
+ numverts = surmd->mesh->totvert;
+
+ if (numverts != surmd->numverts || surmd->x == NULL || surmd->v == NULL ||
+ cfra != surmd->cfra + 1) {
+ if (surmd->x) {
+ MEM_freeN(surmd->x);
+ surmd->x = NULL;
+ }
+ if (surmd->v) {
+ MEM_freeN(surmd->v);
+ surmd->v = NULL;
+ }
+
+ surmd->x = MEM_calloc_arrayN(numverts, sizeof(MVert), "MVert");
+ surmd->v = MEM_calloc_arrayN(numverts, sizeof(MVert), "MVert");
+
+ surmd->numverts = numverts;
+
+ init = 1;
+ }
+
+ /* convert to global coordinates and calculate velocity */
+ for (i = 0, x = surmd->x, v = surmd->v; i < numverts; i++, x++, v++) {
+ vec = surmd->mesh->mvert[i].co;
+ mul_m4_v3(ctx->object->obmat, vec);
+
+ if (init)
+ v->co[0] = v->co[1] = v->co[2] = 0.0f;
+ else
+ sub_v3_v3v3(v->co, vec, x->co);
+
+ copy_v3_v3(x->co, vec);
+ }
+
+ surmd->cfra = cfra;
+
+ surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh");
+
+ if (surmd->mesh->totpoly)
+ BKE_bvhtree_from_mesh_get(surmd->bvhtree, surmd->mesh, BVHTREE_FROM_LOOPTRI, 2);
+ else
+ BKE_bvhtree_from_mesh_get(surmd->bvhtree, surmd->mesh, BVHTREE_FROM_EDGES, 2);
+ }
}
-
ModifierTypeInfo modifierType_Surface = {
- /* name */ "Surface",
- /* structName */ "SurfaceModifierData",
- /* structSize */ sizeof(SurfaceModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_NoUserAdd,
-
- /* copyData */ copyData,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ NULL,
- /* freeData */ freeData,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Surface",
+ /* structName */ "SurfaceModifierData",
+ /* structSize */ sizeof(SurfaceModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs |
+ eModifierTypeFlag_NoUserAdd,
+
+ /* copyData */ copyData,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ freeData,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index 46f4f9c78e9..2a9fff47e5d 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -44,1221 +44,1266 @@
#include "MOD_util.h"
typedef struct SDefAdjacency {
- struct SDefAdjacency *next;
- unsigned int index;
+ struct SDefAdjacency *next;
+ unsigned int index;
} SDefAdjacency;
typedef struct SDefAdjacencyArray {
- SDefAdjacency *first;
- unsigned int num; /* Careful, this is twice the number of polygons (avoids an extra loop) */
+ SDefAdjacency *first;
+ unsigned int num; /* Careful, this is twice the number of polygons (avoids an extra loop) */
} SDefAdjacencyArray;
typedef struct SDefEdgePolys {
- unsigned int polys[2], num;
+ unsigned int polys[2], num;
} SDefEdgePolys;
typedef struct SDefBindCalcData {
- BVHTreeFromMesh * const treeData;
- const SDefAdjacencyArray * const vert_edges;
- const SDefEdgePolys * const edge_polys;
- SDefVert * const bind_verts;
- const MLoopTri * const looptri;
- const MPoly * const mpoly;
- const MEdge * const medge;
- const MLoop * const mloop;
- float (* const targetCos)[3];
- float (* const vertexCos)[3];
- float imat[4][4];
- const float falloff;
- int success;
+ BVHTreeFromMesh *const treeData;
+ const SDefAdjacencyArray *const vert_edges;
+ const SDefEdgePolys *const edge_polys;
+ SDefVert *const bind_verts;
+ const MLoopTri *const looptri;
+ const MPoly *const mpoly;
+ const MEdge *const medge;
+ const MLoop *const mloop;
+ float (*const targetCos)[3];
+ float (*const vertexCos)[3];
+ float imat[4][4];
+ const float falloff;
+ int success;
} SDefBindCalcData;
typedef struct SDefBindPoly {
- float (*coords)[3];
- float (*coords_v2)[2];
- float point_v2[2];
- float weight_angular;
- float weight_dist_proj;
- float weight_dist;
- float weight;
- float scales[2];
- float centroid[3];
- float centroid_v2[2];
- float normal[3];
- float cent_edgemid_vecs_v2[2][2];
- float edgemid_angle;
- float point_edgemid_angles[2];
- float corner_edgemid_angles[2];
- float dominant_angle_weight;
- unsigned int index;
- unsigned int numverts;
- unsigned int loopstart;
- unsigned int edge_inds[2];
- unsigned int edge_vert_inds[2];
- unsigned int corner_ind;
- unsigned int dominant_edge;
- bool inside;
+ float (*coords)[3];
+ float (*coords_v2)[2];
+ float point_v2[2];
+ float weight_angular;
+ float weight_dist_proj;
+ float weight_dist;
+ float weight;
+ float scales[2];
+ float centroid[3];
+ float centroid_v2[2];
+ float normal[3];
+ float cent_edgemid_vecs_v2[2][2];
+ float edgemid_angle;
+ float point_edgemid_angles[2];
+ float corner_edgemid_angles[2];
+ float dominant_angle_weight;
+ unsigned int index;
+ unsigned int numverts;
+ unsigned int loopstart;
+ unsigned int edge_inds[2];
+ unsigned int edge_vert_inds[2];
+ unsigned int corner_ind;
+ unsigned int dominant_edge;
+ bool inside;
} SDefBindPoly;
typedef struct SDefBindWeightData {
- SDefBindPoly *bind_polys;
- unsigned int numpoly;
- unsigned int numbinds;
+ SDefBindPoly *bind_polys;
+ unsigned int numpoly;
+ unsigned int numbinds;
} SDefBindWeightData;
typedef struct SDefDeformData {
- const SDefVert * const bind_verts;
- float (* const targetCos)[3];
- float (* const vertexCos)[3];
+ const SDefVert *const bind_verts;
+ float (*const targetCos)[3];
+ float (*const vertexCos)[3];
} SDefDeformData;
/* Bind result values */
enum {
- MOD_SDEF_BIND_RESULT_SUCCESS = 1,
- MOD_SDEF_BIND_RESULT_GENERIC_ERR = 0,
- MOD_SDEF_BIND_RESULT_MEM_ERR = -1,
- MOD_SDEF_BIND_RESULT_NONMANY_ERR = -2,
- MOD_SDEF_BIND_RESULT_CONCAVE_ERR = -3,
- MOD_SDEF_BIND_RESULT_OVERLAP_ERR = -4,
+ MOD_SDEF_BIND_RESULT_SUCCESS = 1,
+ MOD_SDEF_BIND_RESULT_GENERIC_ERR = 0,
+ MOD_SDEF_BIND_RESULT_MEM_ERR = -1,
+ MOD_SDEF_BIND_RESULT_NONMANY_ERR = -2,
+ MOD_SDEF_BIND_RESULT_CONCAVE_ERR = -3,
+ MOD_SDEF_BIND_RESULT_OVERLAP_ERR = -4,
};
/* Infinite weight flags */
enum {
- MOD_SDEF_INFINITE_WEIGHT_ANGULAR = (1 << 0),
- MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ = (1 << 1),
- MOD_SDEF_INFINITE_WEIGHT_DIST = (1 << 2),
+ MOD_SDEF_INFINITE_WEIGHT_ANGULAR = (1 << 0),
+ MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ = (1 << 1),
+ MOD_SDEF_INFINITE_WEIGHT_DIST = (1 << 2),
};
static void initData(ModifierData *md)
{
- SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
- smd->target = NULL;
- smd->verts = NULL;
- smd->flags = 0;
- smd->falloff = 4.0f;
+ SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
+ smd->target = NULL;
+ smd->verts = NULL;
+ smd->flags = 0;
+ smd->falloff = 4.0f;
}
static void freeData(ModifierData *md)
{
- SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
-
- if (smd->verts) {
- for (int i = 0; i < smd->numverts; i++) {
- if (smd->verts[i].binds) {
- for (int j = 0; j < smd->verts[i].numbinds; j++) {
- MEM_SAFE_FREE(smd->verts[i].binds[j].vert_inds);
- MEM_SAFE_FREE(smd->verts[i].binds[j].vert_weights);
- }
-
- MEM_SAFE_FREE(smd->verts[i].binds);
- }
- }
-
- MEM_SAFE_FREE(smd->verts);
- }
+ SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
+
+ if (smd->verts) {
+ for (int i = 0; i < smd->numverts; i++) {
+ if (smd->verts[i].binds) {
+ for (int j = 0; j < smd->verts[i].numbinds; j++) {
+ MEM_SAFE_FREE(smd->verts[i].binds[j].vert_inds);
+ MEM_SAFE_FREE(smd->verts[i].binds[j].vert_weights);
+ }
+
+ MEM_SAFE_FREE(smd->verts[i].binds);
+ }
+ }
+
+ MEM_SAFE_FREE(smd->verts);
+ }
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
- const SurfaceDeformModifierData *smd = (const SurfaceDeformModifierData *)md;
- SurfaceDeformModifierData *tsmd = (SurfaceDeformModifierData *)target;
-
- modifier_copyData_generic(md, target, flag);
-
- if (smd->verts) {
- tsmd->verts = MEM_dupallocN(smd->verts);
-
- for (int i = 0; i < smd->numverts; i++) {
- if (smd->verts[i].binds) {
- tsmd->verts[i].binds = MEM_dupallocN(smd->verts[i].binds);
-
- for (int j = 0; j < smd->verts[i].numbinds; j++) {
- if (smd->verts[i].binds[j].vert_inds) {
- tsmd->verts[i].binds[j].vert_inds = MEM_dupallocN(smd->verts[i].binds[j].vert_inds);
- }
-
- if (smd->verts[i].binds[j].vert_weights) {
- tsmd->verts[i].binds[j].vert_weights = MEM_dupallocN(smd->verts[i].binds[j].vert_weights);
- }
- }
- }
- }
- }
+ const SurfaceDeformModifierData *smd = (const SurfaceDeformModifierData *)md;
+ SurfaceDeformModifierData *tsmd = (SurfaceDeformModifierData *)target;
+
+ modifier_copyData_generic(md, target, flag);
+
+ if (smd->verts) {
+ tsmd->verts = MEM_dupallocN(smd->verts);
+
+ for (int i = 0; i < smd->numverts; i++) {
+ if (smd->verts[i].binds) {
+ tsmd->verts[i].binds = MEM_dupallocN(smd->verts[i].binds);
+
+ for (int j = 0; j < smd->verts[i].numbinds; j++) {
+ if (smd->verts[i].binds[j].vert_inds) {
+ tsmd->verts[i].binds[j].vert_inds = MEM_dupallocN(smd->verts[i].binds[j].vert_inds);
+ }
+
+ if (smd->verts[i].binds[j].vert_weights) {
+ tsmd->verts[i].binds[j].vert_weights = MEM_dupallocN(
+ smd->verts[i].binds[j].vert_weights);
+ }
+ }
+ }
+ }
+ }
}
static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
+ SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
- walk(userData, ob, &smd->target, IDWALK_NOP);
+ walk(userData, ob, &smd->target, IDWALK_NOP);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
- if (smd->target != NULL) {
- DEG_add_object_relation(ctx->node, smd->target, DEG_OB_COMP_GEOMETRY, "Surface Deform Modifier");
- }
+ SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
+ if (smd->target != NULL) {
+ DEG_add_object_relation(
+ ctx->node, smd->target, DEG_OB_COMP_GEOMETRY, "Surface Deform Modifier");
+ }
}
-static void freeAdjacencyMap(SDefAdjacencyArray * const vert_edges, SDefAdjacency * const adj_ref, SDefEdgePolys * const edge_polys)
+static void freeAdjacencyMap(SDefAdjacencyArray *const vert_edges,
+ SDefAdjacency *const adj_ref,
+ SDefEdgePolys *const edge_polys)
{
- MEM_freeN(edge_polys);
+ MEM_freeN(edge_polys);
- MEM_freeN(adj_ref);
+ MEM_freeN(adj_ref);
- MEM_freeN(vert_edges);
+ MEM_freeN(vert_edges);
}
-static int buildAdjacencyMap(
- const MPoly *poly, const MEdge *edge, const MLoop * const mloop, const unsigned int numpoly, const unsigned int numedges,
- SDefAdjacencyArray * const vert_edges, SDefAdjacency *adj, SDefEdgePolys * const edge_polys)
+static int buildAdjacencyMap(const MPoly *poly,
+ const MEdge *edge,
+ const MLoop *const mloop,
+ const unsigned int numpoly,
+ const unsigned int numedges,
+ SDefAdjacencyArray *const vert_edges,
+ SDefAdjacency *adj,
+ SDefEdgePolys *const edge_polys)
{
- const MLoop *loop;
-
- /* Fing polygons adjacent to edges */
- for (int i = 0; i < numpoly; i++, poly++) {
- loop = &mloop[poly->loopstart];
-
- for (int j = 0; j < poly->totloop; j++, loop++) {
- if (edge_polys[loop->e].num == 0) {
- edge_polys[loop->e].polys[0] = i;
- edge_polys[loop->e].polys[1] = -1;
- edge_polys[loop->e].num++;
- }
- else if (edge_polys[loop->e].num == 1) {
- edge_polys[loop->e].polys[1] = i;
- edge_polys[loop->e].num++;
- }
- else {
- return MOD_SDEF_BIND_RESULT_NONMANY_ERR;
- }
- }
- }
-
- /* Find edges adjacent to vertices */
- for (int i = 0; i < numedges; i++, edge++) {
- adj->next = vert_edges[edge->v1].first;
- adj->index = i;
- vert_edges[edge->v1].first = adj;
- vert_edges[edge->v1].num += edge_polys[i].num;
- adj++;
-
- adj->next = vert_edges[edge->v2].first;
- adj->index = i;
- vert_edges[edge->v2].first = adj;
- vert_edges[edge->v2].num += edge_polys[i].num;
- adj++;
- }
-
- return MOD_SDEF_BIND_RESULT_SUCCESS;
+ const MLoop *loop;
+
+ /* Fing polygons adjacent to edges */
+ for (int i = 0; i < numpoly; i++, poly++) {
+ loop = &mloop[poly->loopstart];
+
+ for (int j = 0; j < poly->totloop; j++, loop++) {
+ if (edge_polys[loop->e].num == 0) {
+ edge_polys[loop->e].polys[0] = i;
+ edge_polys[loop->e].polys[1] = -1;
+ edge_polys[loop->e].num++;
+ }
+ else if (edge_polys[loop->e].num == 1) {
+ edge_polys[loop->e].polys[1] = i;
+ edge_polys[loop->e].num++;
+ }
+ else {
+ return MOD_SDEF_BIND_RESULT_NONMANY_ERR;
+ }
+ }
+ }
+
+ /* Find edges adjacent to vertices */
+ for (int i = 0; i < numedges; i++, edge++) {
+ adj->next = vert_edges[edge->v1].first;
+ adj->index = i;
+ vert_edges[edge->v1].first = adj;
+ vert_edges[edge->v1].num += edge_polys[i].num;
+ adj++;
+
+ adj->next = vert_edges[edge->v2].first;
+ adj->index = i;
+ vert_edges[edge->v2].first = adj;
+ vert_edges[edge->v2].num += edge_polys[i].num;
+ adj++;
+ }
+
+ return MOD_SDEF_BIND_RESULT_SUCCESS;
}
-BLI_INLINE void sortPolyVertsEdge(unsigned int *indices, const MLoop * const mloop, const unsigned int edge, const unsigned int num)
+BLI_INLINE void sortPolyVertsEdge(unsigned int *indices,
+ const MLoop *const mloop,
+ const unsigned int edge,
+ const unsigned int num)
{
- bool found = false;
-
- for (int i = 0; i < num; i++) {
- if (mloop[i].e == edge) {
- found = true;
- }
- if (found) {
- *indices = mloop[i].v;
- indices++;
- }
- }
-
- /* Fill in remaining vertex indices that occur before the edge */
- for (int i = 0; mloop[i].e != edge; i++) {
- *indices = mloop[i].v;
- indices++;
- }
+ bool found = false;
+
+ for (int i = 0; i < num; i++) {
+ if (mloop[i].e == edge) {
+ found = true;
+ }
+ if (found) {
+ *indices = mloop[i].v;
+ indices++;
+ }
+ }
+
+ /* Fill in remaining vertex indices that occur before the edge */
+ for (int i = 0; mloop[i].e != edge; i++) {
+ *indices = mloop[i].v;
+ indices++;
+ }
}
-BLI_INLINE void sortPolyVertsTri(unsigned int *indices, const MLoop * const mloop, const unsigned int loopstart, const unsigned int num)
+BLI_INLINE void sortPolyVertsTri(unsigned int *indices,
+ const MLoop *const mloop,
+ const unsigned int loopstart,
+ const unsigned int num)
{
- for (int i = loopstart; i < num; i++) {
- *indices = mloop[i].v;
- indices++;
- }
-
- for (int i = 0; i < loopstart; i++) {
- *indices = mloop[i].v;
- indices++;
- }
+ for (int i = loopstart; i < num; i++) {
+ *indices = mloop[i].v;
+ indices++;
+ }
+
+ for (int i = 0; i < loopstart; i++) {
+ *indices = mloop[i].v;
+ indices++;
+ }
}
-BLI_INLINE unsigned int nearestVert(SDefBindCalcData * const data, const float point_co[3])
+BLI_INLINE unsigned int nearestVert(SDefBindCalcData *const data, const float point_co[3])
{
- BVHTreeNearest nearest = { .dist_sq = FLT_MAX, .index = -1, };
- const MPoly *poly;
- const MEdge *edge;
- const MLoop *loop;
- float t_point[3];
- float max_dist = FLT_MAX;
- float dist;
- unsigned int index = 0;
-
- mul_v3_m4v3(t_point, data->imat, point_co);
-
- BLI_bvhtree_find_nearest(data->treeData->tree, t_point, &nearest, data->treeData->nearest_callback, data->treeData);
-
- poly = &data->mpoly[data->looptri[nearest.index].poly];
- loop = &data->mloop[poly->loopstart];
-
- for (int i = 0; i < poly->totloop; i++, loop++) {
- edge = &data->medge[loop->e];
- dist = dist_squared_to_line_segment_v3(point_co, data->targetCos[edge->v1], data->targetCos[edge->v2]);
-
- if (dist < max_dist) {
- max_dist = dist;
- index = loop->e;
- }
- }
-
- edge = &data->medge[index];
- if (len_squared_v3v3(point_co, data->targetCos[edge->v1]) < len_squared_v3v3(point_co, data->targetCos[edge->v2])) {
- return edge->v1;
- }
- else {
- return edge->v2;
- }
+ BVHTreeNearest nearest = {
+ .dist_sq = FLT_MAX,
+ .index = -1,
+ };
+ const MPoly *poly;
+ const MEdge *edge;
+ const MLoop *loop;
+ float t_point[3];
+ float max_dist = FLT_MAX;
+ float dist;
+ unsigned int index = 0;
+
+ mul_v3_m4v3(t_point, data->imat, point_co);
+
+ BLI_bvhtree_find_nearest(
+ data->treeData->tree, t_point, &nearest, data->treeData->nearest_callback, data->treeData);
+
+ poly = &data->mpoly[data->looptri[nearest.index].poly];
+ loop = &data->mloop[poly->loopstart];
+
+ for (int i = 0; i < poly->totloop; i++, loop++) {
+ edge = &data->medge[loop->e];
+ dist = dist_squared_to_line_segment_v3(
+ point_co, data->targetCos[edge->v1], data->targetCos[edge->v2]);
+
+ if (dist < max_dist) {
+ max_dist = dist;
+ index = loop->e;
+ }
+ }
+
+ edge = &data->medge[index];
+ if (len_squared_v3v3(point_co, data->targetCos[edge->v1]) <
+ len_squared_v3v3(point_co, data->targetCos[edge->v2])) {
+ return edge->v1;
+ }
+ else {
+ return edge->v2;
+ }
}
BLI_INLINE int isPolyValid(const float coords[][2], const unsigned int nr)
{
- float prev_co[2];
- float curr_vec[2], prev_vec[2];
+ float prev_co[2];
+ float curr_vec[2], prev_vec[2];
- if (!is_poly_convex_v2(coords, nr)) {
- return MOD_SDEF_BIND_RESULT_CONCAVE_ERR;
- }
+ if (!is_poly_convex_v2(coords, nr)) {
+ return MOD_SDEF_BIND_RESULT_CONCAVE_ERR;
+ }
- copy_v2_v2(prev_co, coords[nr - 1]);
- sub_v2_v2v2(prev_vec, prev_co, coords[nr - 2]);
- normalize_v2(prev_vec);
+ copy_v2_v2(prev_co, coords[nr - 1]);
+ sub_v2_v2v2(prev_vec, prev_co, coords[nr - 2]);
+ normalize_v2(prev_vec);
- for (int i = 0; i < nr; i++) {
- sub_v2_v2v2(curr_vec, coords[i], prev_co);
+ for (int i = 0; i < nr; i++) {
+ sub_v2_v2v2(curr_vec, coords[i], prev_co);
- const float curr_len = normalize_v2(curr_vec);
- if (curr_len < FLT_EPSILON) {
- return MOD_SDEF_BIND_RESULT_OVERLAP_ERR;
- }
+ const float curr_len = normalize_v2(curr_vec);
+ if (curr_len < FLT_EPSILON) {
+ return MOD_SDEF_BIND_RESULT_OVERLAP_ERR;
+ }
- if (1.0f - dot_v2v2(prev_vec, curr_vec) < FLT_EPSILON) {
- return MOD_SDEF_BIND_RESULT_CONCAVE_ERR;
- }
+ if (1.0f - dot_v2v2(prev_vec, curr_vec) < FLT_EPSILON) {
+ return MOD_SDEF_BIND_RESULT_CONCAVE_ERR;
+ }
- copy_v2_v2(prev_co, coords[i]);
- copy_v2_v2(prev_vec, curr_vec);
- }
+ copy_v2_v2(prev_co, coords[i]);
+ copy_v2_v2(prev_vec, curr_vec);
+ }
- return MOD_SDEF_BIND_RESULT_SUCCESS;
+ return MOD_SDEF_BIND_RESULT_SUCCESS;
}
-static void freeBindData(SDefBindWeightData * const bwdata)
+static void freeBindData(SDefBindWeightData *const bwdata)
{
- SDefBindPoly *bpoly = bwdata->bind_polys;
+ SDefBindPoly *bpoly = bwdata->bind_polys;
- if (bwdata->bind_polys) {
- for (int i = 0; i < bwdata->numpoly; bpoly++, i++) {
- MEM_SAFE_FREE(bpoly->coords);
- MEM_SAFE_FREE(bpoly->coords_v2);
- }
+ if (bwdata->bind_polys) {
+ for (int i = 0; i < bwdata->numpoly; bpoly++, i++) {
+ MEM_SAFE_FREE(bpoly->coords);
+ MEM_SAFE_FREE(bpoly->coords_v2);
+ }
- MEM_freeN(bwdata->bind_polys);
- }
+ MEM_freeN(bwdata->bind_polys);
+ }
- MEM_freeN(bwdata);
+ MEM_freeN(bwdata);
}
BLI_INLINE float computeAngularWeight(const float point_angle, const float edgemid_angle)
{
- float weight;
+ float weight;
- weight = point_angle;
- weight /= edgemid_angle;
- weight *= M_PI_2;
+ weight = point_angle;
+ weight /= edgemid_angle;
+ weight *= M_PI_2;
- return sinf(weight);
+ return sinf(weight);
}
-BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData * const data, const float point_co[3])
+BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
+ const float point_co[3])
{
- const unsigned int nearest = nearestVert(data, point_co);
- const SDefAdjacency * const vert_edges = data->vert_edges[nearest].first;
- const SDefEdgePolys * const edge_polys = data->edge_polys;
-
- const SDefAdjacency *vedge;
- const MPoly *poly;
- const MLoop *loop;
-
- SDefBindWeightData *bwdata;
- SDefBindPoly *bpoly;
-
- float world[3] = {0.0f, 0.0f, 1.0f};
- float avg_point_dist = 0.0f;
- float tot_weight = 0.0f;
- int inf_weight_flags = 0;
-
- bwdata = MEM_callocN(sizeof(*bwdata), "SDefBindWeightData");
- if (bwdata == NULL) {
- data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
- return NULL;
- }
-
- bwdata->numpoly = data->vert_edges[nearest].num / 2;
-
- bpoly = MEM_calloc_arrayN(bwdata->numpoly, sizeof(*bpoly), "SDefBindPoly");
- if (bpoly == NULL) {
- freeBindData(bwdata);
- data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
- return NULL;
- }
-
- bwdata->bind_polys = bpoly;
-
- /* Loop over all adjacent edges, and build the SDefBindPoly data for each poly adjacent to those */
- for (vedge = vert_edges; vedge; vedge = vedge->next) {
- unsigned int edge_ind = vedge->index;
-
- for (int i = 0; i < edge_polys[edge_ind].num; i++) {
- {
- bpoly = bwdata->bind_polys;
-
- for (int j = 0; j < bwdata->numpoly; bpoly++, j++) {
- /* If coords isn't allocated, we have reached the first uninitialized bpoly */
- if ((bpoly->index == edge_polys[edge_ind].polys[i]) || (!bpoly->coords)) {
- break;
- }
- }
- }
-
- /* Check if poly was already created by another edge or still has to be initialized */
- if (!bpoly->coords) {
- float angle;
- float axis[3];
- float tmp_vec_v2[2];
- int is_poly_valid;
-
- bpoly->index = edge_polys[edge_ind].polys[i];
- bpoly->coords = NULL;
- bpoly->coords_v2 = NULL;
-
- /* Copy poly data */
- poly = &data->mpoly[bpoly->index];
- loop = &data->mloop[poly->loopstart];
-
- bpoly->numverts = poly->totloop;
- bpoly->loopstart = poly->loopstart;
-
- bpoly->coords = MEM_malloc_arrayN(poly->totloop, sizeof(*bpoly->coords), "SDefBindPolyCoords");
- if (bpoly->coords == NULL) {
- freeBindData(bwdata);
- data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
- return NULL;
- }
-
- bpoly->coords_v2 = MEM_malloc_arrayN(poly->totloop, sizeof(*bpoly->coords_v2), "SDefBindPolyCoords_v2");
- if (bpoly->coords_v2 == NULL) {
- freeBindData(bwdata);
- data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
- return NULL;
- }
-
- for (int j = 0; j < poly->totloop; j++, loop++) {
- copy_v3_v3(bpoly->coords[j], data->targetCos[loop->v]);
-
- /* Find corner and edge indices within poly loop array */
- if (loop->v == nearest) {
- bpoly->corner_ind = j;
- bpoly->edge_vert_inds[0] = (j == 0) ? (poly->totloop - 1) : (j - 1);
- bpoly->edge_vert_inds[1] = (j == poly->totloop - 1) ? (0) : (j + 1);
-
- bpoly->edge_inds[0] = data->mloop[poly->loopstart + bpoly->edge_vert_inds[0]].e;
- bpoly->edge_inds[1] = loop->e;
- }
- }
-
- /* Compute poly's parametric data */
- mid_v3_v3_array(bpoly->centroid, bpoly->coords, poly->totloop);
- normal_poly_v3(bpoly->normal, bpoly->coords, poly->totloop);
-
- /* Compute poly skew angle and axis */
- angle = angle_normalized_v3v3(bpoly->normal, world);
-
- cross_v3_v3v3(axis, bpoly->normal, world);
- normalize_v3(axis);
-
- /* Map coords onto 2d normal plane */
- map_to_plane_axis_angle_v2_v3v3fl(bpoly->point_v2, point_co, axis, angle);
-
- zero_v2(bpoly->centroid_v2);
- for (int j = 0; j < poly->totloop; j++) {
- map_to_plane_axis_angle_v2_v3v3fl(bpoly->coords_v2[j], bpoly->coords[j], axis, angle);
- madd_v2_v2fl(bpoly->centroid_v2, bpoly->coords_v2[j], 1.0f / poly->totloop);
- }
-
- is_poly_valid = isPolyValid(bpoly->coords_v2, poly->totloop);
-
- if (is_poly_valid != MOD_SDEF_BIND_RESULT_SUCCESS) {
- freeBindData(bwdata);
- data->success = is_poly_valid;
- return NULL;
- }
-
- bpoly->inside = isect_point_poly_v2(bpoly->point_v2, bpoly->coords_v2, poly->totloop, false);
-
- /* Initialize weight components */
- bpoly->weight_angular = 1.0f;
- bpoly->weight_dist_proj = len_v2v2(bpoly->centroid_v2, bpoly->point_v2);
- bpoly->weight_dist = len_v3v3(bpoly->centroid, point_co);
-
- avg_point_dist += bpoly->weight_dist;
-
- /* Compute centroid to mid-edge vectors */
- mid_v2_v2v2(bpoly->cent_edgemid_vecs_v2[0],
- bpoly->coords_v2[bpoly->edge_vert_inds[0]],
- bpoly->coords_v2[bpoly->corner_ind]);
-
- mid_v2_v2v2(bpoly->cent_edgemid_vecs_v2[1],
- bpoly->coords_v2[bpoly->edge_vert_inds[1]],
- bpoly->coords_v2[bpoly->corner_ind]);
-
- sub_v2_v2(bpoly->cent_edgemid_vecs_v2[0], bpoly->centroid_v2);
- sub_v2_v2(bpoly->cent_edgemid_vecs_v2[1], bpoly->centroid_v2);
-
- /* Compute poly scales with respect to mid-edges, and normalize the vectors */
- bpoly->scales[0] = normalize_v2(bpoly->cent_edgemid_vecs_v2[0]);
- bpoly->scales[1] = normalize_v2(bpoly->cent_edgemid_vecs_v2[1]);
-
- /* Compute the required polygon angles */
- bpoly->edgemid_angle = angle_normalized_v2v2(bpoly->cent_edgemid_vecs_v2[0], bpoly->cent_edgemid_vecs_v2[1]);
-
- sub_v2_v2v2(tmp_vec_v2, bpoly->coords_v2[bpoly->corner_ind], bpoly->centroid_v2);
- normalize_v2(tmp_vec_v2);
-
- bpoly->corner_edgemid_angles[0] = angle_normalized_v2v2(tmp_vec_v2, bpoly->cent_edgemid_vecs_v2[0]);
- bpoly->corner_edgemid_angles[1] = angle_normalized_v2v2(tmp_vec_v2, bpoly->cent_edgemid_vecs_v2[1]);
-
- /* Check for inifnite weights, and compute angular data otherwise */
- if (bpoly->weight_dist < FLT_EPSILON) {
- inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ;
- inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST;
- }
- else if (bpoly->weight_dist_proj < FLT_EPSILON) {
- inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ;
- }
- else {
- float cent_point_vec[2];
-
- sub_v2_v2v2(cent_point_vec, bpoly->point_v2, bpoly->centroid_v2);
- normalize_v2(cent_point_vec);
-
- bpoly->point_edgemid_angles[0] = angle_normalized_v2v2(cent_point_vec, bpoly->cent_edgemid_vecs_v2[0]);
- bpoly->point_edgemid_angles[1] = angle_normalized_v2v2(cent_point_vec, bpoly->cent_edgemid_vecs_v2[1]);
- }
- }
- }
- }
-
- avg_point_dist /= bwdata->numpoly;
-
- /* If weights 1 and 2 are not infinite, loop over all adjacent edges again,
- * and build adjacency dependent angle data (depends on all polygons having been computed) */
- if (!inf_weight_flags) {
- for (vedge = vert_edges; vedge; vedge = vedge->next) {
- SDefBindPoly *bpolys[2];
- const SDefEdgePolys *epolys;
- float ang_weights[2];
- unsigned int edge_ind = vedge->index;
- unsigned int edge_on_poly[2];
-
- epolys = &edge_polys[edge_ind];
-
- /* Find bind polys corresponding to the edge's adjacent polys */
- bpoly = bwdata->bind_polys;
-
- for (int i = 0, j = 0; (i < bwdata->numpoly) && (j < epolys->num); bpoly++, i++) {
- if (ELEM(bpoly->index, epolys->polys[0], epolys->polys[1])) {
- bpolys[j] = bpoly;
-
- if (bpoly->edge_inds[0] == edge_ind) {
- edge_on_poly[j] = 0;
- }
- else {
- edge_on_poly[j] = 1;
- }
-
- j++;
- }
- }
-
- /* Compute angular weight component */
- if (epolys->num == 1) {
- ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]], bpolys[0]->edgemid_angle);
- bpolys[0]->weight_angular *= ang_weights[0] * ang_weights[0];
- }
- else if (epolys->num == 2) {
- ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]], bpolys[0]->edgemid_angle);
- ang_weights[1] = computeAngularWeight(bpolys[1]->point_edgemid_angles[edge_on_poly[1]], bpolys[1]->edgemid_angle);
-
- bpolys[0]->weight_angular *= ang_weights[0] * ang_weights[1];
- bpolys[1]->weight_angular *= ang_weights[0] * ang_weights[1];
- }
- }
- }
-
- /* Compute scalings and falloff.
- * Scale all weights if no infinite weight is found,
- * scale only unprojected weight if projected weight is infinite,
- * scale none if both are infinite. */
- if (!inf_weight_flags) {
- bpoly = bwdata->bind_polys;
-
- for (int i = 0; i < bwdata->numpoly; bpoly++, i++) {
- float corner_angle_weights[2];
- float scale_weight, sqr, inv_sqr;
-
- corner_angle_weights[0] = bpoly->point_edgemid_angles[0] / bpoly->corner_edgemid_angles[0];
- corner_angle_weights[1] = bpoly->point_edgemid_angles[1] / bpoly->corner_edgemid_angles[1];
-
- if (isnan(corner_angle_weights[0]) || isnan(corner_angle_weights[1])) {
- freeBindData(bwdata);
- data->success = MOD_SDEF_BIND_RESULT_GENERIC_ERR;
- return NULL;
- }
-
- /* Find which edge the point is closer to */
- if (corner_angle_weights[0] < corner_angle_weights[1]) {
- bpoly->dominant_edge = 0;
- bpoly->dominant_angle_weight = corner_angle_weights[0];
- }
- else {
- bpoly->dominant_edge = 1;
- bpoly->dominant_angle_weight = corner_angle_weights[1];
- }
-
- bpoly->dominant_angle_weight = sinf(bpoly->dominant_angle_weight * M_PI_2);
-
- /* Compute quadratic angular scale interpolation weight */
- scale_weight = bpoly->point_edgemid_angles[bpoly->dominant_edge] / bpoly->edgemid_angle;
- scale_weight /= scale_weight + (bpoly->point_edgemid_angles[!bpoly->dominant_edge] / bpoly->edgemid_angle);
-
- sqr = scale_weight * scale_weight;
- inv_sqr = 1.0f - scale_weight;
- inv_sqr *= inv_sqr;
- scale_weight = sqr / (sqr + inv_sqr);
-
- /* Compute interpolated scale (no longer need the individual scales,
- * so simply storing the result over the scale in index zero) */
- bpoly->scales[0] = bpoly->scales[bpoly->dominant_edge] * (1.0f - scale_weight) +
- bpoly->scales[!bpoly->dominant_edge] * scale_weight;
-
- /* Scale the point distance weights, and introduce falloff */
- bpoly->weight_dist_proj /= bpoly->scales[0];
- bpoly->weight_dist_proj = powf(bpoly->weight_dist_proj, data->falloff);
-
- bpoly->weight_dist /= avg_point_dist;
- bpoly->weight_dist = powf(bpoly->weight_dist, data->falloff);
-
- /* Re-check for infinite weights, now that all scalings and interpolations are computed */
- if (bpoly->weight_dist < FLT_EPSILON) {
- inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ;
- inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST;
- }
- else if (bpoly->weight_dist_proj < FLT_EPSILON) {
- inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ;
- }
- else if (bpoly->weight_angular < FLT_EPSILON) {
- inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_ANGULAR;
- }
- }
- }
- else if (!(inf_weight_flags & MOD_SDEF_INFINITE_WEIGHT_DIST)) {
- bpoly = bwdata->bind_polys;
-
- for (int i = 0; i < bwdata->numpoly; bpoly++, i++) {
- /* Scale the point distance weight by average point distance, and introduce falloff */
- bpoly->weight_dist /= avg_point_dist;
- bpoly->weight_dist = powf(bpoly->weight_dist, data->falloff);
-
- /* Re-check for infinite weights, now that all scalings and interpolations are computed */
- if (bpoly->weight_dist < FLT_EPSILON) {
- inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST;
- }
- }
- }
-
- /* Final loop, to compute actual weights */
- bpoly = bwdata->bind_polys;
-
- for (int i = 0; i < bwdata->numpoly; bpoly++, i++) {
- /* Weight computation from components */
- if (inf_weight_flags & MOD_SDEF_INFINITE_WEIGHT_DIST) {
- bpoly->weight = bpoly->weight_dist < FLT_EPSILON ? 1.0f : 0.0f;
- }
- else if (inf_weight_flags & MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ) {
- bpoly->weight = bpoly->weight_dist_proj < FLT_EPSILON ?
- 1.0f / bpoly->weight_dist : 0.0f;
- }
- else if (inf_weight_flags & MOD_SDEF_INFINITE_WEIGHT_ANGULAR) {
- bpoly->weight = bpoly->weight_angular < FLT_EPSILON ?
- 1.0f / bpoly->weight_dist_proj / bpoly->weight_dist : 0.0f;
- }
- else {
- bpoly->weight = 1.0f / bpoly->weight_angular /
- bpoly->weight_dist_proj /
- bpoly->weight_dist;
- }
-
- tot_weight += bpoly->weight;
- }
-
- bpoly = bwdata->bind_polys;
-
- for (int i = 0; i < bwdata->numpoly; bpoly++, i++) {
- bpoly->weight /= tot_weight;
-
- /* Evaluate if this poly is relevant to bind */
- /* Even though the weights should add up to 1.0,
- * the losses of weights smaller than epsilon here
- * should be negligible... */
- if (bpoly->weight >= FLT_EPSILON) {
- if (bpoly->inside) {
- bwdata->numbinds += 1;
- }
- else {
- if (bpoly->dominant_angle_weight < FLT_EPSILON || 1.0f - bpoly->dominant_angle_weight < FLT_EPSILON) {
- bwdata->numbinds += 1;
- }
- else {
- bwdata->numbinds += 2;
- }
- }
- }
- }
-
- return bwdata;
+ const unsigned int nearest = nearestVert(data, point_co);
+ const SDefAdjacency *const vert_edges = data->vert_edges[nearest].first;
+ const SDefEdgePolys *const edge_polys = data->edge_polys;
+
+ const SDefAdjacency *vedge;
+ const MPoly *poly;
+ const MLoop *loop;
+
+ SDefBindWeightData *bwdata;
+ SDefBindPoly *bpoly;
+
+ float world[3] = {0.0f, 0.0f, 1.0f};
+ float avg_point_dist = 0.0f;
+ float tot_weight = 0.0f;
+ int inf_weight_flags = 0;
+
+ bwdata = MEM_callocN(sizeof(*bwdata), "SDefBindWeightData");
+ if (bwdata == NULL) {
+ data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
+ return NULL;
+ }
+
+ bwdata->numpoly = data->vert_edges[nearest].num / 2;
+
+ bpoly = MEM_calloc_arrayN(bwdata->numpoly, sizeof(*bpoly), "SDefBindPoly");
+ if (bpoly == NULL) {
+ freeBindData(bwdata);
+ data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
+ return NULL;
+ }
+
+ bwdata->bind_polys = bpoly;
+
+ /* Loop over all adjacent edges, and build the SDefBindPoly data for each poly adjacent to those */
+ for (vedge = vert_edges; vedge; vedge = vedge->next) {
+ unsigned int edge_ind = vedge->index;
+
+ for (int i = 0; i < edge_polys[edge_ind].num; i++) {
+ {
+ bpoly = bwdata->bind_polys;
+
+ for (int j = 0; j < bwdata->numpoly; bpoly++, j++) {
+ /* If coords isn't allocated, we have reached the first uninitialized bpoly */
+ if ((bpoly->index == edge_polys[edge_ind].polys[i]) || (!bpoly->coords)) {
+ break;
+ }
+ }
+ }
+
+ /* Check if poly was already created by another edge or still has to be initialized */
+ if (!bpoly->coords) {
+ float angle;
+ float axis[3];
+ float tmp_vec_v2[2];
+ int is_poly_valid;
+
+ bpoly->index = edge_polys[edge_ind].polys[i];
+ bpoly->coords = NULL;
+ bpoly->coords_v2 = NULL;
+
+ /* Copy poly data */
+ poly = &data->mpoly[bpoly->index];
+ loop = &data->mloop[poly->loopstart];
+
+ bpoly->numverts = poly->totloop;
+ bpoly->loopstart = poly->loopstart;
+
+ bpoly->coords = MEM_malloc_arrayN(
+ poly->totloop, sizeof(*bpoly->coords), "SDefBindPolyCoords");
+ if (bpoly->coords == NULL) {
+ freeBindData(bwdata);
+ data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
+ return NULL;
+ }
+
+ bpoly->coords_v2 = MEM_malloc_arrayN(
+ poly->totloop, sizeof(*bpoly->coords_v2), "SDefBindPolyCoords_v2");
+ if (bpoly->coords_v2 == NULL) {
+ freeBindData(bwdata);
+ data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
+ return NULL;
+ }
+
+ for (int j = 0; j < poly->totloop; j++, loop++) {
+ copy_v3_v3(bpoly->coords[j], data->targetCos[loop->v]);
+
+ /* Find corner and edge indices within poly loop array */
+ if (loop->v == nearest) {
+ bpoly->corner_ind = j;
+ bpoly->edge_vert_inds[0] = (j == 0) ? (poly->totloop - 1) : (j - 1);
+ bpoly->edge_vert_inds[1] = (j == poly->totloop - 1) ? (0) : (j + 1);
+
+ bpoly->edge_inds[0] = data->mloop[poly->loopstart + bpoly->edge_vert_inds[0]].e;
+ bpoly->edge_inds[1] = loop->e;
+ }
+ }
+
+ /* Compute poly's parametric data */
+ mid_v3_v3_array(bpoly->centroid, bpoly->coords, poly->totloop);
+ normal_poly_v3(bpoly->normal, bpoly->coords, poly->totloop);
+
+ /* Compute poly skew angle and axis */
+ angle = angle_normalized_v3v3(bpoly->normal, world);
+
+ cross_v3_v3v3(axis, bpoly->normal, world);
+ normalize_v3(axis);
+
+ /* Map coords onto 2d normal plane */
+ map_to_plane_axis_angle_v2_v3v3fl(bpoly->point_v2, point_co, axis, angle);
+
+ zero_v2(bpoly->centroid_v2);
+ for (int j = 0; j < poly->totloop; j++) {
+ map_to_plane_axis_angle_v2_v3v3fl(bpoly->coords_v2[j], bpoly->coords[j], axis, angle);
+ madd_v2_v2fl(bpoly->centroid_v2, bpoly->coords_v2[j], 1.0f / poly->totloop);
+ }
+
+ is_poly_valid = isPolyValid(bpoly->coords_v2, poly->totloop);
+
+ if (is_poly_valid != MOD_SDEF_BIND_RESULT_SUCCESS) {
+ freeBindData(bwdata);
+ data->success = is_poly_valid;
+ return NULL;
+ }
+
+ bpoly->inside = isect_point_poly_v2(
+ bpoly->point_v2, bpoly->coords_v2, poly->totloop, false);
+
+ /* Initialize weight components */
+ bpoly->weight_angular = 1.0f;
+ bpoly->weight_dist_proj = len_v2v2(bpoly->centroid_v2, bpoly->point_v2);
+ bpoly->weight_dist = len_v3v3(bpoly->centroid, point_co);
+
+ avg_point_dist += bpoly->weight_dist;
+
+ /* Compute centroid to mid-edge vectors */
+ mid_v2_v2v2(bpoly->cent_edgemid_vecs_v2[0],
+ bpoly->coords_v2[bpoly->edge_vert_inds[0]],
+ bpoly->coords_v2[bpoly->corner_ind]);
+
+ mid_v2_v2v2(bpoly->cent_edgemid_vecs_v2[1],
+ bpoly->coords_v2[bpoly->edge_vert_inds[1]],
+ bpoly->coords_v2[bpoly->corner_ind]);
+
+ sub_v2_v2(bpoly->cent_edgemid_vecs_v2[0], bpoly->centroid_v2);
+ sub_v2_v2(bpoly->cent_edgemid_vecs_v2[1], bpoly->centroid_v2);
+
+ /* Compute poly scales with respect to mid-edges, and normalize the vectors */
+ bpoly->scales[0] = normalize_v2(bpoly->cent_edgemid_vecs_v2[0]);
+ bpoly->scales[1] = normalize_v2(bpoly->cent_edgemid_vecs_v2[1]);
+
+ /* Compute the required polygon angles */
+ bpoly->edgemid_angle = angle_normalized_v2v2(bpoly->cent_edgemid_vecs_v2[0],
+ bpoly->cent_edgemid_vecs_v2[1]);
+
+ sub_v2_v2v2(tmp_vec_v2, bpoly->coords_v2[bpoly->corner_ind], bpoly->centroid_v2);
+ normalize_v2(tmp_vec_v2);
+
+ bpoly->corner_edgemid_angles[0] = angle_normalized_v2v2(tmp_vec_v2,
+ bpoly->cent_edgemid_vecs_v2[0]);
+ bpoly->corner_edgemid_angles[1] = angle_normalized_v2v2(tmp_vec_v2,
+ bpoly->cent_edgemid_vecs_v2[1]);
+
+ /* Check for inifnite weights, and compute angular data otherwise */
+ if (bpoly->weight_dist < FLT_EPSILON) {
+ inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ;
+ inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST;
+ }
+ else if (bpoly->weight_dist_proj < FLT_EPSILON) {
+ inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ;
+ }
+ else {
+ float cent_point_vec[2];
+
+ sub_v2_v2v2(cent_point_vec, bpoly->point_v2, bpoly->centroid_v2);
+ normalize_v2(cent_point_vec);
+
+ bpoly->point_edgemid_angles[0] = angle_normalized_v2v2(cent_point_vec,
+ bpoly->cent_edgemid_vecs_v2[0]);
+ bpoly->point_edgemid_angles[1] = angle_normalized_v2v2(cent_point_vec,
+ bpoly->cent_edgemid_vecs_v2[1]);
+ }
+ }
+ }
+ }
+
+ avg_point_dist /= bwdata->numpoly;
+
+ /* If weights 1 and 2 are not infinite, loop over all adjacent edges again,
+ * and build adjacency dependent angle data (depends on all polygons having been computed) */
+ if (!inf_weight_flags) {
+ for (vedge = vert_edges; vedge; vedge = vedge->next) {
+ SDefBindPoly *bpolys[2];
+ const SDefEdgePolys *epolys;
+ float ang_weights[2];
+ unsigned int edge_ind = vedge->index;
+ unsigned int edge_on_poly[2];
+
+ epolys = &edge_polys[edge_ind];
+
+ /* Find bind polys corresponding to the edge's adjacent polys */
+ bpoly = bwdata->bind_polys;
+
+ for (int i = 0, j = 0; (i < bwdata->numpoly) && (j < epolys->num); bpoly++, i++) {
+ if (ELEM(bpoly->index, epolys->polys[0], epolys->polys[1])) {
+ bpolys[j] = bpoly;
+
+ if (bpoly->edge_inds[0] == edge_ind) {
+ edge_on_poly[j] = 0;
+ }
+ else {
+ edge_on_poly[j] = 1;
+ }
+
+ j++;
+ }
+ }
+
+ /* Compute angular weight component */
+ if (epolys->num == 1) {
+ ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]],
+ bpolys[0]->edgemid_angle);
+ bpolys[0]->weight_angular *= ang_weights[0] * ang_weights[0];
+ }
+ else if (epolys->num == 2) {
+ ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]],
+ bpolys[0]->edgemid_angle);
+ ang_weights[1] = computeAngularWeight(bpolys[1]->point_edgemid_angles[edge_on_poly[1]],
+ bpolys[1]->edgemid_angle);
+
+ bpolys[0]->weight_angular *= ang_weights[0] * ang_weights[1];
+ bpolys[1]->weight_angular *= ang_weights[0] * ang_weights[1];
+ }
+ }
+ }
+
+ /* Compute scalings and falloff.
+ * Scale all weights if no infinite weight is found,
+ * scale only unprojected weight if projected weight is infinite,
+ * scale none if both are infinite. */
+ if (!inf_weight_flags) {
+ bpoly = bwdata->bind_polys;
+
+ for (int i = 0; i < bwdata->numpoly; bpoly++, i++) {
+ float corner_angle_weights[2];
+ float scale_weight, sqr, inv_sqr;
+
+ corner_angle_weights[0] = bpoly->point_edgemid_angles[0] / bpoly->corner_edgemid_angles[0];
+ corner_angle_weights[1] = bpoly->point_edgemid_angles[1] / bpoly->corner_edgemid_angles[1];
+
+ if (isnan(corner_angle_weights[0]) || isnan(corner_angle_weights[1])) {
+ freeBindData(bwdata);
+ data->success = MOD_SDEF_BIND_RESULT_GENERIC_ERR;
+ return NULL;
+ }
+
+ /* Find which edge the point is closer to */
+ if (corner_angle_weights[0] < corner_angle_weights[1]) {
+ bpoly->dominant_edge = 0;
+ bpoly->dominant_angle_weight = corner_angle_weights[0];
+ }
+ else {
+ bpoly->dominant_edge = 1;
+ bpoly->dominant_angle_weight = corner_angle_weights[1];
+ }
+
+ bpoly->dominant_angle_weight = sinf(bpoly->dominant_angle_weight * M_PI_2);
+
+ /* Compute quadratic angular scale interpolation weight */
+ scale_weight = bpoly->point_edgemid_angles[bpoly->dominant_edge] / bpoly->edgemid_angle;
+ scale_weight /= scale_weight +
+ (bpoly->point_edgemid_angles[!bpoly->dominant_edge] / bpoly->edgemid_angle);
+
+ sqr = scale_weight * scale_weight;
+ inv_sqr = 1.0f - scale_weight;
+ inv_sqr *= inv_sqr;
+ scale_weight = sqr / (sqr + inv_sqr);
+
+ /* Compute interpolated scale (no longer need the individual scales,
+ * so simply storing the result over the scale in index zero) */
+ bpoly->scales[0] = bpoly->scales[bpoly->dominant_edge] * (1.0f - scale_weight) +
+ bpoly->scales[!bpoly->dominant_edge] * scale_weight;
+
+ /* Scale the point distance weights, and introduce falloff */
+ bpoly->weight_dist_proj /= bpoly->scales[0];
+ bpoly->weight_dist_proj = powf(bpoly->weight_dist_proj, data->falloff);
+
+ bpoly->weight_dist /= avg_point_dist;
+ bpoly->weight_dist = powf(bpoly->weight_dist, data->falloff);
+
+ /* Re-check for infinite weights, now that all scalings and interpolations are computed */
+ if (bpoly->weight_dist < FLT_EPSILON) {
+ inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ;
+ inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST;
+ }
+ else if (bpoly->weight_dist_proj < FLT_EPSILON) {
+ inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ;
+ }
+ else if (bpoly->weight_angular < FLT_EPSILON) {
+ inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_ANGULAR;
+ }
+ }
+ }
+ else if (!(inf_weight_flags & MOD_SDEF_INFINITE_WEIGHT_DIST)) {
+ bpoly = bwdata->bind_polys;
+
+ for (int i = 0; i < bwdata->numpoly; bpoly++, i++) {
+ /* Scale the point distance weight by average point distance, and introduce falloff */
+ bpoly->weight_dist /= avg_point_dist;
+ bpoly->weight_dist = powf(bpoly->weight_dist, data->falloff);
+
+ /* Re-check for infinite weights, now that all scalings and interpolations are computed */
+ if (bpoly->weight_dist < FLT_EPSILON) {
+ inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST;
+ }
+ }
+ }
+
+ /* Final loop, to compute actual weights */
+ bpoly = bwdata->bind_polys;
+
+ for (int i = 0; i < bwdata->numpoly; bpoly++, i++) {
+ /* Weight computation from components */
+ if (inf_weight_flags & MOD_SDEF_INFINITE_WEIGHT_DIST) {
+ bpoly->weight = bpoly->weight_dist < FLT_EPSILON ? 1.0f : 0.0f;
+ }
+ else if (inf_weight_flags & MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ) {
+ bpoly->weight = bpoly->weight_dist_proj < FLT_EPSILON ? 1.0f / bpoly->weight_dist : 0.0f;
+ }
+ else if (inf_weight_flags & MOD_SDEF_INFINITE_WEIGHT_ANGULAR) {
+ bpoly->weight = bpoly->weight_angular < FLT_EPSILON ?
+ 1.0f / bpoly->weight_dist_proj / bpoly->weight_dist :
+ 0.0f;
+ }
+ else {
+ bpoly->weight = 1.0f / bpoly->weight_angular / bpoly->weight_dist_proj / bpoly->weight_dist;
+ }
+
+ tot_weight += bpoly->weight;
+ }
+
+ bpoly = bwdata->bind_polys;
+
+ for (int i = 0; i < bwdata->numpoly; bpoly++, i++) {
+ bpoly->weight /= tot_weight;
+
+ /* Evaluate if this poly is relevant to bind */
+ /* Even though the weights should add up to 1.0,
+ * the losses of weights smaller than epsilon here
+ * should be negligible... */
+ if (bpoly->weight >= FLT_EPSILON) {
+ if (bpoly->inside) {
+ bwdata->numbinds += 1;
+ }
+ else {
+ if (bpoly->dominant_angle_weight < FLT_EPSILON ||
+ 1.0f - bpoly->dominant_angle_weight < FLT_EPSILON) {
+ bwdata->numbinds += 1;
+ }
+ else {
+ bwdata->numbinds += 2;
+ }
+ }
+ }
+ }
+
+ return bwdata;
}
-BLI_INLINE float computeNormalDisplacement(const float point_co[3], const float point_co_proj[3], const float normal[3])
+BLI_INLINE float computeNormalDisplacement(const float point_co[3],
+ const float point_co_proj[3],
+ const float normal[3])
{
- float disp_vec[3];
- float normal_dist;
+ float disp_vec[3];
+ float normal_dist;
- sub_v3_v3v3(disp_vec, point_co, point_co_proj);
- normal_dist = len_v3(disp_vec);
+ sub_v3_v3v3(disp_vec, point_co, point_co_proj);
+ normal_dist = len_v3(disp_vec);
- if (dot_v3v3(disp_vec, normal) < 0) {
- normal_dist *= -1;
- }
+ if (dot_v3v3(disp_vec, normal) < 0) {
+ normal_dist *= -1;
+ }
- return normal_dist;
+ return normal_dist;
}
-static void bindVert(
- void *__restrict userdata,
- const int index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+static void bindVert(void *__restrict userdata,
+ const int index,
+ const ParallelRangeTLS *__restrict UNUSED(tls))
{
- SDefBindCalcData * const data = (SDefBindCalcData *)userdata;
- float point_co[3];
- float point_co_proj[3];
-
- SDefBindWeightData *bwdata;
- SDefVert *sdvert = data->bind_verts + index;
- SDefBindPoly *bpoly;
- SDefBind *sdbind;
-
- if (data->success != MOD_SDEF_BIND_RESULT_SUCCESS) {
- sdvert->binds = NULL;
- sdvert->numbinds = 0;
- return;
- }
-
- copy_v3_v3(point_co, data->vertexCos[index]);
- bwdata = computeBindWeights(data, point_co);
-
- if (bwdata == NULL) {
- sdvert->binds = NULL;
- sdvert->numbinds = 0;
- return;
- }
-
- sdvert->binds = MEM_calloc_arrayN(bwdata->numbinds, sizeof(*sdvert->binds), "SDefVertBindData");
- if (sdvert->binds == NULL) {
- data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
- sdvert->numbinds = 0;
- return;
- }
-
- sdvert->numbinds = bwdata->numbinds;
-
- sdbind = sdvert->binds;
-
- bpoly = bwdata->bind_polys;
-
- for (int i = 0; i < bwdata->numbinds; bpoly++) {
- if (bpoly->weight >= FLT_EPSILON) {
- if (bpoly->inside) {
- const MLoop *loop = &data->mloop[bpoly->loopstart];
-
- sdbind->influence = bpoly->weight;
- sdbind->numverts = bpoly->numverts;
-
- sdbind->mode = MOD_SDEF_MODE_NGON;
- sdbind->vert_weights = MEM_malloc_arrayN(bpoly->numverts, sizeof(*sdbind->vert_weights), "SDefNgonVertWeights");
- if (sdbind->vert_weights == NULL) {
- data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
- return;
- }
-
- sdbind->vert_inds = MEM_malloc_arrayN(bpoly->numverts, sizeof(*sdbind->vert_inds), "SDefNgonVertInds");
- if (sdbind->vert_inds == NULL) {
- data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
- return;
- }
-
- interp_weights_poly_v2(sdbind->vert_weights, bpoly->coords_v2, bpoly->numverts, bpoly->point_v2);
-
- /* Reproject vert based on weights and original poly verts, to reintroduce poly non-planarity */
- zero_v3(point_co_proj);
- for (int j = 0; j < bpoly->numverts; j++, loop++) {
- madd_v3_v3fl(point_co_proj, bpoly->coords[j], sdbind->vert_weights[j]);
- sdbind->vert_inds[j] = loop->v;
- }
-
- sdbind->normal_dist = computeNormalDisplacement(point_co, point_co_proj, bpoly->normal);
-
- sdbind++;
- i++;
- }
- else {
- float tmp_vec[3];
- float cent[3], norm[3];
- float v1[3], v2[3], v3[3];
-
- if (1.0f - bpoly->dominant_angle_weight >= FLT_EPSILON) {
- sdbind->influence = bpoly->weight * (1.0f - bpoly->dominant_angle_weight);
- sdbind->numverts = bpoly->numverts;
-
- sdbind->mode = MOD_SDEF_MODE_CENTROID;
- sdbind->vert_weights = MEM_malloc_arrayN(3, sizeof(*sdbind->vert_weights), "SDefCentVertWeights");
- if (sdbind->vert_weights == NULL) {
- data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
- return;
- }
-
- sdbind->vert_inds = MEM_malloc_arrayN(bpoly->numverts, sizeof(*sdbind->vert_inds), "SDefCentVertInds");
- if (sdbind->vert_inds == NULL) {
- data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
- return;
- }
-
- sortPolyVertsEdge(sdbind->vert_inds, &data->mloop[bpoly->loopstart],
- bpoly->edge_inds[bpoly->dominant_edge], bpoly->numverts);
-
- copy_v3_v3(v1, data->targetCos[sdbind->vert_inds[0]]);
- copy_v3_v3(v2, data->targetCos[sdbind->vert_inds[1]]);
- copy_v3_v3(v3, bpoly->centroid);
-
- mid_v3_v3v3v3(cent, v1, v2, v3);
- normal_tri_v3(norm, v1, v2, v3);
-
- add_v3_v3v3(tmp_vec, point_co, bpoly->normal);
-
- /* We are sure the line is not parallel to the plane.
- * Checking return value just to avoid warning... */
- if (!isect_line_plane_v3(point_co_proj, point_co, tmp_vec, cent, norm)) {
- BLI_assert(false);
- }
-
- interp_weights_tri_v3(sdbind->vert_weights, v1, v2, v3, point_co_proj);
-
- sdbind->normal_dist = computeNormalDisplacement(point_co, point_co_proj, bpoly->normal);
-
- sdbind++;
- i++;
- }
-
- if (bpoly->dominant_angle_weight >= FLT_EPSILON) {
- sdbind->influence = bpoly->weight * bpoly->dominant_angle_weight;
- sdbind->numverts = bpoly->numverts;
-
- sdbind->mode = MOD_SDEF_MODE_LOOPTRI;
- sdbind->vert_weights = MEM_malloc_arrayN(3, sizeof(*sdbind->vert_weights), "SDefTriVertWeights");
- if (sdbind->vert_weights == NULL) {
- data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
- return;
- }
-
- sdbind->vert_inds = MEM_malloc_arrayN(bpoly->numverts, sizeof(*sdbind->vert_inds), "SDefTriVertInds");
- if (sdbind->vert_inds == NULL) {
- data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
- return;
- }
-
- sortPolyVertsTri(sdbind->vert_inds, &data->mloop[bpoly->loopstart], bpoly->edge_vert_inds[0], bpoly->numverts);
-
- copy_v3_v3(v1, data->targetCos[sdbind->vert_inds[0]]);
- copy_v3_v3(v2, data->targetCos[sdbind->vert_inds[1]]);
- copy_v3_v3(v3, data->targetCos[sdbind->vert_inds[2]]);
-
- mid_v3_v3v3v3(cent, v1, v2, v3);
- normal_tri_v3(norm, v1, v2, v3);
-
- add_v3_v3v3(tmp_vec, point_co, bpoly->normal);
-
- /* We are sure the line is not parallel to the plane.
- * Checking return value just to avoid warning... */
- if (!isect_line_plane_v3(point_co_proj, point_co, tmp_vec, cent, norm)) {
- BLI_assert(false);
- }
-
- interp_weights_tri_v3(sdbind->vert_weights, v1, v2, v3, point_co_proj);
-
- sdbind->normal_dist = computeNormalDisplacement(point_co, point_co_proj, bpoly->normal);
-
- sdbind++;
- i++;
- }
- }
- }
- }
-
- freeBindData(bwdata);
+ SDefBindCalcData *const data = (SDefBindCalcData *)userdata;
+ float point_co[3];
+ float point_co_proj[3];
+
+ SDefBindWeightData *bwdata;
+ SDefVert *sdvert = data->bind_verts + index;
+ SDefBindPoly *bpoly;
+ SDefBind *sdbind;
+
+ if (data->success != MOD_SDEF_BIND_RESULT_SUCCESS) {
+ sdvert->binds = NULL;
+ sdvert->numbinds = 0;
+ return;
+ }
+
+ copy_v3_v3(point_co, data->vertexCos[index]);
+ bwdata = computeBindWeights(data, point_co);
+
+ if (bwdata == NULL) {
+ sdvert->binds = NULL;
+ sdvert->numbinds = 0;
+ return;
+ }
+
+ sdvert->binds = MEM_calloc_arrayN(bwdata->numbinds, sizeof(*sdvert->binds), "SDefVertBindData");
+ if (sdvert->binds == NULL) {
+ data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
+ sdvert->numbinds = 0;
+ return;
+ }
+
+ sdvert->numbinds = bwdata->numbinds;
+
+ sdbind = sdvert->binds;
+
+ bpoly = bwdata->bind_polys;
+
+ for (int i = 0; i < bwdata->numbinds; bpoly++) {
+ if (bpoly->weight >= FLT_EPSILON) {
+ if (bpoly->inside) {
+ const MLoop *loop = &data->mloop[bpoly->loopstart];
+
+ sdbind->influence = bpoly->weight;
+ sdbind->numverts = bpoly->numverts;
+
+ sdbind->mode = MOD_SDEF_MODE_NGON;
+ sdbind->vert_weights = MEM_malloc_arrayN(
+ bpoly->numverts, sizeof(*sdbind->vert_weights), "SDefNgonVertWeights");
+ if (sdbind->vert_weights == NULL) {
+ data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
+ return;
+ }
+
+ sdbind->vert_inds = MEM_malloc_arrayN(
+ bpoly->numverts, sizeof(*sdbind->vert_inds), "SDefNgonVertInds");
+ if (sdbind->vert_inds == NULL) {
+ data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
+ return;
+ }
+
+ interp_weights_poly_v2(
+ sdbind->vert_weights, bpoly->coords_v2, bpoly->numverts, bpoly->point_v2);
+
+ /* Reproject vert based on weights and original poly verts, to reintroduce poly non-planarity */
+ zero_v3(point_co_proj);
+ for (int j = 0; j < bpoly->numverts; j++, loop++) {
+ madd_v3_v3fl(point_co_proj, bpoly->coords[j], sdbind->vert_weights[j]);
+ sdbind->vert_inds[j] = loop->v;
+ }
+
+ sdbind->normal_dist = computeNormalDisplacement(point_co, point_co_proj, bpoly->normal);
+
+ sdbind++;
+ i++;
+ }
+ else {
+ float tmp_vec[3];
+ float cent[3], norm[3];
+ float v1[3], v2[3], v3[3];
+
+ if (1.0f - bpoly->dominant_angle_weight >= FLT_EPSILON) {
+ sdbind->influence = bpoly->weight * (1.0f - bpoly->dominant_angle_weight);
+ sdbind->numverts = bpoly->numverts;
+
+ sdbind->mode = MOD_SDEF_MODE_CENTROID;
+ sdbind->vert_weights = MEM_malloc_arrayN(
+ 3, sizeof(*sdbind->vert_weights), "SDefCentVertWeights");
+ if (sdbind->vert_weights == NULL) {
+ data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
+ return;
+ }
+
+ sdbind->vert_inds = MEM_malloc_arrayN(
+ bpoly->numverts, sizeof(*sdbind->vert_inds), "SDefCentVertInds");
+ if (sdbind->vert_inds == NULL) {
+ data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
+ return;
+ }
+
+ sortPolyVertsEdge(sdbind->vert_inds,
+ &data->mloop[bpoly->loopstart],
+ bpoly->edge_inds[bpoly->dominant_edge],
+ bpoly->numverts);
+
+ copy_v3_v3(v1, data->targetCos[sdbind->vert_inds[0]]);
+ copy_v3_v3(v2, data->targetCos[sdbind->vert_inds[1]]);
+ copy_v3_v3(v3, bpoly->centroid);
+
+ mid_v3_v3v3v3(cent, v1, v2, v3);
+ normal_tri_v3(norm, v1, v2, v3);
+
+ add_v3_v3v3(tmp_vec, point_co, bpoly->normal);
+
+ /* We are sure the line is not parallel to the plane.
+ * Checking return value just to avoid warning... */
+ if (!isect_line_plane_v3(point_co_proj, point_co, tmp_vec, cent, norm)) {
+ BLI_assert(false);
+ }
+
+ interp_weights_tri_v3(sdbind->vert_weights, v1, v2, v3, point_co_proj);
+
+ sdbind->normal_dist = computeNormalDisplacement(point_co, point_co_proj, bpoly->normal);
+
+ sdbind++;
+ i++;
+ }
+
+ if (bpoly->dominant_angle_weight >= FLT_EPSILON) {
+ sdbind->influence = bpoly->weight * bpoly->dominant_angle_weight;
+ sdbind->numverts = bpoly->numverts;
+
+ sdbind->mode = MOD_SDEF_MODE_LOOPTRI;
+ sdbind->vert_weights = MEM_malloc_arrayN(
+ 3, sizeof(*sdbind->vert_weights), "SDefTriVertWeights");
+ if (sdbind->vert_weights == NULL) {
+ data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
+ return;
+ }
+
+ sdbind->vert_inds = MEM_malloc_arrayN(
+ bpoly->numverts, sizeof(*sdbind->vert_inds), "SDefTriVertInds");
+ if (sdbind->vert_inds == NULL) {
+ data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
+ return;
+ }
+
+ sortPolyVertsTri(sdbind->vert_inds,
+ &data->mloop[bpoly->loopstart],
+ bpoly->edge_vert_inds[0],
+ bpoly->numverts);
+
+ copy_v3_v3(v1, data->targetCos[sdbind->vert_inds[0]]);
+ copy_v3_v3(v2, data->targetCos[sdbind->vert_inds[1]]);
+ copy_v3_v3(v3, data->targetCos[sdbind->vert_inds[2]]);
+
+ mid_v3_v3v3v3(cent, v1, v2, v3);
+ normal_tri_v3(norm, v1, v2, v3);
+
+ add_v3_v3v3(tmp_vec, point_co, bpoly->normal);
+
+ /* We are sure the line is not parallel to the plane.
+ * Checking return value just to avoid warning... */
+ if (!isect_line_plane_v3(point_co_proj, point_co, tmp_vec, cent, norm)) {
+ BLI_assert(false);
+ }
+
+ interp_weights_tri_v3(sdbind->vert_weights, v1, v2, v3, point_co_proj);
+
+ sdbind->normal_dist = computeNormalDisplacement(point_co, point_co_proj, bpoly->normal);
+
+ sdbind++;
+ i++;
+ }
+ }
+ }
+ }
+
+ freeBindData(bwdata);
}
-static bool surfacedeformBind(
- SurfaceDeformModifierData *smd, float (*vertexCos)[3],
- unsigned int numverts, unsigned int tnumpoly, unsigned int tnumverts, Mesh *target)
+static bool surfacedeformBind(SurfaceDeformModifierData *smd,
+ float (*vertexCos)[3],
+ unsigned int numverts,
+ unsigned int tnumpoly,
+ unsigned int tnumverts,
+ Mesh *target)
{
- BVHTreeFromMesh treeData = {NULL};
- const MVert *mvert = target->mvert;
- const MPoly *mpoly = target->mpoly;
- const MEdge *medge = target->medge;
- const MLoop *mloop = target->mloop;
- unsigned int tnumedges = target->totedge;
- int adj_result;
- SDefAdjacencyArray *vert_edges;
- SDefAdjacency *adj_array;
- SDefEdgePolys *edge_polys;
-
- vert_edges = MEM_calloc_arrayN(tnumverts, sizeof(*vert_edges), "SDefVertEdgeMap");
- if (vert_edges == NULL) {
- modifier_setError((ModifierData *)smd, "Out of memory");
- return false;
- }
-
- adj_array = MEM_malloc_arrayN(tnumedges, 2 * sizeof(*adj_array), "SDefVertEdge");
- if (adj_array == NULL) {
- modifier_setError((ModifierData *)smd, "Out of memory");
- MEM_freeN(vert_edges);
- return false;
- }
-
- edge_polys = MEM_calloc_arrayN(tnumedges, sizeof(*edge_polys), "SDefEdgeFaceMap");
- if (edge_polys == NULL) {
- modifier_setError((ModifierData *)smd, "Out of memory");
- MEM_freeN(vert_edges);
- MEM_freeN(adj_array);
- return false;
- }
-
- smd->verts = MEM_malloc_arrayN(numverts, sizeof(*smd->verts), "SDefBindVerts");
- if (smd->verts == NULL) {
- modifier_setError((ModifierData *)smd, "Out of memory");
- freeAdjacencyMap(vert_edges, adj_array, edge_polys);
- return false;
- }
-
- BKE_bvhtree_from_mesh_get(&treeData, target, BVHTREE_FROM_LOOPTRI, 2);
- if (treeData.tree == NULL) {
- modifier_setError((ModifierData *)smd, "Out of memory");
- freeAdjacencyMap(vert_edges, adj_array, edge_polys);
- MEM_freeN(smd->verts);
- smd->verts = NULL;
- return false;
- }
-
- adj_result = buildAdjacencyMap(mpoly, medge, mloop, tnumpoly, tnumedges, vert_edges, adj_array, edge_polys);
-
- if (adj_result == MOD_SDEF_BIND_RESULT_NONMANY_ERR) {
- modifier_setError((ModifierData *)smd, "Target has edges with more than two polygons");
- freeAdjacencyMap(vert_edges, adj_array, edge_polys);
- free_bvhtree_from_mesh(&treeData);
- MEM_freeN(smd->verts);
- smd->verts = NULL;
- return false;
- }
-
- smd->numverts = numverts;
- smd->numpoly = tnumpoly;
-
- SDefBindCalcData data = {
- .treeData = &treeData,
- .vert_edges = vert_edges,
- .edge_polys = edge_polys,
- .mpoly = mpoly,
- .medge = medge,
- .mloop = mloop,
- .looptri = BKE_mesh_runtime_looptri_ensure(target),
- .targetCos = MEM_malloc_arrayN(tnumverts, sizeof(float[3]), "SDefTargetBindVertArray"),
- .bind_verts = smd->verts,
- .vertexCos = vertexCos,
- .falloff = smd->falloff,
- .success = MOD_SDEF_BIND_RESULT_SUCCESS,
- };
-
- if (data.targetCos == NULL) {
- modifier_setError((ModifierData *)smd, "Out of memory");
- freeData((ModifierData *)smd);
- return false;
- }
-
- invert_m4_m4(data.imat, smd->mat);
-
- for (int i = 0; i < tnumverts; i++) {
- mul_v3_m4v3(data.targetCos[i], smd->mat, mvert[i].co);
- }
-
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.use_threading = (numverts > 10000);
- BLI_task_parallel_range(0, numverts,
- &data,
- bindVert,
- &settings);
-
- MEM_freeN(data.targetCos);
-
- if (data.success == MOD_SDEF_BIND_RESULT_MEM_ERR) {
- modifier_setError((ModifierData *)smd, "Out of memory");
- freeData((ModifierData *)smd);
- }
- else if (data.success == MOD_SDEF_BIND_RESULT_NONMANY_ERR) {
- modifier_setError((ModifierData *)smd, "Target has edges with more than two polygons");
- freeData((ModifierData *)smd);
- }
- else if (data.success == MOD_SDEF_BIND_RESULT_CONCAVE_ERR) {
- modifier_setError((ModifierData *)smd, "Target contains concave polygons");
- freeData((ModifierData *)smd);
- }
- else if (data.success == MOD_SDEF_BIND_RESULT_OVERLAP_ERR) {
- modifier_setError((ModifierData *)smd, "Target contains overlapping verts");
- freeData((ModifierData *)smd);
- }
- else if (data.success == MOD_SDEF_BIND_RESULT_GENERIC_ERR) {
- /* I know this message is vague, but I could not think of a way
- * to explain this with a reasonably sized message.
- * Though it shouldn't really matter all that much,
- * because this is very unlikely to occur */
- modifier_setError((ModifierData *)smd, "Target contains invalid polygons");
- freeData((ModifierData *)smd);
- }
-
- freeAdjacencyMap(vert_edges, adj_array, edge_polys);
- free_bvhtree_from_mesh(&treeData);
-
- return data.success == 1;
+ BVHTreeFromMesh treeData = {NULL};
+ const MVert *mvert = target->mvert;
+ const MPoly *mpoly = target->mpoly;
+ const MEdge *medge = target->medge;
+ const MLoop *mloop = target->mloop;
+ unsigned int tnumedges = target->totedge;
+ int adj_result;
+ SDefAdjacencyArray *vert_edges;
+ SDefAdjacency *adj_array;
+ SDefEdgePolys *edge_polys;
+
+ vert_edges = MEM_calloc_arrayN(tnumverts, sizeof(*vert_edges), "SDefVertEdgeMap");
+ if (vert_edges == NULL) {
+ modifier_setError((ModifierData *)smd, "Out of memory");
+ return false;
+ }
+
+ adj_array = MEM_malloc_arrayN(tnumedges, 2 * sizeof(*adj_array), "SDefVertEdge");
+ if (adj_array == NULL) {
+ modifier_setError((ModifierData *)smd, "Out of memory");
+ MEM_freeN(vert_edges);
+ return false;
+ }
+
+ edge_polys = MEM_calloc_arrayN(tnumedges, sizeof(*edge_polys), "SDefEdgeFaceMap");
+ if (edge_polys == NULL) {
+ modifier_setError((ModifierData *)smd, "Out of memory");
+ MEM_freeN(vert_edges);
+ MEM_freeN(adj_array);
+ return false;
+ }
+
+ smd->verts = MEM_malloc_arrayN(numverts, sizeof(*smd->verts), "SDefBindVerts");
+ if (smd->verts == NULL) {
+ modifier_setError((ModifierData *)smd, "Out of memory");
+ freeAdjacencyMap(vert_edges, adj_array, edge_polys);
+ return false;
+ }
+
+ BKE_bvhtree_from_mesh_get(&treeData, target, BVHTREE_FROM_LOOPTRI, 2);
+ if (treeData.tree == NULL) {
+ modifier_setError((ModifierData *)smd, "Out of memory");
+ freeAdjacencyMap(vert_edges, adj_array, edge_polys);
+ MEM_freeN(smd->verts);
+ smd->verts = NULL;
+ return false;
+ }
+
+ adj_result = buildAdjacencyMap(
+ mpoly, medge, mloop, tnumpoly, tnumedges, vert_edges, adj_array, edge_polys);
+
+ if (adj_result == MOD_SDEF_BIND_RESULT_NONMANY_ERR) {
+ modifier_setError((ModifierData *)smd, "Target has edges with more than two polygons");
+ freeAdjacencyMap(vert_edges, adj_array, edge_polys);
+ free_bvhtree_from_mesh(&treeData);
+ MEM_freeN(smd->verts);
+ smd->verts = NULL;
+ return false;
+ }
+
+ smd->numverts = numverts;
+ smd->numpoly = tnumpoly;
+
+ SDefBindCalcData data = {
+ .treeData = &treeData,
+ .vert_edges = vert_edges,
+ .edge_polys = edge_polys,
+ .mpoly = mpoly,
+ .medge = medge,
+ .mloop = mloop,
+ .looptri = BKE_mesh_runtime_looptri_ensure(target),
+ .targetCos = MEM_malloc_arrayN(tnumverts, sizeof(float[3]), "SDefTargetBindVertArray"),
+ .bind_verts = smd->verts,
+ .vertexCos = vertexCos,
+ .falloff = smd->falloff,
+ .success = MOD_SDEF_BIND_RESULT_SUCCESS,
+ };
+
+ if (data.targetCos == NULL) {
+ modifier_setError((ModifierData *)smd, "Out of memory");
+ freeData((ModifierData *)smd);
+ return false;
+ }
+
+ invert_m4_m4(data.imat, smd->mat);
+
+ for (int i = 0; i < tnumverts; i++) {
+ mul_v3_m4v3(data.targetCos[i], smd->mat, mvert[i].co);
+ }
+
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.use_threading = (numverts > 10000);
+ BLI_task_parallel_range(0, numverts, &data, bindVert, &settings);
+
+ MEM_freeN(data.targetCos);
+
+ if (data.success == MOD_SDEF_BIND_RESULT_MEM_ERR) {
+ modifier_setError((ModifierData *)smd, "Out of memory");
+ freeData((ModifierData *)smd);
+ }
+ else if (data.success == MOD_SDEF_BIND_RESULT_NONMANY_ERR) {
+ modifier_setError((ModifierData *)smd, "Target has edges with more than two polygons");
+ freeData((ModifierData *)smd);
+ }
+ else if (data.success == MOD_SDEF_BIND_RESULT_CONCAVE_ERR) {
+ modifier_setError((ModifierData *)smd, "Target contains concave polygons");
+ freeData((ModifierData *)smd);
+ }
+ else if (data.success == MOD_SDEF_BIND_RESULT_OVERLAP_ERR) {
+ modifier_setError((ModifierData *)smd, "Target contains overlapping verts");
+ freeData((ModifierData *)smd);
+ }
+ else if (data.success == MOD_SDEF_BIND_RESULT_GENERIC_ERR) {
+ /* I know this message is vague, but I could not think of a way
+ * to explain this with a reasonably sized message.
+ * Though it shouldn't really matter all that much,
+ * because this is very unlikely to occur */
+ modifier_setError((ModifierData *)smd, "Target contains invalid polygons");
+ freeData((ModifierData *)smd);
+ }
+
+ freeAdjacencyMap(vert_edges, adj_array, edge_polys);
+ free_bvhtree_from_mesh(&treeData);
+
+ return data.success == 1;
}
-static void deformVert(
- void *__restrict userdata,
- const int index,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+static void deformVert(void *__restrict userdata,
+ const int index,
+ const ParallelRangeTLS *__restrict UNUSED(tls))
{
- const SDefDeformData * const data = (SDefDeformData *)userdata;
- const SDefBind *sdbind = data->bind_verts[index].binds;
- float * const vertexCos = data->vertexCos[index];
- float norm[3], temp[3];
-
- zero_v3(vertexCos);
-
- for (int j = 0; j < data->bind_verts[index].numbinds; j++, sdbind++) {
- /* Mode-generic operations (allocate poly coordinates) */
- float (*coords)[3] = MEM_malloc_arrayN(sdbind->numverts, sizeof(*coords), "SDefDoPolyCoords");
-
- for (int k = 0; k < sdbind->numverts; k++) {
- copy_v3_v3(coords[k], data->targetCos[sdbind->vert_inds[k]]);
- }
-
- normal_poly_v3(norm, coords, sdbind->numverts);
- zero_v3(temp);
-
- /* ---------- looptri mode ---------- */
- if (sdbind->mode == MOD_SDEF_MODE_LOOPTRI) {
- madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[0]], sdbind->vert_weights[0]);
- madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[1]], sdbind->vert_weights[1]);
- madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[2]], sdbind->vert_weights[2]);
- }
- else {
- /* ---------- ngon mode ---------- */
- if (sdbind->mode == MOD_SDEF_MODE_NGON) {
- for (int k = 0; k < sdbind->numverts; k++) {
- madd_v3_v3fl(temp, coords[k], sdbind->vert_weights[k]);
- }
- }
-
- /* ---------- centroid mode ---------- */
- else if (sdbind->mode == MOD_SDEF_MODE_CENTROID) {
- float cent[3];
- mid_v3_v3_array(cent, coords, sdbind->numverts);
-
- madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[0]], sdbind->vert_weights[0]);
- madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[1]], sdbind->vert_weights[1]);
- madd_v3_v3fl(temp, cent, sdbind->vert_weights[2]);
- }
- }
-
- MEM_freeN(coords);
-
- /* Apply normal offset (generic for all modes) */
- madd_v3_v3fl(temp, norm, sdbind->normal_dist);
-
- madd_v3_v3fl(vertexCos, temp, sdbind->influence);
- }
+ const SDefDeformData *const data = (SDefDeformData *)userdata;
+ const SDefBind *sdbind = data->bind_verts[index].binds;
+ float *const vertexCos = data->vertexCos[index];
+ float norm[3], temp[3];
+
+ zero_v3(vertexCos);
+
+ for (int j = 0; j < data->bind_verts[index].numbinds; j++, sdbind++) {
+ /* Mode-generic operations (allocate poly coordinates) */
+ float(*coords)[3] = MEM_malloc_arrayN(sdbind->numverts, sizeof(*coords), "SDefDoPolyCoords");
+
+ for (int k = 0; k < sdbind->numverts; k++) {
+ copy_v3_v3(coords[k], data->targetCos[sdbind->vert_inds[k]]);
+ }
+
+ normal_poly_v3(norm, coords, sdbind->numverts);
+ zero_v3(temp);
+
+ /* ---------- looptri mode ---------- */
+ if (sdbind->mode == MOD_SDEF_MODE_LOOPTRI) {
+ madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[0]], sdbind->vert_weights[0]);
+ madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[1]], sdbind->vert_weights[1]);
+ madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[2]], sdbind->vert_weights[2]);
+ }
+ else {
+ /* ---------- ngon mode ---------- */
+ if (sdbind->mode == MOD_SDEF_MODE_NGON) {
+ for (int k = 0; k < sdbind->numverts; k++) {
+ madd_v3_v3fl(temp, coords[k], sdbind->vert_weights[k]);
+ }
+ }
+
+ /* ---------- centroid mode ---------- */
+ else if (sdbind->mode == MOD_SDEF_MODE_CENTROID) {
+ float cent[3];
+ mid_v3_v3_array(cent, coords, sdbind->numverts);
+
+ madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[0]], sdbind->vert_weights[0]);
+ madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[1]], sdbind->vert_weights[1]);
+ madd_v3_v3fl(temp, cent, sdbind->vert_weights[2]);
+ }
+ }
+
+ MEM_freeN(coords);
+
+ /* Apply normal offset (generic for all modes) */
+ madd_v3_v3fl(temp, norm, sdbind->normal_dist);
+
+ madd_v3_v3fl(vertexCos, temp, sdbind->influence);
+ }
}
-static void surfacedeformModifier_do(
- ModifierData *md,
- const ModifierEvalContext *ctx,
- float (*vertexCos)[3], unsigned int numverts, Object *ob)
+static void surfacedeformModifier_do(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ float (*vertexCos)[3],
+ unsigned int numverts,
+ Object *ob)
{
- SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
- Mesh *target;
- unsigned int tnumverts, tnumpoly;
-
- /* Exit function if bind flag is not set (free bind data if any). */
- if (!(smd->flags & MOD_SDEF_BIND)) {
- if (smd->verts != NULL) {
- if (!DEG_is_active(ctx->depsgraph)) {
- modifier_setError(md, "Attempt to bind from inactive dependency graph");
- return;
- }
- ModifierData *md_orig = modifier_get_original(md);
- freeData(md_orig);
- }
- return;
- }
-
- Object *ob_target = smd->target;
- target = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob_target, false);
- if (!target) {
- modifier_setError(md, "No valid target mesh");
- return;
- }
-
- tnumverts = target->totvert;
- tnumpoly = target->totpoly;
-
- /* If not bound, execute bind. */
- if (smd->verts == NULL) {
- if (!DEG_is_active(ctx->depsgraph)) {
- modifier_setError(md, "Attempt to unbind from inactive dependency graph");
- return;
- }
-
- SurfaceDeformModifierData *smd_orig = (SurfaceDeformModifierData *)modifier_get_original(md);
- float tmp_mat[4][4];
-
- invert_m4_m4(tmp_mat, ob->obmat);
- mul_m4_m4m4(smd_orig->mat, tmp_mat, ob_target->obmat);
-
- if (!surfacedeformBind(smd_orig, vertexCos, numverts, tnumpoly, tnumverts, target)) {
- smd->flags &= ~MOD_SDEF_BIND;
- }
- /* Early abort, this is binding 'call', no need to perform whole evaluation. */
- return;
- }
-
- /* Poly count checks */
- if (smd->numverts != numverts) {
- modifier_setError(md, "Verts changed from %u to %u", smd->numverts, numverts);
- return;
- }
- else if (smd->numpoly != tnumpoly) {
- modifier_setError(md, "Target polygons changed from %u to %u", smd->numpoly, tnumpoly);
- return;
- }
-
- /* Actual vertex location update starts here */
- SDefDeformData data = {
- .bind_verts = smd->verts,
- .targetCos = MEM_malloc_arrayN(tnumverts, sizeof(float[3]), "SDefTargetVertArray"),
- .vertexCos = vertexCos,
- };
-
- if (data.targetCos != NULL) {
- const MVert * const mvert = target->mvert;
-
- for (int i = 0; i < tnumverts; i++) {
- mul_v3_m4v3(data.targetCos[i], smd->mat, mvert[i].co);
- }
-
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.use_threading = (numverts > 10000);
- BLI_task_parallel_range(0, numverts,
- &data,
- deformVert,
- &settings);
-
- MEM_freeN(data.targetCos);
- }
+ SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
+ Mesh *target;
+ unsigned int tnumverts, tnumpoly;
+
+ /* Exit function if bind flag is not set (free bind data if any). */
+ if (!(smd->flags & MOD_SDEF_BIND)) {
+ if (smd->verts != NULL) {
+ if (!DEG_is_active(ctx->depsgraph)) {
+ modifier_setError(md, "Attempt to bind from inactive dependency graph");
+ return;
+ }
+ ModifierData *md_orig = modifier_get_original(md);
+ freeData(md_orig);
+ }
+ return;
+ }
+
+ Object *ob_target = smd->target;
+ target = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob_target, false);
+ if (!target) {
+ modifier_setError(md, "No valid target mesh");
+ return;
+ }
+
+ tnumverts = target->totvert;
+ tnumpoly = target->totpoly;
+
+ /* If not bound, execute bind. */
+ if (smd->verts == NULL) {
+ if (!DEG_is_active(ctx->depsgraph)) {
+ modifier_setError(md, "Attempt to unbind from inactive dependency graph");
+ return;
+ }
+
+ SurfaceDeformModifierData *smd_orig = (SurfaceDeformModifierData *)modifier_get_original(md);
+ float tmp_mat[4][4];
+
+ invert_m4_m4(tmp_mat, ob->obmat);
+ mul_m4_m4m4(smd_orig->mat, tmp_mat, ob_target->obmat);
+
+ if (!surfacedeformBind(smd_orig, vertexCos, numverts, tnumpoly, tnumverts, target)) {
+ smd->flags &= ~MOD_SDEF_BIND;
+ }
+ /* Early abort, this is binding 'call', no need to perform whole evaluation. */
+ return;
+ }
+
+ /* Poly count checks */
+ if (smd->numverts != numverts) {
+ modifier_setError(md, "Verts changed from %u to %u", smd->numverts, numverts);
+ return;
+ }
+ else if (smd->numpoly != tnumpoly) {
+ modifier_setError(md, "Target polygons changed from %u to %u", smd->numpoly, tnumpoly);
+ return;
+ }
+
+ /* Actual vertex location update starts here */
+ SDefDeformData data = {
+ .bind_verts = smd->verts,
+ .targetCos = MEM_malloc_arrayN(tnumverts, sizeof(float[3]), "SDefTargetVertArray"),
+ .vertexCos = vertexCos,
+ };
+
+ if (data.targetCos != NULL) {
+ const MVert *const mvert = target->mvert;
+
+ for (int i = 0; i < tnumverts; i++) {
+ mul_v3_m4v3(data.targetCos[i], smd->mat, mvert[i].co);
+ }
+
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.use_threading = (numverts > 10000);
+ BLI_task_parallel_range(0, numverts, &data, deformVert, &settings);
+
+ MEM_freeN(data.targetCos);
+ }
}
-static void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *UNUSED(mesh),
- float (*vertexCos)[3], int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *UNUSED(mesh),
+ float (*vertexCos)[3],
+ int numVerts)
{
- surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object);
+ surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object);
}
-static void deformVertsEM(
- ModifierData *md, const ModifierEvalContext *ctx,
- struct BMEditMesh *UNUSED(editData),
- Mesh *UNUSED(mesh),
- float (*vertexCos)[3], int numVerts)
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *UNUSED(editData),
+ Mesh *UNUSED(mesh),
+ float (*vertexCos)[3],
+ int numVerts)
{
- surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object);
+ surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object);
}
static bool isDisabled(const Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
{
- SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
+ SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
- return smd->target == NULL && !(smd->verts != NULL && !(smd->flags & MOD_SDEF_BIND));
+ return smd->target == NULL && !(smd->verts != NULL && !(smd->flags & MOD_SDEF_BIND));
}
ModifierTypeInfo modifierType_SurfaceDeform = {
- /* name */ "Surface Deform",
- /* structName */ "SurfaceDeformModifierData",
- /* structSize */ sizeof(SurfaceDeformModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsEditmode,
-
- /* copyData */ copyData,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ NULL,
- /* freeData */ freeData,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Surface Deform",
+ /* structName */ "SurfaceDeformModifierData",
+ /* structSize */ sizeof(SurfaceDeformModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ copyData,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL,
+ /* freeData */ freeData,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c
index 0b4de9c8d17..7d890b29365 100644
--- a/source/blender/modifiers/intern/MOD_triangulate.c
+++ b/source/blender/modifiers/intern/MOD_triangulate.c
@@ -34,114 +34,112 @@
#include "MOD_modifiertypes.h"
-static Mesh *triangulate_mesh(Mesh *mesh, const int quad_method, const int ngon_method, const int min_vertices, const int flag)
+static Mesh *triangulate_mesh(Mesh *mesh,
+ const int quad_method,
+ const int ngon_method,
+ const int min_vertices,
+ const int flag)
{
- Mesh *result;
- BMesh *bm;
- int total_edges, i;
- MEdge *me;
- CustomData_MeshMasks cddata_masks = {.vmask = CD_MASK_ORIGINDEX, .emask = CD_MASK_ORIGINDEX, .pmask = CD_MASK_ORIGINDEX};
+ Mesh *result;
+ BMesh *bm;
+ int total_edges, i;
+ MEdge *me;
+ CustomData_MeshMasks cddata_masks = {
+ .vmask = CD_MASK_ORIGINDEX, .emask = CD_MASK_ORIGINDEX, .pmask = CD_MASK_ORIGINDEX};
- bool keep_clnors = (flag & MOD_TRIANGULATE_KEEP_CUSTOMLOOP_NORMALS) != 0;
+ bool keep_clnors = (flag & MOD_TRIANGULATE_KEEP_CUSTOMLOOP_NORMALS) != 0;
- if (keep_clnors) {
- BKE_mesh_calc_normals_split(mesh);
- /* We need that one to 'survive' to/from BMesh conversions. */
- CustomData_clear_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
- cddata_masks.lmask |= CD_MASK_NORMAL;
- }
+ if (keep_clnors) {
+ BKE_mesh_calc_normals_split(mesh);
+ /* We need that one to 'survive' to/from BMesh conversions. */
+ CustomData_clear_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
+ cddata_masks.lmask |= CD_MASK_NORMAL;
+ }
- bm = BKE_mesh_to_bmesh_ex(
- mesh,
- &((struct BMeshCreateParams){0}),
- &((struct BMeshFromMeshParams){
- .calc_face_normal = true,
- .cd_mask_extra = cddata_masks,
- }));
+ bm = BKE_mesh_to_bmesh_ex(mesh,
+ &((struct BMeshCreateParams){0}),
+ &((struct BMeshFromMeshParams){
+ .calc_face_normal = true,
+ .cd_mask_extra = cddata_masks,
+ }));
- BM_mesh_triangulate(bm, quad_method, ngon_method, min_vertices, false, NULL, NULL, NULL);
+ BM_mesh_triangulate(bm, quad_method, ngon_method, min_vertices, false, NULL, NULL, NULL);
- result = BKE_mesh_from_bmesh_for_eval_nomain(bm, &cddata_masks);
- BM_mesh_free(bm);
+ result = BKE_mesh_from_bmesh_for_eval_nomain(bm, &cddata_masks);
+ BM_mesh_free(bm);
+ if (keep_clnors) {
+ float(*lnors)[3] = CustomData_get_layer(&result->ldata, CD_NORMAL);
+ BLI_assert(lnors != NULL);
- if (keep_clnors) {
- float (*lnors)[3] = CustomData_get_layer(&result->ldata, CD_NORMAL);
- BLI_assert(lnors != NULL);
+ BKE_mesh_set_custom_normals(result, lnors);
- BKE_mesh_set_custom_normals(result, lnors);
+ /* Do some cleanup, we do not want those temp data to stay around. */
+ CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
+ CustomData_set_layer_flag(&result->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
+ }
- /* Do some cleanup, we do not want those temp data to stay around. */
- CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
- CustomData_set_layer_flag(&result->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
- }
+ total_edges = result->totedge;
+ me = result->medge;
- total_edges = result->totedge;
- me = result->medge;
+ /* force drawing of all edges (seems to be omitted in CDDM_from_bmesh) */
+ for (i = 0; i < total_edges; i++, me++) {
+ me->flag |= ME_EDGEDRAW | ME_EDGERENDER;
+ }
- /* force drawing of all edges (seems to be omitted in CDDM_from_bmesh) */
- for (i = 0; i < total_edges; i++, me++) {
- me->flag |= ME_EDGEDRAW | ME_EDGERENDER;
- }
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
-
- return result;
+ return result;
}
-
static void initData(ModifierData *md)
{
- TriangulateModifierData *tmd = (TriangulateModifierData *)md;
+ TriangulateModifierData *tmd = (TriangulateModifierData *)md;
- /* Enable in editmode by default */
- md->mode |= eModifierMode_Editmode;
- tmd->quad_method = MOD_TRIANGULATE_QUAD_SHORTEDGE;
- tmd->ngon_method = MOD_TRIANGULATE_NGON_BEAUTY;
- tmd->min_vertices = 4;
+ /* Enable in editmode by default */
+ md->mode |= eModifierMode_Editmode;
+ tmd->quad_method = MOD_TRIANGULATE_QUAD_SHORTEDGE;
+ tmd->ngon_method = MOD_TRIANGULATE_NGON_BEAUTY;
+ tmd->min_vertices = 4;
}
-static Mesh *applyModifier(
- ModifierData *md,
- const ModifierEvalContext *UNUSED(ctx),
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
{
- TriangulateModifierData *tmd = (TriangulateModifierData *)md;
- Mesh *result;
- if (!(result = triangulate_mesh(mesh, tmd->quad_method, tmd->ngon_method, tmd->min_vertices, tmd->flag))) {
- return mesh;
- }
-
- return result;
+ TriangulateModifierData *tmd = (TriangulateModifierData *)md;
+ Mesh *result;
+ if (!(result = triangulate_mesh(
+ mesh, tmd->quad_method, tmd->ngon_method, tmd->min_vertices, tmd->flag))) {
+ return mesh;
+ }
+
+ return result;
}
ModifierTypeInfo modifierType_Triangulate = {
- /* name */ "Triangulate",
- /* structName */ "TriangulateModifierData",
- /* structSize */ sizeof(TriangulateModifierData),
- /* type */ eModifierTypeType_Constructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_SupportsMapping |
- eModifierTypeFlag_EnableInEditmode |
- eModifierTypeFlag_AcceptsCVs,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ NULL, //requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Triangulate",
+ /* structName */ "TriangulateModifierData",
+ /* structSize */ sizeof(TriangulateModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode |
+ eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_EnableInEditmode |
+ eModifierTypeFlag_AcceptsCVs,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ NULL, //requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c
index 1bb38001328..b23dff753f8 100644
--- a/source/blender/modifiers/intern/MOD_util.c
+++ b/source/blender/modifiers/intern/MOD_util.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include <string.h>
#include "BLI_utildefines.h"
@@ -59,245 +58,248 @@
void MOD_init_texture(MappingInfoModifierData *dmd, const ModifierEvalContext *ctx)
{
- Tex *tex = dmd->texture;
+ Tex *tex = dmd->texture;
- if (tex == NULL) {
- return;
- }
+ if (tex == NULL) {
+ return;
+ }
- if (tex->ima && BKE_image_is_animated(tex->ima)) {
- BKE_image_user_frame_calc(&tex->iuser, DEG_get_ctime(ctx->depsgraph));
- }
+ if (tex->ima && BKE_image_is_animated(tex->ima)) {
+ BKE_image_user_frame_calc(&tex->iuser, DEG_get_ctime(ctx->depsgraph));
+ }
}
/* TODO to be renamed to get_texture_coords once we are done with moving modifiers to Mesh. */
/** \param cos: may be NULL, in which case we use directly mesh vertices' coordinates. */
-void MOD_get_texture_coords(
- MappingInfoModifierData *dmd,
- const ModifierEvalContext *UNUSED(ctx),
- Object *ob,
- Mesh *mesh,
- float (*cos)[3],
- float (*r_texco)[3])
+void MOD_get_texture_coords(MappingInfoModifierData *dmd,
+ const ModifierEvalContext *UNUSED(ctx),
+ Object *ob,
+ Mesh *mesh,
+ float (*cos)[3],
+ float (*r_texco)[3])
{
- const int numVerts = mesh->totvert;
- int i;
- int texmapping = dmd->texmapping;
- float mapob_imat[4][4];
-
- if (texmapping == MOD_DISP_MAP_OBJECT) {
- if (dmd->map_object != NULL) {
- Object *map_object = dmd->map_object;
- invert_m4_m4(mapob_imat, 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(&mesh->ldata, CD_MLOOPUV)) {
- MPoly *mpoly = mesh->mpoly;
- MPoly *mp;
- MLoop *mloop = mesh->mloop;
- BLI_bitmap *done = BLI_BITMAP_NEW(numVerts, __func__);
- const int numPolys = mesh->totpoly;
- char uvname[MAX_CUSTOMDATA_LAYER_NAME];
- MLoopUV *mloop_uv;
-
- CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, dmd->uvlayer_name, uvname);
- mloop_uv = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname);
-
- /* verts are given the UV from the first face that uses them */
- for (i = 0, mp = mpoly; i < numPolys; ++i, ++mp) {
- unsigned int fidx = mp->totloop - 1;
-
- do {
- unsigned int lidx = mp->loopstart + fidx;
- unsigned int vidx = mloop[lidx].v;
-
- if (!BLI_BITMAP_TEST(done, vidx)) {
- /* remap UVs from [0, 1] to [-1, 1] */
- r_texco[vidx][0] = (mloop_uv[lidx].uv[0] * 2.0f) - 1.0f;
- r_texco[vidx][1] = (mloop_uv[lidx].uv[1] * 2.0f) - 1.0f;
- BLI_BITMAP_ENABLE(done, vidx);
- }
-
- } while (fidx--);
- }
-
- MEM_freeN(done);
- return;
- }
- else {
- /* if there are no UVs, default to local */
- texmapping = MOD_DISP_MAP_LOCAL;
- }
- }
-
- MVert *mv = mesh->mvert;
- for (i = 0; i < numVerts; ++i, ++mv, ++r_texco) {
- switch (texmapping) {
- case MOD_DISP_MAP_LOCAL:
- copy_v3_v3(*r_texco, cos != NULL ? *cos : mv->co);
- break;
- case MOD_DISP_MAP_GLOBAL:
- mul_v3_m4v3(*r_texco, ob->obmat, cos != NULL ? *cos : mv->co);
- break;
- case MOD_DISP_MAP_OBJECT:
- mul_v3_m4v3(*r_texco, ob->obmat, cos != NULL ? *cos : mv->co);
- mul_m4_v3(mapob_imat, *r_texco);
- break;
- }
- if (cos != NULL) {
- cos++;
- }
- }
+ const int numVerts = mesh->totvert;
+ int i;
+ int texmapping = dmd->texmapping;
+ float mapob_imat[4][4];
+
+ if (texmapping == MOD_DISP_MAP_OBJECT) {
+ if (dmd->map_object != NULL) {
+ Object *map_object = dmd->map_object;
+ invert_m4_m4(mapob_imat, 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(&mesh->ldata, CD_MLOOPUV)) {
+ MPoly *mpoly = mesh->mpoly;
+ MPoly *mp;
+ MLoop *mloop = mesh->mloop;
+ BLI_bitmap *done = BLI_BITMAP_NEW(numVerts, __func__);
+ const int numPolys = mesh->totpoly;
+ char uvname[MAX_CUSTOMDATA_LAYER_NAME];
+ MLoopUV *mloop_uv;
+
+ CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, dmd->uvlayer_name, uvname);
+ mloop_uv = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname);
+
+ /* verts are given the UV from the first face that uses them */
+ for (i = 0, mp = mpoly; i < numPolys; ++i, ++mp) {
+ unsigned int fidx = mp->totloop - 1;
+
+ do {
+ unsigned int lidx = mp->loopstart + fidx;
+ unsigned int vidx = mloop[lidx].v;
+
+ if (!BLI_BITMAP_TEST(done, vidx)) {
+ /* remap UVs from [0, 1] to [-1, 1] */
+ r_texco[vidx][0] = (mloop_uv[lidx].uv[0] * 2.0f) - 1.0f;
+ r_texco[vidx][1] = (mloop_uv[lidx].uv[1] * 2.0f) - 1.0f;
+ BLI_BITMAP_ENABLE(done, vidx);
+ }
+
+ } while (fidx--);
+ }
+
+ MEM_freeN(done);
+ return;
+ }
+ else {
+ /* if there are no UVs, default to local */
+ texmapping = MOD_DISP_MAP_LOCAL;
+ }
+ }
+
+ MVert *mv = mesh->mvert;
+ for (i = 0; i < numVerts; ++i, ++mv, ++r_texco) {
+ switch (texmapping) {
+ case MOD_DISP_MAP_LOCAL:
+ copy_v3_v3(*r_texco, cos != NULL ? *cos : mv->co);
+ break;
+ case MOD_DISP_MAP_GLOBAL:
+ mul_v3_m4v3(*r_texco, ob->obmat, cos != NULL ? *cos : mv->co);
+ break;
+ case MOD_DISP_MAP_OBJECT:
+ mul_v3_m4v3(*r_texco, ob->obmat, cos != NULL ? *cos : mv->co);
+ mul_m4_v3(mapob_imat, *r_texco);
+ break;
+ }
+ if (cos != NULL) {
+ cos++;
+ }
+ }
}
void MOD_previous_vcos_store(ModifierData *md, float (*vertexCos)[3])
{
- while ((md = md->next) && md->type == eModifierType_Armature) {
- ArmatureModifierData *amd = (ArmatureModifierData *) md;
- if (amd->multi && amd->prevCos == NULL)
- amd->prevCos = MEM_dupallocN(vertexCos);
- else
- break;
- }
- /* lattice/mesh modifier too */
+ while ((md = md->next) && md->type == eModifierType_Armature) {
+ ArmatureModifierData *amd = (ArmatureModifierData *)md;
+ if (amd->multi && amd->prevCos == NULL)
+ amd->prevCos = MEM_dupallocN(vertexCos);
+ else
+ break;
+ }
+ /* lattice/mesh modifier too */
}
/* returns a mesh if mesh == NULL, for deforming modifiers that need it */
-Mesh *MOD_deform_mesh_eval_get(
- Object *ob, struct BMEditMesh *em, Mesh *mesh,
- float (*vertexCos)[3], const int num_verts,
- const bool use_normals, const bool use_orco)
+Mesh *MOD_deform_mesh_eval_get(Object *ob,
+ struct BMEditMesh *em,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ const int num_verts,
+ const bool use_normals,
+ const bool use_orco)
{
- if (mesh != NULL) {
- /* pass */
- }
- else if (ob->type == OB_MESH) {
- if (em) {
- mesh = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL);
- }
- else {
- /* TODO(sybren): after modifier conversion of DM to Mesh is done, check whether
- * we really need a copy here. Maybe the CoW ob->data can be directly used. */
- Mesh *mesh_prior_modifiers = BKE_object_get_pre_modified_mesh(ob);
- BKE_id_copy_ex(
- NULL, &mesh_prior_modifiers->id, (ID **)&mesh,
- (LIB_ID_COPY_LOCALIZE |
- LIB_ID_COPY_CD_REFERENCE));
- mesh->runtime.deformed_only = 1;
- }
-
- /* TODO(sybren): after modifier conversion of DM to Mesh is done, check whether
- * we really need vertexCos here. */
- if (vertexCos) {
- BKE_mesh_apply_vert_coords(mesh, vertexCos);
- mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- }
-
- if (use_orco) {
- CustomData_add_layer(&mesh->vdata, CD_ORCO, CD_ASSIGN, BKE_mesh_orco_verts_get(ob), mesh->totvert);
- }
- }
- else if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
- /* TODO(sybren): get evaluated mesh from depsgraph once that's properly generated for curves. */
- mesh = BKE_mesh_new_nomain_from_curve(ob);
-
- /* Currently, that may not be the case everytime
- * (texts e.g. tend to give issues, also when deforming curve points instead of generated curve geometry... ). */
- if (mesh != NULL && mesh->totvert != num_verts) {
- BKE_id_free(NULL, mesh);
- mesh = NULL;
- }
- }
-
- if (use_normals) {
- if (LIKELY(mesh)) {
- BKE_mesh_ensure_normals(mesh);
- }
- }
-
- BLI_assert(mesh == NULL || mesh->totvert == num_verts);
-
- return mesh;
+ if (mesh != NULL) {
+ /* pass */
+ }
+ else if (ob->type == OB_MESH) {
+ if (em) {
+ mesh = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL);
+ }
+ else {
+ /* TODO(sybren): after modifier conversion of DM to Mesh is done, check whether
+ * we really need a copy here. Maybe the CoW ob->data can be directly used. */
+ Mesh *mesh_prior_modifiers = BKE_object_get_pre_modified_mesh(ob);
+ BKE_id_copy_ex(NULL,
+ &mesh_prior_modifiers->id,
+ (ID **)&mesh,
+ (LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_CD_REFERENCE));
+ mesh->runtime.deformed_only = 1;
+ }
+
+ /* TODO(sybren): after modifier conversion of DM to Mesh is done, check whether
+ * we really need vertexCos here. */
+ if (vertexCos) {
+ BKE_mesh_apply_vert_coords(mesh, vertexCos);
+ mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ }
+
+ if (use_orco) {
+ CustomData_add_layer(
+ &mesh->vdata, CD_ORCO, CD_ASSIGN, BKE_mesh_orco_verts_get(ob), mesh->totvert);
+ }
+ }
+ else if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
+ /* TODO(sybren): get evaluated mesh from depsgraph once that's properly generated for curves. */
+ mesh = BKE_mesh_new_nomain_from_curve(ob);
+
+ /* Currently, that may not be the case everytime
+ * (texts e.g. tend to give issues, also when deforming curve points instead of generated curve geometry... ). */
+ if (mesh != NULL && mesh->totvert != num_verts) {
+ BKE_id_free(NULL, mesh);
+ mesh = NULL;
+ }
+ }
+
+ if (use_normals) {
+ if (LIKELY(mesh)) {
+ BKE_mesh_ensure_normals(mesh);
+ }
+ }
+
+ BLI_assert(mesh == NULL || mesh->totvert == num_verts);
+
+ return mesh;
}
-void MOD_get_vgroup(Object *ob, struct Mesh *mesh, const char *name, MDeformVert **dvert, int *defgrp_index)
+void MOD_get_vgroup(
+ Object *ob, struct Mesh *mesh, const char *name, MDeformVert **dvert, int *defgrp_index)
{
- *defgrp_index = defgroup_name_index(ob, name);
- *dvert = NULL;
-
- if (*defgrp_index != -1) {
- if (ob->type == OB_LATTICE)
- *dvert = BKE_lattice_deform_verts_get(ob);
- else if (mesh)
- *dvert = mesh->dvert;
- }
+ *defgrp_index = defgroup_name_index(ob, name);
+ *dvert = NULL;
+
+ if (*defgrp_index != -1) {
+ if (ob->type == OB_LATTICE)
+ *dvert = BKE_lattice_deform_verts_get(ob);
+ else if (mesh)
+ *dvert = mesh->dvert;
+ }
}
-
/* only called by BKE_modifier.h/modifier.c */
void modifier_type_init(ModifierTypeInfo *types[])
{
#define INIT_TYPE(typeName) (types[eModifierType_##typeName] = &modifierType_##typeName)
- INIT_TYPE(None);
- INIT_TYPE(Curve);
- INIT_TYPE(Lattice);
- INIT_TYPE(Subsurf);
- INIT_TYPE(Build);
- INIT_TYPE(Array);
- INIT_TYPE(Mirror);
- INIT_TYPE(EdgeSplit);
- INIT_TYPE(Bevel);
- INIT_TYPE(Displace);
- INIT_TYPE(UVProject);
- INIT_TYPE(Decimate);
- INIT_TYPE(Smooth);
- INIT_TYPE(Cast);
- INIT_TYPE(Wave);
- INIT_TYPE(Armature);
- INIT_TYPE(Hook);
- INIT_TYPE(Softbody);
- INIT_TYPE(Cloth);
- INIT_TYPE(Collision);
- INIT_TYPE(Boolean);
- INIT_TYPE(MeshDeform);
- INIT_TYPE(Ocean);
- INIT_TYPE(ParticleSystem);
- INIT_TYPE(ParticleInstance);
- INIT_TYPE(Explode);
- INIT_TYPE(Shrinkwrap);
- INIT_TYPE(Fluidsim);
- INIT_TYPE(Mask);
- INIT_TYPE(SimpleDeform);
- INIT_TYPE(Multires);
- INIT_TYPE(Surface);
- INIT_TYPE(Smoke);
- INIT_TYPE(ShapeKey);
- INIT_TYPE(Solidify);
- INIT_TYPE(Screw);
- INIT_TYPE(Warp);
- INIT_TYPE(WeightVGEdit);
- INIT_TYPE(WeightVGMix);
- INIT_TYPE(WeightVGProximity);
- INIT_TYPE(DynamicPaint);
- INIT_TYPE(Remesh);
- INIT_TYPE(Skin);
- INIT_TYPE(LaplacianSmooth);
- INIT_TYPE(Triangulate);
- INIT_TYPE(UVWarp);
- INIT_TYPE(MeshCache);
- INIT_TYPE(LaplacianDeform);
- INIT_TYPE(Wireframe);
- INIT_TYPE(DataTransfer);
- INIT_TYPE(NormalEdit);
- INIT_TYPE(CorrectiveSmooth);
- INIT_TYPE(MeshSequenceCache);
- INIT_TYPE(SurfaceDeform);
- INIT_TYPE(WeightedNormal);
+ INIT_TYPE(None);
+ INIT_TYPE(Curve);
+ INIT_TYPE(Lattice);
+ INIT_TYPE(Subsurf);
+ INIT_TYPE(Build);
+ INIT_TYPE(Array);
+ INIT_TYPE(Mirror);
+ INIT_TYPE(EdgeSplit);
+ INIT_TYPE(Bevel);
+ INIT_TYPE(Displace);
+ INIT_TYPE(UVProject);
+ INIT_TYPE(Decimate);
+ INIT_TYPE(Smooth);
+ INIT_TYPE(Cast);
+ INIT_TYPE(Wave);
+ INIT_TYPE(Armature);
+ INIT_TYPE(Hook);
+ INIT_TYPE(Softbody);
+ INIT_TYPE(Cloth);
+ INIT_TYPE(Collision);
+ INIT_TYPE(Boolean);
+ INIT_TYPE(MeshDeform);
+ INIT_TYPE(Ocean);
+ INIT_TYPE(ParticleSystem);
+ INIT_TYPE(ParticleInstance);
+ INIT_TYPE(Explode);
+ INIT_TYPE(Shrinkwrap);
+ INIT_TYPE(Fluidsim);
+ INIT_TYPE(Mask);
+ INIT_TYPE(SimpleDeform);
+ INIT_TYPE(Multires);
+ INIT_TYPE(Surface);
+ INIT_TYPE(Smoke);
+ INIT_TYPE(ShapeKey);
+ INIT_TYPE(Solidify);
+ INIT_TYPE(Screw);
+ INIT_TYPE(Warp);
+ INIT_TYPE(WeightVGEdit);
+ INIT_TYPE(WeightVGMix);
+ INIT_TYPE(WeightVGProximity);
+ INIT_TYPE(DynamicPaint);
+ INIT_TYPE(Remesh);
+ INIT_TYPE(Skin);
+ INIT_TYPE(LaplacianSmooth);
+ INIT_TYPE(Triangulate);
+ INIT_TYPE(UVWarp);
+ INIT_TYPE(MeshCache);
+ INIT_TYPE(LaplacianDeform);
+ INIT_TYPE(Wireframe);
+ INIT_TYPE(DataTransfer);
+ INIT_TYPE(NormalEdit);
+ INIT_TYPE(CorrectiveSmooth);
+ INIT_TYPE(MeshSequenceCache);
+ INIT_TYPE(SurfaceDeform);
+ INIT_TYPE(WeightedNormal);
#undef INIT_TYPE
}
diff --git a/source/blender/modifiers/intern/MOD_util.h b/source/blender/modifiers/intern/MOD_util.h
index 2325f865d6a..ba3ca44c026 100644
--- a/source/blender/modifiers/intern/MOD_util.h
+++ b/source/blender/modifiers/intern/MOD_util.h
@@ -18,7 +18,6 @@
* \ingroup modifiers
*/
-
#ifndef __MOD_UTIL_H__
#define __MOD_UTIL_H__
@@ -36,23 +35,27 @@ struct Scene;
struct Tex;
void MOD_init_texture(struct MappingInfoModifierData *dmd, const struct ModifierEvalContext *ctx);
-void MOD_get_texture_coords(
- struct MappingInfoModifierData *dmd,
- const struct ModifierEvalContext *ctx,
- struct Object *ob,
- struct Mesh *mesh,
- float (*cos)[3],
- float (*r_texco)[3]);
+void MOD_get_texture_coords(struct MappingInfoModifierData *dmd,
+ const struct ModifierEvalContext *ctx,
+ struct Object *ob,
+ struct Mesh *mesh,
+ float (*cos)[3],
+ float (*r_texco)[3]);
void MOD_previous_vcos_store(struct ModifierData *md, float (*vertexCos)[3]);
-struct Mesh *MOD_deform_mesh_eval_get(
- struct Object *ob, struct BMEditMesh *em, struct Mesh *mesh,
- float (*vertexCos)[3], const int num_verts,
- const bool use_normals, const bool use_orco);
-
-void MOD_get_vgroup(
- struct Object *ob, struct Mesh *mesh,
- const char *name, struct MDeformVert **dvert, int *defgrp_index);
+struct Mesh *MOD_deform_mesh_eval_get(struct Object *ob,
+ struct BMEditMesh *em,
+ struct Mesh *mesh,
+ float (*vertexCos)[3],
+ const int num_verts,
+ const bool use_normals,
+ const bool use_orco);
+
+void MOD_get_vgroup(struct Object *ob,
+ struct Mesh *mesh,
+ const char *name,
+ struct MDeformVert **dvert,
+ int *defgrp_index);
#endif /* __MOD_UTIL_H__ */
diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c
index 06cd7a80494..5a9c115dc12 100644
--- a/source/blender/modifiers/intern/MOD_uvproject.c
+++ b/source/blender/modifiers/intern/MOD_uvproject.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
/* UV Project modifier: Generates UVs projected from an object */
#include "BLI_utildefines.h"
@@ -49,295 +48,290 @@
static void initData(ModifierData *md)
{
- UVProjectModifierData *umd = (UVProjectModifierData *) md;
-
+ UVProjectModifierData *umd = (UVProjectModifierData *)md;
- umd->num_projectors = 1;
- umd->aspectx = umd->aspecty = 1.0f;
- umd->scalex = umd->scaley = 1.0f;
+ umd->num_projectors = 1;
+ umd->aspectx = umd->aspecty = 1.0f;
+ umd->scalex = umd->scaley = 1.0f;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md), CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *UNUSED(md),
+ CustomData_MeshMasks *r_cddata_masks)
{
- /* ask for UV coordinates */
- r_cddata_masks->lmask |= CD_MLOOPUV;
+ /* ask for UV coordinates */
+ r_cddata_masks->lmask |= CD_MLOOPUV;
}
-static void foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- UVProjectModifierData *umd = (UVProjectModifierData *) md;
- int i;
+ UVProjectModifierData *umd = (UVProjectModifierData *)md;
+ int i;
- for (i = 0; i < MOD_UVPROJECT_MAXPROJECTORS; ++i)
- walk(userData, ob, &umd->projectors[i], IDWALK_CB_NOP);
+ for (i = 0; i < MOD_UVPROJECT_MAXPROJECTORS; ++i)
+ walk(userData, ob, &umd->projectors[i], IDWALK_CB_NOP);
}
-static void foreachIDLink(
- ModifierData *md, Object *ob,
- IDWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
#if 0
- UVProjectModifierData *umd = (UVProjectModifierData *) md;
+ UVProjectModifierData *umd = (UVProjectModifierData *) md;
#endif
- foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
+ foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- UVProjectModifierData *umd = (UVProjectModifierData *)md;
- bool do_add_own_transform = false;
- for (int i = 0; i < umd->num_projectors; ++i) {
- if (umd->projectors[i] != NULL) {
- DEG_add_object_relation(ctx->node, umd->projectors[i], DEG_OB_COMP_TRANSFORM, "UV Project Modifier");
- do_add_own_transform = true;
- }
- }
- if (do_add_own_transform) {
- DEG_add_modifier_to_transform_relation(ctx->node, "UV Project Modifier");
- }
+ UVProjectModifierData *umd = (UVProjectModifierData *)md;
+ bool do_add_own_transform = false;
+ for (int i = 0; i < umd->num_projectors; ++i) {
+ if (umd->projectors[i] != NULL) {
+ DEG_add_object_relation(
+ ctx->node, umd->projectors[i], DEG_OB_COMP_TRANSFORM, "UV Project Modifier");
+ do_add_own_transform = true;
+ }
+ }
+ if (do_add_own_transform) {
+ DEG_add_modifier_to_transform_relation(ctx->node, "UV Project Modifier");
+ }
}
typedef struct Projector {
- Object *ob; /* object this projector is derived from */
- float projmat[4][4]; /* projection matrix */
- float normal[3]; /* projector normal in world space */
- void *uci; /* optional uv-project info (panorama projection) */
+ Object *ob; /* object this projector is derived from */
+ float projmat[4][4]; /* projection matrix */
+ float normal[3]; /* projector normal in world space */
+ void *uci; /* optional uv-project info (panorama projection) */
} Projector;
-static Mesh *uvprojectModifier_do(
- UVProjectModifierData *umd,
- const ModifierEvalContext *UNUSED(ctx),
- Object *ob, Mesh *mesh)
+static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
+ const ModifierEvalContext *UNUSED(ctx),
+ Object *ob,
+ Mesh *mesh)
{
- float (*coords)[3], (*co)[3];
- MLoopUV *mloop_uv;
- int i, numVerts, numPolys, numLoops;
- MPoly *mpoly, *mp;
- MLoop *mloop;
- Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
- int num_projectors = 0;
- char uvname[MAX_CUSTOMDATA_LAYER_NAME];
- float aspx = umd->aspectx ? umd->aspectx : 1.0f;
- float aspy = umd->aspecty ? umd->aspecty : 1.0f;
- float scax = umd->scalex ? umd->scalex : 1.0f;
- float scay = umd->scaley ? umd->scaley : 1.0f;
- int free_uci = 0;
-
- for (i = 0; i < umd->num_projectors; ++i) {
- if (umd->projectors[i] != NULL) {
- projectors[num_projectors++].ob = umd->projectors[i];
- }
- }
-
- if (num_projectors == 0)
- return mesh;
-
- /* make sure there are UV Maps available */
-
- if (!CustomData_has_layer(&mesh->ldata, CD_MLOOPUV)) return mesh;
-
- /* make sure we're using an existing layer */
- CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, umd->uvlayer_name, uvname);
-
- /* calculate a projection matrix and normal for each projector */
- for (i = 0; i < num_projectors; ++i) {
- float tmpmat[4][4];
- float offsetmat[4][4];
- Camera *cam = NULL;
- /* calculate projection matrix */
- invert_m4_m4(projectors[i].projmat, projectors[i].ob->obmat);
-
- projectors[i].uci = NULL;
-
- if (projectors[i].ob->type == OB_CAMERA) {
- cam = (Camera *)projectors[i].ob->data;
- if (cam->type == CAM_PANO) {
- projectors[i].uci = BLI_uvproject_camera_info(projectors[i].ob, NULL, aspx, aspy);
- BLI_uvproject_camera_info_scale(projectors[i].uci, scax, scay);
- free_uci = 1;
- }
- else {
- CameraParams params;
-
- /* setup parameters */
- BKE_camera_params_init(&params);
- BKE_camera_params_from_object(&params, projectors[i].ob);
-
- /* compute matrix, viewplane, .. */
- BKE_camera_params_compute_viewplane(&params, 1, 1, aspx, aspy);
-
- /* scale the view-plane */
- params.viewplane.xmin *= scax;
- params.viewplane.xmax *= scax;
- params.viewplane.ymin *= scay;
- params.viewplane.ymax *= scay;
-
- BKE_camera_params_compute_matrix(&params);
- mul_m4_m4m4(tmpmat, params.winmat, projectors[i].projmat);
- }
- }
- else {
- copy_m4_m4(tmpmat, projectors[i].projmat);
- }
-
- unit_m4(offsetmat);
- mul_mat3_m4_fl(offsetmat, 0.5);
- offsetmat[3][0] = offsetmat[3][1] = offsetmat[3][2] = 0.5;
-
- mul_m4_m4m4(projectors[i].projmat, offsetmat, tmpmat);
-
- /* calculate worldspace projector normal (for best projector test) */
- projectors[i].normal[0] = 0;
- projectors[i].normal[1] = 0;
- projectors[i].normal[2] = 1;
- mul_mat3_m4_v3(projectors[i].ob->obmat, projectors[i].normal);
- }
-
- numPolys = mesh->totpoly;
- numLoops = mesh->totloop;
-
- /* make sure we are not modifying the original UV map */
- mloop_uv = CustomData_duplicate_referenced_layer_named(&mesh->ldata,
- CD_MLOOPUV, uvname, numLoops);
-
- coords = BKE_mesh_vertexCos_get(mesh, &numVerts);
-
- /* convert coords to world space */
- for (i = 0, co = coords; i < numVerts; ++i, ++co)
- mul_m4_v3(ob->obmat, *co);
-
- /* if only one projector, project coords to UVs */
- if (num_projectors == 1 && projectors[0].uci == NULL)
- for (i = 0, co = coords; i < numVerts; ++i, ++co)
- mul_project_m4_v3(projectors[0].projmat, *co);
-
- mpoly = mesh->mpoly;
- mloop = mesh->mloop;
-
- /* apply coords as UVs */
- for (i = 0, mp = mpoly; i < numPolys; ++i, ++mp) {
- if (num_projectors == 1) {
- if (projectors[0].uci) {
- unsigned int fidx = mp->totloop - 1;
- do {
- unsigned int lidx = mp->loopstart + fidx;
- unsigned int vidx = mloop[lidx].v;
- BLI_uvproject_from_camera(mloop_uv[lidx].uv, coords[vidx], projectors[0].uci);
- } while (fidx--);
- }
- else {
- /* apply transformed coords as UVs */
- unsigned int fidx = mp->totloop - 1;
- do {
- unsigned int lidx = mp->loopstart + fidx;
- unsigned int vidx = mloop[lidx].v;
- copy_v2_v2(mloop_uv[lidx].uv, coords[vidx]);
- } while (fidx--);
- }
- }
- else {
- /* multiple projectors, select the closest to face normal direction */
- float face_no[3];
- int j;
- Projector *best_projector;
- float best_dot;
-
- /* get the untransformed face normal */
- BKE_mesh_calc_poly_normal_coords(mp, mloop + mp->loopstart, (const float (*)[3])coords, face_no);
-
- /* find the projector which the face points at most directly
- * (projector normal with largest dot product is best)
- */
- best_dot = dot_v3v3(projectors[0].normal, face_no);
- best_projector = &projectors[0];
-
- for (j = 1; j < num_projectors; ++j) {
- float tmp_dot = dot_v3v3(projectors[j].normal, face_no);
- if (tmp_dot > best_dot) {
- best_dot = tmp_dot;
- best_projector = &projectors[j];
- }
- }
-
- if (best_projector->uci) {
- unsigned int fidx = mp->totloop - 1;
- do {
- unsigned int lidx = mp->loopstart + fidx;
- unsigned int vidx = mloop[lidx].v;
- BLI_uvproject_from_camera(mloop_uv[lidx].uv, coords[vidx], best_projector->uci);
- } while (fidx--);
- }
- else {
- unsigned int fidx = mp->totloop - 1;
- do {
- unsigned int lidx = mp->loopstart + fidx;
- unsigned int vidx = mloop[lidx].v;
- mul_v2_project_m4_v3(mloop_uv[lidx].uv, best_projector->projmat, coords[vidx]);
- } while (fidx--);
- }
- }
- }
-
- MEM_freeN(coords);
-
- if (free_uci) {
- int j;
- for (j = 0; j < num_projectors; ++j) {
- if (projectors[j].uci) {
- MEM_freeN(projectors[j].uci);
- }
- }
- }
-
- /* Mark tessellated CD layers as dirty. */
- mesh->runtime.cd_dirty_vert |= CD_MASK_TESSLOOPNORMAL;
-
- return mesh;
+ float(*coords)[3], (*co)[3];
+ MLoopUV *mloop_uv;
+ int i, numVerts, numPolys, numLoops;
+ MPoly *mpoly, *mp;
+ MLoop *mloop;
+ Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
+ int num_projectors = 0;
+ char uvname[MAX_CUSTOMDATA_LAYER_NAME];
+ float aspx = umd->aspectx ? umd->aspectx : 1.0f;
+ float aspy = umd->aspecty ? umd->aspecty : 1.0f;
+ float scax = umd->scalex ? umd->scalex : 1.0f;
+ float scay = umd->scaley ? umd->scaley : 1.0f;
+ int free_uci = 0;
+
+ for (i = 0; i < umd->num_projectors; ++i) {
+ if (umd->projectors[i] != NULL) {
+ projectors[num_projectors++].ob = umd->projectors[i];
+ }
+ }
+
+ if (num_projectors == 0)
+ return mesh;
+
+ /* make sure there are UV Maps available */
+
+ if (!CustomData_has_layer(&mesh->ldata, CD_MLOOPUV))
+ return mesh;
+
+ /* make sure we're using an existing layer */
+ CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, umd->uvlayer_name, uvname);
+
+ /* calculate a projection matrix and normal for each projector */
+ for (i = 0; i < num_projectors; ++i) {
+ float tmpmat[4][4];
+ float offsetmat[4][4];
+ Camera *cam = NULL;
+ /* calculate projection matrix */
+ invert_m4_m4(projectors[i].projmat, projectors[i].ob->obmat);
+
+ projectors[i].uci = NULL;
+
+ if (projectors[i].ob->type == OB_CAMERA) {
+ cam = (Camera *)projectors[i].ob->data;
+ if (cam->type == CAM_PANO) {
+ projectors[i].uci = BLI_uvproject_camera_info(projectors[i].ob, NULL, aspx, aspy);
+ BLI_uvproject_camera_info_scale(projectors[i].uci, scax, scay);
+ free_uci = 1;
+ }
+ else {
+ CameraParams params;
+
+ /* setup parameters */
+ BKE_camera_params_init(&params);
+ BKE_camera_params_from_object(&params, projectors[i].ob);
+
+ /* compute matrix, viewplane, .. */
+ BKE_camera_params_compute_viewplane(&params, 1, 1, aspx, aspy);
+
+ /* scale the view-plane */
+ params.viewplane.xmin *= scax;
+ params.viewplane.xmax *= scax;
+ params.viewplane.ymin *= scay;
+ params.viewplane.ymax *= scay;
+
+ BKE_camera_params_compute_matrix(&params);
+ mul_m4_m4m4(tmpmat, params.winmat, projectors[i].projmat);
+ }
+ }
+ else {
+ copy_m4_m4(tmpmat, projectors[i].projmat);
+ }
+
+ unit_m4(offsetmat);
+ mul_mat3_m4_fl(offsetmat, 0.5);
+ offsetmat[3][0] = offsetmat[3][1] = offsetmat[3][2] = 0.5;
+
+ mul_m4_m4m4(projectors[i].projmat, offsetmat, tmpmat);
+
+ /* calculate worldspace projector normal (for best projector test) */
+ projectors[i].normal[0] = 0;
+ projectors[i].normal[1] = 0;
+ projectors[i].normal[2] = 1;
+ mul_mat3_m4_v3(projectors[i].ob->obmat, projectors[i].normal);
+ }
+
+ numPolys = mesh->totpoly;
+ numLoops = mesh->totloop;
+
+ /* make sure we are not modifying the original UV map */
+ mloop_uv = CustomData_duplicate_referenced_layer_named(
+ &mesh->ldata, CD_MLOOPUV, uvname, numLoops);
+
+ coords = BKE_mesh_vertexCos_get(mesh, &numVerts);
+
+ /* convert coords to world space */
+ for (i = 0, co = coords; i < numVerts; ++i, ++co)
+ mul_m4_v3(ob->obmat, *co);
+
+ /* if only one projector, project coords to UVs */
+ if (num_projectors == 1 && projectors[0].uci == NULL)
+ for (i = 0, co = coords; i < numVerts; ++i, ++co)
+ mul_project_m4_v3(projectors[0].projmat, *co);
+
+ mpoly = mesh->mpoly;
+ mloop = mesh->mloop;
+
+ /* apply coords as UVs */
+ for (i = 0, mp = mpoly; i < numPolys; ++i, ++mp) {
+ if (num_projectors == 1) {
+ if (projectors[0].uci) {
+ unsigned int fidx = mp->totloop - 1;
+ do {
+ unsigned int lidx = mp->loopstart + fidx;
+ unsigned int vidx = mloop[lidx].v;
+ BLI_uvproject_from_camera(mloop_uv[lidx].uv, coords[vidx], projectors[0].uci);
+ } while (fidx--);
+ }
+ else {
+ /* apply transformed coords as UVs */
+ unsigned int fidx = mp->totloop - 1;
+ do {
+ unsigned int lidx = mp->loopstart + fidx;
+ unsigned int vidx = mloop[lidx].v;
+ copy_v2_v2(mloop_uv[lidx].uv, coords[vidx]);
+ } while (fidx--);
+ }
+ }
+ else {
+ /* multiple projectors, select the closest to face normal direction */
+ float face_no[3];
+ int j;
+ Projector *best_projector;
+ float best_dot;
+
+ /* get the untransformed face normal */
+ BKE_mesh_calc_poly_normal_coords(
+ mp, mloop + mp->loopstart, (const float(*)[3])coords, face_no);
+
+ /* find the projector which the face points at most directly
+ * (projector normal with largest dot product is best)
+ */
+ best_dot = dot_v3v3(projectors[0].normal, face_no);
+ best_projector = &projectors[0];
+
+ for (j = 1; j < num_projectors; ++j) {
+ float tmp_dot = dot_v3v3(projectors[j].normal, face_no);
+ if (tmp_dot > best_dot) {
+ best_dot = tmp_dot;
+ best_projector = &projectors[j];
+ }
+ }
+
+ if (best_projector->uci) {
+ unsigned int fidx = mp->totloop - 1;
+ do {
+ unsigned int lidx = mp->loopstart + fidx;
+ unsigned int vidx = mloop[lidx].v;
+ BLI_uvproject_from_camera(mloop_uv[lidx].uv, coords[vidx], best_projector->uci);
+ } while (fidx--);
+ }
+ else {
+ unsigned int fidx = mp->totloop - 1;
+ do {
+ unsigned int lidx = mp->loopstart + fidx;
+ unsigned int vidx = mloop[lidx].v;
+ mul_v2_project_m4_v3(mloop_uv[lidx].uv, best_projector->projmat, coords[vidx]);
+ } while (fidx--);
+ }
+ }
+ }
+
+ MEM_freeN(coords);
+
+ if (free_uci) {
+ int j;
+ for (j = 0; j < num_projectors; ++j) {
+ if (projectors[j].uci) {
+ MEM_freeN(projectors[j].uci);
+ }
+ }
+ }
+
+ /* Mark tessellated CD layers as dirty. */
+ mesh->runtime.cd_dirty_vert |= CD_MASK_TESSLOOPNORMAL;
+
+ return mesh;
}
-static Mesh *applyModifier(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- Mesh *result;
- UVProjectModifierData *umd = (UVProjectModifierData *) md;
+ Mesh *result;
+ UVProjectModifierData *umd = (UVProjectModifierData *)md;
- result = uvprojectModifier_do(umd, ctx, ctx->object, mesh);
+ result = uvprojectModifier_do(umd, ctx, ctx->object, mesh);
- return result;
+ return result;
}
-
ModifierTypeInfo modifierType_UVProject = {
- /* name */ "UVProject",
- /* structName */ "UVProjectModifierData",
- /* structSize */ sizeof(UVProjectModifierData),
- /* type */ eModifierTypeType_NonGeometrical,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsMapping |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_EnableInEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ foreachIDLink,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "UVProject",
+ /* structName */ "UVProjectModifierData",
+ /* structSize */ sizeof(UVProjectModifierData),
+ /* type */ eModifierTypeType_NonGeometrical,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c
index a850bb34111..83b9a8e1804 100644
--- a/source/blender/modifiers/intern/MOD_uvwarp.c
+++ b/source/blender/modifiers/intern/MOD_uvwarp.c
@@ -29,7 +29,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "BKE_action.h" /* BKE_pose_channel_find_name */
+#include "BKE_action.h" /* BKE_pose_channel_find_name */
#include "BKE_deform.h"
#include "BKE_library_query.h"
#include "BKE_modifier.h"
@@ -38,238 +38,236 @@
#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 uv_dst[2], const float uv_src[2], float warp_mat[4][4], int axis_u, int axis_v)
{
- float tuv[3] = {0.0f};
+ float tuv[3] = {0.0f};
- tuv[axis_u] = uv_src[0];
- tuv[axis_v] = uv_src[1];
+ tuv[axis_u] = uv_src[0];
+ tuv[axis_v] = uv_src[1];
- mul_m4_v3(warp_mat, tuv);
+ mul_m4_v3(warp_mat, tuv);
- uv_dst[0] = tuv[axis_u];
- uv_dst[1] = tuv[axis_v];
+ 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);
+ UVWarpModifierData *umd = (UVWarpModifierData *)md;
+ umd->axis_u = 0;
+ umd->axis_v = 1;
+ copy_v2_fl(umd->center, 0.5f);
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- UVWarpModifierData *umd = (UVWarpModifierData *)md;
+ UVWarpModifierData *umd = (UVWarpModifierData *)md;
- /* ask for vertexgroups if we need them */
- if (umd->vgroup_name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ /* ask for vertexgroups if we need them */
+ if (umd->vgroup_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
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) {
- mul_m4_m4m4(mat, ob->obmat, pchan->pose_mat);
- }
- else {
- copy_m4_m4(mat, ob->obmat);
- }
+ bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bonename);
+ if (pchan) {
+ mul_m4_m4m4(mat, ob->obmat, pchan->pose_mat);
+ }
+ else {
+ copy_m4_m4(mat, ob->obmat);
+ }
}
typedef struct UVWarpData {
- MPoly *mpoly;
- MLoop *mloop;
- MLoopUV *mloopuv;
+ MPoly *mpoly;
+ MLoop *mloop;
+ MLoopUV *mloopuv;
- MDeformVert *dvert;
- int defgrp_index;
+ MDeformVert *dvert;
+ int defgrp_index;
- float (*warp_mat)[4];
- int axis_u;
- int axis_v;
+ float (*warp_mat)[4];
+ int axis_u;
+ int axis_v;
} UVWarpData;
-static void uv_warp_compute(
- void *__restrict userdata,
- const int i,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+static void uv_warp_compute(void *__restrict userdata,
+ const int i,
+ const ParallelRangeTLS *__restrict UNUSED(tls))
{
- const UVWarpData *data = userdata;
-
- const MPoly *mp = &data->mpoly[i];
- const MLoop *ml = &data->mloop[mp->loopstart];
- MLoopUV *mluv = &data->mloopuv[mp->loopstart];
-
- const MDeformVert *dvert = data->dvert;
- const int defgrp_index = data->defgrp_index;
-
- float (*warp_mat)[4] = data->warp_mat;
- const int axis_u = data->axis_u;
- const int axis_v = data->axis_v;
-
- int l;
-
- if (dvert) {
- for (l = 0; l < mp->totloop; l++, ml++, mluv++) {
- float uv[2];
- 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 {
- for (l = 0; l < mp->totloop; l++, ml++, mluv++) {
- uv_warp_from_mat4_pair(mluv->uv, mluv->uv, warp_mat, axis_u, axis_v);
- }
- }
+ const UVWarpData *data = userdata;
+
+ const MPoly *mp = &data->mpoly[i];
+ const MLoop *ml = &data->mloop[mp->loopstart];
+ MLoopUV *mluv = &data->mloopuv[mp->loopstart];
+
+ const MDeformVert *dvert = data->dvert;
+ const int defgrp_index = data->defgrp_index;
+
+ float(*warp_mat)[4] = data->warp_mat;
+ const int axis_u = data->axis_u;
+ const int axis_v = data->axis_v;
+
+ int l;
+
+ if (dvert) {
+ for (l = 0; l < mp->totloop; l++, ml++, mluv++) {
+ float uv[2];
+ 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 {
+ for (l = 0; l < mp->totloop; l++, ml++, mluv++) {
+ uv_warp_from_mat4_pair(mluv->uv, mluv->uv, warp_mat, axis_u, axis_v);
+ }
+ }
}
-static Mesh *applyModifier(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- UVWarpModifierData *umd = (UVWarpModifierData *) md;
- int 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(&mesh->ldata, CD_MLOOPUV)) {
- return mesh;
- }
- else if (ELEM(NULL, umd->object_src, umd->object_dst)) {
- modifier_setError(md, "From/To objects must be set");
- return mesh;
- }
-
- /* 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);
- mul_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);
-
- mul_m4_m4m4(warp_mat, warp_mat, imat_cent);
- mul_m4_m4m4(warp_mat, mat_cent, warp_mat);
- }
-
- /* make sure we're using an existing layer */
- CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, umd->uvlayer_name, uvname);
-
- numPolys = mesh->totpoly;
- numLoops = mesh->totloop;
-
- mpoly = mesh->mpoly;
- mloop = mesh->mloop;
- /* make sure we are not modifying the original UV map */
- mloopuv = CustomData_duplicate_referenced_layer_named(&mesh->ldata, CD_MLOOPUV, uvname, numLoops);
- MOD_get_vgroup(ctx->object, mesh, umd->vgroup_name, &dvert, &defgrp_index);
-
- UVWarpData data = {
- .mpoly = mpoly, .mloop = mloop, .mloopuv = mloopuv,
- .dvert = dvert, .defgrp_index = defgrp_index,
- .warp_mat = warp_mat, .axis_u = axis_u, .axis_v = axis_v,
- };
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.use_threading = (numPolys > 1000);
- BLI_task_parallel_range(0, numPolys,
- &data,
- uv_warp_compute,
- &settings);
-
- /* XXX TODO is this still needed? */
-// me_eval->dirty |= DM_DIRTY_TESS_CDLAYERS;
-
- return mesh;
+ UVWarpModifierData *umd = (UVWarpModifierData *)md;
+ int 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(&mesh->ldata, CD_MLOOPUV)) {
+ return mesh;
+ }
+ else if (ELEM(NULL, umd->object_src, umd->object_dst)) {
+ modifier_setError(md, "From/To objects must be set");
+ return mesh;
+ }
+
+ /* 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);
+ mul_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);
+
+ mul_m4_m4m4(warp_mat, warp_mat, imat_cent);
+ mul_m4_m4m4(warp_mat, mat_cent, warp_mat);
+ }
+
+ /* make sure we're using an existing layer */
+ CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, umd->uvlayer_name, uvname);
+
+ numPolys = mesh->totpoly;
+ numLoops = mesh->totloop;
+
+ mpoly = mesh->mpoly;
+ mloop = mesh->mloop;
+ /* make sure we are not modifying the original UV map */
+ mloopuv = CustomData_duplicate_referenced_layer_named(
+ &mesh->ldata, CD_MLOOPUV, uvname, numLoops);
+ MOD_get_vgroup(ctx->object, mesh, umd->vgroup_name, &dvert, &defgrp_index);
+
+ UVWarpData data = {
+ .mpoly = mpoly,
+ .mloop = mloop,
+ .mloopuv = mloopuv,
+ .dvert = dvert,
+ .defgrp_index = defgrp_index,
+ .warp_mat = warp_mat,
+ .axis_u = axis_u,
+ .axis_v = axis_v,
+ };
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.use_threading = (numPolys > 1000);
+ BLI_task_parallel_range(0, numPolys, &data, uv_warp_compute, &settings);
+
+ /* XXX TODO is this still needed? */
+ // me_eval->dirty |= DM_DIRTY_TESS_CDLAYERS;
+
+ return mesh;
}
static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- UVWarpModifierData *umd = (UVWarpModifierData *) md;
+ UVWarpModifierData *umd = (UVWarpModifierData *)md;
- walk(userData, ob, &umd->object_dst, IDWALK_CB_NOP);
- walk(userData, ob, &umd->object_src, IDWALK_CB_NOP);
+ walk(userData, ob, &umd->object_dst, IDWALK_CB_NOP);
+ walk(userData, ob, &umd->object_src, IDWALK_CB_NOP);
}
-static void uv_warp_deps_object_bone_new(
- struct DepsNodeHandle *node,
- Object *object,
- const char *bonename)
+static void uv_warp_deps_object_bone_new(struct DepsNodeHandle *node,
+ Object *object,
+ const char *bonename)
{
- if (object != NULL) {
- if (bonename[0])
- DEG_add_object_relation(node, object, DEG_OB_COMP_EVAL_POSE, "UVWarp Modifier");
- else
- DEG_add_object_relation(node, object, DEG_OB_COMP_TRANSFORM, "UVWarp Modifier");
- }
+ if (object != NULL) {
+ if (bonename[0])
+ DEG_add_object_relation(node, object, DEG_OB_COMP_EVAL_POSE, "UVWarp Modifier");
+ else
+ DEG_add_object_relation(node, object, DEG_OB_COMP_TRANSFORM, "UVWarp Modifier");
+ }
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- UVWarpModifierData *umd = (UVWarpModifierData *) md;
+ UVWarpModifierData *umd = (UVWarpModifierData *)md;
- uv_warp_deps_object_bone_new(ctx->node, umd->object_src, umd->bone_src);
- uv_warp_deps_object_bone_new(ctx->node, umd->object_dst, umd->bone_dst);
+ uv_warp_deps_object_bone_new(ctx->node, umd->object_src, umd->bone_src);
+ uv_warp_deps_object_bone_new(ctx->node, umd->object_dst, umd->bone_dst);
- DEG_add_modifier_to_transform_relation(ctx->node, "UVWarp Modifier");
+ DEG_add_modifier_to_transform_relation(ctx->node, "UVWarp Modifier");
}
ModifierTypeInfo modifierType_UVWarp = {
- /* name */ "UVWarp",
- /* structName */ "UVWarpModifierData",
- /* structSize */ sizeof(UVWarpModifierData),
- /* type */ eModifierTypeType_NonGeometrical,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_EnableInEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "UVWarp",
+ /* structName */ "UVWarpModifierData",
+ /* structSize */ sizeof(UVWarpModifierData),
+ /* type */ eModifierTypeType_NonGeometrical,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode |
+ eModifierTypeFlag_EnableInEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c
index 30bd391ef84..67b91cfd963 100644
--- a/source/blender/modifiers/intern/MOD_warp.c
+++ b/source/blender/modifiers/intern/MOD_warp.c
@@ -46,332 +46,338 @@
#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;
+ 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(const ModifierData *md, ModifierData *target, const int flag)
{
- const WarpModifierData *wmd = (const WarpModifierData *) md;
- WarpModifierData *twmd = (WarpModifierData *) target;
+ const WarpModifierData *wmd = (const WarpModifierData *)md;
+ WarpModifierData *twmd = (WarpModifierData *)target;
- modifier_copyData_generic(md, target, flag);
+ modifier_copyData_generic(md, target, flag);
- twmd->curfalloff = curvemapping_copy(wmd->curfalloff);
+ twmd->curfalloff = curvemapping_copy(wmd->curfalloff);
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- WarpModifierData *wmd = (WarpModifierData *)md;
+ WarpModifierData *wmd = (WarpModifierData *)md;
- /* ask for vertexgroups if we need them */
- if (wmd->defgrp_name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ /* ask for vertexgroups if we need them */
+ if (wmd->defgrp_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
- /* ask for UV coordinates if we need them */
- if (wmd->texmapping == MOD_DISP_MAP_UV) {
- r_cddata_masks->fmask |= CD_MASK_MTFACE;
- }
+ /* ask for UV coordinates if we need them */
+ if (wmd->texmapping == MOD_DISP_MAP_UV) {
+ r_cddata_masks->fmask |= CD_MASK_MTFACE;
+ }
}
static bool dependsOnTime(ModifierData *md)
{
- WarpModifierData *wmd = (WarpModifierData *)md;
-
- if (wmd->texture) {
- return BKE_texture_dependsOnTime(wmd->texture);
- }
- else {
- return false;
- }
+ WarpModifierData *wmd = (WarpModifierData *)md;
+
+ if (wmd->texture) {
+ return BKE_texture_dependsOnTime(wmd->texture);
+ }
+ else {
+ return false;
+ }
}
static void freeData(ModifierData *md)
{
- WarpModifierData *wmd = (WarpModifierData *) md;
- curvemapping_free(wmd->curfalloff);
+ WarpModifierData *wmd = (WarpModifierData *)md;
+ curvemapping_free(wmd->curfalloff);
}
-
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(userRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(userRenderParams))
{
- WarpModifierData *wmd = (WarpModifierData *) md;
+ WarpModifierData *wmd = (WarpModifierData *)md;
- return !(wmd->object_from && wmd->object_to);
+ return !(wmd->object_from && wmd->object_to);
}
static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- WarpModifierData *wmd = (WarpModifierData *) md;
+ WarpModifierData *wmd = (WarpModifierData *)md;
- walk(userData, ob, &wmd->object_from, IDWALK_CB_NOP);
- walk(userData, ob, &wmd->object_to, IDWALK_CB_NOP);
- walk(userData, ob, &wmd->map_object, IDWALK_CB_NOP);
+ walk(userData, ob, &wmd->object_from, IDWALK_CB_NOP);
+ walk(userData, ob, &wmd->object_to, IDWALK_CB_NOP);
+ walk(userData, ob, &wmd->map_object, IDWALK_CB_NOP);
}
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
- WarpModifierData *wmd = (WarpModifierData *) md;
+ WarpModifierData *wmd = (WarpModifierData *)md;
- walk(userData, ob, (ID **)&wmd->texture, IDWALK_CB_USER);
+ walk(userData, ob, (ID **)&wmd->texture, IDWALK_CB_USER);
- foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
+ foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
}
static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
{
- walk(userData, ob, md, "texture");
+ walk(userData, ob, md, "texture");
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- WarpModifierData *wmd = (WarpModifierData *) md;
- if (wmd->object_from != NULL && wmd->object_to != NULL) {
- DEG_add_modifier_to_transform_relation(ctx->node, "Warplace Modifier");
- DEG_add_object_relation(ctx->node, wmd->object_from, DEG_OB_COMP_TRANSFORM, "Warp Modifier from");
- DEG_add_object_relation(ctx->node, wmd->object_to, DEG_OB_COMP_TRANSFORM, "Warp Modifier to");
- }
- if ((wmd->texmapping == MOD_DISP_MAP_OBJECT) && wmd->map_object != NULL) {
- DEG_add_object_relation(ctx->node, wmd->map_object, DEG_OB_COMP_TRANSFORM, "Warp Modifier map");
- }
- if (wmd->texture != NULL) {
- DEG_add_generic_id_relation(ctx->node, &wmd->texture->id, "Warp Modifier");
- }
+ WarpModifierData *wmd = (WarpModifierData *)md;
+ if (wmd->object_from != NULL && wmd->object_to != NULL) {
+ DEG_add_modifier_to_transform_relation(ctx->node, "Warplace Modifier");
+ DEG_add_object_relation(
+ ctx->node, wmd->object_from, DEG_OB_COMP_TRANSFORM, "Warp Modifier from");
+ DEG_add_object_relation(ctx->node, wmd->object_to, DEG_OB_COMP_TRANSFORM, "Warp Modifier to");
+ }
+ if ((wmd->texmapping == MOD_DISP_MAP_OBJECT) && wmd->map_object != NULL) {
+ DEG_add_object_relation(
+ ctx->node, wmd->map_object, DEG_OB_COMP_TRANSFORM, "Warp Modifier map");
+ }
+ if (wmd->texture != NULL) {
+ DEG_add_generic_id_relation(ctx->node, &wmd->texture->id, "Warp Modifier");
+ }
}
-static void warpModifier_do(
- WarpModifierData *wmd, const ModifierEvalContext *ctx,
- Mesh *mesh, float (*vertexCos)[3], int numVerts)
+static void warpModifier_do(WarpModifierData *wmd,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- Object *ob = ctx->object;
- 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];
-
- const float falloff_radius_sq = SQUARE(wmd->falloff_radius);
- float strength = wmd->strength;
- float fac = 1.0f, weight;
- int i;
- int defgrp_index;
- MDeformVert *dvert, *dv = NULL;
-
- float (*tex_co)[3] = NULL;
-
- if (!(wmd->object_from && wmd->object_to))
- return;
-
- MOD_get_vgroup(ob, mesh, wmd->defgrp_name, &dvert, &defgrp_index);
- if (dvert == NULL) {
- defgrp_index = -1;
- }
-
- 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);
-
- if (wmd->curfalloff) {
- curvemapping_initialize(wmd->curfalloff);
- }
-
- invert_m4_m4(obinv, ob->obmat);
-
- mul_m4_m4m4(mat_from, obinv, wmd->object_from->obmat);
- mul_m4_m4m4(mat_to, obinv, wmd->object_to->obmat);
-
- invert_m4_m4(tmat, mat_from); // swap?
- mul_m4_m4m4(mat_final, tmat, mat_to);
-
- invert_m4_m4(mat_from_inv, mat_from);
-
- unit_m4(mat_unit);
-
- if (strength < 0.0f) {
- float loc[3];
- strength = -strength;
-
- /* inverted location is not useful, just use the negative */
- copy_v3_v3(loc, mat_final[3]);
- invert_m4(mat_final);
- negate_v3_v3(mat_final[3], loc);
-
- }
- weight = strength;
-
- Tex *tex_target = wmd->texture;
- if (mesh != NULL && tex_target != NULL) {
- tex_co = MEM_malloc_arrayN(numVerts, sizeof(*tex_co), "warpModifier_do tex_co");
- MOD_get_texture_coords((MappingInfoModifierData *)wmd, ctx, ob, mesh, vertexCos, tex_co);
-
- MOD_init_texture((MappingInfoModifierData *)wmd, ctx);
- }
-
- for (i = 0; i < numVerts; i++) {
- float *co = vertexCos[i];
-
- if (wmd->falloff_type == eWarp_Falloff_None ||
- ((fac = len_squared_v3v3(co, mat_from[3])) < falloff_radius_sq &&
- (fac = (wmd->falloff_radius - sqrtf(fac)) / wmd->falloff_radius)))
- {
- /* skip if no vert group found */
- if (defgrp_index != -1) {
- dv = &dvert[i];
- weight = defvert_find_weight(dv, defgrp_index) * 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 = sqrtf(fac);
- break;
- case eWarp_Falloff_Linear:
- /* pass */
- break;
- case eWarp_Falloff_Const:
- fac = 1.0f;
- break;
- case eWarp_Falloff_Sphere:
- fac = sqrtf(2 * fac - fac * fac);
- break;
- case eWarp_Falloff_InvSquare:
- fac = fac * (2.0f - fac);
- break;
- }
-
- fac *= weight;
-
- if (tex_co) {
- struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- TexResult texres;
- texres.nor = NULL;
- BKE_texture_get_value(scene, tex_target, tex_co[i], &texres, false);
- fac *= texres.tin;
- }
-
- if (fac != 0.0f) {
- /* into the 'from' objects space */
- mul_m4_v3(mat_from_inv, co);
-
- if (fac == 1.0f) {
- mul_m4_v3(mat_final, co);
- }
- else {
- 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);
- }
+ Object *ob = ctx->object;
+ 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];
+
+ const float falloff_radius_sq = SQUARE(wmd->falloff_radius);
+ float strength = wmd->strength;
+ float fac = 1.0f, weight;
+ int i;
+ int defgrp_index;
+ MDeformVert *dvert, *dv = NULL;
+
+ float(*tex_co)[3] = NULL;
+
+ if (!(wmd->object_from && wmd->object_to))
+ return;
+
+ MOD_get_vgroup(ob, mesh, wmd->defgrp_name, &dvert, &defgrp_index);
+ if (dvert == NULL) {
+ defgrp_index = -1;
+ }
+
+ 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);
+
+ if (wmd->curfalloff) {
+ curvemapping_initialize(wmd->curfalloff);
+ }
+
+ invert_m4_m4(obinv, ob->obmat);
+
+ mul_m4_m4m4(mat_from, obinv, wmd->object_from->obmat);
+ mul_m4_m4m4(mat_to, obinv, wmd->object_to->obmat);
+
+ invert_m4_m4(tmat, mat_from); // swap?
+ mul_m4_m4m4(mat_final, tmat, mat_to);
+
+ invert_m4_m4(mat_from_inv, mat_from);
+
+ unit_m4(mat_unit);
+
+ if (strength < 0.0f) {
+ float loc[3];
+ strength = -strength;
+
+ /* inverted location is not useful, just use the negative */
+ copy_v3_v3(loc, mat_final[3]);
+ invert_m4(mat_final);
+ negate_v3_v3(mat_final[3], loc);
+ }
+ weight = strength;
+
+ Tex *tex_target = wmd->texture;
+ if (mesh != NULL && tex_target != NULL) {
+ tex_co = MEM_malloc_arrayN(numVerts, sizeof(*tex_co), "warpModifier_do tex_co");
+ MOD_get_texture_coords((MappingInfoModifierData *)wmd, ctx, ob, mesh, vertexCos, tex_co);
+
+ MOD_init_texture((MappingInfoModifierData *)wmd, ctx);
+ }
+
+ for (i = 0; i < numVerts; i++) {
+ float *co = vertexCos[i];
+
+ if (wmd->falloff_type == eWarp_Falloff_None ||
+ ((fac = len_squared_v3v3(co, mat_from[3])) < falloff_radius_sq &&
+ (fac = (wmd->falloff_radius - sqrtf(fac)) / wmd->falloff_radius))) {
+ /* skip if no vert group found */
+ if (defgrp_index != -1) {
+ dv = &dvert[i];
+ weight = defvert_find_weight(dv, defgrp_index) * 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 = sqrtf(fac);
+ break;
+ case eWarp_Falloff_Linear:
+ /* pass */
+ break;
+ case eWarp_Falloff_Const:
+ fac = 1.0f;
+ break;
+ case eWarp_Falloff_Sphere:
+ fac = sqrtf(2 * fac - fac * fac);
+ break;
+ case eWarp_Falloff_InvSquare:
+ fac = fac * (2.0f - fac);
+ break;
+ }
+
+ fac *= weight;
+
+ if (tex_co) {
+ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ TexResult texres;
+ texres.nor = NULL;
+ BKE_texture_get_value(scene, tex_target, tex_co[i], &texres, false);
+ fac *= texres.tin;
+ }
+
+ if (fac != 0.0f) {
+ /* into the 'from' objects space */
+ mul_m4_v3(mat_from_inv, co);
+
+ if (fac == 1.0f) {
+ mul_m4_v3(mat_final, co);
+ }
+ else {
+ 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 void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh,
- float (*vertexCos)[3], int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- WarpModifierData *wmd = (WarpModifierData *)md;
- Mesh *mesh_src = NULL;
+ WarpModifierData *wmd = (WarpModifierData *)md;
+ Mesh *mesh_src = NULL;
- if (wmd->defgrp_name[0] != '\0' || wmd->texture != NULL) {
- /* mesh_src is only needed for vgroups and textures. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
- }
+ if (wmd->defgrp_name[0] != '\0' || wmd->texture != NULL) {
+ /* mesh_src is only needed for vgroups and textures. */
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ }
- warpModifier_do(wmd, ctx, mesh_src, vertexCos, numVerts);
+ warpModifier_do(wmd, ctx, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-static void deformVertsEM(
- ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *em,
- Mesh *mesh, float (*vertexCos)[3], int numVerts)
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *em,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- WarpModifierData *wmd = (WarpModifierData *)md;
- Mesh *mesh_src = NULL;
+ WarpModifierData *wmd = (WarpModifierData *)md;
+ Mesh *mesh_src = NULL;
- if (wmd->defgrp_name[0] != '\0' || wmd->texture != NULL) {
- /* mesh_src is only needed for vgroups and textures. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false);
- }
+ if (wmd->defgrp_name[0] != '\0' || wmd->texture != NULL) {
+ /* mesh_src is only needed for vgroups and textures. */
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false);
+ }
- warpModifier_do(wmd, ctx, mesh_src, vertexCos, numVerts);
+ warpModifier_do(wmd, ctx, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-
ModifierTypeInfo modifierType_Warp = {
- /* name */ "Warp",
- /* structName */ "WarpModifierData",
- /* structSize */ sizeof(WarpModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_AcceptsLattice |
- eModifierTypeFlag_SupportsEditmode,
- /* copyData */ copyData,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ freeData,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ foreachIDLink,
- /* foreachTexLink */ foreachTexLink,
- /* freeRuntimeData */ NULL,
+ /* name */ "Warp",
+ /* structName */ "WarpModifierData",
+ /* structSize */ sizeof(WarpModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice |
+ eModifierTypeFlag_SupportsEditmode,
+ /* copyData */ copyData,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ freeData,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ foreachTexLink,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c
index d5c372a2809..c0b686dd098 100644
--- a/source/blender/modifiers/intern/MOD_wave.c
+++ b/source/blender/modifiers/intern/MOD_wave.c
@@ -21,7 +21,6 @@
* \ingroup modifiers
*/
-
#include "BLI_utildefines.h"
#include "BLI_math.h"
@@ -50,328 +49,327 @@
static void initData(ModifierData *md)
{
- WaveModifierData *wmd = (WaveModifierData *) md; // whadya know, moved here from Iraq
-
- wmd->flag |= (MOD_WAVE_X | MOD_WAVE_Y | MOD_WAVE_CYCL |
- MOD_WAVE_NORM_X | MOD_WAVE_NORM_Y | MOD_WAVE_NORM_Z);
-
- wmd->objectcenter = NULL;
- wmd->texture = NULL;
- wmd->map_object = NULL;
- wmd->height = 0.5f;
- wmd->width = 1.5f;
- wmd->speed = 0.25f;
- wmd->narrow = 1.5f;
- wmd->lifetime = 0.0f;
- wmd->damp = 10.0f;
- wmd->falloff = 0.0f;
- wmd->texmapping = MOD_DISP_MAP_LOCAL;
- wmd->defgrp_name[0] = 0;
+ WaveModifierData *wmd = (WaveModifierData *)md; // whadya know, moved here from Iraq
+
+ wmd->flag |= (MOD_WAVE_X | MOD_WAVE_Y | MOD_WAVE_CYCL | MOD_WAVE_NORM_X | MOD_WAVE_NORM_Y |
+ MOD_WAVE_NORM_Z);
+
+ wmd->objectcenter = NULL;
+ wmd->texture = NULL;
+ wmd->map_object = NULL;
+ wmd->height = 0.5f;
+ wmd->width = 1.5f;
+ wmd->speed = 0.25f;
+ wmd->narrow = 1.5f;
+ wmd->lifetime = 0.0f;
+ wmd->damp = 10.0f;
+ wmd->falloff = 0.0f;
+ wmd->texmapping = MOD_DISP_MAP_LOCAL;
+ wmd->defgrp_name[0] = 0;
}
static bool dependsOnTime(ModifierData *UNUSED(md))
{
- return true;
+ return true;
}
-static void foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- WaveModifierData *wmd = (WaveModifierData *) md;
+ WaveModifierData *wmd = (WaveModifierData *)md;
- walk(userData, ob, &wmd->objectcenter, IDWALK_CB_NOP);
- walk(userData, ob, &wmd->map_object, IDWALK_CB_NOP);
+ walk(userData, ob, &wmd->objectcenter, IDWALK_CB_NOP);
+ walk(userData, ob, &wmd->map_object, IDWALK_CB_NOP);
}
-static void foreachIDLink(
- ModifierData *md, Object *ob,
- IDWalkFunc walk, void *userData)
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
- WaveModifierData *wmd = (WaveModifierData *) md;
+ WaveModifierData *wmd = (WaveModifierData *)md;
- walk(userData, ob, (ID **)&wmd->texture, IDWALK_CB_USER);
+ walk(userData, ob, (ID **)&wmd->texture, IDWALK_CB_USER);
- foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
+ foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
}
-static void foreachTexLink(
- ModifierData *md, Object *ob,
- TexWalkFunc walk, void *userData)
+static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
{
- walk(userData, ob, md, "texture");
+ walk(userData, ob, md, "texture");
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- WaveModifierData *wmd = (WaveModifierData *)md;
- if (wmd->objectcenter != NULL) {
- DEG_add_object_relation(ctx->node, wmd->objectcenter, DEG_OB_COMP_TRANSFORM, "Wave Modifier");
- }
- if (wmd->map_object != NULL) {
- DEG_add_object_relation(ctx->node, wmd->map_object, DEG_OB_COMP_TRANSFORM, "Wave Modifier");
- }
- if (wmd->objectcenter != NULL || wmd->map_object != NULL) {
- DEG_add_modifier_to_transform_relation(ctx->node, "Wave Modifier");
- }
- if (wmd->texture != NULL) {
- DEG_add_generic_id_relation(ctx->node, &wmd->texture->id, "Wave Modifier");
- }
+ WaveModifierData *wmd = (WaveModifierData *)md;
+ if (wmd->objectcenter != NULL) {
+ DEG_add_object_relation(ctx->node, wmd->objectcenter, DEG_OB_COMP_TRANSFORM, "Wave Modifier");
+ }
+ if (wmd->map_object != NULL) {
+ DEG_add_object_relation(ctx->node, wmd->map_object, DEG_OB_COMP_TRANSFORM, "Wave Modifier");
+ }
+ if (wmd->objectcenter != NULL || wmd->map_object != NULL) {
+ DEG_add_modifier_to_transform_relation(ctx->node, "Wave Modifier");
+ }
+ if (wmd->texture != NULL) {
+ DEG_add_generic_id_relation(ctx->node, &wmd->texture->id, "Wave Modifier");
+ }
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- WaveModifierData *wmd = (WaveModifierData *)md;
+ WaveModifierData *wmd = (WaveModifierData *)md;
- /* ask for UV coordinates if we need them */
- if (wmd->texture && wmd->texmapping == MOD_DISP_MAP_UV) {
- r_cddata_masks->fmask |= CD_MASK_MTFACE;
- }
+ /* ask for UV coordinates if we need them */
+ if (wmd->texture && wmd->texmapping == MOD_DISP_MAP_UV) {
+ r_cddata_masks->fmask |= CD_MASK_MTFACE;
+ }
- /* ask for vertexgroups if we need them */
- if (wmd->defgrp_name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ /* ask for vertexgroups if we need them */
+ if (wmd->defgrp_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
static bool dependsOnNormals(ModifierData *md)
{
- WaveModifierData *wmd = (WaveModifierData *)md;
+ WaveModifierData *wmd = (WaveModifierData *)md;
- return (wmd->flag & MOD_WAVE_NORM) != 0;
+ return (wmd->flag & MOD_WAVE_NORM) != 0;
}
-static void waveModifier_do(
- WaveModifierData *md,
- const ModifierEvalContext *ctx,
- Object *ob, Mesh *mesh,
- float (*vertexCos)[3], int numVerts)
+static void waveModifier_do(WaveModifierData *md,
+ const ModifierEvalContext *ctx,
+ Object *ob,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- WaveModifierData *wmd = (WaveModifierData *) md;
- MVert *mvert = NULL;
- MDeformVert *dvert;
- int defgrp_index;
- float ctime = DEG_get_ctime(ctx->depsgraph);
- float minfac = (float)(1.0 / exp(wmd->width * wmd->narrow * wmd->width * wmd->narrow));
- float lifefac = wmd->height;
- float (*tex_co)[3] = NULL;
- const int wmd_axis = wmd->flag & (MOD_WAVE_X | MOD_WAVE_Y);
- const float falloff = wmd->falloff;
- float falloff_fac = 1.0f; /* when falloff == 0.0f this stays at 1.0f */
-
- if ((wmd->flag & MOD_WAVE_NORM) && (mesh != NULL)) {
- mvert = mesh->mvert;
- }
-
- if (wmd->objectcenter != NULL) {
- float mat[4][4];
- /* get the control object's location in local coordinates */
- invert_m4_m4(ob->imat, ob->obmat);
- mul_m4_m4m4(mat, ob->imat, wmd->objectcenter->obmat);
-
- wmd->startx = mat[3][0];
- wmd->starty = mat[3][1];
- }
-
- /* get the index of the deform group */
- MOD_get_vgroup(ob, mesh, wmd->defgrp_name, &dvert, &defgrp_index);
-
- if (wmd->damp == 0.0f) {
- wmd->damp = 10.0f;
- }
-
- if (wmd->lifetime != 0.0f) {
- float x = ctime - wmd->timeoffs;
-
- if (x > wmd->lifetime) {
- lifefac = x - wmd->lifetime;
-
- if (lifefac > wmd->damp) lifefac = 0.0;
- else lifefac = (float)(wmd->height * (1.0f - sqrtf(lifefac / wmd->damp)));
- }
- }
-
- Tex *tex_target = wmd->texture;
- if (mesh != NULL && tex_target != NULL) {
- tex_co = MEM_malloc_arrayN(numVerts, sizeof(*tex_co), "waveModifier_do tex_co");
- MOD_get_texture_coords((MappingInfoModifierData *)wmd, ctx, ob, mesh, vertexCos, tex_co);
-
- MOD_init_texture((MappingInfoModifierData *)wmd, ctx);
- }
-
- if (lifefac != 0.0f) {
- /* avoid divide by zero checks within the loop */
- float falloff_inv = falloff != 0.0f ? 1.0f / falloff : 1.0f;
- int i;
-
- for (i = 0; i < numVerts; i++) {
- float *co = vertexCos[i];
- float x = co[0] - wmd->startx;
- float y = co[1] - wmd->starty;
- float amplit = 0.0f;
- float def_weight = 1.0f;
-
- /* get weights */
- if (dvert) {
- def_weight = defvert_find_weight(&dvert[i], defgrp_index);
-
- /* if this vert isn't in the vgroup, don't deform it */
- if (def_weight == 0.0f) {
- continue;
- }
- }
-
- switch (wmd_axis) {
- case MOD_WAVE_X | MOD_WAVE_Y:
- amplit = sqrtf(x * x + y * y);
- break;
- case MOD_WAVE_X:
- amplit = x;
- break;
- case MOD_WAVE_Y:
- amplit = y;
- break;
- }
-
- /* this way it makes nice circles */
- amplit -= (ctime - wmd->timeoffs) * wmd->speed;
-
- if (wmd->flag & MOD_WAVE_CYCL) {
- amplit = (float)fmodf(amplit - wmd->width, 2.0f * wmd->width) +
- wmd->width;
- }
-
- if (falloff != 0.0f) {
- float dist = 0.0f;
-
- switch (wmd_axis) {
- case MOD_WAVE_X | MOD_WAVE_Y:
- dist = sqrtf(x * x + y * y);
- break;
- case MOD_WAVE_X:
- dist = fabsf(x);
- break;
- case MOD_WAVE_Y:
- dist = fabsf(y);
- break;
- }
-
- falloff_fac = (1.0f - (dist * falloff_inv));
- CLAMP(falloff_fac, 0.0f, 1.0f);
- }
-
- /* GAUSSIAN */
- if ((falloff_fac != 0.0f) && (amplit > -wmd->width) && (amplit < wmd->width)) {
- amplit = amplit * wmd->narrow;
- amplit = (float)(1.0f / expf(amplit * amplit) - minfac);
-
- /*apply texture*/
- if (tex_target) {
- Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- TexResult texres;
- texres.nor = NULL;
- BKE_texture_get_value(scene, tex_target, tex_co[i], &texres, false);
- amplit *= texres.tin;
- }
-
- /*apply weight & falloff */
- amplit *= def_weight * falloff_fac;
-
- if (mvert) {
- /* move along normals */
- if (wmd->flag & MOD_WAVE_NORM_X) {
- co[0] += (lifefac * amplit) * mvert[i].no[0] / 32767.0f;
- }
- if (wmd->flag & MOD_WAVE_NORM_Y) {
- co[1] += (lifefac * amplit) * mvert[i].no[1] / 32767.0f;
- }
- if (wmd->flag & MOD_WAVE_NORM_Z) {
- co[2] += (lifefac * amplit) * mvert[i].no[2] / 32767.0f;
- }
- }
- else {
- /* move along local z axis */
- co[2] += lifefac * amplit;
- }
- }
- }
- }
-
- MEM_SAFE_FREE(tex_co);
+ WaveModifierData *wmd = (WaveModifierData *)md;
+ MVert *mvert = NULL;
+ MDeformVert *dvert;
+ int defgrp_index;
+ float ctime = DEG_get_ctime(ctx->depsgraph);
+ float minfac = (float)(1.0 / exp(wmd->width * wmd->narrow * wmd->width * wmd->narrow));
+ float lifefac = wmd->height;
+ float(*tex_co)[3] = NULL;
+ const int wmd_axis = wmd->flag & (MOD_WAVE_X | MOD_WAVE_Y);
+ const float falloff = wmd->falloff;
+ float falloff_fac = 1.0f; /* when falloff == 0.0f this stays at 1.0f */
+
+ if ((wmd->flag & MOD_WAVE_NORM) && (mesh != NULL)) {
+ mvert = mesh->mvert;
+ }
+
+ if (wmd->objectcenter != NULL) {
+ float mat[4][4];
+ /* get the control object's location in local coordinates */
+ invert_m4_m4(ob->imat, ob->obmat);
+ mul_m4_m4m4(mat, ob->imat, wmd->objectcenter->obmat);
+
+ wmd->startx = mat[3][0];
+ wmd->starty = mat[3][1];
+ }
+
+ /* get the index of the deform group */
+ MOD_get_vgroup(ob, mesh, wmd->defgrp_name, &dvert, &defgrp_index);
+
+ if (wmd->damp == 0.0f) {
+ wmd->damp = 10.0f;
+ }
+
+ if (wmd->lifetime != 0.0f) {
+ float x = ctime - wmd->timeoffs;
+
+ if (x > wmd->lifetime) {
+ lifefac = x - wmd->lifetime;
+
+ if (lifefac > wmd->damp)
+ lifefac = 0.0;
+ else
+ lifefac = (float)(wmd->height * (1.0f - sqrtf(lifefac / wmd->damp)));
+ }
+ }
+
+ Tex *tex_target = wmd->texture;
+ if (mesh != NULL && tex_target != NULL) {
+ tex_co = MEM_malloc_arrayN(numVerts, sizeof(*tex_co), "waveModifier_do tex_co");
+ MOD_get_texture_coords((MappingInfoModifierData *)wmd, ctx, ob, mesh, vertexCos, tex_co);
+
+ MOD_init_texture((MappingInfoModifierData *)wmd, ctx);
+ }
+
+ if (lifefac != 0.0f) {
+ /* avoid divide by zero checks within the loop */
+ float falloff_inv = falloff != 0.0f ? 1.0f / falloff : 1.0f;
+ int i;
+
+ for (i = 0; i < numVerts; i++) {
+ float *co = vertexCos[i];
+ float x = co[0] - wmd->startx;
+ float y = co[1] - wmd->starty;
+ float amplit = 0.0f;
+ float def_weight = 1.0f;
+
+ /* get weights */
+ if (dvert) {
+ def_weight = defvert_find_weight(&dvert[i], defgrp_index);
+
+ /* if this vert isn't in the vgroup, don't deform it */
+ if (def_weight == 0.0f) {
+ continue;
+ }
+ }
+
+ switch (wmd_axis) {
+ case MOD_WAVE_X | MOD_WAVE_Y:
+ amplit = sqrtf(x * x + y * y);
+ break;
+ case MOD_WAVE_X:
+ amplit = x;
+ break;
+ case MOD_WAVE_Y:
+ amplit = y;
+ break;
+ }
+
+ /* this way it makes nice circles */
+ amplit -= (ctime - wmd->timeoffs) * wmd->speed;
+
+ if (wmd->flag & MOD_WAVE_CYCL) {
+ amplit = (float)fmodf(amplit - wmd->width, 2.0f * wmd->width) + wmd->width;
+ }
+
+ if (falloff != 0.0f) {
+ float dist = 0.0f;
+
+ switch (wmd_axis) {
+ case MOD_WAVE_X | MOD_WAVE_Y:
+ dist = sqrtf(x * x + y * y);
+ break;
+ case MOD_WAVE_X:
+ dist = fabsf(x);
+ break;
+ case MOD_WAVE_Y:
+ dist = fabsf(y);
+ break;
+ }
+
+ falloff_fac = (1.0f - (dist * falloff_inv));
+ CLAMP(falloff_fac, 0.0f, 1.0f);
+ }
+
+ /* GAUSSIAN */
+ if ((falloff_fac != 0.0f) && (amplit > -wmd->width) && (amplit < wmd->width)) {
+ amplit = amplit * wmd->narrow;
+ amplit = (float)(1.0f / expf(amplit * amplit) - minfac);
+
+ /*apply texture*/
+ if (tex_target) {
+ Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ TexResult texres;
+ texres.nor = NULL;
+ BKE_texture_get_value(scene, tex_target, tex_co[i], &texres, false);
+ amplit *= texres.tin;
+ }
+
+ /*apply weight & falloff */
+ amplit *= def_weight * falloff_fac;
+
+ if (mvert) {
+ /* move along normals */
+ if (wmd->flag & MOD_WAVE_NORM_X) {
+ co[0] += (lifefac * amplit) * mvert[i].no[0] / 32767.0f;
+ }
+ if (wmd->flag & MOD_WAVE_NORM_Y) {
+ co[1] += (lifefac * amplit) * mvert[i].no[1] / 32767.0f;
+ }
+ if (wmd->flag & MOD_WAVE_NORM_Z) {
+ co[2] += (lifefac * amplit) * mvert[i].no[2] / 32767.0f;
+ }
+ }
+ else {
+ /* move along local z axis */
+ co[2] += lifefac * amplit;
+ }
+ }
+ }
+ }
+
+ MEM_SAFE_FREE(tex_co);
}
-static void deformVerts(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh,
- float (*vertexCos)[3],
- int numVerts)
+static void deformVerts(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- WaveModifierData *wmd = (WaveModifierData *)md;
- Mesh *mesh_src = NULL;
+ WaveModifierData *wmd = (WaveModifierData *)md;
+ Mesh *mesh_src = NULL;
- if (wmd->flag & MOD_WAVE_NORM) {
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, vertexCos, numVerts, true, false);
- }
- else if (wmd->texture != NULL || wmd->defgrp_name[0] != '\0') {
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
- }
+ if (wmd->flag & MOD_WAVE_NORM) {
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, vertexCos, numVerts, true, false);
+ }
+ else if (wmd->texture != NULL || wmd->defgrp_name[0] != '\0') {
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ }
- waveModifier_do(wmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+ waveModifier_do(wmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-static void deformVertsEM(
- ModifierData *md, const ModifierEvalContext *ctx,
- struct BMEditMesh *editData,
- Mesh *mesh, float (*vertexCos)[3], int numVerts)
+static void deformVertsEM(ModifierData *md,
+ const ModifierEvalContext *ctx,
+ struct BMEditMesh *editData,
+ Mesh *mesh,
+ float (*vertexCos)[3],
+ int numVerts)
{
- WaveModifierData *wmd = (WaveModifierData *)md;
- Mesh *mesh_src = NULL;
-
- if (wmd->flag & MOD_WAVE_NORM) {
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, vertexCos, numVerts, true, false);
- }
- else if (wmd->texture != NULL || wmd->defgrp_name[0] != '\0') {
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
- }
-
- waveModifier_do(wmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
-
- if (!ELEM(mesh_src, NULL, mesh)) {
- BKE_id_free(NULL, mesh_src);
- }
+ WaveModifierData *wmd = (WaveModifierData *)md;
+ Mesh *mesh_src = NULL;
+
+ if (wmd->flag & MOD_WAVE_NORM) {
+ mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, editData, mesh, vertexCos, numVerts, true, false);
+ }
+ else if (wmd->texture != NULL || wmd->defgrp_name[0] != '\0') {
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ }
+
+ waveModifier_do(wmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
-
ModifierTypeInfo modifierType_Wave = {
- /* name */ "Wave",
- /* structName */ "WaveModifierData",
- /* structSize */ sizeof(WaveModifierData),
- /* type */ eModifierTypeType_OnlyDeform,
- /* flags */ eModifierTypeFlag_AcceptsCVs |
- eModifierTypeFlag_AcceptsLattice |
- eModifierTypeFlag_SupportsEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ deformVerts,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ deformVertsEM,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ NULL,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ foreachIDLink,
- /* foreachTexLink */ foreachTexLink,
- /* freeRuntimeData */ NULL,
+ /* name */ "Wave",
+ /* structName */ "WaveModifierData",
+ /* structSize */ sizeof(WaveModifierData),
+ /* type */ eModifierTypeType_OnlyDeform,
+ /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsLattice |
+ eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ deformVerts,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ deformVertsEM,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ NULL,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ dependsOnNormals,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ foreachTexLink,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.c b/source/blender/modifiers/intern/MOD_weighted_normal.c
index 98b2117e5a3..2162f223b7a 100644
--- a/source/blender/modifiers/intern/MOD_weighted_normal.c
+++ b/source/blender/modifiers/intern/MOD_weighted_normal.c
@@ -38,616 +38,678 @@
#define CLNORS_VALID_VEC_LEN (1e-6f)
typedef struct ModePair {
- float val; /* Contains mode based value (face area / corner angle). */
- int index; /* Index value per poly or per loop. */
+ float val; /* Contains mode based value (face area / corner angle). */
+ int index; /* Index value per poly or per loop. */
} ModePair;
/* Sorting function used in modifier, sorts in decreasing order. */
static int modepair_cmp_by_val_inverse(const void *p1, const void *p2)
{
- ModePair *r1 = (ModePair *)p1;
- ModePair *r2 = (ModePair *)p2;
+ ModePair *r1 = (ModePair *)p1;
+ ModePair *r2 = (ModePair *)p2;
- return (r1->val < r2->val) ? 1 : ((r1->val > r2->val) ? -1 : 0);
+ return (r1->val < r2->val) ? 1 : ((r1->val > r2->val) ? -1 : 0);
}
/* There will be one of those per vertex (simple case, computing one normal per vertex), or per smooth fan. */
typedef struct WeightedNormalDataAggregateItem {
- float normal[3];
+ float normal[3];
- int num_loops; /* Count number of loops using this item so far. */
- float curr_val; /* Current max val for this item. */
- int curr_strength; /* Current max strength encountered for this item. */
+ int num_loops; /* Count number of loops using this item so far. */
+ float curr_val; /* Current max val for this item. */
+ int curr_strength; /* Current max strength encountered for this item. */
} WeightedNormalDataAggregateItem;
#define NUM_CACHED_INVERSE_POWERS_OF_WEIGHT 128
typedef struct WeightedNormalData {
- const int numVerts;
- const int numEdges;
- const int numLoops;
- const int numPolys;
+ const int numVerts;
+ const int numEdges;
+ const int numLoops;
+ const int numPolys;
- MVert *mvert;
- MEdge *medge;
+ MVert *mvert;
+ MEdge *medge;
- MLoop *mloop;
- short (*clnors)[2];
- const bool has_clnors; /* True if clnors already existed, false if we had to create them. */
- const float split_angle;
+ MLoop *mloop;
+ short (*clnors)[2];
+ const bool has_clnors; /* True if clnors already existed, false if we had to create them. */
+ const float split_angle;
- MPoly *mpoly;
- float (*polynors)[3];
- int *poly_strength;
+ MPoly *mpoly;
+ float (*polynors)[3];
+ int *poly_strength;
- MDeformVert *dvert;
- const int defgrp_index;
- const bool use_invert_vgroup;
+ MDeformVert *dvert;
+ const int defgrp_index;
+ const bool use_invert_vgroup;
- const float weight;
- const short mode;
+ const float weight;
+ const short mode;
- /* Lower-level, internal processing data. */
- float cached_inverse_powers_of_weight[NUM_CACHED_INVERSE_POWERS_OF_WEIGHT];
+ /* Lower-level, internal processing data. */
+ float cached_inverse_powers_of_weight[NUM_CACHED_INVERSE_POWERS_OF_WEIGHT];
- WeightedNormalDataAggregateItem *items_data;
+ WeightedNormalDataAggregateItem *items_data;
- ModePair *mode_pair;
+ ModePair *mode_pair;
- int *loop_to_poly;
+ int *loop_to_poly;
} WeightedNormalData;
/* Check strength of given poly compared to those found so far for that given item (vertex or smooth fan),
* and reset matching item_data in case we get a stronger new strength. */
-static bool check_item_poly_strength(
- WeightedNormalData *wn_data, WeightedNormalDataAggregateItem *item_data, const int mp_index)
+static bool check_item_poly_strength(WeightedNormalData *wn_data,
+ WeightedNormalDataAggregateItem *item_data,
+ const int mp_index)
{
- BLI_assert (wn_data->poly_strength != NULL);
+ BLI_assert(wn_data->poly_strength != NULL);
- const int mp_strength = wn_data->poly_strength[mp_index];
+ const int mp_strength = wn_data->poly_strength[mp_index];
- if (mp_strength > item_data->curr_strength) {
- item_data->curr_strength = mp_strength;
- item_data->curr_val = 0.0f;
- item_data->num_loops = 0;
- zero_v3(item_data->normal);
- }
+ if (mp_strength > item_data->curr_strength) {
+ item_data->curr_strength = mp_strength;
+ item_data->curr_val = 0.0f;
+ item_data->num_loops = 0;
+ zero_v3(item_data->normal);
+ }
- return mp_strength == item_data->curr_strength;
+ return mp_strength == item_data->curr_strength;
}
-static void aggregate_item_normal(
- WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data,
- WeightedNormalDataAggregateItem *item_data,
- const int mv_index, const int mp_index,
- const float curr_val, const bool use_face_influence)
+static void aggregate_item_normal(WeightedNormalModifierData *wnmd,
+ WeightedNormalData *wn_data,
+ WeightedNormalDataAggregateItem *item_data,
+ const int mv_index,
+ const int mp_index,
+ const float curr_val,
+ const bool use_face_influence)
{
- float (*polynors)[3] = wn_data->polynors;
-
- MDeformVert *dvert = wn_data->dvert;
- const int defgrp_index = wn_data->defgrp_index;
- const bool use_invert_vgroup = wn_data->use_invert_vgroup;
-
- const float weight = wn_data->weight;
-
- float *cached_inverse_powers_of_weight = wn_data->cached_inverse_powers_of_weight;
-
- const bool has_vgroup = dvert != NULL;
- const bool vert_of_group = has_vgroup && defvert_find_index(&dvert[mv_index], defgrp_index) != NULL;
-
- if (has_vgroup && ((vert_of_group && use_invert_vgroup) || (!vert_of_group && !use_invert_vgroup))) {
- return;
- }
-
- if (use_face_influence && !check_item_poly_strength(wn_data, item_data, mp_index)) {
- return;
- }
-
- /* If item's curr_val is 0 init it to present value. */
- if (item_data->curr_val == 0.0f) {
- item_data->curr_val = curr_val;
- }
- if (!compare_ff(item_data->curr_val, curr_val, wnmd->thresh)) {
- /* item's curr_val and present value differ more than threshold, update. */
- item_data->num_loops++;
- item_data->curr_val = curr_val;
- }
-
- /* Exponentially divided weight for each normal (since a few values will be used by most cases, we cache those). */
- const int num_loops = item_data->num_loops;
- if (num_loops < NUM_CACHED_INVERSE_POWERS_OF_WEIGHT && cached_inverse_powers_of_weight[num_loops] == 0.0f) {
- cached_inverse_powers_of_weight[num_loops] = 1.0f / powf(weight, num_loops);
- }
- const float inverted_n_weight = num_loops < NUM_CACHED_INVERSE_POWERS_OF_WEIGHT ?
- cached_inverse_powers_of_weight[num_loops] : 1.0f / powf(weight, num_loops);
-
- madd_v3_v3fl(item_data->normal, polynors[mp_index], curr_val * inverted_n_weight);
+ float(*polynors)[3] = wn_data->polynors;
+
+ MDeformVert *dvert = wn_data->dvert;
+ const int defgrp_index = wn_data->defgrp_index;
+ const bool use_invert_vgroup = wn_data->use_invert_vgroup;
+
+ const float weight = wn_data->weight;
+
+ float *cached_inverse_powers_of_weight = wn_data->cached_inverse_powers_of_weight;
+
+ const bool has_vgroup = dvert != NULL;
+ const bool vert_of_group = has_vgroup &&
+ defvert_find_index(&dvert[mv_index], defgrp_index) != NULL;
+
+ if (has_vgroup &&
+ ((vert_of_group && use_invert_vgroup) || (!vert_of_group && !use_invert_vgroup))) {
+ return;
+ }
+
+ if (use_face_influence && !check_item_poly_strength(wn_data, item_data, mp_index)) {
+ return;
+ }
+
+ /* If item's curr_val is 0 init it to present value. */
+ if (item_data->curr_val == 0.0f) {
+ item_data->curr_val = curr_val;
+ }
+ if (!compare_ff(item_data->curr_val, curr_val, wnmd->thresh)) {
+ /* item's curr_val and present value differ more than threshold, update. */
+ item_data->num_loops++;
+ item_data->curr_val = curr_val;
+ }
+
+ /* Exponentially divided weight for each normal (since a few values will be used by most cases, we cache those). */
+ const int num_loops = item_data->num_loops;
+ if (num_loops < NUM_CACHED_INVERSE_POWERS_OF_WEIGHT &&
+ cached_inverse_powers_of_weight[num_loops] == 0.0f) {
+ cached_inverse_powers_of_weight[num_loops] = 1.0f / powf(weight, num_loops);
+ }
+ const float inverted_n_weight = num_loops < NUM_CACHED_INVERSE_POWERS_OF_WEIGHT ?
+ cached_inverse_powers_of_weight[num_loops] :
+ 1.0f / powf(weight, num_loops);
+
+ madd_v3_v3fl(item_data->normal, polynors[mp_index], curr_val * inverted_n_weight);
}
-static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data)
+static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
+ WeightedNormalData *wn_data)
{
- const int numVerts = wn_data->numVerts;
- const int numEdges = wn_data->numEdges;
- const int numLoops = wn_data->numLoops;
- const int numPolys = wn_data->numPolys;
-
- MVert *mvert = wn_data->mvert;
- MEdge *medge = wn_data->medge;
-
- MLoop *mloop = wn_data->mloop;
- short (*clnors)[2] = wn_data->clnors;
- int *loop_to_poly = wn_data->loop_to_poly;
-
- MPoly *mpoly = wn_data->mpoly;
- float (*polynors)[3] = wn_data->polynors;
- int *poly_strength = wn_data->poly_strength;
-
- MDeformVert *dvert = wn_data->dvert;
-
- const short mode = wn_data->mode;
- ModePair *mode_pair = wn_data->mode_pair;
-
- const bool has_clnors = wn_data->has_clnors;
- const float split_angle = wn_data->split_angle;
- MLoopNorSpaceArray lnors_spacearr = {NULL};
-
- const bool keep_sharp = (wnmd->flag & MOD_WEIGHTEDNORMAL_KEEP_SHARP) != 0;
- const bool use_face_influence = (wnmd->flag & MOD_WEIGHTEDNORMAL_FACE_INFLUENCE) != 0 && poly_strength != NULL;
- const bool has_vgroup = dvert != NULL;
-
- float (*loop_normals)[3] = NULL;
-
- WeightedNormalDataAggregateItem *items_data = NULL;
- int num_items = 0;
- if (keep_sharp) {
- BLI_bitmap *done_loops = BLI_BITMAP_NEW(numLoops, __func__);
-
- /* This will give us loop normal spaces, we do not actually care about computed loop_normals for now... */
- loop_normals = MEM_calloc_arrayN((size_t)numLoops, sizeof(*loop_normals), __func__);
- BKE_mesh_normals_loop_split(mvert, numVerts, medge, numEdges,
- mloop, loop_normals, numLoops, mpoly, polynors, numPolys,
- true, split_angle, &lnors_spacearr, has_clnors ? clnors : NULL, loop_to_poly);
-
- num_items = lnors_spacearr.num_spaces;
- items_data = MEM_calloc_arrayN((size_t)num_items, sizeof(*items_data), __func__);
-
- /* In this first loop, we assign each WeightedNormalDataAggregateItem
- * to its smooth fan of loops (aka lnor space). */
- MPoly *mp;
- int mp_index;
- int item_index;
- for (mp = mpoly, mp_index = 0, item_index = 0; mp_index < numPolys; mp++, mp_index++) {
- int ml_index = mp->loopstart;
- const int ml_end_index = ml_index + mp->totloop;
-
- for (; ml_index < ml_end_index; ml_index++) {
- if (BLI_BITMAP_TEST(done_loops, ml_index)) {
- /* Smooth fan of this loop has already been processed, skip it. */
- continue;
- }
- BLI_assert(item_index < num_items);
-
- WeightedNormalDataAggregateItem *itdt = &items_data[item_index];
- itdt->curr_strength = FACE_STRENGTH_WEAK;
-
- MLoopNorSpace *lnor_space = lnors_spacearr.lspacearr[ml_index];
- lnor_space->user_data = itdt;
-
- if (!(lnor_space->flags & MLNOR_SPACE_IS_SINGLE)) {
- for (LinkNode *lnode = lnor_space->loops; lnode; lnode = lnode->next) {
- const int ml_fan_index = POINTER_AS_INT(lnode->link);
- BLI_BITMAP_ENABLE(done_loops, ml_fan_index);
- }
- }
- else {
- BLI_BITMAP_ENABLE(done_loops, ml_index);
- }
-
- item_index++;
- }
- }
-
- MEM_freeN(done_loops);
- }
- else {
- num_items = numVerts;
- items_data = MEM_calloc_arrayN((size_t)num_items, sizeof(*items_data), __func__);
- if (use_face_influence) {
- for (int item_index = 0; item_index < num_items; item_index++) {
- items_data[item_index].curr_strength = FACE_STRENGTH_WEAK;
- }
- }
- }
- wn_data->items_data = items_data;
-
- switch (mode) {
- case MOD_WEIGHTEDNORMAL_MODE_FACE:
- for (int i = 0; i < numPolys; i++) {
- const int mp_index = mode_pair[i].index;
- const float mp_val = mode_pair[i].val;
-
- int ml_index = mpoly[mp_index].loopstart;
- const int ml_index_end = ml_index + mpoly[mp_index].totloop;
- for (; ml_index < ml_index_end; ml_index++) {
- const int mv_index = mloop[ml_index].v;
- WeightedNormalDataAggregateItem *item_data = keep_sharp ?
- lnors_spacearr.lspacearr[ml_index]->user_data:
- &items_data[mv_index];
-
- aggregate_item_normal(wnmd, wn_data, item_data, mv_index, mp_index, mp_val, use_face_influence);
- }
- }
- break;
- case MOD_WEIGHTEDNORMAL_MODE_ANGLE:
- case MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE:
- BLI_assert(loop_to_poly != NULL);
-
- for (int i = 0; i < numLoops; i++) {
- const int ml_index = mode_pair[i].index;
- const float ml_val = mode_pair[i].val;
-
- const int mp_index = loop_to_poly[ml_index];
- const int mv_index = mloop[ml_index].v;
- WeightedNormalDataAggregateItem *item_data = keep_sharp ?
- lnors_spacearr.lspacearr[ml_index]->user_data:
- &items_data[mv_index];
-
- aggregate_item_normal(wnmd, wn_data, item_data, mv_index, mp_index, ml_val, use_face_influence);
- }
- break;
- default:
- BLI_assert(0);
- }
-
- /* Validate computed weighted normals. */
- for (int item_index = 0; item_index < num_items; item_index++) {
- if (normalize_v3(items_data[item_index].normal) < CLNORS_VALID_VEC_LEN) {
- zero_v3(items_data[item_index].normal);
- }
- }
-
- if (keep_sharp) {
- /* Set loop normals for normal computed for each lnor space (smooth fan).
- * Note that loop_normals is already populated with clnors (before this modifier is applied, at start of
- * this function), so no need to recompute them here. */
- for (int ml_index = 0; ml_index < numLoops; ml_index++) {
- WeightedNormalDataAggregateItem *item_data = lnors_spacearr.lspacearr[ml_index]->user_data;
- if (!is_zero_v3(item_data->normal)) {
- copy_v3_v3(loop_normals[ml_index], item_data->normal);
- }
- }
-
- BKE_mesh_normals_loop_custom_set(mvert, numVerts, medge, numEdges,
- mloop, loop_normals, numLoops, mpoly, polynors, numPolys, clnors);
- }
- else {
- /* TODO: Ideally, we could add an option to BKE_mesh_normals_loop_custom_[from_vertices_]set() to keep current
- * clnors instead of resetting them to default autocomputed ones, when given new custom normal is zero-vec.
- * But this is not exactly trivial change, better to keep this optimization for later...
- */
- if (!has_vgroup) {
- /* Note: in theory, we could avoid this extra allocation & copying... But think we can live with it for now,
- * and it makes code simpler & cleaner. */
- float (*vert_normals)[3] = MEM_calloc_arrayN((size_t)numVerts, sizeof(*loop_normals), __func__);
-
- for (int ml_index = 0; ml_index < numLoops; ml_index++) {
- const int mv_index = mloop[ml_index].v;
- copy_v3_v3(vert_normals[mv_index], items_data[mv_index].normal);
- }
-
- BKE_mesh_normals_loop_custom_from_vertices_set(mvert, vert_normals, numVerts, medge, numEdges,
- mloop, numLoops, mpoly, polynors, numPolys, clnors);
-
- MEM_freeN(vert_normals);
- }
- else {
- loop_normals = MEM_calloc_arrayN((size_t)numLoops, sizeof(*loop_normals), __func__);
-
- BKE_mesh_normals_loop_split(mvert, numVerts, medge, numEdges,
- mloop, loop_normals, numLoops, mpoly, polynors, numPolys,
- true, split_angle, NULL, has_clnors ? clnors : NULL, loop_to_poly);
-
- for (int ml_index = 0; ml_index < numLoops; ml_index++) {
- const int item_index = mloop[ml_index].v;
- if (!is_zero_v3(items_data[item_index].normal)) {
- copy_v3_v3(loop_normals[ml_index], items_data[item_index].normal);
- }
- }
-
- BKE_mesh_normals_loop_custom_set(mvert, numVerts, medge, numEdges,
- mloop, loop_normals, numLoops, mpoly, polynors, numPolys, clnors);
- }
- }
-
- if (keep_sharp) {
- BKE_lnor_spacearr_free(&lnors_spacearr);
- }
- MEM_SAFE_FREE(loop_normals);
+ const int numVerts = wn_data->numVerts;
+ const int numEdges = wn_data->numEdges;
+ const int numLoops = wn_data->numLoops;
+ const int numPolys = wn_data->numPolys;
+
+ MVert *mvert = wn_data->mvert;
+ MEdge *medge = wn_data->medge;
+
+ MLoop *mloop = wn_data->mloop;
+ short(*clnors)[2] = wn_data->clnors;
+ int *loop_to_poly = wn_data->loop_to_poly;
+
+ MPoly *mpoly = wn_data->mpoly;
+ float(*polynors)[3] = wn_data->polynors;
+ int *poly_strength = wn_data->poly_strength;
+
+ MDeformVert *dvert = wn_data->dvert;
+
+ const short mode = wn_data->mode;
+ ModePair *mode_pair = wn_data->mode_pair;
+
+ const bool has_clnors = wn_data->has_clnors;
+ const float split_angle = wn_data->split_angle;
+ MLoopNorSpaceArray lnors_spacearr = {NULL};
+
+ const bool keep_sharp = (wnmd->flag & MOD_WEIGHTEDNORMAL_KEEP_SHARP) != 0;
+ const bool use_face_influence = (wnmd->flag & MOD_WEIGHTEDNORMAL_FACE_INFLUENCE) != 0 &&
+ poly_strength != NULL;
+ const bool has_vgroup = dvert != NULL;
+
+ float(*loop_normals)[3] = NULL;
+
+ WeightedNormalDataAggregateItem *items_data = NULL;
+ int num_items = 0;
+ if (keep_sharp) {
+ BLI_bitmap *done_loops = BLI_BITMAP_NEW(numLoops, __func__);
+
+ /* This will give us loop normal spaces, we do not actually care about computed loop_normals for now... */
+ loop_normals = MEM_calloc_arrayN((size_t)numLoops, sizeof(*loop_normals), __func__);
+ BKE_mesh_normals_loop_split(mvert,
+ numVerts,
+ medge,
+ numEdges,
+ mloop,
+ loop_normals,
+ numLoops,
+ mpoly,
+ polynors,
+ numPolys,
+ true,
+ split_angle,
+ &lnors_spacearr,
+ has_clnors ? clnors : NULL,
+ loop_to_poly);
+
+ num_items = lnors_spacearr.num_spaces;
+ items_data = MEM_calloc_arrayN((size_t)num_items, sizeof(*items_data), __func__);
+
+ /* In this first loop, we assign each WeightedNormalDataAggregateItem
+ * to its smooth fan of loops (aka lnor space). */
+ MPoly *mp;
+ int mp_index;
+ int item_index;
+ for (mp = mpoly, mp_index = 0, item_index = 0; mp_index < numPolys; mp++, mp_index++) {
+ int ml_index = mp->loopstart;
+ const int ml_end_index = ml_index + mp->totloop;
+
+ for (; ml_index < ml_end_index; ml_index++) {
+ if (BLI_BITMAP_TEST(done_loops, ml_index)) {
+ /* Smooth fan of this loop has already been processed, skip it. */
+ continue;
+ }
+ BLI_assert(item_index < num_items);
+
+ WeightedNormalDataAggregateItem *itdt = &items_data[item_index];
+ itdt->curr_strength = FACE_STRENGTH_WEAK;
+
+ MLoopNorSpace *lnor_space = lnors_spacearr.lspacearr[ml_index];
+ lnor_space->user_data = itdt;
+
+ if (!(lnor_space->flags & MLNOR_SPACE_IS_SINGLE)) {
+ for (LinkNode *lnode = lnor_space->loops; lnode; lnode = lnode->next) {
+ const int ml_fan_index = POINTER_AS_INT(lnode->link);
+ BLI_BITMAP_ENABLE(done_loops, ml_fan_index);
+ }
+ }
+ else {
+ BLI_BITMAP_ENABLE(done_loops, ml_index);
+ }
+
+ item_index++;
+ }
+ }
+
+ MEM_freeN(done_loops);
+ }
+ else {
+ num_items = numVerts;
+ items_data = MEM_calloc_arrayN((size_t)num_items, sizeof(*items_data), __func__);
+ if (use_face_influence) {
+ for (int item_index = 0; item_index < num_items; item_index++) {
+ items_data[item_index].curr_strength = FACE_STRENGTH_WEAK;
+ }
+ }
+ }
+ wn_data->items_data = items_data;
+
+ switch (mode) {
+ case MOD_WEIGHTEDNORMAL_MODE_FACE:
+ for (int i = 0; i < numPolys; i++) {
+ const int mp_index = mode_pair[i].index;
+ const float mp_val = mode_pair[i].val;
+
+ int ml_index = mpoly[mp_index].loopstart;
+ const int ml_index_end = ml_index + mpoly[mp_index].totloop;
+ for (; ml_index < ml_index_end; ml_index++) {
+ const int mv_index = mloop[ml_index].v;
+ WeightedNormalDataAggregateItem *item_data =
+ keep_sharp ? lnors_spacearr.lspacearr[ml_index]->user_data : &items_data[mv_index];
+
+ aggregate_item_normal(
+ wnmd, wn_data, item_data, mv_index, mp_index, mp_val, use_face_influence);
+ }
+ }
+ break;
+ case MOD_WEIGHTEDNORMAL_MODE_ANGLE:
+ case MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE:
+ BLI_assert(loop_to_poly != NULL);
+
+ for (int i = 0; i < numLoops; i++) {
+ const int ml_index = mode_pair[i].index;
+ const float ml_val = mode_pair[i].val;
+
+ const int mp_index = loop_to_poly[ml_index];
+ const int mv_index = mloop[ml_index].v;
+ WeightedNormalDataAggregateItem *item_data =
+ keep_sharp ? lnors_spacearr.lspacearr[ml_index]->user_data : &items_data[mv_index];
+
+ aggregate_item_normal(
+ wnmd, wn_data, item_data, mv_index, mp_index, ml_val, use_face_influence);
+ }
+ break;
+ default:
+ BLI_assert(0);
+ }
+
+ /* Validate computed weighted normals. */
+ for (int item_index = 0; item_index < num_items; item_index++) {
+ if (normalize_v3(items_data[item_index].normal) < CLNORS_VALID_VEC_LEN) {
+ zero_v3(items_data[item_index].normal);
+ }
+ }
+
+ if (keep_sharp) {
+ /* Set loop normals for normal computed for each lnor space (smooth fan).
+ * Note that loop_normals is already populated with clnors (before this modifier is applied, at start of
+ * this function), so no need to recompute them here. */
+ for (int ml_index = 0; ml_index < numLoops; ml_index++) {
+ WeightedNormalDataAggregateItem *item_data = lnors_spacearr.lspacearr[ml_index]->user_data;
+ if (!is_zero_v3(item_data->normal)) {
+ copy_v3_v3(loop_normals[ml_index], item_data->normal);
+ }
+ }
+
+ BKE_mesh_normals_loop_custom_set(mvert,
+ numVerts,
+ medge,
+ numEdges,
+ mloop,
+ loop_normals,
+ numLoops,
+ mpoly,
+ polynors,
+ numPolys,
+ clnors);
+ }
+ else {
+ /* TODO: Ideally, we could add an option to BKE_mesh_normals_loop_custom_[from_vertices_]set() to keep current
+ * clnors instead of resetting them to default autocomputed ones, when given new custom normal is zero-vec.
+ * But this is not exactly trivial change, better to keep this optimization for later...
+ */
+ if (!has_vgroup) {
+ /* Note: in theory, we could avoid this extra allocation & copying... But think we can live with it for now,
+ * and it makes code simpler & cleaner. */
+ float(*vert_normals)[3] = MEM_calloc_arrayN(
+ (size_t)numVerts, sizeof(*loop_normals), __func__);
+
+ for (int ml_index = 0; ml_index < numLoops; ml_index++) {
+ const int mv_index = mloop[ml_index].v;
+ copy_v3_v3(vert_normals[mv_index], items_data[mv_index].normal);
+ }
+
+ BKE_mesh_normals_loop_custom_from_vertices_set(mvert,
+ vert_normals,
+ numVerts,
+ medge,
+ numEdges,
+ mloop,
+ numLoops,
+ mpoly,
+ polynors,
+ numPolys,
+ clnors);
+
+ MEM_freeN(vert_normals);
+ }
+ else {
+ loop_normals = MEM_calloc_arrayN((size_t)numLoops, sizeof(*loop_normals), __func__);
+
+ BKE_mesh_normals_loop_split(mvert,
+ numVerts,
+ medge,
+ numEdges,
+ mloop,
+ loop_normals,
+ numLoops,
+ mpoly,
+ polynors,
+ numPolys,
+ true,
+ split_angle,
+ NULL,
+ has_clnors ? clnors : NULL,
+ loop_to_poly);
+
+ for (int ml_index = 0; ml_index < numLoops; ml_index++) {
+ const int item_index = mloop[ml_index].v;
+ if (!is_zero_v3(items_data[item_index].normal)) {
+ copy_v3_v3(loop_normals[ml_index], items_data[item_index].normal);
+ }
+ }
+
+ BKE_mesh_normals_loop_custom_set(mvert,
+ numVerts,
+ medge,
+ numEdges,
+ mloop,
+ loop_normals,
+ numLoops,
+ mpoly,
+ polynors,
+ numPolys,
+ clnors);
+ }
+ }
+
+ if (keep_sharp) {
+ BKE_lnor_spacearr_free(&lnors_spacearr);
+ }
+ MEM_SAFE_FREE(loop_normals);
}
static void wn_face_area(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data)
{
- const int numPolys = wn_data->numPolys;
+ const int numPolys = wn_data->numPolys;
- MVert *mvert = wn_data->mvert;
- MLoop *mloop = wn_data->mloop;
- MPoly *mpoly = wn_data->mpoly;
+ MVert *mvert = wn_data->mvert;
+ MLoop *mloop = wn_data->mloop;
+ MPoly *mpoly = wn_data->mpoly;
- MPoly *mp;
- int mp_index;
+ MPoly *mp;
+ int mp_index;
- ModePair *face_area = MEM_malloc_arrayN((size_t)numPolys, sizeof(*face_area), __func__);
+ ModePair *face_area = MEM_malloc_arrayN((size_t)numPolys, sizeof(*face_area), __func__);
- ModePair *f_area = face_area;
- for (mp_index = 0, mp = mpoly; mp_index < numPolys; mp_index++, mp++, f_area++) {
- f_area->val = BKE_mesh_calc_poly_area(mp, &mloop[mp->loopstart], mvert);
- f_area->index = mp_index;
- }
+ ModePair *f_area = face_area;
+ for (mp_index = 0, mp = mpoly; mp_index < numPolys; mp_index++, mp++, f_area++) {
+ f_area->val = BKE_mesh_calc_poly_area(mp, &mloop[mp->loopstart], mvert);
+ f_area->index = mp_index;
+ }
- qsort(face_area, numPolys, sizeof(*face_area), modepair_cmp_by_val_inverse);
+ qsort(face_area, numPolys, sizeof(*face_area), modepair_cmp_by_val_inverse);
- wn_data->mode_pair = face_area;
- apply_weights_vertex_normal(wnmd, wn_data);
+ wn_data->mode_pair = face_area;
+ apply_weights_vertex_normal(wnmd, wn_data);
}
static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data)
{
- const int numLoops = wn_data->numLoops;
- const int numPolys = wn_data->numPolys;
+ const int numLoops = wn_data->numLoops;
+ const int numPolys = wn_data->numPolys;
- MVert *mvert = wn_data->mvert;
- MLoop *mloop = wn_data->mloop;
- MPoly *mpoly = wn_data->mpoly;
+ MVert *mvert = wn_data->mvert;
+ MLoop *mloop = wn_data->mloop;
+ MPoly *mpoly = wn_data->mpoly;
- MPoly *mp;
- int mp_index;
+ MPoly *mp;
+ int mp_index;
- int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__);
+ int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__);
- ModePair *corner_angle = MEM_malloc_arrayN((size_t)numLoops, sizeof(*corner_angle), __func__);
+ ModePair *corner_angle = MEM_malloc_arrayN((size_t)numLoops, sizeof(*corner_angle), __func__);
- for (mp_index = 0, mp = mpoly; mp_index < numPolys; mp_index++, mp++) {
- MLoop *ml_start = &mloop[mp->loopstart];
+ for (mp_index = 0, mp = mpoly; mp_index < numPolys; mp_index++, mp++) {
+ MLoop *ml_start = &mloop[mp->loopstart];
- float *index_angle = MEM_malloc_arrayN((size_t)mp->totloop, sizeof(*index_angle), __func__);
- BKE_mesh_calc_poly_angles(mp, ml_start, mvert, index_angle);
+ float *index_angle = MEM_malloc_arrayN((size_t)mp->totloop, sizeof(*index_angle), __func__);
+ BKE_mesh_calc_poly_angles(mp, ml_start, mvert, index_angle);
- ModePair *c_angl = &corner_angle[mp->loopstart];
- float *angl = index_angle;
- for (int ml_index = mp->loopstart; ml_index < mp->loopstart + mp->totloop; ml_index++, c_angl++, angl++) {
- c_angl->val = (float)M_PI - *angl;
- c_angl->index = ml_index;
+ ModePair *c_angl = &corner_angle[mp->loopstart];
+ float *angl = index_angle;
+ for (int ml_index = mp->loopstart; ml_index < mp->loopstart + mp->totloop;
+ ml_index++, c_angl++, angl++) {
+ c_angl->val = (float)M_PI - *angl;
+ c_angl->index = ml_index;
- loop_to_poly[ml_index] = mp_index;
- }
- MEM_freeN(index_angle);
- }
+ loop_to_poly[ml_index] = mp_index;
+ }
+ MEM_freeN(index_angle);
+ }
- qsort(corner_angle, numLoops, sizeof(*corner_angle), modepair_cmp_by_val_inverse);
+ qsort(corner_angle, numLoops, sizeof(*corner_angle), modepair_cmp_by_val_inverse);
- wn_data->loop_to_poly = loop_to_poly;
- wn_data->mode_pair = corner_angle;
- apply_weights_vertex_normal(wnmd, wn_data);
+ wn_data->loop_to_poly = loop_to_poly;
+ wn_data->mode_pair = corner_angle;
+ apply_weights_vertex_normal(wnmd, wn_data);
}
static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data)
{
- const int numLoops = wn_data->numLoops;
- const int numPolys = wn_data->numPolys;
+ const int numLoops = wn_data->numLoops;
+ const int numPolys = wn_data->numPolys;
- MVert *mvert = wn_data->mvert;
- MLoop *mloop = wn_data->mloop;
- MPoly *mpoly = wn_data->mpoly;
+ MVert *mvert = wn_data->mvert;
+ MLoop *mloop = wn_data->mloop;
+ MPoly *mpoly = wn_data->mpoly;
- MPoly *mp;
- int mp_index;
+ MPoly *mp;
+ int mp_index;
- int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__);
+ int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__);
- ModePair *combined = MEM_malloc_arrayN((size_t)numLoops, sizeof(*combined), __func__);
+ ModePair *combined = MEM_malloc_arrayN((size_t)numLoops, sizeof(*combined), __func__);
- for (mp_index = 0, mp = mpoly; mp_index < numPolys; mp_index++, mp++) {
- MLoop *ml_start = &mloop[mp->loopstart];
+ for (mp_index = 0, mp = mpoly; mp_index < numPolys; mp_index++, mp++) {
+ MLoop *ml_start = &mloop[mp->loopstart];
- float face_area = BKE_mesh_calc_poly_area(mp, ml_start, mvert);
- float *index_angle = MEM_malloc_arrayN((size_t)mp->totloop, sizeof(*index_angle), __func__);
- BKE_mesh_calc_poly_angles(mp, ml_start, mvert, index_angle);
+ float face_area = BKE_mesh_calc_poly_area(mp, ml_start, mvert);
+ float *index_angle = MEM_malloc_arrayN((size_t)mp->totloop, sizeof(*index_angle), __func__);
+ BKE_mesh_calc_poly_angles(mp, ml_start, mvert, index_angle);
- ModePair *cmbnd = &combined[mp->loopstart];
- float *angl = index_angle;
- for (int ml_index = mp->loopstart; ml_index < mp->loopstart + mp->totloop; ml_index++, cmbnd++, angl++) {
- /* In this case val is product of corner angle and face area. */
- cmbnd->val = ((float)M_PI - *angl) * face_area;
- cmbnd->index = ml_index;
+ ModePair *cmbnd = &combined[mp->loopstart];
+ float *angl = index_angle;
+ for (int ml_index = mp->loopstart; ml_index < mp->loopstart + mp->totloop;
+ ml_index++, cmbnd++, angl++) {
+ /* In this case val is product of corner angle and face area. */
+ cmbnd->val = ((float)M_PI - *angl) * face_area;
+ cmbnd->index = ml_index;
- loop_to_poly[ml_index] = mp_index;
- }
- MEM_freeN(index_angle);
- }
+ loop_to_poly[ml_index] = mp_index;
+ }
+ MEM_freeN(index_angle);
+ }
- qsort(combined, numLoops, sizeof(*combined), modepair_cmp_by_val_inverse);
+ qsort(combined, numLoops, sizeof(*combined), modepair_cmp_by_val_inverse);
- wn_data->loop_to_poly = loop_to_poly;
- wn_data->mode_pair = combined;
- apply_weights_vertex_normal(wnmd, wn_data);
+ wn_data->loop_to_poly = loop_to_poly;
+ wn_data->mode_pair = combined;
+ apply_weights_vertex_normal(wnmd, wn_data);
}
static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- WeightedNormalModifierData *wnmd = (WeightedNormalModifierData *)md;
- Object *ob = ctx->object;
+ WeightedNormalModifierData *wnmd = (WeightedNormalModifierData *)md;
+ Object *ob = ctx->object;
- /* XXX TODO ARG GRRR XYQWNMPRXTYY
- * Once we fully switch to Mesh evaluation of modifiers, we can expect to get that flag from the COW copy.
- * But for now, it is lost in the DM intermediate step, so we need to directly check orig object's data. */
+ /* XXX TODO ARG GRRR XYQWNMPRXTYY
+ * Once we fully switch to Mesh evaluation of modifiers, we can expect to get that flag from the COW copy.
+ * But for now, it is lost in the DM intermediate step, so we need to directly check orig object's data. */
#if 0
- if (!(mesh->flag & ME_AUTOSMOOTH)) {
+ if (!(mesh->flag & ME_AUTOSMOOTH)) {
#else
- if (!(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH)) {
+ if (!(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH)) {
#endif
- modifier_setError((ModifierData *)wnmd, "Enable 'Auto Smooth' option in mesh settings");
- return mesh;
- }
-
- Mesh *result;
- BKE_id_copy_ex(NULL, &mesh->id, (ID **)&result, LIB_ID_COPY_LOCALIZE);
-
- const int numVerts = result->totvert;
- const int numEdges = result->totedge;
- const int numLoops = result->totloop;
- const int numPolys = result->totpoly;
-
- MEdge *medge = result->medge;
- MPoly *mpoly = result->mpoly;
- MVert *mvert = result->mvert;
- MLoop *mloop = result->mloop;
-
- /* Right now:
- * If weight = 50 then all faces are given equal weight.
- * If weight > 50 then more weight given to faces with larger vals (face area / corner angle).
- * If weight < 50 then more weight given to faces with lesser vals. However current calculation
- * does not converge to min/max.
- */
- float weight = ((float)wnmd->weight) / 50.0f;
- if (wnmd->weight == 100) {
- weight = (float)SHRT_MAX;
- }
- else if (wnmd->weight == 1) {
- weight = 1 / (float)SHRT_MAX;
- }
- else if ((weight - 1) * 25 > 1) {
- weight = (weight - 1) * 25;
- }
-
- CustomData *pdata = &result->pdata;
- float (*polynors)[3] = CustomData_get_layer(pdata, CD_NORMAL);
- if (!polynors) {
- polynors = CustomData_add_layer(pdata, CD_NORMAL, CD_CALLOC, NULL, numPolys);
- CustomData_set_layer_flag(pdata, CD_NORMAL, CD_FLAG_TEMPORARY);
- }
- BKE_mesh_calc_normals_poly(mvert, NULL, numVerts, mloop, mpoly, numLoops, numPolys, polynors, false);
-
-
- const float split_angle = mesh->smoothresh;
- short (*clnors)[2];
- CustomData *ldata = &result->ldata;
- clnors = CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL);
-
- /* Keep info whether we had clnors, it helps when generating clnor spaces and default normals. */
- const bool has_clnors = clnors != NULL;
- if (!clnors) {
- clnors = CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, numLoops);
- }
-
- MDeformVert *dvert;
- int defgrp_index;
- MOD_get_vgroup(ctx->object, mesh, wnmd->defgrp_name, &dvert, &defgrp_index);
-
- WeightedNormalData wn_data = {
- .numVerts = numVerts,
- .numEdges = numEdges,
- .numLoops = numLoops,
- .numPolys = numPolys,
-
- .mvert = mvert,
- .medge = medge,
-
- .mloop = mloop,
- .clnors = clnors,
- .has_clnors = has_clnors,
- .split_angle = split_angle,
-
- .mpoly = mpoly,
- .polynors = polynors,
- .poly_strength = CustomData_get_layer_named(
- &result->pdata, CD_PROP_INT,
- MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID),
-
- .dvert = dvert,
- .defgrp_index = defgrp_index,
- .use_invert_vgroup = (wnmd->flag & MOD_WEIGHTEDNORMAL_INVERT_VGROUP) != 0,
-
- .weight = weight,
- .mode = wnmd->mode,
- };
-
- switch (wnmd->mode) {
- case MOD_WEIGHTEDNORMAL_MODE_FACE:
- wn_face_area(wnmd, &wn_data);
- break;
- case MOD_WEIGHTEDNORMAL_MODE_ANGLE:
- wn_corner_angle(wnmd, &wn_data);
- break;
- case MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE:
- wn_face_with_angle(wnmd, &wn_data);
- break;
- }
-
- MEM_SAFE_FREE(wn_data.loop_to_poly);
- MEM_SAFE_FREE(wn_data.mode_pair);
- MEM_SAFE_FREE(wn_data.items_data);
-
- /* Currently Modifier stack assumes there is no poly normal data passed around... */
- CustomData_free_layers(pdata, CD_NORMAL, numPolys);
- return result;
+ modifier_setError((ModifierData *)wnmd, "Enable 'Auto Smooth' option in mesh settings");
+ return mesh;
+}
+
+Mesh *result;
+BKE_id_copy_ex(NULL, &mesh->id, (ID **)&result, LIB_ID_COPY_LOCALIZE);
+
+const int numVerts = result->totvert;
+const int numEdges = result->totedge;
+const int numLoops = result->totloop;
+const int numPolys = result->totpoly;
+
+MEdge *medge = result->medge;
+MPoly *mpoly = result->mpoly;
+MVert *mvert = result->mvert;
+MLoop *mloop = result->mloop;
+
+/* Right now:
+ * If weight = 50 then all faces are given equal weight.
+ * If weight > 50 then more weight given to faces with larger vals (face area / corner angle).
+ * If weight < 50 then more weight given to faces with lesser vals. However current calculation
+ * does not converge to min/max.
+ */
+float weight = ((float)wnmd->weight) / 50.0f;
+if (wnmd->weight == 100) {
+ weight = (float)SHRT_MAX;
+}
+else if (wnmd->weight == 1) {
+ weight = 1 / (float)SHRT_MAX;
+}
+else if ((weight - 1) * 25 > 1) {
+ weight = (weight - 1) * 25;
+}
+
+CustomData *pdata = &result->pdata;
+float (*polynors)[3] = CustomData_get_layer(pdata, CD_NORMAL);
+if (!polynors) {
+ polynors = CustomData_add_layer(pdata, CD_NORMAL, CD_CALLOC, NULL, numPolys);
+ CustomData_set_layer_flag(pdata, CD_NORMAL, CD_FLAG_TEMPORARY);
+}
+BKE_mesh_calc_normals_poly(
+ mvert, NULL, numVerts, mloop, mpoly, numLoops, numPolys, polynors, false);
+
+const float split_angle = mesh->smoothresh;
+short (*clnors)[2];
+CustomData *ldata = &result->ldata;
+clnors = CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL);
+
+/* Keep info whether we had clnors, it helps when generating clnor spaces and default normals. */
+const bool has_clnors = clnors != NULL;
+if (!clnors) {
+ clnors = CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, numLoops);
+}
+
+MDeformVert *dvert;
+int defgrp_index;
+MOD_get_vgroup(ctx->object, mesh, wnmd->defgrp_name, &dvert, &defgrp_index);
+
+WeightedNormalData wn_data = {
+ .numVerts = numVerts,
+ .numEdges = numEdges,
+ .numLoops = numLoops,
+ .numPolys = numPolys,
+
+ .mvert = mvert,
+ .medge = medge,
+
+ .mloop = mloop,
+ .clnors = clnors,
+ .has_clnors = has_clnors,
+ .split_angle = split_angle,
+
+ .mpoly = mpoly,
+ .polynors = polynors,
+ .poly_strength = CustomData_get_layer_named(
+ &result->pdata, CD_PROP_INT, MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID),
+
+ .dvert = dvert,
+ .defgrp_index = defgrp_index,
+ .use_invert_vgroup = (wnmd->flag & MOD_WEIGHTEDNORMAL_INVERT_VGROUP) != 0,
+
+ .weight = weight,
+ .mode = wnmd->mode,
+};
+
+switch (wnmd->mode) {
+ case MOD_WEIGHTEDNORMAL_MODE_FACE:
+ wn_face_area(wnmd, &wn_data);
+ break;
+ case MOD_WEIGHTEDNORMAL_MODE_ANGLE:
+ wn_corner_angle(wnmd, &wn_data);
+ break;
+ case MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE:
+ wn_face_with_angle(wnmd, &wn_data);
+ break;
+}
+
+MEM_SAFE_FREE(wn_data.loop_to_poly);
+MEM_SAFE_FREE(wn_data.mode_pair);
+MEM_SAFE_FREE(wn_data.items_data);
+
+/* Currently Modifier stack assumes there is no poly normal data passed around... */
+CustomData_free_layers(pdata, CD_NORMAL, numPolys);
+return result;
}
static void initData(ModifierData *md)
{
- WeightedNormalModifierData *wnmd = (WeightedNormalModifierData *)md;
- wnmd->mode = MOD_WEIGHTEDNORMAL_MODE_FACE;
- wnmd->weight = 50;
- wnmd->thresh = 1e-2f;
- wnmd->flag = 0;
+ WeightedNormalModifierData *wnmd = (WeightedNormalModifierData *)md;
+ wnmd->mode = MOD_WEIGHTEDNORMAL_MODE_FACE;
+ wnmd->weight = 50;
+ wnmd->thresh = 1e-2f;
+ wnmd->flag = 0;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- WeightedNormalModifierData *wnmd = (WeightedNormalModifierData *)md;
+ WeightedNormalModifierData *wnmd = (WeightedNormalModifierData *)md;
- r_cddata_masks->lmask = CD_MASK_CUSTOMLOOPNORMAL;
+ r_cddata_masks->lmask = CD_MASK_CUSTOMLOOPNORMAL;
- if (wnmd->defgrp_name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ if (wnmd->defgrp_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
- if (wnmd->flag & MOD_WEIGHTEDNORMAL_FACE_INFLUENCE) {
- r_cddata_masks->pmask |= CD_MASK_PROP_INT;
- }
+ if (wnmd->flag & MOD_WEIGHTEDNORMAL_FACE_INFLUENCE) {
+ r_cddata_masks->pmask |= CD_MASK_PROP_INT;
+ }
}
static bool dependsOnNormals(ModifierData *UNUSED(md))
{
- return true;
+ return true;
}
ModifierTypeInfo modifierType_WeightedNormal = {
- /* name */ "Weighted Normal",
- /* structName */ "WeightedNormalModifierData",
- /* structSize */ sizeof(WeightedNormalModifierData),
- /* type */ eModifierTypeType_Constructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsMapping |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_EnableInEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepsgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Weighted Normal",
+ /* structName */ "WeightedNormalModifierData",
+ /* structSize */ sizeof(WeightedNormalModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ dependsOnNormals,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c
index d0631a0c30b..3e1c2f9bc02 100644
--- a/source/blender/modifiers/intern/MOD_weightvg_util.c
+++ b/source/blender/modifiers/intern/MOD_weightvg_util.c
@@ -27,18 +27,18 @@
#include "BLI_rand.h"
#include "BLI_string.h"
-#include "DNA_color_types.h" /* CurveMapping. */
+#include "DNA_color_types.h" /* CurveMapping. */
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "BKE_colortools.h" /* CurveMapping. */
+#include "BKE_colortools.h" /* CurveMapping. */
#include "BKE_customdata.h"
#include "BKE_deform.h"
#include "BKE_modifier.h"
-#include "BKE_texture.h" /* Texture masking. */
+#include "BKE_texture.h" /* Texture masking. */
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
@@ -46,7 +46,7 @@
#include "MEM_guardedalloc.h"
#include "MOD_util.h"
#include "MOD_weightvg_util.h"
-#include "RE_shader_ext.h" /* Texture masking. */
+#include "RE_shader_ext.h" /* Texture masking. */
/* Maps new_w weights in place, using either one of the predefined functions, or a custom curve.
* Return values are in new_w.
@@ -56,54 +56,57 @@
*/
void weightvg_do_map(int num, float *new_w, short falloff_type, CurveMapping *cmap, RNG *rng)
{
- int i;
+ int i;
- /* Return immediately, if we have nothing to do! */
- /* Also security checks... */
- if (((falloff_type == MOD_WVG_MAPPING_CURVE) && (cmap == NULL)) ||
- !ELEM(falloff_type, MOD_WVG_MAPPING_CURVE, MOD_WVG_MAPPING_SHARP, MOD_WVG_MAPPING_SMOOTH,
- MOD_WVG_MAPPING_ROOT, MOD_WVG_MAPPING_SPHERE, MOD_WVG_MAPPING_RANDOM,
- MOD_WVG_MAPPING_STEP))
- {
- return;
- }
+ /* Return immediately, if we have nothing to do! */
+ /* Also security checks... */
+ if (((falloff_type == MOD_WVG_MAPPING_CURVE) && (cmap == NULL)) || !ELEM(falloff_type,
+ MOD_WVG_MAPPING_CURVE,
+ MOD_WVG_MAPPING_SHARP,
+ MOD_WVG_MAPPING_SMOOTH,
+ MOD_WVG_MAPPING_ROOT,
+ MOD_WVG_MAPPING_SPHERE,
+ MOD_WVG_MAPPING_RANDOM,
+ MOD_WVG_MAPPING_STEP)) {
+ return;
+ }
- if (cmap && falloff_type == MOD_WVG_MAPPING_CURVE) {
- curvemapping_initialize(cmap);
- }
+ if (cmap && falloff_type == MOD_WVG_MAPPING_CURVE) {
+ curvemapping_initialize(cmap);
+ }
- /* Map each weight (vertex) to its new value, accordingly to the chosen mode. */
- for (i = 0; i < num; ++i) {
- float fac = new_w[i];
+ /* Map each weight (vertex) to its new value, accordingly to the chosen mode. */
+ for (i = 0; i < num; ++i) {
+ float fac = new_w[i];
- /* Code borrowed from the warp modifier. */
- /* Closely matches PROP_SMOOTH and similar. */
- switch (falloff_type) {
- case MOD_WVG_MAPPING_CURVE:
- fac = curvemapping_evaluateF(cmap, 0, fac);
- break;
- case MOD_WVG_MAPPING_SHARP:
- fac = fac * fac;
- break;
- case MOD_WVG_MAPPING_SMOOTH:
- fac = 3.0f * fac * fac - 2.0f * fac * fac * fac;
- break;
- case MOD_WVG_MAPPING_ROOT:
- fac = sqrtf(fac);
- break;
- case MOD_WVG_MAPPING_SPHERE:
- fac = sqrtf(2 * fac - fac * fac);
- break;
- case MOD_WVG_MAPPING_RANDOM:
- fac = BLI_rng_get_float(rng) * fac;
- break;
- case MOD_WVG_MAPPING_STEP:
- fac = (fac >= 0.5f) ? 1.0f : 0.0f;
- break;
- }
+ /* Code borrowed from the warp modifier. */
+ /* Closely matches PROP_SMOOTH and similar. */
+ switch (falloff_type) {
+ case MOD_WVG_MAPPING_CURVE:
+ fac = curvemapping_evaluateF(cmap, 0, fac);
+ break;
+ case MOD_WVG_MAPPING_SHARP:
+ fac = fac * fac;
+ break;
+ case MOD_WVG_MAPPING_SMOOTH:
+ fac = 3.0f * fac * fac - 2.0f * fac * fac * fac;
+ break;
+ case MOD_WVG_MAPPING_ROOT:
+ fac = sqrtf(fac);
+ break;
+ case MOD_WVG_MAPPING_SPHERE:
+ fac = sqrtf(2 * fac - fac * fac);
+ break;
+ case MOD_WVG_MAPPING_RANDOM:
+ fac = BLI_rng_get_float(rng) * fac;
+ break;
+ case MOD_WVG_MAPPING_STEP:
+ fac = (fac >= 0.5f) ? 1.0f : 0.0f;
+ break;
+ }
- new_w[i] = fac;
- }
+ new_w[i] = fac;
+ }
}
/* Applies new_w weights to org_w ones, using either a texture, vgroup or constant value as factor.
@@ -112,158 +115,174 @@ void weightvg_do_map(int num, float *new_w, short falloff_type, CurveMapping *cm
* vertex index (in case the weight tables do not cover the whole vertices...).
* XXX The standard "factor" value is assumed in [0.0, 1.0] range. Else, weird results might appear.
*/
-void weightvg_do_mask(
- const ModifierEvalContext *ctx,
- const int num, const int *indices, float *org_w, const float *new_w,
- Object *ob, Mesh *mesh, const float fact, const char defgrp_name[MAX_VGROUP_NAME],
- Scene *scene, Tex *texture, const int tex_use_channel, const int tex_mapping,
- Object *tex_map_object, const char *tex_uvlayer_name)
+void weightvg_do_mask(const ModifierEvalContext *ctx,
+ const int num,
+ const int *indices,
+ float *org_w,
+ const float *new_w,
+ Object *ob,
+ Mesh *mesh,
+ const float fact,
+ const char defgrp_name[MAX_VGROUP_NAME],
+ Scene *scene,
+ Tex *texture,
+ const int tex_use_channel,
+ const int tex_mapping,
+ Object *tex_map_object,
+ const char *tex_uvlayer_name)
{
- int ref_didx;
- int i;
+ int ref_didx;
+ int i;
- /* If influence factor is null, nothing to do! */
- if (fact == 0.0f) return;
+ /* If influence factor is null, nothing to do! */
+ if (fact == 0.0f)
+ return;
- /* If we want to mask vgroup weights from a texture. */
- if (texture != NULL) {
- /* The texture coordinates. */
- float (*tex_co)[3];
- /* See mapping note below... */
- MappingInfoModifierData t_map;
- const int numVerts = mesh->totvert;
+ /* If we want to mask vgroup weights from a texture. */
+ if (texture != NULL) {
+ /* The texture coordinates. */
+ float(*tex_co)[3];
+ /* See mapping note below... */
+ MappingInfoModifierData t_map;
+ const int numVerts = mesh->totvert;
- /* Use new generic get_texture_coords, but do not modify our DNA struct for it...
- * XXX Why use a ModifierData stuff here ? Why not a simple, generic struct for parameters ?
- * What e.g. if a modifier wants to use several textures ?
- * Why use only v_co, and not MVert (or both) ?
- */
- t_map.texture = texture;
- t_map.map_object = tex_map_object;
- BLI_strncpy(t_map.uvlayer_name, tex_uvlayer_name, sizeof(t_map.uvlayer_name));
- t_map.texmapping = tex_mapping;
+ /* Use new generic get_texture_coords, but do not modify our DNA struct for it...
+ * XXX Why use a ModifierData stuff here ? Why not a simple, generic struct for parameters ?
+ * What e.g. if a modifier wants to use several textures ?
+ * Why use only v_co, and not MVert (or both) ?
+ */
+ t_map.texture = texture;
+ t_map.map_object = tex_map_object;
+ BLI_strncpy(t_map.uvlayer_name, tex_uvlayer_name, sizeof(t_map.uvlayer_name));
+ t_map.texmapping = tex_mapping;
- tex_co = MEM_calloc_arrayN(numVerts, sizeof(*tex_co), "WeightVG Modifier, TEX mode, tex_co");
- MOD_get_texture_coords(&t_map, ctx, ob, mesh, NULL, tex_co);
+ tex_co = MEM_calloc_arrayN(numVerts, sizeof(*tex_co), "WeightVG Modifier, TEX mode, tex_co");
+ MOD_get_texture_coords(&t_map, ctx, ob, mesh, NULL, tex_co);
- MOD_init_texture(&t_map, ctx);
+ MOD_init_texture(&t_map, ctx);
- /* For each weight (vertex), make the mix between org and new weights. */
- for (i = 0; i < num; ++i) {
- int idx = indices ? indices[i] : i;
- TexResult texres;
- float hsv[3]; /* For HSV color space. */
- bool do_color_manage;
+ /* For each weight (vertex), make the mix between org and new weights. */
+ for (i = 0; i < num; ++i) {
+ int idx = indices ? indices[i] : i;
+ TexResult texres;
+ float hsv[3]; /* For HSV color space. */
+ bool do_color_manage;
- do_color_manage = tex_use_channel != MOD_WVG_MASK_TEX_USE_INT;
+ do_color_manage = tex_use_channel != MOD_WVG_MASK_TEX_USE_INT;
- texres.nor = NULL;
- BKE_texture_get_value(scene, texture, tex_co[idx], &texres, do_color_manage);
- /* Get the good channel value... */
- switch (tex_use_channel) {
- case MOD_WVG_MASK_TEX_USE_INT:
- org_w[i] = (new_w[i] * texres.tin * fact) + (org_w[i] * (1.0f - (texres.tin * fact)));
- break;
- case MOD_WVG_MASK_TEX_USE_RED:
- org_w[i] = (new_w[i] * texres.tr * fact) + (org_w[i] * (1.0f - (texres.tr * fact)));
- break;
- case MOD_WVG_MASK_TEX_USE_GREEN:
- org_w[i] = (new_w[i] * texres.tg * fact) + (org_w[i] * (1.0f - (texres.tg * fact)));
- break;
- case MOD_WVG_MASK_TEX_USE_BLUE:
- org_w[i] = (new_w[i] * texres.tb * fact) + (org_w[i] * (1.0f - (texres.tb * fact)));
- break;
- case MOD_WVG_MASK_TEX_USE_HUE:
- rgb_to_hsv_v(&texres.tr, hsv);
- org_w[i] = (new_w[i] * hsv[0] * fact) + (org_w[i] * (1.0f - (hsv[0] * fact)));
- break;
- case MOD_WVG_MASK_TEX_USE_SAT:
- rgb_to_hsv_v(&texres.tr, hsv);
- org_w[i] = (new_w[i] * hsv[1] * fact) + (org_w[i] * (1.0f - (hsv[1] * fact)));
- break;
- case MOD_WVG_MASK_TEX_USE_VAL:
- rgb_to_hsv_v(&texres.tr, hsv);
- org_w[i] = (new_w[i] * hsv[2] * fact) + (org_w[i] * (1.0f - (hsv[2] * fact)));
- break;
- case MOD_WVG_MASK_TEX_USE_ALPHA:
- org_w[i] = (new_w[i] * texres.ta * fact) + (org_w[i] * (1.0f - (texres.ta * fact)));
- break;
- default:
- org_w[i] = (new_w[i] * texres.tin * fact) + (org_w[i] * (1.0f - (texres.tin * fact)));
- break;
- }
- }
+ texres.nor = NULL;
+ BKE_texture_get_value(scene, texture, tex_co[idx], &texres, do_color_manage);
+ /* Get the good channel value... */
+ switch (tex_use_channel) {
+ case MOD_WVG_MASK_TEX_USE_INT:
+ org_w[i] = (new_w[i] * texres.tin * fact) + (org_w[i] * (1.0f - (texres.tin * fact)));
+ break;
+ case MOD_WVG_MASK_TEX_USE_RED:
+ org_w[i] = (new_w[i] * texres.tr * fact) + (org_w[i] * (1.0f - (texres.tr * fact)));
+ break;
+ case MOD_WVG_MASK_TEX_USE_GREEN:
+ org_w[i] = (new_w[i] * texres.tg * fact) + (org_w[i] * (1.0f - (texres.tg * fact)));
+ break;
+ case MOD_WVG_MASK_TEX_USE_BLUE:
+ org_w[i] = (new_w[i] * texres.tb * fact) + (org_w[i] * (1.0f - (texres.tb * fact)));
+ break;
+ case MOD_WVG_MASK_TEX_USE_HUE:
+ rgb_to_hsv_v(&texres.tr, hsv);
+ org_w[i] = (new_w[i] * hsv[0] * fact) + (org_w[i] * (1.0f - (hsv[0] * fact)));
+ break;
+ case MOD_WVG_MASK_TEX_USE_SAT:
+ rgb_to_hsv_v(&texres.tr, hsv);
+ org_w[i] = (new_w[i] * hsv[1] * fact) + (org_w[i] * (1.0f - (hsv[1] * fact)));
+ break;
+ case MOD_WVG_MASK_TEX_USE_VAL:
+ rgb_to_hsv_v(&texres.tr, hsv);
+ org_w[i] = (new_w[i] * hsv[2] * fact) + (org_w[i] * (1.0f - (hsv[2] * fact)));
+ break;
+ case MOD_WVG_MASK_TEX_USE_ALPHA:
+ org_w[i] = (new_w[i] * texres.ta * fact) + (org_w[i] * (1.0f - (texres.ta * fact)));
+ break;
+ default:
+ org_w[i] = (new_w[i] * texres.tin * fact) + (org_w[i] * (1.0f - (texres.tin * fact)));
+ break;
+ }
+ }
- MEM_freeN(tex_co);
- }
- else if ((ref_didx = defgroup_name_index(ob, defgrp_name)) != -1) {
- MDeformVert *dvert = NULL;
+ MEM_freeN(tex_co);
+ }
+ else if ((ref_didx = defgroup_name_index(ob, defgrp_name)) != -1) {
+ MDeformVert *dvert = NULL;
- /* Check whether we want to set vgroup weights from a constant weight factor or a vertex
- * group.
- */
- /* Get vgroup idx from its name. */
+ /* Check whether we want to set vgroup weights from a constant weight factor or a vertex
+ * group.
+ */
+ /* Get vgroup idx from its name. */
- /* Proceed only if vgroup is valid, else use constant factor. */
- /* Get actual dverts (ie vertex group data). */
- dvert = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT);
- /* Proceed only if vgroup is valid, else assume factor = O. */
- if (dvert == NULL) {
- return;
- }
+ /* Proceed only if vgroup is valid, else use constant factor. */
+ /* Get actual dverts (ie vertex group data). */
+ dvert = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT);
+ /* Proceed only if vgroup is valid, else assume factor = O. */
+ if (dvert == NULL) {
+ return;
+ }
- /* For each weight (vertex), make the mix between org and new weights. */
- for (i = 0; i < num; i++) {
- int idx = indices ? indices[i] : i;
- const float f = defvert_find_weight(&dvert[idx], ref_didx) * fact;
- org_w[i] = (new_w[i] * f) + (org_w[i] * (1.0f - f));
- /* If that vertex is not in ref vgroup, assume null factor, and hence do nothing! */
- }
- }
- else {
- /* Default "influence" behavior. */
- /* For each weight (vertex), make the mix between org and new weights. */
- const float ifact = 1.0f - fact;
- for (i = 0; i < num; i++) {
- org_w[i] = (new_w[i] * fact) + (org_w[i] * ifact);
- }
- }
+ /* For each weight (vertex), make the mix between org and new weights. */
+ for (i = 0; i < num; i++) {
+ int idx = indices ? indices[i] : i;
+ const float f = defvert_find_weight(&dvert[idx], ref_didx) * fact;
+ org_w[i] = (new_w[i] * f) + (org_w[i] * (1.0f - f));
+ /* If that vertex is not in ref vgroup, assume null factor, and hence do nothing! */
+ }
+ }
+ else {
+ /* Default "influence" behavior. */
+ /* For each weight (vertex), make the mix between org and new weights. */
+ const float ifact = 1.0f - fact;
+ for (i = 0; i < num; i++) {
+ org_w[i] = (new_w[i] * fact) + (org_w[i] * ifact);
+ }
+ }
}
-
/* Applies weights to given vgroup (defgroup), and optionally add/remove vertices from the group.
* If dws is not NULL, it must be an array of MDeformWeight pointers of same length as weights (and
* defgrp_idx can then have any value).
* If indices is not NULL, it must be an array of same length as weights, mapping to the real
* vertex index (in case the weight array does not cover the whole vertices...).
*/
-void weightvg_update_vg(
- MDeformVert *dvert, int defgrp_idx, MDeformWeight **dws, int num,
- const int *indices, const float *weights, const bool do_add,
- const float add_thresh, const bool do_rem, const float rem_thresh)
+void weightvg_update_vg(MDeformVert *dvert,
+ int defgrp_idx,
+ MDeformWeight **dws,
+ int num,
+ const int *indices,
+ const float *weights,
+ const bool do_add,
+ const float add_thresh,
+ const bool do_rem,
+ const float rem_thresh)
{
- int i;
+ int i;
- for (i = 0; i < num; i++) {
- float w = weights[i];
- MDeformVert *dv = &dvert[indices ? indices[i] : i];
- MDeformWeight *dw = dws ? dws[i] : ((defgrp_idx >= 0) ? defvert_find_index(dv, defgrp_idx) : NULL);
+ for (i = 0; i < num; i++) {
+ float w = weights[i];
+ MDeformVert *dv = &dvert[indices ? indices[i] : i];
+ MDeformWeight *dw = dws ? dws[i] :
+ ((defgrp_idx >= 0) ? defvert_find_index(dv, defgrp_idx) : NULL);
- /* Never allow weights out of [0.0, 1.0] range. */
- CLAMP(w, 0.0f, 1.0f);
+ /* Never allow weights out of [0.0, 1.0] range. */
+ CLAMP(w, 0.0f, 1.0f);
- /* If the vertex is in this vgroup, remove it if needed, or just update it. */
- if (dw != NULL) {
- if (do_rem && w < rem_thresh) {
- defvert_remove_group(dv, dw);
- }
- else {
- dw->weight = w;
- }
- }
- /* Else, add it if needed! */
- else if (do_add && w > add_thresh) {
- defvert_add_index_notest(dv, defgrp_idx, w);
- }
- }
+ /* If the vertex is in this vgroup, remove it if needed, or just update it. */
+ if (dw != NULL) {
+ if (do_rem && w < rem_thresh) {
+ defvert_remove_group(dv, dw);
+ }
+ else {
+ dw->weight = w;
+ }
+ }
+ /* Else, add it if needed! */
+ else if (do_add && w > add_thresh) {
+ defvert_add_index_notest(dv, defgrp_idx, w);
+ }
+ }
}
diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.h b/source/blender/modifiers/intern/MOD_weightvg_util.h
index 8bc56eb61f9..d73cca935d7 100644
--- a/source/blender/modifiers/intern/MOD_weightvg_util.h
+++ b/source/blender/modifiers/intern/MOD_weightvg_util.h
@@ -50,7 +50,7 @@ struct Tex;
* we clamp weightf to this value (or its negative version).
* Also used to avoid null power factor.
*/
-#define MOD_WVG_ZEROFLOOR 1.0e-32f
+#define MOD_WVG_ZEROFLOOR 1.0e-32f
/* Maps new_w weights in place, using either one of the predefined functions, or a custom curve.
* Return values are in new_w.
@@ -58,7 +58,8 @@ struct Tex;
* vertex index (in case the weight tables do not cover the whole vertices...).
* cmap might be NULL, in which case curve mapping mode will return unmodified data.
*/
-void weightvg_do_map(int num, float *new_w, short mode, struct CurveMapping *cmap, struct RNG *rng);
+void weightvg_do_map(
+ int num, float *new_w, short mode, struct CurveMapping *cmap, struct RNG *rng);
/* Applies new_w weights to org_w ones, using either a texture, vgroup or constant value as factor.
* Return values are in org_w.
@@ -66,20 +67,35 @@ void weightvg_do_map(int num, float *new_w, short mode, struct CurveMapping *cma
* vertex index (in case the weight tables do not cover the whole vertices...).
* XXX The standard "factor" value is assumed in [0.0, 1.0] range. Else, weird results might appear.
*/
-void weightvg_do_mask(
- const ModifierEvalContext *ctx,
- const int num, const int *indices, float *org_w, const float *new_w, Object *ob,
- struct Mesh *mesh, const float fact, const char defgrp_name[MAX_VGROUP_NAME],
- struct Scene *scene, Tex *texture, const int tex_use_channel, const int tex_mapping,
- Object *tex_map_object, const char *tex_uvlayer_name);
+void weightvg_do_mask(const ModifierEvalContext *ctx,
+ const int num,
+ const int *indices,
+ float *org_w,
+ const float *new_w,
+ Object *ob,
+ struct Mesh *mesh,
+ const float fact,
+ const char defgrp_name[MAX_VGROUP_NAME],
+ struct Scene *scene,
+ Tex *texture,
+ const int tex_use_channel,
+ const int tex_mapping,
+ Object *tex_map_object,
+ const char *tex_uvlayer_name);
/* Applies weights to given vgroup (defgroup), and optionally add/remove vertices from the group.
* If indices is not NULL, it must be a table of same length as weights, mapping to the real
* vertex index (in case the weight table does not cover the whole vertices...).
*/
-void weightvg_update_vg(
- struct MDeformVert *dvert, int defgrp_idx, struct MDeformWeight **dws, int num,
- const int *indices, const float *weights, const bool do_add,
- const float add_thresh, const bool do_rem, const float rem_thresh);
+void weightvg_update_vg(struct MDeformVert *dvert,
+ int defgrp_idx,
+ struct MDeformWeight **dws,
+ int num,
+ const int *indices,
+ const float *weights,
+ const bool do_add,
+ const float add_thresh,
+ const bool do_rem,
+ const float rem_thresh);
#endif /* __MOD_WEIGHTVG_UTIL_H__ */
diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c
index 17ccd67dfc9..5f4983af6cc 100644
--- a/source/blender/modifiers/intern/MOD_weightvgedit.c
+++ b/source/blender/modifiers/intern/MOD_weightvgedit.c
@@ -27,17 +27,17 @@
#include "BLI_listbase.h"
#include "BLI_rand.h"
-#include "DNA_color_types.h" /* CurveMapping. */
+#include "DNA_color_types.h" /* CurveMapping. */
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
-#include "BKE_colortools.h" /* CurveMapping. */
+#include "BKE_colortools.h" /* CurveMapping. */
#include "BKE_deform.h"
#include "BKE_library_query.h"
#include "BKE_modifier.h"
-#include "BKE_texture.h" /* Texture masking. */
+#include "BKE_texture.h" /* Texture masking. */
#include "DEG_depsgraph_build.h"
#include "DEG_depsgraph_query.h"
@@ -52,248 +52,266 @@
**************************************/
static void initData(ModifierData *md)
{
- WeightVGEditModifierData *wmd = (WeightVGEditModifierData *) md;
- wmd->edit_flags = 0;
- wmd->falloff_type = MOD_WVG_MAPPING_NONE;
- wmd->default_weight = 0.0f;
+ WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
+ wmd->edit_flags = 0;
+ wmd->falloff_type = MOD_WVG_MAPPING_NONE;
+ wmd->default_weight = 0.0f;
- wmd->cmap_curve = curvemapping_add(1, 0.0, 0.0, 1.0, 1.0);
- curvemapping_initialize(wmd->cmap_curve);
+ wmd->cmap_curve = curvemapping_add(1, 0.0, 0.0, 1.0, 1.0);
+ curvemapping_initialize(wmd->cmap_curve);
- wmd->rem_threshold = 0.01f;
- wmd->add_threshold = 0.01f;
+ wmd->rem_threshold = 0.01f;
+ wmd->add_threshold = 0.01f;
- wmd->mask_constant = 1.0f;
- wmd->mask_tex_use_channel = MOD_WVG_MASK_TEX_USE_INT; /* Use intensity by default. */
- wmd->mask_tex_mapping = MOD_DISP_MAP_LOCAL;
+ wmd->mask_constant = 1.0f;
+ wmd->mask_tex_use_channel = MOD_WVG_MASK_TEX_USE_INT; /* Use intensity by default. */
+ wmd->mask_tex_mapping = MOD_DISP_MAP_LOCAL;
}
static void freeData(ModifierData *md)
{
- WeightVGEditModifierData *wmd = (WeightVGEditModifierData *) md;
- curvemapping_free(wmd->cmap_curve);
+ WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
+ curvemapping_free(wmd->cmap_curve);
}
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
{
- const WeightVGEditModifierData *wmd = (const WeightVGEditModifierData *) md;
- WeightVGEditModifierData *twmd = (WeightVGEditModifierData *) target;
+ const WeightVGEditModifierData *wmd = (const WeightVGEditModifierData *)md;
+ WeightVGEditModifierData *twmd = (WeightVGEditModifierData *)target;
- modifier_copyData_generic(md, target, flag);
+ modifier_copyData_generic(md, target, flag);
- twmd->cmap_curve = curvemapping_copy(wmd->cmap_curve);
+ twmd->cmap_curve = curvemapping_copy(wmd->cmap_curve);
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- WeightVGEditModifierData *wmd = (WeightVGEditModifierData *) md;
+ WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
- /* We need vertex groups! */
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ /* We need vertex groups! */
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- /* Ask for UV coordinates if we need them. */
- if (wmd->mask_tex_mapping == MOD_DISP_MAP_UV) {
- r_cddata_masks->fmask |= CD_MASK_MTFACE;
- }
+ /* Ask for UV coordinates if we need them. */
+ if (wmd->mask_tex_mapping == MOD_DISP_MAP_UV) {
+ r_cddata_masks->fmask |= CD_MASK_MTFACE;
+ }
- /* No need to ask for CD_PREVIEW_MLOOPCOL... */
+ /* No need to ask for CD_PREVIEW_MLOOPCOL... */
}
static bool dependsOnTime(ModifierData *md)
{
- WeightVGEditModifierData *wmd = (WeightVGEditModifierData *) md;
+ WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
- if (wmd->mask_texture)
- return BKE_texture_dependsOnTime(wmd->mask_texture);
- return false;
+ if (wmd->mask_texture)
+ return BKE_texture_dependsOnTime(wmd->mask_texture);
+ return false;
}
static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- WeightVGEditModifierData *wmd = (WeightVGEditModifierData *) md;
- walk(userData, ob, &wmd->mask_tex_map_obj, IDWALK_CB_NOP);
+ WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
+ walk(userData, ob, &wmd->mask_tex_map_obj, IDWALK_CB_NOP);
}
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
- WeightVGEditModifierData *wmd = (WeightVGEditModifierData *) md;
+ WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
- walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER);
+ walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER);
- foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
+ foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
}
static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
{
- walk(userData, ob, md, "mask_texture");
+ walk(userData, ob, md, "mask_texture");
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
- if (wmd->mask_tex_map_obj != NULL && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) {
- DEG_add_object_relation(ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_TRANSFORM, "WeightVGEdit Modifier");
- DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGEdit Modifier");
- }
- else if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL) {
- DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGEdit Modifier");
- }
- if (wmd->mask_texture != NULL) {
- DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGEdit Modifier");
- }
+ WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
+ if (wmd->mask_tex_map_obj != NULL && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) {
+ DEG_add_object_relation(
+ ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_TRANSFORM, "WeightVGEdit Modifier");
+ DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGEdit Modifier");
+ }
+ else if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL) {
+ DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGEdit Modifier");
+ }
+ if (wmd->mask_texture != NULL) {
+ DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGEdit Modifier");
+ }
}
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(useRenderParams))
{
- WeightVGEditModifierData *wmd = (WeightVGEditModifierData *) md;
- /* If no vertex group, bypass. */
- return (wmd->defgrp_name[0] == '\0');
+ WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
+ /* If no vertex group, bypass. */
+ return (wmd->defgrp_name[0] == '\0');
}
-static Mesh *applyModifier(
- ModifierData *md,
- const ModifierEvalContext *ctx,
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- BLI_assert(mesh != NULL);
+ BLI_assert(mesh != NULL);
- WeightVGEditModifierData *wmd = (WeightVGEditModifierData *) md;
+ WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
- MDeformVert *dvert = NULL;
- MDeformWeight **dw = NULL;
- float *org_w; /* Array original weights. */
- float *new_w; /* Array new weights. */
- int i;
+ MDeformVert *dvert = NULL;
+ MDeformWeight **dw = NULL;
+ float *org_w; /* Array original weights. */
+ float *new_w; /* Array new weights. */
+ int i;
- /* Flags. */
- const bool do_add = (wmd->edit_flags & MOD_WVG_EDIT_ADD2VG) != 0;
- const bool do_rem = (wmd->edit_flags & MOD_WVG_EDIT_REMFVG) != 0;
- /* Only do weight-preview in Object, Sculpt and Pose modes! */
+ /* Flags. */
+ const bool do_add = (wmd->edit_flags & MOD_WVG_EDIT_ADD2VG) != 0;
+ const bool do_rem = (wmd->edit_flags & MOD_WVG_EDIT_REMFVG) != 0;
+ /* Only do weight-preview in Object, Sculpt and Pose modes! */
#if 0
- const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview);
+ const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview);
#endif
- /* Get number of verts. */
- const int numVerts = mesh->totvert;
-
- /* Check if we can just return the original mesh.
- * Must have verts and therefore verts assigned to vgroups to do anything useful!
- */
- if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) {
- return mesh;
- }
-
- /* Get vgroup idx from its name. */
- const int defgrp_index = defgroup_name_index(ctx->object, wmd->defgrp_name);
- if (defgrp_index == -1) {
- return mesh;
- }
-
- const bool has_mdef = CustomData_has_layer(&mesh->vdata, CD_MDEFORMVERT);
- /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
- if (!has_mdef) {
- /* If this modifier is not allowed to add vertices, just return. */
- if (!do_add) {
- return mesh;
- }
- }
-
- if (has_mdef) {
- dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts);
- }
- else {
- /* Add a valid data layer! */
- dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts);
- }
- /* Ultimate security check. */
- if (!dvert) {
- return mesh;
- }
- mesh->dvert = dvert;
-
- /* Get org weights, assuming 0.0 for vertices not in given vgroup. */
- org_w = MEM_malloc_arrayN(numVerts, sizeof(float), "WeightVGEdit Modifier, org_w");
- new_w = MEM_malloc_arrayN(numVerts, sizeof(float), "WeightVGEdit Modifier, new_w");
- dw = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGEdit Modifier, dw");
- for (i = 0; i < numVerts; i++) {
- dw[i] = defvert_find_index(&dvert[i], defgrp_index);
- if (dw[i]) {
- org_w[i] = new_w[i] = dw[i]->weight;
- }
- else {
- org_w[i] = new_w[i] = wmd->default_weight;
- }
- }
-
- /* Do mapping. */
- if (wmd->falloff_type != MOD_WVG_MAPPING_NONE) {
- RNG *rng = NULL;
-
- if (wmd->falloff_type == MOD_WVG_MAPPING_RANDOM) {
- rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ctx->object->id.name + 2));
- }
-
- weightvg_do_map(numVerts, new_w, wmd->falloff_type, wmd->cmap_curve, rng);
-
- if (rng) {
- BLI_rng_free(rng);
- }
- }
-
- /* Do masking. */
- struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- weightvg_do_mask(ctx, numVerts, NULL, org_w, new_w, ctx->object, mesh, wmd->mask_constant,
- wmd->mask_defgrp_name, scene, wmd->mask_texture,
- wmd->mask_tex_use_channel, wmd->mask_tex_mapping,
- wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name);
-
- /* Update/add/remove from vgroup. */
- weightvg_update_vg(dvert, defgrp_index, dw, numVerts, NULL, org_w, do_add, wmd->add_threshold,
- do_rem, wmd->rem_threshold);
-
- /* If weight preview enabled... */
+ /* Get number of verts. */
+ const int numVerts = mesh->totvert;
+
+ /* Check if we can just return the original mesh.
+ * Must have verts and therefore verts assigned to vgroups to do anything useful!
+ */
+ if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) {
+ return mesh;
+ }
+
+ /* Get vgroup idx from its name. */
+ const int defgrp_index = defgroup_name_index(ctx->object, wmd->defgrp_name);
+ if (defgrp_index == -1) {
+ return mesh;
+ }
+
+ const bool has_mdef = CustomData_has_layer(&mesh->vdata, CD_MDEFORMVERT);
+ /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
+ if (!has_mdef) {
+ /* If this modifier is not allowed to add vertices, just return. */
+ if (!do_add) {
+ return mesh;
+ }
+ }
+
+ if (has_mdef) {
+ dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts);
+ }
+ else {
+ /* Add a valid data layer! */
+ dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts);
+ }
+ /* Ultimate security check. */
+ if (!dvert) {
+ return mesh;
+ }
+ mesh->dvert = dvert;
+
+ /* Get org weights, assuming 0.0 for vertices not in given vgroup. */
+ org_w = MEM_malloc_arrayN(numVerts, sizeof(float), "WeightVGEdit Modifier, org_w");
+ new_w = MEM_malloc_arrayN(numVerts, sizeof(float), "WeightVGEdit Modifier, new_w");
+ dw = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGEdit Modifier, dw");
+ for (i = 0; i < numVerts; i++) {
+ dw[i] = defvert_find_index(&dvert[i], defgrp_index);
+ if (dw[i]) {
+ org_w[i] = new_w[i] = dw[i]->weight;
+ }
+ else {
+ org_w[i] = new_w[i] = wmd->default_weight;
+ }
+ }
+
+ /* Do mapping. */
+ if (wmd->falloff_type != MOD_WVG_MAPPING_NONE) {
+ RNG *rng = NULL;
+
+ if (wmd->falloff_type == MOD_WVG_MAPPING_RANDOM) {
+ rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ctx->object->id.name + 2));
+ }
+
+ weightvg_do_map(numVerts, new_w, wmd->falloff_type, wmd->cmap_curve, rng);
+
+ if (rng) {
+ BLI_rng_free(rng);
+ }
+ }
+
+ /* Do masking. */
+ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ weightvg_do_mask(ctx,
+ numVerts,
+ NULL,
+ org_w,
+ new_w,
+ ctx->object,
+ mesh,
+ wmd->mask_constant,
+ wmd->mask_defgrp_name,
+ scene,
+ wmd->mask_texture,
+ wmd->mask_tex_use_channel,
+ wmd->mask_tex_mapping,
+ wmd->mask_tex_map_obj,
+ wmd->mask_tex_uvlayer_name);
+
+ /* Update/add/remove from vgroup. */
+ weightvg_update_vg(dvert,
+ defgrp_index,
+ dw,
+ numVerts,
+ NULL,
+ org_w,
+ do_add,
+ wmd->add_threshold,
+ do_rem,
+ wmd->rem_threshold);
+
+ /* If weight preview enabled... */
#if 0 /* XXX Currently done in mod stack :/ */
- if (do_prev)
- DM_update_weight_mcol(ob, dm, 0, org_w, 0, NULL);
+ if (do_prev)
+ DM_update_weight_mcol(ob, dm, 0, org_w, 0, NULL);
#endif
- /* Freeing stuff. */
- MEM_freeN(org_w);
- MEM_freeN(new_w);
- MEM_freeN(dw);
+ /* Freeing stuff. */
+ MEM_freeN(org_w);
+ MEM_freeN(new_w);
+ MEM_freeN(dw);
- /* Return the vgroup-modified mesh. */
- return mesh;
+ /* Return the vgroup-modified mesh. */
+ return mesh;
}
-
ModifierTypeInfo modifierType_WeightVGEdit = {
- /* name */ "VertexWeightEdit",
- /* structName */ "WeightVGEditModifierData",
- /* structSize */ sizeof(WeightVGEditModifierData),
- /* type */ eModifierTypeType_NonGeometrical,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsMapping |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_UsesPreview,
-
- /* copyData */ copyData,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ freeData,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ foreachIDLink,
- /* foreachTexLink */ foreachTexLink,
- /* freeRuntimeData */ NULL,
+ /* name */ "VertexWeightEdit",
+ /* structName */ "WeightVGEditModifierData",
+ /* structSize */ sizeof(WeightVGEditModifierData),
+ /* type */ eModifierTypeType_NonGeometrical,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_UsesPreview,
+
+ /* copyData */ copyData,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ freeData,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ foreachTexLink,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c
index 0894d30cfc1..ed2c2e5e940 100644
--- a/source/blender/modifiers/intern/MOD_weightvgmix.c
+++ b/source/blender/modifiers/intern/MOD_weightvgmix.c
@@ -35,7 +35,7 @@
#include "BKE_deform.h"
#include "BKE_library_query.h"
#include "BKE_modifier.h"
-#include "BKE_texture.h" /* Texture masking. */
+#include "BKE_texture.h" /* Texture masking. */
#include "DEG_depsgraph_build.h"
#include "DEG_depsgraph_query.h"
@@ -51,55 +51,56 @@
static float mix_weight(float weight, float weight2, char mix_mode)
{
#if 0
- /*
- * XXX Don't know why, but the switch version takes many CPU time,
- * and produces lag in realtime playback...
- */
- switch (mix_mode)
- {
- case MOD_WVG_MIX_ADD:
- return (weight + weight2);
- case MOD_WVG_MIX_SUB:
- return (weight - weight2);
- case MOD_WVG_MIX_MUL:
- return (weight * weight2);
- case MOD_WVG_MIX_DIV:
- /* Avoid dividing by zero (or really small values). */
- if (0.0 <= weight2 < MOD_WVG_ZEROFLOOR)
- weight2 = MOD_WVG_ZEROFLOOR;
- else if (-MOD_WVG_ZEROFLOOR < weight2)
- weight2 = -MOD_WVG_ZEROFLOOR;
- return (weight / weight2);
- case MOD_WVG_MIX_DIF:
- return (weight < weight2 ? weight2 - weight : weight - weight2);
- case MOD_WVG_MIX_AVG:
- return (weight + weight2) / 2.0;
- case MOD_WVG_MIX_SET:
- default:
- return weight2;
- }
+ /*
+ * XXX Don't know why, but the switch version takes many CPU time,
+ * and produces lag in realtime playback...
+ */
+ switch (mix_mode)
+ {
+ case MOD_WVG_MIX_ADD:
+ return (weight + weight2);
+ case MOD_WVG_MIX_SUB:
+ return (weight - weight2);
+ case MOD_WVG_MIX_MUL:
+ return (weight * weight2);
+ case MOD_WVG_MIX_DIV:
+ /* Avoid dividing by zero (or really small values). */
+ if (0.0 <= weight2 < MOD_WVG_ZEROFLOOR)
+ weight2 = MOD_WVG_ZEROFLOOR;
+ else if (-MOD_WVG_ZEROFLOOR < weight2)
+ weight2 = -MOD_WVG_ZEROFLOOR;
+ return (weight / weight2);
+ case MOD_WVG_MIX_DIF:
+ return (weight < weight2 ? weight2 - weight : weight - weight2);
+ case MOD_WVG_MIX_AVG:
+ return (weight + weight2) / 2.0;
+ case MOD_WVG_MIX_SET:
+ default:
+ return weight2;
+ }
#endif
- if (mix_mode == MOD_WVG_MIX_SET)
- return weight2;
- else if (mix_mode == MOD_WVG_MIX_ADD)
- return (weight + weight2);
- else if (mix_mode == MOD_WVG_MIX_SUB)
- return (weight - weight2);
- else if (mix_mode == MOD_WVG_MIX_MUL)
- return (weight * weight2);
- else if (mix_mode == MOD_WVG_MIX_DIV) {
- /* Avoid dividing by zero (or really small values). */
- if (weight2 < 0.0f && weight2 > -MOD_WVG_ZEROFLOOR)
- weight2 = -MOD_WVG_ZEROFLOOR;
- else if (weight2 >= 0.0f && weight2 < MOD_WVG_ZEROFLOOR)
- weight2 = MOD_WVG_ZEROFLOOR;
- return (weight / weight2);
- }
- else if (mix_mode == MOD_WVG_MIX_DIF)
- return (weight < weight2 ? weight2 - weight : weight - weight2);
- else if (mix_mode == MOD_WVG_MIX_AVG)
- return (weight + weight2) * 0.5f;
- else return weight2;
+ if (mix_mode == MOD_WVG_MIX_SET)
+ return weight2;
+ else if (mix_mode == MOD_WVG_MIX_ADD)
+ return (weight + weight2);
+ else if (mix_mode == MOD_WVG_MIX_SUB)
+ return (weight - weight2);
+ else if (mix_mode == MOD_WVG_MIX_MUL)
+ return (weight * weight2);
+ else if (mix_mode == MOD_WVG_MIX_DIV) {
+ /* Avoid dividing by zero (or really small values). */
+ if (weight2 < 0.0f && weight2 > -MOD_WVG_ZEROFLOOR)
+ weight2 = -MOD_WVG_ZEROFLOOR;
+ else if (weight2 >= 0.0f && weight2 < MOD_WVG_ZEROFLOOR)
+ weight2 = MOD_WVG_ZEROFLOOR;
+ return (weight / weight2);
+ }
+ else if (mix_mode == MOD_WVG_MIX_DIF)
+ return (weight < weight2 ? weight2 - weight : weight - weight2);
+ else if (mix_mode == MOD_WVG_MIX_AVG)
+ return (weight + weight2) * 0.5f;
+ else
+ return weight2;
}
/**************************************
@@ -107,306 +108,330 @@ static float mix_weight(float weight, float weight2, char mix_mode)
**************************************/
static void initData(ModifierData *md)
{
- WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md;
+ WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
- wmd->default_weight_a = 0.0f;
- wmd->default_weight_b = 0.0f;
- wmd->mix_mode = MOD_WVG_MIX_SET;
- wmd->mix_set = MOD_WVG_SET_AND;
+ wmd->default_weight_a = 0.0f;
+ wmd->default_weight_b = 0.0f;
+ wmd->mix_mode = MOD_WVG_MIX_SET;
+ wmd->mix_set = MOD_WVG_SET_AND;
- wmd->mask_constant = 1.0f;
- wmd->mask_tex_use_channel = MOD_WVG_MASK_TEX_USE_INT; /* Use intensity by default. */
- wmd->mask_tex_mapping = MOD_DISP_MAP_LOCAL;
+ wmd->mask_constant = 1.0f;
+ wmd->mask_tex_use_channel = MOD_WVG_MASK_TEX_USE_INT; /* Use intensity by default. */
+ wmd->mask_tex_mapping = MOD_DISP_MAP_LOCAL;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md;
+ WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
- /* We need vertex groups! */
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ /* We need vertex groups! */
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- /* Ask for UV coordinates if we need them. */
- if (wmd->mask_tex_mapping == MOD_DISP_MAP_UV) {
- r_cddata_masks->fmask |= CD_MASK_MTFACE;
- }
+ /* Ask for UV coordinates if we need them. */
+ if (wmd->mask_tex_mapping == MOD_DISP_MAP_UV) {
+ r_cddata_masks->fmask |= CD_MASK_MTFACE;
+ }
- /* No need to ask for CD_PREVIEW_MLOOPCOL... */
+ /* No need to ask for CD_PREVIEW_MLOOPCOL... */
}
static bool dependsOnTime(ModifierData *md)
{
- WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md;
+ WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
- if (wmd->mask_texture)
- return BKE_texture_dependsOnTime(wmd->mask_texture);
- return false;
+ if (wmd->mask_texture)
+ return BKE_texture_dependsOnTime(wmd->mask_texture);
+ return false;
}
static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md;
- walk(userData, ob, &wmd->mask_tex_map_obj, IDWALK_CB_NOP);
+ WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
+ walk(userData, ob, &wmd->mask_tex_map_obj, IDWALK_CB_NOP);
}
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
- WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md;
+ WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
- walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER);
+ walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER);
- foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
+ foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
}
static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
{
- walk(userData, ob, md, "mask_texture");
+ walk(userData, ob, md, "mask_texture");
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md;
- if (wmd->mask_tex_map_obj != NULL && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) {
- DEG_add_object_relation(ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_TRANSFORM, "WeightVGMix Modifier");
- DEG_add_object_relation(ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_GEOMETRY, "WeightVGMix Modifier");
-
- DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGMix Modifier");
- }
- else if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL) {
- DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGMix Modifier");
- }
- if (wmd->mask_texture != NULL) {
- DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGMix Modifier");
- }
+ WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
+ if (wmd->mask_tex_map_obj != NULL && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) {
+ DEG_add_object_relation(
+ ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_TRANSFORM, "WeightVGMix Modifier");
+ DEG_add_object_relation(
+ ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_GEOMETRY, "WeightVGMix Modifier");
+
+ DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGMix Modifier");
+ }
+ else if (wmd->mask_tex_mapping == MOD_DISP_MAP_GLOBAL) {
+ DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGMix Modifier");
+ }
+ if (wmd->mask_texture != NULL) {
+ DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGMix Modifier");
+ }
}
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(useRenderParams))
{
- WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md;
- /* If no vertex group, bypass. */
- return (wmd->defgrp_name_a[0] == '\0');
+ WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
+ /* If no vertex group, bypass. */
+ return (wmd->defgrp_name_a[0] == '\0');
}
static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- BLI_assert(mesh != NULL);
-
- WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md;
-
- MDeformVert *dvert = NULL;
- MDeformWeight **dw1, **tdw1, **dw2, **tdw2;
- float *org_w;
- float *new_w;
- int *tidx, *indices = NULL;
- int numIdx = 0;
- int i;
- /* Flags. */
+ BLI_assert(mesh != NULL);
+
+ WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md;
+
+ MDeformVert *dvert = NULL;
+ MDeformWeight **dw1, **tdw1, **dw2, **tdw2;
+ float *org_w;
+ float *new_w;
+ int *tidx, *indices = NULL;
+ int numIdx = 0;
+ int i;
+ /* Flags. */
#if 0
- const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview) != 0;
+ const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview) != 0;
#endif
- /* Get number of verts. */
- const int numVerts = mesh->totvert;
-
- /* Check if we can just return the original mesh.
- * Must have verts and therefore verts assigned to vgroups to do anything useful!
- */
- if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) {
- return mesh;
- }
-
- /* Get vgroup idx from its name. */
- const int defgrp_index = defgroup_name_index(ctx->object, wmd->defgrp_name_a);
- if (defgrp_index == -1) {
- return mesh;
- }
- /* Get second vgroup idx from its name, if given. */
- int defgrp_index_other = -1;
- if (wmd->defgrp_name_b[0] != '\0') {
- defgrp_index_other = defgroup_name_index(ctx->object, wmd->defgrp_name_b);
- if (defgrp_index_other == -1) {
- return mesh;
- }
- }
-
- const bool has_mdef = CustomData_has_layer(&mesh->vdata, CD_MDEFORMVERT);
- /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
- if (!has_mdef) {
- /* If not affecting all vertices, just return. */
- if (wmd->mix_set != MOD_WVG_SET_ALL) {
- return mesh;
- }
- }
-
- if (has_mdef) {
- dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts);
- }
- else {
- /* Add a valid data layer! */
- dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts);
- }
- /* Ultimate security check. */
- if (!dvert) {
- return mesh;
- }
- mesh->dvert = dvert;
-
- /* Find out which vertices to work on. */
- tidx = MEM_malloc_arrayN(numVerts, sizeof(int), "WeightVGMix Modifier, tidx");
- tdw1 = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw1");
- tdw2 = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw2");
- switch (wmd->mix_set) {
- case MOD_WVG_SET_A:
- /* All vertices in first vgroup. */
- for (i = 0; i < numVerts; i++) {
- MDeformWeight *dw = defvert_find_index(&dvert[i], defgrp_index);
- if (dw) {
- tdw1[numIdx] = dw;
- tdw2[numIdx] = (defgrp_index_other >= 0) ? defvert_find_index(&dvert[i], defgrp_index_other) : NULL;
- tidx[numIdx++] = i;
- }
- }
- break;
- case MOD_WVG_SET_B:
- /* All vertices in second vgroup. */
- for (i = 0; i < numVerts; i++) {
- MDeformWeight *dw = (defgrp_index_other >= 0) ? defvert_find_index(&dvert[i], defgrp_index_other) : NULL;
- if (dw) {
- tdw1[numIdx] = defvert_find_index(&dvert[i], defgrp_index);
- tdw2[numIdx] = dw;
- tidx[numIdx++] = i;
- }
- }
- break;
- case MOD_WVG_SET_OR:
- /* All vertices in one vgroup or the other. */
- for (i = 0; i < numVerts; i++) {
- MDeformWeight *adw = defvert_find_index(&dvert[i], defgrp_index);
- MDeformWeight *bdw = (defgrp_index_other >= 0) ? defvert_find_index(&dvert[i], defgrp_index_other) : NULL;
- if (adw || bdw) {
- tdw1[numIdx] = adw;
- tdw2[numIdx] = bdw;
- tidx[numIdx++] = i;
- }
- }
- break;
- case MOD_WVG_SET_AND:
- /* All vertices in both vgroups. */
- for (i = 0; i < numVerts; i++) {
- MDeformWeight *adw = defvert_find_index(&dvert[i], defgrp_index);
- MDeformWeight *bdw = (defgrp_index_other >= 0) ? defvert_find_index(&dvert[i], defgrp_index_other) : NULL;
- if (adw && bdw) {
- tdw1[numIdx] = adw;
- tdw2[numIdx] = bdw;
- tidx[numIdx++] = i;
- }
- }
- break;
- case MOD_WVG_SET_ALL:
- default:
- /* Use all vertices. */
- for (i = 0; i < numVerts; i++) {
- tdw1[i] = defvert_find_index(&dvert[i], defgrp_index);
- tdw2[i] = (defgrp_index_other >= 0) ? defvert_find_index(&dvert[i], defgrp_index_other) : NULL;
- }
- numIdx = -1;
- break;
- }
- if (numIdx == 0) {
- /* Use no vertices! Hence, return org data. */
- MEM_freeN(tdw1);
- MEM_freeN(tdw2);
- MEM_freeN(tidx);
- return mesh;
- }
- if (numIdx != -1) {
- indices = MEM_malloc_arrayN(numIdx, sizeof(int), "WeightVGMix Modifier, indices");
- memcpy(indices, tidx, sizeof(int) * numIdx);
- dw1 = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw1");
- memcpy(dw1, tdw1, sizeof(MDeformWeight *) * numIdx);
- MEM_freeN(tdw1);
- dw2 = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw2");
- memcpy(dw2, tdw2, sizeof(MDeformWeight *) * numIdx);
- MEM_freeN(tdw2);
- }
- else {
- /* Use all vertices. */
- numIdx = numVerts;
- /* Just copy MDeformWeight pointers arrays, they will be freed at the end. */
- dw1 = tdw1;
- dw2 = tdw2;
- }
- MEM_freeN(tidx);
-
- org_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGMix Modifier, org_w");
- new_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGMix Modifier, new_w");
-
- /* Mix weights. */
- for (i = 0; i < numIdx; i++) {
- float weight2;
- org_w[i] = dw1[i] ? dw1[i]->weight : wmd->default_weight_a;
- weight2 = dw2[i] ? dw2[i]->weight : wmd->default_weight_b;
-
- new_w[i] = mix_weight(org_w[i], weight2, wmd->mix_mode);
- }
-
- /* Do masking. */
- struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- weightvg_do_mask(ctx, numIdx, indices, org_w, new_w, ctx->object, mesh, wmd->mask_constant,
- wmd->mask_defgrp_name, scene, wmd->mask_texture,
- wmd->mask_tex_use_channel, wmd->mask_tex_mapping,
- wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name);
-
- /* Update (add to) vgroup.
- * XXX Depending on the MOD_WVG_SET_xxx option chosen, we might have to add vertices to vgroup.
- */
- weightvg_update_vg(dvert, defgrp_index, dw1, numIdx, indices, org_w, true, -FLT_MAX, false, 0.0f);
-
- /* If weight preview enabled... */
+ /* Get number of verts. */
+ const int numVerts = mesh->totvert;
+
+ /* Check if we can just return the original mesh.
+ * Must have verts and therefore verts assigned to vgroups to do anything useful!
+ */
+ if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) {
+ return mesh;
+ }
+
+ /* Get vgroup idx from its name. */
+ const int defgrp_index = defgroup_name_index(ctx->object, wmd->defgrp_name_a);
+ if (defgrp_index == -1) {
+ return mesh;
+ }
+ /* Get second vgroup idx from its name, if given. */
+ int defgrp_index_other = -1;
+ if (wmd->defgrp_name_b[0] != '\0') {
+ defgrp_index_other = defgroup_name_index(ctx->object, wmd->defgrp_name_b);
+ if (defgrp_index_other == -1) {
+ return mesh;
+ }
+ }
+
+ const bool has_mdef = CustomData_has_layer(&mesh->vdata, CD_MDEFORMVERT);
+ /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
+ if (!has_mdef) {
+ /* If not affecting all vertices, just return. */
+ if (wmd->mix_set != MOD_WVG_SET_ALL) {
+ return mesh;
+ }
+ }
+
+ if (has_mdef) {
+ dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts);
+ }
+ else {
+ /* Add a valid data layer! */
+ dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts);
+ }
+ /* Ultimate security check. */
+ if (!dvert) {
+ return mesh;
+ }
+ mesh->dvert = dvert;
+
+ /* Find out which vertices to work on. */
+ tidx = MEM_malloc_arrayN(numVerts, sizeof(int), "WeightVGMix Modifier, tidx");
+ tdw1 = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw1");
+ tdw2 = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw2");
+ switch (wmd->mix_set) {
+ case MOD_WVG_SET_A:
+ /* All vertices in first vgroup. */
+ for (i = 0; i < numVerts; i++) {
+ MDeformWeight *dw = defvert_find_index(&dvert[i], defgrp_index);
+ if (dw) {
+ tdw1[numIdx] = dw;
+ tdw2[numIdx] = (defgrp_index_other >= 0) ?
+ defvert_find_index(&dvert[i], defgrp_index_other) :
+ NULL;
+ tidx[numIdx++] = i;
+ }
+ }
+ break;
+ case MOD_WVG_SET_B:
+ /* All vertices in second vgroup. */
+ for (i = 0; i < numVerts; i++) {
+ MDeformWeight *dw = (defgrp_index_other >= 0) ?
+ defvert_find_index(&dvert[i], defgrp_index_other) :
+ NULL;
+ if (dw) {
+ tdw1[numIdx] = defvert_find_index(&dvert[i], defgrp_index);
+ tdw2[numIdx] = dw;
+ tidx[numIdx++] = i;
+ }
+ }
+ break;
+ case MOD_WVG_SET_OR:
+ /* All vertices in one vgroup or the other. */
+ for (i = 0; i < numVerts; i++) {
+ MDeformWeight *adw = defvert_find_index(&dvert[i], defgrp_index);
+ MDeformWeight *bdw = (defgrp_index_other >= 0) ?
+ defvert_find_index(&dvert[i], defgrp_index_other) :
+ NULL;
+ if (adw || bdw) {
+ tdw1[numIdx] = adw;
+ tdw2[numIdx] = bdw;
+ tidx[numIdx++] = i;
+ }
+ }
+ break;
+ case MOD_WVG_SET_AND:
+ /* All vertices in both vgroups. */
+ for (i = 0; i < numVerts; i++) {
+ MDeformWeight *adw = defvert_find_index(&dvert[i], defgrp_index);
+ MDeformWeight *bdw = (defgrp_index_other >= 0) ?
+ defvert_find_index(&dvert[i], defgrp_index_other) :
+ NULL;
+ if (adw && bdw) {
+ tdw1[numIdx] = adw;
+ tdw2[numIdx] = bdw;
+ tidx[numIdx++] = i;
+ }
+ }
+ break;
+ case MOD_WVG_SET_ALL:
+ default:
+ /* Use all vertices. */
+ for (i = 0; i < numVerts; i++) {
+ tdw1[i] = defvert_find_index(&dvert[i], defgrp_index);
+ tdw2[i] = (defgrp_index_other >= 0) ? defvert_find_index(&dvert[i], defgrp_index_other) :
+ NULL;
+ }
+ numIdx = -1;
+ break;
+ }
+ if (numIdx == 0) {
+ /* Use no vertices! Hence, return org data. */
+ MEM_freeN(tdw1);
+ MEM_freeN(tdw2);
+ MEM_freeN(tidx);
+ return mesh;
+ }
+ if (numIdx != -1) {
+ indices = MEM_malloc_arrayN(numIdx, sizeof(int), "WeightVGMix Modifier, indices");
+ memcpy(indices, tidx, sizeof(int) * numIdx);
+ dw1 = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw1");
+ memcpy(dw1, tdw1, sizeof(MDeformWeight *) * numIdx);
+ MEM_freeN(tdw1);
+ dw2 = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw2");
+ memcpy(dw2, tdw2, sizeof(MDeformWeight *) * numIdx);
+ MEM_freeN(tdw2);
+ }
+ else {
+ /* Use all vertices. */
+ numIdx = numVerts;
+ /* Just copy MDeformWeight pointers arrays, they will be freed at the end. */
+ dw1 = tdw1;
+ dw2 = tdw2;
+ }
+ MEM_freeN(tidx);
+
+ org_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGMix Modifier, org_w");
+ new_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGMix Modifier, new_w");
+
+ /* Mix weights. */
+ for (i = 0; i < numIdx; i++) {
+ float weight2;
+ org_w[i] = dw1[i] ? dw1[i]->weight : wmd->default_weight_a;
+ weight2 = dw2[i] ? dw2[i]->weight : wmd->default_weight_b;
+
+ new_w[i] = mix_weight(org_w[i], weight2, wmd->mix_mode);
+ }
+
+ /* Do masking. */
+ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ weightvg_do_mask(ctx,
+ numIdx,
+ indices,
+ org_w,
+ new_w,
+ ctx->object,
+ mesh,
+ wmd->mask_constant,
+ wmd->mask_defgrp_name,
+ scene,
+ wmd->mask_texture,
+ wmd->mask_tex_use_channel,
+ wmd->mask_tex_mapping,
+ wmd->mask_tex_map_obj,
+ wmd->mask_tex_uvlayer_name);
+
+ /* Update (add to) vgroup.
+ * XXX Depending on the MOD_WVG_SET_xxx option chosen, we might have to add vertices to vgroup.
+ */
+ weightvg_update_vg(
+ dvert, defgrp_index, dw1, numIdx, indices, org_w, true, -FLT_MAX, false, 0.0f);
+
+ /* If weight preview enabled... */
#if 0 /* XXX Currently done in mod stack :/ */
- if (do_prev)
- DM_update_weight_mcol(ob, dm, 0, org_w, numIdx, indices);
+ if (do_prev)
+ DM_update_weight_mcol(ob, dm, 0, org_w, numIdx, indices);
#endif
- /* Freeing stuff. */
- MEM_freeN(org_w);
- MEM_freeN(new_w);
- MEM_freeN(dw1);
- MEM_freeN(dw2);
- MEM_SAFE_FREE(indices);
+ /* Freeing stuff. */
+ MEM_freeN(org_w);
+ MEM_freeN(new_w);
+ MEM_freeN(dw1);
+ MEM_freeN(dw2);
+ MEM_SAFE_FREE(indices);
- /* Return the vgroup-modified mesh. */
- return mesh;
+ /* Return the vgroup-modified mesh. */
+ return mesh;
}
-
ModifierTypeInfo modifierType_WeightVGMix = {
- /* name */ "VertexWeightMix",
- /* structName */ "WeightVGMixModifierData",
- /* structSize */ sizeof(WeightVGMixModifierData),
- /* type */ eModifierTypeType_NonGeometrical,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsMapping |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_UsesPreview,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ foreachIDLink,
- /* foreachTexLink */ foreachTexLink,
- /* freeRuntimeData */ NULL,
+ /* name */ "VertexWeightMix",
+ /* structName */ "WeightVGMixModifierData",
+ /* structSize */ sizeof(WeightVGMixModifierData),
+ /* type */ eModifierTypeType_NonGeometrical,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_UsesPreview,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ foreachTexLink,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c
index 89ba5395775..66b7ddb54d6 100644
--- a/source/blender/modifiers/intern/MOD_weightvgproximity.c
+++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c
@@ -42,7 +42,7 @@
#include "BKE_library_query.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
-#include "BKE_texture.h" /* Texture masking. */
+#include "BKE_texture.h" /* Texture masking. */
#include "DEG_depsgraph_build.h"
#include "DEG_depsgraph_query.h"
@@ -68,135 +68,138 @@
#define OUT_OF_MEMORY() ((void)printf("WeightVGProximity: Out of memory.\n"))
typedef struct Vert2GeomData {
- /* Read-only data */
- float (*v_cos)[3];
+ /* Read-only data */
+ float (*v_cos)[3];
- const SpaceTransform *loc2trgt;
+ const SpaceTransform *loc2trgt;
- BVHTreeFromMesh *treeData[3];
+ BVHTreeFromMesh *treeData[3];
- /* Write data, but not needing locking (two different threads will never write same index). */
- float *dist[3];
+ /* Write data, but not needing locking (two different threads will never write same index). */
+ float *dist[3];
} Vert2GeomData;
/* Data which is localized to each computed chunk (i.e. thread-safe, and with continuous subset of index range). */
typedef struct Vert2GeomDataChunk {
- /* Read-only data */
- float last_hit_co[3][3];
- bool is_init[3];
+ /* Read-only data */
+ float last_hit_co[3][3];
+ bool is_init[3];
} Vert2GeomDataChunk;
/**
* Callback used by BLI_task 'for loop' helper.
*/
-static void vert2geom_task_cb_ex(
- void *__restrict userdata,
- const int iter,
- const ParallelRangeTLS *__restrict tls)
+static void vert2geom_task_cb_ex(void *__restrict userdata,
+ const int iter,
+ const ParallelRangeTLS *__restrict tls)
{
- Vert2GeomData *data = userdata;
- Vert2GeomDataChunk *data_chunk = tls->userdata_chunk;
-
- float tmp_co[3];
- int i;
-
- /* Convert the vertex to tree coordinates. */
- copy_v3_v3(tmp_co, data->v_cos[iter]);
- BLI_space_transform_apply(data->loc2trgt, tmp_co);
-
- for (i = 0; i < ARRAY_SIZE(data->dist); i++) {
- if (data->dist[i]) {
- BVHTreeNearest nearest = {0};
-
- /* Note that we use local proximity heuristics (to reduce the nearest search).
- *
- * If we already had an hit before in same chunk of tasks (i.e. previous vertex by index),
- * we assume this vertex is going to have a close hit to that other vertex, so we can initiate
- * the "nearest.dist" with the expected value to that last hit.
- * This will lead in pruning of the search tree.
- */
- nearest.dist_sq = data_chunk->is_init[i] ? len_squared_v3v3(tmp_co, data_chunk->last_hit_co[i]) : FLT_MAX;
- nearest.index = -1;
-
- /* Compute and store result. If invalid (-1 idx), keep FLT_MAX dist. */
- BLI_bvhtree_find_nearest(data->treeData[i]->tree, tmp_co, &nearest,
- data->treeData[i]->nearest_callback, data->treeData[i]);
- data->dist[i][iter] = sqrtf(nearest.dist_sq);
-
- if (nearest.index != -1) {
- copy_v3_v3(data_chunk->last_hit_co[i], nearest.co);
- data_chunk->is_init[i] = true;
- }
- }
- }
+ Vert2GeomData *data = userdata;
+ Vert2GeomDataChunk *data_chunk = tls->userdata_chunk;
+
+ float tmp_co[3];
+ int i;
+
+ /* Convert the vertex to tree coordinates. */
+ copy_v3_v3(tmp_co, data->v_cos[iter]);
+ BLI_space_transform_apply(data->loc2trgt, tmp_co);
+
+ for (i = 0; i < ARRAY_SIZE(data->dist); i++) {
+ if (data->dist[i]) {
+ BVHTreeNearest nearest = {0};
+
+ /* Note that we use local proximity heuristics (to reduce the nearest search).
+ *
+ * If we already had an hit before in same chunk of tasks (i.e. previous vertex by index),
+ * we assume this vertex is going to have a close hit to that other vertex, so we can initiate
+ * the "nearest.dist" with the expected value to that last hit.
+ * This will lead in pruning of the search tree.
+ */
+ nearest.dist_sq = data_chunk->is_init[i] ?
+ len_squared_v3v3(tmp_co, data_chunk->last_hit_co[i]) :
+ FLT_MAX;
+ nearest.index = -1;
+
+ /* Compute and store result. If invalid (-1 idx), keep FLT_MAX dist. */
+ BLI_bvhtree_find_nearest(data->treeData[i]->tree,
+ tmp_co,
+ &nearest,
+ data->treeData[i]->nearest_callback,
+ data->treeData[i]);
+ data->dist[i][iter] = sqrtf(nearest.dist_sq);
+
+ if (nearest.index != -1) {
+ copy_v3_v3(data_chunk->last_hit_co[i], nearest.co);
+ data_chunk->is_init[i] = true;
+ }
+ }
+ }
}
/**
* Find nearest vertex and/or edge and/or face, for each vertex (adapted from shrinkwrap.c).
*/
-static void get_vert2geom_distance(
- int numVerts, float (*v_cos)[3],
- float *dist_v, float *dist_e, float *dist_f,
- Mesh *target, const SpaceTransform *loc2trgt)
+static void get_vert2geom_distance(int numVerts,
+ float (*v_cos)[3],
+ float *dist_v,
+ float *dist_e,
+ float *dist_f,
+ Mesh *target,
+ const SpaceTransform *loc2trgt)
{
- Vert2GeomData data = {0};
- Vert2GeomDataChunk data_chunk = {{{0}}};
-
- BVHTreeFromMesh treeData_v = {NULL};
- BVHTreeFromMesh treeData_e = {NULL};
- BVHTreeFromMesh treeData_f = {NULL};
-
- if (dist_v) {
- /* Create a bvh-tree of the given target's verts. */
- BKE_bvhtree_from_mesh_get(&treeData_v, target, BVHTREE_FROM_VERTS, 2);
- if (treeData_v.tree == NULL) {
- OUT_OF_MEMORY();
- return;
- }
- }
- if (dist_e) {
- /* Create a bvh-tree of the given target's edges. */
- BKE_bvhtree_from_mesh_get(&treeData_e, target, BVHTREE_FROM_EDGES, 2);
- if (treeData_e.tree == NULL) {
- OUT_OF_MEMORY();
- return;
- }
- }
- if (dist_f) {
- /* Create a bvh-tree of the given target's faces. */
- BKE_bvhtree_from_mesh_get(&treeData_f, target, BVHTREE_FROM_LOOPTRI, 2);
- if (treeData_f.tree == NULL) {
- OUT_OF_MEMORY();
- return;
- }
- }
-
- data.v_cos = v_cos;
- data.loc2trgt = loc2trgt;
- data.treeData[0] = &treeData_v;
- data.treeData[1] = &treeData_e;
- data.treeData[2] = &treeData_f;
- data.dist[0] = dist_v;
- data.dist[1] = dist_e;
- data.dist[2] = dist_f;
-
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.use_threading = (numVerts > 10000);
- settings.userdata_chunk = &data_chunk;
- settings.userdata_chunk_size = sizeof(data_chunk);
- BLI_task_parallel_range(
- 0, numVerts,
- &data,
- vert2geom_task_cb_ex,
- &settings);
-
- if (dist_v)
- free_bvhtree_from_mesh(&treeData_v);
- if (dist_e)
- free_bvhtree_from_mesh(&treeData_e);
- if (dist_f)
- free_bvhtree_from_mesh(&treeData_f);
+ Vert2GeomData data = {0};
+ Vert2GeomDataChunk data_chunk = {{{0}}};
+
+ BVHTreeFromMesh treeData_v = {NULL};
+ BVHTreeFromMesh treeData_e = {NULL};
+ BVHTreeFromMesh treeData_f = {NULL};
+
+ if (dist_v) {
+ /* Create a bvh-tree of the given target's verts. */
+ BKE_bvhtree_from_mesh_get(&treeData_v, target, BVHTREE_FROM_VERTS, 2);
+ if (treeData_v.tree == NULL) {
+ OUT_OF_MEMORY();
+ return;
+ }
+ }
+ if (dist_e) {
+ /* Create a bvh-tree of the given target's edges. */
+ BKE_bvhtree_from_mesh_get(&treeData_e, target, BVHTREE_FROM_EDGES, 2);
+ if (treeData_e.tree == NULL) {
+ OUT_OF_MEMORY();
+ return;
+ }
+ }
+ if (dist_f) {
+ /* Create a bvh-tree of the given target's faces. */
+ BKE_bvhtree_from_mesh_get(&treeData_f, target, BVHTREE_FROM_LOOPTRI, 2);
+ if (treeData_f.tree == NULL) {
+ OUT_OF_MEMORY();
+ return;
+ }
+ }
+
+ data.v_cos = v_cos;
+ data.loc2trgt = loc2trgt;
+ data.treeData[0] = &treeData_v;
+ data.treeData[1] = &treeData_e;
+ data.treeData[2] = &treeData_f;
+ data.dist[0] = dist_v;
+ data.dist[1] = dist_e;
+ data.dist[2] = dist_f;
+
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.use_threading = (numVerts > 10000);
+ settings.userdata_chunk = &data_chunk;
+ settings.userdata_chunk_size = sizeof(data_chunk);
+ BLI_task_parallel_range(0, numVerts, &data, vert2geom_task_cb_ex, &settings);
+
+ if (dist_v)
+ free_bvhtree_from_mesh(&treeData_v);
+ if (dist_e)
+ free_bvhtree_from_mesh(&treeData_e);
+ if (dist_f)
+ free_bvhtree_from_mesh(&treeData_f);
}
/**
@@ -204,19 +207,18 @@ static void get_vert2geom_distance(
* Note that it works in final world space (i.e. with constraints etc. applied).
*/
static void get_vert2ob_distance(
- int numVerts, float (*v_cos)[3], float *dist,
- Object *ob, Object *obr)
+ int numVerts, float (*v_cos)[3], float *dist, Object *ob, Object *obr)
{
- /* Vertex and ref object coordinates. */
- float v_wco[3];
- unsigned int i = numVerts;
-
- while (i-- > 0) {
- /* Get world-coordinates of the vertex (constraints and anim included). */
- mul_v3_m4v3(v_wco, ob->obmat, v_cos[i]);
- /* Return distance between both coordinates. */
- dist[i] = len_v3v3(v_wco, obr->obmat[3]);
- }
+ /* Vertex and ref object coordinates. */
+ float v_wco[3];
+ unsigned int i = numVerts;
+
+ while (i-- > 0) {
+ /* Get world-coordinates of the vertex (constraints and anim included). */
+ mul_v3_m4v3(v_wco, ob->obmat, v_cos[i]);
+ /* Return distance between both coordinates. */
+ dist[i] = len_v3v3(v_wco, obr->obmat[3]);
+ }
}
/**
@@ -225,49 +227,56 @@ static void get_vert2ob_distance(
*/
static float get_ob2ob_distance(const Object *ob, const Object *obr)
{
- return len_v3v3(ob->obmat[3], obr->obmat[3]);
+ return len_v3v3(ob->obmat[3], obr->obmat[3]);
}
/**
* Maps distances to weights, with an optional "smoothing" mapping.
*/
-static void do_map(Object *ob, float *weights, const int nidx, const float min_d, const float max_d, short mode)
+static void do_map(
+ Object *ob, float *weights, const int nidx, const float min_d, const float max_d, short mode)
{
- const float range_inv = 1.0f / (max_d - min_d); /* invert since multiplication is faster */
- unsigned int i = nidx;
- if (max_d == min_d) {
- while (i-- > 0) {
- weights[i] = (weights[i] >= max_d) ? 1.0f : 0.0f; /* "Step" behavior... */
- }
- }
- else if (max_d > min_d) {
- while (i-- > 0) {
- if (weights[i] >= max_d) weights[i] = 1.0f; /* most likely case first */
- else if (weights[i] <= min_d) weights[i] = 0.0f;
- else weights[i] = (weights[i] - min_d) * range_inv;
- }
- }
- else {
- while (i-- > 0) {
- if (weights[i] <= max_d) weights[i] = 1.0f; /* most likely case first */
- else if (weights[i] >= min_d) weights[i] = 0.0f;
- else weights[i] = (weights[i] - min_d) * range_inv;
- }
- }
-
- if (!ELEM(mode, MOD_WVG_MAPPING_NONE, MOD_WVG_MAPPING_CURVE)) {
- RNG *rng = NULL;
-
- if (mode == MOD_WVG_MAPPING_RANDOM) {
- rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name + 2));
- }
-
- weightvg_do_map(nidx, weights, mode, NULL, rng);
-
- if (rng) {
- BLI_rng_free(rng);
- }
- }
+ const float range_inv = 1.0f / (max_d - min_d); /* invert since multiplication is faster */
+ unsigned int i = nidx;
+ if (max_d == min_d) {
+ while (i-- > 0) {
+ weights[i] = (weights[i] >= max_d) ? 1.0f : 0.0f; /* "Step" behavior... */
+ }
+ }
+ else if (max_d > min_d) {
+ while (i-- > 0) {
+ if (weights[i] >= max_d)
+ weights[i] = 1.0f; /* most likely case first */
+ else if (weights[i] <= min_d)
+ weights[i] = 0.0f;
+ else
+ weights[i] = (weights[i] - min_d) * range_inv;
+ }
+ }
+ else {
+ while (i-- > 0) {
+ if (weights[i] <= max_d)
+ weights[i] = 1.0f; /* most likely case first */
+ else if (weights[i] >= min_d)
+ weights[i] = 0.0f;
+ else
+ weights[i] = (weights[i] - min_d) * range_inv;
+ }
+ }
+
+ if (!ELEM(mode, MOD_WVG_MAPPING_NONE, MOD_WVG_MAPPING_CURVE)) {
+ RNG *rng = NULL;
+
+ if (mode == MOD_WVG_MAPPING_RANDOM) {
+ rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name + 2));
+ }
+
+ weightvg_do_map(nidx, weights, mode, NULL, rng);
+
+ if (rng) {
+ BLI_rng_free(rng);
+ }
+ }
}
/**************************************
@@ -275,312 +284,332 @@ static void do_map(Object *ob, float *weights, const int nidx, const float min_d
**************************************/
static void initData(ModifierData *md)
{
- WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *) md;
+ WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
- wmd->proximity_mode = MOD_WVG_PROXIMITY_OBJECT;
- wmd->proximity_flags = MOD_WVG_PROXIMITY_GEOM_VERTS;
+ wmd->proximity_mode = MOD_WVG_PROXIMITY_OBJECT;
+ wmd->proximity_flags = MOD_WVG_PROXIMITY_GEOM_VERTS;
- wmd->falloff_type = MOD_WVG_MAPPING_NONE;
+ wmd->falloff_type = MOD_WVG_MAPPING_NONE;
- wmd->mask_constant = 1.0f;
- wmd->mask_tex_use_channel = MOD_WVG_MASK_TEX_USE_INT; /* Use intensity by default. */
- wmd->mask_tex_mapping = MOD_DISP_MAP_LOCAL;
- wmd->max_dist = 1.0f; /* vert arbitrary distance, but don't use 0 */
+ wmd->mask_constant = 1.0f;
+ wmd->mask_tex_use_channel = MOD_WVG_MASK_TEX_USE_INT; /* Use intensity by default. */
+ wmd->mask_tex_mapping = MOD_DISP_MAP_LOCAL;
+ wmd->max_dist = 1.0f; /* vert arbitrary distance, but don't use 0 */
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *) md;
+ WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
- /* We need vertex groups! */
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ /* We need vertex groups! */
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- /* Ask for UV coordinates if we need them. */
- if (wmd->mask_tex_mapping == MOD_DISP_MAP_UV) {
- r_cddata_masks->fmask |= CD_MASK_MTFACE;
- }
+ /* Ask for UV coordinates if we need them. */
+ if (wmd->mask_tex_mapping == MOD_DISP_MAP_UV) {
+ r_cddata_masks->fmask |= CD_MASK_MTFACE;
+ }
- /* No need to ask for CD_PREVIEW_MLOOPCOL... */
+ /* No need to ask for CD_PREVIEW_MLOOPCOL... */
}
static bool dependsOnTime(ModifierData *md)
{
- WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *) md;
+ WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
- if (wmd->mask_texture)
- return BKE_texture_dependsOnTime(wmd->mask_texture);
- return 0;
+ if (wmd->mask_texture)
+ return BKE_texture_dependsOnTime(wmd->mask_texture);
+ return 0;
}
static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *) md;
- walk(userData, ob, &wmd->proximity_ob_target, IDWALK_CB_NOP);
- walk(userData, ob, &wmd->mask_tex_map_obj, IDWALK_CB_NOP);
+ WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
+ walk(userData, ob, &wmd->proximity_ob_target, IDWALK_CB_NOP);
+ walk(userData, ob, &wmd->mask_tex_map_obj, IDWALK_CB_NOP);
}
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
- WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *) md;
+ WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
- walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER);
+ walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER);
- foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
+ foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
}
static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
{
- walk(userData, ob, md, "mask_texture");
+ walk(userData, ob, md, "mask_texture");
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
- if (wmd->proximity_ob_target != NULL) {
- DEG_add_object_relation(ctx->node, wmd->proximity_ob_target, DEG_OB_COMP_TRANSFORM, "WeightVGProximity Modifier");
- if (wmd->proximity_ob_target->data != NULL && wmd->proximity_mode == MOD_WVG_PROXIMITY_GEOMETRY) {
- DEG_add_object_relation(ctx->node, wmd->proximity_ob_target, DEG_OB_COMP_GEOMETRY, "WeightVGProximity Modifier");
- }
- }
- if (wmd->mask_tex_map_obj != NULL && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) {
- DEG_add_object_relation(ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_TRANSFORM, "WeightVGProximity Modifier");
- DEG_add_object_relation(ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_GEOMETRY, "WeightVGProximity Modifier");
- }
- if (wmd->mask_texture != NULL) {
- DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGProximity Modifier");
- }
- DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGProximity Modifier");
+ WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
+ if (wmd->proximity_ob_target != NULL) {
+ DEG_add_object_relation(
+ ctx->node, wmd->proximity_ob_target, DEG_OB_COMP_TRANSFORM, "WeightVGProximity Modifier");
+ if (wmd->proximity_ob_target->data != NULL &&
+ wmd->proximity_mode == MOD_WVG_PROXIMITY_GEOMETRY) {
+ DEG_add_object_relation(
+ ctx->node, wmd->proximity_ob_target, DEG_OB_COMP_GEOMETRY, "WeightVGProximity Modifier");
+ }
+ }
+ if (wmd->mask_tex_map_obj != NULL && wmd->mask_tex_mapping == MOD_DISP_MAP_OBJECT) {
+ DEG_add_object_relation(
+ ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_TRANSFORM, "WeightVGProximity Modifier");
+ DEG_add_object_relation(
+ ctx->node, wmd->mask_tex_map_obj, DEG_OB_COMP_GEOMETRY, "WeightVGProximity Modifier");
+ }
+ if (wmd->mask_texture != NULL) {
+ DEG_add_generic_id_relation(ctx->node, &wmd->mask_texture->id, "WeightVGProximity Modifier");
+ }
+ DEG_add_modifier_to_transform_relation(ctx->node, "WeightVGProximity Modifier");
}
-static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
+static bool isDisabled(const struct Scene *UNUSED(scene),
+ ModifierData *md,
+ bool UNUSED(useRenderParams))
{
- WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *) md;
- /* If no vertex group, bypass. */
- if (wmd->defgrp_name[0] == '\0') return 1;
- /* If no target object, bypass. */
- return (wmd->proximity_ob_target == NULL);
+ WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
+ /* If no vertex group, bypass. */
+ if (wmd->defgrp_name[0] == '\0')
+ return 1;
+ /* If no target object, bypass. */
+ return (wmd->proximity_ob_target == NULL);
}
static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- BLI_assert(mesh != NULL);
-
- WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *) md;
- MDeformVert *dvert = NULL;
- MDeformWeight **dw, **tdw;
- float (*v_cos)[3] = NULL; /* The vertices coordinates. */
- Object *ob = ctx->object;
- Object *obr = NULL; /* Our target object. */
- int defgrp_index;
- float *tw = NULL;
- float *org_w = NULL;
- float *new_w = NULL;
- int *tidx, *indices = NULL;
- int numIdx = 0;
- int i;
- /* Flags. */
+ BLI_assert(mesh != NULL);
+
+ WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
+ MDeformVert *dvert = NULL;
+ MDeformWeight **dw, **tdw;
+ float(*v_cos)[3] = NULL; /* The vertices coordinates. */
+ Object *ob = ctx->object;
+ Object *obr = NULL; /* Our target object. */
+ int defgrp_index;
+ float *tw = NULL;
+ float *org_w = NULL;
+ float *new_w = NULL;
+ int *tidx, *indices = NULL;
+ int numIdx = 0;
+ int i;
+ /* Flags. */
#if 0
- const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview) != 0;
+ const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview) != 0;
#endif
#ifdef USE_TIMEIT
- TIMEIT_START(perf);
+ TIMEIT_START(perf);
#endif
- /* Get number of verts. */
- const int numVerts = mesh->totvert;
-
- /* Check if we can just return the original mesh.
- * Must have verts and therefore verts assigned to vgroups to do anything useful!
- */
- if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) {
- return mesh;
- }
-
- /* Get our target object. */
- obr = wmd->proximity_ob_target;
- if (obr == NULL) {
- return mesh;
- }
-
- /* Get vgroup idx from its name. */
- defgrp_index = defgroup_name_index(ob, wmd->defgrp_name);
- if (defgrp_index == -1) {
- return mesh;
- }
-
- const bool has_mdef = CustomData_has_layer(&mesh->vdata, CD_MDEFORMVERT);
- /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
- /* As this modifier never add vertices to vgroup, just return. */
- if (!has_mdef) {
- return mesh;
- }
-
- dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts);
- /* Ultimate security check. */
- if (!dvert) {
- return mesh;
- }
- mesh->dvert = dvert;
-
- /* Find out which vertices to work on (all vertices in vgroup), and get their relevant weight. */
- tidx = MEM_malloc_arrayN(numVerts, sizeof(int), "WeightVGProximity Modifier, tidx");
- tw = MEM_malloc_arrayN(numVerts, sizeof(float), "WeightVGProximity Modifier, tw");
- tdw = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGProximity Modifier, tdw");
- for (i = 0; i < numVerts; i++) {
- MDeformWeight *_dw = defvert_find_index(&dvert[i], defgrp_index);
- if (_dw) {
- tidx[numIdx] = i;
- tw[numIdx] = _dw->weight;
- tdw[numIdx++] = _dw;
- }
- }
- /* If no vertices found, return org data! */
- if (numIdx == 0) {
- MEM_freeN(tidx);
- MEM_freeN(tw);
- MEM_freeN(tdw);
- return mesh;
- }
- if (numIdx != numVerts) {
- indices = MEM_malloc_arrayN(numIdx, sizeof(int), "WeightVGProximity Modifier, indices");
- memcpy(indices, tidx, sizeof(int) * numIdx);
- org_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGProximity Modifier, org_w");
- memcpy(org_w, tw, sizeof(float) * numIdx);
- dw = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGProximity Modifier, dw");
- memcpy(dw, tdw, sizeof(MDeformWeight *) * numIdx);
- MEM_freeN(tw);
- MEM_freeN(tdw);
- }
- else {
- org_w = tw;
- dw = tdw;
- }
- new_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGProximity Modifier, new_w");
- MEM_freeN(tidx);
-
- /* Get our vertex coordinates. */
- if (numIdx != numVerts) {
- float (*tv_cos)[3] = BKE_mesh_vertexCos_get(mesh, NULL);
- v_cos = MEM_malloc_arrayN(numIdx, sizeof(float[3]), "WeightVGProximity Modifier, v_cos");
- for (i = 0; i < numIdx; i++) {
- copy_v3_v3(v_cos[i], tv_cos[indices[i]]);
- }
- MEM_freeN(tv_cos);
- }
- else {
- v_cos = BKE_mesh_vertexCos_get(mesh, NULL);
- }
-
- /* Compute wanted distances. */
- if (wmd->proximity_mode == MOD_WVG_PROXIMITY_OBJECT) {
- const float dist = get_ob2ob_distance(ob, obr);
- for (i = 0; i < numIdx; i++) {
- new_w[i] = dist;
- }
- }
- else if (wmd->proximity_mode == MOD_WVG_PROXIMITY_GEOMETRY) {
- const bool use_trgt_verts = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_VERTS) != 0;
- const bool use_trgt_edges = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_EDGES) != 0;
- const bool use_trgt_faces = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_FACES) != 0;
-
- if (use_trgt_verts || use_trgt_edges || use_trgt_faces) {
- Mesh *target_mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(obr, false);
-
- /* We must check that we do have a valid target_mesh! */
- if (target_mesh != NULL) {
- SpaceTransform loc2trgt;
- float *dists_v = use_trgt_verts ? MEM_malloc_arrayN(numIdx, sizeof(float), "dists_v") : NULL;
- float *dists_e = use_trgt_edges ? MEM_malloc_arrayN(numIdx, sizeof(float), "dists_e") : NULL;
- float *dists_f = use_trgt_faces ? MEM_malloc_arrayN(numIdx, sizeof(float), "dists_f") : NULL;
-
- BLI_SPACE_TRANSFORM_SETUP(&loc2trgt, ob, obr);
- get_vert2geom_distance(numIdx, v_cos, dists_v, dists_e, dists_f,
- target_mesh, &loc2trgt);
- for (i = 0; i < numIdx; i++) {
- new_w[i] = dists_v ? dists_v[i] : FLT_MAX;
- if (dists_e)
- new_w[i] = min_ff(dists_e[i], new_w[i]);
- if (dists_f)
- new_w[i] = min_ff(dists_f[i], new_w[i]);
- }
-
- MEM_SAFE_FREE(dists_v);
- MEM_SAFE_FREE(dists_e);
- MEM_SAFE_FREE(dists_f);
- }
- /* Else, fall back to default obj2vert behavior. */
- else {
- get_vert2ob_distance(numIdx, v_cos, new_w, ob, obr);
- }
- }
- else {
- get_vert2ob_distance(numIdx, v_cos, new_w, ob, obr);
- }
- }
-
- /* Map distances to weights. */
- do_map(ob, new_w, numIdx, wmd->min_dist, wmd->max_dist, wmd->falloff_type);
-
- /* Do masking. */
- struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- weightvg_do_mask(ctx, numIdx, indices, org_w, new_w, ob, mesh, wmd->mask_constant,
- wmd->mask_defgrp_name, scene, wmd->mask_texture,
- wmd->mask_tex_use_channel, wmd->mask_tex_mapping,
- wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name);
-
- /* Update vgroup. Note we never add nor remove vertices from vgroup here. */
- weightvg_update_vg(dvert, defgrp_index, dw, numIdx, indices, org_w, false, 0.0f, false, 0.0f);
-
- /* If weight preview enabled... */
+ /* Get number of verts. */
+ const int numVerts = mesh->totvert;
+
+ /* Check if we can just return the original mesh.
+ * Must have verts and therefore verts assigned to vgroups to do anything useful!
+ */
+ if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) {
+ return mesh;
+ }
+
+ /* Get our target object. */
+ obr = wmd->proximity_ob_target;
+ if (obr == NULL) {
+ return mesh;
+ }
+
+ /* Get vgroup idx from its name. */
+ defgrp_index = defgroup_name_index(ob, wmd->defgrp_name);
+ if (defgrp_index == -1) {
+ return mesh;
+ }
+
+ const bool has_mdef = CustomData_has_layer(&mesh->vdata, CD_MDEFORMVERT);
+ /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
+ /* As this modifier never add vertices to vgroup, just return. */
+ if (!has_mdef) {
+ return mesh;
+ }
+
+ dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts);
+ /* Ultimate security check. */
+ if (!dvert) {
+ return mesh;
+ }
+ mesh->dvert = dvert;
+
+ /* Find out which vertices to work on (all vertices in vgroup), and get their relevant weight. */
+ tidx = MEM_malloc_arrayN(numVerts, sizeof(int), "WeightVGProximity Modifier, tidx");
+ tw = MEM_malloc_arrayN(numVerts, sizeof(float), "WeightVGProximity Modifier, tw");
+ tdw = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGProximity Modifier, tdw");
+ for (i = 0; i < numVerts; i++) {
+ MDeformWeight *_dw = defvert_find_index(&dvert[i], defgrp_index);
+ if (_dw) {
+ tidx[numIdx] = i;
+ tw[numIdx] = _dw->weight;
+ tdw[numIdx++] = _dw;
+ }
+ }
+ /* If no vertices found, return org data! */
+ if (numIdx == 0) {
+ MEM_freeN(tidx);
+ MEM_freeN(tw);
+ MEM_freeN(tdw);
+ return mesh;
+ }
+ if (numIdx != numVerts) {
+ indices = MEM_malloc_arrayN(numIdx, sizeof(int), "WeightVGProximity Modifier, indices");
+ memcpy(indices, tidx, sizeof(int) * numIdx);
+ org_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGProximity Modifier, org_w");
+ memcpy(org_w, tw, sizeof(float) * numIdx);
+ dw = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGProximity Modifier, dw");
+ memcpy(dw, tdw, sizeof(MDeformWeight *) * numIdx);
+ MEM_freeN(tw);
+ MEM_freeN(tdw);
+ }
+ else {
+ org_w = tw;
+ dw = tdw;
+ }
+ new_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGProximity Modifier, new_w");
+ MEM_freeN(tidx);
+
+ /* Get our vertex coordinates. */
+ if (numIdx != numVerts) {
+ float(*tv_cos)[3] = BKE_mesh_vertexCos_get(mesh, NULL);
+ v_cos = MEM_malloc_arrayN(numIdx, sizeof(float[3]), "WeightVGProximity Modifier, v_cos");
+ for (i = 0; i < numIdx; i++) {
+ copy_v3_v3(v_cos[i], tv_cos[indices[i]]);
+ }
+ MEM_freeN(tv_cos);
+ }
+ else {
+ v_cos = BKE_mesh_vertexCos_get(mesh, NULL);
+ }
+
+ /* Compute wanted distances. */
+ if (wmd->proximity_mode == MOD_WVG_PROXIMITY_OBJECT) {
+ const float dist = get_ob2ob_distance(ob, obr);
+ for (i = 0; i < numIdx; i++) {
+ new_w[i] = dist;
+ }
+ }
+ else if (wmd->proximity_mode == MOD_WVG_PROXIMITY_GEOMETRY) {
+ const bool use_trgt_verts = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_VERTS) != 0;
+ const bool use_trgt_edges = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_EDGES) != 0;
+ const bool use_trgt_faces = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_FACES) != 0;
+
+ if (use_trgt_verts || use_trgt_edges || use_trgt_faces) {
+ Mesh *target_mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(obr, false);
+
+ /* We must check that we do have a valid target_mesh! */
+ if (target_mesh != NULL) {
+ SpaceTransform loc2trgt;
+ float *dists_v = use_trgt_verts ? MEM_malloc_arrayN(numIdx, sizeof(float), "dists_v") :
+ NULL;
+ float *dists_e = use_trgt_edges ? MEM_malloc_arrayN(numIdx, sizeof(float), "dists_e") :
+ NULL;
+ float *dists_f = use_trgt_faces ? MEM_malloc_arrayN(numIdx, sizeof(float), "dists_f") :
+ NULL;
+
+ BLI_SPACE_TRANSFORM_SETUP(&loc2trgt, ob, obr);
+ get_vert2geom_distance(numIdx, v_cos, dists_v, dists_e, dists_f, target_mesh, &loc2trgt);
+ for (i = 0; i < numIdx; i++) {
+ new_w[i] = dists_v ? dists_v[i] : FLT_MAX;
+ if (dists_e)
+ new_w[i] = min_ff(dists_e[i], new_w[i]);
+ if (dists_f)
+ new_w[i] = min_ff(dists_f[i], new_w[i]);
+ }
+
+ MEM_SAFE_FREE(dists_v);
+ MEM_SAFE_FREE(dists_e);
+ MEM_SAFE_FREE(dists_f);
+ }
+ /* Else, fall back to default obj2vert behavior. */
+ else {
+ get_vert2ob_distance(numIdx, v_cos, new_w, ob, obr);
+ }
+ }
+ else {
+ get_vert2ob_distance(numIdx, v_cos, new_w, ob, obr);
+ }
+ }
+
+ /* Map distances to weights. */
+ do_map(ob, new_w, numIdx, wmd->min_dist, wmd->max_dist, wmd->falloff_type);
+
+ /* Do masking. */
+ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ weightvg_do_mask(ctx,
+ numIdx,
+ indices,
+ org_w,
+ new_w,
+ ob,
+ mesh,
+ wmd->mask_constant,
+ wmd->mask_defgrp_name,
+ scene,
+ wmd->mask_texture,
+ wmd->mask_tex_use_channel,
+ wmd->mask_tex_mapping,
+ wmd->mask_tex_map_obj,
+ wmd->mask_tex_uvlayer_name);
+
+ /* Update vgroup. Note we never add nor remove vertices from vgroup here. */
+ weightvg_update_vg(dvert, defgrp_index, dw, numIdx, indices, org_w, false, 0.0f, false, 0.0f);
+
+ /* If weight preview enabled... */
#if 0 /* XXX Currently done in mod stack :/ */
- if (do_prev)
- DM_update_weight_mcol(ob, dm, 0, org_w, numIdx, indices);
+ if (do_prev)
+ DM_update_weight_mcol(ob, dm, 0, org_w, numIdx, indices);
#endif
- /* Freeing stuff. */
- MEM_freeN(org_w);
- MEM_freeN(new_w);
- MEM_freeN(dw);
- MEM_freeN(v_cos);
- MEM_SAFE_FREE(indices);
+ /* Freeing stuff. */
+ MEM_freeN(org_w);
+ MEM_freeN(new_w);
+ MEM_freeN(dw);
+ MEM_freeN(v_cos);
+ MEM_SAFE_FREE(indices);
#ifdef USE_TIMEIT
- TIMEIT_END(perf);
+ TIMEIT_END(perf);
#endif
- /* Return the vgroup-modified mesh. */
- return mesh;
+ /* Return the vgroup-modified mesh. */
+ return mesh;
}
-
ModifierTypeInfo modifierType_WeightVGProximity = {
- /* name */ "VertexWeightProximity",
- /* structName */ "WeightVGProximityModifierData",
- /* structSize */ sizeof(WeightVGProximityModifierData),
- /* type */ eModifierTypeType_NonGeometrical,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsMapping |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_UsesPreview,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ dependsOnTime,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ foreachIDLink,
- /* foreachTexLink */ foreachTexLink,
- /* freeRuntimeData */ NULL,
+ /* name */ "VertexWeightProximity",
+ /* structName */ "WeightVGProximityModifierData",
+ /* structSize */ sizeof(WeightVGProximityModifierData),
+ /* type */ eModifierTypeType_NonGeometrical,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_UsesPreview,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ dependsOnTime,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ foreachTexLink,
+ /* freeRuntimeData */ NULL,
};
diff --git a/source/blender/modifiers/intern/MOD_wireframe.c b/source/blender/modifiers/intern/MOD_wireframe.c
index 74ab0ac3d8c..7af9ef6f5b6 100644
--- a/source/blender/modifiers/intern/MOD_wireframe.c
+++ b/source/blender/modifiers/intern/MOD_wireframe.c
@@ -33,103 +33,103 @@
static void initData(ModifierData *md)
{
- WireframeModifierData *wmd = (WireframeModifierData *)md;
- wmd->offset = 0.02f;
- wmd->flag = MOD_WIREFRAME_REPLACE | MOD_WIREFRAME_OFS_EVEN;
- wmd->crease_weight = 1.0f;
+ WireframeModifierData *wmd = (WireframeModifierData *)md;
+ wmd->offset = 0.02f;
+ wmd->flag = MOD_WIREFRAME_REPLACE | MOD_WIREFRAME_OFS_EVEN;
+ wmd->crease_weight = 1.0f;
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- WireframeModifierData *wmd = (WireframeModifierData *)md;
+ WireframeModifierData *wmd = (WireframeModifierData *)md;
- /* ask for vertexgroups if we need them */
- if (wmd->defgrp_name[0] != '\0') {
- r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
- }
+ /* ask for vertexgroups if we need them */
+ if (wmd->defgrp_name[0] != '\0') {
+ r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
+ }
}
static bool dependsOnNormals(ModifierData *UNUSED(md))
{
- return true;
+ return true;
}
static Mesh *WireframeModifier_do(WireframeModifierData *wmd, Object *ob, Mesh *mesh)
{
- Mesh *result;
- BMesh *bm;
-
- const int defgrp_index = defgroup_name_index(ob, wmd->defgrp_name);
-
- bm = BKE_mesh_to_bmesh_ex(
- mesh,
- &(struct BMeshCreateParams){0},
- &(struct BMeshFromMeshParams){
- .calc_face_normal = true,
- .add_key_index = false,
- .use_shapekey = false,
- .active_shapekey = 0,
- .cd_mask_extra = {.vmask = CD_MASK_ORIGINDEX, .emask = CD_MASK_ORIGINDEX, .pmask = CD_MASK_ORIGINDEX},
- });
-
- BM_mesh_wireframe(
- bm,
- wmd->offset, wmd->offset_fac, wmd->offset_fac_vg,
- (wmd->flag & MOD_WIREFRAME_REPLACE) != 0,
- (wmd->flag & MOD_WIREFRAME_BOUNDARY) != 0,
- (wmd->flag & MOD_WIREFRAME_OFS_EVEN) != 0,
- (wmd->flag & MOD_WIREFRAME_OFS_RELATIVE) != 0,
- (wmd->flag & MOD_WIREFRAME_CREASE) != 0,
- wmd->crease_weight,
- defgrp_index,
- (wmd->flag & MOD_WIREFRAME_INVERT_VGROUP) != 0,
- wmd->mat_ofs,
- MAX2(ob->totcol - 1, 0),
- false);
-
- result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
- BM_mesh_free(bm);
-
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
-
- return result;
-
+ Mesh *result;
+ BMesh *bm;
+
+ const int defgrp_index = defgroup_name_index(ob, wmd->defgrp_name);
+
+ bm = BKE_mesh_to_bmesh_ex(mesh,
+ &(struct BMeshCreateParams){0},
+ &(struct BMeshFromMeshParams){
+ .calc_face_normal = true,
+ .add_key_index = false,
+ .use_shapekey = false,
+ .active_shapekey = 0,
+ .cd_mask_extra = {.vmask = CD_MASK_ORIGINDEX,
+ .emask = CD_MASK_ORIGINDEX,
+ .pmask = CD_MASK_ORIGINDEX},
+ });
+
+ BM_mesh_wireframe(bm,
+ wmd->offset,
+ wmd->offset_fac,
+ wmd->offset_fac_vg,
+ (wmd->flag & MOD_WIREFRAME_REPLACE) != 0,
+ (wmd->flag & MOD_WIREFRAME_BOUNDARY) != 0,
+ (wmd->flag & MOD_WIREFRAME_OFS_EVEN) != 0,
+ (wmd->flag & MOD_WIREFRAME_OFS_RELATIVE) != 0,
+ (wmd->flag & MOD_WIREFRAME_CREASE) != 0,
+ wmd->crease_weight,
+ defgrp_index,
+ (wmd->flag & MOD_WIREFRAME_INVERT_VGROUP) != 0,
+ wmd->mat_ofs,
+ MAX2(ob->totcol - 1, 0),
+ false);
+
+ result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
+ BM_mesh_free(bm);
+
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+
+ return result;
}
-static Mesh *applyModifier(
- ModifierData *md,
- const struct ModifierEvalContext *ctx,
- struct Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md,
+ const struct ModifierEvalContext *ctx,
+ struct Mesh *mesh)
{
- return WireframeModifier_do((WireframeModifierData *)md, ctx->object, mesh);
+ return WireframeModifier_do((WireframeModifierData *)md, ctx->object, mesh);
}
-
ModifierTypeInfo modifierType_Wireframe = {
- /* name */ "Wireframe",
- /* structName */ "WireframeModifierData",
- /* structSize */ sizeof(WireframeModifierData),
- /* type */ eModifierTypeType_Constructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ dependsOnNormals,
- /* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "Wireframe",
+ /* structName */ "WireframeModifierData",
+ /* structSize */ sizeof(WireframeModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ dependsOnNormals,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};