chiark / gitweb /
Better initial auto-arrangement. And detect objects that are no longer on the platform.
authordaid303 <daid303@gmail.com>
Tue, 26 Mar 2013 09:03:50 +0000 (10:03 +0100)
committerdaid303 <daid303@gmail.com>
Tue, 26 Mar 2013 09:03:50 +0000 (10:03 +0100)
Cura/gui/sceneView.py
Cura/util/objectScene.py

index 0d90b1330573e2b66c9c9cba31007fa20d3eb7a4..74934985dfefa13cff38f2c7529cab3e468c7241 100644 (file)
@@ -70,6 +70,7 @@ class SceneView(openglGui.glGuiPanel):
                        for obj in meshLoader.loadMeshes(filename):
                                obj._loadAnim = anim(1, 0, 2)
                                self._scene.add(obj)
+                               self._selectObject(obj)
 
        def _deleteObject(self, obj):
                if obj == self._selectedObj:
@@ -81,12 +82,20 @@ class SceneView(openglGui.glGuiPanel):
                        if m.vbo is not None:
                                self.glReleaseList.append(m.vbo)
 
+       def _selectObject(self, obj):
+               self._selectedObj = obj
+               newViewPos = numpy.array([self._selectedObj.getPosition()[0], self._selectedObj.getPosition()[1], self._selectedObj.getMaximum()[2] / 2])
+               self._animView = anim(self._viewTarget.copy(), newViewPos, 0.5)
+               newZoom = self._selectedObj.getBoundaryCircle() * 6
+               self._animZoom = anim(self._zoom, newZoom, 0.5)
+
        def updateProfileToControls(self):
                self._machineSize = numpy.array([profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')])
                self._objColors[0] = profile.getPreferenceColour('model_colour')
                self._objColors[1] = profile.getPreferenceColour('model_colour2')
                self._objColors[2] = profile.getPreferenceColour('model_colour3')
                self._objColors[3] = profile.getPreferenceColour('model_colour4')
+               self._scene.setMachineSize(self._machineSize)
 
        def OnKeyChar(self, keyCode):
                if keyCode == wx.WXK_DELETE or keyCode == wx.WXK_NUMPAD_DELETE:
@@ -122,11 +131,7 @@ class SceneView(openglGui.glGuiPanel):
                if self._mouseState == 'dragOrClick':
                        if e.Button == 1:
                                if self._focusObj is not None:
-                                       self._selectedObj = self._focusObj
-                                       newViewPos = numpy.array([self._selectedObj.getPosition()[0], self._selectedObj.getPosition()[1], self._selectedObj.getMaximum()[2] / 2])
-                                       self._animView = anim(self._viewTarget.copy(), newViewPos, 0.5)
-                                       newZoom = self._selectedObj.getBoundaryCircle() * 6
-                                       self._animZoom = anim(self._zoom, newZoom, 0.5)
+                                       self._selectObject(self._focusObj)
                                else:
                                        self._selectedObj = None
                                        self.Refresh()
@@ -302,6 +307,8 @@ void main(void)
                                else:
                                        continue
                        col = self._objColors[0]
+                       if not self._scene.checkPlatform(obj):
+                               col = [0.5,0.5,0.5,0.8]
                        glDisable(GL_STENCIL_TEST)
                        if self._selectedObj == obj:
                                col = map(lambda n: n * 1.5, col)
@@ -331,7 +338,7 @@ void main(void)
                self._drawMachine()
 
                #Draw the outline of the selected object, on top of everything else except the GUI.
-               if self._selectedObj is not None:
+               if self._selectedObj is not None and self._selectedObj._loadAnim is None:
                        glDisable(GL_DEPTH_TEST)
                        glEnable(GL_CULL_FACE)
                        glEnable(GL_STENCIL_TEST)
index e84eedf660060b14ba5ae6b43fe29245c8e6660a..9d4746119376527f87c642061264941c25a961ae 100644 (file)
@@ -4,11 +4,17 @@ import numpy
 class Scene():
        def __init__(self):
                self._objectList = []
+               self._sizeOffsets = numpy.array([3.0,3.0], numpy.float32)
+               self._machineSize = numpy.array([100,100,100], numpy.float32)
+
+       def setMachineSize(self, machineSize):
+               self._machineSize = machineSize
 
        def objects(self):
                return self._objectList
 
        def add(self, obj):
+               self._findFreePositionFor(obj)
                self._objectList.append(obj)
                self.pushFree()
 
@@ -34,7 +40,7 @@ class Scene():
                                aPos = a.getPosition()
                                bPos = b.getPosition()
                                center = (aPos[axis] + bPos[axis]) / 2
-                               distance = (a.getSize()[axis] + b.getSize()[axis]) / 2 + 0.1
+                               distance = (a.getSize()[axis] + b.getSize()[axis]) / 2 + 0.1 + self._sizeOffsets[axis] * 2
                                if posDiff[axis] < 0:
                                        distance = -distance
                                aPos[axis] = center + distance / 2
@@ -48,6 +54,53 @@ class Scene():
                if a == b:
                        return False
                posDiff = a.getPosition() - b.getPosition()
-               if abs(posDiff[0]) < (a.getSize()[0] + b.getSize()[0]) / 2 and abs(posDiff[1]) < (a.getSize()[1] + b.getSize()[1]) / 2:
+               if abs(posDiff[0]) < (a.getSize()[0] + b.getSize()[0]) / 2 + self._sizeOffsets[0] * 2 and abs(posDiff[1]) < (a.getSize()[1] + b.getSize()[1]) / 2 + self._sizeOffsets[1] * 2:
                        return True
                return False
+
+       def checkPlatform(self, obj):
+               p = obj.getPosition()
+               s = obj.getSize()[0:2] / 2 + self._sizeOffsets
+               if p[0] - s[0] < -self._machineSize[0] / 2:
+                       return False
+               if p[0] + s[0] > self._machineSize[0] / 2:
+                       return False
+               if p[1] - s[1] < -self._machineSize[1] / 2:
+                       return False
+               if p[1] + s[1] > self._machineSize[1] / 2:
+                       return False
+               return True
+
+       def _findFreePositionFor(self, obj):
+               posList = []
+               for a in self._objectList:
+                       p = a.getPosition()
+                       s = (a.getSize()[0:2] + obj.getSize()[0:2]) / 2 + self._sizeOffsets * 2
+                       posList.append(p + s * ( 1, 1))
+                       posList.append(p + s * ( 0, 1))
+                       posList.append(p + s * (-1, 1))
+                       posList.append(p + s * ( 1, 0))
+                       posList.append(p + s * (-1, 0))
+                       posList.append(p + s * ( 1,-1))
+                       posList.append(p + s * ( 0,-1))
+                       posList.append(p + s * (-1,-1))
+
+               best = None
+               bestDist = None
+               for p in posList:
+                       obj.setPosition(p)
+                       ok = True
+                       for a in self._objectList:
+                               if self._checkHit(a, obj):
+                                       ok = False
+                                       break
+                       if not ok:
+                               continue
+                       dist = numpy.linalg.norm(p)
+                       if not self.checkPlatform(obj):
+                               dist *= 3
+                       if best is None or dist < bestDist:
+                               best = p
+                               bestDist = dist
+               if best is not None:
+                       obj.setPosition(best)