Project > 4D

Progress Painter

Sets the percent complete of the selected objects (a Playground > Progress property) and updates the TimeLiner progress of the tasks that hold them, or paints the model in four progress bands with a legend.

Tab and panelProject > 4D
KindButton
Live whenA model is open

Status

Untested Never executed inside Navisworks. Passed the headless checks only.

The public ask

What do i do if i want to visualise 50% (part completion) of a task o be shown in the model.

CADTutor, 2011-01. Open the source

Quoted from the page itself.

Events it listens to

None. It runs only when you click it.

Files

Paths are relative to the Playground.extension folder.

  • Project.tab/4D.panel/Progress_Painter.pushbutton/bundle.yaml
  • Project.tab/4D.panel/Progress_Painter.pushbutton/icon.dark.png
  • Project.tab/4D.panel/Progress_Painter.pushbutton/icon.png
  • Project.tab/4D.panel/Progress_Painter.pushbutton/icon.small.dark.png
  • Project.tab/4D.panel/Progress_Painter.pushbutton/icon.small.png
  • Project.tab/4D.panel/Progress_Painter.pushbutton/script.py

Install

  1. Only this tool. In Navisworks, click pyNavis > Playground, search for Progress Painter, 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. Progress Painter is on the Project tab, 4D 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.

Project.tab/4D.panel/Progress_Painter.pushbutton/script.py View on GitHub
# -*- coding: utf-8 -*-
"""Sets percent complete on the selected objects and their TimeLiner tasks, or paints the model by progress."""
from pynavis import forms, script, toast

from namo import fourd_common, fourd_progress, fourd_ui, items, progress, timeliner, ui

TITLE = 'Progress Painter'
DEFAULTS = {'percent': 50.0}
SET = 'Set progress of the selection'
PAINT_ITEMS = 'Paint by object progress'
PAINT_TASKS = 'Paint by TimeLiner task progress'
CLEAR = 'Clear the progress paint'


def set_progress(doc, selected):
    values = script.get_config(DEFAULTS)
    objects = items.objects(selected)
    percent = forms.ask_number('Percent complete for %s (0 to 100):' % fourd_common.plural(len(objects), 'object'),
                               default=values.get('percent', 50.0), min_value=0, max_value=100, title=TITLE)
    if percent is None:
        return
    values['percent'] = percent
    script.save_config(values)
    result = progress.run(TITLE, lambda report: fourd_progress.set_progress(objects, percent, doc, report))
    if result is progress.CANCELLED:
        return
    shown = ('%.1f' % percent).rstrip('0').rstrip('.')
    if not result['timeliner']:
        detail = 'TimeLiner is not available here, so no task was updated.'
    elif result['tasks']:
        detail = 'Updated the progress of %s.' % fourd_common.plural(result['tasks'], 'TimeLiner task')
    else:
        detail = 'No TimeLiner task holds these objects.'
    if result['errors']:
        toast.warning('Set %s%% on %s, %d failed' % (shown, fourd_common.plural(result['objects'], 'object'),
                                                    len(result['errors'])), result['errors'][0])
    else:
        toast.success('Set %s%% on %s' % (shown, fourd_common.plural(result['objects'], 'object')), detail)


def paint(doc, by_tasks):
    if by_tasks:
        try:
            rows = timeliner.snapshot(doc)
        except RuntimeError as error:
            toast.error('TimeLiner is not available', str(error))
            return
        if not [r for r in rows if r.get('progress') is not None and (r.get('attach_kind') or 'none') != 'none']:
            toast.info('No task has progress and items', 'Set % Complete in TimeLiner, or use Set progress first.')
            return
        outcome = progress.run(TITLE, lambda report: fourd_progress.paint_tasks(rows, doc, report))
        source = 'Colours from TimeLiner task progress.'
    else:
        def work(report):
            objects = items.objects(items.roots(doc), tick=progress.tick(report))
            return fourd_progress.paint_items(objects, doc, report)
        outcome = progress.run(TITLE, work)
        source = 'Colours from each object\'s Playground > Progress.'
    if outcome is progress.CANCELLED:
        return
    counts, painted = outcome
    if not painted:
        toast.info('Nothing to paint', 'No object carries a progress value yet. Select objects and set their progress.')
        return
    toast.success('Painted %s by progress' % fourd_common.plural(len(painted), 'object'), 'Ctrl+Z undoes it.')

    def clear():
        count = fourd_progress.clear_paint(doc)
        if count:
            toast.success('Cleared the progress paint', fourd_common.plural(count, 'object'))
    fourd_ui.show_legend(counts, source, clear)


def run():
    if ui.is_runner():
        toast.info('%s needs a person at the screen' % TITLE, 'Run it from the ribbon.')
        return
    doc = fourd_common.active_doc()
    if not fourd_common.has_models(doc):
        toast.info('No model is open', 'Open or append a model first.')
        return
    selected = items.selected(doc)
    options = ([SET] if selected else []) + [PAINT_ITEMS, PAINT_TASKS, CLEAR]
    prompt = 'What should Progress Painter do?' if selected else \
        'Nothing is selected, so progress cannot be set. Paint instead?'
    choice = forms.ask_options(prompt, options, title=TITLE)
    if choice is None:
        return
    if choice == SET:
        set_progress(doc, selected)
    elif choice == CLEAR:
        count = fourd_progress.clear_paint(doc)
        if count is None:
            toast.info('Nothing painted in this session', 'Ctrl+Z, or Reset All > Appearance in Navisworks, removes older paint.')
        else:
            toast.success('Cleared the progress paint', fourd_common.plural(count, 'object'))
    else:
        paint(doc, choice == PAINT_TASKS)


run()

Library modules this tool uses

From the shared namo library, which installs with every tool. Each name opens the module on GitHub.

  • namo.fourd_commonHelpers the 4D, Quantities and Field tools share: scopes, default files, text.
  • namo.fourd_progressProgress Painter: percent complete on model objects, rolled up into TimeLiner tasks, and the model painted by progress.
  • namo.fourd_uiWindows of the 4D tools, built on namo.ui.
  • namo.itemsModel items: walking, collecting, identifying, measuring and showing them.
  • namo.progressGlue between pyNavis' cancellable progress window and Playground's progress callbacks.
  • namo.timelinerTimeLiner: every Playground access to Navisworks TimeLiner, plus the pure schedule logic.
  • 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.

Project.tab/4D.panel/Progress_Painter.pushbutton/bundle.yaml View on GitHub
title: Progress\nPainter
tooltip: Sets the percent complete of the selected objects (a Playground > Progress property) and updates the TimeLiner progress of the tasks that hold them, or paints the model in four progress bands with a legend.
context: doc