From: daid303 Date: Tue, 26 Mar 2013 09:03:50 +0000 (+0100) Subject: Better initial auto-arrangement. And detect objects that are no longer on the platform. X-Git-Tag: 13.05~154 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=b3babfbf700f26648861489f2b017803e013353d;p=cura.git Better initial auto-arrangement. And detect objects that are no longer on the platform. --- diff --git a/Cura/gui/sceneView.py b/Cura/gui/sceneView.py index 0d90b133..74934985 100644 --- a/Cura/gui/sceneView.py +++ b/Cura/gui/sceneView.py @@ -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) diff --git a/Cura/util/objectScene.py b/Cura/util/objectScene.py index e84eedf6..9d474611 100644 --- a/Cura/util/objectScene.py +++ b/Cura/util/objectScene.py @@ -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)