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 'intern/opensubdiv/opensubdiv_evaluator_capi.cc')
-rw-r--r--intern/opensubdiv/opensubdiv_evaluator_capi.cc516
1 files changed, 0 insertions, 516 deletions
diff --git a/intern/opensubdiv/opensubdiv_evaluator_capi.cc b/intern/opensubdiv/opensubdiv_evaluator_capi.cc
deleted file mode 100644
index fb5313b8501..00000000000
--- a/intern/opensubdiv/opensubdiv_evaluator_capi.cc
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * ***** 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>
-
-#ifdef _MSC_VER
-# include "iso646.h"
-#endif
-
-#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_intern.h"
-#include "opensubdiv_topology_refiner.h"
-
-#include "MEM_guardedalloc.h"
-
-using OpenSubdiv::Osd::BufferDescriptor;
-using OpenSubdiv::Osd::PatchCoord;
-using OpenSubdiv::Far::PatchMap;
-using OpenSubdiv::Far::PatchTable;
-using OpenSubdiv::Far::PatchTableFactory;
-using OpenSubdiv::Far::StencilTable;
-using OpenSubdiv::Far::StencilTableFactory;
-using OpenSubdiv::Far::TopologyRefiner;
-
-namespace {
-
-/* Helper class to wrap numerous of patch coords into a buffer.
- * Used to pass coordinates to the CPU evaluator. Other evaluators
- * are not supported.
- */
-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));
- }
-};
-
-/* Helper class to wrap single of patch coord into a buffer.
- * Used to pass coordinates to the CPU evaluator. Other evaluators
- * are not supported.
- */
-class SinglePatchCoordBuffer {
-public:
- SinglePatchCoordBuffer() {
- }
- SinglePatchCoordBuffer(const PatchCoord& patch_coord)
- : patch_coord_(patch_coord){
- }
- static SinglePatchCoordBuffer *Create()
- {
- SinglePatchCoordBuffer *buffer = new SinglePatchCoordBuffer();
- return buffer;
- }
- PatchCoord *BindCpuBuffer() {
- return (PatchCoord*)&patch_coord_;
- }
- int GetNumVertices() {
- return 1;
- }
- void UpdateData(const PatchCoord& patch_coord)
- {
- patch_coord_ = patch_coord;
- }
-protected:
- PatchCoord patch_coord_;
-};
-
-/* Helper class which is aimed to be used in cases when buffer
- * 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 evaluator.
- */
-template <int element_size, int num_verts>
-class StackAllocatedBuffer {
-public:
- static PatchCoordBuffer *Create(int /*size*/)
- {
- StackAllocatedBuffer<element_size, num_verts> *buffer =
- new StackAllocatedBuffer<element_size, num_verts>();
- return buffer;
- }
- float *BindCpuBuffer() {
- return &data_[0];
- }
- int GetNumVertices() {
- return num_verts;
- }
- /* TODO(sergey): Support UpdateData(). */
-protected:
- float data_[element_size * num_verts];
-};
-
-/* Volatile evaluator which can be used from threads.
- *
- * TODO(sergey): Make it possible to evaluate coordinates in chunks.
- */
-template<typename SRC_VERTEX_BUFFER,
- typename EVAL_VERTEX_BUFFER,
- typename STENCIL_TABLE,
- typename PATCH_TABLE,
- typename EVALUATOR,
- typename DEVICE_CONTEXT = void>
-class VolatileEvalOutput {
-public:
- typedef OpenSubdiv::Osd::EvaluatorCacheT<EVALUATOR> EvaluatorCache;
-
- VolatileEvalOutput(const StencilTable *vertex_stencils,
- const StencilTable *varying_stencils,
- int num_coarse_verts,
- int num_total_verts,
- const PatchTable *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),
- 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_);
- 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_);
- }
-
- ~VolatileEvalOutput()
- {
- delete src_data_;
- delete src_varying_data_;
- delete patch_table_;
- delete vertex_stencils_;
- delete varying_stencils_;
- }
-
- 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;
-
- const EVALUATOR *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 EvalPatchCoord(PatchCoord& patch_coord, float P[3])
- {
- StackAllocatedBuffer<6, 1> vertex_data;
- BufferDescriptor vertex_desc(0, 3, 6);
- SinglePatchCoordBuffer patch_coord_buffer(patch_coord);
- const EVALUATOR *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_coord_buffer.GetNumVertices(),
- &patch_coord_buffer,
- patch_table_, eval_instance, device_context_);
- float *refined_verts = vertex_data.BindCpuBuffer();
- memcpy(P, refined_verts, sizeof(float) * 3);
- }
-
- void EvalPatchesWithDerivatives(PatchCoord& patch_coord,
- float P[3],
- float dPdu[3],
- float dPdv[3])
- {
- StackAllocatedBuffer<6, 1> vertex_data, derivatives;
- BufferDescriptor vertex_desc(0, 3, 6),
- du_desc(0, 3, 6),
- dv_desc(3, 3, 6);
- SinglePatchCoordBuffer patch_coord_buffer(patch_coord);
- const EVALUATOR *eval_instance =
- OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(evaluator_cache_,
- src_desc_,
- vertex_desc,
- du_desc,
- dv_desc,
- device_context_);
- EVALUATOR::EvalPatches(src_data_, src_desc_,
- &vertex_data, vertex_desc,
- &derivatives, du_desc,
- &derivatives, dv_desc,
- patch_coord_buffer.GetNumVertices(),
- &patch_coord_buffer,
- patch_table_, eval_instance, device_context_);
- float *refined_verts = vertex_data.BindCpuBuffer();
- memcpy(P, refined_verts, sizeof(float) * 3);
- if (dPdu != NULL || dPdv != NULL) {
- float *refined_drivatives = derivatives.BindCpuBuffer();
- if (dPdu) {
- memcpy(dPdu, refined_drivatives, sizeof(float) * 3);
- }
- if (dPdv) {
- memcpy(dPdv, refined_drivatives + 3, sizeof(float) * 3);
- }
- }
- }
-
- void EvalPatchVarying(PatchCoord& patch_coord,
- float varying[3]) {
- StackAllocatedBuffer<3, 1> varying_data;
- BufferDescriptor varying_desc(0, 3, 3);
- SinglePatchCoordBuffer patch_coord_buffer(patch_coord);
- EVALUATOR const *eval_instance =
- OpenSubdiv::Osd::GetEvaluator<EVALUATOR>(evaluator_cache_,
- src_varying_desc_,
- varying_desc,
- device_context_);
-
- EVALUATOR::EvalPatches(src_varying_data_, src_varying_desc_,
- &varying_data, varying_desc,
- patch_coord_buffer.GetNumVertices(),
- &patch_coord_buffer,
- patch_table_, eval_instance, device_context_);
- float *refined_varying = varying_data.BindCpuBuffer();
- memcpy(varying, refined_varying, sizeof(float) * 3);
- }
-private:
- SRC_VERTEX_BUFFER *src_data_;
- SRC_VERTEX_BUFFER *src_varying_data_;
- PatchCoordBuffer *patch_coords_;
- PATCH_TABLE *patch_table_;
- BufferDescriptor src_desc_;
- BufferDescriptor src_varying_desc_;
- int num_coarse_verts_;
-
- const STENCIL_TABLE *vertex_stencils_;
- const STENCIL_TABLE *varying_stencils_;
-
- EvaluatorCache *evaluator_cache_;
- DEVICE_CONTEXT *device_context_;
-};
-
-} /* namespace */
-
-typedef VolatileEvalOutput<OpenSubdiv::Osd::CpuVertexBuffer,
- OpenSubdiv::Osd::CpuVertexBuffer,
- OpenSubdiv::Far::StencilTable,
- OpenSubdiv::Osd::CpuPatchTable,
- OpenSubdiv::Osd::CpuEvaluator> CpuEvalOutput;
-
-typedef struct OpenSubdiv_EvaluatorDescr {
- CpuEvalOutput *eval_output;
- const PatchMap *patch_map;
- const PatchTable *patch_table;
-} OpenSubdiv_EvaluatorDescr;
-
-OpenSubdiv_EvaluatorDescr *openSubdiv_createEvaluatorDescr(
- OpenSubdiv_TopologyRefinerDescr *topology_refiner,
- int subsurf_level)
-{
- /* TODO(sergey): Look into re-using refiner with GLMesh. */
- TopologyRefiner *refiner = topology_refiner->osd_refiner;
- if(refiner == NULL) {
- /* Happens on bad topology. */
- return NULL;
- }
- /* 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 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);
- /* Append local points stencils. */
- 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);
- delete vertex_stencils;
- vertex_stencils = table;
- }
- 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);
- delete varying_stencils;
- varying_stencils = table;
- }
-
- /* 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 we've got duplicated stencils arrays. */
- delete varying_stencils;
- delete vertex_stencils;
- return evaluator_descr;
-}
-
-void openSubdiv_deleteEvaluatorDescr(OpenSubdiv_EvaluatorDescr *evaluator_descr)
-{
- delete evaluator_descr->eval_output;
- delete evaluator_descr->patch_map;
- delete evaluator_descr->patch_table;
- OBJECT_GUARDED_DELETE(evaluator_descr, OpenSubdiv_EvaluatorDescr);
-}
-
-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_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_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. */
- 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();
-}
-
-void openSubdiv_evaluateLimit(OpenSubdiv_EvaluatorDescr *evaluator_descr,
- int osd_face_index,
- float face_u, float face_v,
- float P[3],
- float dPdu[3],
- float dPdv[3])
-{
- assert((face_u >= 0.0f) && (face_u <= 1.0f) && (face_v >= 0.0f) && (face_v <= 1.0f));
- const PatchTable::PatchHandle *handle =
- evaluator_descr->patch_map->FindPatch(osd_face_index, face_u, face_v);
- PatchCoord patch_coord(*handle, face_u, face_v);
- if (dPdu != NULL || dPdv != NULL) {
- evaluator_descr->eval_output->EvalPatchesWithDerivatives(patch_coord,
- P,
- dPdu,
- dPdv);
- }
- else {
- evaluator_descr->eval_output->EvalPatchCoord(patch_coord, P);
- }
-}
-
-void openSubdiv_evaluateVarying(OpenSubdiv_EvaluatorDescr *evaluator_descr,
- int osd_face_index,
- float face_u, float face_v,
- float varying[3])
-{
- assert((face_u >= 0.0f) && (face_u <= 1.0f) && (face_v >= 0.0f) && (face_v <= 1.0f));
- const PatchTable::PatchHandle *handle =
- evaluator_descr->patch_map->FindPatch(osd_face_index, face_u, face_v);
- PatchCoord patch_coord(*handle, face_u, face_v);
- evaluator_descr->eval_output->EvalPatchVarying(patch_coord, varying);
-}