|
|
|
@ -3,6 +3,7 @@ import { observable } from "mobx";
|
|
|
|
|
import { Box3, Matrix4, Vector3 } from "three";
|
|
|
|
|
import { begin } from "xaop";
|
|
|
|
|
import { app } from "../../ApplicationServices/Application";
|
|
|
|
|
import { HostApplicationServices } from "../../ApplicationServices/HostApplicationServices";
|
|
|
|
|
import { appCache } from "../../Common/AppCache";
|
|
|
|
|
import { arrayLast, arrayRemoveIf } from "../../Common/ArrayExt";
|
|
|
|
|
import { EBoardKeyList } from "../../Common/BoardKeyList";
|
|
|
|
@ -26,8 +27,7 @@ import { Polyline } from "../../DatabaseServices/Entity/Polyline";
|
|
|
|
|
import { GroupRecord } from "../../DatabaseServices/GroupTableRecord";
|
|
|
|
|
import { ObjectId } from "../../DatabaseServices/ObjectId";
|
|
|
|
|
import { Shape } from "../../DatabaseServices/Shape";
|
|
|
|
|
import { FindInWall } from "../../Editor/TranstrolControl/ParseWalls";
|
|
|
|
|
import { FindClosestInterval, Segment1d, Segment1dSubtraction2, operInterval } from "../../Editor/TranstrolControl/Segment1dUtil";
|
|
|
|
|
import { FindClosestInterval, FindInWall, OperInterval, Segment1d, Segment1dSubtraction2 } from "../../Editor/TranstrolControl/Segment1dUtil";
|
|
|
|
|
import { userConfig } from "../../Editor/UserConfig";
|
|
|
|
|
import { Box3Ext } from "../../Geometry/Box";
|
|
|
|
|
import { CanDrawHoleFuzz } from "../../Geometry/DrillParse/CanDrawHoleFuzz";
|
|
|
|
@ -58,6 +58,7 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
private _isDrillTouch = false;//排钻或木销与造型碰撞
|
|
|
|
|
private _HasAutoDeviation = false; //有自动偏移
|
|
|
|
|
private _AutoDeviation = false; //智能偏移
|
|
|
|
|
private _MoveMinDist = 16; //偏移最小距离
|
|
|
|
|
|
|
|
|
|
constructor()
|
|
|
|
|
{
|
|
|
|
@ -219,6 +220,7 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
let ljgRad = this.m_Option.ljgRad;
|
|
|
|
|
let ljgLength = safeEval(this.m_Option.ljgLengthExpr, EvalParam);
|
|
|
|
|
let ymjDepth = safeEval(this.m_Option.ymjDepthExpr, EvalParam);
|
|
|
|
|
this.m_Option.ymjDepth = ymjDepth;
|
|
|
|
|
|
|
|
|
|
let goodsId = this.m_Option.goodsId;
|
|
|
|
|
let goodsSn = this.m_Option.goodsSn;
|
|
|
|
@ -359,19 +361,12 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
{
|
|
|
|
|
this.m_Face.FixedInterval = [];
|
|
|
|
|
let subs: Segment1d[] = [];
|
|
|
|
|
let minDist = Math.max(this.m_Option.pxlRad, this.m_Option.ljgRad) + 2;
|
|
|
|
|
this.m_Face.Segment1D = [];
|
|
|
|
|
this.m_Face.Segment1D.push([minDist, this.m_Face.Length - minDist]);
|
|
|
|
|
let intBoard = this.m_Face.InterBoard;
|
|
|
|
|
let refDrillList: ObjectId[][] = [];
|
|
|
|
|
let intBoardDrills = intBoard.__OriginalEnt__?.DrillList ?? intBoard.DrillList;
|
|
|
|
|
|
|
|
|
|
//加入相交板件区间
|
|
|
|
|
for (let [id, v] of intBoardDrills)
|
|
|
|
|
if (id && id.Object)
|
|
|
|
|
refDrillList.push(...v.filter(ds => ds.length > 0 && ds[0].Object && !ds[0].IsErase));
|
|
|
|
|
this._MoveMinDist = this.m_Option.spacing === SpacingType.EqualDist ? 16 : 32;
|
|
|
|
|
const MinDist = Math.max(this.m_Option.pxlRad, this.m_Option.ljgRad) + 2;
|
|
|
|
|
//起始位置 - 终点位置
|
|
|
|
|
this.m_Face.Segment1D = [[this.m_Option.originDist - 0.1, this.m_Face.Length - this.m_Option.retDist + 0.1]];
|
|
|
|
|
|
|
|
|
|
const CheckCollision = (ent: Entity, effectiveBox: Box3) =>
|
|
|
|
|
const CheckCollision = (ent: Entity, effectiveBox: Box3, useBoxWidth?: boolean) =>
|
|
|
|
|
{
|
|
|
|
|
let grooveBox = ent.GetBoundingBoxInMtx(this.m_Face.OCSInv);
|
|
|
|
|
grooveBox.applyMatrix4(new Matrix4().scale(new Vector3(1, 1, -1)));
|
|
|
|
@ -380,12 +375,22 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
{
|
|
|
|
|
let max = Math.ceil(intersectBox.max.x);
|
|
|
|
|
let min = Math.floor(intersectBox.min.x);
|
|
|
|
|
let roundedUp = max + minDist; // 向上舍入
|
|
|
|
|
let roundedDown = min - minDist; // 向下舍入
|
|
|
|
|
|
|
|
|
|
subs.push([roundedDown, roundedUp]);
|
|
|
|
|
if (useBoxWidth)
|
|
|
|
|
{
|
|
|
|
|
let dist = (max - min) / 2 + 2;
|
|
|
|
|
max += dist;
|
|
|
|
|
min -= dist;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
max += MinDist; // 向上舍入
|
|
|
|
|
min -= MinDist; // 向下舍入
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.m_Face.FixedInterval.push([roundedDown, roundedUp]);
|
|
|
|
|
subs.push([min, max]);
|
|
|
|
|
|
|
|
|
|
this.m_Face.FixedInterval.push([min, max]);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -393,27 +398,33 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
new Vector3,
|
|
|
|
|
new Vector3(
|
|
|
|
|
this.m_Face.Length,
|
|
|
|
|
this.m_Face.LocalBoard.Thickness,
|
|
|
|
|
parseInt(this.m_Option.ljgLengthExpr) + this.m_Option.pxlRad
|
|
|
|
|
this.m_Face.InterBoard.Thickness,
|
|
|
|
|
parseFloat(this.m_Option.ljgLengthExpr) + this.m_Option.pxlRad
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
for (let g of this.m_Face.InterBoard.Grooves)
|
|
|
|
|
CheckCollision(g, effectiveBoxOnInterBoard);
|
|
|
|
|
|
|
|
|
|
let localBoardThickness = 0;
|
|
|
|
|
if (this.m_Option.ymjRad)
|
|
|
|
|
{
|
|
|
|
|
localBoardThickness = this.m_Option.ymjDepth;
|
|
|
|
|
if (this.m_Option.isDrawWood)
|
|
|
|
|
{
|
|
|
|
|
localBoardThickness = Math.max(localBoardThickness, this.m_Option.wdepth);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let effectiveBoxOnLocalBoard = new Box3(
|
|
|
|
|
new Vector3(0, 0, -this.m_Face.LocalBoard.Thickness),
|
|
|
|
|
new Vector3(0, 0, -localBoardThickness),
|
|
|
|
|
new Vector3(this.m_Face.Length, this.m_Face.InterBoard.Thickness, 0)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
//对板存在的造型洞
|
|
|
|
|
for (let g of this.m_Face.LocalBoard.Grooves)
|
|
|
|
|
CheckCollision(g, effectiveBoxOnLocalBoard);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (let drills of refDrillList)
|
|
|
|
|
for (let drill of drills)
|
|
|
|
|
CheckCollision(drill.Object as Entity, effectiveBoxOnInterBoard);
|
|
|
|
|
|
|
|
|
|
this.m_Face.FixedInterval.sort((a, b) => { return a[0] - b[0]; });
|
|
|
|
|
//计算可以放置排钻的区间
|
|
|
|
|
this.m_Face.Segment1D = Segment1dSubtraction2(this.m_Face.Segment1D, subs);
|
|
|
|
@ -427,7 +438,6 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
let count = this.m_Option.count;
|
|
|
|
|
let length = this.m_Face.Length;
|
|
|
|
|
let spacingSize: number;
|
|
|
|
|
let caclDist: Function;
|
|
|
|
|
|
|
|
|
|
//是否从面坐标原点开始算
|
|
|
|
|
let isFromOrigin = true;
|
|
|
|
@ -451,8 +461,6 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
caclDist = (i) => spacingSize * (i - 1) * dir;
|
|
|
|
|
|
|
|
|
|
//碰撞最大偏移值
|
|
|
|
|
// this._DrillSpaceDist = spacingSize;
|
|
|
|
|
//排钻初始移动距离
|
|
|
|
@ -460,7 +468,7 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
|
|
|
|
|
//加入从第一个排钻开始的移动距离
|
|
|
|
|
for (let i = 2; i <= count; i++)
|
|
|
|
|
this.m_MoveDistList[i - 1] = caclDist(i) + this.m_MoveDistList[0];
|
|
|
|
|
this.m_MoveDistList[i - 1] = spacingSize * (i - 1) * dir + this.m_MoveDistList[0];
|
|
|
|
|
}
|
|
|
|
|
//32倍数
|
|
|
|
|
private Multiple32()
|
|
|
|
@ -595,34 +603,129 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
const Fid = (this.m_Face.LocalBoard.__OriginalEnt__ ?? this.m_Face.LocalBoard).Id;
|
|
|
|
|
|
|
|
|
|
//排钻占位大小 这个+-范围不能放置排钻
|
|
|
|
|
const minDrillDist = Math.max(this.m_Option.pxlRad, this.m_Option.ljgRad) * 2 + 2;
|
|
|
|
|
const MinDrillDist = Math.max(this.m_Option.pxlRad, this.m_Option.ljgRad) + 2;
|
|
|
|
|
|
|
|
|
|
for (let dist of this.m_MoveDistList)
|
|
|
|
|
let hasStarWood = false;
|
|
|
|
|
let hasEndWood = false;
|
|
|
|
|
const originDistMap: Map<number, boolean> = new Map();
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < this.m_MoveDistList.length; i++)
|
|
|
|
|
{
|
|
|
|
|
const IsStarDrill = i === 0;
|
|
|
|
|
const IsEndDrill = i === this.m_MoveDistList.length - 1;
|
|
|
|
|
|
|
|
|
|
let dist = this.m_MoveDistList[i];
|
|
|
|
|
|
|
|
|
|
//木销与排钻距离
|
|
|
|
|
let offsetDist = 0;
|
|
|
|
|
if (IsStarDrill || IsEndDrill)
|
|
|
|
|
{
|
|
|
|
|
if (this.m_Option.isFromBack)
|
|
|
|
|
offsetDist = i === 0 ? -32 : 32;
|
|
|
|
|
else
|
|
|
|
|
offsetDist = i === 0 ? 32 : -32;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dist > this.m_Face.Length - ljgRad || dist < ljgRad)
|
|
|
|
|
{
|
|
|
|
|
Log(`移动距离${dist.toFixed(2)},碰撞面宽度${this.m_Face.Length.toFixed(2)},排钻将绘制在板外,跳过绘制`, LogType.Warning);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else if (this._AutoDeviation && !this.m_Face.Segment1D.find(([a, b]) => dist >= a && dist <= b)?.length)
|
|
|
|
|
else if (this._AutoDeviation)
|
|
|
|
|
{
|
|
|
|
|
//智能偏移
|
|
|
|
|
let { closestNum } = FindClosestInterval(dist, this.m_Face.Segment1D, 32, this.m_Face.Length);
|
|
|
|
|
//偏移值在有效区间 或 有木销时, 第一个和最后一个排钻距离32的位置是否可以放置木销
|
|
|
|
|
if (!FindInWall(dist, this.m_Face.Segment1D) ||
|
|
|
|
|
((offsetDist && this.m_Option.isDrawWood) ? !FindInWall(dist + offsetDist, this.m_Face.Segment1D) : false))
|
|
|
|
|
{
|
|
|
|
|
//计算偏移可放置数值
|
|
|
|
|
let { closestNum } = FindClosestInterval(dist, this.m_Face.Segment1D, this.m_Face.Length, this._MoveMinDist, offsetDist);
|
|
|
|
|
|
|
|
|
|
this._HasAutoDeviation = true;
|
|
|
|
|
this._InteractionLog("有排钻与造型碰撞,或不在合适位置,自动偏移", LogType.Info);
|
|
|
|
|
dist = closestNum;
|
|
|
|
|
//偏移超出邻边两侧排钻距离
|
|
|
|
|
let leftIndex = this.m_Option.isFromBack ? (i + 1) : (i - 1);
|
|
|
|
|
let rightIndex = this.m_Option.isFromBack ? (i - 1) : (i + 1);
|
|
|
|
|
let neighborLeftDist = this.m_MoveDistList[leftIndex] ?? -Infinity;
|
|
|
|
|
let neighborRightDist = this.m_MoveDistList[rightIndex] ?? Infinity;
|
|
|
|
|
|
|
|
|
|
//判断邻边是否有木销
|
|
|
|
|
{
|
|
|
|
|
if (this.m_Option.isDrawWood && this.m_Option.isFromBack ? (leftIndex === this.m_MoveDistList.length - 1) : leftIndex === 0)
|
|
|
|
|
neighborLeftDist += 32;
|
|
|
|
|
|
|
|
|
|
neighborLeftDist += ((originDistMap.get(leftIndex) ? this.m_Option.tHoleOffset : 0) + 2 * MinDrillDist);
|
|
|
|
|
|
|
|
|
|
if (this.m_Option.isDrawWood && this.m_Option.isFromBack ? (rightIndex === 0) : (rightIndex === this.m_MoveDistList.length - 1))
|
|
|
|
|
neighborRightDist -= 32;
|
|
|
|
|
|
|
|
|
|
neighborRightDist -= (2 * MinDrillDist - (originDistMap.get(rightIndex) ? this.m_Option.tHoleOffset : 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
!(closestNum && (neighborLeftDist < closestNum && closestNum < neighborRightDist)) ||
|
|
|
|
|
((offsetDist && this.m_Option.isDrawWood) && !(neighborLeftDist < (closestNum + offsetDist) && (closestNum + offsetDist) < neighborRightDist))
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
//没有与木销合适的位置 那只管自己 不管木销
|
|
|
|
|
if (!FindInWall(dist, this.m_Face.Segment1D))
|
|
|
|
|
{
|
|
|
|
|
let { closestNum } = FindClosestInterval(dist, this.m_Face.Segment1D, this.m_Face.Length, this._MoveMinDist, 0, this.m_Option.tHoleOffset);
|
|
|
|
|
if (closestNum && (neighborLeftDist < closestNum && closestNum < neighborRightDist))
|
|
|
|
|
{
|
|
|
|
|
this._HasAutoDeviation = true;
|
|
|
|
|
this._InteractionLog("有排钻与造型碰撞,或不在合适位置,自动偏移", LogType.Info);
|
|
|
|
|
this.m_MoveDistList[i] = closestNum;
|
|
|
|
|
dist = closestNum;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//自身难保 跳过绘制
|
|
|
|
|
this._isDrillTouch = true;
|
|
|
|
|
InteractionLog([
|
|
|
|
|
{ msg: `板件${this.m_Face.LocalBoard.Name}`, entity: [this.m_Face.LocalBoard] },
|
|
|
|
|
{ msg: "-" },
|
|
|
|
|
{ msg: `板件${this.m_Face.InterBoard.Name}`, entity: [this.m_Face.InterBoard] },
|
|
|
|
|
{ msg: "有排钻没有合适的偏移位置,跳过绘制" }
|
|
|
|
|
], LogType.Warning);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (IsStarDrill)
|
|
|
|
|
hasStarWood = true;
|
|
|
|
|
else if (IsEndDrill)
|
|
|
|
|
hasEndWood = true;
|
|
|
|
|
|
|
|
|
|
//排钻和木销有合适的位置一起放置
|
|
|
|
|
this._HasAutoDeviation = true;
|
|
|
|
|
this._InteractionLog("有排钻与造型碰撞,或不在合适位置,自动偏移", LogType.Info);
|
|
|
|
|
this.m_MoveDistList[i] = closestNum;
|
|
|
|
|
dist = closestNum;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
originDistMap.set(i, true);
|
|
|
|
|
if (IsStarDrill)
|
|
|
|
|
hasStarWood = true;
|
|
|
|
|
else if (IsEndDrill)
|
|
|
|
|
hasEndWood = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (this.CheckModelingCollision(localBox3, intBox3, dist))
|
|
|
|
|
{
|
|
|
|
|
this._isDrillTouch = true;
|
|
|
|
|
|
|
|
|
|
this._InteractionLog("有排钻与造型碰撞,跳过绘制");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else if (!this.CheckDrillInBoard(dist))
|
|
|
|
|
{
|
|
|
|
|
InteractionLog([{ msg: `板件${this.m_Face.LocalBoard.Name}`, entity: [this.m_Face.LocalBoard] }, { msg: "-" }, { msg: `板件${this.m_Face.InterBoard.Name}`, entity: [this.m_Face.InterBoard] }, { msg: "有排钻在板件外,跳过绘制" }], LogType.Warning);
|
|
|
|
|
InteractionLog([
|
|
|
|
|
{ msg: `板件${this.m_Face.LocalBoard.Name}`, entity: [this.m_Face.LocalBoard] },
|
|
|
|
|
{ msg: "-" },
|
|
|
|
|
{ msg: `板件${this.m_Face.InterBoard.Name}`, entity: [this.m_Face.InterBoard] },
|
|
|
|
|
{ msg: "有排钻在板件外,跳过绘制" }
|
|
|
|
|
], LogType.Warning);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -641,7 +744,12 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
newDrillentList.push(newDrillEnts);
|
|
|
|
|
//裁剪掉用过的
|
|
|
|
|
if (this._AutoDeviation)
|
|
|
|
|
this.m_Face.Segment1D = Segment1dSubtraction2(this.m_Face.Segment1D, [[dist - minDrillDist, dist + minDrillDist]]);
|
|
|
|
|
{
|
|
|
|
|
let subSegment1D: Segment1d[] = [[dist - MinDrillDist, dist + MinDrillDist]];
|
|
|
|
|
if ((IsStarDrill || IsEndDrill) && (hasStarWood || hasStarWood) && this.woodPins.length)
|
|
|
|
|
subSegment1D.push([Math.min(dist, dist + offsetDist) - MinDrillDist, Math.max(dist, dist + offsetDist) + MinDrillDist]);
|
|
|
|
|
this.m_Face.Segment1D = Segment1dSubtraction2(this.m_Face.Segment1D, subSegment1D);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let startDist = this.m_MoveDistList[0];
|
|
|
|
@ -657,8 +765,7 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
eDist = startDist;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this.woodPins.length > 0
|
|
|
|
|
&& (this.m_MoveDistList.length === 1 || sDist + eDist + 96 <= this.m_Face.Length))
|
|
|
|
|
if (this.woodPins.length > 0 && (this.m_MoveDistList.length === 1 || sDist + eDist + 96 <= this.m_Face.Length))
|
|
|
|
|
{
|
|
|
|
|
let dists: number[] = [];
|
|
|
|
|
|
|
|
|
@ -678,8 +785,9 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
dists.push(endDist);
|
|
|
|
|
|
|
|
|
|
if (dists.length === 1 || !equaln(dists[0], dists[1]))
|
|
|
|
|
for (let dist of dists)
|
|
|
|
|
for (let i = 0; i < dists.length; i++)
|
|
|
|
|
{
|
|
|
|
|
let dist = dists[i];
|
|
|
|
|
if (dist >= this.m_Face.Length - ljgRad || dist <= ljgRad)
|
|
|
|
|
{
|
|
|
|
|
Log(`移动距离${dist.toFixed(2)},碰撞面宽度${this.m_Face.Length.toFixed(2)},木销将绘制在板外,跳过绘制`, LogType.Warning);
|
|
|
|
@ -696,25 +804,34 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
|
|
|
|
|
let { localBox3, intBox3 } = this.GetBoxes(this.drillEnts);
|
|
|
|
|
|
|
|
|
|
let erase = false;
|
|
|
|
|
//造型碰撞自动偏移
|
|
|
|
|
if (this._AutoDeviation)
|
|
|
|
|
{
|
|
|
|
|
if (!FindInWall(dist, this.m_Face.Segment1D))
|
|
|
|
|
if (i === 0)
|
|
|
|
|
{
|
|
|
|
|
this._HasAutoDeviation = true;
|
|
|
|
|
//智能偏移
|
|
|
|
|
let { closestNum, closestDist } = FindClosestInterval(dist, this.m_Face.Segment1D, 32, this.m_Face.Length);
|
|
|
|
|
// if (closestNum && closestDist < this._DrillSpaceDist)
|
|
|
|
|
if (!hasStarWood)
|
|
|
|
|
{
|
|
|
|
|
dist = closestNum;
|
|
|
|
|
this._InteractionLog("有木销与造型碰撞,自动偏移", LogType.Info);
|
|
|
|
|
erase = true;
|
|
|
|
|
InteractionLog([
|
|
|
|
|
{ msg: `板件${this.m_Face.LocalBoard.Name}`, entity: [this.m_Face.LocalBoard] },
|
|
|
|
|
{ msg: "-" },
|
|
|
|
|
{ msg: `板件${this.m_Face.InterBoard.Name}`, entity: [this.m_Face.InterBoard] },
|
|
|
|
|
{ msg: "第一个木销未找到合适放置位置,跳过绘制" }
|
|
|
|
|
], LogType.Warning);
|
|
|
|
|
}
|
|
|
|
|
// else
|
|
|
|
|
// {
|
|
|
|
|
// this._InteractionLog("有木销与造型碰撞,未找到合适放置位置,跳过绘制");
|
|
|
|
|
// continue;
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if (!hasEndWood)
|
|
|
|
|
{
|
|
|
|
|
erase = true;
|
|
|
|
|
InteractionLog([
|
|
|
|
|
{ msg: `板件${this.m_Face.LocalBoard.Name}`, entity: [this.m_Face.LocalBoard] },
|
|
|
|
|
{ msg: "-" },
|
|
|
|
|
{ msg: `板件${this.m_Face.InterBoard.Name}`, entity: [this.m_Face.InterBoard] },
|
|
|
|
|
{ msg: "第二个木销未找到合适放置位置,跳过绘制" }
|
|
|
|
|
], LogType.Warning);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//造型碰撞跳过绘制
|
|
|
|
|
else
|
|
|
|
@ -735,12 +852,14 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
cloneD.ApplyMatrix(MoveMatrix(new Vector3(dist)))
|
|
|
|
|
.ApplyMatrix(this.m_Face.OCS);
|
|
|
|
|
app.Database.ModelSpace.Append(cloneD);
|
|
|
|
|
|
|
|
|
|
//需要知道第几个绘制的木销 但不需要绘制
|
|
|
|
|
if (erase)
|
|
|
|
|
cloneD.Erase();
|
|
|
|
|
|
|
|
|
|
newWoodEnts.push(cloneD.Id);
|
|
|
|
|
}
|
|
|
|
|
woodPinss.push(newWoodEnts);
|
|
|
|
|
//裁剪掉用过的
|
|
|
|
|
if (this._AutoDeviation)
|
|
|
|
|
this.m_Face.Segment1D = Segment1dSubtraction2(this.m_Face.Segment1D, [[dist - minDrillDist, dist + minDrillDist]]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.ParseDrillList(newDrillentList, woodPinss);
|
|
|
|
@ -846,6 +965,29 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
refDrillList.push(...v.filter(ds => ds.length > 0 && ds[0].Object && !ds[0].IsErase));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const MinDrillDist = Math.max(this.m_Option.pxlRad, this.m_Option.ljgRad);
|
|
|
|
|
const dirllHeight = this.m_Option.pxlRad + this.m_Option.ljgLength;
|
|
|
|
|
const intersectBox = new Box3(new Vector3(0, 0, -dirllHeight), new Vector3(this.m_Face.Length, locaBoard.Thickness, intBoard.Thickness));
|
|
|
|
|
|
|
|
|
|
//localDrills放置的位置加入不可释放区间
|
|
|
|
|
if (this._AutoDeviation)
|
|
|
|
|
{
|
|
|
|
|
for (let drillent of refDrillList)
|
|
|
|
|
{
|
|
|
|
|
for (let dirll of drillent)
|
|
|
|
|
{
|
|
|
|
|
let box = (dirll.Object as Entity).GetBoundingBoxInMtx(this.m_Face.OCSInv);
|
|
|
|
|
if (box.intersectsBox(intersectBox))
|
|
|
|
|
{
|
|
|
|
|
let posSegment1D = [box.min.x - MinDrillDist, box.max.x + MinDrillDist] as Segment1d;
|
|
|
|
|
this.m_Face.FixedInterval.push(posSegment1D);
|
|
|
|
|
//计算剩余可放置位置
|
|
|
|
|
this.m_Face.Segment1D = Segment1dSubtraction2(this.m_Face.Segment1D, [posSegment1D]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (refDrillList.length > 0)
|
|
|
|
|
{
|
|
|
|
|
this.ParseThroughHoles(drills, refDrillList, woodPinss);
|
|
|
|
@ -858,6 +1000,25 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
refDrillList.push(...v.filter(ds => ds.length > 0 && ds[0].Object && !ds[0].IsErase));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//intDrills放置的位置加入不可释放区间 这边偷懒直接分析refDrillList
|
|
|
|
|
if (this._AutoDeviation)
|
|
|
|
|
{
|
|
|
|
|
for (let drillent of refDrillList)
|
|
|
|
|
{
|
|
|
|
|
for (let dirll of drillent)
|
|
|
|
|
{
|
|
|
|
|
let box = (dirll.Object as Entity).GetBoundingBoxInMtx(this.m_Face.OCSInv);
|
|
|
|
|
if (box.intersectsBox(intersectBox))
|
|
|
|
|
{
|
|
|
|
|
let posSegment1D = [box.min.x - MinDrillDist, box.max.x + MinDrillDist] as Segment1d;
|
|
|
|
|
this.m_Face.FixedInterval.push(posSegment1D);
|
|
|
|
|
//计算剩余可放置位置
|
|
|
|
|
this.m_Face.Segment1D = Segment1dSubtraction2(this.m_Face.Segment1D, [posSegment1D]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//碰撞检测
|
|
|
|
|
this.CheckCollision(drills, refDrillList, woodPinss);
|
|
|
|
|
|
|
|
|
@ -873,9 +1034,7 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
for (let ds of drills)
|
|
|
|
|
{
|
|
|
|
|
for (let id of ds)
|
|
|
|
|
{
|
|
|
|
|
app.Database.ModelSpace.Remove(id.Object as Hole);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -931,7 +1090,9 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
//需要删除的通孔排钻
|
|
|
|
|
let needRemoveDrillList = new WeakSet();
|
|
|
|
|
|
|
|
|
|
const minDrillDist = Math.max(this.m_Option.pxlRad, this.m_Option.ljgRad) + 2;
|
|
|
|
|
const THoleOffset = this.m_Option.tHoleOffset;
|
|
|
|
|
const TIsOffset = this.m_Option.tIsOffset;
|
|
|
|
|
const MinDrillDist = Math.max(this.m_Option.pxlRad, this.m_Option.ljgRad) + 2;
|
|
|
|
|
|
|
|
|
|
//是否与造型碰撞
|
|
|
|
|
const IsIntersectZX = (moveAfterDrills: CylinderHole[]) =>
|
|
|
|
@ -948,56 +1109,6 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
//检查是否碰撞
|
|
|
|
|
const CheckCollision = (hole: ObjectId<CADObject>[], moveAfterDrills: CylinderHole[], isWoodPinss: boolean) =>
|
|
|
|
|
{
|
|
|
|
|
if (this._AutoDeviation)
|
|
|
|
|
{
|
|
|
|
|
let posX = moveAfterDrills[0].Position.clone().applyMatrix4(this.m_Face.OCSInv).x;
|
|
|
|
|
|
|
|
|
|
let oldSegment1D: Segment1d[] = [];
|
|
|
|
|
for (let [start, end] of this.m_Face.Segment1D)
|
|
|
|
|
oldSegment1D.push([start, end]);
|
|
|
|
|
//对原区间释放排钻的占位 凹槽周围的固定距离不释放
|
|
|
|
|
let newSegment1D = operInterval(
|
|
|
|
|
this.m_Face.Segment1D,
|
|
|
|
|
[[posX - this.m_Option.tHoleOffset - (minDrillDist * 2), posX - this.m_Option.tHoleOffset + (minDrillDist * 2)]],
|
|
|
|
|
this.m_Face.FixedInterval
|
|
|
|
|
);
|
|
|
|
|
newSegment1D.sort((a, b) => { return a[0] - b[0]; });
|
|
|
|
|
|
|
|
|
|
//通孔偏移后是否在有效的区间
|
|
|
|
|
if (!FindInWall(posX, newSegment1D))
|
|
|
|
|
{
|
|
|
|
|
let { closestDist, positive, closestNum } = FindClosestInterval(posX - this.m_Option.tHoleOffset, newSegment1D, 32, this.m_Face.Length);
|
|
|
|
|
// if (closestDist < this._DrillSpaceDist)
|
|
|
|
|
{
|
|
|
|
|
//找到合适的位置偏移
|
|
|
|
|
this.MoveDrillEnts(hole, (positive ? closestDist : -closestDist) - this.m_Option.tHoleOffset);
|
|
|
|
|
//新的放置区间
|
|
|
|
|
let posSegment1D = [closestNum - minDrillDist, closestNum + minDrillDist] as Segment1d;
|
|
|
|
|
//计算剩余可放置位置
|
|
|
|
|
this.m_Face.Segment1D = Segment1dSubtraction2(oldSegment1D, [posSegment1D]);
|
|
|
|
|
//放置的位置加入不可释放区间
|
|
|
|
|
this.m_Face.FixedInterval.push(posSegment1D);
|
|
|
|
|
this._InteractionLog(`有${isWoodPinss ? "木销" : "通孔排钻"}偏移后与造型碰撞,自动偏移`, LogType.Info);
|
|
|
|
|
this._HasAutoDeviation = true;
|
|
|
|
|
}
|
|
|
|
|
// else
|
|
|
|
|
// {
|
|
|
|
|
// //没有找到合适位置
|
|
|
|
|
// this._isDrillTouch = true;
|
|
|
|
|
// this._InteractionLog(`有${isWoodPinss ? "木销" : "通孔排钻"}偏移后与造型或排钻碰撞,未找到合适位置放置,跳过绘制`);
|
|
|
|
|
// needRemoveDrillList.add(hole);
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
let posSegment1D = [posX - minDrillDist, posX + minDrillDist] as Segment1d;
|
|
|
|
|
//计算剩余可放置位置
|
|
|
|
|
this.m_Face.Segment1D = Segment1dSubtraction2(oldSegment1D, [[posX - minDrillDist, posX + minDrillDist]]);
|
|
|
|
|
//放置的位置加入不可释放区间
|
|
|
|
|
this.m_Face.FixedInterval.push(posSegment1D);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//检测偏移后是否与造型碰撞
|
|
|
|
|
if (IsIntersectZX(moveAfterDrills))
|
|
|
|
@ -1021,26 +1132,34 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
let drillent = drills[i];
|
|
|
|
|
let isThought = false;
|
|
|
|
|
let ljgEnts = GetParseEnts(drills[i]);//获取连接杆
|
|
|
|
|
let moveAfterDrills: CylinderHole[] = [];
|
|
|
|
|
|
|
|
|
|
//排钻
|
|
|
|
|
for (let refDrill of refDrillList)
|
|
|
|
|
{
|
|
|
|
|
for (let refDrill of refDrillList)
|
|
|
|
|
if (isThoughtDrillsSet.has(refDrill)) continue;
|
|
|
|
|
|
|
|
|
|
let refEns = GetParseEnts(refDrill);
|
|
|
|
|
//不是通孔逻辑时 通孔改预埋件半径 木销不做通孔偏移操作
|
|
|
|
|
isThought = this.ParseHolesisThrough(ljgEnts, refEns);
|
|
|
|
|
if (isThought)
|
|
|
|
|
{
|
|
|
|
|
if (isThoughtDrillsSet.has(refDrill)) continue;
|
|
|
|
|
isThoughtDrillsSet.add(refDrill);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let refEns = GetParseEnts(refDrill);
|
|
|
|
|
isThought = this.ParseHolesisThrough(ljgEnts, refEns);
|
|
|
|
|
if (isThought)
|
|
|
|
|
{
|
|
|
|
|
isThoughtDrillsSet.add(refDrill);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
//通孔偏移
|
|
|
|
|
if (isThought && TIsOffset && THoleOffset)
|
|
|
|
|
{
|
|
|
|
|
if (this._AutoDeviation)
|
|
|
|
|
{
|
|
|
|
|
this.AutoDeviation(drillent, woodPinss, needRemoveDrillList, THoleOffset, MinDrillDist);
|
|
|
|
|
}
|
|
|
|
|
let tHoleOffset = this.m_Option.tHoleOffset;
|
|
|
|
|
//通孔偏移
|
|
|
|
|
if (isThought && this.m_Option.tIsOffset && tHoleOffset)
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this.MoveDrillEnts(drillent, this.m_Option.tHoleOffset);
|
|
|
|
|
let moveAfterDrills: CylinderHole[] = [];
|
|
|
|
|
|
|
|
|
|
this.MoveDrillEnts(drillent, THoleOffset);
|
|
|
|
|
|
|
|
|
|
//偏移后的通孔排钻或木销
|
|
|
|
|
for (let drill of drillent)
|
|
|
|
@ -1048,85 +1167,39 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
|
|
|
|
|
//检查排钻
|
|
|
|
|
CheckCollision(drillent, moveAfterDrills, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//木销 通孔改预埋件半径时(!this.m_Option.tIsOffset) 木销不做通孔偏移操作
|
|
|
|
|
{
|
|
|
|
|
if (woodPinss.length === 0 || !this.m_Option.tIsOffset) continue;
|
|
|
|
|
let needCheckWoodPinss = [];
|
|
|
|
|
moveAfterDrills = [];
|
|
|
|
|
|
|
|
|
|
if (i === 0)
|
|
|
|
|
needCheckWoodPinss = woodPinss[0];
|
|
|
|
|
else if (i === drills.length - 1 && woodPinss.length === 2)
|
|
|
|
|
needCheckWoodPinss = woodPinss[1];
|
|
|
|
|
//木销
|
|
|
|
|
if (!woodPinss.length) continue;
|
|
|
|
|
let needCheckWoodPinss: ObjectId<CADObject>[] = [];
|
|
|
|
|
moveAfterDrills = [];
|
|
|
|
|
|
|
|
|
|
if (needCheckWoodPinss.length === 0) continue;
|
|
|
|
|
if (i === 0)
|
|
|
|
|
needCheckWoodPinss = woodPinss[0];
|
|
|
|
|
else if (i === drills.length - 1 && woodPinss.length === 2)
|
|
|
|
|
needCheckWoodPinss = woodPinss[1];
|
|
|
|
|
|
|
|
|
|
//获取连接杆
|
|
|
|
|
ljgEnts = GetParseEnts(needCheckWoodPinss);
|
|
|
|
|
if (!needCheckWoodPinss.length) continue;
|
|
|
|
|
|
|
|
|
|
for (let refDrill of refDrillList)
|
|
|
|
|
{
|
|
|
|
|
if (isThoughtDrillsSet.has(refDrill)) continue;
|
|
|
|
|
this.MoveDrillEnts(needCheckWoodPinss, THoleOffset);
|
|
|
|
|
|
|
|
|
|
let refEns = GetParseEnts(refDrill);
|
|
|
|
|
isThought = this.ParseHolesisThrough(ljgEnts, refEns);
|
|
|
|
|
if (isThought)
|
|
|
|
|
{
|
|
|
|
|
isThoughtDrillsSet.add(refDrill);
|
|
|
|
|
this.MoveDrillEnts(needCheckWoodPinss, this.m_Option.tHoleOffset);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (let wp of needCheckWoodPinss)
|
|
|
|
|
moveAfterDrills.push(wp.Object as CylinderHole);
|
|
|
|
|
|
|
|
|
|
for (let wp of needCheckWoodPinss)
|
|
|
|
|
moveAfterDrills.push(wp.Object as CylinderHole);
|
|
|
|
|
if (!needCheckWoodPinss.length) continue;
|
|
|
|
|
|
|
|
|
|
if (needCheckWoodPinss.length === 0 || !isThought) continue;
|
|
|
|
|
|
|
|
|
|
//检查木销
|
|
|
|
|
CheckCollision(needCheckWoodPinss, moveAfterDrills, true);
|
|
|
|
|
//检查木销
|
|
|
|
|
CheckCollision(needCheckWoodPinss, moveAfterDrills, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//移除已经是通孔的参考排钻,避免触发碰撞偏移#I101LC
|
|
|
|
|
arrayRemoveIf(refDrillList, (ds) => isThoughtDrillsSet.has(ds));
|
|
|
|
|
//移除与造型碰撞的通孔排钻
|
|
|
|
|
arrayRemoveIf(drills, (ds) =>
|
|
|
|
|
{
|
|
|
|
|
if (needRemoveDrillList.has(ds))
|
|
|
|
|
{
|
|
|
|
|
for (let d of ds)
|
|
|
|
|
app.Database.ModelSpace.Remove(d.Object as Hole);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else return false;
|
|
|
|
|
});
|
|
|
|
|
//移除与造型碰撞的木销
|
|
|
|
|
arrayRemoveIf(woodPinss, (wps) =>
|
|
|
|
|
{
|
|
|
|
|
if (needRemoveDrillList.has(wps))
|
|
|
|
|
{
|
|
|
|
|
for (let wp of wps)
|
|
|
|
|
app.Database.ModelSpace.Remove(wp.Object as Hole);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else return false;
|
|
|
|
|
});
|
|
|
|
|
//移除与造型碰撞的木梢
|
|
|
|
|
arrayRemoveIf(woodPinss, (wps) =>
|
|
|
|
|
{
|
|
|
|
|
if (needRemoveDrillList.has(wps))
|
|
|
|
|
{
|
|
|
|
|
for (let wp of wps)
|
|
|
|
|
app.Database.ModelSpace.Remove(wp.Object as Hole);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else return false;
|
|
|
|
|
});
|
|
|
|
|
RemoveDrillList(drills, needRemoveDrillList, woodPinss);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//解析孔是通孔
|
|
|
|
|
private ParseHolesisThrough(ents: CylinderHole[] | ExtrudeHole[], refEnts: CylinderHole[] | ExtrudeHole[])
|
|
|
|
|
{
|
|
|
|
@ -1157,8 +1230,8 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
else
|
|
|
|
|
refRadius = refEn.Radius;
|
|
|
|
|
|
|
|
|
|
let p2 = refEn.Position.applyMatrix4(enOcsInv);
|
|
|
|
|
let p2End = refEn.Position.add(refEn.Normal.multiplyScalar(refEn.Height)).applyMatrix4(enOcsInv);
|
|
|
|
|
let p2 = refEn.Position.clone().applyMatrix4(enOcsInv);
|
|
|
|
|
let p2End = refEn.Position.clone().add(refEn.Normal.multiplyScalar(refEn.Height)).applyMatrix4(enOcsInv);
|
|
|
|
|
|
|
|
|
|
if (equaln(radius, refRadius, 1e-2)
|
|
|
|
|
&& isParallelTo(p2, ZAxis, 0.01)
|
|
|
|
@ -1248,34 +1321,57 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
CheckCollision(drills: ObjectId[][], refDrillList: ObjectId[][], woodPinss: ObjectId[][])
|
|
|
|
|
{
|
|
|
|
|
let isCollsion = false;
|
|
|
|
|
|
|
|
|
|
let faceOcsInv = this.m_Face.OCSInv;
|
|
|
|
|
const MinDrillDist = Math.max(this.m_Option.pxlRad, this.m_Option.ljgRad) + 2;
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < drills.length; i++)
|
|
|
|
|
{
|
|
|
|
|
const ds = drills[i];
|
|
|
|
|
if (this.IsTk(ds)) continue;
|
|
|
|
|
if (this.IsTk(ds) && !this._AutoDeviation) continue;
|
|
|
|
|
let bs1 = this.GetDrillsBox(ds, faceOcsInv);
|
|
|
|
|
for (let refDr of refDrillList)
|
|
|
|
|
|
|
|
|
|
let checkWoodPinss: ObjectId<CADObject>[];
|
|
|
|
|
if (woodPinss.length)
|
|
|
|
|
{
|
|
|
|
|
if (this.IsTk(refDr)) continue;
|
|
|
|
|
let bs2 = this.GetDrillsBox(refDr, faceOcsInv);
|
|
|
|
|
//#I1FFNB
|
|
|
|
|
if (bs1.some(b => bs2.some(b2 => this.DrillIsCollsion(b, b2))))
|
|
|
|
|
for (let wood of woodPinss)
|
|
|
|
|
{
|
|
|
|
|
let offsetDist = this.m_Option.collsionDist;
|
|
|
|
|
this.MoveDrillEnts(ds, offsetDist, bs1);
|
|
|
|
|
if (!wood[0].IsErase)
|
|
|
|
|
for (let box of this.GetDrillsBox(wood, faceOcsInv))
|
|
|
|
|
bs1.push(box);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//是否仍存在碰撞
|
|
|
|
|
isCollsion = bs1.some(b => bs2.some(b2 => this.DrillIsCollsion(b, b2)));
|
|
|
|
|
for (let refDr of refDrillList)
|
|
|
|
|
{
|
|
|
|
|
if (this._AutoDeviation)
|
|
|
|
|
{
|
|
|
|
|
let bs2 = this.GetDrillsBox(refDr, faceOcsInv);
|
|
|
|
|
|
|
|
|
|
if (woodPinss.length === 0) continue;
|
|
|
|
|
if (i === 0)
|
|
|
|
|
//#I1FFNB
|
|
|
|
|
if (bs1.some(b => bs2.some(b2 => this.DrillIsCollsion(b, b2))))
|
|
|
|
|
{
|
|
|
|
|
this.MoveDrillEnts(woodPinss[0], offsetDist);
|
|
|
|
|
//需要删除的通孔排钻
|
|
|
|
|
let needRemoveDrillList = new WeakSet();
|
|
|
|
|
this.AutoDeviation(ds, woodPinss, needRemoveDrillList, this.m_Option.spacing === SpacingType.Multiple32 ? 32 : 16, MinDrillDist);
|
|
|
|
|
RemoveDrillList(drills, needRemoveDrillList, woodPinss);
|
|
|
|
|
}
|
|
|
|
|
else if (i === drills.length - 1 && woodPinss.length === 2)
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (this.IsTk(refDr)) continue;
|
|
|
|
|
|
|
|
|
|
let bs2 = this.GetDrillsBox(refDr, faceOcsInv);
|
|
|
|
|
//#I1FFNB
|
|
|
|
|
if (bs1.some(b => bs2.some(b2 => this.DrillIsCollsion(b, b2))))
|
|
|
|
|
{
|
|
|
|
|
this.MoveDrillEnts(woodPinss[1], offsetDist);
|
|
|
|
|
let offsetDist = this.m_Option.collsionDist;
|
|
|
|
|
this.MoveDrillEnts(ds, offsetDist, bs1);
|
|
|
|
|
|
|
|
|
|
//是否仍存在碰撞
|
|
|
|
|
isCollsion = bs1.some(b => bs2.some(b2 => this.DrillIsCollsion(b, b2)));
|
|
|
|
|
|
|
|
|
|
if (checkWoodPinss?.length)
|
|
|
|
|
this.MoveDrillEnts(checkWoodPinss, offsetDist);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1437,7 +1533,8 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this._AutoDeviation = false;//!this.m_Option.haveDist && !this.m_Option.useTemp && this.m_Option.autoDeviation;
|
|
|
|
|
//适用于距离大于200
|
|
|
|
|
this._AutoDeviation = !this.m_Option.haveDist && !this.m_Option.useTemp && HostApplicationServices.autoDeviation && this.m_Face.Length > 200;
|
|
|
|
|
|
|
|
|
|
//智能偏移获取可以放置排钻的区间
|
|
|
|
|
if (this._AutoDeviation)
|
|
|
|
@ -1650,7 +1747,6 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
this.CheckDrillList(result);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1677,4 +1773,211 @@ export class DrawDrillingTool extends Singleton
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private AutoDeviation(drillent: ObjectId<CADObject>[], woodPinss: ObjectId<CADObject>[][], needRemoveDrillList: WeakSet<WeakKey>, tHoleOffset: number, minDrillSegment: number)
|
|
|
|
|
{
|
|
|
|
|
const posX = (drillent[0].Object as CylinderHole).Position.clone().applyMatrix4(this.m_Face.OCSInv).x;
|
|
|
|
|
const index = this.m_MoveDistList.findIndex((d) => equaln(posX, d));
|
|
|
|
|
|
|
|
|
|
if (index === -1) return;
|
|
|
|
|
|
|
|
|
|
//第一个 最后一个排钻
|
|
|
|
|
const IsStarDrill = index === 0;
|
|
|
|
|
const IsEndDrill = index === this.m_MoveDistList.length - 1;
|
|
|
|
|
|
|
|
|
|
let offsetDist = 32;
|
|
|
|
|
if (IsStarDrill || IsEndDrill)
|
|
|
|
|
{
|
|
|
|
|
if (this.m_Option.isFromBack)
|
|
|
|
|
offsetDist = index === 0 ? -32 : 32;
|
|
|
|
|
else
|
|
|
|
|
offsetDist = index === 0 ? 32 : -32;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let oldSegment1D: Segment1d[] = [];
|
|
|
|
|
for (let [start, end] of this.m_Face.Segment1D)
|
|
|
|
|
oldSegment1D.push([start, end]);
|
|
|
|
|
|
|
|
|
|
let drillDist = tHoleOffset;
|
|
|
|
|
let wpDist = 0;
|
|
|
|
|
|
|
|
|
|
let needCheckWoodPinss: ObjectId<CADObject>[] = [];
|
|
|
|
|
if (index === 0)
|
|
|
|
|
needCheckWoodPinss = woodPinss[0];
|
|
|
|
|
else if (index === this.m_MoveDistList.length - 1 && woodPinss.length === 2)
|
|
|
|
|
needCheckWoodPinss = woodPinss[1];
|
|
|
|
|
|
|
|
|
|
if (needCheckWoodPinss?.length && !needCheckWoodPinss[0].IsErase)
|
|
|
|
|
wpDist = drillDist;
|
|
|
|
|
|
|
|
|
|
let newSegment1D = this.m_Face.Segment1D;
|
|
|
|
|
if (wpDist)
|
|
|
|
|
{
|
|
|
|
|
let selfSegment1d: Segment1d = [Math.min(posX, posX + offsetDist) - minDrillSegment, Math.max(posX, posX + offsetDist) + minDrillSegment];
|
|
|
|
|
newSegment1D = OperInterval(this.m_Face.Segment1D, [selfSegment1d], this.m_Face.FixedInterval);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//通孔偏移后没有在有效的区间
|
|
|
|
|
if (!FindInWall(posX + drillDist, newSegment1D) || (wpDist && !FindInWall(posX + drillDist + offsetDist, newSegment1D)))
|
|
|
|
|
{
|
|
|
|
|
//往反方向偏移(32 - drillDist)
|
|
|
|
|
if (FindInWall(posX - (32 - drillDist), newSegment1D) && (!wpDist || FindInWall(posX - (32 - drillDist) + offsetDist, newSegment1D)))
|
|
|
|
|
{
|
|
|
|
|
drillDist = drillDist - 32;
|
|
|
|
|
wpDist = drillDist;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
let { closestDist, positive, closestNum } = FindClosestInterval(posX, newSegment1D, this.m_Face.Length, this._MoveMinDist, offsetDist, tHoleOffset);
|
|
|
|
|
|
|
|
|
|
//偏移超出邻边两侧排钻距离
|
|
|
|
|
let leftIndex = this.m_Option.isFromBack ? (index + 1) : (index - 1);
|
|
|
|
|
let rightIndex = this.m_Option.isFromBack ? (index - 1) : (index + 1);
|
|
|
|
|
let neighborLeftDist = this.m_MoveDistList[leftIndex] ?? -Infinity;
|
|
|
|
|
let neighborRightDist = this.m_MoveDistList[rightIndex] ?? Infinity;
|
|
|
|
|
|
|
|
|
|
//判断邻边是否有木销
|
|
|
|
|
{
|
|
|
|
|
if (this.m_Option.isDrawWood && this.m_Option.isFromBack ? (leftIndex === this.m_MoveDistList.length - 1) : leftIndex === 0)
|
|
|
|
|
neighborLeftDist += 32;
|
|
|
|
|
|
|
|
|
|
neighborLeftDist += (this.m_Option.tHoleOffset + 2 * minDrillSegment);
|
|
|
|
|
|
|
|
|
|
if (this.m_Option.isDrawWood && this.m_Option.isFromBack ? (rightIndex === 0) : (rightIndex === this.m_MoveDistList.length - 1))
|
|
|
|
|
neighborRightDist -= 32;
|
|
|
|
|
|
|
|
|
|
neighborRightDist -= (2 * minDrillSegment - this.m_Option.tHoleOffset);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
!(closestNum && (neighborLeftDist < closestNum && closestNum < neighborRightDist)) ||
|
|
|
|
|
((offsetDist && this.m_Option.isDrawWood) && !(neighborLeftDist < (closestNum + offsetDist) && (closestNum + offsetDist) < neighborRightDist))
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
wpDist = 0;
|
|
|
|
|
if (!FindInWall(posX + drillDist, newSegment1D))
|
|
|
|
|
{
|
|
|
|
|
//没有与木销合适的位置 那只管自己 不管木销
|
|
|
|
|
let { closestDist, positive } = FindClosestInterval(posX, newSegment1D, this.m_Face.Length, this._MoveMinDist, null, tHoleOffset);
|
|
|
|
|
|
|
|
|
|
if (closestNum)
|
|
|
|
|
{
|
|
|
|
|
drillDist = closestDist * positive;
|
|
|
|
|
this._HasAutoDeviation = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//自身难保 跳过绘制
|
|
|
|
|
drillDist = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
drillDist = closestDist * positive;
|
|
|
|
|
wpDist = drillDist;
|
|
|
|
|
this._HasAutoDeviation = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (drillDist)
|
|
|
|
|
{
|
|
|
|
|
//找到合适的位置偏移
|
|
|
|
|
this.MoveDrillEnts(drillent, drillDist);
|
|
|
|
|
//旧的放置区间
|
|
|
|
|
let posOldSegment1D = [posX - minDrillSegment, posX + minDrillSegment] as Segment1d;
|
|
|
|
|
//新的放置区间
|
|
|
|
|
let posSegment1D = [posX + drillDist - minDrillSegment, posX + drillDist + minDrillSegment] as Segment1d;
|
|
|
|
|
//计算剩余可放置位置
|
|
|
|
|
this.m_Face.Segment1D = Segment1dSubtraction2(oldSegment1D, [posOldSegment1D, posSegment1D]);
|
|
|
|
|
// //放置的位置加入不可释放区间
|
|
|
|
|
// this.m_Face.FixedInterval.push(posSegment1D);
|
|
|
|
|
this._InteractionLog("有通孔排钻偏移后未放置合适位置,自动偏移", LogType.Info);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
needRemoveDrillList.add(drillent);
|
|
|
|
|
InteractionLog([
|
|
|
|
|
{ msg: `板件${this.m_Face.LocalBoard.Name}`, entity: [this.m_Face.LocalBoard] },
|
|
|
|
|
{ msg: "-" },
|
|
|
|
|
{ msg: `板件${this.m_Face.InterBoard.Name}`, entity: [this.m_Face.InterBoard] },
|
|
|
|
|
{ msg: "有通孔排钻偏移后没有合适的偏移位置,跳过绘制" }
|
|
|
|
|
], LogType.Warning);
|
|
|
|
|
|
|
|
|
|
//旧的放置区间
|
|
|
|
|
let posOldSegment1D = [posX + drillDist - minDrillSegment, posX + drillDist + minDrillSegment] as Segment1d;
|
|
|
|
|
//计算剩余可放置位置
|
|
|
|
|
this.m_Face.Segment1D = Segment1dSubtraction2(oldSegment1D, [posOldSegment1D]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (needCheckWoodPinss?.length && !needCheckWoodPinss[0].IsErase)
|
|
|
|
|
{
|
|
|
|
|
if (wpDist)
|
|
|
|
|
{
|
|
|
|
|
this.MoveDrillEnts(needCheckWoodPinss, wpDist);
|
|
|
|
|
const oldX = posX + offsetDist;
|
|
|
|
|
const newX = posX + wpDist + offsetDist;
|
|
|
|
|
//旧的放置区间
|
|
|
|
|
let posOldSegment1D = [oldX - minDrillSegment, oldX + minDrillSegment] as Segment1d;
|
|
|
|
|
//新的放置区间
|
|
|
|
|
let posSegment1D = [newX - minDrillSegment, newX + minDrillSegment] as Segment1d;
|
|
|
|
|
//计算剩余可放置位置
|
|
|
|
|
this.m_Face.Segment1D = Segment1dSubtraction2(this.m_Face.Segment1D, [posOldSegment1D, posSegment1D]);
|
|
|
|
|
// //放置的位置加入不可释放区间
|
|
|
|
|
// this.m_Face.FixedInterval.push(posSegment1D);
|
|
|
|
|
}
|
|
|
|
|
//删除木销
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
needRemoveDrillList.add(needCheckWoodPinss);
|
|
|
|
|
InteractionLog([
|
|
|
|
|
{ msg: `板件${this.m_Face.LocalBoard.Name}`, entity: [this.m_Face.LocalBoard] },
|
|
|
|
|
{ msg: "-" },
|
|
|
|
|
{ msg: `板件${this.m_Face.InterBoard.Name}`, entity: [this.m_Face.InterBoard] },
|
|
|
|
|
{ msg: "有通孔木销偏移后没有合适的偏移位置,跳过绘制" }
|
|
|
|
|
], LogType.Warning);
|
|
|
|
|
//旧的放置区间
|
|
|
|
|
let posOldSegment1D = [posX + drillDist - minDrillSegment, posX + drillDist + minDrillSegment] as Segment1d;
|
|
|
|
|
//计算剩余可放置位置
|
|
|
|
|
this.m_Face.Segment1D = Segment1dSubtraction2(this.m_Face.Segment1D, [posOldSegment1D]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function RemoveDrillList(drills: ObjectId<CADObject>[][], needRemoveDrillList: WeakSet<WeakKey>, woodPinss: ObjectId<CADObject>[][])
|
|
|
|
|
{
|
|
|
|
|
arrayRemoveIf(drills, (ds) =>
|
|
|
|
|
{
|
|
|
|
|
if (needRemoveDrillList.has(ds))
|
|
|
|
|
{
|
|
|
|
|
for (let d of ds)
|
|
|
|
|
app.Database.ModelSpace.Remove(d.Object as Hole);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else return false;
|
|
|
|
|
});
|
|
|
|
|
//移除与造型碰撞的木销
|
|
|
|
|
arrayRemoveIf(woodPinss, (wps) =>
|
|
|
|
|
{
|
|
|
|
|
if (needRemoveDrillList.has(wps))
|
|
|
|
|
{
|
|
|
|
|
for (let wp of wps)
|
|
|
|
|
app.Database.ModelSpace.Remove(wp.Object as Hole);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else return false;
|
|
|
|
|
});
|
|
|
|
|
//移除与造型碰撞的木梢
|
|
|
|
|
arrayRemoveIf(woodPinss, (wps) =>
|
|
|
|
|
{
|
|
|
|
|
if (needRemoveDrillList.has(wps))
|
|
|
|
|
{
|
|
|
|
|
for (let wp of wps)
|
|
|
|
|
app.Database.ModelSpace.Remove(wp.Object as Hole);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else return false;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|