Changeset View
Changeset View
Standalone View
Standalone View
source/blender/modifiers/intern/MOD_displace.c
| Show First 20 Lines • Show All 166 Lines • ▼ Show 20 Lines | typedef struct DisplaceUserdata { | ||||
| float weight; | float weight; | ||||
| int defgrp_index; | int defgrp_index; | ||||
| int direction; | int direction; | ||||
| bool use_global_direction; | bool use_global_direction; | ||||
| Tex *tex_target; | Tex *tex_target; | ||||
| float (*tex_co)[3]; | float (*tex_co)[3]; | ||||
| float (*vertexCos)[3]; | float (*vertexCos)[3]; | ||||
| float local_mat[4][4]; | float local_mat[4][4]; | ||||
| MVert *mvert; | Mesh *mesh; | ||||
| float (*vert_clnors)[3]; | float (*vert_clnors)[3]; | ||||
| } DisplaceUserdata; | } DisplaceUserdata; | ||||
| static void displaceModifier_do_task(void *__restrict userdata, | static void displaceModifier_do_task(void *__restrict userdata, | ||||
| const int iter, | const int iter, | ||||
| const TaskParallelTLS *__restrict UNUSED(tls)) | const TaskParallelTLS *__restrict UNUSED(tls)) | ||||
| { | { | ||||
| DisplaceUserdata *data = (DisplaceUserdata *)userdata; | DisplaceUserdata *data = (DisplaceUserdata *)userdata; | ||||
| DisplaceModifierData *dmd = data->dmd; | DisplaceModifierData *dmd = data->dmd; | ||||
| MDeformVert *dvert = data->dvert; | MDeformVert *dvert = data->dvert; | ||||
| const bool invert_vgroup = (dmd->flag & MOD_DISP_INVERT_VGROUP) != 0; | const bool invert_vgroup = (dmd->flag & MOD_DISP_INVERT_VGROUP) != 0; | ||||
| float weight = data->weight; | float weight = data->weight; | ||||
| int defgrp_index = data->defgrp_index; | int defgrp_index = data->defgrp_index; | ||||
| int direction = data->direction; | int direction = data->direction; | ||||
| bool use_global_direction = data->use_global_direction; | bool use_global_direction = data->use_global_direction; | ||||
| float(*tex_co)[3] = data->tex_co; | float(*tex_co)[3] = data->tex_co; | ||||
| float(*vertexCos)[3] = data->vertexCos; | float(*vertexCos)[3] = data->vertexCos; | ||||
| MVert *mvert = data->mvert; | |||||
| float(*vert_clnors)[3] = data->vert_clnors; | float(*vert_clnors)[3] = data->vert_clnors; | ||||
| const float delta_fixed = 1.0f - | const float delta_fixed = 1.0f - | ||||
| dmd->midlevel; /* when no texture is used, we fallback to white */ | dmd->midlevel; /* when no texture is used, we fallback to white */ | ||||
| TexResult texres; | TexResult texres; | ||||
| float strength = dmd->strength; | float strength = dmd->strength; | ||||
| float delta; | float delta; | ||||
| ▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | case MOD_DISP_DIR_RGB_XYZ: | ||||
| local_vec[1] = texres.tg - dmd->midlevel; | local_vec[1] = texres.tg - dmd->midlevel; | ||||
| local_vec[2] = texres.tb - dmd->midlevel; | local_vec[2] = texres.tb - dmd->midlevel; | ||||
| if (use_global_direction) { | if (use_global_direction) { | ||||
| mul_transposed_mat3_m4_v3(data->local_mat, local_vec); | mul_transposed_mat3_m4_v3(data->local_mat, local_vec); | ||||
| } | } | ||||
| mul_v3_fl(local_vec, strength); | mul_v3_fl(local_vec, strength); | ||||
| add_v3_v3(vertexCos[iter], local_vec); | add_v3_v3(vertexCos[iter], local_vec); | ||||
| break; | break; | ||||
| case MOD_DISP_DIR_NOR: | case MOD_DISP_DIR_NOR: { | ||||
| vertexCos[iter][0] += delta * (mvert[iter].no[0] / 32767.0f); | float no[3]; | ||||
| vertexCos[iter][1] += delta * (mvert[iter].no[1] / 32767.0f); | if (data->mesh != NULL) { | ||||
| vertexCos[iter][2] += delta * (mvert[iter].no[2] / 32767.0f); | const MVert *mvert = data->mesh->mvert; | ||||
| normal_short_to_float_v3(no, mvert[iter].no); | |||||
| } | |||||
| else { | |||||
| /* This code path is hit when the modifier is applied on a curve at a pre-tessellation | |||||
| * point. There is no known surface (at least, not usable here as there is no access to the | |||||
| * NURBS surface, for example). So calculate normal in a similar way how loose vertices | |||||
| * would be calculated in edit mode or for subdivision surface. | |||||
| * | |||||
| * Note that by default the modifier is applied on a post-tessellation point, so this code | |||||
| * path is not hit at all. It is only hit when the modifier is manually set to be applied | |||||
| * on a pre-tessellation point, or when clicking "Apply" button. Both of there operations | |||||
| * can not be done in a "lossless manner", so this heuristic should be good enough. */ | |||||
| normalize_v3_v3(no, vertexCos[iter]); | |||||
| } | |||||
| madd_v3_v3fl(vertexCos[iter], no, delta); | |||||
| break; | break; | ||||
| } | |||||
| case MOD_DISP_DIR_CLNOR: | case MOD_DISP_DIR_CLNOR: | ||||
| madd_v3_v3fl(vertexCos[iter], vert_clnors[iter], delta); | madd_v3_v3fl(vertexCos[iter], vert_clnors[iter], delta); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| static void displaceModifier_do(DisplaceModifierData *dmd, | static void displaceModifier_do(DisplaceModifierData *dmd, | ||||
| const ModifierEvalContext *ctx, | const ModifierEvalContext *ctx, | ||||
| Mesh *mesh, | Mesh *mesh, | ||||
| float (*vertexCos)[3], | float (*vertexCos)[3], | ||||
| const int numVerts) | const int numVerts) | ||||
| { | { | ||||
| Object *ob = ctx->object; | Object *ob = ctx->object; | ||||
| MVert *mvert; | |||||
| MDeformVert *dvert; | MDeformVert *dvert; | ||||
| int direction = dmd->direction; | int direction = dmd->direction; | ||||
| int defgrp_index; | int defgrp_index; | ||||
| float(*tex_co)[3]; | float(*tex_co)[3]; | ||||
| float weight = 1.0f; /* init value unused but some compilers may complain */ | float weight = 1.0f; /* init value unused but some compilers may complain */ | ||||
| float(*vert_clnors)[3] = NULL; | float(*vert_clnors)[3] = NULL; | ||||
| float local_mat[4][4] = {{0}}; | float local_mat[4][4] = {{0}}; | ||||
| const bool use_global_direction = dmd->space == MOD_DISP_SPACE_GLOBAL; | const bool use_global_direction = dmd->space == MOD_DISP_SPACE_GLOBAL; | ||||
| if (dmd->texture == NULL && dmd->direction == MOD_DISP_DIR_RGB_XYZ) { | if (dmd->texture == NULL && dmd->direction == MOD_DISP_DIR_RGB_XYZ) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (dmd->strength == 0.0f) { | if (dmd->strength == 0.0f) { | ||||
| return; | return; | ||||
| } | } | ||||
| mvert = mesh->mvert; | if (mesh != NULL) { | ||||
| MOD_get_vgroup(ob, mesh, dmd->defgrp_name, &dvert, &defgrp_index); | MOD_get_vgroup(ob, mesh, dmd->defgrp_name, &dvert, &defgrp_index); | ||||
| } | |||||
| else { | |||||
| dvert = NULL; | |||||
| defgrp_index = -1; | |||||
| } | |||||
| if (defgrp_index >= 0 && dvert == NULL) { | if (defgrp_index >= 0 && dvert == NULL) { | ||||
| /* There is a vertex group, but it has no vertices. */ | /* There is a vertex group, but it has no vertices. */ | ||||
| return; | return; | ||||
| } | } | ||||
| Tex *tex_target = dmd->texture; | Tex *tex_target = dmd->texture; | ||||
| if (tex_target != NULL) { | if (tex_target != NULL) { | ||||
| Show All 38 Lines | static void displaceModifier_do(DisplaceModifierData *dmd, | ||||
| data.weight = weight; | data.weight = weight; | ||||
| data.defgrp_index = defgrp_index; | data.defgrp_index = defgrp_index; | ||||
| data.direction = direction; | data.direction = direction; | ||||
| data.use_global_direction = use_global_direction; | data.use_global_direction = use_global_direction; | ||||
| data.tex_target = tex_target; | data.tex_target = tex_target; | ||||
| data.tex_co = tex_co; | data.tex_co = tex_co; | ||||
| data.vertexCos = vertexCos; | data.vertexCos = vertexCos; | ||||
| copy_m4_m4(data.local_mat, local_mat); | copy_m4_m4(data.local_mat, local_mat); | ||||
| data.mvert = mvert; | data.mesh = mesh; | ||||
| data.vert_clnors = vert_clnors; | data.vert_clnors = vert_clnors; | ||||
| if (tex_target != NULL) { | if (tex_target != NULL) { | ||||
| data.pool = BKE_image_pool_new(); | data.pool = BKE_image_pool_new(); | ||||
| BKE_texture_fetch_images_for_pool(tex_target, data.pool); | BKE_texture_fetch_images_for_pool(tex_target, data.pool); | ||||
| } | } | ||||
| TaskParallelSettings settings; | TaskParallelSettings settings; | ||||
| BLI_parallel_range_settings_defaults(&settings); | BLI_parallel_range_settings_defaults(&settings); | ||||
| settings.use_threading = (numVerts > 512); | settings.use_threading = (numVerts > 512); | ||||
| ▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | static void deformVertsEM(ModifierData *md, | ||||
| } | } | ||||
| } | } | ||||
| ModifierTypeInfo modifierType_Displace = { | ModifierTypeInfo modifierType_Displace = { | ||||
| /* name */ "Displace", | /* name */ "Displace", | ||||
| /* structName */ "DisplaceModifierData", | /* structName */ "DisplaceModifierData", | ||||
| /* structSize */ sizeof(DisplaceModifierData), | /* structSize */ sizeof(DisplaceModifierData), | ||||
| /* type */ eModifierTypeType_OnlyDeform, | /* type */ eModifierTypeType_OnlyDeform, | ||||
| /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, | /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | | ||||
| eModifierTypeFlag_SupportsEditmode, | |||||
| /* copyData */ modifier_copyData_generic, | /* copyData */ modifier_copyData_generic, | ||||
| /* deformVerts */ deformVerts, | /* deformVerts */ deformVerts, | ||||
| /* deformMatrices */ NULL, | /* deformMatrices */ NULL, | ||||
| /* deformVertsEM */ deformVertsEM, | /* deformVertsEM */ deformVertsEM, | ||||
| /* deformMatricesEM */ NULL, | /* deformMatricesEM */ NULL, | ||||
| /* applyModifier */ NULL, | /* applyModifier */ NULL, | ||||
| Show All 13 Lines | |||||