Commit: d118d74ba393e04e0af6baae346b25675a928cf6
Author: Mai Lavelle
Date:   Tue Jun 21 06:14:05 2016 -0400
Branches: temp-cycles-microdisplacement
https://developer.blender.org/rBd118d74ba393e04e0af6baae346b25675a928cf6

Attribute interpolation for ngons

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

M       intern/cycles/blender/blender_mesh.cpp
M       intern/cycles/kernel/geom/geom_triangle.h
M       intern/cycles/render/attribute.cpp
M       intern/cycles/render/attribute.h
M       intern/cycles/render/mesh.cpp
M       intern/cycles/render/mesh.h
M       intern/cycles/subd/subd_dice.cpp

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

diff --git a/intern/cycles/blender/blender_mesh.cpp 
b/intern/cycles/blender/blender_mesh.cpp
index b384035..3f22355 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -584,6 +584,7 @@ static void create_mesh(Scene *scene,
        int numfaces = b_mesh.tessfaces.length();
        int numtris = 0;
        int total_corners = 0;
+       int num_ngons = 0;
        bool use_loop_normals = b_mesh.use_auto_smooth();
 
        BL::Mesh::vertices_iterator v;
@@ -595,13 +596,14 @@ static void create_mesh(Scene *scene,
                        numtris += (vi[3] == 0)? 1: 2;
                }
                else {
+                       num_ngons += (vi[3] == 0)? 1: 0;
                        total_corners += (vi[3] == 0)? 3: 4;
                }
        }
 
        /* allocate memory */
        mesh->reserve_mesh(numverts, numtris);
-       mesh->reserve_subd_faces(numfaces, total_corners);
+       mesh->reserve_subd_faces(numfaces, num_ngons, total_corners);
 
        /* create vertex coordinates and normals */
        for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
diff --git a/intern/cycles/kernel/geom/geom_triangle.h 
b/intern/cycles/kernel/geom/geom_triangle.h
index 0d57d02..12b31c5 100644
--- a/intern/cycles/kernel/geom/geom_triangle.h
+++ b/intern/cycles/kernel/geom/geom_triangle.h
@@ -246,7 +246,32 @@ ccl_device_inline uint 
subd_triangle_patch_face(KernelGlobals *kg, int patch)
 
 ccl_device_inline uint subd_triangle_patch_num_corners(KernelGlobals *kg, int 
patch)
 {
-       return kernel_tex_fetch(__patches, patch+1).y;
+       return kernel_tex_fetch(__patches, patch+1).y & 0xffff;
+}
+
+/* Indices of the four corners that are used by the patch */
+
+ccl_device_inline void subd_triangle_patch_corners(KernelGlobals *kg, int 
patch, int corners[4])
+{
+       uint4 data = kernel_tex_fetch(__patches, patch+1);
+       int num_corners = data.y & 0xffff;
+
+       if(num_corners == 4) {
+               /* quad */
+               corners[0] = data.z;
+               corners[1] = data.z+1;
+               corners[2] = data.z+2;
+               corners[3] = data.z+3;
+       }
+       else {
+               /* ngon */
+               int c = data.y >> 16;
+
+               corners[0] = data.z + c;
+               corners[1] = data.z + mod(c+1, num_corners);
+               corners[2] = data.w;
+               corners[3] = data.z + mod(c-1, num_corners);
+       }
 }
 
 /* Reading attributes on various subdivision triangle elements */
@@ -271,20 +296,17 @@ ccl_device float 
subd_triangle_attribute_float(KernelGlobals *kg, const ShaderDa
                float f0 = kernel_tex_fetch(__attributes_float, offset + v.x);
                float f1 = kernel_tex_fetch(__attributes_float, offset + v.y);
                float f2 = kernel_tex_fetch(__attributes_float, offset + v.z);
+               float f3 = kernel_tex_fetch(__attributes_float, offset + v.w);
 
-               if(subd_triangle_patch_num_corners(kg, patch) == 4) {
-                       float f3 = kernel_tex_fetch(__attributes_float, offset 
+ v.w);
-
-                       a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), 
uv[0].y);
-                       b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), 
uv[1].y);
-                       c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), 
uv[2].y);
-               }
-               else {
-                       a = uv[0].x*f0 + uv[0].y*f1 + (1.0f - uv[0].x - 
uv[0].y)*f2;
-                       b = uv[1].x*f0 + uv[1].y*f1 + (1.0f - uv[1].x - 
uv[1].y)*f2;
-                       c = uv[2].x*f0 + uv[2].y*f1 + (1.0f - uv[2].x - 
uv[2].y)*f2;
+               if(subd_triangle_patch_num_corners(kg, patch) != 4) {
+                       f1 = (f1+f0)*0.5f;
+                       f3 = (f3+f0)*0.5f;
                }
 
+               a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+               b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+               c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
+
 #ifdef __RAY_DIFFERENTIALS__
                if(dx) *dx = ccl_fetch(sd, du).dx*a + ccl_fetch(sd, dv).dx*b - 
(ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*c;
                if(dy) *dy = ccl_fetch(sd, du).dy*a + ccl_fetch(sd, dv).dy*b - 
(ccl_fetch(sd, du).dy + ccl_fetch(sd, dv).dy)*c;
@@ -293,30 +315,28 @@ ccl_device float 
subd_triangle_attribute_float(KernelGlobals *kg, const ShaderDa
                return ccl_fetch(sd, u)*a + ccl_fetch(sd, v)*b + (1.0f - 
ccl_fetch(sd, u) - ccl_fetch(sd, v))*c;
        }
        else if(elem == ATTR_ELEMENT_CORNER) {
-               int p = offset + subd_triangle_patch_face(kg, patch)*4;
+               int corners[4];
+               subd_triangle_patch_corners(kg, patch, corners);
 
                float2 uv[3];
                subd_triangle_patch_uv(kg, sd, uv);
 
                float a, b, c;
 
-               float f0 = kernel_tex_fetch(__attributes_float, p + 0);
-               float f1 = kernel_tex_fetch(__attributes_float, p + 1);
-               float f2 = kernel_tex_fetch(__attributes_float, p + 2);
+               float f0 = kernel_tex_fetch(__attributes_float, corners[0] + 
offset);
+               float f1 = kernel_tex_fetch(__attributes_float, corners[1] + 
offset);
+               float f2 = kernel_tex_fetch(__attributes_float, corners[2] + 
offset);
+               float f3 = kernel_tex_fetch(__attributes_float, corners[3] + 
offset);
 
-               if(subd_triangle_patch_num_corners(kg, patch) == 4) {
-                       float f3 = kernel_tex_fetch(__attributes_float, p + 3);
-
-                       a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), 
uv[0].y);
-                       b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), 
uv[1].y);
-                       c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), 
uv[2].y);
-               }
-               else {
-                       a = uv[0].x*f0 + uv[0].y*f1 + (1.0f - uv[0].x - 
uv[0].y)*f2;
-                       b = uv[1].x*f0 + uv[1].y*f1 + (1.0f - uv[1].x - 
uv[1].y)*f2;
-                       c = uv[2].x*f0 + uv[2].y*f1 + (1.0f - uv[2].x - 
uv[2].y)*f2;
+               if(subd_triangle_patch_num_corners(kg, patch) != 4) {
+                       f1 = (f1+f0)*0.5f;
+                       f3 = (f3+f0)*0.5f;
                }
 
+               a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+               b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+               c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
+
 #ifdef __RAY_DIFFERENTIALS__
                if(dx) *dx = ccl_fetch(sd, du).dx*a + ccl_fetch(sd, dv).dx*b - 
(ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*c;
                if(dy) *dy = ccl_fetch(sd, du).dy*a + ccl_fetch(sd, dv).dy*b - 
(ccl_fetch(sd, du).dy + ccl_fetch(sd, dv).dy)*c;
@@ -352,20 +372,17 @@ ccl_device float3 
subd_triangle_attribute_float3(KernelGlobals *kg, const Shader
                float3 f0 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.x));
                float3 f1 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.y));
                float3 f2 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.z));
+               float3 f3 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.w));
 
-               if(subd_triangle_patch_num_corners(kg, patch) == 4) {
-                       float3 f3 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.w));
-
-                       a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), 
uv[0].y);
-                       b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), 
uv[1].y);
-                       c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), 
uv[2].y);
-               }
-               else {
-                       a = uv[0].x*f0 + uv[0].y*f1 + (1.0f - uv[0].x - 
uv[0].y)*f2;
-                       b = uv[1].x*f0 + uv[1].y*f1 + (1.0f - uv[1].x - 
uv[1].y)*f2;
-                       c = uv[2].x*f0 + uv[2].y*f1 + (1.0f - uv[2].x - 
uv[2].y)*f2;
+               if(subd_triangle_patch_num_corners(kg, patch) != 4) {
+                       f1 = (f1+f0)*0.5f;
+                       f3 = (f3+f0)*0.5f;
                }
 
+               a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+               b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+               c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
+
 #ifdef __RAY_DIFFERENTIALS__
                if(dx) *dx = ccl_fetch(sd, du).dx*a + ccl_fetch(sd, dv).dx*b - 
(ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*c;
                if(dy) *dy = ccl_fetch(sd, du).dy*a + ccl_fetch(sd, dv).dy*b - 
(ccl_fetch(sd, du).dy + ccl_fetch(sd, dv).dy)*c;
@@ -374,7 +391,8 @@ ccl_device float3 
subd_triangle_attribute_float3(KernelGlobals *kg, const Shader
                return ccl_fetch(sd, u)*a + ccl_fetch(sd, v)*b + (1.0f - 
ccl_fetch(sd, u) - ccl_fetch(sd, v))*c;
        }
        else if(elem == ATTR_ELEMENT_CORNER || elem == 
ATTR_ELEMENT_CORNER_BYTE) {
-               int p = offset + subd_triangle_patch_face(kg, patch)*4;
+               int corners[4];
+               subd_triangle_patch_corners(kg, patch, corners);
 
                float2 uv[3];
                subd_triangle_patch_uv(kg, sd, uv);
@@ -383,34 +401,27 @@ ccl_device float3 
subd_triangle_attribute_float3(KernelGlobals *kg, const Shader
                float3 f0, f1, f2, f3;
 
                if(elem == ATTR_ELEMENT_CORNER) {
-                       f0 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, p + 0));
-                       f1 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, p + 1));
-                       f2 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, p + 2));
+                       f0 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[0] + offset));
+                       f1 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[1] + offset));
+                       f2 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[2] + offset));
+                       f3 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[3] + offset));
                }
                else {
-                       f0 = 
color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, p + 0));
-                       f1 = 
color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, p + 1));
-                       f2 = 
color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, p + 2));
+                       f0 = 
color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[0] + offset));
+                       f1 = 
color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[1] + offset));
+                       f2 = 
color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[2] + offset));
+                       f3 = 
color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[3] + offset));
                }
 
-               if(subd_triangle_patch_num_corners(kg, patch) == 4) {
-                       if(elem == ATTR_ELEMENT_CORNER) {
-                               f3 = 
float4_to_float3(kernel_tex_fetch(__attributes_float3, p + 3));
-                       }
-                       else {
-                               f3 = 
color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, p + 3));
-                       }
-
-                       a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), 
uv[0].y);
-                       b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), 
uv[1].y);
-                       c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), 
uv[2].y);
-               }
-               else {
-                       a = uv[0].x*f0 + uv[0].y*f1 + (1.0f - uv[0].x - 
uv[0].y)*f2;
-                       b = uv[1].x*f0 + uv[1].y*f1 + (1.0f - uv[1].x - 
uv[1].y)*f2;
-                       c = uv[2].x*f0 + uv[2].y*f1 + (1.0f - uv[2].x - 
uv[2].y)*f2;
+               if(subd_triangle_patch_num_corners(kg, patch) != 4) {
+                       f1 = (f1+f0)*0.5f;
+                       f3 = (f3+f0)*0.5f;
                }
 
+               a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
+               b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
+               c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
+
 #ifdef __RAY_DIFFERENTIALS__
                if(dx) *dx = ccl_fetch(sd, du).dx*a + ccl_fetch(sd, dv).dx*b - 
(ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*c;
                if(dy) *dy = ccl_fetch(sd, du).dy*a + ccl_fetch(sd, dv).dy*b - (

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to