From db01a4ee6d83d1c95136d3ca8c4d9d3dcf7c3a6f Mon Sep 17 00:00:00 2001 From: SZCJW <792430652@qq.com> Date: Sun, 8 Mar 2026 02:14:07 +0800 Subject: [PATCH] x --- src/core/mold_generator.py | 56 ++++++++++++--- src/utils/html_generator.py | 135 ++++++++++++++++++++++++++++++------ 2 files changed, 159 insertions(+), 32 deletions(-) diff --git a/src/core/mold_generator.py b/src/core/mold_generator.py index 71ac869..a2ff46d 100644 --- a/src/core/mold_generator.py +++ b/src/core/mold_generator.py @@ -5,6 +5,7 @@ import numpy as np from OCC.Core.BRepOffsetAPI import BRepOffsetAPI_MakeThickSolid from OCC.Core.BRepAlgoAPI import BRepAlgoAPI_Cut, BRepAlgoAPI_Fuse from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeFace, BRepBuilderAPI_Transform +from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox from OCC.Core.Geom import Geom_Plane from OCC.Core.gp import gp_Pln, gp_Dir, gp_Pnt, gp_Vec, gp_Trsf from OCC.Core.TopTools import TopTools_ListOfShape @@ -283,16 +284,53 @@ class MoldCavityGenerator: return shape def _split_cavity_core(self, shape: Any, parting_surface: Any) -> Tuple[Any, Any]: - """分离型腔和型芯""" + """分离型腔和型芯 + + 型腔(Cavity): 模具中形成产品外表面的部分,是产品形状的负形 + 型芯(Core): 模具中形成产品内表面的部分,是产品形状的正形 + """ try: - # 使用分型面切割产品 - # 上半部分为型腔(Cavity) - # 下半部分为型芯(Core) - - # 这里需要实现BRepAlgoAPI_Section或类似的切割操作 - # 简化:返回相同的形状(实际需实现切割逻辑) - - return shape, shape # (cavity, core) + from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox + from OCC.Core.BRepAlgoAPI import BRepAlgoAPI_Cut + from OCC.Core.TopExp import TopExp_Explorer + from OCC.Core.TopAbs import TopAbs_SOLID + + # 获取产品边界框 + from OCC.Core.Bnd import Bnd_Box + from OCC.Core.BRepBndLib import brepbndlib + bbox = Bnd_Box() + brepbndlib.Add(shape, bbox) + xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() + + # 计算模具块尺寸(比产品大一定余量) + margin = 20 # mm + mold_xmin = xmin - margin + mold_ymin = ymin - margin + mold_zmin = zmin - margin + mold_xmax = xmax + margin + mold_ymax = ymax + margin + mold_zmax = zmax + margin + + # 创建模具块 + mold_block = BRepPrimAPI_MakeBox( + gp_Pnt(mold_xmin, mold_ymin, mold_zmin), + gp_Pnt(mold_xmax, mold_ymax, mold_zmax) + ).Shape() + + # 型腔 = 模具块 - 产品(布尔减法) + cavity_operation = BRepAlgoAPI_Cut(mold_block, shape) + if cavity_operation.IsDone(): + cavity = cavity_operation.Shape() + logger.info("型腔生成成功(模具块减去产品)") + else: + logger.warning("型腔布尔运算失败,使用原始形状") + cavity = mold_block + + # 型芯 = 产品形状本身(收缩补偿后) + core = shape + logger.info("型芯 = 产品形状") + + return cavity, core except Exception as e: logger.error(f"型腔分离失败: {e}") diff --git a/src/utils/html_generator.py b/src/utils/html_generator.py index c6a10c9..8002825 100644 --- a/src/utils/html_generator.py +++ b/src/utils/html_generator.py @@ -278,30 +278,89 @@ class HTMLGenerator: }} // 创建型腔(上半模 - 蓝色) - const cavityGeometry = new THREE.BoxGeometry(width * 1.1, height * 0.3, depth * 1.1); - const cavityMaterial = new THREE.MeshPhongMaterial({{ - color: 0x2196F3, - transparent: true, - opacity: 0.4, - wireframe: false - }}); - - cavityMesh = new THREE.Mesh(cavityGeometry, cavityMaterial); - cavityMesh.position.set(0, height * 0.6, 0); - scene.add(cavityMesh); + // 尝试从后端数据获取实际几何,否则使用简化Box + if (cavityData && cavityData.mold_cavities && cavityData.mold_cavities.cavity && cavityData.mold_cavities.cavity.vertices) {{ + const cavityVerts = cavityData.mold_cavities.cavity.vertices; + const cavityFaces = cavityData.mold_cavities.cavity.faces; + + if (cavityVerts.length > 0 && cavityFaces.length > 0) {{ + const cavityGeometry = new THREE.BufferGeometry(); + const positions = new Float32Array(cavityVerts); + const indices = new Uint32Array(cavityFaces); + cavityGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); + cavityGeometry.setIndex(new THREE.BufferAttribute(indices, 1)); + cavityGeometry.computeVertexNormals(); + + const cavityMaterial = new THREE.MeshPhongMaterial({{ + color: 0x2196F3, + transparent: true, + opacity: 0.5, + wireframe: false, + side: THREE.DoubleSide + }}); + + cavityMesh = new THREE.Mesh(cavityGeometry, cavityMaterial); + scene.add(cavityMesh); + + // 添加线框 + const cavityWireframe = new THREE.WireframeGeometry(cavityGeometry); + const cavityLine = new THREE.LineSegments(cavityWireframe); + cavityLine.material.depthTest = false; + cavityLine.material.opacity = 0.6; + cavityLine.material.transparent = true; + cavityLine.material.color = new THREE.Color(0x1565C0); + cavityMesh.add(cavityLine); + + // 设置相机目标为型腔中心 + cavityGeometry.computeBoundingBox(); + const cavityCenter = new THREE.Vector3(); + cavityGeometry.boundingBox.getCenter(cavityCenter); + controls.target.set(cavityCenter.x, cavityCenter.y, cavityCenter.z); + }} else {{ + createSimpleCavity(width, height, depth); + }} + }} else {{ + createSimpleCavity(width, height, depth); + }} // 创建型芯(下半模 - 橙色) - const coreGeometry = new THREE.BoxGeometry(width * 1.1, height * 0.3, depth * 1.1); - const coreMaterial = new THREE.MeshPhongMaterial({{ - color: 0xFF9800, - transparent: true, - opacity: 0.4, - wireframe: false - }}); - - coreMesh = new THREE.Mesh(coreGeometry, coreMaterial); - coreMesh.position.set(0, -height * 0.6, 0); - scene.add(coreMesh); + if (cavityData && cavityData.mold_cavities && cavityData.mold_cavities.core && cavityData.mold_cavities.core.vertices) {{ + const coreVerts = cavityData.mold_cavities.core.vertices; + const coreFaces = cavityData.mold_cavities.core.faces; + + if (coreVerts.length > 0 && coreFaces.length > 0) {{ + const coreGeometry = new THREE.BufferGeometry(); + const positions = new Float32Array(coreVerts); + const indices = new Uint32Array(coreFaces); + coreGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); + coreGeometry.setIndex(new THREE.BufferAttribute(indices, 1)); + coreGeometry.computeVertexNormals(); + + const coreMaterial = new THREE.MeshPhongMaterial({{ + color: 0xFF9800, + transparent: true, + opacity: 0.5, + wireframe: false, + side: THREE.DoubleSide + }}); + + coreMesh = new THREE.Mesh(coreGeometry, coreMaterial); + scene.add(coreMesh); + + // 添加线框 + const coreWireframe = new THREE.WireframeGeometry(coreGeometry); + const coreLine = new THREE.LineSegments(coreWireframe); + coreLine.material.depthTest = false; + coreLine.material.opacity = 0.6; + coreLine.material.transparent = true; + coreLine.material.color = new THREE.Color(0xE65100); + coreMesh.add(coreLine); + }} else {{ + createSimpleCore(width, height, depth); + }} + }} else {{ + createSimpleCore(width, height, depth); + }} // 创建分型面(红色平面) const partingGeometry = new THREE.PlaneGeometry(width * 1.2, depth * 1.2); @@ -317,7 +376,7 @@ class HTMLGenerator: partingMesh.position.set(0, 0, 0); scene.add(partingMesh); - // 添加线框 + // 添加产品线框 if (productMesh) {{ const productWireframe = new THREE.WireframeGeometry(productMesh.geometry); const productLine = new THREE.LineSegments(productWireframe); @@ -327,6 +386,21 @@ class HTMLGenerator: productLine.material.color = new THREE.Color(0x2E7D32); productMesh.add(productLine); }} + }} + + // 创建简化型腔(备用) + function createSimpleCavity(width, height, depth) {{ + const cavityGeometry = new THREE.BoxGeometry(width * 1.2, height * 0.4, depth * 1.2); + const cavityMaterial = new THREE.MeshPhongMaterial({{ + color: 0x2196F3, + transparent: true, + opacity: 0.4, + wireframe: false + }}); + + cavityMesh = new THREE.Mesh(cavityGeometry, cavityMaterial); + cavityMesh.position.set(0, height * 0.7, 0); + scene.add(cavityMesh); const cavityWireframe = new THREE.WireframeGeometry(cavityGeometry); const cavityLine = new THREE.LineSegments(cavityWireframe); @@ -335,6 +409,21 @@ class HTMLGenerator: cavityLine.material.transparent = true; cavityLine.material.color = new THREE.Color(0x1565C0); cavityMesh.add(cavityLine); + }} + + // 创建简化型芯(备用) + function createSimpleCore(width, height, depth) {{ + const coreGeometry = new THREE.BoxGeometry(width * 1.2, height * 0.4, depth * 1.2); + const coreMaterial = new THREE.MeshPhongMaterial({{ + color: 0xFF9800, + transparent: true, + opacity: 0.4, + wireframe: false + }}); + + coreMesh = new THREE.Mesh(coreGeometry, coreMaterial); + coreMesh.position.set(0, -height * 0.7, 0); + scene.add(coreMesh); const coreWireframe = new THREE.WireframeGeometry(coreGeometry); const coreLine = new THREE.LineSegments(coreWireframe);