def iter_aggregated_by_color(json_filename): """Yields TiltBrushMesh instances, each of a uniform color.""" def by_color(m): return m.c[0] meshes = iter_meshes(json_filename) for (_, group) in itertools.groupby(sorted(meshes, key=by_color), key=by_color): yield TiltBrushMesh.from_meshes(group)
def main(): import argparse parser = argparse.ArgumentParser( description="Converts Tilt Brush '.json' exports to .obj.") parser.add_argument('filename', help="Exported .json files to convert to obj") parser.add_argument( '--cooked', action='store_true', dest='cooked', default=True, help= "(default) Strip geometry of normals, weld verts, and give single-sided triangles corresponding backfaces." ) parser.add_argument( '--color', action='store_true', help= "Add vertex color to 'v' and 'vc' elements. WARNING: May produce incompatible .obj files." ) parser.add_argument( '--raw', action='store_false', dest='cooked', help= "Emit geometry just as it comes from Tilt Brush. Depending on the brush, triangles may not have backfaces, adjacent triangles will mostly not share verts." ) parser.add_argument('-o', dest='output_filename', metavar='FILE', help="Name of output file; defaults to <filename>.obj") args = parser.parse_args() if args.output_filename is None: args.output_filename = os.path.splitext(args.filename)[0] + '.obj' meshes = list(iter_meshes(args.filename)) for mesh in meshes: mesh.remove_degenerate() if args.cooked: for mesh in meshes: if mesh.brush_guid in SINGLE_SIDED_FLAT_BRUSH: mesh.add_backfaces() mesh = TiltBrushMesh.from_meshes(meshes) mesh.collapse_verts(ignore=('uv0', 'uv1', 'c', 't')) mesh.remove_degenerate() else: mesh = TiltBrushMesh.from_meshes(meshes) write_obj(mesh, args.output_filename, args.color) print "Wrote", args.output_filename
def main(): import argparse parser = argparse.ArgumentParser(description="""Converts Tilt Brush '.json' exports to .fbx.""") parser.add_argument('filename', help="Exported .json files to convert to fbx") grp = parser.add_argument_group(description="Merging and optimization") grp.add_argument('--merge-stroke', action='store_true', help="Merge all strokes into a single mesh") grp.add_argument('--merge-brush', action='store_true', help="(default) Merge strokes that use the same brush into a single mesh") grp.add_argument('--no-merge-brush', action='store_false', dest='merge_brush', help="Turn off --merge-brush") grp.add_argument('--weld-verts', action='store_true', help="(default) Weld vertices") grp.add_argument('--no-weld-verts', action='store_false', dest='weld_verts', help="Turn off --weld-verts") parser.add_argument('--add-backface', action='store_true', help="Add backfaces to strokes that don't have them") parser.add_argument('-o', dest='output_filename', metavar='FILE', help="Name of output file; defaults to <filename>.fbx") parser.set_defaults(merge_brush=True, weld_verts=True) args = parser.parse_args() if args.output_filename is None: args.output_filename = os.path.splitext(args.filename)[0] + '.fbx' meshes = list(iter_meshes(args.filename)) for mesh in meshes: mesh.remove_degenerate() if args.add_backface and mesh.brush_guid in SINGLE_SIDED_FLAT_BRUSH: mesh.add_backface() if args.merge_stroke: meshes = [ TiltBrushMesh.from_meshes(meshes, name='strokes') ] elif args.merge_brush: def by_guid(m): return (m.brush_guid, m.brush_name) meshes = [ TiltBrushMesh.from_meshes(list(group), name='All %s' % (key[1], )) for (key, group) in groupby(sorted(meshes, key=by_guid), key=by_guid) ] if args.weld_verts: for mesh in meshes: # We don't write out tangents, so it's safe to ignore them when welding mesh.collapse_verts(ignore=('t',)) mesh.remove_degenerate() write_fbx_meshes(meshes, args.output_filename) print "Wrote", args.output_filename
def main(): global n global export_name global metadata global polyareadata polyareadata = [] metadata = {} metadata['fbxmeta'] = [] n = 1000 #name counter import argparse parser = argparse.ArgumentParser( description="""Converts Tilt Brush '.json' exports to .fbx.""") parser.add_argument('filename', help="Exported .json files to convert to fbx", action='store_true') grp = parser.add_argument_group(description="Merging and optimization") grp.add_argument('--merge-stroke', action='store_true', help="Merge all strokes into a single mesh") grp.add_argument( '--merge-brush', action='store_true', help= "(default) Merge strokes that use the same brush into a single mesh") grp.add_argument('--no-merge-brush', action='store_false', dest='merge_brush', help="Turn off --merge-brush") grp.add_argument('--weld-verts', action='store_true', help="(default) Weld vertices") grp.add_argument('--no-weld-verts', action='store_false', dest='weld_verts', help="Turn off --weld-verts") parser.add_argument('--add-backface', action='store_true', help="Add backfaces to strokes that don't have them") parser.add_argument('-o', dest='output_filename', metavar='FILE', help="Name of output file; defaults to <filename>.fbx") parser.set_defaults(merge_brush=True, weld_verts=True) args = parser.parse_args() args.filename = FNAME args.merge_brush = MERGE_BRUSH if args.output_filename is None: args.output_filename = os.path.splitext(args.filename)[0] + '.fbx' export_name = os.path.splitext(args.filename)[0] + "_fbx_metadata.json" meshes = list(iter_meshes(args.filename)) for mesh in meshes: mesh.remove_degenerate() if args.add_backface and mesh.brush_guid in SINGLE_SIDED_FLAT_BRUSH: mesh.add_backface() if args.merge_stroke: meshes = [TiltBrushMesh.from_meshes(meshes, name='strokes')] elif args.merge_brush: def by_guid(m): return (m.brush_guid, m.brush_name) meshes = [ TiltBrushMesh.from_meshes(list(group), name='All %s' % (key[1], )) for (key, group) in groupby(sorted(meshes, key=by_guid), key=by_guid) ] if args.weld_verts: for mesh in meshes: # We don't write out tangents, so it's safe to ignore them when welding mesh.collapse_verts(ignore=('t', )) mesh.remove_degenerate() if EXPORT_RELOCATION == 1 or RELOCATE_BRUSHES is False: write_fbx_meshes(meshes, args.output_filename) if EXPORT_RELOCATION == 2: #BRUSH IN INDIVIDUAL FILE for mesh in meshes: write_fbx_meshes(mesh, args.output_filename) metadata['fbxname'] = args.output_filename print "Wrote", args.output_filename if EXPORT_BRUSH_AREA is True: areaexport_name = os.path.splitext(args.filename)[0] + "_brushsize.txt" print areaexport_name with open(areaexport_name, 'w') as f: json.dump(polyareadata, f) with open(export_name, 'w') as f: json.dump(metadata, f) print "Wrote", export_name