41 return mesh->num_triangles();
51 return face_num * 3 + vert_num;
57 return mesh->get_triangles()[corner];
71 const int corner_index =
CornerIndex(face_num, vert_num);
72 const float2 tfuv =
uv[corner_index];
84 if (
mesh->get_smooth()[face_num]) {
85 const int vertex_index =
VertexIndex(face_num, vert_num);
97 const int corner_index =
CornerIndex(face_num, vert_num);
100 tangent_sign[corner_index] = orientation ? 1.0f : -1.0f;
106 return uv !=
nullptr;
120 const bool need_sign,
123 const char *tangent_postfix,
124 const char *tangent_sign_postfix)
130 if (attr_vN ==
nullptr) {
138 const ustring
name = ustring((attr_uv) ? attr_uv->
name.string() + tangent_postfix :
142 attr = attributes.
add(tangent_std,
name);
149 float *tangent_sign =
nullptr;
151 const ustring name_sign = ustring((attr_uv) ? attr_uv->
name.string() + tangent_sign_postfix :
155 attr_sign = attributes.
add(tangent_sign_std, name_sign);
179 const size_t num_verts,
180 const size_t num_steps,
185 const size_t max_step = num_steps - 1;
186 const size_t step =
min((
size_t)(time * max_step), max_step - 1);
187 const float t = time * max_step -
step;
194 r_verts[0] = (1.0f - t) * curr_verts[0] + t * next_verts[0];
195 r_verts[1] = (1.0f - t) * curr_verts[1] + t * next_verts[1];
196 r_verts[2] = (1.0f - t) * curr_verts[2] + t * next_verts[2];
201 const size_t num_verts,
202 const size_t num_steps,
206 const size_t center_step = ((num_steps - 1) / 2);
207 if (
step == center_step) {
215 if (
step > center_step) {
218 const size_t offset =
step * num_verts;
219 r_verts[0] = vert_steps[offset +
v[0]];
220 r_verts[1] = vert_steps[offset +
v[1]];
221 r_verts[2] = vert_steps[offset +
v[2]];
231 const float normlen =
len(
norm);
232 if (normlen == 0.0f) {
235 return norm / normlen;
265 static NodeEnum subdivision_type_enum;
271 static NodeEnum subdivision_boundary_interpolation_enum;
274 subdivision_boundary_interpolation_enum.
insert(
"edge_and_corner",
277 "Subdivision Boundary Interpolation",
278 subdivision_boundary_interpolation_enum,
281 static NodeEnum subdivision_fvar_interpolation_enum;
284 subdivision_fvar_interpolation_enum.
insert(
"corners_plus1",
286 subdivision_fvar_interpolation_enum.
insert(
"corners_plus2",
291 "Subdivision Face-Varying Interpolation",
292 subdivision_fvar_interpolation_enum,
297 subd_vert_creases_weight,
"Subdivision Vertex Crease Weights",
array<float>());
308 static NodeEnum subd_adaptive_space_enum;
313 "Subdivision Adaptive Space",
314 subd_adaptive_space_enum,
316 SOCKET_FLOAT(subd_dicing_rate,
"Subdivision Dicing Rate", 1.0f)
317 SOCKET_INT(subd_max_level,
"Max Subdivision Level", 1);
326 (verts_is_modified() || subd_dicing_rate_is_modified() ||
327 subd_adaptive_space_is_modified() || subd_objecttoworld_is_modified() ||
328 subd_max_level_is_modified());
339 num_subd_added_verts = 0;
349 verts.resize(numverts);
350 triangles.resize(numtris * 3);
351 shader.resize(numtris);
352 smooth.resize(numtris);
360 verts.reserve(numverts);
361 triangles.reserve(numtris * 3);
362 shader.reserve(numtris);
363 smooth.reserve(numtris);
370 subd_start_corner.resize(numfaces);
371 subd_num_corners.resize(numfaces);
372 subd_shader.resize(numfaces);
373 subd_smooth.resize(numfaces);
374 subd_ptex_offset.resize(numfaces);
375 subd_face_corners.resize(numcorners);
376 num_subd_faces = numfaces;
383 subd_start_corner.reserve(numfaces);
384 subd_num_corners.reserve(numfaces);
385 subd_shader.reserve(numfaces);
386 subd_smooth.reserve(numfaces);
387 subd_ptex_offset.reserve(numfaces);
388 subd_face_corners.reserve(numcorners);
389 num_subd_faces = numfaces;
396 subd_creases_edge.reserve(num_creases * 2);
397 subd_creases_weight.reserve(num_creases);
404 num_subd_added_verts = 0;
418 subd_start_corner.clear();
419 subd_num_corners.clear();
422 subd_ptex_offset.clear();
423 subd_face_corners.clear();
425 subd_creases_edge.clear();
426 subd_creases_weight.clear();
438 clear(preserve_shaders,
false);
443 verts.push_back_reserved(
P);
444 tag_verts_modified();
450 tag_verts_modified();
455 triangles.push_back_reserved(v0);
456 triangles.push_back_reserved(v1);
457 triangles.push_back_reserved(
v2);
458 shader.push_back_reserved(shader_);
459 smooth.push_back_reserved(smooth_);
461 tag_triangles_modified();
462 tag_shader_modified();
463 tag_smooth_modified();
467 const int num_corners,
471 const int start_corner = subd_face_corners.size();
473 for (
int i = 0;
i < num_corners;
i++) {
474 subd_face_corners.push_back_reserved(corners[
i]);
480 if (subd_shader.size()) {
485 subd_start_corner.push_back_reserved(start_corner);
486 subd_num_corners.push_back_reserved(num_corners);
487 subd_shader.push_back_reserved(shader_);
488 subd_smooth.push_back_reserved(smooth_);
489 subd_ptex_offset.push_back_reserved(ptex_offset);
491 tag_subd_face_corners_modified();
492 tag_subd_start_corner_modified();
493 tag_subd_num_corners_modified();
494 tag_subd_shader_modified();
495 tag_subd_smooth_modified();
496 tag_subd_ptex_offset_modified();
512 subd_creases_edge.push_back_slow(v0);
513 subd_creases_edge.push_back_slow(v1);
514 subd_creases_weight.push_back_slow(weight);
516 tag_subd_creases_edge_modified();
517 tag_subd_creases_edge_modified();
518 tag_subd_creases_weight_modified();
523 subd_vert_creases.push_back_slow(
v);
524 subd_vert_creases_weight.push_back_slow(weight);
526 tag_subd_vert_creases_modified();
527 tag_subd_vert_creases_weight_modified();
539 const size_t numverts =
verts.size();
573 const size_t verts_size =
verts.size();
575 if (verts_size > 0) {
576 for (
size_t i = 0;
i < verts_size;
i++) {
581 if (use_motion_blur && attr) {
582 const size_t steps_size =
verts.size() * (motion_steps - 1);
585 for (
size_t i = 0;
i < steps_size;
i++) {
586 bnds.
grow(vert_steps[
i]);
594 for (
size_t i = 0;
i < verts_size;
i++) {
598 if (use_motion_blur && attr) {
599 const size_t steps_size =
verts.size() * (motion_steps - 1);
602 for (
size_t i = 0;
i < steps_size;
i++) {
622 const size_t num_verts =
verts.size();
623 for (
size_t i = 0;
i < num_verts;
i++) {
627 tag_verts_modified();
629 if (apply_to_motion) {
633 const size_t steps_size =
verts.size() * (motion_steps - 1);
636 for (
size_t i = 0;
i < steps_size;
i++) {
645 const size_t steps_size =
verts.size() * (motion_steps - 1);
648 for (
size_t i = 0;
i < steps_size;
i++) {
658 const size_t verts_size =
verts.size();
672 for (
size_t i = 0;
i < triangles_size;
i++) {
674 for (
size_t j = 0; j < 3; j++) {
680 for (
size_t i = 0;
i < verts_size;
i++) {
685 for (
size_t i = 0;
i < verts_size;
i++) {
706 for (
size_t i = 0;
i < triangles_size;
i++) {
709 for (
size_t j = 0; j < 3; j++) {
715 for (
size_t i = 0;
i < verts_size;
i++) {
720 for (
size_t i = 0;
i < verts_size;
i++) {
741 const size_t corner = subd_face_corners[face.
start_corner + j];
747 for (
size_t i = 0;
i < verts_size;
i++) {
752 for (
size_t i = 0;
i < verts_size;
i++) {
795 const size_t verts_size =
verts.size();
798 for (
size_t i = 0;
i < verts_size; ++
i) {
812 ccl::set<ustring> uv_maps;
819 const char *tangent_postfix = (undisplaced) ?
".undisplaced_tangent" :
".tangent";
820 const char *tangent_sign_postfix = (undisplaced) ?
".undisplaced_tangent_sign" :
".tangent_sign";
832 tangent_sign_postfix);
841 const ustring tangent_name = ustring(attr.
name.string() + tangent_postfix);
842 const ustring tangent_sign_name = ustring(attr.
name.string() + tangent_sign_postfix);
853 tangent_sign_postfix);
861 uint last_shader = -1;
862 bool last_smooth =
false;
865 const int *shader_ptr = shader.data();
866 const bool *smooth_ptr = smooth.data();
868 for (
size_t i = 0;
i < triangles_size;
i++) {
869 const int new_shader = shader_ptr ? shader_ptr[
i] : INT_MAX;
870 const bool new_smooth = smooth_ptr ? smooth_ptr[
i] :
false;
872 if (new_shader != last_shader || last_smooth != new_smooth) {
873 last_shader = new_shader;
874 last_smooth = new_smooth;
875 Shader *shader = (last_shader < used_shaders.size()) ?
876 static_cast<Shader *
>(used_shaders[last_shader]) :
878 shader_id = scene->
shader_manager->get_shader_id(shader, last_smooth);
881 tri_shader[
i] = shader_id;
888 if (attr_vN ==
nullptr) {
897 const size_t verts_size =
verts.size();
900 for (
size_t i = 0;
i < verts_size;
i++) {
905 for (
size_t i = 0;
i < verts_size;
i++) {
913 const size_t verts_size =
verts.size();
915 const int *p_tris = triangles.data();
917 for (
size_t i = 0;
i < verts_size;
i++) {
920 for (
size_t i = 0;
i < triangles_size;
i++) {
bool map_to_sphere(float *r_u, float *r_v, float x, float y, float z)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
Attribute * find(ustring name) const
Attribute * add(ustring name, const TypeDesc type, AttributeElement element)
Transform transform_normal
int motion_step(const float time) const
bool need_attribute(Scene *scene, AttributeStandard std)
Geometry(const NodeType *node_type, const Type type)
bool transform_negative_scaled
virtual void clear(bool preserve_shaders=false)
#define CCL_NAMESPACE_END
#define assert(assertion)
VecBase< float, D > normalize(VecOp< float, D >) RET
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
ccl_gpu_kernel_postfix ccl_global KernelWorkTile * tiles
@ PRIMITIVE_MOTION_TRIANGLE
@ ATTR_STD_MOTION_VERTEX_NORMAL
@ ATTR_STD_POSITION_UNDISPLACED
@ ATTR_STD_MOTION_VERTEX_POSITION
@ ATTR_STD_NORMAL_UNDISPLACED
@ ATTR_STD_UV_TANGENT_SIGN
@ ATTR_STD_UV_TANGENT_SIGN_UNDISPLACED
@ ATTR_STD_UV_TANGENT_UNDISPLACED
ccl_device_inline bool isfinite_safe(const float f)
ccl_device_inline float2 safe_normalize(const float2 a)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
#define SOCKET_BOOLEAN_ARRAY(name, ui_name, default_value,...)
#define SOCKET_POINT_ARRAY(name, ui_name, default_value,...)
#define SOCKET_FLOAT(name, ui_name, default_value,...)
#define SOCKET_INT(name, ui_name, default_value,...)
#define SOCKET_FLOAT_ARRAY(name, ui_name, default_value,...)
#define SOCKET_TRANSFORM(name, ui_name, default_value,...)
#define SOCKET_INT_ARRAY(name, ui_name, default_value,...)
#define NODE_DEFINE(structname)
#define SOCKET_ENUM(name, ui_name, values, default_value,...)
static void mikk_compute_tangents(Attribute *attr_uv, Mesh *mesh, const bool need_sign, const AttributeStandard tangent_std, const AttributeStandard tangent_sign_std, const char *tangent_postfix, const char *tangent_sign_postfix)
void get_uv_tiles(Geometry *geom, AttributePrimitive prim, unordered_set< int > &tiles) const
static const char * standard_name(AttributeStandard std)
size_t buffer_size(Geometry *geom, AttributePrimitive prim) const
__forceinline bool valid() const
__forceinline void grow_safe(const float3 &pt)
__forceinline void grow(const float3 &pt)
int num_ptex_faces() const
float3 normal(const Mesh *mesh) const
bool valid(const float3 *verts) const
void bounds_grow(const float3 *verts, BoundBox &bounds) const
void motion_verts(const float3 *verts, const float3 *vert_steps, const size_t num_verts, const size_t num_steps, const float time, float3 r_verts[3]) const
float3 compute_normal(const float3 *verts) const
void verts_for_step(const float3 *verts, const float3 *vert_steps, const size_t num_verts, const size_t num_steps, const size_t step, float3 r_verts[3]) const
size_t get_num_subd_faces() const
void add_undisplaced(Scene *scene)
@ SUBDIVISION_ADAPTIVE_SPACE_OBJECT
@ SUBDIVISION_ADAPTIVE_SPACE_PIXEL
void add_triangle(const int v0, const int v1, const int v2, const int shader, bool smooth)
void reserve_subd_creases(const size_t num_creases)
void compute_bounds() override
void add_vertex_normals()
AttributeSet subd_attributes
void copy_center_to_motion_step(const int motion_step)
Mesh(const NodeType *node_type_, Type geom_type_)
void clear(bool preserve_shaders=false) override
void add_vertex_slow(const float3 P)
bool has_motion_blur() const override
void pack_verts(packed_float3 *tri_verts, packed_uint3 *tri_vindex)
@ SUBDIVISION_FVAR_LINEAR_NONE
@ SUBDIVISION_FVAR_LINEAR_CORNERS_PLUS2
@ SUBDIVISION_FVAR_LINEAR_CORNERS_ONLY
@ SUBDIVISION_FVAR_LINEAR_ALL
@ SUBDIVISION_FVAR_LINEAR_BOUNDARIES
@ SUBDIVISION_FVAR_LINEAR_CORNERS_PLUS1
void add_vertex_crease(const int v, const float weight)
SubdFace get_subd_face(const size_t index) const
void reserve_mesh(const int numverts, const int numtris)
@ SUBDIVISION_CATMULL_CLARK
void add_subd_face(const int *corners, const int num_corners, const int shader_, bool smooth_)
size_t num_triangles() const
void resize_subd_faces(const int numfaces, const int numcorners)
void pack_normals(packed_float3 *vnormal)
void add_vertex(const float3 P)
void get_uv_tiles(ustring map, unordered_set< int > &tiles) override
void resize_mesh(const int numverts, const int numtris)
void update_generated(Scene *scene)
Triangle get_triangle(const size_t i) const
void pack_shaders(Scene *scene, uint *shader)
PrimitiveType primitive_type() const override
void reserve_subd_faces(const int numfaces, const int numcorners)
void add_edge_crease(const int v0, const int v1, const float weight)
void update_tangents(Scene *scene, bool undisplaced)
void apply_transform(const Transform &tfm, const bool apply_to_motion) override
@ SUBDIVISION_BOUNDARY_EDGE_ONLY
@ SUBDIVISION_BOUNDARY_EDGE_AND_CORNER
@ SUBDIVISION_BOUNDARY_NONE
mikk::float3 GetNormal(const int face_num, const int vert_num)
MikkMeshWrapper(const Mesh *mesh, const float3 *normal, const float2 *uv, float3 *tangent, float *tangent_sign)
int VertexIndex(const int face_num, const int vert_num)
void SetTangentSpace(const int face_num, const int vert_num, mikk::float3 T, bool orientation)
int CornerIndex(const int face_num, const int vert_num)
int GetNumVerticesOfFace(const int)
mikk::float3 GetPosition(const int face_num, const int vert_num)
mikk::float3 GetTexCoord(const int face_num, const int vert_num)
void insert(const char *x, const int y)
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=nullptr)
unique_ptr< ShaderManager > shader_manager
ccl_device_inline packed_uint3 make_packed_uint3(const uint x, const uint y, uint z)