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.

Tab and panelModel > Look
KindButton
Live whenA model is open

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.yaml
  • Model.tab/Look.panel/Color_by_Property.pushbutton/icon.dark.png
  • Model.tab/Look.panel/Color_by_Property.pushbutton/icon.png
  • Model.tab/Look.panel/Color_by_Property.pushbutton/icon.small.dark.png
  • Model.tab/Look.panel/Color_by_Property.pushbutton/icon.small.png
  • Model.tab/Look.panel/Color_by_Property.pushbutton/script.py

Install

  1. Only this tool. In Navisworks, click pyNavis > Playground, search for Color by Property, tick it and click Install.
  2. The whole extension. Download Playground.extension.zip, unzip it, put the Playground.extension folder 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.

Report

Source

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 GitHub
title: 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