18 #ifdef WITH_OPENSUBDIV
22 # include <opensubdiv/far/patchMap.h>
23 # include <opensubdiv/far/patchTableFactory.h>
24 # include <opensubdiv/far/primvarRefiner.h>
25 # include <opensubdiv/far/topologyRefinerFactory.h>
30 namespace OPENSUBDIV_VERSION {
33 bool TopologyRefinerFactory<ccl::Mesh>::resizeComponentTopology(TopologyRefiner &refiner,
36 setNumBaseVertices(refiner,
mesh.get_verts().
size());
40 setNumBaseFaceVertices(refiner, i,
mesh.get_subd_num_corners()[i]);
47 bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTopology(TopologyRefiner &refiner,
50 const ccl::array<int> &subd_face_corners =
mesh.get_subd_face_corners();
51 const ccl::array<int> &subd_start_corner =
mesh.get_subd_start_corner();
52 const ccl::array<int> &subd_num_corners =
mesh.get_subd_num_corners();
55 IndexArray face_verts = getBaseFaceVertices(refiner, i);
57 int start_corner = subd_start_corner[i];
58 int *
corner = &subd_face_corners[start_corner];
60 for (
int j = 0; j < subd_num_corners[i]; j++,
corner++) {
69 bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTags(TopologyRefiner &refiner,
73 static constexpr
float CREASE_SCALE = 10.0f;
75 size_t num_creases =
mesh.get_subd_creases_weight().
size();
76 size_t num_vertex_creases =
mesh.get_subd_vert_creases().
size();
79 if (num_creases == 0 && num_vertex_creases == 0) {
83 for (
int i = 0; i < num_creases; i++) {
85 Index
edge = findBaseEdge(refiner, crease.v[0], crease.v[1]);
88 setBaseEdgeSharpness(refiner, edge, crease.crease * CREASE_SCALE);
92 std::map<int, float> vertex_creases;
94 for (
size_t i = 0; i < num_vertex_creases; ++i) {
95 const int vertex_idx =
mesh.get_subd_vert_creases()[i];
96 const float weight =
mesh.get_subd_vert_creases_weight()[i];
98 vertex_creases[vertex_idx] = weight * CREASE_SCALE;
101 for (
int i = 0; i <
mesh.get_verts().
size(); i++) {
102 float sharpness = 0.0f;
103 std::map<int, float>::const_iterator iter = vertex_creases.find(i);
105 if (iter != vertex_creases.end()) {
106 sharpness = iter->second;
109 ConstIndexArray vert_edges = getBaseVertexEdges(refiner, i);
111 if (vert_edges.size() == 2) {
112 const float sharpness0 = refiner.getLevel(0).getEdgeSharpness(vert_edges[0]);
113 const float sharpness1 = refiner.getLevel(0).getEdgeSharpness(vert_edges[1]);
115 sharpness +=
ccl::min(sharpness0, sharpness1);
116 sharpness =
ccl::min(sharpness, CREASE_SCALE);
119 if (sharpness != 0.0f) {
120 setBaseVertexSharpness(refiner, i, sharpness);
128 bool TopologyRefinerFactory<ccl::Mesh>::assignFaceVaryingTopology(TopologyRefiner & ,
135 void TopologyRefinerFactory<ccl::Mesh>::reportInvalidTopology(TopologyError ,
150 template<
typename T>
struct OsdValue {
157 void Clear(
void * = 0)
159 memset(&value, 0,
sizeof(
T));
162 void AddWithWeight(OsdValue<T>
const &
src,
float weight)
164 value +=
src.value * weight;
168 template<>
void OsdValue<uchar4>::AddWithWeight(OsdValue<uchar4>
const &
src,
float weight)
170 for (
int i = 0; i < 4; i++) {
171 value[i] += (
uchar)(
src.value[i] * weight);
179 vector<OsdValue<float3>>
verts;
180 Far::TopologyRefiner *refiner;
181 Far::PatchTable *patch_table;
182 Far::PatchMap *patch_map;
196 void build_from_mesh(
Mesh *mesh_)
201 Sdc::SchemeType
type = Sdc::SCHEME_CATMARK;
204 options.SetVtxBoundaryInterpolation(Sdc::Options::VTX_BOUNDARY_EDGE_ONLY);
207 refiner = Far::TopologyRefinerFactory<Mesh>::Create(
211 int max_isolation = calculate_max_isolation();
212 refiner->RefineAdaptive(Far::TopologyRefiner::AdaptiveOptions(max_isolation));
215 Far::PatchTableFactory::Options patch_options;
216 patch_options.endCapType = Far::PatchTableFactory::Options::ENDCAP_GREGORY_BASIS;
218 patch_table = Far::PatchTableFactory::Create(*refiner, patch_options);
221 int num_refiner_verts = refiner->GetNumVerticesTotal();
222 int num_local_points = patch_table->GetNumLocalPoints();
224 verts.resize(num_refiner_verts + num_local_points);
225 for (
int i = 0; i <
mesh->get_verts().
size(); i++) {
229 OsdValue<float3> *
src =
verts.data();
230 for (
int i = 0; i < refiner->GetMaxLevel(); i++) {
231 OsdValue<float3> *
dest =
src + refiner->GetLevel(i).GetNumVertices();
232 Far::PrimvarRefiner(*refiner).Interpolate(i + 1,
src,
dest);
236 if (num_local_points) {
237 patch_table->ComputeLocalPointValues(&
verts[0], &
verts[num_refiner_verts]);
241 patch_map =
new Far::PatchMap(*patch_table);
244 void subdivide_attribute(
Attribute &attr)
246 Far::PrimvarRefiner primvar_refiner(*refiner);
249 int num_refiner_verts = refiner->GetNumVerticesTotal();
250 int num_local_points = patch_table->GetNumLocalPoints();
252 attr.
resize(num_refiner_verts + num_local_points);
257 for (
int i = 0; i < refiner->GetMaxLevel(); i++) {
261 primvar_refiner.Interpolate(i + 1, (OsdValue<float> *)
src, (OsdValue<float> *&)
dest);
264 primvar_refiner.Interpolate(i + 1, (OsdValue<float2> *)
src, (OsdValue<float2> *&)
dest);
267 primvar_refiner.Interpolate(i + 1, (OsdValue<float4> *)
src, (OsdValue<float4> *&)
dest);
273 if (num_local_points) {
275 patch_table->ComputeLocalPointValues(
276 (OsdValue<float> *)&attr.
buffer[0],
280 patch_table->ComputeLocalPointValues(
281 (OsdValue<float2> *)&attr.
buffer[0],
285 patch_table->ComputeLocalPointValues(
286 (OsdValue<float4> *)&attr.
buffer[0],
296 int calculate_max_isolation()
299 const Far::TopologyLevel &level = refiner->GetLevel(0);
304 float longest_edge = 0.0f;
306 for (
size_t i = 0; i < level.GetNumEdges(); i++) {
307 Far::ConstIndexArray
verts = level.GetEdgeVertices(i);
321 edge_len =
len(
a -
b);
324 longest_edge =
max(longest_edge, edge_len);
328 int isolation = (int)(log2f(
max(longest_edge / subd_params->
dicing_rate, 1.0f)) + 1.0f);
330 return min(isolation, 10);
333 friend struct OsdPatch;
339 struct OsdPatch :
Patch {
345 OsdPatch(OsdData *
data) : osd_data(
data)
352 patch_index, (
double)u, (
double)
v);
355 float p_weights[20], du_weights[20], dv_weights[20];
356 osd_data->patch_table->EvaluateBasis(*handle, u,
v, p_weights, du_weights, dv_weights);
358 Far::ConstIndexArray cv = osd_data->patch_table->GetPatchVertices(*handle);
366 for (
int i = 0; i < cv.size(); i++) {
367 float3 p = osd_data->verts[cv[i]].value;
370 *
P += p * p_weights[i];
371 du += p * du_weights[i];
372 dv += p * dv_weights[i];
396 #ifdef WITH_OPENSUBDIV
398 bool need_packed_patch_table =
false;
400 if (subdivision_type == SUBDIVISION_CATMULL_CLARK) {
401 if (get_num_subd_faces()) {
402 osd_data.build_from_mesh(
this);
411 subdivision_type = SUBDIVISION_LINEAR;
414 foreach (
Attribute &attr, subd_attributes.attributes) {
419 int num_faces = get_num_subd_faces();
426 for (
int f = 0; f < num_faces; f++) {
438 #ifdef WITH_OPENSUBDIV
439 if (subdivision_type == SUBDIVISION_CATMULL_CLARK) {
440 vector<OsdPatch> osd_patches(num_patches, &osd_data);
441 OsdPatch *patch = osd_patches.data();
443 for (
int f = 0; f < num_faces; f++) {
448 patch->from_ngon =
false;
449 patch->shader = face.
shader;
455 patch->from_ngon =
true;
456 patch->shader = face.
shader;
463 split->split_patches(osd_patches.data(),
sizeof(OsdPatch));
468 vector<LinearQuadPatch> linear_patches(num_patches);
471 for (
int f = 0; f < num_faces; f++) {
481 for (
int i = 0; i < 4; i++) {
486 for (
int i = 0; i < 4; i++) {
492 for (
int i = 0; i < 4; i++) {
497 swap(hull[2], hull[3]);
529 hull[3] = center_vert;
531 hull[1] = (hull[1] + hull[0]) * 0.5;
532 hull[2] = (hull[2] + hull[0]) * 0.5;
548 for (
int i = 0; i < 4; i++) {
563 foreach (
Attribute &attr, subd_attributes.attributes) {
564 #ifdef WITH_OPENSUBDIV
570 else if (get_num_subd_faces()) {
571 osd_data.subdivide_attribute(attr);
573 need_packed_patch_table =
true;
585 for (
int f = 0; f < num_faces; f++) {
608 for (
int f = 0; f < num_faces; f++) {
627 for (
int f = 0; f < num_faces; f++) {
637 for (
int i = 0; i < 4; i++) {
643 for (
int i = 0; i < 4; i++) {
656 #ifdef WITH_OPENSUBDIV
658 if (need_packed_patch_table) {
661 patch_table->
pack(osd_data.patch_table);
typedef float(TangentPoint)[2]
NSNotificationCenter * center
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei stride
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static bool same_storage(TypeDesc a, TypeDesc b)
void add_with_weight(void *dst, void *src, float weight)
void resize(Geometry *geom, AttributePrimitive prim, bool reserve_only)
void zero_data(void *dst)
size_t data_sizeof() const
#define CCL_NAMESPACE_END
CCL_NAMESPACE_BEGIN struct Options options
SyclQueue void void * src
CCL_NAMESPACE_BEGIN struct PatchHandle PatchHandle
@ ATTR_ELEMENT_CORNER_BYTE
@ ATTR_ELEMENT_VERTEX_MOTION
ccl_device_inline float3 zero_float3()
ccl_device_inline float4 zero_float4()
void split(const std::string &s, const char delim, std::vector< std::string > &tokens)
vec_base< T, 3 > cross(const vec_base< T, 3 > &a, const vec_base< T, 3 > &b)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
MutableSpan< float3 > normals
CCL_NAMESPACE_BEGIN static constexpr OIIO_NAMESPACE_USING TypeDesc TypeFloat2(TypeDesc::FLOAT, TypeDesc::VEC2)
float world_to_raster_size(float3 P)
float3 normal(const Mesh *mesh) const
void tessellate(DiagSplit *split)
SubdParams * get_subd_params()
size_t get_num_subd_faces() const
SubdEdgeCrease get_subd_crease(size_t i) const
void pack(Far::PatchTable *patch_table, int offset=0)
ccl_device_inline int mod(int x, int m)