diff --git a/.claude/settings.local.json b/.claude/settings.local.json
new file mode 100644
index 0000000..b0cf4f5
--- /dev/null
+++ b/.claude/settings.local.json
@@ -0,0 +1,12 @@
+{
+ "permissions": {
+ "allow": [
+ "mcp__chrome-devtools__list_pages",
+ "mcp__chrome-devtools__navigate_page",
+ "mcp__chrome-devtools__take_snapshot",
+ "mcp__chrome-devtools__take_screenshot",
+ "mcp__chrome-devtools__evaluate_script",
+ "mcp__chrome-devtools__drag"
+ ]
+ }
+}
diff --git a/src/assets/data.json b/src/assets/data.json
index 91fb5b3..7b41b86 100644
--- a/src/assets/data.json
+++ b/src/assets/data.json
@@ -7,71 +7,91 @@
"label_en": "Lateral bands",
"fields": [
{
- "field_type": "select",
- "data_type": "model",
- "material": "metal",
- "color": "#FFFFFF",
+ "field_type": "group",
"label": "DX",
- "label_en": "",
- "options": [
- {
- "label": "Nessuno",
- "label_en": "None",
- "value": ""
- },
+ "label_en": "Right",
+ "id": 100,
+ "parent_id": 99,
+ "fields": [
{
+ "field_type": "checkbox",
+ "data_type": "model",
"label_en": "Band 14",
"label": "Banda 14",
- "value": "2_banda 14"
+ "value": "2_banda 14",
+ "material": "metal",
+ "color": "#FFFFFF",
+ "parent_id": 100,
+ "id": "input-101"
},
{
+ "field_type": "checkbox",
+ "data_type": "model",
"label_en": "Band 15",
"label": "Banda 15",
- "value": "2_banda 15"
- },
+ "value": "2_banda 15",
+ "material": "metal",
+ "color": "#FFFFFF",
+ "parent_id": 100,
+ "id": "input-102"
+ },
{
+ "field_type": "checkbox",
+ "data_type": "model",
"label_en": "Band 16",
"label": "Banda 16",
- "value": "2_banda 16"
- }
- ],
- "parent_id": 1,
- "id": "input-1"
+ "value": "2_banda 16",
+ "material": "metal",
+ "color": "#FFFFFF",
+ "parent_id": 100,
+ "id": "input-103"
+ }
+ ]
},
- {
- "field_type": "select",
- "data_type": "model",
- "material": "metal",
- "color": "#FFFFFF",
+ {
+ "field_type": "group",
"label": "SX",
- "label_en": "",
- "options": [
- {
- "label": "Nessuno",
- "label_en": "None",
- "value": ""
- },
+ "label_en": "Left",
+ "id": 101,
+ "parent_id": 99,
+ "fields": [
{
+ "field_type": "checkbox",
+ "data_type": "model",
"label_en": "Band 24",
"label": "Banda 24",
- "value": "2_banda 24"
+ "value": "2_banda 24",
+ "material": "metal",
+ "color": "#FFFFFF",
+ "parent_id": 101,
+ "id": "input-104"
},
{
+ "field_type": "checkbox",
+ "data_type": "model",
"label_en": "Band 25",
"label": "Banda 25",
- "value": "2_banda 25"
- },
+ "value": "2_banda 25",
+ "material": "metal",
+ "color": "#FFFFFF",
+ "parent_id": 101,
+ "id": "input-105"
+ },
{
+ "field_type": "checkbox",
+ "data_type": "model",
"label_en": "Band 26",
"label": "Banda 26",
- "value": "2_banda 26"
- }
- ],
- "parent_id": 1,
- "id": "input-2"
- }
+ "value": "2_banda 26",
+ "material": "metal",
+ "color": "#FFFFFF",
+ "parent_id": 101,
+ "id": "input-106"
+ }
+ ]
+ }
],
- "id": 1
+ "id": 99
},
{
"label": "TADS",
@@ -114,8 +134,8 @@
"data_type": "model",
"material": "metal",
"color": "#FFFFFF",
- "label": "Numero di Tads",
- "label_en": "Number of Tads",
+ "label": "Tipologia Viti",
+ "label_en": "Type of Screws",
"options": [
{
"label": "Nessuno",
@@ -223,6 +243,7 @@
"label_en": "TADS Tandem",
"material": "metal",
"color": "#FFFFFF",
+ "reset_field": "input-4",
"options": [
{
"label": "Nessuno",
@@ -306,6 +327,8 @@
"data_type": "model",
"label": "Modulo DX",
"label_en": "Right Module",
+
+ "depends_on": {"id":"input-14", "value":"11_modulo dx", "hide": true},
"material": "metal",
"value": "10_modulo dx",
"color": "#FFFFFF",
@@ -316,6 +339,7 @@
"data_type": "model",
"label": "Modulo SX",
"label_en": "Left Module",
+ "depends_on": {"id":"input-15", "value":"11_modulo sx", "hide": true},
"material": "metal",
"value": "10_modulo sx",
"color": "#FFFFFF",
@@ -333,6 +357,8 @@
"data_type": "model",
"label": "Modulo DX",
"label_en": "Right Module",
+ "depends_on": {"id":"input-12", "value":"10_modulo dx", "hide": true},
+
"material": "metal",
"value": "11_modulo dx",
"color": "#FFFFFF",
@@ -343,6 +369,7 @@
"data_type": "model",
"label": "Modulo SX",
"label_en": "Left Module",
+ "depends_on": {"id":"input-13", "value":"10_modulo sx", "hide": true},
"material": "metal",
"value": "11_modulo sx",
"color": "#FFFFFF",
@@ -360,8 +387,14 @@
"data_type": "model",
"label": "Modulo DX",
"label_en": "Right Module",
+ "depends_on": {"id":"input-18", "value":"13_modulo x intrudere dx", "hide": true},
"material": "metal",
"value": "12_modulo dx",
+ "other_models": [{
+ "color": "#f073c4",
+ "material": "plastic",
+ "model": "12_molla dx"
+ }],
"color": "#FFFFFF",
"parent_id": 11,
"id": "input-16"
@@ -370,8 +403,14 @@
"data_type": "model",
"label": "Modulo SX",
"label_en": "Left Module",
- "material": "metal",
+ "depends_on": {"id":"input-19", "value":"13_modulo x intrudere sx", "hide": true},
"value": "12_modulo sx",
+ "other_models": [{
+ "color": "#f073c4",
+ "material": "plastic",
+ "model": "12_molla sx"
+ }],
+ "material": "metal",
"color": "#FFFFFF",
"parent_id": 11,
"id": "input-17"
@@ -387,6 +426,16 @@
"data_type": "model",
"label": "Modulo DX",
"label_en": "Right Module",
+ "depends_on": {"id":"input-16", "value":"12_modulo dx", "hide": true},
+ "other_models": [{
+ "color": "#f073c4",
+ "material": "plastic",
+ "model": "13_molla dx"
+ },{
+ "color": "#34eb3d",
+ "material": "plastic",
+ "model": "13_denti dx"
+ }],
"material": "metal",
"value": "13_modulo x intrudere dx",
"color": "#FFFFFF",
@@ -397,6 +446,16 @@
"data_type": "model",
"label": "Modulo SX",
"label_en": "Left Module",
+ "depends_on": {"id":"input-17", "value":"12_modulo sx", "hide": true},
+ "other_models": [{
+ "color": "#f073c4",
+ "material": "plastic",
+ "model": "13_molla sx"
+ },{
+ "color": "#34eb3d",
+ "material": "plastic",
+ "model": "13_denti sx"
+ }],
"material": "metal",
"value": "13_modulo x intrudere sx",
"color": "#FFFFFF",
@@ -412,8 +471,9 @@
{
"field_type": "checkbox",
"data_type": "model",
- "label": "Attacchi per Mask",
- "label_en": "Mask Hooks",
+ "label": "Attacchi per Aligners",
+ "label_en": "Aligners Hooks",
+ "hide_elements": ["input-21","input-22", "input-25"],
"material": "metal",
"value": "14_attacchi x mask",
"color": "#FFFFFF",
@@ -424,6 +484,7 @@
"data_type": "model",
"label": "Attacco doppia canula DX",
"label_en": "Double Cannula Hook Right",
+ "hide_elements": ["input-20"],
"material": "metal",
"value": "14_attacco doppia canula dx",
"color": "#FFFFFF",
@@ -434,6 +495,7 @@
"data_type": "model",
"label": "Attacco doppia canula SX",
"label_en": "Double Cannula Hook Left",
+ "hide_elements": ["input-20"],
"material": "metal",
"value": "14_attacco doppia canula sx",
"color": "#FFFFFF",
@@ -464,6 +526,7 @@
"data_type": "model",
"label": "Gradino",
"label_en": "Step",
+ "hide_elements": ["input-20"],
"material": "metal",
"value": "14_gradino",
"color": "#FFFFFF",
diff --git a/src/assets/glb/12_modulo dx.glb b/src/assets/glb/12_modulo dx.glb
index d381731..569ac1a 100644
Binary files a/src/assets/glb/12_modulo dx.glb and b/src/assets/glb/12_modulo dx.glb differ
diff --git a/src/assets/glb/12_modulo sx.glb b/src/assets/glb/12_modulo sx.glb
index 3ef8984..2ee434b 100644
Binary files a/src/assets/glb/12_modulo sx.glb and b/src/assets/glb/12_modulo sx.glb differ
diff --git a/src/assets/glb/12_molla dx.glb b/src/assets/glb/12_molla dx.glb
new file mode 100644
index 0000000..cb1b642
Binary files /dev/null and b/src/assets/glb/12_molla dx.glb differ
diff --git a/src/assets/glb/12_molla sx.glb b/src/assets/glb/12_molla sx.glb
new file mode 100644
index 0000000..33ac594
Binary files /dev/null and b/src/assets/glb/12_molla sx.glb differ
diff --git a/src/assets/glb/13_denti dx.glb b/src/assets/glb/13_denti dx.glb
new file mode 100644
index 0000000..d0f25bf
Binary files /dev/null and b/src/assets/glb/13_denti dx.glb differ
diff --git a/src/assets/glb/13_denti sx.glb b/src/assets/glb/13_denti sx.glb
new file mode 100644
index 0000000..c513011
Binary files /dev/null and b/src/assets/glb/13_denti sx.glb differ
diff --git a/src/assets/glb/13_modulo x intrudere dx.glb b/src/assets/glb/13_modulo x intrudere dx.glb
index e0e6841..514b8a4 100644
Binary files a/src/assets/glb/13_modulo x intrudere dx.glb and b/src/assets/glb/13_modulo x intrudere dx.glb differ
diff --git a/src/assets/glb/13_modulo x intrudere sx.glb b/src/assets/glb/13_modulo x intrudere sx.glb
index 9c4bfbd..99276d4 100644
Binary files a/src/assets/glb/13_modulo x intrudere sx.glb and b/src/assets/glb/13_modulo x intrudere sx.glb differ
diff --git a/src/assets/glb/13_molla dx.glb b/src/assets/glb/13_molla dx.glb
new file mode 100644
index 0000000..4591701
Binary files /dev/null and b/src/assets/glb/13_molla dx.glb differ
diff --git a/src/assets/glb/13_molla sx.glb b/src/assets/glb/13_molla sx.glb
new file mode 100644
index 0000000..024112a
Binary files /dev/null and b/src/assets/glb/13_molla sx.glb differ
diff --git a/src/assets/glb/14_attacchi x mask.glb b/src/assets/glb/14_attacchi x mask.glb
index 3ce8411..11edb69 100644
Binary files a/src/assets/glb/14_attacchi x mask.glb and b/src/assets/glb/14_attacchi x mask.glb differ
diff --git a/src/assets/glb/14_attacco doppia canula dx.glb b/src/assets/glb/14_attacco doppia canula dx.glb
index 808b305..e3524ec 100644
Binary files a/src/assets/glb/14_attacco doppia canula dx.glb and b/src/assets/glb/14_attacco doppia canula dx.glb differ
diff --git a/src/assets/glb/14_attacco doppia canula sx.glb b/src/assets/glb/14_attacco doppia canula sx.glb
index 1f2de2b..5bd915d 100644
Binary files a/src/assets/glb/14_attacco doppia canula sx.glb and b/src/assets/glb/14_attacco doppia canula sx.glb differ
diff --git a/src/assets/glb/14_ganci x delaire esterna.glb b/src/assets/glb/14_ganci x delaire esterna.glb
index 1be9c6b..f4d35b5 100644
Binary files a/src/assets/glb/14_ganci x delaire esterna.glb and b/src/assets/glb/14_ganci x delaire esterna.glb differ
diff --git a/src/assets/glb/14_gradino.glb b/src/assets/glb/14_gradino.glb
index 0dd7352..61c3795 100644
Binary files a/src/assets/glb/14_gradino.glb and b/src/assets/glb/14_gradino.glb differ
diff --git a/src/assets/images/logo.jpg b/src/assets/images/logo.jpg
index 2fd7848..6b09df1 100644
Binary files a/src/assets/images/logo.jpg and b/src/assets/images/logo.jpg differ
diff --git a/src/assets/images/logo_1.png b/src/assets/images/logo_1.png
new file mode 100644
index 0000000..c1b1216
Binary files /dev/null and b/src/assets/images/logo_1.png differ
diff --git a/src/assets/images/logo_old.jpg b/src/assets/images/logo_old.jpg
new file mode 100644
index 0000000..2fd7848
Binary files /dev/null and b/src/assets/images/logo_old.jpg differ
diff --git a/src/assets/project.json b/src/assets/project.json
new file mode 100644
index 0000000..3da6cda
--- /dev/null
+++ b/src/assets/project.json
@@ -0,0 +1,467 @@
+{
+ "metadata": {},
+ "project": {
+ "shadows": true,
+ "shadowType": 1,
+ "toneMapping": 0,
+ "toneMappingExposure": 1
+ },
+ "camera": {
+ "metadata": {
+ "version": 4.7,
+ "type": "Object",
+ "generator": "Object3D.toJSON"
+ },
+ "object": {
+ "uuid": "395a500c-0494-41ec-b6d0-c8bbe4349725",
+ "type": "PerspectiveCamera",
+ "name": "Camera",
+ "layers": 1,
+ "matrix": [
+ 0.11049213351682519,
+ 2.7755575615628914e-17,
+ 0.9938769986426388,
+ 0,
+ 0.4629545750185746,
+ 0.8848864948632306,
+ -0.051467977209491755,
+ 0,
+ -0.8794683336540725,
+ 0.4658067101370114,
+ 0.09777299673766349,
+ 0,
+ -205.25558887415772,
+ 82.23047074745682,
+ 17.26020551692521,
+ 1
+ ],
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "fov": 50,
+ "zoom": 1,
+ "near": 0.01,
+ "far": 1000,
+ "focus": 10,
+ "aspect": 1.7745302713987474,
+ "filmGauge": 35,
+ "filmOffset": 0
+ }
+ },
+ "controls": {
+ "center": [
+ -50,
+ 0,
+ 0
+ ]
+ },
+ "scene": {
+ "metadata": {
+ "version": 4.7,
+ "type": "Object",
+ "generator": "Object3D.toJSON"
+ },
+ "object": {
+ "uuid": "a2253e4f-b675-48b1-8c2c-76d897bcac25",
+ "type": "Scene",
+ "name": "Scene",
+ "layers": 1,
+ "matrix": [
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1
+ ],
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "children": [
+ {
+ "uuid": "2ef7dca1-f570-417b-b55a-46c017f98630",
+ "type": "Scene",
+ "name": "Scene",
+ "layers": 1,
+ "matrix": [
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1
+ ],
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "children": [
+ {
+ "uuid": "f106381a-534c-497e-acbd-a3b2ad121b9a",
+ "type": "DirectionalLight",
+ "name": "DirectionalLight",
+ "layers": 1,
+ "matrix": [
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 3.0997198829600077,
+ -97.44223652603492,
+ 1
+ ],
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "color": 16777215,
+ "intensity": 0.8,
+ "shadow": {
+ "camera": {
+ "uuid": "38eaf299-1e78-4fc7-adce-080811a9fe47",
+ "type": "OrthographicCamera",
+ "layers": 1,
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "zoom": 1,
+ "left": -5,
+ "right": 5,
+ "top": 5,
+ "bottom": -5,
+ "near": 0.5,
+ "far": 500
+ }
+ },
+ "target": "0e530621-c1bb-48c8-87e3-224a85a2e9c1"
+ },
+ {
+ "uuid": "0b4faf09-07b3-4ab2-80a7-955bf83b8815",
+ "type": "DirectionalLight",
+ "name": "DirectionalLight",
+ "layers": 1,
+ "matrix": [
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 50,
+ 0,
+ 0,
+ 1
+ ],
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "color": 16777215,
+ "intensity": 1,
+ "shadow": {
+ "camera": {
+ "uuid": "3487b036-5d5a-4331-b589-3b9c0472d0af",
+ "type": "OrthographicCamera",
+ "layers": 1,
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "zoom": 1,
+ "left": -5,
+ "right": 5,
+ "top": 5,
+ "bottom": -5,
+ "near": 0.5,
+ "far": 500
+ }
+ },
+ "target": "77316e30-bf2c-49ae-bbbd-1a40c413140c"
+ },
+ {
+ "uuid": "4ef0f77a-df7b-42f8-809d-35028cfc71bc",
+ "type": "DirectionalLight",
+ "name": "DirectionalLight",
+ "layers": 1,
+ "matrix": [
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ -50,
+ 0,
+ 0,
+ 1
+ ],
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "color": 16777215,
+ "intensity": 1,
+ "shadow": {
+ "camera": {
+ "uuid": "0d0ac848-ef38-4ddc-9d4b-bd1a3fa259e6",
+ "type": "OrthographicCamera",
+ "layers": 1,
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "zoom": 1,
+ "left": -5,
+ "right": 5,
+ "top": 5,
+ "bottom": -5,
+ "near": 0.5,
+ "far": 500
+ }
+ },
+ "target": "9a8f9881-3997-4b11-9a5d-ab5dbaf0de11"
+ },
+ {
+ "uuid": "54bbb245-78cb-4ab9-bd57-0f02711f8a03",
+ "type": "DirectionalLight",
+ "name": "DirectionalLight",
+ "layers": 1,
+ "matrix": [
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ -38.28056498637591,
+ 4.399184106340684,
+ 1
+ ],
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "color": 16777215,
+ "intensity": 0.6,
+ "shadow": {
+ "camera": {
+ "uuid": "ba78f102-e863-4df9-a295-f56af374dbe9",
+ "type": "OrthographicCamera",
+ "layers": 1,
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "zoom": 1,
+ "left": -5,
+ "right": 5,
+ "top": 5,
+ "bottom": -5,
+ "near": 0.5,
+ "far": 500
+ }
+ },
+ "target": "ac43e49a-3301-4a12-9d90-0ce724dff367"
+ },
+ {
+ "uuid": "5f633583-57db-4472-be10-2dce0a75d139",
+ "type": "DirectionalLight",
+ "name": "DirectionalLight",
+ "layers": 1,
+ "matrix": [
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 15.833769711930671,
+ 37.90623637377939,
+ 1
+ ],
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "color": 16777215,
+ "intensity": 0.5,
+ "shadow": {
+ "camera": {
+ "uuid": "9e8a1c42-2f57-4648-9db1-40e59ac6b6e0",
+ "type": "OrthographicCamera",
+ "layers": 1,
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "zoom": 1,
+ "left": -5,
+ "right": 5,
+ "top": 5,
+ "bottom": -5,
+ "near": 0.5,
+ "far": 500
+ }
+ },
+ "target": "44ee6450-dc88-46e5-90e7-781de0a69288"
+ }
+ ],
+ "backgroundRotation": [
+ 0,
+ 0,
+ 0,
+ "XYZ"
+ ],
+ "environmentRotation": [
+ 0,
+ 0,
+ 0,
+ "XYZ"
+ ]
+ },
+ {
+ "uuid": "09cd262e-79bd-4975-b449-1b813209f26d",
+ "type": "DirectionalLight",
+ "name": "DirectionalLight",
+ "layers": 1,
+ "matrix": [
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 25.33505179809299,
+ -6.19180174206452,
+ 1
+ ],
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "color": 16777215,
+ "intensity": 0.6,
+ "shadow": {
+ "camera": {
+ "uuid": "192b16bb-49e2-4be6-8a88-5058304606a6",
+ "type": "OrthographicCamera",
+ "layers": 1,
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "zoom": 1,
+ "left": -5,
+ "right": 5,
+ "top": 5,
+ "bottom": -5,
+ "near": 0.5,
+ "far": 500
+ }
+ },
+ "target": "06277cc9-87d0-49d9-8716-5f745df7ee03"
+ }
+ ],
+ "backgroundBlurriness": 0.2,
+ "backgroundIntensity": 0.93,
+ "backgroundRotation": [
+ 0,
+ 0,
+ 0,
+ "XYZ"
+ ],
+ "environmentRotation": [
+ 0,
+ 0,
+ 0,
+ "XYZ"
+ ]
+ }
+ },
+ "scripts": {},
+ "history": {
+ "undos": [],
+ "redos": []
+ },
+ "environment": null
+}
\ No newline at end of file
diff --git a/src/assets/scene.json b/src/assets/scene.json
index 059dfd7..8a84dff 100644
--- a/src/assets/scene.json
+++ b/src/assets/scene.json
@@ -11,131 +11,262 @@
"layers": 1,
"matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],
"up": [0,1,0],
- "children": [
- {
- "uuid": "f106381a-534c-497e-acbd-a3b2ad121b9a",
- "type": "DirectionalLight",
- "name": "DirectionalLight",
- "layers": 1,
- "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,3.0997198829600077,-97.44223652603492,1],
- "up": [0,1,0],
- "color": 16777215,
- "intensity": 0.8,
- "shadow": {
- "camera": {
- "uuid": "38eaf299-1e78-4fc7-adce-080811a9fe47",
- "type": "OrthographicCamera",
- "layers": 1,
- "up": [0,1,0],
- "zoom": 1,
- "left": -5,
- "right": 5,
- "top": 5,
- "bottom": -5,
- "near": 0.5,
- "far": 500
- }
- }
- },
- {
- "uuid": "0b4faf09-07b3-4ab2-80a7-955bf83b8815",
- "type": "DirectionalLight",
- "name": "DirectionalLight",
- "layers": 1,
- "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,50,0,0,1],
- "up": [0,1,0],
- "color": 16777215,
- "intensity": 1,
- "shadow": {
- "camera": {
- "uuid": "3487b036-5d5a-4331-b589-3b9c0472d0af",
- "type": "OrthographicCamera",
- "layers": 1,
- "up": [0,1,0],
- "zoom": 1,
- "left": -5,
- "right": 5,
- "top": 5,
- "bottom": -5,
- "near": 0.5,
- "far": 500
- }
- }
- },
- {
- "uuid": "4ef0f77a-df7b-42f8-809d-35028cfc71bc",
- "type": "DirectionalLight",
- "name": "DirectionalLight",
- "layers": 1,
- "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,-50,0,0,1],
- "up": [0,1,0],
- "color": 16777215,
- "intensity": 1,
- "shadow": {
- "camera": {
- "uuid": "0d0ac848-ef38-4ddc-9d4b-bd1a3fa259e6",
- "type": "OrthographicCamera",
- "layers": 1,
- "up": [0,1,0],
- "zoom": 1,
- "left": -5,
- "right": 5,
- "top": 5,
- "bottom": -5,
- "near": 0.5,
- "far": 500
- }
- }
- },
- {
- "uuid": "54bbb245-78cb-4ab9-bd57-0f02711f8a03",
- "type": "DirectionalLight",
- "name": "DirectionalLight",
- "layers": 1,
- "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,-38.28056498637591,4.399184106340684,1],
- "up": [0,1,0],
- "color": 16777215,
- "intensity": 0.6,
- "shadow": {
- "camera": {
- "uuid": "ba78f102-e863-4df9-a295-f56af374dbe9",
- "type": "OrthographicCamera",
- "layers": 1,
- "up": [0,1,0],
- "zoom": 1,
- "left": -5,
- "right": 5,
- "top": 5,
- "bottom": -5,
- "near": 0.5,
- "far": 500
- }
- }
- },
- {
- "uuid": "5f633583-57db-4472-be10-2dce0a75d139",
- "type": "DirectionalLight",
- "name": "DirectionalLight",
- "layers": 1,
- "matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,15.833769711930671,37.90623637377939,1],
- "up": [0,1,0],
- "color": 16777215,
- "intensity": 0.5,
- "shadow": {
- "camera": {
- "uuid": "9e8a1c42-2f57-4648-9db1-40e59ac6b6e0",
- "type": "OrthographicCamera",
- "layers": 1,
- "up": [0,1,0],
- "zoom": 1,
- "left": -5,
- "right": 5,
- "top": 5,
- "bottom": -5,
- "near": 0.5,
- "far": 500
- }
- }
- }]
+ "children": [
+ {
+ "uuid": "f106381a-534c-497e-acbd-a3b2ad121b9a",
+ "type": "DirectionalLight",
+ "name": "DirectionalLight",
+ "layers": 1,
+ "matrix": [
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 3.0997198829600077,
+ -97.44223652603492,
+ 1
+ ],
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "color": 16777215,
+ "intensity": 0.8,
+ "shadow": {
+ "camera": {
+ "uuid": "38eaf299-1e78-4fc7-adce-080811a9fe47",
+ "type": "OrthographicCamera",
+ "layers": 1,
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "zoom": 1,
+ "left": -5,
+ "right": 5,
+ "top": 5,
+ "bottom": -5,
+ "near": 0.5,
+ "far": 500
+ }
+ },
+ "target": "0e530621-c1bb-48c8-87e3-224a85a2e9c1"
+ },
+ {
+ "uuid": "0b4faf09-07b3-4ab2-80a7-955bf83b8815",
+ "type": "DirectionalLight",
+ "name": "DirectionalLight",
+ "layers": 1,
+ "matrix": [
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 50,
+ 0,
+ 0,
+ 1
+ ],
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "color": 16777215,
+ "intensity": 1,
+ "shadow": {
+ "camera": {
+ "uuid": "3487b036-5d5a-4331-b589-3b9c0472d0af",
+ "type": "OrthographicCamera",
+ "layers": 1,
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "zoom": 1,
+ "left": -5,
+ "right": 5,
+ "top": 5,
+ "bottom": -5,
+ "near": 0.5,
+ "far": 500
+ }
+ },
+ "target": "77316e30-bf2c-49ae-bbbd-1a40c413140c"
+ },
+ {
+ "uuid": "4ef0f77a-df7b-42f8-809d-35028cfc71bc",
+ "type": "DirectionalLight",
+ "name": "DirectionalLight",
+ "layers": 1,
+ "matrix": [
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ -50,
+ 0,
+ 0,
+ 1
+ ],
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "color": 16777215,
+ "intensity": 1,
+ "shadow": {
+ "camera": {
+ "uuid": "0d0ac848-ef38-4ddc-9d4b-bd1a3fa259e6",
+ "type": "OrthographicCamera",
+ "layers": 1,
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "zoom": 1,
+ "left": -5,
+ "right": 5,
+ "top": 5,
+ "bottom": -5,
+ "near": 0.5,
+ "far": 500
+ }
+ },
+ "target": "9a8f9881-3997-4b11-9a5d-ab5dbaf0de11"
+ },
+ {
+ "uuid": "54bbb245-78cb-4ab9-bd57-0f02711f8a03",
+ "type": "DirectionalLight",
+ "name": "DirectionalLight",
+ "layers": 1,
+ "matrix": [
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ -38.28056498637591,
+ 4.399184106340684,
+ 1
+ ],
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "color": 16777215,
+ "intensity": 0.6,
+ "shadow": {
+ "camera": {
+ "uuid": "ba78f102-e863-4df9-a295-f56af374dbe9",
+ "type": "OrthographicCamera",
+ "layers": 1,
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "zoom": 1,
+ "left": -5,
+ "right": 5,
+ "top": 5,
+ "bottom": -5,
+ "near": 0.5,
+ "far": 500
+ }
+ },
+ "target": "ac43e49a-3301-4a12-9d90-0ce724dff367"
+ },
+ {
+ "uuid": "5f633583-57db-4472-be10-2dce0a75d139",
+ "type": "DirectionalLight",
+ "name": "DirectionalLight",
+ "layers": 1,
+ "matrix": [
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 15.833769711930671,
+ 37.90623637377939,
+ 1
+ ],
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "color": 16777215,
+ "intensity": 0.5,
+ "shadow": {
+ "camera": {
+ "uuid": "9e8a1c42-2f57-4648-9db1-40e59ac6b6e0",
+ "type": "OrthographicCamera",
+ "layers": 1,
+ "up": [
+ 0,
+ 1,
+ 0
+ ],
+ "zoom": 1,
+ "left": -5,
+ "right": 5,
+ "top": 5,
+ "bottom": -5,
+ "near": 0.5,
+ "far": 500
+ }
+ },
+ "target": "44ee6450-dc88-46e5-90e7-781de0a69288"
+ }
+ ]
}
}
\ No newline at end of file
diff --git a/src/index.html b/src/index.html
index 5be98df..cfedf67 100644
--- a/src/index.html
+++ b/src/index.html
@@ -166,6 +166,31 @@
+
+
diff --git a/src/modules/controller.js b/src/modules/controller.js
index d5bf0f5..c501368 100644
--- a/src/modules/controller.js
+++ b/src/modules/controller.js
@@ -15,7 +15,7 @@ let controller = this;
let prescrizione;
let def_config;
let lang = navigator.language.split('-')[0] != 'it' ? 'en' : 'it';
-
+const hidden_fields = {};
let API = 'http://localhost/api/';
let CRM_URL = 'http://localhost/prescrizioni/';
let CFG_URL = 'http://localhost/config-predefinite/';
@@ -182,6 +182,21 @@ export const init = async (_scene, _cameraControls) => {
}else{
generaModalProdotti(); //riattivare
+ /** eliminare prima di andare in produzione */
+
+ $("#salvaDati").on('click', () => {
+ $("#clinicoPazienteModal").modal('hide');
+ let clinico = $("#nomeClinico").val();
+ let paziente = $("#nomePaziente").val();
+ let html = clinico ? '
'+_t('clinico')+': '+clinico+'
' : '';
+ html += '
'+_t('paziente')+': '+paziente+'
';
+ $(".dettagli-prescrizione").html(html);
+ });
+
+ $("#clinicoPazienteModal").modal('show');
+
+ /* ***** */
+
$(".btn-salva").addClass('d-none');
$(".btn-torna-prescrizione").addClass('d-none');
}
@@ -281,15 +296,12 @@ const attivaEvento = (field) => {
if(field.field_type == 'select'){
label = $("#"+field.id+" option:selected").text();
- //console.log("LABEL",label)
}
if(field.data_type == 'model'){
updateConfig(field, val, label);
- //console.log("model",field);
-
}else{
config[field.id] = {field: field, value: val, label: label};
Object.keys(config).forEach((k) => {
@@ -302,15 +314,80 @@ const attivaEvento = (field) => {
ui.generaListaConfig(config,menu_data)
}
- if(field.check_depends){
+
+ if(field.check_depends && field?.depends_on?.hide == null){
+
document.querySelectorAll(`[data-dep-id="${field.id}"]`).forEach((el) => {
-
+
if (el.getAttribute('data-dep-value') !== val) {
el.style.display = 'none';
} else {
el.style.display = '';
}
+
});
+
+ let firstVisibleOption = document.querySelector(`[data-dep-id="${field.id}"]:not([style*="display: none"])`);
+
+ if (firstVisibleOption) {
+ let emptyOption = firstVisibleOption.parentNode.querySelector('option[value=""]');
+
+ if (emptyOption) {
+ emptyOption.selected = true;
+ } else {
+ firstVisibleOption.selected = true;
+ }
+
+ firstVisibleOption.parentElement.dispatchEvent(new Event('change'));
+ }
+ }else if(field.check_depends && field.depends_on.hide){
+
+ document.querySelectorAll(`[data-dep-id]`).forEach((el) => {
+ if(el.type === 'checkbox') {
+
+ if(el.getAttribute('data-dep-id') === field.id) {
+ if(!el.checked && val.length > 0) {
+ el.parentElement.style.display = 'none';
+ } else {
+ el.parentElement.style.display = '';
+ }
+ }
+ }
+
+ });
+
+ //document.querySelector(`#${field.depends_on.id}`).parentElement.style.display = 'none';
+
+ }
+ if(field.reset_field){
+ //console.log("resetto", field.reset_field)
+ $("#"+field.reset_field).val('');
+ $("#"+field.reset_field).trigger('change');
+ }
+
+ if(field.hide_elements != null){
+ field.hide_elements.forEach((el_id) => {
+ if(hidden_fields[el_id] == null)
+ hidden_fields[el_id] = 0;
+
+ if(val.length > 0)
+
+ hidden_fields[el_id]++;
+ else{
+ hidden_fields[el_id]--;
+ if(hidden_fields[el_id] < 0)
+ hidden_fields[el_id] = 0;
+ }
+
+ })
+ }
+
+ for(let k in hidden_fields){
+ if(hidden_fields[k] > 0){
+ $("#"+k).parent().parent().hide();
+ }else{
+ $("#"+k).parent().parent().show();
+ }
}
})
}
diff --git a/src/modules/interfaccia.js b/src/modules/interfaccia.js
index a8029a5..c36f7d1 100644
--- a/src/modules/interfaccia.js
+++ b/src/modules/interfaccia.js
@@ -93,14 +93,14 @@ export const generaMenu = (data) => {
field_list.forEach((field) => {
if (field.depends_on) {
- let dependentField = field_list.find(f => f.id === field.depends_on);
+ let dependentField = field_list.find(f => f.id === field.depends_on || f.id === field.depends_on.id);
+
if (dependentField) {
dependentField.check_depends = true;
}
}
});
- console.log("field_list", field_list);
return field_list;
}
@@ -215,15 +215,21 @@ export const generaCheckbox = (field) => {
field.id = 'input-'+gen_id;
gen_id++;
}
+
+ let depends_str = '';
+ if(field.depends_on != null){
+ depends_str = ` data-dep-id="${field.depends_on.id}" data-dep-value="${field.depends_on.value}"`
+ }
+
let inline = field.inline ? 'd-inline-block' : '';
- let html = '
';
+ let html = `
`;
field_list.push(field);
return html;
diff --git a/src/modules/scena-controller copy.js b/src/modules/scena-controller copy.js
new file mode 100644
index 0000000..d5c8f80
--- /dev/null
+++ b/src/modules/scena-controller copy.js
@@ -0,0 +1,707 @@
+import * as THREE from 'three'
+import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls';
+import * as interfaccia from './interfaccia';
+import { STLLoader } from 'three/examples/jsm/loaders/STLLoader';
+import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
+import { FontLoader } from 'three/addons/loaders/FontLoader.js';
+import { TextGeometry } from 'three/addons/geometries/TextGeometry.js';
+import { DecalGeometry } from 'three/examples/jsm/geometries/DecalGeometry.js';
+
+
+import WebGPU from 'three/examples/jsm/capabilities/WebGPU';
+import WebGL from 'three/examples/jsm/capabilities/WebGL';
+
+
+import * as JSZip from 'jszip';
+import * as JSZipUtils from 'jszip-utils';
+import 'jszip-utils';
+import { degToRad } from 'three/src/math/MathUtils';
+
+
+/**
+ * Sizes
+ */
+const sizes = {}
+
+
+// Scene
+let scene = new THREE.Scene()
+let mainGroup = new THREE.Group();
+
+let camera;
+let cameraControls;
+const clock = new THREE.Clock();
+
+let actions = [];
+let mixers = [];
+let end = false;
+let doRender = false;
+let renderer = null;
+
+let frustumSize = 1600; // Aumentato per vedere meglio i modelli (era 1100)
+
+$(".loading").css('visibility','visible');
+
+window.addEventListener('resize', () =>
+{
+ // Save sizes
+ updateWindowSize();
+
+ if(camera != null){
+ // Update camera
+ // Aggiorna le dimensioni del frustum della camera
+ var aspect = sizes.width / sizes.height;
+ // Imposta questo al valore che preferisci
+
+ camera.left = -frustumSize * aspect / 2;
+ camera.right = frustumSize * aspect / 2;
+ camera.top = frustumSize / 2;
+ camera.bottom = -frustumSize / 2;
+
+ // Aggiorna la matrice di proiezione della camera
+ camera.updateProjectionMatrix();
+
+ }
+ // Update renderer
+ renderer.setPixelRatio(window.devicePixelRatio)
+ renderer.setSize(sizes.width, sizes.height)// renderer.setSize(sizes.width, sizes.height, true)
+ doRender = true;
+})
+
+window.addEventListener('load', ()=>{ init(); });
+
+
+const updateWindowSize = () => {
+ let canvas = document.querySelector('.canvas-container');
+ sizes.width = canvas.clientWidth
+ sizes.height = canvas.clientHeight
+
+ //console.log("canvas size", sizes)
+}
+
+export const matValues = (nome) => {
+
+ let roughness = parseFloat($("#roughness-"+nome).val());
+ let metalness = parseFloat($("#metalness-"+nome).val());
+
+ if(isNaN(roughness)) roughness = 0;
+ if(isNaN(metalness)) metalness = 0;
+ let obj = scene.getObjectByName(nome);
+
+ if(obj.isMesh){
+
+ obj.material.roughness = roughness;
+ obj.material.metalness = metalness;
+ obj.material.needsUpdate = true;
+ doRender = true;
+
+ }
+
+};
+
+const loadJsonModel = (name, path, callback = null) => {
+
+ const loader = new THREE.ObjectLoader();
+ let loadBar = $(".load-bar");
+
+ JSZipUtils.getBinaryContent('./assets/'+name+'.zip', {
+
+ progress: (update) => {
+ //console.log(e.percent + "% loaded");
+ $(loadBar).text(parseInt(update.percent) + '%');
+ },
+ callback: (err, data) => {
+ if(err) {
+ throw err; // or handle err
+ }
+
+ $(".loading").text("Inizializzazione scena...");
+ // loadStatus.nativeElement.innerHTML = 'Caricamento...';
+ //clearInterval(timer);
+ JSZip.loadAsync(data).then((zip) => {
+ let sceneFile = zip.file(name+'.json');
+ sceneFile.async('string', (update) => {
+ //console.log(update);
+ $(loadBar).text(parseInt(update.percent) + '%');
+ }).then((objectJson) => {
+
+ loader.parse(JSON.parse(objectJson), (parsedObj)=>{
+
+ if(callback != null){
+ callback(parsedObj);
+ }
+
+ });
+ });
+
+ });
+ }});
+
+}
+
+export const loadSTLModel = async (name, path, color, material, callback = null) => {
+
+ return new Promise(async (resolve, reject) => {
+ const loader = new STLLoader();
+
+ interfaccia.showLoader();
+
+ let geometry;
+ loader.loadAsync(path+name+".stl", (progress) => {
+ interfaccia.aggiornaLoader(progress);
+ }).then((obj) => {
+
+ let mesh = addModelToScene(obj, name, color, material);
+ interfaccia.resetLoader();
+ resolve(mesh);
+
+ }).catch((err) => {
+
+ interfaccia.resetLoader();
+ resolve(null)
+ console.log(err);
+
+ });
+ });
+
+}
+
+export const loadGLBModel = async (name, path, color, material, callback = null) => {
+
+ return new Promise(async (resolve, reject) => {
+ const loader = new GLTFLoader();
+
+ interfaccia.showLoader();
+
+ let geometry;
+ loader.loadAsync(path+name+".glb", (progress) => {
+ interfaccia.aggiornaLoader(progress);
+ }).then((obj) => {
+
+ let mesh = addModelToScene(obj.scene.children[0], name, color, material);
+ interfaccia.resetLoader();
+ resolve(mesh);
+
+ }).catch((err) => {
+
+ interfaccia.resetLoader();
+ resolve(null)
+ console.log(err);
+
+ });
+
+
+ //if(callback != null) callback();
+ });
+
+}
+
+export const addModelToScene = (obj, name, color, material_type) => {
+
+ let mesh = null;
+
+
+ let roughness = 1;
+ let metalness = 0;
+
+ if(material_type == 'metal'){
+ metalness = 0.3;
+ roughness = 0.20;
+ }
+
+ const material = new THREE.MeshStandardMaterial({color: color, roughness: roughness, metalness: metalness}); //'#a0a0a0'
+
+ if(obj.isMesh){
+ mesh = obj;
+ mesh.material.color = new THREE.Color(color);
+ mesh.material.roughness = roughness;
+ mesh.material.metalness = metalness;
+ mesh.material.needsUpdate = true;
+ }else{
+ mesh = new THREE.Mesh(obj, material);
+ }
+
+ mesh.scale.multiplyScalar(15);
+ mesh.name = name;
+ mesh.castShadow = false;
+ mesh.receiveShadow = false;
+ mainGroup.add(mesh)
+ //console.log(mesh)
+ //scene.add(mesh);
+ //console.log(scene)
+ doRender = true;
+ return mesh;
+}
+
+export const mostraArcata = async (model) => {
+
+ const url = new URL(location.href);
+ const params = url.searchParams;
+
+ let debug = params.get('debug');
+
+ let el = scene.getObjectByName("modello-"+model);
+ $(".color-"+model).addClass('d-none');
+
+ if(el){
+ if(el.visible){
+ el.visible = false;
+
+
+ }else{
+ el.visible = true;
+ if(debug == 'true'){
+ $(".color-"+model).removeClass('d-none');
+ }
+ }
+
+ doRender = true;
+ }
+ else{
+ let obj = await loadGLBModel("modello-"+model, './assets/glb/', '#ffffff');
+ obj.userData = {"type":"arcata"};
+ obj.material.roughness = 0.26;
+ obj.material.metalness = 0;
+
+ if(debug == 'true'){
+ $(".color-"+model).removeClass('d-none');
+ }
+
+ }
+
+}
+
+const randomColor = () => {
+ var color = '#';
+ var caratteri = '0123456789ABCDEF';
+
+ for (var i = 0; i < 6; i++) {
+ color += caratteri[Math.floor(Math.random() * 16)];
+ }
+
+ return color;
+}
+
+export const loadModels = async (config) => {
+ let activeObjs = [];
+ console.log("Config:", config);
+ return new Promise(async (resolve, reject)=>{
+ for(let key in config){
+
+ let el = config[key];
+
+ if(el.field.data_type == 'model' && el.value != ""){
+ let obj = scene.getObjectByName(el.value);
+ el.colore = el.colore == null ? el.field.color: el.colore
+ console.log("Loading model:", el.value, el.colore, el.field.material);
+ if(obj != null)
+ activeObjs.push(obj);
+ else{
+
+ obj = await loadGLBModel(el.value, './assets/glb/', el.colore, el.field.material);
+ if(obj != null)
+ activeObjs.push(obj);
+ else{
+ el.model_not_found = true;
+ }
+
+ }
+
+ if(el.field.accessory != null && el.field.accessory != ""){
+ let acc = scene.getObjectByName(el.field.accessory);
+ if(acc != null)
+ activeObjs.push(acc);
+ else{
+ acc = await loadGLBModel(el.field.accessory, './assets/glb/', el.colore, el.field.material);
+ if(acc != null)
+ activeObjs.push(acc);
+ else{
+ el.accessory_not_found = true;
+ }
+ }
+ }
+ }
+
+
+ }
+
+ console.log("Active objs:", activeObjs);
+
+ mainGroup.traverse((el) => {
+ if(el.isMesh && el.userData.type != 'arcata') el.visible = false;
+ });
+
+ activeObjs.forEach((obj) => {
+ obj.visible = true;
+ });
+
+ doRender = true;
+ resolve();
+ })
+
+
+}
+
+export const init = async () => {
+
+ //let scena = await (await fetch("./assets/scene.json")).json();
+ const loader = new THREE.ObjectLoader();
+ scene = await loader.loadAsync("./assets/scene.json");
+
+ let pointLight, ambientLight;
+ updateWindowSize();
+ renderer = new THREE.WebGLRenderer({
+ canvas: document.querySelector('.webgl'),
+ antialias: true,
+ alpha: true,
+ useLegacyLights: false
+ })
+
+ mainGroup.rotateX(degToRad(-90));
+ scene.add(mainGroup);
+
+ /*
+ scene.traverse((obj) => {
+
+ if(obj.isLight && Math.abs(obj.position.x) == 50){
+ obj.shadow.mapSize.width = 1024; // default
+ obj.shadow.mapSize.height = 1024; // default
+ obj.shadow.camera.near = 330; // default
+ obj.shadow.camera.far = 1000; // default
+ obj.shadow.camera.right = 500;
+ obj.shadow.camera.left = -500;
+ obj.shadow.camera.top = 500;
+ obj.shadow.camera.bottom = -500;
+ obj.shadow.radius = 2000;
+ obj.shadow.blurSamples = 2500;
+ obj.position.y = 0;
+ obj.castShadow = true;
+
+ //const helper = new THREE.CameraHelper( obj.shadow.camera );
+ //scene.add( helper );
+
+ }
+ })
+
+ renderer.shadowMap.autoUpdate = false;
+ renderer.shadowMap.needsUpdate = true; //chiamare ogni volta che viene aggiunto un elemento
+*/
+
+ let view = {
+ left: 0,
+ bottom: 0,
+ width: 1,
+ height: 1,
+ background: new THREE.Color( 0.5, 0.5, 0.7 ),
+ eye: [0,0,2800],// [ 0, 300, 1800 ],
+ up: [ 0, 1, 0 ],
+ fov: 50,
+ frustum: 120,
+ container: '.view1',
+ active: true,
+ main: true,
+ updateCamera: function ( camera, scene, mouseX ) {
+
+ }
+ }
+
+ let aspect = sizes.width / sizes.height;
+
+ //camera = new THREE.PerspectiveCamera(50, sizes.width / sizes.height, 0.1, 10000);
+ camera = new THREE.OrthographicCamera( frustumSize * aspect / - 2, frustumSize * aspect / 2, frustumSize / 2, frustumSize / - 2, 0.1, 10000 );
+
+ camera.position.fromArray( view.eye );
+ camera.up.fromArray( view.up );
+
+ scene.add(camera);
+
+ var pointLight2 = new THREE.PointLight( 0xffffff, 0.8 ); // 0xff6666
+ camera.add( pointLight2 );
+/*
+
+ ambientLight = new THREE.AmbientLight( 0xffffff, 0.3 );
+ scene.add( ambientLight );
+
+ pointLight = new THREE.PointLight( 0x7c7b7b, 0.5 ); // 0xff0000
+ pointLight.position.z = 2500;
+ scene.add( pointLight );
+
+
+ var pointLight3 = new THREE.PointLight( 0x7c7b7b, 0.5 ); // 0x0000ff
+ pointLight3.position.x = - 1000;
+ pointLight3.position.z = 1000;
+ scene.add( pointLight3 );
+
+ let pointLight4 = new THREE.DirectionalLight( 0x7c7b7b, 0.8 ); // 0xff0000
+ pointLight4.position.y = 0;
+
+ scene.add( pointLight4 );
+*/
+ window.scene = scene;
+
+ renderer.setPixelRatio(window.devicePixelRatio)
+ renderer.setSize(sizes.width, sizes.height)
+ renderer.toneMapping = THREE.CineonToneMapping;
+ renderer.toneMappingExposure = 0.5;
+ renderer.shadowMap.type = THREE.PCFSoftShadowMap;
+ renderer.shadowMap.enabled = true;
+ renderer.physicallyCorrectLights = false;
+
+
+
+ cameraControls = new TrackballControls( camera, renderer.domElement );
+
+ cameraControls.minDistance = 1;
+ cameraControls.maxDistance = Infinity;
+
+ // TrackballControls permette rotazione infinita in tutte le direzioni
+ cameraControls.rotateSpeed = 2.5; // Aumentata sensibilità rotazione
+ cameraControls.zoomSpeed = 1.2;
+ cameraControls.panSpeed = 0.8;
+
+ // No damping per TrackballControls (usa staticMoving)
+ cameraControls.staticMoving = false;
+ cameraControls.dynamicDampingFactor = 0.2;
+
+ // Salva il metodo update originale per modificarlo
+ const originalUpdate = cameraControls.update.bind(cameraControls);
+
+ // Override del metodo update per bloccare la rotazione Z
+ cameraControls.update = function() {
+ // Chiama l'update originale
+ originalUpdate();
+
+ // Resetta la rotazione Z della camera mantenendola sempre a zero
+ const up = new THREE.Vector3(0, 1, 0);
+ const right = new THREE.Vector3();
+
+ // Calcola il vettore right come perpendicolare a forward e up
+ const forward = new THREE.Vector3();
+ forward.subVectors(this.target, camera.position).normalize();
+ right.crossVectors(forward, up).normalize();
+
+ // Ricalcola up come perpendicolare a forward e right per mantenere l'orientamento
+ up.crossVectors(right, forward).normalize();
+
+ // Imposta l'up della camera
+ camera.up.copy(up);
+ };
+
+ window.camera = camera;
+ window.cc = cameraControls;
+ // Update camera
+ camera.aspect = sizes.width / sizes.height
+ camera.updateProjectionMatrix()
+
+
+ // Update renderer
+ //renderer.setPixelRatio(sizes.width / sizes.height);
+ renderer.setSize(sizes.width, sizes.height, true)
+ doRender = true;
+
+ loop();
+}
+
+const textToMesh = async (text) => {
+ const loader = new FontLoader();
+ const font = await loader.loadAsync('assets/fonts/Agency_FB_Bold.json');
+
+ let geometry = new TextGeometry( text, {
+ font: font,
+ size: 80,
+ height: 5,
+ /*
+ curveSegments: 12,
+ bevelEnabled: true,
+ bevelThickness: 10,
+ bevelSize: 8,
+ bevelOffset: 0,
+ bevelSegments: 5*/
+ } );
+
+ geometry.center();
+ let material = new THREE.MeshBasicMaterial( { color: 0xFF0000 } );
+ let mesh = new THREE.Mesh( geometry, material );
+ mesh.position.z = 0;
+ mesh.position.y = 0;
+ mesh.position.x = 0;
+ //scene.add(mesh);
+ return mesh;
+
+
+}
+
+async function applyTextToMesh(mesh, text, font, size, color) {
+ // Crea un nuovo elemento canvas
+ const canvas = document.createElement('canvas');
+ const context = canvas.getContext('2d');
+
+ // Imposta il font e il colore del testo
+ context.font = `${size}px ${font}`;
+ context.fillStyle = color;
+
+ // Disegna il testo sul canvas
+ context.fillText(text, 0, size);
+
+ const loader = new THREE.TextureLoader();
+
+ // Carica la texture dall'immagine base64
+ const texture = await loader.loadAsync(canvas.toDataURL("image/jpeg"));
+
+
+ console.log(canvas.toDataURL("image/jpeg"))
+ // Crea una nuova texture dal canvas
+
+ console.log("asd",texture);
+ mesh.material.map = texture;
+ mesh.material.needsUpdate = true;
+ // Crea un nuovo materiale utilizzando la texture
+ //const material = new THREE.MeshBasicMaterial({ map: texture });
+
+ // Applica il materiale alla mesh
+ //mesh.material = material;
+ mesh.geometry.computeVertexNormals();
+
+}
+
+
+
+
+/**
+ * Loop
+ */
+const loop = () =>
+{
+ // TrackballControls.update() deve essere chiamato ad ogni frame
+ cameraControls.update();
+
+ // Render sempre per vedere gli aggiornamenti dei controlli
+ renderer.render( scene, camera );
+
+ if(doRender){
+ // Render aggiuntivo se richiesto da altre parti del codice
+ }
+
+ doRender = false;
+ window.requestAnimationFrame(loop)
+
+}
+
+export const cambiaColore = (objName, color) => {
+
+ let obj = scene.getObjectByName(objName);
+
+ if(obj == null) return;
+ obj.material.color = new THREE.Color(color);
+ obj.material.needsUpdate = true;
+ doRender = true;
+}
+
+export const toggleModel = (objName) => {
+ let obj = scene.getObjectByName(objName);
+ console.log(obj.material)
+ obj.material.transparent = !obj.material.transparent;
+ if(obj.material.transparent)obj.material.opacity = 0.1;
+
+ obj.material.needsUpdate = true;
+
+ doRender = true;
+}
+
+window.esporta = () => {
+ var output = scene.toJSON();
+ output = JSON.stringify( output, 1, '\t' );
+ output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
+ saveString(output, "scena.json");
+}
+
+
+function save( blob, filename ) {
+
+ var link = document.createElement( 'a' );
+ link.style.display = 'none';
+ document.body.appendChild( link );
+
+ link.href = URL.createObjectURL( blob );
+ link.download = filename;
+ link.click();
+
+ // URL.revokeObjectURL( url ); breaks Firefox...
+
+}
+
+function saveString( text, filename ) {
+
+ save( new Blob( [ text ], { type: 'text/plain' } ), filename );
+
+}
+
+
+
+const toggleMobileMenu = () => {
+ $(".navbar-collapse").removeClass('show');
+}
+
+window.rotateTo = (side) => {
+
+ toggleMobileMenu();
+
+ $('.pos-btn').removeClass('active');
+
+ // Calcola la posizione della camera in base alla vista richiesta
+ const distance = camera.position.distanceTo(cameraControls.target);
+ let newPosition = new THREE.Vector3();
+
+ switch ( side ) {
+
+ case 'front':
+ // Vista frontale: camera davanti all'oggetto
+ newPosition.set(0, 0, distance);
+ break;
+
+ case 'back':
+ // Vista posteriore: camera dietro all'oggetto
+ newPosition.set(0, 0, -distance);
+ break;
+
+ case 'up':
+ // Vista dall'alto: camera sopra l'oggetto
+ newPosition.set(0, distance, 0);
+ break;
+
+ case 'down':
+ // Vista dal basso: camera sotto l'oggetto
+ newPosition.set(0, -distance, 0);
+ break;
+
+ case 'right':
+ // Vista destra: camera a destra dell'oggetto
+ newPosition.set(distance, 0, 0);
+ break;
+
+ case 'left':
+ // Vista sinistra: camera a sinistra dell'oggetto
+ newPosition.set(-distance, 0, 0);
+ break;
+
+ }
+
+ // Anima la transizione con GSAP
+ if(window.gsap) {
+ gsap.to(camera.position, {
+ duration: 0.8,
+ x: newPosition.x,
+ y: newPosition.y,
+ z: newPosition.z,
+ onUpdate: () => {
+ camera.lookAt(cameraControls.target);
+ }
+ });
+ } else {
+ camera.position.copy(newPosition);
+ camera.lookAt(cameraControls.target);
+ }
+
+ $('.move-'+side).addClass('active');
+
+}
diff --git a/src/modules/scena-controller.js b/src/modules/scena-controller.js
index 0130de5..19219a7 100644
--- a/src/modules/scena-controller.js
+++ b/src/modules/scena-controller.js
@@ -206,8 +206,8 @@ export const addModelToScene = (obj, name, color, material_type) => {
let metalness = 0;
if(material_type == 'metal'){
- metalness = 0.9;
- roughness = 0.28;
+ metalness = 0.86 ;
+ roughness = 0.3;
}
const material = new THREE.MeshStandardMaterial({color: color, roughness: roughness, metalness: metalness}); //'#a0a0a0'
@@ -259,9 +259,9 @@ export const mostraArcata = async (model) => {
doRender = true;
}
else{
- let obj = await loadGLBModel("modello-"+model, './assets/glb/', '#ffffff');
+ let obj = await loadGLBModel("modello-"+model, './assets/glb/', '#efc971');
obj.userData = {"type":"arcata"};
- obj.material.roughness = 0.26;
+ obj.material.roughness = 0.40;
obj.material.metalness = 0;
if(debug == 'true'){
@@ -285,7 +285,7 @@ const randomColor = () => {
export const loadModels = async (config) => {
let activeObjs = [];
- console.log("Config:", config);
+ //console.log("Config:", config);
return new Promise(async (resolve, reject)=>{
for(let key in config){
@@ -294,7 +294,7 @@ export const loadModels = async (config) => {
if(el.field.data_type == 'model' && el.value != ""){
let obj = scene.getObjectByName(el.value);
el.colore = el.colore == null ? el.field.color: el.colore
- console.log("Loading model:", el.value, el.colore, el.field.material);
+ //console.log("Loading model:", el.value, el.colore, el.field.material);
if(obj != null)
activeObjs.push(obj);
else{
@@ -308,19 +308,22 @@ export const loadModels = async (config) => {
}
- if(el.field.accessory != null && el.field.accessory != ""){
- let acc = scene.getObjectByName(el.field.accessory);
- if(acc != null)
- activeObjs.push(acc);
- else{
- acc = await loadGLBModel(el.field.accessory, './assets/glb/', el.colore, el.field.material);
- if(acc != null)
+ if(el.field.other_models != null){
+ for(let om of el.field.other_models){
+ let acc = scene.getObjectByName(om.model);
+ if(acc != null)
activeObjs.push(acc);
- else{
- el.accessory_not_found = true;
- }
+ else{
+ acc = await loadGLBModel(om.model, './assets/glb/', om.color, om.material);
+ if(acc != null)
+ activeObjs.push(acc);
+ else{
+ el.accessory_not_found = true;
+ }
+ }
}
}
+
}
diff --git a/utils/converter.py b/utils/converter.py
index 08a51a6..402a49c 100644
--- a/utils/converter.py
+++ b/utils/converter.py
@@ -250,14 +250,14 @@ def stl_to_gltf(path_to_stl, out_path, is_binary):
print("Done! Exported to %s" %out_path)
def batch_conversion(binary_stl_path, out_path, is_binary):
- #print(os.listdir(binary_stl_path))
+
for f in os.listdir(binary_stl_path):
new_file_name = f.replace('.stl','.glb')
destination = out_path+'/'+new_file_name
source = binary_stl_path+'/'+f
- if source.endswith('.stl') and not source.startswith('.'):
+ if source.endswith('.stl') and not f.startswith('.'):
stl_to_gltf(source, destination, is_binary)
print('Convert: '+f+ ' ---> '+new_file_name)
@@ -267,8 +267,8 @@ if __name__ == '__main__':
import sys
if len(sys.argv) < 3:
- print("use it like python3 stl_to_gltf.py /path/to/stl /path/to/gltf/folder -b -batch")
- print("or python3 stl_to_gltf.py /path/to/stl /path/to/glb/file -b")
+ print("use it like python3 converter.py /path/to/stl /path/to/gltf/folder -b -batch")
+ print("or python3 converter.py /path/to/stl /path/to/glb/file -b")
sys.exit(1)
path_to_stl = sys.argv[1]