Blender V4.5
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
11
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_listbase.h"
21#include "BLI_math_vector.h"
22
23#include "DEG_depsgraph.hh"
25
26#include "ED_view3d.hh"
27
28#include "paint_intern.hh" /* own include */
29
30/* Opaque Structs for internal use */
31
32/* stored while painting */
45
46/* only for passing to the callbacks */
49
50 /* runtime */
52 const float *mval_fl;
53};
54
55/* -------------------------------------------------------------------- */
56/* Internal Init */
57
58static void vpaint_proj_dm_map_cosnos_init__map_cb(void *user_data,
59 int index,
60 const float co[3],
61 const float no[3])
62{
63 VertProjHandle *vp_handle = static_cast<VertProjHandle *>(user_data);
64
65 /* check if we've been here before (normal should not be 0) */
66 if (!blender::math::is_zero(vp_handle->vert_normals[index])) {
67 /* remember that multiple dm verts share the same source vert */
68 vp_handle->use_update = true;
69 return;
70 }
71
72 vp_handle->vert_positions[index] = co;
73 vp_handle->vert_normals[index] = no;
74}
75
77 Scene & /*scene*/,
78 Object &ob,
79 VertProjHandle &vp_handle)
80{
81 const Object *ob_eval = DEG_get_evaluated(&depsgraph, &ob);
82 const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
83
84 vp_handle.vert_normals.fill(blender::float3(0));
87}
88
89/* -------------------------------------------------------------------- */
90/* Internal Update */
91
92/* Same as init but take mouse location into account */
93
94static void vpaint_proj_dm_map_cosnos_update__map_cb(void *user_data,
95 int index,
96 const float co[3],
97 const float no[3])
98{
99 VertProjUpdate *vp_update = static_cast<VertProjUpdate *>(user_data);
100 VertProjHandle *vp_handle = vp_update->vp_handle;
101
102 /* find closest vertex */
103 {
104 /* first find distance to this vertex */
105 float co_ss[2]; /* screenspace */
106
108 vp_update->region, co, co_ss, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) ==
110 {
111 const float dist_sq = len_squared_v2v2(vp_update->mval_fl, co_ss);
112 if (dist_sq > vp_handle->dists_sq[index]) {
113 /* bail out! */
114 return;
115 }
116
117 vp_handle->dists_sq[index] = dist_sq;
118 }
119 else if (vp_handle->dists_sq[index] != FLT_MAX) {
120 /* already initialized & couldn't project this 'co' */
121 return;
122 }
123 }
124 /* continue with regular functionality */
125
126 vp_handle->vert_positions[index] = co;
127 vp_handle->vert_normals[index] = no;
128}
129
131 VertProjHandle *vp_handle,
132 ARegion *region,
133 const float mval_fl[2])
134{
135 VertProjUpdate vp_update = {vp_handle, region, mval_fl};
136
137 Object &ob = *vp_handle->ob;
138
139 const Object *ob_eval = DEG_get_evaluated(depsgraph, &ob);
140 const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
141
142 /* quick sanity check - we shouldn't have to run this if there are no modifiers */
144
145 vp_handle->dists_sq.fill(FLT_MAX);
148}
149
150/* -------------------------------------------------------------------- */
151/* Public Functions */
152
154 Scene &scene,
155 Object &ob,
156 blender::Span<blender::float3> &r_vert_positions,
157 blender::Span<blender::float3> &r_vert_normals)
158{
159 VertProjHandle *vp_handle = MEM_new<VertProjHandle>(__func__);
160 Mesh *mesh = static_cast<Mesh *>(ob.data);
161
162 /* setup the handle */
163 vp_handle->vert_positions.reinitialize(mesh->verts_num);
164 vp_handle->vert_normals.reinitialize(mesh->verts_num);
165 vp_handle->use_update = false;
166
167 /* sets 'use_update' if needed */
168 vpaint_proj_dm_map_cosnos_init(depsgraph, scene, ob, *vp_handle);
169
170 if (vp_handle->use_update) {
171 vp_handle->dists_sq.reinitialize(mesh->verts_num);
172 vp_handle->ob = &ob;
173 vp_handle->scene = &scene;
174 }
175 else {
176 vp_handle->ob = nullptr;
177 vp_handle->scene = nullptr;
178 }
179
180 r_vert_positions = vp_handle->vert_positions;
181 r_vert_normals = vp_handle->vert_normals;
182 return vp_handle;
183}
184
186 VertProjHandle *vp_handle,
187 ARegion *region,
188 const float mval_fl[2])
189{
190 if (vp_handle->use_update) {
191 vpaint_proj_dm_map_cosnos_update(depsgraph, vp_handle, region, mval_fl);
192 }
193}
194
196{
197 MEM_delete(vp_handle);
198}
@ 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:46
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
MINLINE float len_squared_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
Object is a sort of wrapper for general info.
@ V3D_PROJ_TEST_CLIP_NEAR
Definition ED_view3d.hh:282
@ V3D_PROJ_TEST_CLIP_BB
Definition ED_view3d.hh:280
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:256
Read Guarded memory(de)allocation.
BPy_StructRNA * depsgraph
void fill(const T &value) const
Definition BLI_array.hh:261
void reinitialize(const int64_t new_size)
Definition BLI_array.hh:398
bool is_zero(const T &a)
VecBase< float, 3 > float3
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
int verts_num
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