Blender V4.3
paint_vertex_proj.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2013 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12#include "MEM_guardedalloc.h"
13
14#include "DNA_mesh_types.h"
15#include "DNA_object_types.h"
16
17#include "BKE_mesh_iterators.hh"
18#include "BKE_object.hh"
19
20#include "BLI_math_vector.h"
21
22#include "DEG_depsgraph.hh"
24
25#include "ED_view3d.hh"
26
27#include "paint_intern.hh" /* own include */
28
29/* Opaque Structs for internal use */
30
31/* stored while painting */
44
45/* only for passing to the callbacks */
48
49 /* runtime */
51 const float *mval_fl;
52};
53
54/* -------------------------------------------------------------------- */
55/* Internal Init */
56
57static void vpaint_proj_dm_map_cosnos_init__map_cb(void *user_data,
58 int index,
59 const float co[3],
60 const float no[3])
61{
62 VertProjHandle *vp_handle = static_cast<VertProjHandle *>(user_data);
63
64 /* check if we've been here before (normal should not be 0) */
65 if (!blender::math::is_zero(vp_handle->vert_normals[index])) {
66 /* remember that multiple dm verts share the same source vert */
67 vp_handle->use_update = true;
68 return;
69 }
70
71 vp_handle->vert_positions[index] = co;
72 vp_handle->vert_normals[index] = no;
73}
74
76 Scene & /*scene*/,
77 Object &ob,
78 VertProjHandle &vp_handle)
79{
80 const Object *ob_eval = DEG_get_evaluated_object(&depsgraph, &ob);
81 const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
82
83 vp_handle.vert_normals.fill(blender::float3(0));
86}
87
88/* -------------------------------------------------------------------- */
89/* Internal Update */
90
91/* Same as init but take mouse location into account */
92
93static void vpaint_proj_dm_map_cosnos_update__map_cb(void *user_data,
94 int index,
95 const float co[3],
96 const float no[3])
97{
98 VertProjUpdate *vp_update = static_cast<VertProjUpdate *>(user_data);
99 VertProjHandle *vp_handle = vp_update->vp_handle;
100
101 /* find closest vertex */
102 {
103 /* first find distance to this vertex */
104 float co_ss[2]; /* screenspace */
105
107 vp_update->region, co, co_ss, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) ==
109 {
110 const float dist_sq = len_squared_v2v2(vp_update->mval_fl, co_ss);
111 if (dist_sq > vp_handle->dists_sq[index]) {
112 /* bail out! */
113 return;
114 }
115
116 vp_handle->dists_sq[index] = dist_sq;
117 }
118 else if (vp_handle->dists_sq[index] != FLT_MAX) {
119 /* already initialized & couldn't project this 'co' */
120 return;
121 }
122 }
123 /* continue with regular functionality */
124
125 vp_handle->vert_positions[index] = co;
126 vp_handle->vert_normals[index] = no;
127}
128
130 VertProjHandle *vp_handle,
131 ARegion *region,
132 const float mval_fl[2])
133{
134 VertProjUpdate vp_update = {vp_handle, region, mval_fl};
135
136 Object &ob = *vp_handle->ob;
137
138 const Object *ob_eval = DEG_get_evaluated_object(depsgraph, &ob);
139 const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
140
141 /* quick sanity check - we shouldn't have to run this if there are no modifiers */
143
144 vp_handle->dists_sq.fill(FLT_MAX);
147}
148
149/* -------------------------------------------------------------------- */
150/* Public Functions */
151
153 Scene &scene,
154 Object &ob,
155 blender::Span<blender::float3> &r_vert_positions,
156 blender::Span<blender::float3> &r_vert_normals)
157{
158 VertProjHandle *vp_handle = MEM_new<VertProjHandle>(__func__);
159 Mesh *mesh = static_cast<Mesh *>(ob.data);
160
161 /* setup the handle */
162 vp_handle->vert_positions.reinitialize(mesh->verts_num);
163 vp_handle->vert_normals.reinitialize(mesh->verts_num);
164 vp_handle->use_update = false;
165
166 /* sets 'use_update' if needed */
167 vpaint_proj_dm_map_cosnos_init(depsgraph, scene, ob, *vp_handle);
168
169 if (vp_handle->use_update) {
170 vp_handle->dists_sq.reinitialize(mesh->verts_num);
171 vp_handle->ob = &ob;
172 vp_handle->scene = &scene;
173 }
174 else {
175 vp_handle->ob = nullptr;
176 vp_handle->scene = nullptr;
177 }
178
179 r_vert_positions = vp_handle->vert_positions;
180 r_vert_normals = vp_handle->vert_normals;
181 return vp_handle;
182}
183
185 VertProjHandle *vp_handle,
186 ARegion *region,
187 const float mval_fl[2])
188{
189 if (vp_handle->use_update) {
190 vpaint_proj_dm_map_cosnos_update(depsgraph, vp_handle, region, mval_fl);
191 }
192}
193
195{
196 MEM_delete(vp_handle);
197}
@ MESH_FOREACH_USE_NORMAL
void BKE_mesh_foreach_mapped_vert(const Mesh *mesh, void(*func)(void *user_data, int index, const float co[3], const float no[3]), void *user_data, MeshForeachFlag flag)
General operations, lookup, etc. for blender objects.
Mesh * BKE_object_get_evaluated_mesh(const Object *object_eval)
#define BLI_assert(a)
Definition BLI_assert.h:50
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
MINLINE float len_squared_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
Object is a sort of wrapper for general info.
@ V3D_PROJ_TEST_CLIP_NEAR
Definition ED_view3d.hh:269
@ V3D_PROJ_TEST_CLIP_BB
Definition ED_view3d.hh:267
eV3DProjStatus ED_view3d_project_float_object(const ARegion *region, const float co[3], float r_co[2], eV3DProjTest flag)
@ V3D_PROJ_RET_OK
Definition ED_view3d.hh:243
Read Guarded memory(de)allocation.
void fill(const T &value) const
Definition BLI_array.hh:261
void reinitialize(const int64_t new_size)
Definition BLI_array.hh:388
const Depsgraph * depsgraph
bool is_zero(const T &a)
static void vpaint_proj_dm_map_cosnos_update__map_cb(void *user_data, int index, const float co[3], const float no[3])
VertProjHandle * ED_vpaint_proj_handle_create(Depsgraph &depsgraph, Scene &scene, Object &ob, blender::Span< blender::float3 > &r_vert_positions, blender::Span< blender::float3 > &r_vert_normals)
static void vpaint_proj_dm_map_cosnos_update(Depsgraph *depsgraph, VertProjHandle *vp_handle, ARegion *region, const float mval_fl[2])
static void vpaint_proj_dm_map_cosnos_init(Depsgraph &depsgraph, Scene &, Object &ob, VertProjHandle &vp_handle)
static void vpaint_proj_dm_map_cosnos_init__map_cb(void *user_data, int index, const float co[3], const float no[3])
void ED_vpaint_proj_handle_update(Depsgraph *depsgraph, VertProjHandle *vp_handle, ARegion *region, const float mval_fl[2])
void ED_vpaint_proj_handle_free(VertProjHandle *vp_handle)
#define FLT_MAX
Definition stdcycles.h:14
ListBase modifiers
blender::Array< blender::float3 > vert_positions
blender::Array< blender::float3 > vert_normals
blender::Array< float > dists_sq
VertProjHandle * vp_handle
const float * mval_fl