23 using namespace Alembic::AbcGeom;
29 template<
typename SchemaType>
35 std::vector<std::string> face_set_names;
36 schema.getFaceSetNames(face_set_names);
38 if (face_set_names.empty()) {
42 for (
const std::string &face_set_name : face_set_names) {
46 if (
node->name == face_set_name) {
53 if (shader_index >= used_shaders.size()) {
58 const Alembic::AbcGeom::IFaceSet face_set = schema.getFaceSet(face_set_name);
60 if (!face_set.valid()) {
64 result.push_back({face_set, shader_index});
73 curve_first_key.clear();
79 subd_creases_edge.clear();
80 subd_creases_weight.clear();
81 subd_face_corners.clear();
82 subd_num_corners.clear();
83 subd_ptex_offset.clear();
85 subd_start_corner.clear();
92 points_shader.clear();
94 for (CachedAttribute &attr : attributes) {
101 CachedData::CachedAttribute &CachedData::add_attribute(
const ustring &name,
102 const TimeSampling &time_sampling)
104 for (
auto &attr : attributes) {
105 if (attr.name == name) {
110 CachedAttribute &attr = attributes.emplace_back();
112 attr.data.set_time_sampling(time_sampling);
116 bool CachedData::is_constant()
const
118 # define CHECK_IF_CONSTANT(data) \
119 if (!data.is_constant()) { \
123 CHECK_IF_CONSTANT(curve_first_key)
124 CHECK_IF_CONSTANT(curve_keys)
125 CHECK_IF_CONSTANT(curve_radius)
126 CHECK_IF_CONSTANT(curve_shader)
127 CHECK_IF_CONSTANT(num_ngons)
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
155 void 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 num_ngons.invalidate_last_loaded_time();
170 shader.invalidate_last_loaded_time();
171 subd_creases_edge.invalidate_last_loaded_time();
172 subd_creases_weight.invalidate_last_loaded_time();
173 subd_face_corners.invalidate_last_loaded_time();
174 subd_num_corners.invalidate_last_loaded_time();
175 subd_ptex_offset.invalidate_last_loaded_time();
176 subd_smooth.invalidate_last_loaded_time();
177 subd_start_corner.invalidate_last_loaded_time();
178 transforms.invalidate_last_loaded_time();
179 triangles.invalidate_last_loaded_time();
180 uv_loops.invalidate_last_loaded_time();
181 vertices.invalidate_last_loaded_time();
182 points.invalidate_last_loaded_time();
183 radiuses.invalidate_last_loaded_time();
184 points_shader.invalidate_last_loaded_time();
187 void CachedData::set_time_sampling(TimeSampling time_sampling)
189 curve_first_key.set_time_sampling(time_sampling);
190 curve_keys.set_time_sampling(time_sampling);
191 curve_radius.set_time_sampling(time_sampling);
192 curve_shader.set_time_sampling(time_sampling);
193 num_ngons.set_time_sampling(time_sampling);
194 shader.set_time_sampling(time_sampling);
195 subd_creases_edge.set_time_sampling(time_sampling);
196 subd_creases_weight.set_time_sampling(time_sampling);
197 subd_face_corners.set_time_sampling(time_sampling);
198 subd_num_corners.set_time_sampling(time_sampling);
199 subd_ptex_offset.set_time_sampling(time_sampling);
200 subd_smooth.set_time_sampling(time_sampling);
201 subd_start_corner.set_time_sampling(time_sampling);
202 transforms.set_time_sampling(time_sampling);
203 triangles.set_time_sampling(time_sampling);
204 uv_loops.set_time_sampling(time_sampling);
205 vertices.set_time_sampling(time_sampling);
206 points.set_time_sampling(time_sampling);
207 radiuses.set_time_sampling(time_sampling);
208 points_shader.set_time_sampling(time_sampling);
210 for (CachedAttribute &attr : attributes) {
211 attr.data.set_time_sampling(time_sampling);
215 size_t CachedData::memory_used()
const
219 mem_used += curve_first_key.memory_used();
220 mem_used += curve_keys.memory_used();
221 mem_used += curve_radius.memory_used();
222 mem_used += curve_shader.memory_used();
223 mem_used += num_ngons.memory_used();
224 mem_used += shader.memory_used();
225 mem_used += subd_creases_edge.memory_used();
226 mem_used += subd_creases_weight.memory_used();
227 mem_used += subd_face_corners.memory_used();
228 mem_used += subd_num_corners.memory_used();
229 mem_used += subd_ptex_offset.memory_used();
230 mem_used += subd_smooth.memory_used();
231 mem_used += subd_start_corner.memory_used();
232 mem_used += transforms.memory_used();
233 mem_used += triangles.memory_used();
234 mem_used += uv_loops.memory_used();
235 mem_used += vertices.memory_used();
236 mem_used += points.memory_used();
237 mem_used += radiuses.memory_used();
238 mem_used += points_shader.memory_used();
240 for (
const CachedAttribute &attr : attributes) {
241 mem_used += attr.data.memory_used();
247 static M44d convert_yup_zup(
const M44d &mtx,
float scale_mult)
249 V3d scale, shear, rotation, translation;
256 IMATH_INTERNAL_NAMESPACE::Euler<double>::XZY);
258 M44d rot_mat, scale_mat, trans_mat;
259 rot_mat.setEulerAngles(V3d(rotation.x, -rotation.z, rotation.y));
260 scale_mat.setScale(V3d(scale.x, scale.z, scale.y));
261 trans_mat.setTranslation(V3d(translation.x, -translation.z, translation.y));
263 M44d temp_mat = scale_mat * rot_mat * trans_mat;
265 scale_mat.setScale(
static_cast<double>(scale_mult));
267 return temp_mat * scale_mat;
271 const M44d &mat, V3d &scale, V3d &shear, Quatd &rotation, V3d &translation)
273 M44d mat_remainder(mat);
276 Imath::extractAndRemoveScalingAndShear(mat_remainder, scale, shear);
279 translation.x = mat_remainder[3][0];
280 translation.y = mat_remainder[3][1];
281 translation.z = mat_remainder[3][2];
284 rotation = extractQuat(mat_remainder);
289 const Quatd &rotation,
290 const V3d &translation)
292 M44d scale_mat, shear_mat, rot_mat, trans_mat;
294 scale_mat.setScale(scale);
295 shear_mat.setShear(shear);
296 rot_mat = rotation.toMatrix44();
297 trans_mat.setTranslation(translation);
299 return scale_mat * shear_mat * rot_mat * trans_mat;
304 static M44d get_matrix_for_time(
const MatrixSampleMap &samples, chrono_t
time)
306 MatrixSampleMap::const_iterator iter = samples.find(
time);
307 if (iter != samples.end()) {
316 static M44d get_interpolated_matrix_for_time(
const MatrixSampleMap &samples, chrono_t
time)
318 if (samples.empty()) {
323 MatrixSampleMap::const_iterator iter = samples.find(
time);
324 if (iter != samples.end()) {
328 if (samples.size() == 1) {
329 return samples.begin()->second;
332 if (
time <= samples.begin()->first) {
333 return samples.begin()->second;
336 if (
time >= samples.rbegin()->first) {
337 return samples.rbegin()->second;
341 chrono_t prev_time = samples.begin()->first;
342 chrono_t next_time = samples.rbegin()->first;
344 for (MatrixSampleMap::const_iterator
I = samples.begin();
I != samples.end(); ++
I) {
345 chrono_t current_time = (*I).first;
347 if (current_time > prev_time && current_time <=
time) {
348 prev_time = current_time;
351 if (current_time > next_time && current_time >=
time) {
352 next_time = current_time;
356 const M44d prev_mat = get_matrix_for_time(samples, prev_time);
357 const M44d next_mat = get_matrix_for_time(samples, next_time);
359 V3d prev_scale, next_scale;
360 V3d prev_shear, next_shear;
361 V3d prev_translation, next_translation;
362 Quatd prev_rotation, next_rotation;
367 chrono_t
t = (
time - prev_time) / (next_time - prev_time);
370 if ((prev_rotation ^ next_rotation) < 0) {
371 next_rotation = -next_rotation;
380 static void concatenate_xform_samples(
const MatrixSampleMap &parent_samples,
381 const MatrixSampleMap &local_samples,
382 MatrixSampleMap &output_samples)
384 set<chrono_t> union_of_samples;
386 for (
const std::pair<chrono_t, M44d> pair : parent_samples) {
387 union_of_samples.insert(pair.first);
390 for (
const std::pair<chrono_t, M44d> pair : local_samples) {
391 union_of_samples.insert(pair.first);
394 foreach (chrono_t
time, union_of_samples) {
395 M44d parent_matrix = get_interpolated_matrix_for_time(parent_samples,
time);
396 M44d local_matrix = get_interpolated_matrix_for_time(local_samples,
time);
398 output_samples[
time] = local_matrix * parent_matrix;
404 M44d m = convert_yup_zup(
a, scale);
406 for (
int j = 0; j < 3; j++) {
407 for (
int i = 0; i < 4; i++) {
408 trans[j][i] =
static_cast<float>(m[i][j]);
423 SOCKET_INT(subd_max_level,
"Max Subdivision Level", 1);
424 SOCKET_FLOAT(subd_dicing_rate,
"Subdivision Dicing Rate", 1.0f);
431 AlembicObject::AlembicObject() :
Node(get_node_type())
433 schema_type = INVALID;
436 AlembicObject::~AlembicObject()
440 void AlembicObject::set_object(
Object *object_)
445 Object *AlembicObject::get_object()
450 bool AlembicObject::has_data_loaded()
const
455 void AlembicObject::load_data_in_cache(CachedData &cached_data,
456 AlembicProcedural *proc,
457 IPolyMeshSchema &schema,
467 PolyMeshSchemaData
data;
468 data.topology_variance = schema.getTopologyVariance();
469 data.time_sampling = schema.getTimeSampling();
470 data.positions = schema.getPositionsProperty();
471 data.face_counts = schema.getFaceCountsProperty();
472 data.face_indices = schema.getFaceIndicesProperty();
473 data.normals = schema.getNormalsParam();
474 data.num_samples = schema.getNumSamples();
475 data.shader_face_sets = parse_face_sets_for_shader_assignment(schema, get_used_shaders());
477 read_geometry_data(proc, cached_data,
data, progress);
486 proc, cached_data, schema, schema.getUVsParam(), get_requested_attributes(), progress);
492 cached_data.invalidate_last_loaded_time(
true);
496 void AlembicObject::load_data_in_cache(CachedData &cached_data,
497 AlembicProcedural *proc,
508 if (this->get_ignore_subdivision()) {
509 PolyMeshSchemaData
data;
510 data.topology_variance = schema.getTopologyVariance();
511 data.time_sampling = schema.getTimeSampling();
512 data.positions = schema.getPositionsProperty();
513 data.face_counts = schema.getFaceCountsProperty();
514 data.face_indices = schema.getFaceIndicesProperty();
515 data.num_samples = schema.getNumSamples();
516 data.velocities = schema.getVelocitiesProperty();
517 data.shader_face_sets = parse_face_sets_for_shader_assignment(schema, get_used_shaders());
519 read_geometry_data(proc, cached_data,
data, progress);
528 proc, cached_data, schema, schema.getUVsParam(), get_requested_attributes(), progress);
530 cached_data.invalidate_last_loaded_time(
true);
536 data.time_sampling = schema.getTimeSampling();
537 data.num_samples = schema.getNumSamples();
538 data.topology_variance = schema.getTopologyVariance();
539 data.face_counts = schema.getFaceCountsProperty();
540 data.face_indices = schema.getFaceIndicesProperty();
541 data.positions = schema.getPositionsProperty();
542 data.face_varying_interpolate_boundary = schema.getFaceVaryingInterpolateBoundaryProperty();
543 data.face_varying_propagate_corners = schema.getFaceVaryingPropagateCornersProperty();
544 data.interpolate_boundary = schema.getInterpolateBoundaryProperty();
545 data.crease_indices = schema.getCreaseIndicesProperty();
546 data.crease_lengths = schema.getCreaseLengthsProperty();
547 data.crease_sharpnesses = schema.getCreaseSharpnessesProperty();
548 data.corner_indices = schema.getCornerIndicesProperty();
549 data.corner_sharpnesses = schema.getCornerSharpnessesProperty();
550 data.holes = schema.getHolesProperty();
551 data.subdivision_scheme = schema.getSubdivisionSchemeProperty();
552 data.velocities = schema.getVelocitiesProperty();
553 data.shader_face_sets = parse_face_sets_for_shader_assignment(schema, get_used_shaders());
555 read_geometry_data(proc, cached_data,
data, progress);
564 proc, cached_data, schema, schema.getUVsParam(), get_requested_attributes(), progress);
566 cached_data.invalidate_last_loaded_time(
true);
570 void AlembicObject::load_data_in_cache(CachedData &cached_data,
571 AlembicProcedural *proc,
572 const ICurvesSchema &schema,
582 CurvesSchemaData
data;
583 data.positions = schema.getPositionsProperty();
584 data.position_weights = schema.getPositionWeightsProperty();
585 data.normals = schema.getNormalsParam();
586 data.knots = schema.getKnotsProperty();
587 data.orders = schema.getOrdersProperty();
588 data.widths = schema.getWidthsParam();
589 data.velocities = schema.getVelocitiesProperty();
590 data.time_sampling = schema.getTimeSampling();
591 data.topology_variance = schema.getTopologyVariance();
592 data.num_samples = schema.getNumSamples();
593 data.num_vertices = schema.getNumVerticesProperty();
594 data.default_radius = proc->get_default_radius();
595 data.radius_scale = get_radius_scale();
597 read_geometry_data(proc, cached_data,
data, progress);
606 proc, cached_data, schema, schema.getUVsParam(), get_requested_attributes(), progress);
608 cached_data.invalidate_last_loaded_time(
true);
612 void AlembicObject::setup_transform_cache(CachedData &cached_data,
float scale)
614 cached_data.transforms.clear();
615 cached_data.transforms.invalidate_last_loaded_time();
621 if (xform_time_sampling) {
622 cached_data.transforms.set_time_sampling(*xform_time_sampling);
625 if (xform_samples.size() == 0) {
627 cached_data.transforms.add_data(tfm, 0.0);
633 M44d first_matrix = xform_samples.begin()->first;
634 bool has_animation =
false;
635 for (
const std::pair<chrono_t, M44d> pair : xform_samples) {
636 if (pair.second != first_matrix) {
637 has_animation =
true;
642 if (!has_animation) {
644 cached_data.transforms.add_data(tfm, 0.0);
647 for (
const std::pair<chrono_t, M44d> pair : xform_samples) {
649 cached_data.transforms.add_data(tfm, pair.first);
659 Geometry *geometry =
object->get_geometry();
662 foreach (
Node *
node, geometry->get_used_shaders()) {
666 if (attr.
name !=
"") {
667 requested_attributes.
add(attr.
name);
672 return requested_attributes;
677 static void update_attributes(
AttributeSet &attributes, CachedData &cached_data,
double frame_time)
679 set<Attribute *> cached_attributes;
681 for (CachedData::CachedAttribute &
attribute : cached_data.attributes) {
682 const CacheLookupResult<array<char>>
result =
attribute.data.data_for_time(frame_time);
684 if (
result.has_no_data_for_time()) {
697 cached_attributes.insert(attr);
699 if (!
result.has_new_data()) {
703 const ccl::array<char> &attr_data =
result.get_data();
707 if (attr->
buffer.size() != attr_data.size()) {
708 attr->
buffer.resize(attr_data.size());
711 memcpy(attr->
data(), attr_data.data(), attr_data.size());
716 list<Attribute>::iterator it;
718 if (cached_attributes.find(&(*it)) == cached_attributes.end()) {
744 SOCKET_INT(prefetch_cache_size,
"Prefetch Cache Size", 4096);
749 AlembicProcedural::AlembicProcedural() :
Procedural(get_node_type())
751 objects_loaded =
false;
755 AlembicProcedural::~AlembicProcedural()
757 ccl::set<Geometry *> geometries_set;
758 ccl::set<Object *> objects_set;
759 ccl::set<AlembicObject *> abc_objects_set;
762 AlembicObject *abc_object =
static_cast<AlembicObject *
>(
node);
764 if (abc_object->get_object()) {
765 objects_set.insert(abc_object->get_object());
767 if (abc_object->get_object()->get_geometry()) {
768 geometries_set.insert(abc_object->get_object()->get_geometry());
772 delete_node(abc_object);
777 assert(geometries_set.empty());
778 assert(objects_set.empty());
782 scene_->delete_nodes(geometries_set,
this);
783 scene_->delete_nodes(objects_set,
this);
788 assert(scene_ ==
nullptr || scene_ ==
scene);
791 if (frame < start_frame || frame > end_frame) {
796 bool need_shader_updates =
false;
797 bool need_data_updates =
false;
799 foreach (
Node *object_node, objects) {
800 AlembicObject *
object =
static_cast<AlembicObject *
>(object_node);
802 if (object->is_modified()) {
803 need_data_updates =
true;
807 if (object->used_shaders_is_modified() &&
object->get_object() &&
808 object->get_object()->get_geometry()) {
809 Geometry *geometry =
object->get_object()->get_geometry();
811 geometry->set_used_shaders(used_shaders);
812 need_shader_updates =
true;
816 foreach (
Node *shader_node, object->get_used_shaders()) {
820 object->need_shader_update =
true;
821 need_shader_updates =
true;
826 if (!is_modified() && !need_shader_updates && !need_data_updates) {
830 if (!archive.valid() || filepath_is_modified() || layers_is_modified()) {
831 Alembic::AbcCoreFactory::IFactory factory;
832 factory.setPolicy(Alembic::Abc::ErrorHandler::kQuietNoopPolicy);
834 std::vector<std::string> filenames;
835 filenames.push_back(filepath.c_str());
837 for (
const ustring &layer : layers) {
838 filenames.push_back(layer.c_str());
842 std::reverse(filenames.begin(), filenames.end());
844 archive = factory.getArchive(filenames);
846 if (!archive.valid()) {
855 if (!objects_loaded || objects_is_modified()) {
856 load_objects(progress);
857 objects_loaded =
true;
860 const chrono_t frame_time = (chrono_t)((frame - frame_offset) / frame_rate);
864 AlembicObject *
object =
static_cast<AlembicObject *
>(
node);
866 if (object->schema_type != AlembicObject::SUBD) {
870 if (object->ignore_subdivision_is_modified()) {
871 object->clear_cache();
875 if (use_prefetch_is_modified()) {
878 AlembicObject *
object =
static_cast<AlembicObject *
>(
node);
879 object->clear_cache();
884 if (prefetch_cache_size_is_modified()) {
887 size_t memory_used = 0ul;
889 AlembicObject *
object =
static_cast<AlembicObject *
>(
node);
890 memory_used +=
object->get_cached_data().memory_used();
893 if (memory_used > get_prefetch_cache_size_in_bytes()) {
894 progress.
set_error(
"Error: Alembic Procedural memory limit reached");
899 build_caches(progress);
902 AlembicObject *
object =
static_cast<AlembicObject *
>(
node);
909 if (object->is_constant() && !
object->is_modified() && !
object->need_shader_update &&
910 !scale_is_modified()) {
914 if (object->schema_type == AlembicObject::POLY_MESH) {
915 read_mesh(
object, frame_time);
917 else if (object->schema_type == AlembicObject::CURVES) {
918 read_curves(
object, frame_time);
920 else if (object->schema_type == AlembicObject::POINTS) {
921 read_points(
object, frame_time);
923 else if (object->schema_type == AlembicObject::SUBD) {
924 read_subd(
object, frame_time);
927 object->need_shader_update =
false;
928 object->clear_modified();
934 void AlembicProcedural::add_object(AlembicObject *
object)
936 objects.push_back_slow(
object);
937 tag_objects_modified();
940 void AlembicProcedural::tag_update(
Scene *
scene)
945 AlembicObject *AlembicProcedural::get_or_create_object(
const ustring &path)
948 AlembicObject *
object =
static_cast<AlembicObject *
>(
node);
950 if (object->get_path() == path) {
955 AlembicObject *
object = create_node<AlembicObject>();
956 object->set_path(path);
963 void AlembicProcedural::load_objects(
Progress &progress)
965 unordered_map<string, AlembicObject *> object_map;
968 AlembicObject *
object =
static_cast<AlembicObject *
>(
node);
971 if (object->get_object() ==
nullptr) {
972 object_map.insert({
object->get_path().c_str(),
object});
976 IObject root = archive.getTop();
978 for (
size_t i = 0; i < root.getNumChildren(); ++i) {
979 walk_hierarchy(root, root.getChildHeader(i), {}, object_map, progress);
983 for (std::pair<string, AlembicObject *> pair : object_map) {
984 AlembicObject *abc_object = pair.second;
988 if (!abc_object->instance_of) {
989 if (abc_object->schema_type == AlembicObject::CURVES) {
990 geometry = scene_->create_node<
Hair>();
992 else if (abc_object->schema_type == AlembicObject::POINTS) {
995 else if (abc_object->schema_type == AlembicObject::POLY_MESH ||
996 abc_object->schema_type == AlembicObject::SUBD) {
997 geometry = scene_->create_node<
Mesh>();
1004 geometry->
name = abc_object->iobject.getName();
1006 array<Node *> used_shaders = abc_object->get_used_shaders();
1007 geometry->set_used_shaders(used_shaders);
1012 object->set_geometry(geometry);
1013 object->name = abc_object->iobject.getName();
1015 abc_object->set_object(
object);
1020 AlembicObject *abc_object =
static_cast<AlembicObject *
>(
node);
1022 if (abc_object->instance_of) {
1023 abc_object->get_object()->set_geometry(
1024 abc_object->instance_of->get_object()->get_geometry());
1025 abc_object->schema_type = abc_object->instance_of->schema_type;
1030 void AlembicProcedural::read_mesh(AlembicObject *abc_object, Abc::chrono_t frame_time)
1032 CachedData &cached_data = abc_object->get_cached_data();
1036 Object *
object = abc_object->get_object();
1037 cached_data.transforms.copy_to_socket(frame_time,
object, object->get_tfm_socket());
1044 if (abc_object->instance_of) {
1048 Mesh *
mesh =
static_cast<Mesh *
>(
object->get_geometry());
1051 if (
mesh->used_shaders_is_modified()) {
1052 mesh->tag_shader_modified();
1055 cached_data.vertices.copy_to_socket(frame_time,
mesh,
mesh->get_verts_socket());
1057 cached_data.shader.copy_to_socket(frame_time,
mesh,
mesh->get_shader_socket());
1059 array<int3> *triangle_data = cached_data.triangles.data_for_time(frame_time).get_data_or_null();
1060 if (triangle_data) {
1067 for (
size_t i = 0; i < triangle_data->
size(); ++i) {
1068 int3 tri = (*triangle_data)[i];
1072 smooth.push_back_reserved(1);
1075 mesh->set_triangles(triangles);
1084 bool need_rebuild =
mesh->triangles_is_modified();
1089 void AlembicProcedural::read_subd(AlembicObject *abc_object, Abc::chrono_t frame_time)
1091 if (abc_object->get_ignore_subdivision()) {
1092 read_mesh(abc_object, frame_time);
1096 CachedData &cached_data = abc_object->get_cached_data();
1100 Object *
object = abc_object->get_object();
1101 cached_data.transforms.copy_to_socket(frame_time,
object, object->get_tfm_socket());
1108 if (abc_object->instance_of) {
1112 if (abc_object->subd_max_level_is_modified() || abc_object->subd_dicing_rate_is_modified()) {
1114 cached_data.invalidate_last_loaded_time();
1117 Mesh *
mesh =
static_cast<Mesh *
>(
object->get_geometry());
1120 if (
mesh->used_shaders_is_modified()) {
1121 mesh->tag_shader_modified();
1126 if (!cached_data.is_constant()) {
1127 cached_data.invalidate_last_loaded_time();
1131 mesh->set_triangles(triangles);
1137 mesh->set_subdivision_type(Mesh::SubdivisionType::SUBDIVISION_CATMULL_CLARK);
1138 mesh->set_subd_max_level(abc_object->get_subd_max_level());
1139 mesh->set_subd_dicing_rate(abc_object->get_subd_dicing_rate());
1141 cached_data.vertices.copy_to_socket(frame_time,
mesh,
mesh->get_verts_socket());
1144 cached_data.shader.copy_to_socket(frame_time,
mesh,
mesh->get_subd_shader_socket());
1146 cached_data.subd_start_corner.copy_to_socket(
1147 frame_time,
mesh,
mesh->get_subd_start_corner_socket());
1149 cached_data.subd_num_corners.copy_to_socket(
1150 frame_time,
mesh,
mesh->get_subd_num_corners_socket());
1152 cached_data.subd_smooth.copy_to_socket(frame_time,
mesh,
mesh->get_subd_smooth_socket());
1154 cached_data.subd_ptex_offset.copy_to_socket(
1155 frame_time,
mesh,
mesh->get_subd_ptex_offset_socket());
1157 cached_data.subd_face_corners.copy_to_socket(
1158 frame_time,
mesh,
mesh->get_subd_face_corners_socket());
1160 cached_data.num_ngons.copy_to_socket(frame_time,
mesh,
mesh->get_num_ngons_socket());
1162 cached_data.subd_creases_edge.copy_to_socket(
1163 frame_time,
mesh,
mesh->get_subd_creases_edge_socket());
1165 cached_data.subd_creases_weight.copy_to_socket(
1166 frame_time,
mesh,
mesh->get_subd_creases_weight_socket());
1168 cached_data.subd_vertex_crease_indices.copy_to_socket(
1169 frame_time,
mesh,
mesh->get_subd_vert_creases_socket());
1171 cached_data.subd_vertex_crease_weights.copy_to_socket(
1172 frame_time,
mesh,
mesh->get_subd_vert_creases_weight_socket());
1178 update_attributes(
mesh->subd_attributes, cached_data, frame_time);
1181 bool need_rebuild = (
mesh->triangles_is_modified()) ||
1182 (
mesh->subd_num_corners_is_modified()) ||
1183 (
mesh->subd_shader_is_modified()) || (
mesh->subd_smooth_is_modified()) ||
1184 (
mesh->subd_ptex_offset_is_modified()) ||
1185 (
mesh->subd_start_corner_is_modified()) ||
1186 (
mesh->subd_face_corners_is_modified());
1192 void AlembicProcedural::read_curves(AlembicObject *abc_object, Abc::chrono_t frame_time)
1194 CachedData &cached_data = abc_object->get_cached_data();
1198 Object *
object = abc_object->get_object();
1199 cached_data.transforms.copy_to_socket(frame_time,
object, object->get_tfm_socket());
1206 if (abc_object->instance_of) {
1210 Hair *hair =
static_cast<Hair *
>(
object->get_geometry());
1213 if (hair->used_shaders_is_modified()) {
1214 hair->tag_curve_shader_modified();
1217 cached_data.curve_keys.copy_to_socket(frame_time, hair, hair->get_curve_keys_socket());
1219 cached_data.curve_radius.copy_to_socket(frame_time, hair, hair->get_curve_radius_socket());
1221 cached_data.curve_shader.copy_to_socket(frame_time, hair, hair->get_curve_shader_socket());
1223 cached_data.curve_first_key.copy_to_socket(frame_time, hair, hair->get_curve_first_key_socket());
1227 update_attributes(hair->
attributes, cached_data, frame_time);
1229 const bool rebuild = (hair->curve_keys_is_modified() || hair->curve_radius_is_modified());
1233 void AlembicProcedural::read_points(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());
1247 if (abc_object->instance_of) {
1254 if (point_cloud->used_shaders_is_modified()) {
1255 point_cloud->tag_shader_modified();
1258 cached_data.points.copy_to_socket(frame_time, point_cloud, point_cloud->get_points_socket());
1259 cached_data.radiuses.copy_to_socket(frame_time, point_cloud, point_cloud->get_radius_socket());
1260 cached_data.points_shader.copy_to_socket(
1261 frame_time, point_cloud, point_cloud->get_shader_socket());
1265 update_attributes(point_cloud->
attributes, cached_data, frame_time);
1267 const bool rebuild = (point_cloud->points_is_modified() || point_cloud->radius_is_modified() ||
1268 point_cloud->shader_is_modified());
1272 void AlembicProcedural::walk_hierarchy(
1274 const ObjectHeader &header,
1275 MatrixSamplesData matrix_samples_data,
1276 const unordered_map<std::string, AlembicObject *> &object_map,
1283 IObject next_object;
1285 MatrixSampleMap concatenated_xform_samples;
1287 if (IXform::matches(header)) {
1288 IXform xform(parent, header.getName());
1290 IXformSchema &xs = xform.getSchema();
1292 if (xs.getNumOps() > 0) {
1293 TimeSamplingPtr ts = xs.getTimeSampling();
1294 MatrixSampleMap local_xform_samples;
1296 MatrixSampleMap *temp_xform_samples =
nullptr;
1297 if (matrix_samples_data.samples ==
nullptr) {
1299 temp_xform_samples = &concatenated_xform_samples;
1303 temp_xform_samples = &local_xform_samples;
1306 for (
size_t i = 0; i < xs.getNumSamples(); ++i) {
1307 chrono_t sample_time = ts->getSampleTime(index_t(i));
1308 XformSample
sample = xs.getValue(ISampleSelector(sample_time));
1309 temp_xform_samples->insert({sample_time,
sample.getMatrix()});
1312 if (matrix_samples_data.samples !=
nullptr) {
1313 concatenate_xform_samples(
1314 *matrix_samples_data.samples, local_xform_samples, concatenated_xform_samples);
1317 matrix_samples_data.samples = &concatenated_xform_samples;
1318 matrix_samples_data.time_sampling = ts;
1321 next_object = xform;
1323 else if (ISubD::matches(header)) {
1324 ISubD subd(parent, header.getName());
1326 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1327 iter = object_map.find(subd.getFullName());
1329 if (iter != object_map.end()) {
1330 AlembicObject *abc_object = iter->second;
1331 abc_object->iobject = subd;
1332 abc_object->schema_type = AlembicObject::SUBD;
1334 if (matrix_samples_data.samples) {
1335 abc_object->xform_samples = *matrix_samples_data.samples;
1336 abc_object->xform_time_sampling = matrix_samples_data.time_sampling;
1342 else if (IPolyMesh::matches(header)) {
1343 IPolyMesh
mesh(parent, header.getName());
1345 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1346 iter = object_map.find(
mesh.getFullName());
1348 if (iter != object_map.end()) {
1349 AlembicObject *abc_object = iter->second;
1350 abc_object->iobject =
mesh;
1351 abc_object->schema_type = AlembicObject::POLY_MESH;
1353 if (matrix_samples_data.samples) {
1354 abc_object->xform_samples = *matrix_samples_data.samples;
1355 abc_object->xform_time_sampling = matrix_samples_data.time_sampling;
1361 else if (ICurves::matches(header)) {
1362 ICurves
curves(parent, header.getName());
1364 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1365 iter = object_map.find(
curves.getFullName());
1367 if (iter != object_map.end()) {
1368 AlembicObject *abc_object = iter->second;
1369 abc_object->iobject =
curves;
1370 abc_object->schema_type = AlembicObject::CURVES;
1372 if (matrix_samples_data.samples) {
1373 abc_object->xform_samples = *matrix_samples_data.samples;
1374 abc_object->xform_time_sampling = matrix_samples_data.time_sampling;
1380 else if (IFaceSet::matches(header)) {
1383 else if (IPoints::matches(header)) {
1384 IPoints points(parent, header.getName());
1386 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1387 iter = object_map.find(points.getFullName());
1389 if (iter != object_map.end()) {
1390 AlembicObject *abc_object = iter->second;
1391 abc_object->iobject = points;
1392 abc_object->schema_type = AlembicObject::POINTS;
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;
1400 next_object = points;
1402 else if (INuPatch::matches(header)) {
1406 next_object = parent.getChild(header.getName());
1408 if (next_object.isInstanceRoot()) {
1409 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1412 iter = object_map.find(next_object.getFullName());
1414 if (iter != object_map.end()) {
1415 AlembicObject *abc_object = iter->second;
1418 iter = object_map.find(next_object.instanceSourcePath());
1420 if (iter != object_map.end()) {
1421 abc_object->iobject = next_object;
1422 abc_object->instance_of = iter->second;
1424 if (matrix_samples_data.samples) {
1425 abc_object->xform_samples = *matrix_samples_data.samples;
1426 abc_object->xform_time_sampling = matrix_samples_data.time_sampling;
1433 if (next_object.valid()) {
1434 for (
size_t i = 0; i < next_object.getNumChildren(); ++i) {
1436 next_object, next_object.getChildHeader(i), matrix_samples_data, object_map, progress);
1441 void AlembicProcedural::build_caches(
Progress &progress)
1443 size_t memory_used = 0;
1446 AlembicObject *
object =
static_cast<AlembicObject *
>(
node);
1452 if (object->schema_type == AlembicObject::POLY_MESH) {
1453 if (!object->has_data_loaded()) {
1454 IPolyMesh polymesh(object->iobject, Alembic::Abc::kWrapExisting);
1455 IPolyMeshSchema schema = polymesh.getSchema();
1456 object->load_data_in_cache(object->get_cached_data(),
this, schema, progress);
1458 else if (object->need_shader_update) {
1459 IPolyMesh polymesh(object->iobject, Alembic::Abc::kWrapExisting);
1460 IPolyMeshSchema schema = polymesh.getSchema();
1461 read_attributes(
this,
1462 object->get_cached_data(),
1464 schema.getUVsParam(),
1465 object->get_requested_attributes(),
1469 else if (object->schema_type == AlembicObject::CURVES) {
1470 if (!object->has_data_loaded() || default_radius_is_modified() ||
1471 object->radius_scale_is_modified()) {
1472 ICurves
curves(object->iobject, Alembic::Abc::kWrapExisting);
1473 ICurvesSchema schema =
curves.getSchema();
1474 object->load_data_in_cache(object->get_cached_data(),
this, schema, progress);
1477 else if (object->schema_type == AlembicObject::POINTS) {
1478 if (!object->has_data_loaded() || default_radius_is_modified() ||
1479 object->radius_scale_is_modified()) {
1480 IPoints points(object->iobject, Alembic::Abc::kWrapExisting);
1481 IPointsSchema schema = points.getSchema();
1482 object->load_data_in_cache(object->get_cached_data(),
this, schema, progress);
1485 else if (object->schema_type == AlembicObject::SUBD) {
1486 if (!object->has_data_loaded()) {
1487 ISubD subd_mesh(object->iobject, Alembic::Abc::kWrapExisting);
1488 ISubDSchema schema = subd_mesh.getSchema();
1489 object->load_data_in_cache(object->get_cached_data(),
this, schema, progress);
1491 else if (object->need_shader_update) {
1492 ISubD subd_mesh(object->iobject, Alembic::Abc::kWrapExisting);
1493 ISubDSchema schema = subd_mesh.getSchema();
1494 read_attributes(
this,
1495 object->get_cached_data(),
1497 schema.getUVsParam(),
1498 object->get_requested_attributes(),
1503 if (scale_is_modified() || object->get_cached_data().transforms.size() == 0) {
1504 object->setup_transform_cache(object->get_cached_data(), scale);
1507 memory_used +=
object->get_cached_data().memory_used();
1510 if (memory_used > get_prefetch_cache_size_in_bytes()) {
1511 progress.
set_error(
"Error: Alembic Procedural memory limit reached");
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to curves
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
SIMD_FORCE_INLINE btQuaternion slerp(const btQuaternion &q1, const btQuaternion &q2, const btScalar &t)
Return the result of spherical linear interpolation betwen two quaternions.
vector< AttributeRequest > requests
Attribute * add(ustring name, TypeDesc type, AttributeElement element)
list< Attribute > attributes
void remove(ustring name)
void tag_update(Scene *scene, bool rebuild)
void set_error(const string &error_message_)
bool need_update_geometry() const
AttributeRequestSet attributes
void push_back_reserved(const T &t)
void reserve(size_t newcapacity)
#define CCL_NAMESPACE_END
static char * generate(GHash *messages, size_t *r_output_size)
static void clear(Message *msg)
static float lerp(float t, float a, float b)
std::unique_ptr< IDProperty, IDPropertyDeleter > create(StringRefNull prop_name, int32_t value)
Allocate a new IDProperty of type IDP_INT, set its name and value.
#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,...)
smooth(Type::FLOAT, "mask_weight")
string string_human_readable_size(size_t size)
void set_num_subd_faces(size_t num_subd_faces_)
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)
ProceduralManager * procedural_manager