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 'source/blender/draw/intern/mesh_extractors/extract_mesh.cc')
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh.cc153
1 files changed, 153 insertions, 0 deletions
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh.cc
new file mode 100644
index 00000000000..ec7d3a933b4
--- /dev/null
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.cc
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2021 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup draw
+ *
+ * \brief Extraction of Mesh data into VBO to feed to GPU.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_object_types.h"
+
+#include "ED_uvedit.h"
+
+#include "extract_mesh.hh"
+
+#include "draw_cache_impl.h"
+
+void *mesh_extract_buffer_get(const MeshExtract *extractor, MeshBufferList *mbuflist)
+{
+ /* NOTE: POINTER_OFFSET on windows platforms casts internally to `void *`, but on GCC/CLANG to
+ * `MeshBufferList *`. What shows a different usage versus intent. */
+ void **buffer_ptr = (void **)POINTER_OFFSET(mbuflist, extractor->mesh_buffer_offset);
+ void *buffer = *buffer_ptr;
+ BLI_assert(buffer);
+ return buffer;
+}
+
+eMRIterType mesh_extract_iter_type(const MeshExtract *ext)
+{
+ eMRIterType type = (eMRIterType)0;
+ SET_FLAG_FROM_TEST(type, (ext->iter_looptri_bm || ext->iter_looptri_mesh), MR_ITER_LOOPTRI);
+ SET_FLAG_FROM_TEST(type, (ext->iter_poly_bm || ext->iter_poly_mesh), MR_ITER_POLY);
+ SET_FLAG_FROM_TEST(type, (ext->iter_ledge_bm || ext->iter_ledge_mesh), MR_ITER_LEDGE);
+ SET_FLAG_FROM_TEST(type, (ext->iter_lvert_bm || ext->iter_lvert_mesh), MR_ITER_LVERT);
+ return type;
+}
+
+/* ---------------------------------------------------------------------- */
+/** \name Override extractors
+ * Extractors can be overridden. When overridden a specialized version is used. The next functions
+ * would check for any needed overrides and usage of the specialized version.
+ * \{ */
+
+static const MeshExtract *mesh_extract_override_hq_normals(const MeshExtract *extractor)
+{
+ if (extractor == &extract_pos_nor) {
+ return &extract_pos_nor_hq;
+ }
+ if (extractor == &extract_lnor) {
+ return &extract_lnor_hq;
+ }
+ if (extractor == &extract_tan) {
+ return &extract_tan_hq;
+ }
+ if (extractor == &extract_fdots_nor) {
+ return &extract_fdots_nor_hq;
+ }
+ return extractor;
+}
+
+static const MeshExtract *mesh_extract_override_single_material(const MeshExtract *extractor)
+{
+ if (extractor == &extract_tris) {
+ return &extract_tris_single_mat;
+ }
+ return extractor;
+}
+
+const MeshExtract *mesh_extract_override_get(const MeshExtract *extractor,
+ const bool do_hq_normals,
+ const bool do_single_mat)
+{
+ if (do_hq_normals) {
+ extractor = mesh_extract_override_hq_normals(extractor);
+ }
+
+ if (do_single_mat) {
+ extractor = mesh_extract_override_single_material(extractor);
+ }
+
+ return extractor;
+}
+
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name Extract Edit Flag Utils
+ * \{ */
+
+void mesh_render_data_face_flag(const MeshRenderData *mr,
+ const BMFace *efa,
+ const int cd_ofs,
+ EditLoopData *eattr)
+{
+ if (efa == mr->efa_act) {
+ eattr->v_flag |= VFLAG_FACE_ACTIVE;
+ }
+ if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
+ eattr->v_flag |= VFLAG_FACE_SELECTED;
+ }
+
+ if (efa == mr->efa_act_uv) {
+ eattr->v_flag |= VFLAG_FACE_UV_ACTIVE;
+ }
+ if ((cd_ofs != -1) && uvedit_face_select_test_ex(mr->toolsettings, (BMFace *)efa, cd_ofs)) {
+ eattr->v_flag |= VFLAG_FACE_UV_SELECT;
+ }
+
+#ifdef WITH_FREESTYLE
+ if (mr->freestyle_face_ofs != -1) {
+ const FreestyleFace *ffa = (const FreestyleFace *)BM_ELEM_CD_GET_VOID_P(
+ efa, mr->freestyle_face_ofs);
+ if (ffa->flag & FREESTYLE_FACE_MARK) {
+ eattr->v_flag |= VFLAG_FACE_FREESTYLE;
+ }
+ }
+#endif
+}
+
+void mesh_render_data_loop_flag(const MeshRenderData *mr,
+ BMLoop *l,
+ const int cd_ofs,
+ EditLoopData *eattr)
+{
+ if (cd_ofs == -1) {
+ return;
+ }
+ MLoopUV *luv = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l, cd_ofs);
+ if (luv != nullptr && (luv->flag & MLOOPUV_PINNED)) {
+ eattr->v_flag |= VFLAG_VERT_UV_PINNED;
+ }
+ if (uvedit_uv_select_test_ex(mr->toolsettings, l, cd_ofs)) {
+ eattr->v_flag |= VFLAG_VERT_UV_SELECT;
+ }
+}
+
+void mesh_render_data_loop_edge_flag(const MeshRenderData *mr,
+ BMLoop *l,
+ const int cd_ofs,
+ EditLoopData *eattr)
+{
+ if (cd_ofs == -1) {
+ return;
+ }
+ if (uvedit_edge_select_test_ex(mr->toolsettings, l, cd_ofs)) {
+ eattr->v_flag |= VFLAG_EDGE_UV_SELECT;
+ eattr->v_flag |= VFLAG_VERT_UV_SELECT;
+ }
+}
+
+/** \} */