diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index baff3c206b7..24c2c57082f 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -618,18 +618,19 @@ static void create_mesh(Scene *scene, if(is_zero(cross(mesh->verts[vi[1]] - mesh->verts[vi[0]], mesh->verts[vi[2]] - mesh->verts[vi[0]])) || is_zero(cross(mesh->verts[vi[2]] - mesh->verts[vi[0]], mesh->verts[vi[3]] - mesh->verts[vi[0]]))) { - mesh->set_triangle(ti++, vi[0], vi[1], vi[3], shader, smooth); - mesh->set_triangle(ti++, vi[2], vi[3], vi[1], shader, smooth); + // TODO(mai): order here is probably wrong + mesh->set_triangle(ti++, vi[0], vi[1], vi[3], shader, smooth, true); + mesh->set_triangle(ti++, vi[2], vi[3], vi[1], shader, smooth, true); face_flags[fi] |= FACE_FLAG_DIVIDE_24; } else { - mesh->set_triangle(ti++, vi[0], vi[1], vi[2], shader, smooth); - mesh->set_triangle(ti++, vi[0], vi[2], vi[3], shader, smooth); + mesh->set_triangle(ti++, vi[0], vi[1], vi[2], shader, smooth, true); + mesh->set_triangle(ti++, vi[0], vi[2], vi[3], shader, smooth, true); face_flags[fi] |= FACE_FLAG_DIVIDE_13; } } else - mesh->set_triangle(ti++, vi[0], vi[1], vi[2], shader, smooth); + mesh->set_triangle(ti++, vi[0], vi[1], vi[2], shader, smooth, false); nverts[fi] = n; } @@ -661,37 +662,10 @@ static void create_subd_mesh(Scene *scene, PointerRNA *cmesh, const vector& used_shaders) { - /* create subd mesh */ - SubdMesh sdmesh; + Mesh basemesh; + create_mesh(scene, &basemesh, b_mesh, used_shaders); - /* create vertices */ - BL::Mesh::vertices_iterator v; - - for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) - sdmesh.add_vert(get_float3(v->co())); - - /* create faces */ - BL::Mesh::tessfaces_iterator f; - - for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f) { - int4 vi = get_int4(f->vertices_raw()); - int n = (vi[3] == 0) ? 3: 4; - //int shader = used_shaders[f->material_index()]; - - if(n == 4) - sdmesh.add_face(vi[0], vi[1], vi[2], vi[3]); - else - sdmesh.add_face(vi[0], vi[1], vi[2]); - } - - /* finalize subd mesh */ - sdmesh.finish(); - - /* parameters */ - bool need_ptex = mesh->need_attribute(scene, ATTR_STD_PTEX_FACE_ID) || - mesh->need_attribute(scene, ATTR_STD_PTEX_UV); - - SubdParams sdparams(mesh, used_shaders[0], true, need_ptex); + SubdParams sdparams(mesh, used_shaders[0], true, false); sdparams.dicing_rate = RNA_float_get(cmesh, "dicing_rate"); scene->camera->update(); @@ -700,7 +674,7 @@ static void create_subd_mesh(Scene *scene, /* tesselate */ DiagSplit dsplit(sdparams); - sdmesh.tessellate(&dsplit); + basemesh.tessellate(&dsplit); } /* Sync */ diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt index 17ca6ce0f48..38450a9f762 100644 --- a/intern/cycles/render/CMakeLists.txt +++ b/intern/cycles/render/CMakeLists.txt @@ -6,6 +6,7 @@ set(INC ../kernel/svm ../kernel/osl ../bvh + ../subd ../util ../../glew-mx ) diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 7692c49791d..aa9f773917a 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -35,6 +35,9 @@ #include "util_progress.h" #include "util_set.h" +#include "subd_split.h" +#include "subd_patch.h" + CCL_NAMESPACE_BEGIN /* Triangle */ @@ -112,6 +115,9 @@ void Mesh::reserve(int numverts, int numtris, int numcurves, int numcurvekeys) triangles.resize(numtris); shader.resize(numtris); smooth.resize(numtris); + + forms_quad.resize(numtris); + curve_keys.resize(numcurvekeys); curves.resize(numcurves); @@ -127,6 +133,8 @@ void Mesh::clear() shader.clear(); smooth.clear(); + forms_quad.clear(); + curve_keys.clear(); curves.clear(); @@ -156,7 +164,7 @@ int Mesh::split_vertex(int vertex) return verts.size() - 1; } -void Mesh::set_triangle(int i, int v0, int v1, int v2, int shader_, bool smooth_) +void Mesh::set_triangle(int i, int v0, int v1, int v2, int shader_, bool smooth_, bool forms_quad_) { Triangle tri; tri.v[0] = v0; @@ -166,9 +174,10 @@ void Mesh::set_triangle(int i, int v0, int v1, int v2, int shader_, bool smooth_ triangles[i] = tri; shader[i] = shader_; smooth[i] = smooth_; + forms_quad[i] = forms_quad_; } -void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_) +void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_, bool forms_quad_) { Triangle tri; tri.v[0] = v0; @@ -178,6 +187,7 @@ void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_) triangles.push_back(tri); shader.push_back(shader_); smooth.push_back(smooth_); + forms_quad.push_back(forms_quad_); } void Mesh::add_curve_key(float3 co, float radius) @@ -1437,5 +1447,42 @@ bool Mesh::need_attribute(Scene *scene, ustring name) return false; } +void Mesh::tessellate(DiagSplit *split) +{ + int num_faces = triangles.size(); + + for(int f = 0; f < num_faces; f++) { + if(!forms_quad[f]) { + /* triangle */ + LinearTrianglePatch* patch = new LinearTrianglePatch(); + float3 *hull = patch->hull; + + for(int i = 0; i < 3; i++) { + hull[i] = verts[triangles[f].v[i]]; + } + + split->split_triangle(patch); + delete patch; + } + else { + /* quad */ + LinearQuadPatch* patch = new LinearQuadPatch(); + float3 *hull = patch->hull; + + hull[0] = verts[triangles[f ].v[0]]; + hull[1] = verts[triangles[f ].v[1]]; + hull[3] = verts[triangles[f ].v[2]]; + hull[2] = verts[triangles[f+1].v[2]]; + + split->split_quad(patch); + delete patch; + + // consume second triangle in quad + f++; + } + + } +} + CCL_NAMESPACE_END diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h index 57b16f7fd4e..006a4889d50 100644 --- a/intern/cycles/render/mesh.h +++ b/intern/cycles/render/mesh.h @@ -38,6 +38,7 @@ class Progress; class Scene; class SceneParams; class AttributeRequest; +class DiagSplit; /* Mesh */ @@ -85,6 +86,7 @@ public: vector triangles; vector shader; vector smooth; + vector forms_quad; /* used to tell if triangle is part of a quad patch */ bool has_volume; /* Set in the device_update_flags(). */ bool has_surface_bssrdf; /* Set in the device_update_flags(). */ @@ -123,8 +125,8 @@ public: void reserve(int numverts, int numfaces, int numcurves, int numcurvekeys); void clear(); - void set_triangle(int i, int v0, int v1, int v2, int shader, bool smooth); - void add_triangle(int v0, int v1, int v2, int shader, bool smooth); + void set_triangle(int i, int v0, int v1, int v2, int shader, bool smooth, bool forms_quad = false); + void add_triangle(int v0, int v1, int v2, int shader, bool smooth, bool forms_quad = false); void add_curve_key(float3 loc, float radius); void add_curve(int first_key, int num_keys, int shader); int split_vertex(int vertex); @@ -157,6 +159,8 @@ public: /* Check if the mesh should be treated as instanced. */ bool is_instanced() const; + + void tessellate(DiagSplit *split); }; /* Mesh Manager */