From 9396e11180fbdc380f06dbd4c696a9c39ff32ec9 Mon Sep 17 00:00:00 2001 From: Mai Lavelle Date: Sun, 14 Aug 2016 12:41:45 -0400 Subject: [PATCH] Cycles microdisplacement: Move call to tessellate() from addon to Cycles By calling `tessellate()` from the mesh manager in Cycles we can do pre/post processing or even threaded tessellation without concerning client side code with the details. --- intern/cycles/blender/blender_mesh.cpp | 9 +++--- intern/cycles/render/mesh.cpp | 42 +++++++++++++++++++++++++- intern/cycles/render/mesh.h | 3 ++ intern/cycles/subd/CMakeLists.txt | 1 + 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 6dc26c2981b..c33bc4c263f 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -806,7 +806,10 @@ static void create_subd_mesh(Scene *scene, } /* set subd params */ - SubdParams sdparams(mesh); + if(!mesh->subd_params) { + mesh->subd_params = new SubdParams(mesh); + } + SubdParams& sdparams = *mesh->subd_params; PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles"); @@ -816,10 +819,6 @@ static void create_subd_mesh(Scene *scene, scene->camera->update(); sdparams.camera = scene->camera; sdparams.objecttoworld = get_transform(b_ob.matrix_world()); - - /* tesselate */ - DiagSplit dsplit(sdparams); - mesh->tessellate(&dsplit); } /* Sync */ diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index f90c19a11c8..fcf4e69984d 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -30,6 +30,7 @@ #include "osl_globals.h" +#include "subd_split.h" #include "subd_patch_table.h" #include "util_foreach.h" @@ -172,6 +173,7 @@ Mesh::Mesh() num_ngons = 0; subdivision_type = SUBDIVISION_NONE; + subd_params = NULL; patch_table = NULL; } @@ -180,6 +182,7 @@ Mesh::~Mesh() { delete bvh; delete patch_table; + delete subd_params; } void Mesh::resize_mesh(int numverts, int numtris) @@ -1659,6 +1662,42 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen } } + /* Tessellate meshes that are using subdivision */ + size_t total_tess_needed = 0; + foreach(Mesh *mesh, scene->meshes) { + if(mesh->need_update && + mesh->subdivision_type != Mesh::SUBDIVISION_NONE && + mesh->num_subd_verts == 0 && + mesh->subd_params) + { + total_tess_needed++; + } + } + + size_t i = 0; + foreach(Mesh *mesh, scene->meshes) { + if(mesh->need_update && + mesh->subdivision_type != Mesh::SUBDIVISION_NONE && + mesh->num_subd_verts == 0 && + mesh->subd_params) + { + string msg = "Tessellating "; + if(mesh->name == "") + msg += string_printf("%u/%u", (uint)(i+1), (uint)total_tess_needed); + else + msg += string_printf("%s %u/%u", mesh->name.c_str(), (uint)(i+1), (uint)total_tess_needed); + + progress.set_status("Updating Mesh", msg); + + DiagSplit dsplit(*mesh->subd_params); + mesh->tessellate(&dsplit); + + i++; + + if(progress.get_cancel()) return; + } + } + /* Update images needed for true displacement. */ bool true_displacement_used = false; bool old_need_object_flags_update = false; @@ -1719,7 +1758,7 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen } /* Update bvh. */ - size_t i = 0, num_bvh = 0; + size_t num_bvh = 0; foreach(Mesh *mesh, scene->meshes) { if(mesh->need_update && mesh->need_build_bvh()) { num_bvh++; @@ -1728,6 +1767,7 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen TaskPool pool; + i = 0; foreach(Mesh *mesh, scene->meshes) { if(mesh->need_update) { pool.push(function_bind(&Mesh::compute_bvh, diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h index eff5c50e635..a77e296ea4a 100644 --- a/intern/cycles/render/mesh.h +++ b/intern/cycles/render/mesh.h @@ -39,6 +39,7 @@ class Progress; class Scene; class SceneParams; class AttributeRequest; +struct SubdParams; class DiagSplit; struct PackedPatchTable; @@ -156,6 +157,8 @@ public: array subd_creases; + SubdParams *subd_params; + vector used_shaders; AttributeSet attributes; AttributeSet curve_attributes; diff --git a/intern/cycles/subd/CMakeLists.txt b/intern/cycles/subd/CMakeLists.txt index 9265299e82b..dafb807bdf3 100644 --- a/intern/cycles/subd/CMakeLists.txt +++ b/intern/cycles/subd/CMakeLists.txt @@ -22,6 +22,7 @@ set(SRC set(SRC_HEADERS subd_dice.h subd_patch.h + subd_patch_table.h subd_split.h )