Refactor: BcfWpAttributeGroupComponent,

ViewerBridgeService, IFCViewerService + Add ViewpointsService
pull/8406/head
Aleix Suau 5 years ago committed by Wieland Lindenthal
parent 340bee2bd6
commit c8ed85f81a
  1. 4
      frontend/src/app/modules/bim/bcf/api/viewpoints/bcf-viewpoint.interface.ts
  2. 17
      frontend/src/app/modules/bim/bcf/bcf-viewer-bridge/revit-bridge.service.ts
  3. 11
      frontend/src/app/modules/bim/bcf/bcf-viewer-bridge/viewer-bridge.service.ts
  4. 4
      frontend/src/app/modules/bim/bcf/bcf-wp-attribute-group/bcf-new-wp-attribute-group.component.ts
  5. 2
      frontend/src/app/modules/bim/bcf/bcf-wp-attribute-group/bcf-wp-attribute-group.component.html
  6. 238
      frontend/src/app/modules/bim/bcf/bcf-wp-attribute-group/bcf-wp-attribute-group.component.ts
  7. 86
      frontend/src/app/modules/bim/bcf/helper/viewpoints.service.ts
  8. 8
      frontend/src/app/modules/bim/bcf/openproject-bcf.module.ts
  9. 10
      frontend/src/app/modules/bim/ifc_models/ifc-base-view/event-handler/bcf-click-handler.ts
  10. 49
      frontend/src/app/modules/bim/ifc_models/ifc-viewer/ifc-viewer.service.ts

@ -3,7 +3,9 @@ export interface BcfViewpointInterface {
guid:string; guid:string;
components:unknown; components:unknown;
bitmaps:unknown[]; bitmaps:unknown[];
snapshot:{ snapshot_type:string, snapshot_data:string };
orthogonal_camera?:unknown; orthogonal_camera?:unknown;
perspective_camera?:unknown; perspective_camera?:unknown;
snapshot:{ snapshot_type:string, snapshot_data:string }; clipping_planes?:unknown[];
lines?:unknown[];
} }

@ -1,9 +1,11 @@
import {Injectable} from '@angular/core'; import {Injectable, Injector} from '@angular/core';
import {Observable, Subject} from "rxjs"; import {Observable, Subject} from "rxjs";
import {distinctUntilChanged, filter, first, mapTo} from "rxjs/operators"; import {distinctUntilChanged, filter, first, mapTo} from "rxjs/operators";
import {BcfViewpointInterface} from "core-app/modules/bim/bcf/api/viewpoints/bcf-viewpoint.interface"; import {BcfViewpointInterface} from "core-app/modules/bim/bcf/api/viewpoints/bcf-viewpoint.interface";
import {ViewerBridgeService} from "core-app/modules/bim/bcf/bcf-viewer-bridge/viewer-bridge.service"; import {ViewerBridgeService} from "core-app/modules/bim/bcf/bcf-viewer-bridge/viewer-bridge.service";
import {input} from "reactivestates"; import {input} from "reactivestates";
import {WorkPackageResource} from "core-app/modules/hal/resources/work-package-resource";
declare global { declare global {
interface Window { interface Window {
@ -19,7 +21,7 @@ export class RevitBridgeService extends ViewerBridgeService {
revitMessageReceived$ = this.revitMessageReceivedSource.asObservable(); revitMessageReceived$ = this.revitMessageReceivedSource.asObservable();
constructor() { constructor(readonly injector:Injector) {
super(); super();
if (window.RevitBridge) { if (window.RevitBridge) {
@ -34,11 +36,11 @@ export class RevitBridgeService extends ViewerBridgeService {
} }
} }
viewerVisible() { public viewerVisible() {
return this._ready$.getValueOr(false); return this._ready$.getValueOr(false);
} }
getViewpoint():Promise<any> { public getViewpoint():Promise<any> {
const trackingId = this.newTrackingId(); const trackingId = this.newTrackingId();
this.sendMessageToRevit('ViewpointGenerationRequest', trackingId, ''); this.sendMessageToRevit('ViewpointGenerationRequest', trackingId, '');
@ -62,8 +64,11 @@ export class RevitBridgeService extends ViewerBridgeService {
}); });
} }
showViewpoint(data:BcfViewpointInterface) { public showViewpoint(workPackage:WorkPackageResource, index:number) {
this.sendMessageToRevit('ShowViewpoint', this.newTrackingId(), JSON.stringify(data)); /* const viewPointResource = this.getViewPointResource(workPackage:WorkPackageResource, index:number);
this.getViewPointData$(viewpointHref)
.subscribe(viewpoint => this.sendMessageToRevit('ShowViewpoint', this.newTrackingId(), JSON.stringify(viewpoint))); */
} }
sendMessageToRevit(messageType:string, trackingId:string, messagePayload?:any) { sendMessageToRevit(messageType:string, trackingId:string, messagePayload?:any) {

@ -1,17 +1,24 @@
import {Injector, Injectable} from '@angular/core';
import {BcfViewpointInterface} from "core-app/modules/bim/bcf/api/viewpoints/bcf-viewpoint.interface"; import {BcfViewpointInterface} from "core-app/modules/bim/bcf/api/viewpoints/bcf-viewpoint.interface";
import {Observable} from "rxjs"; import {Observable} from "rxjs";
import {WorkPackageResource} from "core-app/modules/hal/resources/work-package-resource";
import {InjectField} from "core-app/helpers/angular/inject-field.decorator";
@Injectable()
export abstract class ViewerBridgeService { export abstract class ViewerBridgeService {
constructor(readonly injector:Injector) {}
/** /**
* Get a viewpoint from the viewer * Get a viewpoint from the viewer
*/ */
abstract getViewpoint():Promise<BcfViewpointInterface>; abstract getViewpoint$():Observable<BcfViewpointInterface>;
/** /**
* Show the given viewpoint JSON in the viewer * Show the given viewpoint JSON in the viewer
* @param viewpoint * @param viewpoint
*/ */
abstract showViewpoint(viewpoint:BcfViewpointInterface):void; abstract showViewpoint(workPackage:WorkPackageResource, index:number):void;
/** /**
* Determine whether a viewer is present to ensure we can show viewpoints * Determine whether a viewer is present to ensure we can show viewpoints

@ -22,11 +22,11 @@ export class BcfNewWpAttributeGroupComponent extends BcfWpAttributeGroupComponen
} }
// Disable show viewpoint functionality // Disable show viewpoint functionality
showViewpoint(index:number) { showViewpoint(workPackage:WorkPackageResource, index:number) {
return; return;
} }
deleteViewpoint(index:number) { deleteViewpoint(workPackage:WorkPackageResource, index:number) {
this.setViewpoints( this.setViewpoints(
this.viewpoints.filter((_, i) => i !== index) this.viewpoints.filter((_, i) => i !== index)
); );

@ -20,7 +20,7 @@
<a *ngIf="viewerVisible && createAllowed" <a *ngIf="viewerVisible && createAllowed"
[title]="text.add_viewpoint" [title]="text.add_viewpoint"
class="button" class="button"
(click)="saveCurrentAsViewpoint()"> (click)="saveCurrentAsViewpoint(workPackage)">
<op-icon icon-classes="button--icon icon-add"></op-icon> <op-icon icon-classes="button--icon icon-add"></op-icon>
<span class="button--text"> {{text.viewpoint}} </span> <span class="button--text"> {{text.viewpoint}} </span>
</a> </a>

@ -23,6 +23,8 @@ import {NotificationsService} from "core-app/modules/common/notifications/notifi
import {BcfViewpointInterface} from "core-app/modules/bim/bcf/api/viewpoints/bcf-viewpoint.interface"; import {BcfViewpointInterface} from "core-app/modules/bim/bcf/api/viewpoints/bcf-viewpoint.interface";
import {WorkPackageCreateService} from "core-components/wp-new/wp-create.service"; import {WorkPackageCreateService} from "core-components/wp-new/wp-create.service";
import {BcfAuthorizationService} from "core-app/modules/bim/bcf/api/bcf-authorization.service"; import {BcfAuthorizationService} from "core-app/modules/bim/bcf/api/bcf-authorization.service";
import {ViewpointsService} from "core-app/modules/bim/bcf/helper/viewpoints.service";
export interface ViewpointItem { export interface ViewpointItem {
/** The URL of the viewpoint, if persisted */ /** The URL of the viewpoint, if persisted */
@ -132,7 +134,8 @@ export class BcfWpAttributeGroupComponent extends UntilDestroyedMixin implements
readonly wpCreate:WorkPackageCreateService, readonly wpCreate:WorkPackageCreateService,
readonly notifications:NotificationsService, readonly notifications:NotificationsService,
readonly cdRef:ChangeDetectorRef, readonly cdRef:ChangeDetectorRef,
readonly I18n:I18nService) { readonly I18n:I18nService,
readonly viewpointsService:ViewpointsService) {
super(); super();
} }
@ -141,29 +144,71 @@ export class BcfWpAttributeGroupComponent extends UntilDestroyedMixin implements
this.observeChanges(); this.observeChanges();
} }
showViewpoint(index:number) { protected observeChanges() {
this this.wpCache
.observe(this.workPackage.id!)
.pipe(
this.untilDestroyed()
)
.subscribe(async wp => {
this.workPackage = wp;
//this.setTopicUUIDFromWorkPackage();
const projectId = this.workPackage.project.idFromLink;
this.viewAllowed = await this.bcfAuthorization.isAllowedTo(projectId, 'project_actions', 'viewTopic');
this.createAllowed = await this.bcfAuthorization.isAllowedTo(projectId, 'topic_actions', 'createViewpoint');
if (wp.bcfViewpoints) {
this.viewpoints = wp.bcfViewpoints.map((el:HalLink) => {
return { href: el.href, snapshotURL: `${el.href}/snapshot` };
});
this.setViewpointsOnGallery(this.viewpoints);
this.loadViewpointFromRoute(this.workPackage);
}
this.cdRef.detectChanges();
});
}
protected showViewpoint(workPackage:WorkPackageResource, index:number) {
this.viewerBridge.showViewpoint(workPackage, index);
/* this
.viewpointFromIndex(index) .viewpointFromIndex(index)
.get() .get()
.subscribe(data => { .subscribe(data => {
if (this.viewerVisible) { if (this.viewerVisible) {
this.viewerBridge.showViewpoint(data); this.viewerBridge.showViewpoint(data);
} else { } else {
// Send a message to Revit, waiting for response
// TODO: Show feedback to the user (Trying to communicate with Revit...)
// TODO: Check if there is a 'model-loaded' event
// SKIP this on PLUGINS SCENARIO
window.location.href = this.pathHelper.bimDetailsPath( window.location.href = this.pathHelper.bimDetailsPath(
this.workPackage.project.idFromLink, this.workPackage.project.idFromLink,
this.workPackage.id!, this.workPackage.id!,
index index
); );
} }
}); }); */
} }
deleteViewpoint(index:number) { protected deleteViewpoint(workPackage:WorkPackageResource, index:number) {
if (!window.confirm(this.text.text_are_you_sure)) { if (!window.confirm(this.text.text_are_you_sure)) {
return; return;
} }
this this.viewpointsService
.deleteViewPoint$(workPackage, index)
.subscribe(data => {
// Update the work package to reload the viewpoint
this.notifications.addSuccess(this.text.notice_successful_delete);
this.wpCache.require(this.workPackage.id!, true);
this.gallery.preview.close();
});
/* this
.viewpointFromIndex(index) .viewpointFromIndex(index)
.delete() .delete()
.subscribe(data => { .subscribe(data => {
@ -171,62 +216,47 @@ export class BcfWpAttributeGroupComponent extends UntilDestroyedMixin implements
this.notifications.addSuccess(this.text.notice_successful_delete); this.notifications.addSuccess(this.text.notice_successful_delete);
this.wpCache.require(this.workPackage.id!, true); this.wpCache.require(this.workPackage.id!, true);
this.gallery.preview.close(); this.gallery.preview.close();
}); }); */
} }
async saveCurrentAsViewpoint() { public saveCurrentAsViewpoint(workPackage:WorkPackageResource) {
const viewpoint = await this.viewerBridge!.getViewpoint(); this.viewpointsService
.saveCurrentAsViewpoint$(workPackage)
.subscribe(response => {
console.log('Type this response', response);
// Update the work package to reload the viewpoint
this.notifications.addSuccess(this.text.notice_successful_create);
this.showIndex = this.viewpoints.length;
this.wpCache.require(this.workPackage.id!, true);
});
/* const viewpoint = await this.viewerBridge!.getViewpoint();
await this.persistViewpoint(viewpoint); await this.persistViewpoint(viewpoint);
// Update the work package to reload the viewpoint // Update the work package to reload the viewpoint
this.notifications.addSuccess(this.text.notice_successful_create); this.notifications.addSuccess(this.text.notice_successful_create);
this.showIndex = this.viewpoints.length; this.showIndex = this.viewpoints.length;
this.wpCache.require(this.workPackage.id!, true); this.wpCache.require(this.workPackage.id!, true); */
} }
galleryPreviewOpen():void { protected loadViewpointFromRoute(workPackage:WorkPackageResource) {
jQuery('#top-menu').addClass('-no-z-index'); if (typeof (this.state.params.viewpoint) === 'number') {
} const index = this.state.params.viewpoint;
this.showViewpoint(workPackage, index);
galleryPreviewClose():void { this.showIndex = index;
jQuery('#top-menu').removeClass('-no-z-index'); this.selectViewpointInGallery();
} this.state.go('.', { ...this.state.params, viewpoint: undefined }, { reload: false });
}
selectViewpointInGallery() {
setTimeout(() => this.gallery?.show(this.showIndex), 250);
}
onGalleryChanged(event:{ index:number }) {
this.showIndex = event.index;
} }
protected observeChanges() { public shouldShowGroup() {
this.wpCache return this.viewAllowed &&
.observe(this.workPackage.id!) (this.viewpoints.length > 0 ||
.pipe( (this.createAllowed && this.viewerVisible));
this.untilDestroyed()
)
.subscribe(async wp => {
this.workPackage = wp;
this.setTopicUUIDFromWorkPackage();
const projectId = this.workPackage.project.idFromLink;
this.viewAllowed = await this.bcfAuthorization.isAllowedTo(projectId, 'project_actions', 'viewTopic');
this.createAllowed = await this.bcfAuthorization.isAllowedTo(projectId, 'topic_actions', 'createViewpoint');
if (wp.bcfViewpoints) {
this.setViewpoints(wp.bcfViewpoints.map((el:HalLink) => {
return { href: el.href, snapshotURL: `${el.href}/snapshot` };
}));
this.loadViewpointFromRoute();
}
this.cdRef.detectChanges();
});
} }
protected async persistViewpoint(viewpoint:BcfViewpointInterface) { /* protected async persistViewpoint(viewpoint:BcfViewpointInterface) {
this.topicUUID = this.topicUUID || await this.createBcfTopic(); this.topicUUID = this.topicUUID || await this.createBcfTopic();
return this.bcfApi return this.bcfApi
@ -235,95 +265,95 @@ export class BcfWpAttributeGroupComponent extends UntilDestroyedMixin implements
.viewpoints .viewpoints
.post(viewpoint) .post(viewpoint)
.toPromise(); .toPromise();
} } */
protected set showIndex(value:number) {
const options = [...this.galleryOptions];
options[0].startIndex = value;
this.galleryOptions = options;
}
protected get showIndex():number {
return this.galleryOptions[0].startIndex!;
}
protected setTopicUUIDFromWorkPackage() { /* protected setTopicUUIDFromWorkPackage() {
const topicHref:string|undefined = this.workPackage.bcfTopic?.href; const topicHref:string|undefined = this.workPackage.bcfTopic?.href;
if (topicHref) { if (topicHref) {
this.topicUUID = this.bcfApi.parse<BcfViewpointPaths>(topicHref)!.id as string; this.topicUUID = this.bcfApi.parse<BcfViewpointPaths>(topicHref)!.id as string;
} }
} } */
protected async createBcfTopic():Promise<string> { /* protected async createBcfTopic():Promise<string> {
return this.bcfApi return this.bcfApi
.projects.id(this.wpProjectId) .projects.id(this.wpProjectId)
.topics .topics
.post(this.workPackage.convertBCF.payload) .post(this.workPackage.convertBCF.payload)
.toPromise() .toPromise()
.then(resource => resource.guid); .then(resource => resource.guid);
} } */
protected setViewpoints(viewpoints:ViewpointItem[]) {
const length = viewpoints.length;
this.setThumbnailProperties(length);
if (this.showIndex < 0 || length < 1) {
this.showIndex = 0;
} else if (this.showIndex >= length) {
this.showIndex = length - 1;
}
this.viewpoints = viewpoints;
this.galleryImages = viewpoints.map(viewpoint => {
return {
small: viewpoint.snapshotURL,
medium: viewpoint.snapshotURL,
big: viewpoint.snapshotURL
};
});
this.cdRef.detectChanges();
}
protected viewpointFromIndex(index:number):BcfViewpointPaths { /* protected viewpointFromIndex(index:number):BcfViewpointPaths {
let viewpointHref = this.workPackage.bcfViewpoints[index].href; let viewpointHref = this.workPackage.bcfViewpoints[index].href;
return this.bcfApi.parse<BcfViewpointPaths>(viewpointHref); return this.bcfApi.parse<BcfViewpointPaths>(viewpointHref);
} } */
protected loadViewpointFromRoute() { /* protected get wpProjectId() {
if (typeof (this.state.params.viewpoint) === 'number') { return this.workPackage.project.idFromLink;
const index = this.state.params.viewpoint; } */
this.showViewpoint(index);
this.showIndex = index;
this.selectViewpointInGallery();
this.state.go('.', { ...this.state.params, viewpoint: undefined }, { reload: false });
}
}
// Gallery functionality
protected actions() { protected actions() {
return [ return [
{ {
icon: 'icon-view-model', icon: 'icon-view-model',
onClick: (evt:any, index:number) => this.showViewpoint(index), onClick: (evt: any, index: number) => this.showViewpoint(this.workPackage, index),
titleText: this.text.show_viewpoint titleText: this.text.show_viewpoint
}, },
{ {
icon: 'icon-delete', icon: 'icon-delete',
onClick: (evt:any, index:number) => this.deleteViewpoint(index), onClick: (evt:any, index:number) => this.deleteViewpoint(this.workPackage, index),
titleText: this.text.delete_viewpoint titleText: this.text.delete_viewpoint
} }
]; ];
} }
protected get wpProjectId() { public galleryPreviewOpen():void {
return this.workPackage.project.idFromLink; jQuery('#top-menu').addClass('-no-z-index');
} }
shouldShowGroup() { public galleryPreviewClose():void {
return this.viewAllowed && jQuery('#top-menu').removeClass('-no-z-index');
(this.viewpoints.length > 0 || }
(this.createAllowed && this.viewerVisible));
public selectViewpointInGallery() {
setTimeout(() => this.gallery?.show(this.showIndex), 250);
}
public onGalleryChanged(event:{ index:number }) {
this.showIndex = event.index;
}
protected set showIndex(value:number) {
const options = [...this.galleryOptions];
options[0].startIndex = value;
this.galleryOptions = options;
}
protected get showIndex():number {
return this.galleryOptions[0].startIndex!;
}
protected setViewpointsOnGallery(viewpoints:ViewpointItem[]) {
const length = viewpoints.length;
this.setThumbnailProperties(length);
if (this.showIndex < 0 || length < 1) {
this.showIndex = 0;
} else if (this.showIndex >= length) {
this.showIndex = length - 1;
}
this.galleryImages = viewpoints.map(viewpoint => {
return {
small: viewpoint.snapshotURL,
medium: viewpoint.snapshotURL,
big: viewpoint.snapshotURL
};
});
this.cdRef.detectChanges();
} }
protected setThumbnailProperties(viewpointCount:number) { protected setThumbnailProperties(viewpointCount:number) {

@ -0,0 +1,86 @@
import {Injectable, Injector} from '@angular/core';
import {InjectField} from "core-app/helpers/angular/inject-field.decorator";
import {BcfApiService} from "core-app/modules/bim/bcf/api/bcf-api.service";
import {WorkPackageResource} from "core-app/modules/hal/resources/work-package-resource";
import {BcfViewpointPaths} from "core-app/modules/bim/bcf/api/viewpoints/bcf-viewpoint.paths";
import {ViewerBridgeService} from "core-app/modules/bim/bcf/bcf-viewer-bridge/viewer-bridge.service";
import {switchMap, map} from 'rxjs/operators';
import {of, forkJoin, Observable} from 'rxjs';
import {BcfViewpointInterface} from "core-app/modules/bim/bcf/api/viewpoints/bcf-viewpoint.interface";
@Injectable()
export class ViewpointsService {
@InjectField() bcfApi:BcfApiService;
@InjectField() viewerBridge:ViewerBridgeService;
constructor(readonly injector:Injector) {
console.log('this.bcfApi: ', this.bcfApi);
}
public getViewPointResource(workPackage:WorkPackageResource, index:number):BcfViewpointPaths {
const viewpointHref = workPackage.bcfViewpoints[index].href;
return this.bcfApi.parse<BcfViewpointPaths>(viewpointHref);
}
public getViewPoint$(workPackage:WorkPackageResource, index:number):Observable<BcfViewpointInterface> {
const viewpointResource = this.getViewPointResource(workPackage, index);
return viewpointResource.get();
}
public deleteViewPoint$(workPackage:WorkPackageResource, index:number):Observable<BcfViewpointInterface> {
const viewpointResource = this.getViewPointResource(workPackage, index);
return viewpointResource.delete();
}
public saveCurrentAsViewpoint$(workPackage:WorkPackageResource): Observable<BcfViewpointInterface> {
const wpProjectId = workPackage.project.idFromLink;
const topicHref = workPackage.bcfTopic?.href;
const topicUUID$ = topicHref ?
of(this.bcfApi.parse<BcfViewpointPaths>(topicHref)!.id) :
this.createBcfTopic$(workPackage);
return forkJoin({
topicUUID: topicUUID$,
viewpoint: this.viewerBridge!.getViewpoint$(),
})
.pipe(
switchMap(results => this.bcfApi
.projects.id(wpProjectId)
.topics.id(results.topicUUID as (string | number))
.viewpoints
.post(results.viewpoint))
);
/* const viewpoint = await this.viewerBridge!.getViewpoint();
const topicUUID = workPackage.bcfTopic?.href ?
this.bcfApi.parse<BcfViewpointPaths>(topicHref)!.id :
this.createBcfTopic();
const wpProjectId = workPackage.project.idFromLink;
return this.bcfApi
.projects.id(wpProjectId)
.topics.id(topicUUID)
.viewpoints
.post(viewpoint); */
}
protected createBcfTopic$(workPackage:WorkPackageResource):Observable<string> {
const wpProjectId = workPackage.project.idFromLink;
const wpPayload = workPackage.convertBCF.payload
return this.bcfApi
.projects.id(wpProjectId)
.topics
.post(wpPayload)
.pipe(
map((resource: BcfViewpointInterface) => {
console.log('Type this: ', resource);
return resource.guid;
})
);
}
}

@ -35,6 +35,7 @@ import {HTTP_INTERCEPTORS} from "@angular/common/http";
import {OpenProjectHeaderInterceptor} from "core-app/modules/hal/http/openproject-header-interceptor"; import {OpenProjectHeaderInterceptor} from "core-app/modules/hal/http/openproject-header-interceptor";
import {BcfDetectorService} from "core-app/modules/bim/bcf/helper/bcf-detector.service"; import {BcfDetectorService} from "core-app/modules/bim/bcf/helper/bcf-detector.service";
import {BcfPathHelperService} from "core-app/modules/bim/bcf/helper/bcf-path-helper.service"; import {BcfPathHelperService} from "core-app/modules/bim/bcf/helper/bcf-path-helper.service";
import {ViewpointsService} from "core-app/modules/bim/bcf/helper/viewpoints.service";
import {BcfImportButtonComponent} from "core-app/modules/bim/ifc_models/toolbar/import-export-bcf/bcf-import-button.component"; import {BcfImportButtonComponent} from "core-app/modules/bim/ifc_models/toolbar/import-export-bcf/bcf-import-button.component";
import {BcfExportButtonComponent} from "core-app/modules/bim/ifc_models/toolbar/import-export-bcf/bcf-export-button.component"; import {BcfExportButtonComponent} from "core-app/modules/bim/ifc_models/toolbar/import-export-bcf/bcf-export-button.component";
import {RevitBridgeService} from "core-app/modules/bim/bcf/bcf-viewer-bridge/revit-bridge.service"; import {RevitBridgeService} from "core-app/modules/bim/bcf/bcf-viewer-bridge/revit-bridge.service";
@ -53,9 +54,9 @@ import {BcfNewWpAttributeGroupComponent} from "core-app/modules/bim/bcf/bcf-wp-a
*/ */
export const viewerBridgeServiceFactory = (injector:Injector) => { export const viewerBridgeServiceFactory = (injector:Injector) => {
if (window.navigator.userAgent.search('Revit') > -1) { if (window.navigator.userAgent.search('Revit') > -1) {
return new RevitBridgeService(); return new RevitBridgeService(injector);
} else { } else {
return injector.get(IFCViewerService, new IFCViewerService()); return injector.get(IFCViewerService, new IFCViewerService(injector));
} }
}; };
@ -72,7 +73,8 @@ export const viewerBridgeServiceFactory = (injector:Injector) => {
deps: [Injector] deps: [Injector]
}, },
BcfDetectorService, BcfDetectorService,
BcfPathHelperService BcfPathHelperService,
ViewpointsService,
], ],
declarations: [ declarations: [
BcfWpAttributeGroupComponent, BcfWpAttributeGroupComponent,

@ -16,13 +16,7 @@ export class BcfClickHandler extends CardClickHandler {
// Open the viewpoint if any // Open the viewpoint if any
if (this.viewer.viewerVisible() && wp.bcfViewpoints) { if (this.viewer.viewerVisible() && wp.bcfViewpoints) {
const first = wp.bcfViewpoints[0].href; this.viewer.showViewpoint(wp, 0);
const resource = this.bcfApi.parse(first) as BcfViewpointPaths;
resource
.get()
.subscribe((viewpoint) => {
this.viewer.showViewpoint(viewpoint);
});
} }
} }
} }

@ -1,8 +1,15 @@
import {Injectable} from '@angular/core'; import {Injectable, Inject, Injector} from '@angular/core';
import {XeokitServer} from "core-app/modules/bim/ifc_models/xeokit/xeokit-server"; import {XeokitServer} from "core-app/modules/bim/ifc_models/xeokit/xeokit-server";
import {BcfViewpointInterface} from "core-app/modules/bim/bcf/api/viewpoints/bcf-viewpoint.interface"; import {BcfViewpointInterface} from "core-app/modules/bim/bcf/api/viewpoints/bcf-viewpoint.interface";
import {ViewerBridgeService} from "core-app/modules/bim/bcf/bcf-viewer-bridge/viewer-bridge.service"; import {ViewerBridgeService} from "core-app/modules/bim/bcf/bcf-viewer-bridge/viewer-bridge.service";
import {Observable, Subject} from "rxjs"; import {Observable, Subject} from "rxjs";
import {WorkPackageResource} from "core-app/modules/hal/resources/work-package-resource";
import {PathHelperService} from "core-app/modules/common/path-helper/path-helper.service";
import {BcfApiService} from "core-app/modules/bim/bcf/api/bcf-api.service";
import {InjectField} from "core-app/helpers/angular/inject-field.decorator";
import {ViewpointsService} from "core-app/modules/bim/bcf/helper/viewpoints.service";
import {of} from 'rxjs';
export interface XeokitElements { export interface XeokitElements {
canvasElement:HTMLElement; canvasElement:HTMLElement;
@ -26,10 +33,22 @@ export interface BCFLoadOptions {
@Injectable() @Injectable()
export class IFCViewerService extends ViewerBridgeService { export class IFCViewerService extends ViewerBridgeService {
@InjectField() pathHelper:PathHelperService;
@InjectField() bcfApi:BcfApiService;
@InjectField() viewpointsService:ViewpointsService;
private _viewer:any; private _viewer:any;
// private _loaded:BehaviorSubject<boolean> = new BehaviorSubject(false);
// readonly loaded$:Observable<boolean> = this._loaded.asObservable().pipe(shareReplay({refCount: true, bufferSize: 1}));
private $loaded = new Subject<void>(); private $loaded = new Subject<void>();
constructor(readonly injector:Injector){
super(injector);
console.log('IFCViewerService constructor called', this.pathHelper, this.bcfApi);
}
public newViewer(elements:XeokitElements, projects:any[]) { public newViewer(elements:XeokitElements, projects:any[]) {
import('@xeokit/xeokit-bim-viewer/dist/main').then((XeokitViewerModule:any) => { import('@xeokit/xeokit-bim-viewer/dist/main').then((XeokitViewerModule:any) => {
let server = new XeokitServer(); let server = new XeokitServer();
@ -70,24 +89,42 @@ export class IFCViewerService extends ViewerBridgeService {
this.viewer.setKeyboardEnabled(val); this.viewer.setKeyboardEnabled(val);
} }
public getViewpoint():Promise<BcfViewpointInterface> { public getViewpoint$():Observable<BcfViewpointInterface> {
const viewpoint = this.viewer.saveBCFViewpoint({ spacesVisible: true }); const viewpoint = this.viewer.saveBCFViewpoint({ spacesVisible: true });
// The backend rejects viewpoints with bitmaps // The backend rejects viewpoints with bitmaps
delete viewpoint.bitmaps; delete viewpoint.bitmaps;
return Promise.resolve(viewpoint); return of(viewpoint);
} }
public showViewpoint(viewpoint:BcfViewpointInterface) { public showViewpoint(workPackage:WorkPackageResource, index:number) {
this.viewer.loadBCFViewpoint(viewpoint, {}); console.log('showViewpoint 1:', workPackage, workPackage.project.identifier, index, this.viewer, this.pathHelper, this.bcfApi, this.pathHelper.bimDetailsPath(
workPackage.project.idFromLink,
workPackage.id!,
index
));
if (this.viewer) {
this.viewpointsService
.getViewPoint$(workPackage, index)
.subscribe(viewpoint => this.viewer.loadBCFViewpoint(viewpoint, {}));
} else {
// Reload the whole app to get the correct menus and GON data
window.location.href = this.pathHelper.bimDetailsPath(
workPackage.project.idFromLink,
workPackage.id!,
index
);
}
} }
public viewerVisible():boolean { public viewerVisible():boolean {
return !!this.viewer; return !!this.viewer;
} }
// TODO: Remove this?
public onLoad$():Observable<void> { public onLoad$():Observable<void> {
return this.$loaded; return this.$loaded;
} }
} }
Loading…
Cancel
Save