11 #include <Alembic/AbcGeom/All.h>
13 #include <unordered_map>
31 using Alembic::AbcGeom::kFacevaryingScope;
32 using Alembic::AbcGeom::kVaryingScope;
33 using Alembic::AbcGeom::kVertexScope;
35 using Alembic::Abc::C4fArraySample;
36 using Alembic::Abc::UInt32ArraySample;
37 using Alembic::Abc::V2fArraySample;
39 using Alembic::AbcGeom::OC4fGeomParam;
40 using Alembic::AbcGeom::OV2fGeomParam;
41 using Alembic::AbcGeom::OV3fGeomParam;
49 std::vector<Imath::V2f> &uvs,
50 std::vector<uint32_t> &uvidx,
53 const MLoopUV *mloopuv_array =
static_cast<const MLoopUV *
>(cd_data);
59 const int num_poly = config.
totpoly;
69 for (
int i = 0; i < num_poly; i++) {
70 MPoly ¤t_poly = polygons[i];
73 for (
int j = 0; j < current_poly.
totloop; j++,
count++) {
84 std::vector<std::vector<uint32_t>> idx_map(config.
totvert);
87 for (
int i = 0; i < num_poly; i++) {
88 MPoly ¤t_poly = polygons[i];
92 for (
int j = 0; j < current_poly.
totloop; j++) {
96 Imath::V2f uv(loopuv->
uv[0], loopuv->
uv[1]);
97 bool found_same =
false;
100 for (
uint32_t uv_idx : idx_map[looppoly->
v]) {
101 if (uvs[uv_idx] == uv) {
103 uvidx.push_back(uv_idx);
111 idx_map[looppoly->
v].push_back(uv_idx);
112 uvidx.push_back(uv_idx);
124 if (active_uvlayer < 0) {
140 static void write_uv(
const OCompoundProperty &prop,
146 std::vector<Imath::V2f> uvs;
150 if (
indices.empty() || uvs.empty()) {
154 std::string uv_map_name(name);
155 OV2fGeomParam param = config.
abc_uv_maps[uv_map_name];
157 if (!param.valid()) {
158 param = OV2fGeomParam(prop, name,
true, kFacevaryingScope, 1);
160 OV2fGeomParam::Sample
sample(V2fArraySample(&uvs.front(), uvs.size()),
170 std::vector<Imath::C4f> &
buffer,
171 std::vector<uint32_t> &uvidx,
174 const float cscale = 1.0f / 255.0f;
177 const MCol *cfaces =
static_cast<const MCol *
>(cd_data);
184 for (
int i = 0; i < config.
totpoly; i++) {
185 const MPoly *p = &polys[i];
189 for (
int j = 0; j < p->
totloop; j++) {
193 col[0] = cface->
a * cscale;
194 col[1] = cface->
r * cscale;
195 col[2] = cface->
g * cscale;
196 col[3] = cface->
b * cscale;
199 uvidx.push_back(
buffer.size() - 1);
214 std::vector<Imath::C4f>
buffer;
222 std::string vcol_name(name);
225 if (!param.valid()) {
226 param = OC4fGeomParam(prop, name,
true, kFacevaryingScope, 1);
243 if (customdata ==
nullptr) {
247 const float(*orcodata)[3] =
static_cast<const float(*)[3]
>(customdata);
250 std::vector<Imath::V3f> coords(config.
totvert);
252 for (
int vertex_idx = 0; vertex_idx < config.
totvert; vertex_idx++) {
254 coords[vertex_idx].setValue(orco_yup[0], orco_yup[1], orco_yup[2]);
260 mesh,
reinterpret_cast<float(*)[3]
>(coords.data()),
mesh->
totvert,
true);
267 OV3fGeomParam::Sample
sample(coords, kVertexScope);
285 for (
int i = 0; i < tot_layers; i++) {
291 if (i == active_layer) {
295 write_uv(prop, config, cd_data, name);
305 using Alembic::Abc::C3fArraySamplePtr;
306 using Alembic::Abc::C4fArraySamplePtr;
307 using Alembic::Abc::PropertyHeader;
308 using Alembic::Abc::UInt32ArraySamplePtr;
310 using Alembic::AbcGeom::IC3fGeomParam;
311 using Alembic::AbcGeom::IC4fGeomParam;
312 using Alembic::AbcGeom::IV2fGeomParam;
313 using Alembic::AbcGeom::IV3fGeomParam;
318 const Alembic::AbcGeom::V2fArraySamplePtr &uvs,
319 const UInt32ArraySamplePtr &
indices)
325 unsigned int uv_index, loop_index, rev_loop_index;
330 for (
int i = 0; i < config.
totpoly; i++) {
331 MPoly &poly = mpolys[i];
334 for (
int f = 0; f < poly.
totloop; f++) {
335 rev_loop_index = rev_loop_offset - f;
336 loop_index = do_uvs_per_loop ? poly.
loopstart + f : mloops[rev_loop_index].
v;
337 uv_index = (*indices)[loop_index];
338 const Imath::V2f &uv = (*uvs)[uv_index];
340 MLoopUV &loopuv = mloopuvs[rev_loop_index];
341 loopuv.
uv[0] = uv[0];
342 loopuv.
uv[1] = uv[1];
348 const size_t array_size,
349 const std::string &iobject_full_name,
350 const PropertyHeader &prop_header,
351 bool &r_is_out_of_bounds,
352 bool &r_bounds_warning_given)
354 if (color_index < array_size) {
358 if (!r_bounds_warning_given) {
359 std::cerr <<
"Alembic: color index out of bounds "
360 "reading face colors for object "
361 << iobject_full_name <<
", property " << prop_header.getName() << std::endl;
362 r_bounds_warning_given =
true;
364 r_is_out_of_bounds =
true;
369 const ICompoundProperty &arbGeomParams,
370 const PropertyHeader &prop_header,
372 const Alembic::Abc::ISampleSelector &iss)
374 C3fArraySamplePtr c3f_ptr = C3fArraySamplePtr();
375 C4fArraySamplePtr c4f_ptr = C4fArraySamplePtr();
376 Alembic::Abc::UInt32ArraySamplePtr
indices;
381 if (IC3fGeomParam::matches(prop_header)) {
382 IC3fGeomParam color_param(arbGeomParams, prop_header.getName());
383 IC3fGeomParam::Sample
sample;
386 color_param.getIndexed(
sample, iss);
387 is_facevarying =
sample.getScope() == kFacevaryingScope &&
390 c3f_ptr =
sample.getVals();
394 else if (IC4fGeomParam::matches(prop_header)) {
395 IC4fGeomParam color_param(arbGeomParams, prop_header.getName());
396 IC4fGeomParam::Sample
sample;
399 color_param.getIndexed(
sample, iss);
400 is_facevarying =
sample.getScope() == kFacevaryingScope &&
403 c4f_ptr =
sample.getVals();
416 MCol *cfaces =
static_cast<MCol *
>(cd_data);
420 size_t face_index = 0;
422 bool bounds_warning_given =
false;
428 bool use_dual_indexing = is_facevarying &&
indices->size() > 0;
430 for (
int i = 0; i < config.
totpoly; i++) {
431 MPoly *poly = &mpolys[i];
435 for (
int j = 0; j < poly->
totloop; j++, face_index++) {
439 color_index = is_facevarying ? face_index : mloop->
v;
440 if (use_dual_indexing) {
441 color_index = (*indices)[color_index];
444 bool is_mcols_out_of_bounds =
false;
449 is_mcols_out_of_bounds,
450 bounds_warning_given);
451 if (is_mcols_out_of_bounds) {
454 const Imath::C3f &
color = (*c3f_ptr)[color_index];
461 bool is_mcols_out_of_bounds =
false;
466 is_mcols_out_of_bounds,
467 bounds_warning_given);
468 if (is_mcols_out_of_bounds) {
471 const Imath::C4f &
color = (*c4f_ptr)[color_index];
482 const PropertyHeader &prop_header,
484 const Alembic::Abc::ISampleSelector &iss)
486 IV2fGeomParam uv_param(prop, prop_header.getName());
488 if (!uv_param.isIndexed()) {
492 IV2fGeomParam::Sample
sample;
493 uv_param.getIndexed(
sample, iss);
495 UInt32ArraySamplePtr uvs_indices =
sample.getIndices();
505 read_uvs(config, cd_data, uv_scope,
sample.getVals(), uvs_indices);
510 const Alembic::Abc::ISampleSelector &iss)
518 if (!param.valid() || param.isIndexed()) {
522 if (param.getScope() != kVertexScope) {
527 IV3fGeomParam::Sample
sample = param.getExpandedValue(iss);
528 Alembic::AbcGeom::V3fArraySamplePtr abc_orco =
sample.getVals();
529 const size_t totvert = abc_orco.get()->size();
546 float(*orcodata)[3] =
static_cast<float(*)[3]
>(cd_data);
547 for (
int vertex_idx = 0; vertex_idx < totvert; ++vertex_idx) {
548 const Imath::V3f &abc_coords = (*abc_orco)[vertex_idx];
558 const ICompoundProperty &prop,
560 const Alembic::Abc::ISampleSelector &iss)
568 const size_t num_props = prop.getNumProperties();
570 for (
size_t i = 0; i < num_props; i++) {
571 const Alembic::Abc::PropertyHeader &prop_header = prop.getPropertyHeader(i);
574 if (IV2fGeomParam::matches(prop_header) && Alembic::AbcGeom::isUV(prop_header)) {
584 if (IC3fGeomParam::matches(prop_header) || IC4fGeomParam::matches(prop_header)) {
593 const Alembic::AbcGeom::UInt32ArraySamplePtr &
indices)
595 if (scope == kFacevaryingScope &&
indices->size() == config.
totloop) {
602 if ((
ELEM(scope, kVaryingScope, kVertexScope)) &&
indices->size() == config.
totvert) {
typedef float(TangentPoint)[2]
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)
void * CustomData_get_layer(const struct CustomData *data, int type)
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
void BKE_mesh_orco_verts_transform(struct Mesh *me, float(*orco)[3], int totvert, int invert)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
ccl_global float * buffer
ccl_gpu_kernel_postfix int ccl_global int * indices
MINLINE unsigned char unit_float_to_uchar_clamp(float val)
AbcUvScope get_uv_scope(const Alembic::AbcGeom::GeometryScope scope, const CDStreamConfig &config, const Alembic::AbcGeom::UInt32ArraySamplePtr &indices)
BLI_INLINE void copy_yup_from_zup(float yup[3], const float zup[3])
const char * get_uv_sample(UVSample &sample, const CDStreamConfig &config, CustomData *data)
static void write_uv(const OCompoundProperty &prop, CDStreamConfig &config, const void *data, const char *name)
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)
void write_custom_data(const OCompoundProperty &prop, CDStreamConfig &config, CustomData *data, int data_type)
static void write_mcol(const OCompoundProperty &prop, CDStreamConfig &config, const void *data, const char *name)
BLI_INLINE void copy_zup_from_yup(float zup[3], const float yup[3])
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, const void *cd_data)
static const std::string propNameOriginalCoordinates("Pref")
static void read_custom_data_uvs(const ICompoundProperty &prop, const PropertyHeader &prop_header, const CDStreamConfig &config, const Alembic::Abc::ISampleSelector &iss)
void read_generated_coordinates(const ICompoundProperty &prop, 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 write_generated_coordinates(const OCompoundProperty &prop, CDStreamConfig &config)
static void get_cols(const CDStreamConfig &config, std::vector< Imath::C4f > &buffer, std::vector< uint32_t > &uvidx, const void *cd_data)
static void read_uvs(const CDStreamConfig &config, void *data, const AbcUvScope uv_scope, const Alembic::AbcGeom::V2fArraySamplePtr &uvs, const UInt32ArraySamplePtr &indices)
std::map< std::string, Alembic::AbcGeom::OC4fGeomParam > abc_vertex_colors
void *(* add_customdata_cb)(Mesh *mesh, const char *name, int data_type)
Alembic::AbcGeom::OV3fGeomParam abc_orco
std::map< std::string, Alembic::AbcGeom::OV2fGeomParam > abc_uv_maps