22#include "util/color.h"
42 const char *layer_name,
53 if (layer_name ==
NULL) {
64 Attribute *attr_uv = attributes.find(ustring(layer_name));
65 if (attr_uv !=
NULL) {
73 if constexpr (is_subd) {
74 return mesh->get_num_subd_faces();
77 return mesh->num_triangles();
83 if constexpr (is_subd) {
84 return mesh->get_subd_num_corners()[face_num];
93 if constexpr (is_subd) {
98 return face_num * 3 + vert_num;
105 if constexpr (is_subd) {
106 return mesh->get_subd_face_corners()[corner];
109 return mesh->get_triangles()[corner];
124 const int corner_index =
CornerIndex(face_num, vert_num);
129 const int vertex_index =
VertexIndex(face_num, vert_num);
144 const int vertex_index =
VertexIndex(face_num, vert_num);
148 vN = face.normal(mesh);
152 if (mesh->get_smooth()[face_num]) {
153 const int vertex_index =
VertexIndex(face_num, vert_num);
166 const int corner_index =
CornerIndex(face_num, vert_num);
167 tangent[corner_index] =
make_float3(T.x, T.y, T.z);
169 tangent_sign[corner_index] = orientation ? 1.0f : -1.0f;
187 const ::Mesh &b_mesh,
const char *layer_name,
Mesh *mesh,
bool need_sign,
bool active_render)
190 const bool is_subd = mesh->get_num_subd_faces();
194 if (layer_name !=
NULL) {
195 name = ustring((
string(layer_name) +
".tangent").c_str());
198 name = ustring(
"orco.tangent");
208 float *tangent_sign =
NULL;
212 if (layer_name !=
NULL) {
213 name_sign = ustring((
string(layer_name) +
".tangent_sign").c_str());
216 name_sign = ustring(
"orco.tangent_sign");
243 const float motion_scale)
245 const int numverts = mesh->get_verts().size();
248 mesh->set_motion_steps(3);
251 float3 *
P = &mesh->get_verts()[0];
259 float motion_times[2] = {-1.0f, 1.0f};
260 for (
int step = 0; step < 2; step++) {
261 const float relative_time = motion_times[step] * 0.5f * motion_scale;
264 for (
int i = 0; i < numverts; i++) {
265 mP[i] =
P[i] +
make_float3(b_attr[i][0], b_attr[i][1], b_attr[i][2]) * relative_time;
272 const ::Mesh &b_mesh,
273 const bool subdivision,
274 const bool need_motion,
275 const float motion_scale)
280 corner_tris = b_mesh.corner_tris();
281 tri_faces = b_mesh.corner_tri_faces();
284 AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
285 static const ustring u_velocity(
"velocity");
289 const ustring name{std::string_view(iter.
name)};
290 const bool is_render_color = name == default_color_name;
292 if (need_motion && name == u_velocity) {
298 if (!(mesh->need_attribute(scene, name) ||
303 if (attributes.find(name)) {
321 if (is_render_color) {
329 data[i] =
make_uchar4(src[i][0], src[i][1], src[i][2], src[i][3]);
336 src[tri[0]][0], src[tri[0]][1], src[tri[0]][2], src[tri[0]][3]);
338 src[tri[1]][0], src[tri[1]][1], src[tri[1]][2], src[tri[1]][3]);
340 src[tri[2]][0], src[tri[2]][1], src[tri[2]][2], src[tri[2]][3]);
363 using BlenderT = decltype(dummy);
364 using Converter = typename ccl::AttributeConverter<BlenderT>;
365 using CyclesT = typename Converter::CyclesT;
366 if constexpr (!std::is_void_v<CyclesT>) {
367 Attribute *attr = attributes.add(name, Converter::type_desc, element);
368 if (is_render_color) {
369 attr->std = ATTR_STD_VERTEX_COLOR;
372 CyclesT *data = reinterpret_cast<CyclesT *>(attr->data());
374 const blender::VArraySpan src = b_attr.varray.typed<BlenderT>();
375 switch (b_attr.domain) {
376 case blender::bke::AttrDomain::Corner: {
378 for (const int i : src.index_range()) {
379 data[i] = Converter::convert(src[i]);
383 for (const int i : corner_tris.index_range()) {
384 const blender::int3 &tri = corner_tris[i];
385 data[i * 3 + 0] = Converter::convert(src[tri[0]]);
386 data[i * 3 + 1] = Converter::convert(src[tri[1]]);
387 data[i * 3 + 2] = Converter::convert(src[tri[2]]);
392 case blender::bke::AttrDomain::Point: {
393 for (const int i : src.index_range()) {
394 data[i] = Converter::convert(src[i]);
398 case blender::bke::AttrDomain::Face: {
400 for (const int i : src.index_range()) {
401 data[i] = Converter::convert(src[i]);
405 for (const int i : corner_tris.index_range()) {
406 data[i] = Converter::convert(src[tri_faces[i]]);
423 set<ustring> uv_names;
426 if (!blender::bke::attribute_name_is_anonymous(iter.name)) {
427 uv_names.emplace(std::string_view(iter.name));
437 const ::Mesh &b_mesh,
438 const set<ustring> &blender_uv_names)
443 if (!blender_uv_names.empty()) {
444 for (
const ustring &uv_name : blender_uv_names) {
445 const bool active_render = uv_name == render_name;
448 ustring tangent_name = ustring((
string(uv_name) +
".tangent").c_str());
451 const bool need_uv = mesh->need_attribute(scene, uv_name) ||
452 mesh->need_attribute(scene, uv_std);
454 const bool need_tangent = mesh->need_attribute(scene, tangent_name) ||
455 (active_render && mesh->need_attribute(scene, tangent_std));
462 if (need_uv || need_tangent) {
464 uv_attr = mesh->attributes.
add(uv_std, uv_name);
475 fdata[i * 3 + 0] =
make_float2(b_uv_map[tri[0]][0], b_uv_map[tri[0]][1]);
476 fdata[i * 3 + 1] =
make_float2(b_uv_map[tri[1]][0], b_uv_map[tri[1]][1]);
477 fdata[i * 3 + 2] =
make_float2(b_uv_map[tri[2]][0], b_uv_map[tri[2]][1]);
484 ustring sign_name = ustring((
string(uv_name) +
".tangent_sign").c_str());
485 bool need_sign = (mesh->need_attribute(scene, sign_name) ||
486 mesh->need_attribute(scene, sign_std));
490 if (!need_uv && uv_attr !=
NULL) {
491 mesh->attributes.remove(uv_attr);
506 const ::Mesh &b_mesh,
508 const set<ustring> &blender_uv_names)
511 if (faces.is_empty()) {
515 if (!blender_uv_names.empty()) {
517 const ustring render_name(
519 for (
const ustring &uv_name : blender_uv_names) {
520 const bool active_render = uv_name == render_name;
523 ustring tangent_name = ustring((
string(uv_name) +
".tangent").c_str());
526 const bool need_uv = mesh->need_attribute(scene, uv_name) ||
527 mesh->need_attribute(scene, uv_std);
529 const bool need_tangent = mesh->need_attribute(scene, tangent_name) ||
530 (active_render && mesh->need_attribute(scene, tangent_std));
535 if (need_uv || need_tangent) {
537 uv_attr = mesh->subd_attributes.
add(uv_std, uv_name);
551 for (
const int i : faces.index_range()) {
553 for (
const int corner : face) {
554 *(fdata++) =
make_float2(b_uv_map[corner][0], b_uv_map[corner][1]);
562 ustring sign_name = ustring((
string(uv_name) +
".tangent_sign").c_str());
563 bool need_sign = (mesh->need_attribute(scene, sign_name) ||
564 mesh->need_attribute(scene, sign_std));
568 if (!need_uv && uv_attr !=
NULL) {
569 mesh->subd_attributes.remove(uv_attr);
589 bool operator()(
const int &vert_idx_a,
const int &vert_idx_b)
593 if (vert_a == vert_b) {
595 return vert_idx_a > vert_idx_b;
597 const float x1 = vert_a.
x + vert_a.
y + vert_a.
z;
598 const float x2 = vert_b.
x + vert_b.
y + vert_b.
z;
612 const int num_verts = positions.
size();
613 if (positions.is_empty()) {
621 for (
int vert_index = 0; vert_index < num_verts; ++vert_index) {
622 sorted_vert_indeices[vert_index] = vert_index;
625 sort(sorted_vert_indeices.begin(), sorted_vert_indeices.end(), compare);
630 for (
int sorted_vert_index = 0; sorted_vert_index < num_verts; ++sorted_vert_index) {
631 const int vert_index = sorted_vert_indeices[sorted_vert_index];
632 const float3 &vert_co = mesh->get_verts()[vert_index];
634 for (
int other_sorted_vert_index = sorted_vert_index + 1; other_sorted_vert_index < num_verts;
635 ++other_sorted_vert_index)
637 const int other_vert_index = sorted_vert_indeices[other_sorted_vert_index];
638 const float3 &other_vert_co = mesh->get_verts()[other_vert_index];
640 if ((other_vert_co.
x + other_vert_co.
y + other_vert_co.
z) -
641 (vert_co.
x + vert_co.
y + vert_co.
z) >
647 if (
len_squared(other_vert_co - vert_co) < FLT_EPSILON) {
649 vert_orig_index[vert_index] = other_vert_index;
654 vert_orig_index[vert_index] = vert_index;
658 for (
int vert_index = 0; vert_index < num_verts; ++vert_index) {
659 int orig_index = vert_orig_index[vert_index];
660 while (orig_index != vert_orig_index[orig_index]) {
661 orig_index = vert_orig_index[orig_index];
663 vert_orig_index[vert_index] = orig_index;
671 for (
int vert_index = 0; vert_index < num_verts; ++vert_index) {
672 const float *b_vert_normal = b_vert_normals[vert_index];
673 const int orig_index = vert_orig_index[vert_index];
674 vert_normal[orig_index] +=
make_float3(b_vert_normal[0], b_vert_normal[1], b_vert_normal[2]);
679 for (
int vert_index = 0; vert_index < num_verts; ++vert_index) {
680 const int orig_index = vert_orig_index[vert_index];
681 vert_normal[vert_index] =
normalize(vert_normal[orig_index]);
688 memset(&counter[0], 0,
sizeof(
int) * counter.size());
690 for (
const int i : edges.index_range()) {
692 const int v0 = vert_orig_index[b_edge[0]];
693 const int v1 = vert_orig_index[b_edge[1]];
694 if (visited_edges.
exists(v0, v1)) {
697 visited_edges.
insert(v0, v1);
701 edge_accum[v0] += edge;
702 edge_accum[v1] += -edge;
706 for (
int vert_index = 0; vert_index < num_verts; ++vert_index) {
707 const int orig_index = vert_orig_index[vert_index];
708 if (orig_index != vert_index) {
712 if (counter[vert_index] > 0) {
713 const float3 normal = vert_normal[vert_index];
714 const float angle =
safe_acosf(
dot(normal, edge_accum[vert_index] / counter[vert_index]));
715 raw_data[vert_index] = angle * M_1_PI_F;
718 raw_data[vert_index] = 0.0f;
722 AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
725 memcpy(data, &raw_data[0],
sizeof(
float) * raw_data.size());
726 memset(&counter[0], 0,
sizeof(
int) * counter.size());
727 visited_edges.
clear();
728 for (
const int i : edges.index_range()) {
730 const int v0 = vert_orig_index[b_edge[0]];
731 const int v1 = vert_orig_index[b_edge[1]];
732 if (visited_edges.
exists(v0, v1)) {
735 visited_edges.
insert(v0, v1);
736 data[v0] += raw_data[v1];
737 data[v1] += raw_data[v0];
741 for (
int vert_index = 0; vert_index < num_verts; ++vert_index) {
742 data[vert_index] /= counter[vert_index] + 1;
745 for (
int vert_index = 0; vert_index < num_verts; ++vert_index) {
746 const int orig_index = vert_orig_index[vert_index];
747 data[vert_index] = data[orig_index];
763 const ::Mesh &b_mesh,
770 if (b_mesh.verts_num == 0) {
779 for (
const int i : edges.index_range()) {
780 vertices_sets.
join(edges[i][0], edges[i][1]);
783 AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
785 float *data = attribute->data_float();
791 const int vert = corner_verts[corner_tris[i][0]];
798 if (!faces.is_empty()) {
799 for (
const int i : faces.index_range()) {
800 const int vert = corner_verts[faces[i].start()];
811 const ::Mesh &b_mesh,
813 const bool need_motion,
814 const float motion_scale,
815 const bool subdivision =
false,
816 const bool subdivide_uvs =
true)
823 int numfaces = (!subdivision) ? b_mesh.corner_tris().size() : faces.size();
829 if (faces.is_empty()) {
838 if (use_corner_normals) {
839 corner_normals = b_mesh.corner_normals();
849 for (
const int i : faces.index_range()) {
850 numngons += (faces[i].size() == 4) ? 0 : 1;
856 mesh->resize_subd_faces(numfaces, numngons, corner_verts.
size());
858 mesh->resize_mesh(positions.size(), numtris);
861 for (
const int i : positions.index_range()) {
865 AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
869 if (subdivision || !(use_corner_normals && !corner_normals.is_empty())) {
872 N[i] =
make_float3(vert_normals[i][0], vert_normals[i][1], vert_normals[i][2]);
879 const bool need_default_tangent = (subdivision ==
false) && (blender_uv_names.empty()) &&
882 const float(*orco)[3] =
static_cast<const float(*)[3]
>(
890 float texspace_location[3], texspace_size[3];
897 for (
const int i : positions.index_range()) {
903 value = positions[i];
905 generated[i] =
make_float3(value[0], value[1], value[2]) * size - loc;
909 auto clamp_material_index = [&](
const int material_index) ->
int {
910 return clamp(material_index, 0, used_shaders.
size() - 1);
915 int *triangles = mesh->get_triangles().data();
916 bool *smooth = mesh->get_smooth().data();
917 int *shader = mesh->get_shader().data();
922 triangles[i * 3 + 0] = corner_verts[tri[0]];
923 triangles[i * 3 + 1] = corner_verts[tri[1]];
924 triangles[i * 3 + 2] = corner_verts[tri[2]];
930 shader[i] = clamp_material_index(material_indices[tri_faces[i]]);
934 std::fill(shader, shader + numtris, 0);
937 if (!sharp_faces.is_empty() && !(use_corner_normals && !corner_normals.is_empty())) {
940 smooth[i] = !sharp_faces[tri_faces[i]];
948 if (use_corner_normals && !corner_normals.is_empty()) {
951 for (
int i = 0; i < 3; i++) {
952 const int corner = tri[i];
953 const int vert = corner_verts[corner];
954 const float *normal = corner_normals[corner];
960 mesh->tag_triangles_modified();
961 mesh->tag_shader_modified();
962 mesh->tag_smooth_modified();
965 int *subd_start_corner = mesh->get_subd_start_corner().data();
966 int *subd_num_corners = mesh->get_subd_num_corners().data();
967 int *subd_shader = mesh->get_subd_shader().data();
968 bool *subd_smooth = mesh->get_subd_smooth().data();
969 int *subd_ptex_offset = mesh->get_subd_ptex_offset().data();
970 int *subd_face_corners = mesh->get_subd_face_corners().data();
972 if (!sharp_faces.is_empty() && !use_corner_normals) {
973 for (
int i = 0; i < numfaces; i++) {
974 subd_smooth[i] = !sharp_faces[i];
978 std::fill(subd_smooth, subd_smooth + numfaces,
true);
982 for (
int i = 0; i < numfaces; i++) {
983 subd_shader[i] = clamp_material_index(material_indices[i]);
987 std::fill(subd_shader, subd_shader + numfaces, 0);
990 std::copy(corner_verts.
data(), corner_verts.
data() + corner_verts.
size(), subd_face_corners);
994 for (
const int i : faces.index_range()) {
997 subd_start_corner[i] = face.
start();
998 subd_num_corners[i] = face.size();
999 subd_ptex_offset[i] = ptex_offset;
1000 const int num_ptex = (face.size() == 4) ? 1 : face.size();
1001 ptex_offset += num_ptex;
1004 mesh->tag_subd_face_corners_modified();
1005 mesh->tag_subd_start_corner_modified();
1006 mesh->tag_subd_num_corners_modified();
1007 mesh->tag_subd_shader_modified();
1008 mesh->tag_subd_smooth_modified();
1009 mesh->tag_subd_ptex_offset_modified();
1045 const ::Mesh &b_mesh,
1047 const bool need_motion,
1048 const float motion_scale,
1050 int max_subdivisions)
1054 BL::SubsurfModifier subsurf_mod(b_ob.modifiers[b_ob.modifiers.length() - 1]);
1055 bool subdivide_uvs = subsurf_mod.uv_smooth() != BL::SubsurfModifier::uv_smooth_NONE;
1057 create_mesh(scene, mesh, b_mesh, used_shaders, need_motion, motion_scale,
true, subdivide_uvs);
1062 size_t num_creases = 0;
1064 if (creases[i] != 0.0f) {
1069 mesh->reserve_subd_creases(num_creases);
1072 for (
const int i : edges.index_range()) {
1073 const float crease = creases[i];
1074 if (crease != 0.0f) {
1076 mesh->add_edge_crease(b_edge[0], b_edge[1], crease);
1085 if (vert_creases[i] != 0.0f) {
1086 mesh->add_vertex_crease(i, vert_creases[i]);
1093 float subd_dicing_rate =
max(0.1f,
RNA_float_get(&cobj,
"dicing_rate") * dicing_rate);
1095 mesh->set_subd_dicing_rate(subd_dicing_rate);
1096 mesh->set_subd_max_level(max_subdivisions);
1097 mesh->set_subd_objecttoworld(
get_transform(b_ob.matrix_world()));
1102void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph,
BObjectInfo &b_ob_info,
Mesh *mesh)
1109 new_mesh.set_used_shaders(used_shaders);
1111 if (view_layer.use_surfaces) {
1114 if (!scene->bake_manager->get_baking()) {
1115 new_mesh.set_subdivision_type(
1122 b_data, b_ob_info, b_depsgraph, need_undeformed, new_mesh.get_subdivision_type());
1127 const float motion_scale = (need_motion) ?
1128 scene->motion_shutter_time() /
1129 (b_scene.render().fps() / b_scene.render().fps_base()) :
1137 *
static_cast<const ::
Mesh *
>(b_mesh.ptr.data),
1138 new_mesh.get_used_shaders(),
1147 *
static_cast<const ::
Mesh *
>(b_mesh.ptr.data),
1148 new_mesh.get_used_shaders(),
1160 mesh->clear_non_sockets();
1162 for (
const SocketType &socket : new_mesh.type->inputs) {
1164 if (socket.name ==
"use_motion_blur" || socket.name ==
"motion_steps" ||
1165 socket.name ==
"used_shaders")
1169 mesh->set_value(socket, new_mesh, socket);
1172 mesh->attributes.update(std::move(new_mesh.
attributes));
1178 bool rebuild = (mesh->triangles_is_modified()) || (mesh->subd_num_corners_is_modified()) ||
1179 (mesh->subd_shader_is_modified()) || (mesh->subd_smooth_is_modified()) ||
1180 (mesh->subd_ptex_offset_is_modified()) ||
1181 (mesh->subd_start_corner_is_modified()) ||
1182 (mesh->subd_face_corners_is_modified());
1184 mesh->tag_update(scene, rebuild);
1187void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
1193 size_t numverts = mesh->get_verts().size();
1194 if (numverts == 0) {
1201 if (ccl::BKE_object_is_deform_modified(b_ob_info, b_scene, preview)) {
1206 const std::string ob_name = b_ob_info.
real_object.name();
1210 const ::Mesh &b_mesh = *
static_cast<const ::
Mesh *
>(b_mesh_rna.ptr.data);
1211 const int b_verts_num = b_mesh.
verts_num;
1213 if (positions.is_empty()) {
1223 bool new_attribute =
false;
1231 new_attribute =
true;
1240 for (
int i = 0; i < std::min<size_t>(b_verts_num, numverts); i++) {
1241 mP[i] =
make_float3(positions[i][0], positions[i][1], positions[i][2]);
1245 for (
int i = 0; i < std::min<size_t>(b_verts_num, numverts); i++) {
1246 mN[i] =
make_float3(b_vert_normals[i][0], b_vert_normals[i][1], b_vert_normals[i][2]);
1249 if (new_attribute) {
1251 if (b_verts_num != numverts ||
1252 memcmp(mP, &mesh->get_verts()[0],
sizeof(
float3) * numverts) == 0)
1255 if (b_verts_num != numverts) {
1256 VLOG_WARNING <<
"Topology differs, disabling motion blur for object " << ob_name;
1259 VLOG_DEBUG <<
"No actual deformation motion for object " << ob_name;
1266 else if (motion_step > 0) {
1267 VLOG_DEBUG <<
"Filling deformation motion for object " << ob_name;
1270 float3 *
P = &mesh->get_verts()[0];
1272 for (
int step = 0;
step < motion_step;
step++) {
1281 if (b_verts_num != numverts) {
1282 VLOG_WARNING <<
"Topology differs, discarding motion blur for object " << ob_name
1283 <<
" at time " << motion_step;
1284 memcpy(mP, &mesh->get_verts()[0],
sizeof(
float3) * numverts);
1296 mesh->copy_center_to_motion_step(motion_step);
const char * BKE_id_attributes_default_color_name(const struct ID *id)
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
const char * CustomData_get_render_layer_name(const CustomData *data, eCustomDataType type)
void BKE_mesh_texspace_get(Mesh *mesh, float r_texspace_location[3], float r_texspace_size[3])
MINLINE float safe_acosf(float a)
bool map_to_sphere(float *r_u, float *r_v, float x, float y, float z)
MINLINE void madd_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3])
constexpr PointerRNA PointerRNA_NULL
static void attr_create_generic(Scene *scene, Mesh *mesh, const ::Mesh &b_mesh, const bool subdivision, const bool need_motion, const float motion_scale)
static void attr_create_random_per_island(Scene *scene, Mesh *mesh, const ::Mesh &b_mesh, bool subdivision)
static void mikk_compute_tangents(const ::Mesh &b_mesh, const char *layer_name, Mesh *mesh, bool need_sign, bool active_render)
static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, const ::Mesh &b_mesh, bool subdivide_uvs, const set< ustring > &blender_uv_names)
static void create_subd_mesh(Scene *scene, Mesh *mesh, BObjectInfo &b_ob_info, const ::Mesh &b_mesh, const array< Node * > &used_shaders, const bool need_motion, const float motion_scale, float dicing_rate, int max_subdivisions)
static void create_mesh(Scene *scene, Mesh *mesh, const ::Mesh &b_mesh, const array< Node * > &used_shaders, const bool need_motion, const float motion_scale, const bool subdivision=false, const bool subdivide_uvs=true)
static void attr_create_motion_from_velocity(Mesh *mesh, const blender::Span< blender::float3 > b_attr, const float motion_scale)
static void attr_create_pointiness(Mesh *mesh, const blender::Span< blender::float3 > positions, const blender::Span< blender::float3 > b_vert_normals, const blender::Span< blender::int2 > edges, bool subdivision)
static void attr_create_uv_map(Scene *scene, Mesh *mesh, const ::Mesh &b_mesh, const set< ustring > &blender_uv_names)
static set< ustring > get_blender_uv_names(const ::Mesh &b_mesh)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static DBVT_INLINE btDbvtNode * sort(btDbvtNode *n, btDbvtNode *&r)
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
list< Attribute > attributes
Transform * data_transform()
void join(size_t x, size_t y)
void insert(int v0, int v1)
bool exists(int v0, int v1)
bool need_attribute(Scene *scene, AttributeStandard std)
VertexAverageComparator(const array< float3 > &verts)
bool operator()(const int &vert_idx_a, const int &vert_idx_b)
const array< float3 > & verts_
const CPPType & type() const
VArray< T > typed() const
constexpr int64_t start() const
constexpr const T * data() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
void foreach_attribute(const FunctionRef< void(const AttributeIter &)> fn) const
GAttributeReader lookup(const StringRef attribute_id) const
eCustomDataType data_type
GAttributeReader get() const
additional_info("compositor_sum_squared_difference_float_shared") .push_constant(Type output_img float dot(value.rgb, luminance_coefficients)") .define("LOAD(value)"
static void mesh_texture_space(const ::Mesh &b_mesh, float3 &loc, float3 &size)
static void free_object_to_mesh(BL::BlendData &, BObjectInfo &b_ob_info, BL::Mesh &mesh)
static BL::Mesh object_to_mesh(BL::BlendData &, BObjectInfo &b_ob_info, BL::Depsgraph &, bool, Mesh::SubdivisionType subdivision_type)
static bool object_need_motion_attribute(BObjectInfo &b_ob_info, Scene *scene)
static Mesh::SubdivisionType object_subdivision_type(BL::Object &b_ob, bool preview, bool experimental)
static Transform get_transform(const BL::Array< float, 16 > &array)
#define CCL_NAMESPACE_END
draw_view in_light_buf[] float
ccl_device_inline float hash_uint_to_float(uint kx)
@ ATTR_STD_GENERATED_TRANSFORM
@ ATTR_STD_MOTION_VERTEX_NORMAL
@ ATTR_STD_MOTION_VERTEX_POSITION
@ ATTR_STD_UV_TANGENT_SIGN
@ ATTR_STD_RANDOM_PER_ISLAND
@ ATTR_ELEMENT_CORNER_BYTE
ccl_device_inline float len_squared(const float2 a)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
void convert_to_static_type(const CPPType &cpp_type, const Func &func)
T step(const T &edge, const T &value)
static constexpr TypeDesc TypeRGBA(TypeDesc::FLOAT, TypeDesc::VEC4, TypeDesc::COLOR)
CCL_NAMESPACE_BEGIN static OIIO_NAMESPACE_USING constexpr TypeDesc TypeFloat2(TypeDesc::FLOAT, TypeDesc::VEC2)
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
float RNA_float_get(PointerRNA *ptr, const char *name)
float3 compute_normal(const float3 *verts) const
size_t get_num_subd_faces() const
AttributeSet subd_attributes
@ SUBDIVISION_CATMULL_CLARK
mikk::float3 GetPosition(const int face_num, const int vert_num)
int GetNumVerticesOfFace(const int face_num)
void SetTangentSpace(const int face_num, const int vert_num, mikk::float3 T, bool orientation)
MikkMeshWrapper(const ::Mesh &b_mesh, const char *layer_name, const Mesh *mesh, float3 *tangent, float *tangent_sign)
mikk::float3 GetNormal(const int face_num, const int vert_num)
mikk::float3 GetTexCoord(const int face_num, const int vert_num)
int CornerIndex(const int face_num, const int vert_num)
int VertexIndex(const int face_num, const int vert_num)
ccl_device_inline int clamp(int a, int mn, int mx)