Various fixes and cleanups
This commit is contained in:
parent
4ed7b4338d
commit
61de7565de
|
@ -1005,7 +1005,7 @@ static void create_mesh(Scene *scene,
|
|||
if (sharp_faces) {
|
||||
return sharp_faces->data[poly_index].value();
|
||||
}
|
||||
return 0;
|
||||
return false;
|
||||
};
|
||||
|
||||
/* create faces */
|
||||
|
|
|
@ -473,7 +473,7 @@ void BKE_mesh_ensure_normals_for_display(struct Mesh *mesh);
|
|||
* Used when defining an empty custom loop normals data layer,
|
||||
* to keep same shading as with auto-smooth!
|
||||
*
|
||||
* \param sharp_faces: Optional array used to mark specific faces as sharp.
|
||||
* \param sharp_faces: Optional array used to mark specific faces for sharp shading.
|
||||
*/
|
||||
void BKE_edges_sharp_from_angle_set(int numEdges,
|
||||
const struct MLoop *mloops,
|
||||
|
@ -596,7 +596,7 @@ void BKE_lnor_space_custom_normal_to_data(const MLoopNorSpace *lnor_space,
|
|||
* (splitting edges).
|
||||
*
|
||||
* \param loop_to_poly_map: Optional pre-created map from loops to their polygon.
|
||||
* \param sharp_faces: Optional array used to mark specific faces as sharp.
|
||||
* \param sharp_faces: Optional array used to mark specific faces for sharp shading.
|
||||
* \param sharp_edges: Optional array of sharp edge tags, used to split the evaluated normals on
|
||||
* each side of the edge.
|
||||
*/
|
||||
|
|
|
@ -3246,6 +3246,10 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds,
|
|||
mpolys = BKE_mesh_polys_for_write(me);
|
||||
mloops = BKE_mesh_loops_for_write(me);
|
||||
|
||||
const bool is_sharp = orgmesh->attributes().lookup_or_default<bool>(
|
||||
"sharp_face", ATTR_DOMAIN_FACE, false)[0];
|
||||
BKE_mesh_smooth_flag_set(me, !is_sharp);
|
||||
|
||||
/* Get size (dimension) but considering scaling. */
|
||||
copy_v3_v3(cell_size_scaled, fds->cell_size);
|
||||
mul_v3_v3(cell_size_scaled, ob->scale);
|
||||
|
|
|
@ -286,9 +286,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
|
|||
}
|
||||
}
|
||||
|
||||
if (!is_smooth) {
|
||||
sharp_faces.span[dst_poly] = true;
|
||||
}
|
||||
sharp_faces.span[dst_poly] = !is_smooth;
|
||||
dst_poly++;
|
||||
dst_loop += 3;
|
||||
index += 3;
|
||||
|
@ -371,9 +369,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
|
|||
}
|
||||
}
|
||||
|
||||
if (!is_smooth) {
|
||||
sharp_faces.span[dst_poly] = true;
|
||||
}
|
||||
sharp_faces.span[dst_poly] = !is_smooth;
|
||||
dst_poly++;
|
||||
dst_loop += 4;
|
||||
|
||||
|
@ -390,6 +386,14 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
|
|||
make_edges_mdata_extend(*mesh);
|
||||
}
|
||||
|
||||
int sharp_faces_count = 0;
|
||||
for (const bool value : sharp_faces.span) {
|
||||
if (value) {
|
||||
sharp_faces_count++;
|
||||
}
|
||||
}
|
||||
std::cout << "Number of sharp faces: " << sharp_faces_count << '\n';
|
||||
|
||||
material_indices.finish();
|
||||
sharp_faces.finish();
|
||||
|
||||
|
|
|
@ -1855,7 +1855,7 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh)
|
|||
".select_poly", ATTR_DOMAIN_FACE);
|
||||
threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
select_poly.span[i] = (polys[i].flag_legacy & ME_FACE_SEL) != 0;
|
||||
select_poly.span[i] = polys[i].flag_legacy & ME_FACE_SEL;
|
||||
}
|
||||
});
|
||||
select_poly.finish();
|
||||
|
|
|
@ -802,7 +802,7 @@ static void mesh_edges_sharp_tag(const Span<MPoly> polys,
|
|||
{
|
||||
using namespace blender;
|
||||
const float split_angle_cos = check_angle ? cosf(split_angle) : -1.0f;
|
||||
auto face_is_smooth = [&](const int poly_i) {
|
||||
auto poly_is_smooth = [&](const int poly_i) {
|
||||
return sharp_faces.is_empty() || !sharp_faces[poly_i];
|
||||
};
|
||||
|
||||
|
@ -819,7 +819,7 @@ static void mesh_edges_sharp_tag(const Span<MPoly> polys,
|
|||
/* 'Empty' edge until now, set e2l[0] (and e2l[1] to INDEX_UNSET to tag it as unset). */
|
||||
e2l[0] = loop_index;
|
||||
/* We have to check this here too, else we might miss some flat faces!!! */
|
||||
e2l[1] = (face_is_smooth(poly_i)) ? INDEX_UNSET : INDEX_INVALID;
|
||||
e2l[1] = (poly_is_smooth(poly_i)) ? INDEX_UNSET : INDEX_INVALID;
|
||||
}
|
||||
else if (e2l[1] == INDEX_UNSET) {
|
||||
const bool is_angle_sharp = (check_angle &&
|
||||
|
@ -831,7 +831,7 @@ static void mesh_edges_sharp_tag(const Span<MPoly> polys,
|
|||
* or both poly have opposed (flipped) normals, i.e. both loops on the same edge share the
|
||||
* same vertex, or angle between both its polys' normals is above split_angle value.
|
||||
*/
|
||||
if (!face_is_smooth(poly_i) || (!sharp_edges.is_empty() && sharp_edges[edge_i]) ||
|
||||
if (!poly_is_smooth(poly_i) || (!sharp_edges.is_empty() && sharp_edges[edge_i]) ||
|
||||
vert_i == loops[e2l[0]].v || is_angle_sharp) {
|
||||
/* NOTE: we are sure that loop != 0 here ;). */
|
||||
e2l[1] = INDEX_INVALID;
|
||||
|
@ -1944,7 +1944,8 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const
|
|||
MutableAttributeAccessor attributes = mesh->attributes_for_write();
|
||||
SpanAttributeWriter<bool> sharp_edges = attributes.lookup_or_add_for_write_span<bool>(
|
||||
"sharp_edge", ATTR_DOMAIN_EDGE);
|
||||
|
||||
const bool *sharp_faces = static_cast<const bool *>(
|
||||
CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face"));
|
||||
mesh_normals_loop_custom_set(reinterpret_cast<const float(*)[3]>(positions.data()),
|
||||
BKE_mesh_vertex_normals_ensure(mesh),
|
||||
positions.size(),
|
||||
|
@ -1955,8 +1956,7 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const
|
|||
loops.size(),
|
||||
polys.data(),
|
||||
BKE_mesh_poly_normals_ensure(mesh),
|
||||
static_cast<const bool *>(CustomData_get_layer_named(
|
||||
&mesh->pdata, CD_PROP_BOOL, "sharp_face")),
|
||||
sharp_faces,
|
||||
polys.size(),
|
||||
sharp_edges.span,
|
||||
clnors,
|
||||
|
|
|
@ -278,15 +278,14 @@ struct SGLSLMeshToTangent {
|
|||
const float (*precomputedFaceNormals)[3];
|
||||
const float (*precomputedLoopNormals)[3];
|
||||
const MLoopTri *looptri;
|
||||
const float2 *mloopuv; /* texture coordinates */
|
||||
const MPoly *mpoly; /* indices */
|
||||
const MLoop *mloop; /* indices */
|
||||
const MVert *mvert; /* vertex coordinates */
|
||||
const bool *sharp_faces;
|
||||
const float2 *mloopuv; /* texture coordinates */
|
||||
const MPoly *mpoly; /* indices */
|
||||
const MLoop *mloop; /* indices */
|
||||
const float (*positions)[3]; /* vertex coordinates */
|
||||
const float (*vert_normals)[3];
|
||||
const float (*orco)[3];
|
||||
float (*tangent)[4]; /* destination */
|
||||
const bool *sharp_faces;
|
||||
int numTessFaces;
|
||||
|
||||
#ifdef USE_LOOPTRI_DETECT_QUADS
|
||||
|
|
|
@ -437,12 +437,12 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
|
|||
BM_elem_index_set(f, bm->totface - 1); /* set_ok */
|
||||
|
||||
/* Transfer flag. */
|
||||
if (hide_poly && hide_poly[i]) {
|
||||
BM_elem_flag_enable(f, BM_ELEM_HIDDEN);
|
||||
}
|
||||
if (!(sharp_faces && sharp_faces[i])) {
|
||||
BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
|
||||
}
|
||||
if (hide_poly && hide_poly[i]) {
|
||||
BM_elem_flag_enable(f, BM_ELEM_HIDDEN);
|
||||
}
|
||||
if (select_poly && select_poly[i]) {
|
||||
BM_face_select_set(bm, f, true);
|
||||
}
|
||||
|
@ -1174,13 +1174,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
|
|||
ATTR_DOMAIN_FACE,
|
||||
[&](const int i) { return int(BM_face_at_index(bm, i)->mat_nr); });
|
||||
}
|
||||
if (need_sharp_face) {
|
||||
BM_mesh_elem_table_ensure(bm, BM_FACE);
|
||||
write_fn_to_attribute<bool>(
|
||||
me->attributes_for_write(), "sharp_face", ATTR_DOMAIN_FACE, [&](const int i) {
|
||||
return !BM_elem_flag_test(BM_face_at_index(bm, i), BM_ELEM_SMOOTH);
|
||||
});
|
||||
}
|
||||
if (need_sharp_edge) {
|
||||
BM_mesh_elem_table_ensure(bm, BM_EDGE);
|
||||
write_fn_to_attribute<bool>(
|
||||
|
@ -1188,6 +1181,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_sharp_face) {
|
||||
BM_mesh_elem_table_ensure(bm, BM_FACE);
|
||||
write_fn_to_attribute<bool>(
|
||||
me->attributes_for_write(), "sharp_face", ATTR_DOMAIN_FACE, [&](const int i) {
|
||||
return !BM_elem_flag_test(BM_face_at_index(bm, i), BM_ELEM_SMOOTH);
|
||||
});
|
||||
}
|
||||
|
||||
/* Patch hook indices and vertex parents. */
|
||||
if (params->calc_object_remap && (ototvert > 0)) {
|
||||
|
|
|
@ -785,7 +785,7 @@ static void draw_subdiv_cache_extra_coarse_face_data_mapped(Mesh *mesh,
|
|||
/* Selection and hiding from bmesh. */
|
||||
uint32_t flag = (f) ? compute_coarse_face_flag_bm(f, mr->efa_act) : 0;
|
||||
/* Smooth from mesh. */
|
||||
if ((mr->sharp_faces && mr->sharp_faces[i])) {
|
||||
if (!(mr->sharp_faces && mr->sharp_faces[i])) {
|
||||
flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH;
|
||||
}
|
||||
flags_data[i] = uint(polys[i].loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
|
||||
|
|
|
@ -1542,40 +1542,30 @@ void ED_mesh_split_faces(Mesh *mesh)
|
|||
const Span<MPoly> polys = mesh->polys();
|
||||
const Span<MLoop> loops = mesh->loops();
|
||||
const float split_angle = (mesh->flag & ME_AUTOSMOOTH) != 0 ? mesh->smoothresh : float(M_PI);
|
||||
const bool *sharp_faces = static_cast<const bool *>(
|
||||
CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face"));
|
||||
|
||||
Array<bool> sharp_edges(mesh->totedge, false);
|
||||
const bool *sharp_faces_ptr = static_cast<const bool *>(
|
||||
CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face"));
|
||||
BKE_edges_sharp_from_angle_set(mesh->totedge,
|
||||
loops.data(),
|
||||
loops.size(),
|
||||
polys.data(),
|
||||
BKE_mesh_poly_normals_ensure(mesh),
|
||||
sharp_faces_ptr,
|
||||
sharp_faces,
|
||||
polys.size(),
|
||||
split_angle,
|
||||
sharp_edges.data());
|
||||
|
||||
const bke::AttributeAccessor attributes = mesh->attributes();
|
||||
const VArray<bool> sharp_faces = attributes.lookup_or_default<bool>(
|
||||
"sharp_face", ATTR_DOMAIN_FACE, false);
|
||||
if (const std::optional<bool> value = sharp_faces.get_if_single()) {
|
||||
if (value) {
|
||||
sharp_edges.fill(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) {
|
||||
for (const int poly_i : range) {
|
||||
const MPoly &poly = polys[poly_i];
|
||||
if (sharp_faces[poly_i]) {
|
||||
for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
|
||||
sharp_edges[loop.e] = true;
|
||||
}
|
||||
threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) {
|
||||
for (const int poly_i : range) {
|
||||
const MPoly &poly = polys[poly_i];
|
||||
if (sharp_faces && sharp_faces[poly_i]) {
|
||||
for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
|
||||
sharp_edges[loop.e] = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Vector<int64_t> split_indices;
|
||||
const IndexMask split_mask = index_mask_ops::find_indices_from_virtual_array(
|
||||
|
|
|
@ -1474,12 +1474,12 @@ struct EdgeFeatData {
|
|||
Object *ob_eval; /* For evaluated materials. */
|
||||
const MLoopTri *mlooptri;
|
||||
const int *material_indices;
|
||||
blender::VArray<bool> sharp_faces;
|
||||
blender::Span<MEdge> edges;
|
||||
blender::Span<MLoop> loops;
|
||||
blender::Span<MPoly> polys;
|
||||
LineartTriangle *tri_array;
|
||||
blender::VArray<bool> sharp_edges;
|
||||
blender::VArray<bool> sharp_faces;
|
||||
LineartVert *v_array;
|
||||
float crease_threshold;
|
||||
bool use_auto_smooth;
|
||||
|
@ -1937,9 +1937,6 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info,
|
|||
const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me);
|
||||
const int tot_tri = BKE_mesh_runtime_looptri_len(me);
|
||||
|
||||
const bke::AttributeAccessor attributes = me->attributes();
|
||||
const VArray<bool> sharp_faces = attributes.lookup_or_default<bool>(
|
||||
"sharp_face", ATTR_DOMAIN_FACE, false);
|
||||
const int *material_indices = (const int *)CustomData_get_layer_named(
|
||||
&me->pdata, CD_PROP_INT32, "material_index");
|
||||
|
||||
|
@ -2073,8 +2070,11 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info,
|
|||
edge_feat_settings.userdata_chunk_size = sizeof(EdgeFeatReduceData);
|
||||
edge_feat_settings.func_reduce = feat_data_sum_reduce;
|
||||
|
||||
const bke::AttributeAccessor attributes = me->attributes();
|
||||
const VArray<bool> sharp_edges = attributes.lookup_or_default<bool>(
|
||||
"sharp_edge", ATTR_DOMAIN_EDGE, false);
|
||||
const VArray<bool> sharp_faces = attributes.lookup_or_default<bool>(
|
||||
"sharp_face", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
EdgeFeatData edge_feat_data = {nullptr};
|
||||
edge_feat_data.ld = la_data;
|
||||
|
@ -2082,11 +2082,11 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info,
|
|||
edge_feat_data.ob_eval = ob_info->original_ob_eval;
|
||||
edge_feat_data.mlooptri = mlooptri;
|
||||
edge_feat_data.material_indices = material_indices;
|
||||
edge_feat_data.sharp_faces = sharp_faces;
|
||||
edge_feat_data.edges = me->edges();
|
||||
edge_feat_data.polys = me->polys();
|
||||
edge_feat_data.loops = me->loops();
|
||||
edge_feat_data.sharp_edges = sharp_edges;
|
||||
edge_feat_data.sharp_faces = sharp_faces;
|
||||
edge_feat_data.edge_nabr = lineart_build_edge_neighbor(me, total_edges);
|
||||
edge_feat_data.tri_array = la_tri_arr;
|
||||
edge_feat_data.v_array = la_v_arr;
|
||||
|
|
|
@ -625,11 +625,11 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh,
|
|||
MaterialIdPrimitiveArrayMap mat_prim_map;
|
||||
|
||||
int *material_indices = BKE_mesh_material_indices_for_write(me);
|
||||
bool *sharp_faces = (bool *)CustomData_get_layer_named_for_write(
|
||||
&me->pdata, CD_PROP_BOOL, "sharp_face", me->totpoly);
|
||||
if (sharp_faces) {
|
||||
sharp_faces = (bool *)CustomData_add_layer_named(
|
||||
&me->pdata, CD_PROP_BOOL, CD_SET_DEFAULT, NULL, me->totpoly, "sharp_face");
|
||||
bool *sharp_faces = static_cast<bool *>(
|
||||
CustomData_get_layer_named_for_write(&me->pdata, CD_PROP_BOOL, "sharp_face", me->totpoly));
|
||||
if (!sharp_faces) {
|
||||
sharp_faces = static_cast<bool *>(CustomData_add_layer_named(
|
||||
&me->pdata, CD_PROP_BOOL, CD_SET_DEFAULT, NULL, me->totpoly, "sharp_face"));
|
||||
}
|
||||
|
||||
COLLADAFW::MeshPrimitiveArray &prim_arr = collada_mesh->getMeshPrimitives();
|
||||
|
@ -673,9 +673,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh,
|
|||
if (mp_has_normals) { /* vertex normals, same implementation as for the triangles */
|
||||
/* The same for vertices normals. */
|
||||
uint vertex_normal_indices[3] = {first_normal, normal_indices[1], normal_indices[2]};
|
||||
if (is_flat_face(vertex_normal_indices, nor, 3)) {
|
||||
*sharp_faces = true;
|
||||
}
|
||||
*sharp_faces = is_flat_face(vertex_normal_indices, nor, 3);
|
||||
normal_indices++;
|
||||
}
|
||||
|
||||
|
@ -746,9 +744,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh,
|
|||
if (mp_has_normals) {
|
||||
/* If it turns out that we have complete custom normals for each MPoly
|
||||
* and we want to use custom normals, this will be overridden. */
|
||||
if (!is_flat_face(normal_indices, nor, vcount)) {
|
||||
*sharp_faces = true;
|
||||
}
|
||||
*sharp_faces = is_flat_face(normal_indices, nor, vcount);
|
||||
|
||||
if (use_custom_normals) {
|
||||
/* Store the custom normals for later application. */
|
||||
|
|
|
@ -41,7 +41,6 @@ class OBJMesh : NonCopyable {
|
|||
Span<MEdge> mesh_edges_;
|
||||
Span<MPoly> mesh_polys_;
|
||||
Span<MLoop> mesh_loops_;
|
||||
|
||||
VArray<bool> sharp_faces_;
|
||||
|
||||
/**
|
||||
|
|
|
@ -203,9 +203,7 @@ void MeshFromGeometry::create_polys_loops(Mesh *mesh, bool use_vertex_groups)
|
|||
MPoly &mpoly = polys[poly_idx];
|
||||
mpoly.totloop = curr_face.corner_count_;
|
||||
mpoly.loopstart = tot_loop_idx;
|
||||
if (!curr_face.shaded_smooth) {
|
||||
sharp_faces.span[poly_idx] = true;
|
||||
}
|
||||
sharp_faces.span[poly_idx] = !curr_face.shaded_smooth;
|
||||
material_indices.span[poly_idx] = curr_face.material_index;
|
||||
/* Importing obj files without any materials would result in negative indices, which is not
|
||||
* supported. */
|
||||
|
|
|
@ -674,8 +674,8 @@ static void rna_MeshPolygon_use_smooth_set(PointerRNA *ptr, bool value)
|
|||
bool *sharp_faces = (bool *)CustomData_get_layer_named_for_write(
|
||||
&mesh->pdata, CD_PROP_BOOL, "sharp_face", mesh->totpoly);
|
||||
if (!sharp_faces) {
|
||||
if (value) {
|
||||
/* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */
|
||||
if (!value) {
|
||||
/* Skip adding layer if the value is the same as the default. */
|
||||
return;
|
||||
}
|
||||
sharp_faces = (bool *)CustomData_add_layer_named(
|
||||
|
@ -2855,9 +2855,9 @@ static void rna_def_mpolygon(BlenderRNA *brna)
|
|||
RNA_def_property_update(prop, 0, "rna_Mesh_update_select");
|
||||
|
||||
prop = RNA_def_property(srna, "use_smooth", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Smooth", "");
|
||||
RNA_def_property_boolean_funcs(
|
||||
prop, "rna_MeshPolygon_use_smooth_get", "rna_MeshPolygon_use_smooth_set");
|
||||
RNA_def_property_ui_text(prop, "Smooth", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
|
||||
|
||||
prop = RNA_def_property(srna, "use_freestyle_mark", PROP_BOOLEAN, PROP_NONE);
|
||||
|
|
|
@ -336,7 +336,8 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd,
|
|||
/* We need to recompute vertex normals! */
|
||||
BKE_mesh_normals_tag_dirty(mesh);
|
||||
}
|
||||
|
||||
const bool *sharp_faces = static_cast<const bool *>(
|
||||
CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face"));
|
||||
BKE_mesh_normals_loop_custom_set(vert_positions,
|
||||
BKE_mesh_vertex_normals_ensure(mesh),
|
||||
verts_num,
|
||||
|
@ -347,8 +348,7 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd,
|
|||
loops_num,
|
||||
mpoly,
|
||||
poly_normals,
|
||||
static_cast<const bool *>(CustomData_get_layer_named(
|
||||
&mesh->pdata, CD_PROP_BOOL, "sharp_face")),
|
||||
sharp_faces,
|
||||
polys_num,
|
||||
sharp_edges,
|
||||
clnors);
|
||||
|
@ -460,7 +460,8 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd,
|
|||
polys_num)) {
|
||||
BKE_mesh_normals_tag_dirty(mesh);
|
||||
}
|
||||
|
||||
const bool *sharp_faces = static_cast<const bool *>(
|
||||
CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face"));
|
||||
BKE_mesh_normals_loop_custom_set(positions,
|
||||
BKE_mesh_vertex_normals_ensure(mesh),
|
||||
verts_num,
|
||||
|
@ -471,8 +472,7 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd,
|
|||
loops_num,
|
||||
mpoly,
|
||||
poly_normals,
|
||||
static_cast<const bool *>(CustomData_get_layer_named(
|
||||
&mesh->pdata, CD_PROP_BOOL, "sharp_face")),
|
||||
sharp_faces,
|
||||
polys_num,
|
||||
sharp_edges,
|
||||
clnors);
|
||||
|
|
|
@ -197,7 +197,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext * /*ctx*/, M
|
|||
MEM_freeN(output);
|
||||
}
|
||||
|
||||
BKE_mesh_smooth_flag_set(result, (rmd->flag & MOD_REMESH_SMOOTH_SHADING));
|
||||
BKE_mesh_smooth_flag_set(result, rmd->flag & MOD_REMESH_SMOOTH_SHADING);
|
||||
|
||||
BKE_mesh_copy_parameters_for_eval(result, mesh);
|
||||
BKE_mesh_calc_edges(result, true, false);
|
||||
|
|
|
@ -44,7 +44,6 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords)
|
|||
result = BKE_mesh_new_nomain(verts_num, edges_num, 0, loops_num, faces_num);
|
||||
BKE_id_material_eval_ensure_default_slot(&result->id);
|
||||
}
|
||||
|
||||
BKE_mesh_smooth_flag_set(result, false);
|
||||
|
||||
/* Copy vertices. */
|
||||
|
|
|
@ -109,11 +109,11 @@ static Mesh *create_circle_mesh(const float radius,
|
|||
circle_corner_total(fill_type, verts_num),
|
||||
circle_face_total(fill_type, verts_num));
|
||||
BKE_id_material_eval_ensure_default_slot(&mesh->id);
|
||||
BKE_mesh_smooth_flag_set(mesh, false);
|
||||
MutableSpan<float3> positions = mesh->vert_positions_for_write();
|
||||
MutableSpan<MEdge> edges = mesh->edges_for_write();
|
||||
MutableSpan<MPoly> polys = mesh->polys_for_write();
|
||||
MutableSpan<MLoop> loops = mesh->loops_for_write();
|
||||
BKE_mesh_smooth_flag_set(mesh, false);
|
||||
|
||||
/* Assign vertex coordinates. */
|
||||
const float angle_delta = 2.0f * (M_PI / float(verts_num));
|
||||
|
|
|
@ -690,13 +690,13 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top,
|
|||
|
||||
Mesh *mesh = BKE_mesh_new_nomain(
|
||||
config.tot_verts, config.tot_edges, 0, config.tot_corners, config.tot_faces);
|
||||
BKE_mesh_smooth_flag_set(mesh, false);
|
||||
BKE_id_material_eval_ensure_default_slot(&mesh->id);
|
||||
|
||||
MutableSpan<float3> positions = mesh->vert_positions_for_write();
|
||||
MutableSpan<MEdge> edges = mesh->edges_for_write();
|
||||
MutableSpan<MPoly> polys = mesh->polys_for_write();
|
||||
MutableSpan<MLoop> loops = mesh->loops_for_write();
|
||||
BKE_mesh_smooth_flag_set(mesh, false);
|
||||
|
||||
calculate_cone_verts(config, positions);
|
||||
calculate_cone_edges(config, edges);
|
||||
|
|
|
@ -54,11 +54,11 @@ Mesh *create_grid_mesh(const int verts_x,
|
|||
0,
|
||||
edges_x * edges_y * 4,
|
||||
edges_x * edges_y);
|
||||
BKE_mesh_smooth_flag_set(mesh, false);
|
||||
MutableSpan<float3> positions = mesh->vert_positions_for_write();
|
||||
MutableSpan<MEdge> edges = mesh->edges_for_write();
|
||||
MutableSpan<MPoly> polys = mesh->polys_for_write();
|
||||
MutableSpan<MLoop> loops = mesh->loops_for_write();
|
||||
BKE_mesh_smooth_flag_set(mesh, false);
|
||||
|
||||
{
|
||||
const float dx = edges_x == 0 ? 0.0f : size_x / edges_x;
|
||||
|
|
|
@ -315,12 +315,12 @@ static Mesh *create_uv_sphere_mesh(const float radius,
|
|||
0,
|
||||
sphere_corner_total(segments, rings),
|
||||
sphere_face_total(segments, rings));
|
||||
BKE_mesh_smooth_flag_set(mesh, false);
|
||||
BKE_id_material_eval_ensure_default_slot(&mesh->id);
|
||||
MutableSpan<float3> positions = mesh->vert_positions_for_write();
|
||||
MutableSpan<MEdge> edges = mesh->edges_for_write();
|
||||
MutableSpan<MPoly> polys = mesh->polys_for_write();
|
||||
MutableSpan<MLoop> loops = mesh->loops_for_write();
|
||||
BKE_mesh_smooth_flag_set(mesh, false);
|
||||
|
||||
threading::parallel_invoke(
|
||||
1024 < segments * rings,
|
||||
|
|
|
@ -16,8 +16,8 @@ static void node_declare(NodeDeclarationBuilder &b)
|
|||
|
||||
/**
|
||||
* When the `sharp_face` attribute doesn't exist, all faces are considered smooth. If all faces
|
||||
* are selected and the sharp value is a constant false value, we can remove the attribute instead,
|
||||
* as an optimization to avoid propagating and storing it in the future.
|
||||
* are selected and the sharp value is a constant false value, we can remove the attribute instead
|
||||
* as an optimization to avoid storing it and propagating it in the future.
|
||||
*/
|
||||
static bool try_removing_sharp_attribute(Mesh &mesh,
|
||||
const Field<bool> &selection_field,
|
||||
|
@ -38,14 +38,13 @@ static bool try_removing_sharp_attribute(Mesh &mesh,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void set_smooth(Mesh &mesh,
|
||||
const Field<bool> &selection_field,
|
||||
const Field<bool> &sharp_field)
|
||||
static void set_sharp_faces(Mesh &mesh,
|
||||
const Field<bool> &selection_field,
|
||||
const Field<bool> &sharp_field)
|
||||
{
|
||||
if (mesh.totpoly == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (try_removing_sharp_attribute(mesh, selection_field, sharp_field)) {
|
||||
return;
|
||||
}
|
||||
|
@ -71,7 +70,7 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
|
||||
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
|
||||
if (Mesh *mesh = geometry_set.get_mesh_for_write()) {
|
||||
set_smooth(*mesh, selection_field, fn::invert_boolean_field(smooth_field));
|
||||
set_sharp_faces(*mesh, selection_field, fn::invert_boolean_field(smooth_field));
|
||||
}
|
||||
});
|
||||
params.set_output("Geometry", std::move(geometry_set));
|
||||
|
|
Loading…
Reference in New Issue