add the logic to reduce slicing time between shared-mesh objects

also reduce the storage size

Change-Id: I61d6e0997979ec0ce701cc580fa6640a21b6260f
This commit is contained in:
lane.wei 2022-08-18 15:29:33 +08:00 committed by Lane.Wei
parent 9245b4f36a
commit fdd9582e3e
12 changed files with 446 additions and 125 deletions

View file

@ -185,10 +185,10 @@ Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* c
if (model.objects.empty())
throw Slic3r::RuntimeError("The supplied file couldn't be read because it's empty");
for (ModelObject *o : model.objects)
o->input_file = input_file;
if (options & LoadStrategy::AddDefaultInstances)
model.add_default_instances();
@ -259,14 +259,14 @@ Model Model::read_from_archive(const std::string& input_file, DynamicPrintConfig
//BBS
//CustomGCode::update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z, config);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format("import 3mf IMPORT_STAGE_UPDATE_GCODE\n");
if (proFn) {
proFn(IMPORT_STAGE_UPDATE_GCODE, 0, 1, cb_cancel);
if (cb_cancel)
throw Slic3r::RuntimeError("Canceled");
}
CustomGCode::check_mode_for_custom_gcode_per_print_z(model.custom_gcode_per_print_z);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format("import 3mf IMPORT_STAGE_CHECK_MODE_GCODE\n");
@ -416,7 +416,7 @@ void Model::collect_reusable_objects(std::vector<ObjectBase*>& objects)
std::mem_fn(&ObjectBase::id));
model_object->volumes.clear();
}
// we never own these objects
// we never own these objects
this->objects.clear();
}
@ -591,7 +591,7 @@ void Model::convert_multipart_object(unsigned int max_extruders)
assert(this->objects.size() >= 2);
if (this->objects.size() < 2)
return;
ModelObject* object = new ModelObject(this);
object->input_file = this->objects.front()->input_file;
object->name = boost::filesystem::path(this->objects.front()->input_file).stem().string();
@ -601,7 +601,7 @@ void Model::convert_multipart_object(unsigned int max_extruders)
for (const ModelObject* o : this->objects)
for (const ModelVolume* v : o->volumes) {
// If there are more than one object, put all volumes together
// If there are more than one object, put all volumes together
// Each object may contain any number of volumes and instances
// The volumes transformations are relative to the object containing them...
Geometry::Transformation trafo_volume = v->get_transformation();
@ -620,7 +620,7 @@ void Model::convert_multipart_object(unsigned int max_extruders)
} else {
for (const ModelInstance* i : o->instances)
// ...so, transform everything to a common reference system (world)
copy_volume(object->add_volume(*v))->set_transformation(i->get_transformation() * trafo_volume);
copy_volume(object->add_volume(*v))->set_transformation(i->get_transformation() * trafo_volume);
}
}
@ -1010,6 +1010,20 @@ ModelVolume* ModelObject::add_volume(const ModelVolume &other, TriangleMesh &&me
return v;
}
ModelVolume* ModelObject::add_volume_with_shared_mesh(const ModelVolume &other, ModelVolumeType type /*= ModelVolumeType::INVALID*/)
{
ModelVolume* v = new ModelVolume(this, other.m_mesh);
if (type != ModelVolumeType::INVALID && v->type() != type)
v->set_type(type);
this->volumes.push_back(v);
// The volume should already be centered at this point of time when copying shared pointers of the triangle mesh and convex hull.
// v->center_geometry_after_creation();
// this->invalidate_bounding_box();
// BBS: backup
Slic3r::save_object_mesh(*this);
return v;
}
void ModelObject::delete_volume(size_t idx)
{
ModelVolumePtrs::iterator i = this->volumes.begin() + idx;
@ -1324,7 +1338,7 @@ Polygon ModelObject::convex_hull_2d(const Transform3d& trafo_instance) const
void ModelObject::center_around_origin(bool include_modifiers)
{
// calculate the displacements needed to
// calculate the displacements needed to
// center this object around the origin
const BoundingBoxf3 bb = include_modifiers ? full_raw_mesh_bounding_box() : raw_mesh_bounding_box();
@ -1476,8 +1490,8 @@ void ModelObject::convert_units(ModelObjectPtrs& new_objects, ConversionType con
// Perform conversion only if the target "imperial" state is different from the current one.
// This check supports conversion of "mixed" set of volumes, each with different "imperial" state.
if (//vol->source.is_converted_from_inches != from_imperial &&
(volume_idxs.empty() ||
if (//vol->source.is_converted_from_inches != from_imperial &&
(volume_idxs.empty() ||
std::find(volume_idxs.begin(), volume_idxs.end(), vol_idx) != volume_idxs.end())) {
vol->scale_geometry_after_creation(koef);
vol->set_offset(Vec3d(koef, koef, koef).cwiseProduct(volume->get_offset()));
@ -1598,7 +1612,7 @@ ModelObjectPtrs ModelObject::cut(size_t instance, std::array<Vec3d, 4> plane_poi
if (attributes.has(ModelObjectCutAttribute::KeepLower))
lower->add_volume(*volume);
}
else if (! volume->mesh().empty()) {
else if (! volume->mesh().empty()) {
// Transform the mesh by the combined transformation matrix.
// Flip the triangles in case the composite transformation is left handed.
TriangleMesh mesh(volume->mesh());
@ -1744,7 +1758,7 @@ ModelObjectPtrs ModelObject::segment(size_t instance, unsigned int max_extruders
// Modifiers are not cut, but we still need to add the instance transformation
// to the modifier volume transformation to preserve their shape properly.
volume->set_transformation(Geometry::Transformation(instance_matrix * volume_matrix));
upper->add_volume(*volume);
upper->add_volume(*volume);
}
else if (!volume->mesh().empty()) {
// Transform the mesh by the combined transformation matrix.
@ -2185,7 +2199,7 @@ void ModelObject::print_info() const
using namespace std;
cout << fixed;
boost::nowide::cout << "[" << boost::filesystem::path(this->input_file).filename().string() << "]" << endl;
TriangleMesh mesh = this->raw_mesh();
BoundingBoxf3 bb = mesh.bounding_box();
Vec3d size = bb.size();
@ -2203,7 +2217,7 @@ void ModelObject::print_info() const
cout << "manifold = " << (mesh.stats().manifold() ? "yes" : "no") << endl;
if (! mesh.stats().manifold())
cout << "open_edges = " << mesh.stats().open_edges << endl;
if (mesh.stats().repaired()) {
const RepairedMeshErrors& stats = mesh.stats().repaired_errors;
if (stats.degenerate_facets > 0)
@ -2286,7 +2300,7 @@ void ModelVolume::set_material_id(t_model_material_id material_id)
}
ModelMaterial* ModelVolume::material() const
{
{
return this->object->get_model()->get_material(m_material_id);
}
@ -2362,8 +2376,10 @@ void ModelVolume::center_geometry_after_creation(bool update_source_offset)
Vec3d shift = this->mesh().bounding_box().center();
if (!shift.isApprox(Vec3d::Zero()))
{
if (m_mesh)
const_cast<TriangleMesh*>(m_mesh.get())->translate(-(float)shift(0), -(float)shift(1), -(float)shift(2));
if (m_mesh) {
const_cast<TriangleMesh*>(m_mesh.get())->translate(-(float)shift(0), -(float)shift(1), -(float)shift(2));
const_cast<TriangleMesh*>(m_mesh.get())->set_init_shift(shift);
}
if (m_convex_hull)
const_cast<TriangleMesh*>(m_convex_hull.get())->translate(-(float)shift(0), -(float)shift(1), -(float)shift(2));
translate(shift);
@ -2803,7 +2819,7 @@ double Model::getThermalLength(const std::vector<ModelVolume*> modelVolumePtrs)
}
return thermalLength;
}
// max printing speed, difference in bed temperature and envirument temperature and bed adhension coefficients are considered
// max printing speed, difference in bed temperature and envirument temperature and bed adhension coefficients are considered
double ModelInstance::get_auto_brim_width(double deltaT, double adhension) const
{
BoundingBoxf3 raw_bbox = object->raw_mesh_bounding_box();
@ -2896,7 +2912,7 @@ double ModelInstance::get_auto_brim_width() const
void ModelInstance::get_arrange_polygon(void* ap) const
{
// static const double SIMPLIFY_TOLERANCE_MM = 0.1;
Vec3d rotation = get_rotation();
rotation.z() = 0.;
Transform3d trafo_instance =
@ -2909,7 +2925,7 @@ void ModelInstance::get_arrange_polygon(void* ap) const
// pp = p.simplify(scaled<double>(SIMPLIFY_TOLERANCE_MM));
// if (!pp.empty()) p = pp.front();
// }
arrangement::ArrangePolygon& ret = *(arrangement::ArrangePolygon*)ap;
ret.poly.contour = std::move(p);
ret.translation = Vec2crd{scaled(get_offset(X)), scaled(get_offset(Y))};
@ -3039,6 +3055,12 @@ void FacetsAnnotation::set_triangle_from_string(int triangle_id, const std::stri
}
}
bool FacetsAnnotation::equals(const FacetsAnnotation &other) const
{
const std::pair<std::vector<std::pair<int, int>>, std::vector<bool>>& data = other.get_data();
return (m_data == data);
}
// Test whether the two models contain the same number of ModelObjects with the same set of IDs
// ordered in the same order. In that case it is not necessary to kill the background processing.
bool model_object_list_equal(const Model &model_old, const Model &model_new)
@ -3140,22 +3162,22 @@ bool model_property_changed(const ModelObject &model_object_old, const ModelObje
bool model_custom_supports_data_changed(const ModelObject& mo, const ModelObject& mo_new)
{
return model_property_changed(mo, mo_new,
[](const ModelVolumeType t) { return t == ModelVolumeType::MODEL_PART; },
return model_property_changed(mo, mo_new,
[](const ModelVolumeType t) { return t == ModelVolumeType::MODEL_PART; },
[](const ModelVolume &mv_old, const ModelVolume &mv_new){ return mv_old.supported_facets.timestamp_matches(mv_new.supported_facets); });
}
bool model_custom_seam_data_changed(const ModelObject& mo, const ModelObject& mo_new)
{
return model_property_changed(mo, mo_new,
[](const ModelVolumeType t) { return t == ModelVolumeType::MODEL_PART; },
return model_property_changed(mo, mo_new,
[](const ModelVolumeType t) { return t == ModelVolumeType::MODEL_PART; },
[](const ModelVolume &mv_old, const ModelVolume &mv_new){ return mv_old.seam_facets.timestamp_matches(mv_new.seam_facets); });
}
bool model_mmu_segmentation_data_changed(const ModelObject& mo, const ModelObject& mo_new)
{
return model_property_changed(mo, mo_new,
[](const ModelVolumeType t) { return t == ModelVolumeType::MODEL_PART; },
return model_property_changed(mo, mo_new,
[](const ModelVolumeType t) { return t == ModelVolumeType::MODEL_PART; },
[](const ModelVolume &mv_old, const ModelVolume &mv_new){ return mv_old.mmu_segmentation_facets.timestamp_matches(mv_new.mmu_segmentation_facets); });
}
@ -3189,7 +3211,7 @@ bool model_has_advanced_features(const Model &model)
void check_model_ids_validity(const Model &model)
{
std::set<ObjectID> ids;
auto check = [&ids](ObjectID id) {
auto check = [&ids](ObjectID id) {
assert(id.valid());
assert(ids.find(id) == ids.end());
ids.insert(id);