diff --git a/src/DatabaseServices/Extrude.ts b/src/DatabaseServices/Extrude.ts index 767aab0ad..6f9bba540 100644 --- a/src/DatabaseServices/Extrude.ts +++ b/src/DatabaseServices/Extrude.ts @@ -55,7 +55,7 @@ export class ExtureSolid extends Entity protected isRect = true; /** - * 拉伸形状 + * 拉伸形状 * 出于优化考虑,可能未初始化 * 形状位于WCS 0点位置,不随OCS变化而变化 */ @@ -328,6 +328,7 @@ export class ExtureSolid extends Entity AppendGroove(groove: ExtureSolid) { + this.WriteAllObjectRecord(); if (this.GrooveCheckPosition(groove) === Status.True) { this.grooves.push(groove); @@ -609,9 +610,9 @@ export class ExtureSolid extends Entity } /** - * (步骤1.2.) - * 将目标拉伸实体转换成在板件内部可用的凹槽实体 - * @param target 该对象可能被修改(内部不拷贝该实体) + * (步骤1.2.) + * 将目标拉伸实体转换成在板件内部可用的凹槽实体 + * @param target 该对象可能被修改(内部不拷贝该实体) * @param useClone 转换后的实体是目标实体拷贝后修改的 */ ConverToLocalGroove(target: this, useClone = false): ExtureSolid[] @@ -623,7 +624,7 @@ export class ExtureSolid extends Entity return this.GrooveCheckContour(target); } - else + else { let yv = target.Normal; let zv = this.Normal; diff --git a/src/Geometry/ThreeCSG.ts b/src/Geometry/ThreeCSG.ts index 19e68227c..8e5d24101 100644 --- a/src/Geometry/ThreeCSG.ts +++ b/src/Geometry/ThreeCSG.ts @@ -1,4 +1,4 @@ -import { Face3, Face4, Geometry, Material, Matrix4, Mesh, Vector2, Vector3, BufferGeometry } from "three"; +import { BufferGeometry, Face3, Geometry, Material, Matrix4, Mesh, Vector2, Vector3 } from "three"; const EPSILON = 1e-5, COPLANAR = 0, //共面 @@ -12,17 +12,9 @@ export default class ThreeBSP matrix: Matrix4; Node: Node; Vertex: Vertex[]; - Polygon: Polygon[]; + Polygon: Polygon[] = []; constructor(obj: Geometry | Mesh | Node) { - // Convert Geometry to ThreeBSP - let i, _length_i, - face, vertex, faceVertexUvs, uvs, - polygon, - polygons = []; - - this.Polygon = polygons; - this.Vertex = vertex; let geometry: Geometry; if (obj instanceof Geometry) { @@ -38,7 +30,6 @@ export default class ThreeBSP geometry = new Geometry().fromBufferGeometry(geo); else geometry = geo; - } else if (obj instanceof Node) { @@ -51,71 +42,41 @@ export default class ThreeBSP throw 'ThreeBSP: Given geometry is unsupported'; } - for (i = 0, _length_i = geometry.faces.length; i < _length_i; i++) + + for (let i = 0; i < geometry.faces.length; i++) { - face = geometry.faces[i]; - faceVertexUvs = geometry.faceVertexUvs[0][i]; - polygon = new Polygon(); + let face = geometry.faces[i]; + let faceVertexUvs = geometry.faceVertexUvs[0][i]; + let polygon = new Polygon(); if (face instanceof Face3) { - vertex = geometry.vertices[face.a]; - uvs = faceVertexUvs ? new Vector2(faceVertexUvs[0].x, faceVertexUvs[0].y) : null; - vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[0], uvs); - vertex.applyMatrix4(this.matrix); - polygon.vertices.push(vertex); - - vertex = geometry.vertices[face.b]; - uvs = faceVertexUvs ? new Vector2(faceVertexUvs[1].x, faceVertexUvs[1].y) : null; - vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[1], uvs); - vertex.applyMatrix4(this.matrix); - polygon.vertices.push(vertex); - - vertex = geometry.vertices[face.c]; - uvs = faceVertexUvs ? new Vector2(faceVertexUvs[2].x, faceVertexUvs[2].y) : null; - vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[2], uvs); - vertex.applyMatrix4(this.matrix); - polygon.vertices.push(vertex); - } - else if (typeof Face4) - { - vertex = geometry.vertices[face.a]; - uvs = faceVertexUvs ? new Vector2(faceVertexUvs[0].x, faceVertexUvs[0].y) : null; - vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[0], uvs); - vertex.applyMatrix4(this.matrix); - polygon.vertices.push(vertex); + let vertex = geometry.vertices[face.a]; + let uvs = faceVertexUvs ? new Vector2(faceVertexUvs[0].x, faceVertexUvs[0].y) : null; + let vertex1 = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[0], uvs); + vertex1.applyMatrix4(this.matrix); + polygon.vertices.push(vertex1); vertex = geometry.vertices[face.b]; uvs = faceVertexUvs ? new Vector2(faceVertexUvs[1].x, faceVertexUvs[1].y) : null; - vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[1], uvs); - vertex.applyMatrix4(this.matrix); - polygon.vertices.push(vertex); + let vertex2 = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[1], uvs); + vertex2.applyMatrix4(this.matrix); + polygon.vertices.push(vertex2); vertex = geometry.vertices[face.c]; uvs = faceVertexUvs ? new Vector2(faceVertexUvs[2].x, faceVertexUvs[2].y) : null; - vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[2], uvs); - vertex.applyMatrix4(this.matrix); - polygon.vertices.push(vertex); - - vertex = geometry.vertices[face.d]; - uvs = faceVertexUvs ? new Vector2(faceVertexUvs[3].x, faceVertexUvs[3].y) : null; - vertex = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[3], uvs); - vertex.applyMatrix4(this.matrix); - polygon.vertices.push(vertex); - } - else - { - throw 'Invalid face type at index ' + i; + let vertex3 = new Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[2], uvs); + vertex3.applyMatrix4(this.matrix); + polygon.vertices.push(vertex3); } polygon.calculateProperties(); - polygons.push(polygon); + this.Polygon.push(polygon); } - this.tree = new Node(polygons); + this.tree = new Node(this.Polygon); } - //减 subtract(other_tree: ThreeBSP) { let a = this.tree.clone(), @@ -134,7 +95,6 @@ export default class ThreeBSP return bsp; } - //结合 union(other_tree: ThreeBSP) { let a = this.tree.clone(), @@ -151,7 +111,6 @@ export default class ThreeBSP return bsp; } - //相交 intersect(other_tree: ThreeBSP) { let a = this.tree.clone(), @@ -171,68 +130,65 @@ export default class ThreeBSP toGeometry() { - let i, j, + let matrix = new Matrix4().getInverse(this.matrix), geometry = new Geometry(), polygons = this.tree.allPolygons(), polygon_count = polygons.length, - polygon, polygon_vertice_count, vertice_dict = {}, - vertex_idx_a, vertex_idx_b, vertex_idx_c, - vertex, face, - verticeUvs; + vertex_idx_a: number, vertex_idx_b: number, vertex_idx_c: number; - for (i = 0; i < polygon_count; i++) + for (let i = 0; i < polygon_count; i++) { - polygon = polygons[i]; - polygon_vertice_count = polygon.vertices.length; + let polygon = polygons[i]; + let polygon_vertice_count = polygon.vertices.length; - for (j = 2; j < polygon_vertice_count; j++) + for (let j = 2; j < polygon_vertice_count; j++) { - verticeUvs = []; + let verticeUvs = []; - vertex = polygon.vertices[0]; + let vertex = polygon.vertices[0]; verticeUvs.push(new Vector2(vertex.uv.x, vertex.uv.y)); - vertex = new Vector3(vertex.x, vertex.y, vertex.z); - vertex.applyMatrix4(matrix); + let vertex1 = new Vector3(vertex.x, vertex.y, vertex.z); + vertex1.applyMatrix4(matrix); - if (typeof vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] !== 'undefined') + if (typeof vertice_dict[vertex1.x + ',' + vertex1.y + ',' + vertex1.z] !== 'undefined') { - vertex_idx_a = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z]; + vertex_idx_a = vertice_dict[vertex1.x + ',' + vertex1.y + ',' + vertex1.z]; } else { - geometry.vertices.push(vertex); - vertex_idx_a = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] = geometry.vertices.length - 1; + geometry.vertices.push(vertex1); + vertex_idx_a = vertice_dict[vertex1.x + ',' + vertex1.y + ',' + vertex1.z] = geometry.vertices.length - 1; } vertex = polygon.vertices[j - 1]; verticeUvs.push(new Vector2(vertex.uv.x, vertex.uv.y)); - vertex = new Vector3(vertex.x, vertex.y, vertex.z); - vertex.applyMatrix4(matrix); - if (typeof vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] !== 'undefined') + let vertex2 = new Vector3(vertex.x, vertex.y, vertex.z); + vertex2.applyMatrix4(matrix); + if (typeof vertice_dict[vertex2.x + ',' + vertex2.y + ',' + vertex2.z] !== 'undefined') { - vertex_idx_b = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z]; + vertex_idx_b = vertice_dict[vertex2.x + ',' + vertex2.y + ',' + vertex2.z]; } else { - geometry.vertices.push(vertex); - vertex_idx_b = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] = geometry.vertices.length - 1; + geometry.vertices.push(vertex2); + vertex_idx_b = vertice_dict[vertex2.x + ',' + vertex2.y + ',' + vertex2.z] = geometry.vertices.length - 1; } vertex = polygon.vertices[j]; verticeUvs.push(new Vector2(vertex.uv.x, vertex.uv.y)); - vertex = new Vector3(vertex.x, vertex.y, vertex.z); - vertex.applyMatrix4(matrix); - if (typeof vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] !== 'undefined') + let vertex3 = new Vector3(vertex.x, vertex.y, vertex.z); + vertex3.applyMatrix4(matrix); + if (typeof vertice_dict[vertex3.x + ',' + vertex3.y + ',' + vertex3.z] !== 'undefined') { - vertex_idx_c = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z]; + vertex_idx_c = vertice_dict[vertex3.x + ',' + vertex3.y + ',' + vertex3.z]; } else { - geometry.vertices.push(vertex); - vertex_idx_c = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] = geometry.vertices.length - 1; + geometry.vertices.push(vertex3); + vertex_idx_c = vertice_dict[vertex3.x + ',' + vertex3.y + ',' + vertex3.z] = geometry.vertices.length - 1; } - face = new Face3( + let face = new Face3( vertex_idx_a, vertex_idx_b, vertex_idx_c, @@ -257,7 +213,6 @@ export default class ThreeBSP } } -//多边形 export class Polygon { w: number; @@ -298,10 +253,8 @@ export class Polygon clone() { - let i, vertice_count, - polygon = new Polygon(); - - for (i = 0, vertice_count = this.vertices.length; i < vertice_count; i++) + let polygon = new Polygon(); + for (let i = 0, vertice_count = this.vertices.length; i < vertice_count; i++) { polygon.vertices.push(this.vertices[i].clone()); } @@ -312,12 +265,12 @@ export class Polygon flip() { - let i, vertices = []; + let vertices = []; this.normal.multiplyScalar(-1); this.w *= -1; - for (i = this.vertices.length - 1; i >= 0; i--) + for (let i = this.vertices.length - 1; i >= 0; i--) { vertices.push(this.vertices[i]); } @@ -327,7 +280,7 @@ export class Polygon } //划分? - classifyVertex(vertex: Vector3) + classifyVertex(vertex: Vector3 | Vertex) { let side_value = this.normal.dot(vertex) - this.w; @@ -346,37 +299,28 @@ export class Polygon //划分边? classifySide(polygon: Polygon) { - let i, vertex, classification, - num_positive = 0, + let num_positive = 0, num_negative = 0, vertice_count = polygon.vertices.length; - for (i = 0; i < vertice_count; i++) + for (let i = 0; i < vertice_count; i++) { - vertex = polygon.vertices[i]; - classification = this.classifyVertex(vertex); + let vertex = polygon.vertices[i]; + let classification = this.classifyVertex(vertex); if (classification === FRONT) - { num_positive++; - } else if (classification === BACK) - { + else if (classification === BACK) num_negative++; - } } if (num_positive > 0 && num_negative === 0) - { return FRONT; - } else if (num_positive === 0 && num_negative > 0) - { + else if (num_positive === 0 && num_negative > 0) return BACK; - } else if (num_positive === 0 && num_negative === 0) - { + else if (num_positive === 0 && num_negative === 0) return COPLANAR; - } else - { + else return SPANNING; - } } //分解 分离 区域? @@ -386,55 +330,48 @@ export class Polygon if (classification === COPLANAR) { - (this.normal.dot(polygon.normal) > 0 ? coplanar_front : coplanar_back).push(polygon); - - } else if (classification === FRONT) + } + else if (classification === FRONT) { - front.push(polygon); - - } else if (classification === BACK) + } + else if (classification === BACK) { - back.push(polygon); - - } else + } + else { + let f = []; + let b = []; - let vertice_count, - i, j, ti, tj, vi, vj, - t, v, - f = [], - b = []; - - for (i = 0, vertice_count = polygon.vertices.length; i < vertice_count; i++) + for (let i = 0, vertice_count = polygon.vertices.length; i < vertice_count; i++) { - - j = (i + 1) % vertice_count; - vi = polygon.vertices[i]; - vj = polygon.vertices[j]; - ti = this.classifyVertex(vi); - tj = this.classifyVertex(vj); + let j = (i + 1) % vertice_count; + let vi = polygon.vertices[i]; + let vj = polygon.vertices[j]; + let ti = this.classifyVertex(vi); + let tj = this.classifyVertex(vj); if (ti != BACK) f.push(vi); if (ti != FRONT) b.push(vi); if ((ti | tj) === SPANNING) { - t = (this.w - this.normal.dot(vi)) / this.normal.dot(vj.clone().subtract(vi)); - v = vi.interpolate(vj, t); + let t = (this.w - this.normal.dot(vi)) / this.normal.dot(vj.clone().subtract(vi)); + let v = vi.interpolate(vj, t); f.push(v); b.push(v); } } - if (f.length >= 3) front.push(new Polygon(f).calculateProperties()); if (b.length >= 3) back.push(new Polygon(b).calculateProperties()); } } } +type v3 = Vector3 | Vertex; + class Vertex { @@ -457,7 +394,7 @@ class Vertex return new Vertex(this.x, this.y, this.z, this.normal.clone(), this.uv.clone()); } - add(vertex) + add(vertex: v3) { this.x += vertex.x; this.y += vertex.y; @@ -465,7 +402,7 @@ class Vertex return this; } - subtract(vertex) + subtract(vertex: v3) { this.x -= vertex.x; this.y -= vertex.y; @@ -482,7 +419,7 @@ class Vertex } //×乘 - cross(vertex) + cross(vertex: v3) { let x = this.x, y = this.y, @@ -507,7 +444,7 @@ class Vertex } //点乘 - dot(vertex) + dot(vertex: v3) { return this.x * vertex.x + this.y * vertex.y + this.z * vertex.z; } @@ -538,9 +475,7 @@ class Vertex applyMatrix4(m) { - // input: Matrix4 affine matrix - let x = this.x, y = this.y, z = this.z; let e = m.elements; @@ -561,8 +496,7 @@ class Node polygons: Polygon[]; constructor(polygons?: Polygon[]) { - let i, polygon_count, - front = [], + let front = [], back = []; this.polygons = []; @@ -572,7 +506,7 @@ class Node this.divider = polygons[0].clone(); - for (i = 0, polygon_count = polygons.length; i < polygon_count; i++) + for (let i = 0, polygon_count = polygons.length; i < polygon_count; i++) { this.divider.splitPolygon(polygons[i], this.polygons, this.polygons, front, back); } @@ -588,13 +522,11 @@ class Node } } - //是凸的? 凸包? isConvex(polygons: Polygon[]) { - let i, j; - for (i = 0; i < polygons.length; i++) + for (let i = 0; i < polygons.length; i++) { - for (j = 0; j < polygons.length; j++) + for (let j = 0; j < polygons.length; j++) { if (i !== j && polygons[i].classifySide(polygons[j]) !== BACK) { @@ -607,8 +539,7 @@ class Node build(polygons: Polygon[]) { - let i, polygon_count, - front = [], + let front = [], back = []; if (!this.divider) @@ -616,7 +547,7 @@ class Node this.divider = polygons[0].clone(); } - for (i = 0, polygon_count = polygons.length; i < polygon_count; i++) + for (let i = 0, polygon_count = polygons.length; i < polygon_count; i++) { this.divider.splitPolygon(polygons[i], this.polygons, this.polygons, front, back); } @@ -660,9 +591,7 @@ class Node //反转 invert() { - let i, polygon_count, temp; - - for (i = 0, polygon_count = this.polygons.length; i < polygon_count; i++) + for (let i = 0, polygon_count = this.polygons.length; i < polygon_count; i++) { this.polygons[i].flip(); } @@ -671,7 +600,7 @@ class Node if (this.front) this.front.invert(); if (this.back) this.back.invert(); - temp = this.front; + let temp = this.front; this.front = this.back; this.back = temp; @@ -681,15 +610,12 @@ class Node // clipPolygons(polygons: Polygon[]) { - let i, polygon_count, - front, back; - if (!this.divider) return polygons.slice(); - front = []; - back = []; + let front = []; + let back = []; - for (i = 0, polygon_count = polygons.length; i < polygon_count; i++) + for (let i = 0, polygon_count = polygons.length; i < polygon_count; i++) { this.divider.splitPolygon(polygons[i], front, back, front, back); }