mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-18 02:35:57 +08:00
Fix --center, --dont-arrange, --export-* and other things
This commit is contained in:
parent
b17f623915
commit
945bbc030c
@ -119,6 +119,19 @@ int CLI::run(int argc, char **argv) {
|
||||
Model m;
|
||||
for (auto &model : this->models)
|
||||
m.merge(model);
|
||||
|
||||
// Rearrange instances unless --dont-arrange is supplied
|
||||
if (!this->config.getBool("dont_arrange")) {
|
||||
m.add_default_instances();
|
||||
const BoundingBoxf bb{ this->full_print_config.bed_shape.values };
|
||||
m.arrange_objects(
|
||||
this->full_print_config.min_object_distance(),
|
||||
// if we are going to use the merged model for printing, honor
|
||||
// the configured print bed for arranging, otherwise do it freely
|
||||
this->has_print_action() ? &bb : nullptr
|
||||
);
|
||||
}
|
||||
|
||||
this->models = {m};
|
||||
} else if (opt_key == "duplicate") {
|
||||
const BoundingBoxf bb{ this->full_print_config.bed_shape.values };
|
||||
@ -144,30 +157,38 @@ int CLI::run(int argc, char **argv) {
|
||||
model.duplicate_objects_grid(x, y, (distance > 0) ? distance : 6); // TODO: this is not the right place for setting a default
|
||||
} else if (opt_key == "center") {
|
||||
for (auto &model : this->models) {
|
||||
model.add_default_instances();
|
||||
// this affects instances:
|
||||
model.center_instances_around_point(config.opt<ConfigOptionPoint>("center")->value);
|
||||
// this affects volumes:
|
||||
model.align_to_ground();
|
||||
}
|
||||
} else if (opt_key == "align_xy") {
|
||||
const Pointf p{ this->config.opt<ConfigOptionPoint>("align_xy")->value };
|
||||
for (auto &model : this->models) {
|
||||
BoundingBoxf3 bb{ model.bounding_box() };
|
||||
// this affects volumes:
|
||||
model.translate(-(bb.min.x - p.x), -(bb.min.y - p.y), -bb.min.z);
|
||||
}
|
||||
} else if (opt_key == "rotate") {
|
||||
for (auto &model : this->models)
|
||||
for (auto &o : model.objects)
|
||||
// this affects volumes:
|
||||
o->rotate(Geometry::deg2rad(config.getFloat(opt_key)), Z);
|
||||
} else if (opt_key == "rotate_x") {
|
||||
for (auto &model : this->models)
|
||||
for (auto &o : model.objects)
|
||||
// this affects volumes:
|
||||
o->rotate(Geometry::deg2rad(config.getFloat(opt_key)), X);
|
||||
} else if (opt_key == "rotate_y") {
|
||||
for (auto &model : this->models)
|
||||
for (auto &o : model.objects)
|
||||
// this affects volumes:
|
||||
o->rotate(Geometry::deg2rad(config.getFloat(opt_key)), Y);
|
||||
} else if (opt_key == "scale") {
|
||||
for (auto &model : this->models)
|
||||
for (auto &o : model.objects)
|
||||
// this affects volumes:
|
||||
o->scale(config.get_abs_value(opt_key, 1));
|
||||
} else if (opt_key == "scale_to_fit") {
|
||||
const auto opt = config.opt<ConfigOptionPoint3>(opt_key);
|
||||
@ -177,6 +198,7 @@ int CLI::run(int argc, char **argv) {
|
||||
}
|
||||
for (auto &model : this->models)
|
||||
for (auto &o : model.objects)
|
||||
// this affects volumes:
|
||||
o->scale_to_fit(opt->value);
|
||||
} else if (opt_key == "cut" || opt_key == "cut_x" || opt_key == "cut_y") {
|
||||
std::vector<Model> new_models;
|
||||
@ -253,13 +275,21 @@ int CLI::run(int argc, char **argv) {
|
||||
this->print_config.save(config.getString("save"));
|
||||
} else if (opt_key == "info") {
|
||||
// --info works on unrepaired model
|
||||
for (const Model &model : this->models)
|
||||
for (Model &model : this->models) {
|
||||
model.add_default_instances();
|
||||
model.print_info();
|
||||
}
|
||||
} else if (opt_key == "export_stl") {
|
||||
for (auto &model : this->models)
|
||||
model.add_default_instances();
|
||||
this->export_models(IO::STL);
|
||||
} else if (opt_key == "export_obj") {
|
||||
for (auto &model : this->models)
|
||||
model.add_default_instances();
|
||||
this->export_models(IO::OBJ);
|
||||
} else if (opt_key == "export_pov") {
|
||||
for (auto &model : this->models)
|
||||
model.add_default_instances();
|
||||
this->export_models(IO::POV);
|
||||
} else if (opt_key == "export_amf") {
|
||||
this->export_models(IO::AMF);
|
||||
@ -278,11 +308,16 @@ int CLI::run(int argc, char **argv) {
|
||||
}
|
||||
} else if (opt_key == "export_gcode") {
|
||||
for (const Model &model : this->models) {
|
||||
// If all objects have defined instances, their relative positions will be
|
||||
// honored when printing (they will be only centered, unless --dont-arrange
|
||||
// is supplied); if any object has no instances, it will get a default one
|
||||
// and all instances will be rearranged (unless --dont-arrange is supplied).
|
||||
SimplePrint print;
|
||||
print.status_cb = [](int ln, const std::string& msg) {
|
||||
boost::nowide::cout << msg << std::endl;
|
||||
};
|
||||
print.apply_config(this->print_config);
|
||||
print.arrange = !this->config.getBool("dont_arrange");
|
||||
print.center = !this->config.has("center")
|
||||
&& !this->config.has("align_xy")
|
||||
&& !this->config.getBool("dont_arrange");
|
||||
@ -365,8 +400,7 @@ CLI::print_help(bool include_print_options) const {
|
||||
|
||||
void
|
||||
CLI::export_models(IO::ExportFormat format) {
|
||||
for (size_t i = 0; i < this->models.size(); ++i) {
|
||||
Model &model = this->models[i];
|
||||
for (const Model& model : this->models) {
|
||||
const std::string outfile = this->output_filepath(model, format);
|
||||
|
||||
IO::write_model.at(format)(model, outfile);
|
||||
|
@ -27,6 +27,10 @@ class CLI {
|
||||
/// Exports loaded models to a file of the specified format, according to the options affecting output filename.
|
||||
void export_models(IO::ExportFormat format);
|
||||
|
||||
bool has_print_action() const {
|
||||
return this->config.has("export_gcode") || this->config.has("export_sla_svg");
|
||||
};
|
||||
|
||||
std::string output_filepath(const Model &model, IO::ExportFormat format) const;
|
||||
};
|
||||
|
||||
|
@ -170,20 +170,17 @@ bool
|
||||
POV::write(const Model &model, std::string output_file)
|
||||
{
|
||||
TriangleMesh mesh{ model.mesh() };
|
||||
return STL::write(mesh, output_file);
|
||||
return POV::write(mesh, output_file);
|
||||
}
|
||||
|
||||
bool
|
||||
POV::write(const TriangleMesh& mesh, std::string output_file)
|
||||
{
|
||||
TriangleMesh mesh2 = mesh;
|
||||
mesh2.center_around_origin();
|
||||
|
||||
using namespace std;
|
||||
boost::nowide::ofstream pov;
|
||||
pov.open(output_file.c_str(), ios::out | ios::trunc);
|
||||
for (int i = 0; i < mesh2.stl.stats.number_of_facets; ++i) {
|
||||
const stl_facet &f = mesh2.stl.facet_start[i];
|
||||
for (int i = 0; i < mesh.stl.stats.number_of_facets; ++i) {
|
||||
const stl_facet &f = mesh.stl.facet_start[i];
|
||||
pov << "triangle { ";
|
||||
pov << "<" << f.vertex[0].x << "," << f.vertex[0].y << "," << f.vertex[0].z << ">,";
|
||||
pov << "<" << f.vertex[1].x << "," << f.vertex[1].y << "," << f.vertex[1].z << ">,";
|
||||
|
@ -933,7 +933,7 @@ ModelObject::print_info() const
|
||||
cout << fixed;
|
||||
cout << "[" << boost::filesystem::path(this->input_file).filename().string() << "]" << endl;
|
||||
|
||||
TriangleMesh mesh = this->raw_mesh();
|
||||
TriangleMesh mesh = this->mesh();
|
||||
mesh.check_topology();
|
||||
BoundingBoxf3 bb = mesh.bounding_box();
|
||||
Sizef3 size = bb.size();
|
||||
|
@ -2092,7 +2092,7 @@ CLIMiscConfigDef::CLIMiscConfigDef()
|
||||
def = this->add("output", coString);
|
||||
def->label = __TRANS("Output File");
|
||||
def->tooltip = __TRANS("The file where the output will be written (if not specified, it will be based on the input file).");
|
||||
def->cli = "output";
|
||||
def->cli = "output|o";
|
||||
|
||||
#ifdef USE_WX
|
||||
def = this->add("autosave", coString);
|
||||
|
@ -11,15 +11,19 @@ SimplePrint::set_model(const Model &model) {
|
||||
// make method idempotent so that the object is reusable
|
||||
this->_print.clear_objects();
|
||||
|
||||
// make sure all objects have at least one defined instance
|
||||
this->_model.add_default_instances();
|
||||
|
||||
// align to z = 0
|
||||
for (ModelObject* o : this->_model.objects)
|
||||
o->translate(0, 0, -o->bounding_box().min.z);
|
||||
|
||||
// make sure all objects have at least one defined instance
|
||||
if (this->_model.add_default_instances() && this->arrange) {
|
||||
// if we added at least one default instance, we need to rearrange
|
||||
const BoundingBoxf bb{ this->_print.config.bed_shape.values };
|
||||
this->_model.arrange_objects(this->_print.config.min_object_distance(), &bb);
|
||||
}
|
||||
|
||||
if (this->center) {
|
||||
Polygon bed_polygon{ scale(this->_print.config.bed_shape.values) };
|
||||
const Polygon bed_polygon{ scale(this->_print.config.bed_shape.values) };
|
||||
this->_model.center_instances_around_point(Slic3r::Pointf::new_unscale(bed_polygon.centroid()));
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ namespace Slic3r {
|
||||
|
||||
class SimplePrint {
|
||||
public:
|
||||
bool arrange{true};
|
||||
bool center{true};
|
||||
std::function<void(int, const std::string&)> status_cb {nullptr};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user