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:
parent
18a0a7e6e7
commit
01e2a2032b
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue