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;
119 if (attr_vN ==
nullptr) {
127 const ustring name = ustring((attr_uv) ? attr_uv->
name.string() +
".tangent" :
138 float *tangent_sign =
nullptr;
140 const ustring name_sign = ustring((attr_uv) ?
141 attr_uv->
name.string() +
".tangent_sign" :
169 const size_t num_verts,
170 const size_t num_steps,
175 const size_t max_step = num_steps - 1;
176 const size_t step =
min((
size_t)(time * max_step), max_step - 1);
177 const float t = time * max_step -
step;
184 r_verts[0] = (1.0f - t) * curr_verts[0] + t * next_verts[0];
185 r_verts[1] = (1.0f - t) * curr_verts[1] + t * next_verts[1];
186 r_verts[2] = (1.0f - t) * curr_verts[2] + t * next_verts[2];
191 const size_t num_verts,
192 const size_t num_steps,
196 const size_t center_step = ((num_steps - 1) / 2);
197 if (
step == center_step) {
205 if (
step > center_step) {
208 const size_t offset =
step * num_verts;
209 r_verts[0] = vert_steps[offset +
v[0]];
210 r_verts[1] = vert_steps[offset +
v[1]];
211 r_verts[2] = vert_steps[offset +
v[2]];
221 const float normlen =
len(
norm);
222 if (normlen == 0.0f) {
225 return norm / normlen;
255 static NodeEnum subdivision_type_enum;
261 static NodeEnum subdivision_boundary_interpolation_enum;
264 subdivision_boundary_interpolation_enum.
insert(
"edge_and_corner",
267 "Subdivision Boundary Interpolation",
268 subdivision_boundary_interpolation_enum,
271 static NodeEnum subdivision_fvar_interpolation_enum;
274 subdivision_fvar_interpolation_enum.
insert(
"corners_plus1",
276 subdivision_fvar_interpolation_enum.
insert(
"corners_plus2",
281 "Subdivision Face-Varying Interpolation",
282 subdivision_fvar_interpolation_enum,
287 subd_vert_creases_weight,
"Subdivision Vertex Crease Weights",
array<float>());
298 SOCKET_FLOAT(subd_dicing_rate,
"Subdivision Dicing Rate", 1.0f)
299 SOCKET_INT(subd_max_level,
"Max Subdivision Level", 1);
308 (verts_is_modified() || subd_dicing_rate_is_modified() ||
309 subd_objecttoworld_is_modified() || subd_max_level_is_modified());
320 num_subd_added_verts = 0;
330 verts.resize(numverts);
331 triangles.resize(numtris * 3);
332 shader.resize(numtris);
333 smooth.resize(numtris);
341 verts.reserve(numverts);
342 triangles.reserve(numtris * 3);
343 shader.reserve(numtris);
344 smooth.reserve(numtris);
351 subd_start_corner.resize(numfaces);
352 subd_num_corners.resize(numfaces);
353 subd_shader.resize(numfaces);
354 subd_smooth.resize(numfaces);
355 subd_ptex_offset.resize(numfaces);
356 subd_face_corners.resize(numcorners);
357 num_subd_faces = numfaces;
364 subd_start_corner.reserve(numfaces);
365 subd_num_corners.reserve(numfaces);
366 subd_shader.reserve(numfaces);
367 subd_smooth.reserve(numfaces);
368 subd_ptex_offset.reserve(numfaces);
369 subd_face_corners.reserve(numcorners);
370 num_subd_faces = numfaces;
377 subd_creases_edge.reserve(num_creases * 2);
378 subd_creases_weight.reserve(num_creases);
385 num_subd_added_verts = 0;
399 subd_start_corner.clear();
400 subd_num_corners.clear();
403 subd_ptex_offset.clear();
404 subd_face_corners.clear();
406 subd_creases_edge.clear();
407 subd_creases_weight.clear();
419 clear(preserve_shaders,
false);
424 verts.push_back_reserved(
P);
425 tag_verts_modified();
431 tag_verts_modified();
436 triangles.push_back_reserved(v0);
437 triangles.push_back_reserved(v1);
438 triangles.push_back_reserved(
v2);
439 shader.push_back_reserved(shader_);
440 smooth.push_back_reserved(smooth_);
442 tag_triangles_modified();
443 tag_shader_modified();
444 tag_smooth_modified();
448 const int num_corners,
452 const int start_corner = subd_face_corners.size();
454 for (
int i = 0;
i < num_corners;
i++) {
455 subd_face_corners.push_back_reserved(corners[
i]);
461 if (subd_shader.size()) {
466 subd_start_corner.push_back_reserved(start_corner);
467 subd_num_corners.push_back_reserved(num_corners);
468 subd_shader.push_back_reserved(shader_);
469 subd_smooth.push_back_reserved(smooth_);
470 subd_ptex_offset.push_back_reserved(ptex_offset);
472 tag_subd_face_corners_modified();
473 tag_subd_start_corner_modified();
474 tag_subd_num_corners_modified();
475 tag_subd_shader_modified();
476 tag_subd_smooth_modified();
477 tag_subd_ptex_offset_modified();
493 subd_creases_edge.push_back_slow(v0);
494 subd_creases_edge.push_back_slow(v1);
495 subd_creases_weight.push_back_slow(weight);
497 tag_subd_creases_edge_modified();
498 tag_subd_creases_edge_modified();
499 tag_subd_creases_weight_modified();
504 subd_vert_creases.push_back_slow(
v);
505 subd_vert_creases_weight.push_back_slow(weight);
507 tag_subd_vert_creases_modified();
508 tag_subd_vert_creases_weight_modified();
520 const size_t numverts =
verts.size();
554 const size_t verts_size =
verts.size();
556 if (verts_size > 0) {
557 for (
size_t i = 0;
i < verts_size;
i++) {
562 if (use_motion_blur && attr) {
563 const size_t steps_size =
verts.size() * (motion_steps - 1);
566 for (
size_t i = 0;
i < steps_size;
i++) {
567 bnds.
grow(vert_steps[
i]);
575 for (
size_t i = 0;
i < verts_size;
i++) {
579 if (use_motion_blur && attr) {
580 const size_t steps_size =
verts.size() * (motion_steps - 1);
583 for (
size_t i = 0;
i < steps_size;
i++) {
603 const size_t num_verts =
verts.size();
604 for (
size_t i = 0;
i < num_verts;
i++) {
608 tag_verts_modified();
610 if (apply_to_motion) {
614 const size_t steps_size =
verts.size() * (motion_steps - 1);
617 for (
size_t i = 0;
i < steps_size;
i++) {
626 const size_t steps_size =
verts.size() * (motion_steps - 1);
629 for (
size_t i = 0;
i < steps_size;
i++) {
639 const size_t verts_size =
verts.size();
653 for (
size_t i = 0;
i < triangles_size;
i++) {
655 for (
size_t j = 0; j < 3; j++) {
661 for (
size_t i = 0;
i < verts_size;
i++) {
666 for (
size_t i = 0;
i < verts_size;
i++) {
687 for (
size_t i = 0;
i < triangles_size;
i++) {
690 for (
size_t j = 0; j < 3; j++) {
696 for (
size_t i = 0;
i < verts_size;
i++) {
701 for (
size_t i = 0;
i < verts_size;
i++) {
722 const size_t corner = subd_face_corners[face.
start_corner + j];
728 for (
size_t i = 0;
i < verts_size;
i++) {
733 for (
size_t i = 0;
i < verts_size;
i++) {
778 const size_t verts_size =
verts.size();
781 for (
size_t i = 0;
i < verts_size; ++
i) {
795 ccl::set<ustring> uv_maps;
809 const ustring tangent_name = ustring(attr.
name.string() +
".tangent");
820 uint last_shader = -1;
821 bool last_smooth =
false;
824 const int *shader_ptr = shader.data();
825 const bool *smooth_ptr = smooth.data();
827 for (
size_t i = 0;
i < triangles_size;
i++) {
828 const int new_shader = shader_ptr ? shader_ptr[
i] : INT_MAX;
829 const bool new_smooth = smooth_ptr ? smooth_ptr[
i] :
false;
831 if (new_shader != last_shader || last_smooth != new_smooth) {
832 last_shader = new_shader;
833 last_smooth = new_smooth;
834 Shader *shader = (last_shader < used_shaders.size()) ?
835 static_cast<Shader *
>(used_shaders[last_shader]) :
837 shader_id = scene->
shader_manager->get_shader_id(shader, last_smooth);
840 tri_shader[
i] = shader_id;
847 if (attr_vN ==
nullptr) {
856 const size_t verts_size =
verts.size();
859 for (
size_t i = 0;
i < verts_size;
i++) {
864 for (
size_t i = 0;
i < verts_size;
i++) {
872 const size_t verts_size =
verts.size();
874 const int *p_tris = triangles.data();
876 for (
size_t i = 0;
i < verts_size;
i++) {
879 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 has_true_displacement() 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
VecBase< float, D > normalize(VecOp< float, D >) RET
#define assert(assertion)
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
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)
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)
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 update_tangents(Scene *scene)
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 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)