From 62b652e1e85b2f247c00b2cf4ffe906d0aa6b5f0 Mon Sep 17 00:00:00 2001 From: chenjw28 <792430652@qq.com> Date: Wed, 6 May 2026 18:00:35 +0800 Subject: [PATCH] x --- src/core/base_mold_generator.py | 71 +++++++++++++++++++++++++-------- src/utils/html_generator.py | 14 +++---- 2 files changed, 62 insertions(+), 23 deletions(-) diff --git a/src/core/base_mold_generator.py b/src/core/base_mold_generator.py index 02c0a50..3609764 100644 --- a/src/core/base_mold_generator.py +++ b/src/core/base_mold_generator.py @@ -2,7 +2,7 @@ from typing import Dict, List, Any, Tuple, Optional import math import numpy as np from OCC.Core.BRepOffsetAPI import BRepOffsetAPI_DraftAngle -from OCC.Core.BRepAlgoAPI import BRepAlgoAPI_Cut, BRepAlgoAPI_Section, BRepAlgoAPI_Common +from OCC.Core.BRepAlgoAPI import BRepAlgoAPI_Cut, BRepAlgoAPI_Section, BRepAlgoAPI_Common, BRepAlgoAPI_Fuse from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeFace, BRepBuilderAPI_Transform from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox, BRepPrimAPI_MakeHalfSpace from OCC.Core.gp import gp_Pln, gp_Dir, gp_Pnt, gp_Trsf, gp_Ax2 @@ -257,11 +257,14 @@ class BaseMoldGenerator: logger.warning("型腔布尔减运算失败,使用原始模具块") cavity = cavity_block + parting_normal = self._extract_parting_normal(parting_surface) + core = self._build_protruding_core( shape, cavity_block, mold_xmin, mold_ymin, mold_zmin, mold_xmax, mold_ymax, mold_zmax, - xmin, ymin, zmin, xmax, ymax, zmax + xmin, ymin, zmin, xmax, ymax, zmax, + parting_normal ) logger.info("型腔/型芯分离完成(完全嵌入+突出贴合)") @@ -271,6 +274,18 @@ class BaseMoldGenerator: logger.error(f"型腔分离失败: {e}") return self._split_cavity_core_fallback(shape, None) + def _extract_parting_normal(self, parting_surface: Any) -> List[float]: + """从分型面提取法向量方向""" + try: + surface = BRepAdaptor_Surface(parting_surface) + if surface.GetType() == 0: + plane = surface.Plane() + normal = plane.Axis().Direction() + return [float(normal.X()), float(normal.Y()), float(normal.Z())] + except Exception: + pass + return [0.0, 0.0, 1.0] + def _build_protruding_core( self, shape: Any, @@ -279,35 +294,59 @@ class BaseMoldGenerator: mold_xmax: float, mold_ymax: float, mold_zmax: float, xmin: float, ymin: float, zmin: float, xmax: float, ymax: float, zmax: float, + parting_normal: List[float] = None, ) -> Any: """ 构建突出贴合式型芯。 - 型芯 = 模具块 ∩ 产品形状 → 产品突出体。 - 从视觉上:型芯面突出产品形状,与型腔的凹入形状完美贴合。 + 型芯 = 底座平板 + 产品形状突出体。 + 底座平板沿分型方向位于产品下方,产品形状融合在底座之上, + 与型腔的凹入形状完美贴合。 """ + nx, ny, nz = (parting_normal or [0.0, 0.0, 1.0]) + mold_min = [mold_xmin, mold_ymin, mold_zmin] + mold_max = [mold_xmax, mold_ymax, mold_zmax] + prod_min = [xmin, ymin, zmin] + prod_max = [xmax, ymax, zmax] + + base_p1 = list(mold_min) + base_p2 = list(mold_max) + + for i in range(3): + if parting_normal[i] > 0: + base_p2[i] = prod_min[i] + elif parting_normal[i] < 0: + base_p1[i] = prod_max[i] + + base_plate = None try: - common_op = BRepAlgoAPI_Common(cavity_block, shape) - if common_op.IsDone(): - core = common_op.Shape() - logger.info("型芯突出体构建成功(布尔交)") - return core + base_plate = BRepPrimAPI_MakeBox( + gp_Pnt(base_p1[0], base_p1[1], base_p1[2]), + gp_Pnt(base_p2[0], base_p2[1], base_p2[2]) + ).Shape() + logger.info("型芯底座平板构建完成") except Exception as e: - logger.warning(f"布尔交构建型芯失败: {e}") + logger.warning(f"底座平板构建失败: {e}") + return shape + + try: + fuse_op = BRepAlgoAPI_Fuse(base_plate, shape) + if fuse_op.IsDone(): + core = fuse_op.Shape() + logger.info("型芯(底座+产品突出体)融合成功") + return core + except Exception as e: + logger.warning(f"底座与产品融合失败: {e}") try: - core_plate = BRepPrimAPI_MakeBox( - gp_Pnt(mold_xmin, mold_ymin, zmin - 5.0), - gp_Pnt(mold_xmax, mold_ymax, zmin) - ).Shape() cut_op = BRepAlgoAPI_Cut(cavity_block, shape) if cut_op.IsDone(): - logger.info("型芯突出体构建成功(布尔减回退)") + logger.info("型芯通过布尔减回退构建") return cut_op.Shape() except Exception: pass - logger.info("型芯回退为产品形状") + logger.info("型芯最终回退为产品形状") return shape def _get_parting_plane(self, parting_surface: Any, shape: Any) -> Optional[gp_Pln]: diff --git a/src/utils/html_generator.py b/src/utils/html_generator.py index f570484..f200607 100644 --- a/src/utils/html_generator.py +++ b/src/utils/html_generator.py @@ -398,7 +398,7 @@ class HTMLGenerator: lodGeo.setAttribute('position', new THREE.BufferAttribute(new Float32Array(productVerts), 3)); lodGeo.setIndex(new THREE.BufferAttribute(new Uint32Array(productFaces), 1)); lodGeo.computeVertexNormals(); - const lodMat = createPBRMaterial(0x4CAF50, {{ metalness: 0.0, roughness: 0.25, opacity: 0.5 }}); + const lodMat = createPBRMaterial(0xFFFFFF, {{ metalness: 0.0, roughness: 0.20, opacity: 0.55 }}); const lodMesh = new THREE.Mesh(lodGeo, lodMat); lodMesh.castShadow = true; lodMesh.receiveShadow = true; @@ -416,7 +416,7 @@ class HTMLGenerator: productGeometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(productVerts), 3)); productGeometry.setIndex(new THREE.BufferAttribute(new Uint32Array(productFaces), 1)); productGeometry.computeVertexNormals(); - const productMaterial = createPBRMaterial(0x4CAF50, {{ metalness: 0.0, roughness: 0.25, opacity: 0.5 }}); + const productMaterial = createPBRMaterial(0xFFFFFF, {{ metalness: 0.0, roughness: 0.20, opacity: 0.55 }}); productMesh = new THREE.Mesh(productGeometry, productMaterial); productMesh.castShadow = true; productMesh.receiveShadow = true; @@ -437,8 +437,8 @@ class HTMLGenerator: }} }} const ptMaterial = new THREE.PointsMaterial({{ - color: 0x4CAF50, size: 0.5, sizeAttenuation: true, - transparent: true, opacity: 0.85, blending: THREE.NormalBlending, + color: 0xFFFFFF, size: 0.5, sizeAttenuation: true, + transparent: true, opacity: 0.90, blending: THREE.NormalBlending, depthWrite: false, }}); pointcloudMesh = new THREE.Points(ptGeometry, ptMaterial); @@ -450,7 +450,7 @@ class HTMLGenerator: if (!productMesh && !pointcloudMesh) {{ const productGeometry = new THREE.BoxGeometry(width * 0.9, height * 0.9, depth * 0.9); - const productMaterial = createPBRMaterial(0x4CAF50, {{ metalness: 0.0, roughness: 0.3, opacity: 0.6 }}); + const productMaterial = createPBRMaterial(0xFFFFFF, {{ metalness: 0.0, roughness: 0.25, opacity: 0.65 }}); productMesh = new THREE.Mesh(productGeometry, productMaterial); productMesh.position.set(0, 0, 0); scene.add(productMesh); @@ -513,11 +513,11 @@ class HTMLGenerator: if (productMesh.isLOD) {{ productMesh.traverse(child => {{ if (child.isMesh && child.geometry) {{ - addWireframe(child, child.geometry, 0x2E7D32); + addWireframe(child, child.geometry, 0xCCCCCC); }} }}); }} else {{ - addWireframe(productMesh, productMesh.geometry, 0x2E7D32); + addWireframe(productMesh, productMesh.geometry, 0xCCCCCC); }} }}