Detalhes do pacote

forge-convert-utils

petrbroz25kMIT4.0.5

Tools for converting Autodesk Forge file formats.

autodesk, forge, gltf, typescript

readme (leia-me)

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.

changelog (log de mudanças)

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

[4.0.5] - 2023-09-29

  • Added
    • SVF materials that are not referenced by anything are excluded from the glTF output

[4.0.4] - 2023-08-08

  • Added
    • Support for gltf output filtering based on fragment IDs.
    • Support for svf input filtering based on dbID or fragment ID.

[4.0.3] - 2023-06-28

  • Fixed
    • Solved an issue with glTF geometry being broken in certain scenarios (kudos to henrikbuchholz!)

[4.0.2] - 2023-03-10

  • Added
    • Support for custom serialization of the glTF manifest
  • Fixed

[4.0.1] - 2022-03-24

  • Fixed
    • Deduplication of geometries now using maps instead of arrays, bringing dramatic speed improvements (kudos to VFedyk!)

[4.0.0] - 2022-03-24

  • Removed
    • Support for the (experimental) OTG format download and parsing

[3.6.3] - 2022-01-20

  • Fixed
    • Conversion of SVF 3x3 matrix + translation into glTF 4x4 matrix

[3.6.2] - 2021-11-04

  • Fixed
    • Failing TypeScript build due to changes in adm-zip dependency

[3.6.1] - 2021-11-04

  • Fixed
    • Updated dependencies
    • Added URL-encoding when downloading SVF viewables

[3.6.0] - 2021-02-04

  • Added
    • Re-introduced code docs generator
  • Fixed
    • Updated dependencies
  • Changed
    • CI/CD now in Github Actions

[3.5.2] - 2021-01-04

  • Fixed
    • Downloading of SVF assets with special characters (kudos thejakobn)
    • Parsing textures with custom scale (kudos thejakobn)
    • Bug when parsing props with undefined category

[3.5.1] - 2020-11-20

  • Added
    • New version of forge-server-utils
    • Support for chunked download of Model Derivative assets

[3.5.0] - 2020-03-30

  • Added
    • Mapping SVF/OTG glossiness to glTF roughness (need to confirm that the mapping is correct)

[3.4.5] - 2020-03-26

  • Fixed
    • SVF parser property db config from 3.4.4

[3.4.4] - 2020-03-26

  • Added
    • SVF parser can now be configured to skip property DB

[3.4.3] - 2020-03-25

  • Fixed
    • Travis config

[3.4.1] - 2020-03-25

  • Added
    • SVF downloader can now be initialized with custom host URL and region
    • SVF parser can now be initialized with custom host URL and region
  • Removed
    • Docs generator (due to audit warnings and lack of updates); will continue generating the docs manually.

[3.4.0] - 2020-03-24

  • Added
    • Support for meshes with vertex colors

[3.3.1] - 2020-03-17

  • Fixed
    • Npm dependency vulnerability

[3.3.0] - 2020-03-13

  • Added
    • F2D downloader
  • Changed
    • SVF/OTG/F2D downloaders can now accept existing auth tokens
    • SVF/OTG/F2D downloaders can now be configured to ignore missing assets

[3.2.0] - 2020-03-13

  • Added
    • SVF and OTG downloader classes

[3.1.2] - 2020-03-12

  • Fixed
    • When converting to gltf, empty textures or images are removed to prevent validation errors (thanks @AlexPiro!)
  • Added
    • Dev utility for validating gltf manifests (to be used in CI/CD)

[3.1.1] - 2020-02-25

  • Fixed
    • Alpha blending only enabled when opacity is less than 1.0 (#21)

[3.1.0] - 2020-01-15

  • Added
    • [experimental] OTG parser
  • Fixed

[3.0.0] - 2020-01-07

  • Changed
    • Updated to TypeScript version 3.7
    • [BREAKING CHANGE] loaders/writers now load/write a centralized intermediate file format
  • Fixed
    • Extended fix from version 2.0.1: 1x1 black pixel images now used also when materials reference non-existent texture URIs

[2.0.1] - 2019-12-20

  • Fixed
    • Missing SVF textures no longer cause the conversion to fail, and are instead replaced with 1x1 black pixel images

[2.0.0] - 2019-12-17

  • Changed
    • [BREAKING CHANGE] removed post-processing options (Draco compression and binary output)

[1.2.1] - 2019-12-13

  • Added
    • Scaling the output model based on SVF distance units (added by @dykarohora)
  • Fixed
    • Sanitizing URNs (removing trailing '='s)

[1.2.0] - 2019-12-10

  • Fixed
    • Missing folders when post-processing (#11, fixed by @AlexPiro)
  • Added
    • Filtering of objects to be included in the output glTF

[1.1.2] - 2019-11-30

  • Fixed
    • Multi-byte characters in derivative URNs (thanks @dykarohora!)

[1.1.1] - 2019-11-13

  • Changed
    • When exporting to glTF+Draco, resources are no longer embedded into the manifest (#7)

[1.1.0] - 2019-11-08

  • Added
    • Opt-in feature to move the model to origin
  • Changed
    • Forge models are now reoriented based on their metadata to align with the glTF coordinate system (X=left, Y=up, Z=front)

Note: scene hierarchies in the generated glTFs now contain two additional levels: all scene objects are grouped into an xform node that applies additional transformations (for example, moving the model to origin), and the xform node is a child of a root node which transforms the entire scene to the glTF coordinate system.

[1.0.2] - 2019-11-01

[1.0.1] - 2019-10-31

  • Fixed
    • Calls to GltfWriter.prototype.write now await postprocessing (if there's any)

[1.0.0] - 2019-10-31

  • Changed
    • [BREAKING] gltf/glb is now written with a single call (await writer.write(svf, outputDir))
  • Removed
    • debug dependency (using console.log instead)

[0.8.0] - 2019-10-29

  • Added
    • The sqlite flag now generates a sqlite manifest with both the glTF data and the property database
    • When deserializing sqlite back to glTF, you can now pass in a filter of dbids
      • The filter can be either a SELECT dbid FROM properties WHERE ..., or a list of dbids
  • Fixed
    • Iterating of object properties
  • Changed
    • Adding multiple SVFs into single glTF is now considered unsupported
      • Trying to do so will cause an exception in the GltfWriter.write method

[0.7.2] - 2019-10-25

  • Added
    • deserialization of sqlite manifest back to glTF

[0.7.1] - 2019-10-24

  • Fixed
    • glTF deduplication (incl. performance improvement)
    • sqlite serialization when ignoring mesh, line, or point geometries

[0.7.0] - 2019-10-24

  • Added
    • More deduplication, now also on the glTF accessor and mesh level
    • Additional CLI options for ignoring mesh, line, or point geometry
    • (experimental) serialization of glTF manifest into sqlite
      • Can only be used when texture/buffer data is referenced and not embedded
      • Potentially could be used for dynamically generating glTF variants with subsets of the original model
      • Additional CLI option for serializing glTF manifest into sqlite
      • Note that the schema of the sqlite database might change

[0.6.4] - 2019-10-22

  • Added
    • Skipping texture UVs when there's no material using them
  • Fixed
    • Computing position bounds

[0.6.3] - 2019-10-17

  • Changed
    • Geometry deduplication now on BufferView (instead of Mesh) level
    • Sample scripts now using proper error catching

[0.6.2] - 2019-10-17

  • Added
    • Opt-in deduplication of materials
  • Fixed
    • Caching of meshes

[0.6.1] - 2019-10-14

  • Added
    • Progress logging when parsing SVF and writing glTF
  • Fixed
    • Typo in reference to package.json in CLI tool
    • Typo in CLI when accessing Forge credentials

[0.6.0] - 2019-10-11

  • Added
    • Opt-in deduplication of exported geometries
    • Opt-in output to GLB
    • Opt-in output with Draco compression
  • Fixed
    • Normalizing windows/posix paths of SVF assets

[0.5.0] - 2019-10-08

  • Added
    • Listing IDs of object children from SVF property database
  • Changed
    • Excluding internal attributes when parsing SVF property database

[0.4.1] - 2019-10-07

  • Added
    • Access to internal SVF manifest
  • Fixed
    • Gltf schema now included in build output

[0.4.0] - 2019-10-07

  • Added
    • Support for converting both remote and local SVFs using the CLI tool
    • Support for configuring glTF output (max. size of binary files, ignoring line/point geometries, ...)
    • Outputting multiple scenes in one glTF
  • Changed
    • Moved to new version of forge-server-utils

[0.3.0] - 2019-10-07

  • Added
    • TypeScript definition files with glTF and SVF schemas
  • Changed
    • Code restructure
    • SVF parsing code moved from forge-server-utils back here

[0.2.1] - 2019-10-04

  • Fixed
    • Images now extracted with both lower-cased and unmodified URIs

[0.2.0] - 2019-10-03

  • Added
    • Support for line/point geometry, incl. colors

[0.1.0] - 2019-10-03

  • Added
    • Parsing individual SVF assets in parallel
    • CI/CD pipeline setup
    • Support for basic material textures (texture transforms not yet supported)
  • Changed
    • Moved to TypeScript for additional type security, incl. official typings for the glTF 2.0 schema
    • Moved to yarn
    • Reusing SVF parser from forge-server-utils module
  • Fixed
    • Crash when no materials are available

[0.0.2] - 2019-09-24

  • Fixed
    • CLI script

[0.0.1] - 2019-09-20

  • First release