8 #include "util/color.h"
13 using namespace Alembic::AbcGeom;
17 static float3 make_float3_from_yup(
const V3f &
v)
23 static set<chrono_t> get_relevant_sample_times(AlembicProcedural *proc,
24 const TimeSampling &time_sampling,
37 if (proc->get_use_prefetch()) {
39 start_frame =
static_cast<double>(proc->get_start_frame());
40 end_frame =
static_cast<double>(proc->get_end_frame());
44 start_frame =
static_cast<double>(proc->get_frame());
45 end_frame = start_frame;
48 const double frame_rate =
static_cast<double>(proc->get_frame_rate());
49 const double start_time = start_frame / frame_rate;
50 const double end_time = (end_frame + 1) / frame_rate;
52 const size_t start_index = time_sampling.getFloorIndex(start_time,
num_samples).first;
53 const size_t end_index = time_sampling.getCeilIndex(end_time,
num_samples).first;
55 for (
size_t i = start_index; i < end_index; ++i) {
56 result.insert(time_sampling.getSampleTime(i));
65 template<
typename Params,
typename DataReadingFunc>
66 static void read_data_loop(AlembicProcedural *proc,
67 CachedData &cached_data,
69 DataReadingFunc &&func,
72 const std::set<chrono_t> times = get_relevant_sample_times(
75 cached_data.set_time_sampling(*
params.time_sampling);
77 for (chrono_t
time : times) {
90 static void compute_vertex_normals(CachedData &cache,
double current_time)
92 if (cache.vertices.size() == 0) {
96 CachedData::CachedAttribute &attr_normal = cache.add_attribute(
97 ustring(
"N"), cache.vertices.get_time_sampling());
100 attr_normal.type_desc = TypeNormal;
103 cache.vertices.data_for_time_no_check(current_time).get_data_or_null();
105 cache.triangles.data_for_time_no_check(current_time).get_data_or_null();
107 if (!vertices || !triangles) {
108 attr_normal.
data.add_no_data(current_time);
113 float3 *attr_ptr =
reinterpret_cast<float3 *
>(attr_data.data());
114 memset(attr_ptr, 0, vertices->
size() *
sizeof(
float3));
116 for (
size_t t = 0;
t < triangles->
size(); ++
t) {
117 const int3 tri_int3 = triangles->
data()[
t];
119 tri.
v[0] = tri_int3[0];
120 tri.v[1] = tri_int3[1];
121 tri.v[2] = tri_int3[2];
123 const float3 tri_N = tri.compute_normal(vertices->
data());
125 for (
int v = 0;
v < 3; ++
v) {
126 attr_ptr[tri_int3[
v]] += tri_N;
130 for (
size_t v = 0;
v < vertices->
size(); ++
v) {
134 attr_normal.data.add_data(attr_data, current_time);
137 static void add_normals(
const Int32ArraySamplePtr face_indices,
140 CachedData &cached_data)
143 case kFacevaryingScope: {
144 const ISampleSelector iss = ISampleSelector(
time);
145 const IN3fGeomParam::Sample
sample =
normals.getExpandedValue(iss);
151 CachedData::CachedAttribute &attr = cached_data.add_attribute(ustring(
normals.getName()),
156 cached_data.vertices.data_for_time_no_check(
time).get_data_or_null();
167 const int *face_indices_array = face_indices->get();
168 const N3fArraySamplePtr values =
sample.getVals();
170 for (
size_t i = 0; i < face_indices->size(); ++i) {
172 data_float3[
point_index] = make_float3_from_yup(values->get()[i]);
180 const ISampleSelector iss = ISampleSelector(
time);
181 const IN3fGeomParam::Sample
sample =
normals.getExpandedValue(iss);
187 CachedData::CachedAttribute &attr = cached_data.add_attribute(ustring(
normals.getName()),
192 cached_data.vertices.data_for_time_no_check(
time).get_data_or_null();
203 const Imath::V3f *values =
sample.getVals()->get();
205 for (
size_t i = 0; i < vertices->
size(); ++i) {
206 data_float3[i] = make_float3_from_yup(values[i]);
219 static void add_positions(
const P3fArraySamplePtr
positions,
double time, CachedData &cached_data)
228 for (
size_t i = 0; i <
positions->size(); i++) {
233 cached_data.vertices.add_data(vertices,
time);
236 static void add_triangles(
const Int32ArraySamplePtr face_counts,
237 const Int32ArraySamplePtr face_indices,
239 CachedData &cached_data,
242 if (!face_counts || !face_indices) {
246 const size_t num_faces = face_counts->size();
247 const int *face_counts_array = face_counts->get();
248 const int *face_indices_array = face_indices->get();
250 size_t num_triangles = 0;
251 for (
size_t i = 0; i < face_counts->size(); i++) {
252 num_triangles += face_counts_array[i] - 2;
259 triangles.
reserve(num_triangles);
260 uv_loops.
reserve(num_triangles * 3);
261 int index_offset = 0;
263 for (
size_t i = 0; i < num_faces; i++) {
264 int current_shader = 0;
266 if (!polygon_to_shader.
empty()) {
267 current_shader = polygon_to_shader[i];
270 for (
int j = 0; j < face_counts_array[i] - 2; j++) {
271 int v0 = face_indices_array[index_offset];
272 int v1 = face_indices_array[index_offset + j + 1];
273 int v2 = face_indices_array[index_offset + j + 2];
284 index_offset += face_counts_array[i];
287 cached_data.triangles.add_data(triangles,
time);
288 cached_data.uv_loops.add_data(uv_loops,
time);
289 cached_data.shader.add_data(shader,
time);
292 static array<int> compute_polygon_to_shader_map(
293 const Int32ArraySamplePtr &face_counts,
295 ISampleSelector sample_sel)
297 if (face_set_shader_index.empty()) {
305 if (face_counts->size() == 0) {
309 array<int> polygon_to_shader(face_counts->size());
311 for (
const FaceSetShaderIndexPair &pair : face_set_shader_index) {
312 const IFaceSet &face_set = pair.face_set;
313 const IFaceSetSchema face_schem = face_set.getSchema();
314 const IFaceSetSchema::Sample face_sample = face_schem.getValue(sample_sel);
315 const Int32ArraySamplePtr group_faces = face_sample.getFaces();
316 const size_t num_group_faces = group_faces->size();
318 for (
size_t l = 0;
l < num_group_faces;
l++) {
319 size_t pos = (*group_faces)[
l];
321 if (
pos >= polygon_to_shader.
size()) {
325 polygon_to_shader[
pos] = pair.shader_index;
329 return polygon_to_shader;
332 static void read_poly_mesh_geometry(CachedData &cached_data,
333 const PolyMeshSchemaData &
data,
336 const ISampleSelector iss = ISampleSelector(
time);
338 add_positions(
data.positions.getValue(iss),
time, cached_data);
340 const Int32ArraySamplePtr face_counts =
data.face_counts.getValue(iss);
341 const Int32ArraySamplePtr face_indices =
data.face_indices.getValue(iss);
344 if (
data.topology_variance != kHomogeneousTopology || cached_data.triangles.size() == 0) {
345 bool do_triangles =
true;
348 if (cached_data.triangles.size() > 0) {
351 if (key == cached_data.triangles.key1) {
352 do_triangles =
false;
355 cached_data.triangles.key1 = key;
359 const array<int> polygon_to_shader = compute_polygon_to_shader_map(
360 face_counts,
data.shader_face_sets, iss);
361 add_triangles(face_counts, face_indices,
time, cached_data, polygon_to_shader);
364 cached_data.triangles.reuse_data_for_last_time(
time);
365 cached_data.uv_loops.reuse_data_for_last_time(
time);
366 cached_data.shader.reuse_data_for_last_time(
time);
370 if (
data.topology_variance != kHomogeneousTopology && cached_data.triangles.size() == 1) {
371 cached_data.triangles.key1 = face_indices->getKey();
375 if (
data.normals.valid()) {
376 add_normals(face_indices,
data.normals,
time, cached_data);
379 compute_vertex_normals(cached_data,
time);
383 void read_geometry_data(AlembicProcedural *proc,
384 CachedData &cached_data,
385 const PolyMeshSchemaData &
data,
388 read_data_loop(proc, cached_data,
data, read_poly_mesh_geometry, progress);
393 static void add_subd_polygons(CachedData &cached_data,
const SubDSchemaData &
data, chrono_t
time)
395 const ISampleSelector iss = ISampleSelector(
time);
397 const Int32ArraySamplePtr face_counts =
data.face_counts.getValue(iss);
398 const Int32ArraySamplePtr face_indices =
data.face_indices.getValue(iss);
408 const size_t num_faces = face_counts->
size();
409 const int *face_counts_array = face_counts->get();
410 const int *face_indices_array = face_indices->get();
414 for (
size_t i = 0; i < face_counts->size(); i++) {
415 num_ngons += (face_counts_array[i] == 4 ? 0 : 1);
416 num_corners += face_counts_array[i];
419 subd_start_corner.
reserve(num_faces);
420 subd_num_corners.
reserve(num_faces);
421 subd_smooth.
reserve(num_faces);
422 subd_ptex_offset.
reserve(num_faces);
424 subd_face_corners.
reserve(num_corners);
427 int start_corner = 0;
428 int current_shader = 0;
431 const array<int> polygon_to_shader = compute_polygon_to_shader_map(
432 face_counts,
data.shader_face_sets, iss);
434 for (
size_t i = 0; i < face_counts->size(); i++) {
435 num_corners = face_counts_array[i];
437 if (!polygon_to_shader.
empty()) {
438 current_shader = polygon_to_shader[i];
444 for (
int j = 0; j < num_corners; ++j) {
453 ptex_offset += (num_corners == 4 ? 1 : num_corners);
455 start_corner += num_corners;
458 cached_data.shader.add_data(shader,
time);
459 cached_data.subd_start_corner.add_data(subd_start_corner,
time);
460 cached_data.subd_num_corners.add_data(subd_num_corners,
time);
461 cached_data.subd_smooth.add_data(subd_smooth,
time);
462 cached_data.subd_ptex_offset.add_data(subd_ptex_offset,
time);
463 cached_data.subd_face_corners.add_data(subd_face_corners,
time);
464 cached_data.num_ngons.add_data(num_ngons,
time);
465 cached_data.uv_loops.add_data(uv_loops,
time);
468 static void add_subd_edge_creases(CachedData &cached_data,
469 const SubDSchemaData &
data,
472 if (!(
data.crease_indices.valid() &&
data.crease_lengths.valid() &&
473 data.crease_sharpnesses.valid())) {
477 const ISampleSelector iss = ISampleSelector(
time);
479 const Int32ArraySamplePtr creases_length =
data.crease_lengths.getValue(iss);
480 const Int32ArraySamplePtr creases_indices =
data.crease_indices.getValue(iss);
481 const FloatArraySamplePtr creases_sharpnesses =
data.crease_sharpnesses.getValue(iss);
483 if (creases_length && creases_indices && creases_sharpnesses) {
487 creases_edge.
reserve(creases_sharpnesses->size() * 2);
488 creases_weight.
reserve(creases_sharpnesses->size());
490 int length_offset = 0;
491 int weight_offset = 0;
492 for (
size_t c = 0;
c < creases_length->size(); ++
c) {
493 const int crease_length = creases_length->get()[
c];
495 for (
size_t j = 0; j < crease_length - 1; ++j) {
501 length_offset += crease_length;
504 cached_data.subd_creases_edge.add_data(creases_edge,
time);
505 cached_data.subd_creases_weight.add_data(creases_weight,
time);
509 static void add_subd_vertex_creases(CachedData &cached_data,
510 const SubDSchemaData &
data,
513 if (!(
data.corner_indices.valid() &&
data.crease_sharpnesses.valid())) {
517 const ISampleSelector iss = ISampleSelector(
time);
518 const Int32ArraySamplePtr creases_indices =
data.crease_indices.getValue(iss);
519 const FloatArraySamplePtr creases_sharpnesses =
data.crease_sharpnesses.getValue(iss);
521 if (!(creases_indices && creases_sharpnesses) ||
522 creases_indices->size() != creases_sharpnesses->size()) {
527 sharpnesses.
reserve(creases_indices->size());
529 indices.reserve(creases_indices->size());
531 for (
size_t i = 0; i < creases_indices->size(); i++) {
532 indices.push_back_reserved((*creases_indices)[i]);
536 cached_data.subd_vertex_crease_indices.add_data(
indices,
time);
537 cached_data.subd_vertex_crease_weights.add_data(sharpnesses,
time);
540 static void read_subd_geometry(CachedData &cached_data,
const SubDSchemaData &
data, chrono_t
time)
542 const ISampleSelector iss = ISampleSelector(
time);
544 add_positions(
data.positions.getValue(iss),
time, cached_data);
546 if (
data.topology_variance != kHomogeneousTopology || cached_data.shader.size() == 0) {
547 add_subd_polygons(cached_data,
data,
time);
548 add_subd_edge_creases(cached_data,
data,
time);
549 add_subd_vertex_creases(cached_data,
data,
time);
553 void read_geometry_data(AlembicProcedural *proc,
554 CachedData &cached_data,
555 const SubDSchemaData &
data,
558 read_data_loop(proc, cached_data,
data, read_subd_geometry, progress);
563 static void read_curves_data(CachedData &cached_data,
const CurvesSchemaData &
data, chrono_t
time)
565 const ISampleSelector iss = ISampleSelector(
time);
567 const Int32ArraySamplePtr curves_num_vertices =
data.num_vertices.getValue(iss);
568 const P3fArraySamplePtr position =
data.positions.getValue(iss);
570 FloatArraySamplePtr radiuses;
572 if (
data.widths.valid()) {
573 IFloatGeomParam::Sample wsample =
data.widths.getExpandedValue(iss);
574 radiuses = wsample.getVals();
577 const bool do_radius = (radiuses !=
nullptr) && (radiuses->size() > 1);
578 float radius = (radiuses && radiuses->size() == 1) ? (*radiuses)[0] :
data.default_radius;
585 const bool is_homogeneous =
data.topology_variance == kHomogeneousTopology;
587 curve_keys.
reserve(position->size());
588 curve_radius.
reserve(position->size());
589 curve_first_key.
reserve(curves_num_vertices->size());
590 curve_shader.
reserve(curves_num_vertices->size());
593 for (
size_t i = 0; i < curves_num_vertices->size(); i++) {
594 const int num_vertices = curves_num_vertices->get()[i];
596 for (
int j = 0; j < num_vertices; j++) {
597 const V3f &f = position->get()[
offset + j];
602 radius = (*radiuses)[
offset + j];
608 if (!is_homogeneous || cached_data.curve_first_key.size() == 0) {
616 cached_data.curve_keys.add_data(curve_keys,
time);
617 cached_data.curve_radius.add_data(curve_radius,
time);
619 if (!is_homogeneous || cached_data.curve_first_key.size() == 0) {
620 cached_data.curve_first_key.add_data(curve_first_key,
time);
621 cached_data.curve_shader.add_data(curve_shader,
time);
625 void read_geometry_data(AlembicProcedural *proc,
626 CachedData &cached_data,
627 const CurvesSchemaData &
data,
630 read_data_loop(proc, cached_data,
data, read_curves_data, progress);
635 static void read_points_data(CachedData &cached_data,
const PointsSchemaData &
data, chrono_t
time)
637 const ISampleSelector iss = ISampleSelector(
time);
639 const P3fArraySamplePtr position =
data.positions.getValue(iss);
640 FloatArraySamplePtr radiuses;
645 a_positions.
reserve(position->size());
646 a_radius.
reserve(position->size());
647 a_shader.
reserve(position->size());
649 if (
data.radiuses.valid()) {
650 IFloatGeomParam::Sample wsample =
data.radiuses.getExpandedValue(iss);
651 radiuses = wsample.getVals();
654 const bool do_radius = (radiuses !=
nullptr) && (radiuses->size() > 1);
655 float radius = (radiuses && radiuses->size() == 1) ? (*radiuses)[0] :
data.default_radius;
658 for (
size_t i = 0; i < position->size(); i++) {
659 const V3f &f = position->get()[
offset + i];
663 radius = (*radiuses)[
offset + i];
670 cached_data.points.add_data(a_positions,
time);
671 cached_data.radiuses.add_data(a_radius,
time);
672 cached_data.points_shader.add_data(a_shader,
time);
675 void read_geometry_data(AlembicProcedural *proc,
676 CachedData &cached_data,
677 const PointsSchemaData &
data,
680 read_data_loop(proc, cached_data,
data, read_points_data, progress);
687 template<
typename T>
struct value_type_converter {
688 using cycles_type =
float;
691 static constexpr
const char *type_name =
"float (default)";
693 static cycles_type convert_value(
T value)
695 return static_cast<float>(value);
699 template<>
struct value_type_converter<Imath::V2f> {
700 using cycles_type =
float2;
701 static constexpr TypeDesc type_desc =
TypeFloat2;
702 static constexpr
const char *type_name =
"float2";
704 static cycles_type convert_value(Imath::V2f value)
710 template<>
struct value_type_converter<Imath::V3f> {
711 using cycles_type =
float3;
712 static constexpr TypeDesc type_desc = TypeVector;
713 static constexpr
const char *type_name =
"float3";
715 static cycles_type convert_value(Imath::V3f value)
717 return make_float3_from_yup(value);
721 template<>
struct value_type_converter<Imath::C3f> {
722 using cycles_type =
uchar4;
723 static constexpr TypeDesc type_desc =
TypeRGBA;
724 static constexpr
const char *type_name =
"rgb";
726 static cycles_type convert_value(Imath::C3f value)
732 template<>
struct value_type_converter<Imath::C4f> {
733 using cycles_type =
uchar4;
734 static constexpr TypeDesc type_desc =
TypeRGBA;
735 static constexpr
const char *type_name =
"rgba";
737 static cycles_type convert_value(Imath::C4f value)
744 template<
typename TRAIT>
745 static void process_attribute(CachedData &cache,
748 const typename ITypedGeomParam<TRAIT>::Sample &
sample,
751 using abc_type =
typename TRAIT::value_type;
752 using cycles_type =
typename value_type_converter<abc_type>::cycles_type;
754 const TypedArraySample<TRAIT> &values = *
sample.getVals();
760 cache.vertices.data_for_time_no_check(
time).get_data_or_null();
767 if (vertices->
size() != values.size()) {
774 cycles_type *pod_typed_data =
reinterpret_cast<cycles_type *
>(
data.data());
776 for (
size_t i = 0; i < values.size(); ++i) {
777 *pod_typed_data++ = value_type_converter<abc_type>::convert_value(values[i]);
783 case kVaryingScope: {
785 cache.triangles.data_for_time_no_check(
time).get_data_or_null();
794 cycles_type *pod_typed_data =
reinterpret_cast<cycles_type *
>(
data.data());
796 for (
const int3 &tri : *triangles) {
797 *pod_typed_data++ = value_type_converter<abc_type>::convert_value(values[tri.x]);
798 *pod_typed_data++ = value_type_converter<abc_type>::convert_value(values[tri.y]);
799 *pod_typed_data++ = value_type_converter<abc_type>::convert_value(values[tri.z]);
813 static void process_uvs(CachedData &cache,
816 const IV2fGeomParam::Sample &
sample,
819 if (scope != kFacevaryingScope && scope != kVaryingScope && scope != kVertexScope) {
823 const array<int> *uv_loops = cache.uv_loops.data_for_time_no_check(
time).get_data_or_null();
826 if (!uv_loops && scope == kFacevaryingScope) {
830 const array<int3> *triangles = cache.triangles.data_for_time_no_check(
time).get_data_or_null();
832 cache.subd_face_corners.data_for_time_no_check(
time).get_data_or_null();
848 const V2f *values =
sample.getVals()->get();
850 if (scope == kFacevaryingScope) {
851 for (
const int uv_loop_index : *uv_loops) {
853 *data_float2++ =
make_float2(values[index][0], values[index][1]);
856 else if (scope == kVaryingScope || scope == kVertexScope) {
858 for (
size_t i = 0; i < triangles->
size(); i++) {
859 const int3 t = (*triangles)[i];
860 *data_float2++ =
make_float2(values[
t.x][0], values[
t.x][1]);
861 *data_float2++ =
make_float2(values[
t.y][0], values[
t.y][1]);
862 *data_float2++ =
make_float2(values[
t.z][0], values[
t.z][1]);
866 for (
size_t i = 0; i < corners->
size(); i++) {
867 const int c = (*corners)[i];
878 template<
typename TRAIT>
879 using process_callback_type =
void (*)(CachedData &,
880 CachedData::CachedAttribute &,
882 const typename ITypedGeomParam<TRAIT>::Sample &,
888 template<
typename TRAIT>
889 static void read_attribute_loop(AlembicProcedural *proc,
891 const ITypedGeomParam<TRAIT> ¶m,
892 process_callback_type<TRAIT>
callback,
896 const std::set<chrono_t> times = get_relevant_sample_times(
897 proc, *param.getTimeSampling(), param.getNumSamples());
903 std::string name = param.getName();
906 std::string uv_source_name = Alembic::Abc::GetSourceName(param.getMetaData());
911 if (!uv_source_name.empty()) {
912 name = uv_source_name;
916 CachedData::CachedAttribute &
attribute = cache.add_attribute(ustring(name),
917 *param.getTimeSampling());
919 using abc_type =
typename TRAIT::value_type;
921 attribute.data.set_time_sampling(*param.getTimeSampling());
923 attribute.type_desc = value_type_converter<abc_type>::type_desc;
929 if (param.getScope() == kVaryingScope || param.getScope() == kFacevaryingScope) {
937 for (
const chrono_t
time : times) {
942 ISampleSelector iss = ISampleSelector(
time);
943 typename ITypedGeomParam<TRAIT>::Sample
sample;
944 param.getIndexed(
sample, iss);
957 if (param.isConstant()) {
964 const bool is_same_as_last_time = (indices_key ==
attribute.data.key1 &&
970 if (is_same_as_last_time) {
984 struct PropHeaderAndParent {
985 const PropertyHeader *prop;
986 ICompoundProperty parent;
993 static void parse_requested_attributes_recursive(
const AttributeRequestSet &requested_attributes,
994 const ICompoundProperty &arb_geom_params,
997 if (!arb_geom_params.valid()) {
1002 const PropertyHeader *property_header = arb_geom_params.getPropertyHeader(req.
name.c_str());
1004 if (!property_header) {
1008 requested_properties.push_back({property_header, arb_geom_params});
1012 for (
size_t i = 0; i < arb_geom_params.getNumProperties(); ++i) {
1013 const PropertyHeader &property_header = arb_geom_params.getPropertyHeader(i);
1015 if (property_header.isCompound()) {
1016 ICompoundProperty compound_property = ICompoundProperty(arb_geom_params,
1017 property_header.getName());
1018 parse_requested_attributes_recursive(
1019 requested_attributes, compound_property, requested_properties);
1028 const AttributeRequestSet &requested_attributes,
const ICompoundProperty &arb_geom_params)
1031 parse_requested_attributes_recursive(
1032 requested_attributes, arb_geom_params, requested_properties);
1033 return requested_properties;
1040 void read_attributes(AlembicProcedural *proc,
1042 const ICompoundProperty &arb_geom_params,
1043 const IV2fGeomParam &default_uvs_param,
1047 if (default_uvs_param.valid()) {
1049 read_attribute_loop(proc, cache, default_uvs_param, process_uvs, progress,
ATTR_STD_UV);
1053 requested_attributes, arb_geom_params);
1055 for (
const PropHeaderAndParent &prop_and_parent : requested_properties) {
1060 const PropertyHeader *prop = prop_and_parent.prop;
1061 const ICompoundProperty &parent = prop_and_parent.parent;
1063 if (IBoolGeomParam::matches(*prop)) {
1064 const IBoolGeomParam ¶m = IBoolGeomParam(parent, prop->getName());
1065 read_attribute_loop(proc, cache, param, process_attribute<BooleanTPTraits>, progress);
1067 else if (IInt32GeomParam::matches(*prop)) {
1068 const IInt32GeomParam ¶m = IInt32GeomParam(parent, prop->getName());
1069 read_attribute_loop(proc, cache, param, process_attribute<Int32TPTraits>, progress);
1071 else if (IFloatGeomParam::matches(*prop)) {
1072 const IFloatGeomParam ¶m = IFloatGeomParam(parent, prop->getName());
1073 read_attribute_loop(proc, cache, param, process_attribute<Float32TPTraits>, progress);
1075 else if (IV2fGeomParam::matches(*prop)) {
1076 const IV2fGeomParam ¶m = IV2fGeomParam(parent, prop->getName());
1077 if (Alembic::AbcGeom::isUV(*prop)) {
1078 read_attribute_loop(proc, cache, param, process_uvs, progress);
1081 read_attribute_loop(proc, cache, param, process_attribute<V2fTPTraits>, progress);
1084 else if (IV3fGeomParam::matches(*prop)) {
1085 const IV3fGeomParam ¶m = IV3fGeomParam(parent, prop->getName());
1086 read_attribute_loop(proc, cache, param, process_attribute<V3fTPTraits>, progress);
1088 else if (IN3fGeomParam::matches(*prop)) {
1089 const IN3fGeomParam ¶m = IN3fGeomParam(parent, prop->getName());
1090 read_attribute_loop(proc, cache, param, process_attribute<N3fTPTraits>, progress);
1092 else if (IC3fGeomParam::matches(*prop)) {
1093 const IC3fGeomParam ¶m = IC3fGeomParam(parent, prop->getName());
1094 read_attribute_loop(proc, cache, param, process_attribute<C3fTPTraits>, progress);
1096 else if (IC4fGeomParam::matches(*prop)) {
1097 const IC4fGeomParam ¶m = IC4fGeomParam(parent, prop->getName());
1098 read_attribute_loop(proc, cache, param, process_attribute<C4fTPTraits>, progress);
1102 cache.invalidate_last_loaded_time(
true);
typedef float(TangentPoint)[2]
typedef double(DMatrix)[4][4]
_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
_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 v1
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
vector< AttributeRequest > requests
void push_back_reserved(const T &t)
void reserve(size_t newcapacity)
void push_back_slow(const T &t)
#define CCL_NAMESPACE_END
DEGForeachIDComponentCallback callback
SyclQueue void void size_t num_bytes void
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
ccl_gpu_kernel_postfix int ccl_global int * indices
ccl_gpu_kernel_postfix ccl_global float int int int int ccl_global const float int int int int int int int int int int int int num_samples
@ ATTR_ELEMENT_CORNER_BYTE
vec_base< T, Size > normalize(const vec_base< T, Size > &v)
MutableSpan< float3 > positions
MutableSpan< float3 > normals
static constexpr TypeDesc TypeRGBA(TypeDesc::FLOAT, TypeDesc::VEC4, TypeDesc::COLOR)
CCL_NAMESPACE_BEGIN static constexpr OIIO_NAMESPACE_USING TypeDesc TypeFloat2(TypeDesc::FLOAT, TypeDesc::VEC2)
ccl_device uchar4 color_float4_to_uchar4(float4 c)
ccl_device uchar4 color_float_to_byte(float3 c)