Mesh: Move bevel weight out of MVert and MEdge

As described in T95966, the goal is to move to a "struct of arrays"
approach rather than gathering an arbitrary set of data in hard-coded
structs. This has performance benefits, but also code complexity
benefits (this patch removes plenty of code, though the boilerplate
for the new operators outweighs that here).

To mirror the internal change, the options for storing mesh bevel
weights are converted into operators that add or remove the layer,
like for some other layers.

The most complex change is to the solidify modifier, where bevel
weights had special handling. Other than that, most changes are
removing clearing of the weights, boilerplate for the add/remove
operators, and removing the manual transfer of bevel weights
in bmesh - mesh conversion.

Eventually bevel weights can become a fully generic attribute,
but for now this patch aims to avoid most functional changes.

Bevel weights are still written and read from the mesh in the old way,
so neither forward nor backward compatibility are affected. As described
in T95965, writing in the old format will be done until 4.0.

Differential Revision: https://developer.blender.org/D14077
This commit is contained in:
Hans Goudey 2022-09-09 08:29:07 -05:00
parent 21f2bacad9
commit 291c313f80
Notes: blender-bot 2023-02-13 22:37:44 +01:00
Referenced by commit 8ee020d11f, Fix T103195: Initialize face sets from bevel weights broken
Referenced by issue #103011, Regression: Boolean modifier create uncorrect weight attribute for bevel modifier
Referenced by issue #101471, Regression: Crash in Solidify Modifier with complex flat boundary mode
Referenced by issue #101118, Regression: Crash in Solidify modifier when adjusting Bevel Convex slider
Referenced by issue #95966, Struct of Arrays Refactor for Mesh Edges
Referenced by issue #93602, Struct of Arrays Refactor for Mesh Vertices
31 changed files with 390 additions and 253 deletions

View File

@ -493,11 +493,19 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel):
else:
col.operator("mesh.customdata_custom_splitnormals_add", icon='ADD')
if me.has_bevel_weight_edge:
col.operator("mesh.customdata_bevel_weight_edge_clear", icon='X')
else:
col.operator("mesh.customdata_bevel_weight_edge_add", icon='ADD')
if me.has_bevel_weight_vertex:
col.operator("mesh.customdata_bevel_weight_vertex_clear", icon='X')
else:
col.operator("mesh.customdata_bevel_weight_vertex_add", icon='ADD')
col = layout.column(heading="Store")
col.enabled = obj is not None and obj.mode != 'EDIT'
col.prop(me, "use_customdata_vertex_bevel", text="Vertex Bevel Weight")
col.prop(me, "use_customdata_edge_bevel", text="Edge Bevel Weight")
col.prop(me, "use_customdata_vertex_crease", text="Vertex Crease")
col.prop(me, "use_customdata_edge_crease", text="Edge Crease")

View File

@ -640,7 +640,6 @@ enum {
CD_FAKE_CREASE = CD_FAKE | CD_CREASE, /* *sigh*. */
/* Multiple types of mesh elements... */
CD_FAKE_BWEIGHT = CD_FAKE | CD_BWEIGHT, /* *sigh*. */
CD_FAKE_UV = CD_FAKE |
CD_MLOOPUV, /* UV flag, because we handle both loop's UVs and poly's textures. */

View File

@ -17,6 +17,15 @@ struct CustomData;
struct Mesh;
struct MFace;
/**
* Copy bevel weights from separate layers into vertices and edges.
*/
void BKE_mesh_legacy_bevel_weight_from_layers(struct Mesh *mesh);
/**
* Copy bevel weights from vertices and edges to separate layers.
*/
void BKE_mesh_legacy_bevel_weight_to_layers(struct Mesh *mesh);
/**
* Convert the hidden element attributes to the old flag format for writing.
*/

View File

@ -1867,7 +1867,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* 28: CD_SHAPEKEY */
{sizeof(float[3]), "", 0, N_("ShapeKey"), nullptr, nullptr, layerInterp_shapekey},
/* 29: CD_BWEIGHT */
{sizeof(float), "", 0, N_("BevelWeight"), nullptr, nullptr, layerInterp_bweight},
{sizeof(MFloatProperty), "MFloatProperty", 1, nullptr, nullptr, nullptr, layerInterp_bweight},
/* 30: CD_CREASE */
/* NOTE: we do not interpolate crease data as it should be either inherited for subdivided
* edges, or for vertex creases, only present on the original vertex. */
@ -2108,23 +2108,23 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
};
const CustomData_MeshMasks CD_MASK_BAREMESH = {
/* vmask */ CD_MASK_MVERT | CD_MASK_BWEIGHT,
/* emask */ CD_MASK_MEDGE | CD_MASK_BWEIGHT,
/* vmask */ CD_MASK_MVERT,
/* emask */ CD_MASK_MEDGE,
/* fmask */ 0,
/* pmask */ CD_MASK_MPOLY | CD_MASK_FACEMAP,
/* lmask */ CD_MASK_MLOOP,
};
const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX = {
/* vmask */ CD_MASK_MVERT | CD_MASK_BWEIGHT | CD_MASK_ORIGINDEX,
/* emask */ CD_MASK_MEDGE | CD_MASK_BWEIGHT | CD_MASK_ORIGINDEX,
/* vmask */ CD_MASK_MVERT | CD_MASK_ORIGINDEX,
/* emask */ CD_MASK_MEDGE | CD_MASK_ORIGINDEX,
/* fmask */ 0,
/* pmask */ CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_ORIGINDEX,
/* lmask */ CD_MASK_MLOOP,
};
const CustomData_MeshMasks CD_MASK_MESH = {
/* vmask */ (CD_MASK_MVERT | CD_MASK_MDEFORMVERT | CD_MASK_MVERT_SKIN | CD_MASK_PAINT_MASK |
CD_MASK_PROP_ALL | CD_MASK_CREASE),
/* emask */ (CD_MASK_MEDGE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL),
CD_MASK_PROP_ALL | CD_MASK_CREASE | CD_MASK_BWEIGHT),
/* emask */ (CD_MASK_MEDGE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL | CD_MASK_BWEIGHT),
/* fmask */ 0,
/* pmask */
(CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL |
@ -2136,8 +2136,8 @@ const CustomData_MeshMasks CD_MASK_MESH = {
const CustomData_MeshMasks CD_MASK_DERIVEDMESH = {
/* vmask */ (CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | CD_MASK_SHAPEKEY | CD_MASK_MVERT_SKIN |
CD_MASK_PAINT_MASK | CD_MASK_ORCO | CD_MASK_CLOTH_ORCO | CD_MASK_PROP_ALL |
CD_MASK_CREASE),
/* emask */ (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL),
CD_MASK_CREASE | CD_MASK_BWEIGHT),
/* emask */ (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_BWEIGHT | CD_MASK_PROP_ALL),
/* fmask */ (CD_MASK_ORIGINDEX | CD_MASK_ORIGSPACE | CD_MASK_PREVIEW_MCOL | CD_MASK_TANGENT),
/* pmask */
(CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL |
@ -5175,7 +5175,7 @@ void CustomData_data_transfer(const MeshPairRemap *me_remap,
else {
const LayerTypeInfo *type_info = layerType_getInfo(data_type);
/* NOTE: we can use 'fake' CDLayers, like e.g. for crease, bweight, etc. :/. */
/* NOTE: we can use 'fake' CDLayers for crease :/. */
data_size = (size_t)type_info->size;
data_step = laymap->elem_size ? laymap->elem_size : data_size;
data_offset = laymap->data_offset;

View File

@ -192,7 +192,7 @@ int BKE_object_data_transfer_dttype_to_cdtype(const int dtdata_type)
case DT_TYPE_SKIN:
return CD_MVERT_SKIN;
case DT_TYPE_BWEIGHT_VERT:
return CD_FAKE_BWEIGHT;
return CD_BWEIGHT;
case DT_TYPE_SHARP_EDGE:
return CD_FAKE_SHARP;
@ -201,7 +201,7 @@ int BKE_object_data_transfer_dttype_to_cdtype(const int dtdata_type)
case DT_TYPE_CREASE:
return CD_FAKE_CREASE;
case DT_TYPE_BWEIGHT_EDGE:
return CD_FAKE_BWEIGHT;
return CD_BWEIGHT;
case DT_TYPE_FREESTYLE_EDGE:
return CD_FREESTYLE_EDGE;
@ -928,38 +928,6 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
}
return true;
}
if (cddata_type == CD_FAKE_BWEIGHT) {
const size_t elem_size = sizeof(*((MVert *)NULL));
const size_t data_size = sizeof(((MVert *)NULL)->bweight);
const size_t data_offset = offsetof(MVert, bweight);
const uint64_t data_flag = 0;
if (!(me_src->cd_flag & ME_CDFLAG_VERT_BWEIGHT)) {
if (use_delete) {
me_dst->cd_flag &= ~ME_CDFLAG_VERT_BWEIGHT;
}
return true;
}
me_dst->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
if (r_map) {
data_transfer_layersmapping_add_item(r_map,
cddata_type,
mix_mode,
mix_factor,
mix_weights,
BKE_mesh_verts(me_src),
BKE_mesh_verts_for_write(me_dst),
me_src->totvert,
me_dst->totvert,
elem_size,
data_size,
data_offset,
data_flag,
data_transfer_interp_char,
interp_data);
}
return true;
}
if (cddata_type == CD_FAKE_MDEFORMVERT) {
bool ret;
@ -1045,38 +1013,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
}
return true;
}
if (cddata_type == CD_FAKE_BWEIGHT) {
const size_t elem_size = sizeof(*((MEdge *)NULL));
const size_t data_size = sizeof(((MEdge *)NULL)->bweight);
const size_t data_offset = offsetof(MEdge, bweight);
const uint64_t data_flag = 0;
if (!(me_src->cd_flag & ME_CDFLAG_EDGE_BWEIGHT)) {
if (use_delete) {
me_dst->cd_flag &= ~ME_CDFLAG_EDGE_BWEIGHT;
}
return true;
}
me_dst->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
if (r_map) {
data_transfer_layersmapping_add_item(r_map,
cddata_type,
mix_mode,
mix_factor,
mix_weights,
BKE_mesh_edges(me_src),
BKE_mesh_edges_for_write(me_dst),
me_src->totedge,
me_dst->totedge,
elem_size,
data_size,
data_offset,
data_flag,
data_transfer_interp_char,
interp_data);
}
return true;
}
if (r_map && ELEM(cddata_type, CD_FAKE_SHARP, CD_FAKE_SEAM)) {
const size_t elem_size = sizeof(*((MEdge *)NULL));
const size_t data_size = sizeof(((MEdge *)NULL)->flag);

View File

@ -1447,7 +1447,6 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
MVert *mvert = CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CONSTRUCT, NULL, mesh->totvert);
for (int i = 0; i < mesh->totvert; i++) {
copy_v3_v3(mvert[i].co, process.co[i]);
mvert->bweight = 0;
mvert->flag = 0;
}
MEM_freeN(process.co);

View File

@ -251,6 +251,7 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
if (!BLO_write_is_undo(writer)) {
BKE_mesh_legacy_convert_hide_layers_to_flags(mesh);
BKE_mesh_legacy_convert_material_indices_to_mpoly(mesh);
BKE_mesh_legacy_bevel_weight_from_layers(mesh);
/* When converting to the old mesh format, don't save redundant attributes. */
names_to_skip.add_multiple_new({".hide_vert", ".hide_edge", ".hide_poly"});
@ -348,6 +349,7 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
if (!BLO_read_data_is_undo(reader)) {
BKE_mesh_legacy_convert_flags_to_hide_layers(mesh);
BKE_mesh_legacy_convert_mpoly_to_material_indices(mesh);
BKE_mesh_legacy_bevel_weight_to_layers(mesh);
}
/* We don't expect to load normals from files, since they are derived data. */

View File

@ -381,7 +381,6 @@ static void copy_vert_attributes(Mesh *dest_mesh,
int mv_index,
int index_in_orig_me)
{
mv->bweight = orig_mv->bweight;
mv->flag = orig_mv->flag;
/* For all layers in the orig mesh, copy the layer information. */
@ -450,7 +449,6 @@ static void copy_edge_attributes(Mesh *dest_mesh,
int medge_index,
int index_in_orig_me)
{
medge->bweight = orig_medge->bweight;
medge->crease = orig_medge->crease;
medge->flag = orig_medge->flag;
CustomData *target_cd = &dest_mesh->edata;

View File

@ -118,7 +118,7 @@ static void make_edges_mdata_extend(Mesh &mesh)
BLI_edgehashIterator_getKey(ehi, &medge->v1, &medge->v2);
BLI_edgehashIterator_setValue(ehi, POINTER_FROM_UINT(e_index));
medge->crease = medge->bweight = 0;
medge->crease = 0;
medge->flag = ME_EDGEDRAW | ME_EDGERENDER;
}
BLI_edgehashIterator_free(ehi);

View File

@ -30,12 +30,6 @@
static void mesh_debug_info_from_cd_flag(const Mesh *me, DynStr *dynstr)
{
BLI_dynstr_append(dynstr, "'cd_flag': {");
if (me->cd_flag & ME_CDFLAG_VERT_BWEIGHT) {
BLI_dynstr_append(dynstr, "'VERT_BWEIGHT', ");
}
if (me->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
BLI_dynstr_append(dynstr, "'EDGE_BWEIGHT', ");
}
if (me->cd_flag & ME_CDFLAG_EDGE_CREASE) {
BLI_dynstr_append(dynstr, "'EDGE_CREASE', ");
}

View File

@ -917,6 +917,67 @@ void BKE_mesh_add_mface_layers(CustomData *fdata, CustomData *ldata, int total)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Bevel Weight Conversion
* \{ */
void BKE_mesh_legacy_bevel_weight_from_layers(Mesh *mesh)
{
using namespace blender;
MutableSpan<MVert> verts = mesh->verts_for_write();
if (const float *weights = static_cast<const float *>(
CustomData_get_layer(&mesh->vdata, CD_BWEIGHT))) {
mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
for (const int i : verts.index_range()) {
verts[i].bweight = std::clamp(weights[i], 0.0f, 1.0f) * 255.0f;
}
}
else {
mesh->cd_flag &= ~ME_CDFLAG_VERT_BWEIGHT;
for (const int i : verts.index_range()) {
verts[i].bweight = 0;
}
}
MutableSpan<MEdge> edges = mesh->edges_for_write();
if (const float *weights = static_cast<const float *>(
CustomData_get_layer(&mesh->edata, CD_BWEIGHT))) {
mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
for (const int i : edges.index_range()) {
edges[i].bweight = std::clamp(weights[i], 0.0f, 1.0f) * 255.0f;
}
}
else {
mesh->cd_flag &= ~ME_CDFLAG_EDGE_BWEIGHT;
for (const int i : edges.index_range()) {
edges[i].bweight = 0;
}
}
}
void BKE_mesh_legacy_bevel_weight_to_layers(Mesh *mesh)
{
using namespace blender;
const Span<MVert> verts = mesh->verts();
if (mesh->cd_flag & ME_CDFLAG_VERT_BWEIGHT) {
float *weights = static_cast<float *>(
CustomData_add_layer(&mesh->vdata, CD_BWEIGHT, CD_CONSTRUCT, nullptr, verts.size()));
for (const int i : verts.index_range()) {
weights[i] = verts[i].bweight / 255.0f;
}
}
const Span<MEdge> edges = mesh->edges();
if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
float *weights = static_cast<float *>(
CustomData_add_layer(&mesh->edata, CD_BWEIGHT, CD_CONSTRUCT, nullptr, edges.size()));
for (const int i : edges.index_range()) {
weights[i] = edges[i].bweight / 255.0f;
}
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Hide Attribute and Legacy Flag Conversion
* \{ */

View File

@ -791,7 +791,6 @@ static void subdiv_copy_edge_data(SubdivMeshContext *ctx,
const int subdiv_edge_index = subdiv_edge - ctx->subdiv_edges;
if (coarse_edge == nullptr) {
subdiv_edge->crease = 0;
subdiv_edge->bweight = 0;
subdiv_edge->flag = 0;
if (!ctx->settings->use_optimal_display) {
subdiv_edge->flag |= ME_EDGERENDER;
@ -1138,9 +1137,6 @@ static void subdiv_mesh_vertex_of_loose_edge(const SubdivForeachContext *foreach
subdiv_vertex->co);
/* Reset flags and such. */
subdiv_vertex->flag = 0;
/* TODO(sergey): This matches old behavior, but we can as well interpolate
* it. Maybe even using vertex varying attributes. */
subdiv_vertex->bweight = 0.0f;
}
/** \} */

View File

@ -879,7 +879,7 @@ static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float r_no[3])
BLI_INLINE void ccgDM_to_MVert(MVert *mv, const CCGKey *key, CCGElem *elem)
{
copy_v3_v3(mv->co, CCG_elem_co(key, elem));
mv->flag = mv->bweight = 0;
mv->flag = 0;
}
static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
@ -949,7 +949,7 @@ BLI_INLINE void ccgDM_to_MEdge(MEdge *med, const int v1, const int v2, const sho
{
med->v1 = v1;
med->v2 = v2;
med->crease = med->bweight = 0;
med->crease = 0;
med->flag = flag;
}

View File

@ -126,17 +126,6 @@ void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag)
BLI_assert(bm->edata.totlayer == 0 || bm->edata.pool != nullptr);
BLI_assert(bm->pdata.totlayer == 0 || bm->pdata.pool != nullptr);
if (cd_flag & ME_CDFLAG_VERT_BWEIGHT) {
if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT);
}
}
else {
if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
BM_data_layer_free(bm, &bm->vdata, CD_BWEIGHT);
}
}
if (cd_flag & ME_CDFLAG_VERT_CREASE) {
if (!CustomData_has_layer(&bm->vdata, CD_CREASE)) {
BM_data_layer_add(bm, &bm->vdata, CD_CREASE);
@ -148,17 +137,6 @@ void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag)
}
}
if (cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT);
}
}
else {
if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
BM_data_layer_free(bm, &bm->edata, CD_BWEIGHT);
}
}
if (cd_flag & ME_CDFLAG_EDGE_CREASE) {
if (!CustomData_has_layer(&bm->edata, CD_CREASE)) {
BM_data_layer_add(bm, &bm->edata, CD_CREASE);
@ -174,15 +152,9 @@ void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag)
char BM_mesh_cd_flag_from_bmesh(BMesh *bm)
{
char cd_flag = 0;
if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
}
if (CustomData_has_layer(&bm->vdata, CD_CREASE)) {
cd_flag |= ME_CDFLAG_VERT_CREASE;
}
if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
}
if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
cd_flag |= ME_CDFLAG_EDGE_CREASE;
}
@ -342,12 +314,6 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
/* Only copy these values over if the source mesh is flagged to be using them.
* Even if `bm` has these layers, they may have been added from another mesh, when `!is_new`. */
const int cd_vert_bweight_offset = (me->cd_flag & ME_CDFLAG_VERT_BWEIGHT) ?
CustomData_get_offset(&bm->vdata, CD_BWEIGHT) :
-1;
const int cd_edge_bweight_offset = (me->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) ?
CustomData_get_offset(&bm->edata, CD_BWEIGHT) :
-1;
const int cd_edge_crease_offset = (me->cd_flag & ME_CDFLAG_EDGE_CREASE) ?
CustomData_get_offset(&bm->edata, CD_CREASE) :
-1;
@ -391,10 +357,6 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
/* Copy Custom Data */
CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data, true);
if (cd_vert_bweight_offset != -1) {
BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mvert[i].bweight / 255.0f);
}
/* Set shape key original index. */
if (cd_shape_keyindex_offset != -1) {
BM_ELEM_CD_SET_INT(v, cd_shape_keyindex_offset, i);
@ -433,9 +395,6 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
/* Copy Custom Data */
CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data, true);
if (cd_edge_bweight_offset != -1) {
BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)medge[i].bweight / 255.0f);
}
if (cd_edge_crease_offset != -1) {
BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)medge[i].crease / 255.0f);
}
@ -990,8 +949,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
BMIter iter;
int i, j;
const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
const int cd_shape_keyindex_offset = CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX);
@ -1073,10 +1030,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
/* Copy over custom-data. */
CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i);
if (cd_vert_bweight_offset != -1) {
mvert[i].bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(v, cd_vert_bweight_offset);
}
i++;
BM_CHECK_ELEMENT(v);
@ -1103,9 +1056,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
if (cd_edge_crease_offset != -1) {
medge[i].crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_crease_offset);
}
if (cd_edge_bweight_offset != -1) {
medge[i].bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_bweight_offset);
}
i++;
BM_CHECK_ELEMENT(e);
@ -1312,8 +1262,6 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
MLoop *mloop = loops.data();
unsigned int i, j;
const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
bool need_hide_vert = false;
@ -1339,14 +1287,6 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
need_hide_vert = true;
}
if (cd_vert_bweight_offset != -1) {
mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset);
}
if (cd_vert_bweight_offset != -1) {
mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset);
}
CustomData_from_bmesh_block(&bm->vdata, &me->vdata, eve->head.data, i);
}
bm->elem_index_dirty &= ~BM_VERT;
@ -1375,9 +1315,6 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
if (cd_edge_crease_offset != -1) {
med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset);
}
if (cd_edge_bweight_offset != -1) {
med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset);
}
CustomData_from_bmesh_block(&bm->edata, &me->edata, eed->head.data, i);
}

View File

@ -21,6 +21,7 @@
#include "BLI_math.h"
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_layer.h"
#include "BKE_report.h"
@ -348,7 +349,9 @@ static void edgetag_ensure_cd_flag(Mesh *me, const char edge_mode)
BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_CREASE);
break;
case EDGE_MODE_TAG_BEVEL:
BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_BWEIGHT);
if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT);
}
break;
#ifdef WITH_FREESTYLE
case EDGE_MODE_TAG_FREESTYLE:

View File

@ -626,6 +626,28 @@ static int mesh_customdata_clear_exec__internal(bContext *C, char htype, int typ
return OPERATOR_CANCELLED;
}
static int mesh_customdata_add_exec__internal(bContext *C, char htype, int type)
{
Mesh *mesh = ED_mesh_context(C);
int tot;
CustomData *data = mesh_customdata_get_type(mesh, htype, &tot);
BLI_assert(CustomData_layertype_is_singleton(type) == true);
if (mesh->edit_mesh) {
BM_data_layer_add(mesh->edit_mesh->bm, data, type);
}
else {
CustomData_add_layer(data, type, CD_SET_DEFAULT, NULL, tot);
}
DEG_id_tag_update(&mesh->id, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, mesh);
return CustomData_has_layer(data, type) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
/* Clear Mask */
static bool mesh_customdata_mask_clear_poll(bContext *C)
{
@ -848,6 +870,126 @@ void MESH_OT_customdata_custom_splitnormals_clear(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* Vertex bevel weight. */
static int mesh_customdata_bevel_weight_vertex_state(bContext *C)
{
const Object *object = ED_object_context(C);
if (object && object->type == OB_MESH) {
const Mesh *mesh = static_cast<Mesh *>(object->data);
if (!ID_IS_LINKED(mesh)) {
const CustomData *data = GET_CD_DATA(mesh, vdata);
return CustomData_has_layer(data, CD_BWEIGHT);
}
}
return -1;
}
static bool mesh_customdata_bevel_weight_vertex_add_poll(bContext *C)
{
return mesh_customdata_bevel_weight_vertex_state(C) == 0;
}
static int mesh_customdata_bevel_weight_vertex_add_exec(bContext *C, wmOperator *UNUSED(op))
{
return mesh_customdata_add_exec__internal(C, BM_VERT, CD_BWEIGHT);
}
void MESH_OT_customdata_bevel_weight_vertex_add(wmOperatorType *ot)
{
ot->name = "Add Vertex Bevel Weight";
ot->idname = "MESH_OT_customdata_bevel_weight_vertex_add";
ot->description = "Add a vertex bevel weight layer";
ot->exec = mesh_customdata_bevel_weight_vertex_add_exec;
ot->poll = mesh_customdata_bevel_weight_vertex_add_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static bool mesh_customdata_bevel_weight_vertex_clear_poll(bContext *C)
{
return (mesh_customdata_bevel_weight_vertex_state(C) == 1);
}
static int mesh_customdata_bevel_weight_vertex_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
return mesh_customdata_clear_exec__internal(C, BM_VERT, CD_BWEIGHT);
}
void MESH_OT_customdata_bevel_weight_vertex_clear(wmOperatorType *ot)
{
ot->name = "Clear Vertex Bevel Weight";
ot->idname = "MESH_OT_customdata_bevel_weight_vertex_clear";
ot->description = "Clear the vertex bevel weight layer";
ot->exec = mesh_customdata_bevel_weight_vertex_clear_exec;
ot->poll = mesh_customdata_bevel_weight_vertex_clear_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* Edge bevel weight. */
static int mesh_customdata_bevel_weight_edge_state(bContext *C)
{
const Object *ob = ED_object_context(C);
if (ob && ob->type == OB_MESH) {
const Mesh *mesh = static_cast<Mesh *>(ob->data);
if (!ID_IS_LINKED(mesh)) {
const CustomData *data = GET_CD_DATA(mesh, edata);
return CustomData_has_layer(data, CD_BWEIGHT);
}
}
return -1;
}
static bool mesh_customdata_bevel_weight_edge_add_poll(bContext *C)
{
return mesh_customdata_bevel_weight_edge_state(C) == 0;
}
static int mesh_customdata_bevel_weight_edge_add_exec(bContext *C, wmOperator *UNUSED(op))
{
return mesh_customdata_add_exec__internal(C, BM_EDGE, CD_BWEIGHT);
}
void MESH_OT_customdata_bevel_weight_edge_add(wmOperatorType *ot)
{
ot->name = "Add Edge Bevel Weight";
ot->idname = "MESH_OT_customdata_bevel_weight_edge_add";
ot->description = "Add an edge bevel weight layer";
ot->exec = mesh_customdata_bevel_weight_edge_add_exec;
ot->poll = mesh_customdata_bevel_weight_edge_add_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static bool mesh_customdata_bevel_weight_edge_clear_poll(bContext *C)
{
return mesh_customdata_bevel_weight_edge_state(C) == 1;
}
static int mesh_customdata_bevel_weight_edge_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
return mesh_customdata_clear_exec__internal(C, BM_EDGE, CD_BWEIGHT);
}
void MESH_OT_customdata_bevel_weight_edge_clear(wmOperatorType *ot)
{
ot->name = "Clear Edge Bevel Weight";
ot->idname = "MESH_OT_customdata_bevel_weight_edge_clear";
ot->description = "Clear the edge bevel weight layer";
ot->exec = mesh_customdata_bevel_weight_edge_clear_exec;
ot->poll = mesh_customdata_bevel_weight_edge_clear_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/************************** Add Geometry Layers *************************/
void ED_mesh_update(Mesh *mesh, bContext *C, bool calc_edges, bool calc_edges_loose)

View File

@ -313,6 +313,10 @@ void MESH_OT_customdata_skin_add(struct wmOperatorType *ot);
void MESH_OT_customdata_skin_clear(struct wmOperatorType *ot);
void MESH_OT_customdata_custom_splitnormals_add(struct wmOperatorType *ot);
void MESH_OT_customdata_custom_splitnormals_clear(struct wmOperatorType *ot);
void MESH_OT_customdata_bevel_weight_vertex_add(struct wmOperatorType *ot);
void MESH_OT_customdata_bevel_weight_vertex_clear(struct wmOperatorType *ot);
void MESH_OT_customdata_bevel_weight_edge_add(struct wmOperatorType *ot);
void MESH_OT_customdata_bevel_weight_edge_clear(struct wmOperatorType *ot);
#ifdef __cplusplus
}

View File

@ -139,6 +139,10 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_customdata_skin_clear);
WM_operatortype_append(MESH_OT_customdata_custom_splitnormals_add);
WM_operatortype_append(MESH_OT_customdata_custom_splitnormals_clear);
WM_operatortype_append(MESH_OT_customdata_bevel_weight_vertex_add);
WM_operatortype_append(MESH_OT_customdata_bevel_weight_vertex_clear);
WM_operatortype_append(MESH_OT_customdata_bevel_weight_edge_add);
WM_operatortype_append(MESH_OT_customdata_bevel_weight_edge_clear);
WM_operatortype_append(MESH_OT_edgering_select);
WM_operatortype_append(MESH_OT_loopcut);

View File

@ -995,7 +995,9 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
if (apply_vcos || median->bv_weight || median->v_crease || median->skin[0] ||
median->skin[1]) {
if (median->bv_weight) {
BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_VERT_BWEIGHT);
if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT);
}
cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
BLI_assert(cd_vert_bweight_offset != -1);
@ -1061,7 +1063,9 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
if (median->be_weight || median->e_crease) {
if (median->be_weight) {
BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_BWEIGHT);
if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT);
}
cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
BLI_assert(cd_edge_bweight_offset != -1);

View File

@ -67,7 +67,9 @@ static void createTransEdge(bContext *UNUSED(C), TransInfo *t)
/* create data we need */
if (t->mode == TFM_BWEIGHT) {
BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_BWEIGHT);
if (!CustomData_has_layer(&em->bm->edata, CD_BWEIGHT)) {
BM_data_layer_add(em->bm, &em->bm->edata, CD_BWEIGHT);
}
cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT);
}
else { /* if (t->mode == TFM_EDGE_CREASE) { */

View File

@ -84,7 +84,9 @@ static void createTransMeshVertCData(bContext *UNUSED(C), TransInfo *t)
int cd_offset = -1;
if (t->mode == TFM_BWEIGHT) {
BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_VERT_BWEIGHT);
if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT);
}
cd_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
}
else {

View File

@ -1233,7 +1233,6 @@ static void customdata_weld(
float no[3] = {0.0f, 0.0f, 0.0f};
#endif
int crease = 0;
int bweight = 0;
short flag = 0;
/* interpolates a layer at a time */
@ -1267,7 +1266,6 @@ static void customdata_weld(
no[1] += mv_src_no[1];
no[2] += mv_src_no[2];
#endif
bweight += mv_src->bweight;
flag |= mv_src->flag;
}
}
@ -1275,7 +1273,6 @@ static void customdata_weld(
for (j = 0; j < count; j++) {
MEdge *me_src = &((MEdge *)src_data)[src_indices[j]];
crease += me_src->crease;
bweight += me_src->bweight;
flag |= me_src->flag;
}
}
@ -1312,8 +1309,6 @@ static void customdata_weld(
if (type == CD_MVERT) {
MVert *mv = &((MVert *)layer_dst->data)[dest_index];
mul_v3_fl(co, fac);
bweight *= fac;
CLAMP_MAX(bweight, 255);
copy_v3_v3(mv->co, co);
#ifdef USE_WELD_NORMALS
@ -1325,17 +1320,13 @@ static void customdata_weld(
#endif
mv->flag = (char)flag;
mv->bweight = (char)bweight;
}
else if (type == CD_MEDGE) {
MEdge *me = &((MEdge *)layer_dst->data)[dest_index];
crease *= fac;
bweight *= fac;
CLAMP_MAX(crease, 255);
CLAMP_MAX(bweight, 255);
me->crease = (char)crease;
me->bweight = (char)bweight;
me->flag = flag;
}
else if (CustomData_layer_has_interp(dest, dest_i)) {

View File

@ -135,8 +135,6 @@ static void read_mverts_interp(MVert *mverts,
interp_v3_v3v3(tmp, floor_pos.getValue(), ceil_pos.getValue(), static_cast<float>(weight));
copy_zup_from_yup(mvert.co, tmp);
mvert.bweight = 0;
}
}
@ -163,8 +161,6 @@ void read_mverts(Mesh &mesh, const P3fArraySamplePtr positions, const N3fArraySa
Imath::V3f pos_in = (*positions)[i];
copy_zup_from_yup(mvert.co, pos_in.getValue());
mvert.bweight = 0;
}
if (normals) {
float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(&mesh);

View File

@ -587,7 +587,6 @@ void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me)
unsigned int *indices = mp->getPositionIndices().getData();
for (int j = 0; j < edge_count; j++, med++) {
med->bweight = 0;
med->crease = 0;
med->flag |= ME_LOOSEEDGE;
med->v1 = indices[2 * j];

View File

@ -440,8 +440,10 @@ enum {
/** #Mesh.cd_flag */
enum {
#ifdef DNA_DEPRECATED_ALLOW
ME_CDFLAG_VERT_BWEIGHT = 1 << 0,
ME_CDFLAG_EDGE_BWEIGHT = 1 << 1,
#endif
ME_CDFLAG_EDGE_CREASE = 1 << 2,
ME_CDFLAG_VERT_CREASE = 1 << 3,
};

View File

@ -25,7 +25,11 @@ extern "C" {
*/
typedef struct MVert {
float co[3];
char flag, bweight;
char flag;
/**
* Deprecated bevel weight storage, now located in #CD_BWEIGHT, except for file read and write.
*/
char bweight DNA_DEPRECATED;
char _pad[2];
} MVert;
@ -47,7 +51,11 @@ enum {
typedef struct MEdge {
/** Un-ordered vertex indices (cannot match). */
unsigned int v1, v2;
char crease, bweight;
char crease;
/**
* Deprecated bevel weight storage, now located in #CD_BWEIGHT, except for file read and write.
*/
char bweight DNA_DEPRECATED;
short flag;
} MEdge;

View File

@ -108,13 +108,11 @@ static CustomData *rna_mesh_vdata(const PointerRNA *ptr)
Mesh *me = rna_mesh(ptr);
return rna_mesh_vdata_helper(me);
}
# if 0
static CustomData *rna_mesh_edata(PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
return rna_mesh_edata_helper(me);
}
# endif
static CustomData *rna_mesh_pdata(const PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
@ -231,6 +229,16 @@ static bool rna_Mesh_has_custom_normals_get(PointerRNA *ptr)
return BKE_mesh_has_custom_loop_normals(me);
}
static bool rna_Mesh_has_edge_bevel_weight_get(PointerRNA *ptr)
{
return CustomData_has_layer(rna_mesh_edata(ptr), CD_BWEIGHT);
}
static bool rna_Mesh_has_vertex_bevel_weight_get(PointerRNA *ptr)
{
return CustomData_has_layer(rna_mesh_vdata(ptr), CD_BWEIGHT);
}
/** \} */
/* -------------------------------------------------------------------- */
@ -430,26 +438,36 @@ static void rna_MeshVertex_hide_set(PointerRNA *ptr, bool value)
static float rna_MeshVertex_bevel_weight_get(PointerRNA *ptr)
{
MVert *mvert = (MVert *)ptr->data;
return mvert->bweight / 255.0f;
const Mesh *mesh = rna_mesh(ptr);
const int index = rna_MeshVertex_index_get(ptr);
const float *values = (const float *)CustomData_get_layer(&mesh->vdata, CD_BWEIGHT);
return values == NULL ? 0.0f : values[index];
}
static void rna_MeshVertex_bevel_weight_set(PointerRNA *ptr, float value)
{
MVert *mvert = (MVert *)ptr->data;
mvert->bweight = round_fl_to_uchar_clamp(value * 255.0f);
Mesh *mesh = rna_mesh(ptr);
const int index = rna_MeshVertex_index_get(ptr);
float *values = (float *)CustomData_add_layer(
&mesh->vdata, CD_BWEIGHT, CD_SET_DEFAULT, NULL, mesh->totvert);
values[index] = clamp_f(value, 0.0f, 1.0f);
}
static float rna_MEdge_bevel_weight_get(PointerRNA *ptr)
{
MEdge *medge = (MEdge *)ptr->data;
return medge->bweight / 255.0f;
const Mesh *mesh = rna_mesh(ptr);
const int index = rna_MeshEdge_index_get(ptr);
const float *values = (const float *)CustomData_get_layer(&mesh->edata, CD_BWEIGHT);
return values == NULL ? 0.0f : values[index];
}
static void rna_MEdge_bevel_weight_set(PointerRNA *ptr, float value)
{
MEdge *medge = (MEdge *)ptr->data;
medge->bweight = round_fl_to_uchar_clamp(value * 255.0f);
Mesh *mesh = rna_mesh(ptr);
const int index = rna_MeshEdge_index_get(ptr);
float *values = (float *)CustomData_add_layer(
&mesh->edata, CD_BWEIGHT, CD_SET_DEFAULT, NULL, mesh->totedge);
values[index] = clamp_f(value, 0.0f, 1.0f);
}
static float rna_MEdge_crease_get(PointerRNA *ptr)
@ -3854,6 +3872,18 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, "rna_Mesh_has_custom_normals_get", NULL);
RNA_define_verify_sdna(true);
prop = RNA_def_property(srna, "has_bevel_weight_edge", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(
prop, "Has Edge Bevel Weight", "True if the mesh has an edge bevel weight layer");
RNA_def_property_boolean_funcs(prop, "rna_Mesh_has_edge_bevel_weight_get", NULL);
prop = RNA_def_property(srna, "has_bevel_weight_vertex", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(
prop, "Has Vertex Bevel Weight", "True if the mesh has an vertex bevel weight layer");
RNA_def_property_boolean_funcs(prop, "rna_Mesh_has_vertex_bevel_weight_get", NULL);
prop = RNA_def_property(srna, "texco_mesh", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "texcomesh");
RNA_def_property_flag(prop, PROP_EDITABLE);
@ -3907,13 +3937,6 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_Mesh_update_vertmask");
/* customdata flags */
prop = RNA_def_property(srna, "use_customdata_vertex_bevel", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_VERT_BWEIGHT);
RNA_def_property_ui_text(prop, "Store Vertex Bevel Weight", "");
prop = RNA_def_property(srna, "use_customdata_edge_bevel", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_EDGE_BWEIGHT);
RNA_def_property_ui_text(prop, "Store Edge Bevel Weight", "");
prop = RNA_def_property(srna, "use_customdata_vertex_crease", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_VERT_CREASE);

View File

@ -294,7 +294,7 @@ static void mesh_merge_transform(Mesh *result,
for (i = 0; i < cap_nverts; i++, mv++) {
mul_m4_v3(cap_offset, mv->co);
/* Reset MVert flags for caps */
mv->flag = mv->bweight = 0;
mv->flag = 0;
}
/* We have to correct normals too, if we do not tag them as dirty later! */

View File

@ -74,6 +74,10 @@ static void requiredDataMask(Object *UNUSED(ob),
if (bmd->defgrp_name[0] != '\0') {
r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
}
if (bmd->lim_flags & MOD_BEVEL_WEIGHT) {
r_cddata_masks->vmask |= CD_MASK_BWEIGHT;
r_cddata_masks->emask |= CD_MASK_BWEIGHT;
}
}
/*

View File

@ -340,11 +340,6 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
MPoly *mpoly = BKE_mesh_polys_for_write(result);
MLoop *mloop = BKE_mesh_loops_for_write(result);
if (do_bevel_convex) {
/* Make sure bweight is enabled. */
result->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
}
if (do_shell) {
CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)verts_num);
CustomData_copy_data(&mesh->vdata, &result->vdata, 0, (int)verts_num, (int)verts_num);
@ -392,6 +387,12 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)polys_num);
}
float *result_edge_bweight = NULL;
if (do_bevel_convex) {
result_edge_bweight = CustomData_add_layer(
&result->edata, CD_BWEIGHT, CD_SET_DEFAULT, NULL, result->totedge);
}
/* initializes: (i_end, do_shell_align, mv). */
#define INIT_VERT_ARRAY_OFFSETS(test) \
if (((ofs_new >= ofs_orig) == do_flip) == test) { \
@ -671,20 +672,18 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
for (uint i = 0; i < edges_num; i++) {
if (edge_users[i] == INVALID_PAIR) {
float angle = edge_angs[i];
medge[i].bweight = (char)clamp_i(
(int)medge[i].bweight + (int)((angle < M_PI ? clamp_f(bevel_convex, 0.0f, 1.0f) :
clamp_f(bevel_convex, -1.0f, 0.0f)) *
255),
0,
255);
result_edge_bweight[i] = clamp_f(result_edge_bweight[i] +
(angle < M_PI ? clamp_f(bevel_convex, 0.0f, 1.0f) :
clamp_f(bevel_convex, -1.0f, 0.0f)),
0.0f,
1.0f);
if (do_shell) {
medge[i + edges_num].bweight = (char)clamp_i(
(int)medge[i + edges_num].bweight +
(int)((angle > M_PI ? clamp_f(bevel_convex, 0.0f, 1.0f) :
clamp_f(bevel_convex, -1.0f, 0.0f)) *
255),
result_edge_bweight[i + edges_num] = clamp_f(
result_edge_bweight[i + edges_num] + (angle > M_PI ?
clamp_f(bevel_convex, 0.0f, 1.0f) :
clamp_f(bevel_convex, -1.0f, 0.0f)),
0,
255);
1.0f);
}
}
}
@ -900,20 +899,17 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
for (i = 0; i < edges_num; i++) {
if (edge_users[i] == INVALID_PAIR) {
float angle = edge_angs[i];
medge[i].bweight = (char)clamp_i(
(int)medge[i].bweight + (int)((angle < M_PI ? clamp_f(bevel_convex, 0, 1) :
clamp_f(bevel_convex, -1, 0)) *
255),
0,
255);
result_edge_bweight[i] = clamp_f(result_edge_bweight[i] +
(angle < M_PI ? clamp_f(bevel_convex, 0.0f, 1.0f) :
clamp_f(bevel_convex, -1.0f, 0.0f)),
0.0f,
1.0f);
if (do_shell) {
medge[i + edges_num].bweight = (char)clamp_i(
(int)medge[i + edges_num].bweight +
(int)((angle > M_PI ? clamp_f(bevel_convex, 0, 1) :
clamp_f(bevel_convex, -1, 0)) *
255),
0,
255);
result_edge_bweight[i + edges_num] = clamp_f(
result_edge_bweight[i + edges_num] +
(angle > M_PI ? clamp_f(bevel_convex, 0, 1) : clamp_f(bevel_convex, -1, 0)),
0.0f,
1.0f);
}
}
}

View File

@ -189,6 +189,10 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
const MPoly *orig_mpoly = BKE_mesh_polys(mesh);
const MLoop *orig_mloop = BKE_mesh_loops(mesh);
/* These might be null. */
const float *orig_vert_bweight = CustomData_get_layer(&mesh->vdata, CD_BWEIGHT);
const float *orig_edge_bweight = CustomData_get_layer(&mesh->edata, CD_BWEIGHT);
uint new_verts_num = 0;
uint new_edges_num = 0;
uint new_loops_num = 0;
@ -1965,9 +1969,10 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
int *origindex_edge = CustomData_get_layer(&result->edata, CD_ORIGINDEX);
int *origindex_poly = CustomData_get_layer(&result->pdata, CD_ORIGINDEX);
if (bevel_convex != 0.0f || (result->cd_flag & ME_CDFLAG_VERT_BWEIGHT) != 0) {
/* make sure bweight is enabled */
result->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
float *result_edge_bweight = CustomData_get_layer(&result->edata, CD_BWEIGHT);
if (bevel_convex != 0.0f || orig_vert_bweight != NULL) {
result_edge_bweight = CustomData_add_layer(
&result->edata, CD_BWEIGHT, CD_SET_DEFAULT, NULL, result->totedge);
}
/* Checks that result has dvert data. */
@ -2038,17 +2043,18 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
medge[insert].v2 = v2;
medge[insert].flag = orig_medge[(*l)->old_edge].flag | ME_EDGEDRAW | ME_EDGERENDER;
medge[insert].crease = orig_medge[(*l)->old_edge].crease;
medge[insert].bweight = orig_medge[(*l)->old_edge].bweight;
if (result_edge_bweight) {
result_edge_bweight[insert] = orig_edge_bweight[(*l)->old_edge];
}
if (bevel_convex != 0.0f && (*l)->faces[1] != NULL) {
medge[insert].bweight = (char)clamp_i(
(int)medge[insert].bweight + (int)(((*l)->angle > M_PI + FLT_EPSILON ?
clamp_f(bevel_convex, 0.0f, 1.0f) :
((*l)->angle < M_PI - FLT_EPSILON ?
clamp_f(bevel_convex, -1.0f, 0.0f) :
0)) *
255),
0,
255);
result_edge_bweight[insert] = clamp_f(
result_edge_bweight[insert] +
((*l)->angle > M_PI + FLT_EPSILON ?
clamp_f(bevel_convex, 0.0f, 1.0f) :
((*l)->angle < M_PI - FLT_EPSILON ? clamp_f(bevel_convex, -1.0f, 0.0f) :
0)),
0.0f,
1.0f);
}
(*l)->new_edge = insert;
}
@ -2113,13 +2119,14 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
EdgeGroup *last_g = NULL;
EdgeGroup *first_g = NULL;
char mv_crease = vertex_crease ? (char)(vertex_crease[i] * 255.0f) : 0;
float mv_bweight = orig_vert_bweight ? orig_vert_bweight[i] : 0.0f;
/* Data calculation cache. */
char max_crease;
char last_max_crease = 0;
char first_max_crease = 0;
char max_bweight;
char last_max_bweight = 0;
char first_max_bweight = 0;
float max_bweight;
float last_max_bweight = 0.0f;
float first_max_bweight = 0.0f;
short flag;
short last_flag = 0;
short first_flag = 0;
@ -2142,20 +2149,24 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
max_crease = ed->crease;
}
if (g->edges[k]->new_edge != MOD_SOLIDIFY_EMPTY_TAG) {
char bweight = medge[g->edges[k]->new_edge].bweight;
if (bweight > max_bweight) {
max_bweight = bweight;
if (result_edge_bweight) {
float bweight = result_edge_bweight[g->edges[k]->new_edge];
if (bweight > max_bweight) {
max_bweight = bweight;
}
}
}
flag |= ed->flag;
}
}
const char bweight_open_edge = min_cc(
orig_medge[g->edges[0]->old_edge].bweight,
orig_medge[g->edges[g->edges_len - 1]->old_edge].bweight);
const float bweight_open_edge =
orig_edge_bweight ?
min_ff(orig_edge_bweight[g->edges[0]->old_edge],
orig_edge_bweight[g->edges[g->edges_len - 1]->old_edge]) :
0.0f;
if (bweight_open_edge > 0) {
max_bweight = min_cc(bweight_open_edge, max_bweight);
max_bweight = min_ff(bweight_open_edge, max_bweight);
}
else {
if (bevel_convex < 0.0f) {
@ -2183,8 +2194,11 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
medge[edge_index].flag = ME_EDGEDRAW | ME_EDGERENDER |
((last_flag | flag) & (ME_SEAM | ME_SHARP));
medge[edge_index].crease = max_cc(mv_crease, min_cc(last_max_crease, max_crease));
medge[edge_index++].bweight = max_cc(mv->bweight,
min_cc(last_max_bweight, max_bweight));
if (result_edge_bweight) {
result_edge_bweight[edge_index] = max_ff(mv_bweight,
min_ff(last_max_bweight, max_bweight));
}
edge_index++;
}
last_g = g;
last_max_crease = max_crease;
@ -2212,8 +2226,11 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
((last_flag | first_flag) & (ME_SEAM | ME_SHARP));
medge[edge_index].crease = max_cc(mv_crease,
min_cc(last_max_crease, first_max_crease));
medge[edge_index++].bweight = max_cc(mv->bweight,
min_cc(last_max_bweight, first_max_bweight));
if (result_edge_bweight) {
result_edge_bweight[edge_index] = max_ff(
mv_bweight, min_ff(last_max_bweight, first_max_bweight));
}
edge_index++;
/* Loop data. */
int *loops = MEM_malloc_arrayN(j, sizeof(*loops), "loops in solidify");