Bugs in Flour with convex conversion and different paths

Senzin

04-01-2013 05:04:14

I found a very odd bug in Flour. I have a python script that calls all the binaries and scripts to convert a .mesh to a .nxs, for both triangle and convex meshes.

Binaries and scripts:
OgreXMLConverter.exe, Ogre 1.8.1
ogrexmltoflower.rb (with appropriate triangle/convex argument)
Flour.exe 0.4.7

CONVERSION BUG:
However, I noticed all the convex meshes were resulting in 0kb size .nxs files. However, when I went through the process manually in cmd.exe, it worked perfectly.

I eventually whittled the problem down to how I was calling Flour.exe from the script. Originally, (and with no problems for all the other binaries/scripts), I was using the os.system() function:
os.system('flour.exe convert ' + name)
When I changed it to use subprocess, it starting working just fine:
subprocess.call('flour.exe convert ' + name)
That's a strange bug, for sure.

PATH BUG:
All the other converters in this pipeline are able to convert files in other locations and will put the output in those same locations. Flour, however, throws an exception if I give it a path to a file in some other directory.


=====================================================================
Path is invalid (FileResource)
=====================================================================

The following path could not be opened or is invalid:
D/Development/Libs/Ogre/OgreSDK_vc10_v1-8-1/mediaMain/physics/NxCon_pCube1.flower

From: d:\development\libs\nxogre\nxogre\build\source\NxOgreFileResource.cpp#113

=====================================================================

Exception Called.

My workaround has been to move the file being converted to the location of flour.exe first, then convert it and move it back. Perhaps there is some special way I can pass the path to flour to make it work? But again, all the others worked just fine. Could I have built it wrong?

FILE LENGTH BUG:
I've run into another bug. When file names are too long, flour outputs a 0kb file, just like the first problem described above. A name such as "NxCon_bldg_wallQuarter_1.mesh" becomes "NxCon_bldg_wallQuarter_1.mesh.xml" and then "NxCon_bldg_wallQuarter_1.flower". That last file name has 25 characters plus 7 more for ".flower" for a total of 32. The output nxs file will be 0kb. If I shorten the file name by one character, it works fine. And once again, this problem only occurs when scripting. If I do it manually in cmd.exe, it works fine.

Edit: Ok, this is really weird. I didn't mention it before, but I actually call my conversion script from within Maya like this:


system("D:/Dev/Libs/NxOgre/flour/run/Convert.lnk " + $lfa_storedExportDir);
print("Convert to Nx Done\n");

This is the mel script that runs when I hit a custom button within Metaldev's LFA Scene Manager. Notice it simply runs a shortcut and passes it the export path used by LFA. The shortcut just runs the python script below. So, I just described above a limitation to the file name length. Well... if I just put the export path in the shortcut and hit it instead of doing it from within Maya, then it works fine. Astonishing! What could possibly be happening between that tiny system call above and the shortcut that causes such strange problems??

SCRIPT:
Here's my conversion script (Python) in case anyone wants to use it. Place the script itself in a directory along with all the conversion binaries (mesh to xml, xml to flower, flower to nxs) in one place. Then you execute the script with the export directory as the argument. The export directory is where your mesh files should be and where the nxs files will end up. All files to be converted must be prefixed with NxCon or NxTri for PhysX Convex and PhysX Triangle. This way the same folder can have other meshes that should not be converted, and also distinguishes between convex and triangle meshes. Also, if an nxs file already exists for a mesh, it will compare their modification dates and will only generate a new nxs file if the mesh file is newer. An easy way to use it is to make a shortcut on your desktop with the export directory as an argument. Then, whenever you export new meshes, just hit the shortcut.


import os
import sys
import inspect
from glob import glob
import subprocess

# Directory of conversion binaries and scripts
binDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))

exportPath = ''
try:
exportPath = sys.argv[1]
if not os.path.isdir(exportPath):
raise
except:
print 'Bad exportPath argument'
exit

# Convert MESH to XML
for f in glob(exportPath + '/*NxCon*.mesh') + glob(exportPath + '/*NxTri*.mesh'):
nxsFile = os.path.splitext(f)[0] + '.nxs'
if os.path.isfile(nxsFile): # If NXS already file exists...
if os.path.getmtime(nxsFile) > os.path.getmtime(f): # And if NXS file is newer...
# No need to convert
continue
os.system('OgreXMLConverter.exe ' + f)

# Convert CONVEX XML to FLOWER
for f in glob(exportPath + '/*NxCon*.mesh.xml'):
os.system('ogrexmltoflower.rb convex ' + f)

# Convert TRIANGLE XML to FLOWER
for f in glob(exportPath + '/*NxTri*.mesh.xml'):
os.system('ogrexmltoflower.rb triangle ' + f)

# Move FLOWER to binDir and convert FLOWER to NXS
for f in glob(exportPath + '/*.flower'):
name = os.path.basename(f)
os.system('move /Y ' + f + ' ' + binDir)
cmd = 'flour.exe convert ' + name
# os.system(cmd)
# subprocess.call(cmd)
p = subprocess.Popen(cmd, shell=True)
p.wait()

# Move NXS to exportPath
for f in glob(binDir + '/*.nxs'):
os.system('move /Y ' + f + ' ' + exportPath)

# Delete XML intermediates
for f in glob(exportPath + '/*.mesh.xml'):
os.system('del ' + f)

# Delete FLOWER intermediates
for f in glob(binDir + '/*.flower'):
os.system('del ' + f)