From d7ee9cca5252fc0c8a2e865109b44b51d80743db Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 28 Mar 2023 11:56:05 -0400 Subject: [PATCH 1/9] Progess --- intern/cycles/blender/mesh.cpp | 209 +++++++++++++++++++-------------- intern/cycles/util/color.h | 5 + 2 files changed, 129 insertions(+), 85 deletions(-) diff --git a/intern/cycles/blender/mesh.cpp b/intern/cycles/blender/mesh.cpp index 3cd762bbf05..3b7ae1c3e24 100644 --- a/intern/cycles/blender/mesh.cpp +++ b/intern/cycles/blender/mesh.cpp @@ -412,43 +412,46 @@ static void attr_create_generic(Scene *scene, switch (b_data_type) { case BL::Attribute::data_type_FLOAT: { BL::FloatAttribute b_float_attribute{b_attribute}; + const float *b_data = static_cast(b_float_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeFloat, element); float *data = attr->data_float(); - fill_generic_attribute(b_mesh, data, b_domain, subdivision, [&](int i) { - return b_float_attribute.data[i].value(); - }); + fill_generic_attribute( + b_mesh, data, b_domain, subdivision, [&](int i) { return b_data[i]; }); break; } case BL::Attribute::data_type_BOOLEAN: { BL::BoolAttribute b_bool_attribute{b_attribute}; + const bool *b_data = static_cast(b_bool_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeFloat, element); float *data = attr->data_float(); - fill_generic_attribute(b_mesh, data, b_domain, subdivision, [&](int i) { - return (float)b_bool_attribute.data[i].value(); - }); + fill_generic_attribute( + b_mesh, data, b_domain, subdivision, [&](int i) { return (float)b_data[i]; }); break; } case BL::Attribute::data_type_INT: { BL::IntAttribute b_int_attribute{b_attribute}; + const int *b_data = static_cast(b_int_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeFloat, element); float *data = attr->data_float(); - fill_generic_attribute(b_mesh, data, b_domain, subdivision, [&](int i) { - return (float)b_int_attribute.data[i].value(); - }); + fill_generic_attribute( + b_mesh, data, b_domain, subdivision, [&](int i) { return (float)b_data[i]; }); break; } case BL::Attribute::data_type_FLOAT_VECTOR: { BL::FloatVectorAttribute b_vector_attribute{b_attribute}; + const float(*b_data)[3] = static_cast( + b_vector_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeVector, element); float3 *data = attr->data_float3(); fill_generic_attribute(b_mesh, data, b_domain, subdivision, [&](int i) { - BL::Array v = b_vector_attribute.data[i].vector(); - return make_float3(v[0], v[1], v[2]); + return make_float3(b_data[i][0], b_data[i][1], b_data[i][2]); }); break; } case BL::Attribute::data_type_BYTE_COLOR: { BL::ByteColorAttribute b_color_attribute{b_attribute}; + const uchar(*b_data)[4] = static_cast( + b_color_attribute.data[0].ptr.data); if (element == ATTR_ELEMENT_CORNER) { element = ATTR_ELEMENT_CORNER_BYTE; @@ -462,21 +465,24 @@ static void attr_create_generic(Scene *scene, uchar4 *data = attr->data_uchar4(); fill_generic_attribute(b_mesh, data, b_domain, subdivision, [&](int i) { /* Compress/encode vertex color using the sRGB curve. */ - const float4 c = get_float4(b_color_attribute.data[i].color()); - return color_float4_to_uchar4(color_linear_to_srgb_v4(c)); + return make_uchar4(b_data[i][0], b_data[i][1], b_data[i][2], b_data[i][3]); }); } else { float4 *data = attr->data_float4(); fill_generic_attribute(b_mesh, data, b_domain, subdivision, [&](int i) { - BL::Array v = b_color_attribute.data[i].color(); - return make_float4(v[0], v[1], v[2], v[3]); + return make_float4(color_srgb_to_linear(byte_to_float(b_data[i][0])), + color_srgb_to_linear(byte_to_float(b_data[i][1])), + color_srgb_to_linear(byte_to_float(b_data[i][2])), + color_srgb_to_linear(byte_to_float(b_data[i][3]))); }); } break; } case BL::Attribute::data_type_FLOAT_COLOR: { BL::FloatColorAttribute b_color_attribute{b_attribute}; + const float(*b_data)[4] = static_cast( + b_color_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeRGBA, element); if (is_render_color) { @@ -485,18 +491,18 @@ static void attr_create_generic(Scene *scene, float4 *data = attr->data_float4(); fill_generic_attribute(b_mesh, data, b_domain, subdivision, [&](int i) { - BL::Array v = b_color_attribute.data[i].color(); - return make_float4(v[0], v[1], v[2], v[3]); + return make_float4(b_data[i][0], b_data[i][1], b_data[i][2], b_data[i][3]); }); break; } case BL::Attribute::data_type_FLOAT2: { BL::Float2Attribute b_float2_attribute{b_attribute}; + const float(*b_data)[2] = static_cast( + b_float2_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeFloat2, element); float2 *data = attr->data_float2(); fill_generic_attribute(b_mesh, data, b_domain, subdivision, [&](int i) { - BL::Array v = b_float2_attribute.data[i].vector(); - return make_float2(v[0], v[1]); + return make_float2(b_data[i][0], b_data[i][1]); }); break; } @@ -818,7 +824,7 @@ static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, b } } -static std::optional find_corner_vert_attribute(BL::Mesh b_mesh) +static const int *find_corner_vert_attribute(BL::Mesh b_mesh) { for (BL::Attribute &b_attribute : b_mesh.attributes) { if (b_attribute.domain() != BL::Attribute::domain_CORNER) { @@ -830,9 +836,9 @@ static std::optional find_corner_vert_attribute(BL::Mesh b_mes if (b_attribute.name() != ".corner_vert") { continue; } - return BL::IntAttribute{b_attribute}; + return static_cast(BL::IntAttribute(b_attribute).data[0].ptr.data); } - return std::nullopt; + return nullptr; } /* The Random Per Island attribute is a random float associated with each @@ -881,10 +887,10 @@ static void attr_create_random_per_island(Scene *scene, else { if (polys_num != 0) { const MPoly *polys = static_cast(b_mesh.polygons[0].ptr.data); - BL::IntAttribute corner_verts = *find_corner_vert_attribute(b_mesh); + const int *corner_verts = find_corner_vert_attribute(b_mesh); for (int i = 0; i < polys_num; i++) { const MPoly &b_poly = polys[i]; - const int vert = corner_verts.data[b_poly.loopstart].value(); + const int vert = corner_verts[b_poly.loopstart]; data[i] = hash_uint_to_float(vertices_sets.find(vert)); } } @@ -893,7 +899,7 @@ static void attr_create_random_per_island(Scene *scene, /* Create Mesh */ -static std::optional find_material_index_attribute(BL::Mesh b_mesh) +static const int *find_material_index_attribute(BL::Mesh b_mesh) { for (BL::Attribute &b_attribute : b_mesh.attributes) { if (b_attribute.domain() != BL::Attribute::domain_FACE) { @@ -905,12 +911,12 @@ static std::optional find_material_index_attribute(BL::Mesh b_ if (b_attribute.name() != "material_index") { continue; } - return BL::IntAttribute{b_attribute}; + return static_cast(BL::IntAttribute{b_attribute}.data[0].ptr.data); } - return std::nullopt; + return nullptr; } -static std::optional find_sharp_face_attribute(BL::Mesh b_mesh) +static const bool *find_sharp_face_attribute(BL::Mesh b_mesh) { for (BL::Attribute &b_attribute : b_mesh.attributes) { if (b_attribute.domain() != BL::Attribute::domain_FACE) { @@ -922,9 +928,9 @@ static std::optional find_sharp_face_attribute(BL::Mesh b_mes if (b_attribute.name() != "sharp_face") { continue; } - return BL::BoolAttribute{b_attribute}; + return static_cast(BL::BoolAttribute{b_attribute}.data[0].ptr.data); } - return std::nullopt; + return nullptr; } static void create_mesh(Scene *scene, @@ -936,13 +942,12 @@ static void create_mesh(Scene *scene, const bool subdivision = false, const bool subdivide_uvs = true) { - /* count vertices and faces */ - int numverts = b_mesh.vertices.length(); + scoped_timer timer; + + const int numverts = b_mesh.vertices.length(); const int polys_num = b_mesh.polygons.length(); int numfaces = (!subdivision) ? b_mesh.loop_triangles.length() : b_mesh.polygons.length(); - int numtris = 0; - int numcorners = 0; - int numngons = 0; + const int numcorners = b_mesh.loops.length(); bool use_loop_normals = b_mesh.use_auto_smooth() && (mesh->get_subdivision_type() != Mesh::SUBDIVISION_CATMULL_CLARK); @@ -952,7 +957,13 @@ static void create_mesh(Scene *scene, } const float(*positions)[3] = static_cast(b_mesh.vertices[0].ptr.data); + const int *corner_verts = find_corner_vert_attribute(b_mesh); + const int *material_indices = find_material_index_attribute(b_mesh); + const bool *sharp_faces = find_sharp_face_attribute(b_mesh); + const float(*corner_normals)[3] = static_cast(b_mesh.loops[0].ptr.data); + int numngons = 0; + int numtris = 0; if (!subdivision) { numtris = numfaces; } @@ -961,20 +972,23 @@ static void create_mesh(Scene *scene, for (int i = 0; i < polys_num; i++) { const MPoly &b_poly = polys[i]; numngons += (b_poly.totloop == 4) ? 0 : 1; - numcorners += b_poly.totloop; } } /* allocate memory */ + mesh->get_verts().resize(numverts); if (subdivision) { - mesh->reserve_subd_faces(numfaces, numngons, numcorners); + mesh->resize_subd_faces(numfaces, numngons, numcorners); + } + else { + mesh->get_triangles().resize(numtris * 3); + mesh->get_shader().resize(numtris); + mesh->get_smooth().resize(numtris); } - mesh->reserve_mesh(numverts, numtris); - - /* create vertex coordinates and normals */ + float3 *verts = mesh->get_verts().data(); for (int i = 0; i < numverts; i++) { - mesh->add_vertex(make_float3(positions[i][0], positions[i][1], positions[i][2])); + verts[i] = make_float3(positions[i][0], positions[i][1], positions[i][2]); } AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes; @@ -1009,66 +1023,89 @@ static void create_mesh(Scene *scene, } } - std::optional material_indices = find_material_index_attribute(b_mesh); - auto get_material_index = [&](const int poly_index) -> int { - if (material_indices) { - return clamp(material_indices->data[poly_index].value(), 0, used_shaders.size() - 1); - } - return 0; - }; - - std::optional sharp_faces = find_sharp_face_attribute(b_mesh); - auto get_face_sharp = [&](const int poly_index) -> bool { - if (sharp_faces) { - return sharp_faces->data[poly_index].value(); - } - return false; + auto clamp_material_index = [&](const int material_index) -> int { + return clamp(material_index, 0, used_shaders.size() - 1); }; /* create faces */ if (!subdivision) { - for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) { - const int poly_index = t.polygon_index(); - int3 vi = get_int3(t.vertices()); + int *triangles = mesh->get_triangles().data(); + bool *smooth = mesh->get_smooth().data(); + int *shader = mesh->get_shader().data(); - int shader = get_material_index(poly_index); - bool smooth = !get_face_sharp(poly_index) || use_loop_normals; + const MLoopTri *looptris = static_cast(b_mesh.loop_triangles[0].ptr.data); + for (int i = 0; i < numtris; i++) { + const MLoopTri &tri = looptris[i]; + triangles[i * 3 + 0] = corner_verts[tri.tri[0]]; + triangles[i * 3 + 1] = corner_verts[tri.tri[1]]; + triangles[i * 3 + 2] = corner_verts[tri.tri[2]]; + } - if (use_loop_normals) { - BL::Array loop_normals = t.split_normals(); + if (material_indices) { + for (int i = 0; i < numtris; i++) { + const int poly_index = looptris[i].poly; + shader[i] = clamp_material_index(material_indices[poly_index]); + } + } + else { + std::fill(shader, shader + numtris, 0); + } + + if (sharp_faces && !use_loop_normals) { + for (int i = 0; i < numtris; i++) { + const int poly_index = looptris[i].poly; + smooth[i] = !sharp_faces[poly_index]; + } + } + else { + std::fill(smooth, smooth + numtris, true); + } + + if (use_loop_normals && corner_normals) { + for (int i = 0; i < numtris; i++) { + const MLoopTri &tri = looptris[i]; for (int i = 0; i < 3; i++) { - N[vi[i]] = make_float3( - loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]); + const int corner = tri.tri[i]; + const int vert = corner_verts[corner]; + const float *normal = corner_normals[corner]; + N[vert] = make_float3(normal[0], normal[1], normal[2]); } } - - /* Create triangles. - * - * NOTE: Autosmooth is already taken care about. - */ - mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth); } } else { - vector vi; + int *subd_start_corner = mesh->get_subd_start_corner().data(); + int *subd_num_corners = mesh->get_subd_num_corners().data(); + int *subd_shader = mesh->get_subd_shader().data(); + bool *subd_smooth = mesh->get_subd_smooth().data(); + int *subd_ptex_offset = mesh->get_subd_ptex_offset().data(); + if (sharp_faces) { + for (int i = 0; i < numfaces; i++) { + subd_smooth[i] = !sharp_faces[i]; + } + } + else { + std::fill(subd_smooth, subd_smooth + numfaces, true); + } + + if (material_indices) { + for (int i = 0; i < numfaces; i++) { + subd_shader[i] = clamp_material_index(material_indices[i]); + } + } + else { + std::fill(subd_shader, subd_shader + numfaces, 0); + } + + int ptex_offset = 0; const MPoly *polys = static_cast(b_mesh.polygons[0].ptr.data); - std::optional corner_verts = find_corner_vert_attribute(b_mesh); - for (int i = 0; i < numfaces; i++) { const MPoly &b_poly = polys[i]; - int n = b_poly.totloop; - int shader = get_material_index(i); - bool smooth = !get_face_sharp(i) || use_loop_normals; - - vi.resize(n); - for (int i = 0; i < n; i++) { - /* NOTE: Autosmooth is already taken care about. */ - vi[i] = corner_verts->data[b_poly.loopstart + i].value(); - } - - /* create subd faces */ - mesh->add_subd_face(&vi[0], n, shader, smooth); + subd_start_corner[i] = b_poly.loopstart; + subd_num_corners[i] = b_poly.totloop; + subd_ptex_offset[i] = ptex_offset; + ptex_offset += b_poly.totloop == 4 ? 1 : b_poly.totloop; } } @@ -1098,6 +1135,8 @@ static void create_mesh(Scene *scene, *tfm = transform_translate(-loc) * transform_scale(size); } + + std::cout << time_human_readable_from_seconds(timer.get_time()) << '\n'; } static void create_subd_mesh(Scene *scene, diff --git a/intern/cycles/util/color.h b/intern/cycles/util/color.h index 93e984120f2..701b710a373 100644 --- a/intern/cycles/util/color.h +++ b/intern/cycles/util/color.h @@ -19,6 +19,11 @@ ccl_device uchar float_to_byte(float val) ((val > (1.0f - 0.5f / 255.0f)) ? 255 : (uchar)((255.0f * val) + 0.5f))); } +ccl_device float byte_to_float(uchar val) +{ + return val * (1.0f / 255.0f); +} + ccl_device uchar4 color_float_to_byte(float3 c) { uchar r, g, b; -- 2.30.2 From f4d9b6fa31d4d6d4e221ddda3848fc2f139cb191 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 29 Mar 2023 12:42:53 -0400 Subject: [PATCH 2/9] Mesh: Add RNA collection property for corner normals --- source/blender/makesrna/intern/rna_mesh.c | 52 +++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 7d4a0fa2391..b334b91c7ca 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -2096,6 +2096,40 @@ int rna_Mesh_poly_normals_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_p return true; } +static void rna_Mesh_corner_normals_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + const Mesh *mesh = rna_mesh(ptr); + const float(*normals)[3] = CustomData_get_layer(&mesh->ldata, CD_NORMAL); + if (!normals) { + iter->valid = false; + return; + } + rna_iterator_array_begin(iter, (void *)normals, sizeof(float[3]), mesh->totloop, false, NULL); +} + +static int rna_Mesh_corner_normals_length(PointerRNA *ptr) +{ + const Mesh *mesh = rna_mesh(ptr); + if (!CustomData_has_layer(&mesh->ldata, CD_NORMAL)) { + return 0; + } + return mesh->totloop; +} + +int rna_Mesh_corner_normals_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr) +{ + const Mesh *mesh = rna_mesh(ptr); + const float(*normals)[3] = CustomData_get_layer(&mesh->ldata, CD_NORMAL); + if (index < 0 || index >= mesh->totloop || !normals) { + return false; + } + /* Casting away const is okay because this RNA type doesn't allow changing the value. */ + r_ptr->owner_id = (ID *)&mesh->id; + r_ptr->type = &RNA_MeshNormalValue; + r_ptr->data = (float *)normals[index]; + return true; +} + static char *rna_MeshUVLoop_path(const PointerRNA *ptr) { return rna_LoopCustomData_data_path(ptr, "uv_layers", CD_PROP_FLOAT2); @@ -4218,6 +4252,24 @@ static void rna_def_mesh(BlenderRNA *brna) NULL, NULL); + prop = RNA_def_property(srna, "corner_normals", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "MeshNormalValue"); + RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); + RNA_def_property_ui_text( + prop, + "Corner Normals", + "The \"slit\" normal direction of each face corner, influenced by vertex normals, " + "sharp faces, sharp edges, and custom normals. May be empty"); + RNA_def_property_collection_funcs(prop, + "rna_Mesh_corner_normals_begin", + "rna_iterator_array_next", + "rna_iterator_array_end", + "rna_iterator_array_get", + "rna_Mesh_corner_normals_length", + "rna_Mesh_corner_normals_lookup_int", + NULL, + NULL); + prop = RNA_def_property(srna, "loop_triangles", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_funcs(prop, "rna_Mesh_loop_triangles_begin", -- 2.30.2 From 74a31fb62c53e99e75c0ba9e0a31f569fc3076b6 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 29 Mar 2023 12:42:59 -0400 Subject: [PATCH 3/9] Progress --- intern/cycles/blender/mesh.cpp | 94 ++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 43 deletions(-) diff --git a/intern/cycles/blender/mesh.cpp b/intern/cycles/blender/mesh.cpp index 5fccd2ed899..c4f0750a63e 100644 --- a/intern/cycles/blender/mesh.cpp +++ b/intern/cycles/blender/mesh.cpp @@ -412,46 +412,43 @@ static void attr_create_generic(Scene *scene, switch (b_data_type) { case BL::Attribute::data_type_FLOAT: { BL::FloatAttribute b_float_attribute{b_attribute}; - const float *b_data = static_cast(b_float_attribute.data[0].ptr.data); + const float *src = static_cast(b_float_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeFloat, element); float *data = attr->data_float(); - fill_generic_attribute( - b_mesh, data, b_domain, subdivision, [&](int i) { return b_data[i]; }); + fill_generic_attribute(b_mesh, data, b_domain, subdivision, [&](int i) { return src[i]; }); break; } case BL::Attribute::data_type_BOOLEAN: { BL::BoolAttribute b_bool_attribute{b_attribute}; - const bool *b_data = static_cast(b_bool_attribute.data[0].ptr.data); + const bool *src = static_cast(b_bool_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeFloat, element); float *data = attr->data_float(); fill_generic_attribute( - b_mesh, data, b_domain, subdivision, [&](int i) { return (float)b_data[i]; }); + b_mesh, data, b_domain, subdivision, [&](int i) { return (float)src[i]; }); break; } case BL::Attribute::data_type_INT: { BL::IntAttribute b_int_attribute{b_attribute}; - const int *b_data = static_cast(b_int_attribute.data[0].ptr.data); + const int *src = static_cast(b_int_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeFloat, element); float *data = attr->data_float(); fill_generic_attribute( - b_mesh, data, b_domain, subdivision, [&](int i) { return (float)b_data[i]; }); + b_mesh, data, b_domain, subdivision, [&](int i) { return (float)src[i]; }); break; } case BL::Attribute::data_type_FLOAT_VECTOR: { BL::FloatVectorAttribute b_vector_attribute{b_attribute}; - const float(*b_data)[3] = static_cast( - b_vector_attribute.data[0].ptr.data); + const float(*src)[3] = static_cast(b_vector_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeVector, element); float3 *data = attr->data_float3(); fill_generic_attribute(b_mesh, data, b_domain, subdivision, [&](int i) { - return make_float3(b_data[i][0], b_data[i][1], b_data[i][2]); + return make_float3(src[i][0], src[i][1], src[i][2]); }); break; } case BL::Attribute::data_type_BYTE_COLOR: { BL::ByteColorAttribute b_color_attribute{b_attribute}; - const uchar(*b_data)[4] = static_cast( - b_color_attribute.data[0].ptr.data); + const uchar(*src)[4] = static_cast(b_color_attribute.data[0].ptr.data); if (element == ATTR_ELEMENT_CORNER) { element = ATTR_ELEMENT_CORNER_BYTE; @@ -465,24 +462,23 @@ static void attr_create_generic(Scene *scene, uchar4 *data = attr->data_uchar4(); fill_generic_attribute(b_mesh, data, b_domain, subdivision, [&](int i) { /* Compress/encode vertex color using the sRGB curve. */ - return make_uchar4(b_data[i][0], b_data[i][1], b_data[i][2], b_data[i][3]); + return make_uchar4(src[i][0], src[i][1], src[i][2], src[i][3]); }); } else { float4 *data = attr->data_float4(); fill_generic_attribute(b_mesh, data, b_domain, subdivision, [&](int i) { - return make_float4(color_srgb_to_linear(byte_to_float(b_data[i][0])), - color_srgb_to_linear(byte_to_float(b_data[i][1])), - color_srgb_to_linear(byte_to_float(b_data[i][2])), - color_srgb_to_linear(byte_to_float(b_data[i][3]))); + return make_float4(color_srgb_to_linear(byte_to_float(src[i][0])), + color_srgb_to_linear(byte_to_float(src[i][1])), + color_srgb_to_linear(byte_to_float(src[i][2])), + color_srgb_to_linear(byte_to_float(src[i][3]))); }); } break; } case BL::Attribute::data_type_FLOAT_COLOR: { BL::FloatColorAttribute b_color_attribute{b_attribute}; - const float(*b_data)[4] = static_cast( - b_color_attribute.data[0].ptr.data); + const float(*src)[4] = static_cast(b_color_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeRGBA, element); if (is_render_color) { @@ -491,18 +487,17 @@ static void attr_create_generic(Scene *scene, float4 *data = attr->data_float4(); fill_generic_attribute(b_mesh, data, b_domain, subdivision, [&](int i) { - return make_float4(b_data[i][0], b_data[i][1], b_data[i][2], b_data[i][3]); + return make_float4(src[i][0], src[i][1], src[i][2], src[i][3]); }); break; } case BL::Attribute::data_type_FLOAT2: { BL::Float2Attribute b_float2_attribute{b_attribute}; - const float(*b_data)[2] = static_cast( - b_float2_attribute.data[0].ptr.data); + const float(*src)[2] = static_cast(b_float2_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeFloat2, element); float2 *data = attr->data_float2(); fill_generic_attribute(b_mesh, data, b_domain, subdivision, [&](int i) { - return make_float2(b_data[i][0], b_data[i][1]); + return make_float2(src[i][0], src[i][1]); }); break; } @@ -858,7 +853,6 @@ static void attr_create_random_per_island(Scene *scene, return; } - const int polys_num = b_mesh.polygons.length(); int number_of_vertices = b_mesh.vertices.length(); if (number_of_vertices == 0) { return; @@ -868,6 +862,7 @@ static void attr_create_random_per_island(Scene *scene, const MEdge *edges = static_cast(b_mesh.edges[0].ptr.data); const int edges_num = b_mesh.edges.length(); + const int *corner_verts = find_corner_vert_attribute(b_mesh); for (int i = 0; i < edges_num; i++) { vertices_sets.join(edges[i].v1, edges[i].v2); @@ -878,14 +873,19 @@ static void attr_create_random_per_island(Scene *scene, float *data = attribute->data_float(); if (!subdivision) { - for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) { - data[t.index()] = hash_uint_to_float(vertices_sets.find(t.vertices()[0])); + const int numtris = b_mesh.loop_triangles.length(); + if (numtris != 0) { + const MLoopTri *looptris = static_cast(b_mesh.loop_triangles[0].ptr.data); + for (int i = 0; i < numtris; i++) { + const int vert = corner_verts[looptris[i].tri[0]]; + data[i] = hash_uint_to_float(vertices_sets.find(vert)); + } } } else { + const int polys_num = b_mesh.polygons.length(); if (polys_num != 0) { const MPoly *polys = static_cast(b_mesh.polygons[0].ptr.data); - const int *corner_verts = find_corner_vert_attribute(b_mesh); for (int i = 0; i < polys_num; i++) { const MPoly &b_poly = polys[i]; const int vert = corner_verts[b_poly.loopstart]; @@ -958,7 +958,8 @@ static void create_mesh(Scene *scene, const int *corner_verts = find_corner_vert_attribute(b_mesh); const int *material_indices = find_material_index_attribute(b_mesh); const bool *sharp_faces = find_sharp_face_attribute(b_mesh); - const float(*corner_normals)[3] = static_cast(b_mesh.loops[0].ptr.data); + const float(*corner_normals)[3] = static_cast( + b_mesh.corner_normals[0].ptr.data); int numngons = 0; int numtris = 0; @@ -974,15 +975,10 @@ static void create_mesh(Scene *scene, } /* allocate memory */ - mesh->get_verts().resize(numverts); if (subdivision) { mesh->resize_subd_faces(numfaces, numngons, numcorners); } - else { - mesh->get_triangles().resize(numtris * 3); - mesh->get_shader().resize(numtris); - mesh->get_smooth().resize(numtris); - } + mesh->resize_mesh(numverts, numtris); float3 *verts = mesh->get_verts().data(); for (int i = 0; i < numverts; i++) { @@ -1070,6 +1066,9 @@ static void create_mesh(Scene *scene, } } } + mesh->tag_triangles_modified(); + mesh->tag_shader_modified(); + mesh->tag_smooth_modified(); } else { int *subd_start_corner = mesh->get_subd_start_corner().data(); @@ -1103,8 +1102,16 @@ static void create_mesh(Scene *scene, subd_start_corner[i] = b_poly.loopstart; subd_num_corners[i] = b_poly.totloop; subd_ptex_offset[i] = ptex_offset; - ptex_offset += b_poly.totloop == 4 ? 1 : b_poly.totloop; + const int num_ptex = (b_poly.totloop == 4) ? 1 : b_poly.totloop; + ptex_offset += num_ptex; } + + mesh->tag_subd_face_corners_modified(); + mesh->tag_subd_start_corner_modified(); + mesh->tag_subd_num_corners_modified(); + mesh->tag_subd_shader_modified(); + mesh->tag_subd_smooth_modified(); + mesh->tag_subd_ptex_offset_modified(); } /* Create all needed attributes. @@ -1157,11 +1164,11 @@ static void create_subd_mesh(Scene *scene, const int edges_num = b_mesh.edges.length(); if (edges_num != 0 && b_mesh.edge_creases.length() > 0) { - BL::MeshEdgeCreaseLayer creases = b_mesh.edge_creases[0]; + const float *creases = static_cast(b_mesh.edge_creases[0].data[0].ptr.data); - size_t num_creases = 0; + int num_creases = 0; for (int i = 0; i < edges_num; i++) { - if (creases.data[i].value() != 0.0f) { + if (creases[i] != 0.0f) { num_creases++; } } @@ -1170,7 +1177,7 @@ static void create_subd_mesh(Scene *scene, const MEdge *edges = static_cast(b_mesh.edges[0].ptr.data); for (int i = 0; i < edges_num; i++) { - const float crease = creases.data[i].value(); + const float crease = creases[i]; if (crease != 0.0f) { const MEdge &b_edge = edges[i]; mesh->add_edge_crease(b_edge.v1, b_edge.v2, crease); @@ -1178,10 +1185,11 @@ static void create_subd_mesh(Scene *scene, } } - for (BL::MeshVertexCreaseLayer &c : b_mesh.vertex_creases) { - for (int i = 0; i < c.data.length(); ++i) { - if (c.data[i].value() != 0.0f) { - mesh->add_vertex_crease(i, c.data[i].value()); + for (BL::MeshVertexCreaseLayer &layer : b_mesh.vertex_creases) { + const float *creases = static_cast(layer.data[0].ptr.data); + for (int i = 0; i < layer.data.length(); ++i) { + if (creases[i] != 0.0f) { + mesh->add_vertex_crease(i, creases[i]); } } } -- 2.30.2 From 86c88457262aa64706e22fcb48b7d8ab1e065da9 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 29 Mar 2023 12:59:50 -0400 Subject: [PATCH 4/9] Cleanup --- intern/cycles/blender/mesh.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/intern/cycles/blender/mesh.cpp b/intern/cycles/blender/mesh.cpp index c4f0750a63e..f89a01798ac 100644 --- a/intern/cycles/blender/mesh.cpp +++ b/intern/cycles/blender/mesh.cpp @@ -958,8 +958,10 @@ static void create_mesh(Scene *scene, const int *corner_verts = find_corner_vert_attribute(b_mesh); const int *material_indices = find_material_index_attribute(b_mesh); const bool *sharp_faces = find_sharp_face_attribute(b_mesh); - const float(*corner_normals)[3] = static_cast( - b_mesh.corner_normals[0].ptr.data); + const float(*corner_normals)[3] = nullptr; + if (use_loop_normals) { + corner_normals = static_cast(b_mesh.corner_normals[0].ptr.data); + } int numngons = 0; int numtris = 0; @@ -989,7 +991,7 @@ static void create_mesh(Scene *scene, Attribute *attr_N = attributes.add(ATTR_STD_VERTEX_NORMAL); float3 *N = attr_N->data_float3(); - if (subdivision || !use_loop_normals) { + if (!corner_normals) { const float(*b_vert_normals)[3] = static_cast( b_mesh.vertex_normals[0].ptr.data); for (int i = 0; i < numverts; i++) { @@ -1045,7 +1047,7 @@ static void create_mesh(Scene *scene, std::fill(shader, shader + numtris, 0); } - if (sharp_faces && !use_loop_normals) { + if (sharp_faces && !corner_normals) { for (int i = 0; i < numtris; i++) { const int poly_index = looptris[i].poly; smooth[i] = !sharp_faces[poly_index]; @@ -1055,7 +1057,7 @@ static void create_mesh(Scene *scene, std::fill(smooth, smooth + numtris, true); } - if (use_loop_normals && corner_normals) { + if (corner_normals) { for (int i = 0; i < numtris; i++) { const MLoopTri &tri = looptris[i]; for (int i = 0; i < 3; i++) { @@ -1095,8 +1097,8 @@ static void create_mesh(Scene *scene, std::fill(subd_shader, subd_shader + numfaces, 0); } - int ptex_offset = 0; const MPoly *polys = static_cast(b_mesh.polygons[0].ptr.data); + int ptex_offset = 0; for (int i = 0; i < numfaces; i++) { const MPoly &b_poly = polys[i]; subd_start_corner[i] = b_poly.loopstart; -- 2.30.2 From 5727218765d2c280f61907161eaa8528c62250b2 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 30 Mar 2023 09:55:14 -0400 Subject: [PATCH 5/9] Fix missing corner verts copy --- intern/cycles/blender/mesh.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/intern/cycles/blender/mesh.cpp b/intern/cycles/blender/mesh.cpp index f89a01798ac..a3e385f7ee6 100644 --- a/intern/cycles/blender/mesh.cpp +++ b/intern/cycles/blender/mesh.cpp @@ -1078,6 +1078,7 @@ static void create_mesh(Scene *scene, int *subd_shader = mesh->get_subd_shader().data(); bool *subd_smooth = mesh->get_subd_smooth().data(); int *subd_ptex_offset = mesh->get_subd_ptex_offset().data(); + int *subd_face_corners = mesh->get_subd_face_corners().data(); if (sharp_faces) { for (int i = 0; i < numfaces; i++) { @@ -1097,6 +1098,8 @@ static void create_mesh(Scene *scene, std::fill(subd_shader, subd_shader + numfaces, 0); } + std::copy(corner_verts, corner_verts + numcorners, subd_face_corners); + const MPoly *polys = static_cast(b_mesh.polygons[0].ptr.data); int ptex_offset = 0; for (int i = 0; i < numfaces; i++) { -- 2.30.2 From f6c690511fcda30ad8a558842a1be63759455a86 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 30 Mar 2023 14:12:19 -0400 Subject: [PATCH 6/9] Fix --- intern/cycles/blender/mesh.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/intern/cycles/blender/mesh.cpp b/intern/cycles/blender/mesh.cpp index a3e385f7ee6..a028bd3036c 100644 --- a/intern/cycles/blender/mesh.cpp +++ b/intern/cycles/blender/mesh.cpp @@ -991,7 +991,7 @@ static void create_mesh(Scene *scene, Attribute *attr_N = attributes.add(ATTR_STD_VERTEX_NORMAL); float3 *N = attr_N->data_float3(); - if (!corner_normals) { + if (subdivision || !(use_loop_normals && corner_normals)) { const float(*b_vert_normals)[3] = static_cast( b_mesh.vertex_normals[0].ptr.data); for (int i = 0; i < numverts; i++) { @@ -1047,7 +1047,7 @@ static void create_mesh(Scene *scene, std::fill(shader, shader + numtris, 0); } - if (sharp_faces && !corner_normals) { + if (sharp_faces && !(use_loop_normals && corner_normals)) { for (int i = 0; i < numtris; i++) { const int poly_index = looptris[i].poly; smooth[i] = !sharp_faces[poly_index]; @@ -1057,7 +1057,7 @@ static void create_mesh(Scene *scene, std::fill(smooth, smooth + numtris, true); } - if (corner_normals) { + if (use_loop_normals && corner_normals) { for (int i = 0; i < numtris; i++) { const MLoopTri &tri = looptris[i]; for (int i = 0; i < 3; i++) { @@ -1068,6 +1068,7 @@ static void create_mesh(Scene *scene, } } } + mesh->tag_triangles_modified(); mesh->tag_shader_modified(); mesh->tag_smooth_modified(); @@ -1080,7 +1081,7 @@ static void create_mesh(Scene *scene, int *subd_ptex_offset = mesh->get_subd_ptex_offset().data(); int *subd_face_corners = mesh->get_subd_face_corners().data(); - if (sharp_faces) { + if (sharp_faces && !use_loop_normals) { for (int i = 0; i < numfaces; i++) { subd_smooth[i] = !sharp_faces[i]; } -- 2.30.2 From da276547d2dbbc88e85b18193a524edf8f0f7c16 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 3 Apr 2023 10:45:40 -0400 Subject: [PATCH 7/9] Add empty data checks in some places --- intern/cycles/blender/mesh.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/intern/cycles/blender/mesh.cpp b/intern/cycles/blender/mesh.cpp index a028bd3036c..b271252ab5c 100644 --- a/intern/cycles/blender/mesh.cpp +++ b/intern/cycles/blender/mesh.cpp @@ -372,6 +372,9 @@ static void attr_create_generic(Scene *scene, for (BL::Attribute &b_attribute : b_mesh.attributes) { const ustring name{b_attribute.name().c_str()}; const bool is_render_color = name == default_color_name; + if (b_attribute.data.length() == 0) { + continue; + } if (need_motion && name == u_velocity) { attr_create_motion(mesh, b_attribute, motion_scale); @@ -829,6 +832,9 @@ static const int *find_corner_vert_attribute(BL::Mesh b_mesh) if (b_attribute.name() != ".corner_vert") { continue; } + if (b_attribute.data.length() == 0) { + return nullptr; + } return static_cast(BL::IntAttribute(b_attribute).data[0].ptr.data); } return nullptr; @@ -873,10 +879,10 @@ static void attr_create_random_per_island(Scene *scene, float *data = attribute->data_float(); if (!subdivision) { - const int numtris = b_mesh.loop_triangles.length(); - if (numtris != 0) { + const int tris_num = b_mesh.loop_triangles.length(); + if (tris_num != 0) { const MLoopTri *looptris = static_cast(b_mesh.loop_triangles[0].ptr.data); - for (int i = 0; i < numtris; i++) { + for (int i = 0; i < tris_num; i++) { const int vert = corner_verts[looptris[i].tri[0]]; data[i] = hash_uint_to_float(vertices_sets.find(vert)); } @@ -909,6 +915,9 @@ static const int *find_material_index_attribute(BL::Mesh b_mesh) if (b_attribute.name() != "material_index") { continue; } + if (b_attribute.data.length() == 0) { + return nullptr; + } return static_cast(BL::IntAttribute{b_attribute}.data[0].ptr.data); } return nullptr; @@ -926,6 +935,9 @@ static const bool *find_sharp_face_attribute(BL::Mesh b_mesh) if (b_attribute.name() != "sharp_face") { continue; } + if (b_attribute.data.length() == 0) { + return nullptr; + } return static_cast(BL::BoolAttribute{b_attribute}.data[0].ptr.data); } return nullptr; @@ -1172,7 +1184,7 @@ static void create_subd_mesh(Scene *scene, if (edges_num != 0 && b_mesh.edge_creases.length() > 0) { const float *creases = static_cast(b_mesh.edge_creases[0].data[0].ptr.data); - int num_creases = 0; + size_t num_creases = 0; for (int i = 0; i < edges_num; i++) { if (creases[i] != 0.0f) { num_creases++; -- 2.30.2 From ef49793adc191b39a72cac205c889a42702ad918 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 3 Apr 2023 10:45:54 -0400 Subject: [PATCH 8/9] Remove timer --- intern/cycles/blender/mesh.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/intern/cycles/blender/mesh.cpp b/intern/cycles/blender/mesh.cpp index b271252ab5c..52db7888fce 100644 --- a/intern/cycles/blender/mesh.cpp +++ b/intern/cycles/blender/mesh.cpp @@ -952,8 +952,6 @@ static void create_mesh(Scene *scene, const bool subdivision = false, const bool subdivide_uvs = true) { - scoped_timer timer; - const int numverts = b_mesh.vertices.length(); const int polys_num = b_mesh.polygons.length(); int numfaces = (!subdivision) ? b_mesh.loop_triangles.length() : b_mesh.polygons.length(); @@ -1158,8 +1156,6 @@ static void create_mesh(Scene *scene, *tfm = transform_translate(-loc) * transform_scale(size); } - - std::cout << time_human_readable_from_seconds(timer.get_time()) << '\n'; } static void create_subd_mesh(Scene *scene, -- 2.30.2 From 824a1e575a6cfb6d7889a2c011b598129954c656 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 3 Apr 2023 10:54:18 -0400 Subject: [PATCH 9/9] Fix compile error from mistake in previous commit --- intern/cycles/blender/mesh.cpp | 39 ++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/intern/cycles/blender/mesh.cpp b/intern/cycles/blender/mesh.cpp index 52db7888fce..678ee4b396a 100644 --- a/intern/cycles/blender/mesh.cpp +++ b/intern/cycles/blender/mesh.cpp @@ -372,9 +372,6 @@ static void attr_create_generic(Scene *scene, for (BL::Attribute &b_attribute : b_mesh.attributes) { const ustring name{b_attribute.name().c_str()}; const bool is_render_color = name == default_color_name; - if (b_attribute.data.length() == 0) { - continue; - } if (need_motion && name == u_velocity) { attr_create_motion(mesh, b_attribute, motion_scale); @@ -415,6 +412,9 @@ static void attr_create_generic(Scene *scene, switch (b_data_type) { case BL::Attribute::data_type_FLOAT: { BL::FloatAttribute b_float_attribute{b_attribute}; + if (b_float_attribute.data.length() == 0) { + continue; + } const float *src = static_cast(b_float_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeFloat, element); float *data = attr->data_float(); @@ -423,6 +423,9 @@ static void attr_create_generic(Scene *scene, } case BL::Attribute::data_type_BOOLEAN: { BL::BoolAttribute b_bool_attribute{b_attribute}; + if (b_bool_attribute.data.length() == 0) { + continue; + } const bool *src = static_cast(b_bool_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeFloat, element); float *data = attr->data_float(); @@ -432,6 +435,9 @@ static void attr_create_generic(Scene *scene, } case BL::Attribute::data_type_INT: { BL::IntAttribute b_int_attribute{b_attribute}; + if (b_int_attribute.data.length() == 0) { + continue; + } const int *src = static_cast(b_int_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeFloat, element); float *data = attr->data_float(); @@ -441,6 +447,9 @@ static void attr_create_generic(Scene *scene, } case BL::Attribute::data_type_FLOAT_VECTOR: { BL::FloatVectorAttribute b_vector_attribute{b_attribute}; + if (b_vector_attribute.data.length() == 0) { + continue; + } const float(*src)[3] = static_cast(b_vector_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeVector, element); float3 *data = attr->data_float3(); @@ -451,6 +460,9 @@ static void attr_create_generic(Scene *scene, } case BL::Attribute::data_type_BYTE_COLOR: { BL::ByteColorAttribute b_color_attribute{b_attribute}; + if (b_color_attribute.data.length() == 0) { + continue; + } const uchar(*src)[4] = static_cast(b_color_attribute.data[0].ptr.data); if (element == ATTR_ELEMENT_CORNER) { @@ -481,6 +493,9 @@ static void attr_create_generic(Scene *scene, } case BL::Attribute::data_type_FLOAT_COLOR: { BL::FloatColorAttribute b_color_attribute{b_attribute}; + if (b_color_attribute.data.length() == 0) { + continue; + } const float(*src)[4] = static_cast(b_color_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeRGBA, element); @@ -496,6 +511,9 @@ static void attr_create_generic(Scene *scene, } case BL::Attribute::data_type_FLOAT2: { BL::Float2Attribute b_float2_attribute{b_attribute}; + if (b_float2_attribute.data.length() == 0) { + continue; + } const float(*src)[2] = static_cast(b_float2_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeFloat2, element); float2 *data = attr->data_float2(); @@ -832,10 +850,11 @@ static const int *find_corner_vert_attribute(BL::Mesh b_mesh) if (b_attribute.name() != ".corner_vert") { continue; } - if (b_attribute.data.length() == 0) { + BL::IntAttribute b_int_attribute{b_attribute}; + if (b_int_attribute.data.length() == 0) { return nullptr; } - return static_cast(BL::IntAttribute(b_attribute).data[0].ptr.data); + return static_cast(b_int_attribute.data[0].ptr.data); } return nullptr; } @@ -915,10 +934,11 @@ static const int *find_material_index_attribute(BL::Mesh b_mesh) if (b_attribute.name() != "material_index") { continue; } - if (b_attribute.data.length() == 0) { + BL::IntAttribute b_int_attribute{b_attribute}; + if (b_int_attribute.data.length() == 0) { return nullptr; } - return static_cast(BL::IntAttribute{b_attribute}.data[0].ptr.data); + return static_cast(b_int_attribute.data[0].ptr.data); } return nullptr; } @@ -935,10 +955,11 @@ static const bool *find_sharp_face_attribute(BL::Mesh b_mesh) if (b_attribute.name() != "sharp_face") { continue; } - if (b_attribute.data.length() == 0) { + BL::IntAttribute b_int_attribute{b_attribute}; + if (b_int_attribute.data.length() == 0) { return nullptr; } - return static_cast(BL::BoolAttribute{b_attribute}.data[0].ptr.data); + return static_cast(b_int_attribute.data[0].ptr.data); } return nullptr; } -- 2.30.2