fix #IWC0A 新增`FromCSG`解决EdgeGeometry丢线和性能差的问题

pull/294/MERGE
ChenX 5 years ago
parent b0645ebd19
commit 67ceed6e54

@ -1,21 +1,16 @@
import { LoadEntityFromFileData } from "../Utils/LoadEntity.util";
import { Board } from "../../src/DatabaseServices/Board";
import { RenderType } from "../../src/GraphicsSystem/RenderType";
import { Line } from "three";
import { RenderType } from "../../src/GraphicsSystem/RenderType";
import { LoadBoardsFromFileData } from "../Utils/LoadEntity.util";
test('EdgeGeometry生成', () =>
{
let d = [1, "Board", 3, 2, 101, false, 1, 2, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -646.2420911908739, 230.97217145381728, -423.9845986472139, 1], 2, 484.63826594239083, 642.7439363026181, 18, false, "Polyline", 3, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 54.03714224287984, -40.88462318428341, 0, 1], 2, 6, [226.89796571085776, 338.3121692475904], 0, [248.97426264670497, 525.5228891266743], 0, [-54.03714224287984, 287.9783168893773], 0, [141.82369879876416, 40.88462318428341], 0, [588.7067940597382, 306.7620304373949], 0, [320.72013691164284, 378.99785818408446], 0, true, 1, 2, 109.48289947281157, 198.20905225226585, 18, false, "Polyline", 3, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -208.29382686305865, -201.59010496470867, 0, 1], 2, 4, [298.05328308824403, 206.16728215262995], 0, [208.29382686305865, 201.59010496470867], 0, [267.90926007565713, 311.07300443752024], 0, [406.5028791153245, 272.1962944735834], 0, true, 0, 3, 0, 0, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -646.2420911908739, 493.3031405597556, -263.2791168667886, 1], 3, 0, 0, 0, 2, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -314.3564875158372, 4019.556363898919, -46.81305616698228, 1], 1, "右侧板", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\"}", 0, 0];
let br: Board = LoadEntityFromFileData(d)[0] as Board;
let obj = br.GetDrawObjectFromRenderType(RenderType.Wireframe);
let line = obj as Line;
let geo = line.geometry;
let d = [3, "Board", 3, 2, 101, false, 1, 11, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 842.2974778978387, -349.77794462809106, 5.207248635008, 1], 2, 1200, 1287.9139521874604, 18, true, "Polyline", 3, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [0, 0], 0, [1287.9139521874604, 0], 0, [1287.9139521874604, 1200], 0, [0, 1200], 0, true, 1, 2, 650.3947318524762, 368.7144637049523, 18, false, "Polyline", 3, 2, 0, false, 0, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1827.9668979500452, -289.76232632197764, 0, 1], 2, 4, [1827.9668979500452, 755.7998263219777], 0, [1827.9668979500452, 289.76232632197764], 0, [2196.6813616549975, 289.76232632197764], 0, [2196.6813616549975, 755.7998263219777], 0.9999999999999999, true, 0, 3, 0, 0, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 842.2974778978387, -132.52737566129053, 492.2690189409713, 1], 3, 0, 0, 0, 2, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -331.4882673815591, 22.964750159997493, 5.207248635008, 1], 1, "左侧板", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\",\"highDrill\":[\"three\",\"three\",\"three\",\"three\",\"three\",\"three\"]}", 0, 0, "Board", 3, 2, 211, false, 1, 2, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1743.9852053204086, 1058.889397823259, -54.29958601640169, 1], 2, 1230.761278665225, 896.6684244728249, 18, false, "Polyline", 3, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5.684341886080802e-14, 30.761278665225063, 0, 1], 2, 6, [0, 0], 0, [300, 0], 1.44245572325029, [315.9503077287227, 816.1221829065471], 0, [600, 1200], 0, [300, 1200], 0.41421356237309503, [0, 900], 0, true, 1, 2, 385.96920000000006, 177.84615384615404, 10, false, "Polyline", 3, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -422.15384615384596, -402.0513128205126, 0, 1], 2, 5, [597.7122651988514, 788.0205128205126], 0, [422.15384615384596, 788.0205128205126], 0, [422.15384615384596, 402.05131282051263], 0, [600, 402.0513128205126], 0, [599.9999999999998, 786.9320348416215], 0.0014989901540299988, true, 0, 3, 0, 0, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1751.9852053204086, 1481.043243977105, 378.51300546933595, 1], 3, 0, 0, 0, 2, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -17.633213176275603, 262.61914493865333, 0, 1], 1, "右侧板", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\",\"highDrill\":[]}", 0, 0, "Board", 3, 2, 212, false, 1, 2, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1111.9162051636208, 2117.9319139518834, -423.9845986472139, 1], 2, 484.63826594239083, 642.7439363026181, 18, false, "Polyline", 3, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 54.03714224287984, -40.88462318428341, 0, 1], 2, 6, [226.89796571085776, 338.3121692475904], 0, [248.97426264670497, 525.5228891266743], 0, [-54.03714224287984, 287.9783168893773], 0, [141.82369879876416, 40.88462318428341], 0, [588.7067940597382, 306.7620304373949], 0, [320.72013691164284, 378.99785818408446], 0, true, 1, 2, 63.40599363597872, 232.13273756151398, 18, false, "Polyline", 3, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -58.35238007400439, -234.55749771884788, 0, 1], 2, 4, [236.13305395456487, 234.55749771884788], 0, [83.25375055383591, 272.608758187791], 0, [58.35238007400439, 297.9634913548266], 0, [290.48511763551835, 268.97109344254164], 0, true, 0, 3, 0, 0, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1111.9162051636208, 2230.3214362687672, -230.31172411264944, 1], 3, 0, 0, 0, 2, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -776.2476068199197, 3557.665244594688, -46.81305616698228, 1], 1, "右侧板", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\",\"highDrill\":[]}", 0, 0]
let brs = LoadBoardsFromFileData(d);
for (let br of brs)
{
let line = br.GetDrawObjectFromRenderType(RenderType.Wireframe) as Line;
//@ts-ignore
expect(geo.attributes.position.length).toBe(246);
expect(line.geometry.attributes.position.length).toMatchSnapshot();
}
});

@ -0,0 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`EdgeGeometry生成 1`] = `1296`;
exports[`EdgeGeometry生成 2`] = `2592`;
exports[`EdgeGeometry生成 3`] = `438`;

@ -87,7 +87,7 @@ export class GangDrill extends Solid3D
{
if (renderType === RenderType.Wireframe)
{
return new LineSegments(new EdgesGeometry(this.CreateGeometry(), 2), ColorMaterial.GetLineMaterial(this.ColorIndex));
return new LineSegments(new EdgesGeometry().FromGeometry(this.CreateGeometry(), 2), ColorMaterial.GetLineMaterial(this.ColorIndex));
}
else
return new THREE.Mesh(this.CreateGeometry(), new MeshNormalMaterial());

@ -111,7 +111,7 @@ export class SweepSolid extends Solid3D
{
if (renderType === RenderType.Wireframe)
{
let geo = new EdgesGeometry(this.CreateGeomtry());
let geo = new EdgesGeometry().fromGeometry(this.CreateGeomtry());
return new LineSegments(geo, ColorMaterial.GetLineMaterial(this.ColorIndex));
}
else

@ -1002,7 +1002,7 @@ export class ExtureSolid extends Entity
if (this._EdgeGeometry)
return this._EdgeGeometry;
this._EdgeGeometry = new EdgesGeometry(this.MeshGeometry);
this._EdgeGeometry = new EdgesGeometry().FromCSG(this.CSG);
return this._EdgeGeometry;
}

@ -1,5 +1,10 @@
import { BufferGeometry, Face3, Float32BufferAttribute, Geometry, Line3, Triangle, Vector3 } from "three";
import { Box3, BufferGeometry, Face3, Float32BufferAttribute, Geometry, Line3, Triangle, Vector3 } from "three";
import { arraySortByNumber } from "../Common/ArrayExt";
import { FixIndex } from "../Common/Utils";
import { CSG } from "../csg/core/CSG";
import { FuzzyCSGFactory } from "../csg/core/FuzzyFactory3d";
import { Polygon } from "../csg/core/math/Polygon3";
import { Vector3D } from "../csg/core/math/Vector3";
import { equalv3 } from "./GeUtils";
//ref: https://github.com/mrdoob/js/issues/10517
@ -7,9 +12,11 @@ const keys = ['a', 'b', 'c'];
export class EdgesGeometry extends BufferGeometry
{
constructor(geometry, thresholdAngle: number = 1)
/**
* 使Extrude,,线,使FromCSG.
*/
FromGeometry(geometry, thresholdAngle: number = 1)
{
super();
let geometry2: Geometry;
if (geometry.isBufferGeometry)
@ -114,6 +121,134 @@ export class EdgesGeometry extends BufferGeometry
}
}
this.addAttribute('position', new Float32BufferAttribute(coords, 3));
return this;
}
/**
*
*/
FromCSG(csg: CSG)
{
let fuzzyfactory = new FuzzyCSGFactory();
let polygonsPerPlane: { [key: number]: Polygon[] } = {};
for (let polygon of csg.polygons)
{
let plane = polygon.plane;
plane = fuzzyfactory.getPlane(plane);
let tag = plane.getTag();
if (!(tag in polygonsPerPlane)) polygonsPerPlane[tag] = [polygon];
else polygonsPerPlane[tag].push(polygon);
}
let coords: number[] = [];
for (let key in polygonsPerPlane)
{
this.PolygonsOutline(polygonsPerPlane[key], coords);
}
this.addAttribute('position', new Float32BufferAttribute(coords, 3));
return this;
}
PolygonsOutline(polygons: Polygon[], coords: number[])
{
let pts: Vector3[] = [];
let fp = new FuzzPoint();
let record: { [key: string]: { p1: Vector3, p2: Vector3, count: number } } = {};
for (let polygon of polygons)
{
for (let i = 0, count = polygon.vertices.length; i < count; i++)
{
let p = polygon.vertices[i];
let np = fp.GetVector(p.pos);
p.pos = np;
if (!("_added_" in np))
{
np["_added_"] = pts.length;
pts.push(np);
}
}
}
for (let polygon of polygons)
{
for (let i = 0, count = polygon.vertices.length; i < count; i++)
{
let p1 = polygon.vertices[i].pos as Vector3;
let p2 = polygon.vertices[FixIndex(i + 1, count)].pos;
let delta = p2.clone().sub(p1);
let lengthSq = delta.dot(delta);
let splitPts: { param: number, pt: Vector3 }[] = [];
let box = new Box3().setFromPoints([p1, p2]).expandByVector(new Vector3(1, 1, 1));
for (let p of pts)
{
if (p === p1 || p === p2) continue;
if (!box.containsPoint(p)) continue;
let delta2 = p.clone().sub(p1);
let len2 = delta2.dot(delta);
let t = len2 / lengthSq;
if (t > 0 && t < 1)
{
let closestPoint = delta.clone().multiplyScalar(t).add(p1);
if (equalv3(closestPoint, p, 1e-3))
splitPts.push({ param: t, pt: p });
}
}
splitPts.sort((p1, p2) => p1.param - p2.param);
splitPts.push({ param: 1, pt: p2 });
let lastP = p1;
for (let p of splitPts)
{
let tag1 = lastP["_added_"] as number;
let tag2 = p.pt["_added_"] as number;
let key: string;
if (tag1 < tag2) key = `${tag1},${tag2}`;
else key = `${tag2},${tag1}`;
if (key in record)
record[key].count++;
else
record[key] = { p1: lastP, p2: p.pt, count: 1 };
lastP = p.pt;
}
}
}
for (let key in record)
{
let d = record[key];
if (d.count === 1)
coords.push(d.p1.x, d.p1.y, d.p1.z, d.p2.x, d.p2.y, d.p2.z);
}
}
}
class FuzzPoint
{
private map: { [key: string]: Vector3D } = {};
GetVector(v: Vector3D)
{
let key = `${v.x.toFixed(3)},${v.y.toFixed(3)},${v.z.toFixed(3)}`;
if (key in this.map) return this.map[key];
else this.map[key] = v;
return v;
}
}

@ -15,6 +15,11 @@ export class Vertex3D
tag: number;
constructor(public pos: Vector3D, public uv = new Vector2D()) { }
clone()
{
return new Vertex3D(this.pos.clone(), this.uv.clone());
}
// Return a vertex with all orientation-specific data (e.g. vertex normal) flipped. Called when the
// orientation of a polygon is flipped.
flipped()

Loading…
Cancel
Save