Added obj support to Cura.
parent
58693d422a
commit
7eb9967ee4
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
Loading…
Reference in New Issue