|
|
|
@ -8,7 +8,7 @@ import { Contour } from "../DatabaseServices/Contour";
|
|
|
|
|
import { Curve } from "../DatabaseServices/Curve";
|
|
|
|
|
import { Line } from "../DatabaseServices/Line";
|
|
|
|
|
import { Polyline } from '../DatabaseServices/Polyline';
|
|
|
|
|
import { equal, equaln } from "../Geometry/GeUtils";
|
|
|
|
|
import { equal, equaln, midPoint } from "../Geometry/GeUtils";
|
|
|
|
|
import { isTargetCurInSourceCur, isTargetCurOutOrOnSourceCur } from "./BoolOperateUtils";
|
|
|
|
|
import { IntersectOption } from "./IntersectWith";
|
|
|
|
|
import { app } from "../ApplicationServices/Application";
|
|
|
|
@ -40,17 +40,17 @@ export class PolyOffestUtil
|
|
|
|
|
let contours: Contour[] = [];
|
|
|
|
|
for (let i = 0; i < plList1.length; i++)
|
|
|
|
|
{
|
|
|
|
|
let con = this.buildContourByTwoSideOfest(plList1[i].curve, plList2[i].curve);
|
|
|
|
|
let con = this.buildContourByTwoSideOfest(plList1[i].curve, plList2[i].curve, i);
|
|
|
|
|
con && contours.push(con);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// contours.forEach(c =>
|
|
|
|
|
// {
|
|
|
|
|
// c.Outline.ColorIndex = 2;
|
|
|
|
|
// app.m_Database.ModelSpace.Append(c.Outline);
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
|
|
let newPls = this.trimAndJointOffestPolyline(plList1, this.m_Polyline);
|
|
|
|
|
|
|
|
|
|
let newPls = this.trimAndJointOffestPolyline1(plList1, this.m_Polyline);
|
|
|
|
|
let cus = this.trimByContours(newPls, contours);
|
|
|
|
|
if (this.m_Polyline.IsClose && this.m_OffDir < 0)
|
|
|
|
|
{
|
|
|
|
@ -79,7 +79,7 @@ export class PolyOffestUtil
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
//通过2侧偏移曲线构建封闭轮廓,由于是双向偏移,所以不可能出现2个曲线都为空的情况
|
|
|
|
|
private buildContourByTwoSideOfest(pl1: Curve, pl2: Curve)
|
|
|
|
|
private buildContourByTwoSideOfest(pl1: Curve, pl2: Curve, index: number)
|
|
|
|
|
{
|
|
|
|
|
if (pl1 && pl2)
|
|
|
|
|
{
|
|
|
|
@ -93,7 +93,25 @@ export class PolyOffestUtil
|
|
|
|
|
let arc = pl1 ? pl1.Clone() as Arc : pl2.Clone() as Arc;
|
|
|
|
|
let l1 = new Line(arc.Center, arc.StartPoint);
|
|
|
|
|
let l2 = new Line(arc.Center, arc.EndPoint);
|
|
|
|
|
return Contour.CreateContour([arc, l1, l2]);
|
|
|
|
|
let con = Contour.CreateContour([arc, l1, l2]);
|
|
|
|
|
if (!this.m_Polyline.IsClose)
|
|
|
|
|
{
|
|
|
|
|
//加入首尾原点源进行合并轮廓
|
|
|
|
|
let offDist = Math.abs(this.m_OffestDist);
|
|
|
|
|
let cir: Contour;
|
|
|
|
|
if (index === 0)
|
|
|
|
|
{
|
|
|
|
|
cir = Contour.CreateContour([new Circle(this.m_Polyline.StartPoint, Math.abs(this.m_OffestDist))]);
|
|
|
|
|
} else if (index === this.m_Polyline.EndParam - 1)
|
|
|
|
|
{
|
|
|
|
|
cir = Contour.CreateContour([new Circle(this.m_Polyline.EndPoint, Math.abs(this.m_OffestDist))]);
|
|
|
|
|
} else
|
|
|
|
|
{
|
|
|
|
|
return con;
|
|
|
|
|
}
|
|
|
|
|
return con.UnionBoolOperation(cir)[0]
|
|
|
|
|
}
|
|
|
|
|
else return con;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -102,7 +120,73 @@ export class PolyOffestUtil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 修剪连接相邻曲线
|
|
|
|
|
private trimAndJointOffestPolyline(offResList: offestRes[], originLine: Polyline)
|
|
|
|
|
// private trimAndJointOffestPolyline(offResList: offestRes[], originLine: Polyline)
|
|
|
|
|
// {
|
|
|
|
|
// offResList = offResList.filter(r => r.curve);
|
|
|
|
|
// if (offResList.length <= 1)
|
|
|
|
|
// return offResList.map(r => r.curve);
|
|
|
|
|
|
|
|
|
|
// let retPlList: Array<Curve> = [];
|
|
|
|
|
|
|
|
|
|
// let nextPt: Vector3 = offResList[0].curve.StartPoint;
|
|
|
|
|
|
|
|
|
|
// for (let i = 0; i < offResList.length; i++)
|
|
|
|
|
// {
|
|
|
|
|
// //前面线
|
|
|
|
|
// let frontLine = offResList[i].curve;
|
|
|
|
|
|
|
|
|
|
// //后面线
|
|
|
|
|
// let laterLine: Curve;
|
|
|
|
|
// //如果是闭合的,继续循环,否则直接添加到新数组列表
|
|
|
|
|
// if (i === offResList.length - 1)
|
|
|
|
|
// {
|
|
|
|
|
// if (retPlList.length === 0)
|
|
|
|
|
// break;
|
|
|
|
|
|
|
|
|
|
// if (this.m_Polyline.IsClose)
|
|
|
|
|
// laterLine = retPlList[0];
|
|
|
|
|
// else
|
|
|
|
|
// {
|
|
|
|
|
// this.appendNewPllist(frontLine, nextPt, frontLine.EndPoint, retPlList);
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// laterLine = offResList[i + 1].curve;
|
|
|
|
|
|
|
|
|
|
// //默认交点
|
|
|
|
|
// let interPt = frontLine.EndPoint;
|
|
|
|
|
// // 如果两线结合点不相等,调整交点位置
|
|
|
|
|
// if (!equal(frontLine.EndPoint, laterLine.StartPoint))
|
|
|
|
|
// {
|
|
|
|
|
// // 多段线交点数组
|
|
|
|
|
// let interPts = frontLine.IntersectWith(laterLine, IntersectOption.ExtendBoth);
|
|
|
|
|
|
|
|
|
|
// //如果没有交点,则用圆弧连接
|
|
|
|
|
// if (interPts.length === 0)
|
|
|
|
|
// {
|
|
|
|
|
// //偏移线段对应的源线段,取其起始点作为圆心
|
|
|
|
|
// let srcOffestRes = offResList[FixIndex(i + 1, offResList)];
|
|
|
|
|
// this.fillArc(offResList[i].index, srcOffestRes.index, nextPt, frontLine, laterLine, retPlList);
|
|
|
|
|
// continue;
|
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// {
|
|
|
|
|
// let pts = interPts.filter(p => frontLine.PtOnCurve(p) && laterLine.PtOnCurve(p));
|
|
|
|
|
// interPt = this.selectFitInterPt(pts.length > 0 ? pts : interPts, frontLine.EndPoint);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// this.appendNewPllist(frontLine, nextPt, interPt, retPlList, laterLine);
|
|
|
|
|
|
|
|
|
|
// if (i === offResList.length - 1)//曲线闭合时,修改第一条线的起点
|
|
|
|
|
// {
|
|
|
|
|
// laterLine.StartPoint = nextPt;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// return retPlList;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
private trimAndJointOffestPolyline1(offResList: offestRes[], originLine: Polyline)
|
|
|
|
|
{
|
|
|
|
|
offResList = offResList.filter(r => r.curve);
|
|
|
|
|
if (offResList.length <= 1)
|
|
|
|
@ -129,7 +213,7 @@ export class PolyOffestUtil
|
|
|
|
|
laterLine = retPlList[0];
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this.appendNewPllist(frontLine, nextPt, frontLine.EndPoint, retPlList);
|
|
|
|
|
this.appendNewPllist1(frontLine, nextPt, frontLine.EndPoint, retPlList);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -155,10 +239,20 @@ export class PolyOffestUtil
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
let pts = interPts.filter(p => frontLine.PtOnCurve(p) && laterLine.PtOnCurve(p));
|
|
|
|
|
interPt = this.selectFitInterPt(pts.length > 0 ? pts : interPts, frontLine.EndPoint);
|
|
|
|
|
if (pts.length > 0)
|
|
|
|
|
{
|
|
|
|
|
interPt = this.selectFitInterPt(pts, frontLine.EndPoint);
|
|
|
|
|
this.appendNewPllist1(frontLine, nextPt, interPt, retPlList);
|
|
|
|
|
} else
|
|
|
|
|
{
|
|
|
|
|
interPt = this.selectFitInterPt(interPts, frontLine.EndPoint);
|
|
|
|
|
this.checkCuAndAppendList(frontLine, laterLine, interPt, nextPt, retPlList, offResList[FixIndex(i + 1, offResList)].index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.appendNewPllist(frontLine, nextPt, interPt, retPlList, laterLine);
|
|
|
|
|
else
|
|
|
|
|
this.appendNewPllist1(frontLine, nextPt, frontLine.EndPoint, retPlList);
|
|
|
|
|
|
|
|
|
|
if (i === offResList.length - 1)//曲线闭合时,修改第一条线的起点
|
|
|
|
|
{
|
|
|
|
@ -169,31 +263,46 @@ export class PolyOffestUtil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//将线段拷贝并修改,加入到结果数组里面.
|
|
|
|
|
appendNewPllist(frontLine: Curve, nextPt: Vector3, interPt: Vector3, newPlList: Curve[], laterLine?: Curve, )
|
|
|
|
|
// appendNewPllist(frontLine: Curve, nextPt: Vector3, interPt: Vector3, newPlList: Curve[], laterLine?: Curve)
|
|
|
|
|
// {
|
|
|
|
|
// let newCu = frontLine.Clone() as Curve;
|
|
|
|
|
|
|
|
|
|
// newCu.StartPoint = nextPt;
|
|
|
|
|
// newCu.EndPoint = interPt;
|
|
|
|
|
|
|
|
|
|
// if (this.isVail(frontLine, newCu))
|
|
|
|
|
// {
|
|
|
|
|
// nextPt.copy(interPt);
|
|
|
|
|
// newPlList.push(newCu);
|
|
|
|
|
// }
|
|
|
|
|
// else if (laterLine)
|
|
|
|
|
// {
|
|
|
|
|
// // if (newPlList.length > 0 && laterLine)
|
|
|
|
|
// // {
|
|
|
|
|
// // //曲线校验补通过,尝试和前一条线段求交点.
|
|
|
|
|
// // let lastCu = arrayLast(newPlList);
|
|
|
|
|
// // let pts = lastCu.IntersectWith(laterLine, IntersectOption.ExtendBoth);
|
|
|
|
|
// // if (pts.length > 0)
|
|
|
|
|
// // {
|
|
|
|
|
// // let intPt = this.selectFitInterPt(pts, lastCu.EndPoint);
|
|
|
|
|
// // lastCu.EndPoint = intPt;
|
|
|
|
|
// // nextPt.copy(intPt)
|
|
|
|
|
// // }
|
|
|
|
|
// // }
|
|
|
|
|
// newCu.EndPoint = frontLine.EndPoint;
|
|
|
|
|
// newPlList.push(newCu);
|
|
|
|
|
// newPlList.push(new Line(frontLine.EndPoint, laterLine.StartPoint));
|
|
|
|
|
// nextPt.copy(laterLine.StartPoint);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
appendNewPllist1(frontLine: Curve, nextPt: Vector3, interPt: Vector3, newPlList: Curve[], laterLine?: Curve)
|
|
|
|
|
{
|
|
|
|
|
let newCu = frontLine.Clone() as Curve;
|
|
|
|
|
|
|
|
|
|
newCu.StartPoint = nextPt;
|
|
|
|
|
newCu.EndPoint = interPt;
|
|
|
|
|
|
|
|
|
|
nextPt.copy(interPt);
|
|
|
|
|
|
|
|
|
|
if (this.isVail(frontLine, newCu))
|
|
|
|
|
{
|
|
|
|
|
newPlList.push(newCu);
|
|
|
|
|
}
|
|
|
|
|
else if (newPlList.length > 0 && laterLine)
|
|
|
|
|
{
|
|
|
|
|
//曲线校验补通过,尝试和前一条线段求交点.
|
|
|
|
|
let lastCu = arrayLast(newPlList);
|
|
|
|
|
let pts = lastCu.IntersectWith(laterLine, IntersectOption.ExtendBoth);
|
|
|
|
|
if (pts.length > 0)
|
|
|
|
|
{
|
|
|
|
|
let intPt = this.selectFitInterPt(pts, lastCu.EndPoint);
|
|
|
|
|
lastCu.EndPoint = intPt;
|
|
|
|
|
nextPt.copy(intPt)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
newPlList.push(newCu);
|
|
|
|
|
}
|
|
|
|
|
isVail(oldCu: Curve, newCu: Curve): boolean
|
|
|
|
|
{
|
|
|
|
@ -203,7 +312,55 @@ export class PolyOffestUtil
|
|
|
|
|
} else
|
|
|
|
|
return oldCu.IsClockWise === newCu.IsClockWise
|
|
|
|
|
}
|
|
|
|
|
checkCuAndAppendList(frontLine, laterLine, intPt, nextPt, newPlList, endIndex)
|
|
|
|
|
{
|
|
|
|
|
let par1 = frontLine.GetParamAtPoint(intPt);
|
|
|
|
|
|
|
|
|
|
if (frontLine instanceof Line)
|
|
|
|
|
{
|
|
|
|
|
if (par1 > 1)
|
|
|
|
|
{
|
|
|
|
|
this.appendNewPllist1(frontLine, nextPt, intPt, newPlList);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this.appendNewPllist1(frontLine, nextPt, frontLine.EndPoint, newPlList);
|
|
|
|
|
newPlList.push(new Line(frontLine.EndPoint, laterLine.StartPoint));
|
|
|
|
|
nextPt.copy(laterLine.StartPoint);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (frontLine instanceof Arc && laterLine instanceof Line)
|
|
|
|
|
{
|
|
|
|
|
let par2 = laterLine.GetParamAtPoint(intPt);
|
|
|
|
|
if (par1 > 1)
|
|
|
|
|
{
|
|
|
|
|
this.appendNewPllist1(frontLine, nextPt, intPt, newPlList);
|
|
|
|
|
}
|
|
|
|
|
else if (par1 < 0 && par2 < 0)
|
|
|
|
|
{
|
|
|
|
|
this.fillArc(endIndex - 1, endIndex, nextPt, frontLine, laterLine, newPlList);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this.appendNewPllist1(frontLine, nextPt, frontLine.EndPoint, newPlList);
|
|
|
|
|
newPlList.push(new Line(frontLine.EndPoint, laterLine.StartPoint));
|
|
|
|
|
nextPt.copy(laterLine.StartPoint);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
let isOnFline = frontLine.PtOnCurve(intPt);
|
|
|
|
|
let isOnLline = laterLine.PtOnCurve(intPt);
|
|
|
|
|
if ((!isOnFline && !isOnLline))
|
|
|
|
|
{
|
|
|
|
|
this.appendNewPllist1(frontLine, nextPt, intPt, newPlList);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this.fillArc(endIndex - 1, endIndex, nextPt, frontLine, laterLine, newPlList);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 补圆弧
|
|
|
|
|
*
|
|
|
|
@ -269,7 +426,7 @@ export class PolyOffestUtil
|
|
|
|
|
let pts = frontLine.IntersectWith(cirs[0], IntersectOption.OnBothOperands);
|
|
|
|
|
let inPt = this.selectFitInterPt(pts, frontLine.EndPoint);
|
|
|
|
|
|
|
|
|
|
this.appendNewPllist(frontLine, nextPt, inPt, retPlList);
|
|
|
|
|
this.appendNewPllist1(frontLine, nextPt, inPt, retPlList);
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < cirs.length - 1; i++)
|
|
|
|
|
{
|
|
|
|
@ -293,7 +450,7 @@ export class PolyOffestUtil
|
|
|
|
|
let tangent = laterLine.GetFistDeriv(0).negate().normalize();
|
|
|
|
|
let circleAngle = -getCirAngleByChordAndTangent(chord, tangent);
|
|
|
|
|
|
|
|
|
|
this.appendNewPllist(frontLine, nextPt, intPt, retPlList, laterLine);
|
|
|
|
|
this.appendNewPllist1(frontLine, nextPt, intPt, retPlList, laterLine);
|
|
|
|
|
|
|
|
|
|
nextPt.copy(laterLine.StartPoint);
|
|
|
|
|
|
|
|
|
@ -322,8 +479,8 @@ export class PolyOffestUtil
|
|
|
|
|
if (pts.length > 0)
|
|
|
|
|
{
|
|
|
|
|
let par = pts.map(p => l.GetParamAtPoint(p));
|
|
|
|
|
let cus = l.GetSplitCurves(par);
|
|
|
|
|
tmpCus.push(...cus.filter(cu => !isTargetCurInSourceCur(outline, cu)));
|
|
|
|
|
let cus = l.GetSplitCurves(par).filter(cu => !isTargetCurInSourceCur(outline, cu));
|
|
|
|
|
tmpCus.push(...cus);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|