Initial: Nutshell Site Aggregator MVP Phase 1

- Backend: Express + TypeORM + PostgreSQL, JWT + OTP auth
- Frontend: React + Vite + Tailwind, 4 pages (Home/Login/Orders/404)
- Docker Compose: PostgreSQL 15 on port 5434
- Tests: 16 tests passing (API + Frontend)
- ai_state: rules.md, INSTRUCTIONS.md, session tasks
- Examples: brand book PDF, logos, page mockups
This commit is contained in:
2026-07-16 11:38:08 +04:00
commit 4420c5c60a
73 changed files with 11088 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
"""
3D Model Validation Module
Validates STL, STEP, and other 3D model formats
"""
import trimesh
import numpy as np
from typing import Dict, Any
import os
class ModelValidator:
"""Validates 3D models for manufacturing"""
def __init__(self):
self.supported_formats = ['.stl', '.obj', '.ply', '.gltf', '.glb']
def validate_model(self, file_path: str) -> Dict[str, Any]:
"""
Validate 3D model file
Returns validation report with mesh integrity, wall thickness, etc.
"""
try:
# Load mesh
mesh = trimesh.load(file_path, force='mesh')
# Validate mesh
report = {
'file_path': file_path,
'file_type': os.path.splitext(file_path)[1].lower(),
'is_valid': True,
'file_size': os.path.getsize(file_path),
'mesh_integrity': 'PASS',
'warnings': [],
'errors': [],
}
# Check if mesh is valid
if not mesh.is_valid:
report['mesh_integrity'] = 'FAIL'
report['is_valid'] = False
report['errors'].append('Mesh is not valid (non-manifold geometry detected)')
# Check for empty mesh
if len(mesh.vertices) == 0:
report['is_valid'] = False
report['errors'].append('Mesh is empty')
return report
# Calculate mesh properties
report['volume_mm3'] = mesh.volume
report['bounding_box'] = {
'x': float(mesh.bounds[1][0] - mesh.bounds[0][0]),
'y': float(mesh.bounds[1][1] - mesh.bounds[0][1]),
'z': float(mesh.bounds[1][2] - mesh.bounds[0][2]),
}
# Check wall thickness (simple check)
# For better results, would need voxelization or distance field
wall_thickness = self._estimate_wall_thickness(mesh)
report['min_wall_thickness_mm'] = wall_thickness
if wall_thickness < 0.5:
report['warnings'].append(f'Wall thickness is very thin ({wall_thickness}mm)')
# Check for non-manifold edges
if not mesh.is_watertight:
report['warnings'].append('Mesh is not watertight (may have gaps)')
# Generate slicing preview data (simplified)
report['slicing_preview'] = {
'layer_count': int(report['bounding_box']['z'] / 0.2),
'suggested_support': not mesh.is_watertight,
}
return report
except Exception as e:
return {
'file_path': file_path,
'is_valid': False,
'errors': [str(e)],
'mesh_integrity': 'FAIL',
}
def _estimate_wall_thickness(self, mesh: trimesh.Trimesh) -> float:
"""Estimate minimum wall thickness"""
# Simplified estimation
# In production, use voxel-based thickness analysis
vertices = mesh.vertices
if len(vertices) < 3:
return 0.0
# Calculate approximate minimum distance
distances = []
for v in vertices[:100]: # Sample vertices
closest_distance = np.min(np.linalg.norm(vertices - v, axis=1)[1:])
distances.append(closest_distance)
return float(np.min(distances)) if distances else 0.1
if __name__ == '__main__':
# Test example
validator = ModelValidator()
print("Model Validator initialized and ready for use")

View File

@@ -0,0 +1,6 @@
trimesh==4.1.0
numpy==1.24.3
scipy==1.11.2
Pillow==10.0.0
requests==2.31.0
python-dotenv==1.0.0