diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a56ab1d..1a47191 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -126,7 +126,7 @@ WebGl3D.Door:release: - *version-fix - *ReplicaX script: - - cd .\IcarusView\WebGl\ + - cd .\WebDoorView\src\ - Set-Content -Path "./.npmrc" -Value "email=ceo@steamware.net `nalways-auth=true `n//nexus.steamware.net/repository/npm-hosted/:_authToken=$NPM_TOKEN" - $JSON_FILE = Get-Content '.\package.json' -raw - $JSON_FILE_RAW = $JSON_FILE | ConvertFrom-Json diff --git a/WebDoorView/3DM_test/test_js_call/index_2.html b/WebDoorView/3DM_test/test_js_call/index_2.html index edf2a49..66e27f5 100644 --- a/WebDoorView/3DM_test/test_js_call/index_2.html +++ b/WebDoorView/3DM_test/test_js_call/index_2.html @@ -33,19 +33,11 @@
-
-
@@ -61,67 +53,48 @@
  • Rotate CTRL + Drag Mouse-Wheel -
  • - +
  • Iso / Ortho
    | key : O
    -
  • Perspective
    | key : P
    -
  • AutoRotate
    | key : R
    -
  • Quotes
    | key : Q
    -
  • Grid
    | key : G
    -
  • Reset
    | key: SpaceBar
    -
  • Menu
    | key : H
    -
  • diff --git a/WebDoorView/3DM_test/test_js_call/package.json b/WebDoorView/3DM_test/test_js_call/package.json index 7ce2cc5..71e76ca 100644 --- a/WebDoorView/3DM_test/test_js_call/package.json +++ b/WebDoorView/3DM_test/test_js_call/package.json @@ -1,5 +1,22 @@ { + "name": "webgl-door-visualizer", "dependencies": { "three": "^0.162.0" - } + }, + "publishConfig": { + "registry": "https://nexus.steamware.net/repository/npm-hosted/" + }, + "version": ".24062212", + "description": "3D WebDoor visualizer ", + "main": "draw_call.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [ + "3D", + "WebGl", + "WebDoor" + ], + "author": "R.E., S.E.L", + "license": "ISC" } diff --git a/WebDoorView/QuickStartC#.md b/WebDoorView/QuickStartC#.md new file mode 100644 index 0000000..283aebe --- /dev/null +++ b/WebDoorView/QuickStartC#.md @@ -0,0 +1,297 @@ +# Visualizzatore 3D Doors (Blazor) + +- [Visualizzatore 3D Doors (Blazor)](#visualizzatore-3d-doors-blazor) + - [0️⃣ Prerequisiti](#0️⃣-prerequisiti) + - [1️⃣ Creare un'applicazione Web (Blazor server app)](#1️⃣-creare-unapplicazione-web-blazor-server-app) + - [⚠️ IMPORTANTE PER IL CORRETTO FUNZIONAMENTO DEL VISUALIZZATORE](#️-importante-per-il-corretto-funzionamento-del-visualizzatore) + - [2️⃣ Setup helper per la comunicazione](#2️⃣-setup-helper-per-la-comunicazione) + - [3️⃣​ Aggiungere i riferimenti ai file `.js`](#3️⃣-aggiungere-i-riferimenti-ai-file-js) + - [4️⃣ Setup componente blazor per il render​](#4️⃣-setup-componente-blazor-per-il-render) + - [5️⃣​ Setup della chiamata alla funzione di render](#5️⃣-setup-della-chiamata-alla-funzione-di-render) + + +## 0️⃣ Prerequisiti + +- .NET SDK installato + + +## 1️⃣ Creare un'applicazione Web (Blazor server app) + +![Tipo di progetto ](image.png) + +Una volta creata l'applicazione web creare nella cartella wwroot una sottocartella denominandola lib. Se si importa localmente inl pacchetto npm viene creata alla fase di definizione del path di destinazione + + +![Import NPM](image-1.png) + +E' possibile importare il pacchetto npm che si traova sul nostro repository nexus (https://nexus.steamware.net/#browse/browse:npm-hosted:webgl-door-visualizer) con il comando seguente + + npm install webgl-door-visualizer@1.2.240622.1216 + +Dove il numero versione va modificato di conseguenza a quanto voluto. + +![Creazione cartella lib](image-1.png) + +Successivamente copiare l'intera cartella src fornita ed incollarla nella cartella lib precedentemente creata. + +![Aggiunta libreria WebGl](image-2.png) + +## ⚠️ IMPORTANTE PER IL CORRETTO FUNZIONAMENTO DEL VISUALIZZATORE + +Visual studio riconosce e permette l'utilizzo di alcuni tipi di file. L'estensione `.3dm` non rientra nella categoria perciò è importante ricordarsi di includere quest'ultima nella classe `Program.cs` le seguenti righe di codice: + +```c# +var provider = new Microsoft.AspNetCore.StaticFiles.FileExtensionContentTypeProvider(); +provider.Mappings[".3dm"] = "model"; // aggiungere l'estensione desiderata e il suo tipo + +app.UseStaticFiles(new StaticFileOptions +{ + ContentTypeProvider = provider +}); +``` + +inoltre ma aggiunta la configurazione per distribuire file 3dm dalla cartella appositamente prevista (ed esterna al programma epr "sopravvivere" agli update dello stesso) + +```c# +string path3dm = configuration.GetValue("ServerConf:path3dm") ?? configuration.GetValue("OptConf:path3dm") ?? ""; +if (!string.IsNullOrEmpty(path3dm)) +{ + // verifico esista folder disegni + if (Directory.Exists(path3dm)) + { + // gestione cartella x PDF + app.UseStaticFiles(new StaticFileOptions + { + FileProvider = new PhysicalFileProvider(path3dm), + RequestPath = "/3dm", + ContentTypeProvider = provider + }); + } +} +``` + +## 2️⃣ Setup helper per la comunicazione + +Nella cartella lib dovrebbe trovarsi il file `draw_call.js`. Questo sarà il file che farà da tramite tra chi gestisce il visualizzatore ( `WebGl` ) e chi mostrerà il visualizzatore ( `WebGlViewer` ) + +Il file conterrà le seguenti righe di codice : + +```javascript +import { webgl_original } from './webgl_draw.js'; + +const WGL = new webgl_original(); + +const infoDiv = document.getElementById( "infoDiv") ; +const doorDiv = document.getElementById( "DoorRender") ; +const cubeDiv = document.getElementById( "Ref1Render") ; +infoDiv.style.display = "none"; + +var isAnimated = true; +var isRotating = true; +var showQuote = true; +var showGrid = true; + +let options ={ + modelPath: "https://iis01.egalware.com/Test3D/THREEJS_DOORS/Door_models", + fName: getUrlParameter("src") +} + +// init controllo +WGL.initcall(options); +``` +In questo caso sono presenti due funzioni : + +- `initcall` permette di avviare i calcoli che permettono il render del visualizzatore 3D. I parametri richiesti : + - modelPath: path da dove vengono restituiti i file 3dm (da configurare nel program.cs come sopra); + - fName: nome del file ( con estensione `.3dm` ) del quale effettuare il render. + +
    + +> **N.B.:** E' fondamentale caricare i propri modelli da visualizzare nella cartella sopra definita in program.cs. +> + + + +## 3️⃣​ Aggiungere i riferimenti ai file `.js` + +Per far si che il codice scritto nel file di base della libreria e nel file **helper** è importante aggiungere le seguenti righe alla pagina +`Pages/_layout.cshtml` : + +```html + + +``` + +Di seguito il risultato di come si presenterà la pagina : + +```html + + + + + + + + + + + + + @RenderBody() + +
    + + An error has occurred. This application may no longer respond until reloaded. + + + An unhandled exception has occurred. See browser dev tools for details. + + Reload + 🗙 +
    + + + + + + + +``` + +## 4️⃣ Setup componente blazor per il render​ + +Successivamente creiamo un nuovo componente razor nella cartelle delle pagine `Pages/WebGlViewer`. + +Nella nuova pagina inserire le seguenti righe di codice che permetteranno di effettuare il render del visualizzatore. + +```html +@inject IJSRuntime JSRuntime +@page "/WebGlViewer" + +
    +
    +
    + + +
    +
    + + + +
    +
    +
    +
    + +
    + + +
    + +
    +
    +
      +
    • + Camera settings +
    • +
    • + Zoom Wheel-Scroll +
    • +
    • + Pan Drag Mouse-Wheel +
    • +
    • + Rotate CTRL + Drag Mouse-Wheel +
    • +
    • +
      Iso / Ortho
      +
      + | key : O +
      +
    • +
    • +
      Perspective
      +
      + | key : P +
      +
    • +
    • +
      AutoRotate
      +
      + | key : R +
      +
    • +
    • +
      Quotes
      +
      + | key : Q +
      +
    • +
    • +
      Grid
      +
      + | key : G +
      +
    • +
    • +
      Reset
      +
      + | key: SpaceBar +
      +
    • +
    • +
      Menu
      +
      + | key : H +
      +
    • +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + WebDoor 3D +
    +
    + Egalware | +
    +
    +
    + +``` +`@inject IJSRuntime JSRuntime` permette di usufruire del servizio che si occupa di eseguire chiamate a funzioni javascript direttamente dal codice c# + +## 5️⃣​ Setup della chiamata alla funzione di render + +... probabilmente non necessario con secondo modulo... +Nella pagina `Pages/WebGlViewer` aggiungere il seguente codice che, una folta effettuato il render della pagina procederà al disegno del visualizzatore. + +```c# +@code { + protected override async Task OnAfterRenderAsync(bool firstRender) + { + await Task.Delay(1); + + if (firstRender) + { + var options = new + { + dimX = 960, + dimY = 540, + fileName = "Cubo.3mf", + _showCalcGrid = false + }; + await JSRuntime.InvokeVoidAsync("setup", options); + } + } +} +``` diff --git a/WebDoorView/QuickStartC#.pdf b/WebDoorView/QuickStartC#.pdf new file mode 100644 index 0000000..fe87014 Binary files /dev/null and b/WebDoorView/QuickStartC#.pdf differ diff --git a/WebDoorView/QuickStartVue.md b/WebDoorView/QuickStartVue.md new file mode 100644 index 0000000..0a5d36d --- /dev/null +++ b/WebDoorView/QuickStartVue.md @@ -0,0 +1,115 @@ +# Visualizzatore 3D Additive (Vue.js) +- [Visualizzatore 3D Additive (Vue.js)](#visualizzatore-3d-additive-vuejs) + - [0️⃣ Prerequisiti](#0️⃣-prerequisiti) + - [1️⃣ Creare un'applicazione Vue.js](#1️⃣-creare-unapplicazione-vuejs) + - [2️⃣ Includere la libreria nel progetto](#2️⃣-includere-la-libreria-nel-progetto) + - [3️⃣ Setup del componente vue](#3️⃣-setup-del-componente-vue) + - [4️⃣ Setup script per richiamare il codice di render](#4️⃣-setup-script-per-richiamare-il-codice-di-render) + - [5️⃣ Risultato finale](#5️⃣-risultato-finale) + - [6️⃣ Ulteriori funzioni](#6️⃣-ulteriori-funzioni) +## 0️⃣ Prerequisiti +- Node.js installato +- file conf x accesso ai nostri repo nexus in cartella utente (.npmrc contenuto in IcarusView) +## 1️⃣ Creare un'applicazione Vue.js + +Il primo passo è creare l'applicazione. Aprire il terminale e navigare fino alla directory nella quale si vuole operare e lanciare il comando: + +```sh +> npm create vue@latest +``` + +Questo comando installerà ed eseguirà `create-vue`, lo strumento ufficiale per eseguire lo scaffolding del progetto Vue. + +```ps + +√ Project name: ... Web3Dviewer +√ Package name: ... web3dviewer +√ Add TypeScript? ... No / Yes +√ Add JSX Support? ... No / Yes +√ Add Vue Router for Single Page Application development? ... No / Yes +√ Add Pinia for state management? ... No / Yes +√ Add Vitest for Unit Testing? ... No / Yes +√ Add an End-to-End Testing Solution? » No +√ Add ESLint for code quality? ... No / Yes + +Scaffolding project in .\Web3Dviewer... +``` + +> **N.B.:** il nome `Web3Dviewer` è solo per esempio, si può inserire qualsiasi nome progetto si voglia. +> + +Una volta creato il progetto, segui le istruzioni per installare le dipendenze e avviare il server di sviluppo: + +```sh +> cd Web3Dviewer +> npm install +> npm run dev +``` + +In questo modo ora abbiamo un'applicazione web funzionante. + +## 2️⃣ Includere la libreria nel progetto + +Per includere la libreria nel progetto è necessario copiare la cartella fornita `WebGl` ed incollarla all'interno della cartella `Web3Dviewer/src/`. + +![Alt text](image-3.png) + +## 3️⃣ Setup del componente vue + +Usando il componente di esempio `App.vue` eliminare tutto il contenuto e sostituirlo con il seguente codice: + +```html + + +``` + +Che permetterà di contenere il visualizzatore. + +## 4️⃣ Setup script per richiamare il codice di render + +Nella pagina `index.html` è necessario aggiungere il seguente codice per poter richiamare le funzioni della libreria: + +```javascript + + + + +``` + +> La variabile `_showCalcGrid` definisce il tipo di griglia da mostrare (Infinita o Calcolata). + + +## 5️⃣ Risultato finale + +![Gif che mostra il risultato finale](chrome_2023-09-19_08-50-36.gif) + +## 6️⃣ Ulteriori funzioni + +La libreria presenta ulteriori funzioni quali: + + - `.refreshCall(nStart, nEnd)`: permette di decidere quali layer dell'oggetto mostrare. + - `.resetCamera()`: gestisce il reset della camera alla posizione iniziale. + - `.setCamerType()`: permette di cambiare il tipo di camera tra: + - Prospettica + - ortografica + + diff --git a/WebDoorView/README.md b/WebDoorView/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/WebDoorView/src/images/LogoEgw.png b/WebDoorView/src/images/LogoEgw.png new file mode 100644 index 0000000..8d5a7c1 Binary files /dev/null and b/WebDoorView/src/images/LogoEgw.png differ diff --git a/WebDoorView/src/images/favicon.ico b/WebDoorView/src/images/favicon.ico new file mode 100644 index 0000000..63e859b Binary files /dev/null and b/WebDoorView/src/images/favicon.ico differ diff --git a/WebDoorView/src/lib/node_modules/webgl-door-visualizer/draw_call.js b/WebDoorView/src/lib/node_modules/webgl-door-visualizer/draw_call.js index 48b4119..a6dc8db 100644 --- a/WebDoorView/src/lib/node_modules/webgl-door-visualizer/draw_call.js +++ b/WebDoorView/src/lib/node_modules/webgl-door-visualizer/draw_call.js @@ -1,20 +1,240 @@ -import { webgl_original } from './webgl_draw.js'; - +import { webgl_original } from "./webgl_draw.js"; const WGL = new webgl_original(); +const infoDiv = document.getElementById( "infoDiv") ; +const doorDiv = document.getElementById( "DoorRender") ; +const cubeDiv = document.getElementById( "Ref1Render") ; +infoDiv.style.display = "none"; + +var isAnimated = true; +var isRotating = true; +var showQuote = true; +var showGrid = true; + let options ={ - modelPath: 'https://iis01.egalware.com/Test3D/THREEJS_DOORS/Door_models', - fName: getUrlParameter('src') + modelPath: "https://iis01.egalware.com/Test3D/THREEJS_DOORS/Door_models", + fName: getUrlParameter("src") } +// init controllo +WGL.initcall(options); + + +// --------------------------------------------------- +// Funzioni pubbliche +// --------------------------------------------------- +window.toggleAnim = () => +{ + isAnimated = !isAnimated; + fixAnimate(true); +} + +// reset camera +window.resetCamera = () => +{ + console.log("Reset Camera"); + document.getElementById("btnReset").className = "btn btn-lg btn-light"; + isAnimated = true; + // isRotating = true; + fixAnimate(true); + // fixBtnRotate(); + // WGL.toggleRotation(); + WGL.resetCamera(); + var millisecondsToWait = 500; + setTimeout(function() { + document.getElementById("btnReset").className = "btn btn-lg btn-secondary"; + }, millisecondsToWait); +} + +// set camera persp +window.setOrtho = () => +{ + console.log("Set Camera ISO/ORTHO"); + document.getElementById("btnOrto").className = "btn btn-lg btn-light"; + document.getElementById("btnPers").className = "btn btn-lg btn-secondary"; + WGL.setCameraOrtho(); +} + +// reset camera persp +window.setPersp = () => +{ + console.log("Set Camera Perspective"); + document.getElementById("btnOrto").className = "btn btn-lg btn-secondary"; + document.getElementById("btnPers").className = "btn btn-lg btn-light"; + WGL.setCameraPersp(); +} + +// toggle griglia +window.toggleGrid = () => +{ + console.log("Toggle Grid"); + showGrid = !showGrid; + if(showGrid) + { + document.getElementById("btnGrid").className = "btn btn-lg btn-light"; + } + else{ + document.getElementById("btnGrid").className = "btn btn-lg btn-secondary"; + } + WGL.toggleGrid(); +} + +// toggle quotatura +window.toggleHelp = () => +{ + console.log("Toggle Menu"); + toggleMenu(); +} + +// toggle quotatura +window.toggleQuote = () => +{ + console.log("Toggle Quote"); + showQuote = !showQuote; + if(showQuote) + { + document.getElementById("btnQuote").className = "btn btn-lg btn-light"; + } + else{ + document.getElementById("btnQuote").className = "btn btn-lg btn-secondary"; + } + WGL.toggleQuotes(); +} + +// toggle rotazione +window.toggleRotate = () => +{ + console.log("Toggle Rotate"); + isRotating = !isRotating; + fixBtnRotate(); + WGL.toggleRotation(); +} + +// --------------------------------------------------- +// Funzioni private +// --------------------------------------------------- + // Reading URL parameters ------------------------------------------------------------------------- function getUrlParameter( name) { // get query string from URL - const queryString = window.location.search ; + const queryString = window.location.search ; // create URLSearchParams object from query string - const urlParams = new URLSearchParams( queryString) ; + const urlParams = new URLSearchParams( queryString) ; // get parameter value by name - return urlParams.get( name) ; - } + return urlParams.get( name) ; +} -WGL.initcall(options); \ No newline at end of file +function toggleMenu() +{ + console.log("Toggle Menu Camera"); + if ( infoDiv.style.display == "none") + infoDiv.style.display = "block" ; + else + infoDiv.style.display = "none"; +} + +function fixAnimate(setRotate) +{ + if( isAnimated ) + { + document.getElementById("btnPlay").className = "btn btn-lg btn-light"; + document.getElementById("btnPause").className = "btn btn-lg btn-secondary"; + if(setRotate) + isRotating = true; + fixBtnRotate(); + WGL.setRotate(isRotating); + WGL.doAnimate(); + } + else + { + document.getElementById("btnPlay").className = "btn btn-lg btn-secondary"; + document.getElementById("btnPause").className = "btn btn-lg btn-light"; + if(setRotate) + isRotating = false; + fixBtnRotate(); + WGL.setRotate(isRotating); + WGL.doFreeze(); + } +} + + +function fixBtnRotate() +{ + var cssClass = "btn btn-lg btn-secondary"; + if(isRotating) + { + cssClass = "btn btn-lg btn-light"; + } + document.getElementById("btnRotate").className = cssClass; +} + +function onKeyPress( event) { + + switch (event.key.toLowerCase() ){ + case " ": + resetCamera(); + break; + case "a": + toggleAnim(); + break; + case "h": + toggleMenu(); + break; + case "g": + toggleGrid(); + break; + case "o": + setOrtho(); + break; + case "p": + setPersp(); + break; + case "q": + toggleQuote(); + break; + case "r": + toggleRotate(); + break; + } +} + +function checkButton(event) +{ + switch(event.button){ + case 0: + // salto! + break; + default: + reAnimate(); + break; + } +} + +function reAnimate() +{ + if( !isAnimated ) + { + isAnimated = true; + fixAnimate(false); + } +} + +function reAnimateRotate() +{ + if( !isAnimated ) + { + isAnimated = true; + fixAnimate(true); + } +} + + +// Event Listner ------------------------------------------------------------------- +// KEY +document.addEventListener( "keypress", onKeyPress) ; +doorDiv.addEventListener( 'pointerup', checkButton ); +doorDiv.addEventListener( 'touchstart', reAnimate ); +// doorDiv.addEventListener( 'touchend', reAnimate ); +// doorDiv.addEventListener( 'touchcancel', reAnimate ); +doorDiv.addEventListener( 'touchmove', reAnimateRotate ); +doorDiv.addEventListener( 'click', toggleAnim ); \ No newline at end of file diff --git a/WebDoorView/src/lib/node_modules/webgl-door-visualizer/jsm/libs/stats.js b/WebDoorView/src/lib/node_modules/webgl-door-visualizer/jsm/libs/stats.js new file mode 100644 index 0000000..4875f72 --- /dev/null +++ b/WebDoorView/src/lib/node_modules/webgl-door-visualizer/jsm/libs/stats.js @@ -0,0 +1,179 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.Stats = factory()); +}(this, (function () { 'use strict'; + +/** + * @author mrdoob / http://mrdoob.com/ + */ + +var Stats = function () { + + var mode = 0; + + var container = document.createElement( 'div' ); + container.style.cssText = 'position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000'; + container.addEventListener( 'click', function ( event ) { + + event.preventDefault(); + showPanel( ++ mode % container.children.length ); + + }, false ); + + // + + function addPanel( panel ) { + + container.appendChild( panel.dom ); + return panel; + + } + + function showPanel( id ) { + + for ( var i = 0; i < container.children.length; i ++ ) { + + container.children[ i ].style.display = i === id ? 'block' : 'none'; + + } + + mode = id; + + } + + // + + var beginTime = ( performance || Date ).now(), prevTime = beginTime, frames = 0; + + var fpsPanel = addPanel( new Stats.Panel( 'FPS', '#0ff', '#002' ) ); + var msPanel = addPanel( new Stats.Panel( 'MS', '#0f0', '#020' ) ); + + if ( self.performance && self.performance.memory ) { + + var memPanel = addPanel( new Stats.Panel( 'MB', '#f08', '#201' ) ); + + } + + showPanel( 0 ); + + return { + + REVISION: 16, + + dom: container, + + addPanel: addPanel, + showPanel: showPanel, + + begin: function () { + + beginTime = ( performance || Date ).now(); + + }, + + end: function () { + + frames ++; + + var time = ( performance || Date ).now(); + + msPanel.update( time - beginTime, 200 ); + + if ( time >= prevTime + 1000 ) { + + fpsPanel.update( ( frames * 1000 ) / ( time - prevTime ), 100 ); + + prevTime = time; + frames = 0; + + if ( memPanel ) { + + var memory = performance.memory; + memPanel.update( memory.usedJSHeapSize / 1048576, memory.jsHeapSizeLimit / 1048576 ); + + } + + } + + return time; + + }, + + update: function () { + + beginTime = this.end(); + + }, + + // Backwards Compatibility + + domElement: container, + setMode: showPanel + + }; + +}; + +Stats.Panel = function ( name, fg, bg ) { + + var min = Infinity, max = 0, round = Math.round; + var PR = round( window.devicePixelRatio || 1 ); + + var WIDTH = 80 * PR, HEIGHT = 48 * PR, + TEXT_X = 3 * PR, TEXT_Y = 2 * PR, + GRAPH_X = 3 * PR, GRAPH_Y = 15 * PR, + GRAPH_WIDTH = 74 * PR, GRAPH_HEIGHT = 30 * PR; + + var canvas = document.createElement( 'canvas' ); + canvas.width = WIDTH; + canvas.height = HEIGHT; + canvas.style.cssText = 'width:80px;height:48px'; + + var context = canvas.getContext( '2d' ); + context.font = 'bold ' + ( 9 * PR ) + 'px Helvetica,Arial,sans-serif'; + context.textBaseline = 'top'; + + context.fillStyle = bg; + context.fillRect( 0, 0, WIDTH, HEIGHT ); + + context.fillStyle = fg; + context.fillText( name, TEXT_X, TEXT_Y ); + context.fillRect( GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT ); + + context.fillStyle = bg; + context.globalAlpha = 0.9; + context.fillRect( GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT ); + + return { + + dom: canvas, + + update: function ( value, maxValue ) { + + min = Math.min( min, value ); + max = Math.max( max, value ); + + context.fillStyle = bg; + context.globalAlpha = 1; + context.fillRect( 0, 0, WIDTH, GRAPH_Y ); + context.fillStyle = fg; + context.fillText( round( value ) + ' ' + name + ' (' + round( min ) + '-' + round( max ) + ')', TEXT_X, TEXT_Y ); + + context.drawImage( canvas, GRAPH_X + PR, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT, GRAPH_X, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT ); + + context.fillRect( GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, GRAPH_HEIGHT ); + + context.fillStyle = bg; + context.globalAlpha = 0.9; + context.fillRect( GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, round( ( 1 - ( value / maxValue ) ) * GRAPH_HEIGHT ) ); + + } + + }; + +}; + +return Stats; + +}))); diff --git a/WebDoorView/src/lib/node_modules/webgl-door-visualizer/webgl_draw.js b/WebDoorView/src/lib/node_modules/webgl-door-visualizer/webgl_draw.js index 8371ee6..697753a 100644 --- a/WebDoorView/src/lib/node_modules/webgl-door-visualizer/webgl_draw.js +++ b/WebDoorView/src/lib/node_modules/webgl-door-visualizer/webgl_draw.js @@ -1,11 +1,12 @@ // importing import * as THREE from './three.module.js' ; +// import Stats from './jsm/libs/stats.js'; import { OrbitControls } from './jsm/controls/OrbitControls.js'; import { Rhino3dmLoader} from './jsm/loaders/3DMLoader.js' ; import ViewCubeControls from './custom/cubeControls.js'; -import { getStaticRef, updateRef } from './custom/refControls.js' ; +// import { getStaticRef, updateRef } from './custom/refControls.js' ; -// VARIABILI DI CONTROLLO +// COSTANTI/VARIABILI DI CONTROLLO const EPS_SMALL = 0.001 ; const GRID_GROUP_NAME = 'gridGroup' ; const FRAME_GROUP_NAME = 'frameGroup' ; @@ -15,23 +16,34 @@ const DIMENSION_GROUP_NAME = 'dimGroup' ; const DIMENSION_DISCRIMINANT_NAME = 'dim_' ; const GENERAL_ENTITY_GROUP_NAME = 'generalGroup' ; const START_CAMERA_POSITION = ( new THREE.Vector3( -0.3994, 0.6339, 0.66223)).normalize() ; -var SCENE_BACKGROUND_COLOR = new THREE.Color( 0x808080) ; +const _changeEvent = { type: 'change' }; +const _startEvent = { type: 'start' }; +const _endEvent = { type: 'end' }; +const clock = new THREE.Clock(); +const fpsTgtHigh = 1 / 60; // Target 60 FPS MAX +const fpsTgtLow = 1 / 6; // Target 6 FPS low +// // statistiche fps +// const stats = new Stats(); +// variabili +var SCENE_BACKGROUND_COLOR = new THREE.Color( 0x87a7ad) ; var CAMERA_TYPE = CAMERA_ORTHO ; var SHOW_DIMENSION = true ; var GRID_MAIN_COLOR = new THREE.Color( 0x000000) ; -var GRID_SECOND_COLOR = new THREE.Color( 0xcccccc) ; +var GRID_SECOND_COLOR = new THREE.Color( 0x363636) ; var PATH = './Door_models' ; var FILE_NAME = 'Demo.3dm' var CTRL_DOWN = false ; +var targetTimeStep = fpsTgtHigh; // ref global variables --------- var scene_ref ; var renderer_ref ; var camera_ref ; var group_ref ; var cube_ref ; -var scene_ref1 ; var renderer_ref1 ; var camera_ref1 ; var group_ref1 ; var frame_ref1 ; +// var scene_ref1 ; var renderer_ref1 ; var camera_ref1 ; var group_ref1 ; var frame_ref1 ; // shared variables /* Box3d of the door ------------ */ var m_box ; var m_size ; var m_center ; // set in setCameraPosition(), used in setGrid(), setFrame() /* ------------------------------ */ +var freezed = false; // costanti globali // scene @@ -49,6 +61,10 @@ renderer.setPixelRatio( 2 * window.devicePixelRatio) ; document.getElementById( 'DoorRender').appendChild( renderer.domElement) ; renderer.shadowMap.enabled = true ; +// // aggiunta panel statistiche +// stats.showPanel(0) // 0: fps, 1: ms, 2: mb, 3+: custom +// document.body.appendChild(stats.dom) + // light const ambientLight = new THREE.AmbientLight( 0xffffff, 2.5) ; // color, intensity scene.add( ambientLight) ; @@ -67,8 +83,16 @@ const gridGroup = new THREE.Group() ; const frameGroup = new THREE.Group() ; -//init(); +/* +* Oggetto principale gestione WebGL Door visualizer +*/ class webgl_original { + + /** + * Metodo Init con visualizzazzione dati + * @param {string} modelPath Percorso base recupero modello 3dm + * @param {string} fName Nome del modello 3dm da visualizzare + */ async initcall({ modelPath, fName}) { PATH = modelPath; FILE_NAME = fName; @@ -82,6 +106,95 @@ class webgl_original { let timeElapsed = endTime - startTime; console.log('init done in : ' + timeElapsed); } + + async doFreeze() + { + freezed = true; + } + + async doAnimate() + { + freezed = false; + // if(freezed) + // { + // freezed = false; + // await animate(); + // } + } + + /** + * reset posizione camera + */ + resetCamera() + { + myResetCamera(); + } + + + /** + * imposta vista isometrica/ortografica + */ + setCameraOrtho() + { + mySetCameraOrtho() + } + + /** + * imposta vista prospettica + */ + setCameraPersp() + { + mySetCameraPersp() + } + + /** + * toggle visualizzazione cubo + */ + toggleCube() + { + myToggleCubeVisibility(); + } + + // /** + // * toggle visualizzazione frame assi + // */ + // toggleFrame() + // { + // myToggleFrameVisibility(); + // } + + /** + * toggle visualizzazione griglia + */ + toggleGrid() + { + myToggleGridVisibility(); + } + + /** + * toggle visualizzazione quotature + */ + toggleQuotes() + { + myToggleQuote() + } + + /** + * toggle rotazione + */ + toggleRotation() + { + myToggleRotation() + } + + /** + * Imposta rotazione + * @param {boolean} isRotating + */ + setRotate(isRotating) + { + mySetRotation(isRotating); + } } export { webgl_original } @@ -90,12 +203,31 @@ export { webgl_original } // rendering function animate() { requestAnimationFrame( animate) ; + + const elapsedTime = clock.getElapsedTime(); + targetTimeStep = fpsTgtHigh; + if (freezed) + { + targetTimeStep = fpsTgtLow; + // Update only if enough time has passed for target FPS + if (elapsedTime < targetTimeStep) + return; + } + + + // if (freezed) + // { + // console.log(freezed); + // return; + // } + renderer.render( scene, controls.object) ; controls.update() ; cube_ref.update( controls) ; renderer_ref.render( scene_ref, camera_ref) ; - updateRef( frame_ref1, camera_ref1, controls) ; - renderer_ref1.render( scene_ref1, camera_ref1) ; + // updateRef( frame_ref1, camera_ref1, controls) ; + // renderer_ref1.render( scene_ref1, camera_ref1) ; + clock.start(); } function readDoor() { @@ -105,22 +237,22 @@ function readDoor() { // removing shading from colors and adjusting z-fighting with lines ( organizing groups entities ) for ( let i = 0 ; i < object.children.length ; ++ i) setOpenGLRenderProperties( object.children[i], dimensionGroup, general_entity_Group) ; - // adding groups to scene + // adding groups to scene scene.add( dimensionGroup) ; scene.add( general_entity_Group) ; - // setting Box3d of the door + // setting Box3d of the door set3dBox( object) ; - // setting camera position + // setting camera position setCameraPosition() ; - // setting grid + // setting grid setGrid() ; - // setting frame + // setting frame setFrame() ; - // static cube + // static cube setStaticCube() ; - // static frame - setStaticFrame() ; - // render loop + // // static frame + // setStaticFrame() ; + // render loop animate() ; }) ; } @@ -258,6 +390,8 @@ function setStaticCube() { // renderer renderer_ref = new THREE.WebGLRenderer({ antialias: true, alpha : true, transparent : true}) ; renderer_ref.setSize( divContainer.clientWidth, divContainer.clientHeight) ; + // valutare abbassamento risoluzione + // renderer_ref.setPixelRatio( 1 * window.devicePixelRatio) ; renderer_ref.setPixelRatio( 2 * window.devicePixelRatio) ; divContainer.appendChild( renderer_ref.domElement) ; // scene @@ -288,38 +422,30 @@ function setStaticCube() { cube_ref._colorCube() ; } -function setStaticFrame() { - // container of the cube - const divContainer = document.getElementById( 'Ref1Render') ; - // renderer - renderer_ref1 = new THREE.WebGLRenderer({ antialias: true, alpha : true, transparent : true}) ; - renderer_ref1.setSize( divContainer.clientWidth, divContainer.clientHeight) ; - renderer_ref1.setPixelRatio( 2 * window.devicePixelRatio) ; - divContainer.appendChild( renderer_ref1.domElement) ; - // scene - scene_ref1 = new THREE.Scene() ; - if ( CAMERA_TYPE == CAMERA_ORTHO) - camera_ref1 = new THREE.OrthographicCamera( - divContainer.clientWidth / 5, divContainer.clientWidth / 5, - divContainer.clientHeight / 5, - divContainer.clientHeight / 5, 0.1, 1000) ; - else - camera_ref1 = new THREE.PerspectiveCamera( 50, 1, 0.1, 1000) ; - // setting standard camera posizion and lookAt -> made according cube dimension - camera_ref1.position.set( 0, 0, 70) ; - camera_ref1.lookAt( 0, 0, 0) ; - // creating the cube object and adding it to the scene - frame_ref1 = getStaticRef( 1, 25) ; - scene_ref1.add( frame_ref1) ; -} +// function setStaticFrame() { +// // container of the cube +// const divContainer = document.getElementById( 'Ref1Render') ; +// // renderer +// renderer_ref1 = new THREE.WebGLRenderer({ antialias: true, alpha : true, transparent : true}) ; +// renderer_ref1.setSize( divContainer.clientWidth, divContainer.clientHeight) ; +// renderer_ref1.setPixelRatio( 2 * window.devicePixelRatio) ; +// divContainer.appendChild( renderer_ref1.domElement) ; +// // scene +// scene_ref1 = new THREE.Scene() ; +// if ( CAMERA_TYPE == CAMERA_ORTHO) +// camera_ref1 = new THREE.OrthographicCamera( - divContainer.clientWidth / 5, divContainer.clientWidth / 5, +// divContainer.clientHeight / 5, - divContainer.clientHeight / 5, 0.1, 1000) ; +// else +// camera_ref1 = new THREE.PerspectiveCamera( 50, 1, 0.1, 1000) ; +// // setting standard camera posizion and lookAt -> made according cube dimension +// camera_ref1.position.set( 0, 0, 70) ; +// camera_ref1.lookAt( 0, 0, 0) ; +// // creating the cube object and adding it to the scene +// frame_ref1 = getStaticRef( 1, 25) ; +// scene_ref1.add( frame_ref1) ; +// } -function ToggleRotation() { - controls.autoRotate = ( ! controls.autoRotate) ; -} - -function toggleDimensionVisibility() { - dimensionGroup.visible = ! dimensionGroup.visible ; -} - -function toggleCubeVisibility() { +function myToggleCubeVisibility() { var cubeContainer = document.getElementById( 'RefRender') ; if ( cubeContainer.style.display === "none") cubeContainer.style.display = "block"; @@ -327,67 +453,46 @@ function toggleCubeVisibility() { cubeContainer.style.display = "none"; } -function toggleFrameVisibility() { - var frameContainer = document.getElementById( 'Ref1Render') ; - if ( frameContainer.style.display === "none") - frameContainer.style.display = "block"; - else - frameContainer.style.display = "none"; -} +// function myToggleFrameVisibility() { +// var frameContainer = document.getElementById( 'Ref1Render') ; +// if ( frameContainer.style.display === "none") +// frameContainer.style.display = "block"; +// else +// frameContainer.style.display = "none"; +// } -function toggleGridVisibility() { +function myToggleGridVisibility() { gridGroup.visible = ! gridGroup.visible ; frameGroup.visible = ! frameGroup.visible ; } -// Event Listner ------------------------------------------------------------------- - // KEY -document.addEventListener( "keypress", function( event) { - if ( event.key.toLowerCase() === "r") - ToggleRotation() ; - else if ( event.key.toLowerCase() === 'p') { - if ( CAMERA_TYPE == CAMERA_PERSP) - return ; - controls.object = perspCamera.clone() ; - CAMERA_TYPE = CAMERA_PERSP ; - setCameraPosition() ; - } - else if ( event.key.toLowerCase() === 'o') { - if ( CAMERA_TYPE == CAMERA_ORTHO) - return ; - controls.object = ortoCamera.clone() ; - CAMERA_TYPE = CAMERA_ORTHO ; - setCameraPosition() ; - } - else if ( event.key.toLowerCase() === 'd') - toggleDimensionVisibility() ; - else if ( event.key.toLowerCase() === ' ') - setCameraPosition() ; - else if ( event.key.toLowerCase() === 'c') - toggleCubeVisibility() ; - else if ( event.key.toLowerCase() === 'f') - toggleFrameVisibility() ; - else if ( event.key.toLowerCase() === 'g') - toggleGridVisibility() ; -}) ; +function mySetRotation(isRotating) { + controls.autoRotate = isRotating ; +} +function myToggleRotation() { + controls.autoRotate = ( ! controls.autoRotate) ; +} - // Elements -var helpButton = document.getElementById( "helpButton") ; -var infoDiv = document.getElementById( "infoDiv") ; -infoDiv.style.display = "none"; -helpButton.addEventListener( "click", function() { - if ( infoDiv.style.display === "none") - infoDiv.style.display = "block" ; - else - infoDiv.style.display = "none"; -}) ; +function myToggleQuote() { + dimensionGroup.visible = ! dimensionGroup.visible ; +} -// // Reading URL parameters ------------------------------------------------------------------------- -// function getUrlParameter( name) { -// // get query string from URL -// const queryString = window.location.search ; -// // create URLSearchParams object from query string -// const urlParams = new URLSearchParams( queryString) ; -// // get parameter value by name -// return urlParams.get( name) ; -// } \ No newline at end of file +function mySetCameraOrtho() { + if ( CAMERA_TYPE == CAMERA_ORTHO) + return ; + controls.object = ortoCamera.clone() ; + CAMERA_TYPE = CAMERA_ORTHO ; + setCameraPosition() ; +} + +function mySetCameraPersp() { + if ( CAMERA_TYPE == CAMERA_PERSP) + return ; + controls.object = perspCamera.clone() ; + CAMERA_TYPE = CAMERA_PERSP ; + setCameraPosition() ; +} + +function myResetCamera() { + setCameraPosition() ; +} diff --git a/WebDoorView/src/style.css b/WebDoorView/src/style.css index 505f31f..fec1c16 100644 --- a/WebDoorView/src/style.css +++ b/WebDoorView/src/style.css @@ -14,59 +14,38 @@ canvas { #divMenu { position: fixed ; - top: 10px ; - right: 10px ; + top: 0.5rem; + right: 0.2rem; background-color: transparent ; - width: 275px ; } -.container { - width: 100% ; - height: auto ; - margin-bottom: 10px ; -} - -.container::after { - content: "" ; - display: table ; - clear: both ; -} - -.container img { - width: 100% ; - height: auto ; - display: block ; -} - -#helpButton { - text-decoration: underline ; - float: right ; - height: auto ; +#divLogo{ + position: fixed ; + top: 4rem; + right: 0.5rem; + height: 5rem; + width: 4rem; + font-size: 0.8rem; } #infoDiv { - width: 100% ; - height: auto ; - color: white ; + position: fixed ; + top: 3.75rem; + right: 0.5rem; + z-index: 10; + + width: 15rem; + height: auto; + /* color: white ; */ background-color: transparent ; font-size: 0.9em ; } #RefRender { position: fixed ; - width: 200px ; - height: 200px ; - bottom: 10px ; - right: 10px ; - /*border: 1px solid black ;*/ -} - -#Ref1Render { - position: fixed ; - width: 150px ; - height: 150px ; - bottom: 10px ; - left: 10px ; + width: 8rem ; + height: 8rem ; + bottom: 0.5rem ; + left: 0.5rem ; background-color: transparent ; - /*border: 1px solid black ;*/ }