Blender  V3.3
paint_vertex_proj.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2013 Blender Foundation. All rights reserved. */
3 
11 #include "MEM_guardedalloc.h"
12 
13 #include "BLI_listbase.h"
14 #include "BLI_math.h"
15 
16 #include "DNA_mesh_types.h"
17 #include "DNA_object_types.h"
18 
19 #include "BKE_context.h"
20 #include "BKE_customdata.h"
21 #include "BKE_mesh_iterators.h"
22 #include "BKE_mesh_runtime.h"
23 
24 #include "DEG_depsgraph.h"
25 #include "DEG_depsgraph_query.h"
26 
27 #include "ED_screen.h"
28 #include "ED_view3d.h"
29 
30 #include "paint_intern.h" /* own include */
31 
32 /* Opaque Structs for internal use */
33 
34 /* stored while painting */
37 
38  bool use_update;
39 
40  /* use for update */
41  float *dists_sq;
42 
45 };
46 
47 /* only for passing to the callbacks */
50 
51  /* runtime */
53  const float *mval_fl;
54 };
55 
56 /* -------------------------------------------------------------------- */
57 /* Internal Init */
58 
59 static void vpaint_proj_dm_map_cosnos_init__map_cb(void *userData,
60  int index,
61  const float co[3],
62  const float no[3])
63 {
64  struct VertProjHandle *vp_handle = userData;
65  CoNo *co_no = &vp_handle->vcosnos[index];
66 
67  /* check if we've been here before (normal should not be 0) */
68  if (!is_zero_v3(co_no->no)) {
69  /* remember that multiple dm verts share the same source vert */
70  vp_handle->use_update = true;
71  return;
72  }
73 
74  copy_v3_v3(co_no->co, co);
75  copy_v3_v3(co_no->no, no);
76 }
77 
79  Scene *UNUSED(scene),
80  Object *ob,
81  struct VertProjHandle *vp_handle)
82 {
85  Mesh *me = ob->data;
86 
88  Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks);
89 
90  memset(vp_handle->vcosnos, 0, sizeof(*vp_handle->vcosnos) * me->totvert);
93 }
94 
95 /* -------------------------------------------------------------------- */
96 /* Internal Update */
97 
98 /* Same as init but take mouse location into account */
99 
100 static void vpaint_proj_dm_map_cosnos_update__map_cb(void *userData,
101  int index,
102  const float co[3],
103  const float no[3])
104 {
105  struct VertProjUpdate *vp_update = userData;
106  struct VertProjHandle *vp_handle = vp_update->vp_handle;
107 
108  CoNo *co_no = &vp_handle->vcosnos[index];
109 
110  /* find closest vertex */
111  {
112  /* first find distance to this vertex */
113  float co_ss[2]; /* screenspace */
114 
116  vp_update->region, co, co_ss, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) ==
117  V3D_PROJ_RET_OK) {
118  const float dist_sq = len_squared_v2v2(vp_update->mval_fl, co_ss);
119  if (dist_sq > vp_handle->dists_sq[index]) {
120  /* bail out! */
121  return;
122  }
123 
124  vp_handle->dists_sq[index] = dist_sq;
125  }
126  else if (vp_handle->dists_sq[index] != FLT_MAX) {
127  /* already initialized & couldn't project this 'co' */
128  return;
129  }
130  }
131  /* continue with regular functionality */
132 
133  copy_v3_v3(co_no->co, co);
134  copy_v3_v3(co_no->no, no);
135 }
136 
138  struct VertProjHandle *vp_handle,
139  ARegion *region,
140  const float mval_fl[2])
141 {
142  struct VertProjUpdate vp_update = {vp_handle, region, mval_fl};
143 
144  Object *ob = vp_handle->ob;
145  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
146  Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
147  Mesh *me = ob->data;
148 
150  Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks);
151 
152  /* quick sanity check - we shouldn't have to run this if there are no modifiers */
154 
155  copy_vn_fl(vp_handle->dists_sq, me->totvert, FLT_MAX);
158 }
159 
160 /* -------------------------------------------------------------------- */
161 /* Public Functions */
162 
164  Scene *scene,
165  Object *ob,
166  CoNo **r_vcosnos)
167 {
168  struct VertProjHandle *vp_handle = MEM_mallocN(sizeof(struct VertProjHandle), __func__);
169  Mesh *me = ob->data;
170 
171  /* setup the handle */
172  vp_handle->vcosnos = MEM_mallocN(sizeof(CoNo) * me->totvert, "vertexcosnos map");
173  vp_handle->use_update = false;
174 
175  /* sets 'use_update' if needed */
177 
178  if (vp_handle->use_update) {
179  vp_handle->dists_sq = MEM_mallocN(sizeof(float) * me->totvert, __func__);
180 
181  vp_handle->ob = ob;
182  vp_handle->scene = scene;
183  }
184  else {
185  vp_handle->dists_sq = NULL;
186 
187  vp_handle->ob = NULL;
188  vp_handle->scene = NULL;
189  }
190 
191  *r_vcosnos = vp_handle->vcosnos;
192  return vp_handle;
193 }
194 
196  struct VertProjHandle *vp_handle,
197  ARegion *region,
198  const float mval_fl[2])
199 {
200  if (vp_handle->use_update) {
201  vpaint_proj_dm_map_cosnos_update(depsgraph, vp_handle, region, mval_fl);
202  }
203 }
204 
206 {
207  if (vp_handle->use_update) {
208  MEM_freeN(vp_handle->dists_sq);
209  }
210 
211  MEM_freeN(vp_handle->vcosnos);
212  MEM_freeN(vp_handle);
213 }
CustomData interface, see also DNA_customdata_types.h.
const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX
Definition: customdata.cc:2058
void BKE_mesh_foreach_mapped_vert(struct Mesh *mesh, void(*func)(void *userData, int index, const float co[3], const float no[3]), void *userData, MeshForeachFlag flag)
@ MESH_FOREACH_USE_NORMAL
struct Mesh * mesh_get_eval_final(struct Depsgraph *depsgraph, const struct Scene *scene, struct Object *ob, const struct CustomData_MeshMasks *dataMask)
#define BLI_assert(a)
Definition: BLI_assert.h:46
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
MINLINE float len_squared_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
void copy_vn_fl(float *array_tar, int size, float val)
Definition: math_vector.c:1259
#define UNUSED(x)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
Object is a sort of wrapper for general info.
@ V3D_PROJ_TEST_CLIP_NEAR
Definition: ED_view3d.h:237
@ V3D_PROJ_TEST_CLIP_BB
Definition: ED_view3d.h:235
@ V3D_PROJ_RET_OK
Definition: ED_view3d.h:217
eV3DProjStatus ED_view3d_project_float_object(const struct ARegion *region, const float co[3], float r_co[2], eV3DProjTest flag)
Read Guarded memory(de)allocation.
Scene scene
const Depsgraph * depsgraph
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
void ED_vpaint_proj_handle_update(struct Depsgraph *depsgraph, struct VertProjHandle *vp_handle, ARegion *region, const float mval_fl[2])
static void vpaint_proj_dm_map_cosnos_init__map_cb(void *userData, int index, const float co[3], const float no[3])
static void vpaint_proj_dm_map_cosnos_update(struct Depsgraph *depsgraph, struct VertProjHandle *vp_handle, ARegion *region, const float mval_fl[2])
static void vpaint_proj_dm_map_cosnos_init(struct Depsgraph *depsgraph, Scene *UNUSED(scene), Object *ob, struct VertProjHandle *vp_handle)
void ED_vpaint_proj_handle_free(struct VertProjHandle *vp_handle)
static void vpaint_proj_dm_map_cosnos_update__map_cb(void *userData, int index, const float co[3], const float no[3])
struct VertProjHandle * ED_vpaint_proj_handle_create(struct Depsgraph *depsgraph, Scene *scene, Object *ob, CoNo **r_vcosnos)
float no[3]
Definition: paint_intern.h:44
float co[3]
Definition: paint_intern.h:43
int totvert
ListBase modifiers
void * data
struct VertProjHandle * vp_handle
const float * mval_fl