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/source
diff options
context:
space:
mode:
authorJeroen Bakker <jeroen@blender.org>2021-06-08 12:37:15 +0300
committerJeroen Bakker <jeroen@blender.org>2021-06-08 13:03:06 +0300
commit088ea59b7e1db0a80cd19c4fc670eea24cac8fc0 (patch)
tree368e8efd52e67cae46b9e4094500d74e77db6389 /source
parentcac9828ae382017fb0d09b48c5187ffcd9bb3126 (diff)
Cleanup: Separate compile unit lines_adjacency.
Diffstat (limited to 'source')
-rw-r--r--source/blender/draw/CMakeLists.txt1
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh_extractors.c152
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc198
3 files changed, 199 insertions, 152 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 8ae6b3505d1..3289a7bd2dd 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -55,6 +55,7 @@ set(SRC
intern/draw_cache_extract_mesh_render_data.c
intern/draw_cache_extract_mesh.cc
intern/mesh_extractors/extract_mesh_ibo_fdots.cc
+ intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc
intern/mesh_extractors/extract_mesh_ibo_lines_paint_mask.cc
intern/mesh_extractors/extract_mesh_ibo_lines.cc
intern/mesh_extractors/extract_mesh_ibo_points.cc
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_extractors.c b/source/blender/draw/intern/draw_cache_extract_mesh_extractors.c
index 3ce2ed0fe2c..2bd8c228cff 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh_extractors.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh_extractors.c
@@ -106,158 +106,6 @@ const MeshExtract *mesh_extract_override_get(const MeshExtract *extractor,
/** \} */
/* ---------------------------------------------------------------------- */
-/** \name Extract Line Adjacency Indices
- * \{ */
-
-#define NO_EDGE INT_MAX
-
-typedef struct MeshExtract_LineAdjacency_Data {
- GPUIndexBufBuilder elb;
- EdgeHash *eh;
- bool is_manifold;
- /* Array to convert vert index to any loop index of this vert. */
- uint vert_to_loop[0];
-} MeshExtract_LineAdjacency_Data;
-
-static void *extract_lines_adjacency_init(const MeshRenderData *mr,
- struct MeshBatchCache *UNUSED(cache),
- void *UNUSED(buf))
-{
- /* Similar to poly_to_tri_count().
- * There is always (loop + triangle - 1) edges inside a polygon.
- * Accumulate for all polys and you get : */
- uint tess_edge_len = mr->loop_len + mr->tri_len - mr->poly_len;
-
- size_t vert_to_loop_size = sizeof(uint) * mr->vert_len;
-
- MeshExtract_LineAdjacency_Data *data = MEM_callocN(sizeof(*data) + vert_to_loop_size, __func__);
- GPU_indexbuf_init(&data->elb, GPU_PRIM_LINES_ADJ, tess_edge_len, mr->loop_len);
- data->eh = BLI_edgehash_new_ex(__func__, tess_edge_len);
- data->is_manifold = true;
- return data;
-}
-
-BLI_INLINE void lines_adjacency_triangle(
- uint v1, uint v2, uint v3, uint l1, uint l2, uint l3, MeshExtract_LineAdjacency_Data *data)
-{
- GPUIndexBufBuilder *elb = &data->elb;
- /* Iterate around the triangle's edges. */
- for (int e = 0; e < 3; e++) {
- SHIFT3(uint, v3, v2, v1);
- SHIFT3(uint, l3, l2, l1);
-
- bool inv_indices = (v2 > v3);
- void **pval;
- bool value_is_init = BLI_edgehash_ensure_p(data->eh, v2, v3, &pval);
- int v_data = POINTER_AS_INT(*pval);
- if (!value_is_init || v_data == NO_EDGE) {
- /* Save the winding order inside the sign bit. Because the
- * Edge-hash sort the keys and we need to compare winding later. */
- int value = (int)l1 + 1; /* 0 cannot be signed so add one. */
- *pval = POINTER_FROM_INT((inv_indices) ? -value : value);
- /* Store loop indices for remaining non-manifold edges. */
- data->vert_to_loop[v2] = l2;
- data->vert_to_loop[v3] = l3;
- }
- else {
- /* HACK Tag as not used. Prevent overhead of BLI_edgehash_remove. */
- *pval = POINTER_FROM_INT(NO_EDGE);
- bool inv_opposite = (v_data < 0);
- uint l_opposite = (uint)abs(v_data) - 1;
- /* TODO Make this part thread-safe. */
- if (inv_opposite == inv_indices) {
- /* Don't share edge if triangles have non matching winding. */
- GPU_indexbuf_add_line_adj_verts(elb, l1, l2, l3, l1);
- GPU_indexbuf_add_line_adj_verts(elb, l_opposite, l2, l3, l_opposite);
- data->is_manifold = false;
- }
- else {
- GPU_indexbuf_add_line_adj_verts(elb, l1, l2, l3, l_opposite);
- }
- }
- }
-}
-
-static void extract_lines_adjacency_iter_looptri_bm(const MeshRenderData *UNUSED(mr),
- BMLoop **elt,
- const int UNUSED(elt_index),
- void *data)
-{
- if (!BM_elem_flag_test(elt[0]->f, BM_ELEM_HIDDEN)) {
- lines_adjacency_triangle(BM_elem_index_get(elt[0]->v),
- BM_elem_index_get(elt[1]->v),
- BM_elem_index_get(elt[2]->v),
- BM_elem_index_get(elt[0]),
- BM_elem_index_get(elt[1]),
- BM_elem_index_get(elt[2]),
- data);
- }
-}
-
-static void extract_lines_adjacency_iter_looptri_mesh(const MeshRenderData *mr,
- const MLoopTri *mlt,
- const int UNUSED(elt_index),
- void *data)
-{
- const MPoly *mp = &mr->mpoly[mlt->poly];
- if (!(mr->use_hide && (mp->flag & ME_HIDE))) {
- lines_adjacency_triangle(mr->mloop[mlt->tri[0]].v,
- mr->mloop[mlt->tri[1]].v,
- mr->mloop[mlt->tri[2]].v,
- mlt->tri[0],
- mlt->tri[1],
- mlt->tri[2],
- data);
- }
-}
-
-static void extract_lines_adjacency_finish(const MeshRenderData *UNUSED(mr),
- struct MeshBatchCache *cache,
- void *buf,
- void *_data)
-{
- GPUIndexBuf *ibo = buf;
- MeshExtract_LineAdjacency_Data *data = _data;
- /* Create edges for remaining non manifold edges. */
- EdgeHashIterator *ehi = BLI_edgehashIterator_new(data->eh);
- for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
- uint v2, v3, l1, l2, l3;
- int v_data = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi));
- if (v_data != NO_EDGE) {
- BLI_edgehashIterator_getKey(ehi, &v2, &v3);
- l1 = (uint)abs(v_data) - 1;
- if (v_data < 0) { /* inv_opposite */
- SWAP(uint, v2, v3);
- }
- l2 = data->vert_to_loop[v2];
- l3 = data->vert_to_loop[v3];
- GPU_indexbuf_add_line_adj_verts(&data->elb, l1, l2, l3, l1);
- data->is_manifold = false;
- }
- }
- BLI_edgehashIterator_free(ehi);
- BLI_edgehash_free(data->eh, NULL);
-
- cache->is_manifold = data->is_manifold;
-
- GPU_indexbuf_build_in_place(&data->elb, ibo);
- MEM_freeN(data);
-}
-
-#undef NO_EDGE
-
-const MeshExtract extract_lines_adjacency = {
- .init = extract_lines_adjacency_init,
- .iter_looptri_bm = extract_lines_adjacency_iter_looptri_bm,
- .iter_looptri_mesh = extract_lines_adjacency_iter_looptri_mesh,
- .finish = extract_lines_adjacency_finish,
- .data_type = 0,
- .use_threading = false,
- .mesh_buffer_offset = offsetof(MeshBufferCache, ibo.lines_adjacency)};
-
-/** \} */
-
-/* ---------------------------------------------------------------------- */
/** \name Extract Edit UV Triangles Indices
* \{ */
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc
new file mode 100644
index 00000000000..570ea46ce8d
--- /dev/null
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc
@@ -0,0 +1,198 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2021 by Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup draw
+ */
+
+#include "draw_cache_extract_mesh_private.h"
+
+#include "BLI_edgehash.h"
+#include "BLI_vector.hh"
+
+#include "MEM_guardedalloc.h"
+
+namespace blender::draw {
+
+/* ---------------------------------------------------------------------- */
+/** \name Extract Line Adjacency Indices
+ * \{ */
+
+#define NO_EDGE INT_MAX
+
+typedef struct MeshExtract_LineAdjacency_Data {
+ GPUIndexBufBuilder elb;
+ EdgeHash *eh;
+ bool is_manifold;
+ /* Array to convert vert index to any loop index of this vert. */
+ uint vert_to_loop[0];
+} MeshExtract_LineAdjacency_Data;
+
+static void *extract_lines_adjacency_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(buf))
+{
+ /* Similar to poly_to_tri_count().
+ * There is always (loop + triangle - 1) edges inside a polygon.
+ * Accumulate for all polys and you get : */
+ uint tess_edge_len = mr->loop_len + mr->tri_len - mr->poly_len;
+
+ size_t vert_to_loop_size = sizeof(uint) * mr->vert_len;
+
+ MeshExtract_LineAdjacency_Data *data = static_cast<MeshExtract_LineAdjacency_Data *>(
+ MEM_callocN(sizeof(*data) + vert_to_loop_size, __func__));
+ GPU_indexbuf_init(&data->elb, GPU_PRIM_LINES_ADJ, tess_edge_len, mr->loop_len);
+ data->eh = BLI_edgehash_new_ex(__func__, tess_edge_len);
+ data->is_manifold = true;
+ return data;
+}
+
+BLI_INLINE void lines_adjacency_triangle(
+ uint v1, uint v2, uint v3, uint l1, uint l2, uint l3, MeshExtract_LineAdjacency_Data *data)
+{
+ GPUIndexBufBuilder *elb = &data->elb;
+ /* Iterate around the triangle's edges. */
+ for (int e = 0; e < 3; e++) {
+ SHIFT3(uint, v3, v2, v1);
+ SHIFT3(uint, l3, l2, l1);
+
+ bool inv_indices = (v2 > v3);
+ void **pval;
+ bool value_is_init = BLI_edgehash_ensure_p(data->eh, v2, v3, &pval);
+ int v_data = POINTER_AS_INT(*pval);
+ if (!value_is_init || v_data == NO_EDGE) {
+ /* Save the winding order inside the sign bit. Because the
+ * Edge-hash sort the keys and we need to compare winding later. */
+ int value = (int)l1 + 1; /* 0 cannot be signed so add one. */
+ *pval = POINTER_FROM_INT((inv_indices) ? -value : value);
+ /* Store loop indices for remaining non-manifold edges. */
+ data->vert_to_loop[v2] = l2;
+ data->vert_to_loop[v3] = l3;
+ }
+ else {
+ /* HACK Tag as not used. Prevent overhead of BLI_edgehash_remove. */
+ *pval = POINTER_FROM_INT(NO_EDGE);
+ bool inv_opposite = (v_data < 0);
+ uint l_opposite = (uint)abs(v_data) - 1;
+ /* TODO Make this part thread-safe. */
+ if (inv_opposite == inv_indices) {
+ /* Don't share edge if triangles have non matching winding. */
+ GPU_indexbuf_add_line_adj_verts(elb, l1, l2, l3, l1);
+ GPU_indexbuf_add_line_adj_verts(elb, l_opposite, l2, l3, l_opposite);
+ data->is_manifold = false;
+ }
+ else {
+ GPU_indexbuf_add_line_adj_verts(elb, l1, l2, l3, l_opposite);
+ }
+ }
+ }
+}
+
+static void extract_lines_adjacency_iter_looptri_bm(const MeshRenderData *UNUSED(mr),
+ BMLoop **elt,
+ const int UNUSED(elt_index),
+ void *_data)
+{
+ MeshExtract_LineAdjacency_Data *data = static_cast<MeshExtract_LineAdjacency_Data *>(_data);
+ if (!BM_elem_flag_test(elt[0]->f, BM_ELEM_HIDDEN)) {
+ lines_adjacency_triangle(BM_elem_index_get(elt[0]->v),
+ BM_elem_index_get(elt[1]->v),
+ BM_elem_index_get(elt[2]->v),
+ BM_elem_index_get(elt[0]),
+ BM_elem_index_get(elt[1]),
+ BM_elem_index_get(elt[2]),
+ data);
+ }
+}
+
+static void extract_lines_adjacency_iter_looptri_mesh(const MeshRenderData *mr,
+ const MLoopTri *mlt,
+ const int UNUSED(elt_index),
+ void *_data)
+{
+ MeshExtract_LineAdjacency_Data *data = static_cast<MeshExtract_LineAdjacency_Data *>(_data);
+ const MPoly *mp = &mr->mpoly[mlt->poly];
+ if (!(mr->use_hide && (mp->flag & ME_HIDE))) {
+ lines_adjacency_triangle(mr->mloop[mlt->tri[0]].v,
+ mr->mloop[mlt->tri[1]].v,
+ mr->mloop[mlt->tri[2]].v,
+ mlt->tri[0],
+ mlt->tri[1],
+ mlt->tri[2],
+ data);
+ }
+}
+
+static void extract_lines_adjacency_finish(const MeshRenderData *UNUSED(mr),
+ struct MeshBatchCache *cache,
+ void *buf,
+ void *_data)
+{
+ GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buf);
+ MeshExtract_LineAdjacency_Data *data = static_cast<MeshExtract_LineAdjacency_Data *>(_data);
+ /* Create edges for remaining non manifold edges. */
+ EdgeHashIterator *ehi = BLI_edgehashIterator_new(data->eh);
+ for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
+ uint v2, v3, l1, l2, l3;
+ int v_data = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi));
+ if (v_data != NO_EDGE) {
+ BLI_edgehashIterator_getKey(ehi, &v2, &v3);
+ l1 = (uint)abs(v_data) - 1;
+ if (v_data < 0) { /* inv_opposite */
+ SWAP(uint, v2, v3);
+ }
+ l2 = data->vert_to_loop[v2];
+ l3 = data->vert_to_loop[v3];
+ GPU_indexbuf_add_line_adj_verts(&data->elb, l1, l2, l3, l1);
+ data->is_manifold = false;
+ }
+ }
+ BLI_edgehashIterator_free(ehi);
+ BLI_edgehash_free(data->eh, NULL);
+
+ cache->is_manifold = data->is_manifold;
+
+ GPU_indexbuf_build_in_place(&data->elb, ibo);
+ MEM_freeN(data);
+}
+
+#undef NO_EDGE
+
+/** \} */
+
+constexpr MeshExtract create_extractor_lines_adjacency()
+{
+ MeshExtract extractor = {0};
+ extractor.init = extract_lines_adjacency_init;
+ extractor.iter_looptri_bm = extract_lines_adjacency_iter_looptri_bm;
+ extractor.iter_looptri_mesh = extract_lines_adjacency_iter_looptri_mesh;
+ extractor.finish = extract_lines_adjacency_finish;
+ extractor.data_type = MR_DATA_NONE;
+ extractor.use_threading = false;
+ extractor.mesh_buffer_offset = offsetof(MeshBufferCache, ibo.lines_adjacency);
+ return extractor;
+}
+
+} // namespace blender::draw
+
+extern "C" {
+const MeshExtract extract_lines_adjacency = blender::draw::create_extractor_lines_adjacency();
+}
+
+/** \} */