Browse Source

Merge branch 'master' into feature_local_container_server

Ghostkeeper 7 years ago
parent
commit
1029d4509c

+ 1 - 0
.gitignore

@@ -45,6 +45,7 @@ plugins/cura-big-flame-graph
 plugins/cura-siemensnx-plugin
 plugins/CuraVariSlicePlugin
 plugins/CuraLiveScriptingPlugin
+plugins/CuraPrintProfileCreator
 
 #Build stuff
 CMakeCache.txt

+ 0 - 173
CHANGES

@@ -1,173 +0,0 @@
-Cura 15.06 Beta
-===============
-
-This is the *Beta* version of Cura 15.06.
-
-Cura 15.06 is a new release built from the ground up on a completely new
-framework called Uranium. This framework has been designed to make it easier to
-extend Cura with additional functionality as well as provide a cleaner UI.
-
-Changes since 15.05.95
-----------------------
-
-* Fixed: Selection ghost remains visible after deleting an object
-* Fixed: Window does not show up immediately after starting application on OSX
-* Fixed: Added display of rotation angle during rotation
-* Fixed: Object changes position while rotating/scaling
-* Fixed: Loading improvements in the layer view
-* Fixed: Added application icons
-* Fixed: Improved feedback when loading models
-* Fixed: Eject device on MacOSX now provides proper feedback
-* Fixed: Make it possible to show retraction settings for UM2
-* Fixed: Opening the machine preferences page will switch to the first available machine
-* Fixed: Improved tool handle hit area size
-* Fixed: Render lines with a thickness based on screen DPI
-
-Changes since 15.05.94
-----------------------
-
-* Added Russian translations
-* Fixed: Infill not displayed in layer view
-* Fixed: Cannot select/scale/rotate when first activating the tool and then trying to select a model.
-* Fixed: Improved font rendering on Windows
-* Fixed: Help > Show Documentation crashes Cura on Windows
-* Fixed: "There is no disk in the drive" repeating messages on Windows
-* Fixed: Retraction settings not visible for Ultimaker2
-* Fixed: Display rotation angle when rotating an object
-* Fixed: Time/Quality slider values are properly rounded
-* Fixed: Improved clarity of buttons and text
-* Fixed: No indication that anything is happening when loading a model
-* Fixed: Eject device now works on Windows
-
-Changes since 15.05.93
-----------------------
-
-* Fixed: No shortcuts for moving up/down layers in layer view.
-* Fixed: Last view layers could not be scrolled through in layer view.
-* Fixed: Files provided on command line would not actually show up on the build
-  platform.
-* Fixed: Render a ghost of the selection in Layer view to make the actual object
-  position clear.
-* Fixed: Showing a menu would clear the selection.
-* Fixed: Size and scaling factor display for scale tool.
-* Fixed: Missing background for additional tool controls.
-* Fixed: Loading message times out when loading large files.
-* Fixed: Show recent files in the file menu.
-* Fixed: Windows installer will now install MSVC 2010 redistributable, to
-  prevent issues with missing DLL's.
-* Fixed: Collapsed/expanded state of setting categories not stored.
-
-Changes since 15.05.91
-----------------------
-
-* There is now a working MacOSX version. Currently it supports OSX 10.7 and
-  higher.
-* Fixed: Need to deselect before selecting a different object.
-* Fixed: Object can be moved on Z axis.
-* Fixed: Error values should be considered invalid values and will not trigger a
-  slice.
-* Fixed: Text fields used a locale-aware validator while the underlying code did
-  not.
-* Fixed: Text fields will trigger a slice on text change, not only after focus
-  change/enter press.
-* Fixed: Rotate Tool snaps to incorrect value.
-* Fixed: Object Collision would only moved objects to the right.
-* Fixed: Object Collision would move the selected object when it should not.
-* Fixed: Camera panning now works correctly instead of doing nothing.
-* Fixed: Camera would flip around center point at maximum rotation.
-* Fixed: Build platform grid blocked view from below objects.
-* Fixed: Viewport on MacOSX with high-DPI screens was only taking 1/4th of the
-window
-
-Changes since 15.05.90
-----------------------
-
-* Fixed: Additional UI elements for tools and views not loading.
-* Fixed: Double click needed to change setting dialog page.
-* Fixed: Context menu entries (reload, center object, etc.) not working.
-* Fixed: "Open With" or passing files from command line not working.
-* Fixed: "Reload All" would not reload files.
-
-In addition, a lot of work has gone into getting a usable Mac OSX version.
-
-New Features
-------------
-
-* Plugin based system
-  The Uranium framework provides us with a plugin-based system
-  that provides additional flexibility when extending Cura. Think
-  of new views, tools, file formats, etc. This is probably the
-  biggest new feature.
-* Improved UI
-  The UI has received a complete overhaul.
-* Time-Quality Slider
-  The 4 static quick print profiles have been replaced with
-  a slider that should make it easier to find the right spot
-  between print time and print quality.
-* More Settings
-  The Advanced mode is now configurable and can show many
-  additional settings that were previously not available, while at
-  the same time not overwhelming new users with too many settings.
-  Custom set of visible settings can be created by the user.
-* Support for high-DPI screens
-  The refreshed UI has been designed with high-DPI screens in
-  mind which should improve the experience of Cura on such
-  devices.
-* Improved language support
-  (Not yet available for the Beta release.)
-* Improved support structure generation
-  The new version of the CuraEngine now features improved
-  support generation algorithms and additional options for support
-  structure generation.
-* Experimental Feature: Wire Printing
-  Wire Printing has been added as an experimental new feature. It
-  will print objects as a structure of lines. It can be enabled by
-  from Advanced Mode -> Fixes -> Wire Printing.
-* Undo/Redo
-  It is now possible to undo and redo most scene operations, like
-  moving or rotating objects.
-
-Features from earlier versions not (yet) in this release
---------------------------------------------------------
-
-* The All-at-once/One-at-a-time toggle is not available.
-  We are working on an improved implementation of this mechanism
-  but it will not be available for this release.
-* No dual extrusion features are available yet.
-  We are working on a completely new workflow for this but this
-  needs additional time.
-* “Lay Flat” has been removed.
-  The existing implementation was unfortunately not salvageable.
-  We will be looking into an improved implementation for this
-  feature.
-* "Split Object Into Parts" has been removed.
-  Due to the same reason as Lay Flat.
-* Support for AMF and DAE file formats has been removed.
-  Both of these will be implemented as plugins in the future.
-* Support for directly loading a GCode file is not yet available.
-  This will be implemented as a plugin in the future.
-* Support for PNG, JPG and other image formats has been removed.
-  These can be supported by a plugin with an improved UI.
-* Support for loading Minecraft levels has been removed.
-  This can be implemented as a plugin.
-* Windows XP support has been dropped.
-  Microsoft is no longer supporting xp, so they no longer back
-  port certain features that we require.
-* X-Ray view is missing.
-  Will be implemented as a (you might have guessed it) plugin.
-* Fixes: Follow Mesh Surface
-  Has been removed from the engine, the same result can be
-  achieved using no infill or top/bottom layers.
-
-Known Issues
-------------
-
-For an up to date list of all known issues, please see
-https://github.com/Ultimaker/Cura/issues and
-https://github.com/Ultimaker/Uranium/issues .
-
-* Some OBJ files are rendered as black objects due to missing
-  normals.
-* Disabling plugins does not work correctly yet.
-* Unicorn occasionally still requires feeding. Do not feed it
-  after midnight.

+ 2 - 2
cura.desktop.in

@@ -1,6 +1,6 @@
 [Desktop Entry]
-Name=Cura
-Name[de]=Cura
+Name=Ultimaker Cura
+Name[de]=Ultimaker Cura
 GenericName=3D Printing Software
 GenericName[de]=3D-Druck-Software
 Comment=Cura converts 3D models into paths for a 3D printer. It prepares your print for maximum accuracy, minimum printing time and good reliability with many extra features that make your print come out great.

+ 2 - 0
cura/Arrange.py

@@ -52,6 +52,8 @@ class Arrange:
         # Place all objects fixed nodes
         for fixed_node in fixed_nodes:
             vertices = fixed_node.callDecoration("getConvexHull")
+            if not vertices:
+                continue
             points = copy.deepcopy(vertices._points)
             shape_arr = ShapeArray.fromPolygon(points, scale = scale)
             arranger.place(0, 0, shape_arr)

+ 17 - 6
cura/BuildVolume.py

@@ -513,14 +513,13 @@ class BuildVolume(SceneNode):
         update_disallowed_areas = False
         update_raft_thickness = False
         update_extra_z_clearance = True
+
         for setting_key in self._changed_settings_since_last_rebuild:
+
             if setting_key == "print_sequence":
                 machine_height = self._global_container_stack.getProperty("machine_height", "value")
-                if Application.getInstance().getGlobalContainerStack().getProperty("print_sequence",
-                                                                                   "value") == "one_at_a_time" and len(
-                        self._scene_objects) > 1:
-                    self._height = min(self._global_container_stack.getProperty("gantry_height", "value"),
-                                       machine_height)
+                if Application.getInstance().getGlobalContainerStack().getProperty("print_sequence", "value") == "one_at_a_time" and len(self._scene_objects) > 1:
+                    self._height = min(self._global_container_stack.getProperty("gantry_height", "value"), machine_height)
                     if self._height < machine_height:
                         self._build_volume_message.show()
                     else:
@@ -528,9 +527,20 @@ class BuildVolume(SceneNode):
                 else:
                     self._height = self._global_container_stack.getProperty("machine_height", "value")
                     self._build_volume_message.hide()
+                update_disallowed_areas = True
+                rebuild_me = True
+
+            # sometimes the machine size or shape settings are adjusted on the active machine, we should reflect this
+            if setting_key in self._machine_settings:
+                self._height = self._global_container_stack.getProperty("machine_height", "value")
+                self._width = self._global_container_stack.getProperty("machine_width", "value")
+                self._depth = self._global_container_stack.getProperty("machine_depth", "value")
+                self._shape = self._global_container_stack.getProperty("machine_shape", "value")
+                update_extra_z_clearance = True
+                update_disallowed_areas = True
                 rebuild_me = True
 
-            if setting_key in self._skirt_settings or setting_key in self._prime_settings or setting_key in self._tower_settings or setting_key == "print_sequence" or setting_key in self._ooze_shield_settings or setting_key in self._distance_settings or setting_key in self._extruder_settings:
+            if setting_key in self._skirt_settings + self._prime_settings + self._tower_settings + self._ooze_shield_settings + self._distance_settings + self._extruder_settings:
                 update_disallowed_areas = True
                 rebuild_me = True
 
@@ -969,6 +979,7 @@ class BuildVolume(SceneNode):
     def _clamp(self, value, min_value, max_value):
         return max(min(value, max_value), min_value)
 
+    _machine_settings = ["machine_width", "machine_depth", "machine_height", "machine_shape", "machine_center_is_zero"]
     _skirt_settings = ["adhesion_type", "skirt_gap", "skirt_line_count", "skirt_brim_line_width", "brim_width", "brim_line_count", "raft_margin", "draft_shield_enabled", "draft_shield_dist", "initial_layer_line_width_factor"]
     _raft_settings = ["adhesion_type", "raft_base_thickness", "raft_interface_thickness", "raft_surface_layers", "raft_surface_thickness", "raft_airgap", "layer_0_z_overlap"]
     _extra_z_settings = ["retraction_hop_enabled", "retraction_hop"]

+ 5 - 0
cura/ConvexHullDecorator.py

@@ -56,6 +56,11 @@ class ConvexHullDecorator(SceneNodeDecorator):
         if self._node is None:
             return None
 
+        if getattr(self._node, "_non_printing_mesh", False):
+            # infill_mesh, cutting_mesh and anti_overhang_mesh do not need a convex hull
+            # node._non_printing_mesh is set in SettingOverrideDecorator
+            return None
+
         hull = self._compute2DConvexHull()
 
         if self._global_stack and self._node:

+ 13 - 8
cura/CuraApplication.py

@@ -1,6 +1,5 @@
 # Copyright (c) 2017 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
-
 from PyQt5.QtNetwork import QLocalServer
 from PyQt5.QtNetwork import QLocalSocket
 
@@ -32,6 +31,7 @@ from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
 from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation
 from UM.Operations.GroupedOperation import GroupedOperation
 from UM.Operations.SetTransformOperation import SetTransformOperation
+
 from cura.Arrange import Arrange
 from cura.ShapeArray import ShapeArray
 from cura.ConvexHullDecorator import ConvexHullDecorator
@@ -95,10 +95,11 @@ numpy.seterr(all="ignore")
 MYPY = False
 if not MYPY:
     try:
-        from cura.CuraVersion import CuraVersion, CuraBuildType
+        from cura.CuraVersion import CuraVersion, CuraBuildType, CuraDebugMode
     except ImportError:
         CuraVersion = "master"  # [CodeStyle: Reflecting imported value]
         CuraBuildType = ""
+        CuraDebugMode = False
 
 
 class CuraApplication(QtApplication):
@@ -127,6 +128,7 @@ class CuraApplication(QtApplication):
     stacksValidationFinished = pyqtSignal()  # Emitted whenever a validation is finished
 
     def __init__(self):
+
         # this list of dir names will be used by UM to detect an old cura directory
         for dir_name in ["extruders", "machine_instances", "materials", "plugins", "quality", "user", "variants"]:
             Resources.addExpectedDirNameInData(dir_name)
@@ -155,7 +157,6 @@ class CuraApplication(QtApplication):
 
         SettingDefinition.addSettingType("extruder", None, str, Validator)
         SettingDefinition.addSettingType("optional_extruder", None, str, None)
-
         SettingDefinition.addSettingType("[int]", None, str, None)
 
         SettingFunction.registerOperator("extruderValues", ExtruderManager.getExtruderValues)
@@ -181,7 +182,8 @@ class CuraApplication(QtApplication):
         ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.DefinitionChangesContainer, "definition_changes")
 
         ##  Initialise the version upgrade manager with Cura's storage paths.
-        import UM.VersionUpgradeManager #Needs to be here to prevent circular dependencies.
+        #   Needs to be here to prevent circular dependencies.
+        import UM.VersionUpgradeManager
 
         UM.VersionUpgradeManager.VersionUpgradeManager.getInstance().setCurrentVersions(
             {
@@ -207,6 +209,7 @@ class CuraApplication(QtApplication):
         self._additional_components = {} # Components to add to certain areas in the interface
 
         super().__init__(name = "cura", version = CuraVersion, buildtype = CuraBuildType,
+                         is_debug_mode = CuraDebugMode,
                          tray_icon_name = "cura-icon-32.png")
 
         self.default_theme = "cura-light"
@@ -226,7 +229,9 @@ class CuraApplication(QtApplication):
             "TranslateTool",
             "FileLogger",
             "XmlMaterialProfile",
-            "PluginBrowser"
+            "PluginBrowser",
+            "PrepareStage",
+            "MonitorStage"
         ])
         self._physics = None
         self._volume = None
@@ -387,7 +392,6 @@ class CuraApplication(QtApplication):
     def needToShowUserAgreement(self):
         return self._need_to_show_user_agreement
 
-
     def setNeedToShowUserAgreement(self, set_value = True):
         self._need_to_show_user_agreement = set_value
 
@@ -606,14 +610,14 @@ class CuraApplication(QtApplication):
 
         controller = self.getController()
 
+        controller.setActiveStage("PrepareStage")
         controller.setActiveView("SolidView")
-
         controller.setCameraTool("CameraTool")
         controller.setSelectionTool("SelectionTool")
 
         t = controller.getTool("TranslateTool")
         if t:
-            t.setEnabledAxis([ToolHandle.XAxis, ToolHandle.YAxis,ToolHandle.ZAxis])
+            t.setEnabledAxis([ToolHandle.XAxis, ToolHandle.YAxis, ToolHandle.ZAxis])
 
         Selection.selectionChanged.connect(self.onSelectionChanged)
 
@@ -657,6 +661,7 @@ class CuraApplication(QtApplication):
         run_headless = self.getCommandLineOption("headless", False)
         if not run_headless:
             self.initializeEngine()
+            controller.setActiveStage("PrepareStage")
 
         if run_headless or self._engine.rootObjects:
             self.closeSplash()

+ 3 - 10
cura/MachineAction.py

@@ -1,12 +1,10 @@
 # Copyright (c) 2016 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
 
-from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal, QUrl
-from PyQt5.QtQml import QQmlComponent, QQmlContext
+from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal
 
 from UM.PluginObject import PluginObject
 from UM.PluginRegistry import PluginRegistry
-from UM.Logger import Logger
 from UM.Application import Application
 
 import os
@@ -26,9 +24,6 @@ class MachineAction(QObject, PluginObject):
         self._key = key
         self._label = label
         self._qml_url = ""
-
-        self._component = None
-        self._context = None
         self._view = None
         self._finished = False
 
@@ -52,7 +47,6 @@ class MachineAction(QObject, PluginObject):
     #   /sa _reset
     @pyqtSlot()
     def reset(self):
-        self._component = None
         self._finished = False
         self._reset()
 
@@ -78,7 +72,6 @@ class MachineAction(QObject, PluginObject):
 
     @pyqtProperty(QObject, constant = True)
     def displayItem(self):
-        if not self._component:
+        if not self._view:
             self._createViewFromQML()
-
-        return self._view
+        return self._view

+ 9 - 38
cura/PrinterOutputDevice.py

@@ -3,19 +3,15 @@
 
 from UM.i18n import i18nCatalog
 from UM.OutputDevice.OutputDevice import OutputDevice
-from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, pyqtSignal, QUrl
-from PyQt5.QtQml import QQmlComponent, QQmlContext
+from PyQt5.QtCore import pyqtProperty, pyqtSlot, QObject, QTimer, pyqtSignal
 from PyQt5.QtWidgets import QMessageBox
 from enum import IntEnum  # For the connection state tracking.
 
 from UM.Settings.ContainerRegistry import ContainerRegistry
 from UM.Logger import Logger
 from UM.Signal import signalemitter
-from UM.PluginRegistry import PluginRegistry
 from UM.Application import Application
 
-import os
-
 i18n_catalog = i18nCatalog("cura")
 
 ##  Printer output device adds extra interface options on top of output device.
@@ -63,11 +59,9 @@ class PrinterOutputDevice(QObject, OutputDevice):
         self._camera_active = False
 
         self._monitor_view_qml_path = ""
-        self._monitor_component = None
         self._monitor_item = None
 
         self._control_view_qml_path = ""
-        self._control_component = None
         self._control_item = None
 
         self._qml_context = None
@@ -155,54 +149,31 @@ class PrinterOutputDevice(QObject, OutputDevice):
         # Note that we specifically only check if the monitor component is created.
         # It could be that it failed to actually create the qml item! If we check if the item was created, it will try to
         # create the item (and fail) every time.
-        if not self._monitor_component:
+        if not self._monitor_item:
             self._createMonitorViewFromQML()
-
         return self._monitor_item
 
     @pyqtProperty(QObject, constant=True)
     def controlItem(self):
-        if not self._control_component:
+        if not self._control_item:
             self._createControlViewFromQML()
-
         return self._control_item
 
     def _createControlViewFromQML(self):
         if not self._control_view_qml_path:
             return
 
-        path = QUrl.fromLocalFile(self._control_view_qml_path)
-
-        # Because of garbage collection we need to keep this referenced by python.
-        self._control_component = QQmlComponent(Application.getInstance()._engine, path)
-
-        # Check if the context was already requested before (Printer output device might have multiple items in the future)
-        if self._qml_context is None:
-            self._qml_context = QQmlContext(Application.getInstance()._engine.rootContext())
-            self._qml_context.setContextProperty("OutputDevice", self)
-
-        self._control_item = self._control_component.create(self._qml_context)
-        if self._control_item is None:
-            Logger.log("e", "QQmlComponent status %s", self._control_component.status())
-            Logger.log("e", "QQmlComponent error string %s", self._control_component.errorString())
+        self._control_item = Application.getInstance().createQmlComponent(self._control_view_qml_path, {
+            "OutputDevice": self
+        })
 
     def _createMonitorViewFromQML(self):
         if not self._monitor_view_qml_path:
             return
-        path = QUrl.fromLocalFile(self._monitor_view_qml_path)
-
-        # Because of garbage collection we need to keep this referenced by python.
-        self._monitor_component = QQmlComponent(Application.getInstance()._engine, path)
-
-        # Check if the context was already requested before (Printer output device might have multiple items in the future)
-        if self._qml_context is None:
-            self._qml_context = QQmlContext(Application.getInstance()._engine.rootContext())
-            self._qml_context.setContextProperty("OutputDevice", self)
 
-        self._monitor_item = self._monitor_component.create(self._qml_context)
-        if self._monitor_item is None:
-            Logger.log("e", "QQmlComponent status %s", self._monitor_component.status())
-            Logger.log("e", "QQmlComponent error string %s", self._monitor_component.errorString())
+        self._monitor_item = Application.getInstance().createQmlComponent(self._monitor_view_qml_path, {
+            "OutputDevice": self
+        })
 
     @pyqtProperty(str, notify=printerTypeChanged)
     def printerType(self):

+ 13 - 1
cura/Settings/ContainerManager.py

@@ -63,7 +63,18 @@ class ContainerManager(QObject):
             return ""
 
         container = containers[0]
+        new_container = self.duplicateContainerInstance(container)
+        return new_container.getId()
 
+    ##  Create a duplicate of the given container instance
+    #
+    #   This will create and add a duplicate of the container that was passed.
+    #
+    #   \param container \type{ContainerInterface} The container to duplicate.
+    #
+    #   \return The duplicated container, or None if duplication failed.
+    def duplicateContainerInstance(self, container):
+        new_container = None
         new_name = self._container_registry.uniqueName(container.getName())
         # Only InstanceContainer has a duplicate method at the moment.
         # So fall back to serialize/deserialize when no duplicate method exists.
@@ -74,10 +85,11 @@ class ContainerManager(QObject):
             new_container.deserialize(container.serialize())
             new_container.setName(new_name)
 
+        # TODO: we probably don't want to add it to the registry here!
         if new_container:
             self._container_registry.addContainer(new_container)
 
-        return new_container.getId()
+        return new_container
 
     ##  Change the name of a specified container to a new name.
     #

Some files were not shown because too many files changed in this diff