15 # include <Alembic/AbcCoreFactory/All.h>
16 # include <Alembic/AbcGeom/All.h>
20 class AlembicProcedural;
26 using MatrixSampleMap = std::map<Alembic::Abc::chrono_t, Alembic::Abc::M44d>;
28 struct MatrixSamplesData {
29 MatrixSampleMap *samples =
nullptr;
30 Alembic::AbcCoreAbstract::TimeSamplingPtr time_sampling;
34 template<
typename>
struct is_array :
public std::false_type {
37 template<
typename T>
struct is_array<
array<
T>> :
public std::true_type {
42 template<
typename T>
class CacheLookupResult {
55 CacheLookupResult() =
default;
58 static CacheLookupResult new_data(
T *
data_)
62 result.state = State::NEW_DATA;
66 static CacheLookupResult no_data_found_for_time()
70 result.state = State::NO_DATA_FOR_TIME;
74 static CacheLookupResult already_loaded()
78 result.state = State::ALREADY_LOADED;
83 const T &get_data()
const
85 assert(
state == State::NEW_DATA);
86 assert(
data !=
nullptr);
90 T *get_data_or_null()
const
96 bool has_new_data()
const
98 return state == State::NEW_DATA;
101 bool has_already_loaded()
const
103 return state == State::ALREADY_LOADED;
106 bool has_no_data_for_time()
const
108 return state == State::NO_DATA_FOR_TIME;
117 template<
typename T>
class DataStore {
119 struct TimeIndexPair {
123 double source_time = 0;
137 Alembic::AbcCoreAbstract::TimeSampling time_sampling{};
146 void set_time_sampling(Alembic::AbcCoreAbstract::TimeSampling time_sampling_)
148 time_sampling = time_sampling_;
151 Alembic::AbcCoreAbstract::TimeSampling get_time_sampling()
const
153 return time_sampling;
158 CacheLookupResult<T> data_for_time(
double time)
161 return CacheLookupResult<T>::no_data_found_for_time();
164 const TimeIndexPair &index = get_index_for_time(
time);
166 if (index.index == -1ul) {
167 return CacheLookupResult<T>::no_data_found_for_time();
170 if (last_loaded_time == index.time || last_loaded_time == index.source_time) {
171 return CacheLookupResult<T>::already_loaded();
174 last_loaded_time = index.source_time;
176 assert(index.index <
data.size());
178 return CacheLookupResult<T>::new_data(&
data[index.index]);
183 CacheLookupResult<T> data_for_time_no_check(
double time)
186 return CacheLookupResult<T>::no_data_found_for_time();
189 const TimeIndexPair &index = get_index_for_time(
time);
191 if (index.index == -1ul) {
192 return CacheLookupResult<T>::no_data_found_for_time();
195 assert(index.index <
data.size());
197 return CacheLookupResult<T>::new_data(&
data[index.index]);
204 if constexpr (is_array<T>::value) {
213 void reuse_data_for_last_time(
double time)
215 const TimeIndexPair &data_index = index_data_map.back();
216 index_data_map.push_back({
time, data_index.source_time, data_index.index});
219 void add_no_data(
double time)
221 index_data_map.push_back({
time,
time, -1ul});
224 bool is_constant()
const
226 return data.size() <= 1;
236 invalidate_last_loaded_time();
238 index_data_map.clear();
241 void invalidate_last_loaded_time()
250 CacheLookupResult<T>
result = data_for_time(
time);
252 if (!
result.has_new_data()) {
259 node->set(*socket, value);
262 size_t memory_used()
const
264 if constexpr (is_array<T>::value) {
274 return data.size() *
sizeof(
T);
278 const TimeIndexPair &get_index_for_time(
double time)
const
280 std::pair<size_t, Alembic::Abc::chrono_t> index_pair;
281 index_pair = time_sampling.getNearIndex(
time, index_data_map.size());
282 return index_data_map[index_pair.first];
291 DataStore<Transform> transforms{};
294 DataStore<array<float3>> vertices;
295 DataStore<array<int3>> triangles{};
298 DataStore<array<int>> uv_loops{};
299 DataStore<array<int>> shader{};
302 DataStore<array<int>> subd_start_corner;
303 DataStore<array<int>> subd_num_corners;
304 DataStore<array<bool>> subd_smooth;
305 DataStore<array<int>> subd_ptex_offset;
306 DataStore<array<int>> subd_face_corners;
307 DataStore<int> num_ngons;
308 DataStore<array<int>> subd_creases_edge;
309 DataStore<array<float>> subd_creases_weight;
310 DataStore<array<int>> subd_vertex_crease_indices;
311 DataStore<array<float>> subd_vertex_crease_weights;
314 DataStore<array<float3>> curve_keys;
315 DataStore<array<float>> curve_radius;
316 DataStore<array<int>> curve_first_key;
317 DataStore<array<int>> curve_shader;
320 DataStore<array<float3>> points;
321 DataStore<array<float>> radiuses;
322 DataStore<array<int>> points_shader;
324 struct CachedAttribute {
329 DataStore<array<char>>
data{};
336 CachedAttribute &add_attribute(
const ustring &name,
337 const Alembic::Abc::TimeSampling &time_sampling);
339 bool is_constant()
const;
341 void invalidate_last_loaded_time(
bool attributes_only =
false);
343 void set_time_sampling(Alembic::AbcCoreAbstract::TimeSampling time_sampling);
345 size_t memory_used()
const;
357 class AlembicObject :
public Node {
384 friend class AlembicProcedural;
386 void set_object(
Object *
object);
389 void load_data_in_cache(CachedData &cached_data,
390 AlembicProcedural *proc,
391 Alembic::AbcGeom::IPolyMeshSchema &schema,
393 void load_data_in_cache(CachedData &cached_data,
394 AlembicProcedural *proc,
395 Alembic::AbcGeom::ISubDSchema &schema,
397 void load_data_in_cache(CachedData &cached_data,
398 AlembicProcedural *proc,
399 const Alembic::AbcGeom::ICurvesSchema &schema,
402 bool has_data_loaded()
const;
414 bool need_shader_update =
true;
416 AlembicObject *instance_of =
nullptr;
418 Alembic::AbcCoreAbstract::TimeSamplingPtr xform_time_sampling;
419 MatrixSampleMap xform_samples;
420 Alembic::AbcGeom::IObject iobject;
423 AbcSchemaType schema_type;
425 CachedData &get_cached_data()
430 bool is_constant()
const
432 return cached_data_.is_constant();
437 cached_data_.clear();
442 bool data_loaded =
false;
444 CachedData cached_data_;
446 void setup_transform_cache(CachedData &cached_data,
float scale);
461 Alembic::AbcGeom::IArchive archive;
509 ~AlembicProcedural();
526 AlembicObject *get_or_create_object(
const ustring &path);
530 void add_object(AlembicObject *
object);
533 void load_objects(
Progress &progress);
538 void walk_hierarchy(Alembic::AbcGeom::IObject parent,
539 const Alembic::AbcGeom::ObjectHeader &ohead,
540 MatrixSamplesData matrix_samples_data,
541 const unordered_map<string, AlembicObject *> &object_map,
546 void read_mesh(AlembicObject *abc_object, Alembic::AbcGeom::Abc::chrono_t frame_time);
550 void read_curves(AlembicObject *abc_object, Alembic::AbcGeom::Abc::chrono_t frame_time);
554 void read_points(AlembicObject *abc_object, Alembic::AbcGeom::Abc::chrono_t frame_time);
558 void read_subd(AlembicObject *abc_object, Alembic::AbcGeom::Abc::chrono_t frame_time);
560 void build_caches(
Progress &progress);
562 size_t get_prefetch_cache_size_in_bytes()
const
565 return static_cast<size_t>(prefetch_cache_size) * 1024 * 1024;
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
#define NODE_SOCKET_API_ARRAY(type_, name)
#define NODE_SOCKET_API(type_, name)
static void clear(Message *msg)