x
This commit is contained in:
@@ -2,7 +2,7 @@ from typing import Dict, List, Any, Tuple, Optional
|
|||||||
import math
|
import math
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from OCC.Core.BRepOffsetAPI import BRepOffsetAPI_DraftAngle
|
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.BRepBuilderAPI import BRepBuilderAPI_MakeFace, BRepBuilderAPI_Transform
|
||||||
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox, BRepPrimAPI_MakeHalfSpace
|
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox, BRepPrimAPI_MakeHalfSpace
|
||||||
from OCC.Core.gp import gp_Pln, gp_Dir, gp_Pnt, gp_Trsf, gp_Ax2
|
from OCC.Core.gp import gp_Pln, gp_Dir, gp_Pnt, gp_Trsf, gp_Ax2
|
||||||
@@ -257,11 +257,14 @@ class BaseMoldGenerator:
|
|||||||
logger.warning("型腔布尔减运算失败,使用原始模具块")
|
logger.warning("型腔布尔减运算失败,使用原始模具块")
|
||||||
cavity = cavity_block
|
cavity = cavity_block
|
||||||
|
|
||||||
|
parting_normal = self._extract_parting_normal(parting_surface)
|
||||||
|
|
||||||
core = self._build_protruding_core(
|
core = self._build_protruding_core(
|
||||||
shape, cavity_block,
|
shape, cavity_block,
|
||||||
mold_xmin, mold_ymin, mold_zmin,
|
mold_xmin, mold_ymin, mold_zmin,
|
||||||
mold_xmax, mold_ymax, mold_zmax,
|
mold_xmax, mold_ymax, mold_zmax,
|
||||||
xmin, ymin, zmin, xmax, ymax, zmax
|
xmin, ymin, zmin, xmax, ymax, zmax,
|
||||||
|
parting_normal
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.info("型腔/型芯分离完成(完全嵌入+突出贴合)")
|
logger.info("型腔/型芯分离完成(完全嵌入+突出贴合)")
|
||||||
@@ -271,6 +274,18 @@ class BaseMoldGenerator:
|
|||||||
logger.error(f"型腔分离失败: {e}")
|
logger.error(f"型腔分离失败: {e}")
|
||||||
return self._split_cavity_core_fallback(shape, None)
|
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(
|
def _build_protruding_core(
|
||||||
self,
|
self,
|
||||||
shape: Any,
|
shape: Any,
|
||||||
@@ -279,35 +294,59 @@ class BaseMoldGenerator:
|
|||||||
mold_xmax: float, mold_ymax: float, mold_zmax: float,
|
mold_xmax: float, mold_ymax: float, mold_zmax: float,
|
||||||
xmin: float, ymin: float, zmin: float,
|
xmin: float, ymin: float, zmin: float,
|
||||||
xmax: float, ymax: float, zmax: float,
|
xmax: float, ymax: float, zmax: float,
|
||||||
|
parting_normal: List[float] = None,
|
||||||
) -> Any:
|
) -> 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:
|
try:
|
||||||
common_op = BRepAlgoAPI_Common(cavity_block, shape)
|
base_plate = BRepPrimAPI_MakeBox(
|
||||||
if common_op.IsDone():
|
gp_Pnt(base_p1[0], base_p1[1], base_p1[2]),
|
||||||
core = common_op.Shape()
|
gp_Pnt(base_p2[0], base_p2[1], base_p2[2])
|
||||||
logger.info("型芯突出体构建成功(布尔交)")
|
).Shape()
|
||||||
return core
|
logger.info("型芯底座平板构建完成")
|
||||||
except Exception as e:
|
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:
|
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)
|
cut_op = BRepAlgoAPI_Cut(cavity_block, shape)
|
||||||
if cut_op.IsDone():
|
if cut_op.IsDone():
|
||||||
logger.info("型芯突出体构建成功(布尔减回退)")
|
logger.info("型芯通过布尔减回退构建")
|
||||||
return cut_op.Shape()
|
return cut_op.Shape()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
logger.info("型芯回退为产品形状")
|
logger.info("型芯最终回退为产品形状")
|
||||||
return shape
|
return shape
|
||||||
|
|
||||||
def _get_parting_plane(self, parting_surface: Any, shape: Any) -> Optional[gp_Pln]:
|
def _get_parting_plane(self, parting_surface: Any, shape: Any) -> Optional[gp_Pln]:
|
||||||
|
|||||||
@@ -398,7 +398,7 @@ class HTMLGenerator:
|
|||||||
lodGeo.setAttribute('position', new THREE.BufferAttribute(new Float32Array(productVerts), 3));
|
lodGeo.setAttribute('position', new THREE.BufferAttribute(new Float32Array(productVerts), 3));
|
||||||
lodGeo.setIndex(new THREE.BufferAttribute(new Uint32Array(productFaces), 1));
|
lodGeo.setIndex(new THREE.BufferAttribute(new Uint32Array(productFaces), 1));
|
||||||
lodGeo.computeVertexNormals();
|
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);
|
const lodMesh = new THREE.Mesh(lodGeo, lodMat);
|
||||||
lodMesh.castShadow = true;
|
lodMesh.castShadow = true;
|
||||||
lodMesh.receiveShadow = true;
|
lodMesh.receiveShadow = true;
|
||||||
@@ -416,7 +416,7 @@ class HTMLGenerator:
|
|||||||
productGeometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(productVerts), 3));
|
productGeometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(productVerts), 3));
|
||||||
productGeometry.setIndex(new THREE.BufferAttribute(new Uint32Array(productFaces), 1));
|
productGeometry.setIndex(new THREE.BufferAttribute(new Uint32Array(productFaces), 1));
|
||||||
productGeometry.computeVertexNormals();
|
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 = new THREE.Mesh(productGeometry, productMaterial);
|
||||||
productMesh.castShadow = true;
|
productMesh.castShadow = true;
|
||||||
productMesh.receiveShadow = true;
|
productMesh.receiveShadow = true;
|
||||||
@@ -437,8 +437,8 @@ class HTMLGenerator:
|
|||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
const ptMaterial = new THREE.PointsMaterial({{
|
const ptMaterial = new THREE.PointsMaterial({{
|
||||||
color: 0x4CAF50, size: 0.5, sizeAttenuation: true,
|
color: 0xFFFFFF, size: 0.5, sizeAttenuation: true,
|
||||||
transparent: true, opacity: 0.85, blending: THREE.NormalBlending,
|
transparent: true, opacity: 0.90, blending: THREE.NormalBlending,
|
||||||
depthWrite: false,
|
depthWrite: false,
|
||||||
}});
|
}});
|
||||||
pointcloudMesh = new THREE.Points(ptGeometry, ptMaterial);
|
pointcloudMesh = new THREE.Points(ptGeometry, ptMaterial);
|
||||||
@@ -450,7 +450,7 @@ class HTMLGenerator:
|
|||||||
|
|
||||||
if (!productMesh && !pointcloudMesh) {{
|
if (!productMesh && !pointcloudMesh) {{
|
||||||
const productGeometry = new THREE.BoxGeometry(width * 0.9, height * 0.9, depth * 0.9);
|
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 = new THREE.Mesh(productGeometry, productMaterial);
|
||||||
productMesh.position.set(0, 0, 0);
|
productMesh.position.set(0, 0, 0);
|
||||||
scene.add(productMesh);
|
scene.add(productMesh);
|
||||||
@@ -513,11 +513,11 @@ class HTMLGenerator:
|
|||||||
if (productMesh.isLOD) {{
|
if (productMesh.isLOD) {{
|
||||||
productMesh.traverse(child => {{
|
productMesh.traverse(child => {{
|
||||||
if (child.isMesh && child.geometry) {{
|
if (child.isMesh && child.geometry) {{
|
||||||
addWireframe(child, child.geometry, 0x2E7D32);
|
addWireframe(child, child.geometry, 0xCCCCCC);
|
||||||
}}
|
}}
|
||||||
}});
|
}});
|
||||||
}} else {{
|
}} else {{
|
||||||
addWireframe(productMesh, productMesh.geometry, 0x2E7D32);
|
addWireframe(productMesh, productMesh.geometry, 0xCCCCCC);
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user