For Developers
Headless Mode
Unwrella-IO can be run without its graphical user interface. In this mode it receives all data it needs to perform its unwrap and pack operations and returns the results through the standard stdin and stdout streams. This can be used to interact with Unwrella-IO from other programs directly without having to export 3d scenes first. Communication with Unwrella-IO through streams can be used with raw binary data (the default mode) or optionally data encoded in JSON format.
Make sure you always provide the correct version number for the communication interface and the corresponding data layout in all communication. This is not identical to the program version of Unwrella-IO.
The latest version for the communication interface is 1.0.0 This is used by Unwrella-IO 1.1.0 (and newer) and Packer-IO 1.2.0 (and newer).
If you are unsure which version of the interface you need, run Unwrella-IO with the graphical user interface and check in Preferences - About. This dialog shows the version number for the interface next to the program’s version number.
Using the Binary Interface
Run Unwrella-IO with the command line argument connect
and provide the input data for your task according to the binary structure below through the process stdin stream. Once Unwrella-IO has received the full data it will start processing and provide responses during and after processing through its stdout stream which are expected to be consumed by the caller. Once all output data has been sent it will exit.
The input and output data makes use of the following data types:
uint32
- an unsigned integer number, always 32 bit, in little endian encoding.double
- a 64 bit floating point number, following IEEE 754 standard.bool
- always 8 bit (to keep alignment convenient). If all bits are null it’s interpreted asfalse
, otherwisetrue
.string
- a sequence of bytes representing a UTF-8 encoded string. Not null terminated. The exact length of the string is provided explicitly as a separateuint32
.
Input data
Input messages start with a size indicator that tells Unwrella-IO how many bytes to read. The 4 bytes for the size indicator itself are not included in this, only the rest of the message.
This is followed by 3 integers specifying the version of the connection interface. This is to make sure that a version incompatibility can be quickly identified.
After this the options that are shared by all objects are provided. For details about these options refer to their counterparts in the Unwrella-IO user interface.
Then the objects are sent with their individual data:
ID is an arbitrary number to identify the object. Results are provided in the same order as the inputs but they also all include the id numbers in case the caller needs to identify the objects again.
The object names are only used in error messages as needed.
The options are individual per object. Different objects can provide different values here to be unwrapped differently. For details about these options refer to their counterparts in the Unwrella-IO user interface.
After this the geometry of the objects is provided in a series of lists. Vertices of the geometry and the UV data are provided as separate lists of vertices and indices to allow reuse of vertex coordinates. Index lists contain one entry for each vertex of each polygon in order. The polygon list contains the degree of each polygon in the mesh. The uv vertices and indices are optional. If the object doesn’t have any uv data yet they can be left empty.
The additional lists for pinned vertices and custom seams are optional and can be empty.
If they are used the pins refer to an offset in the index lists to identify a polygon as pinned. The uv chart this polygon belogs to will not be moved at all during packing. Pinning is only relevant for packing and is ignored if the object is unwrapped.
The pairs of indices in the custom seam list identify edges that are marked as seams. If any are provided the unwrap operations will perform seam cuts along these edges.
Structure for Input Data
uint32 messageSize # size of the message, not including this uint32 itself
uint32 versionMajor # this is the version of the INTERFACE, not the app or the script
uint32 versioMinor
uint32 versionPatch
uint32 width
uint32 height
uint32 packMode # 0: efficient, 1: high quality
double padding
bool useDensity
double density
bool combine
bool rescale
bool preRotate
bool fullRotation
uint32 rotation # 0: 0°, 1: 90°, 2: 45°, 3: 23°
uint32 tilesX
uint32 tilesY
uint32 numObjects
# loop per object
uint32 id
uint32 stringSize
string name
uint32 unwrapMode # 0: organic, 1: hard surface, 2: mosaic, 3: pack, 4: keep existing
double stretch
double hardAngle
bool keepSeams
bool cutConcave
double angleConcave
bool cutConvex
double angleConvex
bool cutHoles
uint32 numGeoVertices
# loop per geoVertex
double geoX
double geoY
double geoZ
uint32 numUVVertices
# loop per uvVertex
double uvX
double uvY
uint32 numGeoIndices
# loop per geoIndex
uint32 geoIndex
uint32 numUVIndices
# loop per uvIndex
uint32 uvIndex
uint32 numPolygons
# loop per polygon
uint32 deg
uint32 numPinned
# loop per pin
uint32 index of pinned
uint32 numCustomSeams
# loop per custom seam
uint32 seamVert0
uint32 seamVert1
Output data
Once the full input data is received it will be processed. During that time Unwrella-IO will repeatedly send progress reports to stdout. All output messages start with the same 2 elements: First a size indicator for the whole message in bytes so that the recipient knows how much data to read for the message and then an integer specifying the type of the message:
0
(MESSAGE_SUCCESS) - This message is sent when all data was processed successfully and it contains the results. This is the final message and nothing further will be sent afterwards.1
(MESSAGE_PROGRESS) - This is a progress message identifying that the data is still being processed. There will be at least one more message after this.2
(MESSAGE_ERROR) - This message is sent when there was a problem processing the data. The message contains an error message with further details. This is the final message and nothing further will be sent afterwards.
The remaining data structure of the message is different depending on the type.
Structure for Output Data
Progress Message
This is sent repeatedly while the input data is being processed. The progress value is a number between 0.0 and 1.0 - a provided value might be lower than the one from a previous message because different processing steps can report their progress independently.
uint32 messageSize # size of the message, not including this uint32 itself
uint32 messageType # 1 MESSAGE_PROGRESS
double progress
Final message with Results
This is sent as the final message if processing was successful. It provides new UV data for each object following the same specification as the input. Coverage specifies the fraction of the default uv area that is used by the uv. If multiple tiles are used or uv data goes beyond the default area (charts were pinned or a high density is enforced) this value can be larger than 1.0. Density specifies the texel density of the result in pixels per system unit.
uint32 messageSize # size of the message, not including this uint32 itself
uint32 messageType # 0 MESSAGE_SUCCESS
uint32 numObjects
(loop per object)
uint32 id
uint32 numUvVertices
(loop per uvVertex)
double uvX
double uvY
uint32 numUVIndices
(loop per uvIndex)
uint32 uvIndex
double coverage
double density
Final Message with Error
This is sent as the final message if processing encountered a problem. The provided string describes the error.
uint32 messageSize # size of the message, not including this uint32 itself
uint32 messageType # 2 MESSAGE_ERROR
uint32 stringSize
string errorMessage
Using the JSON Interface
Run Unwrella-IO with the command line arguments connect
and json
. The process is identical to the binary interface but input and output data is performed with JSON strings as outlined by the JSON Schema below.
JSON Schema for Input Data
{
"$schema": "https://json-schema.org/draft-07/schema",
"$id": "https://www.unwrella.com/files/unwrella-io.input.schema.1.0.0.json",
"title": "Unwrella-IO JSON Interface",
"description": "Interface for headless connection to Unwrella-IO",
"type": "object",
"properties": {
"version": {
"type": "array",
"items": {
"type": "integer",
"minimum": 0
},
"minItems": 3,
"maxItems": 3
},
"width": {
"type": "integer",
"minimum": 1
},
"height": {
"type": "integer",
"minimum": 1
},
"packMode": {
"type": "integer",
"minimum": 0,
"maximum": 1
},
"padding": {
"type": "number",
"minimum": 0.0
},
"useDensity": {
"type": "boolean"
},
"density": {
"type": "number",
"minimum": 0.0
},
"combine": {
"type": "boolean"
},
"rescale": {
"type": "boolean"
},
"preRotate": {
"type": "boolean"
},
"fullRotation": {
"type": "boolean"
},
"rotation": {
"type": "integer",
"minimum": 0,
"maximum": 3
},
"tilesX": {
"type": "integer",
"minimum": 0
},
"tilesY": {
"type": "integer",
"minimum": 0
},
"objects": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"minimum": 0
},
"name": {
"type": "string"
},
"unwrapMode": {
"type": "integer",
"minimum": 0,
"maximum": 4
},
"stretch": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0
},
"hardAngle": {
"type": "number",
"minimum": 0.0,
"maximum": 180.0
},
"keepSeams": {
"type": "boolean"
},
"cutConcave": {
"type": "boolean"
},
"angleConcave": {
"type": "number",
"minimum": 0.0,
"maximum": 180.0
},
"cutConvex": {
"type": "boolean"
},
"angleConvex": {
"type": "number",
"minimum": 0.0,
"maximum": 180.0
},
"cutHoles": {
"type": "boolean"
},
"geoVertices": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 3,
"maxItems": 3
}
},
"uvVertices": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 2
}
},
"geoIndices": {
"type": "array",
"items": {
"type": "integer",
"minimum": 0
}
},
"uvIndices": {
"type": "array",
"items": {
"type": "integer",
"minimum": 0
}
},
"polygons": {
"type": "array",
"items": {
"type": "integer",
"minimum": 0
}
},
"pinned": {
"type": "array",
"items": {
"type": "integer",
"minimum": 0
}
},
"customSeams": {
"type": "array",
"items": {
"type": "integer",
"minimum": 0
}
}
}
}
}
},
"required": ["version"]
}
JSON Schema for Output Data
{
"$schema": "https://json-schema.org/draft-07/schema",
"$id": "https://www.unwrella.com/files/unwrella-io.output.schema.1.0.0.json",
"title": "Unwrella-IO JSON Interface",
"description": "Interface for headless connection to Unwrella-IO",
"type": "object",
"properties": {
"type": {
"type": "integer",
"minimum": 0,
"maximum": 2
}
},
"required": ["type"],
"allOf": [
{
"if": {
"properties": {
"type": {
"const": 0
}
}
},
"then": {
"properties": {
"objects": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"minimum": 0
},
"uvVertices": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 2
}
},
"uvIndices": {
"type": "array",
"items": {
"type": "integer",
"minimum": 0
}
}
},
"required": ["id", "uvVertices", "uvIndices"]
}
},
"coverage": {
"type": "number",
"minimum": 0.0
},
"density": {
"type": "number",
"minimum": 0.0
}
},
"required": ["objects", "coverage", "density"]
}
},
{
"if": {
"properties": {
"type": {
"const": 1
}
}
},
"then": {
"properties": {
"progress": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0
}
},
"required": ["progress"]
}
},
{
"if": {
"properties": {
"type": {
"const": 2
}
}
},
"then": {
"properties": {
"message": {
"type": "string"
}
},
"required": ["message"]
}
}
]
}