Intermediate Asset Format V2
An asset mainly defines multiple plates in various orientations. A plate either means that a new plate will be placed inside kyub, or that it will be merged with an existing plate given that the existing plate matches the expectations. You could also understand these plates as "connectors" of an asset.
Besides defining plates, externalObjects can be placed as well for visualization purposes.
Metadata
Metadata is stored in the database's entry itself, alternatively in the metadata.yml file in the asset's root folder.
Identifying the Format
In order to differentiate this format from the other existing legacy formats, the following metadata keys should be set:
assetType: makerFormat
makerFormatVersion: 2
makerFormatSource: svg (or openscad)
Working with concrete fabrication settings
See Fabrication Settings for an explanation of the different values.
The detailed shape of assets can depend on material thickness, kerf, etc. An imported asset (in the intermediate format) is always a concrete representation with concrete values. If the user needs other values, the asset should be re-imported with different settings.
The concrete fabrication-related settings used to import the asset should be stored in the fabricationSettings key:
fabricationSettings:
MATERIAL_THICKNESS: 4
MATERIAL_TYPE: plywood
KERF: 0.015
FIT: 0
Plates
within the resources/assetPlates, there may be multiple folders, each defining a plate. The folders can be arbitrarily named, but should convey a meaning, e.g. partA-plate0.
Possible files
Each plate folder can contain the following files:
outline.svg: Defines the shape of the plate. Is expected to contain at most two elements- outline: a polygon/rectangle that defines the actual outline of the plate. If no such polygon exists, the outline is assumed to be the SVG's viewbox rectangle. During loading, the outline is linearized, meaning that round curves will be split up into separate smaller lines. You should use simple polygons if possible.
- center: a circle with the id
plateCenterthat defines the center of the plate. When loading the SVG into kyub, all coordinates are transformed so that the middle of the center object is in the 2D origin of the plate. If there is noplateCenterelement, the center is assumed to be the center of the outline's AABB. cutouts.svg: contains shapes that should be interpreted as cutouts. Since kyub will try to import/display them as polygons, there should be no intersecting/degenerated shapes or raster graphics in this file.engravings.svg: contains shapes that should be interpreted as engravings. Raster graphics are allowed. The shapes may have black fill.properties.yml: see below for possible variables. If the file is missing, the default value for each variable will be assumed.
Both cutouts.svg and engravings.svg must not contain the plate's outline. They must have the same dimensions and coordinate system (= width, height and viewbox) as the outline.svg. If the outline.svg file is missing, kyub assumes a rectangular plate outline that matches the SVG's viewbox rectangle.
The SVG's elements should have black stroke and no fill (or black fill in the case of engravings). Color must not have a meaning, except for engraved images that will be interpreted as greyscale. Ideally, the SVG's widht and height properties are defined as mm, but this is optional as usual DPI conversion can be understood by the export.
Coordinate systems: SVG uses a y-down system, while kyub uses a y-up system. The SVG files should be exported so that they are displayed correctly in a SVG viewer (= y-down).
Consequently, during import in kyub, the SVG is converted to mm, the plateCenter object is taken as coordinate origin, and the element's y-coordinates are negated so they are displayed correctly inside kyub.
Plate properties.yml
The plate's properties.yml can define the following values:
transformations: an array that defines the transforms of the plate in the asset's coordinate system (which can be an arbitrary one). Transformations are applied one after another and can be of the following values:{type: rotate, x: 0, y: 0, z: 0}rotates the plate based on the given OpenSCAD rotation (see appendix). The order is XYZ and the angles are specified in degree.{type: translate, x: 0, y: 0, z: 0}translates the plate by the given vector (in mm)dimensionsConception: currently assumed to beexternalwith the normal pointing upwards(0, 0, 1)per default, meaning that the material extends into z-negative direction.materialProperties: The configuration used to generate this specific part of the asset. An asset importer may support (re-)importing an asset with different properties.kerf: kerf of this plate, in mm (default: 0)thickness: material thickness, in mm (default: 4)mergeableSections: an array that defines how the plate can be merged with other plates in the editor. Currently, only the following format is allowed:{start: {x, y}, end: {x, y}}. The start and end positions are in the plate's 2D coordinates (after importing into kyub, so not necessarily SVG coordinates depending where theplateCenteris placed) and need to match one linearized outline section of the plate. They should be ordered so that the normal points outwards (CCW polygon definition). If a section is not marked as mergeable, this border needs to exist in kuyb (E.g. a square asset with 3 mergeable sections and one unmarked section can be placed anywhere in a bigger plate, as long as the unmarked section overlaps with the outline of that plate - basically enforcing a "at the edge" constraint). Per default, there are no mergeable sections. If there exists nooutline.svg, the plate is considered to be mergeable at all sides.part: A string (e.g.A,B, ...) that defines the part this plate belongs to. Defaults toA. A part is a an assembly where all elements are sturdily connected to each other. The asset only needs to define multiple parts if it represents some sort of mechanical function that requires parts of it to be movable relative to each other, e.g. a hinge.
External Objects
For visualization purposes, the asset can define zero or more resource/externalObjects, each in one folder.
It contains the following files:
model.objandtexture.pngthat define the appearance of the objectproperties.ymlwithphysicalProperties: that define themassandcollisionShapespart: that indicates which part (defaultA) this External Object belongs to.transformations: analogous to plates, defines where in the asset the external object is to be placed
Component definition
The resources/components/makerPlate component will be instantiated even if not defined and manages the assset inside kyub. In the folder, there may be these additional files
properties.ymlwhich specify what component is instantiated, it should containcomponentBaseClass: MakerPlateComponentadditionalPlates.svgwhich will be added to the exported SVG by the component, in order to realize pass-through svg compatibility.
(future: define mechanical constraints, e.g. that part A rotates around part B along this axis specified in asset coordinates)
Other
resources/import/makerFormatcontains the originally uploaded files used to create the assetresources/ui/assetcontains the thumbnail1024.jpg for displaying purposes- The asset's name and description (etc) are stored in the database entry's metadata field, or in the
metadata.ymlin the folder root if the API is not used.
Backwards compatibility to existing formats
... to the SVG in-plate format
The in-plate format defines one rectangular plate by using an SVG template. Thus, only one asset plate without an outline.svg and without mergeableSections in its properties.yml is created. This is equivalent to marking the whole plate as "extend in any direction / embed anywhere". The plate has the default transforms of being in the origin. The plate's center is defined as the outline-rectangle's AABB's center.
The External Object is also placed in the origin. Since the convention is to create the 3D model centered in x,y and going z upwards, it will be placed on top of the only asset plate. Note that the EmbedJoint does not need to be defined anymore, as the placement is supposed to be done by the asset component. The baseEmbeddingCutouts.svg are now part of the plate's cutouts.svg.
The additional svg elements are given to the asset's component for pass through (additionalPlates.svg).
... to the "Export plate as whole and re-import" workflow (-> Milan)
Defines just one asset plate that can have an arbitrary polygon as shape, with engravings and cutouts. During instantiation of the asset, the editor should recognize that there is only one ornament to be created, and thus only place the ornament on the plate and not instantiate the asset's component
Appendix
The openSCAD way of rotating stuff
Similar to Euler angles in XYZ order (in degree), but each rotation is around the global coordinate system's axis and not, as in Euler angles, around the already rotated local system.
rotationQuaternions = []
if parseFloat(transformation.x) isnt 0
rotationQuaternions.push new THREE.Quaternion().setFromAxisAngle(
new THREE.Vector3(1, 0, 0),
parseFloat(transformation.x) / 180 * Math.PI
)
if parseFloat(transformation.y) isnt 0
rotationQuaternions.push new THREE.Quaternion().setFromAxisAngle(
new THREE.Vector3(0, 1, 0),
parseFloat(transformation.y) / 180 * Math.PI
)
if parseFloat(transformation.z) isnt 0
rotationQuaternions.push new THREE.Quaternion().setFromAxisAngle(
new THREE.Vector3(0, 0, 1),
parseFloat(transformation.z) / 180 * Math.PI
)
continue if rotationQuaternions.length is 0
finalRotationQuaternion = new THREE.Quaternion()
for rotationQuaternion in rotationQuaternions
finalRotationQuaternion = QuaternionUtils.combineRotations finalRotationQuaternion, rotationQuaternion
assetPlate.rotate finalRotationQuaternion