Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbubnikv <bubnikv@gmail.com>2017-06-15 16:38:15 +0300
committerbubnikv <bubnikv@gmail.com>2017-06-15 16:38:15 +0300
commitb724d789fd6769fdf868a987ca5573bb0bf23eaa (patch)
tree19fc1d26c73a20534a5903ba6745d228903e13d4
parenta1f640346366ad005fed975ffde27dcbf5223632 (diff)
New feature: Splitting an object into a multi-part volume.
-rw-r--r--lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm30
-rw-r--r--xs/src/libslic3r/Model.cpp30
-rw-r--r--xs/src/libslic3r/Model.hpp7
-rw-r--r--xs/src/libslic3r/TriangleMesh.cpp46
-rw-r--r--xs/src/libslic3r/TriangleMesh.hpp4
-rw-r--r--xs/xsp/Model.xsp2
6 files changed, 92 insertions, 27 deletions
diff --git a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm
index f4f610d6a..a362f7ad1 100644
--- a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm
+++ b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm
@@ -56,13 +56,15 @@ sub new {
$self->{btn_load_modifier} = Wx::Button->new($self, -1, "Load modifier…", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
$self->{btn_load_lambda_modifier} = Wx::Button->new($self, -1, "Load generic…", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
$self->{btn_delete} = Wx::Button->new($self, -1, "Delete part", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
- $self->{btn_move_up} = Wx::Button->new($self, -1, $Slic3r::GUI::have_button_icons ? "" : "Up", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
- $self->{btn_move_down} = Wx::Button->new($self, -1, $Slic3r::GUI::have_button_icons ? "" : "Down", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
+ $self->{btn_split} = Wx::Button->new($self, -1, "Split part", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
+ $self->{btn_move_up} = Wx::Button->new($self, -1, $Slic3r::GUI::have_button_icons ? "" : "Up", wxDefaultPosition, [40, -1], wxBU_LEFT);
+ $self->{btn_move_down} = Wx::Button->new($self, -1, $Slic3r::GUI::have_button_icons ? "" : "Down", wxDefaultPosition, [40, -1], wxBU_LEFT);
if ($Slic3r::GUI::have_button_icons) {
$self->{btn_load_part}->SetBitmap(Wx::Bitmap->new($Slic3r::var->("brick_add.png"), wxBITMAP_TYPE_PNG));
$self->{btn_load_modifier}->SetBitmap(Wx::Bitmap->new($Slic3r::var->("brick_add.png"), wxBITMAP_TYPE_PNG));
$self->{btn_load_lambda_modifier}->SetBitmap(Wx::Bitmap->new($Slic3r::var->("brick_add.png"), wxBITMAP_TYPE_PNG));
$self->{btn_delete}->SetBitmap(Wx::Bitmap->new($Slic3r::var->("brick_delete.png"), wxBITMAP_TYPE_PNG));
+ $self->{btn_split}->SetBitmap(Wx::Bitmap->new($Slic3r::var->("shape_ungroup.png"), wxBITMAP_TYPE_PNG));
$self->{btn_move_up}->SetBitmap(Wx::Bitmap->new($Slic3r::var->("bullet_arrow_up.png"), wxBITMAP_TYPE_PNG));
$self->{btn_move_down}->SetBitmap(Wx::Bitmap->new($Slic3r::var->("bullet_arrow_down.png"), wxBITMAP_TYPE_PNG));
}
@@ -73,12 +75,18 @@ sub new {
$buttons_sizer->Add($self->{btn_load_modifier}, 0, wxEXPAND | wxBOTTOM | wxRIGHT, 5);
$buttons_sizer->Add($self->{btn_load_lambda_modifier}, 0, wxEXPAND | wxBOTTOM, 5);
$buttons_sizer->Add($self->{btn_delete}, 0, wxEXPAND | wxRIGHT, 5);
- $buttons_sizer->Add($self->{btn_move_up}, 0, wxEXPAND | wxRIGHT, 5);
- $buttons_sizer->Add($self->{btn_move_down}, 0, wxEXPAND, 5);
+ $buttons_sizer->Add($self->{btn_split}, 0, wxEXPAND | wxRIGHT, 5);
+ {
+ my $up_down_sizer = Wx::GridSizer->new(1, 2);
+ $up_down_sizer->Add($self->{btn_move_up}, 0, wxEXPAND | wxRIGHT, 5);
+ $up_down_sizer->Add($self->{btn_move_down}, 0, wxEXPAND, 5);
+ $buttons_sizer->Add($up_down_sizer, 0, wxEXPAND, 5);
+ }
$self->{btn_load_part}->SetFont($Slic3r::GUI::small_font);
$self->{btn_load_modifier}->SetFont($Slic3r::GUI::small_font);
$self->{btn_load_lambda_modifier}->SetFont($Slic3r::GUI::small_font);
$self->{btn_delete}->SetFont($Slic3r::GUI::small_font);
+ $self->{btn_split}->SetFont($Slic3r::GUI::small_font);
$self->{btn_move_up}->SetFont($Slic3r::GUI::small_font);
$self->{btn_move_down}->SetFont($Slic3r::GUI::small_font);
@@ -182,6 +190,7 @@ sub new {
EVT_BUTTON($self, $self->{btn_load_modifier}, sub { $self->on_btn_load(1) });
EVT_BUTTON($self, $self->{btn_load_lambda_modifier}, sub { $self->on_btn_lambda(1) });
EVT_BUTTON($self, $self->{btn_delete}, \&on_btn_delete);
+ EVT_BUTTON($self, $self->{btn_split}, \&on_btn_split);
EVT_BUTTON($self, $self->{btn_move_up}, \&on_btn_move_up);
EVT_BUTTON($self, $self->{btn_move_down}, \&on_btn_move_down);
@@ -279,6 +288,7 @@ sub selection_changed {
$self->{canvas}->volumes->[ $itemData->{volume_id} ]->set_selected(1);
}
$self->{btn_delete}->Enable;
+ $self->{btn_split}->Enable;
$self->{btn_move_up}->Enable if $itemData->{volume_id} > 0;
$self->{btn_move_down}->Enable if $itemData->{volume_id} + 1 < $self->{model_object}->volumes_count;
@@ -449,6 +459,18 @@ sub on_btn_delete {
$self->_parts_changed;
}
+sub on_btn_split {
+ my ($self) = @_;
+
+ my $itemData = $self->get_selection;
+ if ($itemData && $itemData->{type} eq 'volume') {
+ my $volume = $self->{model_object}->volumes->[$itemData->{volume_id}];
+ $self->{parts_changed} = 1 if $volume->split > 1;
+ }
+
+ $self->_parts_changed;
+}
+
sub _parts_changed {
my ($self) = @_;
diff --git a/xs/src/libslic3r/Model.cpp b/xs/src/libslic3r/Model.cpp
index 29a3786fd..6714966e7 100644
--- a/xs/src/libslic3r/Model.cpp
+++ b/xs/src/libslic3r/Model.cpp
@@ -685,6 +685,36 @@ ModelMaterial* ModelVolume::assign_unique_material()
return model->add_material(this->_material_id);
}
+// Split this volume, append the result to the object owning this volume.
+// Return the number of volumes created from this one.
+// This is useful to assign different materials to different volumes of an object.
+size_t ModelVolume::split()
+{
+ TriangleMeshPtrs meshptrs = this->mesh.split();
+ if (meshptrs.size() <= 1) {
+ delete meshptrs.front();
+ return 1;
+ }
+
+ size_t idx = 0;
+ size_t ivolume = std::find(this->object->volumes.begin(), this->object->volumes.end(), this) - this->object->volumes.begin();
+ std::string name = this->name;
+ for (TriangleMesh *mesh : meshptrs) {
+ mesh->repair();
+ if (idx == 0)
+ this->mesh = std::move(*mesh);
+ else
+ this->object->volumes.insert(this->object->volumes.begin() + (++ ivolume), new ModelVolume(object, *this, std::move(*mesh)));
+ char str_idx[64];
+ sprintf(str_idx, "_%d", idx + 1);
+ this->object->volumes[ivolume]->name = name + str_idx;
+ delete mesh;
+ ++ idx;
+ }
+
+ return idx;
+}
+
void ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) const
{
mesh->rotate_z(this->rotation); // rotate around mesh origin
diff --git a/xs/src/libslic3r/Model.hpp b/xs/src/libslic3r/Model.hpp
index 3ab717a6f..5f3b0eb01 100644
--- a/xs/src/libslic3r/Model.hpp
+++ b/xs/src/libslic3r/Model.hpp
@@ -161,6 +161,10 @@ public:
void material_id(t_model_material_id material_id);
ModelMaterial* material() const;
void set_material(t_model_material_id material_id, const ModelMaterial &material);
+ // Split this volume, append the result to the object owning this volume.
+ // Return the number of volumes created from this one.
+ // This is useful to assign different materials to different volumes of an object.
+ size_t split();
ModelMaterial* assign_unique_material();
@@ -174,6 +178,9 @@ private:
ModelVolume(ModelObject *object, const ModelVolume &other) :
name(other.name), mesh(other.mesh), config(other.config), modifier(other.modifier), object(object)
{ this->material_id(other.material_id()); }
+ ModelVolume(ModelObject *object, const ModelVolume &other, const TriangleMesh &&mesh) :
+ name(other.name), mesh(std::move(mesh)), config(other.config), modifier(other.modifier), object(object)
+ { this->material_id(other.material_id()); }
};
// A single instance of a ModelObject.
diff --git a/xs/src/libslic3r/TriangleMesh.cpp b/xs/src/libslic3r/TriangleMesh.cpp
index 7e16944d8..ee1dc7315 100644
--- a/xs/src/libslic3r/TriangleMesh.cpp
+++ b/xs/src/libslic3r/TriangleMesh.cpp
@@ -78,40 +78,44 @@ TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector<Point3>& fa
stl_get_size(&stl);
}
-TriangleMesh::TriangleMesh(const TriangleMesh &other)
- : stl(other.stl), repaired(other.repaired)
+TriangleMesh::TriangleMesh(const TriangleMesh &other) :
+ repaired(false)
+{
+ stl_initialize(&this->stl);
+ *this = other;
+}
+
+TriangleMesh::TriangleMesh(TriangleMesh &&other) :
+ repaired(false)
{
- this->stl.heads = NULL;
- this->stl.tail = NULL;
+ stl_initialize(&this->stl);
+ this->swap(other);
+}
+
+TriangleMesh& TriangleMesh::operator=(const TriangleMesh &other)
+{
+ stl_close(&this->stl);
+ this->stl = other.stl;
+ this->repaired = other.repaired;
+ this->stl.heads = nullptr;
+ this->stl.tail = nullptr;
this->stl.error = other.stl.error;
- if (other.stl.facet_start != NULL) {
+ if (other.stl.facet_start != nullptr) {
this->stl.facet_start = (stl_facet*)calloc(other.stl.stats.number_of_facets, sizeof(stl_facet));
std::copy(other.stl.facet_start, other.stl.facet_start + other.stl.stats.number_of_facets, this->stl.facet_start);
}
- if (other.stl.neighbors_start != NULL) {
+ if (other.stl.neighbors_start != nullptr) {
this->stl.neighbors_start = (stl_neighbors*)calloc(other.stl.stats.number_of_facets, sizeof(stl_neighbors));
std::copy(other.stl.neighbors_start, other.stl.neighbors_start + other.stl.stats.number_of_facets, this->stl.neighbors_start);
}
- if (other.stl.v_indices != NULL) {
+ if (other.stl.v_indices != nullptr) {
this->stl.v_indices = (v_indices_struct*)calloc(other.stl.stats.number_of_facets, sizeof(v_indices_struct));
std::copy(other.stl.v_indices, other.stl.v_indices + other.stl.stats.number_of_facets, this->stl.v_indices);
}
- if (other.stl.v_shared != NULL) {
+ if (other.stl.v_shared != nullptr) {
this->stl.v_shared = (stl_vertex*)calloc(other.stl.stats.shared_vertices, sizeof(stl_vertex));
std::copy(other.stl.v_shared, other.stl.v_shared + other.stl.stats.shared_vertices, this->stl.v_shared);
}
-}
-
-TriangleMesh::TriangleMesh(TriangleMesh &&other) :
- repaired(false)
-{
- stl_initialize(&this->stl);
- this->swap(other);
-}
-
-TriangleMesh& TriangleMesh::operator= (TriangleMesh other)
-{
- this->swap(other);
return *this;
}
@@ -427,7 +431,7 @@ TriangleMesh::split() const
if (!this->repaired) CONFESS("split() requires repair()");
// loop while we have remaining facets
- while (1) {
+ for (;;) {
// get the first facet
std::queue<int> facet_queue;
std::deque<int> facets;
diff --git a/xs/src/libslic3r/TriangleMesh.hpp b/xs/src/libslic3r/TriangleMesh.hpp
index 907b1f7e9..8072059cf 100644
--- a/xs/src/libslic3r/TriangleMesh.hpp
+++ b/xs/src/libslic3r/TriangleMesh.hpp
@@ -24,8 +24,8 @@ public:
TriangleMesh(const Pointf3s &points, const std::vector<Point3> &facets);
TriangleMesh(const TriangleMesh &other);
TriangleMesh(TriangleMesh &&other);
- TriangleMesh& operator= (TriangleMesh other);
- TriangleMesh& operator= (TriangleMesh &&other);
+ TriangleMesh& operator=(const TriangleMesh &other);
+ TriangleMesh& operator=(TriangleMesh &&other);
void swap(TriangleMesh &other);
~TriangleMesh();
void ReadSTLFile(const char* input_file);
diff --git a/xs/xsp/Model.xsp b/xs/xsp/Model.xsp
index c38b45ed8..855d40d32 100644
--- a/xs/xsp/Model.xsp
+++ b/xs/xsp/Model.xsp
@@ -297,6 +297,8 @@ ModelMaterial::attributes()
%code%{ RETVAL = THIS->modifier; %};
void set_modifier(bool modifier)
%code%{ THIS->modifier = modifier; %};
+
+ size_t split();
ModelMaterial* assign_unique_material();
};