feat(configurator): server-side surface area calculation from STL

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>
This commit is contained in:
gsinghpal
2026-04-12 20:53:54 -04:00
parent 14d7781f4a
commit 795c66c126
5 changed files with 100 additions and 2 deletions

View File

@@ -3,7 +3,7 @@
# License OPL-1 (Odoo Proprietary License v1.0)
# Part of the Fusion Plating product family.
from odoo import fields, models
from odoo import api, fields, models, _
class FpPartCatalog(models.Model):
@@ -63,3 +63,39 @@ class FpPartCatalog(models.Model):
('fp_part_catalog_partner_partnum_uniq', 'unique(partner_id, part_number)',
'Part number must be unique per customer.'),
]
def action_calculate_surface_area(self):
"""Calculate surface area from the uploaded 3D model file."""
self.ensure_one()
if not self.model_attachment_id:
from odoo.exceptions import UserError
raise UserError(_('No 3D model file uploaded.'))
try:
import trimesh
except ImportError:
from odoo.exceptions import UserError
raise UserError(_('trimesh library not installed on the server. Contact your administrator.'))
import base64
import io
raw = base64.b64decode(self.model_attachment_id.datas)
mesh = trimesh.load(io.BytesIO(raw), file_type='stl')
area_mm2 = mesh.area
area_sqin = area_mm2 / 645.16
self.surface_area = round(area_sqin, 4)
self.surface_area_uom = 'sq_in'
self.geometry_source = '3d_model'
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': _('Surface Area Calculated'),
'message': _('%.4f sq in (%.2f mm\u00b2) from %d faces') % (area_sqin, area_mm2, len(mesh.faces)),
'type': 'success',
'sticky': False,
},
}