Coordinate > Clash Reports
Snapshot
Records the current results of the chosen clash tests as a snapshot that Clash Delta and Clash Trends compare with. Shift+Click to snapshot automatically on save, or to delete old snapshots.
Status
Untested Never executed inside Navisworks. Passed the headless checks only.
The public ask
No public source is on record for this tool.
Installs with
Snapshot sits in a stack, so installing it also installs:
Events it listens to
It needs these Navisworks event hooks, so installing it also copies the shared hooks folder:
doc-saved
Files
Paths are relative to the Playground.extension folder.
Coordinate.tab/Clash_Reports.panel/History.stack/Snapshot_Clashes.pushbutton/bundle.yamlCoordinate.tab/Clash_Reports.panel/History.stack/Snapshot_Clashes.pushbutton/config.pyCoordinate.tab/Clash_Reports.panel/History.stack/Snapshot_Clashes.pushbutton/icon.dark.pngCoordinate.tab/Clash_Reports.panel/History.stack/Snapshot_Clashes.pushbutton/icon.pngCoordinate.tab/Clash_Reports.panel/History.stack/Snapshot_Clashes.pushbutton/icon.small.dark.pngCoordinate.tab/Clash_Reports.panel/History.stack/Snapshot_Clashes.pushbutton/icon.small.pngCoordinate.tab/Clash_Reports.panel/History.stack/Snapshot_Clashes.pushbutton/script.py
Install
- Only this tool. In Navisworks, click pyNavis > Playground, search for Snapshot, 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. Snapshot is on the Coordinate tab, Clash Reports 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.
Coordinate.tab/Clash_Reports.panel/History.stack/Snapshot_Clashes.pushbutton/script.py View on GitHub# -*- coding: utf-8 -*-
"""Records the current results of the chosen clash tests as a snapshot for Clash Delta and Clash Trends."""
from pynavis import forms, script, toast
from namo import clashrep_forms as cf
from namo import clashrep_history as hist
from namo import clashreport as cr
from namo import progress
TITLE = 'Clash Snapshot'
DEFAULTS = {'tests': []}
def run():
values = script.get_config(DEFAULTS)
doc = cr.active_doc()
problem = cf.start(doc)
if problem:
toast.show(*problem)
return
if not cr.file_info(doc)[0]:
toast.info('Save the model first', 'Clash snapshots are kept per model file.')
return
if cf.runner_active():
tests, _missing = cr.resolve_tests(values['tests'], doc)
label = ''
else:
tests = cf.pick_tests(TITLE, 'Tick the tests to record.', values['tests'], doc)
if tests is None:
return
if not tests:
toast.info('No clash results yet', 'Run your clash tests in Clash Detective first.')
return
label = forms.ask_string('Label for this snapshot (optional, for example "Before the 12 Oct meeting"):',
'', TITLE)
if label is None:
return
values['tests'] = cf.test_paths(tests)
script.save_config(values)
if not tests:
toast.info('No clash results yet', 'Run your clash tests in Clash Detective first.')
return
try:
outcome = progress.run('Recording clashes', lambda report: cr.record_snapshot(tests, label, doc, report))
except RuntimeError as error:
toast.error('Could not read the clashes', str(error))
return
except (IOError, OSError) as error:
toast.error('Could not save the snapshot', str(error))
return
if outcome is progress.CANCELLED:
return
entry, where = outcome
toast.success(*hist.snapshot_message(entry, where))
run()
config.py
The Shift+Click action.
Coordinate.tab/Clash_Reports.panel/History.stack/Snapshot_Clashes.pushbutton/config.py View on GitHub# -*- coding: utf-8 -*-
"""Options for clash snapshots: take one automatically on save, or delete old ones."""
from pynavis import forms, settings, toast
from namo import clashrep_forms as cf
from namo import clashrep_history as hist
from namo import clashreport as cr
from namo import config as namo_config
from namo import hk_clashhistory as auto
from namo import ui
TITLE = 'Clash snapshots'
AUTOMATIC = 'Snapshot automatically when the model is saved'
REVIEW = 'Review and delete snapshots of this model'
def automatic():
values = auto.load_config()
names = []
try:
from namo import clashdata
names = clashdata.unique_names([t.DisplayName for t in cr.tests_with_results()])
except Exception:
names = []
fields = cf.snapshot_settings_fields(values, names, namo_config.get('data_mode'))
answers = ui.form(TITLE, fields, ok='Save', width=540)
if answers is None:
return
values['auto_on_save'] = bool(answers['auto_on_save'])
if answers.get('min_hours') is not None:
values['min_hours'] = float(answers['min_hours'])
if answers.get('max_results') is not None:
values['max_results'] = int(answers['max_results'])
if 'tests' in answers:
values['tests'] = list(answers['tests'] or [])
try:
settings.save(auto.TOOL, values)
except (IOError, OSError) as error:
toast.error('Could not save the snapshot options', str(error))
return
if values['auto_on_save']:
toast.success('Automatic clash snapshots are on',
'At most one every %s hours, when the clash counts changed, up to %s results.'
% ('%g' % values['min_hours'], '{:,}'.format(values['max_results'])))
else:
toast.success('Automatic clash snapshots are off', 'Use Snapshot to record one by hand.')
def review():
from namo import clashdata
doc_path = cr.file_info()[0]
if not doc_path:
toast.info('Save the model first', 'Clash snapshots are kept per model file.')
return
entries = sorted(clashdata.list_history(doc_path), key=lambda e: (e.get('time') or '', e.get('id') or ''),
reverse=True)
if not entries:
toast.info('No clash snapshots yet', 'Use Snapshot to record one.')
return
rows = []
for entry in entries:
when = hist.entry_time(entry)
totals = hist.entry_totals(entry)
rows.append({'value': entry['id'], 'cells': [when.strftime('%Y-%m-%d %H:%M') if when else '',
entry.get('label') or '', totals['tests'], totals['total'],
totals['open']]})
picked = ui.choose(TITLE, rows, ['Taken', 'Label', 'Tests', 'Clashes', 'Open'], multiselect=True,
prompt='Tick the snapshots to delete. Clash Delta and Clash Trends will no longer see them.',
ok='Delete', width=720)
if picked is None:
return
if not picked:
toast.info('No snapshots ticked', 'Nothing was deleted.')
return
if not forms.confirm('Delete %s? This cannot be undone.' % cr.plural(len(picked), 'snapshot'), TITLE):
return
deleted = 0
try:
for history_id in picked:
if clashdata.delete_history(doc_path, history_id):
deleted += 1
except (IOError, OSError) as error:
toast.error('Could not delete every snapshot', str(error))
return
toast.success('Deleted %s' % cr.plural(deleted, 'snapshot'),
'%s left for this model.' % '{:,}'.format(len(entries) - deleted))
if cf.runner_active():
toast.warning('These options need a window, so they cannot run under pynavis run',
'Shift+Click Snapshot on the ribbon instead.')
else:
choice = forms.ask_options('What do you want to change?', [AUTOMATIC, REVIEW], TITLE)
if choice == AUTOMATIC:
automatic()
elif choice == REVIEW:
review()
Library modules this tool uses
From the shared namo library, which installs with every tool. Each name opens the module on GitHub.
namo.clashdataOne reader for every clash tool: snapshots, groups, run-to-run comparison, history, images, and the per-result edits that are safe at scale.namo.clashrep_formsThe questions the Clash Reports buttons ask, in one place.namo.clashrep_historyClash history maths for Clash Delta, Clash Trends and the automatic snapshot: which snapshot to compare with, what changed since, and the series over time. Pure.namo.clashreportClash reports: the row shaping, summaries and tallies every Clash Reports tool shares.namo.configPlayground-wide settings: one JSON file shared by every Playground tool.namo.hk_clashhistoryAutomatic clash snapshot on save (registered for 'doc-saved' in namo.hooks).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.
bundle.yaml
The bundle contract: the keys pyNavis reads for this tool.
Coordinate.tab/Clash_Reports.panel/History.stack/Snapshot_Clashes.pushbutton/bundle.yaml View on GitHubtitle: Snapshot
tooltip: Records the current results of the chosen clash tests as a snapshot that Clash Delta and Clash Trends compare with. Shift+Click to snapshot automatically on save, or to delete old snapshots.
context: clash-tests