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:
authorSergey Sharybin <sergey.vfx@gmail.com>2018-07-11 11:36:13 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2018-07-11 13:55:22 +0300
commitc37ca437209f00ffe1b56cef2a5e8bbf390e669a (patch)
tree75f09f48e0c07cc18d5f87573344fcc65c80b9a8
parent3eab8156d369f40de9d8c23672b1de28491ea920 (diff)
OpenSubdiv: Changes in C-API
- Made OpenSubdiv_GLMesh private Previously, it was still accessible via C-API from C++ code. - Don't implicitly refine evaluator when updating coarse positions, now there is an explicit call to do this. Allows to first apply all changes to the coarse mesh and then refine once. - Added coarse positions update from a continuous buffer with given starts offset and stride. Allows to update coarse positions directly from MVert array. - Refiner is no longer freed when CPU evaluator is created. Allows to re-use refiner for multiple purposes.
-rw-r--r--intern/opensubdiv/opensubdiv_capi.cc1
-rw-r--r--intern/opensubdiv/opensubdiv_capi.h72
-rw-r--r--intern/opensubdiv/opensubdiv_evaluator_capi.cc140
-rw-r--r--intern/opensubdiv/opensubdiv_gl_mesh.h40
-rw-r--r--intern/opensubdiv/opensubdiv_gpu_capi.cc1
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c3
6 files changed, 162 insertions, 95 deletions
diff --git a/intern/opensubdiv/opensubdiv_capi.cc b/intern/opensubdiv/opensubdiv_capi.cc
index bb865bc0e0f..638039f4f3e 100644
--- a/intern/opensubdiv/opensubdiv_capi.cc
+++ b/intern/opensubdiv/opensubdiv_capi.cc
@@ -70,6 +70,7 @@
#include <opensubdiv/far/stencilTable.h>
#include <opensubdiv/far/primvarRefiner.h>
+#include "opensubdiv_gl_mesh.h"
#include "opensubdiv_intern.h"
#include "opensubdiv_topology_refiner.h"
diff --git a/intern/opensubdiv/opensubdiv_capi.h b/intern/opensubdiv/opensubdiv_capi.h
index 2c3fcee7dbb..c29d08a77e1 100644
--- a/intern/opensubdiv/opensubdiv_capi.h
+++ b/intern/opensubdiv/opensubdiv_capi.h
@@ -32,22 +32,12 @@ extern "C" {
// Types declaration.
struct OpenSubdiv_GLMesh;
+struct OpenSubdiv_GLMeshDescr;
struct OpenSubdiv_GLMeshFVarData;
struct OpenSubdiv_TopologyRefinerDescr;
typedef struct OpenSubdiv_GLMesh OpenSubdiv_GLMesh;
-#ifdef __cplusplus
-struct OpenSubdiv_GLMeshDescr;
-
-typedef struct OpenSubdiv_GLMesh {
- int evaluator_type;
- OpenSubdiv_GLMeshDescr *descriptor;
- OpenSubdiv_TopologyRefinerDescr *topology_refiner;
- OpenSubdiv_GLMeshFVarData *fvar_data;
-} OpenSubdiv_GLMesh;
-#endif
-
// Keep this a bitmask os it's possible to pass available
// evaluators to Blender.
enum {
@@ -86,11 +76,7 @@ void openSubdiv_osdGLMeshBindVertexBuffer(OpenSubdiv_GLMesh *gl_mesh);
const struct OpenSubdiv_TopologyRefinerDescr *openSubdiv_getGLMeshTopologyRefiner(
OpenSubdiv_GLMesh *gl_mesh);
-/* ** Initialize/Deinitialize global OpenGL drawing buffers/GLSL programs ** */
-bool openSubdiv_osdGLDisplayInit(void);
-void openSubdiv_osdGLDisplayDeinit(void);
-
-/* ** Evaluator API ** */
+/* ============================= Evaluator API ============================== */
struct OpenSubdiv_EvaluatorDescr;
typedef struct OpenSubdiv_EvaluatorDescr OpenSubdiv_EvaluatorDescr;
@@ -100,17 +86,29 @@ OpenSubdiv_EvaluatorDescr *openSubdiv_createEvaluatorDescr(
struct OpenSubdiv_TopologyRefinerDescr *topology_refiner,
int subsurf_level);
-void openSubdiv_deleteEvaluatorDescr(OpenSubdiv_EvaluatorDescr *evaluator_descr);
-
-void openSubdiv_setEvaluatorCoarsePositions(OpenSubdiv_EvaluatorDescr *evaluator_descr,
- float *positions,
- int start_vert,
- int num_vert);
-
-void openSubdiv_setEvaluatorVaryingData(OpenSubdiv_EvaluatorDescr *evaluator_descr,
- float *varying_data,
- int start_vert,
- int num_vert);
+void openSubdiv_deleteEvaluatorDescr(
+ OpenSubdiv_EvaluatorDescr *evaluator_descr);
+
+void openSubdiv_setEvaluatorCoarsePositions(
+ OpenSubdiv_EvaluatorDescr *evaluator_descr,
+ const float *positions,
+ int start_vertex_index,
+ int num_vertices);
+void openSubdiv_setEvaluatorVaryingData(
+ OpenSubdiv_EvaluatorDescr *evaluator_descr,
+ const float *varying_data,
+ int start_vertex_index,
+ int num_vertices);
+
+void openSubdiv_setEvaluatorCoarsePositionsFromBuffer(
+ OpenSubdiv_EvaluatorDescr *evaluator_descr,
+ const void *buffer,
+ int start_offset,
+ int stride,
+ int start_vertex_index,
+ int num_vertices);
+
+void openSubdiv_refineEvaluator(OpenSubdiv_EvaluatorDescr *evaluator_descr);
void openSubdiv_evaluateLimit(OpenSubdiv_EvaluatorDescr *evaluator_descr,
int osd_face_index,
@@ -124,15 +122,18 @@ void openSubdiv_evaluateVarying(OpenSubdiv_EvaluatorDescr *evaluator_descr,
float face_u, float face_v,
float varying[3]);
-/* ** Actual drawing ** */
+/* ============================== Mesh drawing =============================== */
+
+/* Initialize/Deinitialize global OpenGL drawing buffers/GLSL programs. */
+bool openSubdiv_osdGLDisplayInit(void);
+void openSubdiv_osdGLDisplayDeinit(void);
/* Initialize all the invariants which stays the same for every single path,
* for example lighting model stays untouched for the whole mesh.
*
* TODO(sergey): Some of the stuff could be initialized once for all meshes.
*/
-void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl,
- int active_uv_index);
+void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl, int active_uv_index);
/* Draw specified patches. */
void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh,
@@ -140,12 +141,15 @@ void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh,
int start_patch,
int num_patches);
-void openSubdiv_osdGLAllocFVar(struct OpenSubdiv_TopologyRefinerDescr *topology_refiner,
- OpenSubdiv_GLMesh *gl_mesh,
- const float *fvar_data);
+void openSubdiv_osdGLAllocFVar(
+ struct OpenSubdiv_TopologyRefinerDescr *topology_refiner,
+ OpenSubdiv_GLMesh *gl_mesh,
+ const float *fvar_data);
+
void openSubdiv_osdGLDestroyFVar(OpenSubdiv_GLMesh *gl_mesh);
-/* ** Utility functions ** */
+/* =========================== Utility functions ============================ */
+
int openSubdiv_getAvailableEvaluators(void);
void openSubdiv_init(void);
void openSubdiv_cleanup(void);
diff --git a/intern/opensubdiv/opensubdiv_evaluator_capi.cc b/intern/opensubdiv/opensubdiv_evaluator_capi.cc
index 049c0aad3bf..fb5313b8501 100644
--- a/intern/opensubdiv/opensubdiv_evaluator_capi.cc
+++ b/intern/opensubdiv/opensubdiv_evaluator_capi.cc
@@ -118,7 +118,7 @@ protected:
* is small enough and better to be allocated in stack rather
* than in heap.
*
- * TODO(sergey): Check if bare arrays could be used by CPU evalautor.
+ * TODO(sergey): Check if bare arrays could be used by CPU evaluator.
*/
template <int element_size, int num_verts>
class StackAllocatedBuffer {
@@ -142,7 +142,7 @@ protected:
/* Volatile evaluator which can be used from threads.
*
- * TODO(sergey): Make it possible to evaluate coordinates in chuncks.
+ * TODO(sergey): Make it possible to evaluate coordinates in chunks.
*/
template<typename SRC_VERTEX_BUFFER,
typename EVAL_VERTEX_BUFFER,
@@ -347,85 +347,80 @@ OpenSubdiv_EvaluatorDescr *openSubdiv_createEvaluatorDescr(
/* Happens on bad topology. */
return NULL;
}
-
- const StencilTable *vertex_stencils = NULL;
- const StencilTable *varying_stencils = NULL;
- int num_total_verts = 0;
-
/* Apply uniform refinement to the mesh so that we can use the
* limit evaluation API features.
*/
TopologyRefiner::UniformOptions options(subsurf_level);
refiner->RefineUniform(options);
-
/* Generate stencil table to update the bi-cubic patches control
* vertices after they have been re-posed (both for vertex & varying
* interpolation).
*/
- StencilTableFactory::Options soptions;
- soptions.generateOffsets = true;
- soptions.generateIntermediateLevels = false;
-
- vertex_stencils = StencilTableFactory::Create(*refiner, soptions);
-
- soptions.interpolationMode = StencilTableFactory::INTERPOLATE_VARYING;
- varying_stencils = StencilTableFactory::Create(*refiner, soptions);
-
+ StencilTableFactory::Options vertex_stencil_options;
+ vertex_stencil_options.generateOffsets = true;
+ vertex_stencil_options.generateIntermediateLevels = false;
+ const StencilTable *vertex_stencils =
+ StencilTableFactory::Create(*refiner, vertex_stencil_options);
+ StencilTableFactory::Options varying_stencil_options;
+ varying_stencil_options.generateOffsets = true;
+ varying_stencil_options.generateIntermediateLevels = false;
+ varying_stencil_options.interpolationMode =
+ StencilTableFactory::INTERPOLATE_VARYING;
+ const StencilTable *varying_stencils =
+ StencilTableFactory::Create(*refiner, varying_stencil_options);
/* Generate bi-cubic patch table for the limit surface. */
PatchTableFactory::Options poptions;
poptions.SetEndCapType(PatchTableFactory::Options::ENDCAP_BSPLINE_BASIS);
-
- const PatchTable *patch_table = PatchTableFactory::Create(*refiner, poptions);
-
+ const PatchTable *patch_table =
+ PatchTableFactory::Create(*refiner, poptions);
/* Append local points stencils. */
- /* TODO(sergey): Do we really need to worry about local points stencils? */
- if (const StencilTable *local_point_stencil_table =
- patch_table->GetLocalPointStencilTable())
- {
+ const StencilTable *local_point_stencil_table =
+ patch_table->GetLocalPointStencilTable();
+ if (local_point_stencil_table != NULL) {
const StencilTable *table =
- StencilTableFactory::AppendLocalPointStencilTable(*refiner,
- vertex_stencils,
- local_point_stencil_table);
+ StencilTableFactory::AppendLocalPointStencilTable(
+ *refiner,
+ vertex_stencils,
+ local_point_stencil_table);
delete vertex_stencils;
vertex_stencils = table;
}
- if (const StencilTable *local_point_varying_stencil_table =
- patch_table->GetLocalPointVaryingStencilTable())
- {
+ const StencilTable *local_point_varying_stencil_table =
+ patch_table->GetLocalPointVaryingStencilTable();
+ if (local_point_varying_stencil_table != NULL) {
const StencilTable *table =
- StencilTableFactory::AppendLocalPointStencilTable(*refiner,
- varying_stencils,
- local_point_varying_stencil_table);
+ StencilTableFactory::AppendLocalPointStencilTable(
+ *refiner,
+ varying_stencils,
+ local_point_varying_stencil_table);
delete varying_stencils;
varying_stencils = table;
}
- /* Total number of vertices = coarse verts + refined verts + gregory basis verts. */
- num_total_verts = vertex_stencils->GetNumControlVertices() +
- vertex_stencils->GetNumStencils();
-
+ /* Total number of vertices = coarse verts + refined verts + gregory
+ * basis verts.
+ */
+ const int num_total_verts = vertex_stencils->GetNumControlVertices() +
+ vertex_stencils->GetNumStencils();
const int num_coarse_verts = refiner->GetLevel(0).GetNumVertices();
-
+ /* Create OpenSubdiv's CPU side evaluator. */
CpuEvalOutput *eval_output = new CpuEvalOutput(vertex_stencils,
varying_stencils,
num_coarse_verts,
num_total_verts,
patch_table);
-
OpenSubdiv::Far::PatchMap *patch_map = new PatchMap(*patch_table);
-
+ /* Wrap everything we need into an object which we control from our
+ * side.
+ */
OpenSubdiv_EvaluatorDescr *evaluator_descr;
evaluator_descr = OBJECT_GUARDED_NEW(OpenSubdiv_EvaluatorDescr);
evaluator_descr->eval_output = eval_output;
evaluator_descr->patch_map = patch_map;
evaluator_descr->patch_table = patch_table;
-
- /* TOOD(sergey): Look into whether w've got duplicated stencils arrays. */
+ /* TOOD(sergey): Look into whether we've got duplicated stencils arrays. */
delete varying_stencils;
delete vertex_stencils;
-
- delete refiner;
-
return evaluator_descr;
}
@@ -437,27 +432,52 @@ void openSubdiv_deleteEvaluatorDescr(OpenSubdiv_EvaluatorDescr *evaluator_descr)
OBJECT_GUARDED_DELETE(evaluator_descr, OpenSubdiv_EvaluatorDescr);
}
-void openSubdiv_setEvaluatorCoarsePositions(OpenSubdiv_EvaluatorDescr *evaluator_descr,
- float *positions,
- int start_vert,
- int num_verts)
+void openSubdiv_setEvaluatorCoarsePositions(
+ OpenSubdiv_EvaluatorDescr *evaluator_descr,
+ const float *positions,
+ int start_vertex_index,
+ int num_vertices)
{
/* TODO(sergey): Add sanity check on indices. */
- evaluator_descr->eval_output->UpdateData(positions, start_vert, num_verts);
- /* TODO(sergey): Consider moving this to a separate call,
- * so we can updatwe coordinates in chunks.
- */
- evaluator_descr->eval_output->Refine();
+ evaluator_descr->eval_output->UpdateData(positions,
+ start_vertex_index,
+ num_vertices);
+}
+
+void openSubdiv_setEvaluatorVaryingData(
+ OpenSubdiv_EvaluatorDescr *evaluator_descr,
+ const float *varying_data,
+ int start_vertex_index,
+ int num_vertices)
+{
+ /* TODO(sergey): Add sanity check on indices. */
+ evaluator_descr->eval_output->UpdateVaryingData(varying_data,
+ start_vertex_index,
+ num_vertices);
}
-void openSubdiv_setEvaluatorVaryingData(OpenSubdiv_EvaluatorDescr *evaluator_descr,
- float *varying_data,
- int start_vert,
- int num_verts)
+void openSubdiv_setEvaluatorCoarsePositionsFromBuffer(
+ OpenSubdiv_EvaluatorDescr *evaluator_descr,
+ const void *buffer,
+ int start_offset,
+ int stride,
+ int start_vertex_index,
+ int num_vertices)
{
+ const unsigned char *current_buffer = (unsigned char *)buffer;
+ current_buffer += start_offset;
/* TODO(sergey): Add sanity check on indices. */
- evaluator_descr->eval_output->UpdateVaryingData(varying_data, start_vert, num_verts);
- /* TODO(sergey): Get rid of this ASAP. */
+ for (int i = 0; i < num_vertices; ++i) {
+ const int current_vertex_index = start_vertex_index + i;
+ evaluator_descr->eval_output->UpdateData((float *)current_buffer,
+ current_vertex_index,
+ 1);
+ current_buffer += stride;
+ }
+}
+
+void openSubdiv_refineEvaluator(OpenSubdiv_EvaluatorDescr *evaluator_descr)
+{
evaluator_descr->eval_output->Refine();
}
diff --git a/intern/opensubdiv/opensubdiv_gl_mesh.h b/intern/opensubdiv/opensubdiv_gl_mesh.h
new file mode 100644
index 00000000000..1e99fc5bce4
--- /dev/null
+++ b/intern/opensubdiv/opensubdiv_gl_mesh.h
@@ -0,0 +1,40 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2018 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Sergey Sharybin.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __OPENSUBDIV_GL_MESH_H__
+#define __OPENSUBDIV_GL_MESH_H__
+
+struct OpenSubdiv_GLMeshDescr;
+struct OpenSubdiv_TopologyRefinerDescr;
+struct OpenSubdiv_GLMeshFVarData;
+
+typedef struct OpenSubdiv_GLMesh {
+ int evaluator_type;
+ OpenSubdiv_GLMeshDescr *descriptor;
+ OpenSubdiv_TopologyRefinerDescr *topology_refiner;
+ OpenSubdiv_GLMeshFVarData *fvar_data;
+} OpenSubdiv_GLMesh;
+
+#endif /* __OPENSUBDIV_GL_MESH_H__ */
diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc
index 7d8085c1ff5..d28b48ddd18 100644
--- a/intern/opensubdiv/opensubdiv_gpu_capi.cc
+++ b/intern/opensubdiv/opensubdiv_gpu_capi.cc
@@ -45,6 +45,7 @@
#include "MEM_guardedalloc.h"
#include "opensubdiv_capi.h"
+#include "opensubdiv_gl_mesh.h"
#include "opensubdiv_topology_refiner.h"
using OpenSubdiv::Osd::GLMeshInterface;
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
index fc4220277eb..46204898709 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
@@ -198,7 +198,7 @@ void ccgSubSurf_checkTopologyChanged(CCGSubSurf *ss, DerivedMesh *dm)
ss->osd_topology_refiner = NULL;
}
- /* Reste CPU side. */
+ /* Reset CPU side. */
if (ss->osd_evaluator != NULL) {
openSubdiv_deleteEvaluatorDescr(ss->osd_evaluator);
ss->osd_evaluator = NULL;
@@ -523,6 +523,7 @@ static void opensubdiv_updateEvaluatorCoarsePositions(CCGSubSurf *ss)
(float *)positions,
0,
num_basis_verts);
+ openSubdiv_refineEvaluator(ss->osd_evaluator);
MEM_freeN(positions);
}