OpenSubdiv/opensubdiv/far/patchTableFactory.h
David G Yu 35d8519895 Refactored Far::PatchTableFactory
Re-organized the implementation of the patch table factory
in advance of adding support for bicubic face-varying patches.

- Renamed the AdaptiveContext internal class to BuilderContext
  since this can be used (eventually) to build patch tables for
  uniformly refined topology as well as adaptively refined
  topology.
- Added utility methods to gather patch vertices from the
  levels (and eventually fvarLevels) of a refiner.
- Replaced the FVarChannelCursor with a simpler array of integer
  face-varying channel indices.
- Extracted the topology inspection needed to identify
  patches into a computePatchTag() method.
- Simplified the two-pass traversal of the topology into a
  single pass traversal of the refined topology followed by
  an iteration over the patches that have been identified.
- Replaced internal templated PatchTypes class with simpler
  and more direct accounting and patch array building facilities.
- Changed the API of the end cap patch factories to no longer
  depend on the patch table factory's PatchFaceTag. This has
  been superseded by the specification of appropriate
  VSpans at the corners of the end patch.
2016-08-05 12:38:05 -07:00

178 lines
7.1 KiB
C++

//
// Copyright 2013 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_FAR_PATCH_TABLE_FACTORY_H
#define OPENSUBDIV3_FAR_PATCH_TABLE_FACTORY_H
#include "../version.h"
#include "../far/patchTable.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Far {
// Forward declarations (for internal implementation purposes):
class PtexIndices;
class TopologyRefiner;
class PatchTableFactory {
public:
// PatchFaceTag
// A simple struct containing all information gathered about a face that is relevant
// to constructing a patch for it (some of these enums should probably be defined more
// as part of PatchTable)
//
// Like the HbrFace<T>::AdaptiveFlags, this struct aggregates all of the face tags
// supporting feature adaptive refinement. For now it is not used elsewhere and can
// remain local to this implementation, but we may want to move it into a header of
// its own if it has greater use later.
//
// Note that several properties being assigned here attempt to do so given a 4-bit
// mask of properties at the edges or vertices of the quad. Still not sure exactly
// what will be done this way, but the goal is to create lookup tables (of size 16
// for the 4 bits) to quickly determine was is needed, rather than iteration and
// branching on the edges or vertices.
//
struct PatchFaceTag {
public:
unsigned int _isRegular : 1;
unsigned int _transitionMask : 4;
unsigned int _boundaryMask : 4;
unsigned int _boundaryIndex : 2;
unsigned int _boundaryCount : 3;
unsigned int _hasBoundaryEdge : 3;
unsigned int _isSingleCrease : 1;
void clear();
void assignBoundaryPropertiesFromEdgeMask(int boundaryEdgeMask);
void assignBoundaryPropertiesFromVertexMask(int boundaryVertexMask);
};
typedef std::vector<PatchFaceTag> PatchTagVector;
struct Options {
enum EndCapType {
ENDCAP_NONE = 0, ///< no endcap
ENDCAP_BILINEAR_BASIS, ///< use bilinear quads (4 cp) as end-caps
ENDCAP_BSPLINE_BASIS, ///< use BSpline basis patches (16 cp) as end-caps
ENDCAP_GREGORY_BASIS, ///< use Gregory basis patches (20 cp) as end-caps
ENDCAP_LEGACY_GREGORY ///< use legacy (2.x) Gregory patches (4 cp + valence table) as end-caps
};
Options(unsigned int maxIsolation=10) :
generateAllLevels(false),
triangulateQuads(false),
useSingleCreasePatch(false),
maxIsolationLevel(maxIsolation),
endCapType(ENDCAP_GREGORY_BASIS),
shareEndCapPatchPoints(true),
generateFVarTables(false),
numFVarChannels(-1),
fvarChannelIndices(0)
{ }
/// \brief Get endcap patch type
EndCapType GetEndCapType() const { return (EndCapType)endCapType; }
/// \brief Set endcap patch type
void SetEndCapType(EndCapType e) { endCapType = e; }
unsigned int generateAllLevels : 1, ///< Include levels from 'firstLevel' to 'maxLevel' (Uniform mode only)
triangulateQuads : 1, ///< Triangulate 'QUADS' primitives (Uniform mode only)
useSingleCreasePatch : 1, ///< Use single crease patch
maxIsolationLevel : 4, ///< Cap adaptive feature isolation to the given level (max. 10)
// end-capping
endCapType : 3, ///< EndCapType
shareEndCapPatchPoints : 1, ///< Share endcap patch points among adjacent endcap patches.
///< currently only work with GregoryBasis.
// face-varying
generateFVarTables : 1;///< Generate face-varying patch tables
int numFVarChannels; ///< Number of channel indices and interpolation modes passed
int const * fvarChannelIndices; ///< List containing the indices of the channels selected for the factory
};
/// \brief Factory constructor for PatchTable
///
/// @param refiner TopologyRefiner from which to generate patches
///
/// @param options Options controlling the creation of the table
///
/// @return A new instance of PatchTable
///
static PatchTable * Create(TopologyRefiner const & refiner,
Options options=Options());
private:
//
// Private helper structures
//
struct BuilderContext;
//
// Methods for allocating and managing the patch table data arrays:
//
static PatchTable * createUniform(TopologyRefiner const & refiner,
Options options);
static PatchTable * createAdaptive(TopologyRefiner const & refiner,
Options options);
//
// High-level methods for identifying and populating patches associated with faces:
//
static bool computePatchTag(BuilderContext & context,
Index const levelIndex,
Index const faceIndex,
PatchTableFactory::PatchFaceTag &patchTag);
static void identifyAdaptivePatches(BuilderContext & context);
static void populateAdaptivePatches(BuilderContext & context,
PatchTable * table);
static void allocateVertexTables(PatchTable * table, bool hasSharpness);
static void allocateFVarChannels(BuilderContext const & context,
PatchTable * table);
static PatchParam computePatchParam(BuilderContext const & context,
int level, int face,
int boundaryMask, int transitionMask);
};
} // end namespace Far
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif /* OPENSUBDIV3_FAR_PATCH_TABLE_FACTORY_H */