[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