npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ngx-ifc-viewer

v0.0.23

Published

*Creator: Mads Holten Rasmussen*

Downloads

63

Readme

IFC-viewer for Angular

Creator: Mads Holten Rasmussen

The library includes my take on an IFC viewer for Angular based on IFC.js.

Install to Angular project

The library uses Angular Material Design, so please install this package beforehand.

npm i --save ngx-ifc-viewer npm i --save three web-ifc-three camera-controls three-fatline npm i --save-dev @types/three

Add to app.module.ts

import { IfcViewerModule } from 'ngx-ifc-viewer';

@NgModule({
  imports: [
    ...,
    IfcViewerModule
  ]
})

Use

See examples of use in the LD-BIM viewer.

Install to non-Angular project

npm i --save ngx-ifc-viewer

Add to HTML body

<ifc-viewer></ifc-viewer>

Copy the files web-ifc.wasm and web-ifc-mt.wasm from the folder node_modules/web-ifc/ to a new folder assets/ifcjs. Add the files IFCWorker.js and IFCWorker.js.map from node_modules/web-ifc-three/.

Add some global styling to buttons that will also affect the buttons in the IFC-viewer (styles.scss):

.btn {
    background-color: DodgerBlue;
    border: none;
    color: white;
    padding: 12px 16px;
    font-size: 16px;
    cursor: pointer;
}

/* Darker background on mouse-over */
.btn:hover {
    background-color: RoyalBlue;
}

Use

See examples of use in the LD-BIM viewer.

Viewer

The viewer inherits the size of its parent div, so the example below will give us a full screen viewer.

<div style="width: 100%; height: 100%">
    <ifc-viewer></ifc-viewer>
</div>

The viewer per default has a button to upload a model, but it is also possible to do that from outside using the IFCModelLoaderService. This service takes a file and returns an observable that first shows the status of the loading process and once finished has the resulting model attached. This model can then be passed to the IFCViewerService or other services such as the Linked Building Data (LBD) toolset. The viewer service can at any time be used to access all the models that have been loaded.

import { IFCModelLoaderService, IFCViewerService } from 'ngx-ifc-viewer';
import { IFCModel } from 'web-ifc-three/IFC/components/IFCModel';

@Component({
  selector: 'app-component',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {

  public models: IFCModel[] = [];

  constructor(
    private: _modelLoader: IFCModelLoaderService,
    private _viewer: IFCViewerService
  ){}

  uploadFile(files: FileList){

    this._modelLoader.loadModel(files[0]).subscribe(async (status: LoadingStatus) => {

        // Load finished
        if(status.result != undefined){

          const model = status.result;

          // Add to array of models
          this.models.push(model);

          // Append model to scene
          this._viewer.appendModel(model);

        }

      }, 
      err => console.log(err))

  }
}

Input

|Name |Description | |:---------|:----------------------------------------------------------------------------------| |settings | An instance of the MenuPanelSettings class which holds all settings for the viewer|

Output

  • elementClick
  • canvasClick

Menu panel

The content displayed in the menu panel can be limited by specifying so in the viewer settings.

The top menu panel can be extended by placing HTML content between the <ifc-viewer>-tags. To display this content in the top menu after a model is loaded in the scene, use the menuPostLoadContent-selector as demonstrated below.

<div style="width: 100%; height: 100%">
    <ifc-viewer>

      <!-- MENU PANEL ADDITIONAL BUTTONS -->
      <ng-container menuPostLoadContent>

        <!-- My function -->
        <button class="btn" *ngIf="rdfParsed" (click)="myFunction()" matTooltip="Do something cool">
            <fa-icon [icon]="faUnicorn"></fa-icon>
        </button>

      </ng-container>

    </ifc-viewer>
</div>

In the above example we append a font-awesome icon with a unicorn. This requires the icon to also be loaded from the @fortawesome/free-solid-svg-icons package:

import { faUnicorn } from '@fortawesome/free-solid-svg-icons';

@Component({
  ...
})
export class AppComponent {
  public faUnicorn = faUnicorn;
  ...
}

Context menu

The content displayed in the context menu on element click can be limited by specifying so in the viewer settings.

The context menu can also be extended with custom items by placing HTML content between the <ifc-viewer>-tags. To display this content in the top menu after a model is loaded in the scene, use the contextMenu-selector as demonstrated below.

This requires MatMenuModule and MatButtonModule to be imported in the app module.

<div style="width: 100%; height: 100%">
    <ifc-viewer (elementClick)="lastClicekedElement = $event">

      <!-- CONTEXT MENU ADDITIONAL BUTTONS -->
      <ng-container contextMenu>
        <button mat-menu-item (click)="colorElement()">Color element</button>
      </ng-container>

    </ifc-viewer>
</div>

Coloring

In the context menu example we define a "color element" function. Implementing this functionality is quite simple using the ColorService. In the example below we make use of the lastClickedElement which is defined by element clicks in the model using the elementClick-output of the viewer (se context menu HTML snippet). From this we can access the expressID of the element and feed it to the colorSubset-method of the color service. We also provide it with a stringified version of the expressID as the customID. The customID is used by the color service to know that it already exists in the scene, and therefore clicking and coloring the same element again will toggle the color off.

import { ColorService, ElementClickEvent } from 'ngx-ifc-viewer';

@Component({
  ...
})
export class AppComponent {
  ...
  public lastClicekedElement?: ElementClickEvent;

  constructor(
    private _color: ColorService
  ){}

  colorElement(){
    if(this.lastClickedElement == undefined) return;
    const expressID = this.lastClickedElement.expressID;
    this._color.colorSubset([expressID], "red", expressID.toString());
  }
}

The color service also has a function that applies color to groups of elements. Simply feed it with a nested array of expressIDs (an array per group) and the service will apply colors and return the colors used. The default color pallette has 10 colors.

import { ColorService, IFCModelLoaderService } from 'ngx-ifc-viewer';

@Component({
  ...
})
export class AppComponent {
  ...
  constructor(
    private _modelLoader: IFCModelLoaderService,
    private _color: ColorService
  ){}

  colorGroups(){
    const wallIDs = await this._modelLoader.ifc.getAllItemsOfType(modelID, IFCWALLSTANDARDCASE, false);
    const windowIDs = await this._modelLoader.ifc.getAllItemsOfType(modelID, IFCWINDOW, false);
    const doorIDs = await this._modelLoader.ifc.getAllItemsOfType(modelID, IFCDOOR, false);
    const colors = await this._color.colorByGroup([wallIDs, windowIDs, doorIDs]);
    console.log(colors);
  }
}