Changeset View
Changeset View
Standalone View
Standalone View
source/blender/modifiers/intern/MOD_remesh.c
| Show All 24 Lines | |||||
| */ | */ | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "BLI_math_base.h" | #include "BLI_math_base.h" | ||||
| #include "BLI_math_vector.h" | #include "BLI_math_vector.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BKE_cdderivedmesh.h" | |||||
| #include "BKE_DerivedMesh.h" | |||||
| #include "DNA_meshdata_types.h" | #include "DNA_meshdata_types.h" | ||||
| #include "DNA_modifier_types.h" | #include "DNA_modifier_types.h" | ||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||
| #include "DNA_mesh_types.h" | |||||
| #include "MOD_modifiertypes.h" | #include "MOD_modifiertypes.h" | ||||
| #include "BKE_mesh.h" | |||||
| #include "BKE_library.h" | |||||
| #include <assert.h> | #include <assert.h> | ||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <string.h> | #include <string.h> | ||||
| #ifdef WITH_MOD_REMESH | #ifdef WITH_MOD_REMESH | ||||
| # include "dualcon.h" | # include "dualcon.h" | ||||
| #endif | #endif | ||||
| static void initData(ModifierData *md) | static void initData(ModifierData *md) | ||||
| { | { | ||||
| RemeshModifierData *rmd = (RemeshModifierData *) md; | RemeshModifierData *rmd = (RemeshModifierData *) md; | ||||
| rmd->scale = 0.9; | rmd->scale = 0.9; | ||||
| rmd->depth = 4; | rmd->depth = 4; | ||||
| rmd->hermite_num = 1; | rmd->hermite_num = 1; | ||||
| rmd->flag = MOD_REMESH_FLOOD_FILL; | rmd->flag = MOD_REMESH_FLOOD_FILL; | ||||
| rmd->mode = MOD_REMESH_SHARP_FEATURES; | rmd->mode = MOD_REMESH_SHARP_FEATURES; | ||||
| rmd->threshold = 1; | rmd->threshold = 1; | ||||
| } | } | ||||
| #ifdef WITH_MOD_REMESH | #ifdef WITH_MOD_REMESH | ||||
| static void init_dualcon_mesh(DualConInput *mesh, DerivedMesh *dm) | static void init_dualcon_mesh(DualConInput *input, Mesh *mesh) | ||||
| { | { | ||||
| memset(mesh, 0, sizeof(DualConInput)); | memset(input, 0, sizeof(DualConInput)); | ||||
| input->co = (void *)mesh->mvert; | |||||
| input->co_stride = sizeof(MVert); | |||||
| input->totco = mesh->totvert; | |||||
| input->mloop = (void *)mesh->mloop; | |||||
| input->loop_stride = sizeof(MLoop); | |||||
| mesh->co = (void *)dm->getVertArray(dm); | BKE_mesh_runtime_looptri_ensure(mesh); | ||||
| mesh->co_stride = sizeof(MVert); | input->looptri = (void *)mesh->runtime.looptris.array; | ||||
| mesh->totco = dm->getNumVerts(dm); | input->tri_stride = sizeof(MLoopTri); | ||||
| input->tottri = mesh->runtime.looptris.len; | |||||
| mesh->mloop = (void *)dm->getLoopArray(dm); | |||||
| mesh->loop_stride = sizeof(MLoop); | |||||
| mesh->looptri = (void *)dm->getLoopTriArray(dm); | |||||
| mesh->tri_stride = sizeof(MLoopTri); | |||||
| mesh->tottri = dm->getNumLoopTri(dm); | |||||
| INIT_MINMAX(mesh->min, mesh->max); | INIT_MINMAX(input->min, input->max); | ||||
| dm->getMinMax(dm, mesh->min, mesh->max); | BKE_mesh_minmax(mesh, input->min, input->max); | ||||
| } | } | ||||
| /* simple structure to hold the output: a CDDM and two counters to | /* simple structure to hold the output: a CDDM and two counters to | ||||
| * keep track of the current elements */ | * keep track of the current elements */ | ||||
| typedef struct { | typedef struct { | ||||
| DerivedMesh *dm; | Mesh *mesh; | ||||
| int curvert, curface; | int curvert, curface; | ||||
| } DualConOutput; | } DualConOutput; | ||||
| /* allocate and initialize a DualConOutput */ | /* allocate and initialize a DualConOutput */ | ||||
| static void *dualcon_alloc_output(int totvert, int totquad) | static void *dualcon_alloc_output(int totvert, int totquad) | ||||
| { | { | ||||
| DualConOutput *output; | DualConOutput *output; | ||||
| if (!(output = MEM_callocN(sizeof(DualConOutput), | if (!(output = MEM_callocN(sizeof(DualConOutput), | ||||
| "DualConOutput"))) | "DualConOutput"))) | ||||
| { | { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| output->dm = CDDM_new(totvert, 0, 0, 4 * totquad, totquad); | output->mesh = BKE_mesh_new_nomain(totvert, 0, 0, 4 * totquad, totquad); | ||||
| return output; | return output; | ||||
| } | } | ||||
| static void dualcon_add_vert(void *output_v, const float co[3]) | static void dualcon_add_vert(void *output_v, const float co[3]) | ||||
| { | { | ||||
| DualConOutput *output = output_v; | DualConOutput *output = output_v; | ||||
| DerivedMesh *dm = output->dm; | Mesh *mesh = output->mesh; | ||||
| assert(output->curvert < dm->getNumVerts(dm)); | assert(output->curvert < mesh->totvert); | ||||
| copy_v3_v3(CDDM_get_verts(dm)[output->curvert].co, co); | copy_v3_v3(mesh->mvert[output->curvert].co, co); | ||||
| output->curvert++; | output->curvert++; | ||||
| } | } | ||||
| static void dualcon_add_quad(void *output_v, const int vert_indices[4]) | static void dualcon_add_quad(void *output_v, const int vert_indices[4]) | ||||
| { | { | ||||
| DualConOutput *output = output_v; | DualConOutput *output = output_v; | ||||
| DerivedMesh *dm = output->dm; | Mesh *mesh = output->mesh; | ||||
| MLoop *mloop; | MLoop *mloop; | ||||
| MPoly *cur_poly; | MPoly *cur_poly; | ||||
| int i; | int i; | ||||
| assert(output->curface < dm->getNumPolys(dm)); | assert(output->curface < mesh->totpoly); | ||||
| mloop = CDDM_get_loops(dm); | mloop = mesh->mloop; | ||||
| cur_poly = CDDM_get_poly(dm, output->curface); | cur_poly = &mesh->mpoly[output->curface]; | ||||
| cur_poly->loopstart = output->curface * 4; | cur_poly->loopstart = output->curface * 4; | ||||
| cur_poly->totloop = 4; | cur_poly->totloop = 4; | ||||
| for (i = 0; i < 4; i++) | for (i = 0; i < 4; i++) | ||||
| mloop[output->curface * 4 + i].v = vert_indices[i]; | mloop[output->curface * 4 + i].v = vert_indices[i]; | ||||
| output->curface++; | output->curface++; | ||||
| } | } | ||||
| static DerivedMesh *applyModifier(ModifierData *md, | static Mesh *applyModifier(ModifierData *md, | ||||
| const ModifierEvalContext *UNUSED(ctx), | const ModifierEvalContext *UNUSED(ctx), | ||||
| DerivedMesh *dm) | Mesh *mesh) | ||||
| { | { | ||||
| RemeshModifierData *rmd; | RemeshModifierData *rmd; | ||||
| DualConOutput *output; | DualConOutput *output; | ||||
| DualConInput input; | DualConInput input; | ||||
| DerivedMesh *result; | Mesh *result; | ||||
| DualConFlags flags = 0; | DualConFlags flags = 0; | ||||
| DualConMode mode = 0; | DualConMode mode = 0; | ||||
| rmd = (RemeshModifierData *)md; | rmd = (RemeshModifierData *)md; | ||||
| init_dualcon_mesh(&input, dm); | init_dualcon_mesh(&input, mesh); | ||||
| if (rmd->flag & MOD_REMESH_FLOOD_FILL) | if (rmd->flag & MOD_REMESH_FLOOD_FILL) | ||||
| flags |= DUALCON_FLOOD_FILL; | flags |= DUALCON_FLOOD_FILL; | ||||
| switch (rmd->mode) { | switch (rmd->mode) { | ||||
| case MOD_REMESH_CENTROID: | case MOD_REMESH_CENTROID: | ||||
| mode = DUALCON_CENTROID; | mode = DUALCON_CENTROID; | ||||
| break; | break; | ||||
| Show All 10 Lines | output = dualcon(&input, | ||||
| dualcon_add_vert, | dualcon_add_vert, | ||||
| dualcon_add_quad, | dualcon_add_quad, | ||||
| flags, | flags, | ||||
| mode, | mode, | ||||
| rmd->threshold, | rmd->threshold, | ||||
| rmd->hermite_num, | rmd->hermite_num, | ||||
| rmd->scale, | rmd->scale, | ||||
| rmd->depth); | rmd->depth); | ||||
| result = output->dm; | result = output->mesh; | ||||
| MEM_freeN(output); | MEM_freeN(output); | ||||
| if (rmd->flag & MOD_REMESH_SMOOTH_SHADING) { | if (rmd->flag & MOD_REMESH_SMOOTH_SHADING) { | ||||
| MPoly *mpoly = CDDM_get_polys(result); | MPoly *mpoly = result->mpoly; | ||||
| int i, totpoly = result->getNumPolys(result); | int i, totpoly = result->totpoly; | ||||
| /* Apply smooth shading to output faces */ | /* Apply smooth shading to output faces */ | ||||
| for (i = 0; i < totpoly; i++) { | for (i = 0; i < totpoly; i++) { | ||||
| mpoly[i].flag |= ME_SMOOTH; | mpoly[i].flag |= ME_SMOOTH; | ||||
| } | } | ||||
| } | } | ||||
| CDDM_calc_edges(result); | BKE_mesh_calc_edges(result, true, false); | ||||
| result->dirty |= DM_DIRTY_NORMALS; | result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; | ||||
| return result; | return result; | ||||
| } | } | ||||
| #else /* !WITH_MOD_REMESH */ | #else /* !WITH_MOD_REMESH */ | ||||
| static DerivedMesh *applyModifier(ModifierData *UNUSED(md), | static DerivedMesh *applyModifier(ModifierData *UNUSED(md), | ||||
| const ModifierEvalContext *UNUSED(ctx), | const ModifierEvalContext *UNUSED(ctx), | ||||
| DerivedMesh *derivedData) | DerivedMesh *derivedData) | ||||
| Show All 13 Lines | /* flags */ eModifierTypeFlag_AcceptsMesh | | ||||
| eModifierTypeFlag_SupportsEditmode, | eModifierTypeFlag_SupportsEditmode, | ||||
| /* copyData */ modifier_copyData_generic, | /* copyData */ modifier_copyData_generic, | ||||
| /* deformVerts_DM */ NULL, | /* deformVerts_DM */ NULL, | ||||
| /* deformMatrices_DM */ NULL, | /* deformMatrices_DM */ NULL, | ||||
| /* deformVertsEM_DM */ NULL, | /* deformVertsEM_DM */ NULL, | ||||
| /* deformMatricesEM_DM*/NULL, | /* deformMatricesEM_DM*/NULL, | ||||
| /* applyModifier_DM */ applyModifier, | /* applyModifier_DM */ NULL, | ||||
| /* applyModifierEM_DM */NULL, | /* applyModifierEM_DM */NULL, | ||||
| /* deformVerts */ NULL, | /* deformVerts */ NULL, | ||||
| /* deformMatrices */ NULL, | /* deformMatrices */ NULL, | ||||
| /* deformVertsEM */ NULL, | /* deformVertsEM */ NULL, | ||||
| /* deformMatricesEM */ NULL, | /* deformMatricesEM */ NULL, | ||||
| /* applyModifier */ NULL, | /* applyModifier */ applyModifier, | ||||
| /* applyModifierEM */ NULL, | /* applyModifierEM */ NULL, | ||||
| /* initData */ initData, | /* initData */ initData, | ||||
| /* requiredDataMask */ NULL, | /* requiredDataMask */ NULL, | ||||
| /* freeData */ NULL, | /* freeData */ NULL, | ||||
| /* isDisabled */ NULL, | /* isDisabled */ NULL, | ||||
| /* updateDepsgraph */ NULL, | /* updateDepsgraph */ NULL, | ||||
| /* dependsOnTime */ NULL, | /* dependsOnTime */ NULL, | ||||
| /* dependsOnNormals */ NULL, | /* dependsOnNormals */ NULL, | ||||
| /* foreachObjectLink */ NULL, | /* foreachObjectLink */ NULL, | ||||
| /* foreachIDLink */ NULL, | /* foreachIDLink */ NULL, | ||||
| }; | }; | ||||