diff options
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/blender/mesh.cpp | 10 | ||||
-rw-r--r-- | intern/cycles/scene/alembic.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/scene/alembic.h | 2 | ||||
-rw-r--r-- | intern/cycles/scene/alembic_read.cpp | 38 | ||||
-rw-r--r-- | intern/cycles/scene/alembic_read.h | 3 | ||||
-rw-r--r-- | intern/cycles/scene/mesh.cpp | 16 | ||||
-rw-r--r-- | intern/cycles/scene/mesh.h | 6 | ||||
-rw-r--r-- | intern/cycles/scene/mesh_subdivision.cpp | 36 |
8 files changed, 108 insertions, 9 deletions
diff --git a/intern/cycles/blender/mesh.cpp b/intern/cycles/blender/mesh.cpp index 5e2b700427a..4ec25a868ae 100644 --- a/intern/cycles/blender/mesh.cpp +++ b/intern/cycles/blender/mesh.cpp @@ -1071,7 +1071,15 @@ static void create_subd_mesh(Scene *scene, for (BL::MeshEdge &e : b_mesh.edges) { if (e.crease() != 0.0f) { - mesh->add_crease(e.vertices()[0], e.vertices()[1], e.crease()); + mesh->add_edge_crease(e.vertices()[0], e.vertices()[1], e.crease()); + } + } + + 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()); + } } } diff --git a/intern/cycles/scene/alembic.cpp b/intern/cycles/scene/alembic.cpp index 7780b13eecb..a8aec133fb6 100644 --- a/intern/cycles/scene/alembic.cpp +++ b/intern/cycles/scene/alembic.cpp @@ -1178,6 +1178,12 @@ void AlembicProcedural::read_subd(AlembicObject *abc_object, Abc::chrono_t frame cached_data.subd_creases_weight.copy_to_socket( frame_time, mesh, mesh->get_subd_creases_weight_socket()); + cached_data.subd_vertex_crease_indices.copy_to_socket( + frame_time, mesh, mesh->get_subd_vert_creases_socket()); + + cached_data.subd_vertex_crease_weights.copy_to_socket( + frame_time, mesh, mesh->get_subd_vert_creases_weight_socket()); + mesh->set_num_subd_faces(mesh->get_subd_shader().size()); /* Update attributes. */ diff --git a/intern/cycles/scene/alembic.h b/intern/cycles/scene/alembic.h index 6068ea3ef03..9ea4737bea1 100644 --- a/intern/cycles/scene/alembic.h +++ b/intern/cycles/scene/alembic.h @@ -320,6 +320,8 @@ struct CachedData { DataStore<int> num_ngons; DataStore<array<int>> subd_creases_edge; DataStore<array<float>> subd_creases_weight; + DataStore<array<int>> subd_vertex_crease_indices; + DataStore<array<float>> subd_vertex_crease_weights; /* hair data */ DataStore<array<float3>> curve_keys; diff --git a/intern/cycles/scene/alembic_read.cpp b/intern/cycles/scene/alembic_read.cpp index 07874b7528e..33908dff6e5 100644 --- a/intern/cycles/scene/alembic_read.cpp +++ b/intern/cycles/scene/alembic_read.cpp @@ -478,7 +478,9 @@ static void add_subd_polygons(CachedData &cached_data, const SubDSchemaData &dat cached_data.uv_loops.add_data(uv_loops, time); } -static void add_subd_creases(CachedData &cached_data, const SubDSchemaData &data, chrono_t time) +static void add_subd_edge_creases(CachedData &cached_data, + const SubDSchemaData &data, + chrono_t time) { if (!(data.crease_indices.valid() && data.crease_indices.valid() && data.crease_sharpnesses.valid())) { @@ -517,6 +519,37 @@ static void add_subd_creases(CachedData &cached_data, const SubDSchemaData &data } } +static void add_subd_vertex_creases(CachedData &cached_data, + const SubDSchemaData &data, + chrono_t time) +{ + if (!(data.corner_indices.valid() && data.crease_sharpnesses.valid())) { + return; + } + + const ISampleSelector iss = ISampleSelector(time); + const Int32ArraySamplePtr creases_indices = data.crease_indices.getValue(iss); + const FloatArraySamplePtr creases_sharpnesses = data.crease_sharpnesses.getValue(iss); + + if (!(creases_indices && creases_sharpnesses) || + creases_indices->size() != creases_sharpnesses->size()) { + return; + } + + array<float> sharpnesses; + sharpnesses.reserve(creases_indices->size()); + array<int> indices; + indices.reserve(creases_indices->size()); + + for (size_t i = 0; i < creases_indices->size(); i++) { + indices.push_back_reserved((*creases_indices)[i]); + sharpnesses.push_back_reserved((*creases_sharpnesses)[i]); + } + + cached_data.subd_vertex_crease_indices.add_data(indices, time); + cached_data.subd_vertex_crease_weights.add_data(sharpnesses, time); +} + static void read_subd_geometry(CachedData &cached_data, const SubDSchemaData &data, chrono_t time) { const ISampleSelector iss = ISampleSelector(time); @@ -525,7 +558,8 @@ static void read_subd_geometry(CachedData &cached_data, const SubDSchemaData &da if (data.topology_variance != kHomogenousTopology || cached_data.shader.size() == 0) { add_subd_polygons(cached_data, data, time); - add_subd_creases(cached_data, data, time); + add_subd_edge_creases(cached_data, data, time); + add_subd_vertex_creases(cached_data, data, time); } } diff --git a/intern/cycles/scene/alembic_read.h b/intern/cycles/scene/alembic_read.h index e95750ce691..94018b82747 100644 --- a/intern/cycles/scene/alembic_read.h +++ b/intern/cycles/scene/alembic_read.h @@ -76,9 +76,10 @@ struct SubDSchemaData { vector<FaceSetShaderIndexPair> shader_face_sets; - // Those are unsupported for now. Alembic::AbcGeom::IInt32ArrayProperty corner_indices; Alembic::AbcGeom::IFloatArrayProperty corner_sharpnesses; + + // Those are unsupported for now. Alembic::AbcGeom::IInt32Property face_varying_interpolate_boundary; Alembic::AbcGeom::IInt32Property face_varying_propagate_corners; Alembic::AbcGeom::IInt32Property interpolate_boundary; diff --git a/intern/cycles/scene/mesh.cpp b/intern/cycles/scene/mesh.cpp index e65b8462e34..c381d7a54ff 100644 --- a/intern/cycles/scene/mesh.cpp +++ b/intern/cycles/scene/mesh.cpp @@ -141,6 +141,9 @@ NODE_DEFINE(Mesh) subdivision_type_enum.insert("catmull_clark", SUBDIVISION_CATMULL_CLARK); SOCKET_ENUM(subdivision_type, "Subdivision Type", subdivision_type_enum, SUBDIVISION_NONE); + SOCKET_INT_ARRAY(subd_vert_creases, "Subdivision Vertex Crease", array<int>()); + SOCKET_FLOAT_ARRAY( + subd_vert_creases_weight, "Subdivision Vertex Crease Weights", array<float>()); SOCKET_INT_ARRAY(subd_creases_edge, "Subdivision Crease Edges", array<int>()); SOCKET_FLOAT_ARRAY(subd_creases_weight, "Subdivision Crease Weights", array<float>()); SOCKET_INT_ARRAY(subd_face_corners, "Subdivision Face Corners", array<int>()); @@ -408,7 +411,7 @@ Mesh::SubdFace Mesh::get_subd_face(size_t index) const return s; } -void Mesh::add_crease(int v0, int v1, float weight) +void Mesh::add_edge_crease(int v0, int v1, float weight) { subd_creases_edge.push_back_slow(v0); subd_creases_edge.push_back_slow(v1); @@ -419,6 +422,17 @@ void Mesh::add_crease(int v0, int v1, float weight) tag_subd_creases_weight_modified(); } +void Mesh::add_vertex_crease(int v, float weight) +{ + assert(v < verts.size()); + + subd_vert_creases.push_back_slow(v); + subd_vert_creases_weight.push_back_slow(weight); + + tag_subd_vert_creases_modified(); + tag_subd_vert_creases_weight_modified(); +} + void Mesh::copy_center_to_motion_step(const int motion_step) { Attribute *attr_mP = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); diff --git a/intern/cycles/scene/mesh.h b/intern/cycles/scene/mesh.h index 254672d0620..07acd5328d2 100644 --- a/intern/cycles/scene/mesh.h +++ b/intern/cycles/scene/mesh.h @@ -160,6 +160,9 @@ class Mesh : public Geometry { NODE_SOCKET_API_ARRAY(array<int>, subd_creases_edge) NODE_SOCKET_API_ARRAY(array<float>, subd_creases_weight) + NODE_SOCKET_API_ARRAY(array<int>, subd_vert_creases) + NODE_SOCKET_API_ARRAY(array<float>, subd_vert_creases_weight) + /* Subdivisions parameters */ NODE_SOCKET_API(float, subd_dicing_rate) NODE_SOCKET_API(int, subd_max_level) @@ -210,7 +213,8 @@ class Mesh : public Geometry { void add_vertex_slow(float3 P); void add_triangle(int v0, int v1, int v2, int shader, bool smooth); void add_subd_face(int *corners, int num_corners, int shader_, bool smooth_); - void add_crease(int v0, int v1, float weight); + void add_edge_crease(int v0, int v1, float weight); + void add_vertex_crease(int v, float weight); void copy_center_to_motion_step(const int motion_step); diff --git a/intern/cycles/scene/mesh_subdivision.cpp b/intern/cycles/scene/mesh_subdivision.cpp index 35f15cfafbc..7c88e310527 100644 --- a/intern/cycles/scene/mesh_subdivision.cpp +++ b/intern/cycles/scene/mesh_subdivision.cpp @@ -82,24 +82,54 @@ template<> bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTags(TopologyRefiner &refiner, ccl::Mesh const &mesh) { + /* Historical maximum crease weight used at Pixar, influencing the maximum in OpenSubDiv. */ + static constexpr float CREASE_SCALE = 10.0f; + size_t num_creases = mesh.get_subd_creases_weight().size(); + size_t num_vertex_creases = mesh.get_subd_vert_creases().size(); + + /* The last loop is over the vertices, so early exit to avoid iterating them needlessly. */ + if (num_creases == 0 && num_vertex_creases == 0) { + return true; + } for (int i = 0; i < num_creases; i++) { ccl::Mesh::SubdEdgeCrease crease = mesh.get_subd_crease(i); Index edge = findBaseEdge(refiner, crease.v[0], crease.v[1]); if (edge != INDEX_INVALID) { - setBaseEdgeSharpness(refiner, edge, crease.crease * 10.0f); + setBaseEdgeSharpness(refiner, edge, crease.crease * CREASE_SCALE); } } + std::map<int, float> vertex_creases; + + for (size_t i = 0; i < num_vertex_creases; ++i) { + const int vertex_idx = mesh.get_subd_vert_creases()[i]; + const float weight = mesh.get_subd_vert_creases_weight()[i]; + + vertex_creases[vertex_idx] = weight * CREASE_SCALE; + } + for (int i = 0; i < mesh.get_verts().size(); i++) { + float sharpness = 0.0f; + std::map<int, float>::const_iterator iter = vertex_creases.find(i); + + if (iter != vertex_creases.end()) { + sharpness = iter->second; + } + ConstIndexArray vert_edges = getBaseVertexEdges(refiner, i); if (vert_edges.size() == 2) { - float sharpness = refiner.getLevel(0).getEdgeSharpness(vert_edges[0]); - sharpness = ccl::min(sharpness, refiner.getLevel(0).getEdgeSharpness(vert_edges[1])); + const float sharpness0 = refiner.getLevel(0).getEdgeSharpness(vert_edges[0]); + const float sharpness1 = refiner.getLevel(0).getEdgeSharpness(vert_edges[1]); + + sharpness += ccl::min(sharpness0, sharpness1); + sharpness = ccl::min(sharpness, CREASE_SCALE); + } + if (sharpness != 0.0f) { setBaseVertexSharpness(refiner, i, sharpness); } } |