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:
authorSergey Sharybin <sergey.vfx@gmail.com>2018-07-17 19:06:32 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2018-07-18 16:42:49 +0300
commitc64262a05ab0e9a7c5b69fc83ea53fb5825f442c (patch)
tree014de046f9e9af6b5642086547e7c3e554b90bbf /intern/opensubdiv
parent428743a9b06cc09b4eb4dd3e7794d45d13457fb8 (diff)
OpenSubdiv: Add API to evaluate face-varying data
There are move changes along the line to keep everything working from from C.
Diffstat (limited to 'intern/opensubdiv')
-rw-r--r--intern/opensubdiv/internal/opensubdiv_converter_factory.cc2
-rw-r--r--intern/opensubdiv/internal/opensubdiv_converter_internal.cc26
-rw-r--r--intern/opensubdiv/internal/opensubdiv_converter_internal.h5
-rw-r--r--intern/opensubdiv/internal/opensubdiv_topology_refiner.cc60
-rw-r--r--intern/opensubdiv/opensubdiv_capi_type.h15
-rw-r--r--intern/opensubdiv/opensubdiv_converter_capi.h15
-rw-r--r--intern/opensubdiv/opensubdiv_topology_refiner_capi.h43
7 files changed, 148 insertions, 18 deletions
diff --git a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc
index bd6edbb9648..48516cc80b7 100644
--- a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc
+++ b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc
@@ -383,6 +383,8 @@ TopologyRefinerFactory<TopologyRefinerData>::assignFaceVaryingTopology(
const int num_uvs = converter->getNumUVCoordinates(converter);
// Fill in per-corner index of the UV.
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) {
Far::IndexArray dst_face_uvs =
getBaseFaceFVarValues(refiner, face_index, channel);
diff --git a/intern/opensubdiv/internal/opensubdiv_converter_internal.cc b/intern/opensubdiv/internal/opensubdiv_converter_internal.cc
index 56b5657121d..32815dc34dc 100644
--- a/intern/opensubdiv/internal/opensubdiv_converter_internal.cc
+++ b/intern/opensubdiv/internal/opensubdiv_converter_internal.cc
@@ -49,6 +49,10 @@ getFVarLinearInterpolationFromCAPI(
return Options::FVAR_LINEAR_NONE;
case OSD_FVAR_LINEAR_INTERPOLATION_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:
return Options::FVAR_LINEAR_BOUNDARIES;
case OSD_FVAR_LINEAR_INTERPOLATION_ALL:
@@ -58,6 +62,28 @@ getFVarLinearInterpolationFromCAPI(
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,
int edge_index) {
if (converter->getNumEdgeFaces(converter, edge_index) == 2) {
diff --git a/intern/opensubdiv/internal/opensubdiv_converter_internal.h b/intern/opensubdiv/internal/opensubdiv_converter_internal.h
index 68518d67884..c47cdd1004d 100644
--- a/intern/opensubdiv/internal/opensubdiv_converter_internal.h
+++ b/intern/opensubdiv/internal/opensubdiv_converter_internal.h
@@ -41,6 +41,11 @@ OpenSubdiv::Sdc::Options::FVarLinearInterpolation
getFVarLinearInterpolationFromCAPI(
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.
float getCompatibleEdgeSharpness(const OpenSubdiv_Converter* converter,
int edge_index);
diff --git a/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc b/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc
index aa6ba953ef9..93f6fdc14a1 100644
--- a/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc
+++ b/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc
@@ -46,6 +46,9 @@ bool getIsAdaptive(const OpenSubdiv_TopologyRefiner* topology_refiner) {
return topology_refiner->internal->settings.is_adaptive;
}
+////////////////////////////////////////////////////////////////////////////////
+// Query basic topology information from base level.
+
int getNumVertices(const OpenSubdiv_TopologyRefiner* topology_refiner) {
return getOSDTopologyBaseLevel(topology_refiner)->GetNumVertices();
}
@@ -58,6 +61,9 @@ int getNumFaces(const OpenSubdiv_TopologyRefiner* topology_refiner) {
return getOSDTopologyBaseLevel(topology_refiner)->GetNumFaces();
}
+////////////////////////////////////////////////////////////////////////////////
+// PTex face geometry queries.
+
int getNumFaceVertices(const OpenSubdiv_TopologyRefiner* topology_refiner,
const int face_index) {
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) {
topology_refiner->getSubdivisionLevel = getSubdivisionLevel;
topology_refiner->getIsAdaptive = getIsAdaptive;
-
+ // Basic topology information.
topology_refiner->getNumVertices = getNumVertices;
topology_refiner->getNumEdges = getNumEdges;
topology_refiner->getNumFaces = getNumFaces;
topology_refiner->getNumFaceVertices = getNumFaceVertices;
-
+ // PTex face geometry.
topology_refiner->getNumFacePtexFaces = getNumFacePtexFaces;
topology_refiner->getNumPtexFaces = getNumPtexFaces;
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() {
@@ -125,9 +172,14 @@ OpenSubdiv_TopologyRefiner* allocateTopologyRefiner() {
OpenSubdiv_TopologyRefiner* openSubdiv_createTopologyRefinerFromConverter(
OpenSubdiv_Converter* converter,
const OpenSubdiv_TopologyRefinerSettings* settings) {
- OpenSubdiv_TopologyRefiner* topology_refiner = allocateTopologyRefiner();
- topology_refiner->internal->osd_topology_refiner =
+ OpenSubdiv::Far::TopologyRefiner* osd_topology_refiner =
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
// in OpenSubdiv's descriptor yet.
topology_refiner->internal->settings = *settings;
diff --git a/intern/opensubdiv/opensubdiv_capi_type.h b/intern/opensubdiv/opensubdiv_capi_type.h
index 04fe2afff53..b326e53e168 100644
--- a/intern/opensubdiv/opensubdiv_capi_type.h
+++ b/intern/opensubdiv/opensubdiv_capi_type.h
@@ -34,6 +34,21 @@ typedef enum eOpenSubdivEvaluator {
OPENSUBDIV_EVALUATOR_GLSL_COMPUTE = (1 << 5),
} 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
}
#endif
diff --git a/intern/opensubdiv/opensubdiv_converter_capi.h b/intern/opensubdiv/opensubdiv_converter_capi.h
index b16d6eb6c8f..a939f1117e0 100644
--- a/intern/opensubdiv/opensubdiv_converter_capi.h
+++ b/intern/opensubdiv/opensubdiv_converter_capi.h
@@ -19,23 +19,12 @@
#ifndef OPENSUBDIV_CONVERTER_CAPI_H_
#define OPENSUBDIV_CONVERTER_CAPI_H_
+#include "opensubdiv_capi_type.h"
+
#ifdef __cplusplus
extern "C" {
#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 {
OpenSubdiv_SchemeType (*getSchemeType)(
const struct OpenSubdiv_Converter* converter);
diff --git a/intern/opensubdiv/opensubdiv_topology_refiner_capi.h b/intern/opensubdiv/opensubdiv_topology_refiner_capi.h
index 103ccd2c1f9..fe4db0ca67c 100644
--- a/intern/opensubdiv/opensubdiv_topology_refiner_capi.h
+++ b/intern/opensubdiv/opensubdiv_topology_refiner_capi.h
@@ -21,6 +21,8 @@
#include <stdint.h> // for bool
+#include "opensubdiv_capi_type.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -45,7 +47,16 @@ typedef struct OpenSubdiv_TopologyRefiner {
bool (*getIsAdaptive)(
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.
+
int (*getNumVertices)(
const struct OpenSubdiv_TopologyRefiner* topology_refiner);
int (*getNumEdges)(
@@ -56,6 +67,9 @@ typedef struct OpenSubdiv_TopologyRefiner {
const struct OpenSubdiv_TopologyRefiner* topology_refiner,
const int face_index);
+ //////////////////////////////////////////////////////////////////////////////
+ // PTex face geometry queries.
+
// Ptex face corresponds to OpenSubdiv's internal "patch" and to Blender's
// subdivision grid. The rule commes as:
// - 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,
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.
//
// Tease: Contains actual OpenSubdiv's refiner and (optionally) some other
@@ -86,6 +125,8 @@ typedef struct OpenSubdiv_TopologyRefiner {
struct OpenSubdiv_TopologyRefinerInternal* internal;
} OpenSubdiv_TopologyRefiner;
+// NOTE: Will return NULL in cases of bad topology.
+// NOTE: Mesh without faces is considered a bad topology.
OpenSubdiv_TopologyRefiner* openSubdiv_createTopologyRefinerFromConverter(
struct OpenSubdiv_Converter* converter,
const OpenSubdiv_TopologyRefinerSettings* settings);
@@ -101,7 +142,7 @@ void openSubdiv_deleteTopologyRefiner(
// complicated parts of subdivision process.
bool openSubdiv_topologyRefinerCompareWithConverter(
const OpenSubdiv_TopologyRefiner* topology_refiner,
- const OpenSubdiv_Converter* converter);
+ const struct OpenSubdiv_Converter* converter);
#ifdef __cplusplus
}