开发:优化类型定义

pull/1816/head
ChenX 3 years ago
parent 477fd511c3
commit 7690b5e70d

@ -1,6 +1,6 @@
import { Vector3 } from 'three';
import { getLoocAtUpVec, rotatePoint, comparePoint } from './../../src/Geometry/GeUtils';
import { getLoocAtUpVec, rotatePoint, ComparePointFnGenerate } from './../../src/Geometry/GeUtils';
test('getLoocAtUpVec', () =>
{
@ -41,19 +41,19 @@ describe('排序测试', () =>
];
test('排序点xyz', () =>
{
pts.sort(comparePoint("xyz"));
pts.sort(ComparePointFnGenerate("xyz"));
expect(pts).toMatchSnapshot();
});
test('排序点Xyz', () =>
{
pts.sort(comparePoint("Xyz"));
pts.sort(ComparePointFnGenerate("Xyz"));
expect(pts).toMatchSnapshot();
});
test('排序点Zx', () =>
{
pts.sort(comparePoint("Zx"));
pts.sort(ComparePointFnGenerate("Zx"));
expect(pts).toMatchSnapshot();
});
});

@ -6,7 +6,7 @@ async function Check(data: any, count: number)
{
let boards = LoadEntityFromFileData(data) as Solid3D[];
for (let i = 0; i < boards.length; i++)
boards[i].objectId = new ObjectId(i);
boards[i].objectId = new ObjectId(i) as any;
await CheckInterfereTool.GetInstance().Check(boards as any[]);
expect(CheckInterfereTool.GetInstance().objMap.length).toBe(count);
}

@ -9,7 +9,7 @@ import { Polyline } from "../../DatabaseServices/Entity/Polyline";
import { Command } from "../../Editor/CommandMachine";
import { PromptStatus } from "../../Editor/PromptResult";
import { CreateContour2 } from "../../Geometry/CreateContour2";
import { AsVector2, comparePoint, equaln, isParallelTo } from "../../Geometry/GeUtils";
import { AsVector2, ComparePointFnGenerate, equaln, isParallelTo } from "../../Geometry/GeUtils";
import { PlaneExt } from "../../Geometry/Plane";
import { RegionParse } from "../../Geometry/RegionParse";
import { IntersectOption } from "../../GraphicsSystem/IntersectWith";
@ -160,7 +160,7 @@ export class LinearCutting implements Command
}
else
{
ipts.sort(comparePoint("xy"));
ipts.sort(ComparePointFnGenerate("xy"));
pl.StartPoint = ipts[0];
pl.EndPoint = arrayLast(ipts);
}

@ -7,7 +7,7 @@ import { Board } from "../../DatabaseServices/Entity/Board";
import { HardwareCompositeEntity } from "../../DatabaseServices/Hardware/HardwareCompositeEntity";
import { Command } from "../../Editor/CommandMachine";
import { PromptStatus } from "../../Editor/PromptResult";
import { comparePoint } from "../../Geometry/GeUtils";
import { ComparePointFnGenerate } from "../../Geometry/GeUtils";
import { AppToaster } from "../../UI/Components/Toaster";
import { BoardOpenDir } from "../../UI/Store/BoardInterface";
@ -58,7 +58,7 @@ export class ParseHinge implements Command
for (let d of hingeMap)
{
let arr = d[1];
arr.sort(comparePoint("xy"));
arr.sort(ComparePointFnGenerate("xy"));
if (arr.every(p => p.x === arr[0].x))//所有的X都相等
hingeMarks.push([d[0], `X:${arr[0].x} Y:${arr.map(p => p.y).join(",")}`]);
else if (arr.every(p => p.y === arr[0].y))

@ -12,7 +12,7 @@ import { Polyline } from "../DatabaseServices/Entity/Polyline";
import { Command } from "../Editor/CommandMachine";
import { PromptStatus } from "../Editor/PromptResult";
import { FuzzDirection } from "../Geometry/FuzzVector";
import { comparePoint, ptToString } from "../Geometry/GeUtils";
import { ComparePointFnGenerate, ptToString } from "../Geometry/GeUtils";
import { PlaneExt } from "../Geometry/Plane";
import { BoardType } from "../UI/Store/BoardInterface";
@ -189,7 +189,8 @@ export class Command_Join implements Command
kbMap.get(kbStr).push(line);
}
}
//连接直线
//连接成一条直线(总是共线,并且忽略间隙)
private JoinLine(kbMap: Map<string, Curve[]>)
{
for (let [, arr] of kbMap)
@ -201,6 +202,7 @@ export class Command_Join implements Command
l.Erase();
}
}
private MergeBoards(brs: Board[])
{
let brMap: Map<BoardType, Board[]> = new Map();
@ -217,7 +219,7 @@ export class Command_Join implements Command
}
private JoinSameTypeBrs(brs: ExtrudeSolid[])
{
let sortFn = comparePoint("xyz");
let sortFn = ComparePointFnGenerate("xyz");
//排序
brs.sort((a, b) =>
{

@ -81,7 +81,7 @@ export abstract class CADObject
if (!this._db)
{
this._db = db;
this.objectId = db.AllocateId();
this.objectId = db.AllocateId() as ObjectId<this>;
this.objectId.Object = this;
}
else
@ -120,9 +120,9 @@ export abstract class CADObject
// -------------------------id-------------------------
//操作这个需要谨慎!
objectId: ObjectId;
objectId: ObjectId<this>;
get Id(): ObjectId
get Id(): ObjectId<this>
{
return this.objectId;
}
@ -137,7 +137,7 @@ export abstract class CADObject
{
let ver = file.Read();
//write Id;
let id = file.ReadObjectId();
let id = file.ReadObjectId() as ObjectId<this>;
if (!this.objectId && id)//避免CopyFrom时错误的修改自身Id
{
this.objectId = id;

@ -199,9 +199,9 @@ export class Circle extends Curve
return angle(pt.clone().applyMatrix4(this.OCSInv)) / (Math.PI * 2);
}
PtOnCurve(pt: Vector3)
PtOnCurve(pt: Vector3, fuzz = 1e-5)
{
return equaln(pt.distanceToSquared(this.Center), this._Radius * this._Radius, 1e-5);
return equaln(pt.distanceToSquared(this.Center), this._Radius * this._Radius, fuzz);
}
GetOffsetCurves(offsetDist: number): Curve[]
{

@ -7,7 +7,7 @@ import { Factory } from "../CADFactory";
import { Entity } from "./Entity";
let pointMaterial: PointsMaterial;
function LoadPointMaterial()
export function LoadPointMaterial()
{
if (!pointMaterial)
{
@ -37,10 +37,9 @@ export class Point extends Entity
/**
* threejs,.
*
*
* @param {RenderType} [renderType=RenderType.Wireframe]
* @returns {Object3D} threejs.
* @memberof Entity
*/
protected InitDrawObject(renderType: RenderType = RenderType.Wireframe): Object3D
@ -81,10 +80,9 @@ export class Point extends Entity
/**
* ,Stretch
*
*
* @param {Array<number>} indexList .
* @param {Vector3} vec
* @memberof Entity
*/
MoveStretchPoints(indexList: Array<number>, vec: Vector3)
{

@ -14,10 +14,10 @@ CADObject对象拥有Id属性,用来记录引用关系.
ObjectId使 Database(dbid,便id)
*/
export class ObjectId
export class ObjectId<T extends CADObject = CADObject>
{
_RelevancyType = RelevancyType.General;
constructor(private index = 0, private obj?: CADObject)
constructor(private index = 0, private obj?: T)
{
}
@ -25,11 +25,11 @@ export class ObjectId
{
return !this.obj || this.obj.IsErase;
}
set Object(obj: CADObject)
set Object(obj: T)
{
this.obj = obj;
}
get Object(): CADObject
get Object(): T
{
return this.obj;
}

@ -26,7 +26,7 @@ export namespace BufferGeometryUtils
bf.needsUpdate = true;
geo.drawRange.count = pts.length;
}
else
else//此时这个Geometry.Dispose后在进行重新生成会比较后,否则属性没有被回收导致内存泄漏
return false;
BufferGeometry2GeometryCacheMap.delete(geo);

@ -57,14 +57,17 @@ export class BoxCheckIntersect
this.box = box;
}
//直线与盒子相交,或者被盒子包含.
//直线与盒子相交,或者被盒子包含. CohenSutherland裁剪算法
IsIntersectLine(p1: Vec2, p2: Vec2): boolean
{
let code1 = ComputeOutCode(p1.x, p1.y, this.box);
let code2 = ComputeOutCode(p2.x, p2.y, this.box);
//按位AND不为0:两个点共享一个外部区域(LEFT,RIGHT,TOP或BOTTOM),因此两个点都必须在窗口外部
if (code1 & code2) return false;
let code = code1 | code2;
if (code1 === 0 || code2 === 0 || code === 3 || code === 12)
if (code1 === 0 || code2 === 0 || code === 3 || code === 12)//点1点2在矩形内,或者竖直贯穿,水平贯穿
return true;
if ((code & TOP) && doIntersect(p1, p2, this.p3, this.p4))
@ -87,3 +90,89 @@ export class BoxCheckIntersect
return ((nearestX - cen.x) ** 2 + (nearestY - cen.y) ** 2) <= radius ** 2;
}
}
//https://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm
function CohenSutherlandLineClip(box: Box2, p1: Vec2, p2: Vec2)
{
let [x0, y0] = [p1.x, p1.y];
let [x1, y1] = [p2.x, p2.y];
let xmin = box.min.x;
let ymin = box.min.y;
let xmax = box.max.x;
let ymax = box.max.y;
// compute outcodes for P0, P1, and whatever point lies outside the clip rectangle
let outcode0 = ComputeOutCode(x0, y0, box);
let outcode1 = ComputeOutCode(x1, y1, box);
let accept = false;
while (true)
{
if (!(outcode0 | outcode1))
{
// bitwise OR is 0: both points inside window; trivially accept and exit loop
accept = true;
break;
}
else if (outcode0 & outcode1)
{
// bitwise AND is not 0: both points share an outside zone (LEFT, RIGHT, TOP,
// or BOTTOM), so both must be outside window; exit loop (accept is false)
break;
}
else
{
// failed both tests, so calculate the line segment to clip
// from an outside point to an intersection with clip edge
let x: number, y: number;
// At least one endpoint is outside the clip rectangle; pick it.
let outcodeOut = outcode1 > outcode0 ? outcode1 : outcode0;
// Now find the intersection point;
// use formulas:
// slope = (y1 - y0) / (x1 - x0)
// x = x0 + (1 / slope) * (ym - y0), where ym is ymin or ymax
// y = y0 + slope * (xm - x0), where xm is xmin or xmax
// No need to worry about divide-by-zero because, in each case, the
// outcode bit being tested guarantees the denominator is non-zero
if (outcodeOut & TOP)
{ // point is above the clip window
x = x0 + (x1 - x0) * (ymax - y0) / (y1 - y0);
y = ymax;
}
else if (outcodeOut & DOWN)
{ // point is below the clip window
x = x0 + (x1 - x0) * (ymin - y0) / (y1 - y0);
y = ymin;
}
else if (outcodeOut & RIGHT)
{ // point is to the right of clip window
y = y0 + (y1 - y0) * (xmax - x0) / (x1 - x0);
x = xmax;
}
else if (outcodeOut & LEFT)
{ // point is to the left of clip window
y = y0 + (y1 - y0) * (xmin - x0) / (x1 - x0);
x = xmin;
}
// Now we move outside point to intersection point to clip
// and get ready for next pass.
if (outcodeOut === outcode0)
{
x0 = x;
y0 = y;
outcode0 = ComputeOutCode(x0, y0, box);
}
else
{
x1 = x;
y1 = y;
outcode1 = ComputeOutCode(x1, y1, box);
}
}
}
}

@ -287,7 +287,7 @@ export class CLineGeometry extends LineGeometry
this.PolygonsOutline(polygonsPerPlane[key], coords);
}
let lineSegments;
let lineSegments: Float32Array;
if (coords instanceof Float32Array)
{

@ -335,7 +335,7 @@ const comparePointCache: Map<string, compareVectorFn> = new Map();
* @param {string} sortKey
* @returns {compareVectorFn}
*/
export function comparePoint(sortKey: string): compareVectorFn
export function ComparePointFnGenerate(sortKey: string): compareVectorFn
{
if (comparePointCache.has(sortKey))
return comparePointCache.get(sortKey);

@ -250,7 +250,7 @@ export class RegionParse
}
}
function CalcRouteAngle(r: Route, length: number)
export function CalcRouteAngle(r: Route, length: number)
{
if (r.an !== undefined) return;
let cu = r.curve;

@ -7,7 +7,7 @@ import { IntersectLAndLFor2D } from "../../GraphicsSystem/IntersectWith";
import { RenderType } from "../../GraphicsSystem/RenderType";
import { Viewer } from "../../GraphicsSystem/Viewer";
import { doIntersect } from "../DoIntersect";
import { AsVector2, AsVector3, comparePoint, compareVectorFn, isParallelTo } from "../GeUtils";
import { AsVector2, AsVector3, ComparePointFnGenerate, compareVectorFn, isParallelTo } from "../GeUtils";
/**
* ,线,.
@ -100,7 +100,7 @@ export class PointSelectBoards
let brs = selectLine.SelectEntityList as Board[];
let compareFn = comparePoint(edgeSorts[i]);
let compareFn = ComparePointFnGenerate(edgeSorts[i]);
let boxCache = new Map<Board, Vector3>();
let dcs = this.view.DCS;

@ -6,7 +6,7 @@ import { Curve } from '../DatabaseServices/Entity/Curve';
import { Ellipse } from '../DatabaseServices/Entity/Ellipse';
import { Line } from '../DatabaseServices/Entity/Line';
import { Polyline } from '../DatabaseServices/Entity/Polyline';
import { comparePoint, equaln, equalv3 } from '../Geometry/GeUtils';
import { ComparePointFnGenerate, equaln, equalv3 } from '../Geometry/GeUtils';
/**
* .
@ -352,7 +352,7 @@ export function IntersectLineAndLine(l1: Line, l2: Line, extType: IntersectOptio
if (equaln(pt1.z, 0, fuzz) && equaln(pt2.z, 0, fuzz) && equaln(pt3.z, 0, fuzz) && equaln(pt4.z, 0, fuzz))
{
ipts = IntersectLAndLFor2D2(pt1, pt2, pt3, pt4);
ipts.sort(comparePoint("xy"));
ipts.sort(ComparePointFnGenerate("xy"));
arrayRemoveDuplicateBySort(ipts, (p1, p2) => equalv3(p1, p2, fuzz));
}
else

@ -19,17 +19,20 @@ interface IOffsetResult
index: number;
curve: Curve;
sp?: Vector3;
preArc?: Curve;
ep?: Vector3;
nextArc?: Curve;
preCurve?: Curve;
nextCurve?: Curve;
paddingCurve?: Curve[];
}
class CurveTreeNode
export class CurveTreeNode
{
children: CurveTreeNode[];
children: this[];
box: Box3;
used: boolean;
Create(curve: Curve, box?: Box3): this { return new (<typeof CurveTreeNode>this.constructor)(curve, box) as this; }
constructor(public curve: Curve, box?: Box3)
{
this.box = box || curve.BoundingBox;
@ -75,7 +78,7 @@ class CurveTreeNode
{
let p = c.GetPointAtParam(0.5);
if (CurveIsFine(c) && (!(box.containsPoint(p) && contour.Curve.PtInCurve(p)) || contour.Curve.PtOnCurve(p)))
this.children.push(new CurveTreeNode(c));
this.children.push(this.Create(c));
}
if (this.children.length === cus.length)
this.children = undefined;
@ -89,7 +92,7 @@ class CurveTreeNode
if (!this.children) return [this];
else
{
let cus: CurveTreeNode[] = [];
let cus: this[] = [];
for (let c of this.children)
cus.push(...c.Nodes);
return cus;
@ -205,7 +208,7 @@ export class OffsetPolyline
}
//连接(延伸)曲线,或者补(圆弧,直线)
protected LinkSubCurves()
LinkSubCurves()
{
let count = this._SubOffsetedCurves.length;
if (!this._IsClose) count--;
@ -341,8 +344,8 @@ export class OffsetPolyline
curveResNow.ep = tp;
curveResNext.sp = tp;
curveResNow.nextArc = curveNext;
curveResNext.preArc = curveNow;
curveResNow.nextCurve = curveNext;
curveResNext.preCurve = curveNow;
}
}
else
@ -466,9 +469,9 @@ export class OffsetPolyline
let l1PadArc: Arc;
let l2PadArc: Arc;
//真理2:隔壁的圆弧不可能破坏当前的圆弧,只能破坏当前的针脚
if (l1Intact && d.preArc && d.preArc instanceof Arc)
if (l1Intact && d.preCurve && d.preCurve instanceof Arc)
{
let a = d.preArc;
let a = d.preCurve;
if (Math.sign(a.Bul) !== this._OffsetDistSign && a.AllAngle > 1e-6)
{
let ipts = a.IntersectWith(l1, IntersectOption.OnBothOperands);
@ -481,9 +484,9 @@ export class OffsetPolyline
}
}
}
if (l2Intact && d.nextArc && d.nextArc instanceof Arc)
if (l2Intact && d.nextCurve && d.nextCurve instanceof Arc)
{
let a = d.nextArc;
let a = d.nextCurve;
if (Math.sign(a.Bul) !== this._OffsetDistSign && a.AllAngle > 1e-6)
{
let ipts = a.IntersectWith(l2, IntersectOption.OnBothOperands);
@ -836,7 +839,7 @@ function EntityEncode2(c1: Curve, c2: Curve)
}
//表示这个是一个正常的曲线,不是0长度的线,也不是0长度的圆弧
function CurveIsFine(curve: Curve)
export function CurveIsFine(curve: Curve)
{
if (curve instanceof Arc && curve.AllAngle < 2e-6) return false;
return curve.Length > 5e-5;

@ -7,7 +7,7 @@ import { Curve } from "../../DatabaseServices/Entity/Curve";
import { Line } from "../../DatabaseServices/Entity/Line";
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
import { Shape } from "../../DatabaseServices/Shape";
import { AsVector2, AsVector3, comparePoint, equaln, equalv3 } from "../../Geometry/GeUtils";
import { AsVector2, AsVector3, ComparePointFnGenerate, equaln, equalv3 } from "../../Geometry/GeUtils";
/**
* ,线
@ -149,7 +149,7 @@ function ChangePlListStartPt(plList: Polyline[])
if (firstPl.IsClose)
{
let minP = undefined;
let compare = comparePoint("xy");
let compare = ComparePointFnGenerate("xy");
for (let p of firstPl.GetStretchPoints())
{
if (!minP)

@ -74,6 +74,8 @@ export class Command_TestDrawYHData implements Command
}
}
if (!nestDb) return;
let placeType = 1;//1 正常的 2弃用的
let placeIndex = -1;//当前绘制的索引

@ -337,7 +337,7 @@ export class TemplateManage extends React.Component<ITemplateManage, {}> {
{
app.Editor.GetPointServices.snapServices.FilterErase = false;
//给个id保证能被捕捉
for (let e of nens) e.objectId = app.Database.ModelSpace.Id;
for (let e of nens) e.objectId = app.Database.ModelSpace.Id as any;
let baseRes = await app.Editor.GetPoint({ Msg: "点取新基点:" });
for (let e of nens) e.objectId = undefined;
app.Editor.GetPointServices.snapServices.FilterErase = true;

Loading…
Cancel
Save