cqparts.codec package¶
Submodules¶
cqparts.codec.amf module¶
-
class
cqparts.codec.amf.AMFExporter(obj)¶ Bases:
cqparts.codec.ExporterExport shape to AMF format.
Name amfExports PartNote
Object is passed to
cadquery.freecad_impl.exporters.exportShape()for exporting.
cqparts.codec.gltf module¶
-
class
cqparts.codec.gltf.GLTFExporter(*args, **kwargs)¶ Bases:
cqparts.codec.ExporterExport
PartorAssemblyto a glTF 2.0 format.Name gltfExports Part&AssemblySpec glTF 2.0 Exporting a Box:
For this example we’ll instantiate an existing
Partclass, a simpleBox:>>> import cpqarts >>> from cqparts_misc.basic.primatives import Box >>> box = Box() >>> box.exporter('gltf')('box.gltf', embed=True)
Will export a single file
box.gltfwith mesh data encoded into it as a string.Embedding vs .bin Files: default generates
.binfilesIf
embedisTruewhencalling, then all data is stored in the output.gltffile. However this is very inefficient, for larger, more complex models when loading on a web-interface.When not embedded, all geometry will be stored as binary
.binfiles in the same directory as the root.gltffile.For example, if we use the
carfrom Make your own Assembly, with the hierarchy:>>> car = Car() >>> print(car.tree_str(name='car')) car ├○ chassis ├─ front_axle │ ├○ axle │ ├○ left_wheel │ └○ right_wheel └─ rear_axle ├○ axle ├○ left_wheel └○ right_wheel >>> car.exporter('gltf')('car.gltf', embed=False)
When exported, a
.binfile will be created for eachPart(denoted by a○).So the following files will be generated:
car.gltf car.chassis.bin car.front_axle.axle.bin car.front_axle.left_wheel.bin car.front_axle.right_wheel.bin car.rear_axle.axle.bin car.rear_axle.left_wheel.bin car.rear_axle.right_wheel.bin
The
car.gltfwill reference each of the.binfiles.The
car.gltfand all.binfiles should be web-hosted to serve the scene correctly.Todo
In this example, all wheels and axles are the same, they should only generate a single buffer.
But how to definitively determine
Partinstance equality?-
TEMPLATE= {'accessors': [], 'materials': [], 'meshes': [], 'asset': {'version': '2.0', 'generator': 'cqparts_0.2.1'}, 'nodes': [{'children': [], 'matrix': [0.001, 0.0, 0.0, 0.0, 0.0, 0.0, -0.001, 0.0, 0.0, 0.001, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]}], 'bufferViews': [], 'scene': 0, 'buffers': [], 'scenes': [{'nodes': [0]}]}¶
-
__call__(filename='out.gltf', embed=False)¶ Parameters:
-
add_part(part, filename=None, name=None, origin=None, parent_idx=0)¶ Adds the given
parttoself.gltf_dict.Parameters: Returns: information about additions to the gltf dict
Return type: Return Format:
The returned
dictis an account of what objects were added to the gltf dict, and the index they may be referenced:<return format> = { 'buffers': [(<index>, <object>), ... ], 'bufferViews': [(<index>, <object>), ... ], 'accessors': [(<index>, <object>), ... ], 'materials': [(<index>, <object>), ... ], 'meshes': [(<index>, <object>), ... ], 'nodes': [(<index>, <object>), ... ], }
Note
The format of the returned
dictlooks similar to the gltf format, but it is not.
-
classmethod
coordsys_dict(coord_sys, matrix=True)¶ Return coordinate system as gltf node transform
Parameters: coord_sys ( CoordSystem) – Coordinate system to transformReturns: node transform keys & values Return type: dict
-
classmethod
part_buffer(part)¶ Export part’s geometry as a glTF 2.0 asset binary stream.
Parameters: world ( bool) – if True, use world coordinates, otherwise use localReturns: byte sream of exported geometry Return type: BytesIOTo embed binary model data into a ‘uri’, you can:
>>> import cqparts >>> from cqparts_misc.basic.primatives import Cube >>> cube = Cube() >>> buff = cube.exporter('gltf').part_buffer(cube) >>> import base64 >>> {'uri': "data:{mimetype};base64,{data}".format( ... mimetype="application/octet-stream", ... data=base64.b64encode(buff.read()).decode('ascii'), ... )} {'uri': 'data:application/octet-stream;base64,AAAAvwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAL8AAAC/AAAAPwAAAL8AAAA/AAAAPwAAAD8AAAC/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAC/AAECAQMCBAUGBAcFAwcCAgcEAAUBBgUAAwEHBwEFBAACBgAE'}
-
classmethod
part_mesh(part)¶ Convert a part’s object to a mesh.
Parameters: Returns: list of (<vertices>, <indexes>)
Return type: Returned mesh format:
<return value> = ( [FreeCAD.Base.Vector(x, y, z), ... ], # list of vertices [(i, j, k), ... ], # indexes of vertices making a polygon )
-
scale= 0.001¶
-
tolerance= 0.01¶
-
-
class
cqparts.codec.gltf.ShapeBuffer(max_index=255)¶ Bases:
objectWrite byte buffer for a set of polygons
To create a buffer for a single polygon:
>>> from cqparts.codec.gltf import ShapeBuffer >>> sb = ShapeBuffer() >>> # Populate data >>> sb.add_vertex(0, 0, 0) # [0] >>> sb.add_vertex(1, 0, 0) # [1] >>> sb.add_vertex(0, 1, 0) # [2] >>> sb.add_poly_index(0, 1, 2) >>> # write to file >>> with open('single-poly.bin', 'wb') as fh: ... for chunk in sb.buffer_iter(): ... fh.write(chunk) >>> # get sizes (relevant for bufferViews, and accessors) >>> (sb.vert_len, sb.vert_offset, sb.vert_size) (36L, 0, 3L) >>> (sb.idx_len, sb.idx_offset, sb.idx_size) (3L, 36L, 3L)
-
__init__(max_index=255)¶ Parameters: max_index ( long) – maximum index number, if > 65535, 4-byte integers are used
-
add_poly_index(i, j, k)¶ Add 3
SCALARofuintto theidx_databuffer.
-
add_vertex(x, y, z)¶ Add a
VEC3offloatsto thevert_databuffer
-
buffer_iter(block_size=1024)¶ Iterate through chunks of the vertices, and indices buffers seamlessly.
Note
To see a usage example, look at the
ShapeBufferdescription.
-
idx_len¶ Number of bytes in
idx_databuffer.
-
idx_offset¶ Offset (in bytes) of the
idx_databuffer.
-
idx_size¶ Number of
idx_dataelements. (ie: number of 2 or 4 byte groups)See Accessor Element Size in the glTF docs for clarification.
-
read()¶ Read buffer out as a single stream.
Warning
Avoid using this function!
Why? This is a convenience function; it doesn’t encourage good memory management.
All memory required for a mesh is duplicated, and returned as a single
str. So at best, using this function will double the memory required for a single model.Instead: Wherever possible, please use
buffer_iter().
-
vert_len¶ Number of bytes in
vert_databuffer.
-
vert_offset¶ Offset (in bytes) of the
vert_databuffer.
-
vert_size¶ Size of
vert_datain groups of 3 floats (ie: number of \(3 \times 4\) byte groups)See Accessor Element Size in the glTF docs for clarification.
-
-
class
cqparts.codec.gltf.WebGL¶ Enumeration container (nothing special).
>>> from cqparts.codec.gltf import WebGL >>> WebGL.ARRAY_BUFFER 34962
This class purely exists to make the code more readable.
All enumerations transcribed from the spec’ where needed.
-
ARRAY_BUFFER= 34962¶
-
BYTE= 5120¶
-
ELEMENT_ARRAY_BUFFER= 34963¶
-
FLOAT= 5126¶
-
LINES= 1¶
-
LINE_LOOP= 2¶
-
LINE_STRIP= 3¶
-
POINTS= 0¶
-
SHORT= 5122¶
-
TRIANGLES= 4¶
-
TRIANGLE_FAN= 6¶
-
TRIANGLE_STRIP= 5¶
-
UNSIGNED_BYTE= 5121¶
-
UNSIGNED_INT= 5125¶
-
UNSIGNED_SHORT= 5123¶
-
cqparts.codec.step module¶
-
class
cqparts.codec.step.STEPAssemblyImporter(cls)¶ Bases:
cqparts.codec.step.STEPPartImporterImport a shape from a STEP formatted file.
Name stepImports AssemblyNote
Step file is passed to
cadquery.freecad_impl.importers.importShape()to do the hard work of extracting geometry.Multi-part STEP
This importer is intended for
STEPfiles with multiple separated meshes defined.Each mesh is imported into a nested
Partcomponent.
-
class
cqparts.codec.step.STEPExporter(obj)¶ Bases:
cqparts.codec.ExporterExport shape to STEP format.
Name stepExports PartNote
Object is passed to
cadquery.freecad_impl.exporters.exportShape()for exporting.
-
class
cqparts.codec.step.STEPPartImporter(cls)¶ Bases:
cqparts.codec.step.STEPPartImporterImport a shape from a STEP formatted file.
Name stepImports PartNote
Step file is passed to
cadquery.freecad_impl.importers.importShape()to do the hard work of extracting geometry.Multi-part STEP
If the
STEPfile has multiple parts, all parts are unioned together to form a singlePart.
cqparts.codec.stl module¶
-
class
cqparts.codec.stl.STLExporter(obj)¶ Bases:
cqparts.codec.ExporterExport shape to STL format.
Name stlExports PartNote
Object is passed to
cadquery.freecad_impl.exporters.exportShape()for exporting.
cqparts.codec.svg module¶
-
class
cqparts.codec.svg.SVGExporter(obj)¶ Bases:
cqparts.codec.ExporterExport shape to AMF format.
Name svgExports PartNote
Object is passed to
cadquery.freecad_impl.exporters.exportShape()for exporting.
cqparts.codec.threejs_json module¶
-
class
cqparts.codec.threejs_json.ThreejsJSONAssemblyExporter(obj)¶ Bases:
cqparts.codec.ExporterExport an
Assemblyinto multiplejsonfiles.Name jsonExports AssemblySpec three.js JSON model format v3 specification Warning
The three.js JSON v3 format does not support multiple models (or, at least, not as far as I can tell).
So this exporter will create multiple files, one per part.
If you’re after a more modern WebGL supported export, consider using
GLTFExporterinstead.
-
class
cqparts.codec.threejs_json.ThreejsJSONExporter(obj)¶ Bases:
cqparts.codec.ExporterExport the
Partto a three.js JSON v3 file format.Name jsonExports PartSpec three.js JSON model format v3 specification For information on how to load in a webpage, look to your WebGL framework of choice:
- ThreeJS: https://threejs.org/docs/#api/loaders/ObjectLoader
- A-Frame: https://aframe.io/docs/0.7.0/core/asset-management-system.html#lt-a-asset-item-gt
-
__call__(filename='out.json', world=False)¶ Write to file.
Parameters:
Module contents¶
-
cqparts.codec.register_exporter(name, base_class)¶ Register an exporter to use for a
Part,Assembly, or both (withComponent).Registration is necessary to use with
Component.exporter().Parameters: >>> from cqparts import Part >>> from cqparts.codec import Exporter, register_exporter >>> @register_exporter('my_type', Part) ... class MyExporter(Exporter): ... def __call__(self, filename='out.mytype'): ... print("export %r to %s" % (self.obj, filename)) >>> from cqparts_misc.basic.primatives import Sphere >>> thing = Sphere(radius=5) >>> thing.exporter('my_type')('some-file.mytype') export <Sphere: radius=5.0> to some-file.mytype
-
cqparts.codec.get_exporter(obj, name)¶ Get an exporter for the
Parameters: Returns: an exporter instance of the given type
Return type: Raises: TypeError – if exporter cannot be found
-
cqparts.codec.register_importer(name, base_class)¶
-
cqparts.codec.get_importer(cls, name)¶ Get an importer for the given registered type.
Parameters: Returns: an importer instance of the given type
Return type: Raises: TypeError – if importer cannot be found
-
class
cqparts.codec.AMFExporter(obj)¶ Bases:
cqparts.codec.ExporterExport shape to AMF format.
Name amfExports PartNote
Object is passed to
cadquery.freecad_impl.exporters.exportShape()for exporting.
-
class
cqparts.codec.GLTFExporter(*args, **kwargs)¶ Bases:
cqparts.codec.ExporterExport
PartorAssemblyto a glTF 2.0 format.Name gltfExports Part&AssemblySpec glTF 2.0 Exporting a Box:
For this example we’ll instantiate an existing
Partclass, a simpleBox:>>> import cpqarts >>> from cqparts_misc.basic.primatives import Box >>> box = Box() >>> box.exporter('gltf')('box.gltf', embed=True)
Will export a single file
box.gltfwith mesh data encoded into it as a string.Embedding vs .bin Files: default generates
.binfilesIf
embedisTruewhencalling, then all data is stored in the output.gltffile. However this is very inefficient, for larger, more complex models when loading on a web-interface.When not embedded, all geometry will be stored as binary
.binfiles in the same directory as the root.gltffile.For example, if we use the
carfrom Make your own Assembly, with the hierarchy:>>> car = Car() >>> print(car.tree_str(name='car')) car ├○ chassis ├─ front_axle │ ├○ axle │ ├○ left_wheel │ └○ right_wheel └─ rear_axle ├○ axle ├○ left_wheel └○ right_wheel >>> car.exporter('gltf')('car.gltf', embed=False)
When exported, a
.binfile will be created for eachPart(denoted by a○).So the following files will be generated:
car.gltf car.chassis.bin car.front_axle.axle.bin car.front_axle.left_wheel.bin car.front_axle.right_wheel.bin car.rear_axle.axle.bin car.rear_axle.left_wheel.bin car.rear_axle.right_wheel.bin
The
car.gltfwill reference each of the.binfiles.The
car.gltfand all.binfiles should be web-hosted to serve the scene correctly.Todo
In this example, all wheels and axles are the same, they should only generate a single buffer.
But how to definitively determine
Partinstance equality?-
TEMPLATE= {'accessors': [], 'materials': [], 'meshes': [], 'asset': {'version': '2.0', 'generator': 'cqparts_0.2.1'}, 'nodes': [{'children': [], 'matrix': [0.001, 0.0, 0.0, 0.0, 0.0, 0.0, -0.001, 0.0, 0.0, 0.001, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]}], 'bufferViews': [], 'scene': 0, 'buffers': [], 'scenes': [{'nodes': [0]}]}¶
-
__call__(filename='out.gltf', embed=False)¶ Parameters:
-
add_part(part, filename=None, name=None, origin=None, parent_idx=0)¶ Adds the given
parttoself.gltf_dict.Parameters: Returns: information about additions to the gltf dict
Return type: Return Format:
The returned
dictis an account of what objects were added to the gltf dict, and the index they may be referenced:<return format> = { 'buffers': [(<index>, <object>), ... ], 'bufferViews': [(<index>, <object>), ... ], 'accessors': [(<index>, <object>), ... ], 'materials': [(<index>, <object>), ... ], 'meshes': [(<index>, <object>), ... ], 'nodes': [(<index>, <object>), ... ], }
Note
The format of the returned
dictlooks similar to the gltf format, but it is not.
-
classmethod
coordsys_dict(coord_sys, matrix=True)¶ Return coordinate system as gltf node transform
Parameters: coord_sys ( CoordSystem) – Coordinate system to transformReturns: node transform keys & values Return type: dict
-
classmethod
part_buffer(part)¶ Export part’s geometry as a glTF 2.0 asset binary stream.
Parameters: world ( bool) – if True, use world coordinates, otherwise use localReturns: byte sream of exported geometry Return type: BytesIOTo embed binary model data into a ‘uri’, you can:
>>> import cqparts >>> from cqparts_misc.basic.primatives import Cube >>> cube = Cube() >>> buff = cube.exporter('gltf').part_buffer(cube) >>> import base64 >>> {'uri': "data:{mimetype};base64,{data}".format( ... mimetype="application/octet-stream", ... data=base64.b64encode(buff.read()).decode('ascii'), ... )} {'uri': 'data:application/octet-stream;base64,AAAAvwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAL8AAAC/AAAAPwAAAL8AAAA/AAAAPwAAAD8AAAC/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAC/AAECAQMCBAUGBAcFAwcCAgcEAAUBBgUAAwEHBwEFBAACBgAE'}
-
classmethod
part_mesh(part)¶ Convert a part’s object to a mesh.
Parameters: Returns: list of (<vertices>, <indexes>)
Return type: Returned mesh format:
<return value> = ( [FreeCAD.Base.Vector(x, y, z), ... ], # list of vertices [(i, j, k), ... ], # indexes of vertices making a polygon )
-
scale= 0.001¶
-
tolerance= 0.01¶
-
-
class
cqparts.codec.STEPExporter(obj)¶ Bases:
cqparts.codec.ExporterExport shape to STEP format.
Name stepExports PartNote
Object is passed to
cadquery.freecad_impl.exporters.exportShape()for exporting.
-
class
cqparts.codec.STLExporter(obj)¶ Bases:
cqparts.codec.ExporterExport shape to STL format.
Name stlExports PartNote
Object is passed to
cadquery.freecad_impl.exporters.exportShape()for exporting.
-
class
cqparts.codec.SVGExporter(obj)¶ Bases:
cqparts.codec.ExporterExport shape to AMF format.
Name svgExports PartNote
Object is passed to
cadquery.freecad_impl.exporters.exportShape()for exporting.
-
class
cqparts.codec.ThreejsJSONExporter(obj)¶ Bases:
cqparts.codec.ExporterExport the
Partto a three.js JSON v3 file format.Name jsonExports PartSpec three.js JSON model format v3 specification For information on how to load in a webpage, look to your WebGL framework of choice:
- ThreeJS: https://threejs.org/docs/#api/loaders/ObjectLoader
- A-Frame: https://aframe.io/docs/0.7.0/core/asset-management-system.html#lt-a-asset-item-gt
-
__call__(filename='out.json', world=False)¶ Write to file.
Parameters:
-
class
cqparts.codec.ThreejsJSONAssemblyExporter(obj)¶ Bases:
cqparts.codec.ExporterExport an
Assemblyinto multiplejsonfiles.Name jsonExports AssemblySpec three.js JSON model format v3 specification Warning
The three.js JSON v3 format does not support multiple models (or, at least, not as far as I can tell).
So this exporter will create multiple files, one per part.
If you’re after a more modern WebGL supported export, consider using
GLTFExporterinstead.