26 #include <Alembic/AbcGeom/All.h>
28 #include <unordered_map>
44 using Alembic::AbcGeom::kFacevaryingScope;
45 using Alembic::AbcGeom::kVertexScope;
47 using Alembic::Abc::C4fArraySample;
48 using Alembic::Abc::UInt32ArraySample;
49 using Alembic::Abc::V2fArraySample;
51 using Alembic::AbcGeom::OC4fGeomParam;
52 using Alembic::AbcGeom::OV2fGeomParam;
56 std::vector<Imath::V2f> &uvs,
57 std::vector<uint32_t> &uvidx,
66 const int num_poly = config.
totpoly;
76 for (
int i = 0; i < num_poly; i++) {
77 MPoly ¤t_poly = polygons[i];
80 for (
int j = 0; j < current_poly.
totloop; j++, cnt++) {
84 uvs[cnt][0] = loopuv->
uv[0];
85 uvs[cnt][1] = loopuv->
uv[1];
91 std::vector<std::vector<uint32_t>> idx_map(config.
totvert);
94 for (
int i = 0; i < num_poly; i++) {
95 MPoly ¤t_poly = polygons[i];
99 for (
int j = 0; j < current_poly.
totloop; j++) {
103 Imath::V2f uv(loopuv->
uv[0], loopuv->
uv[1]);
104 bool found_same =
false;
107 for (
uint32_t uv_idx : idx_map[looppoly->
v]) {
108 if (uvs[uv_idx] == uv) {
110 uvidx.push_back(uv_idx);
118 idx_map[looppoly->
v].push_back(uv_idx);
119 uvidx.push_back(uv_idx);
131 if (active_uvlayer < 0) {
147 static void write_uv(
const OCompoundProperty &prop,
153 std::vector<Imath::V2f> uvs;
157 if (
indices.empty() || uvs.empty()) {
161 std::string uv_map_name(name);
162 OV2fGeomParam param = config.
abc_uv_maps[uv_map_name];
164 if (!param.valid()) {
165 param = OV2fGeomParam(prop, name,
true, kFacevaryingScope, 1);
167 OV2fGeomParam::Sample
sample(V2fArraySample(&uvs.front(), uvs.size()),
184 const float cscale = 1.0f / 255.0f;
189 std::vector<Imath::C4f>
buffer;
197 for (
int i = 0; i < config.
totpoly; i++) {
198 MPoly *p = &polys[i];
202 for (
int j = 0; j < p->
totloop; j++) {
206 col[0] = cface->
a * cscale;
207 col[1] = cface->
r * cscale;
208 col[2] = cface->
g * cscale;
209 col[3] = cface->
b * cscale;
216 OC4fGeomParam param(prop, name,
true, kFacevaryingScope, 1);
239 for (
int i = 0; i < tot_layers; i++) {
245 if (i == active_layer) {
249 write_uv(prop, config, cd_data, name);
259 using Alembic::Abc::C3fArraySamplePtr;
260 using Alembic::Abc::C4fArraySamplePtr;
261 using Alembic::Abc::PropertyHeader;
263 using Alembic::AbcGeom::IC3fGeomParam;
264 using Alembic::AbcGeom::IC4fGeomParam;
265 using Alembic::AbcGeom::IV2fGeomParam;
269 const Alembic::AbcGeom::V2fArraySamplePtr &uvs,
270 const Alembic::AbcGeom::UInt32ArraySamplePtr &
indices)
275 unsigned int uv_index, loop_index, rev_loop_index;
277 for (
int i = 0; i < config.
totpoly; i++) {
278 MPoly &poly = mpolys[i];
281 for (
int f = 0; f < poly.
totloop; f++) {
283 rev_loop_index = rev_loop_offset - f;
284 uv_index = (*indices)[loop_index];
285 const Imath::V2f &uv = (*uvs)[uv_index];
287 MLoopUV &loopuv = mloopuvs[rev_loop_index];
288 loopuv.
uv[0] = uv[0];
289 loopuv.
uv[1] = uv[1];
295 const size_t array_size,
296 const std::string &iobject_full_name,
297 const PropertyHeader &prop_header,
298 bool &r_is_out_of_bounds,
299 bool &r_bounds_warning_given)
301 if (color_index < array_size) {
305 if (!r_bounds_warning_given) {
306 std::cerr <<
"Alembic: color index out of bounds "
307 "reading face colors for object "
308 << iobject_full_name <<
", property " << prop_header.getName() << std::endl;
309 r_bounds_warning_given =
true;
311 r_is_out_of_bounds =
true;
316 const ICompoundProperty &arbGeomParams,
317 const PropertyHeader &prop_header,
319 const Alembic::Abc::ISampleSelector &iss)
321 C3fArraySamplePtr c3f_ptr = C3fArraySamplePtr();
322 C4fArraySamplePtr c4f_ptr = C4fArraySamplePtr();
323 Alembic::Abc::UInt32ArraySamplePtr
indices;
328 if (IC3fGeomParam::matches(prop_header)) {
329 IC3fGeomParam color_param(arbGeomParams, prop_header.getName());
330 IC3fGeomParam::Sample
sample;
333 color_param.getIndexed(
sample, iss);
334 is_facevarying =
sample.getScope() == kFacevaryingScope &&
337 c3f_ptr =
sample.getVals();
341 else if (IC4fGeomParam::matches(prop_header)) {
342 IC4fGeomParam color_param(arbGeomParams, prop_header.getName());
343 IC4fGeomParam::Sample
sample;
346 color_param.getIndexed(
sample, iss);
347 is_facevarying =
sample.getScope() == kFacevaryingScope &&
350 c4f_ptr =
sample.getVals();
363 MCol *cfaces =
static_cast<MCol *
>(cd_data);
367 size_t face_index = 0;
369 bool bounds_warning_given =
false;
375 bool use_dual_indexing = is_facevarying &&
indices->size() > 0;
377 for (
int i = 0; i < config.
totpoly; i++) {
378 MPoly *poly = &mpolys[i];
382 for (
int j = 0; j < poly->
totloop; j++, face_index++) {
386 color_index = is_facevarying ? face_index : mloop->
v;
387 if (use_dual_indexing) {
388 color_index = (*indices)[color_index];
391 bool is_mcols_out_of_bounds =
false;
396 is_mcols_out_of_bounds,
397 bounds_warning_given);
398 if (is_mcols_out_of_bounds) {
401 const Imath::C3f &color = (*c3f_ptr)[color_index];
408 bool is_mcols_out_of_bounds =
false;
413 is_mcols_out_of_bounds,
414 bounds_warning_given);
415 if (is_mcols_out_of_bounds) {
418 const Imath::C4f &color = (*c4f_ptr)[color_index];
429 const PropertyHeader &prop_header,
431 const Alembic::Abc::ISampleSelector &iss)
433 IV2fGeomParam uv_param(prop, prop_header.getName());
435 if (!uv_param.isIndexed()) {
439 IV2fGeomParam::Sample
sample;
440 uv_param.getIndexed(
sample, iss);
442 if (uv_param.getScope() != kFacevaryingScope) {
452 const ICompoundProperty &prop,
454 const Alembic::Abc::ISampleSelector &iss)
463 const size_t num_props = prop.getNumProperties();
465 for (
size_t i = 0; i < num_props; i++) {
466 const Alembic::Abc::PropertyHeader &prop_header = prop.getPropertyHeader(i);
469 if (IV2fGeomParam::matches(prop_header) && Alembic::AbcGeom::isUV(prop_header)) {
479 if (IC3fGeomParam::matches(prop_header) || IC4fGeomParam::matches(prop_header)) {
CustomData interface, see also DNA_customdata_types.h.
const char * CustomData_get_layer_name(const struct CustomData *data, int type, int n)
int CustomData_number_of_layers(const struct CustomData *data, int type)
bool CustomData_has_layer(const struct CustomData *data, int type)
int CustomData_get_active_layer(const struct CustomData *data, int type)
void * CustomData_get_layer_n(const struct CustomData *data, int type, int n)
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
MINLINE unsigned char unit_float_to_uchar_clamp(float val)
static void sample(SocketReader *reader, int x, int y, float color[4])
static void read_uvs(const CDStreamConfig &config, void *data, const Alembic::AbcGeom::V2fArraySamplePtr &uvs, const Alembic::AbcGeom::UInt32ArraySamplePtr &indices)
const char * get_uv_sample(UVSample &sample, const CDStreamConfig &config, CustomData *data)
static void read_custom_data_mcols(const std::string &iobject_full_name, const ICompoundProperty &arbGeomParams, const PropertyHeader &prop_header, const CDStreamConfig &config, const Alembic::Abc::ISampleSelector &iss)
static void write_uv(const OCompoundProperty &prop, CDStreamConfig &config, void *data, const char *name)
void write_custom_data(const OCompoundProperty &prop, CDStreamConfig &config, CustomData *data, int data_type)
void read_custom_data(const std::string &iobject_full_name, const ICompoundProperty &prop, const CDStreamConfig &config, const Alembic::Abc::ISampleSelector &iss)
static void get_uvs(const CDStreamConfig &config, std::vector< Imath::V2f > &uvs, std::vector< uint32_t > &uvidx, void *cd_data)
static void write_mcol(const OCompoundProperty &prop, const CDStreamConfig &config, void *data, const char *name)
static void read_custom_data_uvs(const ICompoundProperty &prop, const PropertyHeader &prop_header, const CDStreamConfig &config, const Alembic::Abc::ISampleSelector &iss)
static size_t mcols_out_of_bounds_check(const size_t color_index, const size_t array_size, const std::string &iobject_full_name, const PropertyHeader &prop_header, bool &r_is_out_of_bounds, bool &r_bounds_warning_given)
void *(* add_customdata_cb)(Mesh *mesh, const char *name, int data_type)
std::map< std::string, Alembic::AbcGeom::OV2fGeomParam > abc_uv_maps