OpenSubdiv
Toggle main menu visibility
Loading...
Searching...
No Matches
patchMap.h
Go to the documentation of this file.
1
//
2
// Copyright 2013 Pixar
3
//
4
// Licensed under the terms set forth in the LICENSE.txt file available at
5
// https://opensubdiv.org/license.
6
//
7
8
#ifndef OPENSUBDIV3_FAR_PATCH_MAP_H
9
#define OPENSUBDIV3_FAR_PATCH_MAP_H
10
11
#include "../version.h"
12
13
#include "
../far/patchTable.h
"
14
15
#include <cassert>
16
17
namespace
OpenSubdiv
{
18
namespace
OPENSUBDIV_VERSION
{
19
20
namespace
Far
{
21
32
class
PatchMap
{
33
public
:
34
35
typedef
PatchTable::PatchHandle
Handle
;
36
41
PatchMap
(
PatchTable
const
& patchTable );
42
57
Handle
const
*
FindPatch
(
int
patchFaceId,
double
u,
double
v )
const
;
58
59
private
:
60
void
initializeHandles(
PatchTable
const
& patchTable);
61
void
initializeQuadtree(
PatchTable
const
& patchTable);
62
63
private
:
64
// Quadtree node with 4 children, tree is just a vector of nodes
65
struct
QuadNode {
66
QuadNode() { std::memset(
this
, 0,
sizeof
(QuadNode)); }
67
68
struct
Child
{
69
unsigned
int
isSet
: 1;
// true if the child has been set
70
unsigned
int
isLeaf
: 1;
// true if the child is a QuadNode
71
unsigned
int
index
: 30;
// child index (either QuadNode or Handle)
72
};
73
74
// sets all the children to point to the patch of given index
75
void
SetChildren(
int
index);
76
77
// sets the child in "quadrant" to point to the node or patch of the given index
78
void
SetChild(
int
quadrant,
int
index,
bool
isLeaf);
79
80
Child
children[4];
81
};
82
typedef
std::vector<QuadNode> QuadTree;
83
84
// Internal methods supporting quadtree construction and queries
85
void
assignRootNode(QuadNode * node,
int
index);
86
QuadNode * assignLeafOrChildNode(QuadNode * node,
bool
isLeaf,
int
quad,
int
index);
87
88
template
<
class
T>
89
static
int
transformUVToQuadQuadrant(T
const
& median, T & u, T & v);
90
template
<
class
T>
91
static
int
transformUVToTriQuadrant(T
const
& median, T & u, T & v,
bool
& rotated);
92
93
private
:
94
bool
_patchesAreTriangular;
// tri and quad assembly and search requirements differ
95
96
int
_minPatchFace;
// minimum patch face index supported by the map
97
int
_maxPatchFace;
// maximum patch face index supported by the map
98
int
_maxDepth;
// maximum depth of a patch in the tree
99
100
std::vector<Handle> _handles;
// all the patches in the PatchTable
101
std::vector<QuadNode> _quadtree;
// quadtree nodes
102
};
103
104
//
105
// Given a median value for both U and V, these methods transform a (u,v) pair
106
// into the quadrant that contains them and returns the quadrant index.
107
//
108
// Quadrant indexing for tri and quad patches -- consistent with PatchParam's
109
// usage of UV bits:
110
//
111
// (0,1) o-----o-----o (1,1) (0,1) o (1,0) o-----o-----o (0,0)
112
// | | | |\ \ 1 |\ 0 |
113
// | 2 | 3 | | \ \ | \ |
114
// | | | | 2 \ \| 3 \|
115
// o-----o-----o o-----o o-----o
116
// | | | |\ 3 |\ \ 2 |
117
// | 0 | 1 | | \ | \ \ |
118
// | | | | 0 \| 1 \ \|
119
// (0,0) o-----o-----o (1,0) (0,0) o-----o-----o (1,0) o (0,1)
120
//
121
// The triangular case also takes and returns/affects the rotation of the
122
// quadrant being searched and identified (quadrant 3 imparts a rotation).
123
//
124
template
<
class
T>
125
inline
int
126
PatchMap::transformUVToQuadQuadrant(T
const
& median, T & u, T & v) {
127
128
int
uHalf = (u >= median);
129
if
(uHalf) u -= median;
130
131
int
vHalf = (v >= median);
132
if
(vHalf) v -= median;
133
134
return
(vHalf << 1) | uHalf;
135
}
136
137
template
<
class
T>
138
int
inline
139
PatchMap::transformUVToTriQuadrant(T
const
& median, T & u, T & v,
bool
& rotated) {
140
141
if
(!rotated) {
142
if
(u >= median) {
143
u -= median;
144
return
1;
145
}
146
if
(v >= median) {
147
v -= median;
148
return
2;
149
}
150
if
((u + v) >= median) {
151
rotated =
true
;
152
return
3;
153
}
154
return
0;
155
}
else
{
156
if
(u < median) {
157
v -= median;
158
return
1;
159
}
160
if
(v < median) {
161
u -= median;
162
return
2;
163
}
164
u -= median;
165
v -= median;
166
if
((u + v) < median) {
167
rotated =
false
;
168
return
3;
169
}
170
return
0;
171
}
172
}
173
175
inline
PatchMap::Handle
const
*
176
PatchMap::FindPatch
(
int
faceid,
double
u,
double
v )
const
{
177
178
//
179
// Reject patch faces not supported by this map, or those corresponding
180
// to holes or otherwise unassigned (the root node for a patch will
181
// have all or no quadrants set):
182
//
183
if
((faceid < _minPatchFace) || (faceid > _maxPatchFace))
return
0;
184
185
QuadNode
const
* node = &_quadtree[faceid - _minPatchFace];
186
187
if
(!node->children[0].
isSet
)
return
0;
188
189
//
190
// Search the tree for the sub-patch containing the given (u,v)
191
//
192
assert( (u>=0.0) && (u<=1.0) && (v>=0.0) && (v<=1.0) );
193
194
double
median = 0.5;
195
bool
triRotated =
false
;
196
197
for
(
int
depth = 0; depth <= _maxDepth; ++depth, median *= 0.5) {
198
199
int
quadrant = _patchesAreTriangular
200
? transformUVToTriQuadrant(median, u, v, triRotated)
201
: transformUVToQuadQuadrant(median, u, v);
202
203
// holes should have been rejected at the root node of the face
204
assert(node->children[quadrant].
isSet
);
205
206
if
(node->children[quadrant].
isLeaf
) {
207
return
&_handles[node->children[quadrant].
index
];
208
}
else
{
209
node = &_quadtree[node->children[quadrant].
index
];
210
}
211
}
212
assert(0);
213
return
0;
214
}
215
216
}
// end namespace Far
217
218
}
// end namespace OPENSUBDIV_VERSION
219
using namespace
OPENSUBDIV_VERSION
;
220
221
}
// end namespace OpenSubdiv
222
223
#endif
/* OPENSUBDIV3_FAR_PATCH_PARAM */
patchTable.h
OpenSubdiv
Definition
limits.h:15
OpenSubdiv::OPENSUBDIV_VERSION
Definition
limits.h:16
OpenSubdiv::OPENSUBDIV_VERSION::Far
Definition
refinerSurfaceFactory.h:19
OpenSubdiv::OPENSUBDIV_VERSION::Far::PatchMap::PatchMap
PatchMap(PatchTable const &patchTable)
Constructor.
OpenSubdiv::OPENSUBDIV_VERSION::Far::PatchMap::FindPatch
Handle const * FindPatch(int patchFaceId, double u, double v) const
Returns a handle to the sub-patch of the face at the given (u,v). Note that the patch face ID corresp...
Definition
patchMap.h:176
OpenSubdiv::OPENSUBDIV_VERSION::Far::PatchMap::Handle
PatchTable::PatchHandle Handle
Definition
patchMap.h:35
OpenSubdiv::OPENSUBDIV_VERSION::Far::PatchMap::QuadNode::Child
Definition
patchMap.h:68
OpenSubdiv::OPENSUBDIV_VERSION::Far::PatchMap::QuadNode::Child::isLeaf
unsigned int isLeaf
Definition
patchMap.h:70
OpenSubdiv::OPENSUBDIV_VERSION::Far::PatchMap::QuadNode::Child::index
unsigned int index
Definition
patchMap.h:71
OpenSubdiv::OPENSUBDIV_VERSION::Far::PatchMap::QuadNode::Child::isSet
unsigned int isSet
Definition
patchMap.h:69
OpenSubdiv::OPENSUBDIV_VERSION::Far::PatchTable
Container for arrays of parametric patches.
Definition
patchTable.h:38
OpenSubdiv::OPENSUBDIV_VERSION::Far::PatchTable::PatchHandle
Handle that can be used as unique patch identifier within PatchTable.
Definition
patchTable.h:43
opensubdiv
far
patchMap.h
Generated on
for OpenSubdiv by
1.18.0