GithubHelp home page GithubHelp logo

yiskang / aps-viewer-revit-systems-extension Goto Github PK

View Code? Open in Web Editor NEW

This project forked from autodesk-platform-services/aps-viewer-revit-systems-extension

0.0 1.0 0.0 11.34 MB

Sample Extension to build Systems Browser in APS Viewer

Home Page: https://autodesk-platform-services.github.io/aps-viewer-revit-systems-extension/

License: MIT License

JavaScript 78.86% HTML 21.14%

aps-viewer-revit-systems-extension's Introduction

aps-viewer-revit-systems-extension

Thumbnail

thumbnail

Introduction

This sample shares an Extension that builds a tree view of the systems available in the rendered design.

It works based on the system-related properties from a model, and the idea is to build a docking panel on top of Viewer that hosts the nodes. We can have nodes referring from Systems to instances of elements, so when you click them, the correlated elements get highlighted in the scene.

The approach

To achieve that we're going to leverage Petr's Custom Tree Views blog and Viewer methods shared below.

Preparing Systems Data

First thing we need to do is preparing the Sytems Data as soon as our design gets loaded. That's achieved with the snippet below.

async getSystemsData(model) {
  // First we grab all MEP Systems for classifications
  let systems = await getSystems(model);
  let SYSTEMS_DATA = {
    name: 'Systems',
    path: 'systems',
    dbIds: [],
    entries: []
  };

  // Here we grab all the leaf nodes
  const leafNodeDbIds = await this.findLeafNodes(model);
  // Here we retrieve system-related properties for the leaf nodes
  let leafNodeResults = await this.getBulkPropertiesAsync(model, leafNodeDbIds, { propFilter: [SYSTEM_TYPE_PROPERTY, SYSTEM_NAME_PROPERTY, SYSTEM_CIRCUIT_NUMBER_PROPERTY, 'name', 'Category'] });
  leafNodeResults = leafNodeResults.filter(e => e.properties.length >= 2);

  for (const system of systems) {
    //For each MEP systems we retrieve its properties
    let systemName = system.name;
    let familyNameProp = system.properties.find(p => p.attributeName == REVIT_FAMILY_NAME_PROPERTY);
    // Here we transform system name to correct classifications
    let systemClassificationName = getSystemClassification(familyNameProp?.displayValue);

    //And then we start populating the SYSTEMS_DATA object
    let currentSystemClassification = SYSTEMS_DATA.entries.find(s => s.name == systemClassificationName);
    if (!currentSystemClassification) {
      SYSTEMS_DATA.entries.push({ name: systemClassificationName, path: `systems/${systemClassificationName}`, dbIds: [], entries: [] });
      currentSystemClassification = SYSTEMS_DATA.entries.find(s => s.name == systemClassificationName);
    }

    let currentSystem = null;
    if (systemClassificationName == 'Electrical') {
      currentSystem = currentSystemClassification;
    } else {
      currentSystem = currentSystemClassification.entries.find(s => s.name == systemName);
      if (!currentSystem) {
        currentSystemClassification.entries.push({ name: systemName, path: `systems/${systemClassificationName}/${systemName}`, dbIds: [], entries: [] });
        currentSystem = currentSystemClassification.entries.find(s => s.name == systemName);
      }
    }

    // Here we grab all MEP System types and their system-related properties
    let systemTypeDbIds = system.properties.filter(p => p.attributeName == CHILD_PROPERTY).map(p => p.displayValue);
    let systemTypeResults = await this.getBulkPropertiesAsync(model, systemTypeDbIds, { propFilter: [SYSTEM_TYPE_PROPERTY, SYSTEM_NAME_PROPERTY, SYSTEM_CIRCUIT_NUMBER_PROPERTY, 'name'] });

    for (let systemTypeResult of systemTypeResults) {
      //For system type we retrieve properties for the leaf nodes
      let systemTypeTypeProp = systemTypeResult.properties.find(p => p.attributeName == SYSTEM_TYPE_PROPERTY);
      let systemTypeNameProp = systemTypeResult.properties.find(p => p.attributeName == SYSTEM_NAME_PROPERTY);
      let circuitNumberProp = systemTypeResult.properties.find(p => p.attributeName == SYSTEM_CIRCUIT_NUMBER_PROPERTY);

      let systemTypeName = systemTypeNameProp?.displayValue;
      let systemTypeEntryPath = `systems/${systemClassificationName}/${systemName}/${systemTypeName}`;
      if (systemClassificationName == 'Electrical') {
        systemTypeName = systemTypeTypeProp?.displayValue;
        systemTypeEntryPath = `systems/${systemClassificationName}/${systemTypeName}`;
      }

      let currentSystemType = currentSystem.entries.find(st => st.name == systemTypeName);
      if (!currentSystemType) {
        currentSystem.entries.push({ name: systemTypeName, path: systemTypeEntryPath, dbIds: [], entries: [] });
        currentSystemType = currentSystem.entries.find(st => st.name == systemTypeName);
      }

      // Here we retrieve system-end elements by their system type value from the leaf nodes
      let endElementResults = null;
      let prevCurrentSystemType = null;
      if (systemClassificationName == 'Electrical') {
        let circuitNumberVal = circuitNumberProp?.displayValue;
        let currentCircuitNumber = currentSystemType.entries.find(st => st.name == circuitNumberVal);
        if (!currentCircuitNumber) {
          currentSystemType.entries.push({ name: circuitNumberVal, path: `${systemTypeEntryPath}/${circuitNumberVal}`, dbIds: [], entries: [] });
          currentCircuitNumber = currentSystemType.entries.find(st => st.name == circuitNumberVal);
        }

        prevCurrentSystemType = currentSystemType;
        currentSystemType = currentCircuitNumber;
        let endElementSearchTerm = SYSTEM_CIRCUIT_NUMBER_PROPERTY;
        endElementResults = leafNodeResults.filter(e =>
          (e.properties.find(prop => prop.attributeName == endElementSearchTerm && prop.displayValue == currentSystemType.name) != null)
        );
      } else {
        let endElementSearchTerm = SYSTEM_NAME_PROPERTY;
        endElementResults = leafNodeResults.filter(e =>
          (e.properties.find(prop => prop.attributeName == endElementSearchTerm && prop.displayValue.split(',').some(s => s == currentSystemType.name)) != null)
        );
      }

      for (let endElement of endElementResults) {
        // Each system-end element we put it into correct system type
        let endElementName = endElement.name;
        let currentEndElement = currentSystemType.entries.find(st => st.name == endElementName);
        if (!currentEndElement) {
          currentSystemType.entries.push({ name: endElementName, path: `${currentSystemType}/${endElementName}`, dbIds: [endElement.dbId], entries: [] });
          currentEndElement = currentSystemType.entries.find(st => st.name == endElementName);
        }
        currentSystemType.dbIds.push(endElement.dbId);
        prevCurrentSystemType?.dbIds.push(endElement.dbId);
        currentSystem.dbIds.push(endElement.dbId);
        currentSystemClassification.dbIds.push(endElement.dbId);
      }

      // Remove unused system types for electrical system as Revit does
      if (currentSystemType.entries.length <= 0 && prevCurrentSystemType != null) {
        let idx = prevCurrentSystemType.entries.indexOf(currentSystemType);
        if (idx != -1)
          prevCurrentSystemType.entries.splice(idx, 1);
      }
    }
  }

  return SYSTEMS_DATA;
}
  • In this case, each node contains an array of dbIds that we can use to isolate its elements

Reacting to node click

We're also adding a reaction when a node gets clicked, so all the related dbIds get isolated.

LIVE DEMO

License

This sample is licensed under the terms of the MIT License. Please see the LICENSE file for full details.

Written by

Joao Martins in/jpornelas, Developer Advocate Eason Kang in/eason-kang-b4398492/, Developer Advocate

aps-viewer-revit-systems-extension's People

Contributors

yiskang avatar joaomartins-callmejohn avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.