This commit is contained in:
Jaime van Kessel 2016-04-08 15:02:30 +02:00
commit dc1630c268
11 changed files with 130 additions and 162 deletions

View file

@ -49,7 +49,7 @@ class ConvexHullJob(Job):
# Then, do a Minkowski hull with a simple 1x1 quad to outset and round the normal convex hull. # Then, do a Minkowski hull with a simple 1x1 quad to outset and round the normal convex hull.
# This is done because of rounding errors. # This is done because of rounding errors.
hull = hull.getMinkowskiHull(Polygon(numpy.array([[-1, -1], [-1, 1], [1, 1], [1, -1]], numpy.float32))) hull = hull.getMinkowskiHull(Polygon(numpy.array([[-0.5, -0.5], [-0.5, 0.5], [0.5, 0.5], [0.5, -0.5]], numpy.float32)))
profile = Application.getInstance().getMachineManager().getWorkingProfile() profile = Application.getInstance().getMachineManager().getWorkingProfile()
if profile: if profile:

View file

@ -28,9 +28,10 @@ class ChangeLog(Extension, QObject,):
self._version = Version(version_string) self._version = Version(version_string)
else: else:
self._version = None self._version = None
self._change_logs = None self._change_logs = None
Application.getInstance().engineCreatedSignal.connect(self._onEngineCreated) Application.getInstance().engineCreatedSignal.connect(self._onEngineCreated)
Preferences.getInstance().addPreference("general/latest_version_changelog_shown", "15.05.90") #First version of CURA with uranium Preferences.getInstance().addPreference("general/latest_version_changelog_shown", "2.0.0") #First version of CURA with uranium
self.addMenuItem(catalog.i18nc("@item:inmenu", "Show Changelog"), self.showChangelog) self.addMenuItem(catalog.i18nc("@item:inmenu", "Show Changelog"), self.showChangelog)
#self.showChangelog() #self.showChangelog()
@ -42,7 +43,6 @@ class ChangeLog(Extension, QObject,):
@pyqtSlot(result = str) @pyqtSlot(result = str)
def getChangeLogString(self): def getChangeLogString(self):
logs = self.getChangeLogs() logs = self.getChangeLogs()
latest_version = Version(Preferences.getInstance().getValue("general/latest_version_changelog_shown")) #TODO: @UnusedVariable
result = "" result = ""
for version in logs: for version in logs:
result += "<h1>" + str(version) + "</h1><br>" result += "<h1>" + str(version) + "</h1><br>"
@ -58,7 +58,7 @@ class ChangeLog(Extension, QObject,):
def loadChangeLogs(self): def loadChangeLogs(self):
self._change_logs = collections.OrderedDict() self._change_logs = collections.OrderedDict()
with open(os.path.join(PluginRegistry.getInstance().getPluginPath("ChangeLogPlugin"), "ChangeLog.txt"), "r",-1, "utf-8") as f: with open(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "ChangeLog.txt"), "r",-1, "utf-8") as f:
open_version = None open_version = None
open_header = None open_header = None
for line in f: for line in f:
@ -78,12 +78,19 @@ class ChangeLog(Extension, QObject,):
def _onEngineCreated(self): def _onEngineCreated(self):
if not self._version: if not self._version:
return #We're on dev branch. return #We're on dev branch.
#if self._version > Preferences.getInstance().getValue("general/latest_version_changelog_shown"):
#self.showChangelog() if Preferences.getInstance().getValue("general/latest_version_changelog_shown") == "master":
latest_version_shown = Version("0.0.0")
else:
latest_version_shown = Version(Preferences.getInstance().getValue("general/latest_version_changelog_shown"))
if self._version > latest_version_shown:
self.showChangelog()
def showChangelog(self): def showChangelog(self):
if not self._changelog_window: if not self._changelog_window:
self.createChangelogWindow() self.createChangelogWindow()
self._changelog_window.show() self._changelog_window.show()
Preferences.getInstance().setValue("general/latest_version_changelog_shown", Application.getInstance().getVersion()) Preferences.getInstance().setValue("general/latest_version_changelog_shown", Application.getInstance().getVersion())
@ -92,7 +99,8 @@ class ChangeLog(Extension, QObject,):
self._changelog_window.hide() self._changelog_window.hide()
def createChangelogWindow(self): def createChangelogWindow(self):
path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("ChangeLogPlugin"), "ChangeLog.qml")) path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "ChangeLog.qml"))
component = QQmlComponent(Application.getInstance()._engine, path) component = QQmlComponent(Application.getInstance()._engine, path)
self._changelog_context = QQmlContext(Application.getInstance()._engine.rootContext()) self._changelog_context = QQmlContext(Application.getInstance()._engine.rootContext())
self._changelog_context.setContextProperty("manager", self) self._changelog_context.setContextProperty("manager", self)

View file

@ -1,55 +1,49 @@
[2.0.0] [2.1.0]
*Naming changes *2.1 Beta release
Infill prints after perimeters → Infill Before Walls Cura has been completely reengineered from the ground up for an even more seamless integration between hardware, software and materials. Together with its intuitive new user interface, its now also ready for any future developments. For the beginner Cura makes 3D printing incredibly easy, and for more advanced users, there are over 140 new customisable settings.
Initial layer thickness → Initial Layer Height
Structure type → Pattern
Cool head lift → Lift Head
Combine everything (Type-A) → Union Overlapping Volumes
Combine everything (Type-B) → Remove All Holes
Keep open faces Keep Disconnected → Faces
Only follow mesh surface → Surface Mode
*All at Once/One at a Time *Select Multiple Objects
Curas default mode is set to All At Once. You can print multiple objects faster with the option print objects One At A Time. This can be changed in Advanced Settings. Please note that in One At A Time mode, grouped objects will still be printed as a single object.
*Setting Profiles
Now you can create preferred setting favourites and share them with others.
*Post-Processing Plugin
This plugin supports post-processing on the GCode generated by the engine allowing for custom scripts. For example, Pause At Height and Tweak At Z.
*Support for Bed Levelling and other wizards
We have restored the Bed Levelling function and several other wizards that were previously available for the Ultimaker Original. Additionally, these are ready to be used with machines from other vendors (BQ, Rep Rap neo).
*Third-Party Printer Profiles
We received printer profiles for third-party vendors (BQ, Rep Rap neo) from the community (thanks guys!). These have been included in this release.
*3MF File Loading Support (New)
Were happy to report we now support loading 3MF files. This is a new file format similar to AMF, but freely available.
*Output Device API for Developers (New)
The Storage Device API has now been replaced with the Output Device API for saving files. Its designed to make it easier for anyone that wants to write a plugin giving them some form of output device, whether its a printer or a web service.
*Improved Cut-Off Object Bottom (New)
Weve added a feature than allows you to move objects below the build plate. You can either correct a model with a rough bottom, or print only a part of an object. Please note that the implementation greatly differs from the old one where it was a setting.
*Improved File Saving (new)
Were happy to report that the way file saving is handled has received a huge overhaul. Now the default action is to save everything on the build plate to a file.
*Select Multiple Objects (New)
You now have the freedom to select and manipulate multiple objects at the same time. You now have the freedom to select and manipulate multiple objects at the same time.
*Grouping (New) *Grouping
You can now group objects together to make it easier to manipulate multiple objects. You can now group objects together to make it easier to manipulate multiple objects.
*Per-Object Settings (New) *Undo/Redo
You can now select different profiles for different objects and in advance mode override individual settings. You can now undo and redo your actions, like moving an object or scaling.
*64-bit Windows Builds (New) *Setting Profiles
Cura now allows 64-bit Windows builds in addition to the 32-bit builds. For users running the 64-bit version of Windows, you can now load models in more detail. The new GUI allows custom profiles to load easily and intuitively, directly from Cura.
*Fuzzy skin mode (New) *3MF File Loading Support
A new engine feature that enables objects to be printed as if they have a fuzzy skin. Were happy to report we now support loading 3MF files. This is a new file format similar to AMF, but freely available.
*Z-seam alignment (New) *Intuitive Cut-Off Object Bottom
Weve added a feature that allows you to move objects below the build plate. You can either correct a model with a rough bottom, or print only a part of an object. Please note that the implementation differs greatly from the old one when it was just a setting.
*64-bit Windows Builds
An optimized 64-bit Windows Cura version is now available. This allows you to load larger model files.
*Automatic calculations
Cura allows you to set a number of lines/layers instead of millimeters. The engine automatically calculates the right settings.
*Per-Object Settings
You can now override individual settings for different objects in advanced mode.
*Fuzzy Skin
Prints the outer walls with a jittering motion to give your object a diffused finish.
*Wire Printing
The object is printed with a mid-air / net-like structure, following the mesh surface. The build plate will move up and down during diagonal segments. Though not visible in layer view, you can view the result in other software, such as Repetier Host or http://chilipeppr.com/tinyg.
* Conical Support
An experimental filament, cost-reduction feature, for support.
*Support Towers
Specialized support for tiny overhang areas.
*ZigZag infill
A new, infill type thats easily breakable, introduced specially for support.
* Avoid Printed Parts
While combing, the print head moves around printed parts, avoiding collisions with the nozzle and a part thats already printed.

View file

@ -12,7 +12,7 @@ def getMetaData():
"name": catalog.i18nc("@label", "Changelog"), "name": catalog.i18nc("@label", "Changelog"),
"author": "Ultimaker", "author": "Ultimaker",
"version": "1.0", "version": "1.0",
"description": catalog.i18nc("@info:whatsthis", "Shows changes since latest checked version."), "description": catalog.i18nc("@info:whatsthis", "Shows changes since latest checked version."),
"api": 2 "api": 2
} }
} }

View file

@ -2,14 +2,12 @@ syntax = "proto3";
package cura.proto; package cura.proto;
message ObjectList message ObjectList
{ {
repeated Object objects = 1; repeated Object objects = 1;
repeated Setting settings = 2; repeated Setting settings = 2;
} }
// typeid 1
message Slice message Slice
{ {
repeated ObjectList object_lists = 1; repeated ObjectList object_lists = 1;
@ -24,28 +22,13 @@ message Object
repeated Setting settings = 5; // Setting override per object, overruling the global settings. repeated Setting settings = 5; // Setting override per object, overruling the global settings.
} }
// typeid 3
message Progress message Progress
{ {
float amount = 1; float amount = 1;
} }
// typeid 2
message SlicedObjectList
{
repeated SlicedObject objects = 1;
}
message SlicedObject
{
int64 id = 1;
repeated Layer layers = 2;
}
message Layer { message Layer {
int32 id = 1; int32 id = 1;
float height = 2; float height = 2;
float thickness = 3; float thickness = 3;
@ -70,20 +53,16 @@ message Polygon {
float line_width = 3; float line_width = 3;
} }
// typeid 4
message GCodeLayer { message GCodeLayer {
int64 id = 1;
bytes data = 2; bytes data = 2;
} }
// typeid 5
message ObjectPrintTime { message ObjectPrintTime {
int64 id = 1; int64 id = 1;
float time = 2; float time = 2;
float material_amount = 3; float material_amount = 3;
} }
// typeid 6
message SettingList { message SettingList {
repeated Setting settings = 1; repeated Setting settings = 1;
} }
@ -94,11 +73,9 @@ message Setting {
bytes value = 2; bytes value = 2;
} }
// typeid 7
message GCodePrefix { message GCodePrefix {
bytes data = 2; bytes data = 2;
} }
// typeid 8
message SlicingFinished { message SlicingFinished {
} }

View file

@ -11,7 +11,8 @@ from UM.Qt.Bindings.BackendProxy import BackendState #To determine the state of
from UM.Message import Message from UM.Message import Message
from UM.PluginRegistry import PluginRegistry from UM.PluginRegistry import PluginRegistry
from . import ProcessSlicedObjectListJob from cura.OneAtATimeIterator import OneAtATimeIterator
from . import ProcessSlicedLayersJob
from . import ProcessGCodeJob from . import ProcessGCodeJob
from . import StartSliceJob from . import StartSliceJob
@ -46,7 +47,7 @@ class CuraEngineBackend(Backend):
self._layer_view_active = False self._layer_view_active = False
Application.getInstance().getController().activeViewChanged.connect(self._onActiveViewChanged) Application.getInstance().getController().activeViewChanged.connect(self._onActiveViewChanged)
self._onActiveViewChanged() self._onActiveViewChanged()
self._stored_layer_data = None self._stored_layer_data = []
# When there are current settings and machine instance is changed, there is no profile changed event. We should # When there are current settings and machine instance is changed, there is no profile changed event. We should
# pretend there is though. # pretend there is though.
@ -61,7 +62,7 @@ class CuraEngineBackend(Backend):
self._change_timer.setSingleShot(True) self._change_timer.setSingleShot(True)
self._change_timer.timeout.connect(self.slice) self._change_timer.timeout.connect(self.slice)
self._message_handlers["cura.proto.SlicedObjectList"] = self._onSlicedObjectListMessage self._message_handlers["cura.proto.Layer"] = self._onLayerMessage
self._message_handlers["cura.proto.Progress"] = self._onProgressMessage self._message_handlers["cura.proto.Progress"] = self._onProgressMessage
self._message_handlers["cura.proto.GCodeLayer"] = self._onGCodeLayerMessage self._message_handlers["cura.proto.GCodeLayer"] = self._onGCodeLayerMessage
self._message_handlers["cura.proto.GCodePrefix"] = self._onGCodePrefixMessage self._message_handlers["cura.proto.GCodePrefix"] = self._onGCodePrefixMessage
@ -85,7 +86,7 @@ class CuraEngineBackend(Backend):
Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onInstanceChanged) Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onInstanceChanged)
## Get the command that is used to call the engine. ## Get the command that is used to call the engine.
# This is useful for debugging and used to actually start the engine # This is usefull for debugging and used to actually start the engine
# \return list of commands and args / parameters. # \return list of commands and args / parameters.
def getEngineCommand(self): def getEngineCommand(self):
active_machine = Application.getInstance().getMachineManager().getActiveMachineInstance() active_machine = Application.getInstance().getMachineManager().getActiveMachineInstance()
@ -152,6 +153,7 @@ class CuraEngineBackend(Backend):
def _terminate(self): def _terminate(self):
self._slicing = False self._slicing = False
self._restart = True self._restart = True
self._stored_layer_data = []
self.slicingCancelled.emit() self.slicingCancelled.emit()
self.processingProgress.emit(0) self.processingProgress.emit(0)
Logger.log("d", "Attempting to kill the engine process") Logger.log("d", "Attempting to kill the engine process")
@ -208,12 +210,9 @@ class CuraEngineBackend(Backend):
def _onSettingChanged(self, setting): def _onSettingChanged(self, setting):
self._onChanged() self._onChanged()
def _onSlicedObjectListMessage(self, message): def _onLayerMessage(self, message):
if self._layer_view_active: self._stored_layer_data.append(message)
self._process_layers_job = ProcessSlicedObjectListJob.ProcessSlicedObjectListJob(message)
self._process_layers_job.start()
else :
self._stored_layer_data = message
def _onProgressMessage(self, message): def _onProgressMessage(self, message):
if self._message: if self._message:
@ -233,6 +232,11 @@ class CuraEngineBackend(Backend):
self._message.hide() self._message.hide()
self._message = None self._message = None
if self._layer_view_active and (self._process_layers_job is None or not self._process_layers_job.isRunning()):
self._process_layers_job = ProcessSlicedLayersJob.ProcessSlicedLayersJob(self._stored_layer_data)
self._process_layers_job.start()
self._stored_layer_data = []
def _onGCodeLayerMessage(self, message): def _onGCodeLayerMessage(self, message):
self._scene.gcode_list.append(message.data.decode("utf-8", "replace")) self._scene.gcode_list.append(message.data.decode("utf-8", "replace"))
@ -262,7 +266,7 @@ class CuraEngineBackend(Backend):
def _onToolOperationStarted(self, tool): def _onToolOperationStarted(self, tool):
self._terminate() # Do not continue slicing once a tool has started self._terminate() # Do not continue slicing once a tool has started
self._enabled = False # Do not reslice when a tool is doing its 'thing' self._enabled = False # Do not reslice when a tool is doing it's 'thing'
def _onToolOperationStopped(self, tool): def _onToolOperationStopped(self, tool):
self._enabled = True # Tool stop, start listening for changes again. self._enabled = True # Tool stop, start listening for changes again.
@ -275,9 +279,9 @@ class CuraEngineBackend(Backend):
# There is data and we're not slicing at the moment # There is data and we're not slicing at the moment
# if we are slicing, there is no need to re-calculate the data as it will be invalid in a moment. # if we are slicing, there is no need to re-calculate the data as it will be invalid in a moment.
if self._stored_layer_data and not self._slicing: if self._stored_layer_data and not self._slicing:
self._process_layers_job = ProcessSlicedObjectListJob.ProcessSlicedObjectListJob(self._stored_layer_data) self._process_layers_job = ProcessSlicedLayersJob.ProcessSlicedLayersJob(self._stored_layer_data)
self._process_layers_job.start() self._process_layers_job.start()
self._stored_layer_data = None self._stored_layer_data = []
else: else:
self._layer_view_active = False self._layer_view_active = False

View file

@ -1,4 +1,4 @@
# Copyright (c) 2015 Ultimaker B.V. # Copyright (c) 2016 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher. # Cura is released under the terms of the AGPLv3 or higher.
from UM.Job import Job from UM.Job import Job
@ -19,10 +19,10 @@ import numpy
catalog = i18nCatalog("cura") catalog = i18nCatalog("cura")
class ProcessSlicedObjectListJob(Job): class ProcessSlicedLayersJob(Job):
def __init__(self, message): def __init__(self, layers):
super().__init__() super().__init__()
self._message = message self._layers = layers
self._scene = Application.getInstance().getController().getScene() self._scene = Application.getInstance().getController().getScene()
self._progress = None self._progress = None
self._abort_requested = False self._abort_requested = False
@ -50,13 +50,12 @@ class ProcessSlicedObjectListJob(Job):
object_id_map = {} object_id_map = {}
new_node = SceneNode() new_node = SceneNode()
## Put all nodes in a dictionary identified by ID
## Remove old layer data (if any)
for node in DepthFirstIterator(self._scene.getRoot()): for node in DepthFirstIterator(self._scene.getRoot()):
if type(node) is SceneNode and node.getMeshData(): if type(node) is SceneNode and node.getMeshData():
if node.callDecoration("getLayerData"): if node.callDecoration("getLayerData"):
self._scene.getRoot().removeChild(node) self._scene.getRoot().removeChild(node)
else:
object_id_map[id(node)] = node
Job.yieldThread() Job.yieldThread()
if self._abort_requested: if self._abort_requested:
if self._progress: if self._progress:
@ -67,56 +66,45 @@ class ProcessSlicedObjectListJob(Job):
mesh = MeshData() mesh = MeshData()
layer_data = LayerData.LayerData() layer_data = LayerData.LayerData()
layer_count = len(self._layers)
layer_count = 0
for i in range(self._message.repeatedMessageCount("objects")):
layer_count += self._message.getRepeatedMessage("objects", i).repeatedMessageCount("layers")
current_layer = 0 current_layer = 0
for object_position in range(self._message.repeatedMessageCount("objects")):
current_object = self._message.getRepeatedMessage("objects", object_position)
try:
node = object_id_map[current_object.id]
except KeyError:
continue
for l in range(current_object.repeatedMessageCount("layers")): for layer in self._layers:
layer = current_object.getRepeatedMessage("layers", l) layer_data.addLayer(layer.id)
layer_data.setLayerHeight(layer.id, layer.height)
layer_data.setLayerThickness(layer.id, layer.thickness)
layer_data.addLayer(layer.id) for p in range(layer.repeatedMessageCount("polygons")):
layer_data.setLayerHeight(layer.id, layer.height) polygon = layer.getRepeatedMessage("polygons", p)
layer_data.setLayerThickness(layer.id, layer.thickness)
for p in range(layer.repeatedMessageCount("polygons")): points = numpy.fromstring(polygon.points, dtype="i8") # Convert bytearray to numpy array
polygon = layer.getRepeatedMessage("polygons", p) points = points.reshape((-1,2)) # We get a linear list of pairs that make up the points, so make numpy interpret them correctly.
points = numpy.fromstring(polygon.points, dtype="i8") # Convert bytearray to numpy array # Create a new 3D-array, copy the 2D points over and insert the right height.
points = points.reshape((-1,2)) # We get a linear list of pairs that make up the points, so make numpy interpret them correctly. # This uses manual array creation + copy rather than numpy.insert since this is
# faster.
new_points = numpy.empty((len(points), 3), numpy.float32)
new_points[:,0] = points[:,0]
new_points[:,1] = layer.height
new_points[:,2] = -points[:,1]
# Create a new 3D-array, copy the 2D points over and insert the right height. new_points /= 1000
# This uses manual array creation + copy rather than numpy.insert since this is
# faster.
new_points = numpy.empty((len(points), 3), numpy.float32)
new_points[:,0] = points[:,0]
new_points[:,1] = layer.height
new_points[:,2] = -points[:,1]
new_points /= 1000 layer_data.addPolygon(layer.id, polygon.type, new_points, polygon.line_width)
layer_data.addPolygon(layer.id, polygon.type, new_points, polygon.line_width)
Job.yieldThread()
Job.yieldThread() Job.yieldThread()
current_layer += 1 Job.yieldThread()
progress = (current_layer / layer_count) * 100 current_layer += 1
# TODO: Rebuild the layer data mesh once the layer has been processed. progress = (current_layer / layer_count) * 100
# This needs some work in LayerData so we can add the new layers instead of recreating the entire mesh. # TODO: Rebuild the layer data mesh once the layer has been processed.
# This needs some work in LayerData so we can add the new layers instead of recreating the entire mesh.
if self._abort_requested: if self._abort_requested:
if self._progress:
self._progress.hide()
return
if self._progress: if self._progress:
self._progress.setProgress(progress) self._progress.hide()
return
if self._progress:
self._progress.setProgress(progress)
# We are done processing all the layers we got from the engine, now create a mesh out of the data # We are done processing all the layers we got from the engine, now create a mesh out of the data
layer_data.build() layer_data.build()

View file

@ -15,16 +15,19 @@ import plistlib
class OSXRemovableDrivePlugin(RemovableDrivePlugin.RemovableDrivePlugin): class OSXRemovableDrivePlugin(RemovableDrivePlugin.RemovableDrivePlugin):
def checkRemovableDrives(self): def checkRemovableDrives(self):
drives = {} drives = {}
p = subprocess.Popen(["system_profiler", "SPUSBDataType", "-xml"], stdout=subprocess.PIPE) p = subprocess.Popen(["system_profiler", "SPUSBDataType", "-xml"], stdout = subprocess.PIPE)
plist = plistlib.loads(p.communicate()[0]) plist = plistlib.loads(p.communicate()[0])
p.wait() p.wait()
for dev in self._findInTree(plist, "Mass Storage Device"): for entry in plist:
if "removable_media" in dev and dev["removable_media"] == "yes" and "volumes" in dev and len(dev["volumes"]) > 0: if "_items" in entry:
for vol in dev["volumes"]: for item in entry["_items"]:
if "mount_point" in vol: for dev in item["_items"]:
volume = vol["mount_point"] if "removable_media" in dev and dev["removable_media"] == "yes" and "volumes" in dev and len(dev["volumes"]) > 0:
drives[volume] = os.path.basename(volume) for vol in dev["volumes"]:
if "mount_point" in vol:
volume = vol["mount_point"]
drives[volume] = os.path.basename(volume)
p = subprocess.Popen(["system_profiler", "SPCardReaderDataType", "-xml"], stdout=subprocess.PIPE) p = subprocess.Popen(["system_profiler", "SPCardReaderDataType", "-xml"], stdout=subprocess.PIPE)
plist = plistlib.loads(p.communicate()[0]) plist = plistlib.loads(p.communicate()[0])
@ -52,15 +55,3 @@ class OSXRemovableDrivePlugin(RemovableDrivePlugin.RemovableDrivePlugin):
return False return False
else: else:
return True return True
def _findInTree(self, t, n):
ret = []
if type(t) is dict:
if "_name" in t and t["_name"] == n:
ret.append(t)
for k, v in t.items(): # TODO: @UnusedVariable "k"
ret += self._findInTree(v, n)
if type(t) is list:
for v in t:
ret += self._findInTree(v, n)
return ret

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before After
Before After

View file

@ -70,10 +70,10 @@
"machine_use_extruder_offset_to_offset_coords": { "default": true }, "machine_use_extruder_offset_to_offset_coords": { "default": true },
"machine_gcode_flavor": { "default": "UltiGCode" }, "machine_gcode_flavor": { "default": "UltiGCode" },
"machine_disallowed_areas": { "default": [ "machine_disallowed_areas": { "default": [
[[-115.0, 112.5], [ -82.0, 112.5], [ -84.0, 104.5], [-115.0, 104.5]], [[-115.0, 112.5], [ -82.0, 112.5], [ -84.0, 102.5], [-115.0, 102.5]],
[[ 115.0, 112.5], [ 115.0, 104.5], [ 110.0, 104.5], [ 108.0, 112.5]], [[ 115.0, 112.5], [ 115.0, 102.5], [ 110.0, 102.5], [ 108.0, 112.5]],
[[-115.0, -112.5], [-115.0, -104.5], [ -84.0, -104.5], [ -82.0, -112.5]], [[-115.0, -112.5], [-115.0, -104.5], [ -84.0, -104.5], [ -82.0, -112.5]],
[[ 115.0, -112.5], [ 108.0, -112.5], [ 110.0, -104.5], [ 115.0, -104.5]] [[ 115.0, -112.5], [ 108.0, -112.5], [ 110.0, -104.5], [ 115.0, -104.5]]
]}, ]},
"machine_platform_offset": { "default": [9.0, 0.0, 0.0] }, "machine_platform_offset": { "default": [9.0, 0.0, 0.0] },

View file

@ -38,6 +38,12 @@
] ]
] ]
}, },
"retraction_amount": { "default": 6.0 } "retraction_amount": { "default": 6.0 },
"machine_disallowed_areas": { "default": [
[[-115.0, 112.5], [ -78.0, 112.5], [ -80.0, 102.5], [-115.0, 102.5]],
[[ 115.0, 112.5], [ 115.0, 102.5], [ 105.0, 102.5], [ 103.0, 112.5]],
[[-115.0, -112.5], [-115.0, -104.5], [ -84.0, -104.5], [ -82.0, -112.5]],
[[ 115.0, -112.5], [ 108.0, -112.5], [ 110.0, -104.5], [ 115.0, -104.5]]
]}
} }
} }