!1459 优化:干涉检查

pull/1459/MERGE
ChenX 4 years ago
parent 995c78bc31
commit a62b0309fb

@ -18,7 +18,7 @@ exports[`双圆多段线倒角 8`] = `1200.793332200017`;
exports[`多段线闭合标志首尾有弧 1`] = `1357.0494514094473`; exports[`多段线闭合标志首尾有弧 1`] = `1357.0494514094473`;
exports[`多段线闭合标志首尾有弧 2`] = `1357.0494514094473`; exports[`多段线闭合标志首尾有弧 2`] = `1357.049451409447`;
exports[`多段线闭合标志首尾有弧 3`] = `1357.049451409447`; exports[`多段线闭合标志首尾有弧 3`] = `1357.049451409447`;

@ -91,7 +91,7 @@ exports[`圆弧合并 4`] = `0`;
exports[`最近点 1`] = ` exports[`最近点 1`] = `
Vector3 { Vector3 {
"x": 0, "x": 0,
"y": 0, "y": 6.123233995736766e-16,
"z": 0, "z": 0,
} }
`; `;

@ -131,7 +131,7 @@ Vector3 {
exports[`最近点 1`] = ` exports[`最近点 1`] = `
Vector3 { Vector3 {
"x": 0, "x": 0,
"y": 0, "y": 6.123233995736766e-16,
"z": 0, "z": 0,
} }
`; `;

File diff suppressed because one or more lines are too long

@ -14,7 +14,7 @@ exports[`多段线 存在大圆弧的多段线面积 1`] = `-24.019436375469752`
exports[`多段线 最近点精度 1`] = ` exports[`多段线 最近点精度 1`] = `
Vector3 { Vector3 {
"x": 1.987500976448074, "x": 1.9875009764480738,
"y": 3.9999218841540816, "y": 3.9999218841540816,
"z": 0, "z": 0,
} }

@ -1,6 +1,6 @@
import { Intent } from "@blueprintjs/core"; import { Intent } from "@blueprintjs/core";
import { app } from "../../ApplicationServices/Application"; import { app } from "../../ApplicationServices/Application";
import { checkInterfereTool } from "../../Common/InterfereUtil"; import { CheckInterfereTool } from "../../Common/InterfereUtil";
import { StoreageKeys } from "../../Common/StoreageKeys"; import { StoreageKeys } from "../../Common/StoreageKeys";
import { Board } from "../../DatabaseServices/Entity/Board"; import { Board } from "../../DatabaseServices/Entity/Board";
import { Entity } from "../../DatabaseServices/Entity/Entity"; import { Entity } from "../../DatabaseServices/Entity/Entity";
@ -149,7 +149,7 @@ async function ExecChaiDan(chaiDanRoute: ErpRoutes)
let originEns = new Set<Board>(); let originEns = new Set<Board>();
for (let b of selction.boardList) for (let b of selction.boardList)
originEns.add(b.__OriginalEnt__ ?? b); originEns.add(b.__OriginalEnt__ ?? b);
checkInterfereTool.Check([...originEns, ...selction.metalsList]).then(objMap => CheckInterfereTool.GetInstance().Check([...originEns, ...selction.metalsList]).then(objMap =>
{ {
if (objMap.size > 0) if (objMap.size > 0)
{ {
@ -159,6 +159,8 @@ async function ExecChaiDan(chaiDanRoute: ErpRoutes)
intent: Intent.DANGER, intent: Intent.DANGER,
}); });
} }
CheckInterfereTool.GetInstance().Clear();
}); });
} }

@ -1,8 +1,9 @@
import { Intent } from '@blueprintjs/core'; import { Intent } from '@blueprintjs/core';
import { app } from '../ApplicationServices/Application'; import { app } from '../ApplicationServices/Application';
import { ColorMaterial } from '../Common/ColorPalette';
import { DisposeThreeObj } from '../Common/Dispose'; import { DisposeThreeObj } from '../Common/Dispose';
import { checkInterfereTool } from '../Common/InterfereUtil'; import { CheckInterfereTool } from '../Common/InterfereUtil';
import { ExtrudeSolid } from '../DatabaseServices/Entity/Extrude'; import { ExtrudeSolid } from '../DatabaseServices/Entity/Extrude';
import { HardwareCompositeEntity } from '../DatabaseServices/Hardware/HardwareCompositeEntity'; import { HardwareCompositeEntity } from '../DatabaseServices/Hardware/HardwareCompositeEntity';
import { PromptStatus } from '../Editor/PromptResult'; import { PromptStatus } from '../Editor/PromptResult';
@ -16,8 +17,12 @@ import { AppToaster } from './../UI/Components/Toaster';
export class Interfere implements Command export class Interfere implements Command
{ {
checkInterfereTool: CheckInterfereTool;
async exec() async exec()
{ {
if (!this.checkInterfereTool)
this.checkInterfereTool = new CheckInterfereTool(ColorMaterial.GetConceptualMaterial(1));
const Filter = { const Filter = {
filterTypes: [HardwareCompositeEntity, ExtrudeSolid, SweepSolid] filterTypes: [HardwareCompositeEntity, ExtrudeSolid, SweepSolid]
}; };
@ -40,7 +45,7 @@ export class Interfere implements Command
timeout: 0 timeout: 0
}, 'interfere'); }, 'interfere');
await checkInterfereTool.Check(selectEnts, (i, all) => await this.checkInterfereTool.Check(selectEnts, (i, all) =>
{ {
let a = i / all; let a = i / all;
if (a - down.progress > 0.1) if (a - down.progress > 0.1)
@ -54,7 +59,7 @@ export class Interfere implements Command
down.progress = 1; down.progress = 1;
let objMap = checkInterfereTool.objMap; let objMap = this.checkInterfereTool.objMap;
if (objMap.size === 0) if (objMap.size === 0)
{ {
@ -66,14 +71,16 @@ export class Interfere implements Command
return; return;
} }
for (let [o,] of objMap) for (let [mesh,] of objMap)
{ app.Viewer.Scene.add(mesh);
app.Viewer.Scene.add(o);
}
let oldType = userConfig.RenderType; let oldType = userConfig.RenderType;
userConfig.RenderType = RenderType.Wireframe; userConfig.RenderType = RenderType.Wireframe;
app.Editor.ModalManage.RenderModeless(InterfereModal, { count: checkInterfereTool.entitySet.size, data: objMap }, { canMinimize: false }); app.Editor.ModalManage.RenderModeless(InterfereModal, { count: this.checkInterfereTool.entitySet.size, data: objMap }, { canMinimize: false });
//等待界面呼出的时候 画布并不会刷新,所以强制刷新
app.Editor.UpdateScreen();
await app.Editor.ModalManage.Wait(); await app.Editor.ModalManage.Wait();
@ -84,5 +91,7 @@ export class Interfere implements Command
} }
userConfig.RenderType = oldType; userConfig.RenderType = oldType;
this.checkInterfereTool.Clear();//回收内存
} }
} }

@ -1,6 +1,8 @@
import { Box3, Face3, Geometry, Mesh, Vector3 } from "three"; import { Box3, Material, Mesh } from "three";
import { CSG } from "../csg/core/CSG"; import { CSG } from "../csg/core/CSG";
import { Geometry2CSG, Vector3DToVector3 } from "../csg/core/Geometry2CSG"; import { FuzzyCSGFactory } from "../csg/core/FuzzyFactory3d";
import { CSG2Geometry, Geometry2CSG } from "../csg/core/Geometry2CSG";
import { Plane } from "../csg/core/math/Plane";
import { ExtrudeHole } from "../DatabaseServices/3DSolid/ExtrudeHole"; import { ExtrudeHole } from "../DatabaseServices/3DSolid/ExtrudeHole";
import { SweepSolid } from "../DatabaseServices/3DSolid/SweepSolid"; import { SweepSolid } from "../DatabaseServices/3DSolid/SweepSolid";
import { Board } from "../DatabaseServices/Entity/Board"; import { Board } from "../DatabaseServices/Entity/Board";
@ -11,19 +13,27 @@ import { ObjectId } from "../DatabaseServices/ObjectId";
import { ProcessingGroupRecord } from "../DatabaseServices/ProcessingGroup/ProcessingGroupRecord"; import { ProcessingGroupRecord } from "../DatabaseServices/ProcessingGroup/ProcessingGroupRecord";
import { TemplateLatticeRecord } from "../DatabaseServices/Template/ProgramTempate/TemplateLatticeRecord"; import { TemplateLatticeRecord } from "../DatabaseServices/Template/ProgramTempate/TemplateLatticeRecord";
import { TemplateWineRackRecord } from "../DatabaseServices/Template/ProgramTempate/TemplateWineRackRecord"; import { TemplateWineRackRecord } from "../DatabaseServices/Template/ProgramTempate/TemplateWineRackRecord";
import { CanDrawHoleFuzz } from "../Geometry/DrillParse/BoardGetFace";
import { equaln, equalv3 } from "../Geometry/GeUtils";
import { OBB } from "../Geometry/OBB/obb"; import { OBB } from "../Geometry/OBB/obb";
import { PlaneExt } from "../Geometry/Plane";
import { ColorMaterial } from "./ColorPalette"; import { ColorMaterial } from "./ColorPalette";
import { Log } from "./Log"; import { Log } from "./Log";
import { Sleep } from "./Sleep"; import { Sleep } from "./Sleep";
import { FixedNotZero } from "./Utils";
export type Solid3D = ExtrudeSolid | SweepSolid | ExtrudeHole; export type Solid3D = ExtrudeSolid | SweepSolid | ExtrudeHole;
export class CheckInterfereTool export class CheckInterfereTool
{ {
constructor(public _MeshMaterial: Material = ColorMaterial.GetBasicMaterial(1))
{
}
static _SingleInstance: CheckInterfereTool;
static GetInstance(): CheckInterfereTool
{
if (this._SingleInstance) return this._SingleInstance;
this._SingleInstance = new CheckInterfereTool;
return this._SingleInstance;
}
entitySet: Set<Solid3D> = new Set(); entitySet: Set<Solid3D> = new Set();
objMap: Map<Mesh, [Solid3D, Solid3D]> = new Map(); objMap: Map<Mesh, [Solid3D, Solid3D]> = new Map();
GetEntitys(selectEnts: (HardwareCompositeEntity | ExtrudeSolid | SweepSolid)[]) GetEntitys(selectEnts: (HardwareCompositeEntity | ExtrudeSolid | SweepSolid)[])
@ -65,7 +75,7 @@ export class CheckInterfereTool
let e1 = ens[i]; let e1 = ens[i];
let IsSkipEntity = this.IsSkipEntity(e1); let IsSkipEntity = this.IsSkipEntity(e1);
if (i % 50 === 0) if (i !== 0 && i % 50 === 0)
{ {
await Sleep(0); await Sleep(0);
if (progressCallBack) if (progressCallBack)
@ -118,11 +128,26 @@ export class CheckInterfereTool
if (!obb1.intersectsOBB(this.GetOBB(e2))) if (!obb1.intersectsOBB(this.GetOBB(e2)))
continue; continue;
function EntityTypeCode(ext: Entity): 0 | 1 | 2
{
if (ext instanceof ExtrudeSolid)
return 1;
else if (ext instanceof ExtrudeHole)
return 2;
else
return 0;
}
let t1 = EntityTypeCode(e1);
let t2 = EntityTypeCode(e2);
//#I2DXNO //#I2DXNO
if (e1 instanceof Board && e2 instanceof Board) if (t1 > 0 && t2 > 0)
{ {
let [b1, b2] = [e1.Clone(), e2.Clone()]; let [b1, b2] = [t1 === 1 ? <ExtrudeSolid>e1.Clone() : (<ExtrudeHole>e1).Convert2ExtrudeSolid(),
if (!b1.Subtract([e2], [b1]) && !b1.IsErase && !b2.Subtract([e1], [b2]) && !b2.IsErase) t2 === 1 ? <ExtrudeSolid>e2.Clone() : (<ExtrudeHole>e2).Convert2ExtrudeSolid()];
if (!b1.Subtract([b2]) && !b1.IsErase
&& !b2.Subtract([b1]) && !b2.IsErase)
continue; continue;
} }
@ -134,97 +159,18 @@ export class CheckInterfereTool
continue; continue;
} }
let c = csg1.intersect(csg2.transform1(e1.OCSInv.multiply(e2.OCS))); let interCsg = csg1.intersect(csg2.transform1(e1.OCSInv.multiply(e2.OCSNoClone)));
if (c.polygons.length > 0)
{
let ptsMap = new Map<string, Vector3[]>(); let planeSet = new Set<Plane>();
let geo = new Geometry; let f = new FuzzyCSGFactory;
for (let polygon of interCsg.polygons)
planeSet.add(f.getPlane(polygon.plane));
for (let poly of c.polygons) if (planeSet.size >= 4)//最少4个面围成一个三维实体
{ {
let normal = Vector3DToVector3(poly.plane.normal); let geo = CSG2Geometry(interCsg).applyMatrix4(e1.OCSNoClone);
if (equalv3(normal, new Vector3())) continue; let mesh = new Mesh(geo, this._MeshMaterial);
let p0 = Vector3DToVector3(poly.vertices[0].pos); objMap.set(mesh, [e1, e2]);
if (poly.vertices.some((v, i) =>
{
if (i === 0)
return false;
let p1 = Vector3DToVector3(v.pos);
return equalv3(p0, p1, 1e-2);
}))
continue;
let k = `${FixedNotZero(normal.x, 2)},${FixedNotZero(normal.y, 2)},${FixedNotZero(normal.z, 2)}`;
let k2 = `${FixedNotZero(-normal.x, 2)},${FixedNotZero(-normal.y, 2)},${FixedNotZero(-normal.z, 2)}`;
let pts = ptsMap.get(k);
if (!pts)
pts = ptsMap.get(k2);
if (!pts)
{
pts = [];
ptsMap.set(k, pts);
}
pts.push(...poly.vertices.map(v => Vector3DToVector3(v.pos)));
for (let v of poly.vertices)
{
v.tag = geo.vertices.length;
geo.vertices.push(Vector3DToVector3(v.pos));
}
let firstVertex = poly.vertices[0];
for (let i = poly.vertices.length - 3; i >= 0; i--)
{
let [a, b, c] = [
firstVertex.tag,
poly.vertices[i + 1].tag,
poly.vertices[i + 2].tag
];
let f = new Face3(a, b, c, normal);
geo.faces.push(f);
}
}
let hasSolid = false;
let count = 0;
let plane = new PlaneExt();
for (let [k, pts] of ptsMap)
{
let nor = new Vector3().fromArray(k.split(",").map(s => parseFloat(s)));
plane.setFromNormalAndCoplanarPoint(nor, pts[0]);
//超过3点不在一个面上,一般可以围城实体
let outCount = 0;
for (let p of pts)
{
let dist = plane.distanceToPoint(p);
if (!equaln(dist, 0, CanDrawHoleFuzz))
{
outCount++;
if (outCount >= 3)
{
count++;
hasSolid = true;
ptsMap.delete(k);
break;
}
}
}
}
if (hasSolid)
{
//围不出一个实体的情况
if (ptsMap.size === 1) continue;
if (ptsMap.size === 0 && count <= 2) continue;
entitySet.add(e1);
entitySet.add(e2);
geo.applyMatrix4(e1.OCS);
let m = new Mesh(geo, ColorMaterial.GetBasicMaterial(1).clone());
objMap.set(m, [e1, e2]);
}
} }
} }
} }
@ -234,6 +180,12 @@ export class CheckInterfereTool
return objMap; return objMap;
} }
Clear()
{
this.entitySet.clear();
this.objMap.clear();
}
csgCache: Map<Entity, CSG> = new Map(); csgCache: Map<Entity, CSG> = new Map();
private GetCSG(en: Solid3D) private GetCSG(en: Solid3D)
{ {
@ -273,5 +225,3 @@ export class CheckInterfereTool
return box; return box;
} }
} }
export const checkInterfereTool = new CheckInterfereTool();

@ -191,7 +191,7 @@ export class ExtrudeHole extends Hole
private GeneralMeshGeometry() private GeneralMeshGeometry()
{ {
let extrudeSettings: ExtrudeGeometryOptions = { let extrudeSettings: ExtrudeGeometryOptions = {
curveSegments: 12, curveSegments: 6,
steps: 1, steps: 1,
bevelEnabled: false, bevelEnabled: false,
depth: this.Height, depth: this.Height,

@ -1,7 +1,7 @@
import { BoxGeometry, BufferGeometry, ExtrudeGeometry, ExtrudeGeometryOptions, Geometry, InstancedInterleavedBuffer, InterleavedBufferAttribute, Line as TLine, LineSegments, Matrix3, Matrix4, Mesh, Object3D, Path, UVGenerator, Vector3 } from "three"; import { BoxGeometry, BufferGeometry, ExtrudeGeometry, ExtrudeGeometryOptions, Geometry, InstancedInterleavedBuffer, InterleavedBufferAttribute, Line as TLine, LineSegments, Matrix3, Matrix4, Mesh, Object3D, Path, UVGenerator, Vector3 } from "three";
import { Line2 } from "three/examples/jsm/lines/Line2"; import { Line2 } from "three/examples/jsm/lines/Line2";
import { LineGeometry } from "three/examples/jsm/lines/LineGeometry"; import { LineGeometry } from "three/examples/jsm/lines/LineGeometry";
import { arrayClone, arrayLast, arrayRemoveIf, arrayRemoveOnce, arraySortByNumber, arraySum } from "../../Common/ArrayExt"; import { arrayClone, arrayLast, arrayPushArray, arrayRemoveIf, arrayRemoveOnce, arraySortByNumber, arraySum } from "../../Common/ArrayExt";
import { ColorMaterial } from "../../Common/ColorPalette"; import { ColorMaterial } from "../../Common/ColorPalette";
import { equalCurve, PolylineSpliteRect } from "../../Common/CurveUtils"; import { equalCurve, PolylineSpliteRect } from "../../Common/CurveUtils";
import { DisposeThreeObj, Object3DRemoveAll } from "../../Common/Dispose"; import { DisposeThreeObj, Object3DRemoveAll } from "../../Common/Dispose";
@ -514,8 +514,8 @@ export class ExtrudeSolid extends Entity
for (let g of this.grooves) for (let g of this.grooves)
{ {
if (equaln(g.thickness, this.thickness)) if (equaln(g.thickness, this.thickness, 1e-3))
holes.push(Contour.CreateContour(g.ContourCurve.Clone().ApplyMatrix(this.OCSInv.multiply(g.OCS)), false)); holes.push(Contour.CreateContour(g.ContourCurve.Clone().ApplyMatrix(this.OCSInv.multiply(g.OCSNoClone)), false));
} }
return new Shape(contour, holes); return new Shape(contour, holes);
} }
@ -666,8 +666,9 @@ export class ExtrudeSolid extends Entity
for (let br of extrudes) for (let br of extrudes)
{ {
let gs = this.ConverToLocalGroove(br); let gs = this.ConverToLocalGroove(br);
grooves.push(...gs); arrayPushArray(grooves, gs);
} }
if (grooves.length === 0) return false;
let area1 = this.ContourCurve.Area; let area1 = this.ContourCurve.Area;
let sum1 = this.Volume; let sum1 = this.Volume;

@ -1,5 +1,6 @@
import { Box3, BufferGeometry, Geometry, Line, Matrix4, Mesh, Object3D, Vector, Vector2, Vector3 } from 'three'; import { Box3, BufferGeometry, Geometry, Line, Matrix4, Mesh, Object3D, Vector, Vector2, Vector3 } from 'three';
import { ToFixed } from '../Common/Utils'; import { ToFixed } from '../Common/Utils';
import { Vec3 } from './IVec3';
export const IdentityMtx4 = new Matrix4(); export const IdentityMtx4 = new Matrix4();
export const ZeroVec = new Vector3(); export const ZeroVec = new Vector3();
@ -73,7 +74,7 @@ interface P2
x: number; y: number; x: number; y: number;
} }
export function equalv3(v1: Vector3, v2: Vector3, fuzz = 1e-8) export function equalv3(v1: Vec3, v2: Vec3, fuzz = 1e-8)
{ {
return equaln(v1.x, v2.x, fuzz) && equaln(v1.y, v2.y, fuzz) && equaln(v1.z, v2.z, fuzz); return equaln(v1.x, v2.x, fuzz) && equaln(v1.y, v2.y, fuzz) && equaln(v1.z, v2.z, fuzz);
} }

@ -2,12 +2,12 @@ import { Button, Card, Classes, Intent } from '@blueprintjs/core';
import { observable } from 'mobx'; import { observable } from 'mobx';
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import React, { Component } from 'react'; import React, { Component } from 'react';
import { Box3, Mesh, MeshBasicMaterial, Vector3 } from 'three'; import { Box3, Mesh, Vector3 } from 'three';
import { app } from '../../../ApplicationServices/Application'; import { app } from '../../../ApplicationServices/Application';
import { Solid3D } from '../../../Common/InterfereUtil';
import { ColorMaterial } from './../../../Common/ColorPalette'; import { ColorMaterial } from './../../../Common/ColorPalette';
import { FixIndex } from './../../../Common/Utils'; import { FixIndex } from './../../../Common/Utils';
import { CommonModal } from './ModalContainer'; import { CommonModal } from './ModalContainer';
import { Solid3D } from '../../../Common/InterfereUtil';
interface IInterfereProps interface IInterfereProps
{ {
@ -72,10 +72,7 @@ export class InterfereModal extends Component<IInterfereProps, {}> {
private restore = (os: Mesh[]) => private restore = (os: Mesh[]) =>
{ {
for (let o of os) for (let o of os)
{ o.material = ColorMaterial.GetConceptualMaterial(1);
let mat = o.material as MeshBasicMaterial;
mat.color = ColorMaterial.GetColor(1);
}
app.Viewer.OutlinePass.selectedObjects = []; app.Viewer.OutlinePass.selectedObjects = [];
}; };
private next = () => private next = () =>
@ -96,8 +93,7 @@ export class InterfereModal extends Component<IInterfereProps, {}> {
}; };
private update = (o: Mesh) => private update = (o: Mesh) =>
{ {
let mat = o.material as MeshBasicMaterial; o.material = ColorMaterial.GetConceptualMaterial(5);
mat.color = ColorMaterial.GetColor(5);
let box = new Box3(); let box = new Box3();
app.Viewer.OutlinePass.selectedObjects = this.props.data.get(o).map(e => app.Viewer.OutlinePass.selectedObjects = this.props.data.get(o).map(e =>
{ {

@ -1,5 +1,5 @@
import { BufferGeometry, Face3, Geometry, Vector2, Vector3 } from "three"; import { BufferGeometry, Face3, Geometry, Vector2, Vector3 } from "three";
import { equalv3, ZeroVec } from "../../Geometry/GeUtils"; import { AsVector2, AsVector3, equalv3, ZeroVec } from "../../Geometry/GeUtils";
import { CSG } from "./CSG"; import { CSG } from "./CSG";
import { Polygon } from "./math/Polygon3"; import { Polygon } from "./math/Polygon3";
import { Vector2D } from "./math/Vector2"; import { Vector2D } from "./math/Vector2";
@ -34,7 +34,7 @@ export function Geometry2CSG(geometry: Geometry | BufferGeometry): CSG
} }
let polygon = new Polygon(vertices); let polygon = new Polygon(vertices);
let normal = Vector3DToVector3(polygon.plane.normal); let normal = AsVector3(polygon.plane.normal);
if (!isNaN(polygon.plane.w) && !equalv3(normal, new Vector3())) if (!isNaN(polygon.plane.w) && !equalv3(normal, new Vector3()))
polygons.push(polygon); polygons.push(polygon);
} }
@ -49,12 +49,12 @@ export function CSG2Geometry(csg: CSG): Geometry
for (let poly of csg.polygons) for (let poly of csg.polygons)
{ {
let normal = Vector3DToVector3(poly.plane.normal); let normal = AsVector3(poly.plane.normal);
if (equalv3(normal, ZeroVec)) continue; if (equalv3(normal, ZeroVec)) continue;
for (let v of poly.vertices) for (let v of poly.vertices)
{ {
v.tag = geo.vertices.length; v.tag = geo.vertices.length;
geo.vertices.push(Vector3DToVector3(v.pos)); geo.vertices.push(AsVector3(v.pos));
} }
let firstVertex = poly.vertices[0]; let firstVertex = poly.vertices[0];
@ -70,9 +70,9 @@ export function CSG2Geometry(csg: CSG): Geometry
geo.faces.push(f); geo.faces.push(f);
uvs.push([ uvs.push([
Vector2DToVector2(firstVertex.uv), AsVector2(firstVertex.uv),
Vector2DToVector2(poly.vertices[i + 1].uv), AsVector2(poly.vertices[i + 1].uv),
Vector2DToVector2(poly.vertices[i + 2].uv) AsVector2(poly.vertices[i + 2].uv)
]); ]);
} }
} }
@ -83,12 +83,3 @@ function Vector3ToVector3D(v: Vector3): Vector3D
{ {
return new Vector3D(v.x, v.y, v.z); return new Vector3D(v.x, v.y, v.z);
} }
export function Vector3DToVector3(v: Vector3D): Vector3
{
return new Vector3(v.x, v.y, v.z);
}
function Vector2DToVector2(v: Vector2D): Vector2
{
return new Vector2(v.x, v.y);
}

@ -1,10 +1,11 @@
import { _CSGDEBUG, EPS } from "../constants"; import { Matrix4 } from "three";
import { arrayLast, arrayRemoveDuplicateBySort } from "../../../Common/ArrayExt";
import { equalv3 } from "../../../Geometry/GeUtils";
import { EPS, _CSGDEBUG } from "../constants";
import { IsMirror } from "./IsMirrot";
import { Plane } from "./Plane"; import { Plane } from "./Plane";
import { Vector3D } from "./Vector3"; import { Vector3D } from "./Vector3";
import { Vertex3D } from "./Vertex3"; import { Vertex3D } from "./Vertex3";
import { arrayRemoveDuplicateBySort } from "../../../Common/ArrayExt";
import { Matrix4 } from "three";
import { IsMirror } from "./IsMirrot";
export enum Type export enum Type
{ {
@ -36,9 +37,9 @@ interface SplitPolygonData
* The plane of the polygon is calculated from the vertex coordinates if not provided. * The plane of the polygon is calculated from the vertex coordinates if not provided.
* The plane can alternatively be passed as the third argument to avoid calculations. * The plane can alternatively be passed as the third argument to avoid calculations.
* *
 * *
 * *
 * *
*/ */
export class Polygon export class Polygon
{ {
@ -201,15 +202,12 @@ export class Polygon
isBack = nextIsBack; isBack = nextIsBack;
} // for vertexindex } // for vertexindex
// remove duplicate vertices: // remove duplicate vertices:
let EPS_SQUARED = EPS * EPS; arrayRemoveDuplicateBySort(backVertices, (v1, v2) => equalv3(v1.pos, v2.pos, EPS));
arrayRemoveDuplicateBySort(backVertices, (v1, v2) => if (backVertices.length > 2 && equalv3(backVertices[0].pos, arrayLast(backVertices).pos, EPS))
{ backVertices.pop();
return v1.pos.distanceToSquared(v2.pos) < EPS_SQUARED; arrayRemoveDuplicateBySort(frontVertices, (v1, v2) => equalv3(v1.pos, v2.pos, EPS));
}); if (frontVertices.length > 2 && equalv3(frontVertices[0].pos, arrayLast(frontVertices).pos, EPS))
arrayRemoveDuplicateBySort(frontVertices, (v1, v2) => frontVertices.pop();
{
return v1.pos.distanceToSquared(v2.pos) < EPS_SQUARED;
});
if (frontVertices.length >= 3) if (frontVertices.length >= 3)
result.front = new Polygon(frontVertices, this.plane); result.front = new Polygon(frontVertices, this.plane);
if (backVertices.length >= 3) if (backVertices.length >= 3)
@ -219,7 +217,13 @@ export class Polygon
return result; return result;
} }
static verticesConvex(vertices: Vertex3D[], planenormal: Vector3D) /**
*
* @param vertices
* @param planenormal 线
* @returns true: false:
*/
static verticesConvex(vertices: Vertex3D[], planenormal: Vector3D): boolean
{ {
let count = vertices.length; let count = vertices.length;
if (count < 3) return false; if (count < 3) return false;

@ -425,8 +425,13 @@ class Node
} }
let args: D = { node: this, polygontreenodes: polygonTreeNodes }; let args: D = { node: this, polygontreenodes: polygonTreeNodes };
let stack: D[] = []; let stack: D[] = [];
let doCount = 0;
do do
{ {
if (doCount > 1e3) throw "程序内部错误:尝试对平面进行切割失败!进入死循环!";
doCount++;
let node = args.node; let node = args.node;
polygonTreeNodes = args.polygontreenodes; polygonTreeNodes = args.polygontreenodes;

Loading…
Cancel
Save