With the amount of issues that can arise from data stored in meshes I decided to write a script. Usually exporting as .obj can solve a lot of things but sometimes it’s easier to resort to rebuilding a mesh by hand especially if you don’t know the problem.
script does exactly that for you in a few seconds (depending on poly count and your processor), and it lets you keep your UVs, normals, and even skin/weights. It is a good way to isolate components as well such as geometry, UVs, normals, and rig.
I wrote it very quickly, I will probably do it properly later but for now with an interface, error checking, and hopefully better efficiency.
If you (after saving a copy…) select your object and run it, it will rebuild your mesh using only the vertex positions.
Note:
It is a draft and there is no error checking, so if you get an error then it was given incorrect information
To use:
- Backup your scene, make a copy, don’t work in your originals
- Copy/Paste the script below into your script editor (accessible via the button in the very bottom-right corner of the Maya interface)
- By default, after rebuilding your mesh, it will copy over your UV’s, normals, and skin/weights. If you don’t want any of these change from ‘True’ to ‘False’ and note the capitalization of the first letter (it will error if you use ‘false’ instead of ‘False’) and don’t use quotation marks
- If your mesh does not have a skin attached you must disable “transferBindAndWeight” by setting it from True to False.
- Close UV editor. It will work with it open but take a VERY long time (maybe 5x longer).
- Select your object (must be an object, not components such as faces or vertices or the script will break)
- Run the script (Either press numpad enter, or click the single blue arrow on the menu at the top of the script editor) - Selecting the text prior to executing will keep it in the script editor, unselected text is consumed on successful execution
A 6k poly mesh took around 10-15 seconds on my i7 @ 3.4ghz, be wary of high density meshes.
If I re-write it I’ll make a thread for it, right now it’s very much a prototype but I whipped it up to see if it’d solve your mesh’s issues.
Here is the python code:
import maya.cmds as cmds
import maya.mel as mel
'''
PolyReconstruct v0.0.1 by Taylor
- Will rebuild a mesh using only the vertex positions,
- Can transfer the UVs and skinning from original
- You MUST specify False for transferBindAndWeight if there is no skin
- Takes around 10-15 seconds for a 6k poly mesh on my i7 processor, be wary for high density meshes
-->CLOSE UV EDITOR BEFORE RUNNING SCRIPT - IT WILL TAKE 5x LONGER IF IT IS OPEN<--
Anything that can update during the execution of a script will update on every operation, including
the UV editor making the running time significantly longer
'''
#--------------------------------
#CHANGE ONLY THESE OPTIONS
transferUVData = True#Keep UVs from original mesh
transferNormalData = True#Keep normals from original mesh
transferBindAndWeight = True#Transfer character skin and weight - DISABLE if no skin!
#--------------------------------
#DO NOT CHANGE BELOW
obj = cmds.ls(sl = 1)[0]
cmds.select(cmds.polyListComponentConversion(obj, tf = 1))
faces = cmds.ls(sl = 1, fl = 1)
newfaces = ]
for f in faces:
cmds.select(cmds.polyListComponentConversion(f, fromFace = 1, toVertex = 1))
vtx = cmds.ls(sl = 1, fl = 1)
vtxPos = ]
bgnV = vtx[0]
finV = ]
match = ]
cmds.select(cmds.polyListComponentConversion(vtx[0], fromVertex = 1, toEdge = 1))
mel.eval("PolySelectConvert 3;")
vertEdge = cmds.ls(sl = 1, fl = 1)
vertEdge.remove(vtx[0])
for v in vtx:
if not v in vertEdge:
finV = v
else:
match.append(v)
if len(vtx) > 3:#poly
order = bgnV, match[0], finV, match[1]
else:#tri
order = bgnV, match[0], match[1]
for o in order:
vtxPos.append(tuple(cmds.xform(o, q = 1, t = 1, ws = 1)))
newfaces.append(cmds.polyCreateFacet(p = vtxPos, ch = 0)[0])
cmds.select(newfaces, r = 1)
newMesh = cmds.polyUnite(newfaces, n = "Generated_PolyReconstruct_Geo", ch = 0)
cmds.polyMergeVertex(newMesh, d = 0.0001, am = 1, ch = 0)
cmds.polyNormal(newMesh, normalMode = 2, userNormalMode = 0, ch = 0)
if transferUVData:
cmds.transferAttributes(obj, newMesh, transferPositions = 0, transferNormals = transferNormalData, transferUVs = 2, transferColors = 2, sampleSpace = 0, searchMethod = 3, flipUVs = 0, colorBorders = 1)
if transferNormalData:
cmds.transferAttributes(obj, newMesh, transferPositions = 0, transferNormals = 1, transferUVs = 0, transferColors = 2, sampleSpace = 0, searchMethod = 3, flipUVs = 0, colorBorders = 1)
cmds.DeleteHistory(newMesh)
if transferBindAndWeight:
jnts = cmds.skinCluster(obj, inf = 1, q = 1)
mif = cmds.skinCluster(obj, mi = 1, q = 1)
bnm = cmds.skinCluster(obj, bm = 1, q = 1)
skm = cmds.skinCluster(obj, sm = 1, q = 1)
nmw = cmds.skinCluster(obj, nw = 1, q = 1)
newSkin = cmds.skinCluster(newMesh, jnts, dr = 4, mi = mif, bm = bnm, sm = skm, nw = nmw)
cmds.copySkinWeights(obj, newMesh, noMirror = 1, surfaceAssociation = "closestPoint", influenceAssociation = "oneToOne")
cmds.select(newMesh, r = 1)