Model > Look
Color by Property
Colors every item by the value of a property you pick, most common values first, and lists the legend with counts. The same value keeps its color from one run to the next.
Status
Untested Never executed inside Navisworks. Passed the headless checks only.
Related asks to confirm
No quote is on record yet. These threads look related, but a person still has to open and read them.
Events it listens to
None. It runs only when you click it.
Files
Paths are relative to the Playground.extension folder.
Model.tab/Look.panel/Color_by_Property.pushbutton/bundle.yamlModel.tab/Look.panel/Color_by_Property.pushbutton/icon.dark.pngModel.tab/Look.panel/Color_by_Property.pushbutton/icon.pngModel.tab/Look.panel/Color_by_Property.pushbutton/icon.small.dark.pngModel.tab/Look.panel/Color_by_Property.pushbutton/icon.small.pngModel.tab/Look.panel/Color_by_Property.pushbutton/script.py
Install
- Only this tool. In Navisworks, click pyNavis > Playground, search for Color by Property, 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. Color by Property is on the Model tab, Look 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.
Model.tab/Look.panel/Color_by_Property.pushbutton/script.py View on GitHub"""Colors every item in the chosen scope by the value of one property and prints the legend."""
from namo import colorize, items, paint, progress, session, ui
from pynavis import doc as nwdoc
from pynavis import script, toast
TITLE = 'Color by Property'
DEFAULTS = {'scope': 'visible', 'top': colorize.DEFAULT_TOP, 'other': 'grey', 'reset': True,
'ghost': False, 'property': []}
SCOPE_LABELS = {'selection': 'current selection', 'visible': 'visible items', 'model': 'whole model'}
EMPTY_SCOPE = {
'selection': 'The selection holds no items with geometry. Select some objects first.',
'visible': 'No visible item was found. Unhide something, or choose Whole model.',
'model': 'The model holds no items with geometry.',
}
def run():
document = nwdoc.get_doc()
if document.Models.Count == 0:
toast.info('No model open', 'Open or append a model, then run Color by Property again.')
return
cfg = script.get_config(DEFAULTS)
selected = items.selected(document)
options = ui.form(TITLE, colorize.options_fields(len(selected), cfg), ok='Next')
if options is None:
return
scope = options['scope']
remembered = cfg.get('scope')
cfg.update(options)
if scope == 'selection' and remembered in ('visible', 'model'):
cfg['scope'] = remembered # the selection is offered anyway; keep the other choice
script.save_config(cfg)
objects = progress.run(TITLE, lambda report: colorize.scope_objects(
scope, document, tick=colorize.counting(report, 'Collecting items:')))
if objects is progress.CANCELLED:
return
if not objects:
toast.info('Nothing to color', EMPTY_SCOPE[scope])
return
names, sampled = colorize.property_names(objects)
if not names:
toast.info('No properties found', 'The items in the %s carry no properties.' % SCOPE_LABELS[scope])
return
last = tuple(cfg.get('property') or ())
picked = ui.choose(TITLE, colorize.property_rows(names, sampled), ['Category', 'Property', 'Found on'],
multiselect=False, checked=[last] if last else None, ok='Color',
prompt='Pick the property to color by. Found on says how many of %s sampled '
'items carry it.' % colorize.count_text(sampled))
if picked is None:
return
category, prop = picked[0]
cfg['property'] = [category, prop]
script.save_config(cfg)
label = colorize.property_label(category, prop)
groups = progress.run(TITLE, lambda report: colorize.read_groups(
objects, category, prop, tick=colorize.counting(report, 'Reading %s:' % prop)))
if groups is progress.CANCELLED:
return
if all(value == colorize.NO_VALUE for value, _members in groups):
toast.info('Nothing to color', 'None of the %s carries %s.' % (
colorize.plural(len(objects), 'item'), label))
return
memory = colorize.load_memory()
key = colorize.scheme_key(category, prop)
ranked = [(value, len(members)) for value, members in groups]
plan = colorize.plan_scheme(ranked, options['top'], options['other'], colorize.memory_map(memory, key))
ghost = colorize.GHOST_TRANSPARENCY if options['ghost'] else None
scheme = colorize.make_scheme(category, prop, plan, SCOPE_LABELS[scope], ghost=ghost)
painted = colorize.apply(colorize.paint_groups(groups, plan), document,
reset_first=options['reset'], rest_transparency=ghost,
reset_items=objects if scope == 'selection' else None)
colorize.save_memory(colorize.update_memory(memory, key, colorize.value_pairs(scheme)))
try:
paint.remember_scheme(scheme)
except Exception as error:
session.log('warning', 'color scheme not remembered for Legend Maker: %s' % error)
colorize.show_legend(scheme)
message, detail = colorize.summary(scheme, painted)
toast.success(message, detail)
run()
Library modules this tool uses
From the shared namo library, which installs with every tool. Each name opens the module on GitHub.
namo.colorizeColouring by property: the engine behind Color by Property, Color Presets and Status Painter.namo.itemsModel items: walking, collecting, identifying, measuring and showing them.namo.paintColouring model items: permanent colour/transparency overrides, ghosting, reset.namo.progressGlue between pyNavis' cancellable progress window and Playground's progress callbacks.namo.sessionState that outlives one run, plus the one logger every namo module shares.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.
Model.tab/Look.panel/Color_by_Property.pushbutton/bundle.yaml View on GitHubtitle: Color by\nProperty
tooltip: Colors every item by the value of a property you pick, most common values first, and lists the legend with counts. The same value keeps its color from one run to the next.
context: doc