All Projects → petrbroz → forge-convert-utils

petrbroz / forge-convert-utils

Licence: MIT license
Utilities for converting Autodesk Forge file formats.

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language
shell
77523 projects

Projects that are alternatives of or similar to forge-convert-utils

Sharpgltf
glTF reader and writer for .NET Standard
Stars: ✭ 159 (+91.57%)
Mutual labels:  gltf
Maya2gltf
Maya to glTF 2.0 exporter
Stars: ✭ 203 (+144.58%)
Mutual labels:  gltf
vim-webgl-viewer
An easy to use online 3D model viewer based on Three.JS.
Stars: ✭ 41 (-50.6%)
Mutual labels:  gltf
Gltf Transform
glTF 2.0 SDK for JavaScript, TypeScript, and Node.js.
Stars: ✭ 174 (+109.64%)
Mutual labels:  gltf
Claygl
A WebGL graphic library for building scalable Web3D applications
Stars: ✭ 2,365 (+2749.4%)
Mutual labels:  gltf
Tinygltfloader
Header only C++ Tiny glTF loader.
Stars: ✭ 223 (+168.67%)
Mutual labels:  gltf
Dem.net
Digital Elevation model library in C#. 3D terrain models, line/point Elevations, intervisibility reports
Stars: ✭ 153 (+84.34%)
Mutual labels:  gltf
maya-glTF
glTF 2.0 exporter for Autodesk Maya
Stars: ✭ 121 (+45.78%)
Mutual labels:  gltf
Stereokit
An easy-to-use mixed reality library for building HoloLens and VR applications with C# and OpenXR!
Stars: ✭ 195 (+134.94%)
Mutual labels:  gltf
Model Viewer
Easily display interactive 3D models on the web and in AR!
Stars: ✭ 3,751 (+4419.28%)
Mutual labels:  gltf
Gltf2usd
command-line utility for converting glTF 2.0 models to USD
Stars: ✭ 182 (+119.28%)
Mutual labels:  gltf
Mayo
3D CAD viewer and converter based on Qt + OpenCascade
Stars: ✭ 192 (+131.33%)
Mutual labels:  gltf
Gltf
A crate for loading glTF 2.0
Stars: ✭ 224 (+169.88%)
Mutual labels:  gltf
Gltf To Usdz Research
Research and proof of concept of converting glTF to USDZ for AR Quick Look (iOS 12+).
Stars: ✭ 164 (+97.59%)
Mutual labels:  gltf
bus derby
A 3D vehicle derby video game rendered in three.js and run on a physi.js physics engine. UV maps designed in Adobe Illustrator; meshes created in Blender and imported as glTF.
Stars: ✭ 88 (+6.02%)
Mutual labels:  gltf
Gltfast
glTF runtime loading library for Unity
Stars: ✭ 156 (+87.95%)
Mutual labels:  gltf
Meshoptimizer
Mesh optimization library that makes meshes smaller and faster to render
Stars: ✭ 2,930 (+3430.12%)
Mutual labels:  gltf
libgltf
glTF 2.0 parser/loader for C++11, supports many extensions likes `KHR_draco_mesh_compression`, `KHR_lights_punctual`, `KHR_materials_clearcoat`, and more.
Stars: ✭ 55 (-33.73%)
Mutual labels:  gltf
home-space
Startpage and WebXR home
Stars: ✭ 43 (-48.19%)
Mutual labels:  gltf
Wickedengine
3D engine focusing on modern rendering techniques and performance.
Stars: ✭ 3,148 (+3692.77%)
Mutual labels:  gltf

forge-convert-utils

Publish to NPM npm version node npm downloads platforms license

Forge & glTF logos

Utilities for converting Autodesk Forge SVF file format into glTF 2.0.

Check out forge-convert-sqlite with an experimental serialization/deserialization of glTF to/from sqlite.

Usage

Command line

  • install the package: npm install --global forge-convert-utils
  • run the forge-convert command without parameters for usage info
  • run the command with a path to a local SVF file
  • run the command with a Model Derivative URN (and optionally viewable GUID)
    • to access Forge you must also specify credentials (FORGE_CLIENT_ID and FORGE_CLIENT_SECRET) or an authentication token (FORGE_ACCESS_TOKEN) as env. variables
    • this will also download the property database in sqlite format
  • optionally, use any combination of the following command line args:
    • --output-folder <folder> to change output folder (by default '.')
    • --deduplicate to try and remove duplicate geometries
    • --skip-unused-uvs to skip texture UVs that are not used by any material
    • --ignore-meshes to exclude mesh geometry from the output
    • --ignore-lines to exclude line geometry from the output
    • --ignore-points to exclude point geometry from the output
    • --center move the model to origin

Unix/macOS

forge-convert <path to local svf> --output-folder <path to output folder>

or

export FORGE_CLIENT_ID=<client id>
export FORGE_CLIENT_SECRET=<client secret>
forge-convert <urn> --output-folder <path to output folder>

or

export FORGE_ACCESS_TOKEN=<access token>>
forge-convert <urn> --output-folder <path to output folder>

Windows

forge-convert <path to local svf> --output-folder <path to output folder>

or

set FORGE_CLIENT_ID=<client id>
set FORGE_CLIENT_SECRET=<client secret>
forge-convert <urn> --output-folder <path to output folder>

or

set FORGE_ACCESS_TOKEN=<access token>
forge-convert <urn> --output-folder <path to output folder>

Node.js

The library can be used at different levels of granularity.

The easiest way to convert an SVF file is to read the entire model into memory using SvfReader#read method, and save the model into glTF using GltfWriter#write:

const path = require('path');
const { ModelDerivativeClient, ManifestHelper } = require('forge-server-utils');
const { SvfReader, GltfWriter } = require('forge-convert-utils');

const { FORGE_CLIENT_ID, FORGE_CLIENT_SECRET } = process.env;

async function run(urn, outputDir) {
    const auth = { client_id: FORGE_CLIENT_ID, client_secret: FORGE_CLIENT_SECRET };
    const modelDerivativeClient = new ModelDerivativeClient(auth);
    const manifestHelper = new ManifestHelper(await modelDerivativeClient.getManifest(urn));
    const derivatives = manifestHelper.search({ type: 'resource', role: 'graphics' });
    const readerOptions = {
        log: console.log
    };
    const writerOptions = {
        deduplicate: true,
        skipUnusedUvs: true,
        center: true,
        log: console.log,
        filter: (dbid) => (dbid >= 100 && dbid <= 200) // only output objects with dbIDs between 100 and 200
    };
    const writer = new GltfWriter(writerOptions);
    for (const derivative of derivatives.filter(d => d.mime === 'application/autodesk-svf')) {
        const reader = await SvfReader.FromDerivativeService(urn, derivative.guid, auth);
        const scene = await reader.read(readerOptions);
        await writer.write(scene, path.join(outputDir, derivative.guid));
    }
}

run('your model urn', 'path/to/output/folder');

If you don't want to read the entire model into memory (for example, when distributing the parsing of an SVF over multiple servers), you can use methods like SvfReader#enumerateFragments or SvfReader#enumerateGeometries to asynchronously iterate over individual elements:

const { ModelDerivativeClient, ManifestHelper } = require('forge-server-utils');
const { SvfReader } = require('forge-convert-utils');

const { FORGE_CLIENT_ID, FORGE_CLIENT_SECRET } = process.env;

async function run (urn) {
    const auth = { client_id: FORGE_CLIENT_ID, client_secret: FORGE_CLIENT_SECRET };
    const modelDerivativeClient = new ModelDerivativeClient(auth);
    const manifestHelper = new ManifestHelper(await modelDerivativeClient.getManifest(urn));
    const derivatives = manifestHelper.search({ type: 'resource', role: 'graphics' });
    for (const derivative of derivatives.filter(d => d.mime === 'application/autodesk-svf')) {
        const reader = await SvfReader.FromDerivativeService(urn, derivative.guid, auth);
        for await (const fragment of reader.enumerateFragments()) {
            console.log(fragment);
        }
    }
}

run('your model urn');

And finally, if you already have the individual SVF assets in memory, you can parse the binary data directly using synchronous iterators like parseMeshes:

const { parseMeshes } = require('forge-convert-utils/lib/svf/meshes');
for (const mesh of parseMeshes(buffer)) {
    console.log(mesh);
}

For additional examples, see the test subfolder.

Customization

You can customize the translation by sub-classing the reader and/or the writer class. For example:

  • The samples/custom-gltf-attribute.js script adds the dbID of each SVF node as a new attribute in its mesh
  • The samples/filter-by-area.js script only outputs geometries that are completely contained within a specified area

Metadata

When converting models from Model Derivative service, you can retrieve the model's properties and metadata in form of a sqlite database. The command line tool downloads this database automatically as properties.sqlite file directly in your output folder. If you're using this library in your own Node.js code, you can find the database in the manifest by looking for an asset with type "resource", and role "Autodesk.CloudPlatform.PropertyDatabase":

    ...
    const pdbDerivatives = manifestHelper.search({ type: 'resource', role: 'Autodesk.CloudPlatform.PropertyDatabase' });
    if (pdbDerivatives.length > 0) {
        const databaseStream = modelDerivativeClient.getDerivativeChunked(urn, pdbDerivatives[0].urn, 1 << 20);
        databaseStream.pipe(fs.createWriteStream('./properties.sdb'));
    }
    ...

The structure of the sqlite database, and the way to extract model properties from it is explained in https://github.com/wallabyway/propertyServer/blob/master/pipeline.md. Here's a simple diagram showing the individual tables in the database, and the relationships between them:

Property Database Diagram

And here's an example query listing all objects with "Material" property containing the "Concrete" word:

SELECT _objects_id.id AS dbId, _objects_id.external_id AS externalId, _objects_attr.name AS propName, _objects_val.value AS propValue
FROM _objects_eav
    INNER JOIN _objects_id ON _objects_eav.entity_id = _objects_id.id
    INNER JOIN _objects_attr ON _objects_eav.attribute_id = _objects_attr.id
    INNER JOIN _objects_val ON _objects_eav.value_id = _objects_val.id
WHERE propName = "Material" AND propValue LIKE "%Concrete%"

GLB, Draco, and other post-processing

Following the Unix philosophy, we removed post-processing dependencies from this project, and instead leave it to developers to "pipe" the output of this library to other tools such as https://github.com/CesiumGS/gltf-pipeline or https://github.com/zeux/meshoptimizer. See ./samples/local-svf-to-gltf.sh or ./samples/remote-svf-to-gltf.sh for examples.

Development

  • clone the repository
  • install dependencies: yarn install
  • build the library (transpile TypeScript): yarn run build
  • run samples in the test subfolder, for example: FORGE_CLIENT_ID=<your client id> FORGE_CLIENT_SECRET=<your client secret> node test/remote-svf-to-gltf.js <model urn> <path to output folder>

If you're using Visual Studio Code, you can use the following "task" and "launch" configurations:

In .vscode/tasks.json:

...
{
    "label": "build",
    "type": "npm",
    "script": "build",
    "problemMatcher": [
        "$tsc"
    ],
    "group": "build",
    "presentation": {
        "echo": true,
        "reveal": "silent",
        "focus": false,
        "panel": "shared",
        "showReuseMessage": false,
        "clear": false
    }
}
...

In .vscode/launch.json:

...
{
    "type": "node",
    "request": "launch",
    "name": "Convert Model Derivative SVF to glTF",
    "program": "${workspaceFolder}/test/remote-svf-to-gltf.js",
    "args": ["<your model urn>", "<path to output folder>"],
    "env": {
        "FORGE_CLIENT_ID": "<your client id>",
        "FORGE_CLIENT_SECRET": "<your client secret>"
    },
    "preLaunchTask": "build"
},
{
    "type": "node",
    "request": "launch",
    "name": "Convert Local SVF to glTF",
    "program": "${workspaceFolder}/test/local-svf-to-gltf.js",
    "args": ["<path to svf file>", "<path to output folder>"],
    "preLaunchTask": "build"
}
...

Intermediate Format

The project provides a collection of interfaces for an intermediate 3D format that is meant to be used by all loaders and writers. When implementing a new loader, make sure that its output implements the intermediate format's IScene interface. Similarly, this interface should also be expected as the input to all new writers.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].