Cycles microdisplacement: Move call to tessellate() from addon to Cycles
authorMai Lavelle <mai.lavelle@gmail.com>
Sun, 14 Aug 2016 16:41:45 +0000 (12:41 -0400)
committerMai Lavelle <mai.lavelle@gmail.com>
Sun, 14 Aug 2016 19:04:21 +0000 (15:04 -0400)
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
intern/cycles/render/mesh.cpp
intern/cycles/render/mesh.h
intern/cycles/subd/CMakeLists.txt

index 6dc26c2981b493c866a89efa493d8ace6e6898a0..c33bc4c263f5de33c34357df57eb302d7d7529cb 100644 (file)
@@ -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 */
index f90c19a11c867003f1a0c713383d279c463dcea0..fcf4e69984df0476b5ee93377442789c196c9495 100644 (file)
@@ -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,
index eff5c50e63505fb0d2432d1fe9ab0255eaf658cf..a77e296ea4a56e9413f8d656c25ce57efb76acf3 100644 (file)
@@ -39,6 +39,7 @@ class Progress;
 class Scene;
 class SceneParams;
 class AttributeRequest;
+struct SubdParams;
 class DiagSplit;
 struct PackedPatchTable;
 
@@ -156,6 +157,8 @@ public:
 
        array<SubdEdgeCrease> subd_creases;
 
+       SubdParams *subd_params;
+
        vector<Shader*> used_shaders;
        AttributeSet attributes;
        AttributeSet curve_attributes;
index 9265299e82b852b82eeff497814de15f76fcaa31..dafb807bdf3b190e1c8878acf1443943e112c5e4 100644 (file)
@@ -22,6 +22,7 @@ set(SRC
 set(SRC_HEADERS
        subd_dice.h
        subd_patch.h
+       subd_patch_table.h
        subd_split.h
 )