diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-07-17 19:06:32 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-07-18 16:42:49 +0300 |
commit | c64262a05ab0e9a7c5b69fc83ea53fb5825f442c (patch) | |
tree | 014de046f9e9af6b5642086547e7c3e554b90bbf /intern/opensubdiv/internal | |
parent | 428743a9b06cc09b4eb4dd3e7794d45d13457fb8 (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/internal')
4 files changed, 89 insertions, 4 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; |