mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-14 16:01:08 +00:00
194 lines
7.2 KiB
C++
194 lines
7.2 KiB
C++
//
|
|
// Copyright 2013 Pixar
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "Apache License")
|
|
// with the following modification; you may not use this file except in
|
|
// compliance with the Apache License and the following modification to it:
|
|
// Section 6. Trademarks. is deleted and replaced with:
|
|
//
|
|
// 6. Trademarks. This License does not grant permission to use the trade
|
|
// names, trademarks, service marks, or product names of the Licensor
|
|
// and its affiliates, except as required to comply with Section 4(c) of
|
|
// the License and to reproduce the content of the NOTICE file.
|
|
//
|
|
// You may obtain a copy of the Apache License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the Apache License with the above modification is
|
|
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
// KIND, either express or implied. See the Apache License for the specific
|
|
// language governing permissions and limitations under the Apache License.
|
|
//
|
|
|
|
#ifndef OSDUTIL_UNIFORM_EVALUATOR_H
|
|
#define OSDUTIL_UNIFORM_EVALUATOR_H
|
|
|
|
#include "../version.h"
|
|
|
|
#include "refiner.h"
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#define HBR_ADAPTIVE
|
|
|
|
#include "../osd/cpuVertexBuffer.h"
|
|
#include "../osd/cpuComputeContext.h"
|
|
#include "../far/mesh.h"
|
|
|
|
namespace OpenSubdiv {
|
|
namespace OPENSUBDIV_VERSION {
|
|
|
|
// This class takes a mesh that has undergone uniform refinement to
|
|
// a fixed subdivision level, and creates required run time OpenSubdiv
|
|
// data structures used to sample values on subdivision surfaces.
|
|
//
|
|
// An important note here is that refined positions and vertex varying
|
|
// attributes are sampled at the n-th subdivision level, not at the
|
|
// exact limit surface. Use OsdUtilAdaptiveEvaluator for true limits.
|
|
//
|
|
class OsdUtilUniformEvaluator {
|
|
public:
|
|
OsdUtilUniformEvaluator();
|
|
|
|
~OsdUtilUniformEvaluator();
|
|
|
|
// Initialize returns false on error. If errorMessage is non-NULL it'll
|
|
// be populated upon error.
|
|
//
|
|
// If successful vertex buffers and compute contexts will have been
|
|
// created and are ready to SetCoarse* methods, call Refine, and then
|
|
// sample refined values with the Get* methods
|
|
//
|
|
// Note that calling this method assumes that the evaluator isn't
|
|
// responsible for the refiner's lifetime, someone else needs to
|
|
// hold onto the refiner pointer. This allows for lightweight sharing
|
|
// of refiners among evaluators.
|
|
//
|
|
bool Initialize(
|
|
OsdUtilRefiner* refiner,
|
|
std::string *errorMessage = NULL);
|
|
|
|
bool Initialize(
|
|
const OsdUtilSubdivTopology &topology,
|
|
std::string *errorMessage = NULL);
|
|
|
|
// Set new coarse-mesh CV positions, need to call Refine
|
|
// before calling Get* methods
|
|
void SetCoarsePositions(
|
|
const std::vector<float>& coords,
|
|
std::string *errorMessage = NULL
|
|
);
|
|
|
|
// Set new coarse-mesh vertex varying values, need to call Refine
|
|
// before calling Get* methods
|
|
void SetCoarseVVData(
|
|
const std::vector<float>& data,
|
|
std::string *errorMessage = NULL
|
|
);
|
|
|
|
// Refine the coarse mesh, needed before calling GetPositions, GetQuads etc.
|
|
// If numThreads is 1, use single cpu. If numThreads > 1 use Omp and set
|
|
// number of omp threads.
|
|
//
|
|
bool Refine(int numThreads,
|
|
std::string *errorMessage = NULL);
|
|
|
|
// Grab position results of calling Refine, return by reference a pointer
|
|
// into _vertexBuffer memory with the refined points positions,
|
|
// packed as 3 floats per point. This doesn't involve a copy, the
|
|
// pointer will be valid as long as _vertexBuffer exists.
|
|
//
|
|
bool GetRefinedPositions(const float **positions, int *numFloats,
|
|
std::string *errorMessage = NULL) const;
|
|
|
|
// Grab vertex varying results of calling Refine, return by reference
|
|
// a pointer into _vvBuffer memory with the refined data,
|
|
// packed as (numElements) floats per point. This doesn't involve
|
|
// a copy, the pointer will be valid as long as _vertexBuffer exists.
|
|
//
|
|
bool GetRefinedVVData(float **data, int *numFloats,
|
|
int *numElements = NULL,
|
|
std::string *errorMessage = NULL) const;
|
|
|
|
// Fetch the face varying attribute values on refined quads, call
|
|
// through to the refiner but keep in evaluator API for
|
|
// one-stop-service for user API
|
|
void GetRefinedFVData( int level,
|
|
const std::vector<std::string>& names,
|
|
std::vector<float>* fvdata) {
|
|
_refiner->GetRefinedFVData(level, names, fvdata);
|
|
}
|
|
|
|
|
|
// Fetch the topology of the post-refined mesh. The "quads" vector
|
|
// will be filled with 4 ints per quad which index into a vector
|
|
// of positions.
|
|
//
|
|
// Calls through to the refiner.
|
|
//
|
|
bool GetRefinedQuads(std::vector<int>* quads,
|
|
std::string *errorMessage = NULL) const {
|
|
return _refiner->GetRefinedQuads(quads, errorMessage);
|
|
}
|
|
|
|
// Fetch the U/V coordinates of the refined quads in the U/V space
|
|
// of their parent coarse face
|
|
bool GetRefinedPtexUvs(std::vector<float>* subfaceUvs,
|
|
std::vector<int>* ptexIndices,
|
|
std::string *errorMessage = NULL) const {
|
|
return _refiner->GetRefinedPtexUvs(subfaceUvs, ptexIndices, errorMessage);
|
|
}
|
|
|
|
bool GetRefinedTopology(
|
|
OsdUtilSubdivTopology *t,
|
|
//positions will have three floats * t->numVertices
|
|
const float **positions,
|
|
std::string *errorMessage = NULL);
|
|
|
|
// Forward these calls through to the refiner, which may forward
|
|
// to the mesh. Make these top level API calls on the evaluator
|
|
// so clients can talk to a single API
|
|
//
|
|
const std::string &GetName() const { return _refiner->GetName();}
|
|
|
|
const OpenSubdiv::HbrMesh<OpenSubdiv::OsdVertex> *GetHbrMesh() {
|
|
return _refiner->GetHbrMesh();
|
|
}
|
|
|
|
const OsdUtilSubdivTopology &GetTopology() const {
|
|
return _refiner->GetTopology();
|
|
}
|
|
|
|
const OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex>* GetFarMesh() {
|
|
return _refiner->GetFarMesh();
|
|
}
|
|
|
|
private:
|
|
|
|
// A pointer to the shared refiner used. Note that this class may
|
|
// own the refiner pointer (if _ownsRefiner is true), or it may
|
|
// assume that someone else is responsible for managing that pointer
|
|
// if _ownsRefiner is false.
|
|
OsdUtilRefiner *_refiner;
|
|
bool _ownsRefiner;
|
|
|
|
// responsible for performing uniform catmull/clark subdivision
|
|
// on the incoming polygonal topology. This only stores topology and
|
|
// face varying data and can be shared among threads. Doesn't store
|
|
// per-vertex information being refined in different threads, those
|
|
// are in vertex buffers that can't be shared.
|
|
OpenSubdiv::OsdCpuComputeContext *_computeContext;
|
|
OpenSubdiv::OsdCpuVertexBuffer *_vertexBuffer;
|
|
OpenSubdiv::OsdCpuVertexBuffer *_vvBuffer;
|
|
};
|
|
|
|
} // end namespace OPENSUBDIV_VERSION
|
|
using namespace OPENSUBDIV_VERSION;
|
|
|
|
} // end namespace OpenSubdiv
|
|
|
|
#endif /* OSDUTIL_UNIFORM_EVALUATOR_H */
|