25using namespace Alembic::AbcGeom;
31template<
typename SchemaType>
37 std::vector<std::string> face_set_names;
38 schema.getFaceSetNames(face_set_names);
40 if (face_set_names.empty()) {
44 for (
const std::string &face_set_name : face_set_names) {
47 for (
Node *node : used_shaders) {
48 if (node->name == face_set_name) {
55 if (shader_index >= used_shaders.size()) {
60 const Alembic::AbcGeom::IFaceSet face_set = schema.getFaceSet(face_set_name);
62 if (!face_set.valid()) {
66 result.push_back({face_set, shader_index});
72void CachedData::clear()
75 curve_first_key.clear();
80 subd_creases_edge.clear();
81 subd_creases_weight.clear();
82 subd_face_corners.clear();
83 subd_num_corners.clear();
84 subd_ptex_offset.clear();
86 subd_start_corner.clear();
93 points_shader.clear();
95 for (CachedAttribute &attr : attributes) {
102CachedData::CachedAttribute &CachedData::add_attribute(
const ustring &name,
103 const TimeSampling &time_sampling)
105 for (
auto &attr : attributes) {
106 if (attr.name == name) {
111 CachedAttribute &attr = attributes.emplace_back();
113 attr.data.set_time_sampling(time_sampling);
117bool CachedData::is_constant()
const
119# define CHECK_IF_CONSTANT(data) \
120 if (!data.is_constant()) { \
124 CHECK_IF_CONSTANT(curve_first_key)
125 CHECK_IF_CONSTANT(curve_keys)
126 CHECK_IF_CONSTANT(curve_radius)
127 CHECK_IF_CONSTANT(curve_shader)
128 CHECK_IF_CONSTANT(shader)
129 CHECK_IF_CONSTANT(subd_creases_edge)
130 CHECK_IF_CONSTANT(subd_creases_weight)
131 CHECK_IF_CONSTANT(subd_face_corners)
132 CHECK_IF_CONSTANT(subd_num_corners)
133 CHECK_IF_CONSTANT(subd_ptex_offset)
134 CHECK_IF_CONSTANT(subd_smooth)
135 CHECK_IF_CONSTANT(subd_start_corner)
136 CHECK_IF_CONSTANT(transforms)
137 CHECK_IF_CONSTANT(triangles)
138 CHECK_IF_CONSTANT(uv_loops)
139 CHECK_IF_CONSTANT(vertices)
140 CHECK_IF_CONSTANT(points)
141 CHECK_IF_CONSTANT(radiuses)
142 CHECK_IF_CONSTANT(points_shader)
144 for (
const CachedAttribute &attr : attributes) {
145 if (!attr.data.is_constant()) {
152# undef CHECK_IF_CONSTANT
155void CachedData::invalidate_last_loaded_time(
bool attributes_only)
157 if (attributes_only) {
158 for (CachedAttribute &attr : attributes) {
159 attr.data.invalidate_last_loaded_time();
165 curve_first_key.invalidate_last_loaded_time();
166 curve_keys.invalidate_last_loaded_time();
167 curve_radius.invalidate_last_loaded_time();
168 curve_shader.invalidate_last_loaded_time();
169 shader.invalidate_last_loaded_time();
170 subd_creases_edge.invalidate_last_loaded_time();
171 subd_creases_weight.invalidate_last_loaded_time();
172 subd_face_corners.invalidate_last_loaded_time();
173 subd_num_corners.invalidate_last_loaded_time();
174 subd_ptex_offset.invalidate_last_loaded_time();
175 subd_smooth.invalidate_last_loaded_time();
176 subd_start_corner.invalidate_last_loaded_time();
177 transforms.invalidate_last_loaded_time();
178 triangles.invalidate_last_loaded_time();
179 uv_loops.invalidate_last_loaded_time();
180 vertices.invalidate_last_loaded_time();
181 points.invalidate_last_loaded_time();
182 radiuses.invalidate_last_loaded_time();
183 points_shader.invalidate_last_loaded_time();
186void CachedData::set_time_sampling(TimeSampling time_sampling)
188 curve_first_key.set_time_sampling(time_sampling);
189 curve_keys.set_time_sampling(time_sampling);
190 curve_radius.set_time_sampling(time_sampling);
191 curve_shader.set_time_sampling(time_sampling);
192 shader.set_time_sampling(time_sampling);
193 subd_creases_edge.set_time_sampling(time_sampling);
194 subd_creases_weight.set_time_sampling(time_sampling);
195 subd_face_corners.set_time_sampling(time_sampling);
196 subd_num_corners.set_time_sampling(time_sampling);
197 subd_ptex_offset.set_time_sampling(time_sampling);
198 subd_smooth.set_time_sampling(time_sampling);
199 subd_start_corner.set_time_sampling(time_sampling);
200 transforms.set_time_sampling(time_sampling);
201 triangles.set_time_sampling(time_sampling);
202 uv_loops.set_time_sampling(time_sampling);
203 vertices.set_time_sampling(time_sampling);
204 points.set_time_sampling(time_sampling);
205 radiuses.set_time_sampling(time_sampling);
206 points_shader.set_time_sampling(time_sampling);
208 for (CachedAttribute &attr : attributes) {
209 attr.data.set_time_sampling(time_sampling);
213size_t CachedData::memory_used()
const
217 mem_used += curve_first_key.memory_used();
218 mem_used += curve_keys.memory_used();
219 mem_used += curve_radius.memory_used();
220 mem_used += curve_shader.memory_used();
221 mem_used += shader.memory_used();
222 mem_used += subd_creases_edge.memory_used();
223 mem_used += subd_creases_weight.memory_used();
224 mem_used += subd_face_corners.memory_used();
225 mem_used += subd_num_corners.memory_used();
226 mem_used += subd_ptex_offset.memory_used();
227 mem_used += subd_smooth.memory_used();
228 mem_used += subd_start_corner.memory_used();
229 mem_used += transforms.memory_used();
230 mem_used += triangles.memory_used();
231 mem_used += uv_loops.memory_used();
232 mem_used += vertices.memory_used();
233 mem_used += points.memory_used();
234 mem_used += radiuses.memory_used();
235 mem_used += points_shader.memory_used();
237 for (
const CachedAttribute &attr : attributes) {
238 mem_used += attr.data.memory_used();
244static M44d convert_yup_zup(
const M44d &mtx,
const float scale_mult)
251 if (!extractSHRT(mtx,
257 IMATH_INTERNAL_NAMESPACE::Euler<double>::XZY))
265 rot_mat.setEulerAngles(V3d(rotation.x, -rotation.z, rotation.y));
267 trans_mat.setTranslation(V3d(translation.x, -translation.z, translation.y));
269 const M44d temp_mat = scale_mat * rot_mat * trans_mat;
271 scale_mat.setScale(
static_cast<double>(scale_mult));
273 return temp_mat * scale_mat;
277 const M44d &mat, V3d &scale, V3d &shear, Quatd &rotation, V3d &translation)
279 M44d mat_remainder(mat);
282 Imath::extractAndRemoveScalingAndShear(mat_remainder, scale, shear);
285 translation.x = mat_remainder[3][0];
286 translation.y = mat_remainder[3][1];
287 translation.z = mat_remainder[3][2];
290 rotation = extractQuat(mat_remainder);
295 const Quatd &rotation,
296 const V3d &translation)
303 scale_mat.setScale(scale);
304 shear_mat.setShear(shear);
305 rot_mat = rotation.toMatrix44();
306 trans_mat.setTranslation(translation);
308 return scale_mat * shear_mat * rot_mat * trans_mat;
313static M44d get_matrix_for_time(
const MatrixSampleMap &samples, chrono_t time)
315 const MatrixSampleMap::const_iterator iter = samples.find(time);
316 if (iter != samples.end()) {
325static M44d get_interpolated_matrix_for_time(
const MatrixSampleMap &samples, chrono_t time)
327 if (samples.empty()) {
332 const MatrixSampleMap::const_iterator iter = samples.find(time);
333 if (iter != samples.end()) {
337 if (samples.size() == 1) {
338 return samples.begin()->second;
341 if (time <= samples.begin()->first) {
342 return samples.begin()->second;
345 if (time >= samples.rbegin()->first) {
346 return samples.rbegin()->second;
350 chrono_t prev_time = samples.begin()->first;
351 chrono_t next_time = samples.rbegin()->first;
353 for (MatrixSampleMap::const_iterator
I = samples.begin();
I != samples.end(); ++
I) {
354 const chrono_t current_time = (*I).first;
356 if (current_time > prev_time && current_time <= time) {
357 prev_time = current_time;
360 if (current_time > next_time && current_time >= time) {
361 next_time = current_time;
365 const M44d prev_mat = get_matrix_for_time(samples, prev_time);
366 const M44d next_mat = get_matrix_for_time(samples, next_time);
372 V3d prev_translation;
373 V3d next_translation;
380 const chrono_t t = (time - prev_time) / (next_time - prev_time);
383 if ((prev_rotation ^ next_rotation) < 0) {
384 next_rotation = -next_rotation;
388 Imath::lerp(prev_shear, next_shear, t),
389 Imath::slerp(prev_rotation, next_rotation, t),
390 Imath::lerp(prev_translation, next_translation, t));
393static void concatenate_xform_samples(
const MatrixSampleMap &parent_samples,
394 const MatrixSampleMap &local_samples,
395 MatrixSampleMap &output_samples)
397 set<chrono_t> union_of_samples;
399 for (
const std::pair<chrono_t, M44d> pair : parent_samples) {
400 union_of_samples.insert(pair.first);
403 for (
const std::pair<chrono_t, M44d> pair : local_samples) {
404 union_of_samples.insert(pair.first);
407 for (
const chrono_t time : union_of_samples) {
408 const M44d parent_matrix = get_interpolated_matrix_for_time(parent_samples, time);
409 const M44d local_matrix = get_interpolated_matrix_for_time(local_samples, time);
411 output_samples[time] = local_matrix * parent_matrix;
417 M44d m = convert_yup_zup(a, scale);
419 for (
int j = 0; j < 3; j++) {
420 for (
int i = 0;
i < 4;
i++) {
421 trans[j][
i] =
static_cast<float>(m[
i][j]);
436 SOCKET_INT(subd_max_level,
"Max Subdivision Level", 1);
437 SOCKET_FLOAT(subd_dicing_rate,
"Subdivision Dicing Rate", 1.0f);
444AlembicObject::AlembicObject() :
Node(get_node_type())
446 schema_type = INVALID;
449AlembicObject::~AlembicObject() =
default;
451void AlembicObject::set_object(
Object *object_)
456Object *AlembicObject::get_object()
461bool AlembicObject::has_data_loaded()
const
466void AlembicObject::load_data_in_cache(CachedData &cached_data,
467 AlembicProcedural *proc,
468 IPolyMeshSchema &schema,
478 PolyMeshSchemaData
data;
479 data.topology_variance = schema.getTopologyVariance();
480 data.time_sampling = schema.getTimeSampling();
481 data.positions = schema.getPositionsProperty();
482 data.face_counts = schema.getFaceCountsProperty();
483 data.face_indices = schema.getFaceIndicesProperty();
484 data.normals = schema.getNormalsParam();
485 data.num_samples = schema.getNumSamples();
486 data.shader_face_sets = parse_face_sets_for_shader_assignment(schema, get_used_shaders());
497 proc, cached_data, schema, schema.getUVsParam(), get_requested_attributes(),
progress);
503 cached_data.invalidate_last_loaded_time(
true);
507void AlembicObject::load_data_in_cache(CachedData &cached_data,
508 AlembicProcedural *proc,
519 if (this->get_ignore_subdivision()) {
520 PolyMeshSchemaData
data;
521 data.topology_variance = schema.getTopologyVariance();
522 data.time_sampling = schema.getTimeSampling();
523 data.positions = schema.getPositionsProperty();
524 data.face_counts = schema.getFaceCountsProperty();
525 data.face_indices = schema.getFaceIndicesProperty();
526 data.num_samples = schema.getNumSamples();
527 data.velocities = schema.getVelocitiesProperty();
528 data.shader_face_sets = parse_face_sets_for_shader_assignment(schema, get_used_shaders());
539 proc, cached_data, schema, schema.getUVsParam(), get_requested_attributes(),
progress);
541 cached_data.invalidate_last_loaded_time(
true);
547 data.time_sampling = schema.getTimeSampling();
548 data.num_samples = schema.getNumSamples();
549 data.topology_variance = schema.getTopologyVariance();
550 data.face_counts = schema.getFaceCountsProperty();
551 data.face_indices = schema.getFaceIndicesProperty();
552 data.positions = schema.getPositionsProperty();
553 data.face_varying_interpolate_boundary = schema.getFaceVaryingInterpolateBoundaryProperty();
554 data.face_varying_propagate_corners = schema.getFaceVaryingPropagateCornersProperty();
555 data.interpolate_boundary = schema.getInterpolateBoundaryProperty();
556 data.crease_indices = schema.getCreaseIndicesProperty();
557 data.crease_lengths = schema.getCreaseLengthsProperty();
558 data.crease_sharpnesses = schema.getCreaseSharpnessesProperty();
559 data.corner_indices = schema.getCornerIndicesProperty();
560 data.corner_sharpnesses = schema.getCornerSharpnessesProperty();
561 data.holes = schema.getHolesProperty();
562 data.subdivision_scheme = schema.getSubdivisionSchemeProperty();
563 data.velocities = schema.getVelocitiesProperty();
564 data.shader_face_sets = parse_face_sets_for_shader_assignment(schema, get_used_shaders());
575 proc, cached_data, schema, schema.getUVsParam(), get_requested_attributes(),
progress);
577 cached_data.invalidate_last_loaded_time(
true);
581void AlembicObject::load_data_in_cache(CachedData &cached_data,
582 AlembicProcedural *proc,
583 const ICurvesSchema &schema,
593 CurvesSchemaData
data;
594 data.positions = schema.getPositionsProperty();
595 data.position_weights = schema.getPositionWeightsProperty();
596 data.normals = schema.getNormalsParam();
597 data.knots = schema.getKnotsProperty();
598 data.orders = schema.getOrdersProperty();
599 data.widths = schema.getWidthsParam();
600 data.velocities = schema.getVelocitiesProperty();
601 data.time_sampling = schema.getTimeSampling();
602 data.topology_variance = schema.getTopologyVariance();
603 data.num_samples = schema.getNumSamples();
604 data.num_vertices = schema.getNumVerticesProperty();
605 data.default_radius = proc->get_default_radius();
606 data.radius_scale = get_radius_scale();
617 proc, cached_data, schema, schema.getUVsParam(), get_requested_attributes(),
progress);
619 cached_data.invalidate_last_loaded_time(
true);
623void AlembicObject::load_data_in_cache(CachedData &cached_data,
624 AlembicProcedural *proc,
625 const IPointsSchema &schema,
635 PointsSchemaData
data;
636 data.positions = schema.getPositionsProperty();
637 data.radiuses = schema.getWidthsParam();
638 data.velocities = schema.getVelocitiesProperty();
639 data.time_sampling = schema.getTimeSampling();
640 data.num_samples = schema.getNumSamples();
641 data.default_radius = proc->get_default_radius();
642 data.radius_scale = get_radius_scale();
652 read_attributes(proc, cached_data, schema, {}, get_requested_attributes(),
progress);
654 cached_data.invalidate_last_loaded_time(
true);
658void AlembicObject::setup_transform_cache(CachedData &cached_data,
float scale)
660 cached_data.transforms.clear();
661 cached_data.transforms.invalidate_last_loaded_time();
667 if (xform_time_sampling) {
668 cached_data.transforms.set_time_sampling(*xform_time_sampling);
671 if (xform_samples.empty()) {
673 cached_data.transforms.add_data(tfm, 0.0);
679 const M44d first_matrix = xform_samples.begin()->first;
680 bool has_animation =
false;
681 for (
const std::pair<chrono_t, M44d> pair : xform_samples) {
682 if (pair.second != first_matrix) {
683 has_animation =
true;
688 if (!has_animation) {
690 cached_data.transforms.add_data(tfm, 0.0);
693 for (
const std::pair<chrono_t, M44d> pair : xform_samples) {
695 cached_data.transforms.add_data(tfm, pair.first);
705 Geometry *geometry =
object->get_geometry();
708 for (
Node *node : geometry->get_used_shaders()) {
712 if (!attr.
name.empty()) {
713 requested_attributes.
add(attr.
name);
718 return requested_attributes;
724 CachedData &cached_data,
725 const double frame_time)
727 set<Attribute *> cached_attributes;
729 for (CachedData::CachedAttribute &attribute : cached_data.attributes) {
730 const CacheLookupResult<array<char>>
result = attribute.data.data_for_time(frame_time);
732 if (
result.has_no_data_for_time()) {
738 attr = attributes.
add(attribute.std, attribute.name);
741 attr = attributes.
add(attribute.name, attribute.type_desc, attribute.element);
745 cached_attributes.insert(attr);
747 if (!
result.has_new_data()) {
755 if (attr->
buffer.size() != attr_data.
size()) {
759 memcpy(attr->
data(), attr_data.
data(), attr_data.
size());
764 list<Attribute>::iterator it;
766 if (cached_attributes.find(&(*it)) == cached_attributes.end()) {
790 SOCKET_INT(prefetch_cache_size,
"Prefetch Cache Size", 4096);
795AlembicProcedural::AlembicProcedural() :
Procedural(get_node_type())
797 objects_loaded =
false;
801AlembicProcedural::~AlembicProcedural()
803 ccl::set<Geometry *> geometries_set;
804 ccl::set<Object *> objects_set;
805 const ccl::set<AlembicObject *> abc_objects_set;
807 for (
Node *node : nodes) {
808 AlembicObject *abc_object =
static_cast<AlembicObject *
>(node);
810 if (abc_object->get_object()) {
811 objects_set.insert(abc_object->get_object());
813 if (abc_object->get_object()->get_geometry()) {
814 geometries_set.insert(abc_object->get_object()->get_geometry());
821 assert(geometries_set.empty());
822 assert(objects_set.empty());
826 scene_->delete_nodes(geometries_set,
this);
827 scene_->delete_nodes(objects_set,
this);
832 assert(scene_ ==
nullptr || scene_ == scene);
835 if (frame < start_frame || frame > end_frame) {
837 objects_modified =
false;
841 bool need_shader_updates =
false;
842 bool need_data_updates =
false;
844 for (
Node *object_node : nodes) {
845 AlembicObject *
object =
static_cast<AlembicObject *
>(object_node);
847 if (object->is_modified()) {
848 need_data_updates =
true;
852 if (object->used_shaders_is_modified() && object->get_object() &&
853 object->get_object()->get_geometry())
855 Geometry *geometry =
object->get_object()->get_geometry();
857 geometry->set_used_shaders(used_shaders);
858 need_shader_updates =
true;
862 for (
Node *shader_node : object->get_used_shaders()) {
866 object->need_shader_update =
true;
867 need_shader_updates =
true;
872 if (!(is_modified() || objects_modified) && !need_shader_updates && !need_data_updates) {
876 if (!archive.valid() || filepath_is_modified() || layers_is_modified()) {
877 Alembic::AbcCoreFactory::IFactory factory;
878 factory.setPolicy(Alembic::Abc::ErrorHandler::kQuietNoopPolicy);
880 std::vector<std::string> filenames;
881 filenames.emplace_back(filepath.c_str());
883 for (
const ustring &layer : layers) {
884 filenames.emplace_back(layer.c_str());
888 std::reverse(filenames.begin(), filenames.end());
890 archive = factory.getArchive(filenames);
892 if (!archive.valid()) {
897 objects_modified =
false;
902 if (!objects_loaded || objects_modified) {
904 objects_loaded =
true;
907 const chrono_t frame_time = (chrono_t)((frame - frame_offset) / frame_rate);
910 for (
Node *node : nodes) {
911 AlembicObject *
object =
static_cast<AlembicObject *
>(node);
913 if (object->schema_type != AlembicObject::SUBD) {
917 if (object->ignore_subdivision_is_modified()) {
918 object->clear_cache();
922 if (use_prefetch_is_modified()) {
924 for (
Node *node : nodes) {
925 AlembicObject *
object =
static_cast<AlembicObject *
>(node);
926 object->clear_cache();
931 if (prefetch_cache_size_is_modified()) {
934 size_t memory_used = 0ul;
935 for (
Node *node : nodes) {
936 AlembicObject *
object =
static_cast<AlembicObject *
>(node);
937 memory_used +=
object->get_cached_data().memory_used();
940 if (memory_used > get_prefetch_cache_size_in_bytes()) {
941 progress.set_error(
"Error: Alembic Procedural memory limit reached");
948 for (
Node *node : nodes) {
949 AlembicObject *
object =
static_cast<AlembicObject *
>(node);
956 if (object->is_constant() && !object->is_modified() && !object->need_shader_update &&
957 !scale_is_modified())
962 if (object->schema_type == AlembicObject::POLY_MESH) {
963 read_mesh(
object, frame_time);
965 else if (object->schema_type == AlembicObject::CURVES) {
966 read_curves(
object, frame_time);
968 else if (object->schema_type == AlembicObject::POINTS) {
969 read_points(
object, frame_time);
971 else if (object->schema_type == AlembicObject::SUBD) {
972 read_subd(
object, frame_time);
975 object->need_shader_update =
false;
976 object->clear_modified();
980 objects_modified =
false;
983void AlembicProcedural::tag_update(
Scene *scene)
988AlembicObject *AlembicProcedural::get_or_create_object(
const ustring &path)
990 for (
Node *node : nodes) {
991 AlembicObject *
object =
static_cast<AlembicObject *
>(node);
993 if (object->get_path() == path) {
998 AlembicObject *
object = create_node<AlembicObject>();
999 object->set_path(path);
1000 objects_modified =
true;
1007 unordered_map<string, AlembicObject *> object_map;
1009 for (
Node *node : nodes) {
1010 AlembicObject *
object =
static_cast<AlembicObject *
>(node);
1013 if (object->get_object() ==
nullptr) {
1014 object_map.insert({
object->get_path().c_str(),
object});
1018 const IObject root = archive.getTop();
1020 for (
size_t i = 0;
i < root.getNumChildren(); ++
i) {
1021 walk_hierarchy(root, root.getChildHeader(
i), {}, object_map,
progress);
1025 for (
const std::pair<string, AlembicObject *> pair : object_map) {
1026 AlembicObject *abc_object = pair.second;
1030 if (!abc_object->instance_of) {
1031 if (abc_object->schema_type == AlembicObject::CURVES) {
1032 geometry = scene_->create_node<
Hair>();
1034 else if (abc_object->schema_type == AlembicObject::POINTS) {
1035 geometry = scene_->create_node<
PointCloud>();
1037 else if (abc_object->schema_type == AlembicObject::POLY_MESH ||
1038 abc_object->schema_type == AlembicObject::SUBD)
1040 geometry = scene_->create_node<
Mesh>();
1047 geometry->
name = abc_object->iobject.getName();
1049 array<Node *> used_shaders = abc_object->get_used_shaders();
1050 geometry->set_used_shaders(used_shaders);
1055 object->set_geometry(geometry);
1056 object->name = abc_object->iobject.getName();
1058 abc_object->set_object(
object);
1062 for (
Node *node : nodes) {
1063 AlembicObject *abc_object =
static_cast<AlembicObject *
>(node);
1065 if (abc_object->instance_of) {
1066 abc_object->get_object()->set_geometry(
1067 abc_object->instance_of->get_object()->get_geometry());
1068 abc_object->schema_type = abc_object->instance_of->schema_type;
1073void AlembicProcedural::read_mesh(AlembicObject *abc_object, Abc::chrono_t frame_time)
1075 CachedData &cached_data = abc_object->get_cached_data();
1079 Object *
object = abc_object->get_object();
1080 cached_data.transforms.copy_to_socket(frame_time,
object, object->get_tfm_socket());
1083 object->tag_update(scene_);
1087 if (abc_object->instance_of) {
1091 Mesh *mesh =
static_cast<Mesh *
>(
object->get_geometry());
1094 if (mesh->used_shaders_is_modified()) {
1095 mesh->tag_shader_modified();
1098 cached_data.vertices.copy_to_socket(frame_time, mesh, mesh->get_verts_socket());
1100 cached_data.shader.copy_to_socket(frame_time, mesh, mesh->get_shader_socket());
1102 array<int3> *triangle_data = cached_data.triangles.data_for_time(frame_time).get_data_or_null();
1103 if (triangle_data) {
1110 for (
size_t i = 0;
i < triangle_data->
size(); ++
i) {
1111 const int3 tri = (*triangle_data)[
i];
1118 mesh->set_triangles(triangles);
1119 mesh->set_smooth(smooth);
1124 update_attributes(mesh->
attributes, cached_data, frame_time);
1127 const bool need_rebuild = mesh->triangles_is_modified();
1132void AlembicProcedural::read_subd(AlembicObject *abc_object, Abc::chrono_t frame_time)
1134 if (abc_object->get_ignore_subdivision()) {
1135 read_mesh(abc_object, frame_time);
1139 CachedData &cached_data = abc_object->get_cached_data();
1143 Object *
object = abc_object->get_object();
1144 cached_data.transforms.copy_to_socket(frame_time,
object, object->get_tfm_socket());
1147 object->tag_update(scene_);
1151 if (abc_object->instance_of) {
1155 if (abc_object->subd_max_level_is_modified() || abc_object->subd_dicing_rate_is_modified()) {
1157 cached_data.invalidate_last_loaded_time();
1160 Mesh *mesh =
static_cast<Mesh *
>(
object->get_geometry());
1163 if (mesh->used_shaders_is_modified()) {
1164 mesh->tag_shader_modified();
1169 if (!cached_data.is_constant()) {
1170 cached_data.invalidate_last_loaded_time();
1174 mesh->set_triangles(triangles);
1181 mesh->set_subd_max_level(abc_object->get_subd_max_level());
1182 mesh->set_subd_dicing_rate(abc_object->get_subd_dicing_rate());
1184 cached_data.vertices.copy_to_socket(frame_time, mesh, mesh->get_verts_socket());
1187 cached_data.shader.copy_to_socket(frame_time, mesh, mesh->get_subd_shader_socket());
1189 cached_data.subd_start_corner.copy_to_socket(
1190 frame_time, mesh, mesh->get_subd_start_corner_socket());
1192 cached_data.subd_num_corners.copy_to_socket(
1193 frame_time, mesh, mesh->get_subd_num_corners_socket());
1195 cached_data.subd_smooth.copy_to_socket(frame_time, mesh, mesh->get_subd_smooth_socket());
1197 cached_data.subd_ptex_offset.copy_to_socket(
1198 frame_time, mesh, mesh->get_subd_ptex_offset_socket());
1200 cached_data.subd_face_corners.copy_to_socket(
1201 frame_time, mesh, mesh->get_subd_face_corners_socket());
1203 cached_data.subd_creases_edge.copy_to_socket(
1204 frame_time, mesh, mesh->get_subd_creases_edge_socket());
1206 cached_data.subd_creases_weight.copy_to_socket(
1207 frame_time, mesh, mesh->get_subd_creases_weight_socket());
1209 cached_data.subd_vertex_crease_indices.copy_to_socket(
1210 frame_time, mesh, mesh->get_subd_vert_creases_socket());
1212 cached_data.subd_vertex_crease_weights.copy_to_socket(
1213 frame_time, mesh, mesh->get_subd_vert_creases_weight_socket());
1222 const bool need_rebuild = (mesh->triangles_is_modified()) ||
1223 (mesh->subd_num_corners_is_modified()) ||
1224 (mesh->subd_shader_is_modified()) ||
1225 (mesh->subd_smooth_is_modified()) ||
1226 (mesh->subd_ptex_offset_is_modified()) ||
1227 (mesh->subd_start_corner_is_modified()) ||
1228 (mesh->subd_face_corners_is_modified());
1234void AlembicProcedural::read_curves(AlembicObject *abc_object, Abc::chrono_t frame_time)
1236 CachedData &cached_data = abc_object->get_cached_data();
1240 Object *
object = abc_object->get_object();
1241 cached_data.transforms.copy_to_socket(frame_time,
object, object->get_tfm_socket());
1244 object->tag_update(scene_);
1248 if (abc_object->instance_of) {
1252 Hair *hair =
static_cast<Hair *
>(
object->get_geometry());
1255 if (hair->used_shaders_is_modified()) {
1256 hair->tag_curve_shader_modified();
1259 cached_data.curve_keys.copy_to_socket(frame_time, hair, hair->get_curve_keys_socket());
1261 cached_data.curve_radius.copy_to_socket(frame_time, hair, hair->get_curve_radius_socket());
1263 cached_data.curve_shader.copy_to_socket(frame_time, hair, hair->get_curve_shader_socket());
1265 cached_data.curve_first_key.copy_to_socket(frame_time, hair, hair->get_curve_first_key_socket());
1269 update_attributes(hair->
attributes, cached_data, frame_time);
1271 const bool rebuild = (hair->curve_keys_is_modified() || hair->curve_radius_is_modified());
1275void AlembicProcedural::read_points(AlembicObject *abc_object, Abc::chrono_t frame_time)
1277 CachedData &cached_data = abc_object->get_cached_data();
1281 Object *
object = abc_object->get_object();
1282 cached_data.transforms.copy_to_socket(frame_time,
object, object->get_tfm_socket());
1285 object->tag_update(scene_);
1289 if (abc_object->instance_of) {
1296 if (point_cloud->used_shaders_is_modified()) {
1297 point_cloud->tag_shader_modified();
1300 cached_data.points.copy_to_socket(frame_time, point_cloud, point_cloud->get_points_socket());
1301 cached_data.radiuses.copy_to_socket(frame_time, point_cloud, point_cloud->get_radius_socket());
1302 cached_data.points_shader.copy_to_socket(
1303 frame_time, point_cloud, point_cloud->get_shader_socket());
1307 update_attributes(point_cloud->
attributes, cached_data, frame_time);
1309 const bool rebuild = (point_cloud->points_is_modified() || point_cloud->radius_is_modified() ||
1310 point_cloud->shader_is_modified());
1314void AlembicProcedural::walk_hierarchy(
1316 const ObjectHeader &header,
1317 MatrixSamplesData matrix_samples_data,
1318 const unordered_map<std::string, AlembicObject *> &object_map,
1325 IObject next_object;
1327 MatrixSampleMap concatenated_xform_samples;
1329 if (IXform::matches(header)) {
1330 IXform xform(parent, header.getName());
1332 const IXformSchema &xs = xform.getSchema();
1334 if (xs.getNumOps() > 0) {
1335 const TimeSamplingPtr ts = xs.getTimeSampling();
1336 MatrixSampleMap local_xform_samples;
1338 MatrixSampleMap *temp_xform_samples =
nullptr;
1339 if (matrix_samples_data.samples ==
nullptr) {
1341 temp_xform_samples = &concatenated_xform_samples;
1345 temp_xform_samples = &local_xform_samples;
1348 for (
size_t i = 0;
i < xs.getNumSamples(); ++
i) {
1349 const chrono_t sample_time = ts->getSampleTime(index_t(
i));
1350 const XformSample
sample = xs.getValue(ISampleSelector(sample_time));
1351 temp_xform_samples->insert({sample_time,
sample.getMatrix()});
1354 if (matrix_samples_data.samples !=
nullptr) {
1355 concatenate_xform_samples(
1356 *matrix_samples_data.samples, local_xform_samples, concatenated_xform_samples);
1359 matrix_samples_data.samples = &concatenated_xform_samples;
1360 matrix_samples_data.time_sampling = ts;
1363 next_object = xform;
1365 else if (ISubD::matches(header)) {
1366 const ISubD subd(parent, header.getName());
1368 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1369 iter = object_map.find(subd.getFullName());
1371 if (iter != object_map.end()) {
1372 AlembicObject *abc_object = iter->second;
1373 abc_object->iobject = subd;
1374 abc_object->schema_type = AlembicObject::SUBD;
1376 if (matrix_samples_data.samples) {
1377 abc_object->xform_samples = *matrix_samples_data.samples;
1378 abc_object->xform_time_sampling = matrix_samples_data.time_sampling;
1384 else if (IPolyMesh::matches(header)) {
1385 const IPolyMesh mesh(parent, header.getName());
1387 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1388 iter = object_map.find(mesh.getFullName());
1390 if (iter != object_map.end()) {
1391 AlembicObject *abc_object = iter->second;
1392 abc_object->iobject = mesh;
1393 abc_object->schema_type = AlembicObject::POLY_MESH;
1395 if (matrix_samples_data.samples) {
1396 abc_object->xform_samples = *matrix_samples_data.samples;
1397 abc_object->xform_time_sampling = matrix_samples_data.time_sampling;
1403 else if (ICurves::matches(header)) {
1404 const ICurves curves(parent, header.getName());
1406 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1407 iter = object_map.find(curves.getFullName());
1409 if (iter != object_map.end()) {
1410 AlembicObject *abc_object = iter->second;
1411 abc_object->iobject = curves;
1412 abc_object->schema_type = AlembicObject::CURVES;
1414 if (matrix_samples_data.samples) {
1415 abc_object->xform_samples = *matrix_samples_data.samples;
1416 abc_object->xform_time_sampling = matrix_samples_data.time_sampling;
1420 next_object = curves;
1422 else if (IFaceSet::matches(header)) {
1425 else if (IPoints::matches(header)) {
1426 const IPoints points(parent, header.getName());
1428 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1429 iter = object_map.find(points.getFullName());
1431 if (iter != object_map.end()) {
1432 AlembicObject *abc_object = iter->second;
1433 abc_object->iobject = points;
1434 abc_object->schema_type = AlembicObject::POINTS;
1436 if (matrix_samples_data.samples) {
1437 abc_object->xform_samples = *matrix_samples_data.samples;
1438 abc_object->xform_time_sampling = matrix_samples_data.time_sampling;
1442 next_object = points;
1444 else if (INuPatch::matches(header)) {
1448 next_object = parent.getChild(header.getName());
1450 if (next_object.isInstanceRoot()) {
1451 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1454 iter = object_map.find(next_object.getFullName());
1456 if (iter != object_map.end()) {
1457 AlembicObject *abc_object = iter->second;
1460 iter = object_map.find(next_object.instanceSourcePath());
1462 if (iter != object_map.end()) {
1463 abc_object->iobject = next_object;
1464 abc_object->instance_of = iter->second;
1466 if (matrix_samples_data.samples) {
1467 abc_object->xform_samples = *matrix_samples_data.samples;
1468 abc_object->xform_time_sampling = matrix_samples_data.time_sampling;
1475 if (next_object.valid()) {
1476 for (
size_t i = 0;
i < next_object.getNumChildren(); ++
i) {
1478 next_object, next_object.getChildHeader(
i), matrix_samples_data, object_map,
progress);
1485 size_t memory_used = 0;
1487 for (
Node *node : nodes) {
1488 AlembicObject *
object =
static_cast<AlembicObject *
>(node);
1494 if (object->schema_type == AlembicObject::POLY_MESH) {
1495 if (!object->has_data_loaded()) {
1496 IPolyMesh polymesh(object->iobject, Alembic::Abc::kWrapExisting);
1497 IPolyMeshSchema schema = polymesh.getSchema();
1498 object->load_data_in_cache(object->get_cached_data(),
this, schema,
progress);
1500 else if (object->need_shader_update) {
1501 IPolyMesh polymesh(object->iobject, Alembic::Abc::kWrapExisting);
1502 const IPolyMeshSchema schema = polymesh.getSchema();
1503 read_attributes(
this,
1504 object->get_cached_data(),
1506 schema.getUVsParam(),
1507 object->get_requested_attributes(),
1511 else if (object->schema_type == AlembicObject::CURVES) {
1512 if (!object->has_data_loaded() || default_radius_is_modified() ||
1513 object->radius_scale_is_modified())
1515 ICurves curves(object->iobject, Alembic::Abc::kWrapExisting);
1516 const ICurvesSchema schema = curves.getSchema();
1517 object->load_data_in_cache(object->get_cached_data(),
this, schema,
progress);
1520 else if (object->schema_type == AlembicObject::POINTS) {
1521 if (!object->has_data_loaded() || default_radius_is_modified() ||
1522 object->radius_scale_is_modified())
1524 IPoints points(object->iobject, Alembic::Abc::kWrapExisting);
1525 const IPointsSchema schema = points.getSchema();
1526 object->load_data_in_cache(object->get_cached_data(),
this, schema,
progress);
1529 else if (object->schema_type == AlembicObject::SUBD) {
1530 if (!object->has_data_loaded()) {
1531 ISubD subd_mesh(object->iobject, Alembic::Abc::kWrapExisting);
1532 ISubDSchema schema = subd_mesh.getSchema();
1533 object->load_data_in_cache(object->get_cached_data(),
this, schema,
progress);
1535 else if (object->need_shader_update) {
1536 ISubD subd_mesh(object->iobject, Alembic::Abc::kWrapExisting);
1537 const ISubDSchema schema = subd_mesh.getSchema();
1538 read_attributes(
this,
1539 object->get_cached_data(),
1541 schema.getUVsParam(),
1542 object->get_requested_attributes(),
1547 if (scale_is_modified() || object->get_cached_data().transforms.size() == 0) {
1548 object->setup_transform_cache(object->get_cached_data(), scale);
1551 memory_used +=
object->get_cached_data().memory_used();
1554 if (memory_used > get_prefetch_cache_size_in_bytes()) {
1555 progress.set_error(
"Error: Alembic Procedural memory limit reached");
BMesh const char void * data
vector< AttributeRequest > requests
list< Attribute > attributes
Attribute * add(ustring name, const TypeDesc type, AttributeElement element)
void remove(ustring name)
void tag_update(Scene *scene, bool rebuild)
bool need_update_geometry() const
AttributeRequestSet attributes
void push_back_reserved(const T &t)
void reserve(const size_t newcapacity)
#define CCL_NAMESPACE_END
#define assert(assertion)
MatBase< T, NumCol, NumRow > scale(const MatBase< T, NumCol, NumRow > &mat, const VectorT &scale)
#define SOCKET_NODE_ARRAY(name, ui_name, node_type,...)
#define SOCKET_FLOAT(name, ui_name, default_value,...)
#define SOCKET_INT(name, ui_name, default_value,...)
#define NODE_DEFINE(structname)
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
#define SOCKET_STRING_ARRAY(name, ui_name, default_value,...)
#define SOCKET_STRING(name, ui_name, default_value,...)
string string_human_readable_size(size_t size)
AttributeSet subd_attributes
void set_num_subd_faces(const size_t num_subd_faces_)
@ SUBDIVISION_CATMULL_CLARK
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=nullptr)
void set_owner(const NodeOwner *owner_)
unique_ptr< ProceduralManager > procedural_manager