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 return context->is_object_visible(
args_.export_params->evaluation_mode);
134 Object *
object = context.object;
135 bool needsfree =
false;
139 if (mesh ==
nullptr) {
146 if (
args_.export_params->triangulate) {
147 const bool tag_only =
false;
148 const int quad_method =
args_.export_params->quad_method;
149 const int ngon_method =
args_.export_params->ngon_method;
165 mesh = triangulated_mesh;
169 m_custom_data_config.pack_uvs =
args_.export_params->packuv;
170 m_custom_data_config.mesh = mesh;
171 m_custom_data_config.face_offsets = mesh->face_offsets_for_write().data();
172 m_custom_data_config.corner_verts = mesh->corner_verts_for_write().data();
175 m_custom_data_config.totvert = mesh->
verts_num;
180 write_subd(context, mesh);
183 write_mesh(context, mesh);
205 std::vector<Imath::V3f> points,
normals;
206 std::vector<int32_t> face_verts, loop_counts;
207 std::vector<Imath::V3f> velocities;
213 write_face_sets(context.object, mesh, abc_poly_mesh_schema_);
216 OPolyMeshSchema::Sample mesh_sample = OPolyMeshSchema::Sample(
217 V3fArraySample(points), Int32ArraySample(face_verts), Int32ArraySample(loop_counts));
219 UVSample uvs_and_indices;
224 if (!uvs_and_indices.indices.empty() && !uvs_and_indices.uvs.empty()) {
225 OV2fGeomParam::Sample uv_sample;
226 uv_sample.setVals(V2fArraySample(uvs_and_indices.uvs));
227 uv_sample.setIndices(UInt32ArraySample(uvs_and_indices.indices));
228 uv_sample.setScope(kFacevaryingScope);
230 abc_poly_mesh_schema_.setUVSourceName(
name);
231 mesh_sample.setUVs(uv_sample);
235 m_custom_data_config,
243 ON3fGeomParam::Sample normals_sample;
245 normals_sample.setScope(kFacevaryingScope);
246 normals_sample.setVals(V3fArraySample(
normals));
249 mesh_sample.setNormals(normals_sample);
252 if (
args_.export_params->orcos) {
256 if (get_velocities(mesh, velocities)) {
257 mesh_sample.setVelocities(V3fArraySample(velocities));
263 abc_poly_mesh_schema_.set(mesh_sample);
265 write_arb_geo_params(mesh);
268void ABCGenericMeshWriter::write_subd(HierarchyContext &context,
Mesh *mesh)
270 std::vector<float> edge_crease_sharpness, vert_crease_sharpness;
271 std::vector<Imath::V3f> points;
272 std::vector<int32_t> face_verts, loop_counts;
273 std::vector<int32_t> edge_crease_indices, edge_crease_lengths, vert_crease_indices;
277 get_edge_creases(mesh, edge_crease_indices, edge_crease_lengths, edge_crease_sharpness);
281 write_face_sets(
context.object, mesh, abc_subdiv_schema_);
284 OSubDSchema::Sample subdiv_sample = OSubDSchema::Sample(
285 V3fArraySample(points), Int32ArraySample(face_verts), Int32ArraySample(loop_counts));
288 if (
args_.export_params->uvs) {
292 OV2fGeomParam::Sample uv_sample;
293 uv_sample.setVals(V2fArraySample(
sample.uvs));
294 uv_sample.setIndices(UInt32ArraySample(
sample.indices));
295 uv_sample.setScope(kFacevaryingScope);
297 abc_subdiv_schema_.setUVSourceName(
name);
298 subdiv_sample.setUVs(uv_sample);
302 m_custom_data_config,
307 if (
args_.export_params->orcos) {
311 if (!edge_crease_indices.empty()) {
312 subdiv_sample.setCreaseIndices(Int32ArraySample(edge_crease_indices));
313 subdiv_sample.setCreaseLengths(Int32ArraySample(edge_crease_lengths));
314 subdiv_sample.setCreaseSharpnesses(FloatArraySample(edge_crease_sharpness));
317 if (!vert_crease_indices.empty()) {
318 subdiv_sample.setCornerIndices(Int32ArraySample(vert_crease_indices));
319 subdiv_sample.setCornerSharpnesses(FloatArraySample(vert_crease_sharpness));
324 abc_subdiv_schema_.set(subdiv_sample);
326 write_arb_geo_params(mesh);
329template<
typename Schema>
330void ABCGenericMeshWriter::write_face_sets(
Object *
object,
Mesh *mesh, Schema &schema)
332 std::map<std::string, std::vector<int32_t>> geo_groups;
333 get_geo_groups(
object, mesh, geo_groups);
335 std::map<std::string, std::vector<int32_t>>::iterator it;
336 for (it = geo_groups.begin(); it != geo_groups.end(); ++it) {
337 OFaceSet face_set = schema.createFaceSet(it->first);
338 OFaceSetSchema::Sample samp;
339 samp.setFaces(Int32ArraySample(it->second));
340 face_set.getSchema().set(samp);
344void ABCGenericMeshWriter::write_arb_geo_params(
Mesh *mesh)
346 if (!
args_.export_params->vcolors) {
350 OCompoundProperty arb_geom_params;
352 arb_geom_params = abc_subdiv_.getSchema().getArbGeomParams();
355 arb_geom_params = abc_poly_mesh_.getSchema().getArbGeomParams();
360bool ABCGenericMeshWriter::get_velocities(
Mesh *mesh, std::vector<Imath::V3f> &vels)
368 if (velocity_layer ==
nullptr) {
373 const float (*mesh_velocities)[3] =
reinterpret_cast<float (*)[3]
>(velocity_layer->
data);
376 vels.resize(totverts);
378 for (
int i = 0;
i < totverts;
i++) {
385void ABCGenericMeshWriter::get_geo_groups(
Object *
object,
387 std::map<std::string, std::vector<int32_t>> &geo_groups)
389 const bke::AttributeAccessor attributes = mesh->
attributes();
390 const VArraySpan<int> material_indices = *attributes.lookup_or_default<
int>(
393 for (
const int i : material_indices.index_range()) {
394 short mnr = material_indices[
i];
402 std::string
name =
args_.hierarchy_iterator->get_id_name(&mat->
id);
404 if (geo_groups.find(
name) == geo_groups.end()) {
405 std::vector<int32_t> faceArray;
406 geo_groups[
name] = faceArray;
409 geo_groups[
name].push_back(
i);
412 if (geo_groups.empty()) {
415 std::string
name = (mat) ?
args_.hierarchy_iterator->get_id_name(&mat->
id) :
"default";
417 std::vector<int32_t> faceArray;
420 faceArray.push_back(
i);
423 geo_groups[
name] = faceArray;
441 std::vector<int32_t> &face_verts,
442 std::vector<int32_t> &loop_counts)
445 const Span<int> corner_verts = mesh->corner_verts();
449 face_verts.reserve(corner_verts.
size());
450 loop_counts.reserve(
faces.size());
453 for (
const int i :
faces.index_range()) {
455 loop_counts.push_back(face.
size());
457 int corner = face.
start() + (face.
size() - 1);
458 for (
int j = 0; j < face.
size(); j++, corner--) {
459 face_verts.push_back(corner_verts[corner]);
466 std::vector<int32_t> &lengths,
467 std::vector<float> &sharpnesses)
482 const float crease = std::clamp(creases[
i], 0.0f, 1.0f);
484 if (crease != 0.0f) {
491 lengths.resize(sharpnesses.size(), 2);
496 std::vector<float> &sharpnesses)
509 const float crease = std::clamp(creases[
i], 0.0f, 1.0f);
511 if (crease != 0.0f) {
522 switch (mesh->normals_domain()) {
535 for (const int i : range) {
537 copy_yup_from_zup(y_up, face_normals[i]);
538 dst_normals.slice(faces[i]).fill(y_up);
549 const Span<float3> corner_normals = mesh->corner_normals();
551 for (const int i : range) {
552 const IndexRange face = faces[i];
553 for (const int i : face.index_range()) {
554 copy_yup_from_zup(dst_normals[face.last(i)], corner_normals[face[i]]);
struct CustomDataLayer * BKE_attribute_find(const AttributeOwner &owner, blender::StringRef name, eCustomDataType type, blender::bke::AttrDomain domain)
void BKE_id_free(Main *bmain, void *idv)
General operations, lookup, etc. for materials.
Material * BKE_object_material_get(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_DEBUG(clg_ref,...)
struct CustomDataLayer CustomDataLayer
@ eModifierMode_DisableTemporary
Object is a sort of wrapper for general info.
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)
void do_write(HierarchyContext &context) override
ABCGenericMeshWriter(const ABCWriterConstructorArgs &args)
Alembic::Abc::OObject get_alembic_object() const override
virtual void free_export_mesh(Mesh *mesh)
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
void create_alembic_objects(const HierarchyContext *context) override
virtual bool export_as_subdivision_surface(Object *ob_eval) const
Mesh * get_export_mesh(Object *object_eval, bool &r_needsfree) override
ABCMeshWriter(const ABCWriterConstructorArgs &args)
static float normals[][3]
BLI_INLINE float crease_to_sharpness(float crease)
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