31 #ifdef WITH_OPENSUBDIV
35 # include <opensubdiv/far/patchMap.h>
36 # include <opensubdiv/far/patchTableFactory.h>
37 # include <opensubdiv/far/primvarRefiner.h>
38 # include <opensubdiv/far/topologyRefinerFactory.h>
43 namespace OPENSUBDIV_VERSION {
46 bool TopologyRefinerFactory<ccl::Mesh>::resizeComponentTopology(TopologyRefiner &refiner,
49 setNumBaseVertices(refiner,
mesh.get_verts().
size());
53 setNumBaseFaceVertices(refiner, i,
mesh.get_subd_num_corners()[i]);
60 bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTopology(TopologyRefiner &refiner,
63 const ccl::array<int> &subd_face_corners =
mesh.get_subd_face_corners();
64 const ccl::array<int> &subd_start_corner =
mesh.get_subd_start_corner();
65 const ccl::array<int> &subd_num_corners =
mesh.get_subd_num_corners();
68 IndexArray face_verts = getBaseFaceVertices(refiner, i);
70 int start_corner = subd_start_corner[i];
71 int *
corner = &subd_face_corners[start_corner];
73 for (
int j = 0; j < subd_num_corners[i]; j++,
corner++) {
82 bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTags(TopologyRefiner &refiner,
85 size_t num_creases =
mesh.get_subd_creases_weight().
size();
87 for (
int i = 0; i < num_creases; i++) {
89 Index edge = findBaseEdge(refiner, crease.v[0], crease.v[1]);
92 setBaseEdgeSharpness(refiner, edge, crease.crease * 10.0f);
96 for (
int i = 0; i <
mesh.get_verts().
size(); i++) {
97 ConstIndexArray vert_edges = getBaseVertexEdges(refiner, i);
99 if (vert_edges.size() == 2) {
100 float sharpness = refiner.getLevel(0).getEdgeSharpness(vert_edges[0]);
101 sharpness =
ccl::min(sharpness, refiner.getLevel(0).getEdgeSharpness(vert_edges[1]));
103 setBaseVertexSharpness(refiner, i, sharpness);
111 bool TopologyRefinerFactory<ccl::Mesh>::assignFaceVaryingTopology(TopologyRefiner & ,
118 void TopologyRefinerFactory<ccl::Mesh>::reportInvalidTopology(TopologyError ,
133 template<
typename T>
struct OsdValue {
140 void Clear(
void * = 0)
142 memset(&value, 0,
sizeof(
T));
145 void AddWithWeight(OsdValue<T>
const &src,
float weight)
147 value += src.value * weight;
151 template<>
void OsdValue<uchar4>::AddWithWeight(OsdValue<uchar4>
const &src,
float weight)
153 for (
int i = 0; i < 4; i++) {
154 value[i] += (
uchar)(src.value[i] * weight);
162 vector<OsdValue<float3>>
verts;
163 Far::TopologyRefiner *refiner;
164 Far::PatchTable *patch_table;
165 Far::PatchMap *patch_map;
179 void build_from_mesh(
Mesh *mesh_)
184 Sdc::SchemeType
type = Sdc::SCHEME_CATMARK;
187 options.SetVtxBoundaryInterpolation(Sdc::Options::VTX_BOUNDARY_EDGE_ONLY);
190 refiner = Far::TopologyRefinerFactory<Mesh>::Create(
194 int max_isolation = calculate_max_isolation();
195 refiner->RefineAdaptive(Far::TopologyRefiner::AdaptiveOptions(max_isolation));
198 Far::PatchTableFactory::Options patch_options;
199 patch_options.endCapType = Far::PatchTableFactory::Options::ENDCAP_GREGORY_BASIS;
201 patch_table = Far::PatchTableFactory::Create(*refiner, patch_options);
204 int num_refiner_verts = refiner->GetNumVerticesTotal();
205 int num_local_points = patch_table->GetNumLocalPoints();
207 verts.resize(num_refiner_verts + num_local_points);
208 for (
int i = 0; i <
mesh->get_verts().
size(); i++) {
212 OsdValue<float3> *src =
verts.data();
213 for (
int i = 0; i < refiner->GetMaxLevel(); i++) {
214 OsdValue<float3> *dest = src + refiner->GetLevel(i).GetNumVertices();
215 Far::PrimvarRefiner(*refiner).Interpolate(i + 1, src, dest);
219 if (num_local_points) {
220 patch_table->ComputeLocalPointValues(&
verts[0], &
verts[num_refiner_verts]);
224 patch_map =
new Far::PatchMap(*patch_table);
227 void subdivide_attribute(
Attribute &attr)
229 Far::PrimvarRefiner primvar_refiner(*refiner);
232 int num_refiner_verts = refiner->GetNumVerticesTotal();
233 int num_local_points = patch_table->GetNumLocalPoints();
235 attr.
resize(num_refiner_verts + num_local_points);
238 char *src = attr.
buffer.data();
240 for (
int i = 0; i < refiner->GetMaxLevel(); i++) {
241 char *dest = src + refiner->GetLevel(i).GetNumVertices() * attr.
data_sizeof();
244 primvar_refiner.Interpolate(i + 1, (OsdValue<float> *)src, (OsdValue<float> *&)dest);
247 primvar_refiner.Interpolate(i + 1, (OsdValue<float2> *)src, (OsdValue<float2> *&)dest);
250 primvar_refiner.Interpolate(i + 1, (OsdValue<float4> *)src, (OsdValue<float4> *&)dest);
256 if (num_local_points) {
258 patch_table->ComputeLocalPointValues(
259 (OsdValue<float> *)&attr.
buffer[0],
263 patch_table->ComputeLocalPointValues(
264 (OsdValue<float2> *)&attr.
buffer[0],
268 patch_table->ComputeLocalPointValues(
269 (OsdValue<float4> *)&attr.
buffer[0],
279 int calculate_max_isolation()
282 const Far::TopologyLevel &level = refiner->GetLevel(0);
287 float longest_edge = 0.0f;
289 for (
size_t i = 0; i < level.GetNumEdges(); i++) {
290 Far::ConstIndexArray
verts = level.GetEdgeVertices(i);
304 edge_len =
len(
a - b);
307 longest_edge =
max(longest_edge, edge_len);
311 int isolation = (int)(log2f(
max(longest_edge / subd_params->
dicing_rate, 1.0f)) + 1.0f);
313 return min(isolation, 10);
316 friend struct OsdPatch;
322 struct OsdPatch :
Patch {
328 OsdPatch(OsdData *
data) : osd_data(
data)
337 float p_weights[20], du_weights[20], dv_weights[20];
338 osd_data->patch_table->EvaluateBasis(*handle, u,
v, p_weights, du_weights, dv_weights);
340 Far::ConstIndexArray cv = osd_data->patch_table->GetPatchVertices(*handle);
348 for (
int i = 0; i < cv.size(); i++) {
349 float3 p = osd_data->verts[cv[i]].value;
352 *
P += p * p_weights[i];
353 du += p * du_weights[i];
354 dv += p * dv_weights[i];
378 #ifdef WITH_OPENSUBDIV
380 bool need_packed_patch_table =
false;
382 if (subdivision_type == SUBDIVISION_CATMULL_CLARK) {
383 if (get_num_subd_faces()) {
384 osd_data.build_from_mesh(
this);
393 subdivision_type = SUBDIVISION_LINEAR;
396 foreach (
Attribute &attr, subd_attributes.attributes) {
401 int num_faces = get_num_subd_faces();
408 for (
int f = 0; f < num_faces; f++) {
420 #ifdef WITH_OPENSUBDIV
421 if (subdivision_type == SUBDIVISION_CATMULL_CLARK) {
422 vector<OsdPatch> osd_patches(num_patches, &osd_data);
423 OsdPatch *patch = osd_patches.data();
425 for (
int f = 0; f < num_faces; f++) {
430 patch->from_ngon =
false;
431 patch->shader = face.
shader;
437 patch->from_ngon =
true;
438 patch->shader = face.
shader;
445 split->split_patches(osd_patches.data(),
sizeof(OsdPatch));
450 vector<LinearQuadPatch> linear_patches(num_patches);
453 for (
int f = 0; f < num_faces; f++) {
463 for (
int i = 0; i < 4; i++) {
468 for (
int i = 0; i < 4; i++) {
474 for (
int i = 0; i < 4; i++) {
479 swap(hull[2], hull[3]);
511 hull[3] = center_vert;
513 hull[1] = (hull[1] + hull[0]) * 0.5;
514 hull[2] = (hull[2] + hull[0]) * 0.5;
530 for (
int i = 0; i < 4; i++) {
545 foreach (
Attribute &attr, subd_attributes.attributes) {
546 #ifdef WITH_OPENSUBDIV
552 else if (get_num_subd_faces()) {
553 osd_data.subdivide_attribute(attr);
555 need_packed_patch_table =
true;
567 for (
int f = 0; f < num_faces; f++) {
590 for (
int f = 0; f < num_faces; f++) {
609 for (
int f = 0; f < num_faces; f++) {
619 for (
int i = 0; i < 4; i++) {
625 for (
int i = 0; i < 4; i++) {
638 #ifdef WITH_OPENSUBDIV
640 if (need_packed_patch_table) {
643 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
CCL_NAMESPACE_BEGIN struct Options options
static float normals[][3]
CCL_NAMESPACE_BEGIN struct PatchHandle PatchHandle
#define CCL_NAMESPACE_END
#define make_float3(x, y, z)
@ ATTR_ELEMENT_CORNER_BYTE
@ ATTR_ELEMENT_VERTEX_MOTION
void split(const std::string &s, const char delim, std::vector< std::string > &tokens)
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)
__forceinline avxf cross(const avxf &a, const avxf &b)
ccl_device_inline int mod(int x, int m)
ccl_device_inline float3 zero_float3()
ccl_device_inline float4 zero_float4()
CCL_NAMESPACE_BEGIN static constexpr OIIO_NAMESPACE_USING TypeDesc TypeFloat2(TypeDesc::FLOAT, TypeDesc::VEC2)