OpenSubdiv: Add API to evaluate face-varying data
There are move changes along the line to keep everything working from from C.
This commit is contained in:
@@ -383,6 +383,8 @@ TopologyRefinerFactory<TopologyRefinerData>::assignFaceVaryingTopology(
|
|||||||
const int num_uvs = converter->getNumUVCoordinates(converter);
|
const int num_uvs = converter->getNumUVCoordinates(converter);
|
||||||
// Fill in per-corner index of the UV.
|
// Fill in per-corner index of the UV.
|
||||||
const int channel = createBaseFVarChannel(refiner, num_uvs);
|
const int channel = createBaseFVarChannel(refiner, num_uvs);
|
||||||
|
// TODO(sergey): Need to check whether converter changed the winding of
|
||||||
|
// face to match OpenSubdiv's expectations.
|
||||||
for (int face_index = 0; face_index < num_faces; ++face_index) {
|
for (int face_index = 0; face_index < num_faces; ++face_index) {
|
||||||
Far::IndexArray dst_face_uvs =
|
Far::IndexArray dst_face_uvs =
|
||||||
getBaseFaceFVarValues(refiner, face_index, channel);
|
getBaseFaceFVarValues(refiner, face_index, channel);
|
||||||
|
|||||||
@@ -49,6 +49,10 @@ getFVarLinearInterpolationFromCAPI(
|
|||||||
return Options::FVAR_LINEAR_NONE;
|
return Options::FVAR_LINEAR_NONE;
|
||||||
case OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY:
|
case OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY:
|
||||||
return Options::FVAR_LINEAR_CORNERS_ONLY;
|
return Options::FVAR_LINEAR_CORNERS_ONLY;
|
||||||
|
case OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_PLUS1:
|
||||||
|
return Options::FVAR_LINEAR_CORNERS_PLUS1;
|
||||||
|
case OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_PLUS2:
|
||||||
|
return Options::FVAR_LINEAR_CORNERS_PLUS2;
|
||||||
case OSD_FVAR_LINEAR_INTERPOLATION_BOUNDARIES:
|
case OSD_FVAR_LINEAR_INTERPOLATION_BOUNDARIES:
|
||||||
return Options::FVAR_LINEAR_BOUNDARIES;
|
return Options::FVAR_LINEAR_BOUNDARIES;
|
||||||
case OSD_FVAR_LINEAR_INTERPOLATION_ALL:
|
case OSD_FVAR_LINEAR_INTERPOLATION_ALL:
|
||||||
@@ -58,6 +62,28 @@ getFVarLinearInterpolationFromCAPI(
|
|||||||
return Options::FVAR_LINEAR_NONE;
|
return Options::FVAR_LINEAR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OpenSubdiv_FVarLinearInterpolation
|
||||||
|
getCAPIFVarLinearInterpolationFromOSD(
|
||||||
|
OpenSubdiv::Sdc::Options::FVarLinearInterpolation linear_interpolation) {
|
||||||
|
typedef OpenSubdiv::Sdc::Options Options;
|
||||||
|
switch (linear_interpolation) {
|
||||||
|
case Options::FVAR_LINEAR_NONE:
|
||||||
|
return OSD_FVAR_LINEAR_INTERPOLATION_NONE;
|
||||||
|
case Options::FVAR_LINEAR_CORNERS_ONLY:
|
||||||
|
return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY;
|
||||||
|
case Options::FVAR_LINEAR_CORNERS_PLUS1:
|
||||||
|
return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_PLUS1;
|
||||||
|
case Options::FVAR_LINEAR_CORNERS_PLUS2:
|
||||||
|
return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_PLUS2;
|
||||||
|
case Options::FVAR_LINEAR_BOUNDARIES:
|
||||||
|
return OSD_FVAR_LINEAR_INTERPOLATION_BOUNDARIES;
|
||||||
|
case Options::FVAR_LINEAR_ALL:
|
||||||
|
return OSD_FVAR_LINEAR_INTERPOLATION_ALL;
|
||||||
|
}
|
||||||
|
assert(!"Unknown fvar linear interpolation passed via C-API");
|
||||||
|
return OSD_FVAR_LINEAR_INTERPOLATION_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
float getCompatibleEdgeSharpness(const OpenSubdiv_Converter* converter,
|
float getCompatibleEdgeSharpness(const OpenSubdiv_Converter* converter,
|
||||||
int edge_index) {
|
int edge_index) {
|
||||||
if (converter->getNumEdgeFaces(converter, edge_index) == 2) {
|
if (converter->getNumEdgeFaces(converter, edge_index) == 2) {
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ OpenSubdiv::Sdc::Options::FVarLinearInterpolation
|
|||||||
getFVarLinearInterpolationFromCAPI(
|
getFVarLinearInterpolationFromCAPI(
|
||||||
OpenSubdiv_FVarLinearInterpolation linear_interpolation);
|
OpenSubdiv_FVarLinearInterpolation linear_interpolation);
|
||||||
|
|
||||||
|
// Similar to above, just other way around.
|
||||||
|
OpenSubdiv_FVarLinearInterpolation
|
||||||
|
getCAPIFVarLinearInterpolationFromOSD(
|
||||||
|
OpenSubdiv::Sdc::Options::FVarLinearInterpolation linear_interpolation);
|
||||||
|
|
||||||
// Get edge sharpness in a way which makes OpenSubdiv happy.
|
// Get edge sharpness in a way which makes OpenSubdiv happy.
|
||||||
float getCompatibleEdgeSharpness(const OpenSubdiv_Converter* converter,
|
float getCompatibleEdgeSharpness(const OpenSubdiv_Converter* converter,
|
||||||
int edge_index);
|
int edge_index);
|
||||||
|
|||||||
@@ -46,6 +46,9 @@ bool getIsAdaptive(const OpenSubdiv_TopologyRefiner* topology_refiner) {
|
|||||||
return topology_refiner->internal->settings.is_adaptive;
|
return topology_refiner->internal->settings.is_adaptive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Query basic topology information from base level.
|
||||||
|
|
||||||
int getNumVertices(const OpenSubdiv_TopologyRefiner* topology_refiner) {
|
int getNumVertices(const OpenSubdiv_TopologyRefiner* topology_refiner) {
|
||||||
return getOSDTopologyBaseLevel(topology_refiner)->GetNumVertices();
|
return getOSDTopologyBaseLevel(topology_refiner)->GetNumVertices();
|
||||||
}
|
}
|
||||||
@@ -58,6 +61,9 @@ int getNumFaces(const OpenSubdiv_TopologyRefiner* topology_refiner) {
|
|||||||
return getOSDTopologyBaseLevel(topology_refiner)->GetNumFaces();
|
return getOSDTopologyBaseLevel(topology_refiner)->GetNumFaces();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// PTex face geometry queries.
|
||||||
|
|
||||||
int getNumFaceVertices(const OpenSubdiv_TopologyRefiner* topology_refiner,
|
int getNumFaceVertices(const OpenSubdiv_TopologyRefiner* topology_refiner,
|
||||||
const int face_index) {
|
const int face_index) {
|
||||||
const OpenSubdiv::Far::TopologyLevel* base_level =
|
const OpenSubdiv::Far::TopologyLevel* base_level =
|
||||||
@@ -97,18 +103,59 @@ void fillFacePtexIndexOffset(const OpenSubdiv_TopologyRefiner* topology_refiner,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Face-varying data.
|
||||||
|
|
||||||
|
int getNumFVarChannels(
|
||||||
|
const struct OpenSubdiv_TopologyRefiner* topology_refiner) {
|
||||||
|
const OpenSubdiv::Far::TopologyLevel* base_level =
|
||||||
|
getOSDTopologyBaseLevel(topology_refiner);
|
||||||
|
return base_level->GetNumFVarChannels();
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenSubdiv_FVarLinearInterpolation getFVarLinearInterpolation(
|
||||||
|
const struct OpenSubdiv_TopologyRefiner* topology_refiner) {
|
||||||
|
return opensubdiv_capi::getCAPIFVarLinearInterpolationFromOSD(
|
||||||
|
getOSDTopologyRefiner(topology_refiner)->GetFVarLinearInterpolation());
|
||||||
|
}
|
||||||
|
|
||||||
|
int getNumFVarValues(
|
||||||
|
const struct OpenSubdiv_TopologyRefiner* topology_refiner,
|
||||||
|
const int channel) {
|
||||||
|
const OpenSubdiv::Far::TopologyLevel* base_level =
|
||||||
|
getOSDTopologyBaseLevel(topology_refiner);
|
||||||
|
return base_level->GetNumFVarValues(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int* getFaceFVarValueIndices(
|
||||||
|
const struct OpenSubdiv_TopologyRefiner* topology_refiner,
|
||||||
|
const int face_index,
|
||||||
|
const int channel) {
|
||||||
|
const OpenSubdiv::Far::TopologyLevel* base_level =
|
||||||
|
getOSDTopologyBaseLevel(topology_refiner);
|
||||||
|
return &base_level->GetFaceFVarValues(face_index, channel)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Internal helpers.
|
||||||
|
|
||||||
void assignFunctionPointers(OpenSubdiv_TopologyRefiner* topology_refiner) {
|
void assignFunctionPointers(OpenSubdiv_TopologyRefiner* topology_refiner) {
|
||||||
topology_refiner->getSubdivisionLevel = getSubdivisionLevel;
|
topology_refiner->getSubdivisionLevel = getSubdivisionLevel;
|
||||||
topology_refiner->getIsAdaptive = getIsAdaptive;
|
topology_refiner->getIsAdaptive = getIsAdaptive;
|
||||||
|
// Basic topology information.
|
||||||
topology_refiner->getNumVertices = getNumVertices;
|
topology_refiner->getNumVertices = getNumVertices;
|
||||||
topology_refiner->getNumEdges = getNumEdges;
|
topology_refiner->getNumEdges = getNumEdges;
|
||||||
topology_refiner->getNumFaces = getNumFaces;
|
topology_refiner->getNumFaces = getNumFaces;
|
||||||
topology_refiner->getNumFaceVertices = getNumFaceVertices;
|
topology_refiner->getNumFaceVertices = getNumFaceVertices;
|
||||||
|
// PTex face geometry.
|
||||||
topology_refiner->getNumFacePtexFaces = getNumFacePtexFaces;
|
topology_refiner->getNumFacePtexFaces = getNumFacePtexFaces;
|
||||||
topology_refiner->getNumPtexFaces = getNumPtexFaces;
|
topology_refiner->getNumPtexFaces = getNumPtexFaces;
|
||||||
topology_refiner->fillFacePtexIndexOffset = fillFacePtexIndexOffset;
|
topology_refiner->fillFacePtexIndexOffset = fillFacePtexIndexOffset;
|
||||||
|
// Face-varying data.
|
||||||
|
topology_refiner->getNumFVarChannels = getNumFVarChannels;
|
||||||
|
topology_refiner->getFVarLinearInterpolation = getFVarLinearInterpolation;
|
||||||
|
topology_refiner->getNumFVarValues = getNumFVarValues;
|
||||||
|
topology_refiner->getFaceFVarValueIndices = getFaceFVarValueIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenSubdiv_TopologyRefiner* allocateTopologyRefiner() {
|
OpenSubdiv_TopologyRefiner* allocateTopologyRefiner() {
|
||||||
@@ -125,9 +172,14 @@ OpenSubdiv_TopologyRefiner* allocateTopologyRefiner() {
|
|||||||
OpenSubdiv_TopologyRefiner* openSubdiv_createTopologyRefinerFromConverter(
|
OpenSubdiv_TopologyRefiner* openSubdiv_createTopologyRefinerFromConverter(
|
||||||
OpenSubdiv_Converter* converter,
|
OpenSubdiv_Converter* converter,
|
||||||
const OpenSubdiv_TopologyRefinerSettings* settings) {
|
const OpenSubdiv_TopologyRefinerSettings* settings) {
|
||||||
OpenSubdiv_TopologyRefiner* topology_refiner = allocateTopologyRefiner();
|
OpenSubdiv::Far::TopologyRefiner* osd_topology_refiner =
|
||||||
topology_refiner->internal->osd_topology_refiner =
|
|
||||||
opensubdiv_capi::createOSDTopologyRefinerFromConverter(converter);
|
opensubdiv_capi::createOSDTopologyRefinerFromConverter(converter);
|
||||||
|
if (osd_topology_refiner == NULL) {
|
||||||
|
// Happens on empty or bad topology.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
OpenSubdiv_TopologyRefiner* topology_refiner = allocateTopologyRefiner();
|
||||||
|
topology_refiner->internal->osd_topology_refiner = osd_topology_refiner;
|
||||||
// Store setting which we want to keep track of and which can not be stored
|
// Store setting which we want to keep track of and which can not be stored
|
||||||
// in OpenSubdiv's descriptor yet.
|
// in OpenSubdiv's descriptor yet.
|
||||||
topology_refiner->internal->settings = *settings;
|
topology_refiner->internal->settings = *settings;
|
||||||
|
|||||||
@@ -34,6 +34,21 @@ typedef enum eOpenSubdivEvaluator {
|
|||||||
OPENSUBDIV_EVALUATOR_GLSL_COMPUTE = (1 << 5),
|
OPENSUBDIV_EVALUATOR_GLSL_COMPUTE = (1 << 5),
|
||||||
} eOpenSubdivEvaluator;
|
} eOpenSubdivEvaluator;
|
||||||
|
|
||||||
|
typedef enum OpenSubdiv_SchemeType {
|
||||||
|
OSD_SCHEME_BILINEAR,
|
||||||
|
OSD_SCHEME_CATMARK,
|
||||||
|
OSD_SCHEME_LOOP,
|
||||||
|
} OpenSubdiv_SchemeType;
|
||||||
|
|
||||||
|
typedef enum OpenSubdiv_FVarLinearInterpolation {
|
||||||
|
OSD_FVAR_LINEAR_INTERPOLATION_NONE,
|
||||||
|
OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY,
|
||||||
|
OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_PLUS1,
|
||||||
|
OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_PLUS2,
|
||||||
|
OSD_FVAR_LINEAR_INTERPOLATION_BOUNDARIES,
|
||||||
|
OSD_FVAR_LINEAR_INTERPOLATION_ALL,
|
||||||
|
} OpenSubdiv_FVarLinearInterpolation;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -19,23 +19,12 @@
|
|||||||
#ifndef OPENSUBDIV_CONVERTER_CAPI_H_
|
#ifndef OPENSUBDIV_CONVERTER_CAPI_H_
|
||||||
#define OPENSUBDIV_CONVERTER_CAPI_H_
|
#define OPENSUBDIV_CONVERTER_CAPI_H_
|
||||||
|
|
||||||
|
#include "opensubdiv_capi_type.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef enum OpenSubdiv_SchemeType {
|
|
||||||
OSD_SCHEME_BILINEAR,
|
|
||||||
OSD_SCHEME_CATMARK,
|
|
||||||
OSD_SCHEME_LOOP,
|
|
||||||
} OpenSubdiv_SchemeType;
|
|
||||||
|
|
||||||
typedef enum OpenSubdiv_FVarLinearInterpolation {
|
|
||||||
OSD_FVAR_LINEAR_INTERPOLATION_NONE,
|
|
||||||
OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY,
|
|
||||||
OSD_FVAR_LINEAR_INTERPOLATION_BOUNDARIES,
|
|
||||||
OSD_FVAR_LINEAR_INTERPOLATION_ALL,
|
|
||||||
} OpenSubdiv_FVarLinearInterpolation;
|
|
||||||
|
|
||||||
typedef struct OpenSubdiv_Converter {
|
typedef struct OpenSubdiv_Converter {
|
||||||
OpenSubdiv_SchemeType (*getSchemeType)(
|
OpenSubdiv_SchemeType (*getSchemeType)(
|
||||||
const struct OpenSubdiv_Converter* converter);
|
const struct OpenSubdiv_Converter* converter);
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
#include <stdint.h> // for bool
|
#include <stdint.h> // for bool
|
||||||
|
|
||||||
|
#include "opensubdiv_capi_type.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -45,7 +47,16 @@ typedef struct OpenSubdiv_TopologyRefiner {
|
|||||||
bool (*getIsAdaptive)(
|
bool (*getIsAdaptive)(
|
||||||
const struct OpenSubdiv_TopologyRefiner* topology_refiner);
|
const struct OpenSubdiv_TopologyRefiner* topology_refiner);
|
||||||
|
|
||||||
|
// NOTE: All queries are querying base level.
|
||||||
|
//
|
||||||
|
// TODO(sergey): Consider making it more obvious in function naming,
|
||||||
|
// but since it's unlikely (or at least, will be uncommon use) for API
|
||||||
|
// which queries final geometry, we should be fine with this name for
|
||||||
|
// now.
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// Query basic topology information from base level.
|
// Query basic topology information from base level.
|
||||||
|
|
||||||
int (*getNumVertices)(
|
int (*getNumVertices)(
|
||||||
const struct OpenSubdiv_TopologyRefiner* topology_refiner);
|
const struct OpenSubdiv_TopologyRefiner* topology_refiner);
|
||||||
int (*getNumEdges)(
|
int (*getNumEdges)(
|
||||||
@@ -56,6 +67,9 @@ typedef struct OpenSubdiv_TopologyRefiner {
|
|||||||
const struct OpenSubdiv_TopologyRefiner* topology_refiner,
|
const struct OpenSubdiv_TopologyRefiner* topology_refiner,
|
||||||
const int face_index);
|
const int face_index);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// PTex face geometry queries.
|
||||||
|
|
||||||
// Ptex face corresponds to OpenSubdiv's internal "patch" and to Blender's
|
// Ptex face corresponds to OpenSubdiv's internal "patch" and to Blender's
|
||||||
// subdivision grid. The rule commes as:
|
// subdivision grid. The rule commes as:
|
||||||
// - Triangle face consist of 3 ptex faces, ordered in the order of
|
// - Triangle face consist of 3 ptex faces, ordered in the order of
|
||||||
@@ -79,6 +93,31 @@ typedef struct OpenSubdiv_TopologyRefiner {
|
|||||||
const struct OpenSubdiv_TopologyRefiner* topology_refiner,
|
const struct OpenSubdiv_TopologyRefiner* topology_refiner,
|
||||||
int* face_ptex_index_offset);
|
int* face_ptex_index_offset);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Face-varying data.
|
||||||
|
|
||||||
|
// Number of face-varying channels (or how they are called in Blender layers).
|
||||||
|
int (*getNumFVarChannels)(
|
||||||
|
const struct OpenSubdiv_TopologyRefiner* topology_refiner);
|
||||||
|
// Get face-varying interpolation type.
|
||||||
|
OpenSubdiv_FVarLinearInterpolation (*getFVarLinearInterpolation)(
|
||||||
|
const struct OpenSubdiv_TopologyRefiner* topology_refiner);
|
||||||
|
// Get total number of face-varying values in a particular channel.
|
||||||
|
int (*getNumFVarValues)(
|
||||||
|
const struct OpenSubdiv_TopologyRefiner* topology_refiner,
|
||||||
|
const int channel);
|
||||||
|
// Get face-varying value indices associated with a particular face.
|
||||||
|
//
|
||||||
|
// This is an array of indices inside of face-varying array, array elements
|
||||||
|
// are aligned with face corners (or loops in Blender terminology).
|
||||||
|
const int* (*getFaceFVarValueIndices)(
|
||||||
|
const struct OpenSubdiv_TopologyRefiner* topology_refiner,
|
||||||
|
const int face_index,
|
||||||
|
const int channel);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Internal use.
|
||||||
|
|
||||||
// Internal storage for the use in this module only.
|
// Internal storage for the use in this module only.
|
||||||
//
|
//
|
||||||
// Tease: Contains actual OpenSubdiv's refiner and (optionally) some other
|
// Tease: Contains actual OpenSubdiv's refiner and (optionally) some other
|
||||||
@@ -86,6 +125,8 @@ typedef struct OpenSubdiv_TopologyRefiner {
|
|||||||
struct OpenSubdiv_TopologyRefinerInternal* internal;
|
struct OpenSubdiv_TopologyRefinerInternal* internal;
|
||||||
} OpenSubdiv_TopologyRefiner;
|
} OpenSubdiv_TopologyRefiner;
|
||||||
|
|
||||||
|
// NOTE: Will return NULL in cases of bad topology.
|
||||||
|
// NOTE: Mesh without faces is considered a bad topology.
|
||||||
OpenSubdiv_TopologyRefiner* openSubdiv_createTopologyRefinerFromConverter(
|
OpenSubdiv_TopologyRefiner* openSubdiv_createTopologyRefinerFromConverter(
|
||||||
struct OpenSubdiv_Converter* converter,
|
struct OpenSubdiv_Converter* converter,
|
||||||
const OpenSubdiv_TopologyRefinerSettings* settings);
|
const OpenSubdiv_TopologyRefinerSettings* settings);
|
||||||
@@ -101,7 +142,7 @@ void openSubdiv_deleteTopologyRefiner(
|
|||||||
// complicated parts of subdivision process.
|
// complicated parts of subdivision process.
|
||||||
bool openSubdiv_topologyRefinerCompareWithConverter(
|
bool openSubdiv_topologyRefinerCompareWithConverter(
|
||||||
const OpenSubdiv_TopologyRefiner* topology_refiner,
|
const OpenSubdiv_TopologyRefiner* topology_refiner,
|
||||||
const OpenSubdiv_Converter* converter);
|
const struct OpenSubdiv_Converter* converter);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user