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
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/subd/subd_dice.cpp')
-rw-r--r--intern/cycles/subd/subd_dice.cpp166
1 files changed, 10 insertions, 156 deletions
diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp
index 7c74f21950e..36981a20f3c 100644
--- a/intern/cycles/subd/subd_dice.cpp
+++ b/intern/cycles/subd/subd_dice.cpp
@@ -48,6 +48,11 @@ void EdgeDice::reserve(int num_verts)
vert_offset = mesh->verts.size();
tri_offset = mesh->num_triangles();
+ /* todo: optimize so we can reserve in advance, this is like push_back_slow() */
+ if(vert_offset + num_verts > mesh->verts.capacity()) {
+ mesh->reserve_mesh(size_t((vert_offset + num_verts) * 1.2), mesh->num_triangles());
+ }
+
mesh->resize_mesh(vert_offset + num_verts, tri_offset);
Attribute *attr_vN = mesh->attributes.add(ATTR_STD_VERTEX_NORMAL);
@@ -66,6 +71,7 @@ int EdgeDice::add_vert(Patch *patch, float2 uv)
mesh_P[vert_offset] = P;
mesh_N[vert_offset] = N;
+ params.mesh->vert_patch_uv[vert_offset] = make_float2(uv.x, uv.y);
if(params.ptex) {
Attribute *attr_ptex_uv = params.mesh->attributes.add(ATTR_STD_PTEX_UV);
@@ -75,6 +81,8 @@ int EdgeDice::add_vert(Patch *patch, float2 uv)
ptex_uv[vert_offset] = make_float3(uv.x, uv.y, 0.0f);
}
+ params.mesh->num_subd_verts++;
+
return vert_offset++;
}
@@ -86,7 +94,8 @@ void EdgeDice::add_triangle(Patch *patch, int v0, int v1, int v2)
if(mesh->triangles.size() == mesh->triangles.capacity())
mesh->reserve_mesh(mesh->verts.size(), size_t(max(mesh->num_triangles() + 1, 1) * 1.2));
- mesh->add_triangle(v0, v1, v2, params.shader, params.smooth, false);
+ mesh->add_triangle(v0, v1, v2, patch->shader, true);
+ params.mesh->triangle_patch[params.mesh->num_triangles()-1] = patch->patch_index;
if(params.ptex) {
Attribute *attr_ptex_face_id = params.mesh->attributes.add(ATTR_STD_PTEX_FACE_ID);
@@ -340,160 +349,5 @@ void QuadDice::dice(SubPatch& sub, EdgeFactors& ef)
assert(vert_offset == params.mesh->verts.size());
}
-/* TriangleDice */
-
-TriangleDice::TriangleDice(const SubdParams& params_)
-: EdgeDice(params_)
-{
-}
-
-void TriangleDice::reserve(EdgeFactors& ef, int M)
-{
- int num_verts = ef.tu + ef.tv + ef.tw;
-
- for(int m = M-2; m > 0; m -= 2)
- num_verts += 3 + (m-1)*3;
-
- if(!(M & 1))
- num_verts++;
-
- EdgeDice::reserve(num_verts);
-}
-
-float2 TriangleDice::map_uv(SubPatch& sub, float2 uv)
-{
- /* map UV from subpatch to patch parametric coordinates */
- return uv.x*sub.Pu + uv.y*sub.Pv + (1.0f - uv.x - uv.y)*sub.Pw;
-}
-
-int TriangleDice::add_vert(SubPatch& sub, float2 uv)
-{
- return EdgeDice::add_vert(sub.patch, map_uv(sub, uv));
-}
-
-void TriangleDice::add_grid(SubPatch& sub, EdgeFactors& ef, int M)
-{
- // XXX normals are flipped, why?
-
- /* grid is constructed starting from the outside edges, and adding
- * progressively smaller inner triangles that connected to the outer
- * one, until M = 1 or 2, the we fill up the last part. */
- vector<int> outer_u, outer_v, outer_w;
- int m;
-
- /* add outer corners vertices */
- {
- float2 p_u = make_float2(1.0f, 0.0f);
- float2 p_v = make_float2(0.0f, 1.0f);
- float2 p_w = make_float2(0.0f, 0.0f);
-
- int corner_u = add_vert(sub, p_u);
- int corner_v = add_vert(sub, p_v);
- int corner_w = add_vert(sub, p_w);
-
- outer_u.push_back(corner_v);
- outer_v.push_back(corner_w);
- outer_w.push_back(corner_u);
-
- for(int i = 1; i < ef.tu; i++)
- outer_u.push_back(add_vert(sub, interp(p_v, p_w, i/(float)ef.tu)));
- for(int i = 1; i < ef.tv; i++)
- outer_v.push_back(add_vert(sub, interp(p_w, p_u, i/(float)ef.tv)));
- for(int i = 1; i < ef.tw; i++)
- outer_w.push_back(add_vert(sub, interp(p_u, p_v, i/(float)ef.tw)));
-
- outer_u.push_back(corner_w);
- outer_v.push_back(corner_u);
- outer_w.push_back(corner_v);
- }
-
- for(m = M-2; m > 0; m -= 2) {
- vector<int> inner_u, inner_v, inner_w;
-
- const float t0 = m / (float)M;
- float2 center = make_float2(1.0f/3.0f, 1.0f/3.0f);
-
- /* 3 corner vertices */
- float2 p_u = interp(center, make_float2(1.0f, 0.0f), t0);
- float2 p_v = interp(center, make_float2(0.0f, 1.0f), t0);
- float2 p_w = interp(center, make_float2(0.0f, 0.0f), t0);
-
- int corner_u = add_vert(sub, p_u);
- int corner_v = add_vert(sub, p_v);
- int corner_w = add_vert(sub, p_w);
-
- /* construct array of vertex indices for each side */
- inner_u.push_back(corner_v);
- inner_v.push_back(corner_w);
- inner_w.push_back(corner_u);
-
- for(int i = 1; i < m; i++) {
- /* add vertices between corners */
- const float t1 = i / (float)m;
-
- inner_u.push_back(add_vert(sub, interp(p_v, p_w, t1)));
- inner_v.push_back(add_vert(sub, interp(p_w, p_u, t1)));
- inner_w.push_back(add_vert(sub, interp(p_u, p_v, t1)));
- }
-
- inner_u.push_back(corner_w);
- inner_v.push_back(corner_u);
- inner_w.push_back(corner_v);
-
- /* stitch together inner/outer with triangles */
- stitch_triangles(sub.patch, outer_u, inner_u);
- stitch_triangles(sub.patch, outer_v, inner_v);
- stitch_triangles(sub.patch, outer_w, inner_w);
-
- outer_u = inner_u;
- outer_v = inner_v;
- outer_w = inner_w;
- }
-
- /* fill up last part */
- if(m == -1) {
- /* single triangle */
- add_triangle(sub.patch, outer_w[0], outer_u[0], outer_v[0]);
- }
- else {
- /* center vertex + up to 6 triangles */
- int center = add_vert(sub, make_float2(1.0f/3.0f, 1.0f/3.0f));
-
- add_triangle(sub.patch, outer_w[0], outer_w[1], center);
- /* if this is false then there is only one triangle on this side */
- if(outer_w.size() > 2)
- add_triangle(sub.patch, outer_w[1], outer_w[2], center);
-
- add_triangle(sub.patch, outer_u[0], outer_u[1], center);
- if(outer_u.size() > 2)
- add_triangle(sub.patch, outer_u[1], outer_u[2], center);
-
- add_triangle(sub.patch, outer_v[0], outer_v[1], center);
- if(outer_v.size() > 2)
- add_triangle(sub.patch, outer_v[1], outer_v[2], center);
- }
-}
-
-void TriangleDice::dice(SubPatch& sub, EdgeFactors& ef)
-{
- /* todo: handle 2 1 1 resolution */
- int M = max(ef.tu, max(ef.tv, ef.tw));
-
- /* Due to the "slant" of the edges of a triangle compared to a quad, the internal
- * triangles end up smaller, causing over-tessellation. This is to correct for this
- * difference in area. Technically its only correct for equilateral triangles, but
- * its better than how it was.
- *
- * (2*cos(radians(30))/3)**0.5
- */
- float S = 0.7598356856515927f;
- M = max((int)ceil(S*M), 1);
-
- reserve(ef, M);
- add_grid(sub, ef, M);
-
- assert(vert_offset == params.mesh->verts.size());
-}
-
CCL_NAMESPACE_END