From 6c61f1b006c7fcb67b58f4cc51d12938c55899bc Mon Sep 17 00:00:00 2001 From: barfowl Date: Tue, 2 Jun 2015 16:27:19 -0700 Subject: [PATCH] Separated Far's TopologyDescriptor from the RefinerFactory classes: - moved TopologyRefiner out of the RefinerFactoryBase into Far - moved implementation of its Factory to far/topologyDescriptor.* - updated examples and tutorials (no more references to FactoryBase) --- examples/mayaPolySmooth/mayaPolySmooth.cpp | 4 +- opensubdiv/far/CMakeLists.txt | 2 + opensubdiv/far/topologyDescriptor.cpp | 185 +++++++ opensubdiv/far/topologyDescriptor.h | 120 ++++ opensubdiv/far/topologyRefiner.h | 2 + opensubdiv/far/topologyRefinerFactory.cpp | 139 +---- opensubdiv/far/topologyRefinerFactory.h | 573 +++++++++----------- tutorials/far/tutorial_0/far_tutorial_0.cpp | 4 +- tutorials/far/tutorial_2/far_tutorial_2.cpp | 4 +- tutorials/far/tutorial_3/far_tutorial_3.cpp | 4 +- tutorials/far/tutorial_4/far_tutorial_4.cpp | 4 +- tutorials/far/tutorial_5/far_tutorial_5.cpp | 4 +- tutorials/far/tutorial_6/far_tutorial_6.cpp | 4 +- tutorials/far/tutorial_7/far_tutorial_7.cpp | 4 +- tutorials/osd/tutorial_0/osd_tutorial_0.cpp | 4 +- 15 files changed, 588 insertions(+), 469 deletions(-) create mode 100644 opensubdiv/far/topologyDescriptor.cpp create mode 100644 opensubdiv/far/topologyDescriptor.h diff --git a/examples/mayaPolySmooth/mayaPolySmooth.cpp b/examples/mayaPolySmooth/mayaPolySmooth.cpp index cd2f8ea0..89db7902 100644 --- a/examples/mayaPolySmooth/mayaPolySmooth.cpp +++ b/examples/mayaPolySmooth/mayaPolySmooth.cpp @@ -60,7 +60,7 @@ #endif // OpenSubdiv includes -#include +#include #include #include @@ -189,7 +189,7 @@ createComp(MFnMeshData &dataCreator, MFn::Type compType, unsigned compId, MIntAr // OpenSubdiv Functions // ==================================== -typedef OpenSubdiv::Far::TopologyRefinerFactoryBase::TopologyDescriptor Descriptor; +typedef OpenSubdiv::Far::TopologyDescriptor Descriptor; // Reference: OSD shape_utils.h:: applyTags() "crease" static float diff --git a/opensubdiv/far/CMakeLists.txt b/opensubdiv/far/CMakeLists.txt index b1770e1e..45194355 100644 --- a/opensubdiv/far/CMakeLists.txt +++ b/opensubdiv/far/CMakeLists.txt @@ -39,6 +39,7 @@ set(SOURCE_FILES stencilTable.cpp stencilTableFactory.cpp stencilBuilder.cpp + topologyDescriptor.cpp topologyRefiner.cpp topologyRefinerFactory.cpp ) @@ -63,6 +64,7 @@ set(PUBLIC_HEADER_FILES ptexIndices.h stencilTable.h stencilTableFactory.h + topologyDescriptor.h topologyLevel.h topologyRefiner.h topologyRefinerFactory.h diff --git a/opensubdiv/far/topologyDescriptor.cpp b/opensubdiv/far/topologyDescriptor.cpp new file mode 100644 index 00000000..4e5c2a5e --- /dev/null +++ b/opensubdiv/far/topologyDescriptor.cpp @@ -0,0 +1,185 @@ +// +// Copyright 2014 DreamWorks Animation LLC. +// +// 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. +// +#include "../far/topologyDescriptor.h" +#include "../far/topologyRefinerFactory.h" +#include "../far/topologyRefiner.h" + +// Unfortunately necessary for error codes that should be more accessible... +#include "../vtr/level.h" + +#include +#ifdef _MSC_VER + #define snprintf _snprintf +#endif + + +namespace OpenSubdiv { +namespace OPENSUBDIV_VERSION { + +namespace Far { + +// +// Definitions for TopologyDescriptor: +// +TopologyDescriptor::TopologyDescriptor() { + memset(this, 0, sizeof(TopologyDescriptor)); +} + + +// +// Definitions/specializations for its RefinerFactory: +// +template <> +bool +TopologyRefinerFactory::resizeComponentTopology( + TopologyRefiner & refiner, TopologyDescriptor const & desc) { + + setNumBaseVertices(refiner, desc.numVertices); + setNumBaseFaces(refiner, desc.numFaces); + + for (int face=0; face +bool +TopologyRefinerFactory::assignComponentTopology( + TopologyRefiner & refiner, TopologyDescriptor const & desc) { + + for (int face=0, idx=0; face 0; --vert) { + + dstFaceVerts[vert] = desc.vertIndicesPerFace[idx++]; + } + } else { + for (int vert=0; vert +bool +TopologyRefinerFactory::assignComponentTags( + TopologyRefiner & refiner, TopologyDescriptor const & desc) { + + if ((desc.numCreases>0) and desc.creaseVertexIndexPairs and desc.creaseWeights) { + + int const * vertIndexPairs = desc.creaseVertexIndexPairs; + for (int edge=0; edge0) and desc.cornerVertexIndices and desc.cornerWeights) { + + for (int vert=0; vert= 0 and idx < getNumBaseVertices(refiner)) { + setBaseVertexSharpness(refiner, idx, desc.cornerWeights[vert]); + } else { + char msg[1024]; + snprintf(msg, 1024, "Vertex %d specified to be sharp does not exist", idx); + reportInvalidTopology(Vtr::internal::Level::TOPOLOGY_INVALID_CREASE_VERT, msg, desc); + } + } + } + if (desc.numHoles>0) { + for (int i=0; i +bool +TopologyRefinerFactory::assignFaceVaryingTopology( + TopologyRefiner & refiner, TopologyDescriptor const & desc) { + + if (desc.numFVarChannels>0) { + + for (int channel=0; channel 0; --vert) { + + dstFaceFVarValues[vert] = srcFVarValues[srcNext++]; + } + } else { + for (int vert = 0; vert < dstFaceFVarValues.size(); ++vert) { + + dstFaceFVarValues[vert] = srcFVarValues[srcNext++]; + } + } + } + } + } + return true; +} + +template <> +void +TopologyRefinerFactory::reportInvalidTopology( + TopologyError /* errCode */, char const * msg, TopologyDescriptor const& /* mesh */) { + Warning(msg); +} + +} // end namespace Far + +} // end namespace OPENSUBDIV_VERSION +} // end namespace OpenSubdiv diff --git a/opensubdiv/far/topologyDescriptor.h b/opensubdiv/far/topologyDescriptor.h new file mode 100644 index 00000000..f5c3ef44 --- /dev/null +++ b/opensubdiv/far/topologyDescriptor.h @@ -0,0 +1,120 @@ +// +// Copyright 2014 DreamWorks Animation LLC. +// +// 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 OPENSUBDIV3_FAR_TOPOLOGY_DESCRIPTOR_H +#define OPENSUBDIV3_FAR_TOPOLOGY_DESCRIPTOR_H + +#include "../version.h" + +#include "../far/topologyRefiner.h" +#include "../far/topologyRefinerFactory.h" +#include "../far/error.h" + +#include + +namespace OpenSubdiv { +namespace OPENSUBDIV_VERSION { + +namespace Far { + +/// +/// \brief Descriptor for raw topology data, provided as a convenience with +/// a corresponding Factory. It should be functionally complete and simple +/// to use, but for more demanding situations, writing a custom Factory is +/// likely warranted. +/// +struct TopologyDescriptor { + + int numVertices, + numFaces; + + int const * numVertsPerFace; + Index const * vertIndicesPerFace; + + int numCreases; + Index const * creaseVertexIndexPairs; + float const * creaseWeights; + + int numCorners; + Index const * cornerVertexIndices; + float const * cornerWeights; + + int numHoles; + Index const * holeIndices; + + bool isLeftHanded; + + // Face-varying data channel -- value indices correspond to vertex indices, + // i.e. one for every vertex of every face: + // + struct FVarChannel { + + int numValues; + Index const * valueIndices; + + FVarChannel() : numValues(0), valueIndices(0) { } + }; + + int numFVarChannels; + FVarChannel const * fvarChannels; + + TopologyDescriptor(); +}; + + +// +// Declaration of factory method specializations (provided internally): +// +template <> +bool +TopologyRefinerFactory::resizeComponentTopology( + TopologyRefiner & refiner, TopologyDescriptor const & desc); + +template <> +bool +TopologyRefinerFactory::assignComponentTopology( + TopologyRefiner & refiner, TopologyDescriptor const & desc); + +template <> +bool +TopologyRefinerFactory::assignComponentTags( + TopologyRefiner & refiner, TopologyDescriptor const & desc); + +template <> +bool +TopologyRefinerFactory::assignFaceVaryingTopology( + TopologyRefiner & refiner, TopologyDescriptor const & desc); + +template <> +void +TopologyRefinerFactory::reportInvalidTopology( + TopologyError errCode, char const * msg, TopologyDescriptor const& /* mesh */); + + +} // end namespace Far + +} // end namespace OPENSUBDIV_VERSION +using namespace OPENSUBDIV_VERSION; +} // end namespace OpenSubdiv + +#endif /* OPENSUBDIV3_FAR_TOPOLOGY_DESCRIPTOR_H */ diff --git a/opensubdiv/far/topologyRefiner.h b/opensubdiv/far/topologyRefiner.h index 20ce652d..450fbeee 100644 --- a/opensubdiv/far/topologyRefiner.h +++ b/opensubdiv/far/topologyRefiner.h @@ -178,6 +178,8 @@ protected: // // Lower level protected methods intended strictly for internal use: // + template + friend class TopologyRefinerFactory; friend class TopologyRefinerFactoryBase; friend class PatchTableFactory; friend class EndCapGregoryBasisPatchFactory; diff --git a/opensubdiv/far/topologyRefinerFactory.cpp b/opensubdiv/far/topologyRefinerFactory.cpp index 0ac46a95..921e5fac 100644 --- a/opensubdiv/far/topologyRefinerFactory.cpp +++ b/opensubdiv/far/topologyRefinerFactory.cpp @@ -143,7 +143,7 @@ TopologyRefinerFactoryBase::prepareComponentTopologyAssignment(TopologyRefiner& } // Now that we have a valid base level, initialize the Refiner's component inventory: - initializeBaseInventory(refiner); + refiner.initializeInventory(); return true; } @@ -283,143 +283,6 @@ TopologyRefinerFactoryBase::prepareFaceVaryingChannels(TopologyRefiner& refiner) return true; } - -// -// Specialization for raw topology data -// -template <> -bool -TopologyRefinerFactory::resizeComponentTopology( - TopologyRefiner & refiner, TopologyDescriptor const & desc) { - - setNumBaseVertices(refiner, desc.numVertices); - setNumBaseFaces(refiner, desc.numFaces); - - for (int face=0; face -bool -TopologyRefinerFactory::assignComponentTopology( - TopologyRefiner & refiner, TopologyDescriptor const & desc) { - - for (int face=0, idx=0; face 0; --vert) { - - dstFaceVerts[vert] = desc.vertIndicesPerFace[idx++]; - } - } else { - for (int vert=0; vert -bool -TopologyRefinerFactory::assignComponentTags( - TopologyRefiner & refiner, TopologyDescriptor const & desc) { - - if ((desc.numCreases>0) and desc.creaseVertexIndexPairs and desc.creaseWeights) { - - int const * vertIndexPairs = desc.creaseVertexIndexPairs; - for (int edge=0; edge0) and desc.cornerVertexIndices and desc.cornerWeights) { - - for (int vert=0; vert= 0 and idx < getNumBaseVertices(refiner)) { - setBaseVertexSharpness(refiner, idx, desc.cornerWeights[vert]); - } else { - char msg[1024]; - snprintf(msg, 1024, "Vertex %d specified to be sharp does not exist", idx); - reportInvalidTopology(Vtr::internal::Level::TOPOLOGY_INVALID_CREASE_VERT, msg, desc); - } - } - } - if (desc.numHoles>0) { - for (int i=0; i -bool -TopologyRefinerFactory::assignFaceVaryingTopology( - TopologyRefiner & refiner, TopologyDescriptor const & desc) { - - if (desc.numFVarChannels>0) { - - for (int channel=0; channel 0; --vert) { - - dstFaceFVarValues[vert] = srcFVarValues[srcNext++]; - } - } else { - for (int vert = 0; vert < dstFaceFVarValues.size(); ++vert) { - - dstFaceFVarValues[vert] = srcFVarValues[srcNext++]; - } - } - } - } - } - return true; -} - -template <> -void -TopologyRefinerFactory::reportInvalidTopology( - TopologyError /* errCode */, char const * msg, TopologyDescriptor const& /* mesh */) { - Warning(msg); -} - -TopologyRefinerFactoryBase::TopologyDescriptor::TopologyDescriptor() { - memset(this, 0, sizeof(TopologyDescriptor)); -} - } // end namespace Far } // end namespace OPENSUBDIV_VERSION diff --git a/opensubdiv/far/topologyRefinerFactory.h b/opensubdiv/far/topologyRefinerFactory.h index 92b7e443..6db7605f 100644 --- a/opensubdiv/far/topologyRefinerFactory.h +++ b/opensubdiv/far/topologyRefinerFactory.h @@ -38,62 +38,108 @@ namespace Far { // // TopologyRefinerFactoryBase: -// This is an abstract base class for subclasses that are intended to construct -// TopologyRefiner from external mesh representations. These subclasses are -// parameterized by the mesh type . -// This base class provides all implementation details related to assembly and -// validation that are independent of the subclass' mesh type. It also includes a -// suite of methods for modifying/assembling a newly created TopologyRefiner. +// This is a base class for subclasses that are intended to construct +// TopologyRefiner from external mesh representations. The subclasses are +// parameterized by the mesh type and are expected to inherit +// the details related to assembly and validation provided here that are +// independent of the subclass' mesh type. // class TopologyRefinerFactoryBase { - -public: - - /// \brief Descriptor for raw topology data, provided as a convenience for one - /// particular factory, but not used by others. - /// - struct TopologyDescriptor { - - int numVertices, - numFaces; - - int const * numVertsPerFace; - Index const * vertIndicesPerFace; - - int numCreases; - Index const * creaseVertexIndexPairs; - float const * creaseWeights; - - int numCorners; - Index const * cornerVertexIndices; - float const * cornerWeights; - - int numHoles; - Index const * holeIndices; - - bool isLeftHanded; - - // Face-varying data channel -- value indices correspond to vertex indices, - // i.e. one for every vertex of every face: - // - struct FVarChannel { - - int numValues; - Index const * valueIndices; - - FVarChannel() : numValues(0), valueIndices(0) { } - }; - - int numFVarChannels; - FVarChannel const * fvarChannels; - - TopologyDescriptor(); - }; - protected: // - // For use by subclasses to construct the base level: + // Protected methods invoked by the subclass template to verify and process each + // stage of construction implemented by the subclass: + // + typedef Vtr::internal::Level::ValidationCallback TopologyCallback; + + static bool prepareComponentTopologySizing(TopologyRefiner& refiner); + static bool prepareComponentTopologyAssignment(TopologyRefiner& refiner, bool fullValidation, + TopologyCallback callback, void const * callbackData); + static bool prepareComponentTagsAndSharpness(TopologyRefiner& refiner); + static bool prepareFaceVaryingChannels(TopologyRefiner& refiner); +}; + + +///\brief Factory for constructing TopologyRefiners from specific mesh classes. +/// +/// TopologyRefinerFactory is the factory class template to convert an instance of +/// TopologyRefiner from an arbitrary mesh class. While a class template, the implementation +/// is not (cannot) be complete, so specialization of a few methods is required (it is a +/// stateless factory, so no instance and only static methods). +/// +/// This template provides both the interface and high level assembly for the construction +/// of the TopologyRefiner instance. The high level construction executes a specific set +/// of operations to convert the client's MESH into TopologyRefiner. This set of operations +/// combines methods independent of MESH from the base class with those specialized here for +/// class MESH. +/// +template +class TopologyRefinerFactory : public TopologyRefinerFactoryBase { + +public: + + /// \brief Options related to the construction of each TopologyRefiner. + /// + struct Options { + + Options(Sdc::SchemeType sdcType = Sdc::SCHEME_CATMARK, Sdc::Options sdcOptions = Sdc::Options()) : + schemeType(sdcType), + schemeOptions(sdcOptions), + validateFullTopology(false) { } + + Sdc::SchemeType schemeType; ///< The subdivision scheme type identifier + Sdc::Options schemeOptions; ///< The full set of options for the scheme, + ///< e.g. boundary interpolation rules... + unsigned int validateFullTopology : 1; ///< Apply more extensive validation of + ///< the constructed topology -- intended + ///< for debugging. + }; + + /// \brief Instantiates TopologyRefiner from client-provided topological + /// representation. + /// + /// If only the face-vertices topological relationships are specified + /// with this factory, edge relationships have to be inferred, which + /// requires additional processing. If the client topological rep can + /// provide this information, it is highly recommended to do so. + /// + /// @param mesh Client's topological representation (or a converter) + // + /// @param options Options controlling the creation of the TopologyRefiner + /// + /// return A new instance of TopologyRefiner or NULL for failure + /// + static TopologyRefiner* Create(MESH const& mesh, Options options = Options()); + +protected: + // + // Methods to be specialized that implement all details specific to class MESH required + // to convert MESH data to TopologyRefiner. Note that some of these *must* be specialized + // in order to complete construction while some are optional. + // + // There are two minimal construction requirements (to specify the size and content of + // all topology relations) and two optional (to specify feature tags and face-varying + // channels). + // + // See comments in the generic stubs or the tutorials for more details on writing these. + // + // Required: + static bool resizeComponentTopology(TopologyRefiner& newRefiner, MESH const& mesh); + static bool assignComponentTopology(TopologyRefiner& newRefiner, MESH const& mesh); + + // Optional: + static bool assignComponentTags(TopologyRefiner& newRefiner, MESH const& mesh); + static bool assignFaceVaryingTopology(TopologyRefiner& newRefiner, MESH const& mesh); + + // Optional error reporting for validation: + typedef Vtr::internal::Level::TopologyError TopologyError; + + static void reportInvalidTopology(TopologyError errCode, char const * msg, MESH const& mesh); + +protected: + // + // Methods used to assemble the base level to implement those above: // // Topology sizing methods required before allocation: static void setNumBaseFaces(TopologyRefiner & newRefiner, int count); @@ -138,242 +184,11 @@ protected: static int createBaseFVarChannel(TopologyRefiner & newRefiner, int numValues, Sdc::Options const& fvarOptions); static IndexArray getBaseFaceFVarValues(TopologyRefiner & newRefiner, Index face, int channel = 0); - static void setBaseMaxValence(TopologyRefiner & newRefiner, int valence); - static void initializeBaseInventory(TopologyRefiner & newRefiner); - protected: - // - // Protected methods invoked by the subclass template to verify and process each - // stage of construction implemented by the subclass: + // Not to be specialized: // - typedef Vtr::internal::Level::ValidationCallback TopologyCallback; - - static bool prepareComponentTopologySizing(TopologyRefiner& refiner); - static bool prepareComponentTopologyAssignment(TopologyRefiner& refiner, bool fullValidation, - TopologyCallback callback, void const * callbackData); - static bool prepareComponentTagsAndSharpness(TopologyRefiner& refiner); - static bool prepareFaceVaryingChannels(TopologyRefiner& refiner); -}; - - -// -// Inline methods: -// -inline void -TopologyRefinerFactoryBase::setNumBaseFaces(TopologyRefiner & newRefiner, int count) { - newRefiner._levels[0]->resizeFaces(count); -} -inline void -TopologyRefinerFactoryBase::setNumBaseEdges(TopologyRefiner & newRefiner, int count) { - newRefiner._levels[0]->resizeEdges(count); -} -inline void -TopologyRefinerFactoryBase::setNumBaseVertices(TopologyRefiner & newRefiner, int count) { - newRefiner._levels[0]->resizeVertices(count); -} - -inline int -TopologyRefinerFactoryBase::getNumBaseFaces(TopologyRefiner const & newRefiner) { - return newRefiner._levels[0]->getNumFaces(); -} -inline int -TopologyRefinerFactoryBase::getNumBaseEdges(TopologyRefiner const & newRefiner) { - return newRefiner._levels[0]->getNumEdges(); -} -inline int -TopologyRefinerFactoryBase::getNumBaseVertices(TopologyRefiner const & newRefiner) { - return newRefiner._levels[0]->getNumVertices(); -} - -inline void -TopologyRefinerFactoryBase::setNumBaseFaceVertices(TopologyRefiner & newRefiner, Index f, int count) { - newRefiner._levels[0]->resizeFaceVertices(f, count); -} -inline void -TopologyRefinerFactoryBase::setNumBaseEdgeFaces(TopologyRefiner & newRefiner, Index e, int count) { - newRefiner._levels[0]->resizeEdgeFaces(e, count); -} -inline void -TopologyRefinerFactoryBase::setNumBaseVertexFaces(TopologyRefiner & newRefiner, Index v, int count) { - newRefiner._levels[0]->resizeVertexFaces(v, count); -} -inline void -TopologyRefinerFactoryBase::setNumBaseVertexEdges(TopologyRefiner & newRefiner, Index v, int count) { - newRefiner._levels[0]->resizeVertexEdges(v, count); -} - -inline IndexArray -TopologyRefinerFactoryBase::getBaseFaceVertices(TopologyRefiner & newRefiner, Index f) { - return newRefiner._levels[0]->getFaceVertices(f); -} -inline IndexArray -TopologyRefinerFactoryBase::getBaseFaceEdges(TopologyRefiner & newRefiner, Index f) { - return newRefiner._levels[0]->getFaceEdges(f); -} -inline IndexArray -TopologyRefinerFactoryBase::getBaseEdgeVertices(TopologyRefiner & newRefiner, Index e) { - return newRefiner._levels[0]->getEdgeVertices(e); -} -inline IndexArray -TopologyRefinerFactoryBase::getBaseEdgeFaces(TopologyRefiner & newRefiner, Index e) { - return newRefiner._levels[0]->getEdgeFaces(e); -} -inline IndexArray -TopologyRefinerFactoryBase::getBaseVertexFaces(TopologyRefiner & newRefiner, Index v) { - return newRefiner._levels[0]->getVertexFaces(v); -} -inline IndexArray -TopologyRefinerFactoryBase::getBaseVertexEdges(TopologyRefiner & newRefiner, Index v) { - return newRefiner._levels[0]->getVertexEdges(v); -} - -inline LocalIndexArray -TopologyRefinerFactoryBase::getBaseEdgeFaceLocalIndices(TopologyRefiner & newRefiner, Index e) { - return newRefiner._levels[0]->getEdgeFaceLocalIndices(e); -} -inline LocalIndexArray -TopologyRefinerFactoryBase::getBaseVertexFaceLocalIndices(TopologyRefiner & newRefiner, Index v) { - return newRefiner._levels[0]->getVertexFaceLocalIndices(v); -} -inline LocalIndexArray -TopologyRefinerFactoryBase::getBaseVertexEdgeLocalIndices(TopologyRefiner & newRefiner, Index v) { - return newRefiner._levels[0]->getVertexEdgeLocalIndices(v); -} - -inline Index -TopologyRefinerFactoryBase::findBaseEdge(TopologyRefiner const & newRefiner, Index v0, Index v1) { - return newRefiner._levels[0]->findEdge(v0, v1); -} - -inline void -TopologyRefinerFactoryBase::populateBaseLocalIndices(TopologyRefiner & newRefiner) { - newRefiner._levels[0]->populateLocalIndices(); -} - -inline void -TopologyRefinerFactoryBase::setBaseEdgeNonManifold(TopologyRefiner & newRefiner, Index e, bool b) { - newRefiner._levels[0]->setEdgeNonManifold(e, b); -} -inline void -TopologyRefinerFactoryBase::setBaseVertexNonManifold(TopologyRefiner & newRefiner, Index v, bool b) { - newRefiner._levels[0]->setVertexNonManifold(v, b); -} - -inline void -TopologyRefinerFactoryBase::setBaseEdgeSharpness(TopologyRefiner & newRefiner, Index e, float s) { - newRefiner._levels[0]->getEdgeSharpness(e) = s; -} -inline void -TopologyRefinerFactoryBase::setBaseVertexSharpness(TopologyRefiner & newRefiner, Index v, float s) { - newRefiner._levels[0]->getVertexSharpness(v) = s; -} -inline void -TopologyRefinerFactoryBase::setBaseFaceHole(TopologyRefiner & newRefiner, Index f, bool b) { - newRefiner._levels[0]->setFaceHole(f, b); - newRefiner._hasHoles |= b; -} - -inline int -TopologyRefinerFactoryBase::createBaseFVarChannel(TopologyRefiner & newRefiner, int numValues) { - return newRefiner._levels[0]->createFVarChannel(numValues, newRefiner._subdivOptions); -} -inline int -TopologyRefinerFactoryBase::createBaseFVarChannel(TopologyRefiner & newRefiner, int numValues, Sdc::Options const& fvarOptions) { - Sdc::Options newOptions = newRefiner._subdivOptions; - newOptions.SetFVarLinearInterpolation(fvarOptions.GetFVarLinearInterpolation()); - return newRefiner._levels[0]->createFVarChannel(numValues, newOptions); -} -inline IndexArray -TopologyRefinerFactoryBase::getBaseFaceFVarValues(TopologyRefiner & newRefiner, Index face, int channel) { - return newRefiner._levels[0]->getFaceFVarValues(face, channel); -} - -inline void -TopologyRefinerFactoryBase::setBaseMaxValence(TopologyRefiner & newRefiner, int valence) { - newRefiner._levels[0]->setMaxValence(valence); -} -inline void -TopologyRefinerFactoryBase::initializeBaseInventory(TopologyRefiner & newRefiner) { - newRefiner.initializeInventory(); -} - - -// -// TopologyRefinerFactory: -// The factory class template to convert and refine an instance of TopologyRefiner -// from an arbitrary mesh class. While a class template, the implementation is not -// (cannot) be complete, so specialization of a few methods is required. -// This template provides both the interface and high level assembly for the -// construction of the TopologyRefiner instance. The high level construction executes -// a specific set of operations to convert the client's MESH into TopologyRefiner, -// using methods independent of MESH from the base class and those specialized for -// class MESH appropriately. -// -template -class TopologyRefinerFactory : public TopologyRefinerFactoryBase { - -public: - - /// \brief Options related to the construction of each TopologyRefiner. - /// - struct Options { - - Options(Sdc::SchemeType sdcType = Sdc::SCHEME_CATMARK, Sdc::Options sdcOptions = Sdc::Options()) : - schemeType(sdcType), - schemeOptions(sdcOptions), - validateFullTopology(false) { } - - Sdc::SchemeType schemeType; ///< The subdivision scheme type identifier - Sdc::Options schemeOptions; ///< The full set of options for the scheme, - ///< e.g. boundary interpolation rules... - unsigned int validateFullTopology : 1; ///< Apply more extensive validation of - ///< the constructed topology -- intended - ///< for debugging. - }; - - /// \brief Instantiates TopologyRefiner from client-provided topological - /// representation. - /// - /// If only the face-vertices topological relationships are specified - /// with this factory, edge relationships have to be inferred, which - /// requires additional processing. If the client topological rep can - /// provide this information, it is highly recommended to do so. - /// - /// @param mesh Client's topological representation (or a converter) - // - /// @param options Options controlling the creation of the TopologyRefiner - /// - /// return A new instance of TopologyRefiner or NULL for failure - /// - static TopologyRefiner* Create(MESH const& mesh, Options options = Options()); - -protected: static bool populateBaseLevel(TopologyRefiner& refiner, MESH const& mesh, Options options); - - // - // Methods to be specialized that implement all details specific to class MESH required - // to convert MESH data to TopologyRefiner. Note that some of these *must* be specialized - // in order to complete construction while some are optional. - // - // There are two minimal construction requirements (to specify the size and content of - // all topology relations) and two optional (to specify feature tags and face-varying - // channels). - // - // See comments in the generic stubs or the tutorials for more details on writing these. - // - // Required: - static bool resizeComponentTopology(TopologyRefiner& refiner, MESH const& mesh); - static bool assignComponentTopology(TopologyRefiner& refiner, MESH const& mesh); - - // Optional: - static bool assignComponentTags(TopologyRefiner& refiner, MESH const& mesh); - static bool assignFaceVaryingTopology(TopologyRefiner& refiner, MESH const& mesh); - - // Optional miscellaneous specializations -- error reporting, etc.: - typedef Vtr::internal::Level::TopologyError TopologyError; - - static void reportInvalidTopology(TopologyError errCode, char const * msg, MESH const& mesh); }; @@ -445,6 +260,166 @@ TopologyRefinerFactory::populateBaseLevel(TopologyRefiner& refiner, MESH c return true; } +template +inline void +TopologyRefinerFactory::setNumBaseFaces(TopologyRefiner & newRefiner, int count) { + newRefiner._levels[0]->resizeFaces(count); +} +template +inline void +TopologyRefinerFactory::setNumBaseEdges(TopologyRefiner & newRefiner, int count) { + newRefiner._levels[0]->resizeEdges(count); +} +template +inline void +TopologyRefinerFactory::setNumBaseVertices(TopologyRefiner & newRefiner, int count) { + newRefiner._levels[0]->resizeVertices(count); +} + +template +inline int +TopologyRefinerFactory::getNumBaseFaces(TopologyRefiner const & newRefiner) { + return newRefiner._levels[0]->getNumFaces(); +} +template +inline int +TopologyRefinerFactory::getNumBaseEdges(TopologyRefiner const & newRefiner) { + return newRefiner._levels[0]->getNumEdges(); +} +template +inline int +TopologyRefinerFactory::getNumBaseVertices(TopologyRefiner const & newRefiner) { + return newRefiner._levels[0]->getNumVertices(); +} + +template +inline void +TopologyRefinerFactory::setNumBaseFaceVertices(TopologyRefiner & newRefiner, Index f, int count) { + newRefiner._levels[0]->resizeFaceVertices(f, count); +} +template +inline void +TopologyRefinerFactory::setNumBaseEdgeFaces(TopologyRefiner & newRefiner, Index e, int count) { + newRefiner._levels[0]->resizeEdgeFaces(e, count); +} +template +inline void +TopologyRefinerFactory::setNumBaseVertexFaces(TopologyRefiner & newRefiner, Index v, int count) { + newRefiner._levels[0]->resizeVertexFaces(v, count); +} +template +inline void +TopologyRefinerFactory::setNumBaseVertexEdges(TopologyRefiner & newRefiner, Index v, int count) { + newRefiner._levels[0]->resizeVertexEdges(v, count); +} + +template +inline IndexArray +TopologyRefinerFactory::getBaseFaceVertices(TopologyRefiner & newRefiner, Index f) { + return newRefiner._levels[0]->getFaceVertices(f); +} +template +inline IndexArray +TopologyRefinerFactory::getBaseFaceEdges(TopologyRefiner & newRefiner, Index f) { + return newRefiner._levels[0]->getFaceEdges(f); +} +template +inline IndexArray +TopologyRefinerFactory::getBaseEdgeVertices(TopologyRefiner & newRefiner, Index e) { + return newRefiner._levels[0]->getEdgeVertices(e); +} +template +inline IndexArray +TopologyRefinerFactory::getBaseEdgeFaces(TopologyRefiner & newRefiner, Index e) { + return newRefiner._levels[0]->getEdgeFaces(e); +} +template +inline IndexArray +TopologyRefinerFactory::getBaseVertexFaces(TopologyRefiner & newRefiner, Index v) { + return newRefiner._levels[0]->getVertexFaces(v); +} +template +inline IndexArray +TopologyRefinerFactory::getBaseVertexEdges(TopologyRefiner & newRefiner, Index v) { + return newRefiner._levels[0]->getVertexEdges(v); +} + +template +inline LocalIndexArray +TopologyRefinerFactory::getBaseEdgeFaceLocalIndices(TopologyRefiner & newRefiner, Index e) { + return newRefiner._levels[0]->getEdgeFaceLocalIndices(e); +} +template +inline LocalIndexArray +TopologyRefinerFactory::getBaseVertexFaceLocalIndices(TopologyRefiner & newRefiner, Index v) { + return newRefiner._levels[0]->getVertexFaceLocalIndices(v); +} +template +inline LocalIndexArray +TopologyRefinerFactory::getBaseVertexEdgeLocalIndices(TopologyRefiner & newRefiner, Index v) { + return newRefiner._levels[0]->getVertexEdgeLocalIndices(v); +} + +template +inline Index +TopologyRefinerFactory::findBaseEdge(TopologyRefiner const & newRefiner, Index v0, Index v1) { + return newRefiner._levels[0]->findEdge(v0, v1); +} + +template +inline void +TopologyRefinerFactory::populateBaseLocalIndices(TopologyRefiner & newRefiner) { + newRefiner._levels[0]->populateLocalIndices(); +} + +template +inline void +TopologyRefinerFactory::setBaseEdgeNonManifold(TopologyRefiner & newRefiner, Index e, bool b) { + newRefiner._levels[0]->setEdgeNonManifold(e, b); +} +template +inline void +TopologyRefinerFactory::setBaseVertexNonManifold(TopologyRefiner & newRefiner, Index v, bool b) { + newRefiner._levels[0]->setVertexNonManifold(v, b); +} + +template +inline void +TopologyRefinerFactory::setBaseEdgeSharpness(TopologyRefiner & newRefiner, Index e, float s) { + newRefiner._levels[0]->getEdgeSharpness(e) = s; +} +template +inline void +TopologyRefinerFactory::setBaseVertexSharpness(TopologyRefiner & newRefiner, Index v, float s) { + newRefiner._levels[0]->getVertexSharpness(v) = s; +} +template +inline void +TopologyRefinerFactory::setBaseFaceHole(TopologyRefiner & newRefiner, Index f, bool b) { + newRefiner._levels[0]->setFaceHole(f, b); + newRefiner._hasHoles |= b; +} + +template +inline int +TopologyRefinerFactory::createBaseFVarChannel(TopologyRefiner & newRefiner, int numValues) { + return newRefiner._levels[0]->createFVarChannel(numValues, newRefiner._subdivOptions); +} +template +inline int +TopologyRefinerFactory::createBaseFVarChannel(TopologyRefiner & newRefiner, int numValues, Sdc::Options const& fvarOptions) { + Sdc::Options newOptions = newRefiner._subdivOptions; + newOptions.SetFVarLinearInterpolation(fvarOptions.GetFVarLinearInterpolation()); + return newRefiner._levels[0]->createFVarChannel(numValues, newOptions); +} +template +inline IndexArray +TopologyRefinerFactory::getBaseFaceFVarValues(TopologyRefiner & newRefiner, Index face, int channel) { + return newRefiner._levels[0]->getFaceFVarValues(face, channel); +} + + + // XXXX manuelk MSVC specializes these templated functions which creates duplicated symbols #ifndef _MSC_VER @@ -452,7 +427,7 @@ template bool TopologyRefinerFactory::resizeComponentTopology(TopologyRefiner& /* refiner */, MESH const& /* mesh */) { - assert("Missing specialization for TopologyRefinerFactory::resizeComponentTopology()" == 0); + Error(FAR_RUNTIME_ERROR, "Missing specialization for TopologyRefinerFactory::resizeComponentTopology()"); // // Sizing the topology tables: @@ -492,7 +467,7 @@ template bool TopologyRefinerFactory::assignComponentTopology(TopologyRefiner& /* refiner */, MESH const& /* mesh */) { - assert("Missing specialization for TopologyRefinerFactory::assignComponentTopology()" == 0); + Error(FAR_RUNTIME_ERROR, "Missing specialization for TopologyRefinerFactory::assignComponentTopology()"); // // Assigning the topology tables: @@ -586,34 +561,6 @@ TopologyRefinerFactory::reportInvalidTopology( #endif -// -// Specialization for raw topology data -// -template <> -bool -TopologyRefinerFactory::resizeComponentTopology( - TopologyRefiner & refiner, TopologyDescriptor const & desc); - -template <> -bool -TopologyRefinerFactory::assignComponentTopology( - TopologyRefiner & refiner, TopologyDescriptor const & desc); - -template <> -bool -TopologyRefinerFactory::assignComponentTags( - TopologyRefiner & refiner, TopologyDescriptor const & desc); - -template <> -bool -TopologyRefinerFactory::assignFaceVaryingTopology( - TopologyRefiner & refiner, TopologyDescriptor const & desc); - -template <> -void -TopologyRefinerFactory::reportInvalidTopology( - TopologyError errCode, char const * msg, TopologyDescriptor const& /* mesh */); - } // end namespace Far } // end namespace OPENSUBDIV_VERSION diff --git a/tutorials/far/tutorial_0/far_tutorial_0.cpp b/tutorials/far/tutorial_0/far_tutorial_0.cpp index 4b5c99cd..0ed7ede9 100644 --- a/tutorials/far/tutorial_0/far_tutorial_0.cpp +++ b/tutorials/far/tutorial_0/far_tutorial_0.cpp @@ -30,7 +30,7 @@ // instantiate and refine a mesh with Far from simple topological data. // -#include +#include #include #include @@ -106,7 +106,7 @@ int main(int, char **) { // Populate a topology descriptor with our raw data - typedef Far::TopologyRefinerFactoryBase::TopologyDescriptor Descriptor; + typedef Far::TopologyDescriptor Descriptor; Sdc::SchemeType type = OpenSubdiv::Sdc::SCHEME_CATMARK; diff --git a/tutorials/far/tutorial_2/far_tutorial_2.cpp b/tutorials/far/tutorial_2/far_tutorial_2.cpp index 61170ab1..165babb4 100644 --- a/tutorials/far/tutorial_2/far_tutorial_2.cpp +++ b/tutorials/far/tutorial_2/far_tutorial_2.cpp @@ -30,7 +30,7 @@ // refine it uniformly and then interpolate additional sets of primvar data. // -#include +#include #include #include @@ -219,7 +219,7 @@ createFarTopologyRefiner() { // Populate a topology descriptor with our raw data - typedef Far::TopologyRefinerFactoryBase::TopologyDescriptor Descriptor; + typedef Far::TopologyDescriptor Descriptor; Sdc::SchemeType type = OpenSubdiv::Sdc::SCHEME_CATMARK; diff --git a/tutorials/far/tutorial_3/far_tutorial_3.cpp b/tutorials/far/tutorial_3/far_tutorial_3.cpp index 6aef2575..22045aaf 100644 --- a/tutorials/far/tutorial_3/far_tutorial_3.cpp +++ b/tutorials/far/tutorial_3/far_tutorial_3.cpp @@ -33,7 +33,7 @@ // 'face-varying' data recorded in the uv texture layout. // -#include +#include #include #include @@ -161,7 +161,7 @@ int main(int, char **) { int maxlevel = 3; - typedef Far::TopologyRefinerFactoryBase::TopologyDescriptor Descriptor; + typedef Far::TopologyDescriptor Descriptor; Sdc::SchemeType type = OpenSubdiv::Sdc::SCHEME_CATMARK; diff --git a/tutorials/far/tutorial_4/far_tutorial_4.cpp b/tutorials/far/tutorial_4/far_tutorial_4.cpp index b3815f5f..30c07677 100644 --- a/tutorials/far/tutorial_4/far_tutorial_4.cpp +++ b/tutorials/far/tutorial_4/far_tutorial_4.cpp @@ -30,7 +30,7 @@ // factorized stencils to interpolate vertex primvar data buffers. // -#include +#include #include #include @@ -164,7 +164,7 @@ static Far::TopologyRefiner * createTopologyRefiner() { // Populate a topology descriptor with our raw data. - typedef Far::TopologyRefinerFactoryBase::TopologyDescriptor Descriptor; + typedef Far::TopologyDescriptor Descriptor; Sdc::SchemeType type = OpenSubdiv::Sdc::SCHEME_CATMARK; diff --git a/tutorials/far/tutorial_5/far_tutorial_5.cpp b/tutorials/far/tutorial_5/far_tutorial_5.cpp index 48e1ee5d..f47e4fb9 100644 --- a/tutorials/far/tutorial_5/far_tutorial_5.cpp +++ b/tutorials/far/tutorial_5/far_tutorial_5.cpp @@ -31,7 +31,7 @@ // vertex colors. // -#include +#include #include #include @@ -214,7 +214,7 @@ createTopologyRefiner() { // Populate a topology descriptor with our raw data. - typedef Far::TopologyRefinerFactoryBase::TopologyDescriptor Descriptor; + typedef Far::TopologyDescriptor Descriptor; Sdc::SchemeType type = OpenSubdiv::Sdc::SCHEME_CATMARK; diff --git a/tutorials/far/tutorial_6/far_tutorial_6.cpp b/tutorials/far/tutorial_6/far_tutorial_6.cpp index fdc6f7bd..88811028 100644 --- a/tutorials/far/tutorial_6/far_tutorial_6.cpp +++ b/tutorials/far/tutorial_6/far_tutorial_6.cpp @@ -40,7 +40,7 @@ // systems that show the tangent and bi-tangent at the random samples locations. // -#include +#include #include #include #include @@ -272,7 +272,7 @@ static Far::TopologyRefiner * createTopologyRefiner() { - typedef Far::TopologyRefinerFactoryBase::TopologyDescriptor Descriptor; + typedef Far::TopologyDescriptor Descriptor; Sdc::SchemeType type = OpenSubdiv::Sdc::SCHEME_CATMARK; diff --git a/tutorials/far/tutorial_7/far_tutorial_7.cpp b/tutorials/far/tutorial_7/far_tutorial_7.cpp index 066b9b0c..01df0d24 100644 --- a/tutorials/far/tutorial_7/far_tutorial_7.cpp +++ b/tutorials/far/tutorial_7/far_tutorial_7.cpp @@ -41,7 +41,7 @@ // of refinement of the original cube. // -#include +#include #include #include @@ -218,7 +218,7 @@ static Far::TopologyRefiner * createTopologyRefiner() { // Populate a topology descriptor with our raw data. - typedef Far::TopologyRefinerFactoryBase::TopologyDescriptor Descriptor; + typedef Far::TopologyDescriptor Descriptor; Sdc::SchemeType type = OpenSubdiv::Sdc::SCHEME_CATMARK; diff --git a/tutorials/osd/tutorial_0/osd_tutorial_0.cpp b/tutorials/osd/tutorial_0/osd_tutorial_0.cpp index 0efe0afa..31ae47f6 100644 --- a/tutorials/osd/tutorial_0/osd_tutorial_0.cpp +++ b/tutorials/osd/tutorial_0/osd_tutorial_0.cpp @@ -30,7 +30,7 @@ // 'Controllers'. // -#include +#include #include #include #include @@ -138,7 +138,7 @@ createTopologyRefiner(int maxlevel) { // Populate a topology descriptor with our raw data - typedef Far::TopologyRefinerFactoryBase::TopologyDescriptor Descriptor; + typedef Far::TopologyDescriptor Descriptor; Sdc::SchemeType type = OpenSubdiv::Sdc::SCHEME_CATMARK;