diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 45ec92a7961..0e46903a50c 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -393,11 +393,16 @@ static void create_subd_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, PointerR /* finalize subd mesh */ sdmesh.finish(); - SubdParams sdparams(mesh, used_shaders[0], true); + /* parameters */ + bool need_ptex = mesh->need_attribute(scene, ATTR_STD_PTEX_FACE_ID) || + mesh->need_attribute(scene, ATTR_STD_PTEX_UV); + + SubdParams sdparams(mesh, used_shaders[0], true, need_ptex); sdparams.dicing_rate = RNA_float_get(cmesh, "dicing_rate"); //scene->camera->update(); //sdparams.camera = scene->camera; + /* tesselate */ DiagSplit dsplit(sdparams);; sdmesh.tessellate(&dsplit); } diff --git a/intern/cycles/kernel/kernel_primitive.h b/intern/cycles/kernel/kernel_primitive.h index ababad28f35..0e39c489fbc 100644 --- a/intern/cycles/kernel/kernel_primitive.h +++ b/intern/cycles/kernel/kernel_primitive.h @@ -89,6 +89,25 @@ ccl_device float3 primitive_uv(KernelGlobals *kg, ShaderData *sd) return uv; } +ccl_device bool primitive_ptex(KernelGlobals *kg, ShaderData *sd, float2 *uv, int *face_id) +{ + /* storing ptex data as attributes is not memory efficient but simple for tests */ + AttributeElement elem_face_id, elem_uv; + int offset_face_id = find_attribute(kg, sd, ATTR_STD_PTEX_FACE_ID, &elem_face_id); + int offset_uv = find_attribute(kg, sd, ATTR_STD_PTEX_UV, &elem_uv); + + if(offset_face_id == ATTR_STD_NOT_FOUND || offset_uv == ATTR_STD_NOT_FOUND) + return false; + + float3 uv3 = primitive_attribute_float3(kg, sd, elem_uv, offset_uv, NULL, NULL); + float face_id_f = primitive_attribute_float(kg, sd, elem_face_id, offset_face_id, NULL, NULL); + + *uv = make_float2(uv3.x, uv3.y); + *face_id = (int)face_id_f; + + return true; +} + ccl_device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd) { #ifdef __HAIR__ diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 3371c580c71..51a49348810 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -436,6 +436,8 @@ typedef enum AttributeStandard { ATTR_STD_MOTION_POST, ATTR_STD_PARTICLE, ATTR_STD_CURVE_INTERCEPT, + ATTR_STD_PTEX_FACE_ID, + ATTR_STD_PTEX_UV, ATTR_STD_NUM, ATTR_STD_NOT_FOUND = ~0 diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index 319616450e1..6640439eca9 100644 --- a/intern/cycles/render/attribute.cpp +++ b/intern/cycles/render/attribute.cpp @@ -147,6 +147,10 @@ const char *Attribute::standard_name(AttributeStandard std) return "particle"; else if(std == ATTR_STD_CURVE_INTERCEPT) return "curve_intercept"; + else if(std == ATTR_STD_PTEX_FACE_ID) + return "ptex_face_id"; + else if(std == ATTR_STD_PTEX_UV) + return "ptex_uv"; return ""; } @@ -246,6 +250,12 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) case ATTR_STD_MOTION_POST: attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX); break; + case ATTR_STD_PTEX_FACE_ID: + attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_FACE); + break; + case ATTR_STD_PTEX_UV: + attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX); + break; default: assert(0); break; diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp index f77df388c87..05ff5ca4b65 100644 --- a/intern/cycles/subd/subd_dice.cpp +++ b/intern/cycles/subd/subd_dice.cpp @@ -34,6 +34,11 @@ EdgeDice::EdgeDice(const SubdParams& params_) vert_offset = 0; params.mesh->attributes.add(ATTR_STD_VERTEX_NORMAL); + + if(params.ptex) { + params.mesh->attributes.add(ATTR_STD_PTEX_UV); + params.mesh->attributes.add(ATTR_STD_PTEX_FACE_ID); + } } void EdgeDice::reserve(int num_verts, int num_tris) @@ -63,12 +68,29 @@ int EdgeDice::add_vert(Patch *patch, float2 uv) mesh_P[vert_offset] = P; mesh_N[vert_offset] = N; + if(params.ptex) { + Attribute *attr_ptex_uv = params.mesh->attributes.add(ATTR_STD_PTEX_UV); + params.mesh->attributes.reserve(); + + float3 *ptex_uv = attr_ptex_uv->data_float3(); + ptex_uv[vert_offset] = make_float3(uv.x, uv.y, 0.0f); + } + return vert_offset++; } void EdgeDice::add_triangle(Patch *patch, int v0, int v1, int v2) { params.mesh->add_triangle(v0, v1, v2, params.shader, params.smooth); + + if(params.ptex) { + Attribute *attr_ptex_face_id = params.mesh->attributes.add(ATTR_STD_PTEX_FACE_ID); + params.mesh->attributes.reserve(); + + float *ptex_face_id = attr_ptex_face_id->data_float(); + ptex_face_id[tri_offset] = (float)patch->ptex_face_id(); + } + tri_offset++; } diff --git a/intern/cycles/subd/subd_dice.h b/intern/cycles/subd/subd_dice.h index 037b17bbfc8..9cf5b0d50b8 100644 --- a/intern/cycles/subd/subd_dice.h +++ b/intern/cycles/subd/subd_dice.h @@ -35,17 +35,19 @@ struct SubdParams { Mesh *mesh; int shader; bool smooth; + bool ptex; int test_steps; int split_threshold; float dicing_rate; Camera *camera; - SubdParams(Mesh *mesh_, int shader_, bool smooth_ = true) + SubdParams(Mesh *mesh_, int shader_, bool smooth_ = true, bool ptex_ = false) { mesh = mesh_; shader = shader_; smooth = smooth_; + ptex = ptex_; test_steps = 3; split_threshold = 1; diff --git a/intern/cycles/subd/subd_patch.h b/intern/cycles/subd/subd_patch.h index b851fef16ae..48f35d78711 100644 --- a/intern/cycles/subd/subd_patch.h +++ b/intern/cycles/subd/subd_patch.h @@ -28,6 +28,7 @@ public: virtual void eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float v) = 0; virtual bool is_triangle() { return false; } virtual BoundBox bound() = 0; + virtual int ptex_face_id() { return -1; } }; /* Linear Quad Patch */