2013-05-17 16:47:44 +00:00
|
|
|
//
|
2013-09-26 19:04:57 +00:00
|
|
|
// Copyright 2013 Pixar
|
2013-05-17 16:47:44 +00:00
|
|
|
//
|
2013-09-26 19:04:57 +00:00
|
|
|
// 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:
|
2013-05-17 16:47:44 +00:00
|
|
|
//
|
2013-09-26 19:04:57 +00:00
|
|
|
// 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.
|
2013-05-17 16:47:44 +00:00
|
|
|
//
|
2013-09-26 19:04:57 +00:00
|
|
|
// You may obtain a copy of the Apache License at
|
2013-05-17 16:47:44 +00:00
|
|
|
//
|
2013-09-26 19:04:57 +00:00
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
2013-07-18 21:19:50 +00:00
|
|
|
//
|
2013-09-26 19:04:57 +00:00
|
|
|
// 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.
|
2013-05-17 16:47:44 +00:00
|
|
|
//
|
|
|
|
|
2015-05-19 18:22:37 +00:00
|
|
|
#ifndef OPENSUBDIV3_FAR_PATCH_PARAM_H
|
|
|
|
#define OPENSUBDIV3_FAR_PATCH_PARAM_H
|
2013-05-17 16:47:44 +00:00
|
|
|
|
2013-06-12 00:25:54 +00:00
|
|
|
#include "../version.h"
|
|
|
|
|
2014-10-09 21:48:50 +00:00
|
|
|
#include "../far/types.h"
|
|
|
|
|
2013-05-17 16:47:44 +00:00
|
|
|
namespace OpenSubdiv {
|
|
|
|
namespace OPENSUBDIV_VERSION {
|
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
namespace Far {
|
|
|
|
|
2016-08-24 20:31:21 +00:00
|
|
|
/// \brief Patch parameterization
|
2013-05-17 16:47:44 +00:00
|
|
|
///
|
2016-08-24 20:31:21 +00:00
|
|
|
/// Topological refinement splits coarse mesh faces into refined faces.
|
2013-05-17 16:47:44 +00:00
|
|
|
///
|
2016-08-24 20:31:21 +00:00
|
|
|
/// This patch parameterzation describes the relationship between one
|
|
|
|
/// of these refined faces and its corresponding coarse face. It is used
|
|
|
|
/// both for refined faces that are represented as full limit surface
|
|
|
|
/// parametric patches as well as for refined faces represented as simple
|
|
|
|
/// triangles or quads. This parameterization is needed to interpolate
|
|
|
|
/// primvar data across a refined face.
|
2014-11-25 20:41:19 +00:00
|
|
|
///
|
2016-08-24 20:31:21 +00:00
|
|
|
/// The U,V and refinement level parameters describe the scale and offset
|
|
|
|
/// needed to map a location on the patch between levels of refinement.
|
|
|
|
/// The encoding of these values exploits the quad-tree organization of
|
|
|
|
/// the faces produced by subdivision. We encode the U,V origin of the
|
|
|
|
/// patch using two 10-bit integer values and the refinement level as
|
|
|
|
/// a 4-bit integer. This is sufficient to represent up through 10 levels
|
|
|
|
/// of refinement.
|
|
|
|
///
|
|
|
|
/// Special consideration must be given to the refined faces resulting from
|
|
|
|
/// irregular coarse faces. We adopt a convention similar to Ptex texture
|
|
|
|
/// mapping and define the parameterization for these faces in terms of the
|
|
|
|
/// regular faces resulting from the first topological splitting of the
|
|
|
|
/// irregular coarse face.
|
|
|
|
///
|
|
|
|
/// When computing the basis functions needed to evaluate the limit surface
|
|
|
|
/// parametric patch representing a refined face, we also need to know which
|
|
|
|
/// edges of the patch are interpolated boundaries. These edges are encoded
|
|
|
|
/// as a boundary bitmask identifying the boundary edges of the patch in
|
|
|
|
/// sequential order starting from the first vertex of the refined face.
|
|
|
|
///
|
|
|
|
/// A sparse topological refinement (like feature adaptive refinement) can
|
|
|
|
/// produce refined faces that are adjacent to faces at the next level of
|
|
|
|
/// subdivision. We identify these transitional edges with a transition
|
|
|
|
/// bitmask using the same encoding as the boundary bitmask.
|
|
|
|
///
|
|
|
|
/// For triangular subdivision schemes we specify the parameterization using
|
|
|
|
/// a similar method. Alternate triangles at a given level of refinement
|
|
|
|
/// are parameterized from their opposite corners and encoded as occupying
|
|
|
|
/// the opposite diagonal of the quad-tree hierarchy. The third barycentric
|
|
|
|
/// coordinate is dependent on and can be derived from the other two
|
|
|
|
/// coordinates. This encoding also takes inspiration from the Ptex
|
|
|
|
/// texture mapping specification.
|
|
|
|
///
|
|
|
|
/// Bitfield layout :
|
2015-06-11 20:18:25 +00:00
|
|
|
///
|
2016-09-29 16:38:32 +00:00
|
|
|
/// Field0 | Bits | Content
|
|
|
|
/// -----------|:----:|------------------------------------------------------
|
|
|
|
/// faceId | 28 | the faceId of the patch
|
|
|
|
/// transition | 4 | transition edge mask encoding
|
|
|
|
///
|
2015-06-11 20:18:25 +00:00
|
|
|
/// Field1 | Bits | Content
|
|
|
|
/// -----------|:----:|------------------------------------------------------
|
|
|
|
/// level | 4 | the subdivision level of the patch
|
2016-09-29 16:38:32 +00:00
|
|
|
/// nonquad | 1 | whether patch is refined from a non-quad face
|
|
|
|
/// regular | 1 | whether patch is regular
|
|
|
|
/// unused | 2 | unused
|
2015-04-17 14:42:53 +00:00
|
|
|
/// boundary | 4 | boundary edge mask encoding
|
2014-11-25 20:41:19 +00:00
|
|
|
/// v | 10 | log2 value of u parameter at first patch corner
|
|
|
|
/// u | 10 | log2 value of v parameter at first patch corner
|
|
|
|
///
|
2013-05-17 16:47:44 +00:00
|
|
|
/// Note : the bitfield is not expanded in the struct due to differences in how
|
|
|
|
/// GPU & CPU compilers pack bit-fields and endian-ness.
|
|
|
|
///
|
2016-08-24 20:31:21 +00:00
|
|
|
/*!
|
|
|
|
\verbatim
|
|
|
|
Quad Patch Parameterization
|
2014-11-25 20:41:19 +00:00
|
|
|
|
2016-08-24 20:31:21 +00:00
|
|
|
(0,1) (1,1)
|
|
|
|
+-------+-------+---------------+
|
|
|
|
| | | |
|
|
|
|
| L2 | L2 | |
|
|
|
|
|0,3 |1,3 | |
|
|
|
|
+-------+-------+ L1 |
|
|
|
|
| | | |
|
|
|
|
| L2 | L2 | |
|
|
|
|
|0,2 |1,2 |1,1 |
|
|
|
|
+-------+-------+---------------+
|
|
|
|
| | |
|
|
|
|
| | |
|
|
|
|
| | |
|
|
|
|
| L1 | L1 |
|
|
|
|
| | |
|
|
|
|
| | |
|
|
|
|
|0,0 |1,0 |
|
|
|
|
+---------------+---------------+
|
|
|
|
(0,0) (1,0)
|
|
|
|
\endverbatim
|
|
|
|
*/
|
|
|
|
/*!
|
|
|
|
\verbatim
|
|
|
|
Triangle Patch Parameterization
|
2015-06-11 20:18:25 +00:00
|
|
|
|
2016-08-24 20:31:21 +00:00
|
|
|
(0,1) (1,1) (0,1,0)
|
|
|
|
+-------+-------+---------------+ +
|
|
|
|
| \ | \ | \ | | \
|
|
|
|
|L2 \ |L2 \ | \ | | \
|
|
|
|
|0,3 \ |1,3 \ | \ | | L2 \
|
|
|
|
+-------+-------+ \ | +-------+
|
|
|
|
| \ | \ | L1 \ | | \ L2 | \
|
|
|
|
|L2 \ |L2 \ | \ | | \ | \
|
|
|
|
|0,2 \ |1,2 \ |1,1 \ | | L2 \ | L2 \
|
|
|
|
+-------+-------+---------------+ +-------+-------+
|
|
|
|
| \ | \ | | \ | \
|
|
|
|
| \ | \ | | \ | \
|
|
|
|
| \ | \ | | \ L1 | \
|
|
|
|
| \ | \ | | \ | \
|
|
|
|
| L1 \ | L1 \ | | L1 \ | L1 \
|
|
|
|
| \ | \ | | \ | \
|
|
|
|
|0,0 \ |1,0 \ | | \ | \
|
|
|
|
+---------------+---------------+ +---------------+---------------+
|
|
|
|
(0,0) (1,0) (0,0,1) (1,0,0)
|
|
|
|
\endverbatim
|
|
|
|
*/
|
2015-06-11 20:18:25 +00:00
|
|
|
|
2016-09-29 16:38:32 +00:00
|
|
|
struct PatchParam {
|
|
|
|
/// \brief Sets the values of the bit fields
|
|
|
|
///
|
|
|
|
/// @param faceid face index
|
|
|
|
///
|
|
|
|
/// @param u value of the u parameter for the first corner of the face
|
|
|
|
/// @param v value of the v parameter for the first corner of the face
|
|
|
|
///
|
|
|
|
/// @param depth subdivision level of the patch
|
|
|
|
/// @param nonquad true if the root face is not a quad
|
|
|
|
///
|
|
|
|
/// @param boundary 4-bits identifying boundary edges
|
|
|
|
/// @param transition 4-bits identifying transition edges
|
|
|
|
///
|
|
|
|
/// @param regular whether the patch is regular
|
|
|
|
///
|
|
|
|
void Set(Index faceid, short u, short v,
|
|
|
|
unsigned short depth, bool nonquad,
|
|
|
|
unsigned short boundary, unsigned short transition,
|
|
|
|
bool regular = false);
|
|
|
|
|
|
|
|
/// \brief Resets everything to 0
|
|
|
|
void Clear() { field0 = field1 = 0; }
|
|
|
|
|
2015-08-12 19:36:58 +00:00
|
|
|
/// \brief Returns the faceid
|
2016-09-29 16:38:32 +00:00
|
|
|
Index GetFaceId() const { return Index(unpack(field0,28,0)); }
|
|
|
|
|
2016-08-24 20:31:21 +00:00
|
|
|
/// \brief Returns the log2 value of the u parameter at
|
|
|
|
/// the first corner of the patch
|
2016-09-29 16:38:32 +00:00
|
|
|
unsigned short GetU() const { return (unsigned short)unpack(field1,10,22); }
|
2015-06-11 20:18:25 +00:00
|
|
|
|
2016-08-24 20:31:21 +00:00
|
|
|
/// \brief Returns the log2 value of the v parameter at
|
|
|
|
/// the first corner of the patch
|
2016-09-29 16:38:32 +00:00
|
|
|
unsigned short GetV() const { return (unsigned short)unpack(field1,10,12); }
|
|
|
|
|
|
|
|
/// \brief Returns the transition edge encoding for the patch.
|
|
|
|
unsigned short GetTransition() const { return (unsigned short)unpack(field0,4,28); }
|
2015-06-11 20:18:25 +00:00
|
|
|
|
|
|
|
/// \brief Returns the boundary edge encoding for the patch.
|
2016-09-29 16:38:32 +00:00
|
|
|
unsigned short GetBoundary() const { return (unsigned short)unpack(field1,4,8); }
|
2015-06-11 20:18:25 +00:00
|
|
|
|
2016-09-30 02:18:16 +00:00
|
|
|
/// \brief True if the parent base face is a non-quad
|
2016-09-29 16:38:32 +00:00
|
|
|
bool NonQuadRoot() const { return (unpack(field1,1,4) != 0); }
|
2015-06-11 20:18:25 +00:00
|
|
|
|
|
|
|
/// \brief Returns the level of subdivision of the patch
|
2016-09-29 16:38:32 +00:00
|
|
|
unsigned short GetDepth() const { return (unsigned short)unpack(field1,4,0); }
|
2016-08-24 20:31:21 +00:00
|
|
|
|
2016-09-30 02:18:16 +00:00
|
|
|
/// \brief Returns the fraction of unit parametric space covered by this face.
|
2016-08-24 20:31:21 +00:00
|
|
|
float GetParamFraction() const;
|
2015-06-11 20:18:25 +00:00
|
|
|
|
2016-09-30 02:18:16 +00:00
|
|
|
/// \brief A (u,v) pair in the fraction of parametric space covered by this
|
|
|
|
/// face is mapped into a normalized parametric space.
|
2015-06-11 20:18:25 +00:00
|
|
|
///
|
2016-09-30 02:18:16 +00:00
|
|
|
/// @param u u parameter
|
|
|
|
/// @param v v parameter
|
2015-06-11 20:18:25 +00:00
|
|
|
///
|
2018-07-28 21:43:32 +00:00
|
|
|
template <typename REAL>
|
|
|
|
void Normalize( REAL & u, REAL & v ) const;
|
2015-06-11 20:18:25 +00:00
|
|
|
|
2016-09-30 02:18:16 +00:00
|
|
|
/// \brief A (u,v) pair in a normalized parametric space is mapped back into the
|
|
|
|
/// fraction of parametric space covered by this face.
|
2016-09-29 16:38:32 +00:00
|
|
|
///
|
|
|
|
/// @param u u parameter
|
|
|
|
/// @param v v parameter
|
|
|
|
///
|
2018-07-28 21:43:32 +00:00
|
|
|
template <typename REAL>
|
|
|
|
void Unnormalize( REAL & u, REAL & v ) const;
|
2013-05-17 16:47:44 +00:00
|
|
|
|
2016-09-29 16:38:32 +00:00
|
|
|
/// \brief Returns whether the patch is regular
|
|
|
|
bool IsRegular() const { return (unpack(field1,1,5) != 0); }
|
2014-11-25 20:41:19 +00:00
|
|
|
|
2016-09-29 16:38:32 +00:00
|
|
|
unsigned int field0:32;
|
|
|
|
unsigned int field1:32;
|
2014-11-25 20:41:19 +00:00
|
|
|
|
2016-09-29 16:38:32 +00:00
|
|
|
private:
|
2016-08-24 20:31:21 +00:00
|
|
|
unsigned int pack(unsigned int value, int width, int offset) const {
|
|
|
|
return (unsigned int)((value & ((1<<width)-1)) << offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int unpack(unsigned int value, int width, int offset) const {
|
2016-10-19 18:57:08 +00:00
|
|
|
return (unsigned int)((value >> offset) & ((1<<width)-1));
|
2016-08-24 20:31:21 +00:00
|
|
|
}
|
|
|
|
};
|
2014-11-25 20:41:19 +00:00
|
|
|
|
2016-09-29 16:38:32 +00:00
|
|
|
typedef std::vector<PatchParam> PatchParamTable;
|
|
|
|
|
|
|
|
typedef Vtr::Array<PatchParam> PatchParamArray;
|
|
|
|
typedef Vtr::ConstArray<PatchParam> ConstPatchParamArray;
|
|
|
|
|
|
|
|
inline void
|
|
|
|
PatchParam::Set(Index faceid, short u, short v,
|
|
|
|
unsigned short depth, bool nonquad,
|
|
|
|
unsigned short boundary, unsigned short transition,
|
|
|
|
bool regular) {
|
|
|
|
field0 = pack(faceid, 28, 0) |
|
|
|
|
pack(transition, 4, 28);
|
|
|
|
|
|
|
|
field1 = pack(u, 10, 22) |
|
|
|
|
pack(v, 10, 12) |
|
|
|
|
pack(boundary, 4, 8) |
|
|
|
|
pack(regular, 1, 5) |
|
|
|
|
pack(nonquad, 1, 4) |
|
|
|
|
pack(depth, 4, 0);
|
|
|
|
}
|
2016-08-24 20:31:21 +00:00
|
|
|
|
2016-09-29 16:38:32 +00:00
|
|
|
inline float
|
|
|
|
PatchParam::GetParamFraction( ) const {
|
2018-07-28 21:43:32 +00:00
|
|
|
return 1.0f / (float)(1 << (GetDepth() - NonQuadRoot()));
|
2013-06-11 22:59:43 +00:00
|
|
|
}
|
|
|
|
|
2018-07-28 21:43:32 +00:00
|
|
|
template <typename REAL>
|
2013-06-13 20:58:23 +00:00
|
|
|
inline void
|
2018-07-28 21:43:32 +00:00
|
|
|
PatchParam::Normalize( REAL & u, REAL & v ) const {
|
2013-06-05 18:44:30 +00:00
|
|
|
|
2018-07-28 21:43:32 +00:00
|
|
|
REAL fracInv = (REAL)(1.0f / GetParamFraction());
|
2013-06-05 18:44:30 +00:00
|
|
|
|
2018-07-28 21:43:32 +00:00
|
|
|
u = u * fracInv - (REAL)GetU();
|
|
|
|
v = v * fracInv - (REAL)GetV();
|
2013-06-05 18:44:30 +00:00
|
|
|
}
|
|
|
|
|
2018-07-28 21:43:32 +00:00
|
|
|
template <typename REAL>
|
2016-08-24 20:31:21 +00:00
|
|
|
inline void
|
2018-07-28 21:43:32 +00:00
|
|
|
PatchParam::Unnormalize( REAL & u, REAL & v ) const {
|
2016-08-24 20:31:21 +00:00
|
|
|
|
2018-07-28 21:43:32 +00:00
|
|
|
REAL frac = (REAL)GetParamFraction();
|
2016-08-24 20:31:21 +00:00
|
|
|
|
2018-07-28 21:43:32 +00:00
|
|
|
u = (u + (REAL)GetU()) * frac;
|
|
|
|
v = (v + (REAL)GetV()) * frac;
|
2016-08-24 20:31:21 +00:00
|
|
|
}
|
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
} // end namespace Far
|
|
|
|
|
2013-05-17 16:47:44 +00:00
|
|
|
} // end namespace OPENSUBDIV_VERSION
|
|
|
|
using namespace OPENSUBDIV_VERSION;
|
|
|
|
|
|
|
|
} // end namespace OpenSubdiv
|
|
|
|
|
2015-05-19 18:22:37 +00:00
|
|
|
#endif /* OPENSUBDIV3_FAR_PATCH_PARAM */
|