16# include <Alembic/AbcCoreFactory/All.h>
17# include <Alembic/AbcGeom/All.h>
21class AlembicProcedural;
27using MatrixSampleMap = std::map<Alembic::Abc::chrono_t, Alembic::Abc::M44d>;
29struct MatrixSamplesData {
30 MatrixSampleMap *samples =
nullptr;
31 Alembic::AbcCoreAbstract::TimeSamplingPtr time_sampling;
35template<
typename>
struct is_array :
public std::false_type {};
37template<
typename T>
struct is_array<
array<
T>> :
public std::true_type {};
41template<
typename T>
class CacheLookupResult {
54 CacheLookupResult() =
default;
57 static CacheLookupResult new_data(
T *data_)
61 result.state = State::NEW_DATA;
65 static CacheLookupResult no_data_found_for_time()
69 result.state = State::NO_DATA_FOR_TIME;
73 static CacheLookupResult already_loaded()
77 result.state = State::ALREADY_LOADED;
82 const T &get_data()
const
84 assert(
state == State::NEW_DATA);
85 assert(
data !=
nullptr);
89 T *get_data_or_null()
const
95 bool has_new_data()
const
97 return state == State::NEW_DATA;
100 bool has_already_loaded()
const
102 return state == State::ALREADY_LOADED;
105 bool has_no_data_for_time()
const
107 return state == State::NO_DATA_FOR_TIME;
116template<
typename T>
class DataStore {
118 struct TimeIndexPair {
122 double source_time = 0;
136 Alembic::AbcCoreAbstract::TimeSampling time_sampling{};
138 double last_loaded_time = std::numeric_limits<double>::max();
142 Alembic::AbcCoreAbstract::ArraySample::Key key1;
143 Alembic::AbcCoreAbstract::ArraySample::Key key2;
145 void set_time_sampling(Alembic::AbcCoreAbstract::TimeSampling time_sampling_)
147 time_sampling = time_sampling_;
150 Alembic::AbcCoreAbstract::TimeSampling get_time_sampling()
const
152 return time_sampling;
157 CacheLookupResult<T> data_for_time(
double time)
160 return CacheLookupResult<T>::no_data_found_for_time();
163 const TimeIndexPair &
index = get_index_for_time(time);
165 if (
index.index == -1ul) {
166 return CacheLookupResult<T>::no_data_found_for_time();
169 if (last_loaded_time ==
index.time || last_loaded_time ==
index.source_time) {
170 return CacheLookupResult<T>::already_loaded();
173 last_loaded_time =
index.source_time;
177 return CacheLookupResult<T>::new_data(&
data[
index.index]);
182 CacheLookupResult<T> data_for_time_no_check(
double time)
185 return CacheLookupResult<T>::no_data_found_for_time();
188 const TimeIndexPair &
index = get_index_for_time(time);
190 if (
index.index == -1ul) {
191 return CacheLookupResult<T>::no_data_found_for_time();
196 return CacheLookupResult<T>::new_data(&
data[
index.index]);
199 void add_data(
T &data_,
double time)
201 index_data_map.push_back({time, time,
data.size()});
203 if constexpr (is_array<T>::value) {
205 data.back().steal_data(data_);
209 data.push_back(data_);
212 void reuse_data_for_last_time(
double time)
214 const TimeIndexPair &data_index = index_data_map.back();
215 index_data_map.push_back({time, data_index.source_time, data_index.index});
218 void add_no_data(
double time)
220 index_data_map.push_back({time, time, -1ul});
223 bool is_constant()
const
225 return data.size() <= 1;
235 invalidate_last_loaded_time();
237 index_data_map.clear();
240 void invalidate_last_loaded_time()
242 last_loaded_time = std::numeric_limits<double>::max();
247 void copy_to_socket(
double time, Node *node,
const SocketType *socket)
249 CacheLookupResult<T>
result = data_for_time(time);
251 if (!
result.has_new_data()) {
258 node->
set(*socket, value);
261 size_t memory_used()
const
263 if constexpr (is_array<T>::value) {
266 for (
const T &array :
data) {
267 mem_used += array.size() *
sizeof(array[0]);
273 return data.size() *
sizeof(
T);
277 const TimeIndexPair &get_index_for_time(
double time)
const
279 std::pair<size_t, Alembic::Abc::chrono_t> index_pair;
280 index_pair = time_sampling.getNearIndex(time, index_data_map.size());
281 return index_data_map[index_pair.first];
290 DataStore<Transform> transforms{};
293 DataStore<array<float3>> vertices;
294 DataStore<array<int3>> triangles{};
297 DataStore<array<int>> uv_loops{};
298 DataStore<array<int>> shader{};
301 DataStore<array<int>> subd_start_corner;
302 DataStore<array<int>> subd_num_corners;
303 DataStore<array<bool>> subd_smooth;
304 DataStore<array<int>> subd_ptex_offset;
305 DataStore<array<int>> subd_face_corners;
306 DataStore<int> num_ngons;
307 DataStore<array<int>> subd_creases_edge;
308 DataStore<array<float>> subd_creases_weight;
309 DataStore<array<int>> subd_vertex_crease_indices;
310 DataStore<array<float>> subd_vertex_crease_weights;
313 DataStore<array<float3>> curve_keys;
314 DataStore<array<float>> curve_radius;
315 DataStore<array<int>> curve_first_key;
316 DataStore<array<int>> curve_shader;
319 DataStore<array<float3>> points;
320 DataStore<array<float>> radiuses;
321 DataStore<array<int>> points_shader;
323 struct CachedAttribute {
328 DataStore<array<char>>
data{};
335 CachedAttribute &add_attribute(
const ustring &name,
336 const Alembic::Abc::TimeSampling &time_sampling);
338 bool is_constant()
const;
340 void invalidate_last_loaded_time(
bool attributes_only =
false);
342 void set_time_sampling(Alembic::AbcCoreAbstract::TimeSampling time_sampling);
344 size_t memory_used()
const;
356class AlembicObject :
public Node {
383 friend class AlembicProcedural;
385 void set_object(
Object *
object);
388 void load_data_in_cache(CachedData &cached_data,
389 AlembicProcedural *proc,
390 Alembic::AbcGeom::IPolyMeshSchema &schema,
392 void load_data_in_cache(CachedData &cached_data,
393 AlembicProcedural *proc,
394 Alembic::AbcGeom::ISubDSchema &schema,
396 void load_data_in_cache(CachedData &cached_data,
397 AlembicProcedural *proc,
398 const Alembic::AbcGeom::ICurvesSchema &schema,
400 void load_data_in_cache(CachedData &cached_data,
401 AlembicProcedural *proc,
402 const Alembic::AbcGeom::IPointsSchema &schema,
405 bool has_data_loaded()
const;
417 bool need_shader_update =
true;
419 AlembicObject *instance_of =
nullptr;
421 Alembic::AbcCoreAbstract::TimeSamplingPtr xform_time_sampling;
422 MatrixSampleMap xform_samples;
423 Alembic::AbcGeom::IObject iobject;
426 AbcSchemaType schema_type;
428 CachedData &get_cached_data()
433 bool is_constant()
const
435 return cached_data_.is_constant();
440 cached_data_.clear();
445 bool data_loaded =
false;
447 CachedData cached_data_;
449 void setup_transform_cache(CachedData &cached_data,
float scale);
451 AttributeRequestSet get_requested_attributes();
464 Alembic::AbcGeom::IArchive archive;
512 ~AlembicProcedural();
519 void tag_update(
Scene *scene);
529 AlembicObject *get_or_create_object(
const ustring &path);
533 void add_object(AlembicObject *
object);
536 void load_objects(Progress &progress);
541 void walk_hierarchy(Alembic::AbcGeom::IObject parent,
542 const Alembic::AbcGeom::ObjectHeader &ohead,
543 MatrixSamplesData matrix_samples_data,
544 const unordered_map<string, AlembicObject *> &object_map,
549 void read_mesh(AlembicObject *abc_object, Alembic::AbcGeom::Abc::chrono_t frame_time);
553 void read_curves(AlembicObject *abc_object, Alembic::AbcGeom::Abc::chrono_t frame_time);
557 void read_points(AlembicObject *abc_object, Alembic::AbcGeom::Abc::chrono_t frame_time);
561 void read_subd(AlembicObject *abc_object, Alembic::AbcGeom::Abc::chrono_t frame_time);
563 void build_caches(Progress &progress);
565 size_t get_prefetch_cache_size_in_bytes()
const
568 return static_cast<size_t>(prefetch_cache_size) * 1024 * 1024;
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 Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture 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 vector
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)
void set(const SocketType &input, bool value)