Browse Source

Merge branch '15.06'

* 15.06:
  Update changelog
  Correct the bottom offset we add when setting the volume for scale to max
  Display progress information during processing of layer data
  If findObject returns none but object_id != 0 use the selected object
  Offset the displayed rotation angle so it does not overlap the mouse cursor
  Abort attempts to connect if an error is thrown when connecting to the serial port
  Fix recent files on Windows
  Defer opening the webbrowser until the next run of the event loop
  Disable slicing and platform physics when an operation is being performed
  Rework LayerData mesh generation for improved performance
  Performance: Only calculate the platform center once, not for every poly
  Add application icons for all three platforms
Arjen Hiemstra 9 years ago
parent
commit
a429e362ad
10 changed files with 65 additions and 18 deletions
  1. 16 10
      CHANGES
  2. 15 3
      cura/CuraActions.py
  3. 20 5
      cura/CuraApplication.py
  4. 14 0
      cura/PlatformPhysics.py
  5. BIN
      icons/cura-128.png
  6. BIN
      icons/cura-32.png
  7. BIN
      icons/cura-48.png
  8. BIN
      icons/cura-64.png
  9. BIN
      icons/cura.icns
  10. BIN
      icons/cura.ico

+ 16 - 10
CHANGES

@@ -7,6 +7,22 @@ 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
 ----------------------
 
@@ -150,18 +166,8 @@ 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 .
 
-* The application has no application icon yet.
-* The Windows version starts a console before starting the
-  application. This is intentional for the beta and it will be
-  removed for the final version.
-* Opening the machine preferences page will switch to the first
-  available machine instead of keeping the current machine
-  selected.
 * Some OBJ files are rendered as black objects due to missing
   normals.
-* The developer documentation for Uranium (available at
-  http://software.ultimaker.com/uranium/index.html) is not yet
-  complete.
 * Disabling plugins does not work correctly yet.
 * Unicorn occasionally still requires feeding. Do not feed it
   after midnight.

+ 15 - 3
cura/CuraActions.py

@@ -1,4 +1,8 @@
-from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, pyqtProperty
+from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, pyqtProperty, QUrl
+from PyQt5.QtGui import QDesktopServices
+
+from UM.Event import CallFunctionEvent
+from UM.Application import Application
 
 import webbrowser
 
@@ -8,8 +12,16 @@ class CuraActions(QObject):
 
     @pyqtSlot()
     def openDocumentation(self):
-        webbrowser.open("http://ultimaker.com/en/support/software")
+        # Starting a web browser from a signal handler connected to a menu will crash on windows.
+        # So instead, defer the call to the next run of the event loop, since that does work.
+        # Note that weirdly enough, only signal handlers that open a web browser fail like that.
+        event = CallFunctionEvent(self._openUrl, [QUrl("http://ultimaker.com/en/support/software")], {})
+        Application.getInstance().functionEvent(event)
 
     @pyqtSlot()
     def openBugReportPage(self):
-        webbrowser.open("http://github.com/Ultimaker/Cura/issues")
+        event = CallFunctionEvent(self._openUrl, [QUrl("http://github.com/Ultimaker/Cura/issues")], {})
+        Application.getInstance().functionEvent(event)
+
+    def _openUrl(self, url):
+        QDesktopServices.openUrl(url)

+ 20 - 5
cura/CuraApplication.py

@@ -85,7 +85,7 @@ class CuraApplication(QtApplication):
             if not os.path.isfile(f):
                 continue
 
-            self._recent_files.append(f)
+            self._recent_files.append(QUrl.fromLocalFile(f))
     
     ##  Handle loading of all plugin types (and the backend explicitly)
     #   \sa PluginRegistery
@@ -215,6 +215,9 @@ class CuraApplication(QtApplication):
     def deleteObject(self, object_id):
         object = self.getController().getScene().findObject(object_id)
 
+        if not object and object_id != 0: #Workaround for tool handles overlapping the selected object
+            object = Selection.getSelectedObject(0)
+
         if object:
             op = RemoveSceneNodeOperation(object)
             op.push()
@@ -224,6 +227,9 @@ class CuraApplication(QtApplication):
     def multiplyObject(self, object_id, count):
         node = self.getController().getScene().findObject(object_id)
 
+        if not node and object_id != 0: #Workaround for tool handles overlapping the selected object
+            node = Selection.getSelectedObject(0)
+
         if node:
             op = GroupedOperation()
             for i in range(count):
@@ -240,6 +246,9 @@ class CuraApplication(QtApplication):
     def centerObject(self, object_id):
         node = self.getController().getScene().findObject(object_id)
 
+        if not node and object_id != 0: #Workaround for tool handles overlapping the selected object
+            node = Selection.getSelectedObject(0)
+
         if node:
             op = SetTransformOperation(node, Vector())
             op.push()
@@ -330,7 +339,7 @@ class CuraApplication(QtApplication):
         return log
 
     recentFilesChanged = pyqtSignal()
-    @pyqtProperty("QStringList", notify = recentFilesChanged)
+    @pyqtProperty("QVariantList", notify = recentFilesChanged)
     def recentFiles(self):
         return self._recent_files
 
@@ -468,7 +477,9 @@ class CuraApplication(QtApplication):
             self._volume.rebuild()
 
             if self.getController().getTool("ScaleTool"):
-                self.getController().getTool("ScaleTool").setMaximumBounds(self._volume.getBoundingBox())
+                bbox = self._volume.getBoundingBox()
+                bbox.setBottom(0.0)
+                self.getController().getTool("ScaleTool").setMaximumBounds(bbox)
 
             offset = machine.getSettingValueByKey("machine_platform_offset")
             if offset:
@@ -508,7 +519,7 @@ class CuraApplication(QtApplication):
         if type(job) is not ReadMeshJob:
             return
 
-        f = job.getFileName()
+        f = QUrl.fromLocalFile(job.getFileName())
         if f in self._recent_files:
             self._recent_files.remove(f)
 
@@ -516,5 +527,9 @@ class CuraApplication(QtApplication):
         if len(self._recent_files) > 10:
             del self._recent_files[10]
 
-        Preferences.getInstance().setValue("cura/recent_files", ";".join(self._recent_files))
+        pref = ""
+        for path in self._recent_files:
+            pref += path.toLocalFile() + ";"
+
+        Preferences.getInstance().setValue("cura/recent_files", pref)
         self.recentFilesChanged.emit()

+ 14 - 0
cura/PlatformPhysics.py

@@ -24,8 +24,12 @@ class PlatformPhysics:
         super().__init__()
         self._controller = controller
         self._controller.getScene().sceneChanged.connect(self._onSceneChanged)
+        self._controller.toolOperationStarted.connect(self._onToolOperationStarted)
+        self._controller.toolOperationStopped.connect(self._onToolOperationStopped)
         self._build_volume = volume
 
+        self._enabled = True
+
         self._change_timer = QTimer()
         self._change_timer.setInterval(100)
         self._change_timer.setSingleShot(True)
@@ -35,6 +39,9 @@ class PlatformPhysics:
         self._change_timer.start()
 
     def _onChangeTimerFinished(self):
+        if not self._enabled:
+            return
+
         root = self._controller.getScene().getRoot()
         for node in BreadthFirstIterator(root):
             if node is root or type(node) is not SceneNode:
@@ -93,3 +100,10 @@ class PlatformPhysics:
             if node.getBoundingBox().intersectsBox(self._build_volume.getBoundingBox()) == AxisAlignedBox.IntersectionResult.FullIntersection:
                 op = ScaleToBoundsOperation(node, self._build_volume.getBoundingBox())
                 op.push()
+
+    def _onToolOperationStarted(self, tool):
+        self._enabled = False
+
+    def _onToolOperationStopped(self, tool):
+        self._enabled = True
+        self._onChangeTimerFinished()

BIN
icons/cura-128.png


BIN
icons/cura-32.png


BIN
icons/cura-48.png


BIN
icons/cura-64.png


BIN
icons/cura.icns


BIN
icons/cura.ico


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