Views > Navigate
Level Sectioner
Cuts the model at the level you choose: a section plane at the cut height above the floor, optionally the floors below hidden and a plan view. Levels come from the grid system or are estimated from the model. Shift+Click for settings.
Status
Launched Ran inside Navisworks at least once with no error logged; nobody checked the result yet.
NameError fixed 2026-10-09; reran headless. The sample model has no levels, so the rerun took the 'No levels found' exit; the fixed chooser path is pinned by a smoke test, not yet clicked in Navisworks.
The public ask
No public source is on record for this tool.
Events it listens to
None. It runs only when you click it.
Files
Paths are relative to the Playground.extension folder.
Views.tab/Navigate.panel/Level_Sectioner.pushbutton/bundle.yamlViews.tab/Navigate.panel/Level_Sectioner.pushbutton/config.pyViews.tab/Navigate.panel/Level_Sectioner.pushbutton/icon.dark.pngViews.tab/Navigate.panel/Level_Sectioner.pushbutton/icon.pngViews.tab/Navigate.panel/Level_Sectioner.pushbutton/icon.small.dark.pngViews.tab/Navigate.panel/Level_Sectioner.pushbutton/icon.small.pngViews.tab/Navigate.panel/Level_Sectioner.pushbutton/script.py
Install
- Only this tool. In Navisworks, click pyNavis > Playground, search for Level Sectioner, 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. Level Sectioner is on the Views tab, Navigate 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.
Views.tab/Navigate.panel/Level_Sectioner.pushbutton/script.py View on GitHub"""Sections the view at the level you choose: cut above the floor, optional slab view and plan camera."""
from namo import levels, progress, ui, vp_common
from pynavis import toast
TITLE = 'Level Sectioner'
def run():
document = vp_common.active_doc()
if not vp_common.has_models(document):
toast.info('No model open', 'Open or append a model, then run Level Sectioner again.')
return
found = levels.cached_or_none(document)
if found is None:
found = progress.run(TITLE, lambda report: levels.find(document, report), 'Looking for levels')
if found is progress.CANCELLED:
return
if not found:
toast.info('No levels found', 'Add a grid system with levels (Grids and Levels), or open a model '
'whose objects carry a Level property.')
return
units = str(document.Units)
cfg = levels.load_settings()
current = levels.current_index(found, document, cfg)
rows = [{'value': i, 'cells': [lv['name'], vp_common.length_text(lv['elevation'], units),
'Estimated' if lv.get('approximate') else 'Grid']}
for i, lv in enumerate(found)]
k = 1.0 / vp_common.to_meters_factor(units)
prompt = 'Cut %s above the level%s%s. Shift+Click changes these.' % (
vp_common.length_text(cfg['cut_height_m'] * k, units),
', floors below hidden' if cfg['slab'] else '', ', plan view' if cfg['plan'] else '')
picked = ui.choose(TITLE, rows, ['Level', 'Elevation', 'Source'], multiselect=False,
checked=[current] if current is not None else None, prompt=prompt, ok='Section')
if picked is None:
return
lv = found[picked[0]]
levels.apply(lv, document, cfg)
cut = lv['elevation'] + cfg['cut_height_m'] * k
detail = 'Cut at %s.' % vp_common.length_text(cut, units)
if lv.get('approximate'):
detail += ' ' + levels.source_note(found)
detail += ' Alt+PgUp and Alt+PgDn step between levels.'
toast.success('Section at %s' % lv['name'], detail)
run()
config.py
The Shift+Click action.
Views.tab/Navigate.panel/Level_Sectioner.pushbutton/config.py View on GitHub"""Sets the cut height, the slab view and the plan camera shared by Level Sectioner, Level Up and Level Down."""
from namo import levels, ui, vp_common
from pynavis import toast
document = vp_common.active_doc()
units = str(document.Units) if document is not None else 'Meters'
cfg = levels.load_settings()
values = ui.form('Level Sectioner settings', levels.settings_fields(cfg, units), ok='Save', units=units)
if values is not None: # None means cancelled: say nothing
m = vp_common.to_meters_factor(units)
cfg.update({'cut_height_m': values['cut'] * m, 'slab': values['slab'], 'plan': values['plan']})
if values.get('depth') is not None:
cfg['slab_depth_m'] = values['depth'] * m
try:
levels.save_settings(cfg)
except (IOError, OSError) as error:
toast.error('Could not save the settings', str(error))
else:
toast.success('Saved', 'Cut %s above the level. Level Up and Level Down use it too.'
% vp_common.length_text(values['cut'], units))
Library modules this tool uses
From the shared namo library, which installs with every tool. Each name opens the module on GitHub.
namo.levelsLevels of the model, and sectioning the view at one of them.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.vp_commonShared helpers for the Views tools (Viewpoints, Capture and Navigate panels).
bundle.yaml
The bundle contract: the keys pyNavis reads for this tool.
Views.tab/Navigate.panel/Level_Sectioner.pushbutton/bundle.yaml View on GitHubtitle: Level\nSectioner
tooltip: Cuts the model at the level you choose: a section plane at the cut height above the floor, optionally the floors below hidden and a plan view. Levels come from the grid system or are estimated from the model. Shift+Click for settings.
context: doc