Add trimesh-based surface area calculation for uploaded STL files: - New /fp/configurator/calculate_surface_area jsonrpc endpoint - action_calculate_surface_area() method on fp.part.catalog - "Calculate from 3D Model" button visible when a 3D model is attached - Returns area in sq in (converted from mm2), vertex/face counts, and bounding box dimensions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
53 lines
1.8 KiB
Python
53 lines
1.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Copyright 2026 Nexa Systems Inc.
|
|
# License OPL-1 (Odoo Proprietary License v1.0)
|
|
# Part of the Fusion Plating product family.
|
|
|
|
import base64
|
|
import io
|
|
import logging
|
|
|
|
from odoo import http
|
|
from odoo.http import request
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class FpConfiguratorController(http.Controller):
|
|
|
|
@http.route('/fp/configurator/calculate_surface_area', type='jsonrpc', auth='user')
|
|
def calculate_surface_area(self, attachment_id, **kw):
|
|
"""Calculate surface area from an uploaded STL file using trimesh."""
|
|
attachment = request.env['ir.attachment'].browse(int(attachment_id))
|
|
if not attachment.exists():
|
|
return {'error': 'Attachment not found.'}
|
|
|
|
try:
|
|
import trimesh
|
|
except ImportError:
|
|
return {'error': 'trimesh library not installed. Run: pip install trimesh'}
|
|
|
|
try:
|
|
raw = base64.b64decode(attachment.datas)
|
|
mesh = trimesh.load(io.BytesIO(raw), file_type='stl')
|
|
|
|
# trimesh returns area in the file's native units (usually mm²)
|
|
area_mm2 = mesh.area
|
|
area_sqin = area_mm2 / 645.16 # mm² to sq in
|
|
|
|
return {
|
|
'surface_area': round(area_sqin, 4),
|
|
'surface_area_mm2': round(area_mm2, 2),
|
|
'unit': 'sq_in',
|
|
'vertex_count': len(mesh.vertices),
|
|
'face_count': len(mesh.faces),
|
|
'bounding_box': {
|
|
'x': round(float(mesh.bounding_box.extents[0]), 2),
|
|
'y': round(float(mesh.bounding_box.extents[1]), 2),
|
|
'z': round(float(mesh.bounding_box.extents[2]), 2),
|
|
},
|
|
}
|
|
except Exception as e:
|
|
_logger.warning('STL surface area calculation failed: %s', e)
|
|
return {'error': str(e)}
|