Retrieve Physical Properties of a Component
This code sample demonstrates the use of the Manufacturing Data Model API to find out physical properties such as area, mass, volume, density, surface area, and bounding box of a component.
See this code sample on the Manufacturing Data Model Samples Git Repository.
Note: This code sample requires Node.js version 16.13.2 or later.
Before you begin
- If you do not have an app registered for the Manufacturing Data Model API, follow the procedure outlined in Create an App to obtain a client ID for your app.
- Make sure that you add the following as the Callback URL:
http://localhost:8080/callback/oauth
. - In the APIs section, verify that the Manufacturing Data Model API is selected.
- Make sure that you add the following as the Callback URL:
- Clone or fork the GitHub Repository.
- In the 4.Get Physical Properties for Component folder, install all dependencies by running:
npm i
Setting up the application
index.js:
// Replace the string literal values with your own client id, client secret,
// hub name, project name and component name.
const clientId = '<YOUR_CLIENT_ID>';
const clientSecret = '<YOUR_CLIENT_SECRET>';
const hubName = '<YOUR_HUB_NAME>';
const projectName = '<YOUR_PROJECT_NAME>';
const componentName = '<YOUR_COMPONENT_NAME>';
In index.js shown earlier, specify values for the following variables:
clientId
- Your Client IDclientSecret
- Your Client SecrethubName
- The name of the hub that contains the design you want to read. (See the following image)projectName
- The name of the project that contains the design you want to read.componentName
- The name of the design you want to read.

Running the sample
- In the terminal, navigate to the 4.Get Physical Properties for Component folder and execute the following command:
npm start
- A URL is provided to be opened in a browser to sign in to your Autodesk Account. Open a browser and go to http://localhost:8080.
- Once the “Got the access token. You can close the browser!” message is displayed on the browser, return to the terminal.
- In the terminal window, you can now see the properties of the component getting generated like the following image.
Workflow description
The workflow can be summarized in three steps:
- Request for the properties such as area, mass, volume, density, bounding box, and surface area of a specific model based on its hub, project, and component name.
- If the status is
IN_PROGRESS
(it is still being generated), keep on checking the status. - Once the status is
COMPLETED
, check the properties of the component in the terminal window.
This workflow can be seen in the following code block:
app.js:
async getPhysicalProperties(hubName, projectName, componentName) {
try {
let projectId = await this.getProjectId(hubName, projectName);
let componentVersionId = await this.getComponentVersionId(projectId, componentName);
while (true) {
let response = await this.sendQuery(
`query GetPhysicalProperties($componentVersionId: ID!) {
componentVersion(componentVersionId: $componentVersionId) {
physicalProperties {
status
area {
displayValue
definition {
units {
name
}
}
}
volume {
displayValue
definition {
units {
name
}
}
}
mass {
displayValue
value
definition {
units {
name
}
}
}
density {
displayValue
definition {
units {
name
}
}
}
boundingBox {
length {
displayValue
definition {
units {
name
}
}
}
height {
displayValue
definition {
units {
name
}
}
}
width {
displayValue
definition {
units {
name
}
}
}
}
}
}
}`,
{
componentVersionId
}
)
let geometry = response.data.data.componentVersion.physicalProperties;
if (geometry.status === "COMPLETED") {
return geometry;
}
}
} catch (err) {
console.log("There was an issue: " + err.message)
}
}
JavaScript source code walk-through
app.js
This is the main operational code of the application. It sends a GraphQL query to open the design and fetch the properties of a component model.
// Axios is a promise-based HTTP client for the browser and node.js.
import axios from "axios";
// We need the following in order to save files to the machine
import fs from "fs";
import path from "path";
// Application constructor
export default class App {
constructor(accessToken) {
this.graphAPI = 'https://developer.api.autodesk.com/mfg/graphql';
this.accessToken = accessToken;
}
getRequestHeaders() {
return {
"Content-type": "application/json",
"Authorization": "Bearer " + this.accessToken,
};
}
async sendQuery(query, variables) {
try {
let response = await axios({
method: "POST",
url: `${this.graphAPI}`,
headers: this.getRequestHeaders(),
data: {
query,
variables,
},
});
return response;
} catch (err) {
if (err.response.data.errors) {
let formatted = JSON.stringify(err.response.data.errors, null, 2);
console.log(`API error:\n${formatted}`);
}
throw err;
}
}
async getProjectId(hubName, projectName) {
try {
// Get first batch of occurrences
let response = await this.sendQuery(
`query GetProjectId($hubName: String!, $projectName: String!) {
hubs(filter: {name: $hubName}) {
results {
name
projects(filter:{name:$projectName}) {
results {
name
id
}
}
}
}
}`,
{
hubName,
projectName
}
);
let projectId = response.data.data.hubs.results[0].projects.results[0].id;
return projectId;
} catch (err) {
console.log("There was an issue: " + err.message);
}
}
async getComponentVersionId(projectId, componentName) {
try {
// Get first batch of occurrences
let response = await this.sendQuery(
`query GetComponentVersionId($projectId: ID!, $componentName: String!) {
project(projectId: $projectId) {
items(filter: {name: $componentName}) {
results {
... on DesignItem {
tipRootComponentVersion {
id
}
}
}
}
}
}`,
{
projectId,
componentName
}
);
let componentVersionId = response.data.data.project.items.results[0].tipRootComponentVersion.id;
return componentVersionId;
} catch (err) {
console.log("There was an issue: " + err.message);
}
}
// <getPhysicalProperties>
async getPhysicalProperties(hubName, projectName, componentName) {
try {
let projectId = await this.getProjectId(hubName, projectName);
let componentVersionId = await this.getComponentVersionId(projectId, componentName);
while (true) {
let response = await this.sendQuery(
`query GetPhysicalProperties($componentVersionId: ID!) {
componentVersion(componentVersionId: $componentVersionId) {
physicalProperties {
status
area {
displayValue
definition {
units {
name
}
}
}
volume {
displayValue
definition {
units {
name
}
}
}
mass {
displayValue
value
definition {
units {
name
}
}
}
density {
displayValue
definition {
units {
name
}
}
}
boundingBox {
length {
displayValue
definition {
units {
name
}
}
}
height {
displayValue
definition {
units {
name
}
}
}
width {
displayValue
definition {
units {
name
}
}
}
}
}
}
}`,
{
componentVersionId
}
)
let geometry = response.data.data.componentVersion.physicalProperties;
if (geometry.status === "COMPLETED") {
return geometry;
}
}
} catch (err) {
console.log("There was an issue: " + err.message)
}
}
// </getPhysicalProperties>
}
index.js
This is the module that you use to run the application and set the required constant variables.
import MyApp from './app.js';
import MyAuth from './auth.js';
// Replace the string literal values with your own client id, client secret,
// hub name, project name and component name.
const clientId = '<YOUR_CLIENT_ID>';
const clientSecret = '<YOUR_CLIENT_SECRET>';
const hubName = '<YOUR_HUB_NAME>';
const projectName = '<YOUR_PROJECT_NAME>';
const componentName = '<YOUR_COMPONENT_NAME>';
// Create an instance of auth.js.
let myApsAuth = new MyAuth(clientId, clientSecret);
// Get an access token from your auth.js instance.
let accessToken = await myApsAuth.getAccessToken();
// Create an instance of app.js using the variable set above.
let myApsApp = new MyApp(
accessToken
);
let properties = await myApsApp.getPhysicalProperties(
hubName,
projectName,
componentName
);
console.log("Physical properties:");
printInfo(properties, "");
function printInfo (properties, indent) {
for (let propertyName of Object.keys(properties)) {
let property = properties[propertyName];
if (propertyName === "status") continue;
if (propertyName === "boundingBox") {
console.log(`${indent}${propertyName}:`);
printInfo(property, indent + " ");
continue;
}
console.log(`${indent}${propertyName}: ${property.displayValue} [${property.propertyDefinition.units.name}]`);
}
}
auth.js
This is the module that you use to obtain a three-legged access token to be used with the POST request you send to the Manufacturing Data Model API.
It uses the POST /v1/gettoken endpoint.
// Axios is a promise-based HTTP client for the browser and node.js.
// See npmjs.com/package/axios
import axios from 'axios';
// Express is a JavaSscript web application framework. See expressjs.com.
import express from 'express';
// Instantiate an express application.
let app = express();
// Export the Auth class for use by other app modules.
export default class Auth {
// Construct the class instance and set global variables, based on the client ID and secret.
constructor(clientId, clientSecret) {
this.host = 'https://developer.api.autodesk.com/';
this.authAPI = `${this.host}authentication/v2/`;
this.port = 8080;
this.redirectUri = `http://localhost:${this.port}/callback/oauth`;
this.accessTokenPromise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
// Handle the callback/redirection by the Autodesk server once the user approves our app’s access to their data.
app.get('/callback/oauth', async (req, res) => {
const { code } = req.query;
// When you are redirected to the callback URL, the URL also contains a ‘code’ parameter with a value that you can exchange for an actual access token.
try {
const response = await axios({
method: 'POST',
url: `${this.authAPI}token`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: `client_id=${clientId}&client_secret=${clientSecret}&grant_type=authorization_code&code=${code}&redirect_uri=${this.redirectUri}`
})
// Set the accessToken variable to the value in the response.
this.accessToken = response.data.access_token
// Resolve the Promise passed by the getAccessToken() function below with the access token.
// Let the rest of the application continue.
this.resolve(this.accessToken);
// No need to listen for incoming calls anymore.
this.server.close();
res.redirect('/');
} catch (error) {
console.log(error);
this.reject(error);
}
});
app.get('/', async (req, res) => {
// Once you have the access token, then there is nothing more to do.
if (this.accessToken) {
res.send('Got the access token. You can close the browser!').end();
return;
}
// Otherwise, redirect the user to the Autodesk log-in site where they can log in with their credentials
// and approve our app’s access to their data.
// Once that happens, the Autodesk server redirects the user to the callback URL provided.
// That callback is handled above in the app.get('/callback/oauth' …) function.
const url =
`${this.authAPI}authorize?response_type=code` +
`&client_id=${clientId}` +
`&redirect_uri=${this.redirectUri}` +
'&scope=data:read data:write data:create';
res.redirect(url);
})
this.server = app.listen(this.port);
console.log(
`Open http://localhost:${this.port} in a web browser in order to log in with your Autodesk account!`
);
}
// Pass back a Promise that only resolves and lets the rest of the application continue
// once you have an access token.
getAccessToken = async () => {
return this.accessTokenPromise;
}
}