Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorMai Lavelle <mai.lavelle@gmail.com>2016-08-23 20:57:45 +0300
committerMai Lavelle <mai.lavelle@gmail.com>2016-08-24 17:39:00 +0300
commit74bd80996287b3d7bb99fa9e980bb545f59155f7 (patch)
treec2a33252d26dca3c93d75bc3d14c380b106649d4 /intern
parent0ca4e3942427ad294428ba1b8db2cafe3bbdf5d6 (diff)
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.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/app/cycles_xml.cpp156
-rw-r--r--intern/cycles/kernel/svm/svm_attribute.h4
-rw-r--r--intern/cycles/render/mesh.cpp30
-rw-r--r--intern/cycles/subd/subd_dice.h2
4 files changed, 86 insertions, 106 deletions
diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp
index a54022268bb..8a3eb98a5a0 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 de978a423b4..0e55c99ae97 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 257e83171e9..b02b9b792b7 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 3002ec780e8..33d13a4ab3a 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;
}