Blender V4.3
transform_convert_mesh_vert_cdata.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "BLI_math_matrix.h"
10#include "BLI_math_vector.h"
11
12#include "BKE_context.hh"
13#include "BKE_editmesh.hh"
14
15#include "DEG_depsgraph.hh"
16
17#include "transform.hh"
19
20#include "transform_convert.hh"
21
22/* -------------------------------------------------------------------- */
26static float *mesh_cdata_transdata_center(const TransIslandData *island_data,
27 const int island_index,
28 BMVert *eve)
29{
30 if (island_data->center && island_index != -1) {
31 return island_data->center[island_index];
32 }
33 return eve->co;
34}
35
37 BMVert *eve,
38 float *weight,
39 const TransIslandData *island_data,
40 const int island_index)
41{
43
44 td->val = weight;
45 td->ival = *weight;
46
48 td->flag |= TD_SELECTED;
49 }
50
51 copy_v3_v3(td->center, mesh_cdata_transdata_center(island_data, island_index, eve));
52 td->extra = eve;
53}
54
56{
59 BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
60 BMesh *bm = em->bm;
61 BMVert *eve;
62 BMIter iter;
63 float mtx[3][3], smtx[3][3];
64 int a;
65 const int prop_mode = (t->flag & T_PROP_EDIT) ? (t->flag & T_PROP_EDIT_ALL) : 0;
66
67 TransIslandData island_data = {nullptr};
68 TransMeshDataCrazySpace crazyspace_data = {nullptr};
69
70 /* Support other objects using proportional editing to adjust these, unless connected is
71 * enabled. */
72 if ((!prop_mode || (prop_mode & T_PROP_CONNECTED)) && (bm->totvertsel == 0)) {
73 continue;
74 }
75
76 int cd_offset = -1;
77 if (t->mode == TFM_BWEIGHT) {
78 if (!CustomData_has_layer_named(&bm->vdata, CD_PROP_FLOAT, "bevel_weight_vert")) {
79 BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_FLOAT, "bevel_weight_vert");
80 }
81 cd_offset = CustomData_get_offset_named(&bm->vdata, CD_PROP_FLOAT, "bevel_weight_vert");
82 }
83 else {
84 if (!CustomData_has_layer_named(&bm->vdata, CD_PROP_FLOAT, "crease_vert")) {
86 }
87 cd_offset = CustomData_get_offset_named(&bm->vdata, CD_PROP_FLOAT, "crease_vert");
88 }
89
90 if (cd_offset == -1) {
91 continue;
92 }
93
94 int data_len = 0;
95 if (prop_mode) {
96 BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
98 data_len++;
99 }
100 }
101 }
102 else {
103 data_len = bm->totvertsel;
104 }
105
106 if (data_len == 0) {
107 continue;
108 }
109
110 const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS);
111 if (is_island_center) {
112 /* In this specific case, near-by vertices will need to know
113 * the island of the nearest connected vertex. */
114 const bool calc_single_islands = ((prop_mode & T_PROP_CONNECTED) &&
117
118 const bool calc_island_center = false;
119 const bool calc_island_axismtx = false;
120
122 em, calc_single_islands, calc_island_center, calc_island_axismtx, &island_data);
123 }
124
125 copy_m3_m4(mtx, tc->obedit->object_to_world().ptr());
126 /* We use a pseudo-inverse so that when one of the axes is scaled to 0,
127 * matrix inversion still works and we can still moving along the other. */
129
130 /* Original index of our connected vertex when connected distances are calculated.
131 * Optional, allocate if needed. */
132 int *dists_index = nullptr;
133 float *dists = nullptr;
134 if (prop_mode & T_PROP_CONNECTED) {
135 dists = static_cast<float *>(MEM_mallocN(bm->totvert * sizeof(float), __func__));
136 if (is_island_center) {
137 dists_index = static_cast<int *>(MEM_mallocN(bm->totvert * sizeof(int), __func__));
138 }
139 transform_convert_mesh_connectivity_distance(em->bm, mtx, dists, dists_index);
140 }
141
142 /* Detect CrazySpace [tm]. */
143 transform_convert_mesh_crazyspace_detect(t, tc, em, &crazyspace_data);
144
145 /* Create TransData. */
146 BLI_assert(data_len >= 1);
147 tc->data_len = data_len;
148 tc->data = static_cast<TransData *>(
149 MEM_callocN(data_len * sizeof(TransData), "TransObData(Mesh EditMode)"));
150
151 TransData *td = tc->data;
152 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
154 continue;
155 }
156
157 int island_index = -1;
158 if (island_data.island_vert_map) {
159 const int connected_index = (dists_index && dists_index[a] != -1) ? dists_index[a] : a;
160 island_index = island_data.island_vert_map[connected_index];
161 }
162
163 float *weight = static_cast<float *>(BM_ELEM_CD_GET_VOID_P(eve, cd_offset));
164 if (prop_mode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
165 mesh_cdata_transdata_create((TransDataBasic *)td, eve, weight, &island_data, island_index);
166
168 createSpaceNormal(td->axismtx, eve->no);
169 }
170 else {
171 /* Setting normals. */
172 copy_v3_v3(td->axismtx[2], eve->no);
173 td->axismtx[0][0] = td->axismtx[0][1] = td->axismtx[0][2] = td->axismtx[1][0] =
174 td->axismtx[1][1] = td->axismtx[1][2] = 0.0f;
175 }
176
177 if (prop_mode) {
178 if (prop_mode & T_PROP_CONNECTED) {
179 td->dist = dists[a];
180 }
181 else {
182 td->dist = FLT_MAX;
183 }
184 }
185
186 /* CrazySpace. */
188 mtx,
189 smtx,
190 !crazyspace_data.defmats.is_empty() ? crazyspace_data.defmats[a].ptr() : nullptr,
191 crazyspace_data.quats && BM_elem_flag_test(eve, BM_ELEM_TAG) ?
192 crazyspace_data.quats[a] :
193 nullptr,
194 td);
195
196 td++;
197 }
198 }
199
202 if (dists) {
203 MEM_freeN(dists);
204 }
205 if (dists_index) {
206 MEM_freeN(dists_index);
207 }
208 }
209}
210
212/* -------------------------------------------------------------------- */
217{
219 DEG_id_tag_update(static_cast<ID *>(tc->obedit->data), ID_RECALC_GEOMETRY);
220 }
221}
222
226 /*flags*/ (T_EDIT | T_POINTS),
227 /*create_trans_data*/ createTransMeshVertCData,
228 /*recalc_data*/ recalcData_mesh_cdata,
229 /*special_aftertrans_update*/ nullptr,
230};
bool CustomData_has_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
BMEditMesh * BKE_editmesh_from_object(Object *ob)
Return the BMEditMesh for a given object.
Definition editmesh.cc:63
#define BLI_assert(a)
Definition BLI_assert.h:50
void pseudoinverse_m3_m3(float inverse[3][3], const float mat[3][3], float epsilon)
void copy_m3_m4(float m1[3][3], const float m2[4][4])
#define PSEUDOINVERSE_EPSILON
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define ELEM(...)
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
@ CD_PROP_FLOAT
@ SCE_SELECT_VERTEX
@ V3D_AROUND_LOCAL_ORIGINS
@ TFM_VERT_CREASE
@ TFM_BWEIGHT
@ BM_ELEM_HIDDEN
@ BM_ELEM_SELECT
@ BM_ELEM_TAG
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
#define BM_elem_flag_test(ele, hflag)
void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name)
#define BM_ITER_MESH(ele, iter, bm, itype)
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
@ BM_VERTS_OF_MESH
ATTR_WARN_UNUSED_RESULT BMesh * bm
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
#define FLT_MAX
Definition stdcycles.h:14
short selectmode
float co[3]
float no[3]
int totvert
CustomData vdata
int totvertsel
Definition DNA_ID.h:413
eTfmMode mode
Definition transform.hh:517
short around
Definition transform.hh:580
eTFlag flag
Definition transform.hh:523
blender::Array< blender::float3x3, 0 > defmats
@ T_PROP_CONNECTED
Definition transform.hh:99
@ T_PROP_EDIT
Definition transform.hh:98
@ T_POINTS
Definition transform.hh:93
@ T_EDIT
Definition transform.hh:91
#define T_PROP_EDIT_ALL
Definition transform.hh:157
#define FOREACH_TRANS_DATA_CONTAINER(t, th)
Definition transform.hh:854
conversion and adaptation of different datablocks to a common struct.
void transform_convert_mesh_crazyspace_transdata_set(const float mtx[3][3], const float smtx[3][3], const float defmat[3][3], const float quat[4], TransData *r_td)
void transform_convert_mesh_islands_calc(BMEditMesh *em, bool calc_single_islands, bool calc_island_center, bool calc_island_axismtx, TransIslandData *r_island_data)
void transform_convert_mesh_crazyspace_detect(TransInfo *t, TransDataContainer *tc, BMEditMesh *em, TransMeshDataCrazySpace *r_crazyspace_data)
void transform_convert_mesh_connectivity_distance(BMesh *bm, const float mtx[3][3], float *dists, int *index)
void transform_convert_mesh_islanddata_free(TransIslandData *island_data)
void transform_convert_mesh_crazyspace_free(TransMeshDataCrazySpace *r_crazyspace_data)
static void mesh_cdata_transdata_create(TransDataBasic *td, BMVert *eve, float *weight, const TransIslandData *island_data, const int island_index)
TransConvertTypeInfo TransConvertType_MeshVertCData
static float * mesh_cdata_transdata_center(const TransIslandData *island_data, const int island_index, BMVert *eve)
static void createTransMeshVertCData(bContext *, TransInfo *t)
static void recalcData_mesh_cdata(TransInfo *t)
@ TD_SELECTED
bool createSpaceNormal(float mat[3][3], const float normal[3])