Changeset View
Changeset View
Standalone View
Standalone View
source/blender/modifiers/intern/MOD_vcol_edit.c
- This file was added.
| /* | |||||
| * ***** BEGIN GPL LICENSE BLOCK ***** | |||||
| * | |||||
| * This program is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU General Public License | |||||
| * as published by the Free Software Foundation; either version 2 | |||||
| * of the License, or (at your option) any later version. | |||||
| * | |||||
| * This program is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | |||||
| * | |||||
| * You should have received a copy of the GNU General Public License | |||||
| * along with this program; if not, write to the Free Software Foundation, | |||||
| * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||||
| * | |||||
| * Contributor(s): Lukas Toenne | |||||
| * | |||||
| * ***** END GPL LICENSE BLOCK ***** | |||||
| * | |||||
| */ | |||||
| /** \file blender/modifiers/intern/MOD_vcol_edit.c | |||||
| * \ingroup modifiers | |||||
| */ | |||||
| #include "DNA_customdata_types.h" | |||||
| #include "DNA_material_types.h" /* for blending modes */ | |||||
| #include "DNA_meshdata_types.h" | |||||
| #include "DNA_object_types.h" | |||||
| #include "BLI_utildefines.h" | |||||
| #include "BLI_math.h" | |||||
| #include "BKE_cdderivedmesh.h" | |||||
| #include "BKE_customdata.h" | |||||
| #include "BKE_deform.h" | |||||
| #include "BKE_library.h" | |||||
| #include "BKE_library_query.h" | |||||
| #include "BKE_material.h" | |||||
| #include "BKE_mesh.h" | |||||
| #include "BKE_modifier.h" | |||||
| #include "BKE_texture.h" | |||||
| #include "depsgraph_private.h" | |||||
| #include "MEM_guardedalloc.h" | |||||
| #include "MOD_util.h" | |||||
| #include "RE_shader_ext.h" | |||||
| /* Vertex Color Edit */ | |||||
| static void initData(ModifierData *md) | |||||
| { | |||||
| VertexColorEditModifierData *vmd = (VertexColorEditModifierData *) md; | |||||
| vmd->texture = NULL; | |||||
| vmd->blend_mode = MA_RAMP_BLEND; | |||||
| vmd->blend_factor = 0.5f; | |||||
| } | |||||
| static void copyData(ModifierData *md, ModifierData *target) | |||||
| { | |||||
| #if 0 | |||||
| VertexColorEditModifierData *vmd = (VertexColorEditModifierData *)md; | |||||
| #endif | |||||
| VertexColorEditModifierData *tvmd = (VertexColorEditModifierData *)target; | |||||
| modifier_copyData_generic(md, target); | |||||
| if (tvmd->texture) { | |||||
| id_us_plus(&tvmd->texture->id); | |||||
| } | |||||
| } | |||||
| static void freeData(ModifierData *md) | |||||
| { | |||||
| VertexColorEditModifierData *vmd = (VertexColorEditModifierData *)md; | |||||
| if (vmd->texture) { | |||||
| id_us_min(&vmd->texture->id); | |||||
| } | |||||
| } | |||||
| static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) | |||||
| { | |||||
| VertexColorEditModifierData *vmd = (VertexColorEditModifierData *)md; | |||||
| CustomDataMask dataMask = 0; | |||||
| /* ask for vertex colors */ | |||||
| if (vmd->vcol_name[0]) { | |||||
| dataMask |= CD_MASK_MLOOPCOL; | |||||
| } | |||||
| /* ask for UV coordinates if we need them */ | |||||
| if (vmd->texmapping == MOD_DISP_MAP_UV) { | |||||
| dataMask |= CD_MASK_MTFACE; | |||||
| } | |||||
| return dataMask; | |||||
| } | |||||
| static bool dependsOnTime(ModifierData *md) | |||||
| { | |||||
| VertexColorEditModifierData *vmd = (VertexColorEditModifierData *)md; | |||||
| if (vmd->texture) { | |||||
| return BKE_texture_dependsOnTime(vmd->texture); | |||||
| } | |||||
| else { | |||||
| return false; | |||||
| } | |||||
| } | |||||
| static void foreachObjectLink(ModifierData *md, Object *ob, | |||||
| ObjectWalkFunc walk, void *userData) | |||||
| { | |||||
| VertexColorEditModifierData *vmd = (VertexColorEditModifierData *) md; | |||||
| walk(userData, ob, &vmd->map_object, IDWALK_NOP); | |||||
| } | |||||
| static void foreachIDLink(ModifierData *md, Object *ob, | |||||
| IDWalkFunc walk, void *userData) | |||||
| { | |||||
| VertexColorEditModifierData *vmd = (VertexColorEditModifierData *) md; | |||||
| walk(userData, ob, (ID **)&vmd->texture, IDWALK_USER); | |||||
| foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData); | |||||
| } | |||||
| static void foreachTexLink(ModifierData *md, Object *ob, | |||||
| TexWalkFunc walk, void *userData) | |||||
| { | |||||
| walk(userData, ob, md, "texture"); | |||||
| } | |||||
| static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams)) | |||||
| { | |||||
| VertexColorEditModifierData *vmd = (VertexColorEditModifierData *) md; | |||||
| return (!vmd->texture); | |||||
| } | |||||
| static void updateDepgraph(ModifierData *md, DagForest *forest, | |||||
| struct Main *UNUSED(bmain), | |||||
| struct Scene *UNUSED(scene), | |||||
| Object *UNUSED(ob), | |||||
| DagNode *obNode) | |||||
| { | |||||
| VertexColorEditModifierData *vmd = (VertexColorEditModifierData *) md; | |||||
| if (vmd->map_object && vmd->texmapping == MOD_DISP_MAP_OBJECT) { | |||||
| DagNode *curNode = dag_get_node(forest, vmd->map_object); | |||||
| dag_add_relation(forest, curNode, obNode, | |||||
| DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Vertex Color Edit Modifier"); | |||||
| } | |||||
| if (vmd->texmapping == MOD_DISP_MAP_GLOBAL) | |||||
| dag_add_relation(forest, obNode, obNode, | |||||
| DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Vertex Color Edit Modifier"); | |||||
| } | |||||
| static void updateDepsgraph(ModifierData *md, | |||||
| struct Main *UNUSED(bmain), | |||||
| struct Scene *UNUSED(scene), | |||||
| Object *ob, | |||||
| struct DepsNodeHandle *node) | |||||
| { | |||||
| VertexColorEditModifierData *vmd = (VertexColorEditModifierData *)md; | |||||
| if (vmd->map_object != NULL && vmd->texmapping == MOD_DISP_MAP_OBJECT) { | |||||
| DEG_add_object_relation(node, vmd->map_object, DEG_OB_COMP_TRANSFORM, "Vertex Color Edit Modifier"); | |||||
| } | |||||
| if (vmd->texmapping == MOD_DISP_MAP_GLOBAL) { | |||||
| DEG_add_object_relation(node, ob, DEG_OB_COMP_TRANSFORM, "Vertex Color Edit Modifier"); | |||||
| } | |||||
| } | |||||
| /* dm must be a CDDerivedMesh */ | |||||
| static void vertexColorEditModifier_do( | |||||
| VertexColorEditModifierData *vmd, Object *ob, | |||||
| DerivedMesh *dm, float (*vertexCos)[3], int numVerts) | |||||
| { | |||||
| MLoop *mloop = dm->getLoopArray(dm); | |||||
| int totloop = dm->getNumLoops(dm); | |||||
| MLoopCol *mcol; | |||||
| MDeformVert *dvert; | |||||
| char layername[MAX_CUSTOMDATA_LAYER_NAME]; | |||||
| int defgrp_index; | |||||
| float (*tex_co)[3]; | |||||
| int i; | |||||
| if (!CustomData_has_layer(&dm->loopData, CD_MLOOPCOL)) | |||||
| return; | |||||
| CustomData_validate_layer_name(&dm->loopData, CD_MLOOPCOL, vmd->vcol_name, layername); | |||||
| mcol = CustomData_get_layer_named(&dm->loopData, CD_MLOOPCOL, layername); | |||||
| if (!mcol) | |||||
| return; | |||||
| modifier_get_vgroup(ob, dm, vmd->defgrp_name, &dvert, &defgrp_index); | |||||
| if (vmd->texture) { | |||||
| tex_co = MEM_callocN(sizeof(*tex_co) * numVerts, | |||||
| "vertexColorEditModifier_do tex_co"); | |||||
| get_texture_coords((MappingInfoModifierData *)vmd, ob, dm, vertexCos, tex_co, numVerts); | |||||
| modifier_init_texture(vmd->modifier.scene, vmd->texture); | |||||
| } | |||||
| else { | |||||
| tex_co = NULL; | |||||
| } | |||||
| for (i = 0; i < totloop; i++) { | |||||
| const int v = mloop[i].v; | |||||
| float weight; | |||||
| float tex_col[4], orig_col[4], new_col[4]; | |||||
| if (dvert) { | |||||
| weight = defvert_find_weight(dvert + v, defgrp_index); | |||||
| if (weight == 0.0f) | |||||
| continue; | |||||
| } | |||||
| else | |||||
| weight = 1.0f; | |||||
| if (vmd->texture) { | |||||
| TexResult texres; | |||||
| texres.nor = NULL; | |||||
| BKE_texture_get_value(vmd->modifier.scene, vmd->texture, tex_co[v], &texres, false); | |||||
| copy_v4_v4(tex_col, &texres.tr); | |||||
| } | |||||
| else { | |||||
| tex_col[0] = tex_col[1] = tex_col[2] = tex_col[3] = 0.0f; | |||||
| } | |||||
| rgba_uchar_to_float(orig_col, &mcol[i].r); | |||||
| copy_v4_v4(new_col, orig_col); | |||||
| ramp_blend(vmd->blend_mode, new_col, vmd->blend_factor * weight, tex_col); | |||||
| rgba_float_to_uchar(&mcol[i].r, new_col); | |||||
| } | |||||
| } | |||||
| static void deformVerts(ModifierData *md, Object *ob, | |||||
| DerivedMesh *derivedData, | |||||
| float (*vertexCos)[3], | |||||
| int numVerts, | |||||
| ModifierApplyFlag UNUSED(flag)) | |||||
| { | |||||
| DerivedMesh *dm = get_cddm(ob, NULL, derivedData, vertexCos, false); | |||||
| vertexColorEditModifier_do((VertexColorEditModifierData *)md, ob, dm, | |||||
| vertexCos, numVerts); | |||||
| if (dm != derivedData) | |||||
| dm->release(dm); | |||||
| } | |||||
| static void deformVertsEM( | |||||
| ModifierData *md, Object *ob, struct BMEditMesh *editData, | |||||
| DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) | |||||
| { | |||||
| DerivedMesh *dm = get_cddm(ob, editData, derivedData, vertexCos, false); | |||||
| vertexColorEditModifier_do((VertexColorEditModifierData *)md, ob, dm, | |||||
| vertexCos, numVerts); | |||||
| if (dm != derivedData) | |||||
| dm->release(dm); | |||||
| } | |||||
| ModifierTypeInfo modifierType_VertexColorEdit = { | |||||
| /* name */ "VertexColorEdit", | |||||
| /* structName */ "VertexColorEditModifierData", | |||||
| /* structSize */ sizeof(VertexColorEditModifierData), | |||||
| /* type */ eModifierTypeType_OnlyDeform, | |||||
| /* flags */ eModifierTypeFlag_AcceptsMesh | | |||||
| eModifierTypeFlag_SupportsEditmode, | |||||
| /* copyData */ copyData, | |||||
| /* deformVerts */ deformVerts, | |||||
| /* deformMatrices */ NULL, | |||||
| /* deformVertsEM */ deformVertsEM, | |||||
| /* deformMatricesEM */ NULL, | |||||
| /* applyModifier */ NULL, | |||||
| /* applyModifierEM */ NULL, | |||||
| /* initData */ initData, | |||||
| /* requiredDataMask */ requiredDataMask, | |||||
| /* freeData */ freeData, | |||||
| /* isDisabled */ isDisabled, | |||||
| /* updateDepgraph */ updateDepgraph, | |||||
| /* updateDepsgraph */ updateDepsgraph, | |||||
| /* dependsOnTime */ dependsOnTime, | |||||
| /* dependsOnNormals */ NULL, | |||||
| /* foreachObjectLink */ foreachObjectLink, | |||||
| /* foreachIDLink */ foreachIDLink, | |||||
| /* foreachTexLink */ foreachTexLink, | |||||
| }; | |||||