Dust3D Remote IO Protocol Specification

Introduction

Dust3D Remote IO is an API based on a TCP/IP connection. It hosts on local TCP port 53309, and enables other software control the modeling progress of Dust3D by sending commands through the TCP connection.

Protocol

Other software connect to tcp host 127.0.0.1:53309, send command, get reply and receive event from Dust3D. One command, or one response, consists of one packet, each packet encoded as hex string, and choose ‘\0’ as packet splitter.

Each response start with a ‘+’ or ‘-‘ when there is an error, the error message comes after the minus sign.

Event start with a ‘#’.

Python Example

#!/usr/bin/env python

# Run Dust3D with option: -remoteio to enable it
#   e.g.
#        $ open ./dust3d.app --args -remoteio
#        $ ./dust3d -remoteio
#        $ ./dust3d.AppImage -remoteio

import socket
import binascii
import uuid

TCP_IP = '127.0.0.1'
TCP_PORT = 53309
BUFFER_SIZE = 4096

def genId():
    return "{" + str(uuid.uuid4()) + "}"

firstNodeId = genId()
secondNodeId = genId()

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(binascii.hexlify("addnodewithid " + firstNodeId + " 0.51 0.51 1.01 0.08") + "\0")
s.send(binascii.hexlify("addnodewithid " + secondNodeId + " 0.51 0.51 1.51 0.08") + "\0")
s.send(binascii.hexlify("addedge " + firstNodeId + " " + secondNodeId + "") + "\0")
s.send(binascii.hexlify("savesnapshot") + "\0")
s.send(binascii.hexlify("exportAsObj") + "\0")
#s.send(binascii.hexlify("getNodePartId {3dc475f6-dcda-45b8-bb76-59948db39968}") + "\0")
response = bytes()
while True:
    oneEnd = response.find(chr(0))
    if (-1 == oneEnd):
        response += s.recv(BUFFER_SIZE)
        continue
    reply = response[:oneEnd]
    response = response[oneEnd + 1:]
    print binascii.unhexlify(reply)
s.close()

Commands

Command Examples
listWindow
send> listwindow
+OK
{658cac48-4cc4-42bf-a561-dbd28330777e} Dust3D%201.0.0-beta.17%20*
selectWindow <windowId>
send> selectwindow {658cac48-4cc4-42bf-a561-dbd28330777e}
+OK
undo
send> undo
+OK
redo
send> redo
+OK
paste
send> paste
+OK
removeNode <nodeId>
send> removeNode {3dc475f6-dcda-45b8-bb76-59948db39968}
+OK
removeEdge <edgeId>
send> removeEdge {a75f39ac-3c78-4754-b34a-dce70779832b}
+OK
removePart <partId>
send> removePart {79a15562-908c-4b74-a489-af604796b1a0}
+OK
addNode <x> <y> <z> <radius> <fromNodeId>
send> addNode 0.51 0.51 1.01 0.08
+OK

send> addNode 0.51 0.51 1.01 0.08 {3dc475f6-dcda-45b8-bb76-59948db39968}
+OK
addNodeWithId <nodeId> <x> <y> <z> <radius> <fromNodeId>
send> addNodeWithId {8d443cbf-fc73-4281-b3a1-268dd38b1c73} 0.51 0.51 1.01 0.08
+OK

send> addNodeWithId {8d443cbf-fc73-4281-b3a1-268dd38b1c73} 0.51 0.51 1.01 0.08 {3dc475f6-dcda-45b8-bb76-59948db39968}
+OK
scaleNodeByAddRadius <nodeId> <amount>
send> scaleNodeByAddRadius {8d443cbf-fc73-4281-b3a1-268dd38b1c73} 0.05
+OK
moveNodeBy <nodeId> <x> <y> <z>
send> moveNodeBy {8d443cbf-fc73-4281-b3a1-268dd38b1c73} 0.05 0.05 0.05
+OK
setNodeOrigin <nodeId> <x> <y> <z>
send> setNodeOrigin {8d443cbf-fc73-4281-b3a1-268dd38b1c73} 0.51 0.51 1.01
+OK
setNodeRadius <nodeId> <radius>
send> setNodeRadius {8d443cbf-fc73-4281-b3a1-268dd38b1c73} 0.08
+OK
setNodeBoneMark <nodeId> <boneMark>
Available bone marks: Neck/Limb/Tail/Joint/None

send> setNodeBoneMark {8d443cbf-fc73-4281-b3a1-268dd38b1c73} Neck
+OK
switchNodeXZ <nodeId>
send> switchNodeXZ {8d443cbf-fc73-4281-b3a1-268dd38b1c73}
+OK
moveOriginBy <x> <y> <z>
send> moveOriginBy 0.01, 0.02, 0.013
+OK
addEdge <fromNodeId> <toNodeId>
send> addEdge {a75f39ac-3c78-4754-b34a-dce70779832b} {507328fd-9baf-41d1-9e05-850fb41fcbfa}
+OK
setPartLockState <partId> <lockState>
send> setPartLockState {79a15562-908c-4b74-a489-af604796b1a0} locked
+OK

send> setPartLockState {79a15562-908c-4b74-a489-af604796b1a0} unlocked
+OK
setPartVisibleState <partId> <visibleState>
send> setPartVisibleState {79a15562-908c-4b74-a489-af604796b1a0} visible
+OK

send> setPartVisibleState {79a15562-908c-4b74-a489-af604796b1a0} invisible
+OK
setPartSubdivState <partId> <subdivState>
send> setPartSubdivState {79a15562-908c-4b74-a489-af604796b1a0} subdived
+OK

send> setPartSubdivState {79a15562-908c-4b74-a489-af604796b1a0} unsubdived
+OK
setPartChamferState <partId> <chamferState>
send> setPartChamferState {79a15562-908c-4b74-a489-af604796b1a0} chamfered
+OK

send> setPartChamferState {79a15562-908c-4b74-a489-af604796b1a0} unchamfered
+OK
setPartRoundState <partId> <roundState>
send> setPartRoundState {79a15562-908c-4b74-a489-af604796b1a0} rounded
+OK

send> setPartRoundState {79a15562-908c-4b74-a489-af604796b1a0} unrounded
+OK
setPartDisableState <partId> <disableState>
send> setPartDisableState {79a15562-908c-4b74-a489-af604796b1a0} disabled
+OK

send> setPartDisableState {79a15562-908c-4b74-a489-af604796b1a0} undisabled
+OK
setPartXmirrorState <partId> <xMirrorState>
send> setPartXmirrorState {79a15562-908c-4b74-a489-af604796b1a0} mirrored
+OK

send> setPartXmirrorState {79a15562-908c-4b74-a489-af604796b1a0} unmirrored
+OK
setPartColor <partId> <colorName>
send> setPartColor {79a15562-908c-4b74-a489-af604796b1a0} red
+OK

send> setPartColor {79a15562-908c-4b74-a489-af604796b1a0}
+OK
getNodePartId <nodeId>
send> getNodePartId {3dc475f6-dcda-45b8-bb76-59948db39968}
+OK
{b8f9ae53-999c-4851-9c2b-69a427fca10c}
saveSnapshot
send> saveSnapshot
+OK
getSnapshot
send> getSnapshot
+OK
<?xml version=”1.0”?>
<canvas>
<nodes>
<node id=”{3dc475f6-dcda-45b8-bb76-59948db39968}” partId=”{b8f9ae53-999c-4851-9c2b-69a427fca10c}” radius=”0.08” x=”0.51” y=”0.51” z=”1.01”/>
</nodes>
<edges/>
<parts>
<part chamfered=”false” disabled=”false” id=”{b8f9ae53-999c-4851-9c2b-69a427fca10c}” locked=”false” rounded=”false” subdived=”false” visible=”true” xMirrored=”false” zMirrored=”false”/>
</parts>
<components>
<component combineMode=”Normal” expanded=”false” id=”{946dad8f-28d5-40c8-8c70-709ecc1ca048}” linkData=”{b8f9ae53-999c-4851-9c2b-69a427fca10c}” linkDataType=”partId”/>
</components>
<materials/>
<poses/>
<motions/>
</canvas>
exportAsObj
send> exportAsObj
+OK
# DUST3D
v -0.08 0.08 0.08
v -0.08 -0.08 0.08
v 0.08 -0.08 0.08
v 0.08 -0.08 -0.08
v -0.08 -0.08 -0.08
v -0.08 0.08 -0.08
v 0.08 0.08 -0.08
v 0.08 0.08 0.08
f 2 1 6 5
f 3 2 5 4
f 2 3 8 1
f 8 3 4 7
f 5 6 7 4
f 1 8 7 6
new
send> new
+OK

Events

Event
nodeadded <nodeId>
partadded <partId>
edgeadded <edgeId>
partremoved
componentnamechanged <componentId>
componentchildrenchanged <componentId>
componentremoved <componentId>
componentadded <componentId>
componentexpandstatechanged <componentId>
noderemoved <nodeId>
edgeremoved <edgeId>
noderadiuschanged <nodeId>
nodebonemarkchanged <nodeId>
nodeoriginchanged <nodeId>
edgechanged <edgeId>
partpreviewchanged <partId>
resultmeshchanged
turnaroundchanged
editmodechanged
skeletonchanged
resulttexturechanged
postprocessedresultchanged
resultrigchanged
rigchanged
partlockstatechanged <partId>
partvisiblestatechanged <partId>
partsubdivstatechanged <partId>
partdisablestatechanged <partId>
partxmirrorstatechanged <partId>
partdeformthicknesschanged <partId>
partdeformwidthchanged <partId>
partroundstatechanged <partId>
partcolorstatechanged <partId>
partcutrotationchanged <partId>
partcuttemplatechanged <partId>
partmaterialidchanged <partId>
partchamferstatechanged <partId>
componentcombinemodechanged <componentId>
cleanup
originchanged
xlockstatechanged
ylockstatechanged
zlockstatechanged
radiuslockstatechanged
checkpart <partId>
partchecked <partId>
partunchecked
enablebackgroundblur
disablebackgroundblur
exportready
uncheckall
checknode <nodeId>
checkedge <edgeId>
optionschanged
rigtypechanged
poseschanged
motionschanged
poseadded <poseId>
poseremoved <poseId>
poselistchanged
posenamechanged <poseId>
poseframeschanged <poseId>
poseturnaroundimageidchanged <poseId>
posepreviewchanged <poseId>
motionadded <motionId>
motionremoved <motionId>
motionlistchanged
motionnamechanged <motionId>
motionclipschanged <motionId>
motionpreviewchanged <motionId>
motionresultchanged <motionId>
materialadded <materialId>
materialremoved <materialId>
materiallistchanged
materialnamechanged <materialId>
materiallayerschanged <materialId>
materialpreviewchanged <materialId>
meshgenerating
postprocessing
texturegenerating
texturechanged