mirror of
https://github.com/RikudouSage/PhpScad.git
synced 2025-01-16 21:28:15 +01:00
Add custom renderer documentation
This commit is contained in:
parent
db5d6131c4
commit
53fedea25c
36
README.md
36
README.md
@ -502,3 +502,39 @@ $model = new ScadModel(facetsConfiguration: new FacetsNumber(30));
|
||||
This topic is covered in [separate documentation](doc/creating-shapes.md).
|
||||
|
||||
**This documentation is a work in progress**
|
||||
|
||||
## Rendering output
|
||||
|
||||
By default, the `ScadModel` uses a `ScadFileRenderer` class which, as the name implies, renders the content into
|
||||
a SCAD file which you can then open in OpenSCAD.
|
||||
|
||||
There are other built-in renderers available:
|
||||
|
||||
- `PngPreviewRenderer`
|
||||
- `StlRenderer`
|
||||
|
||||
Unlike the `ScadFileRenderer`, these two need to find the OpenSCAD binary. If you have OpenSCAD installed in your path
|
||||
or you use the flatpak version, it works out of the box:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Rikudou\PhpScad\ScadModel;
|
||||
use Rikudou\PhpScad\Renderer\PngPreviewRenderer;
|
||||
use Rikudou\PhpScad\Renderer\StlRenderer;
|
||||
use Rikudou\PhpScad\Shape\Cube;
|
||||
|
||||
$model = (new ScadModel())
|
||||
->withRenderable(new Cube(5, 5, 5))
|
||||
;
|
||||
|
||||
$model->withRenderer(new PngPreviewRenderer())->render(__DIR__ . '/preview.png');
|
||||
$model->withRenderer(new StlRenderer())->render(__DIR__ . '/output.stl');
|
||||
|
||||
// you can also provide some settings to the renderers:
|
||||
|
||||
$previewRenderer = new PngPreviewRenderer(width: 512, height: 512, openScadPath: '/custom/path/to/openscad');
|
||||
$stlRenderer = new StlRenderer(openScadPath: '/custom/path/to/openscad');
|
||||
```
|
||||
|
||||
> Tip: You can also create your own reusable renderer, follow the [tutorial here](doc/custom-renderer.md)
|
||||
|
457
doc/custom-renderer.md
Normal file
457
doc/custom-renderer.md
Normal file
@ -0,0 +1,457 @@
|
||||
# Creating a custom renderer
|
||||
|
||||
What is a renderer? It transforms the `ScadModel` object, which houses all the defined `Renderable` objects, into
|
||||
something usable outside of this library.
|
||||
The built-in examples include a SCAD file (for opening in OpenSCAD), a PNG file with model preview and an STL model
|
||||
file for using with 3D viewers, slicers and so on.
|
||||
|
||||
Today we're going to create a renderer that creates a GCode for 3D printers directly.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
We'll need `PrusaSlicer` and `OpenSCAD` installed on our system. It can either be installed locally or from flatpak.
|
||||
|
||||
On Ubuntu, you can install by using `apt install prusa-slicer openscad`. If your system supports flatpaks install using
|
||||
`flatpak install com.prusa3d.PrusaSlicer org.openscad.OpenSCAD`.
|
||||
|
||||
## Creating a renderer
|
||||
|
||||
Creating a renderer starts by creating a class implementing the `Renderer` interface:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Rikudou\PhpScad\Renderer;
|
||||
|
||||
final class GCodeRenderer implements Renderer
|
||||
{
|
||||
public function render(string $outputFile, string $scadContent): void
|
||||
{
|
||||
// TODO: Implement render() method.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
As you can see, the `Renderer` defines a single method `render()` which accepts the output file path as a parameter
|
||||
and the SCAD content.
|
||||
|
||||
### Flow
|
||||
|
||||
We're going to take the `$scadContent` and let the built-in `StlRenderer` convert it into a STL 3D model,
|
||||
then we're going to take the STL file and slice it using PrusaSlicer into GCode.
|
||||
|
||||
We'll be making it as easy to use as possible, which means we'll try to find where PrusaSlicer and OpenSCAD is located
|
||||
but we'll also need to provide some way to use a custom path:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Rikudou\PhpScad\Renderer;
|
||||
|
||||
final class GCodeRenderer implements Renderer
|
||||
{
|
||||
public function __construct(
|
||||
?string $prusaSlicerPath = null,
|
||||
private readonly StlRenderer $stlRenderer = new StlRenderer(),
|
||||
) {
|
||||
}
|
||||
|
||||
public function render(string $outputFile, string $scadContent): void
|
||||
{
|
||||
// TODO: Implement render() method.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
We allow providing of custom PrusaSlicer and custom `StlRenderer` instance which could have a manual path set.
|
||||
The STL renderer has its own logic (which we'll be pretty much replicating for PrusaSlicer in our class)
|
||||
for locating OpenSCAD, so we can skip writing code for that part in our code.
|
||||
|
||||
We'll be checking in constructor that we can find a path if we're not provided one:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Rikudou\PhpScad\Renderer;
|
||||
|
||||
final class GCodeRenderer implements Renderer
|
||||
{
|
||||
private string $prusaSlicerPath;
|
||||
|
||||
public function __construct(
|
||||
?string $prusaSlicerPath = null,
|
||||
private readonly StlRenderer $stlRenderer = new StlRenderer(),
|
||||
) {
|
||||
$this->prusaSlicerPath = $prusaSlicerPath ?? $this->locatePrusaSlicer();
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
private function locatePrusaSlicer(): string
|
||||
{
|
||||
// TODO: find the binary or throw an exception
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For locating the binary I'm pretty much just going to copy & paste from the `AbstractOpenScadBinaryRenderer` library:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Rikudou\PhpScad\Renderer;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
final class GCodeRenderer implements Renderer
|
||||
{
|
||||
private string $prusaSlicerPath;
|
||||
|
||||
public function __construct(
|
||||
?string $prusaSlicerPath = null,
|
||||
private readonly StlRenderer $stlRenderer = new StlRenderer(),
|
||||
) {
|
||||
$this->prusaSlicerPath = $prusaSlicerPath ?? $this->locatePrusaSlicer();
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
private function locatePrusaSlicer(): string
|
||||
{
|
||||
// try finding the binary in $PATH
|
||||
exec('which prusa-slicer', $output, $exitCode);
|
||||
if ($exitCode === 0) { // in Unix, 0 means success
|
||||
return "'{$output[0]}'"; // the path might contain a space, enclose it in a single quote
|
||||
}
|
||||
|
||||
$exception = new RuntimeException('Cannot find PrusaSlicer in path.');
|
||||
|
||||
exec('which flatpak', result_code: $exitCode);
|
||||
if ($exitCode !== 0) { // if flatpak doesn't exist, no need to check further
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
// if the flatpak is not installed, throw an exception
|
||||
exec('flatpak info com.prusa3d.PrusaSlicer', result_code: $exitCode);
|
||||
if ($exitCode !== 0) {
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
// we will need the --file-forwarding flag if we want the Slicer to have access to the files we'll be creating
|
||||
return 'flatpak run --file-forwarding com.prusa3d.PrusaSlicer';
|
||||
}
|
||||
|
||||
private function isFlatpak(): bool
|
||||
{
|
||||
return str_starts_with($this->prusaSlicerPath, 'flatpak ');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Let's also add one helper method:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Rikudou\PhpScad\Renderer;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
final class GCodeRenderer implements Renderer
|
||||
{
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
private array $temporaryFiles = [];
|
||||
|
||||
// ...
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
foreach ($this->temporaryFiles as $temporaryFile) {
|
||||
if (is_file($temporaryFile)) {
|
||||
unlink($temporaryFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function createTemporaryStlFile(): string
|
||||
{
|
||||
$file = tempnam(sys_get_temp_dir(), 'PhpScadGCodeRenderer');
|
||||
rename($file, "{$file}.stl");
|
||||
$this->temporaryFiles[] = $file;
|
||||
|
||||
return "{$file}.stl";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This will help us create temporary files which will be automatically deleted when our script ends.
|
||||
|
||||
Now let's get started by creating the STL file as a temporary file:
|
||||
|
||||
```php
|
||||
public function render(string $outputFile, string $scadContent): void
|
||||
{
|
||||
$stlFile = $this->createTemporaryStlFile();
|
||||
$this->stlRenderer->render($stlFile, $scadContent);
|
||||
}
|
||||
```
|
||||
|
||||
And let's construct and execute the command:
|
||||
|
||||
```php
|
||||
public function render(string $outputFile, string $scadContent): void
|
||||
{
|
||||
$stlFile = $this->createTemporaryStlFile();
|
||||
$this->stlRenderer->render($stlFile, $scadContent);
|
||||
|
||||
// we specify that we want to export a gcode
|
||||
$command = "{$this->prusaSlicerPath} --gcode -o ";
|
||||
// in previous part you can see '-o' which means output file, we need to check whether we're running a flatpak
|
||||
// or not to give the correct path
|
||||
if ($this->isFlatpak()) {
|
||||
// this is a special syntax that tells the flatpak system to forward real filesystem files to the app
|
||||
$command .= "@@ '{$outputFile}' @@";
|
||||
} else {
|
||||
$command .= "'{$outputFile}'";
|
||||
}
|
||||
$command .= ' ';
|
||||
// we do the same for input file
|
||||
if ($this->isFlatpak()) {
|
||||
$command .= "@@ '{$stlFile}' @@";
|
||||
} else {
|
||||
$command .= "'{$stlFile}'";
|
||||
}
|
||||
// this tells the shell that error output should be redirected to standard output
|
||||
$command .= " 2>&1";
|
||||
|
||||
exec($command, $output, result_code: $exitCode);
|
||||
if ($exitCode !== 0) {
|
||||
throw new RuntimeException('There was an error while slicing your model: ' . implode("\n", $output));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This is the simplest form of the command and isn't actually that great because the sliced GCode will probably be wrong
|
||||
regardless of what printer you use.
|
||||
|
||||
To mitigate that let's add support for loading custom options! PrusaSlicer accepts an ini file with configurations
|
||||
(which you can export from the GUI by going to `File -> Export -> Export config` or pressing `CTRL+E`) and we'll
|
||||
add a parameter that allows us to load such a config file!
|
||||
|
||||
> You could also add support for the hundreds of individual parameters, but that would be way too out of scope of this
|
||||
> tutorial.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Rikudou\PhpScad\Renderer;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
final class GCodeRenderer implements Renderer
|
||||
{
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
private array $temporaryFiles = [];
|
||||
private string $prusaSlicerPath;
|
||||
|
||||
public function __construct(
|
||||
private readonly ?string $configFile = null,
|
||||
?string $prusaSlicerPath = null,
|
||||
private readonly StlRenderer $stlRenderer = new StlRenderer(),
|
||||
) {
|
||||
$this->prusaSlicerPath = $prusaSlicerPath ?? $this->locatePrusaSlicer();
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
public function render(string $outputFile, string $scadContent): void
|
||||
{
|
||||
$stlFile = $this->createTemporaryStlFile();
|
||||
$this->stlRenderer->render($stlFile, $scadContent);
|
||||
|
||||
// we specify that we want to export a gcode
|
||||
$command = "{$this->prusaSlicerPath} --gcode -o ";
|
||||
// in previous part you can see '-o' which means output file, we need to check whether we're running a flatpak
|
||||
// or not to give the correct path
|
||||
if ($this->isFlatpak()) {
|
||||
// this is a special syntax that tells the flatpak system to forward real filesystem files to the app
|
||||
$command .= "@@ '{$outputFile}' @@";
|
||||
} else {
|
||||
$command .= "'{$outputFile}'";
|
||||
}
|
||||
$command .= ' ';
|
||||
// we do the same for input file
|
||||
if ($this->isFlatpak()) {
|
||||
$command .= "@@ '{$stlFile}' @@";
|
||||
} else {
|
||||
$command .= "'{$stlFile}'";
|
||||
}
|
||||
if ($this->configFile) {
|
||||
$command .= " --load ";
|
||||
if ($this->isFlatpak()) {
|
||||
$command .= "@@ '{$this->configFile}' @@";
|
||||
} else {
|
||||
$command .= "'{$this->configFile}'";
|
||||
}
|
||||
}
|
||||
// this tells the shell that error output should be redirected to standard output
|
||||
$command .= " 2>&1";
|
||||
|
||||
exec($command, $output, result_code: $exitCode);
|
||||
if ($exitCode !== 0) {
|
||||
throw new RuntimeException('There was an error while slicing your model: ' . implode("\n", $output));
|
||||
}
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
The whole command then might look something like this:
|
||||
|
||||
`flatpak run --file-forwarding com.prusa3d.PrusaSlicer --gcode -o @@ '/home/user/PhpScad/output.gcode' @@ @@ '/tmp/PhpScadGCodeRendererdafabR.stl' @@ --load @@ '/home/user/PhpScad/doc/prusa-mini.ini' @@ 2>&1`
|
||||
|
||||
You can check the [example config file](prusa-mini.ini) to see what it looks like.
|
||||
|
||||
Now let's try it!
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Rikudou\PhpScad\FacetsConfiguration\FacetsNumber;
|
||||
use Rikudou\PhpScad\Renderer\GCodeRenderer;
|
||||
use Rikudou\PhpScad\ScadModel;
|
||||
use Rikudou\PhpScad\Shape\Cube;
|
||||
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
(new ScadModel(facetsConfiguration: new FacetsNumber(60)))
|
||||
->withRenderable(
|
||||
new Cube(5, 10, 15),
|
||||
)
|
||||
->withRenderer(new GCodeRenderer(configFile: __DIR__ . '/prusa-mini.ini'))
|
||||
->render(__DIR__ . '/output.gcode');
|
||||
|
||||
```
|
||||
|
||||
And sure enough, the generated gcode looks good!
|
||||
|
||||
![Rendered GCode](img/renderer-gcode.png)
|
||||
|
||||
Just in case, this is the whole class:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Rikudou\PhpScad\Renderer;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
final class GCodeRenderer implements Renderer
|
||||
{
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
private array $temporaryFiles = [];
|
||||
private string $prusaSlicerPath;
|
||||
|
||||
public function __construct(
|
||||
private readonly ?string $configFile = null,
|
||||
?string $prusaSlicerPath = null,
|
||||
private readonly StlRenderer $stlRenderer = new StlRenderer(),
|
||||
) {
|
||||
$this->prusaSlicerPath = $prusaSlicerPath ?? $this->locatePrusaSlicer();
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
foreach ($this->temporaryFiles as $temporaryFile) {
|
||||
if (is_file($temporaryFile)) {
|
||||
unlink($temporaryFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function render(string $outputFile, string $scadContent): void
|
||||
{
|
||||
$stlFile = $this->createTemporaryStlFile();
|
||||
$this->stlRenderer->render($stlFile, $scadContent);
|
||||
|
||||
// we specify that we want to export a gcode
|
||||
$command = "{$this->prusaSlicerPath} --gcode -o ";
|
||||
// in previous part you can see '-o' which means output file, we need to check whether we're running a flatpak
|
||||
// or not to give the correct path
|
||||
if ($this->isFlatpak()) {
|
||||
// this is a special syntax that tells the flatpak system to forward real filesystem files to the app
|
||||
$command .= "@@ '{$outputFile}' @@";
|
||||
} else {
|
||||
$command .= "'{$outputFile}'";
|
||||
}
|
||||
$command .= ' ';
|
||||
// we do the same for input file
|
||||
if ($this->isFlatpak()) {
|
||||
$command .= "@@ '{$stlFile}' @@";
|
||||
} else {
|
||||
$command .= "'{$stlFile}'";
|
||||
}
|
||||
if ($this->configFile) {
|
||||
$command .= " --load ";
|
||||
if ($this->isFlatpak()) {
|
||||
$command .= "@@ '{$this->configFile}' @@";
|
||||
} else {
|
||||
$command .= "'{$this->configFile}'";
|
||||
}
|
||||
}
|
||||
// this tells the shell that error output should be redirected to standard output
|
||||
$command .= " 2>&1";
|
||||
|
||||
exec($command, $output, result_code: $exitCode);
|
||||
if ($exitCode !== 0) {
|
||||
throw new RuntimeException('There was an error while slicing your model: ' . implode("\n", $output));
|
||||
}
|
||||
}
|
||||
|
||||
private function locatePrusaSlicer(): string
|
||||
{
|
||||
// try finding the binary in $PATH
|
||||
exec('which prusa-slicer', $output, $exitCode);
|
||||
if ($exitCode === 0) { // in Unix, 0 means success
|
||||
return "'{$output[0]}'"; // the path might contain a space, enclose it in a single quote
|
||||
}
|
||||
|
||||
$exception = new RuntimeException('Cannot find PrusaSlicer in path.');
|
||||
|
||||
exec('which flatpak', result_code: $exitCode);
|
||||
if ($exitCode !== 0) { // if flatpak doesn't exist, no need to check further
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
// if the flatpak is not installed, throw an exception
|
||||
exec('flatpak info com.prusa3d.PrusaSlicer', result_code: $exitCode);
|
||||
if ($exitCode !== 0) {
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
// we will need the --file-forwarding flag if we want the Slicer to have access to the files we'll be creating
|
||||
return 'flatpak run --file-forwarding com.prusa3d.PrusaSlicer';
|
||||
}
|
||||
|
||||
private function isFlatpak(): bool
|
||||
{
|
||||
return str_starts_with($this->prusaSlicerPath, 'flatpak ');
|
||||
}
|
||||
|
||||
private function createTemporaryStlFile(): string
|
||||
{
|
||||
$file = tempnam(sys_get_temp_dir(), 'PhpScadGCodeRenderer');
|
||||
rename($file, "{$file}.stl");
|
||||
$this->temporaryFiles[] = $file;
|
||||
|
||||
return "{$file}.stl";
|
||||
}
|
||||
}
|
||||
```
|
BIN
doc/img/renderer-gcode.png
Normal file
BIN
doc/img/renderer-gcode.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 167 KiB |
292
doc/prusa-mini.ini
Normal file
292
doc/prusa-mini.ini
Normal file
@ -0,0 +1,292 @@
|
||||
# generated by PrusaSlicer 2.5.2 on 2023-06-09 at 16:16:29 UTC
|
||||
avoid_crossing_perimeters = 0
|
||||
avoid_crossing_perimeters_max_detour = 0
|
||||
bed_custom_model =
|
||||
bed_custom_texture =
|
||||
bed_shape = 0x0,180x0,180x180,0x180
|
||||
bed_temperature = 60
|
||||
before_layer_gcode = ;BEFORE_LAYER_CHANGE\nG92 E0.0\n;[layer_z]\n\n
|
||||
between_objects_gcode =
|
||||
bottom_fill_pattern = monotonic
|
||||
bottom_solid_layers = 4
|
||||
bottom_solid_min_thickness = 0.5
|
||||
bridge_acceleration = 1000
|
||||
bridge_angle = 0
|
||||
bridge_fan_speed = 100
|
||||
bridge_flow_ratio = 0.95
|
||||
bridge_speed = 25
|
||||
brim_separation = 0.1
|
||||
brim_type = outer_only
|
||||
brim_width = 0
|
||||
clip_multipart_objects = 1
|
||||
color_change_gcode = M600
|
||||
colorprint_heights =
|
||||
compatible_printers_condition_cummulative = "printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.4";"nozzle_diameter[0]!=0.8 and printer_notes!~/.*PG.*/ and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)"
|
||||
complete_objects = 0
|
||||
cooling = 1
|
||||
cooling_tube_length = 5
|
||||
cooling_tube_retraction = 91.5
|
||||
default_acceleration = 1000
|
||||
default_filament_profile = "Prusament PLA"
|
||||
default_print_profile = 0.15mm QUALITY @MINI
|
||||
deretract_speed = 40
|
||||
disable_fan_first_layers = 1
|
||||
dont_support_bridges = 0
|
||||
draft_shield = disabled
|
||||
duplicate_distance = 6
|
||||
elefant_foot_compensation = 0.2
|
||||
end_filament_gcode = "; Filament-specific end gcode"
|
||||
end_gcode = G1 E-1 F2100 ; retract\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+2, max_print_height)} F720 ; Move print head up{endif}\nG1 X178 Y178 F4200 ; park print head\n{if max_layer_z < max_print_height}G1 Z{z_offset+min(max_layer_z+30, max_print_height)} F720 ; Move print head further up{endif}\nG4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM221 S100 ; reset flow\nM900 K0 ; reset LA\nM84 ; disable motors\n; max_layer_z = [max_layer_z]
|
||||
ensure_vertical_shell_thickness = 1
|
||||
external_perimeter_acceleration = 800
|
||||
external_perimeter_extrusion_width = 0.45
|
||||
external_perimeter_speed = 30
|
||||
external_perimeters_first = 0
|
||||
extra_loading_move = -2
|
||||
extra_perimeters = 0
|
||||
extruder_clearance_height = 20
|
||||
extruder_clearance_radius = 35
|
||||
extruder_colour = ""
|
||||
extruder_offset = 0x0
|
||||
extrusion_axis = E
|
||||
extrusion_multiplier = 1
|
||||
extrusion_width = 0.45
|
||||
fan_always_on = 1
|
||||
fan_below_layer_time = 100
|
||||
filament_colour = #FF8000
|
||||
filament_cooling_final_speed = 3.4
|
||||
filament_cooling_initial_speed = 2.2
|
||||
filament_cooling_moves = 4
|
||||
filament_cost = 36.29
|
||||
filament_density = 1.24
|
||||
filament_deretract_speed = nil
|
||||
filament_diameter = 1.75
|
||||
filament_load_time = 0
|
||||
filament_loading_speed = 28
|
||||
filament_loading_speed_start = 3
|
||||
filament_max_volumetric_speed = 15
|
||||
filament_minimal_purge_on_wipe_tower = 15
|
||||
filament_notes = "Affordable filament for everyday printing in premium quality manufactured in-house by Josef Prusa"
|
||||
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_retract_before_travel = nil
|
||||
filament_retract_before_wipe = nil
|
||||
filament_retract_layer_change = nil
|
||||
filament_retract_length = nil
|
||||
filament_retract_lift = nil
|
||||
filament_retract_lift_above = nil
|
||||
filament_retract_lift_below = nil
|
||||
filament_retract_restart_extra = nil
|
||||
filament_retract_speed = nil
|
||||
filament_settings_id = "Prusament PLA"
|
||||
filament_soluble = 0
|
||||
filament_spool_weight = 201
|
||||
filament_toolchange_delay = 0
|
||||
filament_type = PLA
|
||||
filament_unload_time = 0
|
||||
filament_unloading_speed = 90
|
||||
filament_unloading_speed_start = 100
|
||||
filament_vendor = Prusa Polymers
|
||||
filament_wipe = nil
|
||||
fill_angle = 45
|
||||
fill_density = 15%
|
||||
fill_pattern = gyroid
|
||||
first_layer_acceleration = 600
|
||||
first_layer_acceleration_over_raft = 0
|
||||
first_layer_bed_temperature = 60
|
||||
first_layer_extrusion_width = 0.42
|
||||
first_layer_height = 0.2
|
||||
first_layer_speed = 20
|
||||
first_layer_speed_over_raft = 30
|
||||
first_layer_temperature = 215
|
||||
full_fan_speed_layer = 4
|
||||
fuzzy_skin = none
|
||||
fuzzy_skin_point_dist = 0.8
|
||||
fuzzy_skin_thickness = 0.3
|
||||
gap_fill_enabled = 1
|
||||
gap_fill_speed = 40
|
||||
gcode_comments = 0
|
||||
gcode_flavor = marlin2
|
||||
gcode_label_objects = 1
|
||||
gcode_resolution = 0.0125
|
||||
gcode_substitutions =
|
||||
high_current_on_filament_swap = 0
|
||||
host_type = octoprint
|
||||
infill_acceleration = 1500
|
||||
infill_anchor = 2.5
|
||||
infill_anchor_max = 12
|
||||
infill_every_layers = 1
|
||||
infill_extruder = 1
|
||||
infill_extrusion_width = 0.45
|
||||
infill_first = 0
|
||||
infill_only_where_needed = 0
|
||||
infill_overlap = 10%
|
||||
infill_speed = 80
|
||||
interface_shells = 0
|
||||
ironing = 0
|
||||
ironing_flowrate = 15%
|
||||
ironing_spacing = 0.1
|
||||
ironing_speed = 15
|
||||
ironing_type = top
|
||||
layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z]
|
||||
layer_height = 0.2
|
||||
machine_limits_usage = emit_to_gcode
|
||||
machine_max_acceleration_e = 5000
|
||||
machine_max_acceleration_extruding = 2000
|
||||
machine_max_acceleration_retracting = 1250
|
||||
machine_max_acceleration_travel = 2500
|
||||
machine_max_acceleration_x = 2500
|
||||
machine_max_acceleration_y = 2500
|
||||
machine_max_acceleration_z = 400
|
||||
machine_max_feedrate_e = 80
|
||||
machine_max_feedrate_x = 180
|
||||
machine_max_feedrate_y = 180
|
||||
machine_max_feedrate_z = 12
|
||||
machine_max_jerk_e = 10
|
||||
machine_max_jerk_x = 8
|
||||
machine_max_jerk_y = 8
|
||||
machine_max_jerk_z = 2
|
||||
machine_min_extruding_rate = 0
|
||||
machine_min_travel_rate = 0
|
||||
max_fan_speed = 100
|
||||
max_layer_height = 0.25
|
||||
max_print_height = 180
|
||||
max_print_speed = 150
|
||||
max_volumetric_extrusion_rate_slope_negative = 0
|
||||
max_volumetric_extrusion_rate_slope_positive = 0
|
||||
max_volumetric_speed = 0
|
||||
min_bead_width = 85%
|
||||
min_fan_speed = 100
|
||||
min_feature_size = 25%
|
||||
min_layer_height = 0.07
|
||||
min_print_speed = 15
|
||||
min_skirt_length = 4
|
||||
mmu_segmented_region_max_width = 0
|
||||
notes =
|
||||
nozzle_diameter = 0.4
|
||||
only_retract_when_crossing_perimeters = 0
|
||||
ooze_prevention = 0
|
||||
output_filename_format = {input_filename_base}_{layer_height}mm_{printing_filament_types}_{printer_model}_{print_time}.gcode
|
||||
overhangs = 1
|
||||
parking_pos_retraction = 92
|
||||
pause_print_gcode = M601
|
||||
perimeter_acceleration = 900
|
||||
perimeter_extruder = 1
|
||||
perimeter_extrusion_width = 0.45
|
||||
perimeter_generator = arachne
|
||||
perimeter_speed = 40
|
||||
perimeters = 2
|
||||
physical_printer_settings_id =
|
||||
post_process =
|
||||
print_host =
|
||||
print_settings_id = 0.20mm QUALITY @MINI
|
||||
printer_model = MINI
|
||||
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_MINI\n
|
||||
printer_settings_id = Original Prusa MINI & MINI+
|
||||
printer_technology = FFF
|
||||
printer_variant = 0.4
|
||||
printer_vendor =
|
||||
printhost_apikey =
|
||||
printhost_cafile =
|
||||
raft_contact_distance = 0.2
|
||||
raft_expansion = 1.5
|
||||
raft_first_layer_density = 90%
|
||||
raft_first_layer_expansion = 3
|
||||
raft_layers = 0
|
||||
remaining_times = 1
|
||||
resolution = 0
|
||||
retract_before_travel = 1.5
|
||||
retract_before_wipe = 70%
|
||||
retract_layer_change = 1
|
||||
retract_length = 3.2
|
||||
retract_length_toolchange = 4
|
||||
retract_lift = 0.2
|
||||
retract_lift_above = 0
|
||||
retract_lift_below = 179
|
||||
retract_restart_extra = 0
|
||||
retract_restart_extra_toolchange = 0
|
||||
retract_speed = 70
|
||||
seam_position = aligned
|
||||
silent_mode = 0
|
||||
single_extruder_multi_material = 0
|
||||
single_extruder_multi_material_priming = 1
|
||||
skirt_distance = 2
|
||||
skirt_height = 3
|
||||
skirts = 1
|
||||
slice_closing_radius = 0.049
|
||||
slicing_mode = regular
|
||||
slowdown_below_layer_time = 10
|
||||
small_perimeter_speed = 25
|
||||
solid_infill_acceleration = 1500
|
||||
solid_infill_below_area = 0
|
||||
solid_infill_every_layers = 0
|
||||
solid_infill_extruder = 1
|
||||
solid_infill_extrusion_width = 0.45
|
||||
solid_infill_speed = 80
|
||||
spiral_vase = 0
|
||||
standby_temperature_delta = -5
|
||||
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.01{elsif nozzle_diameter[0]==0.6}0.04{else}0.05{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K18{elsif nozzle_diameter[0]==0.8};{else}M900 K30{endif} ; Filament gcode LA 1.0"
|
||||
start_gcode = M862.3 P "[printer_model]" ; printer model check\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S170 ; set extruder temp for bed leveling\nM140 S[first_layer_bed_temperature] ; set bed temp\nM109 R170 ; wait for bed leveling temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM204 T1250 ; set travel acceleration\nG28 ; home all without mesh bed level\nG29 ; mesh bed leveling \nM204 T[machine_max_acceleration_travel] ; restore travel acceleration\nM104 S[first_layer_temperature] ; set extruder temp\nG92 E0\nG1 Y-2 X179 F2400\nG1 Z3 F720\nM109 S[first_layer_temperature] ; wait for extruder temp\n\n; intro line\nG1 X170 F1000\nG1 Z0.2 F720\nG1 X110 E8 F900\nG1 X40 E10 F700\nG92 E0\n\nM221 S95 ; set flow
|
||||
support_material = 0
|
||||
support_material_angle = 0
|
||||
support_material_auto = 1
|
||||
support_material_bottom_contact_distance = 0
|
||||
support_material_bottom_interface_layers = 0
|
||||
support_material_buildplate_only = 0
|
||||
support_material_closing_radius = 2
|
||||
support_material_contact_distance = 0.2
|
||||
support_material_enforce_layers = 0
|
||||
support_material_extruder = 0
|
||||
support_material_extrusion_width = 0.35
|
||||
support_material_interface_contact_loops = 0
|
||||
support_material_interface_extruder = 0
|
||||
support_material_interface_layers = 2
|
||||
support_material_interface_pattern = rectilinear
|
||||
support_material_interface_spacing = 0.2
|
||||
support_material_interface_speed = 80%
|
||||
support_material_pattern = rectilinear
|
||||
support_material_spacing = 2
|
||||
support_material_speed = 40
|
||||
support_material_style = grid
|
||||
support_material_synchronize_layers = 0
|
||||
support_material_threshold = 50
|
||||
support_material_with_sheath = 0
|
||||
support_material_xy_spacing = 60%
|
||||
temperature = 215
|
||||
template_custom_gcode =
|
||||
thick_bridges = 0
|
||||
thin_walls = 0
|
||||
threads = 20
|
||||
thumbnails = 16x16,220x124
|
||||
thumbnails_format = PNG
|
||||
toolchange_gcode =
|
||||
top_fill_pattern = monotoniclines
|
||||
top_infill_extrusion_width = 0.4
|
||||
top_solid_infill_acceleration = 800
|
||||
top_solid_infill_speed = 40
|
||||
top_solid_layers = 6
|
||||
top_solid_min_thickness = 0.7
|
||||
travel_speed = 150
|
||||
travel_speed_z = 12
|
||||
use_firmware_retraction = 0
|
||||
use_relative_e_distances = 1
|
||||
use_volumetric_e = 0
|
||||
variable_layer_height = 1
|
||||
wall_distribution_count = 1
|
||||
wall_transition_angle = 10
|
||||
wall_transition_filter_deviation = 25%
|
||||
wall_transition_length = 100%
|
||||
wipe = 1
|
||||
wipe_into_infill = 0
|
||||
wipe_into_objects = 0
|
||||
wipe_tower = 0
|
||||
wipe_tower_bridging = 10
|
||||
wipe_tower_brim_width = 2
|
||||
wipe_tower_no_sparse_layers = 0
|
||||
wipe_tower_rotation_angle = 0
|
||||
wipe_tower_width = 60
|
||||
wipe_tower_x = 170
|
||||
wipe_tower_y = 140
|
||||
wiping_volumes_extruders = 70,70
|
||||
wiping_volumes_matrix = 0
|
||||
xy_size_compensation = 0
|
||||
z_offset = 0
|
@ -21,6 +21,10 @@ abstract class AbstractOpenScadBinaryRenderer implements Renderer
|
||||
$skipQuotes = false;
|
||||
if ($argument === self::TARGET_FILE_PLACEHOLDER) {
|
||||
$argument = $outputFile;
|
||||
if ($this->isFlatpak()) {
|
||||
$argument = "@@ '{$argument}' @@";
|
||||
$skipQuotes = true;
|
||||
}
|
||||
}
|
||||
if ($argument === self::SCAD_FILE_PLACEHOLDER) {
|
||||
$renderer = new ScadFileRenderer();
|
||||
@ -29,7 +33,7 @@ abstract class AbstractOpenScadBinaryRenderer implements Renderer
|
||||
|
||||
$argument = $file;
|
||||
if ($this->isFlatpak()) {
|
||||
$argument = "@@ {$argument} @@";
|
||||
$argument = "@@ '{$argument}' @@";
|
||||
$skipQuotes = true;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user