OpenSubdiv/opensubdiv/bfr/surfaceFactoryMeshAdapter.h

237 lines
9.3 KiB
C
Raw Normal View History

//
// Copyright 2021 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 OPENSUBDIV3_BFR_SURFACE_FACTORY_ADAPTER_H
#define OPENSUBDIV3_BFR_SURFACE_FACTORY_ADAPTER_H
#include "../version.h"
#include <cstdint>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Bfr {
class VertexDescriptor;
///
/// @brief Abstract interface adapting SurfaceFactory to a connected mesh
/// representation
///
// SurfaceFactoryMeshAdapter is an abstract class that defines the interface
// through which subclasses of SurfaceFactory adapt to a connected mesh
// representation. The interface defines methods that describe the mesh
// topology and control indices in the neighborhood of a mesh -- from
// which the SurfaceFactory to identifies an appropriate limit surface.
//
// SurfaceFactoryMeshAdapter methods require a subclass to provide a complete
// description of the topology around a base face, as well as indices
// associated with it (both vertex and face-varying). The intent here is
// to keep the number of methods required to a minimum, and also to minimize
// the number of invocations required by the factory.
//
// With the need to support both linear and non-linear cases (for which
// linear is trivial by comparison) and the limit surface for both vertex
// and face-varying topologies, the result is a small set of methods
// covering this matrix of functionality.
//
// Since face-varying data may differ in topology from the vertex data --
// with each set of face-varying data potentially having its own unique
// topology -- sets of face-varying data are uniquely distinguished by an
// associated integer (a face-varying ID).
//
class SurfaceFactoryMeshAdapter {
public:
/// @brief Integer type representing a mesh index
typedef int Index;
/// @brief Type used to identify and specify face-varying primvars
///
/// A face-varying ID is used to specify face-varying primvars for
/// evaluation so that they can be identified by the subclass for
/// the mesh. It can be assigned as either a positive integer ID
/// or pointer, with the subclass determining its interpretation.
///
/// Often only one face-varying primvar is of interest, so a default
/// can be assigned to the factory to avoid repeated specification.
///
typedef std::intptr_t FVarID;
protected:
/// @cond PROTECTED
SurfaceFactoryMeshAdapter() { }
virtual ~SurfaceFactoryMeshAdapter() { }
/// @endcond
protected:
//@{
/// @name Methods to query simple face properties
///
/// Methods to return simple properties associated with a face.
///
/// @brief Returns if a face is a hole
virtual bool isFaceHole(Index faceIndex) const = 0;
/// @brief Returns the size of a face (number of vertices)
virtual int getFaceSize(Index faceIndex) const = 0;
//@}
//@{
/// @name Methods to gather indices for the face's vertices
///
/// These methods gather indices associated with the vertices of a
/// face, e.g. the indices of the vertices themselves, or the indices
/// of face-varying values associated with the vertices. These are
/// used to quickly deal with linear limit surfaces without any
/// inspection of the neighboring topology.
///
/// @brief Gather the indices of the face's vertices
virtual int getFaceVertexIndices(Index faceIndex,
Index vertexIndices[]) const = 0;
/// @brief Gather the face-varying indices of the face's vertices
virtual int getFaceFVarValueIndices(Index faceIndex,
FVarID fvarID, Index fvarValueIndices[]) const = 0;
//@}
protected:
//@{
/// @name Methods to identify the neighborhood of a face-vertex
///
/// These methods identify the topology and associated indices for
/// the complete set of incident faces surrounding a corner (or
/// face-vertex) of a face.
///
/// Methods here use "FaceVertex" in the name to emphasize that they
/// require information for a particular corner vertex of the face.
///
/// The topology around the face-vertex is described by populating a
/// given instance of a simple VertexDescriptor class -- which fully
/// describes the face-vertex, it incident faces and any sharpness
/// assigned at or around the face-vertex. (See the comments with
/// the VertexDescriptor definition for more details.)
///
/// Additional methods are then required to identify indices for the
/// incident faces around a face-vertex. One method gathers the
/// indices for control vertices of the mesh assigned to the incident
/// faces (their VertexIndices), while the other gathers indices for
/// a particular set of face-varying values assigned to them (their
/// FVarValueIndices).
///
/// Both methods expect the incident faces to be ordered consistent
/// with the specification in VertexDescriptor, and all indices for
/// all incident faces are required.
///
/// The order of indices assigned to each face for these methods must
/// also be specified relative to the face-vertex, rather than the
/// way the face is defined. For example, if a quad Q is defined by
/// the four vertices {A, B, C, D}, when gathering the indices for Q
/// as part of face-vertex C, the indices should be specified starting
/// with C, i.e. as {C, D, A, B}. Ordering indices this way makes it
/// much easier for the factory to identify when face-varying topology
/// differs from the vertex topology, and both the face-varying and
/// vertex indices are ordered this way for consistency.
///
/// @brief Describe the topology of incident faces around a face-vertex
virtual int populateFaceVertexDescriptor(
Index faceIndex, int faceVertex,
VertexDescriptor * vertexDescriptor) const = 0;
/// @brief Gather vertex indices of incident faces around a face-vertex
virtual int getFaceVertexIncidentFaceVertexIndices(
Index faceIndex, int faceVertex,
Index vertexIndices[]) const = 0;
/// @brief Gather face-varying indices of incident faces around a
/// face-vertex
virtual int getFaceVertexIncidentFaceFVarValueIndices(
Index faceIndex, int faceVertex,
FVarID fvarID, Index fvarValueIndices[]) const = 0;
//@}
protected:
//@{
/// @name Optional methods for purely regular topology
///
/// Optional methods for advanced use to accelerate the case of
/// purely regular topology around a face.
///
/// For cases when a mesh can quickly determine if the neighborhood
/// around a faces is purely regular, these methods can be used to
/// quickly identify the control point indices for the corresponding
/// regular patch defining its limit surface. In doing so, the more
/// tedious topological assembly requiring information about each
/// face-vertex can be avoided.
///
/// The indices returned must be ordered according to the regular
/// patch type corresponding to the subdivision scheme of the mesh.
/// Boundary vertices are allowed and indicated by an Index of -1.
///
/// The face-varying version will only be invoked if the vertex
/// version is purely regular, in which case, the face-varying
/// topology is expected to be similar.
///
/// Note that these methods allow the caller (the SurfaceFactory) to
/// pass nullptr (0) for the index arrays -- in which case only the
/// return value should be provided.
///
virtual bool getFaceNeighborhoodVertexIndicesIfRegular(
Index faceIndex, Index vertexIndices[]) const;
virtual bool getFaceNeighborhoodFVarValueIndicesIfRegular(
Index faceIndex, FVarID fvarID, Index fvarValueIndices[]) const;
//@}
private:
// No private members
};
//
// Inline defaults for optional methods:
//
inline bool
SurfaceFactoryMeshAdapter::getFaceNeighborhoodVertexIndicesIfRegular(
Index, Index[]) const {
return false;
}
inline bool
SurfaceFactoryMeshAdapter::getFaceNeighborhoodFVarValueIndicesIfRegular(
Index, FVarID, Index[]) const {
return false;
}
} // end namespace Bfr
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif /* OPENSUBDIV3_BFR_SURFACE_FACTORY_ADAPTER_H */