28 # include <Alembic/AbcCoreFactory/All.h>
29 # include <Alembic/AbcGeom/All.h>
33 class AlembicProcedural;
39 using MatrixSampleMap = std::map<Alembic::Abc::chrono_t, Alembic::Abc::M44d>;
41 struct MatrixSamplesData {
42 MatrixSampleMap *samples =
nullptr;
43 Alembic::AbcCoreAbstract::TimeSamplingPtr time_sampling;
47 template<
typename>
struct is_array :
public std::false_type {
50 template<
typename T>
struct is_array<
array<
T>> :
public std::true_type {
55 template<
typename T>
class CacheLookupResult {
68 CacheLookupResult() =
default;
71 static CacheLookupResult new_data(
T *
data_)
75 result.state = State::NEW_DATA;
79 static CacheLookupResult no_data_found_for_time()
83 result.state = State::NO_DATA_FOR_TIME;
87 static CacheLookupResult already_loaded()
91 result.state = State::ALREADY_LOADED;
96 const T &get_data()
const
98 assert(
state == State::NEW_DATA);
99 assert(
data !=
nullptr);
103 T *get_data_or_null()
const
109 bool has_new_data()
const
111 return state == State::NEW_DATA;
114 bool has_already_loaded()
const
116 return state == State::ALREADY_LOADED;
119 bool has_no_data_for_time()
const
121 return state == State::NO_DATA_FOR_TIME;
130 template<
typename T>
class DataStore {
132 struct TimeIndexPair {
136 double source_time = 0;
150 Alembic::AbcCoreAbstract::TimeSampling time_sampling{};
155 void set_time_sampling(Alembic::AbcCoreAbstract::TimeSampling time_sampling_)
157 time_sampling = time_sampling_;
160 Alembic::AbcCoreAbstract::TimeSampling get_time_sampling()
const
162 return time_sampling;
167 CacheLookupResult<T> data_for_time(
double time)
170 return CacheLookupResult<T>::no_data_found_for_time();
173 const TimeIndexPair &index = get_index_for_time(
time);
175 if (index.index == -1ul) {
176 return CacheLookupResult<T>::no_data_found_for_time();
179 if (last_loaded_time == index.time || last_loaded_time == index.source_time) {
180 return CacheLookupResult<T>::already_loaded();
183 last_loaded_time = index.source_time;
185 assert(index.index <
data.size());
187 return CacheLookupResult<T>::new_data(&
data[index.index]);
192 CacheLookupResult<T> data_for_time_no_check(
double time)
195 return CacheLookupResult<T>::no_data_found_for_time();
198 const TimeIndexPair &index = get_index_for_time(
time);
200 if (index.index == -1ul) {
201 return CacheLookupResult<T>::no_data_found_for_time();
204 assert(index.index <
data.size());
206 return CacheLookupResult<T>::new_data(&
data[index.index]);
213 if constexpr (is_array<T>::value) {
222 void reuse_data_for_last_time(
double time)
224 const TimeIndexPair &data_index = index_data_map.back();
225 index_data_map.push_back({
time, data_index.source_time, data_index.index});
228 bool is_constant()
const
230 return data.size() <= 1;
240 invalidate_last_loaded_time();
242 index_data_map.clear();
245 void invalidate_last_loaded_time()
254 CacheLookupResult<T>
result = data_for_time(
time);
256 if (!
result.has_new_data()) {
263 node->set(*socket, value);
267 const TimeIndexPair &get_index_for_time(
double time)
const
269 std::pair<size_t, Alembic::Abc::chrono_t> index_pair;
270 index_pair = time_sampling.getNearIndex(
time, index_data_map.size());
271 return index_data_map[index_pair.first];
280 DataStore<Transform> transforms{};
283 DataStore<array<float3>> vertices;
284 DataStore<array<int3>> triangles{};
287 DataStore<array<int3>> triangles_loops{};
288 DataStore<array<int>>
shader{};
291 DataStore<array<int>> subd_start_corner;
292 DataStore<array<int>> subd_num_corners;
293 DataStore<array<bool>> subd_smooth;
294 DataStore<array<int>> subd_ptex_offset;
295 DataStore<array<int>> subd_face_corners;
296 DataStore<int> num_ngons;
297 DataStore<array<int>> subd_creases_edge;
298 DataStore<array<float>> subd_creases_weight;
301 DataStore<array<float3>> curve_keys;
302 DataStore<array<float>> curve_radius;
303 DataStore<array<int>> curve_first_key;
304 DataStore<array<int>> curve_shader;
306 struct CachedAttribute {
311 DataStore<array<char>>
data{};
318 CachedAttribute &add_attribute(
const ustring &name,
319 const Alembic::Abc::TimeSampling &time_sampling);
321 bool is_constant()
const;
323 void invalidate_last_loaded_time(
bool attributes_only =
false);
325 void set_time_sampling(Alembic::AbcCoreAbstract::TimeSampling time_sampling);
337 class AlembicObject :
public Node {
360 friend class AlembicProcedural;
362 void set_object(
Object *
object);
365 void load_all_data(AlembicProcedural *proc,
366 Alembic::AbcGeom::IPolyMeshSchema &schema,
368 void load_all_data(AlembicProcedural *proc,
369 Alembic::AbcGeom::ISubDSchema &schema,
371 void load_all_data(AlembicProcedural *proc,
372 const Alembic::AbcGeom::ICurvesSchema &schema,
374 float default_radius);
376 bool has_data_loaded()
const;
387 bool need_shader_update =
true;
389 AlembicObject *instance_of =
nullptr;
391 Alembic::AbcCoreAbstract::TimeSamplingPtr xform_time_sampling;
392 MatrixSampleMap xform_samples;
393 Alembic::AbcGeom::IObject iobject;
396 AbcSchemaType schema_type;
398 CachedData &get_cached_data()
403 bool is_constant()
const
405 return cached_data.is_constant();
410 bool data_loaded =
false;
412 CachedData cached_data;
414 void update_shader_attributes(
const Alembic::AbcGeom::ICompoundProperty &arb_geom_params,
417 void read_attribute(
const Alembic::AbcGeom::ICompoundProperty &arb_geom_params,
418 const ustring &attr_name,
421 template<
typename SchemaType>
422 void read_face_sets(SchemaType &schema,
424 Alembic::AbcGeom::ISampleSelector sample_sel);
426 void setup_transform_cache(
float scale);
441 Alembic::AbcGeom::IArchive archive;
478 ~AlembicProcedural();
495 AlembicObject *get_or_create_object(
const ustring &path);
499 void add_object(AlembicObject *
object);
502 void load_objects(
Progress &progress);
507 void walk_hierarchy(Alembic::AbcGeom::IObject parent,
508 const Alembic::AbcGeom::ObjectHeader &ohead,
509 MatrixSamplesData matrix_samples_data,
510 const unordered_map<string, AlembicObject *> &object_map,
515 void read_mesh(AlembicObject *abc_object, Alembic::AbcGeom::Abc::chrono_t frame_time);
519 void read_curves(AlembicObject *abc_object, Alembic::AbcGeom::Abc::chrono_t frame_time);
523 void read_subd(AlembicObject *abc_object, Alembic::AbcGeom::Abc::chrono_t frame_time);
525 void build_caches(
Progress &progress);
ATTR_WARN_UNUSED_RESULT const void * element
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
virtual void generate(Scene *scene, Progress &progress)=0
#define CCL_NAMESPACE_END
void KERNEL_FUNCTION_FULL_NAME() shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int filter, int i, int offset, int sample)
static void clear(Message *msg)
#define NODE_SOCKET_API_ARRAY(type_, name)
#define NODE_SOCKET_API(type_, name)