######################################################################################################
# Convert between 3d object formats using Vue
#
# - massconvert.py
# - By Mark Caldwell
# - Version 0.5.1
# - 17th June 2007
# - Copyright Mark Caldwell 2007
# - Tested with Vue 6 Infinite on a PC
#
# Requires wxPython to be installed in to Vue to use.
#
# How to use in 2 easy steps
#
# 1. Download this file onto your computer
#
# 2. Run the script then follow the in script help for
# more information
#
# Conversion options are those currently selected under
# File -> Export As
#
######################################################################################################
######################################################################################################
#
# Set up by importing libraries
#
######################################################################################################
import os # import os libraries
import sys
VuePythonPath = sys.path[1] # get the Vue python path
VuePythonFolder = os.path.abspath(os.path.join(VuePythonPath[0:VuePythonPath.find("Python")],"Python"))
wxPythonFolder = os.path.abspath(os.path.join(VuePythonFolder,"PythonLib/wx"))
os.chdir(wxPythonFolder)
import wx # import the wx libraries
import wx.html # import the wx html libraries
import string # import string libraries
import time # import time
# get the Vue Python Folder
VuePythonFolder,junk = os.path.split(VuePythonPath)
# Get the Vue Root Path
VueRootPath,junk = os.path.split(VuePythonFolder)
######################################################################################################
#
# Create lists of file types that can be imported and exported
#
######################################################################################################
InExtensions=['3dmf','3ds','cob','dxf','lwo','obj','pz3','raw','shd','skp','vob']
OutExtensions=['3ds','c4d','dxf','lwo','obj','shd','vob']
######################################################################################################
#
# Class for the Main GUI
#
######################################################################################################
class MassConvertApp(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, parent = None, id = -1,
title = "MassConvert",
size = (600,400),
style = (wx.DEFAULT_FRAME_STYLE & ~ (wx.RESIZE_BORDER | wx.RESIZE_BOX | wx.MAXIMIZE_BOX)))
self.SetFont(wx.Font(10,wx.DEFAULT,wx.NORMAL,wx.NORMAL)) # Set Default Font
BoldFont=wx.Font(10,wx.DEFAULT,wx.NORMAL,wx.BOLD) # Create Bold Font for later use
self.ClearBackground()
# Set Some variables to use later
self.inFilepath = VueRootPath
self.outFilepath = VueRootPath
self.out_vob=0
self.InExtensionsBox=[]
self.OutExtensionsBox=[]
panel = wx.Panel(self) # Create Panel
panel.SetBackgroundColour('White')
statusBar = self.CreateStatusBar() # Create Status Bar
# Create Menu Structure
menuBar = wx.MenuBar()
menu1 = wx.Menu()
in_dir=menu1.Append(wx.NewId(), "&Import...", "Directory to import files from")
self.Bind(wx.EVT_MENU, self.OnIn, in_dir)
out_dir=menu1.Append(wx.NewId(), "&Export...", "Directory to export files to")
self.Bind(wx.EVT_MENU, self.OnOut, out_dir)
menu1.AppendSeparator()
exit=menu1.Append(wx.NewId(), "Exit")
self.Bind(wx.EVT_MENU, self.OnExit, exit)
menuBar.Append(menu1, "&File")
menu2 = wx.Menu()
helpmenu=menu2.Append(wx.NewId(), "&Help", "Help using MassConvert")
self.Bind(wx.EVT_MENU, self.OnHelp, helpmenu)
about=menu2.Append(wx.NewId(), "&About", "About MassConvert")
self.Bind(wx.EVT_MENU, self.OnAbout, about)
menuBar.Append(menu2, "&Help")
self.SetMenuBar(menuBar)
CheckBoxSize=(90, 20)
InColumnX=35
OutColumnX=180
inc=20
StartY=60
# Create File Path Text Display
text=wx.StaticText(panel,-1,"Import File Path:",(10,10))
text.SetFont(BoldFont)
self.InFilePathText=wx.StaticText(panel,-1,self.inFilepath,(120,10))
text=wx.StaticText(panel,-1,"Export File Path:",(10,10+inc))
text.SetFont(BoldFont)
self.OutFilePathText=wx.StaticText(panel,-1,self.outFilepath,(120,10+inc))
# Create File Import / Export Count Display
self.NumberOfFilesImportedLabel=wx.StaticText(panel,-1,'',(300,60))
self.NumberOfFilesImportedLabel.SetFont(BoldFont)
self.NumberOfFilesImported=wx.StaticText(panel,-1,'',(470,60))
self.NumberOfFilesExportedLabel=wx.StaticText(panel,-1,'',(300,80))
self.NumberOfFilesExportedLabel.SetFont(BoldFont)
self.NumberOfFilesExported=wx.StaticText(panel,-1,'',(470,80))
self.ConvertTimeLabel=wx.StaticText(panel,-1,'',(300,100))
self.ConvertTimeLabel.SetFont(BoldFont)
self.ConvertTime=wx.StaticText(panel,-1,'',(470,100))
# Create Check Boxes for Import Types
y=StartY
text=wx.StaticText(panel,-1,'Input File Types: ',(10,y))
text.SetFont(BoldFont)
y=y+inc
x=InColumnX
for Extension in InExtensions:
Box=wx.CheckBox(panel, -1, Extension, (x, y), CheckBoxSize)
self.InExtensionsBox.append((Extension,Box))
y=y+inc
yBottom=y+inc+inc
# Create Check Boxes for Output Type
y=StartY
x=OutColumnX
text=wx.StaticText(panel,-1,'Output File Types: ',(155,y))
text.SetFont(BoldFont)
y=y+inc
for Extension in OutExtensions:
Box=wx.CheckBox(panel, -1, Extension, (x, y), CheckBoxSize)
self.OutExtensionsBox.append((Extension,Box))
y=y+inc
y=y+inc+inc
# Create Convert Button
self.button = wx.Button(panel, -1, 'Convert', pos=(OutColumnX, y))
self.Bind(wx.EVT_BUTTON, self.OnClickConvert, self.button)
self.button.SetDefault()
self.CenterOnParent() # Center the GUI on the Vue Window
self.ClearBackground()
self.Show(True) # Show the GUI
######################################################################################################
#
# When the convert button is clicked
#
######################################################################################################
def OnClickConvert(self, event):
OutExtensionList=[]
InExtensionList=[]
objImportCount=0
objExportCount=0
startTime=time.time()
for Extension,Check in self.InExtensionsBox:
if Check.IsChecked():
InExtensionList.append(Extension)
for Extension,Check in self.OutExtensionsBox:
if Check.IsChecked():
OutExtensionList.append(Extension)
filenames=os.listdir(self.inFilepath)
for filename in filenames:
for extensionin in InExtensionList:
if '.'+extensionin in filename:
fullPath=self.inFilepath+'/'+filename
obj=ImportObject(fullPath)
if obj:
objImportCount=objImportCount+1
for extensionout in OutExtensionList:
newFileName=self.outFilepath+'/'+filename.replace('.'+extensionin,'.'+extensionout)
if os.path.exists(newFileName)!=True:
SelectOnly(obj)
ExportObject (newFileName)
objExportCount=objExportCount+1
SelectOnly(obj)
Delete()
endTime=time.time()
elapsedTime=endTime-startTime
self.NumberOfFilesImportedLabel.SetLabel('Number of Files Imported:')
self.NumberOfFilesExportedLabel.SetLabel('Number of Files Exported:')
self.ConvertTimeLabel.SetLabel('Time:')
self.NumberOfFilesImported.SetLabel(str(objImportCount))
self.NumberOfFilesExported.SetLabel(str(objExportCount))
self.ConvertTime.SetLabel(str(int(elapsedTime))+' seconds')
self.Raise()
######################################################################################################
#
# When exit and close are clicked
#
######################################################################################################
def OnExit(self, event):
self.Close()
def OnCloseMe(self, event):
self.Close(True)
def OnCloseWindow(self, event):
self.Destroy()
######################################################################################################
#
# Read the Input Directory
#
######################################################################################################
def OnIn(self, event):
dialog = wx.DirDialog(None, "Choose a directory to import from:",self.inFilepath,
style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON)
if dialog.ShowModal() == wx.ID_OK:
self.inFilepath = dialog.GetPath()
self.InFilePathText.SetLabel(self.inFilepath)
dialog.Destroy()
######################################################################################################
#
# Read the Export Directory
#
######################################################################################################
def OnOut(self, event):
dialog = wx.DirDialog(None, "Choose a directory to export to:",self.outFilepath,
style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON)
if dialog.ShowModal() == wx.ID_OK:
self.outFilepath=dialog.GetPath()
self.OutFilePathText.SetLabel(self.outFilepath)
dialog.Destroy()
######################################################################################################
#
# When About is clicked
#
######################################################################################################
def OnAbout(self, event):
dialog = MassConvertAbout(self)
dialog.ShowModal()
dialog.Destroy()
######################################################################################################
#
# When Help is clicked
#
######################################################################################################
def OnHelp(self, event):
dialog = MassConvertHelp(self)
dialog.ShowModal()
dialog.Destroy()
######################################################################################################
#
# About Window
#
######################################################################################################
class MassConvertAbout(wx.Dialog):
text = '''
<html>
<body bgcolor="#ffffff">
<center><table bgcolor="#ffffff" width="100%" cellspacing="0"
cellpadding="0" border="1">
<tr>
<td align="center"><h1>MassConvert</h1></td>
</tr>
</table>
</center>
<p align="center">Version 0.5.0</p>
<p align="center">http://www.impworks.co.uk/</p>
<p align="center">Copyright Mark Caldwell 2007</p>
<p align="center">Tested with Vue 6 Infinite on a PC</p>
</body>
</html>
'''
def __init__(self, parent):
wx.Dialog.__init__(self, parent, -1, 'About MassConvert',
size=(440, 300) )
html = wx.html.HtmlWindow(self)
html.SetPage(self.text)
button = wx.Button(self, wx.ID_OK, "Okay")
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(html, 1, wx.EXPAND|wx.ALL, 5)
sizer.Add(button, 0, wx.ALIGN_CENTER|wx.ALL, 5)
self.SetSizer(sizer)
self.Layout()
######################################################################################################
#
# Help Window
#
######################################################################################################
class MassConvertHelp(wx.Dialog):
text = '''
<html>
<body bgcolor="#ffffff">
<center><table bgcolor="#ffffff" width="100%" cellspacing="0"
cellpadding="0" border="1">
<tr>
<td align="center"><h1>MassConvert Help</h1></td>
</tr>
</table>
</center>
<p>This Vue python script reads 3d object files from a selected import directory and saves them in new formats to
a selected export directory. If it finds a file of the same name as one it is trying to create already exists in the
export directory it doesn't export the file.</p>
<p>Select the directory to import files from in the <em>File</em> menu with <em>Import...</em>.</p>
<p>Select the directory to export files from in the <em>File</em> menu with <em>Export...</em>.</p>
<p>Select the types of file to import and the types of file to export with the check boxes.</p>
<p>Once you've made your selections click the <em>Convert</em> button and Vue will import the selected files
and export them in the selected formats.</p>
<p>The export will use the settings from the last export you did with Vue.</p>
<p>When converting some file formats (such as poser) Vue will ask you to make choices during the import.</p>
</body>
</html>
'''
def __init__(self, parent):
wx.Dialog.__init__(self, parent, -1, 'MassConvert Help',
size=(440, 550) )
html = wx.html.HtmlWindow(self)
html.SetPage(self.text)
button = wx.Button(self, wx.ID_OK, "Close")
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(html, 1, wx.EXPAND|wx.ALL, 5)
sizer.Add(button, 0, wx.ALIGN_CENTER|wx.ALL, 5)
self.SetSizer(sizer)
self.Layout()
######################################################################################################
#
# Start of Program
#
######################################################################################################
app = None # Clear out any previous instances of app
del app # destroy it completely
app = wx.PySimpleApp() # Create a new wx application instance
frame = MassConvertApp() # Create the GUI instance
app.MainLoop() # Execute wx
Refresh()