24using namespace Alembic::AbcGeom;
30template<
typename SchemaType>
36 std::vector<std::string> face_set_names;
37 schema.getFaceSetNames(face_set_names);
39 if (face_set_names.empty()) {
43 for (
const std::string &face_set_name : face_set_names) {
46 for (
Node *node : used_shaders) {
47 if (node->name == face_set_name) {
54 if (shader_index >= used_shaders.
size()) {
59 const Alembic::AbcGeom::IFaceSet face_set = schema.getFaceSet(face_set_name);
61 if (!face_set.valid()) {
65 result.push_back({face_set, shader_index});
71void CachedData::clear()
74 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(num_ngons)
129 CHECK_IF_CONSTANT(shader)
130 CHECK_IF_CONSTANT(subd_creases_edge)
131 CHECK_IF_CONSTANT(subd_creases_weight)
132 CHECK_IF_CONSTANT(subd_face_corners)
133 CHECK_IF_CONSTANT(subd_num_corners)
134 CHECK_IF_CONSTANT(subd_ptex_offset)
135 CHECK_IF_CONSTANT(subd_smooth)
136 CHECK_IF_CONSTANT(subd_start_corner)
137 CHECK_IF_CONSTANT(transforms)
138 CHECK_IF_CONSTANT(triangles)
139 CHECK_IF_CONSTANT(uv_loops)
140 CHECK_IF_CONSTANT(vertices)
141 CHECK_IF_CONSTANT(points)
142 CHECK_IF_CONSTANT(radiuses)
143 CHECK_IF_CONSTANT(points_shader)
145 for (
const CachedAttribute &attr : attributes) {
146 if (!attr.data.is_constant()) {
153# undef CHECK_IF_CONSTANT
156void CachedData::invalidate_last_loaded_time(
bool attributes_only)
158 if (attributes_only) {
159 for (CachedAttribute &attr : attributes) {
160 attr.data.invalidate_last_loaded_time();
166 curve_first_key.invalidate_last_loaded_time();
167 curve_keys.invalidate_last_loaded_time();
168 curve_radius.invalidate_last_loaded_time();
169 curve_shader.invalidate_last_loaded_time();
170 num_ngons.invalidate_last_loaded_time();
171 shader.invalidate_last_loaded_time();
172 subd_creases_edge.invalidate_last_loaded_time();
173 subd_creases_weight.invalidate_last_loaded_time();
174 subd_face_corners.invalidate_last_loaded_time();
175 subd_num_corners.invalidate_last_loaded_time();
176 subd_ptex_offset.invalidate_last_loaded_time();
177 subd_smooth.invalidate_last_loaded_time();
178 subd_start_corner.invalidate_last_loaded_time();
179 transforms.invalidate_last_loaded_time();
180 triangles.invalidate_last_loaded_time();
181 uv_loops.invalidate_last_loaded_time();
182 vertices.invalidate_last_loaded_time();
183 points.invalidate_last_loaded_time();
184 radiuses.invalidate_last_loaded_time();
185 points_shader.invalidate_last_loaded_time();
188void CachedData::set_time_sampling(TimeSampling time_sampling)
190 curve_first_key.set_time_sampling(time_sampling);
191 curve_keys.set_time_sampling(time_sampling);
192 curve_radius.set_time_sampling(time_sampling);
193 curve_shader.set_time_sampling(time_sampling);
194 num_ngons.set_time_sampling(time_sampling);
195 shader.set_time_sampling(time_sampling);
196 subd_creases_edge.set_time_sampling(time_sampling);
197 subd_creases_weight.set_time_sampling(time_sampling);
198 subd_face_corners.set_time_sampling(time_sampling);
199 subd_num_corners.set_time_sampling(time_sampling);
200 subd_ptex_offset.set_time_sampling(time_sampling);
201 subd_smooth.set_time_sampling(time_sampling);
202 subd_start_corner.set_time_sampling(time_sampling);
203 transforms.set_time_sampling(time_sampling);
204 triangles.set_time_sampling(time_sampling);
205 uv_loops.set_time_sampling(time_sampling);
206 vertices.set_time_sampling(time_sampling);
207 points.set_time_sampling(time_sampling);
208 radiuses.set_time_sampling(time_sampling);
209 points_shader.set_time_sampling(time_sampling);
211 for (CachedAttribute &attr : attributes) {
212 attr.data.set_time_sampling(time_sampling);
216size_t CachedData::memory_used()
const
220 mem_used += curve_first_key.memory_used();
221 mem_used += curve_keys.memory_used();
222 mem_used += curve_radius.memory_used();
223 mem_used += curve_shader.memory_used();
224 mem_used += num_ngons.memory_used();
225 mem_used += shader.memory_used();
226 mem_used += subd_creases_edge.memory_used();
227 mem_used += subd_creases_weight.memory_used();
228 mem_used += subd_face_corners.memory_used();
229 mem_used += subd_num_corners.memory_used();
230 mem_used += subd_ptex_offset.memory_used();
231 mem_used += subd_smooth.memory_used();
232 mem_used += subd_start_corner.memory_used();
233 mem_used += transforms.memory_used();
234 mem_used += triangles.memory_used();
235 mem_used += uv_loops.memory_used();
236 mem_used += vertices.memory_used();
237 mem_used += points.memory_used();
238 mem_used += radiuses.memory_used();
239 mem_used += points_shader.memory_used();
241 for (
const CachedAttribute &attr : attributes) {
242 mem_used += attr.data.memory_used();
248static M44d convert_yup_zup(
const M44d &mtx,
float scale_mult)
250 V3d scale, shear, rotation, translation;
252 if (!extractSHRT(mtx,
258 IMATH_INTERNAL_NAMESPACE::Euler<double>::XZY))
263 M44d rot_mat, scale_mat, trans_mat;
264 rot_mat.setEulerAngles(V3d(rotation.x, -rotation.z, rotation.y));
265 scale_mat.setScale(V3d(scale.x, scale.z, scale.y));
266 trans_mat.setTranslation(V3d(translation.x, -translation.z, translation.y));
268 M44d temp_mat = scale_mat * rot_mat * trans_mat;
270 scale_mat.setScale(
static_cast<double>(scale_mult));
272 return temp_mat * scale_mat;
276 const M44d &mat, V3d &scale, V3d &shear, Quatd &rotation, V3d &translation)
278 M44d mat_remainder(mat);
281 Imath::extractAndRemoveScalingAndShear(mat_remainder, scale, shear);
284 translation.x = mat_remainder[3][0];
285 translation.y = mat_remainder[3][1];
286 translation.z = mat_remainder[3][2];
289 rotation = extractQuat(mat_remainder);
294 const Quatd &rotation,
295 const V3d &translation)
297 M44d scale_mat, shear_mat, rot_mat, trans_mat;
299 scale_mat.setScale(scale);
300 shear_mat.setShear(shear);
301 rot_mat = rotation.toMatrix44();
302 trans_mat.setTranslation(translation);
304 return scale_mat * shear_mat * rot_mat * trans_mat;
309static M44d get_matrix_for_time(
const MatrixSampleMap &samples, chrono_t time)
311 MatrixSampleMap::const_iterator iter = samples.find(time);
312 if (iter != samples.end()) {
321static M44d get_interpolated_matrix_for_time(
const MatrixSampleMap &samples, chrono_t time)
323 if (samples.empty()) {
328 MatrixSampleMap::const_iterator iter = samples.find(time);
329 if (iter != samples.end()) {
333 if (samples.size() == 1) {
334 return samples.begin()->second;
337 if (time <= samples.begin()->first) {
338 return samples.begin()->second;
341 if (time >= samples.rbegin()->first) {
342 return samples.rbegin()->second;
346 chrono_t prev_time = samples.begin()->first;
347 chrono_t next_time = samples.rbegin()->first;
349 for (MatrixSampleMap::const_iterator
I = samples.begin();
I != samples.end(); ++
I) {
350 chrono_t current_time = (*I).first;
352 if (current_time > prev_time && current_time <= time) {
353 prev_time = current_time;
356 if (current_time > next_time && current_time >= time) {
357 next_time = current_time;
361 const M44d prev_mat = get_matrix_for_time(samples, prev_time);
362 const M44d next_mat = get_matrix_for_time(samples, next_time);
364 V3d prev_scale, next_scale;
365 V3d prev_shear, next_shear;
366 V3d prev_translation, next_translation;
367 Quatd prev_rotation, next_rotation;
372 chrono_t t = (time - prev_time) / (next_time - prev_time);
375 if ((prev_rotation ^ next_rotation) < 0) {
376 next_rotation = -next_rotation;
380 Imath::lerp(prev_shear, next_shear, t),
381 Imath::slerp(prev_rotation, next_rotation, t),
382 Imath::lerp(prev_translation, next_translation, t));
385static void concatenate_xform_samples(
const MatrixSampleMap &parent_samples,
386 const MatrixSampleMap &local_samples,
387 MatrixSampleMap &output_samples)
389 set<chrono_t> union_of_samples;
391 for (
const std::pair<chrono_t, M44d> pair : parent_samples) {
392 union_of_samples.insert(pair.first);
395 for (
const std::pair<chrono_t, M44d> pair : local_samples) {
396 union_of_samples.insert(pair.first);
399 foreach (chrono_t time, union_of_samples) {
400 M44d parent_matrix = get_interpolated_matrix_for_time(parent_samples, time);
401 M44d local_matrix = get_interpolated_matrix_for_time(local_samples, time);
403 output_samples[
time] = local_matrix * parent_matrix;
409 M44d m = convert_yup_zup(a, scale);
411 for (
int j = 0; j < 3; j++) {
412 for (
int i = 0; i < 4; i++) {
413 trans[j][i] =
static_cast<float>(m[i][j]);
428 SOCKET_INT(subd_max_level,
"Max Subdivision Level", 1);
429 SOCKET_FLOAT(subd_dicing_rate,
"Subdivision Dicing Rate", 1.0f);
436AlembicObject::AlembicObject() :
Node(get_node_type())
438 schema_type = INVALID;
441AlembicObject::~AlembicObject() {}
443void AlembicObject::set_object(
Object *object_)
448Object *AlembicObject::get_object()
453bool AlembicObject::has_data_loaded()
const
458void AlembicObject::load_data_in_cache(CachedData &cached_data,
459 AlembicProcedural *proc,
460 IPolyMeshSchema &schema,
470 PolyMeshSchemaData
data;
471 data.topology_variance = schema.getTopologyVariance();
472 data.time_sampling = schema.getTimeSampling();
473 data.positions = schema.getPositionsProperty();
474 data.face_counts = schema.getFaceCountsProperty();
475 data.face_indices = schema.getFaceIndicesProperty();
476 data.normals = schema.getNormalsParam();
477 data.num_samples = schema.getNumSamples();
478 data.shader_face_sets = parse_face_sets_for_shader_assignment(schema, get_used_shaders());
480 read_geometry_data(proc, cached_data, data, progress);
489 proc, cached_data, schema, schema.getUVsParam(), get_requested_attributes(), progress);
495 cached_data.invalidate_last_loaded_time(
true);
499void AlembicObject::load_data_in_cache(CachedData &cached_data,
500 AlembicProcedural *proc,
511 if (this->get_ignore_subdivision()) {
512 PolyMeshSchemaData
data;
513 data.topology_variance = schema.getTopologyVariance();
514 data.time_sampling = schema.getTimeSampling();
515 data.positions = schema.getPositionsProperty();
516 data.face_counts = schema.getFaceCountsProperty();
517 data.face_indices = schema.getFaceIndicesProperty();
518 data.num_samples = schema.getNumSamples();
519 data.velocities = schema.getVelocitiesProperty();
520 data.shader_face_sets = parse_face_sets_for_shader_assignment(schema, get_used_shaders());
522 read_geometry_data(proc, cached_data, data, progress);
531 proc, cached_data, schema, schema.getUVsParam(), get_requested_attributes(), progress);
533 cached_data.invalidate_last_loaded_time(
true);
539 data.time_sampling = schema.getTimeSampling();
540 data.num_samples = schema.getNumSamples();
541 data.topology_variance = schema.getTopologyVariance();
542 data.face_counts = schema.getFaceCountsProperty();
543 data.face_indices = schema.getFaceIndicesProperty();
544 data.positions = schema.getPositionsProperty();
545 data.face_varying_interpolate_boundary = schema.getFaceVaryingInterpolateBoundaryProperty();
546 data.face_varying_propagate_corners = schema.getFaceVaryingPropagateCornersProperty();
547 data.interpolate_boundary = schema.getInterpolateBoundaryProperty();
548 data.crease_indices = schema.getCreaseIndicesProperty();
549 data.crease_lengths = schema.getCreaseLengthsProperty();
550 data.crease_sharpnesses = schema.getCreaseSharpnessesProperty();
551 data.corner_indices = schema.getCornerIndicesProperty();
552 data.corner_sharpnesses = schema.getCornerSharpnessesProperty();
553 data.holes = schema.getHolesProperty();
554 data.subdivision_scheme = schema.getSubdivisionSchemeProperty();
555 data.velocities = schema.getVelocitiesProperty();
556 data.shader_face_sets = parse_face_sets_for_shader_assignment(schema, get_used_shaders());
558 read_geometry_data(proc, cached_data, data, progress);
567 proc, cached_data, schema, schema.getUVsParam(), get_requested_attributes(), progress);
569 cached_data.invalidate_last_loaded_time(
true);
573void AlembicObject::load_data_in_cache(CachedData &cached_data,
574 AlembicProcedural *proc,
575 const ICurvesSchema &schema,
585 CurvesSchemaData
data;
586 data.positions = schema.getPositionsProperty();
587 data.position_weights = schema.getPositionWeightsProperty();
588 data.normals = schema.getNormalsParam();
589 data.knots = schema.getKnotsProperty();
590 data.orders = schema.getOrdersProperty();
591 data.widths = schema.getWidthsParam();
592 data.velocities = schema.getVelocitiesProperty();
593 data.time_sampling = schema.getTimeSampling();
594 data.topology_variance = schema.getTopologyVariance();
595 data.num_samples = schema.getNumSamples();
596 data.num_vertices = schema.getNumVerticesProperty();
597 data.default_radius = proc->get_default_radius();
598 data.radius_scale = get_radius_scale();
600 read_geometry_data(proc, cached_data, data, progress);
609 proc, cached_data, schema, schema.getUVsParam(), get_requested_attributes(), progress);
611 cached_data.invalidate_last_loaded_time(
true);
615void AlembicObject::load_data_in_cache(CachedData &cached_data,
616 AlembicProcedural *proc,
617 const IPointsSchema &schema,
627 PointsSchemaData
data;
628 data.positions = schema.getPositionsProperty();
629 data.radiuses = schema.getWidthsParam();
630 data.velocities = schema.getVelocitiesProperty();
631 data.time_sampling = schema.getTimeSampling();
632 data.num_samples = schema.getNumSamples();
633 data.default_radius = proc->get_default_radius();
634 data.radius_scale = get_radius_scale();
636 read_geometry_data(proc, cached_data, data, progress);
644 read_attributes(proc, cached_data, schema, {}, get_requested_attributes(), progress);
646 cached_data.invalidate_last_loaded_time(
true);
650void AlembicObject::setup_transform_cache(CachedData &cached_data,
float scale)
652 cached_data.transforms.clear();
653 cached_data.transforms.invalidate_last_loaded_time();
659 if (xform_time_sampling) {
660 cached_data.transforms.set_time_sampling(*xform_time_sampling);
663 if (xform_samples.size() == 0) {
665 cached_data.transforms.add_data(tfm, 0.0);
671 M44d first_matrix = xform_samples.begin()->first;
672 bool has_animation =
false;
673 for (
const std::pair<chrono_t, M44d> pair : xform_samples) {
674 if (pair.second != first_matrix) {
675 has_animation =
true;
680 if (!has_animation) {
682 cached_data.transforms.add_data(tfm, 0.0);
685 for (
const std::pair<chrono_t, M44d> pair : xform_samples) {
687 cached_data.transforms.add_data(tfm, pair.first);
697 Geometry *geometry =
object->get_geometry();
700 foreach (
Node *node, geometry->get_used_shaders()) {
704 if (attr.
name !=
"") {
705 requested_attributes.
add(attr.
name);
710 return requested_attributes;
715static void update_attributes(
AttributeSet &attributes, CachedData &cached_data,
double frame_time)
717 set<Attribute *> cached_attributes;
719 for (CachedData::CachedAttribute &attribute : cached_data.attributes) {
720 const CacheLookupResult<array<char>> result = attribute.data.data_for_time(frame_time);
722 if (result.has_no_data_for_time()) {
728 attr = attributes.
add(attribute.std, attribute.name);
731 attr = attributes.
add(attribute.name, attribute.type_desc, attribute.element);
735 cached_attributes.insert(attr);
737 if (!result.has_new_data()) {
741 const ccl::array<char> &attr_data = result.get_data();
745 if (attr->
buffer.size() != attr_data.size()) {
746 attr->
buffer.resize(attr_data.size());
749 memcpy(attr->
data(), attr_data.data(), attr_data.size());
754 list<Attribute>::iterator it;
755 for (it = attributes.attributes.begin(); it != attributes.attributes.end();) {
756 if (cached_attributes.find(&(*it)) == cached_attributes.end()) {
757 attributes.remove(it++);
782 SOCKET_INT(prefetch_cache_size,
"Prefetch Cache Size", 4096);
787AlembicProcedural::AlembicProcedural() :
Procedural(get_node_type())
789 objects_loaded =
false;
793AlembicProcedural::~AlembicProcedural()
795 ccl::set<Geometry *> geometries_set;
796 ccl::set<Object *> objects_set;
797 ccl::set<AlembicObject *> abc_objects_set;
799 foreach (
Node *node, objects) {
800 AlembicObject *abc_object =
static_cast<AlembicObject *
>(
node);
802 if (abc_object->get_object()) {
803 objects_set.insert(abc_object->get_object());
805 if (abc_object->get_object()->get_geometry()) {
806 geometries_set.insert(abc_object->get_object()->get_geometry());
810 delete_node(abc_object);
815 assert(geometries_set.empty());
816 assert(objects_set.empty());
824void AlembicProcedural::generate(
Scene *scene,
Progress &progress)
826 assert(scene_ ==
nullptr || scene_ == scene);
829 if (frame < start_frame || frame > end_frame) {
834 bool need_shader_updates =
false;
835 bool need_data_updates =
false;
837 foreach (
Node *object_node, objects) {
838 AlembicObject *
object =
static_cast<AlembicObject *
>(object_node);
840 if (object->is_modified()) {
841 need_data_updates =
true;
845 if (object->used_shaders_is_modified() &&
object->get_object() &&
846 object->get_object()->get_geometry())
848 Geometry *geometry =
object->get_object()->get_geometry();
850 geometry->set_used_shaders(used_shaders);
851 need_shader_updates =
true;
855 foreach (
Node *shader_node, object->get_used_shaders()) {
858 if (shader->need_update_geometry()) {
859 object->need_shader_update =
true;
860 need_shader_updates =
true;
865 if (!is_modified() && !need_shader_updates && !need_data_updates) {
869 if (!archive.valid() || filepath_is_modified() || layers_is_modified()) {
870 Alembic::AbcCoreFactory::IFactory factory;
871 factory.setPolicy(Alembic::Abc::ErrorHandler::kQuietNoopPolicy);
873 std::vector<std::string> filenames;
874 filenames.push_back(filepath.c_str());
876 for (
const ustring &layer : layers) {
877 filenames.push_back(layer.c_str());
881 std::reverse(filenames.begin(), filenames.end());
883 archive = factory.getArchive(filenames);
885 if (!archive.valid()) {
894 if (!objects_loaded || objects_is_modified()) {
895 load_objects(progress);
896 objects_loaded =
true;
899 const chrono_t frame_time = (chrono_t)((frame - frame_offset) / frame_rate);
902 for (
Node *node : objects) {
903 AlembicObject *
object =
static_cast<AlembicObject *
>(
node);
905 if (object->schema_type != AlembicObject::SUBD) {
909 if (object->ignore_subdivision_is_modified()) {
910 object->clear_cache();
914 if (use_prefetch_is_modified()) {
916 for (
Node *node : objects) {
917 AlembicObject *
object =
static_cast<AlembicObject *
>(
node);
918 object->clear_cache();
923 if (prefetch_cache_size_is_modified()) {
926 size_t memory_used = 0ul;
927 for (
Node *node : objects) {
928 AlembicObject *
object =
static_cast<AlembicObject *
>(
node);
929 memory_used +=
object->get_cached_data().memory_used();
932 if (memory_used > get_prefetch_cache_size_in_bytes()) {
933 progress.
set_error(
"Error: Alembic Procedural memory limit reached");
938 build_caches(progress);
940 foreach (
Node *node, objects) {
941 AlembicObject *
object =
static_cast<AlembicObject *
>(
node);
948 if (object->is_constant() && !
object->is_modified() && !
object->need_shader_update &&
949 !scale_is_modified())
954 if (object->schema_type == AlembicObject::POLY_MESH) {
955 read_mesh(
object, frame_time);
957 else if (object->schema_type == AlembicObject::CURVES) {
958 read_curves(
object, frame_time);
960 else if (object->schema_type == AlembicObject::POINTS) {
961 read_points(
object, frame_time);
963 else if (object->schema_type == AlembicObject::SUBD) {
964 read_subd(
object, frame_time);
967 object->need_shader_update =
false;
968 object->clear_modified();
974void AlembicProcedural::add_object(AlembicObject *
object)
976 objects.push_back_slow(
object);
977 tag_objects_modified();
980void AlembicProcedural::tag_update(
Scene *scene)
982 scene->procedural_manager->tag_update();
985AlembicObject *AlembicProcedural::get_or_create_object(
const ustring &path)
987 foreach (
Node *node, objects) {
988 AlembicObject *
object =
static_cast<AlembicObject *
>(
node);
990 if (object->get_path() == path) {
995 AlembicObject *
object = create_node<AlembicObject>();
996 object->set_path(path);
1003void AlembicProcedural::load_objects(
Progress &progress)
1005 unordered_map<string, AlembicObject *> object_map;
1007 foreach (
Node *node, objects) {
1008 AlembicObject *
object =
static_cast<AlembicObject *
>(
node);
1011 if (object->get_object() ==
nullptr) {
1012 object_map.insert({
object->get_path().c_str(),
object});
1016 IObject root = archive.getTop();
1018 for (
size_t i = 0; i < root.getNumChildren(); ++i) {
1019 walk_hierarchy(root, root.getChildHeader(i), {}, object_map, progress);
1023 for (std::pair<string, AlembicObject *> pair : object_map) {
1024 AlembicObject *abc_object = pair.second;
1028 if (!abc_object->instance_of) {
1029 if (abc_object->schema_type == AlembicObject::CURVES) {
1032 else if (abc_object->schema_type == AlembicObject::POINTS) {
1035 else if (abc_object->schema_type == AlembicObject::POLY_MESH ||
1036 abc_object->schema_type == AlembicObject::SUBD)
1045 geometry->name = abc_object->iobject.getName();
1047 array<Node *> used_shaders = abc_object->get_used_shaders();
1048 geometry->set_used_shaders(used_shaders);
1053 object->set_geometry(geometry);
1054 object->name = abc_object->iobject.getName();
1056 abc_object->set_object(
object);
1060 foreach (
Node *node, objects) {
1061 AlembicObject *abc_object =
static_cast<AlembicObject *
>(
node);
1063 if (abc_object->instance_of) {
1064 abc_object->get_object()->set_geometry(
1065 abc_object->instance_of->get_object()->get_geometry());
1066 abc_object->schema_type = abc_object->instance_of->schema_type;
1071void AlembicProcedural::read_mesh(AlembicObject *abc_object, Abc::chrono_t frame_time)
1073 CachedData &cached_data = abc_object->get_cached_data();
1077 Object *
object = abc_object->get_object();
1078 cached_data.transforms.copy_to_socket(frame_time,
object, object->get_tfm_socket());
1080 if (object->is_modified()) {
1085 if (abc_object->instance_of) {
1089 Mesh *mesh =
static_cast<Mesh *
>(
object->get_geometry());
1092 if (mesh->used_shaders_is_modified()) {
1093 mesh->tag_shader_modified();
1096 cached_data.vertices.copy_to_socket(frame_time, mesh, mesh->get_verts_socket());
1098 cached_data.shader.copy_to_socket(frame_time, mesh, mesh->get_shader_socket());
1100 array<int3> *triangle_data = cached_data.triangles.data_for_time(frame_time).get_data_or_null();
1101 if (triangle_data) {
1105 triangles.reserve(triangle_data->
size() * 3);
1106 smooth.reserve(triangle_data->
size());
1108 for (
size_t i = 0; i < triangle_data->
size(); ++i) {
1109 int3 tri = (*triangle_data)[i];
1110 triangles.push_back_reserved(tri.
x);
1111 triangles.push_back_reserved(tri.
y);
1112 triangles.push_back_reserved(tri.
z);
1113 smooth.push_back_reserved(1);
1116 mesh->set_triangles(triangles);
1117 mesh->set_smooth(smooth);
1122 update_attributes(mesh->attributes, cached_data, frame_time);
1124 if (mesh->is_modified()) {
1125 bool need_rebuild = mesh->triangles_is_modified();
1126 mesh->tag_update(scene_, need_rebuild);
1130void AlembicProcedural::read_subd(AlembicObject *abc_object, Abc::chrono_t frame_time)
1132 if (abc_object->get_ignore_subdivision()) {
1133 read_mesh(abc_object, frame_time);
1137 CachedData &cached_data = abc_object->get_cached_data();
1141 Object *
object = abc_object->get_object();
1142 cached_data.transforms.copy_to_socket(frame_time,
object, object->get_tfm_socket());
1144 if (object->is_modified()) {
1149 if (abc_object->instance_of) {
1153 if (abc_object->subd_max_level_is_modified() || abc_object->subd_dicing_rate_is_modified()) {
1155 cached_data.invalidate_last_loaded_time();
1158 Mesh *mesh =
static_cast<Mesh *
>(
object->get_geometry());
1161 if (mesh->used_shaders_is_modified()) {
1162 mesh->tag_shader_modified();
1167 if (!cached_data.is_constant()) {
1168 cached_data.invalidate_last_loaded_time();
1172 mesh->set_triangles(triangles);
1175 mesh->clear_non_sockets();
1179 mesh->set_subd_max_level(abc_object->get_subd_max_level());
1180 mesh->set_subd_dicing_rate(abc_object->get_subd_dicing_rate());
1182 cached_data.vertices.copy_to_socket(frame_time, mesh, mesh->get_verts_socket());
1185 cached_data.shader.copy_to_socket(frame_time, mesh, mesh->get_subd_shader_socket());
1187 cached_data.subd_start_corner.copy_to_socket(
1188 frame_time, mesh, mesh->get_subd_start_corner_socket());
1190 cached_data.subd_num_corners.copy_to_socket(
1191 frame_time, mesh, mesh->get_subd_num_corners_socket());
1193 cached_data.subd_smooth.copy_to_socket(frame_time, mesh, mesh->get_subd_smooth_socket());
1195 cached_data.subd_ptex_offset.copy_to_socket(
1196 frame_time, mesh, mesh->get_subd_ptex_offset_socket());
1198 cached_data.subd_face_corners.copy_to_socket(
1199 frame_time, mesh, mesh->get_subd_face_corners_socket());
1201 cached_data.num_ngons.copy_to_socket(frame_time, mesh, mesh->get_num_ngons_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());
1215 mesh->set_num_subd_faces(mesh->get_subd_shader().size());
1219 update_attributes(mesh->subd_attributes, cached_data, frame_time);
1221 if (mesh->is_modified()) {
1222 bool need_rebuild = (mesh->triangles_is_modified()) ||
1223 (mesh->subd_num_corners_is_modified()) ||
1224 (mesh->subd_shader_is_modified()) || (mesh->subd_smooth_is_modified()) ||
1225 (mesh->subd_ptex_offset_is_modified()) ||
1226 (mesh->subd_start_corner_is_modified()) ||
1227 (mesh->subd_face_corners_is_modified());
1229 mesh->tag_update(scene_, need_rebuild);
1233void AlembicProcedural::read_curves(AlembicObject *abc_object, Abc::chrono_t frame_time)
1235 CachedData &cached_data = abc_object->get_cached_data();
1239 Object *
object = abc_object->get_object();
1240 cached_data.transforms.copy_to_socket(frame_time,
object, object->get_tfm_socket());
1242 if (object->is_modified()) {
1247 if (abc_object->instance_of) {
1251 Hair *hair =
static_cast<Hair *
>(
object->get_geometry());
1254 if (hair->used_shaders_is_modified()) {
1255 hair->tag_curve_shader_modified();
1258 cached_data.curve_keys.copy_to_socket(frame_time, hair, hair->get_curve_keys_socket());
1260 cached_data.curve_radius.copy_to_socket(frame_time, hair, hair->get_curve_radius_socket());
1262 cached_data.curve_shader.copy_to_socket(frame_time, hair, hair->get_curve_shader_socket());
1264 cached_data.curve_first_key.copy_to_socket(frame_time, hair, hair->get_curve_first_key_socket());
1268 update_attributes(hair->attributes, cached_data, frame_time);
1270 const bool rebuild = (hair->curve_keys_is_modified() || hair->curve_radius_is_modified());
1271 hair->tag_update(scene_, rebuild);
1274void AlembicProcedural::read_points(AlembicObject *abc_object, Abc::chrono_t frame_time)
1276 CachedData &cached_data = abc_object->get_cached_data();
1280 Object *
object = abc_object->get_object();
1281 cached_data.transforms.copy_to_socket(frame_time,
object, object->get_tfm_socket());
1283 if (object->is_modified()) {
1288 if (abc_object->instance_of) {
1295 if (point_cloud->used_shaders_is_modified()) {
1296 point_cloud->tag_shader_modified();
1299 cached_data.points.copy_to_socket(frame_time, point_cloud, point_cloud->get_points_socket());
1300 cached_data.radiuses.copy_to_socket(frame_time, point_cloud, point_cloud->get_radius_socket());
1301 cached_data.points_shader.copy_to_socket(
1302 frame_time, point_cloud, point_cloud->get_shader_socket());
1306 update_attributes(point_cloud->
attributes, cached_data, frame_time);
1308 const bool rebuild = (point_cloud->points_is_modified() || point_cloud->radius_is_modified() ||
1309 point_cloud->shader_is_modified());
1313void AlembicProcedural::walk_hierarchy(
1315 const ObjectHeader &header,
1316 MatrixSamplesData matrix_samples_data,
1317 const unordered_map<std::string, AlembicObject *> &object_map,
1324 IObject next_object;
1326 MatrixSampleMap concatenated_xform_samples;
1328 if (IXform::matches(header)) {
1329 IXform xform(parent, header.getName());
1331 IXformSchema &xs = xform.getSchema();
1333 if (xs.getNumOps() > 0) {
1334 TimeSamplingPtr ts = xs.getTimeSampling();
1335 MatrixSampleMap local_xform_samples;
1337 MatrixSampleMap *temp_xform_samples =
nullptr;
1338 if (matrix_samples_data.samples ==
nullptr) {
1340 temp_xform_samples = &concatenated_xform_samples;
1344 temp_xform_samples = &local_xform_samples;
1347 for (
size_t i = 0; i < xs.getNumSamples(); ++i) {
1348 chrono_t sample_time = ts->getSampleTime(index_t(i));
1349 XformSample
sample = xs.getValue(ISampleSelector(sample_time));
1350 temp_xform_samples->insert({sample_time,
sample.getMatrix()});
1353 if (matrix_samples_data.samples !=
nullptr) {
1354 concatenate_xform_samples(
1355 *matrix_samples_data.samples, local_xform_samples, concatenated_xform_samples);
1358 matrix_samples_data.samples = &concatenated_xform_samples;
1359 matrix_samples_data.time_sampling = ts;
1362 next_object = xform;
1364 else if (ISubD::matches(header)) {
1365 ISubD subd(parent, header.getName());
1367 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1368 iter = object_map.find(subd.getFullName());
1370 if (iter != object_map.end()) {
1371 AlembicObject *abc_object = iter->second;
1372 abc_object->iobject = subd;
1373 abc_object->schema_type = AlembicObject::SUBD;
1375 if (matrix_samples_data.samples) {
1376 abc_object->xform_samples = *matrix_samples_data.samples;
1377 abc_object->xform_time_sampling = matrix_samples_data.time_sampling;
1383 else if (IPolyMesh::matches(header)) {
1384 IPolyMesh
mesh(parent, header.getName());
1386 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1387 iter = object_map.find(mesh.getFullName());
1389 if (iter != object_map.end()) {
1390 AlembicObject *abc_object = iter->second;
1391 abc_object->iobject =
mesh;
1392 abc_object->schema_type = AlembicObject::POLY_MESH;
1394 if (matrix_samples_data.samples) {
1395 abc_object->xform_samples = *matrix_samples_data.samples;
1396 abc_object->xform_time_sampling = matrix_samples_data.time_sampling;
1402 else if (ICurves::matches(header)) {
1403 ICurves curves(parent, header.getName());
1405 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1406 iter = object_map.find(curves.getFullName());
1408 if (iter != object_map.end()) {
1409 AlembicObject *abc_object = iter->second;
1410 abc_object->iobject = curves;
1411 abc_object->schema_type = AlembicObject::CURVES;
1413 if (matrix_samples_data.samples) {
1414 abc_object->xform_samples = *matrix_samples_data.samples;
1415 abc_object->xform_time_sampling = matrix_samples_data.time_sampling;
1419 next_object = curves;
1421 else if (IFaceSet::matches(header)) {
1424 else if (IPoints::matches(header)) {
1425 IPoints points(parent, header.getName());
1427 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1428 iter = object_map.find(points.getFullName());
1430 if (iter != object_map.end()) {
1431 AlembicObject *abc_object = iter->second;
1432 abc_object->iobject = points;
1433 abc_object->schema_type = AlembicObject::POINTS;
1435 if (matrix_samples_data.samples) {
1436 abc_object->xform_samples = *matrix_samples_data.samples;
1437 abc_object->xform_time_sampling = matrix_samples_data.time_sampling;
1441 next_object = points;
1443 else if (INuPatch::matches(header)) {
1447 next_object = parent.getChild(header.getName());
1449 if (next_object.isInstanceRoot()) {
1450 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1453 iter = object_map.find(next_object.getFullName());
1455 if (iter != object_map.end()) {
1456 AlembicObject *abc_object = iter->second;
1459 iter = object_map.find(next_object.instanceSourcePath());
1461 if (iter != object_map.end()) {
1462 abc_object->iobject = next_object;
1463 abc_object->instance_of = iter->second;
1465 if (matrix_samples_data.samples) {
1466 abc_object->xform_samples = *matrix_samples_data.samples;
1467 abc_object->xform_time_sampling = matrix_samples_data.time_sampling;
1474 if (next_object.valid()) {
1475 for (
size_t i = 0; i < next_object.getNumChildren(); ++i) {
1477 next_object, next_object.getChildHeader(i), matrix_samples_data, object_map, progress);
1482void AlembicProcedural::build_caches(
Progress &progress)
1484 size_t memory_used = 0;
1486 for (
Node *node : objects) {
1487 AlembicObject *
object =
static_cast<AlembicObject *
>(
node);
1493 if (object->schema_type == AlembicObject::POLY_MESH) {
1494 if (!object->has_data_loaded()) {
1495 IPolyMesh polymesh(object->iobject, Alembic::Abc::kWrapExisting);
1496 IPolyMeshSchema schema = polymesh.getSchema();
1497 object->load_data_in_cache(object->get_cached_data(),
this, schema, progress);
1499 else if (object->need_shader_update) {
1500 IPolyMesh polymesh(object->iobject, Alembic::Abc::kWrapExisting);
1501 IPolyMeshSchema schema = polymesh.getSchema();
1502 read_attributes(
this,
1503 object->get_cached_data(),
1505 schema.getUVsParam(),
1506 object->get_requested_attributes(),
1510 else if (object->schema_type == AlembicObject::CURVES) {
1511 if (!object->has_data_loaded() || default_radius_is_modified() ||
1512 object->radius_scale_is_modified())
1514 ICurves curves(object->iobject, Alembic::Abc::kWrapExisting);
1515 ICurvesSchema schema = curves.getSchema();
1516 object->load_data_in_cache(object->get_cached_data(),
this, schema, progress);
1519 else if (object->schema_type == AlembicObject::POINTS) {
1520 if (!object->has_data_loaded() || default_radius_is_modified() ||
1521 object->radius_scale_is_modified())
1523 IPoints points(object->iobject, Alembic::Abc::kWrapExisting);
1524 IPointsSchema schema = points.getSchema();
1525 object->load_data_in_cache(object->get_cached_data(),
this, schema, progress);
1528 else if (object->schema_type == AlembicObject::SUBD) {
1529 if (!object->has_data_loaded()) {
1530 ISubD subd_mesh(object->iobject, Alembic::Abc::kWrapExisting);
1531 ISubDSchema schema = subd_mesh.getSchema();
1532 object->load_data_in_cache(object->get_cached_data(),
this, schema, progress);
1534 else if (object->need_shader_update) {
1535 ISubD subd_mesh(object->iobject, Alembic::Abc::kWrapExisting);
1536 ISubDSchema schema = subd_mesh.getSchema();
1537 read_attributes(
this,
1538 object->get_cached_data(),
1540 schema.getUVsParam(),
1541 object->get_requested_attributes(),
1546 if (scale_is_modified() || object->get_cached_data().transforms.size() == 0) {
1547 object->setup_transform_cache(object->get_cached_data(), scale);
1550 memory_used +=
object->get_cached_data().memory_used();
1553 if (memory_used > get_prefetch_cache_size_in_bytes()) {
1554 progress.
set_error(
"Error: Alembic Procedural memory limit reached");
void tag_update(Scene *scene, bool rebuild)
void set_error(const string &error_message_)
#define CCL_NAMESPACE_END
smooth(Type::VEC3, "P") .flat(Type out_color storage_buf(0, Qualifier::READ, "Surfel", "surfels_buf[]") .push_constant(Type smooth(Type::VEC4, "interp_color")
#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)
@ SUBDIVISION_CATMULL_CLARK
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=NULL)
void set_owner(const NodeOwner *owner_)
void tag_update(Scene *scene)
void delete_nodes(const set< T * > &nodes)
T * create_node(Args &&...args)