Project > Exchange
Geometry Exporter
Exports the selected objects' own triangles with their colours to glTF (.glb), OBJ, STL or DXF 3D faces, adding IDs and chosen properties in glTF. Big selections are budgeted and anything skipped is listed.
Status
Untested Never executed inside Navisworks. Passed the headless checks only.
The public ask
I am trying to export the vertices, faces and colors of a selected object in the Navis.
Stack Overflow, 2015-07. Open the source
Events it listens to
None. It runs only when you click it.
Files
Paths are relative to the Playground.extension folder.
Project.tab/Exchange.panel/Geometry_Exporter.pushbutton/bundle.yamlProject.tab/Exchange.panel/Geometry_Exporter.pushbutton/icon.dark.pngProject.tab/Exchange.panel/Geometry_Exporter.pushbutton/icon.pngProject.tab/Exchange.panel/Geometry_Exporter.pushbutton/icon.small.dark.pngProject.tab/Exchange.panel/Geometry_Exporter.pushbutton/icon.small.pngProject.tab/Exchange.panel/Geometry_Exporter.pushbutton/script.py
Install
- Only this tool. In Navisworks, click pyNavis > Playground, search for Geometry Exporter, tick it and click Install.
- The whole extension. Download
Playground.extension.zip, unzip it, put thePlayground.extensionfolder in%APPDATA%\pyNavis\extensions\, and click pyNavis > Reload. Geometry Exporter is on the Project tab, Exchange panel.
You need pyNavis 1.3.0 or later.
Tried it? Tell us whether it worked or not. That report is what moves a tool up the status ladder.
ReportSource
The tool's own files, word for word as published in pynavis/Playground. Paths are relative to the Playground.extension folder.
script.py
The script that runs on a click.
Project.tab/Exchange.panel/Geometry_Exporter.pushbutton/script.py View on GitHub# -*- coding: utf-8 -*-
"""Exports the selected objects' triangles to glTF (.glb), OBJ, STL or DXF 3D faces."""
import os
from pynavis import doc as nwdoc
from pynavis import script, toast
from namo import items, meshexport, paths, progress, ui, xchg_common
NAME_TEMPLATE = '{file} - Geometry - {date}'
def property_options(selected):
"""Chooser options for the property names on the first objects of the selection."""
try:
sample = items.objects(selected, budget=150)
names = items.sample_properties(sample, limit=150)
except Exception:
return []
return [meshexport.property_option(cat, prop) for cat, prop, _n in names][:400]
def run():
if xchg_common.under_runner():
return
document = nwdoc.get_doc()
selected = items.selected(document)
if not selected:
toast.info('Nothing selected', 'Select the objects to export, then run Geometry Exporter again.')
return
doc_units = str(document.Units)
values = dict(meshexport.DEFAULT_OPTIONS)
values.update(script.get_config(meshexport.DEFAULT_OPTIONS))
fields = meshexport.form_fields(values, doc_units, property_options(selected))
answer = ui.form('Geometry exporter', fields, ok='Export', width=560)
if answer is None:
return
values.update(answer)
script.save_config(dict((k, values[k]) for k in meshexport.DEFAULT_OPTIONS))
fmt = values['format']
ext = meshexport.EXTENSIONS[fmt]
path = xchg_common.ask_save(document, NAME_TEMPLATE, ext, meshexport.FILTERS[fmt], 'Export geometry')
if path is None:
return
pairs = meshexport.property_pairs(values.get('properties'))
title = xchg_common.doc_title(document)
y_up = fmt == 'glb' or (fmt == 'obj' and values['obj_y_up'])
def work(report):
read = meshexport.read_objects(selected, per_object=values['per_object'], total=values['total'],
progress=lambda f, label: report(f * 0.85, label),
identity=values['identity'] and fmt == 'glb',
property_pairs=pairs if fmt == 'glb' else None, doc_units=doc_units)
records = read['records']
if not records:
return read, [], [], []
shift = meshexport.local_origin(meshexport.union_box(records), doc_units) if values['shift'] else None
report(0.87, 'Preparing %s objects' % '{:,}'.format(len(records)))
meshes, dropped = meshexport.build_meshes(records, fmt, doc_units, shift, values['units'],
values['obj_y_up'])
_scale, word = meshexport.target_units(fmt, values['units'], doc_units)
header = ['Source: %s' % title, 'Units: %s' % word, 'Up axis: %s' % ('Y' if y_up else 'Z')]
extras = {'source': title, 'units': 'metres', 'up': 'Y', 'model_units': doc_units}
if shift:
header.append('Local origin subtracted (model units): %s' % ', '.join(
meshexport.num_text(v, 12) for v in shift))
extras['local_origin_model_units'] = list(shift)
report(0.94, 'Writing %s' % os.path.basename(path))
written = meshexport.write_files(path, fmt, meshes, title=title, extras=extras,
layer_by=values['layers'], header_lines=header)
if shift:
note = meshexport.offset_note(shift, doc_units, fmt, word, title, axes_y_up=y_up)
written.append(paths.atomic_write_text(meshexport.sidecar_path(path), note))
report(1.0, 'Done')
return read, meshes, dropped, written
try:
outcome = progress.run('Exporting geometry', work)
except (IOError, OSError) as error:
toast.error('Could not write the file', '%s. Close it in any program that has it open, then try again.' % error)
return
if outcome is progress.CANCELLED:
return
read, meshes, dropped, written = outcome
xchg_common.show_skipped('Geometry exporter', read['skipped'], dropped)
level, message, detail = meshexport.summary(meshes, read['skipped'], dropped, fmt, read['sampled'])
if written:
# Say where the file is whatever else there is to say, and show it in Explorer.
detail = written[0] if level == 'success' else xchg_common.where_text(detail, written[0])
toast.show(level, message, detail)
if written:
xchg_common.reveal(written[0])
run()
Library modules this tool uses
From the shared namo library, which installs with every tool. Each name opens the module on GitHub.
namo.itemsModel items: walking, collecting, identifying, measuring and showing them.namo.meshexportGeometry out of Navisworks: glTF 2.0 binary (.glb), OBJ + MTL, binary STL and DXF 3D faces, from the selected objects' own triangles.namo.pathsWhere Playground keeps its files, and how it writes them safely.namo.progressGlue between pyNavis' cancellable progress window and Playground's progress callbacks.namo.uiWPF building blocks for Playground tools, themed from the pyNavis design system.namo.xchg_commonSmall pieces the Geometry and IFC exporters share: where files go, default names, and the list of skipped objects in the output window.
bundle.yaml
The bundle contract: the keys pyNavis reads for this tool.
Project.tab/Exchange.panel/Geometry_Exporter.pushbutton/bundle.yaml View on GitHubtitle: Geometry\nExporter
tooltip: Exports the selected objects' own triangles with their colours to glTF (.glb), OBJ, STL or DXF 3D faces, adding IDs and chosen properties in glTF. Big selections are budgeted and anything skipped is listed.
context: selection