[Bf-blender-cvs] [74bd809] master: Cycles Standalone: Fix support for subdivision meshes

Mai Lavelle noreply at git.blender.org
Wed Aug 24 16:42:42 CEST 2016


Commit: 74bd80996287b3d7bb99fa9e980bb545f59155f7
Author: Mai Lavelle
Date:   Tue Aug 23 13:57:45 2016 -0400
Branches: master
https://developer.blender.org/rB74bd80996287b3d7bb99fa9e980bb545f59155f7

Cycles Standalone: Fix support for subdivision meshes

Changes from microdisplacement work broke previous support for subdivision
meshes, sometimes leading to crashes; this makes things work again. Files
that contain "patch" nodes will need to be updated to use meshes instead, as
specifying patches was both inefficient and completely unsupported by the new
subdivision code.

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

M	intern/cycles/app/cycles_xml.cpp
M	intern/cycles/kernel/svm/svm_attribute.h
M	intern/cycles/render/mesh.cpp
M	intern/cycles/subd/subd_dice.h

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

diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp
index a540222..8a3eb98 100644
--- a/intern/cycles/app/cycles_xml.cpp
+++ b/intern/cycles/app/cycles_xml.cpp
@@ -62,7 +62,7 @@ struct XMLReadState : public XMLReader {
 	  : scene(NULL),
 	    smooth(false),
 	    shader(NULL),
-	    dicing_rate(0.0f)
+	    dicing_rate(1.0f)
 	{
 		tfm = transform_identity();
 	}
@@ -197,6 +197,9 @@ static void xml_read_camera(XMLReadState& state, pugi::xml_node node)
 	xml_read_int(&cam->width, node, "width");
 	xml_read_int(&cam->height, node, "height");
 
+	cam->full_width = cam->width;
+	cam->full_height = cam->height;
+
 	xml_read_node(state, cam, node);
 
 	cam->matrix = state.tfm;
@@ -412,53 +415,14 @@ static void xml_read_mesh(const XMLReadState& state, pugi::xml_node node)
 	xml_read_int_array(verts, node, "verts");
 	xml_read_int_array(nverts, node, "nverts");
 
-#if 0
 	if(xml_equal_string(node, "subdivision", "catmull-clark")) {
-		/* create subd mesh */
-		SubdMesh sdmesh;
-
-		/* create subd vertices */
-		for(size_t i = 0; i < P.size(); i++)
-			sdmesh.add_vert(P[i]);
-
-		/* create subd faces */
-		int index_offset = 0;
-
-		for(size_t i = 0; i < nverts.size(); i++) {
-			if(nverts[i] == 4) {
-				int v0 = verts[index_offset + 0];
-				int v1 = verts[index_offset + 1];
-				int v2 = verts[index_offset + 2];
-				int v3 = verts[index_offset + 3];
-
-				sdmesh.add_face(v0, v1, v2, v3);
-			}
-			else {
-				for(int j = 0; j < nverts[i]-2; j++) {
-					int v0 = verts[index_offset];
-					int v1 = verts[index_offset + j + 1];
-					int v2 = verts[index_offset + j + 2];
-
-					sdmesh.add_face(v0, v1, v2);
-				}
-			}
-
-			index_offset += nverts[i];
-		}
-
-		/* finalize subd mesh */
-		sdmesh.finish();
-
-		/* parameters */
-		SubdParams sdparams(mesh, shader, smooth);
-		xml_read_float(&sdparams.dicing_rate, node, "dicing_rate");
-
-		DiagSplit dsplit(sdparams);
-		sdmesh.tessellate(&dsplit);
+		mesh->subdivision_type = Mesh::SUBDIVISION_CATMULL_CLARK;
 	}
-	else
-#endif
-	{
+	else if(xml_equal_string(node, "subdivision", "linear")) {
+		mesh->subdivision_type = Mesh::SUBDIVISION_LINEAR;
+	}
+
+	if(mesh->subdivision_type == Mesh::SUBDIVISION_NONE) {
 		/* create vertices */
 		mesh->verts = P;
 
@@ -513,70 +477,63 @@ static void xml_read_mesh(const XMLReadState& state, pugi::xml_node node)
 			}
 		}
 	}
+	else {
+		/* create vertices */
+		mesh->verts = P;
 
-	/* temporary for test compatibility */
-	mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
-}
-
-/* Patch */
+		size_t num_ngons = 0;
+		size_t num_corners = 0;
+		for(size_t i = 0; i < nverts.size(); i++) {
+			num_ngons += (nverts[i] == 4) ? 0 : 1;
+			num_corners += nverts[i];
+		}
+		mesh->reserve_subd_faces(nverts.size(), num_ngons, num_corners);
 
-static void xml_read_patch(const XMLReadState& state, pugi::xml_node node)
-{
-	/* read patch */
-	Patch *patch = NULL;
+		/* create subd_faces */
+		int index_offset = 0;
 
-	vector<float3> P;
-	xml_read_float3_array(P, node, "P");
+		for(size_t i = 0; i < nverts.size(); i++) {
+			mesh->add_subd_face(&verts[index_offset], nverts[i], shader, smooth);
+			index_offset += nverts[i];
+		}
 
-	if(xml_equal_string(node, "type", "bilinear")) {
-		/* bilinear patch */
-		if(P.size() == 4) {
-			LinearQuadPatch *bpatch = new LinearQuadPatch();
+		/* uv map */
+		if(xml_read_float_array(UV, node, "UV")) {
+			ustring name = ustring("UVMap");
+			Attribute *attr = mesh->subd_attributes.add(ATTR_STD_UV, name);
+			float3 *fdata = attr->data_float3();
 
-			for(int i = 0; i < 4; i++)
-				P[i] = transform_point(&state.tfm, P[i]);
-			memcpy(bpatch->hull, &P[0], sizeof(bpatch->hull));
+#if 0
+			if(subdivide_uvs) {
+				attr->flags |= ATTR_SUBDIVIDED;
+			}
+#endif
 
-			patch = bpatch;
+			index_offset = 0;
+			for(size_t i = 0; i < nverts.size(); i++) {
+				for(int j = 0; j < nverts[i]; j++) {
+					*(fdata++) = make_float3(UV[index_offset++]);
+				}
+			}
 		}
-		else
-			fprintf(stderr, "Invalid number of control points for bilinear patch.\n");
-	}
-	else if(xml_equal_string(node, "type", "bicubic")) {
-		/* bicubic patch */
-		if(P.size() == 16) {
-			BicubicPatch *bpatch = new BicubicPatch();
-
-			for(int i = 0; i < 16; i++)
-				P[i] = transform_point(&state.tfm, P[i]);
-			memcpy(bpatch->hull, &P[0], sizeof(bpatch->hull));
 
-			patch = bpatch;
+		/* setup subd params */
+		if(!mesh->subd_params) {
+			mesh->subd_params = new SubdParams(mesh);
 		}
-		else
-			fprintf(stderr, "Invalid number of control points for bicubic patch.\n");
-	}
-	else
-		fprintf(stderr, "Unknown patch type.\n");
+		SubdParams& sdparams = *mesh->subd_params;
 
-	if(patch) {
-		/* add mesh */
-		Mesh *mesh = xml_add_mesh(state.scene, transform_identity());
-
-		mesh->used_shaders.push_back(state.shader);
-
-		/* split */
-		SubdParams sdparams(mesh);
+		sdparams.dicing_rate = state.dicing_rate;
 		xml_read_float(&sdparams.dicing_rate, node, "dicing_rate");
+		sdparams.dicing_rate = std::max(0.1f, sdparams.dicing_rate);
 
-		DiagSplit dsplit(sdparams);
-		dsplit.split_quad(patch);
-
-		delete patch;
-
-		/* temporary for test compatibility */
-		mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
+		state.scene->camera->update();
+		sdparams.camera = state.scene->camera;
+		sdparams.objecttoworld = state.tfm;
 	}
+
+	/* temporary for test compatibility */
+	mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
 }
 
 /* Light */
@@ -676,9 +633,6 @@ static void xml_read_scene(XMLReadState& state, pugi::xml_node scene_node)
 		else if(string_iequals(node.name(), "mesh")) {
 			xml_read_mesh(state, node);
 		}
-		else if(string_iequals(node.name(), "patch")) {
-			xml_read_patch(state, node);
-		}
 		else if(string_iequals(node.name(), "light")) {
 			xml_read_light(state, node);
 		}
@@ -739,7 +693,7 @@ void xml_read_file(Scene *scene, const char *filepath)
 	state.tfm = transform_identity();
 	state.shader = scene->default_surface;
 	state.smooth = false;
-	state.dicing_rate = 0.1f;
+	state.dicing_rate = 1.0f;
 	state.base = path_dirname(filepath);
 
 	xml_read_include(state, path_filename(filepath));
diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h
index de978a4..0e55c99 100644
--- a/intern/cycles/kernel/svm/svm_attribute.h
+++ b/intern/cycles/kernel/svm/svm_attribute.h
@@ -30,14 +30,14 @@ ccl_device AttributeDescriptor svm_node_attr_init(KernelGlobals *kg, ShaderData
 	if(ccl_fetch(sd, object) != OBJECT_NONE) {
 		desc = find_attribute(kg, sd, node.y);
 		if(desc.offset == ATTR_STD_NOT_FOUND) {
-			desc.element = ATTR_ELEMENT_NONE;
+			desc = attribute_not_found();
 			desc.offset = 0;
 			desc.type = (NodeAttributeType)node.w;
 		}
 	}
 	else {
 		/* background */
-		desc.element = ATTR_ELEMENT_NONE;
+		desc = attribute_not_found();
 		desc.offset = 0;
 		desc.type = (NodeAttributeType)node.w;
 	}
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 257e831..b02b9b7 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -500,7 +500,7 @@ void Mesh::add_vertex_normals()
 	size_t triangles_size = num_triangles();
 
 	/* static vertex normals */
-	if(!attributes.find(ATTR_STD_VERTEX_NORMAL)) {
+	if(!attributes.find(ATTR_STD_VERTEX_NORMAL) && triangles_size) {
 		/* get attributes */
 		Attribute *attr_fN = attributes.find(ATTR_STD_FACE_NORMAL);
 		Attribute *attr_vN = attributes.add(ATTR_STD_VERTEX_NORMAL);
@@ -529,7 +529,7 @@ void Mesh::add_vertex_normals()
 	Attribute *attr_mP = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
 	Attribute *attr_mN = attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
 
-	if(has_motion_blur() && attr_mP && !attr_mN) {
+	if(has_motion_blur() && attr_mP && !attr_mN && triangles_size) {
 		/* create attribute */
 		attr_mN = attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
 
@@ -556,6 +556,32 @@ void Mesh::add_vertex_normals()
 			}
 		}
 	}
+
+	/* subd vertex normals */
+	if(!subd_attributes.find(ATTR_STD_VERTEX_NORMAL) && subd_faces.size()) {
+		/* get attributes */
+		Attribute *attr_vN = subd_attributes.add(ATTR_STD_VERTEX_NORMAL);
+		float3 *vN = attr_vN->data_float3();
+
+		/* compute vertex normals */
+		memset(vN, 0, verts.size()*sizeof(float3));
+
+		for(size_t i = 0; i < subd_faces.size(); i++) {
+			SubdFace& face = subd_faces[i];
+
+			for(size_t j = 0; j < face.num_corners; j++) {
+				size_t corner = subd_face_corners[face.start_corner+j];
+				vN[corner] += verts[corner];
+			}
+		}
+
+		for(size_t i = 0; i < verts_size; i++) {
+			vN[i] = normalize(vN[i]);
+			if(flip) {
+				vN[i] = -vN[i];
+			}
+		}
+	}
 }
 
 void Mesh::pack_normals(Scene *scene, uint *tri_shader, float4 *vnormal)
diff --git a/intern/cycles/subd/subd_dice.h b/intern/cycles/subd/subd_dice.h
index 3002ec7..33d13a4 100644
--- a/intern/cycles/subd/subd_dice.h
+++ b/intern/cycles/subd/subd_dice.h
@@ -49,7 +49,7 @@ struct SubdParams {
 
 		test_steps = 3;
 		split_threshold = 1;
-		dicing_rate = 0.1f;
+		dicing_rate = 1.0f;
 		max_level = 12;
 		camera = NULL;
 	}




More information about the Bf-blender-cvs mailing list