[Bf-blender-cvs] [fd39914] opensubdiv-modifier: OpenSubdiv: Implementation of CPU-side evaluator
Sergey Sharybin
noreply at git.blender.org
Sat Jul 11 20:01:51 CEST 2015
Commit: fd39914cf69e3b7cae006fd4cf8616e7a2251a33
Author: Sergey Sharybin
Date: Thu Jul 9 16:24:37 2015 +0200
Branches: opensubdiv-modifier
https://developer.blender.org/rBfd39914cf69e3b7cae006fd4cf8616e7a2251a33
OpenSubdiv: Implementation of CPU-side evaluator
Based on the code from glEvalLimit example from OpenSubdiv.
Still loads of work to make it all working correctly tho.
===================================================================
M intern/opensubdiv/CMakeLists.txt
M intern/opensubdiv/opensubdiv_capi.h
M intern/opensubdiv/opensubdiv_converter.cc
M intern/opensubdiv/opensubdiv_converter.h
A intern/opensubdiv/opensubdiv_evaluator_capi.cc
M source/blender/blenkernel/BKE_subsurf.h
M source/blender/blenkernel/intern/CCGSubSurf.c
M source/blender/blenkernel/intern/CCGSubSurf.h
M source/blender/blenkernel/intern/subsurf_ccg.c
===================================================================
diff --git a/intern/opensubdiv/CMakeLists.txt b/intern/opensubdiv/CMakeLists.txt
index 40236db..deb4e0a 100644
--- a/intern/opensubdiv/CMakeLists.txt
+++ b/intern/opensubdiv/CMakeLists.txt
@@ -42,6 +42,7 @@ set(SRC
opensubdiv_converter.cc
opensubdiv_device_context_cuda.cc
opensubdiv_device_context_opencl.cc
+ opensubdiv_evaluator_capi.cc
opensubdiv_gpu_capi.cc
opensubdiv_utils_capi.cc
diff --git a/intern/opensubdiv/opensubdiv_capi.h b/intern/opensubdiv/opensubdiv_capi.h
index ddc9a4b..6ca9856 100644
--- a/intern/opensubdiv/opensubdiv_capi.h
+++ b/intern/opensubdiv/opensubdiv_capi.h
@@ -99,6 +99,15 @@ void openSubdiv_osdGLMeshBindVertexBuffer(OpenSubdiv_GLMesh *gl_mesh);
void openSubdiv_osdGLDisplayInit(void);
void openSubdiv_osdGLDisplayDeinit(void);
+/* ** Evaluator API ** */
+void openSubdiv_evaluateLimit(//OpenSubdiv_EvaluatorDescr *evaluator_descr,
+ DerivedMesh *dm,
+ int osd_face_index,
+ float face_u, float face_v,
+ float P[3],
+ float dPdu[3],
+ float dPdv[3]);
+
/* ** Actual drawing ** */
/* Initialize all the invariants which stays the same for every single path,
diff --git a/intern/opensubdiv/opensubdiv_converter.cc b/intern/opensubdiv/opensubdiv_converter.cc
index 2bc740e..3897a26 100644
--- a/intern/opensubdiv/opensubdiv_converter.cc
+++ b/intern/opensubdiv/opensubdiv_converter.cc
@@ -62,6 +62,18 @@ int OsdBlenderConverter::get_num_verts() const
return dm_->getNumVerts(dm_);
}
+void OsdBlenderConverter::get_coarse_verts(float *coords) const
+{
+ MVert *mv = dm_->getVertArray(dm_);
+ const int num_verts = dm_->getNumVerts(dm_);
+ for (int i = 0; i < num_verts; ++i) {
+ MVert *mvert = &mv[i];
+ coords[i * 3 + 0] = mvert->co[0];
+ coords[i * 3 + 1] = mvert->co[1];
+ coords[i * 3 + 2] = mvert->co[2];
+ }
+}
+
/* Face relationships. */
int OsdBlenderConverter::get_num_face_verts(int face) const
{
diff --git a/intern/opensubdiv/opensubdiv_converter.h b/intern/opensubdiv/opensubdiv_converter.h
index 6914773..c9635ce 100644
--- a/intern/opensubdiv/opensubdiv_converter.h
+++ b/intern/opensubdiv/opensubdiv_converter.h
@@ -44,6 +44,8 @@ public:
int get_num_edges() const;
int get_num_verts() const;
+ void get_coarse_verts(float *coords) const;
+
/* Face relationships. */
int get_num_face_verts(int face) const;
void get_face_verts(int face, int *face_verts) const;
diff --git a/intern/opensubdiv/opensubdiv_evaluator_capi.cc b/intern/opensubdiv/opensubdiv_evaluator_capi.cc
new file mode 100644
index 0000000..91b1c62
--- /dev/null
+++ b/intern/opensubdiv/opensubdiv_evaluator_capi.cc
@@ -0,0 +1,388 @@
+/*
+ * ***** 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) 2015 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Sergey Sharybin.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "opensubdiv_capi.h"
+
+#include <cstdio>
+#include <vector>
+
+#include <opensubdiv/far/topologyRefinerFactory.h>
+#include <opensubdiv/far/patchMap.h>
+#include <opensubdiv/far/patchTable.h>
+#include <opensubdiv/far/patchTableFactory.h>
+#include <opensubdiv/osd/cpuEvaluator.h>
+#include <opensubdiv/osd/cpuPatchTable.h>
+#include <opensubdiv/osd/cpuVertexBuffer.h>
+#include <opensubdiv/osd/mesh.h>
+#include <opensubdiv/osd/types.h>
+
+#include "opensubdiv_converter.h"
+
+using OpenSubdiv::Osd::BufferDescriptor;
+using OpenSubdiv::Osd::PatchCoord;
+using OpenSubdiv::Far::PatchTable;
+using OpenSubdiv::Far::PatchTableFactory;
+using OpenSubdiv::Far::StencilTable;
+using OpenSubdiv::Far::StencilTableFactory;
+using OpenSubdiv::Far::TopologyRefiner;
+using OpenSubdiv::Far::TopologyRefinerFactory;
+
+namespace {
+
+class PatchCoordBuffer : public std::vector<PatchCoord> {
+public:
+ static PatchCoordBuffer *Create(int size)
+ {
+ PatchCoordBuffer *buffer = new PatchCoordBuffer();
+ buffer->resize(size);
+ return buffer;
+ }
+ PatchCoord *BindCpuBuffer() {
+ return (PatchCoord*)&(*this)[0];
+ }
+ int GetNumVertices() {
+ return size();
+ }
+ void UpdateData(const PatchCoord *patch_coords,
+ int num_patch_coords)
+ {
+ memcpy(&(*this)[0],
+ (void*)patch_coords,
+ num_patch_coords * sizeof(PatchCoord));
+ }
+};
+
+template<typename SRC_VERTEX_BUFFER,
+ typename EVAL_VERTEX_BUFFER,
+ typename STENCIL_TABLE,
+ typename PATCH_TABLE,
+ typename EVALUATOR,
+ typename DEVICE_CONTEXT = void>
+class EvalOutput {
+public:
+ typedef OpenSubdiv::Osd::EvaluatorCacheT<EVALUATOR> EvaluatorCache;
+
+ EvalOutput(StencilTable const *vertex_stencils,
+ StencilTable const *varying_stencils,
+ int num_coarse_verts,
+ int num_total_verts,
+ int num_particles,
+ PatchTable const *patch_table,
+ EvaluatorCache *evaluator_cache = NULL,
+ DEVICE_CONTEXT *device_context = NULL)
+ : src_desc_( /*offset*/ 0, /*length*/ 3, /*stride*/ 3),
+ src_varying_desc_(/*offset*/ 0, /*length*/ 3, /*stride*/ 3),
+ vertex_desc_( /*offset*/ 0, /*legnth*/ 3, /*stride*/ 6),
+ varying_desc_( /*offset*/ 3, /*legnth*/ 3, /*stride*/ 6),
+ du_desc_( /*offset*/ 0, /*legnth*/ 3, /*stride*/ 6),
+ dv_desc_( /*offset*/ 3, /*legnth*/ 3, /*stride*/ 6),
+ num_coarse_verts_(num_coarse_verts),
+ evaluator_cache_ (evaluator_cache),
+ device_context_(device_context)
+ {
+ using OpenSubdiv::Osd::convertToCompatibleStencilTable;
+ src_data_ = SRC_VERTEX_BUFFER::Create(3, num_total_verts, device_context_);
+ src_varying_data_ = SRC_VERTEX_BUFFER::Create(3, num_total_verts, device_context_);
+ vertex_data_ = EVAL_VERTEX_BUFFER::Create(6, num_particles, device_context_);
+ derivatives_ = EVAL_VERTEX_BUFFER::Create(6, num_particles, device_context_);
+ patch_table_ = PATCH_TABLE::Create(patch_table, device_context_);
+ patch_coords_ = NULL;
+ vertex_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(vertex_stencils,
+ device_context_);
+ varying_stencils_ = convertToCompatibleStencilTable<STENCIL_TABLE>(varying_stencils,
+ device_context_);
+ }
+
+ ~EvalOutput()
+ {
+ delete src_data_;
+ delete src_varying_data_;
+ delete vertex_data_;
+ delete derivatives_;
+ delete patch_table_;
+ delete patch_coords_;
+ delete vertex_stencils_;
+ delete varying_stencils_;
+ }
+
+ float *BindCpuVertexData() const
+ {
+ return vertex_data_->BindCpuBuffer();
+ }
+
+ void UpdateData(const float *src, int start_vertex, int num_vertices)
+ {
+ src_data_->UpdateData(src, start_vertex, num_vertices, device_context_);
+ }
+
+ void UpdateVaryingData(const float *src, int start_vertex, int num_vertices)
+ {
+ src_varying_data_->UpdateData(src,
+ start_vertex,
+ num_vertices,
+ device_context_);
+ }
+
+ void Refine()
+ {
+ BufferDescriptor dst_desc = src_desc_;
+ dst_desc.offset += num_coarse_verts_ * src_desc_.stride;
+
+ EVALUATOR const *eval_instance =
+ OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(evaluator_cache_,
+ src_desc_,
+ dst_desc,
+ device_context_);
+
+ EVALUATOR::EvalStencils(src_data_, src_desc_,
+ src_data_, dst_desc,
+ vertex_stencils_,
+ eval_instance,
+ device_context_);
+
+ dst_desc = src_varying_desc_;
+ dst_desc.offset += num_coarse_verts_ * src_varying_desc_.stride;
+ eval_instance =
+ OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(evaluator_cache_,
+ src_varying_desc_,
+ dst_desc,
+ device_context_);
+
+ EVALUATOR::EvalStencils(src_varying_data_, src_varying_desc_,
+ src_varying_data_, dst_desc,
+ varying_stencils_,
+ eval_instance,
+ device_context_);
+ }
+
+ void EvalPatches()
+ {
+ EVALUATOR const *eval_instance =
+ OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(evaluator_cache_,
+ src_desc_,
+ vertex_desc_,
+ device_context_);
+
+ EVALUATOR::EvalPatches(src_data_, src_desc_,
+ vertex_data_, vertex_desc_,
+ patch_coords_->GetNumVertices(),
+ patch_coords_,
+ patch_table_, eval_instance, device_context_);
+ }
+
+ void EvalPatchesWithDerivatives()
+ {
+ EVALUATOR const *eval_instance =
+ OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(evaluator_cache_,
+ src_desc_,
+ vertex_desc_,
+ du_desc_,
+ dv_desc_,
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list