Added obj support to Cura.

master
daid 2012-09-26 14:35:35 +02:00
parent 58693d422a
commit 7eb9967ee4
8 changed files with 96 additions and 23 deletions

View File

@ -5,6 +5,7 @@ import wx, os, platform, types, webbrowser, math, subprocess, multiprocessing, t
from util import profile
from util import sliceRun
from util import meshLoader
from gui import dropTarget
class batchRunWindow(wx.Frame):
@ -13,7 +14,7 @@ class batchRunWindow(wx.Frame):
self.list = []
self.SetDropTarget(dropTarget.FileDropTarget(self.OnDropFiles, '.stl'))
self.SetDropTarget(dropTarget.FileDropTarget(self.OnDropFiles, meshLoader.supportedExtensions()))
wx.EVT_CLOSE(self, self.OnClose)
self.panel = wx.Panel(self, -1)

View File

@ -11,8 +11,14 @@ class FileDropTarget(wx.FileDropTarget):
self.filenameFilter = filenameFilter
def OnDropFiles(self, x, y, filenames):
filteredList = []
if self.filenameFilter != None:
filenames = filter(lambda f: f.endswith(self.filenameFilter) or f.endswith(self.filenameFilter.upper()), filenames)
if len(filenames) > 0:
self.callback(filenames)
for f in filenames:
for ext in self.filenameFilter:
if f.endswith(ext) or f.endswith(ext.upper()):
filteredList.append(f)
else:
filteredList = filenames
if len(filteredList) > 0:
self.callback(filteredList)

View File

@ -22,6 +22,7 @@ from util import validators
from util import profile
from util import version
from util import sliceRun
from util import meshLoader
def main():
#app = wx.App(False)
@ -44,7 +45,7 @@ class mainWindow(configBase.configWindowBase):
wx.EVT_CLOSE(self, self.OnClose)
#self.SetIcon(icon.getMainIcon())
self.SetDropTarget(dropTarget.FileDropTarget(self.OnDropFiles, '.stl'))
self.SetDropTarget(dropTarget.FileDropTarget(self.OnDropFiles, meshLoader.supportedExtensions()))
menubar = wx.MenuBar()
fileMenu = wx.Menu()
@ -339,7 +340,7 @@ class mainWindow(configBase.configWindowBase):
configWizard.configWizard()
self.updateProfileToControls()
def _showOpenDialog(self, title, wildcard = "STL files (*.stl)|*.stl;*.STL"):
def _showOpenDialog(self, title, wildcard = meshLoader.wildcardFilter()):
dlg=wx.FileDialog(self, title, os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
dlg.SetWildcard(wildcard)
if dlg.ShowModal() == wx.ID_OK:

View File

@ -20,7 +20,7 @@ from gui import toolbarUtil
from util import profile
from util import gcodeInterpreter
from util import stl
from util import meshLoader
from util import util3d
from util import sliceRun
@ -264,8 +264,7 @@ class previewPanel(wx.Panel):
for obj in self.objectList:
if obj.filename != None and os.path.isfile(obj.filename) and obj.fileTime != os.stat(obj.filename).st_mtime:
obj.ileTime = os.stat(obj.filename).st_mtime
mesh = stl.stlModel()
mesh.load(obj.filename)
mesh = meshLoader.loadMesh(obj.filename)
obj.dirty = False
obj.mesh = mesh
self.updateModelTransform()

View File

@ -25,6 +25,7 @@ from gui import dropTarget
from util import validators
from util import profile
from util import util3d
from util import meshLoader
from util import stl
from util import mesh
from util import sliceRun
@ -34,11 +35,11 @@ from util import exporer
class Action(object):
pass
class ProjectObject(stl.stlModel):
class ProjectObject(object):
def __init__(self, parent, filename):
super(ProjectObject, self).__init__()
self.load(filename)
self.mesh = meshLoader.loadMesh(filename)
self.parent = parent
self.filename = filename
@ -55,7 +56,7 @@ class ProjectObject(stl.stlModel):
self.modelDisplayList = None
self.modelDirty = False
self.getMinimumZ()
self.mesh.getMinimumZ()
self.centerX = -self.getMinimum()[0] + 5
self.centerY = -self.getMinimum()[1] + 5
@ -89,14 +90,21 @@ class ProjectObject(stl.stlModel):
return True
def updateModelTransform(self):
self.setRotateMirror(self.rotate, self.flipX, self.flipY, self.flipZ, self.swapXZ, self.swapYZ)
minZ = self.getMinimumZ()
self.mesh.setRotateMirror(self.rotate, self.flipX, self.flipY, self.flipZ, self.swapXZ, self.swapYZ)
minZ = self.mesh.getMinimumZ()
minV = self.getMinimum()
maxV = self.getMaximum()
self.vertexes -= numpy.array([minV[0] + (maxV[0] - minV[0]) / 2, minV[1] + (maxV[1] - minV[1]) / 2, minZ])
minZ = self.getMinimumZ()
self.mesh.vertexes -= numpy.array([minV[0] + (maxV[0] - minV[0]) / 2, minV[1] + (maxV[1] - minV[1]) / 2, minZ])
minZ = self.mesh.getMinimumZ()
self.modelDirty = True
def getMinimum(self):
return self.mesh.getMinimum()
def getMaximum(self):
return self.mesh.getMaximum()
def getSize(self):
return self.mesh.getSize()
def clone(self):
p = ProjectObject(self.parent, self.filename)
@ -139,7 +147,7 @@ class projectPlanner(wx.Frame):
self.GetSizer().Add(self.panel, 1, flag=wx.EXPAND)
#self.SetIcon(icon.getMainIcon())
self.SetDropTarget(dropTarget.FileDropTarget(self.OnDropFiles, '.stl'))
self.SetDropTarget(dropTarget.FileDropTarget(self.OnDropFiles, meshLoader.supportedExtensions()))
self.list = []
self.selection = None
@ -268,10 +276,10 @@ class projectPlanner(wx.Frame):
def OnCutMesh(self, e):
dlg=wx.FileDialog(self, "Open file to cut", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
dlg.SetWildcard("STL files (*.stl)|*.stl;*.STL")
dlg.SetWildcard(meshLoader.wildcardFilter())
if dlg.ShowModal() == wx.ID_OK:
filename = dlg.GetPath()
model = stl.stlModel().load(filename)
model = meshLoader.loadMesh(filename)
pd = wx.ProgressDialog('Splitting model.', 'Splitting model into multiple parts.', model.vertexCount, self, wx.PD_ELAPSED_TIME | wx.PD_REMAINING_TIME | wx.PD_SMOOTH)
parts = model.splitToParts(pd.Update)
for part in parts:
@ -317,7 +325,7 @@ class projectPlanner(wx.Frame):
output._prepareVertexCount(totalCount)
for item in self.list:
offset = numpy.array([item.centerX, item.centerY, 0])
for v in item.vertexes:
for v in item.mesh.vertexes:
v0 = v * item.scale + offset
output.addVertex(v0[0], v0[1], v0[2])
stl.saveAsSTL(output, filename)
@ -419,7 +427,7 @@ class projectPlanner(wx.Frame):
def OnAddModel(self, e):
dlg=wx.FileDialog(self, "Open file to print", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST|wx.FD_MULTIPLE)
dlg.SetWildcard("STL files (*.stl)|*.stl;*.STL")
dlg.SetWildcard(meshLoader.wildcardFilter())
if dlg.ShowModal() == wx.ID_OK:
for filename in dlg.GetPaths():
item = ProjectObject(self, filename)
@ -807,7 +815,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
item.modelDirty = False
modelSize = item.getMaximum() - item.getMinimum()
glNewList(item.modelDisplayList, GL_COMPILE)
opengl.DrawMesh(item)
opengl.DrawMesh(item.mesh)
glEndList()
if item.validPlacement:

View File

@ -151,7 +151,7 @@ class simpleModeWindow(configBase.configWindowBase):
def OnLoadModel(self, e):
dlg=wx.FileDialog(self, "Open file to print", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
dlg.SetWildcard("STL files (*.stl)|*.stl;*.STL")
dlg.SetWildcard(meshLoader.wildcardFilter())
if dlg.ShowModal() == wx.ID_OK:
self.filelist = [dlg.GetPath()]
profile.putPreference('lastFile', ';'.join(self.filelist))

20
Cura/util/meshLoader.py Normal file
View File

@ -0,0 +1,20 @@
import stl
import obj
def supportedExtensions():
return ['.stl', '.obj']
def wildcardFilter():
wildcardList = ';'.join(map(lambda s: '*' + s, supportedExtensions()))
return "Mesh files (%s)|%s;%s" % (wildcardList, wildcardList, wildcardList.upper())
def loadMesh(filename):
ext = filename[filename.rfind('.'):].lower()
if ext == '.stl':
return stl.stlModel().load(filename)
if ext == '.obj':
return obj.objModel().load(filename)
print 'Error: Unknown model extension: %s' % (ext)
return None

38
Cura/util/obj.py Normal file
View File

@ -0,0 +1,38 @@
import sys, math, re, os, struct, time
import mesh
class objModel(mesh.mesh):
def __init__(self):
super(objModel, self).__init__()
def load(self, filename):
vertexList = []
faceList = []
f = open(filename, "r")
for line in f:
parts = line.split()
if len(parts) < 1:
continue
if parts[0] == 'v':
vertexList.append([float(parts[1]), float(parts[2]), float(parts[3])])
if parts[0] == 'f':
parts[1] = parts[1].split('/')[0]
parts[2] = parts[2].split('/')[0]
parts[3] = parts[3].split('/')[0]
faceList.append([int(parts[1]), int(parts[2]), int(parts[3])])
f.close()
self._prepareVertexCount(len(faceList) * 3)
for f in faceList:
i = f[0] - 1
self.addVertex(vertexList[i][0], vertexList[i][1], vertexList[i][2])
i = f[1] - 1
self.addVertex(vertexList[i][0], vertexList[i][1], vertexList[i][2])
i = f[2] - 1
self.addVertex(vertexList[i][0], vertexList[i][1], vertexList[i][2])
self._postProcessAfterLoad()
return self