chiark / gitweb /
Fix AMF support. Support merging of objects for multi-extruder prints.
authordaid303 <daid303@gmail.com>
Mon, 8 Apr 2013 17:24:05 +0000 (19:24 +0200)
committerdaid303 <daid303@gmail.com>
Mon, 8 Apr 2013 17:24:05 +0000 (19:24 +0200)
Cura/gui/mainWindow.py
Cura/gui/sceneView.py
Cura/util/meshLoader.py
Cura/util/meshLoaders/amf.py
Cura/util/objectScene.py
Cura/util/sliceEngine.py

index 72764e107295b280dddd97030b1cb1379552f468..8216af47ef2bb24df12b6e80f266e56870fa735e 100644 (file)
@@ -50,7 +50,7 @@ class mainWindow(wx.Frame):
                self.menubar = wx.MenuBar()
                self.fileMenu = wx.Menu()
                i = self.fileMenu.Append(-1, 'Load model file...\tCTRL+L')
-               self.Bind(wx.EVT_MENU, lambda e: self.scene.ShowLoadModel(), i)
+               self.Bind(wx.EVT_MENU, lambda e: self.scene.ShowLoadModel(1), i)
                i = self.fileMenu.Append(-1, 'Print...\tCTRL+P')
                self.Bind(wx.EVT_MENU, lambda e: self.scene.ShowPrintWindow(), i)
 
index 5ba9e9b465a1b5f1875018c70e73687ac2918ea3..d7b3bb941109cf1f17f1c80de5f0f414040ea005 100644 (file)
@@ -237,6 +237,12 @@ class SceneView(openglGui.glGuiPanel):
                self.updateProfileToControls()
                self.sceneUpdated()
 
+       def OnMergeObjects(self, e):
+               if self._selectedObj is None or self._focusObj is None or self._selectedObj == self._focusObj:
+                       return
+               self._scene.merge(self._selectedObj, self._focusObj)
+               self.sceneUpdated()
+
        def sceneUpdated(self):
                self._sceneUpdateTimer.Start(1, True)
                self._slicer.abortSlicer()
@@ -299,6 +305,7 @@ class SceneView(openglGui.glGuiPanel):
                self._objColors[2] = profile.getPreferenceColour('model_colour3')
                self._objColors[3] = profile.getPreferenceColour('model_colour4')
                self._scene.setMachineSize(self._machineSize)
+               self._scene.setSizeOffsets(numpy.array(profile.calculateObjectSizeOffsets(), numpy.float32))
 
                if self._selectedObj is not None:
                        scale = self._selectedObj.getScale()
@@ -358,12 +365,18 @@ class SceneView(openglGui.glGuiPanel):
                                else:
                                        self._selectedObj = None
                                        self.Refresh()
-                       if e.GetButton() == 3 and self._selectedObj == self._focusObj:
-                               #menu = wx.Menu()
-                               #menu.Append(-1, 'Test')
-                               #self.PopupMenu(menu)
-                               #menu.Destroy()
-                               pass
+                       if e.GetButton() == 3:
+                               if self._selectedObj == self._focusObj:
+                                       #menu = wx.Menu()
+                                       #menu.Append(-1, 'Test')
+                                       #self.PopupMenu(menu)
+                                       #menu.Destroy()
+                                       pass
+                               if self._selectedObj != self._focusObj and self._focusObj is not None:
+                                       menu = wx.Menu()
+                                       self.Bind(wx.EVT_MENU, self.OnMergeObjects, menu.Append(-1, 'Merge'))
+                                       self.PopupMenu(menu)
+                                       menu.Destroy()
                elif self._mouseState == 'dragObject' and self._selectedObj is not None:
                        self._scene.pushFree()
                        self.sceneUpdated()
@@ -568,18 +581,19 @@ void main(void)
                                        obj._loadAnim = None
                                else:
                                        continue
-                       col = self._objColors[0]
-                       if not self._scene.checkPlatform(obj):
-                               col = [0.5,0.5,0.5,0.8]
+                       brightness = 1.0
                        glDisable(GL_STENCIL_TEST)
                        if self._selectedObj == obj:
                                glEnable(GL_STENCIL_TEST)
                        if self._focusObj == obj:
-                               col = map(lambda n: n * 1.2, col)
+                               brightness = 1.2
                        elif self._focusObj is not None or self._selectedObj is not None and obj != self._selectedObj:
-                               col = map(lambda n: n * 0.8, col)
-                       glColor4f(col[0], col[1], col[2], col[3])
-                       self._renderObject(obj)
+                               brightness = 0.8
+                       if not self._scene.checkPlatform(obj):
+                               glColor4f(0.5 * brightness, 0.5 * brightness, 0.5 * brightness, 0.8 * brightness)
+                               self._renderObject(obj)
+                       else:
+                               self._renderObject(obj, brightness)
                self._objectShader.unbind()
 
                glDisable(GL_STENCIL_TEST)
@@ -619,6 +633,7 @@ void main(void)
                        glDisable(GL_DEPTH_TEST)
                        glEnable(GL_CULL_FACE)
                        glEnable(GL_STENCIL_TEST)
+                       glDisable(GL_BLEND)
                        glStencilFunc(GL_EQUAL, 0, 255)
 
                        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
@@ -639,7 +654,7 @@ void main(void)
                        self.tool.OnDraw()
                        glPopMatrix()
 
-       def _renderObject(self, obj):
+       def _renderObject(self, obj, brightness = False):
                glPushMatrix()
                glTranslate(obj.getPosition()[0], obj.getPosition()[1], obj.getSize()[2] / 2)
 
@@ -653,9 +668,13 @@ void main(void)
                tempMatrix = opengl.convert3x3MatrixTo4x4(obj.getMatrix())
                glMultMatrixf(tempMatrix)
 
+               n = 0
                for m in obj._meshList:
                        if m.vbo is None:
                                m.vbo = opengl.GLVBO(m.vertexes, m.normal)
+                       if brightness:
+                               glColor4fv(map(lambda n: n * brightness, self._objColors[n]))
+                               n += 1
                        m.vbo.render()
                glPopMatrix()
 
index bc5141508acad823da83cd10ae9a68f71d387ada..809a66a546d75c4e2682ad40613863d7ba8198b0 100644 (file)
@@ -27,6 +27,6 @@ def loadMeshes(filename):
        if ext == '.dae':
                return dae.daeModel().load(filename)
        if ext == '.amf':
-               return amf.amfModel().load(filename)
+               return amf.loadScene(filename)
        print 'Error: Unknown model extension: %s' % (ext)
        return []
index 61a28b585eb995bb971faf7cfb6cd1a22b6bf6cb..ad0077058f2dfc9731c23977b708e4f379240987 100644 (file)
@@ -8,69 +8,69 @@ except:
 
 from Cura.util import mesh
 
-class amfModel(mesh.mesh):
-       def __init__(self):
-               super(amfModel, self).__init__()
+def loadScene(filename):
+       try:
+               zfile = zipfile.ZipFile(filename)
+               xml = zfile.read(zfile.namelist()[0])
+               zfile.close()
+       except zipfile.BadZipfile:
+               f = open(filename, "r")
+               xml = f.read()
+               f.close()
+       amf = ElementTree.fromstring(xml)
+       if 'unit' in amf.attrib:
+               unit = amf.attrib['unit'].lower()
+       else:
+               unit = 'millimeter'
+       if unit == 'millimeter':
+               scale = 1.0
+       elif unit == 'meter':
+               scale = 1000.0
+       elif unit == 'inch':
+               scale = 25.4
+       elif unit == 'feet':
+               scale = 304.8
+       elif unit == 'micron':
+               scale = 0.001
+       else:
+               print "Unknown unit in amf: %s" % (unit)
+               scale = 1.0
 
-       def load(self, filename):
-               try:
-                       zfile = zipfile.ZipFile(filename)
-                       xml = zfile.read(zfile.namelist()[0])
-                       zfile.close()
-               except zipfile.BadZipfile:
-                       f = open(filename, "r")
-                       xml = f.read()
-                       f.close()
-               amf = ElementTree.fromstring(xml)
-               if 'unit' in amf.attrib:
-                       unit = amf.attrib['unit'].lower()
-               else:
-                       unit = 'millimeter'
-               if unit == 'millimeter':
-                       scale = 1.0
-               elif unit == 'meter':
-                       scale = 1000.0
-               elif unit == 'inch':
-                       scale = 25.4
-               elif unit == 'feet':
-                       scale = 304.8
-               elif unit == 'micron':
-                       scale = 0.001
-               else:
-                       print "Unknown unit in amf: %s" % (unit)
-                       scale = 1.0
+       ret = []
+       for amfObj in amf.iter('object'):
+               obj = mesh.printableObject()
+               for amfMesh in amfObj.iter('mesh'):
+                       vertexList = []
+                       for vertices in amfMesh.iter('vertices'):
+                               for vertex in vertices.iter('vertex'):
+                                       for coordinates in vertex.iter('coordinates'):
+                                               v = [0.0,0.0,0.0]
+                                               for t in coordinates:
+                                                       if t.tag == 'x':
+                                                               v[0] = float(t.text)
+                                                       elif t.tag == 'y':
+                                                               v[1] = float(t.text)
+                                                       elif t.tag == 'z':
+                                                               v[2] = float(t.text)
+                                               vertexList.append(v)
 
-               count = 0
-               for obj in amf.iter('object'):
-                       for mesh in obj.iter('mesh'):
-                               for volume in mesh.iter('volume'):
-                                       for triangle in volume.iter('triangle'):
-                                               count += 3
+                       for volume in amfMesh.iter('volume'):
+                               m = obj._addMesh()
+                               count = 0
+                               for triangle in volume.iter('triangle'):
+                                       count += 1
+                               m._prepareFaceCount(count)
 
-               self._prepareVertexCount(count)
+                               for triangle in volume.iter('triangle'):
+                                       for t in triangle:
+                                               if t.tag == 'v1':
+                                                       v1 = vertexList[int(t.text)]
+                                               elif t.tag == 'v2':
+                                                       v2 = vertexList[int(t.text)]
+                                               elif t.tag == 'v3':
+                                                       v3 = vertexList[int(t.text)]
+                                                       m._addFace(v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], v3[0], v3[1], v3[2])
+               obj._postProcessAfterLoad()
+               ret.append(obj)
 
-               for obj in amf.iter('object'):
-                       for mesh in obj.iter('mesh'):
-                               vertexList = []
-                               for vertices in mesh.iter('vertices'):
-                                       for vertex in vertices.iter('vertex'):
-                                               for coordinates in vertex.iter('coordinates'):
-                                                       v = [0.0,0.0,0.0]
-                                                       for t in coordinates:
-                                                               if t.tag == 'x':
-                                                                       v[0] = float(t.text)
-                                                               elif t.tag == 'y':
-                                                                       v[1] = float(t.text)
-                                                               elif t.tag == 'z':
-                                                                       v[2] = float(t.text)
-                                                       vertexList.append(v)
-                               for volume in mesh.iter('volume'):
-                                       for triangle in volume.iter('triangle'):
-                                               for t in triangle:
-                                                       if t.tag == 'v1' or t.tag == 'v2' or t.tag == 'v3':
-                                                               v = vertexList[int(t.text)]
-                                                               self.addVertex(v[0], v[1], v[2])
-
-               self.vertexes *= scale
-               self._postProcessAfterLoad()
-               return self
+       return ret
index 2684bd5baaeb706b96b38e090c1db4691df94f09..0ad1dda60d69712ec29757c7bd2ffbc0da3b403f 100644 (file)
@@ -66,7 +66,7 @@ class _objectOrderFinder(object):
 class Scene(object):
        def __init__(self):
                self._objectList = []
-               self._sizeOffsets = numpy.array([3.0,3.0], numpy.float32)
+               self._sizeOffsets = numpy.array([0.0,0.0], numpy.float32)
                self._machineSize = numpy.array([100,100,100], numpy.float32)
                self._headOffsets = numpy.array([18.0,18.0], numpy.float32)
 
@@ -90,6 +90,11 @@ class Scene(object):
        def remove(self, obj):
                self._objectList.remove(obj)
 
+       def merge(self, obj1, obj2):
+               self.remove(obj2)
+               obj1._meshList += obj2._meshList
+               obj1.processMatrix()
+
        def pushFree(self):
                n = 1000
                while self._pushFree():
@@ -122,6 +127,8 @@ class Scene(object):
                order = _objectOrderFinder(self, self._headOffsets + self._sizeOffsets).order
                if order is None:
                        print "ODD! Cannot find out proper printing order!!!"
+                       for obj in self._objectList:
+                               print obj.getPosition(), obj.getSize()
                return order
 
        def _pushFree(self):
@@ -176,14 +183,14 @@ class Scene(object):
                for a in self._objectList:
                        p = a.getPosition()
                        s = (a.getSize()[0:2] + obj.getSize()[0:2]) / 2 + self._sizeOffsets + self._headOffsets
-                       posList.append(p + s * ( 1, 1))
-                       posList.append(p + s * ( 0, 1))
-                       posList.append(p + s * (-1, 1))
-                       posList.append(p + s * ( 10))
-                       posList.append(p + s * (-10))
-                       posList.append(p + s * ( 1,-1))
-                       posList.append(p + s * ( 0,-1))
-                       posList.append(p + s * (-1,-1))
+                       posList.append(p + s * ( 1.0, 1.0))
+                       posList.append(p + s * ( 0.0, 1.0))
+                       posList.append(p + s * (-1.0, 1.0))
+                       posList.append(p + s * ( 1.0, 0.0))
+                       posList.append(p + s * (-1.0, 0.0))
+                       posList.append(p + s * ( 1.0,-1.0))
+                       posList.append(p + s * ( 0.0,-1.0))
+                       posList.append(p + s * (-1.0,-1.0))
 
                best = None
                bestDist = None
index 2589ff2abd766e2933abadf3aa5628e28fe1bb85..2fa333e366c01403f356eece0bee9e93e8cb7514 100644 (file)
@@ -54,13 +54,14 @@ class Slicer(object):
                        for n in scene.printOrder():
                                obj = scene.objects()[n]
                                for mesh in obj._meshList:
-                                       n = numpy.array(mesh.vertexCount, numpy.int32)
+                                       n = numpy.array([mesh.vertexCount], numpy.int32)
                                        f.write(n.tostring())
                                        f.write(mesh.vertexes.tostring())
                                pos = obj.getPosition() * 1000
                                pos += numpy.array([profile.getPreferenceFloat('machine_width') * 1000 / 2, profile.getPreferenceFloat('machine_depth') * 1000 / 2])
                                commandList += ['-m', ','.join(map(str, obj._matrix.getA().flatten()))]
-                               commandList += ['-s', 'posx=%d' % int(pos[0]), '-s', 'posy=%d' % int(pos[1]), '#']
+                               commandList += ['-s', 'posx=%d' % int(pos[0]), '-s', 'posy=%d' % int(pos[1])]
+                               commandList += ['#' * len(obj._meshList)]
                                self._objCount += 1
                if self._objCount > 0:
                        print ' '.join(commandList)