[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