This commit is contained in:
2026-03-07 01:18:25 +08:00
parent 7ccc97134d
commit e82d2b524b
3 changed files with 190 additions and 112 deletions
+79 -30
View File
@@ -19,7 +19,7 @@ class HTMLGenerator:
geometry_data: Dict[str, Any],
stp_filename: str,
cavity_data: Optional[Dict[str, Any]] = None,
key_info: Optional[Dict[str, Any]] = None
pointcloud_data: Optional[Dict[str, Any]] = None
) -> str:
"""生成3D可视化HTML页面"""
@@ -178,6 +178,7 @@ class HTMLGenerator:
<button onclick="toggleProduct()">显示/隐藏产品</button>
<button onclick="toggleMold()">显示/隐藏模具</button>
<button onclick="toggleParting()">显示/隐藏分型面</button>
<button onclick="togglePointcloud()">显示/隐藏点云</button>
</div>
</div>
@@ -208,29 +209,68 @@ class HTMLGenerator:
const axesHelper = new THREE.AxesHelper(50);
scene.add(axesHelper);
// 创建几何体(模拟模具形状)
// 创建几何体(使用点云数据或模拟模具形状)
const geometryData = {json.dumps(geometry_data, indent=2)};
const cavityData = {json.dumps(cavity_data, indent=2) if cavity_data else 'null'};
const pointcloudData = {json.dumps(pointcloud_data, indent=2) if pointcloud_data else 'null'};
// 根据边界框创建模拟几何体
// 全局变量
let productMesh, cavityMesh, coreMesh, partingMesh, pointcloudMesh;
let productVisible = true;
let moldVisible = true;
let partingVisible = true;
let pointcloudVisible = true;
// 根据边界框创建几何体
const bbox = geometryData.bounding_box;
if (bbox) {{
const width = bbox.dimensions ? bbox.dimensions[0] : 100;
const height = bbox.dimensions ? bbox.dimensions[1] : 100;
const depth = bbox.dimensions ? bbox.dimensions[2] : 100;
// 创建产品几何体(半透明绿色)
const productGeometry = new THREE.BoxGeometry(width * 0.9, height * 0.9, depth * 0.9);
const productMaterial = new THREE.MeshPhongMaterial({{
color: 0x4CAF50,
transparent: true,
opacity: 0.6,
wireframe: false
}});
const productMesh = new THREE.Mesh(productGeometry, productMaterial);
productMesh.position.set(0, 0, 0);
scene.add(productMesh);
// 如果有点云数据,创建点云模型
if (pointcloudData && pointcloudData.points && pointcloudData.points.length > 0) {{
// 创建点云几何体
const pointGeometry = new THREE.BufferGeometry();
const positions = new Float32Array(pointcloudData.points.flat());
pointGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
// 添加法向量(如果有)
if (pointcloudData.normals && pointcloudData.normals.length > 0) {{
const normals = new Float32Array(pointcloudData.normals.flat());
pointGeometry.setAttribute('normal', new THREE.BufferAttribute(normals, 3));
}}
// 创建点云材质
const pointMaterial = new THREE.PointsMaterial({{
color: 0x4CAF50,
size: 0.5,
transparent: true,
opacity: 0.8
}});
pointcloudMesh = new THREE.Points(pointGeometry, pointMaterial);
scene.add(pointcloudMesh);
// 计算中心点并调整相机位置
const center = new THREE.Vector3();
pointGeometry.computeBoundingBox();
pointGeometry.boundingBox.getCenter(center);
controls.target.set(center.x, center.y, center.z);
}} else {{
// 创建产品几何体(半透明绿色)
const productGeometry = new THREE.BoxGeometry(width * 0.9, height * 0.9, depth * 0.9);
const productMaterial = new THREE.MeshPhongMaterial({{
color: 0x4CAF50,
transparent: true,
opacity: 0.6,
wireframe: false
}});
productMesh = new THREE.Mesh(productGeometry, productMaterial);
productMesh.position.set(0, 0, 0);
scene.add(productMesh);
}}
// 创建型腔(上半模 - 蓝色)
const cavityGeometry = new THREE.BoxGeometry(width * 1.1, height * 0.3, depth * 1.1);
@@ -241,7 +281,7 @@ class HTMLGenerator:
wireframe: false
}});
const cavityMesh = new THREE.Mesh(cavityGeometry, cavityMaterial);
cavityMesh = new THREE.Mesh(cavityGeometry, cavityMaterial);
cavityMesh.position.set(0, height * 0.6, 0);
scene.add(cavityMesh);
@@ -254,7 +294,7 @@ class HTMLGenerator:
wireframe: false
}});
const coreMesh = new THREE.Mesh(coreGeometry, coreMaterial);
coreMesh = new THREE.Mesh(coreGeometry, coreMaterial);
coreMesh.position.set(0, -height * 0.6, 0);
scene.add(coreMesh);
@@ -267,21 +307,22 @@ class HTMLGenerator:
side: THREE.DoubleSide
}});
const partingMesh = new THREE.Mesh(partingGeometry, partingMaterial);
partingMesh = new THREE.Mesh(partingGeometry, partingMaterial);
partingMesh.rotation.x = Math.PI / 2;
partingMesh.position.set(0, 0, 0);
scene.add(partingMesh);
// 添加产品线框
const productWireframe = new THREE.WireframeGeometry(productGeometry);
const productLine = new THREE.LineSegments(productWireframe);
productLine.material.depthTest = false;
productLine.material.opacity = 0.5;
productLine.material.transparent = true;
productLine.material.color = new THREE.Color(0x2E7D32);
productMesh.add(productLine);
// 添加线框
if (productMesh) {{
const productWireframe = new THREE.WireframeGeometry(productMesh.geometry);
const productLine = new THREE.LineSegments(productWireframe);
productLine.material.depthTest = false;
productLine.material.opacity = 0.5;
productLine.material.transparent = true;
productLine.material.color = new THREE.Color(0x2E7D32);
productMesh.add(productLine);
}}
// 添加型腔线框
const cavityWireframe = new THREE.WireframeGeometry(cavityGeometry);
const cavityLine = new THREE.LineSegments(cavityWireframe);
cavityLine.material.depthTest = false;
@@ -290,7 +331,6 @@ class HTMLGenerator:
cavityLine.material.color = new THREE.Color(0x1565C0);
cavityMesh.add(cavityLine);
// 添加型芯线框
const coreWireframe = new THREE.WireframeGeometry(coreGeometry);
const coreLine = new THREE.LineSegments(coreWireframe);
coreLine.material.depthTest = false;
@@ -359,6 +399,13 @@ class HTMLGenerator:
partingMesh.visible = partingVisible;
}}
}}
function togglePointcloud() {{
if (pointcloudMesh) {{
pointcloudVisible = !pointcloudVisible;
pointcloudMesh.visible = pointcloudVisible;
}
}}
</script>
</body>
</html>
@@ -385,7 +432,8 @@ class HTMLGenerator:
self,
geometry_data: Dict[str, Any],
stp_filename: str,
cavity_data: Optional[Dict[str, Any]] = None
cavity_data: Optional[Dict[str, Any]] = None,
pointcloud_data: Optional[Dict[str, Any]] = None
) -> str:
"""生成并保存可视化HTML文件"""
try:
@@ -393,7 +441,8 @@ class HTMLGenerator:
html_content = self.generate_3d_viewer_html(
geometry_data,
stp_filename,
cavity_data=cavity_data
cavity_data=cavity_data,
pointcloud_data=pointcloud_data
)
# 创建文件名