Merge remote-tracking branch 'remotes/origin/vb_modelbase_id_refactor' into dev_native
This commit is contained in:
commit
0870f81425
13 changed files with 449 additions and 212 deletions
src/libslic3r
|
@ -21,26 +21,58 @@ namespace Slic3r {
|
|||
|
||||
unsigned int Model::s_auto_extruder_id = 1;
|
||||
|
||||
ModelID ModelBase::s_last_id = 0;
|
||||
size_t ModelBase::s_last_id = 0;
|
||||
|
||||
Model::Model(const Model &rhs)
|
||||
Model& Model::assign_copy(const Model &rhs)
|
||||
{
|
||||
*this = rhs;
|
||||
this->copy_id(rhs);
|
||||
// copy materials
|
||||
this->clear_materials();
|
||||
this->materials = rhs.materials;
|
||||
for (std::pair<const t_model_material_id, ModelMaterial*> &m : this->materials) {
|
||||
// Copy including the ID and m_model.
|
||||
m.second = new ModelMaterial(*m.second);
|
||||
m.second->set_model(this);
|
||||
}
|
||||
// copy objects
|
||||
this->clear_objects();
|
||||
this->objects.reserve(rhs.objects.size());
|
||||
for (const ModelObject *model_object : rhs.objects) {
|
||||
// Copy including the ID, leave ID set to invalid (zero).
|
||||
auto mo = ModelObject::new_copy(*model_object);
|
||||
mo->set_model(this);
|
||||
this->objects.emplace_back(mo);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Model& Model::operator=(const Model &rhs)
|
||||
Model& Model::assign_copy(Model &&rhs)
|
||||
{
|
||||
m_id = rhs.m_id;
|
||||
// copy materials
|
||||
for (const auto &m : rhs.materials)
|
||||
this->add_material(m.first, *m.second);
|
||||
// copy objects
|
||||
this->objects.reserve(rhs.objects.size());
|
||||
for (const ModelObject *o : rhs.objects)
|
||||
this->add_object(*o, true);
|
||||
this->copy_id(rhs);
|
||||
// Move materials, adjust the parent pointer.
|
||||
this->clear_materials();
|
||||
this->materials = std::move(rhs.materials);
|
||||
for (std::pair<const t_model_material_id, ModelMaterial*> &m : this->materials)
|
||||
m.second->set_model(this);
|
||||
rhs.materials.clear();
|
||||
// Move objects, adjust the parent pointer.
|
||||
this->clear_objects();
|
||||
this->objects = std::move(rhs.objects);
|
||||
for (ModelObject *model_object : this->objects)
|
||||
model_object->set_model(this);
|
||||
rhs.objects.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Model::assign_new_unique_ids_recursive()
|
||||
{
|
||||
this->set_new_unique_id();
|
||||
for (std::pair<const t_model_material_id, ModelMaterial*> &m : this->materials)
|
||||
m.second->assign_new_unique_ids_recursive();
|
||||
for (ModelObject *model_object : this->objects)
|
||||
model_object->assign_new_unique_ids_recursive();
|
||||
}
|
||||
|
||||
Model Model::read_from_file(const std::string &input_file, DynamicPrintConfig *config, bool add_default_instances)
|
||||
{
|
||||
Model model;
|
||||
|
@ -150,9 +182,10 @@ ModelObject* Model::add_object(const char *name, const char *path, TriangleMesh
|
|||
return new_object;
|
||||
}
|
||||
|
||||
ModelObject* Model::add_object(const ModelObject &other, bool copy_volumes)
|
||||
ModelObject* Model::add_object(const ModelObject &other)
|
||||
{
|
||||
ModelObject* new_object = new ModelObject(this, other, copy_volumes);
|
||||
ModelObject* new_object = ModelObject::new_clone(other);
|
||||
new_object->set_model(this);
|
||||
this->objects.push_back(new_object);
|
||||
return new_object;
|
||||
}
|
||||
|
@ -164,21 +197,36 @@ void Model::delete_object(size_t idx)
|
|||
this->objects.erase(i);
|
||||
}
|
||||
|
||||
void Model::delete_object(ModelObject* object)
|
||||
bool Model::delete_object(ModelObject* object)
|
||||
{
|
||||
if (object == nullptr)
|
||||
return;
|
||||
|
||||
for (ModelObjectPtrs::iterator it = objects.begin(); it != objects.end(); ++it)
|
||||
{
|
||||
ModelObject* obj = *it;
|
||||
if (obj == object)
|
||||
{
|
||||
delete obj;
|
||||
objects.erase(it);
|
||||
return;
|
||||
if (object != nullptr) {
|
||||
size_t idx = 0;
|
||||
for (ModelObject *model_object : objects) {
|
||||
if (model_object == object) {
|
||||
delete model_object;
|
||||
objects.erase(objects.begin() + idx);
|
||||
return true;
|
||||
}
|
||||
++ idx;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Model::delete_object(ModelID id)
|
||||
{
|
||||
if (id.id != 0) {
|
||||
size_t idx = 0;
|
||||
for (ModelObject *model_object : objects) {
|
||||
if (model_object->id() == id) {
|
||||
delete model_object;
|
||||
objects.erase(objects.begin() + idx);
|
||||
return true;
|
||||
}
|
||||
++ idx;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Model::clear_objects()
|
||||
|
@ -218,7 +266,8 @@ ModelMaterial* Model::add_material(t_model_material_id material_id, const ModelM
|
|||
ModelMaterial* material = this->get_material(material_id);
|
||||
delete material;
|
||||
// set new material
|
||||
material = new ModelMaterial(this, other);
|
||||
material = new ModelMaterial(other);
|
||||
material->set_model(this);
|
||||
this->materials[material_id] = material;
|
||||
return material;
|
||||
}
|
||||
|
@ -421,6 +470,7 @@ void Model::convert_multipart_object(unsigned int max_extruders)
|
|||
ModelObject* object = new ModelObject(this);
|
||||
object->input_file = this->objects.front()->input_file;
|
||||
object->name = this->objects.front()->name;
|
||||
//FIXME copy the config etc?
|
||||
|
||||
reset_auto_extruder_id();
|
||||
|
||||
|
@ -483,53 +533,90 @@ void Model::reset_auto_extruder_id()
|
|||
s_auto_extruder_id = 1;
|
||||
}
|
||||
|
||||
ModelObject::ModelObject(Model *model, const ModelObject &rhs, bool copy_volumes) :
|
||||
m_model(model)
|
||||
{
|
||||
this->assign(&rhs, copy_volumes);
|
||||
}
|
||||
|
||||
ModelObject::~ModelObject()
|
||||
{
|
||||
this->clear_volumes();
|
||||
this->clear_instances();
|
||||
}
|
||||
|
||||
// Clone this ModelObject including its volumes and instances, keep the IDs of the copies equal to the original.
|
||||
// Called by Print::apply() to clone the Model / ModelObject hierarchy to the back end for background processing.
|
||||
ModelObject* ModelObject::clone(Model *parent)
|
||||
// maintains the m_model pointer
|
||||
ModelObject& ModelObject::assign_copy(const ModelObject &rhs)
|
||||
{
|
||||
return new ModelObject(parent, *this, true);
|
||||
}
|
||||
this->copy_id(rhs);
|
||||
|
||||
ModelObject& ModelObject::assign(const ModelObject *rhs, bool copy_volumes)
|
||||
{
|
||||
m_id = rhs->m_id;
|
||||
name = rhs->name;
|
||||
input_file = rhs->input_file;
|
||||
config = rhs->config;
|
||||
sla_support_points = rhs->sla_support_points;
|
||||
layer_height_ranges = rhs->layer_height_ranges;
|
||||
layer_height_profile = rhs->layer_height_profile;
|
||||
layer_height_profile_valid = rhs->layer_height_profile_valid;
|
||||
origin_translation = rhs->origin_translation;
|
||||
m_bounding_box = rhs->m_bounding_box;
|
||||
m_bounding_box_valid = rhs->m_bounding_box_valid;
|
||||
this->name = rhs.name;
|
||||
this->input_file = rhs.input_file;
|
||||
this->config = rhs.config;
|
||||
this->sla_support_points = rhs.sla_support_points;
|
||||
this->layer_height_ranges = rhs.layer_height_ranges;
|
||||
this->layer_height_profile = rhs.layer_height_profile;
|
||||
this->layer_height_profile_valid = rhs.layer_height_profile_valid;
|
||||
this->origin_translation = rhs.origin_translation;
|
||||
m_bounding_box = rhs.m_bounding_box;
|
||||
m_bounding_box_valid = rhs.m_bounding_box_valid;
|
||||
|
||||
volumes.clear();
|
||||
instances.clear();
|
||||
if (copy_volumes) {
|
||||
this->volumes.reserve(rhs->volumes.size());
|
||||
for (ModelVolume *model_volume : rhs->volumes)
|
||||
this->add_volume(*model_volume);
|
||||
this->instances.reserve(rhs->instances.size());
|
||||
for (const ModelInstance *model_instance : rhs->instances)
|
||||
this->add_instance(*model_instance);
|
||||
this->clear_volumes();
|
||||
this->volumes.reserve(rhs.volumes.size());
|
||||
for (ModelVolume *model_volume : rhs.volumes) {
|
||||
this->volumes.emplace_back(new ModelVolume(*model_volume));
|
||||
this->volumes.back()->set_model_object(this);
|
||||
}
|
||||
this->clear_instances();
|
||||
this->instances.reserve(rhs.instances.size());
|
||||
for (const ModelInstance *model_instance : rhs.instances) {
|
||||
this->instances.emplace_back(new ModelInstance(*model_instance));
|
||||
this->instances.back()->set_model_object(this);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// maintains the m_model pointer
|
||||
ModelObject& ModelObject::assign_copy(ModelObject &&rhs)
|
||||
{
|
||||
this->copy_id(rhs);
|
||||
|
||||
this->name = std::move(rhs.name);
|
||||
this->input_file = std::move(rhs.input_file);
|
||||
this->config = std::move(rhs.config);
|
||||
this->sla_support_points = std::move(rhs.sla_support_points);
|
||||
this->layer_height_ranges = std::move(rhs.layer_height_ranges);
|
||||
this->layer_height_profile = std::move(rhs.layer_height_profile);
|
||||
this->layer_height_profile_valid = std::move(rhs.layer_height_profile_valid);
|
||||
this->origin_translation = std::move(rhs.origin_translation);
|
||||
m_bounding_box = std::move(rhs.m_bounding_box);
|
||||
m_bounding_box_valid = std::move(rhs.m_bounding_box_valid);
|
||||
|
||||
this->clear_volumes();
|
||||
this->volumes = std::move(rhs.volumes);
|
||||
rhs.volumes.clear();
|
||||
for (ModelVolume *model_volume : this->volumes)
|
||||
model_volume->set_model_object(this);
|
||||
this->clear_instances();
|
||||
this->instances = std::move(rhs.instances);
|
||||
rhs.instances.clear();
|
||||
for (ModelInstance *model_instance : this->instances)
|
||||
model_instance->set_model_object(this);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ModelObject::assign_new_unique_ids_recursive()
|
||||
{
|
||||
this->set_new_unique_id();
|
||||
for (ModelVolume *model_volume : this->volumes)
|
||||
model_volume->assign_new_unique_ids_recursive();
|
||||
for (ModelInstance *model_instance : this->instances)
|
||||
model_instance->assign_new_unique_ids_recursive();
|
||||
}
|
||||
|
||||
// Clone this ModelObject including its volumes and instances, keep the IDs of the copies equal to the original.
|
||||
// Called by Print::apply() to clone the Model / ModelObject hierarchy to the back end for background processing.
|
||||
//ModelObject* ModelObject::clone(Model *parent)
|
||||
//{
|
||||
// return new ModelObject(parent, *this, true);
|
||||
//}
|
||||
|
||||
ModelVolume* ModelObject::add_volume(const TriangleMesh &mesh)
|
||||
{
|
||||
ModelVolume* v = new ModelVolume(this, mesh);
|
||||
|
@ -554,6 +641,14 @@ ModelVolume* ModelObject::add_volume(const ModelVolume &other)
|
|||
return v;
|
||||
}
|
||||
|
||||
ModelVolume* ModelObject::add_volume(const ModelVolume &other, TriangleMesh &&mesh)
|
||||
{
|
||||
ModelVolume* v = new ModelVolume(this, other, std::move(mesh));
|
||||
this->volumes.push_back(v);
|
||||
this->invalidate_bounding_box();
|
||||
return v;
|
||||
}
|
||||
|
||||
void ModelObject::delete_volume(size_t idx)
|
||||
{
|
||||
ModelVolumePtrs::iterator i = this->volumes.begin() + idx;
|
||||
|
@ -882,7 +977,7 @@ void ModelObject::split(ModelObjectPtrs* new_objects)
|
|||
if (this->volumes.size() > 1) {
|
||||
// We can't split meshes if there's more than one volume, because
|
||||
// we can't group the resulting meshes by object afterwards
|
||||
new_objects->push_back(this);
|
||||
new_objects->emplace_back(this);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -894,16 +989,14 @@ void ModelObject::split(ModelObjectPtrs* new_objects)
|
|||
|
||||
mesh->repair();
|
||||
|
||||
ModelObject* new_object = m_model->add_object(*this, false);
|
||||
new_object->sla_support_points.clear();
|
||||
new_object->input_file = "";
|
||||
ModelVolume* new_volume = new_object->add_volume(*mesh);
|
||||
new_volume->name = volume->name;
|
||||
new_volume->config = volume->config;
|
||||
new_volume->set_type(volume->type());
|
||||
new_volume->set_material_id(volume->material_id());
|
||||
|
||||
new_objects->push_back(new_object);
|
||||
ModelObject* new_object = m_model->add_object();
|
||||
new_object->name = this->name;
|
||||
new_object->config = this->config;
|
||||
new_object->instances.reserve(this->instances.size());
|
||||
for (const ModelInstance *model_instance : this->instances)
|
||||
new_object->add_instance(*model_instance);
|
||||
new_object->add_volume(*volume, std::move(*mesh));
|
||||
new_objects->emplace_back(new_object);
|
||||
delete mesh;
|
||||
}
|
||||
|
||||
|
@ -1037,9 +1130,8 @@ void ModelObject::print_info() const
|
|||
void ModelVolume::set_material_id(t_model_material_id material_id)
|
||||
{
|
||||
m_material_id = material_id;
|
||||
|
||||
// ensure m_material_id references an existing material
|
||||
(void)this->object->get_model()->add_material(material_id);
|
||||
this->object->get_model()->add_material(material_id);
|
||||
}
|
||||
|
||||
ModelMaterial* ModelVolume::material() const
|
||||
|
@ -1050,13 +1142,12 @@ ModelMaterial* ModelVolume::material() const
|
|||
void ModelVolume::set_material(t_model_material_id material_id, const ModelMaterial &material)
|
||||
{
|
||||
m_material_id = material_id;
|
||||
(void)this->object->get_model()->add_material(material_id, material);
|
||||
this->object->get_model()->add_material(material_id, material);
|
||||
}
|
||||
|
||||
ModelMaterial* ModelVolume::assign_unique_material()
|
||||
{
|
||||
Model* model = this->get_object()->get_model();
|
||||
|
||||
// as material-id "0" is reserved by the AMF spec we start from 1
|
||||
m_material_id = 1 + model->materials.size(); // watchout for implicit cast
|
||||
return model->add_material(m_material_id);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue