3DIAX TutorialΒΆ

Authentise has recently released 3DIAX, a platform designed to make it easier for users to maintain a large database of model data in the cloud. We’re pretty excited about this announcement because it marks the first in a series of services that we are going to be making available to the public. This service is designed to simplify managing 3D models and to get them ready for printing.

Before you get started you’ll want to review the Client Authentication documentation. All of the endpoints discussed in this tutorial will require you to have a valid session which means you’ll need to start by creating a user with Authentise and you’ll need to include the session cookie in every request.

Now, let’s assume you have a really cool model that you want to print. It might look something like this:

../_images/logo-blender.png

Wow! What a cool model. I’d love to keep that thing securely backed up in some kind of service for storing models...y’know...in the cloud. Let’s create a model resource where I could store it.

POST https://models.authentise.com/model/
Content-Type: application/json

{
  "name": "Authentise logo",
  "callback": {
    "url" : "https://my.domain.net",
    "method" : "POST",
  }
}

This tells 3DIAX that we need to create a model named ‘Authentise logo’ and that any time the model has a status update we want a the service to POST to https://my.domain.net with the status. 3DIAX will respond with the standard Location header, which will be the URL of the new model resource. It will also respond with a X-Upload-Location. This is a URL where I’ll need to send my model file. That can be done with a PUT request. The body of the request should be the file. Because the service supports both ASCII and binary STL files you must include a Content-Type header that contains application/octet-stream.

If you’d like, you can follow along with the same model we’re working with in this tutorial. Experiment a little, or just plug in the same payloads we’re using. Our Location header is https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/. Now I’m going to PUT the model content into the URL that the resource gave me in X-Upload-Location

PUT https://dev-hoth-models.s3.amazonaws.com:443/3f6d9729-aa44-4019-9129-b6fc215ad87d?Signature=0U%2...
Content-Type: application/octet-stream

model data goes here

After my upload is complete 3DIAX will send a request to the callback URL I provided letting me know that the model is being processed. That request looks like this:

POST https://my.domain.net
Content-Type: application/json

{
    "uri"       : "https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/
    "status"    : "processed",
}

The URI provided is the URI of the model that has changed and the status is the new status of the model. The new processed status means that the model has been analyzed and determined to be a good model. Had I accidentally uploaded a picture of my cat the status would have been less rosy and I would have seen error in the callback.

Now that I’ve got a model in the warehouse let’s take a look at it. As soon as you upload a model 3DIAX will generate a snapshot of the model. We can make a GET request to the URI we got in the Location header and we’ll see:

GET https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/
{
  "analyses": {
    "manifold": true
  },
  "children": [],
  "content": "https://prod-hoth-models.s3.amazonaws.com:443/7ae4aeca-c46b-4d29-843a-ef3743444af3?Signature=...",
  "created": "2015-06-30 20:06:49.947704",
  "name": "Authentise logo",
  "parents": [],
  "size": {
    "x": 6.65288591384888,
    "y": 6.81669282913208,
    "z": 6.65288615226746
  },
  "snapshot": "https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/snapshot/b119f291-a11a-4c53-b2ea-89a3f2acfe98/",
  "status": "processed",
  "updated": "2015-06-30 20:06:50.739383",
  "upload-location": null
}

Because I’ve been taking my time writing this tutorial enough time has passed that the model has already moved into the processed state by the time I performed the GET. We can see that my model has been analyzed and is, in fact, manifold. It has no children so far - those are models that are derivatives of this model and we’ll get to that momentarily. I can download the model using the signed S3 URL provided. The parents property would be populated if this model were a derivative work itself (which it isn’t). The size is the calculated dimensions of the model. Finally we can see my snapshot resource. This is the snapshot that was automatically produced for me after upload. Let’s GET that resource to see what it looks like:

GET https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/snapshot/b119f291-a11a-4c53-b2ea-89a3f2acfe98/
{
  "color": "#FF7F00",
  "content": "https://prod-hoth-snapshots.s3.amazonaws.com:443/b119f291-a11a-4c53-b2ea-89a3f2acfe98?Signature=...",
  "created": "2015-06-30 20:06:50.660878",
  "height": 480,
  "samples": 10,
  "slice_height": null,
  "status": "snapshot_rendered",
  "u": null,
  "v": null,
  "w": null,
  "width": 640,
  "x": null,
  "y": null,
  "z": null
}

The color by default is a lovely shade of orange-yellow that you may recognize. The content is where I can download the actual image itself. The default image is a 640x480 PNG with 10 samples per pixel. Finally the x, y, z and u, v, w values are all set to null which indicates that this is a snapshot where 3DIAX will automatically determine the ideal camera placement. Default snapshots are always like this.

So what does it look like?

../_images/logo-default-render.png

It’s a decent image. But we can do better. Let’s introduce how we can make our own snapshots. Creating a snapshot resource in the simplest case looks like this:

POST https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/snapshot/
Content-Type: application/json

{
    "samples"   : 1,
    "color"     : "#FF7F00",
    "height"    : 480,
    "width"     : 640,
}

Location: https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/snapshot/b119f291-a11a-4c53-b2ea-89a3f2acfe98/

This specifies that I’d like an image that is 640x480 and does just one sample per pixel. The color specifies the color to simulate for the material of the model. The returned Location header can be used to query the status of my render like so

GET https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/snapshot/b119f291-a11a-4c53-b2ea-89a3f2acfe98/

{
    "color"         : "#FF7F00",
    "content"       : "",
    "created"       : "2015-05-13 22:18:22.658536",
    "height"        : 480,
    "samples"       : 1,
    "slice_height"  : None,
    "status"        : "snapshot_rendering",
    "u"             : None,
    "v"             : None,
    "w"             : None,
    "x"             : None,
    "y"             : None,
    "z"             : None,
}

This shows the same data I sent up with a few added properties. It includes an empty content property that will be populated with a link to the image content when the render is complete. It shows a slice_height which is used in Authentise’s Vision Service. It includes the X, Y, Z and U, V, W camera coordinates which we didn’t specify but will be automatically set to a default value that should capture our model. After a few seconds we can hit the endpoint again and the status will change to shapshot_rendered and we’ll have a valid content.

GET https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/snapshot/b119f291-a11a-4c53-b2ea-89a3f2acfe98/

{
    "color"         : "#FF7F00",
    "content"       : "https://prod-hoth-snapshots.s3.amazonaws.com:443/1c0d5b4e-8938-401d-a8db-5db270088df0?Signature=...",
    "created"       : "2015-05-13 22:18:22.658536",
    "height"        : 480,
    "samples"       : 1,
    "slice_height"  : None,
    "status"        : "snapshot_rendered",
    "u"             : None,
    "v"             : None,
    "w"             : None,
    "x"             : None,
    "y"             : None,
    "z"             : None,
}

Now we just have to GET the URL for content and we’ll get our rendered image. Looks like this:

../_images/logo-default-render.png

Yep, that’s the same image that was automatically created earlier. Now you know the Special Sauce we use to create default images when a user uploads a model.

The default render assumes camera parameters that will capture most normal models for a 3D print but does so at the cost of style. Luckily we can improve this quite a bit with a better camera angle. In our request for the image we can specify the camera using X Y Z and U V W. The X Y Z values are the position of the camera and the U V W values are rotation in degrees to apply to the camera to determine where it points. Here’s how I produce an image that is better framed for the model

POST https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/
Content-Type: application/json

{
    "samples"   : 1,
    "color"     : "#FF7F00",
    "height"    : 480,
    "width"     : 640,
    "x"         : -9.2,
    "y"         : -11.3,
    "z"         : 21,
    "u"         : 34.3,
    "v"         : 0,
    "w"         : -38,
}

Location: https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/snapshot/864665b0-a192-4a77-9abd-6fd405dc65d5/
../_images/logo-simple-frame.png

Much better. But unfortunately it looks a bit grainy. Let’s try turning up the number of samples per pixel. This will take more time to render but give us a higher quality image.

POST https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/
Content-Type: application/json

{
    "samples"   : 10,
    "color"     : "#FF7F00",
    "height"    : 480,
    "width"     : 640,
    "x"         : -9.2,
    "y"         : -11.3,
    "z"         : 21,
    "u"         : 34.3,
    "v"         : 0,
    "w"         : -38,
}

Location: https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/snapshot/cae1a5f5-5bdb-48dd-8ee7-580211928326/
../_images/logo-simple-frame-10spp.png

Nice. Sharper. What if I wanted it in blue? Let’s throw in the material color we’d like

POST https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/
Content-Type: application/json

{
    "samples"   : 10,
    "color"     : "#0066FF",
    "height"    : 480,
    "width"     : 640,
    "x"         : -9.2,
    "y"         : -11.3,
    "z"         : 21,
    "u"         : 34.3,
    "v"         : 0,
    "w"         : -38,
}

Location: https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/snapshot/d28ba531-4027-4253-a634-552457713c67/
../_images/logo-simple-frame-10spp-blue.png

Not bad. We’ll stick with orange though. It just sits better with me.

The astute reader will notice that this logo has something wrong with it. A proper Authentise logo should have a bottom section. The problem here is that when I created the model I did not properly set it to the origin. Instead, part of the model is below the XY plane into the negative Z space. This will happen at times with modelers, especially those not completely accustomed to 3D printing. Fortunately 3DIAX provides a system for making modifications to models.

POST https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/transformation/
Content-Type: application/json

{
    "transformations"           : [{
        "type"                      : "auto-translate",
        "parametersAutoTranslate"   : {
            "build"                 : {
                "x"                 : 100,
                "y"                 : 100,
                "z"                 : 100,
            }
        },
    }]
}

Location: https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/snapshot/1684ccba-aee1-44d7-b02b-01394682b849/

This request tells 3DIAX that you would like the model automatically centered in your printer’s bed. We provide the dimensions of the bed - in this case a theoretical cube that’s 100mm to a side - Here’s what it did to my model. Just for completeness, I’ll include the request I made to get the new snapshot. It needed a slightly different camera angle

POST https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/snapshot/
Content-Type: application/json

{
    "samples"   : 10,
    "color"     : "#FF7F00",
    "height"    : 480,
    "width"     : 640,
    "x"         : -9.2,
    "y"         : -11.3,
    "z"         : 21,
    "u"         : 39.3,
    "v"         : 0,
    "w"         : -38,
}

Location: https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/snapshot/e48bbcf4-8209-4e47-9975-a141cefced79/

Which yields

../_images/logo-simple-frame-translated.png

There’s quite a few different transformations that are supported - see the 3DIAX API Reference. You’ll notice that the endpoint takes a list of transformations rather than a single object. That’s because we can apply multiple transformations in a single request. For example

POST https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/transformation/
Content-Type: application/json

{
    "transformations"       : [{
        "type"                  : "scale",
        "parametersScale"       : {
            "x"                 : 1.2,
            "y"                 : 0.6,
            "z"                 : 1,
        },
    },{
        "type"                  : "rotate",
        "parametersRotate"      : {
            "x"                 : 30,
            "y"                 : 30,
            "z"                 : 0,
        },
    },{
        "type"                  : "translate",
        "parametersTranslate"   : {
            "x"                 : 0,
            "y"                 : 0,
            "z"                 : 3,
        }
    }]
}

Location: https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/transformation/bd647a97-1499-4af5-b59a-73e527d8b09c/

These are three separate transforms here, scale first then a rotation then a translation. We’re scaling the X dimensions up, then the y dimensions down, 120% and 60% respectively. Z we are leaving unchanged at 100% scale. Next we rotate by 30 degress both in the X and Y. Finally we translate the object along the positive Z by 3mm.

The order of operations is important of course, if we were to change the scale and rotate ordering we’d have a completely different shape. Here’s what we end up with:

../_images/logo-transformed.png

One important item to note is that I didn’t have to wait until the model was finished uploading to create these new resources. All operations on models are designed to be fully asynchronous with callbacks but they are designed to operate like promises. You can chain together an unlimited number of transformations on models well before you’ve uploaded the model’s STL representation and as soon as the upload is complete the system will perform the transformations and populate the child models. So I could make all of the above requests in rapid succession and upload the model content at the end and I’d still end up with the same results at the end.

Speaking of which, I should cover the callbacks. At each stage I can include information on a callback. For example:

POST https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/transformation/
Content-Type: application/json

{
    "transformations"   : [{
        "type"                      : "auto-translate",
        "parametersAutoTranslate"   : {
            "build"                 : {
                "x"                 : 100,
                "y"                 : 100,
                "z"                 : 100,
            }
        },
    }],
    "callback"          : {
        "method"        : "GET",
        "url"           : "http://my.domain.net",
    }
}

Location: https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/transformation/33bd3c4e-71d9-4d6e-8e6c-74c7cf66bc15/

When I provide a callback in this way 3DIAX will send a GET request to http://my.domain.net when the transformation is ready. The request will look like this:

GET http://my.domain.net/?uri=http://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/&status=processed

If I had requested either a PUT or POST the payload would be JSON and contain the same data:

POST http://my.domain.net/
Content-Type: application/json

{
    "uri"       : "https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/",
    "status"    : "processed",
}

You can see more details in callback-service.

After these requests I actually end up with 3 models total in my warehouse - the original model I uploaded, the first derivative model I auto-translated and the second derivative model I scale-rotate-translated. I can query for information about each model with the URI. As an example here’s my original model that I uploaded.

GET https://models.authentise.com/model/7ae4aeca-c46b-4d29-843a-ef3743444af3/

{
    "content"   : "https://...",
    "status"    : "processed",
    "name"      : "Authentise logo",
    "analyses"  : {"manifold": true},
    "created"   : "2015-05-10T10:12:53",
    "updated"   : "2015-05-10T10:12:53",
    "parents"   : [],
    "children"  : [
        "https://models.authentise.com/model/c145fca8-36e5-4814-8c9e-2ce443053171/",
        "https://models.authentise.com/model/ac87995b-6e2b-4693-8926-6c57bd3cb0ed/",
    ]
}

The content link is where I can download the STL representation of the model. The status is "processed" because enough time has passed that my model has actually been analyzed. You can see the analysis that was performed - whether or not it is manifold - shows that it is indeed manifold. The parents field indicates which models were used to originally compose this model. This field will be populated with one or more model URIs if the model in question was produced via transformations. This model was uploaded directly so it has no parents. On the flip side the children field shows any models that are derivative works of this source model.

We can use the information about parentage to figure out where each model comes from. This can be useful as our library grows to keep track of improvements we make to models. After you make transformations to models you may want to download the content back out of 3DIAX. Models you upload will be kept in their original format. Models that are created via transformations will be stored in gzip format. You’ll need to unzip them yourself after downloading them. From there they will be in STL text format. The downloaded file will be a UUID - you may need to add the .stl.gz extension to get your tools to unzip and recognize the STL file.