[Bf-blender-cvs] [67b4f56] temp-cycles-microdisplacement: Add geometry cache ; mesh

Mai Lavelle noreply at git.blender.org
Tue Apr 12 18:45:54 CEST 2016


Commit: 67b4f56050d19f28aa9eb3d3fb977333c5d93217
Author: Mai Lavelle
Date:   Wed Feb 24 12:46:10 2016 -0500
Branches: temp-cycles-microdisplacement
https://developer.blender.org/rB67b4f56050d19f28aa9eb3d3fb977333c5d93217

Add geometry cache ; mesh

===================================================================

M	intern/cycles/blender/blender_mesh.cpp
M	intern/cycles/render/mesh.cpp
M	intern/cycles/render/mesh.h
M	intern/cycles/render/mesh_subdivision.cpp

===================================================================

diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 410d520..5d15ac3 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -623,19 +623,18 @@ 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]])))
 				{
-					// 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);
+					mesh->set_triangle(ti++, vi[0], vi[1], vi[3], shader, smooth);
+					mesh->set_triangle(ti++, vi[2], vi[3], vi[1], shader, smooth);
 					face_flags[fi] |= FACE_FLAG_DIVIDE_24;
 				}
 				else {
-					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);
+					mesh->set_triangle(ti++, vi[0], vi[1], vi[2], shader, smooth);
+					mesh->set_triangle(ti++, vi[0], vi[2], vi[3], shader, smooth);
 					face_flags[fi] |= FACE_FLAG_DIVIDE_13;
 				}
 			}
 			else
-				mesh->set_triangle(ti++, vi[0], vi[1], vi[2], shader, smooth, false);
+				mesh->set_triangle(ti++, vi[0], vi[1], vi[2], shader, smooth);
 		}
 		else {
 			/* create patches */
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 2a059a0..f80ec68 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -35,6 +35,8 @@
 #include "util_progress.h"
 #include "util_set.h"
 
+#include "geom/geom_cache.h"
+
 CCL_NAMESPACE_BEGIN
 
 /* Triangle */
@@ -70,6 +72,15 @@ void Mesh::Curve::bounds_grow(const int k, const float4 *curve_keys, BoundBox& b
 	bounds.grow(upper, mr);
 }
 
+/* SubPatch */
+
+void Mesh::SubPatch::bounds_grow(BoundBox& bounds_) const
+{
+	// use cached bounds if available
+	if(bounds.valid())
+		bounds_.grow(bounds);
+}
+
 /* Mesh */
 
 Mesh::Mesh()
@@ -96,6 +107,8 @@ Mesh::Mesh()
 	curve_offset = 0;
 	curvekey_offset = 0;
 
+	patch_offset = 0;
+
 	attributes.triangle_mesh = this;
 	curve_attributes.curve_mesh = this;
 
@@ -119,8 +132,6 @@ void Mesh::reserve(int numverts, int numtris, int numcurves, int numcurvekeys, i
 	shader.resize(numtris);
 	smooth.resize(numtris);
 
-	forms_quad.resize(numtris);
-
 	curve_keys.resize(numcurvekeys);
 	curves.resize(numcurves);
 
@@ -138,12 +149,11 @@ void Mesh::clear()
 	shader.clear();
 	smooth.clear();
 
-	forms_quad.clear();
-
 	curve_keys.clear();
 	curves.clear();
 
 	patches.clear();
+	subpatches.clear();
 	free_osd_data();
 
 	attributes.clear();
@@ -172,7 +182,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_, bool forms_quad_)
+void Mesh::set_triangle(int i, int v0, int v1, int v2, int shader_, bool smooth_)
 {
 	Triangle tri;
 	tri.v[0] = v0;
@@ -182,10 +192,9 @@ 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_, bool forms_quad_)
+void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_)
 {
 	Triangle tri;
 	tri.v[0] = v0;
@@ -195,7 +204,6 @@ void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_, bool
 	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)
@@ -260,6 +268,10 @@ void Mesh::compute_bounds()
 				bnds.grow(key_steps[i]);
 		}
 
+		for(size_t i = 0; i < subpatches.size(); i++) {
+			subpatches[i].bounds_grow(bnds);
+		}
+
 		if(!bnds.valid()) {
 			bnds = BoundBox::empty;
 
@@ -285,6 +297,10 @@ void Mesh::compute_bounds()
 				for(size_t i = 0; i < steps_size; i++)
 					bnds.grow_safe(key_steps[i]);
 			}
+
+			for(size_t i = 0; i < subpatches.size(); i++) {
+				subpatches[i].bounds_grow(bnds);
+			}
 		}
 	}
 
@@ -564,6 +580,7 @@ void Mesh::tag_update(Scene *scene, bool rebuild)
 	if(rebuild) {
 		need_update_rebuild = true;
 		scene->light_manager->need_update = true;
+		scene->mesh_manager->need_clear_geom_cache = true;
 	}
 	else {
 		foreach(uint sindex, used_shaders)
@@ -604,6 +621,7 @@ MeshManager::MeshManager()
 	bvh = NULL;
 	need_update = true;
 	need_flags_update = true;
+	need_clear_geom_cache = true;
 }
 
 MeshManager::~MeshManager()
@@ -1062,6 +1080,8 @@ void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene
 	size_t curve_key_size = 0;
 	size_t curve_size = 0;
 
+	size_t patch_size = 0;
+
 	foreach(Mesh *mesh, scene->meshes) {
 		mesh->vert_offset = vert_size;
 		mesh->tri_offset = tri_size;
@@ -1069,11 +1089,15 @@ void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene
 		mesh->curvekey_offset = curve_key_size;
 		mesh->curve_offset = curve_size;
 
+		mesh->patch_offset = patch_size;
+
 		vert_size += mesh->verts.size();
 		tri_size += mesh->triangles.size();
 
 		curve_key_size += mesh->curve_keys.size();
 		curve_size += mesh->curves.size();
+
+		patch_size += mesh->patches.size();
 	}
 
 	if(tri_size != 0) {
@@ -1258,6 +1282,15 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
 	if(!need_update)
 		return;
 
+	GeomCache* geom_cache = device->get_geom_cache();
+	geom_cache_set_scene(geom_cache, scene);
+	geom_cache_set_max_size(geom_cache, scene->params.geom_cache_max_size);
+
+	if(need_clear_geom_cache) {
+		geom_cache_clear(device->get_geom_cache());
+		need_clear_geom_cache = false;
+	}
+
 	/* update normals */
 	foreach(Mesh *mesh, scene->meshes) {
 		foreach(uint shader, mesh->used_shaders) {
@@ -1325,6 +1358,46 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
 		if(progress.get_cancel()) return;
 	}
 
+	/* calculate bounds subpatches, done here since some patches may need to be displaced */
+	foreach(Mesh *mesh, scene->meshes) {
+		if(mesh->need_update) {
+			string msg = string_printf("Computing Subdivision Bounds %s", mesh->name.c_str());
+			progress.set_status("Updating Mesh", msg);
+
+			for(int i = 0; i < mesh->subpatches.size(); i++) {
+				Mesh::SubPatch* subpatch = &mesh->subpatches[i];
+
+				// calculate subpatch size
+				uint num_verts, num_tris;
+				mesh->diced_subpatch_size(i, &num_verts, &num_tris, NULL);
+				size_t size = sizeof(TessellatedSubPatch) + sizeof(float4)*(num_verts*2 + num_tris);
+
+				// dice subpatch
+				TessellatedSubPatch* diced = (TessellatedSubPatch*)malloc(size);
+				memset(diced, 0, sizeof(TessellatedSubPatch));
+
+				diced->vert_offset = 0;
+				diced->tri_offset = num_verts*2;
+
+				mesh->dice_subpatch(diced, i);
+
+				// displace
+				// TODO(mai): implement
+
+				// grow bounds
+				subpatch->bounds = BoundBox::empty;
+				float4* verts = &diced->data[diced->vert_offset];
+
+				for(int i = 0; i < num_verts*2; i += 2) {
+					subpatch->bounds.grow(float4_to_float3(verts[i]));
+				}
+
+				// free subpatch
+				free(diced);
+			}
+		}
+	}
+
 	/* update bvh */
 	size_t i = 0, num_bvh = 0;
 
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index 89233fe..663df93 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -70,16 +70,21 @@ public:
 		uint shader;
 		bool smooth;
 
-		bool is_quad() { return v[3] != -1; }
+		bool is_quad() const { return v[3] != -1; }
 	};
 
 	struct SubPatch {
 		int patch;
 		int edge_factors[4];
 		float2 uv[4];
+		BoundBox bounds;
+
+		SubPatch() : bounds(BoundBox::empty) {}
 
 		bool is_quad() const { return edge_factors[3] != -1; }
 
+		void bounds_grow(BoundBox& bounds) const;
+
 		bool operator == (const SubPatch& other) const
 		{
 			if(patch != other.patch)
@@ -127,7 +132,6 @@ public:
 	vector<Triangle> triangles;
 	vector<uint> shader;
 	vector<bool> smooth;
-	vector<bool> 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(). */
@@ -166,14 +170,16 @@ public:
 	size_t curve_offset;
 	size_t curvekey_offset;
 
+	size_t patch_offset;
+
 	/* Functions */
 	Mesh();
 	~Mesh();
 
 	void reserve(int numverts, int numfaces, int numcurves, int numcurvekeys, int numpatches);
 	void clear();
-	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 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 add_curve_key(float3 loc, float radius);
 	void add_curve(int first_key, int num_keys, int shader);
 	void set_patch(int i, int v0, int v1, int v2, int v3, int shader, bool smooth);
@@ -211,8 +217,9 @@ public:
 	void update_osd();
 	void free_osd_data();
 
-	void dice_subpatch(int p, SubdParams& params);
-	void tessellate(DiagSplit *split);
+	void split_patches(DiagSplit *split);
+	void diced_subpatch_size(int subpatch_id, uint* num_verts, uint* num_tris);
+	void dice_subpatch(TessellatedSubPatch* diced, int subpatch_id);
 };
 
 /* Mesh Manager */
@@ -223,6 +230,7 @@ public:
 
 	bool need_update;
 	bool need_flags_update;
+	bool need_clear_geom_cache;
 
 	MeshManager();
 	~MeshManager();
diff --git a/intern/cycles/render/mesh_subdivision.cpp b/intern/cycles/render/mesh_subdivision.cpp
index 6c650f8..6ca6e19 100644
--- a/intern/cycles/render/mesh_subdivision.cpp
+++ b/intern/cycles/render/mesh_subdivision.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-
 #include <opensubdiv/far/topologyDescriptor.h>
 #include <opensubdiv/far/primvarRefiner.h>
 #include <opensubdiv/far/patchTableFactory.h>
@@ -261,12 +260,63 @@ static float3 patch_normal(Mesh* mesh, int patch) {
 	return norm / normlen;
 }
 
-void Mesh::dice_subpatch(int subpatch_id, SubdParams& params)
+void Mesh::diced_subpatch_size(int

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list