Changeset View
Changeset View
Standalone View
Standalone View
source/blender/modifiers/intern/MOD_uvproject.c
| Show All 29 Lines | |||||
| /** \file blender/modifiers/intern/MOD_uvproject.c | /** \file blender/modifiers/intern/MOD_uvproject.c | ||||
| * \ingroup modifiers | * \ingroup modifiers | ||||
| */ | */ | ||||
| /* UV Project modifier: Generates UVs projected from an object */ | /* UV Project modifier: Generates UVs projected from an object */ | ||||
| #include "DNA_mesh_types.h" | |||||
| #include "DNA_meshdata_types.h" | #include "DNA_meshdata_types.h" | ||||
| #include "DNA_camera_types.h" | #include "DNA_camera_types.h" | ||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BLI_uvproject.h" | #include "BLI_uvproject.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BKE_camera.h" | #include "BKE_camera.h" | ||||
| #include "BKE_library.h" | #include "BKE_library.h" | ||||
| #include "BKE_library_query.h" | #include "BKE_library_query.h" | ||||
| #include "BKE_material.h" | #include "BKE_material.h" | ||||
| #include "BKE_mesh.h" | #include "BKE_mesh.h" | ||||
| #include "BKE_DerivedMesh.h" | |||||
| #include "MOD_modifiertypes.h" | #include "MOD_modifiertypes.h" | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "DEG_depsgraph_build.h" | #include "DEG_depsgraph_build.h" | ||||
| static void initData(ModifierData *md) | static void initData(ModifierData *md) | ||||
| ▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | |||||
| typedef struct Projector { | typedef struct Projector { | ||||
| Object *ob; /* object this projector is derived from */ | Object *ob; /* object this projector is derived from */ | ||||
| float projmat[4][4]; /* projection matrix */ | float projmat[4][4]; /* projection matrix */ | ||||
| float normal[3]; /* projector normal in world space */ | float normal[3]; /* projector normal in world space */ | ||||
| void *uci; /* optional uv-project info (panorama projection) */ | void *uci; /* optional uv-project info (panorama projection) */ | ||||
| } Projector; | } Projector; | ||||
| static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, | static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, | ||||
| Object *ob, DerivedMesh *dm) | Object *ob, Mesh *mesh) | ||||
| { | { | ||||
| float (*coords)[3], (*co)[3]; | float (*coords)[3], (*co)[3]; | ||||
| MLoopUV *mloop_uv; | MLoopUV *mloop_uv; | ||||
| int i, numVerts, numPolys, numLoops; | int i, numVerts, numPolys, numLoops; | ||||
| MPoly *mpoly, *mp; | MPoly *mpoly, *mp; | ||||
| MLoop *mloop; | MLoop *mloop; | ||||
| Projector projectors[MOD_UVPROJECT_MAXPROJECTORS]; | Projector projectors[MOD_UVPROJECT_MAXPROJECTORS]; | ||||
| int num_projectors = 0; | int num_projectors = 0; | ||||
| char uvname[MAX_CUSTOMDATA_LAYER_NAME]; | char uvname[MAX_CUSTOMDATA_LAYER_NAME]; | ||||
| float aspx = umd->aspectx ? umd->aspectx : 1.0f; | float aspx = umd->aspectx ? umd->aspectx : 1.0f; | ||||
| float aspy = umd->aspecty ? umd->aspecty : 1.0f; | float aspy = umd->aspecty ? umd->aspecty : 1.0f; | ||||
| float scax = umd->scalex ? umd->scalex : 1.0f; | float scax = umd->scalex ? umd->scalex : 1.0f; | ||||
| float scay = umd->scaley ? umd->scaley : 1.0f; | float scay = umd->scaley ? umd->scaley : 1.0f; | ||||
| int free_uci = 0; | int free_uci = 0; | ||||
| for (i = 0; i < umd->num_projectors; ++i) | for (i = 0; i < umd->num_projectors; ++i) | ||||
| if (umd->projectors[i]) | if (umd->projectors[i]) | ||||
| projectors[num_projectors++].ob = umd->projectors[i]; | projectors[num_projectors++].ob = umd->projectors[i]; | ||||
| if (num_projectors == 0) return dm; | if (num_projectors == 0) return mesh; | ||||
| /* make sure there are UV Maps available */ | /* make sure there are UV Maps available */ | ||||
| if (!CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) return dm; | if (!CustomData_has_layer(&mesh->ldata, CD_MLOOPUV)) return mesh; | ||||
| /* make sure we're using an existing layer */ | /* make sure we're using an existing layer */ | ||||
| CustomData_validate_layer_name(&dm->loopData, CD_MLOOPUV, umd->uvlayer_name, uvname); | CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, umd->uvlayer_name, uvname); | ||||
| /* calculate a projection matrix and normal for each projector */ | /* calculate a projection matrix and normal for each projector */ | ||||
| for (i = 0; i < num_projectors; ++i) { | for (i = 0; i < num_projectors; ++i) { | ||||
| float tmpmat[4][4]; | float tmpmat[4][4]; | ||||
| float offsetmat[4][4]; | float offsetmat[4][4]; | ||||
| Camera *cam = NULL; | Camera *cam = NULL; | ||||
| /* calculate projection matrix */ | /* calculate projection matrix */ | ||||
| invert_m4_m4(projectors[i].projmat, projectors[i].ob->obmat); | invert_m4_m4(projectors[i].projmat, projectors[i].ob->obmat); | ||||
| Show All 40 Lines | for (i = 0; i < num_projectors; ++i) { | ||||
| /* calculate worldspace projector normal (for best projector test) */ | /* calculate worldspace projector normal (for best projector test) */ | ||||
| projectors[i].normal[0] = 0; | projectors[i].normal[0] = 0; | ||||
| projectors[i].normal[1] = 0; | projectors[i].normal[1] = 0; | ||||
| projectors[i].normal[2] = 1; | projectors[i].normal[2] = 1; | ||||
| mul_mat3_m4_v3(projectors[i].ob->obmat, projectors[i].normal); | mul_mat3_m4_v3(projectors[i].ob->obmat, projectors[i].normal); | ||||
| } | } | ||||
| numPolys = dm->getNumPolys(dm); | numPolys = mesh->totpoly; | ||||
| numLoops = dm->getNumLoops(dm); | numLoops = mesh->totloop; | ||||
| /* make sure we are not modifying the original UV map */ | /* make sure we are not modifying the original UV map */ | ||||
| mloop_uv = CustomData_duplicate_referenced_layer_named(&dm->loopData, | mloop_uv = CustomData_duplicate_referenced_layer_named(&mesh->ldata, | ||||
| CD_MLOOPUV, uvname, numLoops); | CD_MLOOPUV, uvname, numLoops); | ||||
| numVerts = dm->getNumVerts(dm); | coords = BKE_mesh_vertexCos_get(mesh, &numVerts); | ||||
| coords = MEM_malloc_arrayN(numVerts, sizeof(*coords), | |||||
| "uvprojectModifier_do coords"); | |||||
| dm->getVertCos(dm, coords); | |||||
| /* convert coords to world space */ | /* convert coords to world space */ | ||||
| for (i = 0, co = coords; i < numVerts; ++i, ++co) | for (i = 0, co = coords; i < numVerts; ++i, ++co) | ||||
| mul_m4_v3(ob->obmat, *co); | mul_m4_v3(ob->obmat, *co); | ||||
| /* if only one projector, project coords to UVs */ | /* if only one projector, project coords to UVs */ | ||||
| if (num_projectors == 1 && projectors[0].uci == NULL) | if (num_projectors == 1 && projectors[0].uci == NULL) | ||||
| for (i = 0, co = coords; i < numVerts; ++i, ++co) | for (i = 0, co = coords; i < numVerts; ++i, ++co) | ||||
| mul_project_m4_v3(projectors[0].projmat, *co); | mul_project_m4_v3(projectors[0].projmat, *co); | ||||
| mpoly = dm->getPolyArray(dm); | mpoly = mesh->mpoly; | ||||
| mloop = dm->getLoopArray(dm); | mloop = mesh->mloop; | ||||
| /* apply coords as UVs */ | /* apply coords as UVs */ | ||||
| for (i = 0, mp = mpoly; i < numPolys; ++i, ++mp) { | for (i = 0, mp = mpoly; i < numPolys; ++i, ++mp) { | ||||
| if (num_projectors == 1) { | if (num_projectors == 1) { | ||||
| if (projectors[0].uci) { | if (projectors[0].uci) { | ||||
| unsigned int fidx = mp->totloop - 1; | unsigned int fidx = mp->totloop - 1; | ||||
| do { | do { | ||||
| unsigned int lidx = mp->loopstart + fidx; | unsigned int lidx = mp->loopstart + fidx; | ||||
| ▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | if (free_uci) { | ||||
| for (j = 0; j < num_projectors; ++j) { | for (j = 0; j < num_projectors; ++j) { | ||||
| if (projectors[j].uci) { | if (projectors[j].uci) { | ||||
| MEM_freeN(projectors[j].uci); | MEM_freeN(projectors[j].uci); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Mark tessellated CD layers as dirty. */ | /* Mark tessellated CD layers as dirty. */ | ||||
| dm->dirty |= DM_DIRTY_TESS_CDLAYERS; | mesh->runtime.cd_dirty_vert |= CD_MASK_TESSLOOPNORMAL; | ||||
| return dm; | return mesh; | ||||
| } | } | ||||
| static DerivedMesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, | static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, | ||||
| DerivedMesh *derivedData) | Mesh *mesh) | ||||
| { | { | ||||
| DerivedMesh *result; | Mesh *result; | ||||
| UVProjectModifierData *umd = (UVProjectModifierData *) md; | UVProjectModifierData *umd = (UVProjectModifierData *) md; | ||||
| result = uvprojectModifier_do(umd, ctx->object, derivedData); | result = uvprojectModifier_do(umd, ctx->object, mesh); | ||||
| return result; | return result; | ||||
| } | } | ||||
| ModifierTypeInfo modifierType_UVProject = { | ModifierTypeInfo modifierType_UVProject = { | ||||
| /* name */ "UVProject", | /* name */ "UVProject", | ||||
| /* structName */ "UVProjectModifierData", | /* structName */ "UVProjectModifierData", | ||||
| /* structSize */ sizeof(UVProjectModifierData), | /* structSize */ sizeof(UVProjectModifierData), | ||||
| /* type */ eModifierTypeType_NonGeometrical, | /* type */ eModifierTypeType_NonGeometrical, | ||||
| /* flags */ eModifierTypeFlag_AcceptsMesh | | /* flags */ eModifierTypeFlag_AcceptsMesh | | ||||
| eModifierTypeFlag_SupportsMapping | | eModifierTypeFlag_SupportsMapping | | ||||
| eModifierTypeFlag_SupportsEditmode | | eModifierTypeFlag_SupportsEditmode | | ||||
| eModifierTypeFlag_EnableInEditmode, | eModifierTypeFlag_EnableInEditmode, | ||||
| /* 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 */ requiredDataMask, | /* requiredDataMask */ requiredDataMask, | ||||
| /* freeData */ NULL, | /* freeData */ NULL, | ||||
| /* isDisabled */ NULL, | /* isDisabled */ NULL, | ||||
| /* updateDepsgraph */ updateDepsgraph, | /* updateDepsgraph */ updateDepsgraph, | ||||
| /* dependsOnTime */ NULL, | /* dependsOnTime */ NULL, | ||||
| /* dependsOnNormals */ NULL, | /* dependsOnNormals */ NULL, | ||||
| /* foreachObjectLink */ foreachObjectLink, | /* foreachObjectLink */ foreachObjectLink, | ||||
| /* foreachIDLink */ foreachIDLink, | /* foreachIDLink */ foreachIDLink, | ||||
| /* foreachTexLink */ NULL, | /* foreachTexLink */ NULL, | ||||
| }; | }; | ||||