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;
}
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)
{
ModelObjectPtrs::iterator i = this->objects.begin() + idx;
@ -603,6 +618,13 @@ BoundingBoxf3 Model::bounding_box() const
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 num_printable = 0;
@ -1353,6 +1375,15 @@ const BoundingBoxf3& ModelObject::bounding_box() const
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.
TriangleMesh ModelObject::mesh() const
{
@ -3337,6 +3368,10 @@ BoundingBoxf3 ModelInstance::transform_bounding_box(const BoundingBoxf3 &bbox, b
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
{
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 being cached.
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; }
// A mesh containing all transformed instances of this object.
@ -647,6 +648,7 @@ private:
// Bounding box, cached.
mutable BoundingBoxf3 m_bounding_box;
mutable BoundingBoxf3 m_bounding_box_in_assembly_view;
mutable bool m_bounding_box_valid;
mutable BoundingBoxf3 m_raw_bounding_box;
mutable bool m_raw_bounding_box_valid;
@ -1278,7 +1280,7 @@ public:
m_assemble_transformation.set_from_transform(transform);
}
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 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()));
@ -1328,6 +1330,7 @@ public:
BoundingBoxf3 transform_mesh_bounding_box(const TriangleMesh& mesh, bool dont_translate = false) const;
// Transform an external bounding box.
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.
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.
@ -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, TriangleMesh &&mesh);
ModelObject* add_object(const ModelObject &other);
void set_assembly_pos(ModelObject * model_object);
void delete_object(size_t idx);
bool delete_object(ObjectID id);
bool delete_object(ModelObject* object);
@ -1624,6 +1628,7 @@ public:
bool add_default_instances();
// Returns approximate axis aligned bounding box of this model
BoundingBoxf3 bounding_box() const;
BoundingBoxf3 bounding_box_in_assembly_view() const;
// Set the print_volume_state of PrintObject::instances,
// return total number of printable objects.
unsigned int update_print_volume_state(const BuildVolume &build_volume);

View File

@ -1349,7 +1349,7 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type,
const Transform3d & view_matrix,
std::function<bool(const GLVolume &)> filter_func,
bool with_outline,
const std::array<float, 4> & body_color,
const std::array<float, 4> & body_color,
bool partly_inside_enable) const
{
GLVolumeWithIdAndZList to_render = volumes_to_render(volumes, type, view_matrix, filter_func);

View File

@ -1572,6 +1572,10 @@ void GLCanvas3D::refresh_camera_scene_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 bb;

View File

@ -416,7 +416,7 @@ class GLCanvas3D
void render(const std::vector<const ModelInstance*>& sorted_instances) const;
};
class Tooltip
{
std::string m_text;
@ -502,6 +502,7 @@ public:
};
int GetHoverId();
void set_ignore_left_up() { m_mouse.ignore_left_up = true; }
private:
bool m_is_dark = false;
@ -778,6 +779,7 @@ public:
void set_show_world_axes(bool flag) { m_show_world_axes = flag; }
void refresh_camera_scene_box();
BoundingBoxf3 assembly_view_cur_bounding_box() const;
BoundingBoxf3 volumes_bounding_box() const;
BoundingBoxf3 scene_bounding_box() const;
BoundingBoxf3 plate_scene_bounding_box(int plate_idx) const;
@ -1032,7 +1034,7 @@ public:
bool is_overhang_shown() const { return m_slope.is_GlobalUsed(); }
void show_overhang(bool show) { m_slope.globalUse(show); }
bool is_using_slope() const { return m_slope.is_used(); }
void use_slope(bool use) { m_slope.use(use); }
void set_slope_normal_angle(float angle_in_deg) { m_slope.set_normal_angle(angle_in_deg); }

View File

@ -57,7 +57,7 @@ static const Selection& scene_selection()
//BBS AssembleView canvas has its own selection
if (wxGetApp().plater()->get_current_canvas3D()->get_canvas_type() == GLCanvas3D::ECanvasType::CanvasAssembleView)
return wxGetApp().plater()->get_assmeble_canvas3D()->get_selection();
return wxGetApp().plater()->get_view3D_canvas3D()->get_selection();
}
@ -140,7 +140,7 @@ ObjectList::ObjectList(wxWindow* parent) :
int new_selected_column = -1;
#endif //__WXMSW__
GLGizmosManager &gizmos_mgr = wxGetApp().plater()->get_view3D_canvas3D()->get_gizmos_manager();
if ((wxGetKeyState(WXK_SHIFT) || wxGetKeyState(WXK_CONTROL))
if ((wxGetKeyState(WXK_SHIFT) || wxGetKeyState(WXK_CONTROL))
&& gizmos_mgr.is_gizmo_activable_when_single_full_instance()) {
// selection will not be single_full_instance after shift_pressed,Caused exe crashed
UnselectAll();
@ -2281,8 +2281,7 @@ void ObjectList::load_mesh_object(const TriangleMesh &mesh, const wxString &name
new_object->ensure_on_bed();
//BBS init assmeble transformation
Geometry::Transformation t = new_object->instances[0]->get_transformation();
new_object->instances[0]->set_assemble_transformation(t);
new_object->get_model()->set_assembly_pos(new_object);
object_idxs.push_back(model.objects.size() - 1);
#ifdef _DEBUG
@ -2500,7 +2499,7 @@ bool ObjectList::del_from_cut_object(bool is_cut_connector, bool is_model_part/*
const wxString title = is_cut_connector ? _L("Delete connector from object which is a part of cut") :
is_model_part ? _L("Delete solid part from object which is a part of cut") :
is_negative_volume ? _L("Delete negative volume from object which is a part of cut") : "";
const wxString msg_end = is_cut_connector ? ("\n" + _L("To save cut correspondence you can delete all connectors from all related objects.")) : "";
InfoDialog dialog(wxGetApp().plater(), title,
@ -5545,7 +5544,7 @@ void ObjectList::msw_rescale()
void ObjectList::sys_color_changed()
{
wxGetApp().UpdateDVCDarkUI(this, true);
msw_rescale();
if (m_objects_model) { m_objects_model->sys_color_changed(); }

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 CENTER_AROUND_ORIGIN_RATIO = 0.8;
const float LOAD_MODEL_RATIO = 0.9;
bool import_obj_or_stl = false;
for (size_t i = 0; i < input_files.size(); ++i) {
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;
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) {
// BBS: add load_old_project logic
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();
auto loaded_idxs = load_model_objects(model.objects, is_project_file);
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");
wxString msg = wxString::Format(_L("Loading file: %s"), from_path(real_filename));
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);
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;
@ -5828,7 +5839,7 @@ void Plater::priv::reload_from_disk()
new_volume = old_model_object->add_volume(*new_model_object->volumes[new_volume_idx]);
// new_volume = old_model_object->volumes.back();
}
new_volume->set_new_unique_id();
new_volume->config.apply(old_volume->config);
new_volume->set_type(old_volume->type());
@ -6252,7 +6263,7 @@ void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice)
assemble_view->get_canvas3d()->bind_event_handlers();
assemble_view->reload_scene(true);
assemble_view->get_canvas3d()->set_ignore_left_up();
if (old_panel == view3D) {
GLCanvas3D* view3D_canvas = view3D->get_canvas3d();
Selection::IndicesList select_idxs = view3D_canvas->get_selection().get_volume_idxs();