14using namespace Alembic::AbcGeom;
18static float3 make_float3_from_yup(
const V3f &
v)
24static set<chrono_t> get_relevant_sample_times(AlembicProcedural *proc,
25 const TimeSampling &time_sampling,
30 if (num_samples < 2) {
38 if (proc->get_use_prefetch()) {
40 start_frame =
static_cast<double>(proc->get_start_frame());
41 end_frame =
static_cast<double>(proc->get_end_frame());
45 start_frame =
static_cast<double>(proc->get_frame());
46 end_frame = start_frame;
49 const double frame_rate =
static_cast<double>(proc->get_frame_rate());
50 const double start_time = start_frame / frame_rate;
51 const double end_time = (end_frame + 1) / frame_rate;
53 const size_t start_index = time_sampling.getFloorIndex(start_time, num_samples).first;
54 const size_t end_index = time_sampling.getCeilIndex(end_time, num_samples).first;
56 for (
size_t i = start_index; i < end_index; ++i) {
57 result.insert(time_sampling.getSampleTime(i));
66template<
typename Params,
typename DataReadingFunc>
67static void read_data_loop(AlembicProcedural *proc,
68 CachedData &cached_data,
70 DataReadingFunc &&func,
73 const std::set<chrono_t> times = get_relevant_sample_times(
76 cached_data.set_time_sampling(*
params.time_sampling);
78 for (chrono_t time : times) {
83 func(cached_data,
params, time);
91static void compute_vertex_normals(CachedData &cache,
double current_time)
93 if (cache.vertices.size() == 0) {
97 CachedData::CachedAttribute &attr_normal = cache.add_attribute(
98 ustring(
"N"), cache.vertices.get_time_sampling());
101 attr_normal.type_desc = TypeNormal;
104 cache.vertices.data_for_time_no_check(current_time).get_data_or_null();
106 cache.triangles.data_for_time_no_check(current_time).get_data_or_null();
108 if (!vertices || !triangles) {
109 attr_normal.
data.add_no_data(current_time);
114 float3 *attr_ptr =
reinterpret_cast<float3 *
>(attr_data.data());
115 memset(attr_ptr, 0, vertices->size() *
sizeof(
float3));
117 for (
size_t t = 0; t < triangles->size(); ++t) {
118 const int3 tri_int3 = triangles->data()[t];
120 tri.
v[0] = tri_int3[0];
121 tri.v[1] = tri_int3[1];
122 tri.v[2] = tri_int3[2];
124 const float3 tri_N = tri.compute_normal(vertices->data());
126 for (
int v = 0;
v < 3; ++
v) {
127 attr_ptr[tri_int3[
v]] += tri_N;
131 for (
size_t v = 0;
v < vertices->size(); ++
v) {
135 attr_normal.data.add_data(attr_data, current_time);
138static void add_normals(
const Int32ArraySamplePtr face_indices,
139 const IN3fGeomParam &normals,
141 CachedData &cached_data)
143 switch (normals.getScope()) {
144 case kFacevaryingScope: {
145 const ISampleSelector iss = ISampleSelector(time);
146 const IN3fGeomParam::Sample
sample = normals.getExpandedValue(iss);
152 CachedData::CachedAttribute &attr = cached_data.add_attribute(ustring(normals.getName()),
153 *normals.getTimeSampling());
157 cached_data.vertices.data_for_time_no_check(time).get_data_or_null();
166 float3 *data_float3 =
reinterpret_cast<float3 *
>(data.data());
168 const int *face_indices_array = face_indices->get();
169 const N3fArraySamplePtr values =
sample.getVals();
171 for (
size_t i = 0; i < face_indices->size(); ++i) {
172 int point_index = face_indices_array[i];
173 data_float3[point_index] = make_float3_from_yup(values->get()[i]);
176 attr.data.add_data(data, time);
181 const ISampleSelector iss = ISampleSelector(time);
182 const IN3fGeomParam::Sample
sample = normals.getExpandedValue(iss);
188 CachedData::CachedAttribute &attr = cached_data.add_attribute(ustring(normals.getName()),
189 *normals.getTimeSampling());
193 cached_data.vertices.data_for_time_no_check(time).get_data_or_null();
202 float3 *data_float3 =
reinterpret_cast<float3 *
>(data.data());
204 const Imath::V3f *values =
sample.getVals()->get();
206 for (
size_t i = 0; i < vertices->size(); ++i) {
207 data_float3[i] = make_float3_from_yup(values[i]);
210 attr.data.add_data(data, time);
220static void add_positions(
const P3fArraySamplePtr positions,
double time, CachedData &cached_data)
227 vertices.
reserve(positions->size());
229 for (
size_t i = 0; i < positions->size(); i++) {
230 V3f f = positions->get()[i];
231 vertices.push_back_reserved(make_float3_from_yup(f));
234 cached_data.vertices.add_data(vertices, time);
237static void add_triangles(
const Int32ArraySamplePtr face_counts,
238 const Int32ArraySamplePtr face_indices,
240 CachedData &cached_data,
243 if (!face_counts || !face_indices) {
247 const size_t num_faces = face_counts->size();
248 const int *face_counts_array = face_counts->get();
249 const int *face_indices_array = face_indices->get();
251 size_t num_triangles = 0;
252 for (
size_t i = 0; i < face_counts->size(); i++) {
253 num_triangles += face_counts_array[i] - 2;
260 triangles.reserve(num_triangles);
261 uv_loops.
reserve(num_triangles * 3);
262 int index_offset = 0;
264 for (
size_t i = 0; i < num_faces; i++) {
265 int current_shader = 0;
267 if (!polygon_to_shader.
empty()) {
268 current_shader = polygon_to_shader[i];
271 for (
int j = 0; j < face_counts_array[i] - 2; j++) {
272 int v0 = face_indices_array[index_offset];
273 int v1 = face_indices_array[index_offset + j + 1];
274 int v2 = face_indices_array[index_offset + j + 2];
276 shader.push_back_reserved(current_shader);
279 triangles.push_back_reserved(
make_int3(
v2, v1, v0));
285 index_offset += face_counts_array[i];
288 cached_data.triangles.add_data(triangles, time);
289 cached_data.uv_loops.add_data(uv_loops, time);
290 cached_data.shader.add_data(shader, time);
293static array<int> compute_polygon_to_shader_map(
294 const Int32ArraySamplePtr &face_counts,
296 ISampleSelector sample_sel)
298 if (face_set_shader_index.empty()) {
306 if (face_counts->size() == 0) {
310 array<int> polygon_to_shader(face_counts->size());
312 for (
const FaceSetShaderIndexPair &pair : face_set_shader_index) {
313 const IFaceSet &face_set = pair.face_set;
314 const IFaceSetSchema face_schem = face_set.getSchema();
315 const IFaceSetSchema::Sample face_sample = face_schem.getValue(sample_sel);
316 const Int32ArraySamplePtr group_faces = face_sample.getFaces();
317 const size_t num_group_faces = group_faces->size();
319 for (
size_t l = 0;
l < num_group_faces;
l++) {
320 size_t pos = (*group_faces)[
l];
322 if (
pos >= polygon_to_shader.
size()) {
326 polygon_to_shader[
pos] = pair.shader_index;
330 return polygon_to_shader;
333static void read_poly_mesh_geometry(CachedData &cached_data,
334 const PolyMeshSchemaData &data,
337 const ISampleSelector iss = ISampleSelector(time);
339 add_positions(data.positions.getValue(iss), time, cached_data);
341 const Int32ArraySamplePtr face_counts = data.face_counts.getValue(iss);
342 const Int32ArraySamplePtr face_indices = data.face_indices.getValue(iss);
345 if (data.topology_variance != kHomogeneousTopology || cached_data.triangles.size() == 0) {
346 bool do_triangles =
true;
349 if (cached_data.triangles.size() > 0) {
350 const ArraySample::Key key = face_indices->getKey();
352 if (key == cached_data.triangles.key1) {
353 do_triangles =
false;
356 cached_data.triangles.key1 = key;
360 const array<int> polygon_to_shader = compute_polygon_to_shader_map(
361 face_counts, data.shader_face_sets, iss);
362 add_triangles(face_counts, face_indices, time, cached_data, polygon_to_shader);
365 cached_data.triangles.reuse_data_for_last_time(time);
366 cached_data.uv_loops.reuse_data_for_last_time(time);
367 cached_data.shader.reuse_data_for_last_time(time);
371 if (data.topology_variance != kHomogeneousTopology && cached_data.triangles.size() == 1) {
372 cached_data.triangles.key1 = face_indices->getKey();
376 if (data.normals.valid()) {
377 add_normals(face_indices, data.normals, time, cached_data);
380 compute_vertex_normals(cached_data, time);
384void read_geometry_data(AlembicProcedural *proc,
385 CachedData &cached_data,
386 const PolyMeshSchemaData &data,
389 read_data_loop(proc, cached_data, data, read_poly_mesh_geometry, progress);
394static void add_subd_polygons(CachedData &cached_data,
const SubDSchemaData &data, chrono_t time)
396 const ISampleSelector iss = ISampleSelector(time);
398 const Int32ArraySamplePtr face_counts = data.face_counts.getValue(iss);
399 const Int32ArraySamplePtr face_indices = data.face_indices.getValue(iss);
409 const size_t num_faces = face_counts->size();
410 const int *face_counts_array = face_counts->get();
411 const int *face_indices_array = face_indices->get();
415 for (
size_t i = 0; i < face_counts->size(); i++) {
416 num_ngons += (face_counts_array[i] == 4 ? 0 : 1);
417 num_corners += face_counts_array[i];
420 subd_start_corner.
reserve(num_faces);
421 subd_num_corners.
reserve(num_faces);
422 subd_smooth.
reserve(num_faces);
423 subd_ptex_offset.
reserve(num_faces);
424 shader.reserve(num_faces);
425 subd_face_corners.
reserve(num_corners);
428 int start_corner = 0;
429 int current_shader = 0;
432 const array<int> polygon_to_shader = compute_polygon_to_shader_map(
433 face_counts, data.shader_face_sets, iss);
435 for (
size_t i = 0; i < face_counts->size(); i++) {
436 num_corners = face_counts_array[i];
438 if (!polygon_to_shader.
empty()) {
439 current_shader = polygon_to_shader[i];
445 for (
int j = 0; j < num_corners; ++j) {
450 shader.push_back_reserved(current_shader);
454 ptex_offset += (num_corners == 4 ? 1 : num_corners);
456 start_corner += num_corners;
459 cached_data.shader.add_data(shader, time);
460 cached_data.subd_start_corner.add_data(subd_start_corner, time);
461 cached_data.subd_num_corners.add_data(subd_num_corners, time);
462 cached_data.subd_smooth.add_data(subd_smooth, time);
463 cached_data.subd_ptex_offset.add_data(subd_ptex_offset, time);
464 cached_data.subd_face_corners.add_data(subd_face_corners, time);
465 cached_data.num_ngons.add_data(num_ngons, time);
466 cached_data.uv_loops.add_data(uv_loops, time);
469static void add_subd_edge_creases(CachedData &cached_data,
470 const SubDSchemaData &data,
473 if (!(data.crease_indices.valid() && data.crease_lengths.valid() &&
474 data.crease_sharpnesses.valid()))
479 const ISampleSelector iss = ISampleSelector(time);
481 const Int32ArraySamplePtr creases_length = data.crease_lengths.getValue(iss);
482 const Int32ArraySamplePtr creases_indices = data.crease_indices.getValue(iss);
483 const FloatArraySamplePtr creases_sharpnesses = data.crease_sharpnesses.getValue(iss);
485 if (creases_length && creases_indices && creases_sharpnesses) {
489 creases_edge.
reserve(creases_sharpnesses->size() * 2);
490 creases_weight.
reserve(creases_sharpnesses->size());
492 int length_offset = 0;
493 int weight_offset = 0;
494 for (
size_t c = 0; c < creases_length->size(); ++c) {
495 const int crease_length = creases_length->get()[c];
497 for (
size_t j = 0; j < crease_length - 1; ++j) {
503 length_offset += crease_length;
506 cached_data.subd_creases_edge.add_data(creases_edge, time);
507 cached_data.subd_creases_weight.add_data(creases_weight, time);
511static void add_subd_vertex_creases(CachedData &cached_data,
512 const SubDSchemaData &data,
515 if (!(data.corner_indices.valid() && data.crease_sharpnesses.valid())) {
519 const ISampleSelector iss = ISampleSelector(time);
520 const Int32ArraySamplePtr creases_indices = data.crease_indices.getValue(iss);
521 const FloatArraySamplePtr creases_sharpnesses = data.crease_sharpnesses.getValue(iss);
523 if (!(creases_indices && creases_sharpnesses) ||
524 creases_indices->size() != creases_sharpnesses->size())
530 sharpnesses.
reserve(creases_indices->size());
532 indices.
reserve(creases_indices->size());
534 for (
size_t i = 0; i < creases_indices->size(); i++) {
535 indices.push_back_reserved((*creases_indices)[i]);
539 cached_data.subd_vertex_crease_indices.add_data(indices, time);
540 cached_data.subd_vertex_crease_weights.add_data(sharpnesses, time);
543static void read_subd_geometry(CachedData &cached_data,
const SubDSchemaData &data, chrono_t time)
545 const ISampleSelector iss = ISampleSelector(time);
547 add_positions(data.positions.getValue(iss), time, cached_data);
549 if (data.topology_variance != kHomogeneousTopology || cached_data.shader.size() == 0) {
550 add_subd_polygons(cached_data, data, time);
551 add_subd_edge_creases(cached_data, data, time);
552 add_subd_vertex_creases(cached_data, data, time);
556void read_geometry_data(AlembicProcedural *proc,
557 CachedData &cached_data,
558 const SubDSchemaData &data,
561 read_data_loop(proc, cached_data, data, read_subd_geometry, progress);
566static void read_curves_data(CachedData &cached_data,
const CurvesSchemaData &data, chrono_t time)
568 const ISampleSelector iss = ISampleSelector(time);
570 const Int32ArraySamplePtr curves_num_vertices = data.num_vertices.getValue(iss);
571 const P3fArraySamplePtr position = data.positions.getValue(iss);
573 FloatArraySamplePtr radiuses;
575 if (data.widths.valid()) {
576 IFloatGeomParam::Sample wsample = data.widths.getExpandedValue(iss);
577 radiuses = wsample.getVals();
580 const bool do_radius = (radiuses !=
nullptr) && (radiuses->size() > 1);
581 float radius = (radiuses && radiuses->size() == 1) ? (*radiuses)[0] : data.default_radius;
588 const bool is_homogeneous = data.topology_variance == kHomogeneousTopology;
590 curve_keys.
reserve(position->size());
591 curve_radius.
reserve(position->size());
592 curve_first_key.
reserve(curves_num_vertices->size());
593 curve_shader.
reserve(curves_num_vertices->size());
596 for (
size_t i = 0; i < curves_num_vertices->size(); i++) {
597 const int num_vertices = curves_num_vertices->get()[i];
599 for (
int j = 0; j < num_vertices; j++) {
600 const V3f &f = position->get()[offset + j];
605 radius = (*radiuses)[offset + j];
611 if (!is_homogeneous || cached_data.curve_first_key.size() == 0) {
616 offset += num_vertices;
619 cached_data.curve_keys.add_data(curve_keys, time);
620 cached_data.curve_radius.add_data(curve_radius, time);
622 if (!is_homogeneous || cached_data.curve_first_key.size() == 0) {
623 cached_data.curve_first_key.add_data(curve_first_key, time);
624 cached_data.curve_shader.add_data(curve_shader, time);
628void read_geometry_data(AlembicProcedural *proc,
629 CachedData &cached_data,
630 const CurvesSchemaData &data,
633 read_data_loop(proc, cached_data, data, read_curves_data, progress);
638static void read_points_data(CachedData &cached_data,
const PointsSchemaData &data, chrono_t time)
640 const ISampleSelector iss = ISampleSelector(time);
642 const P3fArraySamplePtr position = data.positions.getValue(iss);
643 FloatArraySamplePtr radiuses;
648 a_positions.
reserve(position->size());
649 a_radius.
reserve(position->size());
650 a_shader.
reserve(position->size());
652 if (data.radiuses.valid()) {
653 IFloatGeomParam::Sample wsample = data.radiuses.getExpandedValue(iss);
654 radiuses = wsample.getVals();
657 const bool do_radius = (radiuses !=
nullptr) && (radiuses->size() > 1);
658 float radius = (radiuses && radiuses->size() == 1) ? (*radiuses)[0] : data.default_radius;
661 for (
size_t i = 0; i < position->size(); i++) {
662 const V3f &f = position->get()[offset + i];
666 radius = (*radiuses)[offset + i];
673 cached_data.points.add_data(a_positions, time);
674 cached_data.radiuses.add_data(a_radius, time);
675 cached_data.points_shader.add_data(a_shader, time);
678void read_geometry_data(AlembicProcedural *proc,
679 CachedData &cached_data,
680 const PointsSchemaData &data,
683 read_data_loop(proc, cached_data, data, read_points_data, progress);
690template<
typename T>
struct value_type_converter {
691 using cycles_type =
float;
693 static constexpr TypeDesc type_desc = TypeDesc::FLOAT;
694 static constexpr const char *type_name =
"float (default)";
698 return static_cast<float>(value);
702template<>
struct value_type_converter<Imath::V2f> {
703 using cycles_type =
float2;
705 static constexpr const char *type_name =
"float2";
713template<>
struct value_type_converter<Imath::V3f> {
714 using cycles_type =
float3;
715 static constexpr TypeDesc type_desc = TypeVector;
716 static constexpr const char *type_name =
"float3";
720 return make_float3_from_yup(value);
724template<>
struct value_type_converter<Imath::C3f> {
725 using cycles_type =
uchar4;
727 static constexpr const char *type_name =
"rgb";
735template<>
struct value_type_converter<Imath::C4f> {
736 using cycles_type =
uchar4;
738 static constexpr const char *type_name =
"rgba";
747template<
typename TRAIT>
748static void process_attribute(CachedData &cache,
749 CachedData::CachedAttribute &attribute,
751 const typename ITypedGeomParam<TRAIT>::Sample &
sample,
754 using abc_type =
typename TRAIT::value_type;
755 using cycles_type =
typename value_type_converter<abc_type>::cycles_type;
757 const TypedArraySample<TRAIT> &values = *
sample.getVals();
763 cache.vertices.data_for_time_no_check(time).get_data_or_null();
766 attribute.
data.add_no_data(time);
770 if (vertices->size() != values.size()) {
771 attribute.data.add_no_data(time);
777 cycles_type *pod_typed_data =
reinterpret_cast<cycles_type *
>(data.data());
779 for (
size_t i = 0; i < values.size(); ++i) {
780 *pod_typed_data++ = value_type_converter<abc_type>::convert_value(values[i]);
783 attribute.data.add_data(data, time);
786 case kVaryingScope: {
788 cache.triangles.data_for_time_no_check(time).get_data_or_null();
791 attribute.
data.add_no_data(time);
797 cycles_type *pod_typed_data =
reinterpret_cast<cycles_type *
>(data.data());
799 for (
const int3 &tri : *triangles) {
800 *pod_typed_data++ = value_type_converter<abc_type>::convert_value(values[tri.x]);
801 *pod_typed_data++ = value_type_converter<abc_type>::convert_value(values[tri.y]);
802 *pod_typed_data++ = value_type_converter<abc_type>::convert_value(values[tri.z]);
805 attribute.data.add_data(data, time);
816static void process_uvs(CachedData &cache,
817 CachedData::CachedAttribute &attribute,
819 const IV2fGeomParam::Sample &
sample,
822 if (scope != kFacevaryingScope && scope != kVaryingScope && scope != kVertexScope) {
826 const array<int> *uv_loops = cache.uv_loops.data_for_time_no_check(time).get_data_or_null();
829 if (!uv_loops && scope == kFacevaryingScope) {
833 const array<int3> *triangles = cache.triangles.data_for_time_no_check(time).get_data_or_null();
835 cache.subd_face_corners.data_for_time_no_check(time).get_data_or_null();
842 data.resize(corners->size() *
sizeof(
float2));
848 float2 *data_float2 =
reinterpret_cast<float2 *
>(data.data());
851 const V2f *values =
sample.getVals()->get();
853 if (scope == kFacevaryingScope) {
854 for (
const int uv_loop_index : *uv_loops) {
855 const uint32_t index = indices[uv_loop_index];
856 *data_float2++ =
make_float2(values[index][0], values[index][1]);
859 else if (scope == kVaryingScope || scope == kVertexScope) {
861 for (
size_t i = 0; i < triangles->size(); i++) {
862 const int3 t = (*triangles)[i];
863 *data_float2++ =
make_float2(values[t.
x][0], values[t.
x][1]);
864 *data_float2++ =
make_float2(values[t.
y][0], values[t.
y][1]);
865 *data_float2++ =
make_float2(values[t.
z][0], values[t.
z][1]);
869 for (
size_t i = 0; i < corners->size(); i++) {
870 const int c = (*corners)[i];
871 *data_float2++ =
make_float2(values[c][0], values[c][1]);
876 attribute.data.add_data(data, time);
881template<
typename TRAIT>
882using process_callback_type = void (*)(CachedData &,
883 CachedData::CachedAttribute &,
885 const typename ITypedGeomParam<TRAIT>::Sample &,
891template<
typename TRAIT>
892static void read_attribute_loop(AlembicProcedural *proc,
894 const ITypedGeomParam<TRAIT> ¶m,
895 process_callback_type<TRAIT>
callback,
899 const std::set<chrono_t> times = get_relevant_sample_times(
900 proc, *param.getTimeSampling(), param.getNumSamples());
906 std::string name = param.getName();
909 std::string uv_source_name = Alembic::Abc::GetSourceName(param.getMetaData());
914 if (!uv_source_name.empty()) {
915 name = uv_source_name;
919 CachedData::CachedAttribute &attribute = cache.add_attribute(ustring(name),
920 *param.getTimeSampling());
922 using abc_type =
typename TRAIT::value_type;
924 attribute.data.set_time_sampling(*param.getTimeSampling());
926 attribute.type_desc = value_type_converter<abc_type>::type_desc;
928 if (attribute.type_desc ==
TypeRGBA) {
932 if (param.getScope() == kVaryingScope || param.getScope() == kFacevaryingScope) {
940 for (
const chrono_t time : times) {
945 ISampleSelector iss = ISampleSelector(time);
946 typename ITypedGeomParam<TRAIT>::Sample
sample;
947 param.getIndexed(
sample, iss);
954 attribute.data.add_no_data(time);
959 if (attribute.data.size() != 0) {
960 if (param.isConstant()) {
964 const ArraySample::Key indices_key =
sample.getIndices()->getKey();
965 const ArraySample::Key values_key =
sample.getVals()->getKey();
967 const bool is_same_as_last_time = (indices_key == attribute.data.key1 &&
968 values_key == attribute.data.key2);
970 attribute.data.key1 = indices_key;
971 attribute.data.key2 = values_key;
973 if (is_same_as_last_time) {
974 attribute.data.reuse_data_for_last_time(time);
987struct PropHeaderAndParent {
988 const PropertyHeader *prop;
989 ICompoundProperty parent;
996static void parse_requested_attributes_recursive(
const AttributeRequestSet &requested_attributes,
997 const ICompoundProperty &arb_geom_params,
1000 if (!arb_geom_params.valid()) {
1005 const PropertyHeader *property_header = arb_geom_params.getPropertyHeader(req.name.c_str());
1007 if (!property_header) {
1011 requested_properties.push_back({property_header, arb_geom_params});
1015 for (
size_t i = 0; i < arb_geom_params.getNumProperties(); ++i) {
1016 const PropertyHeader &property_header = arb_geom_params.getPropertyHeader(i);
1018 if (property_header.isCompound()) {
1019 ICompoundProperty compound_property = ICompoundProperty(arb_geom_params,
1020 property_header.getName());
1021 parse_requested_attributes_recursive(
1022 requested_attributes, compound_property, requested_properties);
1031 const AttributeRequestSet &requested_attributes,
const ICompoundProperty &arb_geom_params)
1034 parse_requested_attributes_recursive(
1035 requested_attributes, arb_geom_params, requested_properties);
1036 return requested_properties;
1043void read_attributes(AlembicProcedural *proc,
1045 const ICompoundProperty &arb_geom_params,
1046 const IV2fGeomParam &default_uvs_param,
1050 if (default_uvs_param.valid()) {
1052 read_attribute_loop(proc, cache, default_uvs_param, process_uvs, progress,
ATTR_STD_UV);
1056 requested_attributes, arb_geom_params);
1058 for (
const PropHeaderAndParent &prop_and_parent : requested_properties) {
1063 const PropertyHeader *prop = prop_and_parent.prop;
1064 const ICompoundProperty &parent = prop_and_parent.parent;
1066 if (IBoolGeomParam::matches(*prop)) {
1067 const IBoolGeomParam ¶m = IBoolGeomParam(parent, prop->getName());
1068 read_attribute_loop(proc, cache, param, process_attribute<BooleanTPTraits>, progress);
1070 else if (IInt32GeomParam::matches(*prop)) {
1071 const IInt32GeomParam ¶m = IInt32GeomParam(parent, prop->getName());
1072 read_attribute_loop(proc, cache, param, process_attribute<Int32TPTraits>, progress);
1074 else if (IFloatGeomParam::matches(*prop)) {
1075 const IFloatGeomParam ¶m = IFloatGeomParam(parent, prop->getName());
1076 read_attribute_loop(proc, cache, param, process_attribute<Float32TPTraits>, progress);
1078 else if (IV2fGeomParam::matches(*prop)) {
1079 const IV2fGeomParam ¶m = IV2fGeomParam(parent, prop->getName());
1080 if (Alembic::AbcGeom::isUV(*prop)) {
1081 read_attribute_loop(proc, cache, param, process_uvs, progress);
1084 read_attribute_loop(proc, cache, param, process_attribute<V2fTPTraits>, progress);
1087 else if (IV3fGeomParam::matches(*prop)) {
1088 const IV3fGeomParam ¶m = IV3fGeomParam(parent, prop->getName());
1089 read_attribute_loop(proc, cache, param, process_attribute<V3fTPTraits>, progress);
1091 else if (IN3fGeomParam::matches(*prop)) {
1092 const IN3fGeomParam ¶m = IN3fGeomParam(parent, prop->getName());
1093 read_attribute_loop(proc, cache, param, process_attribute<N3fTPTraits>, progress);
1095 else if (IC3fGeomParam::matches(*prop)) {
1096 const IC3fGeomParam ¶m = IC3fGeomParam(parent, prop->getName());
1097 read_attribute_loop(proc, cache, param, process_attribute<C3fTPTraits>, progress);
1099 else if (IC4fGeomParam::matches(*prop)) {
1100 const IC4fGeomParam ¶m = IC4fGeomParam(parent, prop->getName());
1101 read_attribute_loop(proc, cache, param, process_attribute<C4fTPTraits>, progress);
1105 cache.invalidate_last_loaded_time(
true);
typedef double(DMatrix)[4][4]
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
T * resize(size_t newsize)
void push_back_reserved(const T &t)
void reserve(size_t newcapacity)
void push_back_slow(const T &t)
DEGForeachIDComponentCallback callback
#define CCL_NAMESPACE_END
draw_view in_light_buf[] float
@ ATTR_ELEMENT_CORNER_BYTE
To convert_value(const From 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)
ccl_device uchar4 color_float4_to_uchar4(float4 c)
ccl_device uchar4 color_float_to_byte(float3 c)