33 using namespace Alembic::AbcGeom;
42 curve_first_key.clear();
48 subd_creases_edge.clear();
49 subd_creases_weight.clear();
50 subd_face_corners.clear();
51 subd_num_corners.clear();
52 subd_ptex_offset.clear();
54 subd_start_corner.clear();
57 triangles_loops.clear();
60 for (CachedAttribute &attr : attributes) {
67 CachedData::CachedAttribute &CachedData::add_attribute(
const ustring &name,
68 const TimeSampling &time_sampling)
70 for (
auto &attr : attributes) {
71 if (attr.name == name) {
76 CachedAttribute &attr = attributes.emplace_back();
78 attr.data.set_time_sampling(time_sampling);
82 bool CachedData::is_constant()
const
84 # define CHECK_IF_CONSTANT(data) \
85 if (!data.is_constant()) { \
89 CHECK_IF_CONSTANT(curve_first_key)
90 CHECK_IF_CONSTANT(curve_keys)
91 CHECK_IF_CONSTANT(curve_radius)
92 CHECK_IF_CONSTANT(curve_shader)
93 CHECK_IF_CONSTANT(num_ngons)
95 CHECK_IF_CONSTANT(subd_creases_edge)
96 CHECK_IF_CONSTANT(subd_creases_weight)
97 CHECK_IF_CONSTANT(subd_face_corners)
98 CHECK_IF_CONSTANT(subd_num_corners)
99 CHECK_IF_CONSTANT(subd_ptex_offset)
100 CHECK_IF_CONSTANT(subd_smooth)
101 CHECK_IF_CONSTANT(subd_start_corner)
102 CHECK_IF_CONSTANT(transforms)
103 CHECK_IF_CONSTANT(triangles)
104 CHECK_IF_CONSTANT(triangles_loops)
105 CHECK_IF_CONSTANT(vertices)
107 for (
const CachedAttribute &attr : attributes) {
108 if (!attr.data.is_constant()) {
115 # undef CHECK_IF_CONSTANT
118 void CachedData::invalidate_last_loaded_time(
bool attributes_only)
120 if (attributes_only) {
121 for (CachedAttribute &attr : attributes) {
122 attr.data.invalidate_last_loaded_time();
128 curve_first_key.invalidate_last_loaded_time();
129 curve_keys.invalidate_last_loaded_time();
130 curve_radius.invalidate_last_loaded_time();
131 curve_shader.invalidate_last_loaded_time();
132 num_ngons.invalidate_last_loaded_time();
133 shader.invalidate_last_loaded_time();
134 subd_creases_edge.invalidate_last_loaded_time();
135 subd_creases_weight.invalidate_last_loaded_time();
136 subd_face_corners.invalidate_last_loaded_time();
137 subd_num_corners.invalidate_last_loaded_time();
138 subd_ptex_offset.invalidate_last_loaded_time();
139 subd_smooth.invalidate_last_loaded_time();
140 subd_start_corner.invalidate_last_loaded_time();
141 transforms.invalidate_last_loaded_time();
142 triangles.invalidate_last_loaded_time();
143 triangles_loops.invalidate_last_loaded_time();
144 vertices.invalidate_last_loaded_time();
147 void CachedData::set_time_sampling(TimeSampling time_sampling)
149 curve_first_key.set_time_sampling(time_sampling);
150 curve_keys.set_time_sampling(time_sampling);
151 curve_radius.set_time_sampling(time_sampling);
152 curve_shader.set_time_sampling(time_sampling);
153 num_ngons.set_time_sampling(time_sampling);
154 shader.set_time_sampling(time_sampling);
155 subd_creases_edge.set_time_sampling(time_sampling);
156 subd_creases_weight.set_time_sampling(time_sampling);
157 subd_face_corners.set_time_sampling(time_sampling);
158 subd_num_corners.set_time_sampling(time_sampling);
159 subd_ptex_offset.set_time_sampling(time_sampling);
160 subd_smooth.set_time_sampling(time_sampling);
161 subd_start_corner.set_time_sampling(time_sampling);
162 transforms.set_time_sampling(time_sampling);
163 triangles.set_time_sampling(time_sampling);
164 triangles_loops.set_time_sampling(time_sampling);
165 vertices.set_time_sampling(time_sampling);
167 for (CachedAttribute &attr : attributes) {
168 attr.data.set_time_sampling(time_sampling);
173 static set<chrono_t> get_relevant_sample_times(AlembicProcedural *proc,
174 const TimeSampling &time_sampling,
179 if (num_samples < 2) {
184 double start_frame = (
double)(proc->get_start_frame() / proc->get_frame_rate());
185 double end_frame = (
double)((proc->get_end_frame() + 1) / proc->get_frame_rate());
187 size_t start_index = time_sampling.getFloorIndex(start_frame, num_samples).first;
188 size_t end_index = time_sampling.getCeilIndex(end_frame, num_samples).first;
190 for (
size_t i = start_index; i < end_index; ++i) {
191 result.insert(time_sampling.getSampleTime(i));
197 static float3 make_float3_from_yup(
const V3f &
v)
202 static M44d convert_yup_zup(
const M44d &mtx,
float scale_mult)
204 V3d scale, shear, rotation, translation;
211 IMATH_INTERNAL_NAMESPACE::Euler<double>::XZY);
213 M44d rot_mat, scale_mat, trans_mat;
214 rot_mat.setEulerAngles(V3d(rotation.x, -rotation.z, rotation.y));
215 scale_mat.setScale(V3d(scale.x, scale.z, scale.y));
216 trans_mat.setTranslation(V3d(translation.x, -translation.z, translation.y));
218 M44d temp_mat = scale_mat * rot_mat * trans_mat;
220 scale_mat.setScale(
static_cast<double>(scale_mult));
222 return temp_mat * scale_mat;
226 const M44d &mat, V3d &scale, V3d &shear, Quatd &rotation, V3d &translation)
228 M44d mat_remainder(mat);
231 Imath::extractAndRemoveScalingAndShear(mat_remainder, scale, shear);
234 translation.x = mat_remainder[3][0];
235 translation.y = mat_remainder[3][1];
236 translation.z = mat_remainder[3][2];
239 rotation = extractQuat(mat_remainder);
244 const Quatd &rotation,
245 const V3d &translation)
247 M44d scale_mat, shear_mat, rot_mat, trans_mat;
249 scale_mat.setScale(scale);
250 shear_mat.setShear(shear);
251 rot_mat = rotation.toMatrix44();
252 trans_mat.setTranslation(translation);
254 return scale_mat * shear_mat * rot_mat * trans_mat;
259 static M44d get_matrix_for_time(
const MatrixSampleMap &samples, chrono_t
time)
261 MatrixSampleMap::const_iterator iter = samples.find(
time);
262 if (iter != samples.end()) {
271 static M44d get_interpolated_matrix_for_time(
const MatrixSampleMap &samples, chrono_t
time)
273 if (samples.empty()) {
278 MatrixSampleMap::const_iterator iter = samples.find(
time);
279 if (iter != samples.end()) {
283 if (samples.size() == 1) {
284 return samples.begin()->second;
287 if (
time <= samples.begin()->first) {
288 return samples.begin()->second;
291 if (
time >= samples.rbegin()->first) {
292 return samples.rbegin()->second;
296 chrono_t prev_time = samples.begin()->first;
297 chrono_t next_time = samples.rbegin()->first;
299 for (MatrixSampleMap::const_iterator
I = samples.begin();
I != samples.end(); ++
I) {
300 chrono_t current_time = (*I).first;
302 if (current_time > prev_time && current_time <=
time) {
303 prev_time = current_time;
306 if (current_time > next_time && current_time >=
time) {
307 next_time = current_time;
311 const M44d prev_mat = get_matrix_for_time(samples, prev_time);
312 const M44d next_mat = get_matrix_for_time(samples, next_time);
314 V3d prev_scale, next_scale;
315 V3d prev_shear, next_shear;
316 V3d prev_translation, next_translation;
317 Quatd prev_rotation, next_rotation;
322 chrono_t
t = (
time - prev_time) / (next_time - prev_time);
325 if ((prev_rotation ^ next_rotation) < 0) {
326 next_rotation = -next_rotation;
335 static void concatenate_xform_samples(
const MatrixSampleMap &parent_samples,
336 const MatrixSampleMap &local_samples,
337 MatrixSampleMap &output_samples)
339 set<chrono_t> union_of_samples;
341 for (
const std::pair<chrono_t, M44d> pair : parent_samples) {
342 union_of_samples.insert(pair.first);
345 for (
const std::pair<chrono_t, M44d> pair : local_samples) {
346 union_of_samples.insert(pair.first);
349 foreach (chrono_t
time, union_of_samples) {
350 M44d parent_matrix = get_interpolated_matrix_for_time(parent_samples,
time);
351 M44d local_matrix = get_interpolated_matrix_for_time(local_samples,
time);
353 output_samples[
time] = local_matrix * parent_matrix;
359 M44d m = convert_yup_zup(
a, scale);
361 for (
int j = 0; j < 3; j++) {
362 for (
int i = 0; i < 4; i++) {
363 trans[j][i] =
static_cast<float>(m[i][j]);
369 static void add_uvs(AlembicProcedural *proc,
370 const IV2fGeomParam &uvs,
371 CachedData &cached_data,
374 if (uvs.getScope() != kFacevaryingScope) {
378 const TimeSamplingPtr time_sampling_ptr = uvs.getTimeSampling();
380 TimeSampling time_sampling;
381 if (time_sampling_ptr) {
382 time_sampling = *time_sampling_ptr;
385 std::string name = Alembic::Abc::GetSourceName(uvs.getMetaData());
391 name = uvs.getName();
394 CachedData::CachedAttribute &attr = cached_data.add_attribute(ustring(name), time_sampling);
397 ccl::set<chrono_t> times = get_relevant_sample_times(proc, time_sampling, uvs.getNumSamples());
403 foreach (chrono_t
time, times) {
408 const ISampleSelector iss = ISampleSelector(
time);
409 const IV2fGeomParam::Sample uvsample = uvs.getIndexedValue(iss);
411 if (!uvsample.valid()) {
416 cached_data.triangles.data_for_time_no_check(
time).get_data_or_null();
418 cached_data.triangles_loops.data_for_time_no_check(
time).get_data_or_null();
420 if (!triangles || !triangles_loops) {
432 if (indices_key == previous_indices_key && values_key == previous_values_key) {
433 attr.data.reuse_data_for_last_time(
time);
436 const unsigned int *
indices = uvsample.getIndices()->get();
437 const V2f *values = uvsample.getVals()->get();
439 for (
const int3 &loop : *triangles_loops) {
440 unsigned int v0 =
indices[loop.x];
444 data_float2[0] =
make_float2(values[v0][0], values[v0][1]);
453 previous_indices_key = indices_key;
454 previous_values_key = values_key;
458 static void add_normals(
const Int32ArraySamplePtr face_indices,
461 CachedData &cached_data)
464 case kFacevaryingScope: {
465 const ISampleSelector iss = ISampleSelector(
time);
466 const IN3fGeomParam::Sample
sample =
normals.getExpandedValue(iss);
472 CachedData::CachedAttribute &attr = cached_data.add_attribute(ustring(
normals.getName()),
477 cached_data.vertices.data_for_time_no_check(
time).get_data_or_null();
488 const int *face_indices_array = face_indices->get();
489 const N3fArraySamplePtr values =
sample.getVals();
491 for (
size_t i = 0; i < face_indices->size(); ++i) {
492 int point_index = face_indices_array[i];
493 data_float3[point_index] = make_float3_from_yup(values->get()[i]);
501 const ISampleSelector iss = ISampleSelector(
time);
502 const IN3fGeomParam::Sample
sample =
normals.getExpandedValue(iss);
508 CachedData::CachedAttribute &attr = cached_data.add_attribute(ustring(
normals.getName()),
513 cached_data.vertices.data_for_time_no_check(
time).get_data_or_null();
524 const Imath::V3f *values =
sample.getVals()->get();
526 for (
size_t i = 0; i < vertices->
size(); ++i) {
527 data_float3[i] = make_float3_from_yup(values[i]);
540 static void add_positions(
const P3fArraySamplePtr positions,
double time, CachedData &cached_data)
547 vertices.
reserve(positions->size());
549 for (
size_t i = 0; i < positions->size(); i++) {
550 V3f f = positions->get()[i];
554 cached_data.vertices.add_data(vertices,
time);
557 static void add_triangles(
const Int32ArraySamplePtr face_counts,
558 const Int32ArraySamplePtr face_indices,
560 CachedData &cached_data,
563 if (!face_counts || !face_indices) {
567 const size_t num_faces = face_counts->size();
568 const int *face_counts_array = face_counts->get();
569 const int *face_indices_array = face_indices->get();
571 size_t num_triangles = 0;
572 for (
size_t i = 0; i < face_counts->size(); i++) {
573 num_triangles += face_counts_array[i] - 2;
579 shader.reserve(num_triangles);
580 triangles.
reserve(num_triangles);
581 triangles_loops.
reserve(num_triangles);
582 int index_offset = 0;
584 for (
size_t i = 0; i < num_faces; i++) {
585 int current_shader = 0;
587 if (!polygon_to_shader.
empty()) {
588 current_shader = polygon_to_shader[i];
591 for (
int j = 0; j < face_counts_array[i] - 2; j++) {
592 int v0 = face_indices_array[index_offset];
593 int v1 = face_indices_array[index_offset + j + 1];
594 int v2 = face_indices_array[index_offset + j + 2];
596 shader.push_back_reserved(current_shader);
601 make_int3(index_offset + j + 2, index_offset + j + 1, index_offset));
604 index_offset += face_counts_array[i];
607 cached_data.triangles.add_data(triangles,
time);
608 cached_data.triangles_loops.add_data(triangles_loops,
time);
619 SOCKET_INT(subd_max_level,
"Max Subdivision Level", 1);
620 SOCKET_FLOAT(subd_dicing_rate,
"Subdivision Dicing Rate", 1.0f);
627 AlembicObject::AlembicObject() :
Node(get_node_type())
629 schema_type = INVALID;
632 AlembicObject::~AlembicObject()
636 void AlembicObject::set_object(
Object *object_)
641 Object *AlembicObject::get_object()
646 bool AlembicObject::has_data_loaded()
const
651 void AlembicObject::update_shader_attributes(
const ICompoundProperty &arb_geom_params,
661 bool attr_exists =
false;
662 foreach (CachedData::CachedAttribute &cached_attr, cached_data.attributes) {
663 if (cached_attr.name == attr.
name) {
673 read_attribute(arb_geom_params, attr.
name, progress);
676 cached_data.invalidate_last_loaded_time(
true);
677 need_shader_update =
false;
680 template<
typename SchemaType>
681 void AlembicObject::read_face_sets(SchemaType &schema,
683 ISampleSelector sample_sel)
685 std::vector<std::string> face_sets;
686 schema.getFaceSetNames(face_sets);
688 if (face_sets.empty()) {
692 const Int32ArraySamplePtr face_counts = schema.getFaceCountsProperty().getValue();
694 polygon_to_shader.
resize(face_counts->size());
696 foreach (
const std::string &face_set_name, face_sets) {
697 int shader_index = 0;
699 foreach (
Node *
node, get_used_shaders()) {
700 if (
node->name == face_set_name) {
707 if (shader_index >= get_used_shaders().
size()) {
712 const IFaceSet face_set = schema.getFaceSet(face_set_name);
714 if (!face_set.valid()) {
718 const IFaceSetSchema face_schem = face_set.getSchema();
719 const IFaceSetSchema::Sample face_sample = face_schem.getValue(sample_sel);
720 const Int32ArraySamplePtr group_faces = face_sample.getFaces();
721 const size_t num_group_faces = group_faces->size();
723 for (
size_t l = 0;
l < num_group_faces;
l++) {
724 size_t pos = (*group_faces)[
l];
726 if (
pos >= polygon_to_shader.
size()) {
730 polygon_to_shader[
pos] = shader_index;
735 void AlembicObject::load_all_data(AlembicProcedural *proc,
736 IPolyMeshSchema &schema,
746 const TimeSamplingPtr time_sampling = schema.getTimeSampling();
747 cached_data.set_time_sampling(*time_sampling);
749 const IN3fGeomParam &
normals = schema.getNormalsParam();
751 ccl::set<chrono_t> times = get_relevant_sample_times(
752 proc, *time_sampling, schema.getNumSamples());
760 foreach (chrono_t
time, times) {
765 const ISampleSelector iss = ISampleSelector(
time);
766 const IPolyMeshSchema::Sample
sample = schema.getValue(iss);
768 add_positions(
sample.getPositions(),
time, cached_data);
771 if (schema.getTopologyVariance() != kHomogenousTopology || cached_data.triangles.size() == 0) {
774 if (key == previous_key) {
775 cached_data.triangles.reuse_data_for_last_time(
time);
776 cached_data.triangles_loops.reuse_data_for_last_time(
time);
777 cached_data.shader.reuse_data_for_last_time(
time);
784 read_face_sets(schema, polygon_to_shader, iss);
787 sample.getFaceCounts(),
sample.getFaceIndices(),
time, cached_data, polygon_to_shader);
802 update_shader_attributes(schema.getArbGeomParams(), progress);
808 const IV2fGeomParam &uvs = schema.getUVsParam();
811 add_uvs(proc, uvs, cached_data, progress);
817 void AlembicObject::load_all_data(AlembicProcedural *proc, ISubDSchema &schema,
Progress &progress)
828 const TimeSamplingPtr time_sampling = schema.getTimeSampling();
829 cached_data.set_time_sampling(*time_sampling);
831 ccl::set<chrono_t> times = get_relevant_sample_times(
832 proc, *time_sampling, schema.getNumSamples());
835 foreach (chrono_t
time, times) {
840 const ISampleSelector iss = ISampleSelector(
time);
841 const ISubDSchema::Sample
sample = schema.getValue(iss);
843 add_positions(
sample.getPositions(),
time, cached_data);
845 const Int32ArraySamplePtr face_counts =
sample.getFaceCounts();
846 const Int32ArraySamplePtr face_indices =
sample.getFaceIndices();
850 read_face_sets(schema, polygon_to_shader, iss);
860 const size_t num_faces = face_counts->
size();
861 const int *face_counts_array = face_counts->get();
862 const int *face_indices_array = face_indices->get();
866 for (
size_t i = 0; i < face_counts->size(); i++) {
867 num_ngons += (face_counts_array[i] == 4 ? 0 : 1);
868 num_corners += face_counts_array[i];
871 subd_start_corner.
reserve(num_faces);
872 subd_num_corners.
reserve(num_faces);
873 subd_smooth.
reserve(num_faces);
874 subd_ptex_offset.
reserve(num_faces);
875 shader.reserve(num_faces);
876 subd_face_corners.
reserve(num_corners);
878 int start_corner = 0;
879 int current_shader = 0;
882 for (
size_t i = 0; i < face_counts->size(); i++) {
883 num_corners = face_counts_array[i];
885 if (!polygon_to_shader.
empty()) {
886 current_shader = polygon_to_shader[i];
892 for (
int j = 0; j < num_corners; ++j) {
896 shader.push_back_reserved(current_shader);
900 ptex_offset += (num_corners == 4 ? 1 : num_corners);
902 start_corner += num_corners;
906 cached_data.subd_start_corner.add_data(subd_start_corner,
time);
907 cached_data.subd_num_corners.add_data(subd_num_corners,
time);
908 cached_data.subd_smooth.add_data(subd_smooth,
time);
909 cached_data.subd_ptex_offset.add_data(subd_ptex_offset,
time);
910 cached_data.subd_face_corners.add_data(subd_face_corners,
time);
911 cached_data.num_ngons.add_data(num_ngons,
time);
914 Int32ArraySamplePtr creases_length =
sample.getCreaseLengths();
915 Int32ArraySamplePtr creases_indices =
sample.getCreaseIndices();
916 FloatArraySamplePtr creases_sharpnesses =
sample.getCreaseSharpnesses();
918 if (creases_length && creases_indices && creases_sharpnesses) {
922 creases_edge.
reserve(creases_sharpnesses->size() * 2);
923 creases_weight.
reserve(creases_sharpnesses->size());
925 int length_offset = 0;
926 int weight_offset = 0;
927 for (
size_t c = 0;
c < creases_length->size(); ++
c) {
928 const int crease_length = creases_length->get()[
c];
930 for (
size_t j = 0; j < crease_length - 1; ++j) {
936 length_offset += crease_length;
939 cached_data.subd_creases_edge.add_data(creases_edge,
time);
940 cached_data.subd_creases_weight.add_data(creases_weight,
time);
953 void AlembicObject::load_all_data(AlembicProcedural *proc,
954 const ICurvesSchema &schema,
956 float default_radius)
965 const TimeSamplingPtr time_sampling = schema.getTimeSampling();
966 cached_data.set_time_sampling(*time_sampling);
968 ccl::set<chrono_t> times = get_relevant_sample_times(
969 proc, *time_sampling, schema.getNumSamples());
971 foreach (chrono_t
time, times) {
976 const ISampleSelector iss = ISampleSelector(
time);
977 const ICurvesSchema::Sample
sample = schema.getValue(iss);
979 const Int32ArraySamplePtr curves_num_vertices =
sample.getCurvesNumVertices();
980 const P3fArraySamplePtr position =
sample.getPositions();
982 const IFloatGeomParam widths_param = schema.getWidthsParam();
983 FloatArraySamplePtr radiuses;
985 if (widths_param.valid()) {
986 IFloatGeomParam::Sample wsample = widths_param.getExpandedValue(iss);
987 radiuses = wsample.getVals();
990 const bool do_radius = (radiuses !=
nullptr) && (radiuses->size() > 1);
991 float radius = (radiuses && radiuses->size() == 1) ? (*radiuses)[0] : default_radius;
998 const bool is_homogenous = schema.getTopologyVariance() == kHomogenousTopology;
1000 curve_keys.
reserve(position->size());
1001 curve_radius.
reserve(position->size());
1002 curve_first_key.
reserve(curves_num_vertices->size());
1003 curve_shader.
reserve(curves_num_vertices->size());
1006 for (
size_t i = 0; i < curves_num_vertices->size(); i++) {
1007 const int num_vertices = curves_num_vertices->get()[i];
1009 for (
int j = 0; j < num_vertices; j++) {
1010 const V3f &f = position->get()[offset + j];
1014 radius = (*radiuses)[offset + j];
1020 if (!is_homogenous || cached_data.curve_first_key.size() == 0) {
1025 offset += num_vertices;
1028 cached_data.curve_keys.add_data(curve_keys,
time);
1029 cached_data.curve_radius.add_data(curve_radius,
time);
1031 if (!is_homogenous || cached_data.curve_first_key.size() == 0) {
1032 cached_data.curve_first_key.add_data(curve_first_key,
time);
1033 cached_data.curve_shader.add_data(curve_shader,
time);
1042 void AlembicObject::setup_transform_cache(
float scale)
1044 cached_data.transforms.clear();
1045 cached_data.transforms.invalidate_last_loaded_time();
1047 if (scale == 0.0f) {
1051 if (xform_time_sampling) {
1052 cached_data.transforms.set_time_sampling(*xform_time_sampling);
1055 if (xform_samples.size() == 0) {
1057 cached_data.transforms.add_data(tfm, 0.0);
1063 M44d first_matrix = xform_samples.begin()->first;
1064 bool has_animation =
false;
1065 for (
const std::pair<chrono_t, M44d> pair : xform_samples) {
1066 if (pair.second != first_matrix) {
1067 has_animation =
true;
1072 if (!has_animation) {
1074 cached_data.transforms.add_data(tfm, 0.0);
1077 for (
const std::pair<chrono_t, M44d> pair : xform_samples) {
1079 cached_data.transforms.add_data(tfm, pair.first);
1089 Geometry *geometry =
object->get_geometry();
1092 foreach (
Node *
node, geometry->get_used_shaders()) {
1096 if (attr.
name !=
"") {
1097 requested_attributes.
add(attr.
name);
1102 return requested_attributes;
1105 void AlembicObject::read_attribute(
const ICompoundProperty &arb_geom_params,
1106 const ustring &attr_name,
1109 const PropertyHeader *prop = arb_geom_params.getPropertyHeader(attr_name.c_str());
1111 if (prop ==
nullptr) {
1115 if (IV2fProperty::matches(prop->getMetaData()) && Alembic::AbcGeom::isUV(*prop)) {
1116 const IV2fGeomParam ¶m = IV2fGeomParam(arb_geom_params, prop->getName());
1118 CachedData::CachedAttribute &attribute = cached_data.add_attribute(attr_name,
1119 *param.getTimeSampling());
1121 for (
size_t i = 0; i < param.getNumSamples(); ++i) {
1126 ISampleSelector iss = ISampleSelector(index_t(i));
1128 IV2fGeomParam::Sample
sample;
1129 param.getIndexed(
sample, iss);
1131 const chrono_t
time = param.getTimeSampling()->getSampleTime(index_t(i));
1133 if (param.getScope() == kFacevaryingScope) {
1134 V2fArraySamplePtr values =
sample.getVals();
1142 cached_data.triangles.data_for_time_no_check(
time).get_data_or_null();
1144 cached_data.triangles_loops.data_for_time_no_check(
time).get_data_or_null();
1146 if (!triangles || !triangles_loops) {
1155 for (
const int3 &loop : *triangles_loops) {
1156 unsigned int v0 = (*indices)[loop.x];
1157 unsigned int v1 = (*indices)[loop.y];
1158 unsigned int v2 = (*indices)[loop.z];
1160 data_float2[0] =
make_float2((*values)[v0][0], (*values)[v0][1]);
1166 attribute.data.set_time_sampling(*param.getTimeSampling());
1167 attribute.data.add_data(
data,
time);
1171 else if (IC3fProperty::matches(prop->getMetaData())) {
1172 const IC3fGeomParam ¶m = IC3fGeomParam(arb_geom_params, prop->getName());
1174 CachedData::CachedAttribute &attribute = cached_data.add_attribute(attr_name,
1175 *param.getTimeSampling());
1177 for (
size_t i = 0; i < param.getNumSamples(); ++i) {
1182 ISampleSelector iss = ISampleSelector(index_t(i));
1184 IC3fGeomParam::Sample
sample;
1185 param.getIndexed(
sample, iss);
1187 const chrono_t
time = param.getTimeSampling()->getSampleTime(index_t(i));
1189 C3fArraySamplePtr values =
sample.getVals();
1193 if (param.getScope() == kVaryingScope) {
1198 cached_data.triangles.data_for_time_no_check(
time).get_data_or_null();
1210 for (
const int3 &tri : *triangles) {
1211 Imath::C3f
v = (*values)[tri.x];
1214 v = (*values)[tri.y];
1217 v = (*values)[tri.z];
1223 attribute.data.set_time_sampling(*param.getTimeSampling());
1224 attribute.data.add_data(
data,
time);
1228 else if (IC4fProperty::matches(prop->getMetaData())) {
1229 const IC4fGeomParam ¶m = IC4fGeomParam(arb_geom_params, prop->getName());
1231 CachedData::CachedAttribute &attribute = cached_data.add_attribute(attr_name,
1232 *param.getTimeSampling());
1234 for (
size_t i = 0; i < param.getNumSamples(); ++i) {
1239 ISampleSelector iss = ISampleSelector(index_t(i));
1241 IC4fGeomParam::Sample
sample;
1242 param.getIndexed(
sample, iss);
1244 const chrono_t
time = param.getTimeSampling()->getSampleTime(index_t(i));
1246 C4fArraySamplePtr values =
sample.getVals();
1250 if (param.getScope() == kVaryingScope) {
1255 cached_data.triangles.data_for_time_no_check(
time).get_data_or_null();
1267 for (
const int3 &tri : *triangles) {
1268 Imath::C4f
v = (*values)[tri.x];
1271 v = (*values)[tri.y];
1274 v = (*values)[tri.z];
1280 attribute.data.set_time_sampling(*param.getTimeSampling());
1281 attribute.data.add_data(
data,
time);
1289 static void update_attributes(
AttributeSet &attributes, CachedData &cached_data,
double frame_time)
1291 set<Attribute *> cached_attributes;
1293 for (CachedData::CachedAttribute &attribute : cached_data.attributes) {
1294 const array<char> *attr_data = attribute.
data.data_for_time(frame_time).get_data_or_null();
1298 attr = attributes.
add(attribute.std, attribute.name);
1301 attr = attributes.
add(attribute.name, attribute.type_desc, attribute.element);
1305 cached_attributes.insert(attr);
1314 if (attr->
buffer.size() != attr_data->
size()) {
1318 memcpy(attr->
data(), attr_data->
data(), attr_data->
size());
1323 list<Attribute>::iterator it;
1325 if (cached_attributes.find(&(*it)) == cached_attributes.end()) {
1353 AlembicProcedural::AlembicProcedural() :
Procedural(get_node_type())
1355 objects_loaded =
false;
1359 AlembicProcedural::~AlembicProcedural()
1361 ccl::set<Geometry *> geometries_set;
1362 ccl::set<Object *> objects_set;
1363 ccl::set<AlembicObject *> abc_objects_set;
1366 AlembicObject *abc_object =
static_cast<AlembicObject *
>(
node);
1368 if (abc_object->get_object()) {
1369 objects_set.insert(abc_object->get_object());
1371 if (abc_object->get_object()->get_geometry()) {
1372 geometries_set.insert(abc_object->get_object()->get_geometry());
1376 delete_node(abc_object);
1381 assert(geometries_set.empty());
1382 assert(objects_set.empty());
1386 scene_->delete_nodes(geometries_set,
this);
1387 scene_->delete_nodes(objects_set,
this);
1392 assert(scene_ ==
nullptr || scene_ ==
scene);
1395 if (frame < start_frame || frame > end_frame) {
1400 bool need_shader_updates =
false;
1401 bool need_data_updates =
false;
1403 foreach (
Node *object_node, objects) {
1404 AlembicObject *
object =
static_cast<AlembicObject *
>(object_node);
1406 if (object->is_modified()) {
1407 need_data_updates =
true;
1411 if (object->used_shaders_is_modified() &&
object->get_object() &&
1412 object->get_object()->get_geometry()) {
1413 Geometry *geometry =
object->get_object()->get_geometry();
1415 geometry->set_used_shaders(used_shaders);
1416 need_shader_updates =
true;
1420 foreach (
Node *shader_node, object->get_used_shaders()) {
1423 if (
shader->need_update_geometry()) {
1424 object->need_shader_update =
true;
1425 need_shader_updates =
true;
1430 if (!is_modified() && !need_shader_updates && !need_data_updates) {
1434 if (!archive.valid()) {
1435 Alembic::AbcCoreFactory::IFactory factory;
1436 factory.setPolicy(Alembic::Abc::ErrorHandler::kQuietNoopPolicy);
1437 archive = factory.getArchive(filepath.c_str());
1439 if (!archive.valid()) {
1447 if (!objects_loaded || objects_is_modified()) {
1448 load_objects(progress);
1449 objects_loaded =
true;
1452 const chrono_t frame_time = (chrono_t)((frame - frame_offset) / frame_rate);
1454 build_caches(progress);
1457 AlembicObject *
object =
static_cast<AlembicObject *
>(
node);
1464 if (object->is_constant() && !
object->is_modified() && !
object->need_shader_update &&
1465 !scale_is_modified()) {
1469 if (object->schema_type == AlembicObject::POLY_MESH) {
1470 read_mesh(
object, frame_time);
1472 else if (object->schema_type == AlembicObject::CURVES) {
1473 read_curves(
object, frame_time);
1475 else if (object->schema_type == AlembicObject::SUBD) {
1476 read_subd(
object, frame_time);
1479 object->clear_modified();
1485 void AlembicProcedural::add_object(AlembicObject *
object)
1487 objects.push_back_slow(
object);
1488 tag_objects_modified();
1491 void AlembicProcedural::tag_update(
Scene *
scene)
1496 AlembicObject *AlembicProcedural::get_or_create_object(
const ustring &path)
1499 AlembicObject *
object =
static_cast<AlembicObject *
>(
node);
1501 if (object->get_path() == path) {
1506 AlembicObject *
object = create_node<AlembicObject>();
1507 object->set_path(path);
1514 void AlembicProcedural::load_objects(
Progress &progress)
1516 unordered_map<string, AlembicObject *> object_map;
1519 AlembicObject *
object =
static_cast<AlembicObject *
>(
node);
1522 if (object->get_object() ==
nullptr) {
1523 object_map.insert({
object->get_path().c_str(),
object});
1527 IObject root = archive.getTop();
1529 for (
size_t i = 0; i < root.getNumChildren(); ++i) {
1530 walk_hierarchy(root, root.getChildHeader(i), {}, object_map, progress);
1534 for (std::pair<string, AlembicObject *> pair : object_map) {
1535 AlembicObject *abc_object = pair.second;
1539 if (!abc_object->instance_of) {
1540 if (abc_object->schema_type == AlembicObject::CURVES) {
1541 geometry = scene_->create_node<
Hair>();
1543 else if (abc_object->schema_type == AlembicObject::POLY_MESH ||
1544 abc_object->schema_type == AlembicObject::SUBD) {
1545 geometry = scene_->create_node<
Mesh>();
1552 geometry->
name = abc_object->iobject.getName();
1554 array<Node *> used_shaders = abc_object->get_used_shaders();
1555 geometry->set_used_shaders(used_shaders);
1560 object->set_geometry(geometry);
1561 object->name = abc_object->iobject.getName();
1563 abc_object->set_object(
object);
1568 AlembicObject *abc_object =
static_cast<AlembicObject *
>(
node);
1570 if (abc_object->instance_of) {
1571 abc_object->get_object()->set_geometry(
1572 abc_object->instance_of->get_object()->get_geometry());
1573 abc_object->schema_type = abc_object->instance_of->schema_type;
1578 void AlembicProcedural::read_mesh(AlembicObject *abc_object, Abc::chrono_t frame_time)
1580 CachedData &cached_data = abc_object->get_cached_data();
1584 Object *
object = abc_object->get_object();
1585 cached_data.transforms.copy_to_socket(frame_time,
object, object->get_tfm_socket());
1592 if (abc_object->instance_of) {
1596 Mesh *
mesh =
static_cast<Mesh *
>(
object->get_geometry());
1599 if (
mesh->used_shaders_is_modified()) {
1600 mesh->tag_shader_modified();
1603 cached_data.vertices.copy_to_socket(frame_time,
mesh,
mesh->get_verts_socket());
1605 cached_data.shader.copy_to_socket(frame_time,
mesh,
mesh->get_shader_socket());
1607 array<int3> *triangle_data = cached_data.triangles.data_for_time(frame_time).get_data_or_null();
1608 if (triangle_data) {
1615 for (
size_t i = 0; i < triangle_data->
size(); ++i) {
1616 int3 tri = (*triangle_data)[i];
1623 mesh->set_triangles(triangles);
1624 mesh->set_smooth(smooth);
1640 bool need_rebuild =
mesh->triangles_is_modified();
1645 void AlembicProcedural::read_subd(AlembicObject *abc_object, Abc::chrono_t frame_time)
1647 CachedData &cached_data = abc_object->get_cached_data();
1649 if (abc_object->subd_max_level_is_modified() || abc_object->subd_dicing_rate_is_modified()) {
1651 cached_data.invalidate_last_loaded_time();
1656 Object *
object = abc_object->get_object();
1657 cached_data.transforms.copy_to_socket(frame_time,
object, object->get_tfm_socket());
1664 if (abc_object->instance_of) {
1668 Mesh *
mesh =
static_cast<Mesh *
>(
object->get_geometry());
1671 if (
mesh->used_shaders_is_modified()) {
1672 mesh->tag_shader_modified();
1677 if (!cached_data.is_constant()) {
1678 cached_data.invalidate_last_loaded_time();
1682 mesh->set_triangles(triangles);
1688 mesh->set_subdivision_type(Mesh::SubdivisionType::SUBDIVISION_CATMULL_CLARK);
1689 mesh->set_subd_max_level(abc_object->get_subd_max_level());
1690 mesh->set_subd_dicing_rate(abc_object->get_subd_dicing_rate());
1692 cached_data.vertices.copy_to_socket(frame_time,
mesh,
mesh->get_verts_socket());
1695 cached_data.shader.copy_to_socket(frame_time,
mesh,
mesh->get_subd_shader_socket());
1697 cached_data.subd_start_corner.copy_to_socket(
1698 frame_time,
mesh,
mesh->get_subd_start_corner_socket());
1700 cached_data.subd_num_corners.copy_to_socket(
1701 frame_time,
mesh,
mesh->get_subd_num_corners_socket());
1703 cached_data.subd_smooth.copy_to_socket(frame_time,
mesh,
mesh->get_subd_smooth_socket());
1705 cached_data.subd_ptex_offset.copy_to_socket(
1706 frame_time,
mesh,
mesh->get_subd_ptex_offset_socket());
1708 cached_data.subd_face_corners.copy_to_socket(
1709 frame_time,
mesh,
mesh->get_subd_face_corners_socket());
1711 cached_data.num_ngons.copy_to_socket(frame_time,
mesh,
mesh->get_num_ngons_socket());
1713 cached_data.subd_creases_edge.copy_to_socket(
1714 frame_time,
mesh,
mesh->get_subd_creases_edge_socket());
1716 cached_data.subd_creases_weight.copy_to_socket(
1717 frame_time,
mesh,
mesh->get_subd_creases_weight_socket());
1723 update_attributes(
mesh->subd_attributes, cached_data, frame_time);
1734 bool need_rebuild = (
mesh->triangles_is_modified()) ||
1735 (
mesh->subd_num_corners_is_modified()) ||
1736 (
mesh->subd_shader_is_modified()) || (
mesh->subd_smooth_is_modified()) ||
1737 (
mesh->subd_ptex_offset_is_modified()) ||
1738 (
mesh->subd_start_corner_is_modified()) ||
1739 (
mesh->subd_face_corners_is_modified());
1745 void AlembicProcedural::read_curves(AlembicObject *abc_object, Abc::chrono_t frame_time)
1747 CachedData &cached_data = abc_object->get_cached_data();
1751 Object *
object = abc_object->get_object();
1752 cached_data.transforms.copy_to_socket(frame_time,
object, object->get_tfm_socket());
1759 if (abc_object->instance_of) {
1763 Hair *hair =
static_cast<Hair *
>(
object->get_geometry());
1766 if (hair->used_shaders_is_modified()) {
1767 hair->tag_curve_shader_modified();
1770 cached_data.curve_keys.copy_to_socket(frame_time, hair, hair->get_curve_keys_socket());
1772 cached_data.curve_radius.copy_to_socket(frame_time, hair, hair->get_curve_radius_socket());
1774 cached_data.curve_shader.copy_to_socket(frame_time, hair, hair->get_curve_shader_socket());
1776 cached_data.curve_first_key.copy_to_socket(frame_time, hair, hair->get_curve_first_key_socket());
1780 update_attributes(hair->
attributes, cached_data, frame_time);
1788 for (
size_t i = 0; i < hair->
num_curves(); i++) {
1793 const bool rebuild = (hair->curve_keys_is_modified() || hair->curve_radius_is_modified());
1797 void AlembicProcedural::walk_hierarchy(
1799 const ObjectHeader &header,
1800 MatrixSamplesData matrix_samples_data,
1801 const unordered_map<std::string, AlembicObject *> &object_map,
1808 IObject next_object;
1810 MatrixSampleMap concatenated_xform_samples;
1812 if (IXform::matches(header)) {
1813 IXform xform(parent, header.getName());
1815 IXformSchema &xs = xform.getSchema();
1817 if (xs.getNumOps() > 0) {
1818 TimeSamplingPtr ts = xs.getTimeSampling();
1819 MatrixSampleMap local_xform_samples;
1821 MatrixSampleMap *temp_xform_samples =
nullptr;
1822 if (matrix_samples_data.samples ==
nullptr) {
1824 temp_xform_samples = &concatenated_xform_samples;
1828 temp_xform_samples = &local_xform_samples;
1831 for (
size_t i = 0; i < xs.getNumSamples(); ++i) {
1832 chrono_t sample_time = ts->getSampleTime(index_t(i));
1833 XformSample
sample = xs.getValue(ISampleSelector(sample_time));
1834 temp_xform_samples->insert({sample_time,
sample.getMatrix()});
1837 if (matrix_samples_data.samples !=
nullptr) {
1838 concatenate_xform_samples(
1839 *matrix_samples_data.samples, local_xform_samples, concatenated_xform_samples);
1842 matrix_samples_data.samples = &concatenated_xform_samples;
1843 matrix_samples_data.time_sampling = ts;
1846 next_object = xform;
1848 else if (ISubD::matches(header)) {
1849 ISubD subd(parent, header.getName());
1851 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1852 iter = object_map.find(subd.getFullName());
1854 if (iter != object_map.end()) {
1855 AlembicObject *abc_object = iter->second;
1856 abc_object->iobject = subd;
1857 abc_object->schema_type = AlembicObject::SUBD;
1859 if (matrix_samples_data.samples) {
1860 abc_object->xform_samples = *matrix_samples_data.samples;
1861 abc_object->xform_time_sampling = matrix_samples_data.time_sampling;
1867 else if (IPolyMesh::matches(header)) {
1868 IPolyMesh
mesh(parent, header.getName());
1870 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1871 iter = object_map.find(
mesh.getFullName());
1873 if (iter != object_map.end()) {
1874 AlembicObject *abc_object = iter->second;
1875 abc_object->iobject =
mesh;
1876 abc_object->schema_type = AlembicObject::POLY_MESH;
1878 if (matrix_samples_data.samples) {
1879 abc_object->xform_samples = *matrix_samples_data.samples;
1880 abc_object->xform_time_sampling = matrix_samples_data.time_sampling;
1886 else if (ICurves::matches(header)) {
1887 ICurves curves(parent, header.getName());
1889 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1890 iter = object_map.find(curves.getFullName());
1892 if (iter != object_map.end()) {
1893 AlembicObject *abc_object = iter->second;
1894 abc_object->iobject = curves;
1895 abc_object->schema_type = AlembicObject::CURVES;
1897 if (matrix_samples_data.samples) {
1898 abc_object->xform_samples = *matrix_samples_data.samples;
1899 abc_object->xform_time_sampling = matrix_samples_data.time_sampling;
1903 next_object = curves;
1905 else if (IFaceSet::matches(header)) {
1908 else if (IPoints::matches(header)) {
1911 else if (INuPatch::matches(header)) {
1915 next_object = parent.getChild(header.getName());
1917 if (next_object.isInstanceRoot()) {
1918 unordered_map<std::string, AlembicObject *>::const_iterator iter;
1921 iter = object_map.find(next_object.getFullName());
1923 if (iter != object_map.end()) {
1924 AlembicObject *abc_object = iter->second;
1927 iter = object_map.find(next_object.instanceSourcePath());
1929 if (iter != object_map.end()) {
1930 abc_object->iobject = next_object;
1931 abc_object->instance_of = iter->second;
1933 if (matrix_samples_data.samples) {
1934 abc_object->xform_samples = *matrix_samples_data.samples;
1935 abc_object->xform_time_sampling = matrix_samples_data.time_sampling;
1942 if (next_object.valid()) {
1943 for (
size_t i = 0; i < next_object.getNumChildren(); ++i) {
1945 next_object, next_object.getChildHeader(i), matrix_samples_data, object_map, progress);
1950 void AlembicProcedural::build_caches(
Progress &progress)
1953 AlembicObject *
object =
static_cast<AlembicObject *
>(
node);
1959 if (object->schema_type == AlembicObject::POLY_MESH) {
1960 if (!object->has_data_loaded()) {
1961 IPolyMesh polymesh(object->iobject, Alembic::Abc::kWrapExisting);
1962 IPolyMeshSchema schema = polymesh.getSchema();
1963 object->load_all_data(
this, schema, progress);
1965 else if (object->need_shader_update) {
1966 IPolyMesh polymesh(object->iobject, Alembic::Abc::kWrapExisting);
1967 IPolyMeshSchema schema = polymesh.getSchema();
1968 object->update_shader_attributes(schema.getArbGeomParams(), progress);
1971 else if (object->schema_type == AlembicObject::CURVES) {
1972 if (!object->has_data_loaded() || default_radius_is_modified() ||
1973 object->radius_scale_is_modified()) {
1974 ICurves curves(object->iobject, Alembic::Abc::kWrapExisting);
1975 ICurvesSchema schema = curves.getSchema();
1976 object->load_all_data(
this, schema, progress, default_radius);
1979 else if (object->schema_type == AlembicObject::SUBD) {
1980 if (!object->has_data_loaded()) {
1981 ISubD subd_mesh(object->iobject, Alembic::Abc::kWrapExisting);
1982 ISubDSchema schema = subd_mesh.getSchema();
1983 object->load_all_data(
this, schema, progress);
1985 else if (object->need_shader_update) {
1986 ISubD subd_mesh(object->iobject, Alembic::Abc::kWrapExisting);
1987 ISubDSchema schema = subd_mesh.getSchema();
1988 object->update_shader_attributes(schema.getArbGeomParams(), progress);
1992 if (scale_is_modified() || object->get_cached_data().transforms.size() == 0) {
1993 object->setup_transform_cache(scale);
typedef double(DMatrix)[4][4]
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum 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
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
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
bool need_attribute(Scene *scene, AttributeStandard std)
void tag_update(Scene *scene, bool rebuild)
void push_back_reserved(const T &t)
T * resize(size_t newsize)
void reserve(size_t newcapacity)
static float normals[][3]
#define CCL_NAMESPACE_END
#define make_float2(x, y)
#define make_float4(x, y, z, w)
#define make_int3(x, y, z)
#define make_float3(x, y, z)
void KERNEL_FUNCTION_FULL_NAME() shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int filter, int i, int offset, int sample)
@ ATTR_ELEMENT_CORNER_BYTE
static char * generate(GHash *messages, size_t *r_output_size)
static void clear(Message *msg)
static float lerp(float t, float a, float b)
static void sample(SocketReader *reader, int x, int y, float color[4])
#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_STRING(name, ui_name, default_value,...)
Curve get_curve(size_t i) const
size_t num_curves() const
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
ccl_device uchar4 color_float4_to_uchar4(float4 c)
ccl_device uchar4 color_float_to_byte(float3 c)
static constexpr TypeDesc TypeRGBA(TypeDesc::FLOAT, TypeDesc::VEC4, TypeDesc::COLOR)
CCL_NAMESPACE_BEGIN static constexpr OIIO_NAMESPACE_USING TypeDesc TypeFloat2(TypeDesc::FLOAT, TypeDesc::VEC2)