@colijnit/homedecorator 255.1.2 → 255.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/app/core/model/homedecorator-settings-options.d.ts +1 -0
  2. package/app/core/service/homedecorator-connector-adapter.service.d.ts +1 -1
  3. package/app/core/service/utils.service.d.ts +1 -0
  4. package/app/plugins/core3d/components/ar-gui/ar-gui-root/ar-gui-elements/ar-gui-buttons/ar-gui-buttons.component.scss +2 -4
  5. package/app/plugins/core3d/items/floor-plane-item.d.ts +8 -1
  6. package/app/plugins/core3d/items/metadata.d.ts +2 -0
  7. package/app/plugins/core3d/service/ar.service.d.ts +1 -0
  8. package/app/plugins/core3d/service/floor-pattern.service.d.ts +26 -0
  9. package/app/plugins/core3d/service/floor-tile-intersection.service.d.ts +25 -0
  10. package/app/plugins/core3d/service/outline.service.d.ts +1 -2
  11. package/app/plugins/core3d/service/post-processing.service.d.ts +6 -0
  12. package/app/plugins/core3d/service/scene.service.d.ts +4 -1
  13. package/app/plugins/core3d/service/ssr.service.d.ts +18 -0
  14. package/app/plugins/model-uploader/model-previewer/model-preview.component.d.ts +40 -3
  15. package/app/plugins/render/service/new-render.service.d.ts +1 -0
  16. package/app/plugins/threedselector/threedselector/service/build-furniture.service.d.ts +10 -1
  17. package/app/plugins/threedselector/threedselector/threedselector.component.d.ts +1 -0
  18. package/app/plugins/toolbar/toolbar.module.d.ts +2 -1
  19. package/app/shared/pdf-export/pdf-export.component.d.ts +20 -0
  20. package/app/shared/pdf-export/pdf-export.component.scss +19 -0
  21. package/app/shared/pdf-export/pdf-export.module.d.ts +11 -0
  22. package/assets/icons/pen-ruler.svg +1 -0
  23. package/assets/icons/xmark_regular.svg +1 -0
  24. package/bundles/colijnit-homedecorator.umd.js +1195 -174
  25. package/bundles/colijnit-homedecorator.umd.js.map +1 -1
  26. package/colijnit-homedecorator-255.1.2.tgz +0 -0
  27. package/esm2015/app/app.version.js +4 -4
  28. package/esm2015/app/core/model/homedecorator-settings-options.js +2 -1
  29. package/esm2015/app/core/model/light-preset.js +11 -7
  30. package/esm2015/app/core/service/homedecorator-connector-adapter.service.js +4 -6
  31. package/esm2015/app/core/service/homedecorator-connector.service.js +3 -1
  32. package/esm2015/app/core/service/utils.service.js +16 -1
  33. package/esm2015/app/plugins/core3d/components/ar-gui/ar-gui-root/ar-gui-elements/ar-gui-buttons/ar-gui-buttons.component.js +2 -2
  34. package/esm2015/app/plugins/core3d/items/floor-plane-item.js +25 -2
  35. package/esm2015/app/plugins/core3d/items/metadata.js +1 -1
  36. package/esm2015/app/plugins/core3d/service/ar.service.js +14 -1
  37. package/esm2015/app/plugins/core3d/service/floor-pattern.service.js +156 -0
  38. package/esm2015/app/plugins/core3d/service/floor-tile-intersection.service.js +122 -0
  39. package/esm2015/app/plugins/core3d/service/floor.service.js +5 -2
  40. package/esm2015/app/plugins/core3d/service/outline.service.js +9 -8
  41. package/esm2015/app/plugins/core3d/service/post-processing.service.js +77 -22
  42. package/esm2015/app/plugins/core3d/service/scene.service.js +30 -13
  43. package/esm2015/app/plugins/core3d/service/ssr.service.js +53 -0
  44. package/esm2015/app/plugins/lite-selector/lite-selector/component/selections-summary/selections-summary.component.js +3 -3
  45. package/esm2015/app/plugins/model-uploader/model-previewer/model-preview.component.js +335 -79
  46. package/esm2015/app/plugins/model-uploader/model-uploader/model-uploader.component.js +3 -2
  47. package/esm2015/app/plugins/product-catalog/product-catalog/product-catalog.component.js +3 -2
  48. package/esm2015/app/plugins/render/service/new-render.service.js +37 -13
  49. package/esm2015/app/plugins/threedselector/threedselector/service/build-furniture.service.js +135 -5
  50. package/esm2015/app/plugins/threedselector/threedselector/threedselector.component.js +34 -8
  51. package/esm2015/app/plugins/toolbar/toolbar/toolbar.component.js +9 -25
  52. package/esm2015/app/plugins/toolbar/toolbar.module.js +8 -4
  53. package/esm2015/app/shared/pdf-export/pdf-export.component.js +86 -0
  54. package/esm2015/app/shared/pdf-export/pdf-export.module.js +38 -0
  55. package/fesm2015/colijnit-homedecorator.js +1156 -181
  56. package/fesm2015/colijnit-homedecorator.js.map +1 -1
  57. package/package.json +2 -2
  58. package/assets/hdri/ground_MASK.jpg +0 -0
@@ -31,7 +31,7 @@ import { HttpHeaders } from '@angular/common/http';
31
31
  import axios from 'axios';
32
32
  import * as applyPatch from 'textdiff-patch';
33
33
  import * as THREE from 'three';
34
- import { Vector2, Material as Material$1, Object3D, Mesh, Vector3, Scene, EventDispatcher, PerspectiveCamera, Box3, PlaneGeometry, MeshBasicMaterial, DoubleSide, MeshStandardMaterial, CylinderGeometry, RingGeometry, Matrix4, Raycaster, PointLight, Euler, BoxGeometry, WebGLRenderTarget, NearestFilter, RGBAFormat, SRGBColorSpace, AxesHelper, Group, BufferGeometry, Line, DataTexture, LuminanceAlphaFormat, UnsignedByteType, LinearFilter, Shape, SphereGeometry, PCFSoftShadowMap, ShadowMaterial, LightProbe, Texture as Texture$1, DirectionalLight, MeshPhongMaterial, Color, WebGLRenderer, NoToneMapping, TextureLoader, EllipseCurve, ArcCurve, BufferAttribute, MeshPhysicalMaterial, Quaternion, Path, ShapeGeometry, BasicShadowMap, PCFShadowMap, VSMShadowMap, LinearSRGBColorSpace, Float32BufferAttribute, LineBasicMaterial, EquirectangularReflectionMapping, FrontSide, AdditiveBlending, LineSegments, EdgesGeometry, CircleGeometry, MathUtils, ObjectLoader, Light, Camera as Camera$1, RepeatWrapping, UVMapping, CubeReflectionMapping, CubeRefractionMapping, EquirectangularRefractionMapping, CubeUVReflectionMapping, NearestMipmapNearestFilter, NearestMipMapNearestFilter, NearestMipmapLinearFilter, NearestMipMapLinearFilter, LinearMipmapNearestFilter, LinearMipMapNearestFilter, LinearMipmapLinearFilter, LinearMipMapLinearFilter, AlphaFormat, LuminanceFormat, DepthFormat, DepthStencilFormat, RedFormat, RedIntegerFormat, RGFormat, RGIntegerFormat, RGBAIntegerFormat, ByteType, ShortType, UnsignedShortType, IntType, UnsignedIntType, FloatType, HalfFloatType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedInt248Type, ClampToEdgeWrapping, MirroredRepeatWrapping, ZeroFactor, OneFactor, SrcColorFactor, OneMinusSrcColorFactor, SrcAlphaFactor, OneMinusSrcAlphaFactor, DstAlphaFactor, OneMinusDstAlphaFactor, DstColorFactor, OneMinusDstColorFactor, AddEquation, SubtractEquation, ReverseSubtractEquation, MinEquation, MaxEquation, NoBlending, NormalBlending, SubtractiveBlending, MultiplyBlending, CustomBlending, TangentSpaceNormalMap, ObjectSpaceNormalMap, BackSide, ZeroStencilOp, KeepStencilOp, ReplaceStencilOp, IncrementStencilOp, DecrementStencilOp, IncrementWrapStencilOp, DecrementWrapStencilOp, InvertStencilOp, NeverStencilFunc, LessStencilFunc, EqualStencilFunc, LessEqualStencilFunc, GreaterStencilFunc, NotEqualStencilFunc, GreaterEqualStencilFunc, AlwaysStencilFunc, Source, SpotLight, AmbientLight, HemisphereLight, SpotLightHelper, DirectionalLightHelper, HemisphereLightHelper, PointLightHelper, CanvasTexture, Clock, AnimationMixer, AnimationClip, NoColorSpace, ArrowHelper, PMREMGenerator } from 'three';
34
+ import { Vector2, Material as Material$1, Object3D, Mesh, Vector3, Scene, EventDispatcher, PerspectiveCamera, Box3, PlaneGeometry, MeshBasicMaterial, DoubleSide, MeshStandardMaterial, CylinderGeometry, RingGeometry, Matrix4, Raycaster, PointLight, Euler, BoxGeometry, WebGLRenderTarget, NearestFilter, RGBAFormat, SRGBColorSpace, AxesHelper, Group, BufferGeometry, Line, DataTexture, LuminanceAlphaFormat, UnsignedByteType, LinearFilter, Shape, SphereGeometry, PCFSoftShadowMap, ShadowMaterial, LightProbe, Texture as Texture$1, DirectionalLight, MeshPhongMaterial, DepthTexture, UnsignedIntType, DepthFormat, Color, OrthographicCamera, WebGLRenderer, NoToneMapping, TextureLoader, EllipseCurve, ArcCurve, BufferAttribute, MeshPhysicalMaterial, Quaternion, Path, ShapeGeometry, BasicShadowMap, PCFShadowMap, VSMShadowMap, LinearSRGBColorSpace, Float32BufferAttribute, LineBasicMaterial, EquirectangularReflectionMapping, FrontSide, AdditiveBlending, LineSegments, EdgesGeometry, CircleGeometry, MathUtils, ObjectLoader, Light, Camera as Camera$1, RepeatWrapping, InstancedMesh, UVMapping, CubeReflectionMapping, CubeRefractionMapping, EquirectangularRefractionMapping, CubeUVReflectionMapping, NearestMipmapNearestFilter, NearestMipMapNearestFilter, NearestMipmapLinearFilter, NearestMipMapLinearFilter, LinearMipmapNearestFilter, LinearMipMapNearestFilter, LinearMipmapLinearFilter, LinearMipMapLinearFilter, AlphaFormat, LuminanceFormat, DepthStencilFormat, RedFormat, RedIntegerFormat, RGFormat, RGIntegerFormat, RGBAIntegerFormat, ByteType, ShortType, UnsignedShortType, IntType, FloatType, HalfFloatType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedInt248Type, ClampToEdgeWrapping, MirroredRepeatWrapping, ZeroFactor, OneFactor, SrcColorFactor, OneMinusSrcColorFactor, SrcAlphaFactor, OneMinusSrcAlphaFactor, DstAlphaFactor, OneMinusDstAlphaFactor, DstColorFactor, OneMinusDstColorFactor, AddEquation, SubtractEquation, ReverseSubtractEquation, MinEquation, MaxEquation, NoBlending, NormalBlending, SubtractiveBlending, MultiplyBlending, CustomBlending, TangentSpaceNormalMap, ObjectSpaceNormalMap, BackSide, ZeroStencilOp, KeepStencilOp, ReplaceStencilOp, IncrementStencilOp, DecrementStencilOp, IncrementWrapStencilOp, DecrementWrapStencilOp, InvertStencilOp, NeverStencilFunc, LessStencilFunc, EqualStencilFunc, LessEqualStencilFunc, GreaterStencilFunc, NotEqualStencilFunc, GreaterEqualStencilFunc, AlwaysStencilFunc, Source, SpotLight, AmbientLight, HemisphereLight, SpotLightHelper, DirectionalLightHelper, HemisphereLightHelper, PointLightHelper, CanvasTexture, Clock, AnimationMixer, AnimationClip, NoColorSpace, ArrowHelper, GridHelper, PMREMGenerator } from 'three';
35
35
  import * as TWEEN from '@tweenjs/tween.js';
36
36
  import * as PolygonTools from 'polygon-tools';
37
37
  import { WebGLPathTracer } from 'three-gpu-pathtracer';
@@ -45,11 +45,11 @@ import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer
45
45
  import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass';
46
46
  import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass';
47
47
  import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader';
48
- import { GammaCorrectionShader } from 'three/examples/jsm/shaders/GammaCorrectionShader';
48
+ import { OutputPass } from 'three/examples/jsm/postprocessing/OutputPass';
49
49
  import * as md5 from 'md5';
50
50
  import GUI from 'three/examples/jsm/libs/lil-gui.module.min';
51
51
  import { N8AOPass } from 'n8ao';
52
- import { SMAAPass } from 'three/examples/jsm/postprocessing/SMAAPass';
52
+ import { TAARenderPass } from 'three/examples/jsm/postprocessing/TAARenderPass';
53
53
  import * as i1 from '@angular/platform-browser';
54
54
  import * as i2$1 from 'ngx-device-detector';
55
55
  import * as i5$1 from '@angular/material/icon';
@@ -86,6 +86,7 @@ import { MatButtonModule } from '@angular/material/button';
86
86
  import * as i8 from '@angular/forms';
87
87
  import { NG_VALUE_ACCESSOR, FormsModule, ReactiveFormsModule } from '@angular/forms';
88
88
  import * as BufferGeometryUtils$1 from 'three/examples/jsm/utils/BufferGeometryUtils';
89
+ import { MeshBVH } from 'three-mesh-bvh';
89
90
  import { LinearSRGBColorSpace as LinearSRGBColorSpace$1, SrcAlphaSaturateFactor, LinearFilter as LinearFilter$1, LinearToneMapping, FloatType as FloatType$1 } from 'three/src/constants';
90
91
  import * as i4 from '@colijnit/corecomponents';
91
92
  import { IconModule, CardModule, SlideoutModule, SummaryLineModule, PriceDisplayPipeModule, ButtonModule, HtmlHeaderModule, InputTextModule, InputTextChipsModule } from '@colijnit/corecomponents';
@@ -138,7 +139,8 @@ import html2canvas from 'html2canvas';
138
139
  import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
139
140
  import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader';
140
141
  import { TDSLoader } from 'three/examples/jsm/loaders/TDSLoader';
141
- import * as i6$3 from '@angular/material/radio';
142
+ import { STLLoader } from 'three/examples/jsm/loaders/STLLoader';
143
+ import * as i9$1 from '@angular/material/radio';
142
144
  import { MatRadioModule } from '@angular/material/radio';
143
145
  import * as i19$1 from '@angular/material/toolbar';
144
146
  import { MatToolbarModule } from '@angular/material/toolbar';
@@ -157,6 +159,8 @@ import * as i1$5 from 'ngx-lightbox';
157
159
  import { FlexLayoutModule } from '@angular/flex-layout';
158
160
  import * as i10$2 from '@angular/cdk/drag-drop';
159
161
  import { DragDropModule } from '@angular/cdk/drag-drop';
162
+ import { jsPDF } from 'jspdf';
163
+ import autoTable from 'jspdf-autotable';
160
164
 
161
165
  var MessageType;
162
166
  (function (MessageType) {
@@ -663,9 +667,7 @@ class HomedecoratorConnectorAdapterService {
663
667
  }
664
668
  store3DModelCDN(filename, fileContents) {
665
669
  return __awaiter$1m(this, void 0, void 0, function* () {
666
- // convert ArrayBuffer to Int8Array so the middletier understand it
667
- const int8Array = new Int8Array(fileContents);
668
- const response = yield this.mainApi.uploadModelToCDN(filename, int8Array);
670
+ const response = yield this.mainApi.uploadModelToCDN(filename, fileContents);
669
671
  if (response && response.validationResult && response.validationResult.success) {
670
672
  return response.resultObject;
671
673
  }
@@ -676,7 +678,7 @@ class HomedecoratorConnectorAdapterService {
676
678
  }
677
679
  getCatalogDefinitionsList() {
678
680
  return __awaiter$1m(this, void 0, void 0, function* () {
679
- const response = yield this._articleApi.getCatalogDefinitions().catch(e => {
681
+ const response = yield this.articleApi.getCatalogDefinitions().catch(e => {
680
682
  return new DataServiceResponseData();
681
683
  });
682
684
  if (response && response.validationResult && response.validationResult.success) {
@@ -692,7 +694,7 @@ class HomedecoratorConnectorAdapterService {
692
694
  if (!externalSourceId) {
693
695
  return null;
694
696
  }
695
- const response = yield this._articleApi.getExternalSource(externalSourceId);
697
+ const response = yield this.articleApi.getExternalSource(externalSourceId);
696
698
  if (response && response.validationResult && response.validationResult.success) {
697
699
  if (response.resultObject) {
698
700
  return this._boFactory.makeWithRawBackendData(ExternalSource, response.resultObject);
@@ -870,6 +872,7 @@ class HomedecoratorSettingsOptions {
870
872
  this.useRenderWebsocket = false;
871
873
  this.productRenderSceneAssetId = 'scene_studio_eevee';
872
874
  this.pathTracer = false;
875
+ this.ssrEnabled = false;
873
876
  this.maxRenderSamples = 100;
874
877
  }
875
878
  }
@@ -1648,6 +1651,8 @@ class HomedecoratorConnectorService {
1648
1651
  }
1649
1652
  getArticle(sku, branch) {
1650
1653
  return __awaiter$1g(this, void 0, void 0, function* () {
1654
+ this.selections = [];
1655
+ this._decoNodes = [];
1651
1656
  const article = yield this._connector.getArticle(sku, branch)
1652
1657
  .catch(e => {
1653
1658
  return Promise.reject(e);
@@ -5974,7 +5979,6 @@ class OutlineService {
5974
5979
  this._hideOutlineTimeout = 10000;
5975
5980
  this._animationDuration = 5000;
5976
5981
  this._outlinePassAsError = false;
5977
- this._useMSAA = false;
5978
5982
  this._initializing = false;
5979
5983
  this._subs = [];
5980
5984
  this.needsRender = false;
@@ -5997,16 +6001,18 @@ class OutlineService {
5997
6001
  this._composer = new EffectComposer(this._renderer, this._renderTarget);
5998
6002
  this._composer.setPixelRatio(window.devicePixelRatio);
5999
6003
  const renderPass = new RenderPass(this._scene, this._camera);
6000
- this._composer.addPass(renderPass);
6004
+ this._outputPass = new OutputPass();
6001
6005
  this._outlinePass = new OutlinePass(new Vector2(width, height), this._scene, this._camera);
6002
- this._composer.addPass(this._outlinePass);
6003
6006
  this._fxaaPass = new ShaderPass(FXAAShader);
6004
6007
  this._fxaaPass.material.uniforms['resolution'].value.set(1 / width, 1 / height);
6005
- this._composer.addPass(this._fxaaPass);
6006
6008
  // needed for the sRGBEncoding to work
6007
6009
  // https://stackoverflow.com/questions/72936071/srgbencoding-in-not-working-in-three-effectcomposer
6008
- const gammaCorrectionPass = new ShaderPass(GammaCorrectionShader);
6009
- this._composer.addPass(gammaCorrectionPass);
6010
+ // const gammaCorrectionPass = new ShaderPass(GammaCorrectionShader);
6011
+ this._composer.addPass(renderPass);
6012
+ this._composer.addPass(this._outlinePass);
6013
+ this._composer.addPass(this._fxaaPass);
6014
+ // this._composer.addPass(gammaCorrectionPass);
6015
+ this._composer.addPass(this._outputPass);
6010
6016
  this._setSelectionGlowSettings();
6011
6017
  this._composer.setSize(width, height);
6012
6018
  }
@@ -7345,6 +7351,19 @@ class ArService {
7345
7351
  endSessionEvent() {
7346
7352
  this._session.end();
7347
7353
  }
7354
+ arIOSSupported() {
7355
+ return __awaiter$13(this, void 0, void 0, function* () {
7356
+ const isIOS = /iPad|iPhone|iPod/.test(navigator.platform) ||
7357
+ (navigator.userAgent.includes('Mac') && 'ontouchend' in document);
7358
+ if (isIOS) {
7359
+ const anchor = document.createElement('a');
7360
+ return anchor.relList.supports('ar');
7361
+ }
7362
+ else {
7363
+ return false;
7364
+ }
7365
+ });
7366
+ }
7348
7367
  arSupported() {
7349
7368
  return __awaiter$13(this, void 0, void 0, function* () {
7350
7369
  if (navigator.xr) {
@@ -8113,25 +8132,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImpo
8113
8132
  class PostProcessingService {
8114
8133
  constructor(_configurationService) {
8115
8134
  this._configurationService = _configurationService;
8116
- this._subs = [];
8117
- this._subs.push(this._configurationService.onChange.subscribe((changed) => {
8118
- if (ConfigurationKey.ShowPostProcessingSettings in changed) {
8119
- this._showHideGui(changed[ConfigurationKey.ShowPostProcessingSettings]);
8120
- }
8121
- }));
8122
- }
8123
- ngOnDestroy() {
8124
- this._subs.forEach(s => s.unsubscribe());
8125
- }
8126
- init(renderer, scene, camera, width, height) {
8127
- this._renderer = renderer;
8128
- this._scene = scene;
8129
- this._camera = camera;
8130
- this._composer = new EffectComposer(renderer);
8131
- this._n8aoPass = new N8AOPass(scene, camera, width, height);
8132
- const smaaPass = new SMAAPass(width, height);
8133
- this._composer.addPass(this._n8aoPass);
8134
- this._composer.addPass(smaaPass);
8135
8135
  this._effectController = {
8136
8136
  aoSamples: 32.0,
8137
8137
  denoiseSamples: 8.0,
@@ -8149,7 +8149,51 @@ class PostProcessingService {
8149
8149
  stencil: true,
8150
8150
  accumulate: false
8151
8151
  };
8152
+ this._subs = [];
8153
+ this._subs.push(this._configurationService.onChange.subscribe((changed) => {
8154
+ if (ConfigurationKey.ShowPostProcessingSettings in changed) {
8155
+ this._showHideGui(changed[ConfigurationKey.ShowPostProcessingSettings]);
8156
+ }
8157
+ }));
8158
+ }
8159
+ ngOnDestroy() {
8160
+ this._subs.forEach(s => s.unsubscribe());
8161
+ }
8162
+ init(renderer, scene, camera, width, height) {
8163
+ this._renderer = renderer;
8164
+ this._scene = scene;
8165
+ this._camera = camera;
8166
+ this._renderTarget = new WebGLRenderTarget(width, height, {
8167
+ minFilter: NearestFilter,
8168
+ magFilter: NearestFilter,
8169
+ format: RGBAFormat,
8170
+ colorSpace: SRGBColorSpace
8171
+ });
8172
+ this._renderTarget.samples = 4;
8173
+ this._renderTarget.depthTexture = new DepthTexture(width, height, UnsignedIntType);
8174
+ this._renderTarget.depthTexture.format = DepthFormat;
8175
+ this._composer = new EffectComposer(this._renderer, this._renderTarget);
8176
+ this._n8aoPass = new N8AOPass(scene, camera, width, height);
8177
+ this._n8aoPass.configuration.gammaCorrection = false;
8178
+ this._n8aoPass.debugMode = true;
8179
+ // const smaaPass = new SMAAPass(width, height);
8180
+ // this._composer.addPass(smaaPass);
8181
+ // const fxaaPass = new ShaderPass(FXAAShader);
8182
+ // const pixelRatio = this._renderer.getPixelRatio();
8183
+ // fxaaPass.material.uniforms[ 'resolution' ].value.x = 1 / (width * pixelRatio);
8184
+ // fxaaPass.material.uniforms[ 'resolution' ].value.y = 1 / (height * pixelRatio);
8185
+ this._outputPass = new OutputPass();
8186
+ this._taaRenderPass = new TAARenderPass(this._scene, this._camera, 0x000000, 0);
8187
+ this._taaRenderPass.unbiased = false;
8188
+ this._taaRenderPass.sampleLevel = 4;
8189
+ this._renderPass = new RenderPass(this._scene, this._camera);
8190
+ // this._renderPass.enabled = false;
8191
+ this._composer.addPass(this._renderPass);
8192
+ this._composer.addPass(this._taaRenderPass);
8193
+ this._composer.addPass(this._n8aoPass);
8194
+ this._composer.addPass(this._outputPass);
8152
8195
  this._createGui();
8196
+ this._createGuiTaaPass();
8153
8197
  }
8154
8198
  _updatePass() {
8155
8199
  this._n8aoPass.configuration.aoRadius = this._effectController.aoRadius;
@@ -8169,6 +8213,34 @@ class PostProcessingService {
8169
8213
  this._n8aoPass.configuration.accumulate = this._effectController.accumulate;
8170
8214
  this.render();
8171
8215
  }
8216
+ _createGuiTaaPass() {
8217
+ this._taaPassGui = new GUI();
8218
+ this._taaPassGui.hide();
8219
+ const param = { TAAEnabled: '1', TAASampleLevel: 0 };
8220
+ this._taaPassGui.add(param, 'TAAEnabled', {
8221
+ 'Disabled': '0',
8222
+ 'Enabled': '1'
8223
+ }).onFinishChange(() => {
8224
+ if (this._taaRenderPass) {
8225
+ this._taaRenderPass.enabled = (param.TAAEnabled === '1');
8226
+ }
8227
+ this.render();
8228
+ });
8229
+ this._taaPassGui.add(param, 'TAASampleLevel', {
8230
+ 'Level 0: 1 Sample': 0,
8231
+ 'Level 1: 2 Samples': 1,
8232
+ 'Level 2: 4 Samples': 2,
8233
+ 'Level 3: 8 Samples': 3,
8234
+ 'Level 4: 16 Samples': 4,
8235
+ 'Level 5: 32 Samples': 5
8236
+ }).onFinishChange(() => {
8237
+ if (this._taaRenderPass) {
8238
+ this._taaRenderPass.sampleLevel = param.TAASampleLevel;
8239
+ }
8240
+ this.render();
8241
+ });
8242
+ this._taaPassGui.open();
8243
+ }
8172
8244
  setSize(width, height) {
8173
8245
  this._composer.setSize(width, height);
8174
8246
  }
@@ -8233,6 +8305,56 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImpo
8233
8305
  }]
8234
8306
  }], ctorParameters: function () { return [{ type: ConfigurationService }]; } });
8235
8307
 
8308
+ class SsrService {
8309
+ constructor(_settingsService) {
8310
+ this._settingsService = _settingsService;
8311
+ this._enabled = false;
8312
+ this._subs = [];
8313
+ }
8314
+ set enabled(value) {
8315
+ this._enabled = value;
8316
+ if (this._enabled) {
8317
+ this._prepareWebsocket();
8318
+ }
8319
+ }
8320
+ get enabled() {
8321
+ return this._enabled;
8322
+ }
8323
+ ngOnDestroy() {
8324
+ this._subs.forEach(s => s.unsubscribe());
8325
+ }
8326
+ sceneChanged(scene) {
8327
+ if (this._websocket.readyState === WebSocket.OPEN) {
8328
+ const sceneClone = scene.clone(true);
8329
+ this._websocket.send(JSON.stringify(sceneClone));
8330
+ }
8331
+ }
8332
+ _prepareWebsocket() {
8333
+ if (!this._settingsService.settings.newRenderParameters.websocket) {
8334
+ return;
8335
+ }
8336
+ const webSocketConnection = this._settingsService.settings.newRenderParameters.websocket;
8337
+ this._websocket = new WebSocket(webSocketConnection);
8338
+ // webSocket.onopen = () => {
8339
+ // webSocket.send(JSON.stringify(data));
8340
+ // };
8341
+ this._websocket.onmessage = (event) => {
8342
+ const result = JSON.parse(event.data);
8343
+ if (result) {
8344
+ console.log(result);
8345
+ }
8346
+ };
8347
+ }
8348
+ }
8349
+ SsrService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: SsrService, deps: [{ token: HomedecoratorSettingsService }], target: i0.ɵɵFactoryTarget.Injectable });
8350
+ SsrService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: SsrService, providedIn: 'root' });
8351
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: SsrService, decorators: [{
8352
+ type: Injectable,
8353
+ args: [{
8354
+ providedIn: 'root'
8355
+ }]
8356
+ }], ctorParameters: function () { return [{ type: HomedecoratorSettingsService }]; } });
8357
+
8236
8358
  var __awaiter$12 = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
8237
8359
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
8238
8360
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -8243,7 +8365,7 @@ var __awaiter$12 = (this && this.__awaiter) || function (thisArg, _arguments, P,
8243
8365
  });
8244
8366
  };
8245
8367
  class SceneService {
8246
- constructor(_cameraService, _configurationService, _xrService, _vrService, _arService, _messageBusService, _viewModeService, _outlineService, _settingsService, _postProcessing) {
8368
+ constructor(_cameraService, _configurationService, _xrService, _vrService, _arService, _messageBusService, _viewModeService, _outlineService, _settingsService, _postProcessing, _ssrService) {
8247
8369
  this._cameraService = _cameraService;
8248
8370
  this._configurationService = _configurationService;
8249
8371
  this._xrService = _xrService;
@@ -8254,6 +8376,7 @@ class SceneService {
8254
8376
  this._outlineService = _outlineService;
8255
8377
  this._settingsService = _settingsService;
8256
8378
  this._postProcessing = _postProcessing;
8379
+ this._ssrService = _ssrService;
8257
8380
  this.onBeforeRender = new Subject();
8258
8381
  this.onAfterRender = new Subject();
8259
8382
  this.sceneInitialized = new BehaviorSubject(false);
@@ -8327,6 +8450,7 @@ class SceneService {
8327
8450
  if (loaded) {
8328
8451
  this._initPathTracer();
8329
8452
  this._maxRenderSamples = this._settingsService.settings.options.maxRenderSamples;
8453
+ this._ssrService.enabled = this._settingsService.settings.options.ssrEnabled;
8330
8454
  }
8331
8455
  })
8332
8456
  // this._xrService.sessionStarted.subscribe((mode: XrMode) => {
@@ -8388,6 +8512,20 @@ class SceneService {
8388
8512
  });
8389
8513
  this.needsRender = true;
8390
8514
  }
8515
+ createRenderWithOrthographicCamera() {
8516
+ const aspect = window.innerWidth / window.innerHeight;
8517
+ const frustumSize = 10;
8518
+ const orthographicCamera = new OrthographicCamera(frustumSize * aspect / -2, frustumSize * aspect / 2, frustumSize / 2, frustumSize / -2, 0.1, 100);
8519
+ orthographicCamera.position.set(0, 3, -2);
8520
+ orthographicCamera.lookAt(0, 0, -2);
8521
+ orthographicCamera.name = 'orthographiccamera';
8522
+ this.scene.add(orthographicCamera);
8523
+ this.renderer.render(this.scene, orthographicCamera);
8524
+ const render = this.renderer.domElement.toDataURL('image/jpeg');
8525
+ this.scene.getObjectByName('orthographiccamera').remove();
8526
+ this.renderer.render(this.scene, this._cameraService.camera);
8527
+ return render;
8528
+ }
8391
8529
  _initScene() {
8392
8530
  this.scene = new Scene();
8393
8531
  this._setSceneBackground();
@@ -8447,13 +8585,13 @@ class SceneService {
8447
8585
  // logarithmicDepthBuffer: true*/
8448
8586
  // });
8449
8587
  // this.renderer = new WebGLRenderer({alpha: true, antialias: false, preserveDrawingBuffer: true, premultipliedAlpha: true});
8450
- this.renderer = new WebGLRenderer({
8451
- precision: 'highp',
8452
- powerPreference: 'high-performance',
8453
- antialias: false,
8454
- stencil: false,
8455
- depth: false
8456
- });
8588
+ this.renderer = new WebGLRenderer( /*{
8589
+ precision: 'highp',
8590
+ powerPreference: 'high-performance',
8591
+ antialias: true,
8592
+ stencil: false,
8593
+ depth: false
8594
+ }*/);
8457
8595
  this.renderer.outputColorSpace = SRGBColorSpace;
8458
8596
  this.renderer.autoClear = false;
8459
8597
  this.renderer.setPixelRatio(window.devicePixelRatio);
@@ -8517,8 +8655,8 @@ class SceneService {
8517
8655
  this.renderer.render(this.scene, this._cameraService.camera);
8518
8656
  }
8519
8657
  else {
8520
- // this._outlineService.render();
8521
8658
  this._postProcessing.render();
8659
+ this._outlineService.render();
8522
8660
  }
8523
8661
  // this.renderer.render(this.scene, this._cameraService.camera);
8524
8662
  }
@@ -8564,14 +8702,14 @@ class SceneService {
8564
8702
  return this.renderer.domElement.toDataURL('image/jpeg');
8565
8703
  }
8566
8704
  }
8567
- SceneService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: SceneService, deps: [{ token: CameraService }, { token: ConfigurationService }, { token: XrService }, { token: VrService }, { token: ArService }, { token: MessageBusService }, { token: ViewModeService }, { token: OutlineService }, { token: HomedecoratorSettingsService }, { token: PostProcessingService }], target: i0.ɵɵFactoryTarget.Injectable });
8705
+ SceneService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: SceneService, deps: [{ token: CameraService }, { token: ConfigurationService }, { token: XrService }, { token: VrService }, { token: ArService }, { token: MessageBusService }, { token: ViewModeService }, { token: OutlineService }, { token: HomedecoratorSettingsService }, { token: PostProcessingService }, { token: SsrService }], target: i0.ɵɵFactoryTarget.Injectable });
8568
8706
  SceneService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: SceneService, providedIn: 'root' });
8569
8707
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: SceneService, decorators: [{
8570
8708
  type: Injectable,
8571
8709
  args: [{
8572
8710
  providedIn: 'root'
8573
8711
  }]
8574
- }], ctorParameters: function () { return [{ type: CameraService }, { type: ConfigurationService }, { type: XrService }, { type: VrService }, { type: ArService }, { type: MessageBusService }, { type: ViewModeService }, { type: OutlineService }, { type: HomedecoratorSettingsService }, { type: PostProcessingService }]; } });
8712
+ }], ctorParameters: function () { return [{ type: CameraService }, { type: ConfigurationService }, { type: XrService }, { type: VrService }, { type: ArService }, { type: MessageBusService }, { type: ViewModeService }, { type: OutlineService }, { type: HomedecoratorSettingsService }, { type: PostProcessingService }, { type: SsrService }]; } });
8575
8713
 
8576
8714
  var __awaiter$11 = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
8577
8715
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -11938,12 +12076,16 @@ class LightPreset {
11938
12076
  model.standalone = modelInterface.standalone;
11939
12077
  model.group = modelInterface.group;
11940
12078
  model.navigatorType = modelInterface.navigatorType;
11941
- model.shadowMapType = modelInterface.shadowMapType ?
11942
- Array.from(shadowMapTypesMap.entries()).find((key, value) => key[1] === modelInterface.shadowMapType)[0] :
11943
- ShadowMapLocalType.PCFSoftShadowMap;
11944
- model.outputEncoding = modelInterface.outputEncoding ?
11945
- Array.from(outputEncodingMap.entries()).find((key, value) => key[1] === modelInterface.outputEncoding)[0] :
11946
- OutputEncoding.SRGBColorSpace;
12079
+ if (Array.from(shadowMapTypesMap.entries()).find((key, value) => key[1] === modelInterface.shadowMapType)) {
12080
+ model.shadowMapType = modelInterface.shadowMapType ?
12081
+ Array.from(shadowMapTypesMap.entries()).find((key, value) => key[1] === modelInterface.shadowMapType)[0] :
12082
+ ShadowMapLocalType.PCFSoftShadowMap;
12083
+ }
12084
+ if (Array.from(outputEncodingMap.entries()).find((key, value) => key[1] === modelInterface.outputEncoding)) {
12085
+ model.outputEncoding = modelInterface.outputEncoding ?
12086
+ Array.from(outputEncodingMap.entries()).find((key, value) => key[1] === modelInterface.outputEncoding)[0] :
12087
+ OutputEncoding.SRGBColorSpace;
12088
+ }
11947
12089
  model.shadowRadius = modelInterface.shadowRadius;
11948
12090
  model.toneMappingExposure = modelInterface.toneMappingExposure ? modelInterface.toneMappingExposure : 1;
11949
12091
  model.physicallyCorrectLights = modelInterface.physicallyCorrectLights ? modelInterface.physicallyCorrectLights : false;
@@ -11973,9 +12115,9 @@ class MediaResource {
11973
12115
  // IMPORTANT: THIS FILE IS AUTO GENERATED! DO NOT MANUALLY EDIT!
11974
12116
  /* tslint:disable */
11975
12117
  const VersionInfo = {
11976
- "application": "Homedecorator",
11977
- "appVersion": "252.0.1",
11978
- "revision": "44fb58ea"
12118
+ application: "Homedecorator",
12119
+ appVersion: "255.1.2",
12120
+ revision: "111614"
11979
12121
  };
11980
12122
  /* tslint:enable */
11981
12123
 
@@ -12364,10 +12506,18 @@ class FloorPlaneItem extends Item {
12364
12506
  this.floorTexture = texture;
12365
12507
  if (object && object instanceof Mesh) {
12366
12508
  this._originalFloorMaterial = object.material;
12509
+ this.floorMesh = object;
12510
+ this._volume = new Box3();
12511
+ this._volume.setFromObject(object);
12367
12512
  this._originalUvs = object.geometry.attributes.uv.array;
12368
12513
  this._originalGeometry = object.geometry;
12369
12514
  }
12370
12515
  }
12516
+ get size() {
12517
+ const size = new Vector3();
12518
+ this._volume.getSize(size);
12519
+ return size;
12520
+ }
12371
12521
  set floorMaterial(mat) {
12372
12522
  this.children.forEach(c => {
12373
12523
  if (c instanceof Mesh) {
@@ -12377,6 +12527,20 @@ class FloorPlaneItem extends Item {
12377
12527
  }
12378
12528
  });
12379
12529
  }
12530
+ set floorObject(object) {
12531
+ this.children.forEach(c => c.visible = false);
12532
+ this._restoreObjects = this.children;
12533
+ this._configurableFloor = object;
12534
+ this.add(object);
12535
+ }
12536
+ restoreFloorObject() {
12537
+ if (!this._configurableFloor) {
12538
+ return;
12539
+ }
12540
+ this.remove(this._configurableFloor);
12541
+ this._configurableFloor.children.forEach((child) => child.dispose());
12542
+ this._restoreObjects.forEach(c => c.visible = true);
12543
+ }
12380
12544
  getTexture() {
12381
12545
  return this.floorTexture;
12382
12546
  }
@@ -12387,6 +12551,7 @@ class FloorPlaneItem extends Item {
12387
12551
  return false;
12388
12552
  }
12389
12553
  removed() {
12554
+ this.restoreFloorObject();
12390
12555
  if (this._originalFloorMaterial) {
12391
12556
  this.configurable = false;
12392
12557
  this.metadata.ione = false;
@@ -13161,11 +13326,14 @@ class FloorService {
13161
13326
  else {
13162
13327
  geometry = new ShapeGeometry(shape).center();
13163
13328
  }
13329
+ this._sceneService.needsRender = true;
13330
+ // floorMaterial.metalness = 0;
13331
+ geometry.rotateX(Math.PI / 2);
13164
13332
  const floorMaterial = yield this._createFloorMaterial(color, texture);
13165
13333
  const floorMesh = new ThreeMesh(geometry, floorMaterial);
13166
13334
  const floorPlane = new FloorPlaneItem({ itemType: ItemType.FloorDecoration }, floorMesh);
13167
13335
  floorPlane.name = 'floor-plane';
13168
- floorPlane.rotation.set(Math.PI / 2, 0, 0);
13336
+ // floorPlane.rotation.set(Math.PI / 2, 0, 0);
13169
13337
  floorPlane.receiveShadow = true;
13170
13338
  floorPlane.castShadow = false;
13171
13339
  const floorCenter = corners ? this._getFloorCenter(corners) : new Vector3(0, 0, 0);
@@ -17294,6 +17462,21 @@ class UtilsService {
17294
17462
  this._ktx2Loader.detectSupport(this._sceneService.renderer);
17295
17463
  return this._ktx2Loader;
17296
17464
  }
17465
+ downloadUSDZforARIOS(object) {
17466
+ return __awaiter$R(this, void 0, void 0, function* () {
17467
+ const exporter = new USDZExporter();
17468
+ const arraybuffer = yield exporter.parseAsync(object);
17469
+ const blob = new Blob([arraybuffer], { type: 'model/vnd.usdz+zip' });
17470
+ const url = URL.createObjectURL(blob);
17471
+ const element = document.createElement('a');
17472
+ element.style.display = 'none';
17473
+ element.href = url;
17474
+ document.body.appendChild(element);
17475
+ element.click();
17476
+ document.body.removeChild(element);
17477
+ URL.revokeObjectURL(url);
17478
+ });
17479
+ }
17297
17480
  _download3DModelAsGLB(object) {
17298
17481
  const options = {
17299
17482
  trs: false,
@@ -20601,6 +20784,159 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImpo
20601
20784
  args: [MAT_DIALOG_DATA]
20602
20785
  }] }]; } });
20603
20786
 
20787
+ var FloorPattern;
20788
+ (function (FloorPattern) {
20789
+ FloorPattern[FloorPattern["NORMAL"] = 0] = "NORMAL";
20790
+ FloorPattern[FloorPattern["HERRINGBONE"] = 1] = "HERRINGBONE";
20791
+ FloorPattern[FloorPattern["HON60"] = 2] = "HON60";
20792
+ FloorPattern[FloorPattern["HON45"] = 3] = "HON45";
20793
+ })(FloorPattern || (FloorPattern = {}));
20794
+ var FloorPatternDirection;
20795
+ (function (FloorPatternDirection) {
20796
+ FloorPatternDirection[FloorPatternDirection["STANDING"] = 0] = "STANDING";
20797
+ FloorPatternDirection[FloorPatternDirection["LYING"] = 1] = "LYING";
20798
+ })(FloorPatternDirection || (FloorPatternDirection = {}));
20799
+ class FloorPatternService {
20800
+ generatePattern(floorPattern, plankSize, floorSize, direction = FloorPatternDirection.LYING) {
20801
+ const floorRotation = direction === FloorPatternDirection.STANDING ? 90 : 0;
20802
+ let floorWidth = floorSize.x;
20803
+ let floorLength = floorSize.z;
20804
+ if (direction === FloorPatternDirection.STANDING) {
20805
+ floorWidth = floorSize.z;
20806
+ floorLength = floorSize.x;
20807
+ }
20808
+ switch (floorPattern) {
20809
+ case FloorPattern.NORMAL:
20810
+ return this._normalPattern(plankSize, floorWidth, floorLength, floorRotation);
20811
+ case FloorPattern.HERRINGBONE:
20812
+ return this._herringBone(plankSize, floorWidth, floorLength, floorRotation);
20813
+ case FloorPattern.HON45:
20814
+ return this._hon(plankSize, floorWidth, floorLength, floorRotation, 45);
20815
+ case FloorPattern.HON60:
20816
+ return this._hon(plankSize, floorWidth, floorLength, floorRotation, 60);
20817
+ }
20818
+ }
20819
+ _rotatePatternOnZAxis(items, floorRotation) {
20820
+ if (floorRotation % 360 > 0) {
20821
+ items.forEach(item => {
20822
+ const radians = MathUtils.degToRad(floorRotation);
20823
+ const x = item.position.x;
20824
+ const z = item.position.z;
20825
+ item.position.x = x * Math.cos(radians) - z * Math.sin(radians);
20826
+ item.position.z = x * Math.sin(radians) + z * Math.cos(radians);
20827
+ });
20828
+ }
20829
+ }
20830
+ _normalPattern(plankSize, floorWidth, floorLength, floorRotation) {
20831
+ const items = [];
20832
+ const stepOffsetAmount = .4;
20833
+ const plankWidth = plankSize.x;
20834
+ const plankLength = plankSize.z;
20835
+ const offsetSteps = plankWidth / stepOffsetAmount;
20836
+ const rows = Math.ceil(floorLength / plankLength);
20837
+ const columns = Math.ceil(floorWidth / plankWidth);
20838
+ const centerOffsetX = (floorWidth / 2 * -1) + (plankWidth / 2);
20839
+ const centerOffsetZ = (floorLength / 2 * -1) + (plankLength / 2);
20840
+ let currentOffsetStep = 0;
20841
+ for (let row = 0; row < rows; row++) {
20842
+ if (currentOffsetStep > offsetSteps) {
20843
+ currentOffsetStep = 0;
20844
+ }
20845
+ const plankPosZ = (plankLength * row);
20846
+ const currentOffsetAmount = stepOffsetAmount * currentOffsetStep;
20847
+ const planks = currentOffsetStep > 0 ? columns + 1 : columns;
20848
+ for (let col = 0; col < planks; col++) {
20849
+ const plankPosX = (plankWidth * col) - currentOffsetAmount;
20850
+ items.push({
20851
+ position: new Vector3(plankPosX + centerOffsetX, 0, plankPosZ + centerOffsetZ),
20852
+ rotation: new Vector3(0, MathUtils.degToRad(floorRotation), 0),
20853
+ isLeft: true
20854
+ });
20855
+ }
20856
+ currentOffsetStep++;
20857
+ }
20858
+ this._rotatePatternOnZAxis(items, floorRotation);
20859
+ return items;
20860
+ }
20861
+ _herringBone(plankSize, floorWidth, floorLength, floorRotation) {
20862
+ const items = [];
20863
+ const herringBoneAngle = 45;
20864
+ const sqrt2 = Math.sqrt(2);
20865
+ const plankWidth = plankSize.x;
20866
+ const plankLength = plankSize.z;
20867
+ const offsetPlankPosX = plankWidth * sqrt2;
20868
+ const offsetPlankPosZ = plankLength * sqrt2;
20869
+ const columns = Math.ceil(floorWidth / (plankWidth * sqrt2));
20870
+ const rows = Math.ceil(floorLength / (plankLength * sqrt2) +
20871
+ // add extra rows so that there isn't a gap
20872
+ offsetPlankPosX * 2);
20873
+ const centerOffsetX = floorWidth / 2 * -1 + offsetPlankPosX / 4 - offsetPlankPosZ / 4;
20874
+ const centerOffsetZ = floorLength / 2 * -1 - offsetPlankPosX / 4;
20875
+ for (let column = 0; column < columns; column++) {
20876
+ const plankPosX = offsetPlankPosX * column;
20877
+ for (let row = 0; row < rows; row++) {
20878
+ const plankPosZ = offsetPlankPosZ * row;
20879
+ const plankLeft = {
20880
+ position: new Vector3(plankPosX + centerOffsetX, 0, plankPosZ + centerOffsetZ),
20881
+ rotation: new Vector3(0, MathUtils.degToRad(floorRotation + herringBoneAngle), 0),
20882
+ isLeft: true
20883
+ };
20884
+ const plankRight = {
20885
+ position: new Vector3(plankPosX + offsetPlankPosX / 2 + centerOffsetX, 0, plankPosZ + offsetPlankPosZ / 2 + centerOffsetZ),
20886
+ rotation: new Vector3(0, MathUtils.degToRad(floorRotation - herringBoneAngle), 0),
20887
+ isLeft: false
20888
+ };
20889
+ items.push(plankLeft, plankRight);
20890
+ }
20891
+ }
20892
+ this._rotatePatternOnZAxis(items, floorRotation);
20893
+ return items;
20894
+ }
20895
+ _hon(plankSize, floorWidth, floorLength, floorRotation, patternAngle) {
20896
+ const items = [];
20897
+ const patternAngleRad = MathUtils.degToRad(patternAngle);
20898
+ const plankWidth = plankSize.x;
20899
+ const plankLength = plankSize.z;
20900
+ const sin = Math.sin(patternAngleRad);
20901
+ const cos = Math.cos(patternAngleRad);
20902
+ const overlapValue = plankLength * cos;
20903
+ const rowExtendValue = plankWidth * cos;
20904
+ const offsetZ = plankLength * cos * 2;
20905
+ const offsetX = plankWidth * sin;
20906
+ const centerOffsetX = (floorWidth - offsetX) / 2 + overlapValue;
20907
+ const centerOffsetZ = (floorLength + rowExtendValue) / 2;
20908
+ const columns = Math.ceil(floorWidth / ((offsetX - overlapValue) * 2));
20909
+ const rows = Math.ceil((floorLength + rowExtendValue) / offsetZ);
20910
+ for (let column = 0; column < columns; column++) {
20911
+ const plankPosX = column * (offsetX - overlapValue) * 2;
20912
+ for (let row = 0; row < rows; row++) {
20913
+ const plankPosZ = row * offsetZ;
20914
+ const plankLeft = {
20915
+ position: new Vector3(plankPosX - centerOffsetX, 0, plankPosZ - centerOffsetZ),
20916
+ rotation: new Vector3(0, MathUtils.degToRad((90 - patternAngle) + floorRotation), 0),
20917
+ isLeft: true
20918
+ };
20919
+ const plankRight = {
20920
+ position: new Vector3(plankPosX + offsetX - overlapValue - centerOffsetX, 0, plankPosZ - centerOffsetZ),
20921
+ rotation: new Vector3(0, MathUtils.degToRad((90 + patternAngle) + floorRotation), 0),
20922
+ isLeft: false
20923
+ };
20924
+ items.push(plankLeft, plankRight);
20925
+ }
20926
+ }
20927
+ this._rotatePatternOnZAxis(items, floorRotation);
20928
+ return items;
20929
+ }
20930
+ }
20931
+ FloorPatternService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: FloorPatternService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
20932
+ FloorPatternService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: FloorPatternService, providedIn: 'root' });
20933
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: FloorPatternService, decorators: [{
20934
+ type: Injectable,
20935
+ args: [{
20936
+ providedIn: 'root'
20937
+ }]
20938
+ }] });
20939
+
20604
20940
  var __awaiter$H = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
20605
20941
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
20606
20942
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -21058,6 +21394,123 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImpo
21058
21394
  }]
21059
21395
  }], ctorParameters: function () { return [{ type: SceneService }]; } });
21060
21396
 
21397
+ class FloorTileIntersectionService {
21398
+ constructor(_sceneService) {
21399
+ this._sceneService = _sceneService;
21400
+ this._debug = false;
21401
+ this._edgeCollisionMargin = 0.05;
21402
+ }
21403
+ toggleDebug() {
21404
+ this._debug = !this._debug;
21405
+ }
21406
+ countTiles(floorMesh, floorPattern, geometry) {
21407
+ const result = {
21408
+ left: 0,
21409
+ right: 0,
21410
+ edge: 0,
21411
+ total: 0,
21412
+ };
21413
+ console.log(floorMesh.position);
21414
+ const { floorHits, edgeHits } = this._checkIntersection2(floorMesh, floorPattern, geometry);
21415
+ for (const floorHit of floorHits) {
21416
+ if (floorHit.isLeft) {
21417
+ result.left += 1;
21418
+ }
21419
+ else {
21420
+ result.right += 1;
21421
+ }
21422
+ }
21423
+ result.edge = edgeHits.length;
21424
+ result.total = floorHits.length;
21425
+ return result;
21426
+ }
21427
+ _checkIntersection2(floorMesh, floorPattern, geometry) {
21428
+ // const edgeColliders = this._generateEdgeColliders(floorMesh.geometry);
21429
+ const result = {
21430
+ floorHits: new Array(),
21431
+ edgeHits: new Array()
21432
+ };
21433
+ const bvh = new MeshBVH(geometry);
21434
+ const positionReference = new Object3D();
21435
+ for (const floorItem of floorPattern) {
21436
+ const pos = floorItem.position;
21437
+ positionReference.position.set(pos.x, pos.y, pos.z);
21438
+ positionReference.updateMatrixWorld();
21439
+ const floorWorldToBhv = new Matrix4()
21440
+ .copy(positionReference.matrixWorld)
21441
+ .invert()
21442
+ .multiply(floorMesh.matrixWorld);
21443
+ if (bvh.intersectsGeometry(floorMesh.geometry, floorWorldToBhv)) {
21444
+ result.floorHits.push(floorItem);
21445
+ // TODO: find solution for edge detection, this should work as it used the same logic as for the floor.
21446
+ // for (const edgeCollider of edgeColliders) {
21447
+ // const edgeWorldToBhv = new Matrix4()
21448
+ // .copy(positionReference.matrixWorld)
21449
+ // .invert()
21450
+ // .multiply(edgeCollider.matrixWorld);
21451
+ // if (bvh.intersectsGeometry(edgeCollider.geometry, edgeWorldToBhv)) {
21452
+ // result.edgeHits.push(floorItem);
21453
+ // }
21454
+ // }
21455
+ }
21456
+ }
21457
+ return result;
21458
+ }
21459
+ _generateEdgeColliders(floorGeom) {
21460
+ const edgeLinesGeom = new EdgesGeometry(floorGeom);
21461
+ const linePositions = edgeLinesGeom.getAttribute('position').array;
21462
+ const edges = new Array();
21463
+ for (let i = 0; i < linePositions.length; i += 6) {
21464
+ // store vector a and b (1 line pair), because we work in 2D we skip the y-axis which should be zero
21465
+ const vectorA = new Vector2(linePositions[i], linePositions[i + 2]);
21466
+ const vectorB = new Vector2(linePositions[i + 3], linePositions[i + 5]);
21467
+ // calculate center of line
21468
+ const position = new Vector2().lerpVectors(vectorA, vectorB, .5);
21469
+ // calculate length
21470
+ const length = vectorA.distanceTo(vectorB);
21471
+ // create normalised orientation
21472
+ const unitVector = new Vector2().subVectors(vectorB, vectorA).normalize();
21473
+ // rotation in radians
21474
+ const rotation = Math.atan2(unitVector.y, unitVector.x);
21475
+ // create edge line with volume
21476
+ const edgeGeom = new BoxGeometry(length, 0.1, this._edgeCollisionMargin);
21477
+ const edge = new Mesh(edgeGeom);
21478
+ // position edge
21479
+ edge.rotation.y = rotation * -1;
21480
+ edge.position.z = position.y;
21481
+ edge.position.x = position.x;
21482
+ // update bounding box value for correct collision
21483
+ edge.updateMatrixWorld();
21484
+ edge.geometry.computeBoundingBox();
21485
+ edge.geometry.boundingBox.applyMatrix4(edge.matrixWorld);
21486
+ // adds meshes to scene
21487
+ edges.push(edge);
21488
+ }
21489
+ if (this._debug) {
21490
+ const scene = this._sceneService.scene;
21491
+ for (const edge of edges) {
21492
+ edge.material = this._randomColMat();
21493
+ scene.add(edge);
21494
+ }
21495
+ }
21496
+ return edges;
21497
+ }
21498
+ _randomColMat() {
21499
+ const color = new Color(Math.random(), Math.random(), Math.random());
21500
+ return new MeshBasicMaterial({ color: color, wireframe: false, side: DoubleSide });
21501
+ }
21502
+ ngOnDestroy() {
21503
+ }
21504
+ }
21505
+ FloorTileIntersectionService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: FloorTileIntersectionService, deps: [{ token: SceneService }], target: i0.ɵɵFactoryTarget.Injectable });
21506
+ FloorTileIntersectionService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: FloorTileIntersectionService, providedIn: 'root' });
21507
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: FloorTileIntersectionService, decorators: [{
21508
+ type: Injectable,
21509
+ args: [{
21510
+ providedIn: 'root'
21511
+ }]
21512
+ }], ctorParameters: function () { return [{ type: SceneService }]; } });
21513
+
21061
21514
  var __awaiter$G = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
21062
21515
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
21063
21516
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -21070,7 +21523,7 @@ var __awaiter$G = (this && this.__awaiter) || function (thisArg, _arguments, P,
21070
21523
  const defaultPosition$1 = new Vector3(4, 0, 1);
21071
21524
  const defaultRotation$1 = new Euler(0, Math.PI, 0);
21072
21525
  class BuildFurnitureService {
21073
- constructor(_dialog, _iOne, _threedSelectorService, _collisionManager, _messageBus, _dictionaryService, _hudService, _sceneService, _cameraService, _sceneEventService, _appEventService, _presetService, _itemService, _elementService, _permanentStoreService, _googleTagManager, _settingsService, _utilsService, _variationService, _appStateService, _errorService, _itemGroupService, _variationCacheService, _resizeService, _viewModeService, _floorService) {
21526
+ constructor(_dialog, _iOne, _threedSelectorService, _collisionManager, _messageBus, _dictionaryService, _hudService, _sceneService, _cameraService, _sceneEventService, _appEventService, _presetService, _itemService, _elementService, _permanentStoreService, _googleTagManager, _settingsService, _utilsService, _variationService, _appStateService, _errorService, _itemGroupService, _variationCacheService, _resizeService, _viewModeService, _floorService, _floorPatternService, _floorTileIntersectionService) {
21074
21527
  this._dialog = _dialog;
21075
21528
  this._iOne = _iOne;
21076
21529
  this._threedSelectorService = _threedSelectorService;
@@ -21097,6 +21550,8 @@ class BuildFurnitureService {
21097
21550
  this._resizeService = _resizeService;
21098
21551
  this._viewModeService = _viewModeService;
21099
21552
  this._floorService = _floorService;
21553
+ this._floorPatternService = _floorPatternService;
21554
+ this._floorTileIntersectionService = _floorTileIntersectionService;
21100
21555
  this.toggleSelectedElement = new Subject();
21101
21556
  this.configureModeChanged = new Subject();
21102
21557
  this.buildFinished = new Subject();
@@ -21377,6 +21832,10 @@ class BuildFurnitureService {
21377
21832
  const objectToExport = this._currentCustomFloorGroup ? this._currentCustomFloorGroup : this._itemService.items[0];
21378
21833
  this._utilsService.showExportDialog(objectToExport);
21379
21834
  }
21835
+ downloadUDSZforARIOS() {
21836
+ const objectToExport = this._currentCustomFloorGroup ? this._currentCustomFloorGroup : this._itemService.items[0];
21837
+ this._utilsService.downloadUSDZforARIOS(objectToExport);
21838
+ }
21380
21839
  downloadScene() {
21381
21840
  const assetPath = this._settingsService.settings.assetPath;
21382
21841
  // The ground plane looks odd in renders.
@@ -21444,6 +21903,7 @@ class BuildFurnitureService {
21444
21903
  }
21445
21904
  this._answerSelected.length = 0;
21446
21905
  this._hudService.updateSelectedItemHud();
21906
+ this._generateLayingPattern(item);
21447
21907
  this.buildFinished.next(result);
21448
21908
  if (result.resultType === ResultType.NoSelections) {
21449
21909
  result.resultType = ResultType.ConfigurationFixed;
@@ -21454,6 +21914,126 @@ class BuildFurnitureService {
21454
21914
  return result;
21455
21915
  });
21456
21916
  }
21917
+ _generateLayingPattern(floor) {
21918
+ const floorPatternInfo = this._generateFloorPatternInfo(floor);
21919
+ floor.restoreFloorObject();
21920
+ const meshLeft = this.full3DObjectToUse.children.find(m => m.name === floorPatternInfo.meshIdLeft);
21921
+ this._normalizeMesh(meshLeft);
21922
+ let meshRight = null;
21923
+ if (floorPatternInfo.meshIdRight !== null) {
21924
+ meshRight = this.full3DObjectToUse.children.find(m => m.name === floorPatternInfo.meshIdRight);
21925
+ this._normalizeMesh(meshRight);
21926
+ }
21927
+ const floorSize = floor.size;
21928
+ const plankSize = new Vector3();
21929
+ meshLeft.geometry.boundingBox.getSize(plankSize);
21930
+ const items = this._floorPatternService.generatePattern(floorPatternInfo.floorPattern, plankSize, floorSize, floorPatternInfo.floorPatternDirection);
21931
+ const itemAmount = (meshRight === null) ? items.length : items.length / 2;
21932
+ const material = floor.getMaterial();
21933
+ const planksLeft = new InstancedMesh(meshLeft.geometry, material, itemAmount);
21934
+ let planksRight;
21935
+ if (meshRight) {
21936
+ planksRight = new InstancedMesh(meshRight.geometry, material, itemAmount);
21937
+ }
21938
+ // assign transform to each item in instanced mesh
21939
+ const dummy = new Object3D();
21940
+ let matrixIndex = 0;
21941
+ for (let i = 0; i < items.length; i++) {
21942
+ const item = items[i];
21943
+ const targetPlankMesh = (item.isLeft) ? planksLeft : planksRight;
21944
+ const position = item.position;
21945
+ const rotation = item.rotation;
21946
+ dummy.position.set(position.x, position.y, position.z);
21947
+ dummy.rotation.set(rotation.x, rotation.y, rotation.z);
21948
+ dummy.updateMatrix();
21949
+ targetPlankMesh.setMatrixAt(matrixIndex, dummy.matrix);
21950
+ if (planksRight) {
21951
+ if (i !== 0 && (i % 2 !== 0)) {
21952
+ matrixIndex++;
21953
+ }
21954
+ }
21955
+ else {
21956
+ matrixIndex++;
21957
+ }
21958
+ }
21959
+ const customFloorWrapper = new Object3D();
21960
+ customFloorWrapper.add(planksLeft);
21961
+ if (planksRight)
21962
+ customFloorWrapper.add(planksRight);
21963
+ floor.floorObject = customFloorWrapper;
21964
+ // this._floorTileIntersectionService.toggleDebug();
21965
+ floor.metadata.floorCountResult = this._floorTileIntersectionService.countTiles(floor.floorMesh, items, meshLeft.geometry);
21966
+ }
21967
+ _generateFloorPatternInfo(item) {
21968
+ this._generateSelectedInMetadata(item);
21969
+ const info = {
21970
+ meshIdLeft: null,
21971
+ meshIdRight: null,
21972
+ floorPattern: FloorPattern.NORMAL,
21973
+ floorPatternDirection: FloorPatternDirection.LYING
21974
+ };
21975
+ const selected = item.metadata.selections;
21976
+ const afmeting = selected.find(s => s.question.toLowerCase() === 'plank afmeting');
21977
+ let afmetingString = afmeting.answer.toLowerCase();
21978
+ afmetingString = afmetingString.substr(afmetingString.lastIndexOf(' ') + 1);
21979
+ const legPatroonAnswer = selected.find(s => s.question.toLowerCase() === 'leg patroon').answer.toLowerCase();
21980
+ let legPatroonString = '';
21981
+ switch (true) {
21982
+ case legPatroonAnswer.indexOf('recht') !== -1:
21983
+ legPatroonString = '90';
21984
+ info.floorPattern = FloorPattern.NORMAL;
21985
+ break;
21986
+ case legPatroonAnswer.indexOf('graat') !== -1:
21987
+ legPatroonString = '90';
21988
+ info.floorPattern = FloorPattern.HERRINGBONE;
21989
+ break;
21990
+ case legPatroonAnswer.indexOf('60') !== -1:
21991
+ legPatroonString = '60';
21992
+ info.floorPattern = FloorPattern.HON60;
21993
+ break;
21994
+ case legPatroonAnswer.indexOf('45') !== -1:
21995
+ legPatroonString = '45';
21996
+ info.floorPattern = FloorPattern.HON45;
21997
+ break;
21998
+ }
21999
+ info.meshIdLeft = `${afmetingString}_${legPatroonString}`;
22000
+ if (info.floorPattern === FloorPattern.HON45 || info.floorPattern === FloorPattern.HON60) {
22001
+ info.meshIdRight = `r_${afmetingString}_${legPatroonString}`;
22002
+ }
22003
+ if (info.floorPattern === FloorPattern.HERRINGBONE) {
22004
+ info.meshIdRight = info.meshIdLeft;
22005
+ }
22006
+ const legRichtingAnswer = selected.find(s => s.question.toLowerCase() === 'leg richting').answer.toLowerCase();
22007
+ info.floorPatternDirection = (legRichtingAnswer.indexOf('verticaal') !== -1) ? FloorPatternDirection.STANDING : FloorPatternDirection.LYING;
22008
+ return info;
22009
+ }
22010
+ _generateSelectedInMetadata(item) {
22011
+ const cloneSelections = JSON.parse(JSON.stringify(this.selections));
22012
+ cloneSelections.forEach(s => {
22013
+ s.imageData = undefined;
22014
+ s.imageDataLastAnswer = undefined;
22015
+ if (s.addables) {
22016
+ s.addables.forEach(a => {
22017
+ a.imageData = undefined;
22018
+ });
22019
+ }
22020
+ });
22021
+ item.metadata.decos = Array.from(this._iOne.decoNodes);
22022
+ item.metadata.selections = cloneSelections;
22023
+ }
22024
+ _normalizeMesh(mesh) {
22025
+ const meshSize = new Vector3();
22026
+ mesh.geometry.computeBoundingBox();
22027
+ mesh.geometry.boundingBox.getSize(meshSize);
22028
+ if (meshSize.z > meshSize.x) {
22029
+ mesh.geometry.rotateY(Math.PI / 2);
22030
+ }
22031
+ mesh.geometry.center();
22032
+ mesh.geometry.computeBoundingBox();
22033
+ const center = new Vector3();
22034
+ mesh.geometry.boundingBox.getCenter(center);
22035
+ mesh.position.copy(center);
22036
+ }
21457
22037
  _startToBuildFromConfigurator(metadata) {
21458
22038
  return this.startToBuild(null, metadata);
21459
22039
  }
@@ -22331,14 +22911,14 @@ class BuildFurnitureService {
22331
22911
  }
22332
22912
  }
22333
22913
  }
22334
- BuildFurnitureService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: BuildFurnitureService, deps: [{ token: i1$1.MatDialog }, { token: HomedecoratorConnectorService }, { token: ThreedselectorService }, { token: CollisionManagerService }, { token: MessageBusService }, { token: HomedecoratorDictionaryService }, { token: HudService }, { token: SceneService }, { token: CameraService }, { token: SceneEventService }, { token: HomedecoratorAppEventService }, { token: PresetsService }, { token: ItemService }, { token: ElementService }, { token: PermanentStoreService }, { token: GoogleTagManagerService }, { token: HomedecoratorSettingsService }, { token: UtilsService }, { token: VariationService }, { token: AppStateService }, { token: ErrorService }, { token: ItemGroupService }, { token: VariationCacheService }, { token: ResizeService }, { token: ViewModeService }, { token: FloorService }], target: i0.ɵɵFactoryTarget.Injectable });
22914
+ BuildFurnitureService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: BuildFurnitureService, deps: [{ token: i1$1.MatDialog }, { token: HomedecoratorConnectorService }, { token: ThreedselectorService }, { token: CollisionManagerService }, { token: MessageBusService }, { token: HomedecoratorDictionaryService }, { token: HudService }, { token: SceneService }, { token: CameraService }, { token: SceneEventService }, { token: HomedecoratorAppEventService }, { token: PresetsService }, { token: ItemService }, { token: ElementService }, { token: PermanentStoreService }, { token: GoogleTagManagerService }, { token: HomedecoratorSettingsService }, { token: UtilsService }, { token: VariationService }, { token: AppStateService }, { token: ErrorService }, { token: ItemGroupService }, { token: VariationCacheService }, { token: ResizeService }, { token: ViewModeService }, { token: FloorService }, { token: FloorPatternService }, { token: FloorTileIntersectionService }], target: i0.ɵɵFactoryTarget.Injectable });
22335
22915
  BuildFurnitureService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: BuildFurnitureService, providedIn: 'root' });
22336
22916
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: BuildFurnitureService, decorators: [{
22337
22917
  type: Injectable,
22338
22918
  args: [{
22339
22919
  providedIn: 'root'
22340
22920
  }]
22341
- }], ctorParameters: function () { return [{ type: i1$1.MatDialog }, { type: HomedecoratorConnectorService }, { type: ThreedselectorService }, { type: CollisionManagerService }, { type: MessageBusService }, { type: HomedecoratorDictionaryService }, { type: HudService }, { type: SceneService }, { type: CameraService }, { type: SceneEventService }, { type: HomedecoratorAppEventService }, { type: PresetsService }, { type: ItemService }, { type: ElementService }, { type: PermanentStoreService }, { type: GoogleTagManagerService }, { type: HomedecoratorSettingsService }, { type: UtilsService }, { type: VariationService }, { type: AppStateService }, { type: ErrorService }, { type: ItemGroupService }, { type: VariationCacheService }, { type: ResizeService }, { type: ViewModeService }, { type: FloorService }]; } });
22921
+ }], ctorParameters: function () { return [{ type: i1$1.MatDialog }, { type: HomedecoratorConnectorService }, { type: ThreedselectorService }, { type: CollisionManagerService }, { type: MessageBusService }, { type: HomedecoratorDictionaryService }, { type: HudService }, { type: SceneService }, { type: CameraService }, { type: SceneEventService }, { type: HomedecoratorAppEventService }, { type: PresetsService }, { type: ItemService }, { type: ElementService }, { type: PermanentStoreService }, { type: GoogleTagManagerService }, { type: HomedecoratorSettingsService }, { type: UtilsService }, { type: VariationService }, { type: AppStateService }, { type: ErrorService }, { type: ItemGroupService }, { type: VariationCacheService }, { type: ResizeService }, { type: ViewModeService }, { type: FloorService }, { type: FloorPatternService }, { type: FloorTileIntersectionService }]; } });
22342
22922
 
22343
22923
  var __awaiter$F = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22344
22924
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -27249,13 +27829,15 @@ class NewRenderService {
27249
27829
  _getNewRenderImage(force = false) {
27250
27830
  return __awaiter$x(this, void 0, void 0, function* () {
27251
27831
  if (this._settingsService.settings.blenderRenderService) {
27252
- this.messageService.emit(MessageType.ShowLoadingIndicator, { title: 'Rendering...' });
27253
- const renderInput = {
27254
- 'height': 800,
27255
- 'width': 1200,
27256
- 'sceneAssetId': this._settingsService.settings.productRenderSceneAssetId
27257
- };
27258
- yield this._utilsService.prepRoomForRender(true, renderInput);
27832
+ const data = this._getDataForRender(force);
27833
+ this._handleAjaxBlenderRender(data);
27834
+ // this.messageService.emit(MessageType.ShowLoadingIndicator, {title: 'Rendering...'});
27835
+ // const renderInput = {
27836
+ // 'height': 800,
27837
+ // 'width': 1200,
27838
+ // 'sceneAssetId': this._settingsService.settings.productRenderSceneAssetId
27839
+ // };
27840
+ // await this._utilsService.prepRoomForRender(true, renderInput);
27259
27841
  }
27260
27842
  else {
27261
27843
  const data = this._getDataForRender(force);
@@ -27268,6 +27850,25 @@ class NewRenderService {
27268
27850
  }
27269
27851
  });
27270
27852
  }
27853
+ _handleAjaxBlenderRender(data) {
27854
+ return __awaiter$x(this, void 0, void 0, function* () {
27855
+ const result = yield axios({
27856
+ headers: {
27857
+ 'Content-Type': 'application/json'
27858
+ },
27859
+ method: 'POST',
27860
+ data: JSON.stringify(data),
27861
+ url: `${this._settingsService.settings.newRenderParameters.host}:${this._settingsService.settings.newRenderParameters.port}/getBlenderRenderFromData`,
27862
+ responseType: 'json'
27863
+ });
27864
+ if (result.status === 200) {
27865
+ // const image = `data:${result.data.fileType};base64,${result.data.image}`;
27866
+ // this._showPreviewImage(result.data.image);
27867
+ // console.log(image);
27868
+ this.renderImageChanged.next(result.data.image);
27869
+ }
27870
+ });
27871
+ }
27271
27872
  _handleAjaxRender(data) {
27272
27873
  return __awaiter$x(this, void 0, void 0, function* () {
27273
27874
  const result = yield axios({
@@ -27280,10 +27881,10 @@ class NewRenderService {
27280
27881
  responseType: 'json'
27281
27882
  });
27282
27883
  if (result.status === 200) {
27283
- const image = `data:${result.data.fileType};base64,${result.data.image}`;
27284
- // this._showPreviewImage(image);
27884
+ // const image = `data:${result.data.fileType};base64,${result.data.image}`;
27885
+ // this._showPreviewImage(result.data.image);
27285
27886
  // console.log(image);
27286
- this.renderImageChanged.next(image);
27887
+ this.renderImageChanged.next(result.data.image);
27287
27888
  }
27288
27889
  });
27289
27890
  }
@@ -27338,21 +27939,24 @@ class NewRenderService {
27338
27939
  img.style.position = 'fixed';
27339
27940
  img.style.top = '0';
27340
27941
  img.style.left = '0';
27341
- img.style.width = '800px';
27942
+ // img.style.width = '800px';
27342
27943
  img.style.height = '600px';
27343
27944
  img.style.zIndex = '10';
27344
27945
  }
27345
27946
  img.src = src;
27346
27947
  }
27347
27948
  _getDataForRender(force = false) {
27949
+ this._cameraService.camera.updateMatrixWorld(true);
27950
+ const camMatrix = Array.from(this._cameraService.camera.matrixWorld.elements);
27348
27951
  const options = {
27349
27952
  force: force,
27350
27953
  width: this._settingsService.settings.newRenderParameters.imageWidth,
27351
27954
  height: this._settingsService.settings.newRenderParameters.imageHeight,
27955
+ sceneAssetId: this._settingsService.settings.productRenderSceneAssetId,
27352
27956
  max_samples: this._settingsService.settings.newRenderParameters.iterations,
27353
27957
  cameraOptions: {
27354
27958
  fov: this._cameraService.camera.fov,
27355
- matrix: this.standAloneCameraMatrix
27959
+ matrix: camMatrix
27356
27960
  },
27357
27961
  environmentOptions: {
27358
27962
  hdri: this._settingsService.settings.newRenderParameters.hdri,
@@ -27980,7 +28584,7 @@ class ArGuiButtonsComponent {
27980
28584
  }
27981
28585
  }
27982
28586
  ArGuiButtonsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ArGuiButtonsComponent, deps: [{ token: HomedecoratorIconCacheService }, { token: ArService }], target: i0.ɵɵFactoryTarget.Component });
27983
- ArGuiButtonsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.17", type: ArGuiButtonsComponent, selector: "ar-gui-buttons", ngImport: i0, template: "<div class=\"buttons-container\">\r\n <div class=\"button-container\" xmlns=\"http://www.w3.org/1999/html\">\r\n <button mat-mini-fab class=\"button-icon back\" (click)=\"endSession()\">\r\n <co-icon class=\"icon rotated\" [iconData]=\"iconService.getIcon(icon.TriangleDown)\"></co-icon>\r\n </button>\r\n </div>\r\n\r\n <div class=\"button-container\" xmlns=\"http://www.w3.org/1999/html\">\r\n <button class=\"button-icon\" mat-mini-fab (click)=\"showConfigurator()\">\r\n <co-icon class=\"icon\" [iconData]=\"iconService.getIcon(icon.MagicWand)\"></co-icon>\r\n </button>\r\n </div>\r\n</div>\r\n", styles: [".buttons-container{position:absolute;display:flex;left:50%;bottom:0;transform:translate(-50%)}.button-container{padding:20px}.button-icon{text-align:-webkit-center}.back{padding-right:3px}.icon{width:65%;height:65%;fill:#fff}.rotated{transform:rotate(90deg)}\n"], components: [{ type: i3$1.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4$1.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }] });
28587
+ ArGuiButtonsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.17", type: ArGuiButtonsComponent, selector: "ar-gui-buttons", ngImport: i0, template: "<div class=\"buttons-container\">\r\n <div class=\"button-container\" xmlns=\"http://www.w3.org/1999/html\">\r\n <button mat-mini-fab class=\"button-icon back\" (click)=\"endSession()\">\r\n <co-icon class=\"icon rotated\" [iconData]=\"iconService.getIcon(icon.Cross)\"></co-icon>\r\n </button>\r\n </div>\r\n\r\n <!--div class=\"button-container\" xmlns=\"http://www.w3.org/1999/html\">\r\n <button class=\"button-icon\" mat-mini-fab (click)=\"showConfigurator()\">\r\n <co-icon class=\"icon\" [iconData]=\"iconService.getIcon(icon.MagicWand)\"></co-icon>\r\n </button>\r\n </div-->\r\n</div>\r\n", styles: [".buttons-container{position:absolute;display:flex;right:15px;top:15px}.button-container{padding:20px}.button-icon{text-align:-webkit-center}.back{padding-right:3px}.icon{width:65%;height:65%;fill:#fff}.rotated{transform:rotate(90deg)}\n"], components: [{ type: i3$1.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4$1.IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }] });
27984
28588
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ArGuiButtonsComponent, decorators: [{
27985
28589
  type: Component,
27986
28590
  args: [{
@@ -28492,7 +29096,7 @@ SelectionsSummaryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0
28492
29096
  <mat-icon class="homedecorator-material-icons" aria-hidden="true">close</mat-icon>
28493
29097
  </button>
28494
29098
  </header>
28495
- <div class="selections-content small-scrollbar">
29099
+ <div class="selections-content small-scrollbar" *ngIf="selections && selections.length > 0">
28496
29100
  <ng-container *ngFor="let sel of selections; let index = index">
28497
29101
  <rp-selections-summary-line
28498
29102
  [selection]="sel"
@@ -28531,7 +29135,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImpo
28531
29135
  <mat-icon class="homedecorator-material-icons" aria-hidden="true">close</mat-icon>
28532
29136
  </button>
28533
29137
  </header>
28534
- <div class="selections-content small-scrollbar">
29138
+ <div class="selections-content small-scrollbar" *ngIf="selections && selections.length > 0">
28535
29139
  <ng-container *ngFor="let sel of selections; let index = index">
28536
29140
  <rp-selections-summary-line
28537
29141
  [selection]="sel"
@@ -38881,7 +39485,20 @@ class ThreedselectorComponent {
38881
39485
  }
38882
39486
  }
38883
39487
  };
39488
+ const arIOSButton = {
39489
+ id: 3,
39490
+ elementId: 'standalone_ar_session',
39491
+ tooltip: 'START_AR_SESSION',
39492
+ order: 10,
39493
+ image: this._iconCacheService.getIconAsBase64(IconEnum.ArCircle),
39494
+ toggle: false,
39495
+ show: (yield this._arService.arIOSSupported()) &&
39496
+ this._settingsService.settings.options.showStandaloneARButton &&
39497
+ this._settingsService.settings.options.arEnabled,
39498
+ click: () => this._buildFurnitureService.downloadUDSZforARIOS()
39499
+ };
38884
39500
  this._sceneOptionsService.addSceneOptionButton(arButton);
39501
+ this._sceneOptionsService.addSceneOptionButton(arIOSButton);
38885
39502
  }
38886
39503
  });
38887
39504
  }
@@ -39232,10 +39849,7 @@ class ThreedselectorComponent {
39232
39849
  // }
39233
39850
  const len = selection.decoNode ? selection.decoNode.connectors.length : 0;
39234
39851
  for (let i = 0; i < len; i++) {
39235
- let conObject = this._selectedElementObject.getObjectByName(selection.decoNode.connectors[i].connector);
39236
- if (!conObject && this._selectedElementObject.parent) {
39237
- conObject = this._selectedElementObject.parent.getObjectByName(selection.decoNode.connectors[i].connector);
39238
- }
39852
+ const conObject = this._getConnectorObject(this._selectedElementObject, selection.decoNode.connectors[i].connector);
39239
39853
  if (conObject && this._canShowAddButton(selection.decoNode.connectors[i], conObject)) {
39240
39854
  this.editAddButtons.push(new CustomButton('', () => {
39241
39855
  this._handleAddButtonClick(selection, selection.decoNode.connectors[i], this._selectedElementObject);
@@ -39258,6 +39872,23 @@ class ThreedselectorComponent {
39258
39872
  });
39259
39873
  }
39260
39874
  }
39875
+ _getConnectorObject(obj, connector) {
39876
+ if (!obj) {
39877
+ return null;
39878
+ }
39879
+ const objFound = obj.getObjectByName(connector);
39880
+ if (objFound) {
39881
+ return objFound;
39882
+ }
39883
+ else {
39884
+ if (obj.parent) {
39885
+ return this._getConnectorObject(obj.parent, connector);
39886
+ }
39887
+ else {
39888
+ return null;
39889
+ }
39890
+ }
39891
+ }
39261
39892
  _getOppositeConnectorParts(connector) {
39262
39893
  const connectorPartsArr = connector.split('_');
39263
39894
  connectorPartsArr.pop(); // remove number
@@ -40813,7 +41444,7 @@ var __awaiter$4 = (this && this.__awaiter) || function (thisArg, _arguments, P,
40813
41444
  });
40814
41445
  };
40815
41446
  class ModelPreviewComponent {
40816
- constructor(data, settingsService, _dialogRef, _thirdPartyModelService, _messageService, _dialog, _adapterService) {
41447
+ constructor(data, settingsService, _dialogRef, _thirdPartyModelService, _messageService, _dialog, _adapterService, _lightPresetsService, _dictionaryService, _fontService) {
40817
41448
  this.data = data;
40818
41449
  this.settingsService = settingsService;
40819
41450
  this._dialogRef = _dialogRef;
@@ -40821,8 +41452,21 @@ class ModelPreviewComponent {
40821
41452
  this._messageService = _messageService;
40822
41453
  this._dialog = _dialog;
40823
41454
  this._adapterService = _adapterService;
41455
+ this._lightPresetsService = _lightPresetsService;
41456
+ this._dictionaryService = _dictionaryService;
41457
+ this._fontService = _fontService;
40824
41458
  this.unitsOfMeasurement = 'cm';
40825
41459
  this.mathPi = Math.PI;
41460
+ this.showReferenceModel = true;
41461
+ this.floorSizeHeight = 10;
41462
+ this.floorSizeWidth = 10;
41463
+ this.gridSize = 10;
41464
+ this.gridDivision = 10;
41465
+ this.distanceStep = 1;
41466
+ this.stackable = false;
41467
+ this.heightAdjustable = false;
41468
+ this._measurements = [];
41469
+ this.font = this._fontService.hudFont;
40826
41470
  }
40827
41471
  ngOnInit() {
40828
41472
  this.initScene();
@@ -40856,44 +41500,50 @@ class ModelPreviewComponent {
40856
41500
  this.rendererPreview.domElement.setAttribute('id', 'threed');
40857
41501
  this.rendererPreview.setSize(window.innerWidth / 2, window.innerHeight / 2, true);
40858
41502
  // init camera
40859
- this.cameraPreview = new PerspectiveCamera(45, 1, 0.01, 10000);
41503
+ this.cameraPreview = new PerspectiveCamera(45, 1, 0.01, 100000000);
40860
41504
  this.cameraPreview.position.set(0, 2, 10);
40861
41505
  this.cameraPreview.aspect = window.innerWidth / window.innerHeight;
40862
41506
  this.cameraPreview.updateProjectionMatrix();
40863
41507
  this.controls = new OrbitControls(this.cameraPreview, this.rendererPreview.domElement);
40864
41508
  this.controls.update();
40865
- const box1geo = new BoxGeometry(1, 1, 1);
40866
- const box1 = new Mesh(box1geo, new MeshBasicMaterial({ color: 0x0000ff }));
40867
- box1.position.set(3, 0.5, 3);
40868
- box1.castShadow = true;
40869
- box1.receiveShadow = true;
40870
- box1.name = 'Reference_model';
40871
- this.scenePreview.add(box1);
40872
- const planeGeometry = new PlaneGeometry(10, 10);
40873
- const planeMaterial = new MeshBasicMaterial({ color: 0xFAF9F6, side: THREE.DoubleSide });
41509
+ this.loadFloorPlane();
41510
+ this.loadReferenceModel();
41511
+ this.loadLights();
41512
+ const gridHelper = new GridHelper(this.gridSize, this.gridDivision);
41513
+ gridHelper.name = 'GridHelper';
41514
+ this.scenePreview.add(gridHelper);
41515
+ this._animate();
41516
+ }
41517
+ loadFloorPlane() {
41518
+ const planeGeometry = new PlaneGeometry(this.floorSizeWidth, this.floorSizeHeight);
41519
+ const planeMaterial = new MeshBasicMaterial({ color: 0x899499, side: THREE.DoubleSide });
40874
41520
  const plane = new Mesh(planeGeometry, planeMaterial);
40875
41521
  plane.rotation.x = -Math.PI / 2;
40876
41522
  plane.position.y = 0;
40877
41523
  plane.name = 'floor_plane';
40878
41524
  this.scenePreview.add(plane);
40879
- // Add some basic lights for when models contains MeshLambertMaterial
40880
- const ambientLight = new AmbientLight(0x404040);
40881
- this.scenePreview.add(ambientLight);
40882
- const directionalLight = new DirectionalLight(0xffffff, 8);
40883
- directionalLight.position.set(0, 10, 0);
40884
- directionalLight.castShadow = true;
40885
- this.scenePreview.add(directionalLight);
40886
- const pointLight = new PointLight(0xffffff, 1, 100);
40887
- pointLight.position.set(0, 5, 5);
40888
- this.scenePreview.add(pointLight);
40889
- // basic hdri lighting
40890
- const hdriPath = '/assets/hdri/std_env_v2_A.hdr';
40891
- this.loadHDRI(hdriPath).then(() => {
40892
- // console.log('HDRI loaded successfully.');
40893
- }).catch((error) => {
40894
- // console.error('Error loading HDRI:', error);
40895
- });
40896
- this._animate();
41525
+ }
41526
+ loadLights() {
41527
+ const listOfLightPresets = this._lightPresetsService.loadedLightPresets;
41528
+ const lightPreset = this._lightPresetsService.activeLightPreset;
41529
+ for (const lightProperties of lightPreset.lights) {
41530
+ this._createLightFromProperties(lightProperties);
41531
+ }
41532
+ }
41533
+ loadReferenceModel() {
41534
+ let referenceModelPath = '';
41535
+ const referenceModel = 'reference_pop.glb';
41536
+ if (this.settingsService.settings.threeDAssetPath) {
41537
+ referenceModelPath = this.settingsService.settings.threeDAssetPath + 'assets/';
41538
+ }
41539
+ const loader = new GLTFLoader();
41540
+ loader.load(referenceModelPath + referenceModel, (gltf) => __awaiter$4(this, void 0, void 0, function* () {
41541
+ gltf.scene.position.set(3, 0, 3);
41542
+ gltf.scene.castShadow = true;
41543
+ gltf.scene.receiveShadow = true;
41544
+ gltf.scene.name = 'Reference_model';
41545
+ this.scenePreview.add(gltf.scene);
41546
+ }));
40897
41547
  }
40898
41548
  loadModel(input) {
40899
41549
  this.modelName = this._setModelName(input.file.file.name);
@@ -40910,6 +41560,9 @@ class ModelPreviewComponent {
40910
41560
  else if (fileType === '3ds') {
40911
41561
  this._tdsLoader(input);
40912
41562
  }
41563
+ else if (fileType === 'stl') {
41564
+ this._stlLoader(input);
41565
+ }
40913
41566
  }
40914
41567
  loadHDRI(path) {
40915
41568
  return new Promise((resolve, reject) => {
@@ -40929,11 +41582,10 @@ class ModelPreviewComponent {
40929
41582
  // add timestamp
40930
41583
  const timestamp = new Date().getTime();
40931
41584
  const exportFileName = this._setModelName(this.glbExportName.nativeElement.value) + '_' + timestamp;
40932
- const elementsToRemove = ['Reference_model', 'floor_plane'];
41585
+ const elementsToRemove = ['Reference_model', 'floor_plane', 'GridHelper', 'Ambient', 'Directional front-left', 'spot back (anti-sun)', 'boxHeight', 'boxWidth', 'boxDepth'];
40933
41586
  const gltfExporter = new GLTFExporter();
40934
41587
  let scene;
40935
41588
  scene = this.scenePreview.clone();
40936
- scene.environment.dispose();
40937
41589
  scene.children.forEach(c => {
40938
41590
  if (c instanceof Light) {
40939
41591
  scene.remove(c);
@@ -40958,7 +41610,8 @@ class ModelPreviewComponent {
40958
41610
  else {
40959
41611
  this._downloadModel(`${exportFileName}.glb`, file);
40960
41612
  }
40961
- }, () => {
41613
+ }, (e) => {
41614
+ console.log(e);
40962
41615
  }, options);
40963
41616
  }
40964
41617
  scaleArticle() {
@@ -40987,9 +41640,33 @@ class ModelPreviewComponent {
40987
41640
  }
40988
41641
  this._getBoundingBox(model);
40989
41642
  }
41643
+ moveModel(axis, amount) {
41644
+ const model = this.scenePreview.getObjectByName(this.modelName);
41645
+ if (axis === 'x') {
41646
+ model.position.x += amount;
41647
+ }
41648
+ else if (axis === 'y') {
41649
+ model.position.y += amount;
41650
+ }
41651
+ else if (axis === 'z') {
41652
+ model.position.z += amount;
41653
+ }
41654
+ this._getBoundingBox(model);
41655
+ }
40990
41656
  setUnit(event) {
40991
41657
  this.unitsOfMeasurement = event.value;
40992
41658
  }
41659
+ toggleShowReferenceModel() {
41660
+ const model = this.scenePreview.getObjectByName('Reference_model');
41661
+ model.visible = !this.showReferenceModel;
41662
+ this.showReferenceModel = !this.showReferenceModel;
41663
+ }
41664
+ setStackable(event) {
41665
+ this.stackable = event.value;
41666
+ }
41667
+ setHeightAdjustable(event) {
41668
+ this.heightAdjustable = event.value;
41669
+ }
40993
41670
  _animate() {
40994
41671
  setTimeout(() => {
40995
41672
  this.rendererPreview.setAnimationLoop((timestamp, frame) => this._render(timestamp, frame));
@@ -41011,21 +41688,29 @@ class ModelPreviewComponent {
41011
41688
  }
41012
41689
  _sendModelToCDN(fileName, blob) {
41013
41690
  return __awaiter$4(this, void 0, void 0, function* () {
41014
- this._blobToArrayBuffer(blob).then(file => {
41015
- this._adapterService.store3DModelCDN(fileName, file).then(filePath => {
41016
- console.log(filePath);
41691
+ const reader = new FileReader();
41692
+ reader.readAsDataURL(blob);
41693
+ reader.onloadend = (event) => __awaiter$4(this, void 0, void 0, function* () {
41694
+ const fileAsString = FileUtils.StripMimeStringFromDataUri(event.target.result);
41695
+ this._adapterService.store3DModelCDN(fileName, fileAsString).then(filePath => {
41696
+ if (filePath) {
41697
+ this._blobToArrayBuffer(blob).then(file => {
41698
+ const hash = fileName;
41699
+ const modelUrl = filePath; // Set url from the CDN
41700
+ const configurationData = {};
41701
+ const priceData = {};
41702
+ const metaData = this._thirdPartyModelService.setMetadata(hash, modelUrl, configurationData);
41703
+ metaData.canElevate = this.heightAdjustable;
41704
+ metaData.thirdPartyModel = true;
41705
+ // We also can set the metadata here and pas it as the last argument for parseModelToGLB.
41706
+ this._thirdPartyModelService.parseModelToGLB(file, hash, modelUrl, configurationData, priceData, metaData).then(result => {
41707
+ this._dialog.closeAll();
41708
+ this._messageService.emit(MessageType.HideProductCatalog);
41709
+ });
41710
+ });
41711
+ }
41017
41712
  });
41018
41713
  });
41019
- // const hash: string = fileName;
41020
- // const modelUrl: string = ''; // Set url from the CDN
41021
- // const configurationData: any = {};
41022
- // const priceData: any = {};
41023
- // // const metaData: Metadata = new Metadata();
41024
- // // We also can set the metadata here and pas it as the last argument for parseModelToGLB.
41025
- //
41026
- // await this._thirdPartyModelService.parseModelToGLB(file, hash, modelUrl, configurationData, priceData);
41027
- // this._dialog.closeAll();
41028
- // this._messageService.emit(MessageType.HideProductCatalog);
41029
41714
  });
41030
41715
  }
41031
41716
  _setModelName(name) {
@@ -41035,12 +41720,7 @@ class ModelPreviewComponent {
41035
41720
  _glbLoader(input) {
41036
41721
  const loader = new GLTFLoader();
41037
41722
  loader.parse(input.file.fileContents, '', (object) => __awaiter$4(this, void 0, void 0, function* () {
41038
- object.scene.name = this.modelName;
41039
- object.scene.position.set(0, 0, 0);
41040
- object.scene.scale.set(1, 1, 1);
41041
- this.scenePreview.add(object.scene);
41042
- this.loadedModel = object.scene;
41043
- this._getBoundingBox(object.scene);
41723
+ this._prepModelForScene(object.scene);
41044
41724
  }), error => {
41045
41725
  console.log('Parsing error');
41046
41726
  });
@@ -41048,12 +41728,7 @@ class ModelPreviewComponent {
41048
41728
  _fbxLoader(input) {
41049
41729
  const fbxLoader = new FBXLoader();
41050
41730
  const object = fbxLoader.parse(input.file.fileContents, '');
41051
- object.name = this.modelName;
41052
- object.position.set(0, 0, 0);
41053
- object.scale.set(1, 1, 1);
41054
- this.scenePreview.add(object);
41055
- this.loadedModel = object;
41056
- this._getBoundingBox(object);
41731
+ this._prepModelForScene(object);
41057
41732
  }
41058
41733
  _objLoader(input) {
41059
41734
  const objLoader = new OBJLoader();
@@ -41062,26 +41737,105 @@ class ModelPreviewComponent {
41062
41737
  const decoder = new TextDecoder();
41063
41738
  const str = decoder.decode(buf);
41064
41739
  const object = objLoader.parse(str);
41065
- object.name = this.modelName;
41066
- object.position.set(0, 0, 0);
41067
- object.scale.set(1, 1, 1);
41068
- this.scenePreview.add(object);
41069
- this.loadedModel = object;
41070
- this._getBoundingBox(object);
41740
+ this._prepModelForScene(object);
41071
41741
  }
41072
41742
  _tdsLoader(input) {
41073
41743
  const tdsLoader = new TDSLoader();
41074
41744
  const object = tdsLoader.parse(input.file.fileContents, '');
41745
+ object.traverse(element => {
41746
+ console.log(element);
41747
+ });
41748
+ this._prepModelForScene(object);
41749
+ }
41750
+ _stlLoader(input) {
41751
+ const stlLoader = new STLLoader();
41752
+ const object = stlLoader.parse(input.file.fileContents);
41753
+ this._addFromGeometry(object);
41754
+ }
41755
+ _addFromGeometry(geometry) {
41756
+ const material = new MeshPhongMaterial({ transparent: true, opacity: geometry.alpha });
41757
+ const model = new Mesh(geometry, material);
41758
+ this._prepModelForScene(model);
41759
+ }
41760
+ _prepModelForScene(object) {
41075
41761
  object.name = this.modelName;
41076
41762
  object.position.set(0, 0, 0);
41077
41763
  object.scale.set(1, 1, 1);
41764
+ // Remove lights from the children
41765
+ object.children.forEach(c => {
41766
+ if (c instanceof Light) {
41767
+ object.remove(c);
41768
+ }
41769
+ });
41078
41770
  this.scenePreview.add(object);
41079
41771
  this.loadedModel = object;
41080
41772
  this._getBoundingBox(object);
41081
41773
  }
41082
41774
  _getBoundingBox(object) {
41083
- const boundingBox = new THREE.Box3().setFromObject(object);
41775
+ const boundingBox = new Box3().setFromObject(object);
41084
41776
  this.boundingBoxSize = boundingBox.getSize(new Vector3());
41777
+ this._setMeasurements(this.boundingBoxSize);
41778
+ this._showMeasurements();
41779
+ }
41780
+ _showMeasurements() {
41781
+ const measurementsMeshes = this._measurements.map(value => value.textMesh);
41782
+ measurementsMeshes.forEach(object => this.scenePreview.add(object));
41783
+ }
41784
+ _setMeasurements(boundingBox) {
41785
+ const setHeight = this._createHeightMeasurement(boundingBox.y);
41786
+ this._measurements.push(setHeight);
41787
+ const setWidth = this._createWidthMeasurement(boundingBox.x);
41788
+ this._measurements.push(setWidth);
41789
+ const setDepth = this._createDepthMeasurement(boundingBox.z);
41790
+ this._measurements.push(setDepth);
41791
+ }
41792
+ _createHeightMeasurement(heightInput) {
41793
+ const height = new BoxMeasurement();
41794
+ const heightString = MeasurementUtils.makeText(heightInput, this.unitsOfMeasurement, this.distanceStep);
41795
+ const text = this._dictionaryService.get('LABEL_HEIGHT');
41796
+ height.textMesh = makeTextMesh(heightString, this.font, 0xFF00FF, 0.08, false, false, text);
41797
+ height.positions = this._calculateHeightPositions();
41798
+ height.textMesh.name = 'boxHeight';
41799
+ return height;
41800
+ }
41801
+ _createWidthMeasurement(widthInput) {
41802
+ const width = new BoxMeasurement();
41803
+ const widthString = MeasurementUtils.makeText(widthInput, this.unitsOfMeasurement, this.distanceStep);
41804
+ const text = this._dictionaryService.get('LABEL_WIDTH');
41805
+ width.textMesh = makeTextMesh(widthString, this.font, 0xFF00FF, 0.08, false, false, text);
41806
+ width.positions = this._calculateWidthPositions();
41807
+ width.textMesh.name = 'boxWidth';
41808
+ return width;
41809
+ }
41810
+ _createDepthMeasurement(depthInput) {
41811
+ const depth = new BoxMeasurement();
41812
+ const depthString = MeasurementUtils.makeText(depthInput, this.unitsOfMeasurement, this.distanceStep);
41813
+ const text = this._dictionaryService.get('LABEL_DEPTH');
41814
+ depth.textMesh = makeTextMesh(depthString, this.font, 0xFF00FF, 0.08, false, false, text);
41815
+ depth.positions = this._calculateDepthPositions();
41816
+ depth.textMesh.name = 'boxDepth';
41817
+ return depth;
41818
+ }
41819
+ _calculateHeightPositions() {
41820
+ return positioningFactors.map(([j, k]) => {
41821
+ return new THREE.Vector3()
41822
+ .addScaledVector(xDirection, j / 2 * this.boundingBoxSize.x)
41823
+ .addScaledVector(zDirection, k / 2 * this.boundingBoxSize.z);
41824
+ });
41825
+ }
41826
+ _calculateWidthPositions() {
41827
+ return positioningFactors.map(([j, k]) => {
41828
+ return new THREE.Vector3()
41829
+ .addScaledVector(yDirection, j / 2 * this.boundingBoxSize.y)
41830
+ .addScaledVector(zDirection, k / 2 * this.boundingBoxSize.z);
41831
+ });
41832
+ }
41833
+ _calculateDepthPositions() {
41834
+ return positioningFactors.map(([j, k]) => {
41835
+ return new THREE.Vector3()
41836
+ .addScaledVector(yDirection, j / 2 * this.boundingBoxSize.y)
41837
+ .addScaledVector(xDirection, k / 2 * this.boundingBoxSize.x);
41838
+ });
41085
41839
  }
41086
41840
  _blobToArrayBuffer(blob) {
41087
41841
  return new Promise((resolve, reject) => {
@@ -41100,8 +41854,47 @@ class ModelPreviewComponent {
41100
41854
  reader.readAsArrayBuffer(blob);
41101
41855
  });
41102
41856
  }
41857
+ _createLightFromProperties(lightProperties) {
41858
+ const lightType = lightProperties.type;
41859
+ const getLights = new LightCreateService();
41860
+ const light = getLights.createNewLight(lightType);
41861
+ light.userData.wallOffset = lightProperties.wallOffset;
41862
+ light.userData.rotationOffset = lightProperties.rotationOffset;
41863
+ light.userData.topDownDirectional = lightProperties.topDownDirectional;
41864
+ for (const property in lightProperties) {
41865
+ if (!light.hasOwnProperty(property)) {
41866
+ continue;
41867
+ }
41868
+ if (property === 'position') {
41869
+ light.position.y = lightProperties.position.y;
41870
+ }
41871
+ else if (property === 'color') {
41872
+ light.color = new Color(lightProperties.color);
41873
+ }
41874
+ else if (property === 'groundColor') {
41875
+ light.groundColor = new Color(lightProperties.groundColor);
41876
+ }
41877
+ else {
41878
+ this._setObjectProperties(light, property, lightProperties[property]);
41879
+ }
41880
+ }
41881
+ this.scenePreview.add(light);
41882
+ }
41883
+ _setObjectProperties(object, property, value) {
41884
+ if (property === 'shadow') {
41885
+ for (const prop in value) {
41886
+ if (!object[property].hasOwnProperty(prop)) {
41887
+ continue;
41888
+ }
41889
+ object[property][prop] = value[prop];
41890
+ }
41891
+ }
41892
+ else {
41893
+ object[property] = value;
41894
+ }
41895
+ }
41103
41896
  }
41104
- ModelPreviewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ModelPreviewComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: HomedecoratorSettingsService }, { token: i1$1.MatDialogRef }, { token: ThirdPartyModelService }, { token: MessageBusService }, { token: i1$1.MatDialog }, { token: HomedecoratorConnectorAdapterService }], target: i0.ɵɵFactoryTarget.Component });
41897
+ ModelPreviewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ModelPreviewComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: HomedecoratorSettingsService }, { token: i1$1.MatDialogRef }, { token: ThirdPartyModelService }, { token: MessageBusService }, { token: i1$1.MatDialog }, { token: HomedecoratorConnectorAdapterService }, { token: LightPresetsService }, { token: HomedecoratorDictionaryService }, { token: FontService }], target: i0.ɵɵFactoryTarget.Component });
41105
41898
  ModelPreviewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.17", type: ModelPreviewComponent, selector: "rp-model-preview", viewQueries: [{ propertyName: "glbExportName", first: true, predicate: ["fileName"], descendants: true }, { propertyName: "heightArticle", first: true, predicate: ["heightArticle"], descendants: true }], ngImport: i0, template: `
41106
41899
  <div class="model-preview">
41107
41900
  <div class="model-preview-container" id="canvasContainer">
@@ -41121,6 +41914,10 @@ ModelPreviewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0",
41121
41914
  </div>
41122
41915
  </div>
41123
41916
 
41917
+ <div>
41918
+ <button (click)="toggleShowReferenceModel()">Show Reference model</button>
41919
+ </div>
41920
+
41124
41921
  <div class="rotation-button-container">
41125
41922
  <p>Rotation</p>
41126
41923
  <div class="rotation-x-buttons">
@@ -41137,6 +41934,23 @@ ModelPreviewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0",
41137
41934
  </div>
41138
41935
  </div>
41139
41936
 
41937
+
41938
+ <div class="rotation-button-container">
41939
+ <p>Positie</p>
41940
+ <div class="rotation-x-buttons">
41941
+ <button (click)="moveModel('x', 0.01)">x-as + 0.01</button>
41942
+ <button (click)="moveModel('x', -0.01)">x-as -0.01</button>
41943
+ </div>
41944
+ <div class="rotation-y-buttons">
41945
+ <button (click)="moveModel('y', 0.01)">y-as + 0.01</button>
41946
+ <button (click)="moveModel('y', -0.01)">y-as - 0.01</button>
41947
+ </div>
41948
+ <div class="rotation-z-buttons">
41949
+ <button (click)="moveModel('z', 0.01)">z-as + 0.01</button>
41950
+ <button (click)="moveModel('z', -mathPi / 2)">z-as -0.01</button>
41951
+ </div>
41952
+ </div>
41953
+
41140
41954
  <div class="model-preview-info" *ngIf="this.data">
41141
41955
  <div class="model-preview-info-container">
41142
41956
  <div class="model-preview-info-left">
@@ -41146,14 +41960,35 @@ ModelPreviewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0",
41146
41960
  <input type="text" id="fileName" #fileName value="{{ this.data.file.file.name }}">
41147
41961
  </div>
41148
41962
  </div>
41963
+
41149
41964
  <div class="model-preview-info-container">
41150
41965
  <div class="model-preview-info-left">
41151
- <label>Size</label>
41966
+ <label>Stackable</label>
41152
41967
  </div>
41153
41968
  <div class="model-preview-info-right">
41154
- <label>{{ this.data.file.file.size }}</label>
41969
+ <div class="mat-radio-wrapper">
41970
+ <mat-radio-group aria-label="Select an unit" (change)="setStackable($event)">
41971
+ <mat-radio-button [checked]="true" value="false">No</mat-radio-button>
41972
+ <mat-radio-button value="true">Yes</mat-radio-button>
41973
+ </mat-radio-group>
41974
+ </div>
41155
41975
  </div>
41156
41976
  </div>
41977
+
41978
+ <div class="model-preview-info-container">
41979
+ <div class="model-preview-info-left">
41980
+ <label>Height adjustable</label>
41981
+ </div>
41982
+ <div class="model-preview-info-right">
41983
+ <div class="mat-radio-wrapper">
41984
+ <mat-radio-group aria-label="Select an unit" (change)="setHeightAdjustable($event)">
41985
+ <mat-radio-button [checked]="true" value="false">No</mat-radio-button>
41986
+ <mat-radio-button value="true">Yes</mat-radio-button>
41987
+ </mat-radio-group>
41988
+ </div>
41989
+ </div>
41990
+ </div>
41991
+
41157
41992
  <div class="model-preview-info-container">
41158
41993
  <div class="model-preview-info-left">
41159
41994
  <label>Extension</label>
@@ -41162,13 +41997,13 @@ ModelPreviewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0",
41162
41997
  <label>{{ this.data.file.fileType }}</label>
41163
41998
  </div>
41164
41999
  </div>
41165
- <button class="exportButton" (click)="exportSceneAsGLB('upload')">Add to scene</button>
42000
+ <button class="exportButton" (click)="exportSceneAsGLB('upload')">Upload to CDN and add to scene</button>
41166
42001
  <p></p>
41167
- <button class="exportButton" (click)="exportSceneAsGLB('download')">Download</button>
42002
+ <button class="exportButton" (click)="exportSceneAsGLB('download')">Download model</button>
41168
42003
  </div>
41169
42004
  </div>
41170
42005
  </div>
41171
- `, isInline: true, styles: [".model-preview{display:flex;flex-direction:row}.model-preview .model-preview-actions{min-width:240px;box-sizing:border-box;padding:10px 20px;border-left:1px solid #5b6875}.model-preview .model-preview-actions .model-preview-info-container{margin-bottom:10px}.model-preview .model-preview-actions .model-preview-info-container .model-preview-info-left{font-weight:bolder}.model-preview .exportButton{cursor:pointer;color:#fff;background:#dda73f;border:1px solid #dda73f;border-radius:3px;box-sizing:border-box;padding:5px;display:flex;align-items:center}.model-preview .exportButton:hover{background:#dda73f;color:#fff}input{border:1px solid #5b6875;box-sizing:border-box;padding:3px 10px;border-radius:3px}.mat-radio-wrapper{margin:10px 0}mat-radio-group mat-radio-button{display:block}.rotation-button-container div{display:flex;justify-content:space-between;margin-bottom:10px}.rotation-button-container div button{cursor:pointer;color:#fff;background:#dda73f;border:1px solid #dda73f;border-radius:3px;box-sizing:border-box;padding:5px}.rotation-button-container div button:hover{background:#dda73f;color:#fff}\n"], components: [{ type: i6$3.MatRadioButton, selector: "mat-radio-button", inputs: ["disableRipple", "tabIndex"], exportAs: ["matRadioButton"] }], directives: [{ type: i6$3.MatRadioGroup, selector: "mat-radio-group", exportAs: ["matRadioGroup"] }, { type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
42006
+ `, isInline: true, styles: [".model-preview{display:flex;flex-direction:row}.model-preview .model-preview-actions{min-width:240px;box-sizing:border-box;padding:10px 20px;border-left:1px solid #5b6875}.model-preview .model-preview-actions .model-preview-info-container{margin-bottom:10px}.model-preview .model-preview-actions .model-preview-info-container .model-preview-info-left{font-weight:bolder}.model-preview .exportButton{cursor:pointer;color:#fff;background:#dda73f;border:1px solid #dda73f;border-radius:3px;box-sizing:border-box;padding:5px;display:flex;align-items:center}.model-preview .exportButton:hover{background:#dda73f;color:#fff}input{border:1px solid #5b6875;box-sizing:border-box;padding:3px 10px;border-radius:3px}.mat-radio-wrapper{margin:10px 0}mat-radio-group mat-radio-button{display:block}.rotation-button-container div{display:flex;justify-content:space-between;margin-bottom:10px}.rotation-button-container div button{cursor:pointer;color:#fff;background:#dda73f;border:1px solid #dda73f;border-radius:3px;box-sizing:border-box;padding:5px}.rotation-button-container div button:hover{background:#dda73f;color:#fff}\n"], components: [{ type: i9$1.MatRadioButton, selector: "mat-radio-button", inputs: ["disableRipple", "tabIndex"], exportAs: ["matRadioButton"] }], directives: [{ type: i9$1.MatRadioGroup, selector: "mat-radio-group", exportAs: ["matRadioGroup"] }, { type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
41172
42007
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ModelPreviewComponent, decorators: [{
41173
42008
  type: Component,
41174
42009
  args: [{
@@ -41192,6 +42027,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImpo
41192
42027
  </div>
41193
42028
  </div>
41194
42029
 
42030
+ <div>
42031
+ <button (click)="toggleShowReferenceModel()">Show Reference model</button>
42032
+ </div>
42033
+
41195
42034
  <div class="rotation-button-container">
41196
42035
  <p>Rotation</p>
41197
42036
  <div class="rotation-x-buttons">
@@ -41208,6 +42047,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImpo
41208
42047
  </div>
41209
42048
  </div>
41210
42049
 
42050
+
42051
+ <div class="rotation-button-container">
42052
+ <p>Positie</p>
42053
+ <div class="rotation-x-buttons">
42054
+ <button (click)="moveModel('x', 0.01)">x-as + 0.01</button>
42055
+ <button (click)="moveModel('x', -0.01)">x-as -0.01</button>
42056
+ </div>
42057
+ <div class="rotation-y-buttons">
42058
+ <button (click)="moveModel('y', 0.01)">y-as + 0.01</button>
42059
+ <button (click)="moveModel('y', -0.01)">y-as - 0.01</button>
42060
+ </div>
42061
+ <div class="rotation-z-buttons">
42062
+ <button (click)="moveModel('z', 0.01)">z-as + 0.01</button>
42063
+ <button (click)="moveModel('z', -mathPi / 2)">z-as -0.01</button>
42064
+ </div>
42065
+ </div>
42066
+
41211
42067
  <div class="model-preview-info" *ngIf="this.data">
41212
42068
  <div class="model-preview-info-container">
41213
42069
  <div class="model-preview-info-left">
@@ -41217,14 +42073,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImpo
41217
42073
  <input type="text" id="fileName" #fileName value="{{ this.data.file.file.name }}">
41218
42074
  </div>
41219
42075
  </div>
42076
+
42077
+ <div class="model-preview-info-container">
42078
+ <div class="model-preview-info-left">
42079
+ <label>Stackable</label>
42080
+ </div>
42081
+ <div class="model-preview-info-right">
42082
+ <div class="mat-radio-wrapper">
42083
+ <mat-radio-group aria-label="Select an unit" (change)="setStackable($event)">
42084
+ <mat-radio-button [checked]="true" value="false">No</mat-radio-button>
42085
+ <mat-radio-button value="true">Yes</mat-radio-button>
42086
+ </mat-radio-group>
42087
+ </div>
42088
+ </div>
42089
+ </div>
42090
+
41220
42091
  <div class="model-preview-info-container">
41221
42092
  <div class="model-preview-info-left">
41222
- <label>Size</label>
42093
+ <label>Height adjustable</label>
41223
42094
  </div>
41224
42095
  <div class="model-preview-info-right">
41225
- <label>{{ this.data.file.file.size }}</label>
42096
+ <div class="mat-radio-wrapper">
42097
+ <mat-radio-group aria-label="Select an unit" (change)="setHeightAdjustable($event)">
42098
+ <mat-radio-button [checked]="true" value="false">No</mat-radio-button>
42099
+ <mat-radio-button value="true">Yes</mat-radio-button>
42100
+ </mat-radio-group>
42101
+ </div>
41226
42102
  </div>
41227
42103
  </div>
42104
+
41228
42105
  <div class="model-preview-info-container">
41229
42106
  <div class="model-preview-info-left">
41230
42107
  <label>Extension</label>
@@ -41233,9 +42110,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImpo
41233
42110
  <label>{{ this.data.file.fileType }}</label>
41234
42111
  </div>
41235
42112
  </div>
41236
- <button class="exportButton" (click)="exportSceneAsGLB('upload')">Add to scene</button>
42113
+ <button class="exportButton" (click)="exportSceneAsGLB('upload')">Upload to CDN and add to scene</button>
41237
42114
  <p></p>
41238
- <button class="exportButton" (click)="exportSceneAsGLB('download')">Download</button>
42115
+ <button class="exportButton" (click)="exportSceneAsGLB('download')">Download model</button>
41239
42116
  </div>
41240
42117
  </div>
41241
42118
  </div>
@@ -41245,7 +42122,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImpo
41245
42122
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
41246
42123
  type: Inject,
41247
42124
  args: [MAT_DIALOG_DATA]
41248
- }] }, { type: HomedecoratorSettingsService }, { type: i1$1.MatDialogRef }, { type: ThirdPartyModelService }, { type: MessageBusService }, { type: i1$1.MatDialog }, { type: HomedecoratorConnectorAdapterService }]; }, propDecorators: { glbExportName: [{
42125
+ }] }, { type: HomedecoratorSettingsService }, { type: i1$1.MatDialogRef }, { type: ThirdPartyModelService }, { type: MessageBusService }, { type: i1$1.MatDialog }, { type: HomedecoratorConnectorAdapterService }, { type: LightPresetsService }, { type: HomedecoratorDictionaryService }, { type: FontService }]; }, propDecorators: { glbExportName: [{
41249
42126
  type: ViewChild,
41250
42127
  args: ['fileName']
41251
42128
  }], heightArticle: [{
@@ -41605,20 +42482,12 @@ ToolbarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", versi
41605
42482
  <mat-icon class="homedecorator-material-icons" matTooltip="{{'DOWNLOAD_ROOM_AS_GLB' | localize}}">cloud_download</mat-icon>
41606
42483
  </button>
41607
42484
  </ng-container>
42485
+ <div class="hd-toolbar-spacer"></div>
41608
42486
 
41609
- <!-- <ng-container *ngIf="settingsService.settings.options.showRoomRenderButton">-->
41610
- <!-- <button mat-icon-button (click)="apiRoomRender()">-->
41611
- <!-- <mat-icon class="homedecorator-material-icons" matTooltip="{{'RENDER_GLB' | localize}}">share_windows</mat-icon>-->
41612
- <!-- </button>-->
41613
- <!-- </ng-container>-->
41614
-
41615
- <!-- <ng-container>-->
41616
- <!-- <button mat-icon-button (click)="testRender()">-->
41617
- <!-- TEST-->
41618
- <!-- </button>-->
41619
- <!-- </ng-container>-->
42487
+ <!-- <ng-container>-->
42488
+ <!-- <rp-pdf-export></rp-pdf-export>-->
42489
+ <!-- </ng-container>-->
41620
42490
 
41621
- <div class="hd-toolbar-spacer"></div>
41622
42491
  <mat-nav-list class="toolbar__nav" role="list">
41623
42492
  <div matTooltip="{{'NEW_ROOM' | localize}}">
41624
42493
  <mat-list-item role="listitem" (click)="newRoom()">{{ 'NEW' | localize }}</mat-list-item>
@@ -41769,20 +42638,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImpo
41769
42638
  <mat-icon class="homedecorator-material-icons" matTooltip="{{'DOWNLOAD_ROOM_AS_GLB' | localize}}">cloud_download</mat-icon>
41770
42639
  </button>
41771
42640
  </ng-container>
42641
+ <div class="hd-toolbar-spacer"></div>
41772
42642
 
41773
- <!-- <ng-container *ngIf="settingsService.settings.options.showRoomRenderButton">-->
41774
- <!-- <button mat-icon-button (click)="apiRoomRender()">-->
41775
- <!-- <mat-icon class="homedecorator-material-icons" matTooltip="{{'RENDER_GLB' | localize}}">share_windows</mat-icon>-->
41776
- <!-- </button>-->
41777
- <!-- </ng-container>-->
41778
-
41779
- <!-- <ng-container>-->
41780
- <!-- <button mat-icon-button (click)="testRender()">-->
41781
- <!-- TEST-->
41782
- <!-- </button>-->
41783
- <!-- </ng-container>-->
42643
+ <!-- <ng-container>-->
42644
+ <!-- <rp-pdf-export></rp-pdf-export>-->
42645
+ <!-- </ng-container>-->
41784
42646
 
41785
- <div class="hd-toolbar-spacer"></div>
41786
42647
  <mat-nav-list class="toolbar__nav" role="list">
41787
42648
  <div matTooltip="{{'NEW_ROOM' | localize}}">
41788
42649
  <mat-list-item role="listitem" (click)="newRoom()">{{ 'NEW' | localize }}</mat-list-item>
@@ -42027,13 +42888,14 @@ class ModelUploaderComponent {
42027
42888
  this.file = null;
42028
42889
  this.fileMaxSize = 30; // file size in mb
42029
42890
  this._maxFileSize = this.fileMaxSize * 1024 * 1024; // fileMaxSize to kb
42030
- this._allowedFiles = ['glb', 'obj', 'fbx', '3ds', 'gltf'];
42891
+ this._allowedFiles = ['glb', 'obj', 'fbx', '3ds', 'gltf', 'stl'];
42031
42892
  }
42032
42893
  ngOnInit() {
42033
42894
  }
42034
42895
  ngOnDestroy() {
42035
42896
  }
42036
42897
  onChange(event) {
42898
+ this.showUploadError = false;
42037
42899
  const file = event.target.files[0];
42038
42900
  if (file) {
42039
42901
  this.file = file;
@@ -42261,7 +43123,8 @@ class ProductCatalogComponent {
42261
43123
  if (jsonString) {
42262
43124
  const jsonObj = JSON.parse(jsonString);
42263
43125
  if (jsonObj['hash'] !== undefined) {
42264
- const customerName = 'Linteloo';
43126
+ const customerName = this.catalogInfo.username;
43127
+ // const customerName: string = 'Linteloo';
42265
43128
  // three main api urls
42266
43129
  const modelUrl = this.catalogInfo.externalSource.domain + '/models/' + jsonObj['hash'] + '/glb';
42267
43130
  const configurationUrl = this.catalogInfo.externalSource.domain + '/configurationData/' + jsonObj['hash'];
@@ -44812,6 +45675,115 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImpo
44812
45675
  }]
44813
45676
  }] });
44814
45677
 
45678
+ class ExportPdfComponent {
45679
+ constructor(_sceneService, _floorService, _messageBusService) {
45680
+ this._sceneService = _sceneService;
45681
+ this._floorService = _floorService;
45682
+ this._messageBusService = _messageBusService;
45683
+ this._subs = [];
45684
+ this._diagramBackground = '';
45685
+ this._subs.push(this._messageBusService.subscribe(MessageType.LoadScaledDiagram, (input) => this.setDiagramBackground(input)));
45686
+ }
45687
+ ngOnDestroy() {
45688
+ this._subs.forEach(s => s.unsubscribe());
45689
+ }
45690
+ getFloor() {
45691
+ const activeFloor = this._floorService.floorToConfigure.metadata;
45692
+ const output = [];
45693
+ if (activeFloor) {
45694
+ const floorCountResult = activeFloor.floorCountResult;
45695
+ output.push(['Planken links', floorCountResult.left.toString()]);
45696
+ output.push(['Planken rechts', floorCountResult.right.toString()]);
45697
+ output.push(['Hoek', floorCountResult.edge.toString()]);
45698
+ output.push(['Totaal aantal planken', floorCountResult.total.toString()]);
45699
+ const selectedSelections = activeFloor.selections;
45700
+ for (const selectedSelection of selectedSelections) {
45701
+ if (selectedSelection.commercialAnswer !== undefined) {
45702
+ output.push([selectedSelection.commercialQuestion, selectedSelection.commercialAnswer]);
45703
+ }
45704
+ }
45705
+ console.log(output);
45706
+ }
45707
+ return output;
45708
+ }
45709
+ generatePdf() {
45710
+ // get all data
45711
+ const sceneImage = this._createSceneScreenshot();
45712
+ const doc = new jsPDF();
45713
+ const dataList = this.getFloor();
45714
+ const dataListLength = dataList.length;
45715
+ autoTable(doc, {
45716
+ head: [['Header', 'Value']],
45717
+ body: dataList,
45718
+ bodyStyles: { minCellHeight: 10 }
45719
+ });
45720
+ doc.addPage();
45721
+ doc.addImage(sceneImage, 'JPEG', 0, 0, 210, 117); // size is in mm not pixels!
45722
+ if (this._diagramBackground !== '') {
45723
+ doc.addPage();
45724
+ const offsetYImageTwo = 30 + 125 + (dataListLength * 10);
45725
+ doc.addImage(this._diagramBackground, 'JPEG', 0, 0, 210, 117); // size is in mm not pixels!
45726
+ }
45727
+ doc.save('sample.pdf');
45728
+ }
45729
+ setDiagramBackground(input) {
45730
+ this._diagramBackground = input.background.src;
45731
+ }
45732
+ _createSceneScreenshot() {
45733
+ return this._sceneService.createRenderWithOrthographicCamera();
45734
+ // return this._sceneService.getSceneCanvasImage();
45735
+ }
45736
+ }
45737
+ ExportPdfComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ExportPdfComponent, deps: [{ token: SceneService }, { token: FloorService }, { token: MessageBusService }], target: i0.ɵɵFactoryTarget.Component });
45738
+ ExportPdfComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.17", type: ExportPdfComponent, selector: "rp-pdf-export", ngImport: i0, template: `
45739
+ <div>
45740
+ <button (click)="generatePdf()">Generate PDF</button>
45741
+ </div>
45742
+ `, isInline: true, styles: [":host .mat-dialog-content{margin:0;padding:0;overflow:hidden}:host .mat-nav-list{display:flex;flex-direction:column}.mat-dialog-actions{margin-bottom:0}.item-description{white-space:inherit!important}\n"] });
45743
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ExportPdfComponent, decorators: [{
45744
+ type: Component,
45745
+ args: [{
45746
+ selector: 'rp-pdf-export',
45747
+ template: `
45748
+ <div>
45749
+ <button (click)="generatePdf()">Generate PDF</button>
45750
+ </div>
45751
+ `,
45752
+ styleUrls: ['./pdf-export.component.scss']
45753
+ }]
45754
+ }], ctorParameters: function () { return [{ type: SceneService }, { type: FloorService }, { type: MessageBusService }]; } });
45755
+
45756
+ class ExportPdfModule {
45757
+ }
45758
+ ExportPdfModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ExportPdfModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
45759
+ ExportPdfModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ExportPdfModule, declarations: [ExportPdfComponent], imports: [CoreModule,
45760
+ CommonModule,
45761
+ MatDialogModule,
45762
+ MatListModule], exports: [ExportPdfComponent] });
45763
+ ExportPdfModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ExportPdfModule, imports: [[
45764
+ CoreModule,
45765
+ CommonModule,
45766
+ MatDialogModule,
45767
+ MatListModule
45768
+ ]] });
45769
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ExportPdfModule, decorators: [{
45770
+ type: NgModule,
45771
+ args: [{
45772
+ imports: [
45773
+ CoreModule,
45774
+ CommonModule,
45775
+ MatDialogModule,
45776
+ MatListModule
45777
+ ],
45778
+ exports: [
45779
+ ExportPdfComponent
45780
+ ],
45781
+ declarations: [
45782
+ ExportPdfComponent
45783
+ ]
45784
+ }]
45785
+ }] });
45786
+
44815
45787
  class ToolbarModule {
44816
45788
  }
44817
45789
  ToolbarModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ToolbarModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
@@ -44853,7 +45825,8 @@ ToolbarModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version:
44853
45825
  IconModule,
44854
45826
  MatBadgeModule,
44855
45827
  ThreedInPhotoModule,
44856
- PdfViewerModule], exports: [ToolbarComponent] });
45828
+ PdfViewerModule,
45829
+ ExportPdfModule], exports: [ToolbarComponent] });
44857
45830
  ToolbarModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ToolbarModule, imports: [[
44858
45831
  CoreModule,
44859
45832
  CommonModule,
@@ -44882,7 +45855,8 @@ ToolbarModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version:
44882
45855
  IconModule,
44883
45856
  MatBadgeModule,
44884
45857
  ThreedInPhotoModule,
44885
- PdfViewerModule
45858
+ PdfViewerModule,
45859
+ ExportPdfModule
44886
45860
  ]] });
44887
45861
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ToolbarModule, decorators: [{
44888
45862
  type: NgModule,
@@ -44915,7 +45889,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImpo
44915
45889
  IconModule,
44916
45890
  MatBadgeModule,
44917
45891
  ThreedInPhotoModule,
44918
- PdfViewerModule
45892
+ PdfViewerModule,
45893
+ ExportPdfModule
44919
45894
  ],
44920
45895
  entryComponents: [
44921
45896
  LoadFromCloudDialogComponent,