Blender  V2.93
MOD_shrinkwrap.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) 2005 by the Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <string.h>
25 
26 #include "BLI_utildefines.h"
27 
28 #include "BLT_translation.h"
29 
30 #include "DNA_defaults.h"
31 #include "DNA_mesh_types.h"
32 #include "DNA_object_types.h"
33 #include "DNA_screen_types.h"
34 
35 #include "BKE_context.h"
36 #include "BKE_editmesh.h"
37 #include "BKE_lib_id.h"
38 #include "BKE_lib_query.h"
39 #include "BKE_mesh.h"
40 #include "BKE_mesh_wrapper.h"
41 #include "BKE_modifier.h"
42 #include "BKE_screen.h"
43 #include "BKE_shrinkwrap.h"
44 
45 #include "UI_interface.h"
46 #include "UI_resources.h"
47 
48 #include "RNA_access.h"
49 
50 #include "DEG_depsgraph_query.h"
51 
52 #include "MOD_ui_common.h"
53 #include "MOD_util.h"
54 
55 static bool dependsOnNormals(ModifierData *md);
56 
57 static void initData(ModifierData *md)
58 {
60 
62 
64 }
65 
66 static void requiredDataMask(Object *UNUSED(ob),
67  ModifierData *md,
68  CustomData_MeshMasks *r_cddata_masks)
69 {
71 
72  /* ask for vertexgroups if we need them */
73  if (smd->vgroup_name[0] != '\0') {
74  r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
75  }
76 
77  if ((smd->shrinkType == MOD_SHRINKWRAP_PROJECT) &&
79  /* XXX Really? These should always be present, always... */
80  r_cddata_masks->vmask |= CD_MASK_MVERT;
81  }
82 }
83 
84 static bool isDisabled(const struct Scene *UNUSED(scene),
85  ModifierData *md,
86  bool UNUSED(useRenderParams))
87 {
89 
90  /* The object type check is only needed here in case we have a placeholder
91  * object assigned (because the library containing the mesh is missing).
92  *
93  * In other cases it should be impossible to have a type mismatch.
94  */
95  if (!smd->target || smd->target->type != OB_MESH) {
96  return true;
97  }
98  if (smd->auxTarget && smd->auxTarget->type != OB_MESH) {
99  return true;
100  }
101  return false;
102 }
103 
104 static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
105 {
107 
108  walk(userData, ob, (ID **)&smd->target, IDWALK_CB_NOP);
109  walk(userData, ob, (ID **)&smd->auxTarget, IDWALK_CB_NOP);
110 }
111 
112 static void deformVerts(ModifierData *md,
113  const ModifierEvalContext *ctx,
114  Mesh *mesh,
115  float (*vertexCos)[3],
116  int numVerts)
117 {
120  Mesh *mesh_src = NULL;
121 
122  if (ELEM(ctx->object->type, OB_MESH, OB_LATTICE) ||
123  (swmd->shrinkType == MOD_SHRINKWRAP_PROJECT)) {
124  /* mesh_src is needed for vgroups, but also used as ShrinkwrapCalcData.vert when projecting.
125  * Avoid time-consuming mesh conversion for curves when not projecting. */
126  mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
127  }
128 
129  struct MDeformVert *dvert = NULL;
130  int defgrp_index = -1;
131  MOD_get_vgroup(ctx->object, mesh_src, swmd->vgroup_name, &dvert, &defgrp_index);
132 
134  swmd, ctx, scene, ctx->object, mesh_src, dvert, defgrp_index, vertexCos, numVerts);
135 
136  if (!ELEM(mesh_src, NULL, mesh)) {
137  BKE_id_free(NULL, mesh_src);
138  }
139 }
140 
141 static void deformVertsEM(ModifierData *md,
142  const ModifierEvalContext *ctx,
143  struct BMEditMesh *editData,
144  Mesh *mesh,
145  float (*vertexCos)[3],
146  int numVerts)
147 {
150  Mesh *mesh_src = NULL;
151 
152  if ((swmd->vgroup_name[0] != '\0') || (swmd->shrinkType == MOD_SHRINKWRAP_PROJECT)) {
153  mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
154  }
155 
156  /* TODO(Campbell): use edit-mode data only (remove this line). */
157  if (mesh_src != NULL) {
159  }
160 
161  struct MDeformVert *dvert = NULL;
162  int defgrp_index = -1;
163  if (swmd->vgroup_name[0] != '\0') {
164  MOD_get_vgroup(ctx->object, mesh_src, swmd->vgroup_name, &dvert, &defgrp_index);
165  }
166 
168  swmd, ctx, scene, ctx->object, mesh_src, dvert, defgrp_index, vertexCos, numVerts);
169 
170  if (!ELEM(mesh_src, NULL, mesh)) {
171  BKE_id_free(NULL, mesh_src);
172  }
173 }
174 
176 {
179 
181  mask.vmask |= CD_MASK_NORMAL;
183  }
184 
185  if (smd->target != NULL) {
186  DEG_add_object_relation(ctx->node, smd->target, DEG_OB_COMP_TRANSFORM, "Shrinkwrap Modifier");
187  DEG_add_object_relation(ctx->node, smd->target, DEG_OB_COMP_GEOMETRY, "Shrinkwrap Modifier");
188  DEG_add_customdata_mask(ctx->node, smd->target, &mask);
191  }
192  }
193  if (smd->auxTarget != NULL) {
195  ctx->node, smd->auxTarget, DEG_OB_COMP_TRANSFORM, "Shrinkwrap Modifier");
197  ctx->node, smd->auxTarget, DEG_OB_COMP_GEOMETRY, "Shrinkwrap Modifier");
201  }
202  }
203  DEG_add_modifier_to_transform_relation(ctx->node, "Shrinkwrap Modifier");
204 }
205 
207 {
209 
210  if (smd->target && smd->shrinkType == MOD_SHRINKWRAP_PROJECT) {
212  }
213 
214  return false;
215 }
216 
217 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
218 {
219  uiLayout *row, *col;
220  uiLayout *layout = panel->layout;
222 
223  PointerRNA ob_ptr;
225 
226  uiLayoutSetPropSep(layout, true);
227 
228  int wrap_method = RNA_enum_get(ptr, "wrap_method");
229 
230  uiItemR(layout, ptr, "wrap_method", 0, NULL, ICON_NONE);
231 
232  if (ELEM(wrap_method,
236  uiItemR(layout, ptr, "wrap_mode", 0, NULL, ICON_NONE);
237  }
238 
239  if (wrap_method == MOD_SHRINKWRAP_PROJECT) {
240  uiItemR(layout, ptr, "project_limit", 0, IFACE_("Limit"), ICON_NONE);
241  uiItemR(layout, ptr, "subsurf_levels", 0, NULL, ICON_NONE);
242 
243  col = uiLayoutColumn(layout, false);
244  row = uiLayoutRowWithHeading(col, true, IFACE_("Axis"));
245  uiItemR(row, ptr, "use_project_x", toggles_flag, NULL, ICON_NONE);
246  uiItemR(row, ptr, "use_project_y", toggles_flag, NULL, ICON_NONE);
247  uiItemR(row, ptr, "use_project_z", toggles_flag, NULL, ICON_NONE);
248 
249  uiItemR(col, ptr, "use_negative_direction", 0, NULL, ICON_NONE);
250  uiItemR(col, ptr, "use_positive_direction", 0, NULL, ICON_NONE);
251 
252  uiItemR(layout, ptr, "cull_face", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
253  col = uiLayoutColumn(layout, false);
255  RNA_boolean_get(ptr, "use_negative_direction") &&
256  RNA_enum_get(ptr, "cull_face") != 0);
257  uiItemR(col, ptr, "use_invert_cull", 0, NULL, ICON_NONE);
258  }
259 
260  uiItemR(layout, ptr, "target", 0, NULL, ICON_NONE);
261  if (wrap_method == MOD_SHRINKWRAP_PROJECT) {
262  uiItemR(layout, ptr, "auxiliary_target", 0, NULL, ICON_NONE);
263  }
264  uiItemR(layout, ptr, "offset", 0, NULL, ICON_NONE);
265 
266  modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
267 
268  modifier_panel_end(layout, ptr);
269 }
270 
271 static void panelRegister(ARegionType *region_type)
272 {
274 }
275 
277  /* name */ "Shrinkwrap",
278  /* structName */ "ShrinkwrapModifierData",
279  /* structSize */ sizeof(ShrinkwrapModifierData),
280  /* srna */ &RNA_ShrinkwrapModifier,
281  /* type */ eModifierTypeType_OnlyDeform,
285  /* icon */ ICON_MOD_SHRINKWRAP,
286 
287  /* copyData */ BKE_modifier_copydata_generic,
288 
289  /* deformVerts */ deformVerts,
290  /* deformMatrices */ NULL,
291  /* deformVertsEM */ deformVertsEM,
292  /* deformMatricesEM */ NULL,
293  /* modifyMesh */ NULL,
294  /* modifyHair */ NULL,
295  /* modifyGeometrySet */ NULL,
296  /* modifyVolume */ NULL,
297 
298  /* initData */ initData,
299  /* requiredDataMask */ requiredDataMask,
300  /* freeData */ NULL,
301  /* isDisabled */ isDisabled,
302  /* updateDepsgraph */ updateDepsgraph,
303  /* dependsOnTime */ NULL,
304  /* dependsOnNormals */ dependsOnNormals,
305  /* foreachIDLink */ foreachIDLink,
306  /* foreachTexLink */ NULL,
307  /* freeRuntimeData */ NULL,
308  /* panelRegister */ panelRegister,
309  /* blendWrite */ NULL,
310  /* blendRead */ NULL,
311 };
void BKE_id_free(struct Main *bmain, void *idv)
@ IDWALK_CB_NOP
Definition: BKE_lib_query.h:47
void BKE_mesh_wrapper_ensure_mdata(struct Mesh *me)
Definition: mesh_wrapper.c:98
void(* IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
Definition: BKE_modifier.h:120
@ eModifierTypeFlag_AcceptsCVs
Definition: BKE_modifier.h:81
@ eModifierTypeFlag_EnableInEditmode
Definition: BKE_modifier.h:92
@ eModifierTypeFlag_SupportsEditmode
Definition: BKE_modifier.h:83
@ eModifierTypeFlag_AcceptsVertexCosOnly
Definition: BKE_modifier.h:114
@ eModifierTypeFlag_AcceptsMesh
Definition: BKE_modifier.h:80
void BKE_modifier_copydata_generic(const struct ModifierData *md, struct ModifierData *md_dst, const int flag)
@ eModifierTypeType_OnlyDeform
Definition: BKE_modifier.h:58
void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, const struct ModifierEvalContext *ctx, struct Scene *scene, struct Object *ob, struct Mesh *mesh, struct MDeformVert *dvert, const int defgrp_index, float(*vertexCos)[3], int numVerts)
bool BKE_shrinkwrap_needs_normals(int shrinkType, int shrinkMode)
Definition: shrinkwrap.c:105
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define UNUSED(x)
#define ELEM(...)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define IFACE_(msgid)
@ DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY
Definition: DEG_depsgraph.h:73
void DEG_add_object_relation(struct DepsNodeHandle *node_handle, struct Object *object, eDepsObjectComponentType component, const char *description)
void DEG_add_modifier_to_transform_relation(struct DepsNodeHandle *node_handle, const char *description)
void DEG_add_customdata_mask(struct DepsNodeHandle *handle, struct Object *object, const struct CustomData_MeshMasks *masks)
@ DEG_OB_COMP_GEOMETRY
@ DEG_OB_COMP_TRANSFORM
void DEG_add_special_eval_flag(struct DepsNodeHandle *handle, struct ID *id, uint32_t flag)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
#define CD_MASK_NORMAL
#define CD_MASK_MDEFORMVERT
#define CD_MASK_CUSTOMLOOPNORMAL
#define CD_MASK_MVERT
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:44
@ MOD_SHRINKWRAP_PROJECT_OVER_NORMAL
@ MOD_SHRINKWRAP_TARGET_PROJECT
@ MOD_SHRINKWRAP_PROJECT
@ MOD_SHRINKWRAP_NEAREST_SURFACE
struct ShrinkwrapModifierData ShrinkwrapModifierData
@ eModifierType_Shrinkwrap
Object is a sort of wrapper for general info.
@ OB_LATTICE
@ OB_MESH
static void deformVertsEM(ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *editData, Mesh *mesh, float(*vertexCos)[3], int numVerts)
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
static bool isDisabled(const struct Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams))
static bool dependsOnNormals(ModifierData *md)
static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float(*vertexCos)[3], int numVerts)
ModifierTypeInfo modifierType_Shrinkwrap
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
static void initData(ModifierData *md)
static void panelRegister(ARegionType *region_type)
static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
void modifier_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const char *vgroup_prop, const char *invert_vgroup_prop, const char *text)
Mesh * MOD_deform_mesh_eval_get(Object *ob, struct BMEditMesh *em, Mesh *mesh, const float(*vertexCos)[3], const int num_verts, const bool use_normals, const bool use_orco)
Definition: MOD_util.c:186
void MOD_get_vgroup(Object *ob, struct Mesh *mesh, const char *name, MDeformVert **dvert, int *defgrp_index)
Definition: MOD_util.c:254
StructRNA RNA_ShrinkwrapModifier
#define C
Definition: RandGen.cpp:39
uiLayout * uiLayoutRowWithHeading(uiLayout *layout, bool align, const char *heading)
void uiLayoutSetActive(uiLayout *layout, bool active)
@ UI_ITEM_R_TOGGLE
@ UI_ITEM_R_FORCE_BLANK_DECORATE
@ UI_ITEM_R_EXPAND
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
Scene scene
uint col
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
Definition: DNA_ID.h:273
struct Depsgraph * depsgraph
Definition: BKE_modifier.h:153
struct Object * object
Definition: BKE_modifier.h:154
struct DepsNodeHandle * node
Definition: BKE_modifier.h:147
struct uiLayout * layout
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
PointerRNA * ptr
Definition: wm_files.c:3157