def toSMPX(self, path): defDict = self.toJSON() jsString = json.dumps(defDict) arch = OArchive(str(path)) # alembic does not like unicode filepaths try: par = OXform(arch.getTop(), str(self.name)) props = par.getSchema().getUserProperties() prop = OStringProperty(props, "simplex") prop.setValue(str(jsString)) mesh = OPolyMesh(par, str(self.name)) faces = Int32TPTraits.arrayType(len(self._faces)) for i, f in enumerate(self._faces): faces[i] = f counts = Int32TPTraits.arrayType(len(self._counts)) for i, c in enumerate(self._counts): counts[i] = c schema = mesh.getSchema() for shape in self.shapes: verts = shape.toSMPX() abcSample = OPolyMeshSchemaSample(verts, faces, counts) schema.set(abcSample) except: raise finally: del arch
def _writeSimplex(oarch, name, jsString, faces, counts, newShapes, pBar=None): ''' Separate the writer from oarch creation so garbage collection *hopefully* works as expected ''' par = OXform(oarch.getTop(), name) props = par.getSchema().getUserProperties() prop = OStringProperty(props, "simplex") prop.setValue(str(jsString)) abcMesh = OPolyMesh(par, name) schema = abcMesh.getSchema() if pBar is not None: pBar.setLabelText('Writing Corrected Simplex') pBar.setMaximum(len(newShapes)) for i, newShape in enumerate(newShapes): if pBar is not None: pBar.setValue(i) QApplication.processEvents() else: print "Writing {0: 3d} of {1}\r".format(i, len(newShapes)), verts = mkSampleVertexPoints(newShape) abcSample = OPolyMeshSchemaSample(verts, faces, counts) schema.set(abcSample) if pBar is None: print "Writing {0: 3d} of {1}".format(len(newShapes), len(newShapes))
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 _writeSimplex(oarch, name, jsString, faces, counts, newShapes): par = OXform(oarch.getTop(), name) props = par.getSchema().getUserProperties() prop = OStringProperty(props, "simplex") prop.setValue(str(jsString)) abcMesh = OPolyMesh(par, name) schema = abcMesh.getSchema() for i, newShape in enumerate(newShapes): print "Writing {0: 3d} of {1}\r".format(i, len(newShapes)), abcSample = OPolyMeshSchemaSample(newShape, faces, counts) schema.set(abcSample) print "Writing {0: 3d} of {1}".format(len(newShapes), len(newShapes))
def _writeSimplex(oarch, name, jsString, faces, counts, newShapes): ''' Separate the writer from oarch creation so garbage collection *hopefully* works as expected ''' par = OXform(oarch.getTop(), name) props = par.getSchema().getUserProperties() prop = OStringProperty(props, "simplex") prop.setValue(str(jsString)) abcMesh = OPolyMesh(par, name) schema = abcMesh.getSchema() for i, newShape in enumerate(newShapes): print "Writing {0: 3d} of {1}\r".format(i, len(newShapes)), abcSample = OPolyMeshSchemaSample(newShape, faces, counts) schema.set(abcSample) print "Writing {0: 3d} of {1}".format(len(newShapes), len(newShapes))
def _exportAbc(arch, smpx, shapeArray, faces, counts, uvs): par = OXform(arch.getTop(), str(smpx.name)) props = par.getSchema().getUserProperties() prop = OStringProperty(props, "simplex") prop.setValue(str(smpx.dump())) abcMesh = OPolyMesh(par, str(smpx.name)) schema = abcMesh.getSchema() for i in range(len(smpx.shapes)): if uvs is not None: abcSample = OPolyMeshSchemaSample( mkSampleVertexPoints(shapeArray[i]), faces, counts, uvs) else: # can't just pass uvs as None because of how the Alembic API works abcSample = OPolyMeshSchemaSample( mkSampleVertexPoints(shapeArray[i]), faces, counts) schema.set(abcSample)
def buildAlembicArchiveData(path, name, jsString, ogawa): ''' Set up an output alembic archive with a mesh ready for writing Parameters ---------- path : str The output file path name : str The name of the system jsString : str The simplex definition string ogawa : bool Whether to open in Ogawa (True) or HDF5 (False) mode Returns ------- : OArchive The opened alembic output archive : OPolyMesh The mesh to write the shape data to ''' arch = OArchive(str(path), ogawa) par, props, abcMesh = [None] * 3 try: par = OXform(arch.getTop(), str(name)) props = par.getSchema().getUserProperties() writeStringProperty(props, 'simplex', jsString, ogawa) abcMesh = OPolyMesh(par, str(name)) except Exception: arch, par, props, abcMesh = [None] * 4 raise return arch, abcMesh
def toSMPX(self, path, pBar=None): defDict = self.toJSON() jsString = json.dumps(defDict) # `False` for HDF5 `True` for Ogawa arch = OArchive(str(path), False) # alembic does not like unicode filepaths try: par = OXform(arch.getTop(), str(self.name)) props = par.getSchema().getUserProperties() prop = OStringProperty(props, "simplex") prop.setValue(str(jsString)) mesh = OPolyMesh(par, str(self.name)) faces = Int32TPTraits.arrayType(len(self._faces)) for i, f in enumerate(self._faces): faces[i] = f counts = Int32TPTraits.arrayType(len(self._counts)) for i, c in enumerate(self._counts): counts[i] = c schema = mesh.getSchema() if pBar is not None: pBar.setMaximum(len(self.shapes)) pBar.setValue(0) pBar.setLabelText("Exporting Split Shapes") QApplication.processEvents() for i, shape in enumerate(self.shapes): if pBar is not None: pBar.setValue(i) QApplication.processEvents() else: print "Exporting Shape {0} of {1}\r".format(i+1, len(self.shapes)), verts = shape.toSMPX() abcSample = OPolyMeshSchemaSample(verts, faces, counts) schema.set(abcSample) if pBar is None: print except: raise finally: del arch
def _exportUnsub(outPath, xfoName, meshName, jsString, faces, verts, uvFaces, uvs, pBar=None): oarch = OArchive(str(outPath), OGAWA) # False for HDF5 oxfo = OXform(oarch.getTop(), xfoName) oprops = oxfo.getSchema().getUserProperties() oprop = OStringProperty(oprops, "simplex") oprop.setValue(str(jsString)) omesh = OPolyMesh(oxfo, meshName) osch = omesh.getSchema() if pBar is not None: pBar.setValue(0) pBar.setMaximum(len(verts)) pBar.setLabelText("Exporting Unsubdivided Shapes") QApplication.processEvents() abcIndices = mkSampleIntArray(list(chain.from_iterable(faces))) abcCounts = mkSampleIntArray(map(len, faces)) kwargs = {} if uvs is not None: # Alembic doesn't use None as the placeholder for un-passed kwargs # So I don't have to deal with that, I only set the kwarg dict if the uvs exist uvidx = None if uvFaces is None else list(chain.from_iterable(uvFaces)) uvSample = mkUvSample(uvs, uvidx) kwargs['iUVs'] = uvSample for i, v in enumerate(verts): pbPrint(pBar, "Exporting Unsubdivided Shape", i) sample = OPolyMeshSchemaSample(mkSampleVertexPoints(v), abcIndices, abcCounts, **kwargs) osch.set(sample) pbPrint(pBar, "Done")
def exportABC(self, path): defDict = self.simplex.buildDefinition() jsString = json.dumps(defDict) arch = OArchive(str(path)) # alembic does not like unicode filepaths try: par = OXform(arch.getTop(), str(self.name)) props = par.getSchema().getUserProperties() prop = OStringProperty(props, "simplex") prop.setValue(str(jsString)) mesh = OPolyMesh(par, str(self.name)) self.DCC.exportABC(mesh, defDict) finally: del arch
def extractExternal(self, path, dccMesh): # Extract shapes from an arbitrary mesh based on the current simplex defDict = self.simplex.buildDefinition() jsString = json.dumps(defDict) arch = OArchive(str(path)) # alembic does not like unicode filepaths try: par = OXform(arch.getTop(), str(self.name)) props = par.getSchema().getUserProperties() prop = OStringProperty(props, "simplex") prop.setValue(str(jsString)) abcMesh = OPolyMesh(par, str(self.name)) self.DCC.exportABC(dccMesh, abcMesh, defDict) finally: del arch
def buildAbc(outPath, points, faces, faceCounts=None, uvs=None, uvFaces=None, normals=None, normFaces=None, name='polymsh', shapeSuffix='Shape', transformSuffix='', propDict=None, ogawa=True, pBar=None): ''' Build a single-mesh alembic file from all of the non-alembic raw data Parameters ---------- outPath: str The output path for the alembic file points: list or ndarray The list or array of points. Single multiple frames supported faces: list A list of lists of face indices, or a flattened list of indices. If flat, then faceCounts must be provided faceCounts: list A list of the number of vertices per face. Defaults to None uvs: list or ndarray The Uvs for this mesh. Defaults to None uvFaces: list A list of lists of face indices, or a flattened list of indices. If flat, then faceCounts must be provided. Defaults to None normals: list or ndarray The Normals for this mesh. Defaults to None normFaces: list A list of lists of face indices, or a flattened list of indices. If flat, then faceCounts must be provided. Defaults to None name: str The name to give this mesh. Defaults to "polymsh" shapeSuffix: str The suffix to add to the shape of this mesh. Defaults to "Shape" transformSuffix: str The suffix to add to the transform of this mesh. Defaults to "" propDict: dict A dictionary of properties to add to the xform object ogawa : bool Whether to write to the Ogawa (True) or HDF5 (False) backend pBar : QProgressDialog, optional An optional progress dialog ''' if faceCounts is None: # All the faces are in list-of-list format # put them in index-count format faceCounts, faces = flattenFaces(faces) if uvFaces is not None: _, uvFaces = flattenFaces(uvFaces) if normFaces is not None: _, normFaces = flattenFaces(normFaces) faceCounts = mkSampleIntArray(faceCounts) faces = mkSampleIntArray(faces) if not isinstance(uvs, OV2fGeomParamSample): if uvFaces is not None and uvs is not None: uvs = mkUvSample(uvs, indexes=uvFaces) if not isinstance(normals, ON3fGeomParamSample): if normFaces is not None and normals is not None: normals = mkNormalSample(normals, indexes=normFaces) oarch = OArchive(str(outPath), ogawa) parent, opar, props, omesh, sch = None, None, None, None, None try: parent = oarch.getTop() opar = OXform(parent, str(name+transformSuffix)) if propDict: props = opar.getSchema().getUserProperties() for k, v in propDict.iteritems(): writeStringProperty(props, str(k), str(v), ogawa) omesh = OPolyMesh(opar, str(name+shapeSuffix)) if np is not None: points = np.array(points) if len(points.shape) == 2: points = points[None, ...] else: if not isinstance(points[0][0], (list, tuple)): points = [points] sch = omesh.getSchema() for i, frame in enumerate(points): pbPrint(pBar, message="Exporting Shape", val=i, maxVal=len(points)) abcFrame = mkSampleVertexPoints(frame) setAlembicSample(sch, abcFrame, faceCounts, faces, uvs=uvs, normals=normals) pbPrint(pBar, message="Done Exporting") finally: # Make sure all this gets deleted so the file is freed del parent, opar, props, omesh, sch
def buildAbc(outPath, points, faces, faceCounts=None, uvs=None, uvFaces=None, normals=None, normFaces=None, name='polymsh', shapeSuffix='Shape', transformSuffix='', propDict=None): ''' Build a single-mesh alembic file from all of the non-alembic raw data Parameters ---------- outPath: str or OArchive The output path for the alembic file points: list or ndarray The list or array of points. Single multiple frames supported faces: list A list of lists of face indices, or a flattened list of indices. If flat, then faceCounts must be provided faceCounts: list A list of the number of vertices per face. Defaults to None uvs: list or ndarray The Uvs for this mesh. Defaults to None uvFaces: list A list of lists of face indices, or a flattened list of indices. If flat, then faceCounts must be provided. Defaults to None normals: list or ndarray The Normals for this mesh. Defaults to None normFaces: list A list of lists of face indices, or a flattened list of indices. If flat, then faceCounts must be provided. Defaults to None name: str The name to give this mesh. Defaults to "polymsh" shapeSuffix: str The suffix to add to the shape of this mesh. Defaults to "Shape" transformSuffix: str The suffix to add to the transform of this mesh. Defaults to "" propDict: dict A dictionary of properties to add to the xform object ''' if faceCounts is None: # All the faces are in list-of-list format # put them in index-count format faceCounts, faces = _flattenFaces(faces) if uvFaces is not None: _, uvFaces = _flattenFaces(uvFaces) if normFaces is not None: _, normFaces = _flattenFaces(normFaces) faceCounts = mkSampleIntArray(faceCounts) faces = mkSampleIntArray(faces) if uvFaces is not None and uvs is not None: uvs = mkUvSample(uvs, indexes=uvFaces) if normFaces is not None and normals is not None: normals = mkNormalSample(normals, indexes=normFaces) if isinstance(outPath, basestring): oarch = OArchive(str(outPath), False) #False for HDF5 else: oarch = outPath parent = oarch.getTop() opar = OXform(parent, name + transformSuffix) if propDict: props = opar.getSchema().getUserProperties() for k, v in propDict.iteritems(): prop = OStringProperty(props, str(k)) prop.setValue(str(v)) omesh = OPolyMesh(opar, name + shapeSuffix) if np is not None: points = np.array(points) if len(points.shape) == 2: points = points[None, ...] else: if not isinstance(points[0][0], (list, tuple)): points = [points] sch = omesh.getSchema() for frame in points: abcFrame = mkSampleVertexPoints(frame) setAlembicSample(sch, abcFrame, faces, faceCounts, uvs=uvs, normals=normals) return oarch