Cleanup: Avoid shallow copy in OBJ exporter
Similar to #114791, but a bit more complex since the object was also used to access materials and vertex groups later on. Pull Request: https://projects.blender.org/blender/blender/pulls/114796
This commit is contained in:
@@ -709,7 +709,7 @@ Vector<int> MTLWriter::add_materials(const OBJMesh &mesh_to_export)
|
||||
Vector<int> r_mtl_indices;
|
||||
r_mtl_indices.resize(mesh_to_export.tot_materials());
|
||||
for (int16_t i = 0; i < mesh_to_export.tot_materials(); i++) {
|
||||
const Material *material = mesh_to_export.get_object_material(i);
|
||||
const Material *material = mesh_to_export.materials[i];
|
||||
if (!material) {
|
||||
r_mtl_indices[i] = -1;
|
||||
continue;
|
||||
|
||||
@@ -39,10 +39,9 @@ OBJMesh::OBJMesh(Depsgraph *depsgraph, const OBJExportParams &export_params, Obj
|
||||
{
|
||||
/* We need to copy the object because it may be in temporary space. */
|
||||
Object *obj_eval = DEG_get_evaluated_object(depsgraph, mesh_object);
|
||||
export_object_eval_ = dna::shallow_copy(*obj_eval);
|
||||
export_mesh_ = export_params.apply_modifiers ?
|
||||
BKE_object_get_evaluated_mesh(&export_object_eval_) :
|
||||
BKE_object_get_pre_modified_mesh(&export_object_eval_);
|
||||
object_name_ = obj_eval->id.name + 2;
|
||||
export_mesh_ = export_params.apply_modifiers ? BKE_object_get_evaluated_mesh(obj_eval) :
|
||||
BKE_object_get_pre_modified_mesh(obj_eval);
|
||||
if (export_mesh_) {
|
||||
mesh_positions_ = export_mesh_->vert_positions();
|
||||
mesh_edges_ = export_mesh_->edges();
|
||||
@@ -55,12 +54,18 @@ OBJMesh::OBJMesh(Depsgraph *depsgraph, const OBJExportParams &export_params, Obj
|
||||
/* Curves and NURBS surfaces need a new mesh when they're
|
||||
* exported in the form of vertices and edges.
|
||||
*/
|
||||
this->set_mesh(BKE_mesh_new_from_object(depsgraph, &export_object_eval_, true, true));
|
||||
this->set_mesh(BKE_mesh_new_from_object(depsgraph, obj_eval, true, true));
|
||||
}
|
||||
if (export_params.export_triangulated_mesh && export_object_eval_.type == OB_MESH) {
|
||||
if (export_params.export_triangulated_mesh && obj_eval->type == OB_MESH) {
|
||||
this->triangulate_mesh_eval();
|
||||
}
|
||||
set_world_axes_transform(export_params.forward_axis, export_params.up_axis);
|
||||
|
||||
this->materials.reinitialize(export_mesh_->totcol);
|
||||
for (const int i : this->materials.index_range()) {
|
||||
this->materials[i] = BKE_object_material_get_eval(obj_eval, i + 1);
|
||||
}
|
||||
|
||||
set_world_axes_transform(*obj_eval, export_params.forward_axis, export_params.up_axis);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,17 +139,18 @@ void OBJMesh::triangulate_mesh_eval()
|
||||
this->set_mesh(triangulated);
|
||||
}
|
||||
|
||||
void OBJMesh::set_world_axes_transform(const eIOAxis forward, const eIOAxis up)
|
||||
void OBJMesh::set_world_axes_transform(const Object &obj_eval,
|
||||
const eIOAxis forward,
|
||||
const eIOAxis up)
|
||||
{
|
||||
float axes_transform[3][3];
|
||||
unit_m3(axes_transform);
|
||||
/* +Y-forward and +Z-up are the default Blender axis settings. */
|
||||
mat3_from_axis_conversion(forward, up, IO_AXIS_Y, IO_AXIS_Z, axes_transform);
|
||||
mul_m4_m3m4(world_and_axes_transform_, axes_transform, export_object_eval_.object_to_world);
|
||||
mul_m4_m3m4(world_and_axes_transform_, axes_transform, obj_eval.object_to_world);
|
||||
/* mul_m4_m3m4 does not transform last row of obmat, i.e. location data. */
|
||||
mul_v3_m3v3(
|
||||
world_and_axes_transform_[3], axes_transform, export_object_eval_.object_to_world[3]);
|
||||
world_and_axes_transform_[3][3] = export_object_eval_.object_to_world[3][3];
|
||||
mul_v3_m3v3(world_and_axes_transform_[3], axes_transform, obj_eval.object_to_world[3]);
|
||||
world_and_axes_transform_[3][3] = obj_eval.object_to_world[3][3];
|
||||
|
||||
/* Normals need inverse transpose of the regular matrix to handle non-uniform scale. */
|
||||
float normal_matrix[3][3];
|
||||
@@ -176,7 +182,7 @@ int OBJMesh::tot_edges() const
|
||||
|
||||
int16_t OBJMesh::tot_materials() const
|
||||
{
|
||||
return export_mesh_->totcol;
|
||||
return this->materials.size();
|
||||
}
|
||||
|
||||
int OBJMesh::tot_normal_indices() const
|
||||
@@ -233,19 +239,6 @@ void OBJMesh::calc_poly_order()
|
||||
});
|
||||
}
|
||||
|
||||
const Material *OBJMesh::get_object_material(const int16_t mat_nr) const
|
||||
{
|
||||
/**
|
||||
* The const_cast is safe here because #BKE_object_material_get_eval won't change the object
|
||||
* but it is a big can of worms to fix the declaration of that function right now.
|
||||
*
|
||||
* The call uses "+ 1" as material getter needs one-based indices.
|
||||
*/
|
||||
Object *obj = const_cast<Object *>(&export_object_eval_);
|
||||
const Material *r_mat = BKE_object_material_get_eval(obj, mat_nr + 1);
|
||||
return r_mat;
|
||||
}
|
||||
|
||||
bool OBJMesh::is_ith_poly_smooth(const int face_index) const
|
||||
{
|
||||
return !sharp_faces_[face_index];
|
||||
@@ -253,7 +246,7 @@ bool OBJMesh::is_ith_poly_smooth(const int face_index) const
|
||||
|
||||
const char *OBJMesh::get_object_name() const
|
||||
{
|
||||
return export_object_eval_.id.name + 2;
|
||||
return object_name_.c_str();
|
||||
}
|
||||
|
||||
const char *OBJMesh::get_object_mesh_name() const
|
||||
@@ -261,15 +254,6 @@ const char *OBJMesh::get_object_mesh_name() const
|
||||
return export_mesh_->id.name + 2;
|
||||
}
|
||||
|
||||
const char *OBJMesh::get_object_material_name(const int16_t mat_nr) const
|
||||
{
|
||||
const Material *mat = get_object_material(mat_nr);
|
||||
if (!mat) {
|
||||
return nullptr;
|
||||
}
|
||||
return mat->id.name + 2;
|
||||
}
|
||||
|
||||
float3 OBJMesh::calc_vertex_coords(const int vert_index, const float global_scale) const
|
||||
{
|
||||
float3 r_coords = mesh_positions_[vert_index];
|
||||
@@ -428,10 +412,7 @@ Vector<int> OBJMesh::calc_poly_normal_indices(const int face_index) const
|
||||
|
||||
int OBJMesh::tot_deform_groups() const
|
||||
{
|
||||
if (!BKE_object_supports_vertex_groups(&export_object_eval_)) {
|
||||
return 0;
|
||||
}
|
||||
return BKE_object_defgroup_count(&export_object_eval_);
|
||||
return BLI_listbase_count(&export_mesh_->vertex_group_names);
|
||||
}
|
||||
|
||||
int16_t OBJMesh::get_poly_deform_group_index(const int face_index,
|
||||
@@ -469,7 +450,7 @@ int16_t OBJMesh::get_poly_deform_group_index(const int face_index,
|
||||
const char *OBJMesh::get_poly_deform_group_name(const int16_t def_group_index) const
|
||||
{
|
||||
const bDeformGroup &vertex_group = *(static_cast<bDeformGroup *>(
|
||||
BLI_findlink(BKE_object_defgroup_list(&export_object_eval_), def_group_index)));
|
||||
BLI_findlink(&export_mesh_->vertex_group_names, def_group_index)));
|
||||
return vertex_group.name;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,11 +30,7 @@ const int NEGATIVE_INIT = -10;
|
||||
|
||||
class OBJMesh : NonCopyable {
|
||||
private:
|
||||
/**
|
||||
* We need to copy the entire Object structure here because the dependency graph iterator
|
||||
* sometimes builds an Object in a temporary space that doesn't persist.
|
||||
*/
|
||||
Object export_object_eval_;
|
||||
std::string object_name_;
|
||||
/** A pointer to #owned_export_mesh_ or the object'ed evaluated/original mesh. */
|
||||
const Mesh *export_mesh_;
|
||||
/** A mesh owned here, if created or modified for the export. May be null. */
|
||||
@@ -89,6 +85,8 @@ class OBJMesh : NonCopyable {
|
||||
Vector<int> poly_order_;
|
||||
|
||||
public:
|
||||
Array<const Material *> materials;
|
||||
|
||||
/**
|
||||
* Store evaluated Object and Mesh pointers. Conditionally triangulate a mesh, or
|
||||
* create a new Mesh from a Curve.
|
||||
@@ -114,10 +112,6 @@ class OBJMesh : NonCopyable {
|
||||
* \return Total materials in the object.
|
||||
*/
|
||||
int16_t tot_materials() const;
|
||||
/**
|
||||
* Return mat_nr-th material of the object. The given index should be zero-based.
|
||||
*/
|
||||
const Material *get_object_material(int16_t mat_nr) const;
|
||||
|
||||
/**
|
||||
* Calculate smooth groups of a smooth-shaded object.
|
||||
@@ -138,10 +132,6 @@ class OBJMesh : NonCopyable {
|
||||
* Get Object's Mesh's name.
|
||||
*/
|
||||
const char *get_object_mesh_name() const;
|
||||
/**
|
||||
* Get object's material (at the given index) name. The given index should be zero-based.
|
||||
*/
|
||||
const char *get_object_material_name(int16_t mat_nr) const;
|
||||
|
||||
/**
|
||||
* Calculate coordinates of the vertex at the given index.
|
||||
@@ -232,6 +222,6 @@ class OBJMesh : NonCopyable {
|
||||
/**
|
||||
* Set the final transform after applying axes settings and an Object's world transform.
|
||||
*/
|
||||
void set_world_axes_transform(eIOAxis forward, eIOAxis up);
|
||||
void set_world_axes_transform(const Object &obj_eval, eIOAxis forward, eIOAxis up);
|
||||
};
|
||||
} // namespace blender::io::obj
|
||||
|
||||
Reference in New Issue
Block a user