fix: cleanup
This commit is contained in:
parent
c3f71f8be1
commit
352b17071c
|
|
@ -1,6 +1,6 @@
|
|||
import * as THREE from "three";
|
||||
import { exportTo3MF } from "three-3mf-exporter";
|
||||
import type { TraceResult, PathData } from "./image-tracer";
|
||||
import type { TraceResult } from "./image-tracer";
|
||||
|
||||
export interface ExtrusionSettings {
|
||||
size: number; // 模型整体尺寸 (mm)
|
||||
|
|
@ -57,41 +57,13 @@ export async function generate3MF(
|
|||
const layer = traceResult.layers.find((l) => l.id === layerSetting.id);
|
||||
if (!layer) continue;
|
||||
|
||||
// 为该图层的所有路径创建形状
|
||||
const shapes: THREE.Shape[] = [];
|
||||
|
||||
for (const path of layer.paths) {
|
||||
if (path.points.length < 2) continue;
|
||||
|
||||
const shape = createShapeFromPath(path, scale, offsetX, offsetY);
|
||||
if (shape) {
|
||||
shapes.push(shape);
|
||||
}
|
||||
}
|
||||
|
||||
if (shapes.length === 0) continue;
|
||||
|
||||
// 创建挤压几何体
|
||||
const extrudeSettings: THREE.ExtrudeGeometryOptions = {
|
||||
depth: layerSetting.thickness,
|
||||
curveSegments: 36,
|
||||
bevelEnabled: false,
|
||||
};
|
||||
|
||||
// 如果有多个形状,创建多个几何体并合并
|
||||
const geometries: THREE.ExtrudeGeometry[] = [];
|
||||
for (const shape of shapes) {
|
||||
const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
|
||||
geometries.push(geometry);
|
||||
}
|
||||
|
||||
// 合并同一图层的几何体
|
||||
let combinedGeometry;
|
||||
if (geometries.length === 1) {
|
||||
combinedGeometry = geometries[0];
|
||||
} else {
|
||||
combinedGeometry = mergeGeometries(geometries);
|
||||
}
|
||||
const geometry: THREE.ExtrudeGeometry = new THREE.ExtrudeGeometry(layer.paths, extrudeSettings);
|
||||
|
||||
// 为该图层生成颜色
|
||||
const color = generateLayerColor(layerIndex);
|
||||
|
|
@ -101,7 +73,7 @@ export async function generate3MF(
|
|||
roughness: 0.7,
|
||||
});
|
||||
|
||||
const mesh = new THREE.Mesh(combinedGeometry, material);
|
||||
const mesh = new THREE.Mesh(geometry, material);
|
||||
|
||||
// 设置图层高度(堆叠)
|
||||
mesh.position.y = currentHeight;
|
||||
|
|
@ -135,99 +107,3 @@ export async function generate3MF(
|
|||
|
||||
return blob;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从路径数据创建 Three.js 形状
|
||||
*/
|
||||
function createShapeFromPath(
|
||||
path: PathData,
|
||||
scale: number,
|
||||
offsetX: number,
|
||||
offsetY: number
|
||||
): THREE.Shape | null {
|
||||
if (path.points.length < 2) return null;
|
||||
|
||||
const shape = new THREE.Shape();
|
||||
|
||||
// 移动到起点
|
||||
const startPoint = path.points[0];
|
||||
shape.moveTo(
|
||||
(startPoint.x + offsetX) * scale,
|
||||
(startPoint.y + offsetY) * scale
|
||||
);
|
||||
|
||||
// 绘制线段到后续点
|
||||
for (let i = 1; i < path.points.length; i++) {
|
||||
const point = path.points[i];
|
||||
shape.lineTo(
|
||||
(point.x + offsetX) * scale,
|
||||
(point.y + offsetY) * scale
|
||||
);
|
||||
}
|
||||
|
||||
// 如果是闭合路径,闭合形状
|
||||
if (path.isClosed) {
|
||||
shape.closePath();
|
||||
}
|
||||
|
||||
return shape;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并多个几何体
|
||||
*/
|
||||
function mergeGeometries(
|
||||
geometries: THREE.ExtrudeGeometry[]
|
||||
): THREE.ExtrudeGeometry {
|
||||
const mergedGeometry = geometries[0].clone();
|
||||
|
||||
for (let i = 1; i < geometries.length; i++) {
|
||||
const geometry = geometries[i];
|
||||
|
||||
const positionAttribute = geometry.getAttribute("position");
|
||||
const normalAttribute = geometry.getAttribute("normal");
|
||||
const uvAttribute = geometry.getAttribute("uv");
|
||||
|
||||
if (positionAttribute) {
|
||||
const positions = mergedGeometry.getAttribute("position");
|
||||
const newPositions = new Float32Array(
|
||||
positions.array.length + positionAttribute.array.length
|
||||
);
|
||||
newPositions.set(positions.array);
|
||||
newPositions.set(positionAttribute.array, positions.array.length);
|
||||
mergedGeometry.setAttribute(
|
||||
"position",
|
||||
new THREE.BufferAttribute(newPositions, 3)
|
||||
);
|
||||
}
|
||||
|
||||
if (normalAttribute) {
|
||||
const normals = mergedGeometry.getAttribute("normal");
|
||||
const newNormals = new Float32Array(
|
||||
normals.array.length + normalAttribute.array.length
|
||||
);
|
||||
newNormals.set(normals.array);
|
||||
newNormals.set(normalAttribute.array, normals.array.length);
|
||||
mergedGeometry.setAttribute(
|
||||
"normal",
|
||||
new THREE.BufferAttribute(newNormals, 3)
|
||||
);
|
||||
}
|
||||
|
||||
if (uvAttribute) {
|
||||
const uvs = mergedGeometry.getAttribute("uv");
|
||||
const newUvs = new Float32Array(
|
||||
uvs.array.length + uvAttribute.array.length
|
||||
);
|
||||
newUvs.set(uvs.array);
|
||||
newUvs.set(uvAttribute.array, uvs.array.length);
|
||||
mergedGeometry.setAttribute(
|
||||
"uv",
|
||||
new THREE.BufferAttribute(newUvs, 2)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
mergedGeometry.computeVertexNormals();
|
||||
return mergedGeometry;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { ImageTracer, type TraceData, type OutlinedArea, type SvgLineAttributes, Options } from "@image-tracer-ts/core";
|
||||
import { ImageTracer, Options } from "@image-tracer-ts/core";
|
||||
//@ts-ignore
|
||||
import {SVGLoader, SVGResult} from "three/examples/jsm/loaders/SVGLoader";
|
||||
import {Color, ShapePath, Shape} from "three";
|
||||
|
|
@ -26,12 +26,6 @@ export interface TraceResult {
|
|||
layers: TracedLayer[];
|
||||
}
|
||||
|
||||
interface SvgPath {
|
||||
color: string;
|
||||
d: string;
|
||||
path: PathData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将图像转换为矢量路径
|
||||
* @param image - 要追踪的图片元素
|
||||
|
|
|
|||
Loading…
Reference in New Issue