chiark / gitweb /
Add working rotate/scale/mirror tools to the project planner.
authordaid303 <daid303@gmail.com>
Thu, 7 Mar 2013 11:19:04 +0000 (12:19 +0100)
committerdaid303 <daid303@gmail.com>
Thu, 7 Mar 2013 11:19:04 +0000 (12:19 +0100)
Cura/gui/preview3d.py
Cura/gui/projectPlanner.py
Cura/gui/util/previewTools.py

index 5e91099de6698d5adb146b892fb323312824a17e..162bbc654e4c2eef02fd074ec4b5519e41aa1584 100644 (file)
@@ -124,7 +124,7 @@ class previewPanel(wx.Panel):
                self.scaleUniform = openglGui.glCheckbox(self.scaleForm, True, (1,8), None)
 
                self.viewSelection = openglGui.glComboButton(self.glCanvas, 'View mode', [7,11,15,19,23], ['Normal', 'Transparent', 'X-Ray', 'Overhang', 'Layers'], (-1,0), self.OnViewChange)
-               self.layerSelect = openglGui.glSlider(self.glCanvas, 0, 0, 100, (-1,-2), self.OnLayerNrChange)
+               self.layerSelect = openglGui.glSlider(self.glCanvas, 0, 0, 100, (-1,-2), lambda : self.Refresh())
 
                self.OnViewChange()
                self.OnToolSelect()
@@ -285,23 +285,6 @@ class previewPanel(wx.Panel):
                        obj.steepDirty = True
                self.updateModelTransform()
 
-       def On3DClick(self):
-               self.glCanvas.yaw = 30
-               self.glCanvas.pitch = 60
-               self.glCanvas.zoom = 300
-               self.glCanvas.view3D = True
-               self.glCanvas.Refresh()
-
-       def OnTopClick(self):
-               self.glCanvas.view3D = False
-               self.glCanvas.zoom = 100
-               self.glCanvas.offsetX = 0
-               self.glCanvas.offsetY = 0
-               self.glCanvas.Refresh()
-
-       def OnLayerNrChange(self):
-               self.glCanvas.Refresh()
-       
        def setViewMode(self, mode):
                if mode == "Normal":
                        self.viewSelection.setValue(0)
@@ -408,6 +391,8 @@ class previewPanel(wx.Panel):
                wx.CallAfter(self.checkReloadFileTimer.Start, 1000)
        
        def loadProgress(self, progress):
+               if self.gcode is None:
+                       return True
                if self.layerSelect.getValue() == self.layerSelect.getMaxValue():
                        self.layerSelect.setRange(1, len(self.gcode.layerList) - 1)
                        self.layerSelect.setValue(self.layerSelect.getMaxValue())
index f1e7f11cae801210b549289a1bb5fa902efdedca..f263ad530824519159d48ca7ff157333c58511e2 100644 (file)
@@ -8,6 +8,7 @@ import re
 import shutil
 import ConfigParser
 import numpy
+import math
 
 import OpenGL
 OpenGL.ERROR_CHECKING = False
@@ -67,6 +68,16 @@ class ProjectObject(object):
                self.mesh.matrix = self.matrix
                self.mesh.processMatrix()
 
+               scaleX = numpy.linalg.norm(self.matrix[::,0].getA().flatten())
+               scaleY = numpy.linalg.norm(self.matrix[::,1].getA().flatten())
+               scaleZ = numpy.linalg.norm(self.matrix[::,2].getA().flatten())
+               self.parent.scaleXctrl.setValue(round(scaleX, 2))
+               self.parent.scaleYctrl.setValue(round(scaleY, 2))
+               self.parent.scaleZctrl.setValue(round(scaleZ, 2))
+               self.parent.scaleXmmctrl.setValue(round(self.getSize()[0], 2))
+               self.parent.scaleYmmctrl.setValue(round(self.getSize()[1], 2))
+               self.parent.scaleZmmctrl.setValue(round(self.getSize()[2], 2))
+
        def getMinimum(self):
                return self.mesh.getMinimum()
        def getMaximum(self):
@@ -209,7 +220,6 @@ class projectPlanner(wx.Frame):
                self.layFlatButton       = openglGui.glButton(self.glCanvas, 16, 'Lay flat', (0,-3), self.OnLayFlat)
 
                self.resetScaleButton    = openglGui.glButton(self.glCanvas, 13, 'Reset', (1,-2), self.OnScaleReset)
-               self.scaleMaxButton      = openglGui.glButton(self.glCanvas, 17, 'To max', (1,-3), self.OnScaleMax)
 
                self.mirrorXButton       = openglGui.glButton(self.glCanvas, 14, 'Mirror X', (2,-2), lambda : self.OnMirror(0))
                self.mirrorYButton       = openglGui.glButton(self.glCanvas, 18, 'Mirror Y', (2,-3), lambda : self.OnMirror(1))
@@ -248,7 +258,6 @@ class projectPlanner(wx.Frame):
                self.resetRotationButton.setHidden(not self.rotateToolButton.getSelected())
                self.layFlatButton.setHidden(not self.rotateToolButton.getSelected())
                self.resetScaleButton.setHidden(not self.scaleToolButton.getSelected())
-               self.scaleMaxButton.setHidden(not self.scaleToolButton.getSelected())
                self.scaleForm.setHidden(not self.scaleToolButton.getSelected())
                self.mirrorXButton.setHidden(not self.mirrorToolButton.getSelected())
                self.mirrorYButton.setHidden(not self.mirrorToolButton.getSelected())
@@ -256,17 +265,112 @@ class projectPlanner(wx.Frame):
                self.glCanvas.Refresh()
 
        def OnRotateReset(self):
-               pass
+               if self.selection is None:
+                       return
+               x = numpy.linalg.norm(self.selection.matrix[::,0].getA().flatten())
+               y = numpy.linalg.norm(self.selection.matrix[::,1].getA().flatten())
+               z = numpy.linalg.norm(self.selection.matrix[::,2].getA().flatten())
+               self.selection.matrix = numpy.matrix([[x,0,0],[0,y,0],[0,0,z]], numpy.float64)
+               self.selection.updateMatrix()
+
        def OnLayFlat(self):
-               pass
+               if self.selection is None:
+                       return
+               transformedVertexes = (numpy.matrix(self.selection.mesh.vertexes, copy = False) * self.selection.matrix).getA()
+               minZvertex = transformedVertexes[transformedVertexes.argmin(0)[2]]
+               dotMin = 1.0
+               dotV = None
+               for v in transformedVertexes:
+                       diff = v - minZvertex
+                       len = math.sqrt(diff[0] * diff[0] + diff[1] * diff[1] + diff[2] * diff[2])
+                       if len < 5:
+                               continue
+                       dot = (diff[2] / len)
+                       if dotMin > dot:
+                               dotMin = dot
+                               dotV = diff
+               if dotV is None:
+                       return
+               rad = -math.atan2(dotV[1], dotV[0])
+               self.selection.matrix *= numpy.matrix([[math.cos(rad), math.sin(rad), 0], [-math.sin(rad), math.cos(rad), 0], [0,0,1]], numpy.float64)
+               rad = -math.asin(dotMin)
+               self.selection.matrix *= numpy.matrix([[math.cos(rad), 0, math.sin(rad)], [0,1,0], [-math.sin(rad), 0, math.cos(rad)]], numpy.float64)
+
+
+               transformedVertexes = (numpy.matrix(self.selection.mesh.vertexes, copy = False) * self.selection.matrix).getA()
+               minZvertex = transformedVertexes[transformedVertexes.argmin(0)[2]]
+               dotMin = 1.0
+               dotV = None
+               for v in transformedVertexes:
+                       diff = v - minZvertex
+                       len = math.sqrt(diff[1] * diff[1] + diff[2] * diff[2])
+                       if len < 5:
+                               continue
+                       dot = (diff[2] / len)
+                       if dotMin > dot:
+                               dotMin = dot
+                               dotV = diff
+               if dotV is None:
+                       return
+               if dotV[1] < 0:
+                       rad = math.asin(dotMin)
+               else:
+                       rad = -math.asin(dotMin)
+               self.selection.matrix *= numpy.matrix([[1,0,0], [0, math.cos(rad), math.sin(rad)], [0, -math.sin(rad), math.cos(rad)]], numpy.float64)
+
+               self.selection.updateMatrix()
+
        def OnScaleReset(self):
-               pass
-       def OnScaleMax(self):
-               pass
+               if self.selection is None:
+                       return
+               x = 1/numpy.linalg.norm(self.selection.matrix[::,0].getA().flatten())
+               y = 1/numpy.linalg.norm(self.selection.matrix[::,1].getA().flatten())
+               z = 1/numpy.linalg.norm(self.selection.matrix[::,2].getA().flatten())
+               self.selection.matrix *= numpy.matrix([[x,0,0],[0,y,0],[0,0,z]], numpy.float64)
+               self.selection.updateMatrix()
+
        def OnMirror(self, axis):
-               pass
-       def OnScaleEntry(self, axis):
-               pass
+               if self.selection is None:
+                       return
+               matrix = [[1,0,0], [0, 1, 0], [0, 0, 1]]
+               matrix[axis][axis] = -1
+               self.selection.matrix *= numpy.matrix(matrix, numpy.float64)
+
+       def OnScaleEntry(self, value, axis):
+               if self.selection is None:
+                       return
+               try:
+                       value = float(value)
+               except:
+                       return
+               scale = numpy.linalg.norm(self.selection.matrix[::,axis].getA().flatten())
+               scale = value / scale
+               if scale == 0:
+                       return
+               if self.scaleUniform.getValue():
+                       matrix = [[scale,0,0], [0, scale, 0], [0, 0, scale]]
+               else:
+                       matrix = [[1.0,0,0], [0, 1.0, 0], [0, 0, 1.0]]
+                       matrix[axis][axis] = scale
+               self.selection.matrix *= numpy.matrix(matrix, numpy.float64)
+               self.selection.updateMatrix()
+
+       def OnScaleEntryMM(self, value, axis):
+               try:
+                       value = float(value)
+               except:
+                       return
+               scale = self.selection.getSize()[axis]
+               scale = value / scale
+               if scale == 0:
+                       return
+               if self.scaleUniform.getValue():
+                       matrix = [[scale,0,0], [0, scale, 0], [0, 0, scale]]
+               else:
+                       matrix = [[1,0,0], [0, 1, 0], [0, 0, 1]]
+                       matrix[axis][axis] = scale
+               self.selection.matrix *= numpy.matrix(matrix, numpy.float64)
+               self.selection.updateMatrix()
 
        def OnClose(self, e):
                self.Destroy()
index 0b4a3d3a63e6282b3b2f57c0e273cecd203e735b..16cc6226e0ee78feb9ce6aea13f09eb6d09c717b 100644 (file)
@@ -415,10 +415,10 @@ class toolScale(object):
                glColor3ub(128,0,0)
                glVertex3f(0, 0, 0)
                glVertex3f(sx, 0, 0)
-               glColor3ub(128,128,0)
+               glColor3ub(0,128,0)
                glVertex3f(0, 0, 0)
                glVertex3f(0, sy, 0)
-               glColor3ub(0,128,0)
+               glColor3ub(0,0,128)
                glVertex3f(0, 0, 0)
                glVertex3f(0, 0, sz)
                glEnd()
@@ -445,9 +445,9 @@ class toolScale(object):
                        opengl.glDrawStringCenter("%0.2f" % (scaleX))
                glPopMatrix()
                if self.node == 3:
-                       glColor3ub(255,255,0)
+                       glColor3ub(64,255,64)
                else:
-                       glColor3ub(128,128,0)
+                       glColor3ub(0,128,0)
                glPushMatrix()
                glTranslatef(0,sy,0)
                opengl.DrawBox([-s,-s,-s], [s,s,s])
@@ -456,9 +456,9 @@ class toolScale(object):
                        opengl.glDrawStringCenter("%0.2f" % (scaleY))
                glPopMatrix()
                if self.node == 4:
-                       glColor3ub(64,255,64)
+                       glColor3ub(64,64,255)
                else:
-                       glColor3ub(0,128,0)
+                       glColor3ub(0,0,128)
                glPushMatrix()
                glTranslatef(0,0,sz)
                opengl.DrawBox([-s,-s,-s], [s,s,s])