def buildFromAbc(self, thing, abcPath, pBar=None): """ Load a system from an exported abc file onto the current system """ if pBar is not None: pBar.show() pBar.setMaximum(100) pBar.setValue(0) pBar.setLabelText("Loading Smpx") QApplication.processEvents() iarch = IArchive(str(abcPath)) # because alembic hates unicode try: top = iarch.getTop() par = top.children[0] par = IXform(top, par.getName()) abcMesh = par.children[0] abcMesh = IPolyMesh(par, abcMesh.getName()) systemSchema = par.getSchema() props = systemSchema.getUserProperties() prop = props.getProperty("simplex") jsString = prop.getValue() js = json.loads(jsString) system = self.buildFromDict(thing, js, True, pBar) self.DCC.loadABC(abcMesh, js, pBar) finally: del iarch return system
def loadSMPX(cls, smpx): iarch = IArchive(str(smpx)) # because alembic hates unicode try: top = iarch.getTop() par = top.children[0] par = IXform(top, par.getName()) abcMesh = par.children[0] abcMesh = IPolyMesh(par, abcMesh.getName()) systemSchema = par.getSchema() props = systemSchema.getUserProperties() prop = props.getProperty('simplex') jsString = prop.getValue() js = json.loads(jsString) system = cls.loadJSON(js) system._smpx = smpx meshSchema = abcMesh.getSchema() rawFaces = meshSchema.getFaceIndicesProperty().samples[0] rawCounts = meshSchema.getFaceCountsProperty().samples[0] system._faces = [i for i in rawFaces] system._counts = [i for i in rawCounts] for shape, sample in zip( system.shapes, meshSchema.getPositionsProperty().samples): shape.loadSMPX(sample) finally: del iarch return system
def loadAbc(cls, path, meshName=None, ensureWinding=True): """ Read a .abc file and produce a Mesh object Parameters ---------- path: str The path to the .abc formatted file Returns ------- : Mesh Mesh object containing lists of linked vertices, edges, and faces Raises ------ IOError If the file cannot be opened """ from alembic.Abc import IArchive from alembic.AbcGeom import IPolyMesh from .alembicCommon import findAlembicObject iarch = IArchive(str(path)) # because alembic hates unicode mesh = findAlembicObject(iarch.getTop(), abcType=IPolyMesh, name=meshName) sch = mesh.getSchema() rawVerts = sch.getPositionsProperty().samples[0] rawFaces = sch.getFaceIndicesProperty().samples[0] rawCounts = sch.getFaceCountsProperty().samples[0] iuvs = sch.getUVsParam() faces = [] faceCounter = 0 for count in rawCounts: faces.append(list(rawFaces[faceCounter:faceCounter + count])) faceCounter += count uvs = None uvFaces = None if iuvs.valid(): uvValue = iuvs.getValueProperty().getValue() uvs = list(zip(uvValue.x, uvValue.y)) if iuvs.isIndexed(): idxs = list(iuvs.getIndexProperty().getValue()) uvFaces = [] uvCounter = 0 for count in rawCounts: uvFaces.append(list(idxs[uvCounter:uvCounter + count])) uvCounter += count verts = [] for v in rawVerts: verts.append(list(v)) return cls(verts, faces, uvs=uvs, uvFaces=uvFaces, ensureWinding=ensureWinding)
def exportUnsub(inPath, outPath, newFaces, kept, shapePrefix=None, pBar=None): ''' Export the unsubdivided simplex ''' iarch = IArchive(str(inPath)) # because alembic hates unicode top = iarch.getTop() ixfo = IXform(top, top.children[0].getName()) iprops = ixfo.getSchema().getUserProperties() iprop = iprops.getProperty("simplex") jsString = iprop.getValue() if shapePrefix is not None: d = json.loads(jsString) if d['encodingVersion'] > 1: for shape in d['shapes']: shape['name'] = shapePrefix + shape['name'] else: d['shapes'] = [shapePrefix + i for i in d['shapes']] jsString = json.dumps(d) imesh = IPolyMesh(ixfo, ixfo.children[0].getName()) verts = getSampleArray(imesh) verts = verts[:, kept] indices = [] counts = [] for f in newFaces: indices.extend(f) counts.append(len(f)) abcCounts = mkArray(IntArray, counts) abcIndices = mkArray(IntArray, indices) # `False` for HDF5 `True` for Ogawa oarch = OArchive(str(outPath), False) oxfo = OXform(oarch.getTop(), ixfo.getName()) oprops = oxfo.getSchema().getUserProperties() oprop = OStringProperty(oprops, "simplex") oprop.setValue(str(jsString)) omesh = OPolyMesh(oxfo, imesh.getName()) osch = omesh.getSchema() if pBar is not None: pBar.setValue(0) pBar.setMaximum(len(verts)) pBar.setLabelText("Exporting Unsubdivided Shapes") QApplication.processEvents() for i, v in enumerate(verts): if pBar is not None: pBar.setValue(i) QApplication.processEvents() else: print "Exporting Unsubdivided Shape {0: <4}\r".format(i + 1), sample = OPolyMeshSchemaSample(mkSampleVertexPoints(v), abcIndices, abcCounts) osch.set(sample) if pBar is None: print "Exporting Unsubdivided Shape {0: <4}".format(len(verts))
def post(self): iarch = IArchive('/file.abc') top = iarch.getTop() hierarchy = [] yield self.recurse(top, hierarchy) self.write(escape.json_encode({"hierarchy": hierarchy}) + "\n")
def _openSmpx(inPath): iarch = IArchive(str(inPath)) # because alembic hates unicode top = iarch.getTop() ixfo = IXform(top, top.children[0].getName()) iprops = ixfo.getSchema().getUserProperties() iprop = iprops.getProperty("simplex") jsString = iprop.getValue() imesh = IPolyMesh(ixfo, ixfo.children[0].getName()) return iarch, imesh, jsString, ixfo.getName(), imesh.getName()
def _loadJSString(srcSmpxPath): ''' Get the json string out of a .smpx file ''' iarch = IArchive(str(srcSmpxPath)) top = iarch.getTop() par = top.children[0] parName = par.getName() par = IXform(top, parName) systemSchema = par.getSchema() props = systemSchema.getUserProperties() prop = props.getProperty("simplex") jsString = prop.getValue() return jsString, parName
def mismatchedTransfer(sourcePath, matchPath, outPath, invertMatch=False): ''' Transfer shape data from the sourcePath using the numpy int array at matchPath to make the final output at outPath ''' print "Loading Simplex" sourceArch = IArchive(str(sourcePath)) # because alembic hates unicode sourceShapes = getShapes(sourceArch) jsString = loadJSString(sourceArch) sFaces, counts = getMesh(sourceArch) sFaces = np.array(sFaces) print "Loading Correspondence" c = np.load(matchPath) c = c[c[:, 0].argsort()].T[1] ci = c.argsort() if invertMatch: ci, c = c, ci print "Reordering" targetShapes = sourceShapes[:, c, :] faces = mkSampleIntArray(ci[sFaces]) print "Writing" oarch = OArchive(str(outPath)) # alembic does not like unicode filepaths try: _writeSimplex(oarch, 'Face', jsString, faces, counts, targetShapes) finally: del oarch gc.collect()
def writeSimplex(inPath, outPath, newShapes, name='Face', pBar=None): '''Write a simplex file with new shapes Parameters ---------- inPath : str The input .smpx file path outPath : str The output .smpx file path newShapes : np.array A numpy array of shapes to write name : str The name of the new system pBar : QProgressDialog, optional An optional progress dialog Returns ------- ''' if not os.path.isfile(str(inPath)): raise IOError("File does not exist: " + str(inPath)) iarch = IArchive(str(inPath)) jsString = loadJSString(iarch) faces, counts = loadMesh(iarch) del iarch oarch = OArchive(str(outPath), OGAWA) # alembic does not like unicode filepaths try: _writeSimplex(oarch, name, jsString, faces, counts, newShapes, pBar) finally: del oarch gc.collect()
def hdf5Convert(inPath, outPath, ogawa=False): '''Load and parse all the data from a simplex file Parameters ---------- inPath : str The input .smpx file path outPath : str The output .smpx file path ogawa : bool Whether to write out in Ogawa format. Defaults False Returns ------- ''' if not os.path.isfile(str(inPath)): raise IOError("File does not exist: " + str(inPath)) iarch = IArchive(str(inPath)) jsString = loadJSString(iarch) shapes = loadSmpx(iarch) faces, counts = loadMesh(iarch) del iarch oarch = OArchive(str(outPath), ogawa) # alembic does not like unicode filepaths try: _writeSimplex(oarch, 'Face', jsString, faces, counts, shapes) finally: del oarch gc.collect()
def buildBaseAbc(self, abcPath): iarch = IArchive(str(abcPath)) # because alembic hates unicode try: top = iarch.getTop() par = top.children[0] par = IXform(top, par.getName()) abcMesh = par.children[0] abcMesh = IPolyMesh(par, abcMesh.getName()) systemSchema = par.getSchema() props = systemSchema.getUserProperties() prop = props.getProperty("simplex") jsString = prop.getValue() js = json.loads(jsString) obj = self.DCC.buildRestABC(abcMesh, js) finally: del iarch return obj
def getSmpxArchiveData(abcPath): '''Read and return the low level relevant data from a simplex alembic Parameters ---------- abcPath : str The path to the .smpx file Returns ------- : IArchive An opened Alembic IArchive object handle : IPolyMesh An Alembic Mesh handle : str The json definition string ''' if not os.path.isfile(str(abcPath)): raise IOError("File does not exist: " + str(abcPath)) iarch = IArchive(str(abcPath)) # because alembic hates unicode top, par, abcMesh = [None] * 3 try: top = iarch.getTop() par = top.children[0] par = IXform(top, par.getName()) abcMesh = par.children[0] abcMesh = IPolyMesh(par, abcMesh.getName()) # I *could* come up with a generic property reader # but it's useless for me at this time sch = par.getSchema() props = sch.getUserProperties() jsString = readStringProperty(props, "simplex") except Exception: #pylint: disable=broad-except # ensure that the .smpx file is released iarch, top, par, abcMesh = [None] * 4 raise # Must return the archive, otherwise it gets GC'd return iarch, abcMesh, jsString
def writeSimplex(inPath, outPath, newShapes, name='Face', pBar=None): ''' Write a simplex file with new shapes ''' iarch = IArchive(str(inPath)) jsString = loadJSString(iarch) faces, counts = loadMesh(iarch) del iarch oarch = OArchive(str(outPath)) # alembic does not like unicode filepaths try: _writeSimplex(oarch, name, jsString, faces, counts, newShapes, pBar) finally: del oarch gc.collect()
def hdf5Convert(inPath, outPath): ''' Load and parse all the data from a simplex file ''' iarch = IArchive(str(inPath)) jsString = loadJSString(iarch) shapes = loadSmpx(iarch) faces, counts = loadMesh(iarch) del iarch oarch = OArchive(str(outPath), False) # alembic does not like unicode filepaths try: _writeSimplex(oarch, 'Face', jsString, faces, counts, shapes) finally: del oarch gc.collect()
def readFalloffData(abcPath): '''Load the relevant data from a simplex alembic Parameters ---------- abcPath : str Path to the .smpx file ''' if not os.path.isfile(str(abcPath)): raise IOError("File does not exist: " + str(abcPath)) iarch = IArchive(str(abcPath)) # because alembic hates unicode top, par, systemSchema, foPropPar, foProp = [None] * 5 try: top = iarch.getTop() par = top.children[0] par = IXform(top, par.getName()) systemSchema = par.getSchema() props = systemSchema.getUserProperties() foDict = {} try: foPropPar = props.getProperty("falloffs") except KeyError: pass else: nps = foPropPar.getNumProperties() for i in range(nps): foProp = foPropPar.getProperty(i) fon = foProp.getName() fov = foProp.getValue() # imath.FloatArray fov = list(fov) if np is None else np.array(fov) foDict[fon] = fov finally: iarch, top, par, systemSchema, foPropPar, foProp = [None] * 6 return foDict
def parseAbc(path): """ Read an .abc file and produce a Mesh object Args: path: The path to the .abc formatted file Returns: A list of vertices and the face connectivity Raises: IOError: If the file cannot be opened """ iarch = IArchive(str(path)) # because alembic hates unicode top = iarch.getTop() ixfo = IXform(top, top.children[0].getName()) mesh = IPolyMesh(ixfo, ixfo.children[0].getName()) sch = mesh.getSchema() rawVerts = sch.getPositionsProperty().samples[0] rawFaces = sch.getFaceIndicesProperty().samples[0] rawCounts = sch.getFaceCountsProperty().samples[0] faces = [] faceCounter = 0 for count in rawCounts: f = list(rawFaces[faceCounter: faceCounter+count]) # Ignoring UV/Normal data for now faces.append(f) faceCounter += count verts = [] for v in rawVerts: verts.append(list(v)) return verts, faces
def reorderSimplexPoints(sourcePath, matchPath, outPath, invertMatch=False): '''Transfer shape data from the sourcePath using the numpy int array at matchPath to make the final output at outPath Parameters ---------- sourcePath : str The source .smpx file path matchPath : str The new vert order dumped from numpy outPath : str The new output .smpx path invertMatch : bool Whether to directly apply the match from matchPath, or whether to invert it Returns ------- ''' print "Loading Simplex" if not os.path.isfile(str(sourcePath)): raise IOError("File does not exist: " + str(sourcePath)) sourceArch = IArchive(str(sourcePath)) # because alembic hates unicode sourceShapes = getShapes(sourceArch) jsString = loadJSString(sourceArch) sFaces, counts = getMesh(sourceArch) sFaces = np.array(sFaces) print "Loading Correspondence" c = np.load(matchPath) c = c[c[:, 0].argsort()].T[1] ci = c.argsort() if invertMatch: ci, c = c, ci print "Reordering" targetShapes = sourceShapes[:, c, :] faces = mkSampleIntArray(ci[sFaces]) print "Writing" oarch = OArchive(str(outPath), OGAWA) # alembic does not like unicode filepaths try: _writeSimplex(oarch, 'Face', jsString, faces, counts, targetShapes) finally: del oarch gc.collect()
def hdf5Convert(inPath, outPath, ogawa=False): ''' Load and parse all the data from a simplex file ''' if not os.path.isfile(str(inPath)): raise IOError("File does not exist: " + str(inPath)) iarch = IArchive(str(inPath)) jsString = loadJSString(iarch) shapes = loadSmpx(iarch) faces, counts = loadMesh(iarch) del iarch oarch = OArchive(str(outPath), ogawa) # alembic does not like unicode filepaths try: _writeSimplex(oarch, 'Face', jsString, faces, counts, shapes) finally: del oarch gc.collect()
def loadSimplex(shapePath): ''' Load and parse all the data from a simplex file ''' iarch = IArchive(str(shapePath)) print "Opening File:", iarch jsString = loadJSString(iarch) shapes = loadSmpx(iarch) del iarch simplex = Simplex() simplex.loadJSON(jsString) solver = PySimplex(jsString) # return as delta shapes restIdx = simplex.shapes.index(simplex.restShape) restPts = shapes[restIdx] shapes = shapes - restPts[None, ...] # reshape for broadcasting return jsString, simplex, solver, shapes, restPts
def loadSimplex(shapePath): '''Load and parse all the data from a simplex file Parameters ---------- shapePath : str The path to the .smpx file Returns ------- : str The simplex JSON string : Simplex The simplex system : pySimplex The instantiated simplex solver : np.array A Numpy array of the shape point positions : np.array A Numpy array of the rest pose of the system ''' if not os.path.isfile(str(shapePath)): raise IOError("File does not exist: " + str(shapePath)) iarch = IArchive(str(shapePath)) print "Opening File:", iarch jsString = loadJSString(iarch) shapes = loadSmpx(iarch) del iarch simplex = Simplex.buildSystemFromJsonString(jsString, None, forceDummy=True) solver = PySimplex(jsString) # return as delta shapes restIdx = simplex.shapes.index(simplex.restShape) restPts = shapes[restIdx] shapes = shapes - restPts[None, ...] # reshape for broadcasting return jsString, simplex, solver, shapes, restPts
def loadSimplex(shapePath): ''' Load and parse all the data from a simplex file ''' if not os.path.isfile(str(shapePath)): raise IOError("File does not exist: " + str(shapePath)) iarch = IArchive(str(shapePath)) print "Opening File:", iarch jsString = loadJSString(iarch) shapes = loadSmpx(iarch) del iarch simplex = Simplex.buildSystemFromJsonString(jsString, None, forceDummy=True) solver = PySimplex(jsString) # return as delta shapes restIdx = simplex.shapes.index(simplex.restShape) restPts = shapes[restIdx] shapes = shapes - restPts[None, ...] # reshape for broadcasting return jsString, simplex, solver, shapes, restPts
def getMesh(infile): ''' Get the first found mesh object from the alembic filepath ''' iarch = IArchive(infile) ipolymsh = findAlembicObject(iarch.getTop(), abcType=IPolyMesh) return ipolymsh