[Bf-blender-cvs] [c96ae81] master: Cycles microdisplacement: ngons and attributes for subdivision meshes

Mai Lavelle noreply at git.blender.org
Fri Jul 29 09:49:26 CEST 2016


Commit: c96ae81160ad1a943fafaca44a7d5e97c2d7a0d7
Author: Mai Lavelle
Date:   Sat Jul 16 19:42:28 2016 -0400
Branches: master
https://developer.blender.org/rBc96ae81160ad1a943fafaca44a7d5e97c2d7a0d7

Cycles microdisplacement: ngons and attributes for subdivision meshes

This adds support for ngons and attributes on subdivision meshes. Ngons are
needed for proper attribute interpolation as well as correct Catmull-Clark
subdivision. Several changes are made to achieve this:

- new primitive `SubdFace` added to `Mesh`
- 3 more textures are used to store info on patches from subd meshes
- Blender export uses loop interface instead of tessface for subd meshes
- `Attribute` class is updated with a simplified way to pass primitive counts
  around and to support ngons.
- extra points for ngons are generated for O(1) attribute interpolation
- curves are temporally disabled on subd meshes to avoid various bugs with
  implementation
- old unneeded code is removed from `subd/`
- various fixes and improvements

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D2108

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

M	intern/cycles/app/cycles_xml.cpp
M	intern/cycles/blender/blender_mesh.cpp
M	intern/cycles/blender/blender_util.h
M	intern/cycles/kernel/CMakeLists.txt
M	intern/cycles/kernel/geom/geom.h
M	intern/cycles/kernel/geom/geom_attribute.h
M	intern/cycles/kernel/geom/geom_primitive.h
A	intern/cycles/kernel/geom/geom_subd_triangle.h
M	intern/cycles/kernel/kernel_textures.h
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/kernel/osl/osl_services.cpp
M	intern/cycles/kernel/svm/svm_attribute.h
M	intern/cycles/kernel/svm/svm_image.h
M	intern/cycles/render/CMakeLists.txt
M	intern/cycles/render/attribute.cpp
M	intern/cycles/render/attribute.h
M	intern/cycles/render/mesh.cpp
M	intern/cycles/render/mesh.h
A	intern/cycles/render/mesh_subdivision.cpp
M	intern/cycles/render/scene.h
M	intern/cycles/subd/CMakeLists.txt
M	intern/cycles/subd/subd_dice.cpp
M	intern/cycles/subd/subd_dice.h
D	intern/cycles/subd/subd_mesh.cpp
D	intern/cycles/subd/subd_mesh.h
M	intern/cycles/subd/subd_patch.cpp
M	intern/cycles/subd/subd_patch.h
M	intern/cycles/subd/subd_split.cpp
M	intern/cycles/subd/subd_split.h
M	intern/cycles/util/util_math.h

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

diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp
index 3aca46e..3d3aca3 100644
--- a/intern/cycles/app/cycles_xml.cpp
+++ b/intern/cycles/app/cycles_xml.cpp
@@ -35,7 +35,6 @@
 #include "shader.h"
 #include "scene.h"
 
-#include "subd_mesh.h"
 #include "subd_patch.h"
 #include "subd_split.h"
 
@@ -417,6 +416,7 @@ 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;
@@ -460,7 +460,9 @@ static void xml_read_mesh(const XMLReadState& state, pugi::xml_node node)
 		DiagSplit dsplit(sdparams);
 		sdmesh.tessellate(&dsplit);
 	}
-	else {
+	else
+#endif
+	{
 		/* create vertices */
 		mesh->verts = P;
 
@@ -568,7 +570,7 @@ static void xml_read_patch(const XMLReadState& state, pugi::xml_node node)
 		mesh->used_shaders.push_back(state.shader);
 
 		/* split */
-		SubdParams sdparams(mesh, 0, state.smooth);
+		SubdParams sdparams(mesh);
 		xml_read_float(&sdparams.dicing_rate, node, "dicing_rate");
 
 		DiagSplit dsplit(sdparams);
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index ec11a89..0744bbf 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -24,7 +24,6 @@
 #include "blender_session.h"
 #include "blender_util.h"
 
-#include "subd_mesh.h"
 #include "subd_patch.h"
 #include "subd_split.h"
 
@@ -335,44 +334,71 @@ static void attr_create_vertex_color(Scene *scene,
                                      Mesh *mesh,
                                      BL::Mesh& b_mesh,
                                      const vector<int>& nverts,
-                                     const vector<int>& face_flags)
+                                     const vector<int>& face_flags,
+                                     bool subdivision)
 {
-	BL::Mesh::tessface_vertex_colors_iterator l;
-	for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l) {
-		if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
-			continue;
+	if(subdivision) {
+		BL::Mesh::vertex_colors_iterator l;
 
-		Attribute *attr = mesh->attributes.add(
-			ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER_BYTE);
+		for(b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) {
+			if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
+				continue;
 
-		BL::MeshColorLayer::data_iterator c;
-		uchar4 *cdata = attr->data_uchar4();
-		size_t i = 0;
+			Attribute *attr = mesh->subd_attributes.add(ustring(l->name().c_str()),
+			                                            TypeDesc::TypeColor,
+			                                            ATTR_ELEMENT_CORNER_BYTE);
 
-		for(l->data.begin(c); c != l->data.end(); ++c, ++i) {
-			int tri_a[3], tri_b[3];
-			face_split_tri_indices(nverts[i], face_flags[i], tri_a, tri_b);
+			BL::Mesh::polygons_iterator p;
+			uchar4 *cdata = attr->data_uchar4();
 
-			uchar4 colors[4];
-			colors[0] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color1())));
-			colors[1] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color2())));
-			colors[2] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color3())));
-			if(nverts[i] == 4) {
-				colors[3] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color4())));
+			for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
+				int n = p->loop_total();
+				for(int i = 0; i < n; i++) {
+					float3 color = get_float3(l->data[p->loop_start() + i].color());
+					*(cdata++) = color_float_to_byte(color_srgb_to_scene_linear(color));
+				}
 			}
+		}
+	}
+	else {
+		BL::Mesh::tessface_vertex_colors_iterator l;
+		for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l) {
+			if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
+				continue;
+
+			Attribute *attr = mesh->attributes.add(ustring(l->name().c_str()),
+			                                       TypeDesc::TypeColor,
+			                                       ATTR_ELEMENT_CORNER_BYTE);
+
+			BL::MeshColorLayer::data_iterator c;
+			uchar4 *cdata = attr->data_uchar4();
+			size_t i = 0;
+
+			for(l->data.begin(c); c != l->data.end(); ++c, ++i) {
+				int tri_a[3], tri_b[3];
+				face_split_tri_indices(nverts[i], face_flags[i], tri_a, tri_b);
+
+				uchar4 colors[4];
+				colors[0] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color1())));
+				colors[1] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color2())));
+				colors[2] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color3())));
+				if(nverts[i] == 4) {
+					colors[3] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color4())));
+				}
 
-			cdata[0] = colors[tri_a[0]];
-			cdata[1] = colors[tri_a[1]];
-			cdata[2] = colors[tri_a[2]];
+				cdata[0] = colors[tri_a[0]];
+				cdata[1] = colors[tri_a[1]];
+				cdata[2] = colors[tri_a[2]];
 
-			if(nverts[i] == 4) {
-				cdata[3] = colors[tri_b[0]];
-				cdata[4] = colors[tri_b[1]];
-				cdata[5] = colors[tri_b[2]];
-				cdata += 6;
+				if(nverts[i] == 4) {
+					cdata[3] = colors[tri_b[0]];
+					cdata[4] = colors[tri_b[1]];
+					cdata[5] = colors[tri_b[2]];
+					cdata += 6;
+				}
+				else
+					cdata += 3;
 			}
-			else
-				cdata += 3;
 		}
 	}
 }
@@ -382,9 +408,40 @@ static void attr_create_uv_map(Scene *scene,
                                Mesh *mesh,
                                BL::Mesh& b_mesh,
                                const vector<int>& nverts,
-                               const vector<int>& face_flags)
+                               const vector<int>& face_flags,
+                               bool subdivision)
 {
-	if(b_mesh.tessface_uv_textures.length() != 0) {
+	if(subdivision) {
+		BL::Mesh::uv_layers_iterator l;
+		int i = 0;
+
+		for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, ++i) {
+			bool active_render = b_mesh.uv_textures[i].active_render();
+			AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
+			ustring name = ustring(l->name().c_str());
+
+			/* UV map */
+			if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) {
+				Attribute *attr;
+
+				if(active_render)
+					attr = mesh->subd_attributes.add(std, name);
+				else
+					attr = mesh->subd_attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
+
+				BL::Mesh::polygons_iterator p;
+				float3 *fdata = attr->data_float3();
+
+				for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
+					int n = p->loop_total();
+					for(int j = 0; j < n; j++) {
+						*(fdata++) = get_float3(l->data[p->loop_start() + j].uv());
+					}
+				}
+			}
+		}
+	}
+	else if(b_mesh.tessface_uv_textures.length() != 0) {
 		BL::Mesh::tessface_uv_textures_iterator l;
 
 		for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) {
@@ -465,11 +522,13 @@ static void attr_create_uv_map(Scene *scene,
 /* Create vertex pointiness attributes. */
 static void attr_create_pointiness(Scene *scene,
                                    Mesh *mesh,
-                                   BL::Mesh& b_mesh)
+                                   BL::Mesh& b_mesh,
+                                   bool subdivision)
 {
 	if(mesh->need_attribute(scene, ATTR_STD_POINTINESS)) {
 		const int numverts = b_mesh.vertices.length();
-		Attribute *attr = mesh->attributes.add(ATTR_STD_POINTINESS);
+		AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes;
+		Attribute *attr = attributes.add(ATTR_STD_POINTINESS);
 		float *data = attr->data_float();
 		int *counter = new int[numverts];
 		float *raw_data = new float[numverts];
@@ -532,30 +591,44 @@ static void attr_create_pointiness(Scene *scene,
 static void create_mesh(Scene *scene,
                         Mesh *mesh,
                         BL::Mesh& b_mesh,
-                        const vector<Shader*>& used_shaders)
+                        const vector<Shader*>& used_shaders,
+                        bool subdivision=false)
 {
 	/* count vertices and faces */
 	int numverts = b_mesh.vertices.length();
-	int numfaces = b_mesh.tessfaces.length();
+	int numfaces = (!subdivision) ? b_mesh.tessfaces.length() : b_mesh.polygons.length();
 	int numtris = 0;
+	int numcorners = 0;
+	int numngons = 0;
 	bool use_loop_normals = b_mesh.use_auto_smooth();
 
 	BL::Mesh::vertices_iterator v;
 	BL::Mesh::tessfaces_iterator f;
+	BL::Mesh::polygons_iterator p;
 
-	for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f) {
-		int4 vi = get_int4(f->vertices_raw());
-		numtris += (vi[3] == 0)? 1: 2;
+	if(!subdivision) {
+		for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f) {
+			int4 vi = get_int4(f->vertices_raw());
+			numtris += (vi[3] == 0)? 1: 2;
+		}
+	}
+	else {
+		for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
+			numngons += (p->loop_total() == 4)? 0: 1;
+			numcorners += p->loop_total();
+		}
 	}
 
 	/* allocate memory */
 	mesh->reserve_mesh(numverts, numtris);
+	mesh->reserve_subd_faces(numfaces, numngons, numcorners);
 
 	/* create vertex coordinates and normals */
 	for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
 		mesh->add_vertex(get_float3(v->co()));
 
-	Attribute *attr_N = mesh->attributes.add(ATTR_STD_VERTEX_NORMAL);
+	AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes;
+	Attribute *attr_N = attributes.add(ATTR_STD_VERTEX_NORMAL);
 	float3 *N = attr_N->data_float3();
 
 	for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N)
@@ -564,7 +637,7 @@ static void create_mesh(Scene *scene,
 
 	/* create generated coordinates from undeformed coordinates */
 	if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
-		Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
+		Attribute *attr = attributes.add(ATTR_STD_GENERATED);
 
 		float3 loc, size;
 		mesh_texture_space(b_mesh, loc, size);
@@ -577,67 +650,103 @@ static void create_mesh(Scene *scene,
 	}
 
 	/* 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list