33using Alembic::Abc::FloatArraySample;
34using Alembic::Abc::Int32ArraySample;
35using Alembic::Abc::OObject;
36using Alembic::Abc::V2fArraySample;
37using Alembic::Abc::V3fArraySample;
39using Alembic::AbcGeom::kFacevaryingScope;
40using Alembic::AbcGeom::OBoolProperty;
41using Alembic::AbcGeom::OCompoundProperty;
42using Alembic::AbcGeom::OFaceSet;
43using Alembic::AbcGeom::OFaceSetSchema;
44using Alembic::AbcGeom::ON3fGeomParam;
45using Alembic::AbcGeom::OPolyMesh;
46using Alembic::AbcGeom::OPolyMeshSchema;
47using Alembic::AbcGeom::OSubD;
48using Alembic::AbcGeom::OSubDSchema;
49using Alembic::AbcGeom::OV2fGeomParam;
50using Alembic::AbcGeom::UInt32ArraySample;
58 std::vector<int32_t> &face_verts,
59 std::vector<int32_t> &loop_counts);
62 std::vector<int32_t> &lengths,
63 std::vector<float> &sharpnesses);
66 std::vector<float> &sharpnesses);
77 is_subd_ =
args_.export_params->use_subdiv_schema;
83 abc_subdiv_schema_ = abc_subdiv_.getSchema();
88 abc_poly_mesh_schema_ = abc_poly_mesh_.getSchema();
90 OCompoundProperty typeContainer = abc_poly_mesh_.getSchema().getUserProperties();
91 OBoolProperty type(typeContainer,
"meshtype");
92 type.set(subsurf_modifier_ ==
nullptr);
101 return abc_poly_mesh_;
116 for (; md; md = md->
prev) {
129 if (
args_.export_params->visible_objects_only) {
130 return context->is_object_visible(
args_.export_params->evaluation_mode);
137 Object *
object = context.object;
138 bool needsfree =
false;
142 if (mesh ==
nullptr) {
149 if (
args_.export_params->triangulate) {
150 const bool tag_only =
false;
151 const int quad_method =
args_.export_params->quad_method;
152 const int ngon_method =
args_.export_params->ngon_method;
168 mesh = triangulated_mesh;
172 m_custom_data_config.pack_uvs =
args_.export_params->packuv;
173 m_custom_data_config.mesh = mesh;
174 m_custom_data_config.face_offsets = mesh->face_offsets_for_write().data();
175 m_custom_data_config.corner_verts = mesh->corner_verts_for_write().data();
178 m_custom_data_config.totvert = mesh->
verts_num;
183 write_subd(context, mesh);
186 write_mesh(context, mesh);
208 std::vector<Imath::V3f> points,
normals;
209 std::vector<int32_t> face_verts, loop_counts;
210 std::vector<Imath::V3f> velocities;
216 write_face_sets(context.object, mesh, abc_poly_mesh_schema_);
219 OPolyMeshSchema::Sample mesh_sample = OPolyMeshSchema::Sample(
220 V3fArraySample(points), Int32ArraySample(face_verts), Int32ArraySample(loop_counts));
222 UVSample uvs_and_indices;
227 if (!uvs_and_indices.indices.empty() && !uvs_and_indices.uvs.empty()) {
228 OV2fGeomParam::Sample uv_sample;
229 uv_sample.setVals(V2fArraySample(uvs_and_indices.uvs));
230 uv_sample.setIndices(UInt32ArraySample(uvs_and_indices.indices));
231 uv_sample.setScope(kFacevaryingScope);
233 abc_poly_mesh_schema_.setUVSourceName(name);
234 mesh_sample.setUVs(uv_sample);
238 m_custom_data_config,
246 ON3fGeomParam::Sample normals_sample;
248 normals_sample.setScope(kFacevaryingScope);
249 normals_sample.setVals(V3fArraySample(
normals));
252 mesh_sample.setNormals(normals_sample);
255 if (
args_.export_params->orcos) {
259 if (get_velocities(mesh, velocities)) {
260 mesh_sample.setVelocities(V3fArraySample(velocities));
266 abc_poly_mesh_schema_.set(mesh_sample);
268 write_arb_geo_params(mesh);
271void ABCGenericMeshWriter::write_subd(HierarchyContext &context,
Mesh *mesh)
273 std::vector<float> edge_crease_sharpness, vert_crease_sharpness;
274 std::vector<Imath::V3f> points;
275 std::vector<int32_t> face_verts, loop_counts;
276 std::vector<int32_t> edge_crease_indices, edge_crease_lengths, vert_crease_indices;
280 get_edge_creases(mesh, edge_crease_indices, edge_crease_lengths, edge_crease_sharpness);
284 write_face_sets(
context.object, mesh, abc_subdiv_schema_);
287 OSubDSchema::Sample subdiv_sample = OSubDSchema::Sample(
288 V3fArraySample(points), Int32ArraySample(face_verts), Int32ArraySample(loop_counts));
291 if (
args_.export_params->uvs) {
295 OV2fGeomParam::Sample uv_sample;
296 uv_sample.setVals(V2fArraySample(
sample.uvs));
297 uv_sample.setIndices(UInt32ArraySample(
sample.indices));
298 uv_sample.setScope(kFacevaryingScope);
300 abc_subdiv_schema_.setUVSourceName(name);
301 subdiv_sample.setUVs(uv_sample);
305 m_custom_data_config,
310 if (
args_.export_params->orcos) {
314 if (!edge_crease_indices.empty()) {
315 subdiv_sample.setCreaseIndices(Int32ArraySample(edge_crease_indices));
316 subdiv_sample.setCreaseLengths(Int32ArraySample(edge_crease_lengths));
317 subdiv_sample.setCreaseSharpnesses(FloatArraySample(edge_crease_sharpness));
320 if (!vert_crease_indices.empty()) {
321 subdiv_sample.setCornerIndices(Int32ArraySample(vert_crease_indices));
322 subdiv_sample.setCornerSharpnesses(FloatArraySample(vert_crease_sharpness));
327 abc_subdiv_schema_.set(subdiv_sample);
329 write_arb_geo_params(mesh);
332template<
typename Schema>
333void ABCGenericMeshWriter::write_face_sets(
Object *
object,
Mesh *mesh, Schema &schema)
335 std::map<std::string, std::vector<int32_t>> geo_groups;
336 get_geo_groups(
object, mesh, geo_groups);
338 std::map<std::string, std::vector<int32_t>>::iterator it;
339 for (it = geo_groups.begin(); it != geo_groups.end(); ++it) {
340 OFaceSet face_set = schema.createFaceSet(it->first);
341 OFaceSetSchema::Sample samp;
342 samp.setFaces(Int32ArraySample(it->second));
343 face_set.getSchema().set(samp);
347void ABCGenericMeshWriter::write_arb_geo_params(
Mesh *mesh)
349 if (!
args_.export_params->vcolors) {
353 OCompoundProperty arb_geom_params;
355 arb_geom_params = abc_subdiv_.getSchema().getArbGeomParams();
358 arb_geom_params = abc_poly_mesh_.getSchema().getArbGeomParams();
363bool ABCGenericMeshWriter::get_velocities(
Mesh *mesh, std::vector<Imath::V3f> &vels)
371 if (velocity_layer ==
nullptr) {
376 const float(*mesh_velocities)[3] =
reinterpret_cast<float(*)[3]
>(velocity_layer->
data);
379 vels.resize(totverts);
381 for (
int i = 0; i < totverts; i++) {
388void ABCGenericMeshWriter::get_geo_groups(
Object *
object,
390 std::map<std::string, std::vector<int32_t>> &geo_groups)
392 const bke::AttributeAccessor attributes = mesh->
attributes();
393 const VArraySpan<int> material_indices = *attributes.lookup_or_default<
int>(
396 for (
const int i : material_indices.index_range()) {
397 short mnr = material_indices[i];
405 std::string name =
args_.hierarchy_iterator->get_id_name(&mat->
id);
407 if (geo_groups.find(name) == geo_groups.end()) {
408 std::vector<int32_t> faceArray;
409 geo_groups[name] = faceArray;
412 geo_groups[name].push_back(i);
415 if (geo_groups.empty()) {
418 std::string name = (mat) ?
args_.hierarchy_iterator->get_id_name(&mat->
id) :
"default";
420 std::vector<int32_t> faceArray;
423 faceArray.push_back(i);
426 geo_groups[name] = faceArray;
444 std::vector<int32_t> &face_verts,
445 std::vector<int32_t> &loop_counts)
448 const Span<int> corner_verts = mesh->corner_verts();
452 face_verts.reserve(corner_verts.
size());
453 loop_counts.reserve(
faces.size());
456 for (
const int i :
faces.index_range()) {
458 loop_counts.push_back(face.
size());
460 int corner = face.
start() + (face.
size() - 1);
461 for (
int j = 0; j < face.
size(); j++, corner--) {
462 face_verts.push_back(corner_verts[corner]);
469 std::vector<int32_t> &lengths,
470 std::vector<float> &sharpnesses)
485 const float sharpness = creases[i];
487 if (sharpness != 0.0f) {
488 indices.push_back(edges[i][0]);
489 indices.push_back(edges[i][1]);
490 sharpnesses.push_back(sharpness);
494 lengths.resize(sharpnesses.size(), 2);
499 std::vector<float> &sharpnesses)
512 const float sharpness = creases[i];
514 if (sharpness != 0.0f) {
516 sharpnesses.push_back(sharpness);
525 switch (mesh->normals_domain()) {
538 for (const int i : range) {
540 copy_yup_from_zup(y_up, face_normals[i]);
541 dst_normals.slice(faces[i]).fill(y_up);
552 const Span<float3> corner_normals = mesh->corner_normals();
554 for (const int i : range) {
555 const IndexRange face = faces[i];
556 for (const int i : face.index_range()) {
557 copy_yup_from_zup(dst_normals[face.last(i)], corner_normals[face[i]]);
struct CustomDataLayer * BKE_attribute_find(const AttributeOwner &owner, const char *name, eCustomDataType type, blender::bke::AttrDomain domain)
void BKE_id_free(Main *bmain, void *idv)
General operations, lookup, etc. for materials.
struct Material * BKE_object_material_get(struct Object *ob, short act)
Mesh * BKE_mesh_from_bmesh_for_eval_nomain(BMesh *bm, const CustomData_MeshMasks *cd_mask_extra, const Mesh *me_settings)
BMesh * BKE_mesh_to_bmesh_ex(const Mesh *mesh, const BMeshCreateParams *create_params, const BMeshFromMeshParams *convert_params)
void BKE_mesh_wrapper_ensure_mdata(Mesh *mesh)
General operations, lookup, etc. for blender objects.
Mesh * BKE_object_get_evaluated_mesh(const Object *object_eval)
#define CLOG_INFO(clg_ref, level,...)
struct CustomDataLayer CustomDataLayer
@ eModifierMode_DisableTemporary
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 or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
void BM_mesh_triangulate(BMesh *bm, const int quad_method, const int ngon_method, const int min_vertices, const bool tag_only, BMOperator *op, BMOpSlot *slot_facemap_out, BMOpSlot *slot_facemap_double_out)
static AttributeOwner from_id(ID *id)
constexpr int64_t size() const
constexpr int64_t start() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
GAttributeReader lookup(const StringRef attribute_id) const
ABCAbstractWriter(const ABCWriterConstructorArgs &args)
Alembic::Abc::OCompoundProperty abc_schema_prop_for_custom_props(T abc_schema)
uint32_t timesample_index_
bool frame_has_been_written_
Imath::Box3d bounding_box_
const ABCWriterConstructorArgs args_
virtual void update_bounding_box(Object *object)
virtual void do_write(HierarchyContext &context) override
ABCGenericMeshWriter(const ABCWriterConstructorArgs &args)
virtual Alembic::Abc::OObject get_alembic_object() const override
virtual void free_export_mesh(Mesh *mesh)
virtual bool is_supported(const HierarchyContext *context) const override
virtual Mesh * get_export_mesh(Object *object_eval, bool &r_needsfree)=0
Alembic::Abc::OCompoundProperty abc_prop_for_custom_props() override
virtual void create_alembic_objects(const HierarchyContext *context) override
virtual bool export_as_subdivision_surface(Object *ob_eval) const
virtual Mesh * get_export_mesh(Object *object_eval, bool &r_needsfree) override
ABCMeshWriter(const ABCWriterConstructorArgs &args)
draw_view in_light_buf[] float
static float normals[][3]
int context(const bContext *C, const char *member, bContextDataResult *result)
BLI_INLINE void copy_yup_from_zup(float yup[3], const float zup[3])
static void get_vert_creases(Mesh *mesh, std::vector< int32_t > &indices, std::vector< float > &sharpnesses)
static void get_edge_creases(Mesh *mesh, std::vector< int32_t > &indices, std::vector< int32_t > &lengths, std::vector< float > &sharpnesses)
const char * get_uv_sample(UVSample &sample, const CDStreamConfig &config, CustomData *data)
void write_custom_data(const OCompoundProperty &prop, CDStreamConfig &config, CustomData *data, int data_type)
static void get_loop_normals(const Mesh *mesh, std::vector< Imath::V3f > &normals)
static void get_topology(Mesh *mesh, std::vector< int32_t > &face_verts, std::vector< int32_t > &loop_counts)
void write_generated_coordinates(const OCompoundProperty &prop, CDStreamConfig &config)
static void get_vertices(Mesh *mesh, std::vector< Imath::V3f > &points)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
VecBase< float, 3 > float3
struct ModifierData * prev
const AlembicExportParams * export_params