Blender V4.3
MOD_util.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cstring>
10
11#include "BLI_utildefines.h"
12
13#include "BLI_bitmap.h"
14#include "BLI_math_matrix.h"
15#include "BLI_math_vector.h"
16
17#include "DNA_image_types.h"
18#include "DNA_mesh_types.h"
19#include "DNA_modifier_types.h"
20#include "DNA_object_types.h"
21
22#include "BKE_action.hh" /* BKE_pose_channel_find_name */
23#include "BKE_attribute.hh"
24#include "BKE_deform.hh"
25#include "BKE_editmesh.hh"
26#include "BKE_image.hh"
27#include "BKE_lattice.hh"
28
29#include "BKE_modifier.hh"
30
31#include "DEG_depsgraph.hh"
33
34#include "MOD_modifiertypes.hh"
35#include "MOD_util.hh"
36
37#include "MEM_guardedalloc.h"
38
40{
41 Tex *tex = dmd->texture;
42
43 if (tex == nullptr) {
44 return;
45 }
46
49 }
50}
51
53 const ModifierEvalContext * /*ctx*/,
54 Object *ob,
55 Mesh *mesh,
56 float (*cos)[3],
57 float (*r_texco)[3])
58{
59 /* TODO: to be renamed to `get_texture_coords` once we are done with moving modifiers to Mesh. */
60
61 using namespace blender;
62 const int verts_num = mesh->verts_num;
63 int i;
64 int texmapping = dmd->texmapping;
65 float mapref_imat[4][4];
66
67 if (texmapping == MOD_DISP_MAP_OBJECT) {
68 if (dmd->map_object != nullptr) {
69 Object *map_object = dmd->map_object;
70 if (dmd->map_bone[0] != '\0') {
71 bPoseChannel *pchan = BKE_pose_channel_find_name(map_object->pose, dmd->map_bone);
72 if (pchan) {
73 float mat_bone_world[4][4];
74 mul_m4_m4m4(mat_bone_world, map_object->object_to_world().ptr(), pchan->pose_mat);
75 invert_m4_m4(mapref_imat, mat_bone_world);
76 }
77 else {
78 invert_m4_m4(mapref_imat, map_object->object_to_world().ptr());
79 }
80 }
81 else {
82 invert_m4_m4(mapref_imat, map_object->object_to_world().ptr());
83 }
84 }
85 else { /* if there is no map object, default to local */
86 texmapping = MOD_DISP_MAP_LOCAL;
87 }
88 }
89
90 /* UVs need special handling, since they come from faces */
91 if (texmapping == MOD_DISP_MAP_UV) {
92 if (CustomData_has_layer(&mesh->corner_data, CD_PROP_FLOAT2)) {
93 const OffsetIndices faces = mesh->faces();
94 const Span<int> corner_verts = mesh->corner_verts();
95 BLI_bitmap *done = BLI_BITMAP_NEW(verts_num, __func__);
96 char uvname[MAX_CUSTOMDATA_LAYER_NAME];
98 &mesh->corner_data, CD_PROP_FLOAT2, dmd->uvlayer_name, uvname);
99 const bke::AttributeAccessor attributes = mesh->attributes();
100 const VArraySpan uv_map = *attributes.lookup_or_default<float2>(
101 uvname, bke::AttrDomain::Corner, float2(0));
102
103 /* verts are given the UV from the first face that uses them */
104 for (const int i : faces.index_range()) {
105 const IndexRange face = faces[i];
106 for (const int corner : face) {
107 const int vert = corner_verts[corner];
108 if (!BLI_BITMAP_TEST(done, vert)) {
109 /* remap UVs from [0, 1] to [-1, 1] */
110 r_texco[vert][0] = (uv_map[corner][0] * 2.0f) - 1.0f;
111 r_texco[vert][1] = (uv_map[corner][1] * 2.0f) - 1.0f;
112 BLI_BITMAP_ENABLE(done, vert);
113 }
114 }
115 }
116
117 MEM_freeN(done);
118 return;
119 }
120
121 /* if there are no UVs, default to local */
122 texmapping = MOD_DISP_MAP_LOCAL;
123 }
124
125 const Span<float3> positions = mesh->vert_positions();
126 for (i = 0; i < verts_num; i++, r_texco++) {
127 switch (texmapping) {
129 copy_v3_v3(*r_texco, cos != nullptr ? *cos : positions[i]);
130 break;
132 mul_v3_m4v3(*r_texco, ob->object_to_world().ptr(), cos != nullptr ? *cos : positions[i]);
133 break;
135 mul_v3_m4v3(*r_texco, ob->object_to_world().ptr(), cos != nullptr ? *cos : positions[i]);
136 mul_m4_v3(mapref_imat, *r_texco);
137 break;
138 }
139 if (cos != nullptr) {
140 cos++;
141 }
142 }
143}
144
145void MOD_previous_vcos_store(ModifierData *md, const float (*vert_coords)[3])
146{
147 while ((md = md->next) && md->type == eModifierType_Armature) {
149 if (amd->multi && amd->vert_coords_prev == nullptr) {
150 amd->vert_coords_prev = static_cast<float(*)[3]>(MEM_dupallocN(vert_coords));
151 }
152 else {
153 break;
154 }
155 }
156 /* lattice/mesh modifier too */
157}
158
159void MOD_get_vgroup(const Object *ob,
160 const Mesh *mesh,
161 const char *name,
162 const MDeformVert **dvert,
163 int *defgrp_index)
164{
165 if (mesh) {
166 *defgrp_index = BKE_id_defgroup_name_index(&mesh->id, name);
167 if (*defgrp_index != -1) {
168 *dvert = mesh->deform_verts().data();
169 }
170 else {
171 *dvert = nullptr;
172 }
173 }
174 else if (OB_TYPE_SUPPORT_VGROUP(ob->type)) {
175 *defgrp_index = BKE_object_defgroup_name_index(ob, name);
176 if (*defgrp_index != -1 && ob->type == OB_LATTICE) {
177 *dvert = BKE_lattice_deform_verts_get(ob);
178 }
179 else {
180 *dvert = nullptr;
181 }
182 }
183 else {
184 *defgrp_index = -1;
185 *dvert = nullptr;
186 }
187}
188
190 Object *object,
191 const char *bonename,
192 const char *description)
193{
194 if (object == nullptr) {
195 return;
196 }
197 if (bonename[0] != '\0' && object->type == OB_ARMATURE) {
198 DEG_add_object_relation(node, object, DEG_OB_COMP_EVAL_POSE, description);
199 }
200 else {
201 DEG_add_object_relation(node, object, DEG_OB_COMP_TRANSFORM, description);
202 }
203}
204
206{
207#define INIT_TYPE(typeName) (types[eModifierType_##typeName] = &modifierType_##typeName)
211 INIT_TYPE(Subsurf);
212 INIT_TYPE(Build);
214 INIT_TYPE(Mirror);
215 INIT_TYPE(EdgeSplit);
217 INIT_TYPE(Displace);
218 INIT_TYPE(UVProject);
219 INIT_TYPE(Decimate);
220 INIT_TYPE(Smooth);
221 INIT_TYPE(Cast);
222 INIT_TYPE(Wave);
223 INIT_TYPE(Armature);
224 INIT_TYPE(Hook);
225 INIT_TYPE(Softbody);
227 INIT_TYPE(Collision);
228 INIT_TYPE(Boolean);
229 INIT_TYPE(MeshDeform);
232 INIT_TYPE(ParticleInstance);
233 INIT_TYPE(Explode);
234 INIT_TYPE(Shrinkwrap);
236 INIT_TYPE(SimpleDeform);
237 INIT_TYPE(Multires);
238 INIT_TYPE(Surface);
239 INIT_TYPE(Fluid);
240 INIT_TYPE(ShapeKey);
241 INIT_TYPE(Solidify);
242 INIT_TYPE(Screw);
243 INIT_TYPE(Warp);
244 INIT_TYPE(WeightVGEdit);
245 INIT_TYPE(WeightVGMix);
246 INIT_TYPE(WeightVGProximity);
247 INIT_TYPE(DynamicPaint);
248 INIT_TYPE(Remesh);
249 INIT_TYPE(Skin);
250 INIT_TYPE(LaplacianSmooth);
251 INIT_TYPE(Triangulate);
252 INIT_TYPE(UVWarp);
253 INIT_TYPE(MeshCache);
254 INIT_TYPE(LaplacianDeform);
256 INIT_TYPE(Weld);
257 INIT_TYPE(DataTransfer);
258 INIT_TYPE(NormalEdit);
259 INIT_TYPE(CorrectiveSmooth);
260 INIT_TYPE(MeshSequenceCache);
261 INIT_TYPE(SurfaceDeform);
262 INIT_TYPE(WeightedNormal);
263 INIT_TYPE(MeshToVolume);
264 INIT_TYPE(VolumeDisplace);
265 INIT_TYPE(VolumeToMesh);
266 INIT_TYPE(Nodes);
267 INIT_TYPE(GreasePencilOpacity);
268 INIT_TYPE(GreasePencilSubdiv);
269 INIT_TYPE(GreasePencilColor);
270 INIT_TYPE(GreasePencilTint);
271 INIT_TYPE(GreasePencilSmooth);
272 INIT_TYPE(GreasePencilOffset);
273 INIT_TYPE(GreasePencilNoise);
274 INIT_TYPE(GreasePencilMirror);
275 INIT_TYPE(GreasePencilThickness);
276 INIT_TYPE(GreasePencilLattice);
277 INIT_TYPE(GreasePencilDash);
278 INIT_TYPE(GreasePencilMultiply);
279 INIT_TYPE(GreasePencilLength);
280 INIT_TYPE(GreasePencilWeightAngle);
281 INIT_TYPE(GreasePencilArray);
282 INIT_TYPE(GreasePencilWeightProximity);
283 INIT_TYPE(GreasePencilHook);
284 INIT_TYPE(GreasePencilLineart);
285 INIT_TYPE(GreasePencilArmature);
286 INIT_TYPE(GreasePencilTime);
287 INIT_TYPE(GreasePencilSimplify);
288 INIT_TYPE(GreasePencilEnvelope);
289 INIT_TYPE(GreasePencilOutline);
290 INIT_TYPE(GreasePencilShrinkwrap);
291 INIT_TYPE(GreasePencilBuild);
292 INIT_TYPE(GreasePencilTexture);
293#undef INIT_TYPE
294}
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
void CustomData_validate_layer_name(const CustomData *data, eCustomDataType type, blender::StringRef name, char *outname)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
support for deformation groups and hooks.
int BKE_id_defgroup_name_index(const ID *id, blender::StringRef name)
Definition deform.cc:543
int BKE_object_defgroup_name_index(const Object *ob, blender::StringRef name)
Definition deform.cc:585
void BKE_image_user_frame_calc(Image *ima, ImageUser *iuser, int cfra)
bool BKE_image_is_animated(Image *image)
MDeformVert * BKE_lattice_deform_verts_get(const Object *oblatt)
Definition lattice.cc:575
#define BLI_BITMAP_NEW(_num, _alloc_string)
Definition BLI_bitmap.h:41
#define BLI_BITMAP_TEST(_bitmap, _index)
Definition BLI_bitmap.h:65
#define BLI_BITMAP_ENABLE(_bitmap, _index)
Definition BLI_bitmap.h:82
unsigned int BLI_bitmap
Definition BLI_bitmap.h:17
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void mul_m4_v3(const float M[4][4], float r[3])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
MINLINE void copy_v3_v3(float r[3], const float a[3])
void DEG_add_object_relation(DepsNodeHandle *node_handle, Object *object, eDepsObjectComponentType component, const char *description)
@ DEG_OB_COMP_EVAL_POSE
@ DEG_OB_COMP_TRANSFORM
float DEG_get_ctime(const Depsgraph *graph)
#define MAX_CUSTOMDATA_LAYER_NAME
@ CD_PROP_FLOAT2
@ MOD_DISP_MAP_OBJECT
@ MOD_DISP_MAP_GLOBAL
@ MOD_DISP_MAP_LOCAL
@ MOD_DISP_MAP_UV
@ eModifierType_Armature
Object is a sort of wrapper for general info.
@ OB_LATTICE
@ OB_ARMATURE
#define OB_TYPE_SUPPORT_VGROUP(_type)
Read Guarded memory(de)allocation.
void MOD_init_texture(MappingInfoModifierData *dmd, const ModifierEvalContext *ctx)
Definition MOD_util.cc:39
#define INIT_TYPE(typeName)
void MOD_depsgraph_update_object_bone_relation(DepsNodeHandle *node, Object *object, const char *bonename, const char *description)
Definition MOD_util.cc:189
void MOD_get_vgroup(const Object *ob, const Mesh *mesh, const char *name, const MDeformVert **dvert, int *defgrp_index)
Definition MOD_util.cc:159
void MOD_previous_vcos_store(ModifierData *md, const float(*vert_coords)[3])
Definition MOD_util.cc:145
void modifier_type_init(ModifierTypeInfo *types[])
Definition MOD_util.cc:205
void MOD_get_texture_coords(MappingInfoModifierData *dmd, const ModifierEvalContext *, Object *ob, Mesh *mesh, float(*cos)[3], float(*r_texco)[3])
Definition MOD_util.cc:52
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color or the default fallback if none is specified Separate Split a vector into its and Z components Bevel
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Wireframe
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_dupallocN)(const void *vmemh)
Definition mallocn.cc:39
ccl_device_inline float3 cos(float3 v)
struct ModifierData * next
struct bPose * pose
struct ImageUser iuser
struct Image * ima
float pose_mat[4][4]