Changes in loading of modifiers from file and their positioning
This commit is contained in:
parent
4257ffddde
commit
1a64abac96
@ -1371,12 +1371,15 @@ void ObjectList::load_subobject(ModelVolumeType type, bool from_galery/* = false
|
|||||||
item = m_objects_model->GetItemById(obj_idx);
|
item = m_objects_model->GetItemById(obj_idx);
|
||||||
|
|
||||||
std::vector<ModelVolume*> volumes;
|
std::vector<ModelVolume*> volumes;
|
||||||
load_part((*m_objects)[obj_idx], volumes, type, from_galery);
|
if (type == ModelVolumeType::MODEL_PART)
|
||||||
|
load_part(*(*m_objects)[obj_idx], volumes, type, from_galery);
|
||||||
|
else
|
||||||
|
load_modifier(*(*m_objects)[obj_idx], volumes, type, from_galery);
|
||||||
|
|
||||||
if (volumes.empty())
|
if (volumes.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
take_snapshot(_L("Load Part"));
|
take_snapshot((type == ModelVolumeType::MODEL_PART) ? _L("Load Part") : _L("Load Modifier"));
|
||||||
|
|
||||||
wxDataViewItemArray items = reorder_volumes_and_get_selection(obj_idx, [volumes](const ModelVolume* volume) {
|
wxDataViewItemArray items = reorder_volumes_and_get_selection(obj_idx, [volumes](const ModelVolume* volume) {
|
||||||
return std::find(volumes.begin(), volumes.end(), volume) != volumes.end(); });
|
return std::find(volumes.begin(), volumes.end(), volume) != volumes.end(); });
|
||||||
@ -1394,8 +1397,11 @@ void ObjectList::load_subobject(ModelVolumeType type, bool from_galery/* = false
|
|||||||
selection_changed();
|
selection_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectList::load_part(ModelObject* model_object, std::vector<ModelVolume*>& added_volumes, ModelVolumeType type, bool from_galery/* = false*/)
|
void ObjectList::load_part(ModelObject& model_object, std::vector<ModelVolume*>& added_volumes, ModelVolumeType type, bool from_galery/* = false*/)
|
||||||
{
|
{
|
||||||
|
if (type != ModelVolumeType::MODEL_PART)
|
||||||
|
return;
|
||||||
|
|
||||||
wxWindow* parent = wxGetApp().tab_panel()->GetPage(0);
|
wxWindow* parent = wxGetApp().tab_panel()->GetPage(0);
|
||||||
|
|
||||||
wxArrayString input_files;
|
wxArrayString input_files;
|
||||||
@ -1433,13 +1439,13 @@ void ObjectList::load_part(ModelObject* model_object, std::vector<ModelVolume*>&
|
|||||||
|
|
||||||
for (auto object : model.objects) {
|
for (auto object : model.objects) {
|
||||||
Vec3d delta = Vec3d::Zero();
|
Vec3d delta = Vec3d::Zero();
|
||||||
if (model_object->origin_translation != Vec3d::Zero()) {
|
if (model_object.origin_translation != Vec3d::Zero()) {
|
||||||
object->center_around_origin();
|
object->center_around_origin();
|
||||||
delta = model_object->origin_translation - object->origin_translation;
|
delta = model_object.origin_translation - object->origin_translation;
|
||||||
}
|
}
|
||||||
for (auto volume : object->volumes) {
|
for (auto volume : object->volumes) {
|
||||||
volume->translate(delta);
|
volume->translate(delta);
|
||||||
auto new_volume = model_object->add_volume(*volume, type);
|
auto new_volume = model_object.add_volume(*volume, type);
|
||||||
new_volume->name = boost::filesystem::path(input_file).filename().string();
|
new_volume->name = boost::filesystem::path(input_file).filename().string();
|
||||||
// set a default extruder value, since user can't add it manually
|
// set a default extruder value, since user can't add it manually
|
||||||
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
|
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
|
||||||
@ -1448,7 +1454,98 @@ void ObjectList::load_part(ModelObject* model_object, std::vector<ModelVolume*>&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectList::load_modifier(ModelObject& model_object, std::vector<ModelVolume*>& added_volumes, ModelVolumeType type, bool from_galery)
|
||||||
|
{
|
||||||
|
if (type == ModelVolumeType::MODEL_PART)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxWindow* parent = wxGetApp().tab_panel()->GetPage(0);
|
||||||
|
|
||||||
|
wxArrayString input_files;
|
||||||
|
|
||||||
|
if (from_galery) {
|
||||||
|
GalleryDialog dlg(this);
|
||||||
|
if (dlg.ShowModal() == wxID_CANCEL)
|
||||||
|
return;
|
||||||
|
dlg.get_input_files(input_files);
|
||||||
|
if (input_files.IsEmpty())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
wxGetApp().import_model(parent, input_files);
|
||||||
|
|
||||||
|
wxProgressDialog dlg(_L("Loading") + dots, "", 100, wxGetApp().plater(), wxPD_AUTO_HIDE);
|
||||||
|
wxBusyCursor busy;
|
||||||
|
|
||||||
|
const int obj_idx = get_selected_obj_idx();
|
||||||
|
if (obj_idx < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const Selection& selection = scene_selection();
|
||||||
|
assert(obj_idx == selection.get_object_idx());
|
||||||
|
|
||||||
|
/** Any changes of the Object's composition is duplicated for all Object's Instances
|
||||||
|
* So, It's enough to take a bounding box of a first selected Instance and calculate Part(generic_subobject) position
|
||||||
|
*/
|
||||||
|
int instance_idx = *selection.get_instance_idxs().begin();
|
||||||
|
assert(instance_idx != -1);
|
||||||
|
if (instance_idx == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Bounding box of the selected instance in world coordinate system including the translation, without modifiers.
|
||||||
|
const BoundingBoxf3 instance_bb = model_object.instance_bounding_box(instance_idx);
|
||||||
|
|
||||||
|
// First (any) GLVolume of the selected instance. They all share the same instance matrix.
|
||||||
|
const GLVolume* v = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||||
|
const Geometry::Transformation inst_transform = v->get_instance_transformation();
|
||||||
|
const Transform3d inv_inst_transform = inst_transform.get_matrix(true).inverse();
|
||||||
|
const Vec3d instance_offset = v->get_instance_offset();
|
||||||
|
|
||||||
|
const double side = wxGetApp().plater()->canvas3D()->get_size_proportional_to_max_bed_size(0.1);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < input_files.size(); ++i) {
|
||||||
|
const std::string input_file = input_files.Item(i).ToUTF8().data();
|
||||||
|
|
||||||
|
dlg.Update(static_cast<int>(100.0f * static_cast<float>(i) / static_cast<float>(input_files.size())),
|
||||||
|
_L("Loading file") + ": " + from_path(boost::filesystem::path(input_file).filename()));
|
||||||
|
dlg.Fit();
|
||||||
|
|
||||||
|
Model model;
|
||||||
|
try {
|
||||||
|
model = Model::read_from_file(input_file);
|
||||||
|
}
|
||||||
|
catch (std::exception& e) {
|
||||||
|
auto msg = _L("Error!") + " " + input_file + " : " + e.what() + ".";
|
||||||
|
show_error(parent, msg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
model.center_instances_around_point(Vec2d::Zero());
|
||||||
|
double model_max_size = model.bounding_box().max_size();
|
||||||
|
if (model_max_size == 0.0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
TriangleMesh mesh = model.mesh();
|
||||||
|
mesh.repair();
|
||||||
|
mesh.scale(static_cast<float>(side / model_max_size));
|
||||||
|
|
||||||
|
// Mesh will be centered when loading.
|
||||||
|
ModelVolume* new_volume = model_object.add_volume(std::move(mesh), type);
|
||||||
|
// Transform the new modifier to be aligned with the print bed.
|
||||||
|
const BoundingBoxf3 mesh_bb = new_volume->mesh().bounding_box();
|
||||||
|
new_volume->set_transformation(Geometry::Transformation::volume_to_bed_transformation(inst_transform, mesh_bb));
|
||||||
|
// Set the modifier position.
|
||||||
|
// Translate the new modifier to be pickable: move to the left front corner of the instance's bounding box, lift to print bed.
|
||||||
|
auto offset = Vec3d(instance_bb.max.x(), instance_bb.min.y(), instance_bb.min.z()) + 0.5 * mesh_bb.size() - instance_offset;
|
||||||
|
new_volume->set_offset(inv_inst_transform * offset);
|
||||||
|
new_volume->name = boost::filesystem::path(input_file).filename().string();
|
||||||
|
// set a default extruder value, since user can't add it manually
|
||||||
|
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
|
||||||
|
|
||||||
|
added_volumes.push_back(new_volume);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static TriangleMesh create_mesh(const std::string& type_name, const BoundingBoxf3& bb)
|
static TriangleMesh create_mesh(const std::string& type_name, const BoundingBoxf3& bb)
|
||||||
@ -1498,7 +1595,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
|
|||||||
if (instance_idx == -1)
|
if (instance_idx == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
take_snapshot(_(L("Add Generic Subobject")));
|
take_snapshot(_L("Add Generic Subobject"));
|
||||||
|
|
||||||
// Selected object
|
// Selected object
|
||||||
ModelObject &model_object = *(*m_objects)[obj_idx];
|
ModelObject &model_object = *(*m_objects)[obj_idx];
|
||||||
@ -1510,23 +1607,20 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
|
|||||||
// Mesh will be centered when loading.
|
// Mesh will be centered when loading.
|
||||||
ModelVolume *new_volume = model_object.add_volume(std::move(mesh), type);
|
ModelVolume *new_volume = model_object.add_volume(std::move(mesh), type);
|
||||||
|
|
||||||
if (instance_idx != -1)
|
// First (any) GLVolume of the selected instance. They all share the same instance matrix.
|
||||||
{
|
const GLVolume* v = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||||
// First (any) GLVolume of the selected instance. They all share the same instance matrix.
|
// Transform the new modifier to be aligned with the print bed.
|
||||||
const GLVolume* v = selection.get_volume(*selection.get_volume_idxs().begin());
|
const BoundingBoxf3 mesh_bb = new_volume->mesh().bounding_box();
|
||||||
// Transform the new modifier to be aligned with the print bed.
|
new_volume->set_transformation(Geometry::Transformation::volume_to_bed_transformation(v->get_instance_transformation(), mesh_bb));
|
||||||
const BoundingBoxf3 mesh_bb = new_volume->mesh().bounding_box();
|
// Set the modifier position.
|
||||||
new_volume->set_transformation(Geometry::Transformation::volume_to_bed_transformation(v->get_instance_transformation(), mesh_bb));
|
auto offset = (type_name == "Slab") ?
|
||||||
// Set the modifier position.
|
// Slab: Lift to print bed
|
||||||
auto offset = (type_name == "Slab") ?
|
Vec3d(0., 0., 0.5 * mesh_bb.size().z() + instance_bb.min.z() - v->get_instance_offset().z()) :
|
||||||
// Slab: Lift to print bed
|
// Translate the new modifier to be pickable: move to the left front corner of the instance's bounding box, lift to print bed.
|
||||||
Vec3d(0., 0., 0.5 * mesh_bb.size().z() + instance_bb.min.z() - v->get_instance_offset().z()) :
|
Vec3d(instance_bb.max.x(), instance_bb.min.y(), instance_bb.min.z()) + 0.5 * mesh_bb.size() - v->get_instance_offset();
|
||||||
// Translate the new modifier to be pickable: move to the left front corner of the instance's bounding box, lift to print bed.
|
new_volume->set_offset(v->get_instance_transformation().get_matrix(true).inverse() * offset);
|
||||||
Vec3d(instance_bb.max(0), instance_bb.min(1), instance_bb.min(2)) + 0.5 * mesh_bb.size() - v->get_instance_offset();
|
|
||||||
new_volume->set_offset(v->get_instance_transformation().get_matrix(true).inverse() * offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
const wxString name = _(L("Generic")) + "-" + _(type_name);
|
const wxString name = _L("Generic") + "-" + _(type_name);
|
||||||
new_volume->name = into_u8(name);
|
new_volume->name = into_u8(name);
|
||||||
// set a default extruder value, since user can't add it manually
|
// set a default extruder value, since user can't add it manually
|
||||||
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
|
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
|
||||||
@ -1594,7 +1688,7 @@ void ObjectList::load_mesh_object(const TriangleMesh &mesh, const wxString &name
|
|||||||
|
|
||||||
if (center) {
|
if (center) {
|
||||||
const BoundingBoxf bed_shape = wxGetApp().plater()->bed_shape_bb();
|
const BoundingBoxf bed_shape = wxGetApp().plater()->bed_shape_bb();
|
||||||
new_object->instances[0]->set_offset(Slic3r::to_3d(bed_shape.center().cast<double>(), -new_object->origin_translation(2)));
|
new_object->instances[0]->set_offset(Slic3r::to_3d(bed_shape.center().cast<double>(), -new_object->origin_translation.z()));
|
||||||
} else {
|
} else {
|
||||||
new_object->instances[0]->set_offset(bb.center());
|
new_object->instances[0]->set_offset(bb.center());
|
||||||
}
|
}
|
||||||
|
@ -240,8 +240,9 @@ public:
|
|||||||
bool is_instance_or_object_selected();
|
bool is_instance_or_object_selected();
|
||||||
|
|
||||||
void load_subobject(ModelVolumeType type, bool from_galery = false);
|
void load_subobject(ModelVolumeType type, bool from_galery = false);
|
||||||
void load_part(ModelObject* model_object, std::vector<ModelVolume*> &added_volumes, ModelVolumeType type, bool from_galery = false);
|
void load_part(ModelObject& model_object, std::vector<ModelVolume*>& added_volumes, ModelVolumeType type, bool from_galery = false);
|
||||||
void load_generic_subobject(const std::string& type_name, const ModelVolumeType type);
|
void load_modifier(ModelObject& model_object, std::vector<ModelVolume*>& added_volumes, ModelVolumeType type, bool from_galery = false);
|
||||||
|
void load_generic_subobject(const std::string& type_name, const ModelVolumeType type);
|
||||||
void load_shape_object(const std::string &type_name);
|
void load_shape_object(const std::string &type_name);
|
||||||
void load_mesh_object(const TriangleMesh &mesh, const wxString &name, bool center = true);
|
void load_mesh_object(const TriangleMesh &mesh, const wxString &name, bool center = true);
|
||||||
void del_object(const int obj_idx);
|
void del_object(const int obj_idx);
|
||||||
|
Loading…
Reference in New Issue
Block a user