Model > Data

Data Validator

Checks the model against BEP rules kept as JSON files in the team rules folder (every duct has a system name, every element a level, marks filled in, comments matching a pattern). Reports passes and failures per rule with element links, and can export to Excel and save a selection set per failing rule. Shift+Click for settings.

Tab and panelModel > Data
KindButton
Live whenA model is open

Status

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

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.

  • Model.tab/Data.panel/Data_Validator.pushbutton/bundle.yaml
  • Model.tab/Data.panel/Data_Validator.pushbutton/config.py
  • Model.tab/Data.panel/Data_Validator.pushbutton/icon.dark.png
  • Model.tab/Data.panel/Data_Validator.pushbutton/icon.png
  • Model.tab/Data.panel/Data_Validator.pushbutton/icon.small.dark.png
  • Model.tab/Data.panel/Data_Validator.pushbutton/icon.small.png
  • Model.tab/Data.panel/Data_Validator.pushbutton/script.py

Install

  1. Only this tool. In Navisworks, click pyNavis > Playground, search for Data Validator, 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. Data Validator is on the Model tab, Data 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/Data.panel/Data_Validator.pushbutton/script.py View on GitHub
# -*- coding: utf-8 -*-
"""Validates model properties against the JSON rule files in the team rules folder."""
from pynavis import script, toast

from namo import data_common, progress, reports, ui, validator

DEFAULTS = {'rule_files': [], 'scope': 'model', 'level': 'objects', 'xlsx': False, 'sets': False}


def pick_files(rulesets, values):
    rows = []
    for ruleset in rulesets:
        problems = len(ruleset.get('problems') or [])
        rows.append({'cells': [ruleset['name'], len(ruleset['rules']), ruleset['file'],
                               '%d %s' % (problems, 'problem' if problems == 1 else 'problems') if problems else ''],
                     'value': ruleset['file']})
    remembered = [f for f in values.get('rule_files') or [] if f in [r['file'] for r in rulesets]]
    checked = remembered or [r['file'] for r in rulesets]
    return ui.choose('Data Validator', rows, ['Rule set', 'Rules', 'File', 'Problems'], multiselect=True,
                     checked=checked, ok='Next',
                     prompt='Run which rule files? They live in %s (Shift+Click the button to open the folder).'
                            % validator.rules_folder())


def run():
    if ui.is_runner():
        result = reports.run('data_validation', script.get_config(DEFAULTS), interactive=False)
        if not result.get('cancelled'):
            toast.show(result['level'], result['message'], result['detail'])
        return
    doc = data_common.active_doc()
    if not data_common.has_models(doc):
        data_common.no_model_toast()
        return
    folder = validator.rules_folder()
    created = validator.ensure_starter(folder)
    rulesets = validator.load_folder(folder)
    if not rulesets:
        toast.warning('No rule files', 'Add .json rule files to %s, then run this again.' % folder)
        return
    values = script.get_config(DEFAULTS)
    files = pick_files(rulesets, values)
    if files is None:
        return
    has_selection = data_common.selected_count(doc) > 0
    fields = data_common.scope_fields(has_selection, values.get('scope'), values.get('level'))
    fields.append({'kind': 'check', 'key': 'xlsx', 'label': 'Also save an Excel workbook (every failure)',
                   'default': bool(values.get('xlsx'))})
    fields.append({'kind': 'check', 'key': 'sets', 'label': 'Save a selection set per failing rule (in %s)'
                                                            % validator.SET_FOLDER,
                   'default': bool(values.get('sets'))})
    intro = None
    if created:
        intro = 'A starter rule file was added to the rules folder; copy and edit it for your BEP.'
    answer = ui.form('Data Validator', fields, intro=intro, ok='Validate')
    if answer is None:
        return
    config = {'rule_files': files, 'scope': answer['scope'], 'level': answer['level'],
              'xlsx': bool(answer['xlsx']), 'sets': bool(answer['sets'])}
    script.save_config(config)
    if config['xlsx']:
        path = data_common.ask_save('{file} - Data validation - {date}', 'xlsx', 'Save the validation report', doc)
        if path is None:
            return
        config['path'] = path
    result = progress.run('Data Validator', lambda report: reports.run(
        'data_validation', config, doc=doc, interactive=True, progress=report))
    if result is progress.CANCELLED or result.get('cancelled'):
        return
    toast.show(result['level'], result['message'], result['detail'])


run()

config.py

The Shift+Click action.

Model.tab/Data.panel/Data_Validator.pushbutton/config.py View on GitHub
# -*- coding: utf-8 -*-
"""Opens the validation rules folder, checks every rule file, or restores the starter rules."""
from pynavis import forms, output, toast

from namo import ui, validator

OPEN = 'Open the rules folder'
CHECK = 'Check the rule files'
RESTORE = 'Restore the starter rules'


def check(folder):
    rulesets = validator.load_folder(folder)
    if not rulesets:
        toast.info('No rule files', 'The folder %s holds no .json files.' % folder)
        return
    problems = []
    rules = 0
    for ruleset in rulesets:
        problems.extend(ruleset.get('problems') or [])
        rules += len(ruleset['rules'])
    if not problems:
        toast.success('Every rule file reads cleanly', '%d %s, %d %s.' % (
            len(rulesets), 'file' if len(rulesets) == 1 else 'files', rules, 'rule' if rules == 1 else 'rules'))
        return
    output.print_md('**Rule file problems** in %s' % folder)
    output.print_table([[line] for line in problems], ['Problem'])
    toast.warning('%d %s in the rule files' % (len(problems), 'problem' if len(problems) == 1 else 'problems'),
                  'Each one is listed with its line in the output window.')


def run():
    if ui.is_runner():
        toast.info('Settings need the Navisworks window', 'They cannot open under pynavis run.')
        return
    folder = validator.rules_folder()
    validator.ensure_starter(folder)
    choice = forms.ask_options('Validation rules live in %s.' % folder, [OPEN, CHECK, RESTORE],
                               title='Data Validator')
    if choice is None:
        return
    if choice == OPEN:
        ui.open_path(folder)
        toast.success('Opened the rules folder', folder)
    elif choice == CHECK:
        check(folder)
    else:
        if not forms.confirm('Overwrite %s with the shipped starter rules? Your other rule files are kept.'
                             % validator.STARTER_FILE, title='Data Validator'):
            return
        try:
            path = validator.restore_starter(folder)
        except (IOError, OSError) as error:
            toast.error('Could not write the starter rules', str(error))
            return
        toast.success('Starter rules restored', path)


run()

Library modules this tool uses

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

  • namo.data_commonShared plumbing for the Inspect and Data panel tools: progress stages, where files go by default, the scope dialog fields, and the small checks every button starts with.
  • namo.progressGlue between pyNavis' cancellable progress window and Playground's progress callbacks.
  • namo.reportsThe registry of automation-ready reports, and the helpers every report shares.
  • namo.uiWPF building blocks for Playground tools, themed from the pyNavis design system.
  • namo.validatorData Validator: BEP-style property checks from JSON rule files.

bundle.yaml

The bundle contract: the keys pyNavis reads for this tool.

Model.tab/Data.panel/Data_Validator.pushbutton/bundle.yaml View on GitHub
title: Data\nValidator
tooltip: Checks the model against BEP rules kept as JSON files in the team rules folder (every duct has a system name, every element a level, marks filled in, comments matching a pattern). Reports passes and failures per rule with element links, and can export to Excel and save a selection set per failing rule. Shift+Click for settings.
context: doc