Blender  V2.93
paint_vertex_proj.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2013 Blender Foundation.
17  * All rights reserved.
18  */
19 
27 #include "MEM_guardedalloc.h"
28 
29 #include "BLI_listbase.h"
30 #include "BLI_math.h"
31 
32 #include "DNA_mesh_types.h"
33 #include "DNA_object_types.h"
34 
35 #include "BKE_context.h"
36 #include "BKE_customdata.h"
37 #include "BKE_mesh_iterators.h"
38 #include "BKE_mesh_runtime.h"
39 
40 #include "DEG_depsgraph.h"
41 #include "DEG_depsgraph_query.h"
42 
43 #include "ED_screen.h"
44 #include "ED_view3d.h"
45 
46 #include "paint_intern.h" /* own include */
47 
48 /* Opaque Structs for internal use */
49 
50 /* stored while painting */
53 
54  bool use_update;
55 
56  /* use for update */
57  float *dists_sq;
58 
61 };
62 
63 /* only for passing to the callbacks */
66 
67  /* runtime */
69  const float *mval_fl;
70 };
71 
72 /* -------------------------------------------------------------------- */
73 /* Internal Init */
74 
76  void *userData, int index, const float co[3], const float no_f[3], const short no_s[3])
77 {
78  struct VertProjHandle *vp_handle = userData;
79  CoNo *co_no = &vp_handle->vcosnos[index];
80 
81  /* check if we've been here before (normal should not be 0) */
82  if (!is_zero_v3(co_no->no)) {
83  /* remember that multiple dm verts share the same source vert */
84  vp_handle->use_update = true;
85  return;
86  }
87 
88  copy_v3_v3(co_no->co, co);
89  if (no_f) {
90  copy_v3_v3(co_no->no, no_f);
91  }
92  else {
93  normal_short_to_float_v3(co_no->no, no_s);
94  }
95 }
96 
98  Scene *UNUSED(scene),
99  Object *ob,
100  struct VertProjHandle *vp_handle)
101 {
102  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
104  Mesh *me = ob->data;
105 
107  Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks);
108 
109  memset(vp_handle->vcosnos, 0, sizeof(*vp_handle->vcosnos) * me->totvert);
112 }
113 
114 /* -------------------------------------------------------------------- */
115 /* Internal Update */
116 
117 /* Same as init but take mouse location into account */
118 
120  void *userData, int index, const float co[3], const float no_f[3], const short no_s[3])
121 {
122  struct VertProjUpdate *vp_update = userData;
123  struct VertProjHandle *vp_handle = vp_update->vp_handle;
124 
125  CoNo *co_no = &vp_handle->vcosnos[index];
126 
127  /* find closest vertex */
128  {
129  /* first find distance to this vertex */
130  float co_ss[2]; /* screenspace */
131 
133  vp_update->region, co, co_ss, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) ==
134  V3D_PROJ_RET_OK) {
135  const float dist_sq = len_squared_v2v2(vp_update->mval_fl, co_ss);
136  if (dist_sq > vp_handle->dists_sq[index]) {
137  /* bail out! */
138  return;
139  }
140 
141  vp_handle->dists_sq[index] = dist_sq;
142  }
143  else if (vp_handle->dists_sq[index] != FLT_MAX) {
144  /* already initialized & couldn't project this 'co' */
145  return;
146  }
147  }
148  /* continue with regular functionality */
149 
150  copy_v3_v3(co_no->co, co);
151  if (no_f) {
152  copy_v3_v3(co_no->no, no_f);
153  }
154  else {
155  normal_short_to_float_v3(co_no->no, no_s);
156  }
157 }
158 
160  struct VertProjHandle *vp_handle,
161  ARegion *region,
162  const float mval_fl[2])
163 {
164  struct VertProjUpdate vp_update = {vp_handle, region, mval_fl};
165 
166  Object *ob = vp_handle->ob;
167  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
168  Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
169  Mesh *me = ob->data;
170 
172  Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks);
173 
174  /* quick sanity check - we shouldn't have to run this if there are no modifiers */
176 
177  copy_vn_fl(vp_handle->dists_sq, me->totvert, FLT_MAX);
180 }
181 
182 /* -------------------------------------------------------------------- */
183 /* Public Functions */
184 
186  Scene *scene,
187  Object *ob,
188  CoNo **r_vcosnos)
189 {
190  struct VertProjHandle *vp_handle = MEM_mallocN(sizeof(struct VertProjHandle), __func__);
191  Mesh *me = ob->data;
192 
193  /* setup the handle */
194  vp_handle->vcosnos = MEM_mallocN(sizeof(CoNo) * me->totvert, "vertexcosnos map");
195  vp_handle->use_update = false;
196 
197  /* sets 'use_update' if needed */
199 
200  if (vp_handle->use_update) {
201  vp_handle->dists_sq = MEM_mallocN(sizeof(float) * me->totvert, __func__);
202 
203  vp_handle->ob = ob;
204  vp_handle->scene = scene;
205  }
206  else {
207  vp_handle->dists_sq = NULL;
208 
209  vp_handle->ob = NULL;
210  vp_handle->scene = NULL;
211  }
212 
213  *r_vcosnos = vp_handle->vcosnos;
214  return vp_handle;
215 }
216 
218  struct VertProjHandle *vp_handle,
219  ARegion *region,
220  const float mval_fl[2])
221 {
222  if (vp_handle->use_update) {
223  vpaint_proj_dm_map_cosnos_update(depsgraph, vp_handle, region, mval_fl);
224  }
225 }
226 
228 {
229  if (vp_handle->use_update) {
230  MEM_freeN(vp_handle->dists_sq);
231  }
232 
233  MEM_freeN(vp_handle->vcosnos);
234  MEM_freeN(vp_handle);
235 }
CustomData interface, see also DNA_customdata_types.h.
const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX
Definition: customdata.c:1926
@ MESH_FOREACH_USE_NORMAL
void BKE_mesh_foreach_mapped_vert(struct Mesh *mesh, void(*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]), void *userData, MeshForeachFlag flag)
struct Mesh * mesh_get_eval_final(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, const struct CustomData_MeshMasks *dataMask)
#define BLI_assert(a)
Definition: BLI_assert.h:58
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
void copy_vn_fl(float *array_tar, const int size, const float val)
Definition: math_vector.c:1410
MINLINE float len_squared_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void normal_short_to_float_v3(float r[3], const short n[3])
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
#define UNUSED(x)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
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:196
@ V3D_PROJ_TEST_CLIP_BB
Definition: ED_view3d.h:194
eV3DProjStatus ED_view3d_project_float_object(const struct ARegion *region, const float co[3], float r_co[2], const eV3DProjTest flag)
@ V3D_PROJ_RET_OK
Definition: ED_view3d.h:176
Read Guarded memory(de)allocation.
Scene scene
const Depsgraph * depsgraph
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
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_update(struct Depsgraph *depsgraph, struct VertProjHandle *vp_handle, ARegion *region, const float mval_fl[2])
static void vpaint_proj_dm_map_cosnos_update__map_cb(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3])
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_init__map_cb(void *userData, int index, const float co[3], const float no_f[3], const short no_s[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:51
float co[3]
Definition: paint_intern.h:50
int totvert
ListBase modifiers
void * data
struct VertProjHandle * vp_handle
const float * mval_fl