Mesh: Move edge UV seams to a generic attribute #104728
|
@ -99,6 +99,9 @@ void BKE_mesh_legacy_attribute_strings_to_flags(struct Mesh *mesh);
|
|||
void BKE_mesh_legacy_sharp_edges_to_flags(struct Mesh *mesh);
|
||||
void BKE_mesh_legacy_sharp_edges_from_flags(struct Mesh *mesh);
|
||||
|
||||
void BKE_mesh_legacy_uv_seam_to_flags(struct Mesh *mesh);
|
||||
void BKE_mesh_legacy_uv_seam_from_flags(struct Mesh *mesh);
|
||||
|
||||
struct MVert *BKE_mesh_legacy_convert_positions_to_verts(
|
||||
Mesh *mesh,
|
||||
blender::ResourceScope &temp_arrays_for_convert,
|
||||
|
|
|
@ -260,6 +260,7 @@ typedef bool (*MeshRemapIslandsCalc)(const float (*vert_positions)[3],
|
|||
int totvert,
|
||||
const struct MEdge *edges,
|
||||
int totedge,
|
||||
const bool *uv_seams,
|
||||
const struct MPoly *polys,
|
||||
int totpoly,
|
||||
const struct MLoop *loops,
|
||||
|
@ -277,6 +278,7 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(const float (*vert_positions)[3],
|
|||
int totvert,
|
||||
const struct MEdge *edges,
|
||||
int totedge,
|
||||
const bool *uv_seams,
|
||||
const struct MPoly *polys,
|
||||
int totpoly,
|
||||
const struct MLoop *loops,
|
||||
|
@ -300,6 +302,7 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3],
|
|||
int totvert,
|
||||
struct MEdge *edges,
|
||||
int totedge,
|
||||
const bool *uv_seams,
|
||||
struct MPoly *polys,
|
||||
int totpoly,
|
||||
struct MLoop *loops,
|
||||
|
|
|
@ -95,7 +95,6 @@ typedef struct CCGDerivedMesh {
|
|||
struct CCGFace *face;
|
||||
} * faceMap;
|
||||
|
||||
short *edgeFlags;
|
||||
struct DMFlagMat *faceFlags;
|
||||
|
||||
int *reverseFaceMap;
|
||||
|
|
|
@ -1005,26 +1005,21 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
|
|||
return true;
|
||||
}
|
||||
if (r_map && cddata_type == CD_FAKE_SEAM) {
|
||||
const size_t elem_size = sizeof(*((MEdge *)nullptr));
|
||||
const size_t data_size = sizeof(((MEdge *)nullptr)->flag);
|
||||
const size_t data_offset = offsetof(MEdge, flag);
|
||||
const uint64_t data_flag = ME_SEAM;
|
||||
|
||||
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,
|
||||
nullptr,
|
||||
interp_data);
|
||||
if (!CustomData_get_layer_named(&me_dst->edata, CD_PROP_BOOL, ".uv_seam")) {
|
||||
CustomData_add_layer_named(
|
||||
&me_dst->edata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, me_dst->totedge, ".uv_seam");
|
||||
}
|
||||
data_transfer_layersmapping_add_item_cd(
|
||||
r_map,
|
||||
CD_PROP_BOOL,
|
||||
mix_mode,
|
||||
mix_factor,
|
||||
mix_weights,
|
||||
CustomData_get_layer_named(&me_src->edata, CD_PROP_BOOL, ".uv_seam"),
|
||||
CustomData_get_layer_named_for_write(
|
||||
&me_dst->edata, CD_PROP_BOOL, ".uv_seam", me_dst->totedge),
|
||||
interp,
|
||||
interp_data);
|
||||
return true;
|
||||
}
|
||||
if (r_map && cddata_type == CD_FAKE_SHARP) {
|
||||
|
|
|
@ -2496,6 +2496,7 @@ static void gpencil_generate_edgeloops(Object *ob,
|
|||
const bool use_seams,
|
||||
const bool use_vgroups)
|
||||
{
|
||||
using namespace blender;
|
||||
Mesh *me = (Mesh *)ob->data;
|
||||
if (me->totedge == 0) {
|
||||
return;
|
||||
|
@ -2504,6 +2505,9 @@ static void gpencil_generate_edgeloops(Object *ob,
|
|||
const Span<MEdge> edges = me->edges();
|
||||
const Span<MDeformVert> dverts = me->deform_verts();
|
||||
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(me);
|
||||
const bke::AttributeAccessor attributes = me->attributes();
|
||||
const VArray<bool> uv_seams = attributes.lookup_or_default<bool>(
|
||||
".uv_seam", ATTR_DOMAIN_EDGE, false);
|
||||
|
||||
/* Arrays for all edge vertices (forward and backward) that form a edge loop.
|
||||
* This is reused for each edge-loop to create gpencil stroke. */
|
||||
|
@ -2529,7 +2533,7 @@ static void gpencil_generate_edgeloops(Object *ob,
|
|||
sub_v3_v3v3(gped->vec, vert_positions[ed->v1], vert_positions[ed->v2]);
|
||||
|
||||
/* If use seams, mark as done if not a seam. */
|
||||
if ((use_seams) && ((ed->flag & ME_SEAM) == 0)) {
|
||||
if ((use_seams) && !uv_seams[i]) {
|
||||
gped->flag = 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -272,6 +272,7 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
|
|||
BKE_mesh_legacy_bevel_weight_from_layers(mesh);
|
||||
BKE_mesh_legacy_edge_crease_from_layers(mesh);
|
||||
BKE_mesh_legacy_sharp_edges_to_flags(mesh);
|
||||
BKE_mesh_legacy_uv_seam_to_flags(mesh);
|
||||
BKE_mesh_legacy_attribute_strings_to_flags(mesh);
|
||||
mesh->active_color_attribute = nullptr;
|
||||
mesh->default_color_attribute = nullptr;
|
||||
|
|
|
@ -104,9 +104,9 @@ class MeshesToIMeshInfo {
|
|||
void input_mvert_for_orig_index(int orig_index,
|
||||
const Mesh **r_orig_mesh,
|
||||
int *r_index_in_orig_mesh) const;
|
||||
const MEdge *input_medge_for_orig_index(int orig_index,
|
||||
const Mesh **r_orig_mesh,
|
||||
int *r_index_in_orig_mesh) const;
|
||||
void input_medge_for_orig_index(int orig_index,
|
||||
const Mesh **r_orig_mesh,
|
||||
int *r_index_in_orig_mesh) const;
|
||||
};
|
||||
|
||||
/* Given an index `imesh_v` in the `IMesh`, return the index of the
|
||||
|
@ -199,24 +199,21 @@ void MeshesToIMeshInfo::input_mvert_for_orig_index(int orig_index,
|
|||
}
|
||||
|
||||
/* Similarly for edges. */
|
||||
const MEdge *MeshesToIMeshInfo::input_medge_for_orig_index(int orig_index,
|
||||
const Mesh **r_orig_mesh,
|
||||
int *r_index_in_orig_mesh) const
|
||||
void MeshesToIMeshInfo::input_medge_for_orig_index(int orig_index,
|
||||
const Mesh **r_orig_mesh,
|
||||
int *r_index_in_orig_mesh) const
|
||||
{
|
||||
int orig_mesh_index = input_mesh_for_imesh_edge(orig_index);
|
||||
BLI_assert(0 <= orig_mesh_index && orig_mesh_index < meshes.size());
|
||||
const Mesh *me = meshes[orig_mesh_index];
|
||||
const Span<MEdge> edges = me->edges();
|
||||
int index_in_mesh = orig_index - mesh_edge_offset[orig_mesh_index];
|
||||
BLI_assert(0 <= index_in_mesh && index_in_mesh < me->totedge);
|
||||
const MEdge *medge = &edges[index_in_mesh];
|
||||
if (r_orig_mesh) {
|
||||
*r_orig_mesh = me;
|
||||
}
|
||||
if (r_index_in_orig_mesh) {
|
||||
*r_index_in_orig_mesh = index_in_mesh;
|
||||
}
|
||||
return medge;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -434,13 +431,10 @@ static void copy_poly_attributes(Mesh *dest_mesh,
|
|||
|
||||
/* Similar to copy_vert_attributes but for edge attributes. */
|
||||
static void copy_edge_attributes(Mesh *dest_mesh,
|
||||
MEdge *medge,
|
||||
const MEdge *orig_medge,
|
||||
const Mesh *orig_me,
|
||||
int medge_index,
|
||||
int index_in_orig_me)
|
||||
{
|
||||
medge->flag = orig_medge->flag;
|
||||
CustomData *target_cd = &dest_mesh->edata;
|
||||
const CustomData *source_cd = &orig_me->edata;
|
||||
for (int source_layer_i = 0; source_layer_i < source_cd->totlayer; ++source_layer_i) {
|
||||
|
@ -777,7 +771,6 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
|
|||
|
||||
/* Now that the MEdges are populated, we can copy over the required attributes and custom layers.
|
||||
*/
|
||||
MutableSpan<MEdge> edges = result->edges_for_write();
|
||||
for (int fi : im->face_index_range()) {
|
||||
const Face *f = im->face(fi);
|
||||
const MPoly *mp = &dst_polys[fi];
|
||||
|
@ -785,11 +778,9 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
|
|||
if (f->edge_orig[j] != NO_INDEX) {
|
||||
const Mesh *orig_me;
|
||||
int index_in_orig_me;
|
||||
const MEdge *orig_medge = mim.input_medge_for_orig_index(
|
||||
f->edge_orig[j], &orig_me, &index_in_orig_me);
|
||||
mim.input_medge_for_orig_index(f->edge_orig[j], &orig_me, &index_in_orig_me);
|
||||
int e_index = dst_loops[mp->loopstart + j].e;
|
||||
MEdge *medge = &edges[e_index];
|
||||
copy_edge_attributes(result, medge, orig_medge, orig_me, e_index, index_in_orig_me);
|
||||
copy_edge_attributes(result, orig_me, e_index, index_in_orig_me);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,8 +120,6 @@ static void make_edges_mdata_extend(Mesh &mesh)
|
|||
BLI_edgehashIterator_step(ehi), ++medge, e_index++) {
|
||||
BLI_edgehashIterator_getKey(ehi, &medge->v1, &medge->v2);
|
||||
BLI_edgehashIterator_setValue(ehi, POINTER_FROM_UINT(e_index));
|
||||
|
||||
medge->flag = 0;
|
||||
}
|
||||
BLI_edgehashIterator_free(ehi);
|
||||
|
||||
|
|
|
@ -476,7 +476,7 @@ static void convert_mfaces_to_mpolys(ID *id,
|
|||
|
||||
/* unrelated but avoid having the FGON flag enabled,
|
||||
* so we can reuse it later for something else */
|
||||
me->flag &= ~ME_FGON;
|
||||
me->flag_legacy &= ~ME_FGON;
|
||||
}
|
||||
|
||||
polyindex = (int *)CustomData_get_layer(fdata, CD_ORIGINDEX);
|
||||
|
@ -1379,13 +1379,13 @@ void BKE_mesh_legacy_sharp_edges_to_flags(Mesh *mesh)
|
|||
CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge"))) {
|
||||
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
SET_FLAG_FROM_TEST(edges[i].flag, sharp_edges[i], ME_SHARP);
|
||||
SET_FLAG_FROM_TEST(edges[i].flag_legacy, sharp_edges[i], ME_SHARP);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
for (const int i : edges.index_range()) {
|
||||
edges[i].flag &= ~ME_SHARP;
|
||||
edges[i].flag_legacy &= ~ME_SHARP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1399,13 +1399,14 @@ void BKE_mesh_legacy_sharp_edges_from_flags(Mesh *mesh)
|
|||
if (attributes.contains("sharp_edge")) {
|
||||
return;
|
||||
}
|
||||
if (std::any_of(
|
||||
edges.begin(), edges.end(), [](const MEdge &edge) { return edge.flag & ME_SHARP; })) {
|
||||
if (std::any_of(edges.begin(), edges.end(), [](const MEdge &edge) {
|
||||
return edge.flag_legacy & ME_SHARP;
|
||||
})) {
|
||||
SpanAttributeWriter<bool> sharp_edges = attributes.lookup_or_add_for_write_only_span<bool>(
|
||||
"sharp_edge", ATTR_DOMAIN_EDGE);
|
||||
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
sharp_edges.span[i] = edges[i].flag & ME_SHARP;
|
||||
sharp_edges.span[i] = edges[i].flag_legacy & ME_SHARP;
|
||||
}
|
||||
});
|
||||
sharp_edges.finish();
|
||||
|
@ -1414,6 +1415,54 @@ void BKE_mesh_legacy_sharp_edges_from_flags(Mesh *mesh)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name UV Seam Conversion
|
||||
* \{ */
|
||||
|
||||
void BKE_mesh_legacy_uv_seam_to_flags(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
MutableSpan<MEdge> edges = mesh->edges_for_write();
|
||||
if (const bool *uv_seams = static_cast<const bool *>(
|
||||
CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, ".uv_seam"))) {
|
||||
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
SET_FLAG_FROM_TEST(edges[i].flag_legacy, uv_seams[i], ME_SEAM);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
for (const int i : edges.index_range()) {
|
||||
edges[i].flag_legacy &= ~ME_SEAM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_mesh_legacy_uv_seam_from_flags(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
const Span<MEdge> edges = mesh->edges();
|
||||
MutableAttributeAccessor attributes = mesh->attributes_for_write();
|
||||
if (attributes.contains(".uv_seam")) {
|
||||
return;
|
||||
}
|
||||
if (std::any_of(edges.begin(), edges.end(), [](const MEdge &edge) {
|
||||
return edge.flag_legacy & ME_SEAM;
|
||||
})) {
|
||||
SpanAttributeWriter<bool> uv_seams = attributes.lookup_or_add_for_write_only_span<bool>(
|
||||
".uv_seam", ATTR_DOMAIN_EDGE);
|
||||
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
uv_seams.span[i] = edges[i].flag_legacy & ME_SEAM;
|
||||
}
|
||||
});
|
||||
uv_seams.finish();
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Hide Attribute and Legacy Flag Conversion
|
||||
* \{ */
|
||||
|
@ -1438,7 +1487,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh)
|
|||
".hide_edge", ATTR_DOMAIN_EDGE, false);
|
||||
threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
SET_FLAG_FROM_TEST(edges[i].flag, hide_edge[i], ME_HIDE);
|
||||
SET_FLAG_FROM_TEST(edges[i].flag_legacy, hide_edge[i], ME_HIDE);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1476,13 +1525,14 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
|
|||
}
|
||||
|
||||
const Span<MEdge> edges = mesh->edges();
|
||||
if (std::any_of(
|
||||
edges.begin(), edges.end(), [](const MEdge &edge) { return edge.flag & ME_HIDE; })) {
|
||||
if (std::any_of(edges.begin(), edges.end(), [](const MEdge &edge) {
|
||||
return edge.flag_legacy & ME_HIDE;
|
||||
})) {
|
||||
SpanAttributeWriter<bool> hide_edge = attributes.lookup_or_add_for_write_only_span<bool>(
|
||||
".hide_edge", ATTR_DOMAIN_EDGE);
|
||||
threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
hide_edge.span[i] = edges[i].flag & ME_HIDE;
|
||||
hide_edge.span[i] = edges[i].flag_legacy & ME_HIDE;
|
||||
}
|
||||
});
|
||||
hide_edge.finish();
|
||||
|
@ -1755,7 +1805,7 @@ void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh)
|
|||
".select_edge", ATTR_DOMAIN_EDGE, false);
|
||||
threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
SET_FLAG_FROM_TEST(edges[i].flag, select_edge[i], SELECT);
|
||||
SET_FLAG_FROM_TEST(edges[i].flag_legacy, select_edge[i], SELECT);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1794,13 +1844,14 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh)
|
|||
}
|
||||
|
||||
const Span<MEdge> edges = mesh->edges();
|
||||
if (std::any_of(
|
||||
edges.begin(), edges.end(), [](const MEdge &edge) { return edge.flag & SELECT; })) {
|
||||
if (std::any_of(edges.begin(), edges.end(), [](const MEdge &edge) {
|
||||
return edge.flag_legacy & SELECT;
|
||||
})) {
|
||||
SpanAttributeWriter<bool> select_edge = attributes.lookup_or_add_for_write_only_span<bool>(
|
||||
".select_edge", ATTR_DOMAIN_EDGE);
|
||||
threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
select_edge.span[i] = edges[i].flag & SELECT;
|
||||
select_edge.span[i] = edges[i].flag_legacy & SELECT;
|
||||
}
|
||||
});
|
||||
select_edge.finish();
|
||||
|
@ -1836,12 +1887,12 @@ void BKE_mesh_legacy_convert_loose_edges_to_flag(Mesh *mesh)
|
|||
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
|
||||
if (loose_edges.count == 0) {
|
||||
for (const int64_t i : range) {
|
||||
edges[i].flag &= ~ME_LOOSEEDGE;
|
||||
edges[i].flag_legacy &= ~ME_LOOSEEDGE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (const int64_t i : range) {
|
||||
SET_FLAG_FROM_TEST(edges[i].flag, loose_edges.is_loose_bits[i], ME_LOOSEEDGE);
|
||||
SET_FLAG_FROM_TEST(edges[i].flag_legacy, loose_edges.is_loose_bits[i], ME_LOOSEEDGE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -999,8 +999,8 @@ void BKE_mesh_loop_islands_add(MeshIslandStore *island_store,
|
|||
sizeof(*innrcut->indices) * size_t(num_innercut_items));
|
||||
}
|
||||
|
||||
static bool mesh_calc_islands_loop_poly_uv(const MEdge *edges,
|
||||
const int totedge,
|
||||
static bool mesh_calc_islands_loop_poly_uv(const int totedge,
|
||||
const bool *uv_seams,
|
||||
const MPoly *polys,
|
||||
const int totpoly,
|
||||
const MLoop *loops,
|
||||
|
@ -1085,7 +1085,7 @@ static bool mesh_calc_islands_loop_poly_uv(const MEdge *edges,
|
|||
}
|
||||
|
||||
/* Edge is UV boundary if tagged as seam. */
|
||||
return (edges[edge_index].flag & ME_SEAM) != 0;
|
||||
return uv_seams && uv_seams[edge_index];
|
||||
};
|
||||
|
||||
poly_edge_loop_islands_calc(totedge,
|
||||
|
@ -1185,21 +1185,23 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(const float (*vert_positions)[3],
|
|||
const int totvert,
|
||||
const MEdge *edges,
|
||||
const int totedge,
|
||||
const bool *uv_seams,
|
||||
const MPoly *polys,
|
||||
const int totpoly,
|
||||
const MLoop *loops,
|
||||
const int totloop,
|
||||
MeshIslandStore *r_island_store)
|
||||
{
|
||||
UNUSED_VARS(vert_positions, totvert);
|
||||
UNUSED_VARS(vert_positions, totvert, edges);
|
||||
return mesh_calc_islands_loop_poly_uv(
|
||||
edges, totedge, polys, totpoly, loops, totloop, nullptr, r_island_store);
|
||||
totedge, uv_seams, polys, totpoly, loops, totloop, nullptr, r_island_store);
|
||||
}
|
||||
|
||||
bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3],
|
||||
const int totvert,
|
||||
MEdge *edges,
|
||||
const int totedge,
|
||||
const bool *uv_seams,
|
||||
MPoly *polys,
|
||||
const int totpoly,
|
||||
MLoop *loops,
|
||||
|
@ -1207,10 +1209,10 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3],
|
|||
const float (*luvs)[2],
|
||||
MeshIslandStore *r_island_store)
|
||||
{
|
||||
UNUSED_VARS(vert_positions, totvert);
|
||||
UNUSED_VARS(vert_positions, totvert, edges);
|
||||
BLI_assert(luvs != nullptr);
|
||||
return mesh_calc_islands_loop_poly_uv(
|
||||
edges, totedge, polys, totpoly, loops, totloop, luvs, r_island_store);
|
||||
totedge, uv_seams, polys, totpoly, loops, totloop, luvs, r_island_store);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -1444,10 +1444,13 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
|
|||
|
||||
/* First, generate the islands, if possible. */
|
||||
if (gen_islands_src) {
|
||||
const bool *uv_seams = static_cast<const bool *>(
|
||||
CustomData_get_layer_named(&me_src->edata, CD_PROP_BOOL, ".uv_seam"));
|
||||
use_islands = gen_islands_src(positions_src,
|
||||
num_verts_src,
|
||||
edges_src.data(),
|
||||
int(edges_src.size()),
|
||||
uv_seams,
|
||||
polys_src.data(),
|
||||
int(polys_src.size()),
|
||||
loops_src.data(),
|
||||
|
|
|
@ -911,11 +911,10 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, float (*r_positions)[3])
|
|||
}
|
||||
|
||||
/* utility function */
|
||||
BLI_INLINE void ccgDM_to_MEdge(MEdge *med, const int v1, const int v2, const short flag)
|
||||
BLI_INLINE void ccgDM_to_MEdge(MEdge *med, const int v1, const int v2)
|
||||
{
|
||||
med->v1 = v1;
|
||||
med->v2 = v2;
|
||||
med->flag = flag;
|
||||
}
|
||||
|
||||
static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
|
||||
|
@ -927,7 +926,6 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
|
|||
int gridSize = ccgSubSurf_getGridSize(ss);
|
||||
int edgeSize = ccgSubSurf_getEdgeSize(ss);
|
||||
uint i = 0;
|
||||
short *edgeFlags = ccgdm->edgeFlags;
|
||||
|
||||
totface = ccgSubSurf_getNumFaces(ss);
|
||||
for (index = 0; index < totface; index++) {
|
||||
|
@ -938,20 +936,17 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
|
|||
for (x = 0; x < gridSize - 1; x++) {
|
||||
ccgDM_to_MEdge(&medge[i++],
|
||||
getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize),
|
||||
getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize),
|
||||
0);
|
||||
getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize));
|
||||
}
|
||||
|
||||
for (x = 1; x < gridSize - 1; x++) {
|
||||
for (y = 0; y < gridSize - 1; y++) {
|
||||
ccgDM_to_MEdge(&medge[i++],
|
||||
getFaceIndex(ss, f, S, x, y, edgeSize, gridSize),
|
||||
getFaceIndex(ss, f, S, x, y + 1, edgeSize, gridSize),
|
||||
0);
|
||||
getFaceIndex(ss, f, S, x, y + 1, edgeSize, gridSize));
|
||||
ccgDM_to_MEdge(&medge[i++],
|
||||
getFaceIndex(ss, f, S, y, x, edgeSize, gridSize),
|
||||
getFaceIndex(ss, f, S, y + 1, x, edgeSize, gridSize),
|
||||
0);
|
||||
getFaceIndex(ss, f, S, y + 1, x, edgeSize, gridSize));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -960,21 +955,9 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
|
|||
totedge = ccgSubSurf_getNumEdges(ss);
|
||||
for (index = 0; index < totedge; index++) {
|
||||
CCGEdge *e = ccgdm->edgeMap[index].edge;
|
||||
short ed_flag = 0;
|
||||
int x;
|
||||
int edgeIdx = POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(e));
|
||||
|
||||
if (edgeFlags) {
|
||||
if (edgeIdx != -1) {
|
||||
ed_flag |= (edgeFlags[index] & ME_SEAM);
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < edgeSize - 1; x++) {
|
||||
ccgDM_to_MEdge(&medge[i++],
|
||||
getEdgeIndex(ss, e, x, edgeSize),
|
||||
getEdgeIndex(ss, e, x + 1, edgeSize),
|
||||
ed_flag);
|
||||
for (int x = 0; x < edgeSize - 1; x++) {
|
||||
ccgDM_to_MEdge(
|
||||
&medge[i++], getEdgeIndex(ss, e, x, edgeSize), getEdgeIndex(ss, e, x + 1, edgeSize));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1170,7 +1153,6 @@ static void ccgDM_release(DerivedMesh *dm)
|
|||
if (ccgdm->pmap_mem) {
|
||||
MEM_freeN(ccgdm->pmap_mem);
|
||||
}
|
||||
MEM_freeN(ccgdm->edgeFlags);
|
||||
MEM_freeN(ccgdm->faceFlags);
|
||||
MEM_freeN(ccgdm->vertMap);
|
||||
MEM_freeN(ccgdm->edgeMap);
|
||||
|
@ -1539,7 +1521,6 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
|
|||
int index;
|
||||
int i;
|
||||
int vertNum = 0, edgeNum = 0, faceNum = 0;
|
||||
short *edgeFlags = ccgdm->edgeFlags;
|
||||
DMFlagMat *faceFlags = ccgdm->faceFlags;
|
||||
int *polyidx = nullptr;
|
||||
blender::Vector<int, 16> loopidx;
|
||||
|
@ -1551,7 +1532,6 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
|
|||
int gridSideEdges;
|
||||
int gridInternalEdges;
|
||||
WeightTable wtable = {nullptr};
|
||||
MEdge *medge = nullptr;
|
||||
bool has_edge_cd;
|
||||
|
||||
edgeSize = ccgSubSurf_getEdgeSize(ss);
|
||||
|
@ -1562,8 +1542,6 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
|
|||
gridSideEdges = gridSize - 1;
|
||||
gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
|
||||
|
||||
medge = dm->getEdgeArray(dm);
|
||||
|
||||
const MPoly *mpoly = static_cast<const MPoly *>(CustomData_get_layer(&dm->polyData, CD_MPOLY));
|
||||
const int *material_indices = static_cast<const int *>(
|
||||
CustomData_get_layer_named(&dm->polyData, CD_MPOLY, "material_index"));
|
||||
|
@ -1742,10 +1720,6 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
|
|||
ccgdm->edgeMap[index].startVert = vertNum;
|
||||
ccgdm->edgeMap[index].startEdge = edgeNum;
|
||||
|
||||
if (edgeIdx >= 0 && edgeFlags) {
|
||||
edgeFlags[edgeIdx] = medge[edgeIdx].flag;
|
||||
}
|
||||
|
||||
/* set the edge base vert */
|
||||
*((int *)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum;
|
||||
|
||||
|
@ -1827,6 +1801,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
|
|||
CCGDerivedMesh *ccgdm = MEM_cnew<CCGDerivedMesh>(__func__);
|
||||
|
||||
BLI_assert(totedge == ccgSubSurf_getNumEdges(ss));
|
||||
UNUSED_VARS_NDEBUG(totedge);
|
||||
BLI_assert(totface == ccgSubSurf_getNumFaces(ss));
|
||||
DM_from_template(&ccgdm->dm,
|
||||
dm,
|
||||
|
@ -1849,7 +1824,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
|
|||
ccgdm->useSubsurfUv = useSubsurfUv;
|
||||
|
||||
/* CDDM hack. */
|
||||
ccgdm->edgeFlags = static_cast<short *>(MEM_callocN(sizeof(short) * totedge, "edgeFlags"));
|
||||
ccgdm->faceFlags = static_cast<DMFlagMat *>(
|
||||
MEM_callocN(sizeof(DMFlagMat) * totface, "faceFlags"));
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ static void version_mesh_legacy_to_struct_of_array_format(Mesh &mesh)
|
|||
BKE_mesh_legacy_sharp_edges_from_flags(&mesh);
|
||||
BKE_mesh_legacy_face_set_to_generic(&mesh);
|
||||
BKE_mesh_legacy_edge_crease_to_layers(&mesh);
|
||||
BKE_mesh_legacy_uv_seam_from_flags(&mesh);
|
||||
BKE_mesh_legacy_convert_verts_to_positions(&mesh);
|
||||
BKE_mesh_legacy_attribute_flags_to_strings(&mesh);
|
||||
}
|
||||
|
|
|
@ -113,21 +113,11 @@ using blender::Span;
|
|||
using blender::StringRef;
|
||||
using blender::Vector;
|
||||
|
||||
static char bm_edge_flag_from_mflag(const short mflag)
|
||||
{
|
||||
return ((mflag & ME_SEAM) ? BM_ELEM_SEAM : 0) | BM_ELEM_DRAW;
|
||||
}
|
||||
static char bm_face_flag_from_mflag(const char mflag)
|
||||
{
|
||||
return ((mflag & ME_SMOOTH) ? BM_ELEM_SMOOTH : 0);
|
||||
}
|
||||
|
||||
static short bm_edge_flag_to_mflag(const BMEdge *e)
|
||||
{
|
||||
const char hflag = e->head.hflag;
|
||||
|
||||
return (hflag & BM_ELEM_SEAM) ? ME_SEAM : 0;
|
||||
}
|
||||
static char bm_face_flag_to_mflag(const BMFace *f)
|
||||
{
|
||||
const char hflag = f->head.hflag;
|
||||
|
@ -142,6 +132,7 @@ bool BM_attribute_stored_in_bmesh_builtin(const StringRef name)
|
|||
".hide_vert",
|
||||
".hide_edge",
|
||||
".hide_poly",
|
||||
".uv_seam",
|
||||
".select_vert",
|
||||
".select_edge",
|
||||
".select_poly",
|
||||
|
@ -437,6 +428,8 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
|
|||
&me->pdata, CD_PROP_INT32, "material_index");
|
||||
const bool *sharp_edges = (const bool *)CustomData_get_layer_named(
|
||||
&me->edata, CD_PROP_BOOL, "sharp_edge");
|
||||
const bool *uv_seams = (const bool *)CustomData_get_layer_named(
|
||||
&me->edata, CD_PROP_BOOL, ".uv_seam");
|
||||
|
||||
const Span<float3> positions = me->vert_positions();
|
||||
Array<BMVert *> vtable(me->totvert);
|
||||
|
@ -482,8 +475,10 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
|
|||
bm, vtable[medge[i].v1], vtable[medge[i].v2], nullptr, BM_CREATE_SKIP_CD);
|
||||
BM_elem_index_set(e, i); /* set_ok */
|
||||
|
||||
/* Transfer flags. */
|
||||
e->head.hflag = bm_edge_flag_from_mflag(medge[i].flag);
|
||||
e->head.hflag = 0;
|
||||
if (uv_seams && uv_seams[i]) {
|
||||
BM_elem_flag_enable(e, BM_ELEM_SEAM);
|
||||
}
|
||||
if (hide_edge && hide_edge[i]) {
|
||||
BM_elem_flag_enable(e, BM_ELEM_HIDDEN);
|
||||
}
|
||||
|
@ -1258,6 +1253,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
|
|||
bool need_hide_poly = false;
|
||||
bool need_material_index = false;
|
||||
bool need_sharp_edge = false;
|
||||
bool need_uv_seam = false;
|
||||
|
||||
i = 0;
|
||||
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
|
@ -1285,7 +1281,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
|
|||
medge[i].v1 = BM_elem_index_get(e->v1);
|
||||
medge[i].v2 = BM_elem_index_get(e->v2);
|
||||
|
||||
medge[i].flag = bm_edge_flag_to_mflag(e);
|
||||
if (BM_elem_flag_test(e, BM_ELEM_SEAM)) {
|
||||
need_uv_seam = true;
|
||||
}
|
||||
if (BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
|
||||
need_hide_edge = true;
|
||||
}
|
||||
|
@ -1359,6 +1357,13 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
|
|||
return !BM_elem_flag_test(BM_edge_at_index(bm, i), BM_ELEM_SMOOTH);
|
||||
});
|
||||
}
|
||||
if (need_uv_seam) {
|
||||
BM_mesh_elem_table_ensure(bm, BM_EDGE);
|
||||
write_fn_to_attribute<bool>(
|
||||
me->attributes_for_write(), ".uv_seam", ATTR_DOMAIN_EDGE, [&](const int i) {
|
||||
return BM_elem_flag_test(BM_edge_at_index(bm, i), BM_ELEM_SEAM);
|
||||
});
|
||||
}
|
||||
|
||||
/* Patch hook indices and vertex parents. */
|
||||
if (params->calc_object_remap && (ototvert > 0)) {
|
||||
|
@ -1496,7 +1501,8 @@ static void bm_edge_table_build(BMesh &bm,
|
|||
MutableSpan<const BMEdge *> table,
|
||||
bool &need_select_edge,
|
||||
bool &need_hide_edge,
|
||||
bool &need_sharp_edge)
|
||||
bool &need_sharp_edge,
|
||||
bool &need_uv_seams)
|
||||
{
|
||||
char hflag = 0;
|
||||
BMIter iter;
|
||||
|
@ -1510,6 +1516,7 @@ static void bm_edge_table_build(BMesh &bm,
|
|||
need_select_edge = (hflag & BM_ELEM_SELECT) != 0;
|
||||
need_hide_edge = (hflag & BM_ELEM_HIDDEN) != 0;
|
||||
need_sharp_edge = (hflag & BM_ELEM_SMOOTH) != 0;
|
||||
need_uv_seams = (hflag & BM_ELEM_SEAM) != 0;
|
||||
}
|
||||
|
||||
static void bm_face_loop_table_build(BMesh &bm,
|
||||
|
@ -1574,7 +1581,8 @@ static void bm_to_mesh_edges(const BMesh &bm,
|
|||
Mesh &mesh,
|
||||
MutableSpan<bool> select_edge,
|
||||
MutableSpan<bool> hide_edge,
|
||||
MutableSpan<bool> sharp_edge)
|
||||
MutableSpan<bool> sharp_edge,
|
||||
MutableSpan<bool> uv_seams)
|
||||
{
|
||||
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.edata, mesh.edata);
|
||||
MutableSpan<MEdge> dst_edges = mesh.edges_for_write();
|
||||
|
@ -1584,7 +1592,6 @@ static void bm_to_mesh_edges(const BMesh &bm,
|
|||
MEdge &dst_edge = dst_edges[edge_i];
|
||||
dst_edge.v1 = BM_elem_index_get(src_edge.v1);
|
||||
dst_edge.v2 = BM_elem_index_get(src_edge.v2);
|
||||
dst_edge.flag = bm_edge_flag_to_mflag(&src_edge);
|
||||
bmesh_block_copy_to_mesh_attributes(info, edge_i, src_edge.head.data);
|
||||
}
|
||||
if (!select_edge.is_empty()) {
|
||||
|
@ -1602,6 +1609,11 @@ static void bm_to_mesh_edges(const BMesh &bm,
|
|||
sharp_edge[edge_i] = !BM_elem_flag_test(bm_edges[edge_i], BM_ELEM_SMOOTH);
|
||||
}
|
||||
}
|
||||
if (!uv_seams.is_empty()) {
|
||||
for (const int edge_i : range) {
|
||||
uv_seams[edge_i] = BM_elem_flag_test(bm_edges[edge_i], BM_ELEM_SEAM);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1709,6 +1721,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
|
|||
bool need_hide_poly = false;
|
||||
bool need_material_index = false;
|
||||
bool need_sharp_edge = false;
|
||||
bool need_uv_seams = false;
|
||||
Array<const BMVert *> vert_table;
|
||||
Array<const BMEdge *> edge_table;
|
||||
Array<const BMFace *> face_table;
|
||||
|
@ -1721,7 +1734,8 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
|
|||
},
|
||||
[&]() {
|
||||
edge_table.reinitialize(bm->totedge);
|
||||
bm_edge_table_build(*bm, edge_table, need_select_edge, need_hide_edge, need_sharp_edge);
|
||||
bm_edge_table_build(
|
||||
*bm, edge_table, need_select_edge, need_hide_edge, need_sharp_edge, need_uv_seams);
|
||||
},
|
||||
[&]() {
|
||||
face_table.reinitialize(bm->totface);
|
||||
|
@ -1739,6 +1753,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
|
|||
bke::SpanAttributeWriter<bool> select_edge;
|
||||
bke::SpanAttributeWriter<bool> hide_edge;
|
||||
bke::SpanAttributeWriter<bool> sharp_edge;
|
||||
bke::SpanAttributeWriter<bool> uv_seams;
|
||||
bke::SpanAttributeWriter<bool> select_poly;
|
||||
bke::SpanAttributeWriter<bool> hide_poly;
|
||||
bke::SpanAttributeWriter<int> material_index;
|
||||
|
@ -1754,6 +1769,9 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
|
|||
if (need_sharp_edge) {
|
||||
sharp_edge = attrs.lookup_or_add_for_write_only_span<bool>("sharp_edge", ATTR_DOMAIN_EDGE);
|
||||
}
|
||||
if (need_uv_seams) {
|
||||
uv_seams = attrs.lookup_or_add_for_write_only_span<bool>(".uv_seam", ATTR_DOMAIN_EDGE);
|
||||
}
|
||||
if (need_hide_edge) {
|
||||
hide_edge = attrs.lookup_or_add_for_write_only_span<bool>(".hide_edge", ATTR_DOMAIN_EDGE);
|
||||
}
|
||||
|
@ -1773,7 +1791,13 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
|
|||
me->totvert > 1024,
|
||||
[&]() { bm_to_mesh_verts(*bm, vert_table, *me, select_vert.span, hide_vert.span); },
|
||||
[&]() {
|
||||
bm_to_mesh_edges(*bm, edge_table, *me, select_edge.span, hide_edge.span, sharp_edge.span);
|
||||
bm_to_mesh_edges(*bm,
|
||||
edge_table,
|
||||
*me,
|
||||
select_edge.span,
|
||||
hide_edge.span,
|
||||
sharp_edge.span,
|
||||
uv_seams.span);
|
||||
},
|
||||
[&]() {
|
||||
bm_to_mesh_faces(
|
||||
|
@ -1786,6 +1810,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
|
|||
select_edge.finish();
|
||||
hide_edge.finish();
|
||||
sharp_edge.finish();
|
||||
uv_seams.finish();
|
||||
select_poly.finish();
|
||||
hide_poly.finish();
|
||||
material_index.finish();
|
||||
|
|
|
@ -227,7 +227,9 @@ static void build_poly_connections(blender::AtomicDisjointSet &islands,
|
|||
const Span<MEdge> edges = mesh.edges();
|
||||
const Span<MLoop> loops = mesh.loops();
|
||||
|
||||
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
|
||||
const bke::AttributeAccessor attributes = mesh.attributes();
|
||||
const VArray<bool> uv_seams = attributes.lookup_or_default<bool>(
|
||||
".uv_seam", ATTR_DOMAIN_EDGE, false);
|
||||
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
|
@ -243,7 +245,7 @@ static void build_poly_connections(blender::AtomicDisjointSet &islands,
|
|||
|
||||
for (const int poly_loop_index : poly_loops.index_range()) {
|
||||
const MLoop &outer_mloop = poly_loops[poly_loop_index];
|
||||
if (skip_seams && (edges[outer_mloop.e].flag & ME_SEAM) != 0) {
|
||||
if (skip_seams && uv_seams[outer_mloop.e]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -252,7 +254,7 @@ static void build_poly_connections(blender::AtomicDisjointSet &islands,
|
|||
if (&outer_mloop == &inner_mloop) {
|
||||
continue;
|
||||
}
|
||||
if (skip_seams && (edges[inner_mloop.e].flag & ME_SEAM) != 0) {
|
||||
if (skip_seams && uv_seams[inner_mloop.e]) {
|
||||
continue;
|
||||
}
|
||||
islands.join(inner_mloop.e, outer_mloop.e);
|
||||
|
@ -277,6 +279,8 @@ static void paintface_select_linked_faces(Mesh &mesh,
|
|||
const Span<MLoop> loops = mesh.loops();
|
||||
|
||||
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
|
||||
const VArray<bool> uv_seams = attributes.lookup_or_default<bool>(
|
||||
".uv_seam", ATTR_DOMAIN_EDGE, false);
|
||||
bke::SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_span<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE);
|
||||
|
||||
|
@ -284,7 +288,7 @@ static void paintface_select_linked_faces(Mesh &mesh,
|
|||
for (const int i : face_indices) {
|
||||
const MPoly &poly = polys[i];
|
||||
for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
|
||||
if ((edges[loop.e].flag & ME_SEAM) != 0) {
|
||||
if (uv_seams[loop.e]) {
|
||||
continue;
|
||||
}
|
||||
const int root = islands.find_root(loop.e);
|
||||
|
|
|
@ -680,10 +680,11 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
|
|||
break;
|
||||
}
|
||||
case SCULPT_FACE_SETS_FROM_UV_SEAMS: {
|
||||
const Span<MEdge> edges = mesh->edges();
|
||||
const VArraySpan<bool> uv_seams = mesh->attributes().lookup_or_default<bool>(
|
||||
".uv_seam", ATTR_DOMAIN_EDGE, false);
|
||||
sculpt_face_sets_init_flood_fill(
|
||||
ob, [&](const int /*from_face*/, const int edge, const int /*to_face*/) -> bool {
|
||||
return (edges[edge].flag & ME_SEAM) == 0;
|
||||
return !uv_seams[edge];
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1419,8 +1419,6 @@ static void customdata_weld(
|
|||
int src_i, dest_i;
|
||||
int j;
|
||||
|
||||
short flag = 0;
|
||||
|
||||
/* interpolates a layer at a time */
|
||||
dest_i = 0;
|
||||
for (src_i = 0; src_i < source->totlayer; src_i++) {
|
||||
|
@ -1442,10 +1440,7 @@ static void customdata_weld(
|
|||
if (dest->layers[dest_i].type == type) {
|
||||
void *src_data = source->layers[src_i].data;
|
||||
if (type == CD_MEDGE) {
|
||||
for (j = 0; j < count; j++) {
|
||||
MEdge *me_src = &((MEdge *)src_data)[src_indices[j]];
|
||||
flag |= me_src->flag;
|
||||
}
|
||||
/* Pass. */
|
||||
}
|
||||
else if (CustomData_layer_has_interp(dest, dest_i)) {
|
||||
/* Already calculated.
|
||||
|
@ -1478,8 +1473,7 @@ static void customdata_weld(
|
|||
CustomDataLayer *layer_dst = &dest->layers[dest_i];
|
||||
const int type = layer_dst->type;
|
||||
if (type == CD_MEDGE) {
|
||||
MEdge *me = &((MEdge *)layer_dst->data)[dest_index];
|
||||
me->flag = flag;
|
||||
/* Pass. */
|
||||
}
|
||||
else if (CustomData_layer_has_interp(dest, dest_i)) {
|
||||
/* Already calculated. */
|
||||
|
|
|
@ -32,23 +32,23 @@ typedef struct MEdge {
|
|||
* Deprecated bevel weight storage, now located in #CD_BWEIGHT, except for file read and write.
|
||||
*/
|
||||
char bweight_legacy;
|
||||
short flag;
|
||||
short flag_legacy;
|
||||
} MEdge;
|
||||
|
||||
#ifdef DNA_DEPRECATED_ALLOW
|
||||
/** #MEdge.flag */
|
||||
enum {
|
||||
/** Deprecated selection status. Now stored in ".select_edge" attribute. */
|
||||
/* SELECT = (1 << 0), */
|
||||
ME_SEAM = (1 << 2),
|
||||
/** Deprecated hide status. Now stored in ".hide_edge" attribute. */
|
||||
/* ME_HIDE = (1 << 4), */
|
||||
#ifdef DNA_DEPRECATED_ALLOW
|
||||
/** Deprecated hide status. Now stored in ".hide_edge" attribute. */
|
||||
/* ME_HIDE = (1 << 4), */
|
||||
/** Deprecated loose edge status. Now stored in #Mesh::loose_edges() runtime cache. */
|
||||
ME_LOOSEEDGE = (1 << 7),
|
||||
/** Deprecated sharp edge status. Now stored in "sharp_edge" attribute. */
|
||||
ME_SHARP = (1 << 9),
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Mesh Faces.
|
||||
|
|
|
@ -89,6 +89,7 @@ DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, transparency_mask, material_m
|
|||
DNA_STRUCT_RENAME_ELEM(MDefCell, totinfluence, influences_num)
|
||||
DNA_STRUCT_RENAME_ELEM(MEdge, bweight, bweight_legacy)
|
||||
DNA_STRUCT_RENAME_ELEM(MEdge, crease, crease_legacy)
|
||||
DNA_STRUCT_RENAME_ELEM(MEdge, flag, flag_legacy)
|
||||
DNA_STRUCT_RENAME_ELEM(MPoly, mat_nr, mat_nr_legacy)
|
||||
DNA_STRUCT_RENAME_ELEM(MVert, bweight, bweight_legacy)
|
||||
DNA_STRUCT_RENAME_ELEM(MVert, co, co_legacy)
|
||||
|
|
|
@ -1745,6 +1745,32 @@ static void rna_MeshEdge_use_edge_sharp_set(PointerRNA *ptr, bool value)
|
|||
sharp_edge[index] = value;
|
||||
}
|
||||
|
||||
static bool rna_MeshEdge_use_seam_get(PointerRNA *ptr)
|
||||
{
|
||||
const Mesh *mesh = rna_mesh(ptr);
|
||||
const bool *seam_edge = (const bool *)CustomData_get_layer_named(
|
||||
&mesh->edata, CD_PROP_BOOL, ".uv_seam");
|
||||
const int index = rna_MeshEdge_index_get(ptr);
|
||||
return seam_edge == NULL ? false : seam_edge[index];
|
||||
}
|
||||
|
||||
static void rna_MeshEdge_use_seam_set(PointerRNA *ptr, bool value)
|
||||
{
|
||||
Mesh *mesh = rna_mesh(ptr);
|
||||
bool *seam_edge = (bool *)CustomData_get_layer_named_for_write(
|
||||
&mesh->edata, CD_PROP_BOOL, ".uv_seam", mesh->totedge);
|
||||
if (!seam_edge) {
|
||||
if (!value) {
|
||||
/* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */
|
||||
return;
|
||||
}
|
||||
seam_edge = (bool *)CustomData_add_layer_named(
|
||||
&mesh->edata, CD_PROP_BOOL, CD_SET_DEFAULT, NULL, mesh->totedge, ".uv_seam");
|
||||
}
|
||||
const int index = rna_MeshEdge_index_get(ptr);
|
||||
seam_edge[index] = value;
|
||||
}
|
||||
|
||||
static bool rna_MeshEdge_is_loose_get(PointerRNA *ptr)
|
||||
{
|
||||
const Mesh *mesh = rna_mesh(ptr);
|
||||
|
@ -2718,7 +2744,7 @@ static void rna_def_medge(BlenderRNA *brna)
|
|||
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
|
||||
|
||||
prop = RNA_def_property(srna, "use_seam", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_SEAM);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_MeshEdge_use_seam_get", "rna_MeshEdge_use_seam_set");
|
||||
RNA_def_property_ui_text(prop, "Seam", "Seam edge for UV unwrapping");
|
||||
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
|
||||
|
||||
|
|
|
@ -588,7 +588,6 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh,
|
|||
cut_edge.v1 = dst_loops[mp_dst.loopstart].v;
|
||||
cut_edge.v2 = cut_dst_loop.v;
|
||||
BLI_assert(cut_edge.v1 != cut_edge.v2);
|
||||
cut_edge.flag = 0;
|
||||
edge_index++;
|
||||
|
||||
/* Only handle one of the cuts per iteration. */
|
||||
|
|
|
@ -449,7 +449,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
for (uint i = 0; i < totedge; i++, med_orig++, med_new++) {
|
||||
med_new->v1 = med_orig->v1;
|
||||
med_new->v2 = med_orig->v2;
|
||||
med_new->flag = med_orig->flag;
|
||||
}
|
||||
|
||||
/* build polygon -> edge map */
|
||||
|
@ -801,7 +800,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
/* add the new edge */
|
||||
med_new->v1 = varray_stride + j;
|
||||
med_new->v2 = med_new->v1 - totvert;
|
||||
med_new->flag = 0;
|
||||
med_new++;
|
||||
}
|
||||
}
|
||||
|
@ -819,7 +817,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
for (uint i = 0; i < totvert; i++) {
|
||||
med_new->v1 = i;
|
||||
med_new->v2 = varray_stride + i;
|
||||
med_new->flag = 0;
|
||||
med_new++;
|
||||
}
|
||||
}
|
||||
|
@ -948,7 +945,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
if (step) { /* The first set is already done */
|
||||
med_new->v1 = i1;
|
||||
med_new->v2 = i2;
|
||||
med_new->flag = med_new_firstloop->flag;
|
||||
med_new++;
|
||||
}
|
||||
i1 += totvert;
|
||||
|
@ -975,7 +971,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
/* new vertical edge */
|
||||
med_new->v1 = i1;
|
||||
med_new->v2 = i2;
|
||||
med_new->flag = med_new_firstloop->flag;
|
||||
med_new++;
|
||||
}
|
||||
|
||||
|
|
|
@ -2073,7 +2073,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
|
|||
BLI_assert(v2 != MOD_SOLIDIFY_EMPTY_TAG);
|
||||
edges[insert].v1 = v1;
|
||||
edges[insert].v2 = v2;
|
||||
edges[insert].flag = orig_edges[(*l)->old_edge].flag;
|
||||
if (result_edge_crease) {
|
||||
result_edge_crease[insert] = orig_edge_crease ? orig_edge_crease[(*l)->old_edge] :
|
||||
0.0f;
|
||||
|
@ -2162,14 +2161,10 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
|
|||
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;
|
||||
for (uint j = 0; g->valid; g++) {
|
||||
if ((do_rim && !g->is_orig_closed) || (do_shell && g->split)) {
|
||||
max_crease = 0;
|
||||
max_bweight = 0;
|
||||
flag = 0;
|
||||
|
||||
BLI_assert(g->edges_len >= 2);
|
||||
|
||||
|
@ -2187,7 +2182,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
|
|||
else {
|
||||
for (uint k = 1; k < g->edges_len - 1; k++) {
|
||||
const uint orig_edge_index = g->edges[k]->old_edge;
|
||||
const MEdge *ed = &orig_edges[orig_edge_index];
|
||||
if (result_edge_crease) {
|
||||
if (orig_edge_crease && orig_edge_crease[orig_edge_index] > max_crease) {
|
||||
max_crease = orig_edge_crease[orig_edge_index];
|
||||
|
@ -2201,7 +2195,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
|
|||
}
|
||||
}
|
||||
}
|
||||
flag |= ed->flag;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2222,7 +2215,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
|
|||
first_g = g;
|
||||
first_max_crease = max_crease;
|
||||
first_max_bweight = max_bweight;
|
||||
first_flag = flag;
|
||||
}
|
||||
else {
|
||||
last_g->open_face_edge = edge_index;
|
||||
|
@ -2236,7 +2228,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
|
|||
}
|
||||
edges[edge_index].v1 = last_g->new_vert;
|
||||
edges[edge_index].v2 = g->new_vert;
|
||||
edges[edge_index].flag = ((last_flag | flag) & ME_SEAM);
|
||||
if (result_edge_crease) {
|
||||
result_edge_crease[edge_index] = max_ff(mv_crease,
|
||||
min_ff(last_max_crease, max_crease));
|
||||
|
@ -2250,7 +2241,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
|
|||
last_g = g;
|
||||
last_max_crease = max_crease;
|
||||
last_max_bweight = max_bweight;
|
||||
last_flag = flag;
|
||||
j++;
|
||||
}
|
||||
if (!(g + 1)->valid || g->topo_group != (g + 1)->topo_group) {
|
||||
|
@ -2269,7 +2259,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
|
|||
last_g->open_face_edge = edge_index;
|
||||
edges[edge_index].v1 = last_g->new_vert;
|
||||
edges[edge_index].v2 = first_g->new_vert;
|
||||
edges[edge_index].flag = ((last_flag | first_flag) & ME_SEAM);
|
||||
if (result_edge_crease) {
|
||||
result_edge_crease[edge_index] = max_ff(mv_crease,
|
||||
min_ff(last_max_crease, first_max_crease));
|
||||
|
@ -2373,8 +2362,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
|
|||
first_max_crease = 0;
|
||||
last_max_bweight = 0;
|
||||
first_max_bweight = 0;
|
||||
last_flag = 0;
|
||||
first_flag = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,7 +152,6 @@ static MEdge new_edge(const int v1, const int v2)
|
|||
MEdge edge;
|
||||
edge.v1 = v1;
|
||||
edge.v2 = v2;
|
||||
edge.flag = 0;
|
||||
return edge;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue