mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2025-01-09 00:00:18 +00:00
a1c7be7c8e
This set of commits includes the addition of a new evaluation interface that treats a subdivision mesh more like a piecewise parametric surface primitive. The new interface was placed in namespace "Bfr" for "Base Face Representation" as all concepts and classes relate to a single face of the base mesh.
237 lines
9.3 KiB
C++
237 lines
9.3 KiB
C++
//
|
|
// 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 */
|