x
This commit is contained in:
@@ -5,6 +5,7 @@ import numpy as np
|
|||||||
from OCC.Core.BRepOffsetAPI import BRepOffsetAPI_MakeThickSolid
|
from OCC.Core.BRepOffsetAPI import BRepOffsetAPI_MakeThickSolid
|
||||||
from OCC.Core.BRepAlgoAPI import BRepAlgoAPI_Cut, BRepAlgoAPI_Fuse
|
from OCC.Core.BRepAlgoAPI import BRepAlgoAPI_Cut, 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
|
||||||
from OCC.Core.Geom import Geom_Plane
|
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.gp import gp_Pln, gp_Dir, gp_Pnt, gp_Vec, gp_Trsf
|
||||||
from OCC.Core.TopTools import TopTools_ListOfShape
|
from OCC.Core.TopTools import TopTools_ListOfShape
|
||||||
@@ -283,16 +284,53 @@ class MoldCavityGenerator:
|
|||||||
return shape
|
return shape
|
||||||
|
|
||||||
def _split_cavity_core(self, shape: Any, parting_surface: Any) -> Tuple[Any, Any]:
|
def _split_cavity_core(self, shape: Any, parting_surface: Any) -> Tuple[Any, Any]:
|
||||||
"""分离型腔和型芯"""
|
"""分离型腔和型芯
|
||||||
|
|
||||||
|
型腔(Cavity): 模具中形成产品外表面的部分,是产品形状的负形
|
||||||
|
型芯(Core): 模具中形成产品内表面的部分,是产品形状的正形
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
# 使用分型面切割产品
|
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox
|
||||||
# 上半部分为型腔(Cavity)
|
from OCC.Core.BRepAlgoAPI import BRepAlgoAPI_Cut
|
||||||
# 下半部分为型芯(Core)
|
from OCC.Core.TopExp import TopExp_Explorer
|
||||||
|
from OCC.Core.TopAbs import TopAbs_SOLID
|
||||||
|
|
||||||
# 这里需要实现BRepAlgoAPI_Section或类似的切割操作
|
# 获取产品边界框
|
||||||
# 简化:返回相同的形状(实际需实现切割逻辑)
|
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()
|
||||||
|
|
||||||
return shape, shape # (cavity, core)
|
# 计算模具块尺寸(比产品大一定余量)
|
||||||
|
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:
|
except Exception as e:
|
||||||
logger.error(f"型腔分离失败: {e}")
|
logger.error(f"型腔分离失败: {e}")
|
||||||
|
|||||||
+110
-21
@@ -278,30 +278,89 @@ class HTMLGenerator:
|
|||||||
}}
|
}}
|
||||||
|
|
||||||
// 创建型腔(上半模 - 蓝色)
|
// 创建型腔(上半模 - 蓝色)
|
||||||
const cavityGeometry = new THREE.BoxGeometry(width * 1.1, height * 0.3, depth * 1.1);
|
// 尝试从后端数据获取实际几何,否则使用简化Box
|
||||||
const cavityMaterial = new THREE.MeshPhongMaterial({{
|
if (cavityData && cavityData.mold_cavities && cavityData.mold_cavities.cavity && cavityData.mold_cavities.cavity.vertices) {{
|
||||||
color: 0x2196F3,
|
const cavityVerts = cavityData.mold_cavities.cavity.vertices;
|
||||||
transparent: true,
|
const cavityFaces = cavityData.mold_cavities.cavity.faces;
|
||||||
opacity: 0.4,
|
|
||||||
wireframe: false
|
|
||||||
}});
|
|
||||||
|
|
||||||
cavityMesh = new THREE.Mesh(cavityGeometry, cavityMaterial);
|
if (cavityVerts.length > 0 && cavityFaces.length > 0) {{
|
||||||
cavityMesh.position.set(0, height * 0.6, 0);
|
const cavityGeometry = new THREE.BufferGeometry();
|
||||||
scene.add(cavityMesh);
|
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);
|
if (cavityData && cavityData.mold_cavities && cavityData.mold_cavities.core && cavityData.mold_cavities.core.vertices) {{
|
||||||
const coreMaterial = new THREE.MeshPhongMaterial({{
|
const coreVerts = cavityData.mold_cavities.core.vertices;
|
||||||
color: 0xFF9800,
|
const coreFaces = cavityData.mold_cavities.core.faces;
|
||||||
transparent: true,
|
|
||||||
opacity: 0.4,
|
|
||||||
wireframe: false
|
|
||||||
}});
|
|
||||||
|
|
||||||
coreMesh = new THREE.Mesh(coreGeometry, coreMaterial);
|
if (coreVerts.length > 0 && coreFaces.length > 0) {{
|
||||||
coreMesh.position.set(0, -height * 0.6, 0);
|
const coreGeometry = new THREE.BufferGeometry();
|
||||||
scene.add(coreMesh);
|
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);
|
const partingGeometry = new THREE.PlaneGeometry(width * 1.2, depth * 1.2);
|
||||||
@@ -317,7 +376,7 @@ class HTMLGenerator:
|
|||||||
partingMesh.position.set(0, 0, 0);
|
partingMesh.position.set(0, 0, 0);
|
||||||
scene.add(partingMesh);
|
scene.add(partingMesh);
|
||||||
|
|
||||||
// 添加线框
|
// 添加产品线框
|
||||||
if (productMesh) {{
|
if (productMesh) {{
|
||||||
const productWireframe = new THREE.WireframeGeometry(productMesh.geometry);
|
const productWireframe = new THREE.WireframeGeometry(productMesh.geometry);
|
||||||
const productLine = new THREE.LineSegments(productWireframe);
|
const productLine = new THREE.LineSegments(productWireframe);
|
||||||
@@ -327,6 +386,21 @@ class HTMLGenerator:
|
|||||||
productLine.material.color = new THREE.Color(0x2E7D32);
|
productLine.material.color = new THREE.Color(0x2E7D32);
|
||||||
productMesh.add(productLine);
|
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 cavityWireframe = new THREE.WireframeGeometry(cavityGeometry);
|
||||||
const cavityLine = new THREE.LineSegments(cavityWireframe);
|
const cavityLine = new THREE.LineSegments(cavityWireframe);
|
||||||
@@ -335,6 +409,21 @@ class HTMLGenerator:
|
|||||||
cavityLine.material.transparent = true;
|
cavityLine.material.transparent = true;
|
||||||
cavityLine.material.color = new THREE.Color(0x1565C0);
|
cavityLine.material.color = new THREE.Color(0x1565C0);
|
||||||
cavityMesh.add(cavityLine);
|
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 coreWireframe = new THREE.WireframeGeometry(coreGeometry);
|
||||||
const coreLine = new THREE.LineSegments(coreWireframe);
|
const coreLine = new THREE.LineSegments(coreWireframe);
|
||||||
|
|||||||
Reference in New Issue
Block a user