分模候选方案

This commit is contained in:
2026-04-23 23:57:34 +08:00
parent c1f6b6e827
commit f9acdb767b
5 changed files with 94 additions and 35 deletions
+55 -17
View File
@@ -221,9 +221,49 @@ class HTMLGenerator:
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'};
function toFlatArray(data) {{
if (!Array.isArray(data)) return [];
if (data.length === 0) return [];
return Array.isArray(data[0]) ? data.flat() : data;
}}
function normalizePositions(rawPositions, center) {{
const flat = toFlatArray(rawPositions);
if (!flat.length) return [];
const normalized = [];
for (let i = 0; i + 2 < flat.length; i += 3) {{
const x = Number(flat[i]);
const y = Number(flat[i + 1]);
const z = Number(flat[i + 2]);
if (Number.isFinite(x) && Number.isFinite(y) && Number.isFinite(z)) {{
normalized.push(
x - Number(center[0] || 0),
y - Number(center[1] || 0),
z - Number(center[2] || 0)
);
}}
}}
return normalized;
}}
function fitCameraToScene() {{
const sceneBox = new THREE.Box3().setFromObject(scene);
if (sceneBox.isEmpty()) return;
const center = new THREE.Vector3();
const size = new THREE.Vector3();
sceneBox.getCenter(center);
sceneBox.getSize(size);
const maxDim = Math.max(size.x, size.y, size.z) || 100;
const distance = maxDim * 2.2;
camera.position.set(center.x + distance, center.y + distance, center.z + distance);
controls.target.copy(center);
controls.update();
}}
// 根据边界框创建几何体
const bbox = geometryData.bounding_box;
if (bbox) {{
const centerOffset = bbox.center || [0, 0, 0];
const width = bbox.dimensions ? bbox.dimensions[0] : 100;
const height = bbox.dimensions ? bbox.dimensions[1] : 100;
const depth = bbox.dimensions ? bbox.dimensions[2] : 100;
@@ -232,12 +272,12 @@ class HTMLGenerator:
if (pointcloudData && pointcloudData.points && pointcloudData.points.length > 0) {{
// 创建点云几何体
const pointGeometry = new THREE.BufferGeometry();
const positions = new Float32Array(pointcloudData.points.flat());
const positions = new Float32Array(normalizePositions(pointcloudData.points, centerOffset));
pointGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
// 添加法向量(如果有)
if (pointcloudData.normals && pointcloudData.normals.length > 0) {{
const normals = new Float32Array(pointcloudData.normals.flat());
const normals = new Float32Array(toFlatArray(pointcloudData.normals));
pointGeometry.setAttribute('normal', new THREE.BufferAttribute(normals, 3));
}}
@@ -286,8 +326,8 @@ class HTMLGenerator:
if (cavityVerts.length > 0 && cavityFaces.length > 0) {{
const cavityGeometry = new THREE.BufferGeometry();
const positions = new Float32Array(cavityVerts);
const indices = new Uint32Array(cavityFaces);
const positions = new Float32Array(normalizePositions(cavityVerts, centerOffset));
const indices = new Uint32Array(toFlatArray(cavityFaces));
cavityGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
cavityGeometry.setIndex(new THREE.BufferAttribute(indices, 1));
cavityGeometry.computeVertexNormals();
@@ -331,8 +371,8 @@ class HTMLGenerator:
if (coreVerts.length > 0 && coreFaces.length > 0) {{
const coreGeometry = new THREE.BufferGeometry();
const positions = new Float32Array(coreVerts);
const indices = new Uint32Array(coreFaces);
const positions = new Float32Array(normalizePositions(coreVerts, centerOffset));
const indices = new Uint32Array(toFlatArray(coreFaces));
coreGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
coreGeometry.setIndex(new THREE.BufferAttribute(indices, 1));
coreGeometry.computeVertexNormals();
@@ -364,7 +404,7 @@ class HTMLGenerator:
}}
// 创建分型面(红色平面)
const partingGeometry = new THREE.PlaneGeometry(width * 1.2, depth * 1.2);
const partingGeometry = new THREE.PlaneGeometry(width * 1.2, height * 1.2);
const partingMaterial = new THREE.MeshBasicMaterial({{
color: 0xF44336,
transparent: true,
@@ -373,7 +413,6 @@ class HTMLGenerator:
}});
partingMesh = new THREE.Mesh(partingGeometry, partingMaterial);
partingMesh.rotation.x = Math.PI / 2;
partingMesh.position.set(0, 0, 0);
scene.add(partingMesh);
@@ -392,8 +431,8 @@ class HTMLGenerator:
// 创建简化型腔/A板(定模,分型面以上)— 备用
function createSimpleCavity(width, height, depth) {{
// A板:分型面(Z中心)以上的上半模
const halfHeight = height / 2;
const cavityGeometry = new THREE.BoxGeometry(width * 1.2, depth * 1.2, halfHeight + 10);
const halfDepth = depth / 2;
const cavityGeometry = new THREE.BoxGeometry(width * 1.2, height * 1.2, halfDepth + 10);
const cavityMaterial = new THREE.MeshPhongMaterial({{
color: 0x2196F3,
transparent: true,
@@ -403,7 +442,7 @@ class HTMLGenerator:
cavityMesh = new THREE.Mesh(cavityGeometry, cavityMaterial);
// Z轴开模:A板放在分型面以上
cavityMesh.position.set(0, 0, halfHeight / 2 + 5);
cavityMesh.position.set(0, 0, halfDepth / 2 + 5);
scene.add(cavityMesh);
const cavityWireframe = new THREE.WireframeGeometry(cavityGeometry);
@@ -418,8 +457,8 @@ class HTMLGenerator:
// 创建简化型芯/B板(动模,分型面以下)— 备用
function createSimpleCore(width, height, depth) {{
// B板:分型面(Z中心)以下的下半模
const halfHeight = height / 2;
const coreGeometry = new THREE.BoxGeometry(width * 1.2, depth * 1.2, halfHeight + 10);
const halfDepth = depth / 2;
const coreGeometry = new THREE.BoxGeometry(width * 1.2, height * 1.2, halfDepth + 10);
const coreMaterial = new THREE.MeshPhongMaterial({{
color: 0xFF9800,
transparent: true,
@@ -429,7 +468,7 @@ class HTMLGenerator:
coreMesh = new THREE.Mesh(coreGeometry, coreMaterial);
// Z轴开模:B板放在分型面以下
coreMesh.position.set(0, 0, -halfHeight / 2 - 5);
coreMesh.position.set(0, 0, -halfDepth / 2 - 5);
scene.add(coreMesh);
const coreWireframe = new THREE.WireframeGeometry(coreGeometry);
@@ -441,9 +480,8 @@ class HTMLGenerator:
coreMesh.add(coreLine);
}}
// 设置相机位置
camera.position.set(200, 200, 200);
camera.lookAt(0, 0, 0);
// 统一按场景包围盒调整相机,避免模型错位/尺度不一致导致观感混乱
fitCameraToScene();
// 动画循环
function animate() {{