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:
authorBrecht Van Lommel <brecht@blender.org>2021-10-24 15:19:19 +0300
committerBrecht Van Lommel <brecht@blender.org>2021-10-26 16:37:04 +0300
commitfd25e883e2807a151f673b87c152a59701a0df80 (patch)
tree9441933f32ba2672ca71c58842342a9c525e123e /intern/cycles/subd/subd_split.cpp
parentd7d40745fa09061a3117bd3669c5a46bbf611eae (diff)
Cycles: remove prefix from source code file names
Remove prefix of filenames that is the same as the folder name. This used to help when #includes were using individual files, but now they are always relative to the cycles root directory and so the prefixes are redundant. For patches and branches, git merge and rebase should be able to detect the renames and move over code to the right file.
Diffstat (limited to 'intern/cycles/subd/subd_split.cpp')
-rw-r--r--intern/cycles/subd/subd_split.cpp748
1 files changed, 0 insertions, 748 deletions
diff --git a/intern/cycles/subd/subd_split.cpp b/intern/cycles/subd/subd_split.cpp
deleted file mode 100644
index 6b352ab02c3..00000000000
--- a/intern/cycles/subd/subd_split.cpp
+++ /dev/null
@@ -1,748 +0,0 @@
-/*
- * Copyright 2011-2013 Blender Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "scene/camera.h"
-#include "scene/mesh.h"
-
-#include "subd/subd_dice.h"
-#include "subd/subd_patch.h"
-#include "subd/subd_split.h"
-
-#include "util/util_algorithm.h"
-#include "util/util_foreach.h"
-#include "util/util_hash.h"
-#include "util/util_math.h"
-#include "util/util_types.h"
-
-CCL_NAMESPACE_BEGIN
-
-/* DiagSplit */
-
-#define DSPLIT_NON_UNIFORM -1
-#define STITCH_NGON_CENTER_VERT_INDEX_OFFSET 0x60000000
-#define STITCH_NGON_SPLIT_EDGE_CENTER_VERT_TAG (0x60000000 - 1)
-
-DiagSplit::DiagSplit(const SubdParams &params_) : params(params_)
-{
-}
-
-float3 DiagSplit::to_world(Patch *patch, float2 uv)
-{
- float3 P;
-
- patch->eval(&P, NULL, NULL, NULL, uv.x, uv.y);
- if (params.camera)
- P = transform_point(&params.objecttoworld, P);
-
- return P;
-}
-
-static void order_float2(float2 &a, float2 &b)
-{
- if (b.x < a.x || b.y < a.y) {
- swap(a, b);
- }
-}
-
-int DiagSplit::T(Patch *patch, float2 Pstart, float2 Pend, bool recursive_resolve)
-{
- order_float2(Pstart, Pend); /* May not be necessary, but better to be safe. */
-
- float Lsum = 0.0f;
- float Lmax = 0.0f;
-
- float3 Plast = to_world(patch, Pstart);
-
- for (int i = 1; i < params.test_steps; i++) {
- float t = i / (float)(params.test_steps - 1);
-
- float3 P = to_world(patch, Pstart + t * (Pend - Pstart));
-
- float L;
-
- if (!params.camera) {
- L = len(P - Plast);
- }
- else {
- Camera *cam = params.camera;
-
- float pixel_width = cam->world_to_raster_size((P + Plast) * 0.5f);
- L = len(P - Plast) / pixel_width;
- }
-
- Lsum += L;
- Lmax = max(L, Lmax);
-
- Plast = P;
- }
-
- int tmin = (int)ceilf(Lsum / params.dicing_rate);
- int tmax = (int)ceilf((params.test_steps - 1) * Lmax /
- params.dicing_rate); // XXX paper says N instead of N-1, seems wrong?
- int res = max(tmax, 1);
-
- if (tmax - tmin > params.split_threshold) {
- if (!recursive_resolve) {
- res = DSPLIT_NON_UNIFORM;
- }
- else {
- float2 P = (Pstart + Pend) * 0.5f;
- res = T(patch, Pstart, P, true) + T(patch, P, Pend, true);
- }
- }
-
- limit_edge_factor(res, patch, Pstart, Pend);
- return res;
-}
-
-void DiagSplit::partition_edge(
- Patch *patch, float2 *P, int *t0, int *t1, float2 Pstart, float2 Pend, int t)
-{
- if (t == DSPLIT_NON_UNIFORM) {
- *P = (Pstart + Pend) * 0.5f;
- *t0 = T(patch, Pstart, *P);
- *t1 = T(patch, *P, Pend);
- }
- else {
- assert(t >= 2); /* Need at least two segments to partition into. */
-
- int I = (int)floorf((float)t * 0.5f);
- *P = interp(Pstart, Pend, I / (float)t);
- *t0 = I;
- *t1 = t - I;
- }
-}
-
-void DiagSplit::limit_edge_factor(int &T, Patch *patch, float2 Pstart, float2 Pend)
-{
- int max_t = 1 << params.max_level;
- int max_t_for_edge = int(max_t * len(Pstart - Pend));
-
- if (patch->from_ngon) {
- max_t_for_edge >>= 1; /* Initial split of ngon causes edges to extend half the distance. */
- }
-
- T = (max_t_for_edge <= 1) ? 1 : min(T, max_t_for_edge);
-
- assert(T >= 1 || T == DSPLIT_NON_UNIFORM);
-}
-
-void DiagSplit::resolve_edge_factors(Subpatch &sub)
-{
- /* Resolve DSPLIT_NON_UNIFORM to actual T value if splitting is no longer possible. */
- if (sub.edge_u0.T == 1 && sub.edge_u1.T == DSPLIT_NON_UNIFORM) {
- sub.edge_u1.T = T(sub.patch, sub.c01, sub.c11, true);
- }
- if (sub.edge_u1.T == 1 && sub.edge_u0.T == DSPLIT_NON_UNIFORM) {
- sub.edge_u0.T = T(sub.patch, sub.c00, sub.c10, true);
- }
- if (sub.edge_v0.T == 1 && sub.edge_v1.T == DSPLIT_NON_UNIFORM) {
- sub.edge_v1.T = T(sub.patch, sub.c11, sub.c10, true);
- }
- if (sub.edge_v1.T == 1 && sub.edge_v0.T == DSPLIT_NON_UNIFORM) {
- sub.edge_v0.T = T(sub.patch, sub.c01, sub.c00, true);
- }
-}
-
-void DiagSplit::split(Subpatch &sub, int depth)
-{
- if (depth > 32) {
- /* We should never get here, but just in case end recursion safely. */
- assert(!"diagsplit recursion limit reached");
-
- sub.edge_u0.T = 1;
- sub.edge_u1.T = 1;
- sub.edge_v0.T = 1;
- sub.edge_v1.T = 1;
-
- subpatches.push_back(sub);
- return;
- }
-
- bool split_u = (sub.edge_u0.T == DSPLIT_NON_UNIFORM || sub.edge_u1.T == DSPLIT_NON_UNIFORM);
- bool split_v = (sub.edge_v0.T == DSPLIT_NON_UNIFORM || sub.edge_v1.T == DSPLIT_NON_UNIFORM);
-
- /* Split subpatches such that the ratio of T for opposite edges doesn't
- * exceed 1.5, this reduces over tessellation for some patches
- */
- /* clang-format off */
- if (min(sub.edge_u0.T, sub.edge_u1.T) > 8 && /* Must be uniform and preferably greater than 8 to split. */
- min(sub.edge_v0.T, sub.edge_v1.T) >= 2 && /* Must be uniform and at least 2 to split. */
- max(sub.edge_u0.T, sub.edge_u1.T) / min(sub.edge_u0.T, sub.edge_u1.T) > 1.5f)
- {
- split_v = true;
- }
- if (min(sub.edge_v0.T, sub.edge_v1.T) > 8 &&
- min(sub.edge_u0.T, sub.edge_u1.T) >= 2 &&
- max(sub.edge_v0.T, sub.edge_v1.T) / min(sub.edge_v0.T, sub.edge_v1.T) > 1.5f)
- {
- split_u = true;
- }
- /* clang-format on */
-
- /* Alternate axis. */
- if (split_u && split_v) {
- split_u = depth % 2;
- }
-
- if (!split_u && !split_v) {
- /* Add the unsplit subpatch. */
- subpatches.push_back(sub);
- Subpatch &subpatch = subpatches[subpatches.size() - 1];
-
- /* Update T values and offsets. */
- for (int i = 0; i < 4; i++) {
- Subpatch::edge_t &edge = subpatch.edges[i];
-
- edge.offset = edge.edge->T;
- edge.edge->T += edge.T;
- }
- }
- else {
- /* Copy into new subpatches. */
- Subpatch sub_a = sub;
- Subpatch sub_b = sub;
-
- /* Pointers to various subpatch elements. */
- Subpatch::edge_t *sub_across_0, *sub_across_1;
- Subpatch::edge_t *sub_a_across_0, *sub_a_across_1;
- Subpatch::edge_t *sub_b_across_0, *sub_b_across_1;
-
- Subpatch::edge_t *sub_a_split, *sub_b_split;
-
- float2 *Pa, *Pb, *Pc, *Pd;
-
- /* Set pointers based on split axis. */
- if (split_u) {
- sub_across_0 = &sub.edge_u0;
- sub_across_1 = &sub.edge_u1;
- sub_a_across_0 = &sub_a.edge_u0;
- sub_a_across_1 = &sub_a.edge_u1;
- sub_b_across_0 = &sub_b.edge_u0;
- sub_b_across_1 = &sub_b.edge_u1;
-
- sub_a_split = &sub_a.edge_v1;
- sub_b_split = &sub_b.edge_v0;
-
- Pa = &sub_a.c11;
- Pb = &sub_a.c10;
- Pc = &sub_b.c01;
- Pd = &sub_b.c00;
- }
- else {
- sub_across_0 = &sub.edge_v0;
- sub_across_1 = &sub.edge_v1;
- sub_a_across_0 = &sub_a.edge_v0;
- sub_a_across_1 = &sub_a.edge_v1;
- sub_b_across_0 = &sub_b.edge_v0;
- sub_b_across_1 = &sub_b.edge_v1;
-
- sub_a_split = &sub_a.edge_u0;
- sub_b_split = &sub_b.edge_u1;
-
- Pa = &sub_a.c10;
- Pb = &sub_a.c00;
- Pc = &sub_b.c11;
- Pd = &sub_b.c01;
- }
-
- /* Partition edges */
- float2 P0, P1;
-
- partition_edge(
- sub.patch, &P0, &sub_a_across_0->T, &sub_b_across_0->T, *Pd, *Pb, sub_across_0->T);
- partition_edge(
- sub.patch, &P1, &sub_a_across_1->T, &sub_b_across_1->T, *Pc, *Pa, sub_across_1->T);
-
- /* Split */
- *Pa = P1;
- *Pb = P0;
-
- *Pc = P1;
- *Pd = P0;
-
- int tsplit = T(sub.patch, P0, P1);
-
- if (depth == -2 && tsplit == 1) {
- tsplit = 2; /* Ensure we can always split at depth -1. */
- }
-
- sub_a_split->T = tsplit;
- sub_b_split->T = tsplit;
-
- resolve_edge_factors(sub_a);
- resolve_edge_factors(sub_b);
-
- /* Create new edge */
- Edge &edge = *alloc_edge();
-
- sub_a_split->edge = &edge;
- sub_b_split->edge = &edge;
-
- sub_a_split->offset = 0;
- sub_b_split->offset = 0;
-
- sub_a_split->indices_decrease_along_edge = false;
- sub_b_split->indices_decrease_along_edge = true;
-
- sub_a_split->sub_edges_created_in_reverse_order = !split_u;
- sub_b_split->sub_edges_created_in_reverse_order = !split_u;
-
- edge.top_indices_decrease = sub_across_1->sub_edges_created_in_reverse_order;
- edge.bottom_indices_decrease = sub_across_0->sub_edges_created_in_reverse_order;
-
- /* Recurse */
- edge.T = 0;
- split(sub_a, depth + 1);
-
- int edge_t = edge.T;
- (void)edge_t;
-
- edge.top_offset = sub_across_1->edge->T;
- edge.bottom_offset = sub_across_0->edge->T;
-
- edge.T = 0; /* We calculate T twice along each edge. :/ */
- split(sub_b, depth + 1);
-
- assert(edge.T == edge_t); /* If this fails we will crash at some later point! */
-
- edge.top = sub_across_1->edge;
- edge.bottom = sub_across_0->edge;
- }
-}
-
-int DiagSplit::alloc_verts(int n)
-{
- int a = num_alloced_verts;
- num_alloced_verts += n;
- return a;
-}
-
-Edge *DiagSplit::alloc_edge()
-{
- edges.emplace_back();
- return &edges.back();
-}
-
-void DiagSplit::split_patches(Patch *patches, size_t patches_byte_stride)
-{
- int patch_index = 0;
-
- for (int f = 0; f < params.mesh->get_num_subd_faces(); f++) {
- Mesh::SubdFace face = params.mesh->get_subd_face(f);
-
- Patch *patch = (Patch *)(((char *)patches) + patch_index * patches_byte_stride);
-
- if (face.is_quad()) {
- patch_index++;
-
- split_quad(face, patch);
- }
- else {
- patch_index += face.num_corners;
-
- split_ngon(face, patch, patches_byte_stride);
- }
- }
-
- params.mesh->vert_to_stitching_key_map.clear();
- params.mesh->vert_stitching_map.clear();
-
- post_split();
-}
-
-static Edge *create_edge_from_corner(DiagSplit *split,
- const Mesh *mesh,
- const Mesh::SubdFace &face,
- int corner,
- bool &reversed,
- int v0,
- int v1)
-{
- int a = mesh->get_subd_face_corners()[face.start_corner + mod(corner + 0, face.num_corners)];
- int b = mesh->get_subd_face_corners()[face.start_corner + mod(corner + 1, face.num_corners)];
-
- reversed = !(b < a);
-
- if (b < a) {
- swap(a, b);
- swap(v0, v1);
- }
-
- Edge *edge = split->alloc_edge();
-
- edge->is_stitch_edge = true;
- edge->stitch_start_vert_index = a;
- edge->stitch_end_vert_index = b;
-
- edge->start_vert_index = v0;
- edge->end_vert_index = v1;
-
- edge->stitch_edge_key = {a, b};
-
- return edge;
-}
-
-void DiagSplit::split_quad(const Mesh::SubdFace &face, Patch *patch)
-{
- Subpatch subpatch(patch);
-
- int v = alloc_verts(4);
-
- bool v0_reversed, u1_reversed, v1_reversed, u0_reversed;
- subpatch.edge_v0.edge = create_edge_from_corner(
- this, params.mesh, face, 3, v0_reversed, v + 3, v + 0);
- subpatch.edge_u1.edge = create_edge_from_corner(
- this, params.mesh, face, 2, u1_reversed, v + 2, v + 3);
- subpatch.edge_v1.edge = create_edge_from_corner(
- this, params.mesh, face, 1, v1_reversed, v + 1, v + 2);
- subpatch.edge_u0.edge = create_edge_from_corner(
- this, params.mesh, face, 0, u0_reversed, v + 0, v + 1);
-
- subpatch.edge_v0.sub_edges_created_in_reverse_order = !v0_reversed;
- subpatch.edge_u1.sub_edges_created_in_reverse_order = u1_reversed;
- subpatch.edge_v1.sub_edges_created_in_reverse_order = v1_reversed;
- subpatch.edge_u0.sub_edges_created_in_reverse_order = !u0_reversed;
-
- subpatch.edge_v0.indices_decrease_along_edge = v0_reversed;
- subpatch.edge_u1.indices_decrease_along_edge = u1_reversed;
- subpatch.edge_v1.indices_decrease_along_edge = v1_reversed;
- subpatch.edge_u0.indices_decrease_along_edge = u0_reversed;
-
- /* Forces a split in both axis for quads, needed to match split of ngons into quads. */
- subpatch.edge_u0.T = DSPLIT_NON_UNIFORM;
- subpatch.edge_u1.T = DSPLIT_NON_UNIFORM;
- subpatch.edge_v0.T = DSPLIT_NON_UNIFORM;
- subpatch.edge_v1.T = DSPLIT_NON_UNIFORM;
-
- split(subpatch, -2);
-}
-
-static Edge *create_split_edge_from_corner(DiagSplit *split,
- const Mesh *mesh,
- const Mesh::SubdFace &face,
- int corner,
- int side,
- bool &reversed,
- int v0,
- int v1,
- int vc)
-{
- Edge *edge = split->alloc_edge();
-
- int a = mesh->get_subd_face_corners()[face.start_corner + mod(corner + 0, face.num_corners)];
- int b = mesh->get_subd_face_corners()[face.start_corner + mod(corner + 1, face.num_corners)];
-
- if (b < a) {
- edge->stitch_edge_key = {b, a};
- }
- else {
- edge->stitch_edge_key = {a, b};
- }
-
- reversed = !(b < a);
-
- if (side == 0) {
- a = vc;
- }
- else {
- b = vc;
- }
-
- if (!reversed) {
- swap(a, b);
- swap(v0, v1);
- }
-
- edge->is_stitch_edge = true;
- edge->stitch_start_vert_index = a;
- edge->stitch_end_vert_index = b;
-
- edge->start_vert_index = v0;
- edge->end_vert_index = v1;
-
- return edge;
-}
-
-void DiagSplit::split_ngon(const Mesh::SubdFace &face, Patch *patches, size_t patches_byte_stride)
-{
- Edge *prev_edge_u0 = nullptr;
- Edge *first_edge_v0 = nullptr;
-
- for (int corner = 0; corner < face.num_corners; corner++) {
- Patch *patch = (Patch *)(((char *)patches) + corner * patches_byte_stride);
-
- Subpatch subpatch(patch);
-
- int v = alloc_verts(4);
-
- /* Setup edges. */
- Edge *edge_u1 = alloc_edge();
- Edge *edge_v1 = alloc_edge();
-
- edge_v1->is_stitch_edge = true;
- edge_u1->is_stitch_edge = true;
-
- edge_u1->stitch_start_vert_index = -(face.start_corner + mod(corner + 0, face.num_corners)) -
- 1;
- edge_u1->stitch_end_vert_index = STITCH_NGON_CENTER_VERT_INDEX_OFFSET + face.ptex_offset;
-
- edge_u1->start_vert_index = v + 3;
- edge_u1->end_vert_index = v + 2;
-
- edge_u1->stitch_edge_key = {edge_u1->stitch_start_vert_index, edge_u1->stitch_end_vert_index};
-
- edge_v1->stitch_start_vert_index = -(face.start_corner + mod(corner + 1, face.num_corners)) -
- 1;
- edge_v1->stitch_end_vert_index = STITCH_NGON_CENTER_VERT_INDEX_OFFSET + face.ptex_offset;
-
- edge_v1->start_vert_index = v + 1;
- edge_v1->end_vert_index = v + 2;
-
- edge_v1->stitch_edge_key = {edge_v1->stitch_start_vert_index, edge_v1->stitch_end_vert_index};
-
- bool v0_reversed, u0_reversed;
-
- subpatch.edge_v0.edge = create_split_edge_from_corner(this,
- params.mesh,
- face,
- corner - 1,
- 0,
- v0_reversed,
- v + 3,
- v + 0,
- STITCH_NGON_SPLIT_EDGE_CENTER_VERT_TAG);
-
- subpatch.edge_u1.edge = edge_u1;
- subpatch.edge_v1.edge = edge_v1;
-
- subpatch.edge_u0.edge = create_split_edge_from_corner(this,
- params.mesh,
- face,
- corner + 0,
- 1,
- u0_reversed,
- v + 0,
- v + 1,
- STITCH_NGON_SPLIT_EDGE_CENTER_VERT_TAG);
-
- subpatch.edge_v0.sub_edges_created_in_reverse_order = !v0_reversed;
- subpatch.edge_u1.sub_edges_created_in_reverse_order = false;
- subpatch.edge_v1.sub_edges_created_in_reverse_order = true;
- subpatch.edge_u0.sub_edges_created_in_reverse_order = !u0_reversed;
-
- subpatch.edge_v0.indices_decrease_along_edge = v0_reversed;
- subpatch.edge_u1.indices_decrease_along_edge = false;
- subpatch.edge_v1.indices_decrease_along_edge = true;
- subpatch.edge_u0.indices_decrease_along_edge = u0_reversed;
-
- /* Perform split. */
- {
- subpatch.edge_u0.T = T(subpatch.patch, subpatch.c00, subpatch.c10);
- subpatch.edge_u1.T = T(subpatch.patch, subpatch.c01, subpatch.c11);
- subpatch.edge_v0.T = T(subpatch.patch, subpatch.c00, subpatch.c01);
- subpatch.edge_v1.T = T(subpatch.patch, subpatch.c10, subpatch.c11);
-
- resolve_edge_factors(subpatch);
-
- split(subpatch, 0);
- }
-
- /* Update offsets after T is known from split. */
- edge_u1->top = subpatch.edge_v0.edge;
- edge_u1->stitch_top_offset = edge_u1->top->T * (v0_reversed ? -1 : 1);
- edge_v1->top = subpatch.edge_u0.edge;
- edge_v1->stitch_top_offset = edge_v1->top->T * (!u0_reversed ? -1 : 1);
-
- if (corner == 0) {
- first_edge_v0 = subpatch.edge_v0.edge;
- }
-
- if (prev_edge_u0) {
- if (v0_reversed) {
- subpatch.edge_v0.edge->stitch_offset = prev_edge_u0->T;
- }
- else {
- prev_edge_u0->stitch_offset = subpatch.edge_v0.edge->T;
- }
-
- int T = subpatch.edge_v0.edge->T + prev_edge_u0->T;
- subpatch.edge_v0.edge->stitch_edge_T = T;
- prev_edge_u0->stitch_edge_T = T;
- }
-
- if (corner == face.num_corners - 1) {
- if (v0_reversed) {
- subpatch.edge_u0.edge->stitch_offset = first_edge_v0->T;
- }
- else {
- first_edge_v0->stitch_offset = subpatch.edge_u0.edge->T;
- }
-
- int T = first_edge_v0->T + subpatch.edge_u0.edge->T;
- first_edge_v0->stitch_edge_T = T;
- subpatch.edge_u0.edge->stitch_edge_T = T;
- }
-
- prev_edge_u0 = subpatch.edge_u0.edge;
- }
-}
-
-void DiagSplit::post_split()
-{
- int num_stitch_verts = 0;
-
- /* All patches are now split, and all T values known. */
-
- foreach (Edge &edge, edges) {
- if (edge.second_vert_index < 0) {
- edge.second_vert_index = alloc_verts(edge.T - 1);
- }
-
- if (edge.is_stitch_edge) {
- num_stitch_verts = max(num_stitch_verts,
- max(edge.stitch_start_vert_index, edge.stitch_end_vert_index));
- }
- }
-
- num_stitch_verts += 1;
-
- /* Map of edge key to edge stitching vert offset. */
- struct pair_hasher {
- size_t operator()(const pair<int, int> &k) const
- {
- return hash_uint2(k.first, k.second);
- }
- };
- typedef unordered_map<pair<int, int>, int, pair_hasher> edge_stitch_verts_map_t;
- edge_stitch_verts_map_t edge_stitch_verts_map;
-
- foreach (Edge &edge, edges) {
- if (edge.is_stitch_edge) {
- if (edge.stitch_edge_T == 0) {
- edge.stitch_edge_T = edge.T;
- }
-
- if (edge_stitch_verts_map.find(edge.stitch_edge_key) == edge_stitch_verts_map.end()) {
- edge_stitch_verts_map[edge.stitch_edge_key] = num_stitch_verts;
- num_stitch_verts += edge.stitch_edge_T - 1;
- }
- }
- }
-
- /* Set start and end indices for edges generated from a split. */
- foreach (Edge &edge, edges) {
- if (edge.start_vert_index < 0) {
- /* Fix up offsets. */
- if (edge.top_indices_decrease) {
- edge.top_offset = edge.top->T - edge.top_offset;
- }
-
- edge.start_vert_index = edge.top->get_vert_along_edge(edge.top_offset);
- }
-
- if (edge.end_vert_index < 0) {
- if (edge.bottom_indices_decrease) {
- edge.bottom_offset = edge.bottom->T - edge.bottom_offset;
- }
-
- edge.end_vert_index = edge.bottom->get_vert_along_edge(edge.bottom_offset);
- }
- }
-
- int vert_offset = params.mesh->verts.size();
-
- /* Add verts to stitching map. */
- foreach (const Edge &edge, edges) {
- if (edge.is_stitch_edge) {
- int second_stitch_vert_index = edge_stitch_verts_map[edge.stitch_edge_key];
-
- for (int i = 0; i <= edge.T; i++) {
- /* Get proper stitching key. */
- int key;
-
- if (i == 0) {
- key = edge.stitch_start_vert_index;
- }
- else if (i == edge.T) {
- key = edge.stitch_end_vert_index;
- }
- else {
- key = second_stitch_vert_index + i - 1 + edge.stitch_offset;
- }
-
- if (key == STITCH_NGON_SPLIT_EDGE_CENTER_VERT_TAG) {
- if (i == 0) {
- key = second_stitch_vert_index - 1 + edge.stitch_offset;
- }
- else if (i == edge.T) {
- key = second_stitch_vert_index - 1 + edge.T;
- }
- }
- else if (key < 0 && edge.top) { /* ngon spoke edge */
- int s = edge_stitch_verts_map[edge.top->stitch_edge_key];
- if (edge.stitch_top_offset >= 0) {
- key = s - 1 + edge.stitch_top_offset;
- }
- else {
- key = s - 1 + edge.top->stitch_edge_T + edge.stitch_top_offset;
- }
- }
-
- /* Get real vert index. */
- int vert = edge.get_vert_along_edge(i) + vert_offset;
-
- /* Add to map */
- if (params.mesh->vert_to_stitching_key_map.find(vert) ==
- params.mesh->vert_to_stitching_key_map.end()) {
- params.mesh->vert_to_stitching_key_map[vert] = key;
- params.mesh->vert_stitching_map.insert({key, vert});
- }
- }
- }
- }
-
- /* Dice; TODO(mai): Move this out of split. */
- QuadDice dice(params);
-
- int num_verts = num_alloced_verts;
- int num_triangles = 0;
-
- for (size_t i = 0; i < subpatches.size(); i++) {
- subpatches[i].inner_grid_vert_offset = num_verts;
- num_verts += subpatches[i].calc_num_inner_verts();
- num_triangles += subpatches[i].calc_num_triangles();
- }
-
- dice.reserve(num_verts, num_triangles);
-
- for (size_t i = 0; i < subpatches.size(); i++) {
- Subpatch &sub = subpatches[i];
-
- sub.edge_u0.T = max(sub.edge_u0.T, 1);
- sub.edge_u1.T = max(sub.edge_u1.T, 1);
- sub.edge_v0.T = max(sub.edge_v0.T, 1);
- sub.edge_v1.T = max(sub.edge_v1.T, 1);
-
- dice.dice(sub);
- }
-
- /* Cleanup */
- subpatches.clear();
- edges.clear();
-}
-
-CCL_NAMESPACE_END