chiark / gitweb /
Added dae support which can be exported from google sketchup.
authordaid303 <daid303@gmail.com>
Thu, 18 Oct 2012 21:25:24 +0000 (23:25 +0200)
committerdaid303 <daid303@gmail.com>
Thu, 18 Oct 2012 21:25:24 +0000 (23:25 +0200)
Cura/cura.py
Cura/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/dae.py [new file with mode: 0644]
Cura/util/dae.py [new file with mode: 0644]
Cura/util/meshLoader.py

index f98567617bf9e1c8849d4eb874fecc05f8491775..24c43c0ed1405824e8408ce1ae86a392a8365fdf 100644 (file)
@@ -19,6 +19,7 @@ from util import profile
 
 __author__ = 'Daid'
 __credits__ = """
+David Braam (daid303@gmail.com)
 Enrique Perez (perez_enrique@yahoo.com)
 Adrian Bowyer <http://forums.reprap.org/profile.php?12,13>
 Brendan Erwin <http://forums.reprap.org/profile.php?12,217>
@@ -37,6 +38,7 @@ Xsainnz <http://forums.reprap.org/profile.php?12,563>
 Zach Hoeken <http://blog.zachhoeken.com/>
 
 Organizations:
+Ultimaker <http://www.ultimaker.com>
 Art of Illusion <http://www.artofillusion.org/>"""
 
 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
diff --git a/Cura/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/dae.py b/Cura/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/dae.py
new file mode 100644 (file)
index 0000000..49569bc
--- /dev/null
@@ -0,0 +1,82 @@
+from __future__ import absolute_import
+#Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module.
+import __init__
+
+from fabmetheus_utilities.geometry.geometry_tools import face
+from fabmetheus_utilities.geometry.solids import triangle_mesh
+from fabmetheus_utilities.vector3 import Vector3
+
+from  xml.parsers.expat import ParserCreate
+
+def getCarving(fileName=''):
+       "Get the triangle mesh for the dae file."
+       return daeModel().load(fileName)
+
+class daeModel(triangle_mesh.TriangleMesh):
+       def __init__(self):
+               triangle_mesh.TriangleMesh.__init__(self)
+
+       def load(self, filename):
+               r = ParserCreate()
+               r.StartElementHandler = self._StartElementHandler
+               r.EndElementHandler = self._EndElementHandler
+               r.CharacterDataHandler = self._CharacterDataHandler
+
+               self._base = {}
+               self._cur = self._base
+               self._idMap = {}
+               self._geometryList = []
+               r.ParseFile(open(filename, "r"))
+               for geo in self._geometryList:
+                       self._ParseGeometry(self._idMap[geo['_url']])
+               self._base = None
+               self._cur = None
+               self._idMap = None
+               return self
+       
+       def _StartElementHandler(self, name, attributes):
+               while name in self._cur:
+                       name += "!"
+               self._cur[name] = {'_parent': self._cur}
+               self._cur = self._cur[name]
+               for k in attributes.keys():
+                       self._cur['_' + k] = attributes[k]
+               
+               if 'id' in attributes:
+                       self._idMap['#' + attributes['id']] = self._cur
+               
+               if name == 'instance_geometry':
+                       self._geometryList.append(self._cur)
+               
+       def _EndElementHandler(self, name):
+               self._cur = self._cur['_parent']
+
+       def _CharacterDataHandler(self, data):
+               if len(data.strip()) < 1:
+                       return
+               if '_data' in self._cur:
+                       self._cur['_data'] += data
+               else:
+                       self._cur['_data'] = data
+       
+       def _GetWithKey(self, item, basename, key, value):
+               input = basename
+               while input in item:
+                       if item[basename]['_'+key] == value:
+                               return self._idMap[item[input]['_source']]
+                       basename += "!"
+       
+       def _ParseGeometry(self, geo):
+               indexList = map(int, geo['mesh']['triangles']['p']['_data'].split())
+               vertex = self._GetWithKey(geo['mesh']['triangles'], 'input', 'semantic', 'VERTEX')
+               positionList = map(float, self._GetWithKey(vertex, 'input', 'semantic', 'POSITION')['float_array']['_data'].split())
+               
+               for idx in xrange(0, len(positionList), 3):
+                       self.vertexes.append(Vector3(positionList[idx], positionList[idx+1], positionList[idx+2]))
+               for idx in xrange(0, len(indexList), 3):
+                       f = face.Face()
+                       f.index = len(self.faces)
+                       f.vertexIndexes.append(indexList[idx])
+                       f.vertexIndexes.append(indexList[idx+1])
+                       f.vertexIndexes.append(indexList[idx+2])
+                       self.faces.append(f)
diff --git a/Cura/util/dae.py b/Cura/util/dae.py
new file mode 100644 (file)
index 0000000..3c01046
--- /dev/null
@@ -0,0 +1,69 @@
+import sys, math, re, os, struct, time
+from  xml.parsers.expat import ParserCreate
+
+import mesh
+
+class daeModel(mesh.mesh):
+       def __init__(self):
+               super(daeModel, self).__init__()
+
+       def load(self, filename):
+               r = ParserCreate()
+               r.StartElementHandler = self._StartElementHandler
+               r.EndElementHandler = self._EndElementHandler
+               r.CharacterDataHandler = self._CharacterDataHandler
+
+               self._base = {}
+               self._cur = self._base
+               self._idMap = {}
+               self._geometryList = []
+               r.ParseFile(open(filename, "r"))
+               for geo in self._geometryList:
+                       self._ParseGeometry(self._idMap[geo['_url']])
+               self._base = None
+               self._cur = None
+               self._idMap = None
+               
+               self._postProcessAfterLoad()
+               return self
+       
+       def _StartElementHandler(self, name, attributes):
+               while name in self._cur:
+                       name += "!"
+               self._cur[name] = {'_parent': self._cur}
+               self._cur = self._cur[name]
+               for k in attributes.keys():
+                       self._cur['_' + k] = attributes[k]
+               
+               if 'id' in attributes:
+                       self._idMap['#' + attributes['id']] = self._cur
+               
+               if name == 'instance_geometry':
+                       self._geometryList.append(self._cur)
+               
+       def _EndElementHandler(self, name):
+               self._cur = self._cur['_parent']
+
+       def _CharacterDataHandler(self, data):
+               if len(data.strip()) < 1:
+                       return
+               if '_data' in self._cur:
+                       self._cur['_data'] += data
+               else:
+                       self._cur['_data'] = data
+       
+       def _GetWithKey(self, item, basename, key, value):
+               input = basename
+               while input in item:
+                       if item[basename]['_'+key] == value:
+                               return self._idMap[item[input]['_source']]
+                       basename += "!"
+       
+       def _ParseGeometry(self, geo):
+               indexList = map(int, geo['mesh']['triangles']['p']['_data'].split())
+               vertex = self._GetWithKey(geo['mesh']['triangles'], 'input', 'semantic', 'VERTEX')
+               positionList = map(float, self._GetWithKey(vertex, 'input', 'semantic', 'POSITION')['float_array']['_data'].split())
+               
+               self._prepareVertexCount(len(indexList))
+               for idx in indexList:
+                       self.addVertex(positionList[idx*3], positionList[idx*3+1], positionList[idx*3+2])
index fea8ef6b27e88cf9a5d13a0956ec90ed93899a09..cb45c4b01f2cf054cf5a525cd76ed247967205ce 100644 (file)
@@ -1,9 +1,10 @@
 
 import stl
 import obj
+import dae
 
 def supportedExtensions():
-       return ['.stl', '.obj']
+       return ['.stl', '.obj', '.dae']
 
 def wildcardFilter():
        wildcardList = ';'.join(map(lambda s: '*' + s, supportedExtensions()))
@@ -15,6 +16,8 @@ def loadMesh(filename):
                return stl.stlModel().load(filename)
        if ext == '.obj':
                return obj.objModel().load(filename)
+       if ext == '.dae':
+               return dae.daeModel().load(filename)
        print 'Error: Unknown model extension: %s' % (ext)
        return None