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:
authorLukas Matena <lukasmatena@seznam.cz>2018-08-16 09:56:18 +0300
committerLukas Matena <lukasmatena@seznam.cz>2018-08-16 09:56:18 +0300
commit3f72ca2a155618d3602b7cde879c053a805491d2 (patch)
tree9098b9290d866aeb53ab26433dcbe39e88e0a7f8
parent93ce0d23b75881e8fd7cf71df4ff3a885d54b6af (diff)
parent4d98d321996de6e6d036403c319b6ef044144dcd (diff)
Merge remote-tracking branch 'origin/convex_hull' into lm_lay_flat_round_merged_facets
-rw-r--r--lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm8
-rw-r--r--resources/profiles/PrusaResearch.idx1
-rw-r--r--resources/profiles/PrusaResearch.ini10
-rw-r--r--xs/src/libslic3r/Format/3mf.cpp1
-rw-r--r--xs/src/libslic3r/Format/AMF.cpp1
-rw-r--r--xs/src/libslic3r/GCodeTimeEstimator.cpp2
-rw-r--r--xs/src/libslic3r/Model.cpp140
-rw-r--r--xs/src/libslic3r/Model.hpp36
-rw-r--r--xs/src/libslic3r/TriangleMesh.cpp128
-rw-r--r--xs/src/libslic3r/TriangleMesh.hpp7
-rw-r--r--xs/src/libslic3r/libslic3r.h2
-rw-r--r--xs/src/slic3r/GUI/3DScene.cpp76
-rw-r--r--xs/src/slic3r/GUI/3DScene.hpp16
-rw-r--r--xs/src/slic3r/GUI/GLCanvas3D.cpp4
-rw-r--r--xs/src/slic3r/GUI/GLGizmo.cpp14
-rw-r--r--xs/src/slic3r/GUI/GLGizmo.hpp2
-rw-r--r--xs/xsp/GUI_3DScene.xsp1
17 files changed, 266 insertions, 183 deletions
diff --git a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm
index a20a241f7..783c1a9f5 100644
--- a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm
+++ b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm
@@ -157,7 +157,7 @@ sub new {
my ($volume_idx) = @_;
$self->reload_tree($volume_idx);
});
- Slic3r::GUI::_3DScene::load_model_object($canvas, $self->{model_object}, 0, [0]);
+ Slic3r::GUI::_3DScene::load_model_object($canvas, $self->{model_object}, 0, [0]);
Slic3r::GUI::_3DScene::set_auto_bed_shape($canvas);
Slic3r::GUI::_3DScene::set_axes_length($canvas, 2.0 * max(@{ Slic3r::GUI::_3DScene::get_volumes_bounding_box($canvas)->size }));
$canvas->SetSize([500,700]);
@@ -377,7 +377,8 @@ sub on_btn_load {
}
}
}
-
+
+ $self->{model_object}->center_around_origin if $self->{parts_changed};
$self->_parts_changed;
}
@@ -479,7 +480,8 @@ sub on_btn_delete {
$self->{model_object}->delete_volume($itemData->{volume_id});
$self->{parts_changed} = 1;
}
-
+
+ $self->{model_object}->center_around_origin if $self->{parts_changed};
$self->_parts_changed;
}
diff --git a/resources/profiles/PrusaResearch.idx b/resources/profiles/PrusaResearch.idx
index 21c2e518d..ba4123588 100644
--- a/resources/profiles/PrusaResearch.idx
+++ b/resources/profiles/PrusaResearch.idx
@@ -1,4 +1,5 @@
min_slic3r_version = 1.41.0-alpha
+0.2.0-beta Removed limit on the MK3MMU2 height, added legacy M204 S T format to the MK2 profiles
0.2.0-alpha8 Added filament_load/unload_time for the PLA/ABS MMU2 filament presets.
0.2.0-alpha7 Fixed the *MK3* references
0.2.0-alpha6
diff --git a/resources/profiles/PrusaResearch.ini b/resources/profiles/PrusaResearch.ini
index 496425e0d..32ec800e7 100644
--- a/resources/profiles/PrusaResearch.ini
+++ b/resources/profiles/PrusaResearch.ini
@@ -5,7 +5,7 @@
name = Prusa Research
# Configuration version of this file. Config file will only be installed, if the config_version differs.
# This means, the server may force the Slic3r configuration to be downgraded.
-config_version = 0.2.0-alpha8
+config_version = 0.2.0-beta
# Where to get the updates from?
config_update_url = https://raw.githubusercontent.com/prusa3d/Slic3r-settings/master/live/PrusaResearch/
@@ -563,6 +563,7 @@ filament_cooling_moves = 4
filament_cooling_initial_speed = 2.2
filament_cooling_final_speed = 3.4
filament_ramming_parameters = "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6"
+filament_minimal_purge_on_wipe_tower = 5
filament_cost = 0
filament_density = 0
filament_diameter = 1.75
@@ -1024,7 +1025,7 @@ retract_speed = 35
serial_port =
serial_speed = 250000
single_extruder_multi_material = 0
-start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0
+start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM83 ; extruder relative mode\nM204 S[machine_max_acceleration_extruding] T[machine_max_acceleration_retracting] ; MK2 firmware only supports the old M204 format\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0
toolchange_gcode =
use_firmware_retraction = 0
use_relative_e_distances = 1
@@ -1060,7 +1061,7 @@ printer_model = MK2SMM
inherits = *multimaterial*
end_gcode = G1 E-4 F2100.00000\nG91\nG1 Z1 F7200.000\nG90\nG1 X245 Y1\nG1 X240 E4\nG1 F4000\nG1 X190 E2.7 \nG1 F4600\nG1 X110 E2.8\nG1 F5200\nG1 X40 E3 \nG1 E-15.0000 F5000\nG1 E-50.0000 F5400\nG1 E-15.0000 F3000\nG1 E-12.0000 F2000\nG1 F1600\nG1 X0 Y1 E3.0000\nG1 X50 Y1 E-5.0000\nG1 F2000\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-3.0000\nG4 S0\nM107 ; turn off fan\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)}{endif} ; Move print head up\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nG28 X0 ; home X axis\nM84 ; disable motors\n\n
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK2\nPRINTER_HAS_BOWDEN
-start_gcode = M115 U3.1.0 ; tell printer latest fw version\n; Start G-Code sequence START\nT?\nM104 S[first_layer_temperature]\nM140 S[first_layer_bed_temperature]\nM109 S[first_layer_temperature]\nM190 S[first_layer_bed_temperature]\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\nG92 E0.0
+start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM204 S[machine_max_acceleration_extruding] T[machine_max_acceleration_retracting] ; MK2 firmware only supports the old M204 format\n; Start G-Code sequence START\nT?\nM104 S[first_layer_temperature]\nM140 S[first_layer_bed_temperature]\nM109 S[first_layer_temperature]\nM190 S[first_layer_bed_temperature]\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\nG92 E0.0
default_print_profile = 0.15mm OPTIMAL
[printer:*mm-multi*]
@@ -1069,7 +1070,7 @@ end_gcode = {if not has_wipe_tower}\n; Pull the filament into the cooling tubes.
extruder_colour = #FFAA55;#5182DB;#4ECDD3;#FB7259
nozzle_diameter = 0.4,0.4,0.4,0.4
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK2\nPRINTER_HAS_BOWDEN
-start_gcode = M115 U3.1.0 ; tell printer latest fw version\n; Start G-Code sequence START\nT[initial_tool]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100 ; set max feedrate\nM92 E140 ; E-steps per filament milimeter\n{if not has_single_extruder_multi_material_priming}\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\n{endif}\nG92 E0.0
+start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM204 S[machine_max_acceleration_extruding] T[machine_max_acceleration_retracting] ; MK2 firmware only supports the old M204 format\n; Start G-Code sequence START\nT[initial_tool]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100 ; set max feedrate\nM92 E140 ; E-steps per filament milimeter\n{if not has_single_extruder_multi_material_priming}\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\n{endif}\nG92 E0.0
variable_layer_height = 0
default_print_profile = 0.15mm OPTIMAL
@@ -1195,7 +1196,6 @@ default_print_profile = 0.15mm OPTIMAL 0.6 nozzle MK3
[printer:*mm2*]
inherits = Original Prusa i3 MK3
single_extruder_multi_material = 1
-max_print_height = 200
cooling_tube_length = 10
cooling_tube_retraction = 30
parking_pos_retraction = 85
diff --git a/xs/src/libslic3r/Format/3mf.cpp b/xs/src/libslic3r/Format/3mf.cpp
index dd3500eba..5de1d26c5 100644
--- a/xs/src/libslic3r/Format/3mf.cpp
+++ b/xs/src/libslic3r/Format/3mf.cpp
@@ -1491,6 +1491,7 @@ namespace Slic3r {
stl_get_size(&stl);
volume->mesh.repair();
+ volume->calculate_convex_hull();
// apply volume's name and config data
for (const Metadata& metadata : volume_data.metadata)
diff --git a/xs/src/libslic3r/Format/AMF.cpp b/xs/src/libslic3r/Format/AMF.cpp
index 600aa6cd9..886bbae97 100644
--- a/xs/src/libslic3r/Format/AMF.cpp
+++ b/xs/src/libslic3r/Format/AMF.cpp
@@ -406,6 +406,7 @@ void AMFParserContext::endElement(const char * /* name */)
}
stl_get_size(&stl);
m_volume->mesh.repair();
+ m_volume->calculate_convex_hull();
m_volume_facets.clear();
m_volume = nullptr;
break;
diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp
index b51692fc6..c4ffb572a 100644
--- a/xs/src/libslic3r/GCodeTimeEstimator.cpp
+++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp
@@ -721,6 +721,8 @@ namespace Slic3r {
}
_last_st_synchronized_block_id = _blocks.size() - 1;
+ // The additional time has been consumed (added to the total time), reset it to zero.
+ set_additional_time(0.);
}
void GCodeTimeEstimator::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line)
diff --git a/xs/src/libslic3r/Model.cpp b/xs/src/libslic3r/Model.cpp
index bceeea258..23d447748 100644
--- a/xs/src/libslic3r/Model.cpp
+++ b/xs/src/libslic3r/Model.cpp
@@ -17,6 +17,11 @@
#include "SVG.hpp"
#include <Eigen/Dense>
+static const float UNIT_MATRIX[] = { 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f };
+
namespace Slic3r {
unsigned int Model::s_auto_extruder_id = 1;
@@ -235,14 +240,6 @@ BoundingBoxf3 Model::bounding_box() const
return bb;
}
-BoundingBoxf3 Model::transformed_bounding_box() const
-{
- BoundingBoxf3 bb;
- for (const ModelObject* obj : this->objects)
- bb.merge(obj->tight_bounding_box(false));
- return bb;
-}
-
void Model::center_instances_around_point(const Pointf &point)
{
// BoundingBoxf3 bb = this->bounding_box();
@@ -623,54 +620,6 @@ const BoundingBoxf3& ModelObject::bounding_box() const
return m_bounding_box;
}
-BoundingBoxf3 ModelObject::tight_bounding_box(bool include_modifiers) const
-{
- BoundingBoxf3 bb;
-
- for (const ModelVolume* vol : this->volumes)
- {
- if (include_modifiers || !vol->modifier)
- {
- for (const ModelInstance* inst : this->instances)
- {
- double c = cos(inst->rotation);
- double s = sin(inst->rotation);
-
- for (int f = 0; f < vol->mesh.stl.stats.number_of_facets; ++f)
- {
- const stl_facet& facet = vol->mesh.stl.facet_start[f];
-
- for (int i = 0; i < 3; ++i)
- {
- // original point
- const stl_vertex& v = facet.vertex[i];
- Pointf3 p((double)v.x, (double)v.y, (double)v.z);
-
- // scale
- p.x *= inst->scaling_factor;
- p.y *= inst->scaling_factor;
- p.z *= inst->scaling_factor;
-
- // rotate Z
- double x = p.x;
- double y = p.y;
- p.x = c * x - s * y;
- p.y = s * x + c * y;
-
- // translate
- p.x += inst->offset.x;
- p.y += inst->offset.y;
-
- bb.merge(p);
- }
- }
- }
- }
- }
-
- return bb;
-}
-
// A mesh containing all transformed instances of this object.
TriangleMesh ModelObject::mesh() const
{
@@ -755,15 +704,22 @@ void ModelObject::center_around_origin()
void ModelObject::translate(coordf_t x, coordf_t y, coordf_t z)
{
for (ModelVolume *v : this->volumes)
+ {
v->mesh.translate(float(x), float(y), float(z));
- if (m_bounding_box_valid)
+ v->m_convex_hull.translate(float(x), float(y), float(z));
+ }
+
+ if (m_bounding_box_valid)
m_bounding_box.translate(x, y, z);
}
void ModelObject::scale(const Pointf3 &versor)
{
for (ModelVolume *v : this->volumes)
+ {
v->mesh.scale(versor);
+ v->m_convex_hull.scale(versor);
+ }
// reset origin translation since it doesn't make sense anymore
this->origin_translation = Pointf3(0,0,0);
this->invalidate_bounding_box();
@@ -771,21 +727,13 @@ void ModelObject::scale(const Pointf3 &versor)
void ModelObject::rotate(float angle, const Axis &axis)
{
- float min_z = FLT_MAX;
for (ModelVolume *v : this->volumes)
{
v->mesh.rotate(angle, axis);
- min_z = std::min(min_z, v->mesh.stl.stats.min.z);
+ v->m_convex_hull.rotate(angle, axis);
}
- if (min_z != 0.0f)
- {
- // translate the object so that its minimum z lays on the bed
- for (ModelVolume *v : this->volumes)
- {
- v->mesh.translate(0.0f, 0.0f, -min_z);
- }
- }
+ center_around_origin();
this->origin_translation = Pointf3(0, 0, 0);
this->invalidate_bounding_box();
@@ -799,6 +747,7 @@ void ModelObject::transform(const float* matrix3x4)
for (ModelVolume* v : volumes)
{
v->mesh.transform(matrix3x4);
+ v->m_convex_hull.transform(matrix3x4);
}
origin_translation = Pointf3(0.0, 0.0, 0.0);
@@ -808,8 +757,12 @@ void ModelObject::transform(const float* matrix3x4)
void ModelObject::mirror(const Axis &axis)
{
for (ModelVolume *v : this->volumes)
+ {
v->mesh.mirror(axis);
- this->origin_translation = Pointf3(0,0,0);
+ v->m_convex_hull.mirror(axis);
+ }
+
+ this->origin_translation = Pointf3(0, 0, 0);
this->invalidate_bounding_box();
}
@@ -913,45 +866,20 @@ void ModelObject::split(ModelObjectPtrs* new_objects)
void ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_volume)
{
- for (ModelVolume* vol : this->volumes)
+ for (const ModelVolume* vol : this->volumes)
{
if (!vol->modifier)
{
for (ModelInstance* inst : this->instances)
{
- BoundingBoxf3 bb;
-
- double c = cos(inst->rotation);
- double s = sin(inst->rotation);
+ std::vector<float> world_mat(UNIT_MATRIX, std::end(UNIT_MATRIX));
+ Eigen::Transform<float, 3, Eigen::Affine> m = Eigen::Transform<float, 3, Eigen::Affine>::Identity();
+ m.translate(Eigen::Vector3f((float)inst->offset.x, (float)inst->offset.y, 0.0f));
+ m.rotate(Eigen::AngleAxisf(inst->rotation, Eigen::Vector3f::UnitZ()));
+ m.scale(inst->scaling_factor);
+ ::memcpy((void*)world_mat.data(), (const void*)m.data(), 16 * sizeof(float));
- for (int f = 0; f < vol->mesh.stl.stats.number_of_facets; ++f)
- {
- const stl_facet& facet = vol->mesh.stl.facet_start[f];
-
- for (int i = 0; i < 3; ++i)
- {
- // original point
- const stl_vertex& v = facet.vertex[i];
- Pointf3 p((double)v.x, (double)v.y, (double)v.z);
-
- // scale
- p.x *= inst->scaling_factor;
- p.y *= inst->scaling_factor;
- p.z *= inst->scaling_factor;
-
- // rotate Z
- double x = p.x;
- double y = p.y;
- p.x = c * x - s * y;
- p.y = s * x + c * y;
-
- // translate
- p.x += inst->offset.x;
- p.y += inst->offset.y;
-
- bb.merge(p);
- }
- }
+ BoundingBoxf3 bb = vol->get_convex_hull().transformed_bounding_box(world_mat);
if (print_volume.contains(bb))
inst->print_volume_state = ModelInstance::PVS_Inside;
@@ -1034,6 +962,16 @@ ModelMaterial* ModelVolume::assign_unique_material()
return model->add_material(this->_material_id);
}
+void ModelVolume::calculate_convex_hull()
+{
+ m_convex_hull = mesh.convex_hull_3d();
+}
+
+const TriangleMesh& ModelVolume::get_convex_hull() const
+{
+ return m_convex_hull;
+}
+
// 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.
diff --git a/xs/src/libslic3r/Model.hpp b/xs/src/libslic3r/Model.hpp
index 4c650f0de..23af9fb1c 100644
--- a/xs/src/libslic3r/Model.hpp
+++ b/xs/src/libslic3r/Model.hpp
@@ -105,9 +105,6 @@ public:
// This bounding box is being cached.
const BoundingBoxf3& bounding_box() const;
void invalidate_bounding_box() { m_bounding_box_valid = false; }
- // Returns a snug bounding box of the transformed instances.
- // This bounding box is not being cached.
- BoundingBoxf3 tight_bounding_box(bool include_modifiers) const;
// A mesh containing all transformed instances of this object.
TriangleMesh mesh() const;
@@ -157,6 +154,10 @@ private:
class ModelVolume
{
friend class ModelObject;
+
+ // The convex hull of this model's mesh.
+ TriangleMesh m_convex_hull;
+
public:
std::string name;
// The triangular model.
@@ -180,19 +181,32 @@ public:
ModelMaterial* assign_unique_material();
+ void calculate_convex_hull();
+ const TriangleMesh& get_convex_hull() const;
+
private:
// Parent object owning this ModelVolume.
ModelObject* object;
t_model_material_id _material_id;
- ModelVolume(ModelObject *object, const TriangleMesh &mesh) : mesh(mesh), modifier(false), object(object) {}
- ModelVolume(ModelObject *object, TriangleMesh &&mesh) : mesh(std::move(mesh)), modifier(false), object(object) {}
- 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) :
+ ModelVolume(ModelObject *object, const TriangleMesh &mesh) : mesh(mesh), modifier(false), object(object)
+ {
+ if (mesh.stl.stats.number_of_facets > 1)
+ calculate_convex_hull();
+ }
+ ModelVolume(ModelObject *object, TriangleMesh &&mesh, TriangleMesh &&convex_hull) : mesh(std::move(mesh)), m_convex_hull(std::move(convex_hull)), modifier(false), object(object) {}
+ ModelVolume(ModelObject *object, const ModelVolume &other) :
+ name(other.name), mesh(other.mesh), m_convex_hull(other.m_convex_hull), 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()); }
+ {
+ this->material_id(other.material_id());
+ if (mesh.stl.stats.number_of_facets > 1)
+ calculate_convex_hull();
+ }
};
// A single instance of a ModelObject.
@@ -285,8 +299,6 @@ public:
bool add_default_instances();
// Returns approximate axis aligned bounding box of this model
BoundingBoxf3 bounding_box() const;
- // Returns tight axis aligned bounding box of this model
- BoundingBoxf3 transformed_bounding_box() const;
void center_instances_around_point(const Pointf &point);
void translate(coordf_t x, coordf_t y, coordf_t z) { for (ModelObject *o : this->objects) o->translate(x, y, z); }
TriangleMesh mesh() const;
diff --git a/xs/src/libslic3r/TriangleMesh.cpp b/xs/src/libslic3r/TriangleMesh.cpp
index 197b4d488..957515db3 100644
--- a/xs/src/libslic3r/TriangleMesh.cpp
+++ b/xs/src/libslic3r/TriangleMesh.cpp
@@ -19,6 +19,8 @@
#include <tbb/parallel_for.h>
+#include <Eigen/Dense>
+
#if 0
#define DEBUG
#define _DEBUG
@@ -601,46 +603,130 @@ TriangleMesh::bounding_box() const
return bb;
}
-
-TriangleMesh TriangleMesh::convex_hull3d() const
+BoundingBoxf3 TriangleMesh::transformed_bounding_box(const std::vector<float>& matrix) const
{
- // qhull's realT is assumed to be a typedef for float - let's better check it first:
- static_assert(std::is_same<realT, float>::value, "Internal type realT in the qhull library must be float!");
+ bool has_shared = (stl.v_shared != nullptr);
+ if (!has_shared)
+ stl_generate_shared_vertices(&stl);
+
+ unsigned int vertices_count = (stl.stats.shared_vertices > 0) ? (unsigned int)stl.stats.shared_vertices : 3 * (unsigned int)stl.stats.number_of_facets;
+
+ if (vertices_count == 0)
+ return BoundingBoxf3();
+
+ Eigen::MatrixXf src_vertices(3, vertices_count);
+
+ if (stl.stats.shared_vertices > 0)
+ {
+ stl_vertex* vertex_ptr = stl.v_shared;
+ for (int i = 0; i < stl.stats.shared_vertices; ++i)
+ {
+ src_vertices(0, i) = vertex_ptr->x;
+ src_vertices(1, i) = vertex_ptr->y;
+ src_vertices(2, i) = vertex_ptr->z;
+ vertex_ptr += 1;
+ }
+ }
+ else
+ {
+ stl_facet* facet_ptr = stl.facet_start;
+ unsigned int v_id = 0;
+ while (facet_ptr < stl.facet_start + stl.stats.number_of_facets)
+ {
+ for (int i = 0; i < 3; ++i)
+ {
+ src_vertices(0, v_id) = facet_ptr->vertex[i].x;
+ src_vertices(1, v_id) = facet_ptr->vertex[i].y;
+ src_vertices(2, v_id) = facet_ptr->vertex[i].z;
+ }
+ facet_ptr += 1;
+ ++v_id;
+ }
+ }
+
+ if (!has_shared && (stl.stats.shared_vertices > 0))
+ stl_invalidate_shared_vertices(&stl);
+ Eigen::Transform<float, 3, Eigen::Affine> m;
+ ::memcpy((void*)m.data(), (const void*)matrix.data(), 16 * sizeof(float));
+
+ Eigen::MatrixXf dst_vertices(3, vertices_count);
+ dst_vertices = m * src_vertices.colwise().homogeneous();
+
+ float min_x = dst_vertices(0, 0);
+ float max_x = dst_vertices(0, 0);
+ float min_y = dst_vertices(1, 0);
+ float max_y = dst_vertices(1, 0);
+ float min_z = dst_vertices(2, 0);
+ float max_z = dst_vertices(2, 0);
+
+ for (int i = 1; i < vertices_count; ++i)
+ {
+ min_x = std::min(min_x, dst_vertices(0, i));
+ max_x = std::max(max_x, dst_vertices(0, i));
+ min_y = std::min(min_y, dst_vertices(1, i));
+ max_y = std::max(max_y, dst_vertices(1, i));
+ min_z = std::min(min_z, dst_vertices(2, i));
+ max_z = std::max(max_z, dst_vertices(2, i));
+ }
+
+ return BoundingBoxf3(Pointf3((coordf_t)min_x, (coordf_t)min_y, (coordf_t)min_z), Pointf3((coordf_t)max_x, (coordf_t)max_y, (coordf_t)max_z));
+}
+
+TriangleMesh TriangleMesh::convex_hull_3d() const
+{
// Helper struct for qhull:
struct PointForQHull{
- PointForQHull(float x_p, float y_p, float z_p) : x(x_p), y(y_p), z(z_p) {}
- float x,y,z;
- };
- std::vector<PointForQHull> input_verts;
+ PointForQHull(float x_p, float y_p, float z_p) : x((realT)x_p), y((realT)y_p), z((realT)z_p) {}
+ realT x, y, z;
+ };
+ std::vector<PointForQHull> src_vertices;
// We will now fill the vector with input points for computation:
stl_facet* facet_ptr = stl.facet_start;
- while (facet_ptr < stl.facet_start+stl.stats.number_of_facets) {
- for (int j=0;j<3;++j)
- input_verts.emplace_back(PointForQHull(facet_ptr->vertex[j].x, facet_ptr->vertex[j].y, facet_ptr->vertex[j].z));
- facet_ptr+=1;
+ while (facet_ptr < stl.facet_start + stl.stats.number_of_facets)
+ {
+ for (int i = 0; i < 3; ++i)
+ {
+ const stl_vertex& v = facet_ptr->vertex[i];
+ src_vertices.emplace_back(v.x, v.y, v.z);
+ }
+
+ facet_ptr += 1;
}
// The qhull call:
orgQhull::Qhull qhull;
qhull.disableOutputStream(); // we want qhull to be quiet
- qhull.runQhull("", 3, input_verts.size(), (const realT*)(input_verts.data()), "Qt" );
+ try
+ {
+ qhull.runQhull("", 3, (int)src_vertices.size(), (const realT*)(src_vertices.data()), "Qt");
+ }
+ catch (...)
+ {
+ std::cout << "Unable to create convex hull" << std::endl;
+ return TriangleMesh();
+ }
// Let's collect results:
- Pointf3s vertices;
+ Pointf3s det_vertices;
std::vector<Point3> facets;
auto facet_list = qhull.facetList().toStdVector();
- for (const orgQhull::QhullFacet& facet : facet_list) { // iterate through facets
- for (unsigned char i=0; i<3; ++i) { // iterate through facet's vertices
- orgQhull::QhullPoint p = (facet.vertices())[i].point();
+ for (const orgQhull::QhullFacet& facet : facet_list)
+ { // iterate through facets
+ orgQhull::QhullVertexSet vertices = facet.vertices();
+ for (int i = 0; i < 3; ++i)
+ { // iterate through facet's vertices
+
+ orgQhull::QhullPoint p = vertices[i].point();
const float* coords = p.coordinates();
- Pointf3 vert((float)coords[0], (float)coords[1], (float)coords[2]);
- vertices.emplace_back(vert);
+ det_vertices.emplace_back(coords[0], coords[1], coords[2]);
}
- facets.emplace_back(Point3(vertices.size()-3, vertices.size()-2, vertices.size()-1));
+ unsigned int size = (unsigned int)det_vertices.size();
+ facets.emplace_back(size - 3, size - 2, size - 1);
}
- TriangleMesh output_mesh(vertices, facets);
+
+ TriangleMesh output_mesh(det_vertices, facets);
output_mesh.repair();
return output_mesh;
}
diff --git a/xs/src/libslic3r/TriangleMesh.hpp b/xs/src/libslic3r/TriangleMesh.hpp
index 14fdba6c3..6ab52efe2 100644
--- a/xs/src/libslic3r/TriangleMesh.hpp
+++ b/xs/src/libslic3r/TriangleMesh.hpp
@@ -55,7 +55,10 @@ public:
ExPolygons horizontal_projection() const;
Polygon convex_hull();
BoundingBoxf3 bounding_box() const;
- TriangleMesh convex_hull3d() const;
+ // Returns the bbox of this TriangleMesh transformed by the given matrix
+ BoundingBoxf3 transformed_bounding_box(const std::vector<float>& matrix) const;
+ // Returns the convex hull of this TriangleMesh
+ TriangleMesh convex_hull_3d() const;
void reset_repair_stats();
bool needed_repair() const;
size_t facets_count() const;
@@ -67,7 +70,7 @@ public:
// Count disconnected triangle patches.
size_t number_of_patches() const;
- stl_file stl;
+ mutable stl_file stl;
bool repaired;
private:
diff --git a/xs/src/libslic3r/libslic3r.h b/xs/src/libslic3r/libslic3r.h
index 2f07ca51a..34f61cb12 100644
--- a/xs/src/libslic3r/libslic3r.h
+++ b/xs/src/libslic3r/libslic3r.h
@@ -14,7 +14,7 @@
#include <boost/thread.hpp>
#define SLIC3R_FORK_NAME "Slic3r Prusa Edition"
-#define SLIC3R_VERSION "1.41.0-alpha3"
+#define SLIC3R_VERSION "1.41.0-beta"
#define SLIC3R_BUILD "UNKNOWN"
typedef int32_t coord_t;
diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp
index 3f01eb20c..0709271b8 100644
--- a/xs/src/slic3r/GUI/3DScene.cpp
+++ b/xs/src/slic3r/GUI/3DScene.cpp
@@ -202,7 +202,8 @@ const float GLVolume::SELECTED_OUTSIDE_COLOR[4] = { 0.19f, 0.58f, 1.0f, 1.0f };
GLVolume::GLVolume(float r, float g, float b, float a)
: m_angle_z(0.0f)
, m_scale_factor(1.0f)
- , m_dirty(true)
+ , m_transformed_bounding_box_dirty(true)
+ , m_transformed_convex_hull_bounding_box_dirty(true)
, composite_id(-1)
, select_group_id(-1)
, drag_group_id(-1)
@@ -219,8 +220,6 @@ GLVolume::GLVolume(float r, float g, float b, float a)
, tverts_range(0, size_t(-1))
, qverts_range(0, size_t(-1))
{
- m_world_mat = std::vector<float>(UNIT_MATRIX, std::end(UNIT_MATRIX));
-
color[0] = r;
color[1] = g;
color[2] = b;
@@ -264,45 +263,76 @@ const Pointf3& GLVolume::get_origin() const
void GLVolume::set_origin(const Pointf3& origin)
{
- m_origin = origin;
- m_dirty = true;
+ if (m_origin != origin)
+ {
+ m_origin = origin;
+ m_transformed_bounding_box_dirty = true;
+ m_transformed_convex_hull_bounding_box_dirty = true;
+ }
}
void GLVolume::set_angle_z(float angle_z)
{
- m_angle_z = angle_z;
- m_dirty = true;
+ if (m_angle_z != angle_z)
+ {
+ m_angle_z = angle_z;
+ m_transformed_bounding_box_dirty = true;
+ m_transformed_convex_hull_bounding_box_dirty = true;
+ }
}
void GLVolume::set_scale_factor(float scale_factor)
{
- m_scale_factor = scale_factor;
- m_dirty = true;
+ if (m_scale_factor != scale_factor)
+ {
+ m_scale_factor = scale_factor;
+ m_transformed_bounding_box_dirty = true;
+ m_transformed_convex_hull_bounding_box_dirty = true;
+ }
}
-const std::vector<float>& GLVolume::world_matrix() const
+void GLVolume::set_convex_hull(const TriangleMesh& convex_hull)
{
- if (m_dirty)
- {
- Eigen::Transform<float, 3, Eigen::Affine> m = Eigen::Transform<float, 3, Eigen::Affine>::Identity();
- m.translate(Eigen::Vector3f((float)m_origin.x, (float)m_origin.y, (float)m_origin.z));
- m.rotate(Eigen::AngleAxisf(m_angle_z, Eigen::Vector3f::UnitZ()));
- m.scale(m_scale_factor);
- ::memcpy((void*)m_world_mat.data(), (const void*)m.data(), 16 * sizeof(float));
- m_dirty = false;
- }
+ m_convex_hull = convex_hull;
+}
- return m_world_mat;
+std::vector<float> GLVolume::world_matrix() const
+{
+ std::vector<float> world_mat(UNIT_MATRIX, std::end(UNIT_MATRIX));
+ Eigen::Transform<float, 3, Eigen::Affine> m = Eigen::Transform<float, 3, Eigen::Affine>::Identity();
+ m.translate(Eigen::Vector3f((float)m_origin.x, (float)m_origin.y, (float)m_origin.z));
+ m.rotate(Eigen::AngleAxisf(m_angle_z, Eigen::Vector3f::UnitZ()));
+ m.scale(m_scale_factor);
+ ::memcpy((void*)world_mat.data(), (const void*)m.data(), 16 * sizeof(float));
+ return world_mat;
}
BoundingBoxf3 GLVolume::transformed_bounding_box() const
{
- if (m_dirty)
+ if (m_transformed_bounding_box_dirty)
+ {
m_transformed_bounding_box = bounding_box.transformed(world_matrix());
+ m_transformed_bounding_box_dirty = false;
+ }
return m_transformed_bounding_box;
}
+BoundingBoxf3 GLVolume::transformed_convex_hull_bounding_box() const
+{
+ if (m_transformed_convex_hull_bounding_box_dirty)
+ {
+ if (m_convex_hull.stl.stats.number_of_facets > 0)
+ m_transformed_convex_hull_bounding_box = m_convex_hull.transformed_bounding_box(world_matrix());
+ else
+ m_transformed_convex_hull_bounding_box = bounding_box.transformed(world_matrix());
+
+ m_transformed_convex_hull_bounding_box_dirty = false;
+ }
+
+ return m_transformed_convex_hull_bounding_box;
+}
+
void GLVolume::set_range(double min_z, double max_z)
{
this->qverts_range.first = 0;
@@ -629,6 +659,7 @@ std::vector<int> GLVolumeCollection::load_object(
if (!model_volume->modifier)
{
+ v.set_convex_hull(model_volume->get_convex_hull());
v.layer_height_texture = layer_height_texture;
if (extruder_id != -1)
v.extruder_id = extruder_id;
@@ -716,6 +747,7 @@ int GLVolumeCollection::load_wipe_tower_preview(
v.drag_group_id = obj_idx * 1000;
v.is_wipe_tower = true;
v.shader_outside_printer_detection_enabled = ! size_unknown;
+ v.set_convex_hull(mesh.convex_hull_3d());
return int(this->volumes.size() - 1);
}
@@ -803,7 +835,7 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, M
{
if ((volume != nullptr) && !volume->is_modifier)
{
- const BoundingBoxf3& bb = volume->transformed_bounding_box();
+ const BoundingBoxf3& bb = volume->transformed_convex_hull_bounding_box();
bool contained = print_volume.contains(bb);
all_contained &= contained;
diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp
index a552b32a7..1265bc20d 100644
--- a/xs/src/slic3r/GUI/3DScene.hpp
+++ b/xs/src/slic3r/GUI/3DScene.hpp
@@ -260,12 +260,16 @@ private:
float m_angle_z;
// Scale factor of the volume to be rendered.
float m_scale_factor;
- // World matrix of the volume to be rendered.
- std::vector<float> m_world_mat;
// Bounding box of this volume, in unscaled coordinates.
mutable BoundingBoxf3 m_transformed_bounding_box;
- // Whether or not is needed to recalculate the world matrix.
- mutable bool m_dirty;
+ // Whether or not is needed to recalculate the transformed bounding box.
+ mutable bool m_transformed_bounding_box_dirty;
+ // Convex hull of the original mesh, if any.
+ TriangleMesh m_convex_hull;
+ // Bounding box of this volume, in unscaled coordinates.
+ mutable BoundingBoxf3 m_transformed_convex_hull_bounding_box;
+ // Whether or not is needed to recalculate the transformed convex hull bounding box.
+ mutable bool m_transformed_convex_hull_bounding_box_dirty;
public:
@@ -323,13 +327,15 @@ public:
void set_origin(const Pointf3& origin);
void set_angle_z(float angle_z);
void set_scale_factor(float scale_factor);
+ void set_convex_hull(const TriangleMesh& convex_hull);
int object_idx() const { return this->composite_id / 1000000; }
int volume_idx() const { return (this->composite_id / 1000) % 1000; }
int instance_idx() const { return this->composite_id % 1000; }
- const std::vector<float>& world_matrix() const;
+ std::vector<float> world_matrix() const;
BoundingBoxf3 transformed_bounding_box() const;
+ BoundingBoxf3 transformed_convex_hull_bounding_box() const;
bool empty() const { return this->indexed_vertex_array.empty(); }
bool indexed() const { return this->indexed_vertex_array.indexed(); }
diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp
index 45260544d..2bf516e3f 100644
--- a/xs/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp
@@ -2206,7 +2206,7 @@ void GLCanvas3D::update_gizmos_data()
/////////////////////////////////////////////////////////////////////////
// Following block provides convex hull data to the Flatten gizmo
// It is temporary, it should be optimized and moved elsewhere later
- TriangleMesh ch = model_object->mesh().convex_hull3d();
+ TriangleMesh ch = model_object->mesh().convex_hull_3d();
stl_facet* facet_ptr = ch.stl.facet_start;
std::vector<Pointf3s> points;
const unsigned int k = 20;
@@ -3342,7 +3342,7 @@ BoundingBoxf3 GLCanvas3D::_selected_volumes_bounding_box() const
{
for (const GLVolume* volume : selected_volumes)
{
- bb.merge(volume->transformed_bounding_box());
+ bb.merge(volume->transformed_convex_hull_bounding_box());
}
}
diff --git a/xs/src/slic3r/GUI/GLGizmo.cpp b/xs/src/slic3r/GUI/GLGizmo.cpp
index 5a0944758..5a69bc9b7 100644
--- a/xs/src/slic3r/GUI/GLGizmo.cpp
+++ b/xs/src/slic3r/GUI/GLGizmo.cpp
@@ -189,7 +189,7 @@ GLGizmoRotate::GLGizmoRotate()
, m_angle_z(0.0f)
, m_center(Pointf(0.0, 0.0))
, m_radius(0.0f)
- , m_keep_radius(false)
+ , m_keep_initial_values(false)
{
}
@@ -229,7 +229,7 @@ bool GLGizmoRotate::on_init()
void GLGizmoRotate::on_set_state()
{
- m_keep_radius = (m_state == On) ? false : true;
+ m_keep_initial_values = (m_state == On) ? false : true;
}
void GLGizmoRotate::on_update(const Pointf& mouse_pos)
@@ -255,19 +255,19 @@ void GLGizmoRotate::on_update(const Pointf& mouse_pos)
void GLGizmoRotate::on_refresh()
{
- m_keep_radius = false;
+ m_keep_initial_values = false;
}
void GLGizmoRotate::on_render(const BoundingBoxf3& box) const
{
::glDisable(GL_DEPTH_TEST);
- const Pointf3& size = box.size();
- m_center = box.center();
- if (!m_keep_radius)
+ if (!m_keep_initial_values)
{
+ const Pointf3& size = box.size();
+ m_center = box.center();
m_radius = Offset + ::sqrt(sqr(0.5f * size.x) + sqr(0.5f * size.y));
- m_keep_radius = true;
+ m_keep_initial_values = true;
}
::glLineWidth(2.0f);
diff --git a/xs/src/slic3r/GUI/GLGizmo.hpp b/xs/src/slic3r/GUI/GLGizmo.hpp
index 170a672fd..d1ef6452a 100644
--- a/xs/src/slic3r/GUI/GLGizmo.hpp
+++ b/xs/src/slic3r/GUI/GLGizmo.hpp
@@ -101,7 +101,7 @@ class GLGizmoRotate : public GLGizmoBase
mutable Pointf m_center;
mutable float m_radius;
- mutable bool m_keep_radius;
+ mutable bool m_keep_initial_values;
public:
GLGizmoRotate();
diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp
index 0e0a03f5e..1a0fc9b9f 100644
--- a/xs/xsp/GUI_3DScene.xsp
+++ b/xs/xsp/GUI_3DScene.xsp
@@ -65,7 +65,6 @@
%};
Clone<BoundingBoxf3> bounding_box() const
%code%{ RETVAL = THIS->bounding_box; %};
- Clone<BoundingBoxf3> transformed_bounding_box() const;
bool empty() const;
bool indexed() const;