ENH:import obj by right menu set new assembly pos

jira: STUDIO-7409
Change-Id: I089aea9333cf0f894dbfa67b09fbb8019c6f6023
(cherry picked from commit ab249fa3b4ec9f5e2965c7cffdbbe1f3f2d14332)
This commit is contained in:
zhou.xu 2024-06-24 09:21:26 +08:00 committed by Lane.Wei
parent 18a0a7e6e7
commit 01e2a2032b
7 changed files with 71 additions and 15 deletions

View File

@ -452,6 +452,21 @@ ModelObject* Model::add_object(const ModelObject &other)
return new_object; return new_object;
} }
void Model::set_assembly_pos(ModelObject *model_object)
{
if (!model_object) {return;}
auto cur_assemble_scene_box = bounding_box_in_assembly_view();
if (cur_assemble_scene_box.defined) {
auto offset = cur_assemble_scene_box.center();
auto mo_box = model_object->bounding_box_in_assembly_view();
offset[0] += ((cur_assemble_scene_box.size()[0] / 2.0f + mo_box.size()[0] / 2.0f) * 1.2);
offset[2] = cur_assemble_scene_box.min[2] + mo_box.size()[2];
model_object->instances[0]->set_assemble_offset(offset);
offset[1] += cur_assemble_scene_box.center().y() - model_object->bounding_box_in_assembly_view().center().y();
model_object->instances[0]->set_assemble_offset(offset);
}
}
void Model::delete_object(size_t idx) void Model::delete_object(size_t idx)
{ {
ModelObjectPtrs::iterator i = this->objects.begin() + idx; ModelObjectPtrs::iterator i = this->objects.begin() + idx;
@ -603,6 +618,13 @@ BoundingBoxf3 Model::bounding_box() const
return bb; return bb;
} }
BoundingBoxf3 Model::bounding_box_in_assembly_view() const {
BoundingBoxf3 bb;
for (ModelObject *o : this->objects)
bb.merge(o->bounding_box_in_assembly_view());
return bb;
}
unsigned int Model::update_print_volume_state(const BuildVolume &build_volume) unsigned int Model::update_print_volume_state(const BuildVolume &build_volume)
{ {
unsigned int num_printable = 0; unsigned int num_printable = 0;
@ -1353,6 +1375,15 @@ const BoundingBoxf3& ModelObject::bounding_box() const
return m_bounding_box; return m_bounding_box;
} }
const BoundingBoxf3 &ModelObject::bounding_box_in_assembly_view() const
{
m_bounding_box_in_assembly_view.reset();
BoundingBoxf3 raw_bbox = this->raw_mesh_bounding_box();
for (const ModelInstance *i : this->instances)
m_bounding_box_in_assembly_view.merge(i->transform_bounding_box_in_assembly_view(raw_bbox));
return m_bounding_box_in_assembly_view;
}
// A mesh containing all transformed instances of this object. // A mesh containing all transformed instances of this object.
TriangleMesh ModelObject::mesh() const TriangleMesh ModelObject::mesh() const
{ {
@ -3337,6 +3368,10 @@ BoundingBoxf3 ModelInstance::transform_bounding_box(const BoundingBoxf3 &bbox, b
return bbox.transformed(get_matrix(dont_translate)); return bbox.transformed(get_matrix(dont_translate));
} }
BoundingBoxf3 ModelInstance::transform_bounding_box_in_assembly_view(const BoundingBoxf3 &bbox, bool dont_translate) const {
return bbox.transformed(get_assemble_transformation().get_matrix());
}
Vec3d ModelInstance::transform_vector(const Vec3d& v, bool dont_translate) const Vec3d ModelInstance::transform_vector(const Vec3d& v, bool dont_translate) const
{ {
return get_matrix(dont_translate) * v; return get_matrix(dont_translate) * v;

View File

@ -427,6 +427,7 @@ public:
// This bounding box is approximate and not snug. // This bounding box is approximate and not snug.
// This bounding box is being cached. // This bounding box is being cached.
const BoundingBoxf3& bounding_box() const; const BoundingBoxf3& bounding_box() const;
const BoundingBoxf3& bounding_box_in_assembly_view() const;
void invalidate_bounding_box() { m_bounding_box_valid = false; m_raw_bounding_box_valid = false; m_raw_mesh_bounding_box_valid = false; } void invalidate_bounding_box() { m_bounding_box_valid = false; m_raw_bounding_box_valid = false; m_raw_mesh_bounding_box_valid = false; }
// A mesh containing all transformed instances of this object. // A mesh containing all transformed instances of this object.
@ -647,6 +648,7 @@ private:
// Bounding box, cached. // Bounding box, cached.
mutable BoundingBoxf3 m_bounding_box; mutable BoundingBoxf3 m_bounding_box;
mutable BoundingBoxf3 m_bounding_box_in_assembly_view;
mutable bool m_bounding_box_valid; mutable bool m_bounding_box_valid;
mutable BoundingBoxf3 m_raw_bounding_box; mutable BoundingBoxf3 m_raw_bounding_box;
mutable bool m_raw_bounding_box_valid; mutable bool m_raw_bounding_box_valid;
@ -1278,7 +1280,7 @@ public:
m_assemble_transformation.set_from_transform(transform); m_assemble_transformation.set_from_transform(transform);
} }
const Vec3d& get_assemble_offset() {return m_assemble_transformation.get_offset(); } const Vec3d& get_assemble_offset() {return m_assemble_transformation.get_offset(); }
void set_assemble_offset(const Vec3d& offset) { m_assemble_transformation.set_offset(offset); } void set_assemble_offset(const Vec3d &offset){ m_assemble_initialized = true;m_assemble_transformation.set_offset(offset);}
void set_assemble_rotation(const Vec3d &rotation) { m_assemble_transformation.set_rotation(rotation); } void set_assemble_rotation(const Vec3d &rotation) { m_assemble_transformation.set_rotation(rotation); }
void rotate_assemble(double angle, const Vec3d& axis) { void rotate_assemble(double angle, const Vec3d& axis) {
m_assemble_transformation.set_rotation(m_assemble_transformation.get_rotation() + Geometry::extract_euler_angles(Eigen::Quaterniond(Eigen::AngleAxisd(angle, axis)).toRotationMatrix())); m_assemble_transformation.set_rotation(m_assemble_transformation.get_rotation() + Geometry::extract_euler_angles(Eigen::Quaterniond(Eigen::AngleAxisd(angle, axis)).toRotationMatrix()));
@ -1328,6 +1330,7 @@ public:
BoundingBoxf3 transform_mesh_bounding_box(const TriangleMesh& mesh, bool dont_translate = false) const; BoundingBoxf3 transform_mesh_bounding_box(const TriangleMesh& mesh, bool dont_translate = false) const;
// Transform an external bounding box. // Transform an external bounding box.
BoundingBoxf3 transform_bounding_box(const BoundingBoxf3 &bbox, bool dont_translate = false) const; BoundingBoxf3 transform_bounding_box(const BoundingBoxf3 &bbox, bool dont_translate = false) const;
BoundingBoxf3 transform_bounding_box_in_assembly_view(const BoundingBoxf3 &bbox, bool dont_translate = false) const;
// Transform an external vector. // Transform an external vector.
Vec3d transform_vector(const Vec3d& v, bool dont_translate = false) const; Vec3d transform_vector(const Vec3d& v, bool dont_translate = false) const;
// To be called on an external polygon. It does not translate the polygon, only rotates and scales. // To be called on an external polygon. It does not translate the polygon, only rotates and scales.
@ -1602,6 +1605,7 @@ public:
ModelObject* add_object(const char *name, const char *path, const TriangleMesh &mesh); ModelObject* add_object(const char *name, const char *path, const TriangleMesh &mesh);
ModelObject* add_object(const char *name, const char *path, TriangleMesh &&mesh); ModelObject* add_object(const char *name, const char *path, TriangleMesh &&mesh);
ModelObject* add_object(const ModelObject &other); ModelObject* add_object(const ModelObject &other);
void set_assembly_pos(ModelObject * model_object);
void delete_object(size_t idx); void delete_object(size_t idx);
bool delete_object(ObjectID id); bool delete_object(ObjectID id);
bool delete_object(ModelObject* object); bool delete_object(ModelObject* object);
@ -1624,6 +1628,7 @@ public:
bool add_default_instances(); bool add_default_instances();
// Returns approximate axis aligned bounding box of this model // Returns approximate axis aligned bounding box of this model
BoundingBoxf3 bounding_box() const; BoundingBoxf3 bounding_box() const;
BoundingBoxf3 bounding_box_in_assembly_view() const;
// Set the print_volume_state of PrintObject::instances, // Set the print_volume_state of PrintObject::instances,
// return total number of printable objects. // return total number of printable objects.
unsigned int update_print_volume_state(const BuildVolume &build_volume); unsigned int update_print_volume_state(const BuildVolume &build_volume);

View File

@ -1572,6 +1572,10 @@ void GLCanvas3D::refresh_camera_scene_box()
wxGetApp().plater()->get_camera().set_scene_box(scene_bounding_box()); wxGetApp().plater()->get_camera().set_scene_box(scene_bounding_box());
} }
BoundingBoxf3 GLCanvas3D::assembly_view_cur_bounding_box() const {
return m_model->bounding_box_in_assembly_view();
}
BoundingBoxf3 GLCanvas3D::volumes_bounding_box() const BoundingBoxf3 GLCanvas3D::volumes_bounding_box() const
{ {
BoundingBoxf3 bb; BoundingBoxf3 bb;

View File

@ -502,6 +502,7 @@ public:
}; };
int GetHoverId(); int GetHoverId();
void set_ignore_left_up() { m_mouse.ignore_left_up = true; }
private: private:
bool m_is_dark = false; bool m_is_dark = false;
@ -778,6 +779,7 @@ public:
void set_show_world_axes(bool flag) { m_show_world_axes = flag; } void set_show_world_axes(bool flag) { m_show_world_axes = flag; }
void refresh_camera_scene_box(); void refresh_camera_scene_box();
BoundingBoxf3 assembly_view_cur_bounding_box() const;
BoundingBoxf3 volumes_bounding_box() const; BoundingBoxf3 volumes_bounding_box() const;
BoundingBoxf3 scene_bounding_box() const; BoundingBoxf3 scene_bounding_box() const;
BoundingBoxf3 plate_scene_bounding_box(int plate_idx) const; BoundingBoxf3 plate_scene_bounding_box(int plate_idx) const;

View File

@ -2281,8 +2281,7 @@ void ObjectList::load_mesh_object(const TriangleMesh &mesh, const wxString &name
new_object->ensure_on_bed(); new_object->ensure_on_bed();
//BBS init assmeble transformation //BBS init assmeble transformation
Geometry::Transformation t = new_object->instances[0]->get_transformation(); new_object->get_model()->set_assembly_pos(new_object);
new_object->instances[0]->set_assemble_transformation(t);
object_idxs.push_back(model.objects.size() - 1); object_idxs.push_back(model.objects.size() - 1);
#ifdef _DEBUG #ifdef _DEBUG

View File

@ -3535,7 +3535,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
const float INIT_MODEL_RATIO = 0.75; const float INIT_MODEL_RATIO = 0.75;
const float CENTER_AROUND_ORIGIN_RATIO = 0.8; const float CENTER_AROUND_ORIGIN_RATIO = 0.8;
const float LOAD_MODEL_RATIO = 0.9; const float LOAD_MODEL_RATIO = 0.9;
bool import_obj_or_stl = false;
for (size_t i = 0; i < input_files.size(); ++i) { for (size_t i = 0; i < input_files.size(); ++i) {
int file_percent = 0; int file_percent = 0;
@ -4159,7 +4159,9 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
q->skip_thumbnail_invalid = false; q->skip_thumbnail_invalid = false;
return empty_result; return empty_result;
} }
if (boost::algorithm::iends_with(path.string(), ".stl") || boost::algorithm::iends_with(path.string(), ".obj")) {
import_obj_or_stl = true;
}
if (one_by_one) { if (one_by_one) {
// BBS: add load_old_project logic // BBS: add load_old_project logic
if (type_3mf && !is_project_file && !load_old_project) if (type_3mf && !is_project_file && !load_old_project)
@ -4174,7 +4176,11 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", before load_model_objects, count %1%")%model.objects.size(); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", before load_model_objects, count %1%")%model.objects.size();
auto loaded_idxs = load_model_objects(model.objects, is_project_file); auto loaded_idxs = load_model_objects(model.objects, is_project_file);
obj_idxs.insert(obj_idxs.end(), loaded_idxs.begin(), loaded_idxs.end()); obj_idxs.insert(obj_idxs.end(), loaded_idxs.begin(), loaded_idxs.end());
if (import_obj_or_stl) {
for (int i = 0; i < loaded_idxs.size(); i++) {
q->model().set_assembly_pos(q->model().objects[q->model().objects.size() - 1 - i]);
}
}
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", finished load_model_objects"); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", finished load_model_objects");
wxString msg = wxString::Format(_L("Loading file: %s"), from_path(real_filename)); wxString msg = wxString::Format(_L("Loading file: %s"), from_path(real_filename));
dlg_cont = dlg.Update(progress_percent, msg); dlg_cont = dlg.Update(progress_percent, msg);
@ -4209,6 +4215,11 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
auto loaded_idxs = load_model_objects(new_model->objects); auto loaded_idxs = load_model_objects(new_model->objects);
obj_idxs.insert(obj_idxs.end(), loaded_idxs.begin(), loaded_idxs.end()); obj_idxs.insert(obj_idxs.end(), loaded_idxs.begin(), loaded_idxs.end());
if (import_obj_or_stl) {
for (int i = 0; i < loaded_idxs.size(); i++) {
q->model().set_assembly_pos(q->model().objects[q->model().objects.size() - 1 - i]);
}
}
} }
if (new_model) delete new_model; if (new_model) delete new_model;
@ -6252,7 +6263,7 @@ void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice)
assemble_view->get_canvas3d()->bind_event_handlers(); assemble_view->get_canvas3d()->bind_event_handlers();
assemble_view->reload_scene(true); assemble_view->reload_scene(true);
assemble_view->get_canvas3d()->set_ignore_left_up();
if (old_panel == view3D) { if (old_panel == view3D) {
GLCanvas3D* view3D_canvas = view3D->get_canvas3d(); GLCanvas3D* view3D_canvas = view3D->get_canvas3d();
Selection::IndicesList select_idxs = view3D_canvas->get_selection().get_volume_idxs(); Selection::IndicesList select_idxs = view3D_canvas->get_selection().get_volume_idxs();