first try for calculate from stl

This commit is contained in:
2025-05-19 16:35:42 +02:00
parent b8bd3b0398
commit 00e62fc558
9 changed files with 255 additions and 18 deletions

View File

@@ -32,6 +32,7 @@
}
],
"styles": [
"@angular/material/prebuilt-themes/azure-blue.css",
"src/styles.scss"
],
"scripts": []
@@ -91,6 +92,7 @@
}
],
"styles": [
"@angular/material/prebuilt-themes/azure-blue.css",
"src/styles.scss"
],
"scripts": []

View File

@@ -8,10 +8,12 @@
"name": "frontend",
"version": "0.0.0",
"dependencies": {
"@angular/cdk": "^19.2.16",
"@angular/common": "^19.2.0",
"@angular/compiler": "^19.2.0",
"@angular/core": "^19.2.0",
"@angular/forms": "^19.2.0",
"@angular/material": "^19.2.16",
"@angular/platform-browser": "^19.2.0",
"@angular/platform-browser-dynamic": "^19.2.0",
"@angular/router": "^19.2.0",
@@ -493,6 +495,21 @@
"node": "^10 || ^12 || >=14"
}
},
"node_modules/@angular/cdk": {
"version": "19.2.16",
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-19.2.16.tgz",
"integrity": "sha512-67nbWqoiZIBc8nEaCn7GHd02bM5T9qAbJ5w+Zq4V19CL3oCtrCrS4CV3Lsoi5HETSmn4iZcYS/Dph8omCvNkew==",
"license": "MIT",
"dependencies": {
"parse5": "^7.1.2",
"tslib": "^2.3.0"
},
"peerDependencies": {
"@angular/common": "^19.0.0 || ^20.0.0",
"@angular/core": "^19.0.0 || ^20.0.0",
"rxjs": "^6.5.3 || ^7.4.0"
}
},
"node_modules/@angular/cli": {
"version": "19.2.12",
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-19.2.12.tgz",
@@ -666,6 +683,23 @@
"rxjs": "^6.5.3 || ^7.4.0"
}
},
"node_modules/@angular/material": {
"version": "19.2.16",
"resolved": "https://registry.npmjs.org/@angular/material/-/material-19.2.16.tgz",
"integrity": "sha512-SSky/3MBOTdCBWOEffmVdnnKaCX6T4r3CqK2TJCLqWsHarPz5jovYIacfOe1RJzXijmDxXK5+VYhS64PNJaa6g==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
},
"peerDependencies": {
"@angular/cdk": "19.2.16",
"@angular/common": "^19.0.0 || ^20.0.0",
"@angular/core": "^19.0.0 || ^20.0.0",
"@angular/forms": "^19.0.0 || ^20.0.0",
"@angular/platform-browser": "^19.0.0 || ^20.0.0",
"rxjs": "^6.5.3 || ^7.4.0"
}
},
"node_modules/@angular/platform-browser": {
"version": "19.2.11",
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.2.11.tgz",
@@ -11226,7 +11260,6 @@
"version": "7.3.0",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
"integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
"dev": true,
"license": "MIT",
"dependencies": {
"entities": "^6.0.0"
@@ -11267,7 +11300,6 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz",
"integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"

View File

@@ -10,10 +10,12 @@
},
"private": true,
"dependencies": {
"@angular/cdk": "^19.2.16",
"@angular/common": "^19.2.0",
"@angular/compiler": "^19.2.0",
"@angular/core": "^19.2.0",
"@angular/forms": "^19.2.0",
"@angular/material": "^19.2.16",
"@angular/platform-browser": "^19.2.0",
"@angular/platform-browser-dynamic": "^19.2.0",
"@angular/router": "^19.2.0",
@@ -34,4 +36,4 @@
"karma-jasmine-html-reporter": "~2.1.0",
"typescript": "~5.7.2"
}
}
}

View File

@@ -1,2 +1,37 @@
<h2>Calculator Component</h2>
<p>{{ message }}</p>
<mat-card>
<mat-card-title>3D Print Cost Calculator</mat-card-title>
<input
type="file"
accept=".stl"
(change)="onFileSelected($event)"
/>
<button
mat-raised-button
color="primary"
(click)="uploadAndCalculate()"
[disabled]="!file || loading"
>
{{ loading ? 'Calculating...' : 'Calculate' }}
</button>
<mat-progress-spinner
*ngIf="loading"
diameter="30"
mode="indeterminate"
></mat-progress-spinner>
<p *ngIf="error" class="error">{{ error }}</p>
<div *ngIf="results">
<p>Volume STL: {{ results.stl_volume_mm3 }} mm³</p>
<p>Superficie: {{ results.surface_area_mm2 }} mm²</p>
<p>Volume pareti: {{ results.wall_volume_mm3 }} mm³</p>
<p>Volume infill: {{ results.infill_volume_mm3 }} mm³</p>
<p>Volume stampa: {{ results.print_volume_mm3 }} mm³</p>
<p>Peso stimato: {{ results.weight_g }} g</p>
<p>Costo stimato: CHF {{ results.cost_chf }}</p>
<p>Tempo stimato: {{ results.time_min }} min</p>
</div>
</mat-card>

View File

@@ -1,20 +1,62 @@
import { Component, OnInit } from '@angular/core';
// calculator.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { MatCardModule } from '@angular/material/card';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatButtonModule } from '@angular/material/button';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
@Component({
selector: 'app-calculator',
standalone: true,
imports: [
CommonModule,
FormsModule,
MatCardModule,
MatFormFieldModule,
MatButtonModule,
MatProgressSpinnerModule
],
templateUrl: './calculator.component.html',
styleUrls: ['./calculator.component.css']
styleUrls: ['./calculator.component.scss']
})
export class CalculatorComponent implements OnInit {
message = '';
export class CalculatorComponent {
file: File | null = null;
results: any = null;
error = '';
loading = false;
constructor(private http: HttpClient) {}
ngOnInit(): void {
this.http.get<{ message: string }>('http://localhost:8000/api/hello')
.subscribe(response => {
this.message = response.message;
onFileSelected(event: Event): void {
const input = event.target as HTMLInputElement;
if (input.files && input.files.length > 0) {
this.file = input.files[0];
this.results = null;
this.error = '';
}
}
uploadAndCalculate(): void {
if (!this.file) {
this.error = 'Seleziona un file STL prima di procedere.';
return;
}
const formData = new FormData();
formData.append('file', this.file);
this.loading = true;
this.http.post<any>('http://localhost:8000/calculate/stl', formData)
.subscribe({
next: res => {
this.results = res;
this.loading = false;
},
error: err => {
this.error = err.error?.detail || err.message;
this.loading = false;
}
});
}
}

View File

@@ -6,6 +6,8 @@
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body>
<app-root></app-root>

View File

@@ -1 +1,4 @@
/* You can add global styles to this file, and also import other style files */
html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }