Files
envi-code/SourceCode/Code2026/PIDLineCmd/KTGeUtility.cpp
T
2026-09-28 15:28:50 +08:00

1000 lines
23 KiB
C++

#include "stdafx.h"
#include "KTGeUtility.h"
#include "KTTempTol.h"
#include <vector>
#include <algorithm>
#include "EarThwormDef.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define MIN_DN 5.0
KTGeUtility::KTGeUtility()
{
}
KTGeUtility::~KTGeUtility()
{
}
AcGePoint3d KTGeUtility::Mid(const AcGePoint3d& ptGe1,const AcGePoint3d& ptGe2)
{
return AcGePoint3d( (ptGe1.x + ptGe2.x) / 2.0,
(ptGe1.y + ptGe2.y) / 2.0,
(ptGe1.z + ptGe2.z) / 2.0);
}
AcGePoint3d KTGeUtility::Mid(AcDbCurve* pCurve)
{
ASSERT(pCurve != NULL);
AcGePoint3d ptGeMid;
KTTempTol tol(1.e-6);
double dSta = 0.0,dEnd = 0.0;
pCurve->getStartParam(dSta);
pCurve->getEndParam(dEnd);
pCurve->getPointAtParam((dSta + dEnd) / 2.0,ptGeMid);
return ptGeMid;
}
AcGePoint2d KTGeUtility::ucsToDcs(const AcGePoint3d& pt)
{
resbuf fromRb, toRb;
ads_point newPt;
fromRb.restype = RTSHORT;
fromRb.resval.rint = AcDb::kUserCS;
toRb.restype = RTSHORT;
toRb.resval.rint = AcDb::kCurDisplayCS;
short result = acedTrans(asDblArray(pt), &fromRb, &toRb, FALSE, newPt);
ASSERT(result == RTNORM);
return asPnt2d(newPt);
}
BOOL KTGeUtility::ToPlaneInWcs2D(AcGePoint3d& ptGe,const AcGePlane& plane)
{
AcGePoint3d ptGeT,ptB = ptGe;
AcGeVector3d vtNorm = plane.normal();
if (vtNorm.isParallelTo(AcGeVector3d::kXAxis)) //YZ 面
{
ptGeT.x = ptGe.z;
ptGeT.y = ptGe.y;
ptGeT.z = 0.0;
ptGe = ptGeT;
if (!vtNorm.isCodirectionalTo(AcGeVector3d::kXAxis))
{
AcGeMatrix3d xform;
xform.setToMirroring(AcGeLine3d::kYAxis);
ptGe.transformBy(xform);
}
}
else if (vtNorm.isParallelTo(AcGeVector3d::kYAxis))//XZ 面
{
ptGeT.x = ptGe.x;
ptGeT.y = ptGe.z;
ptGeT.z = 0.0;
ptGe = ptGeT;
if (!vtNorm.isCodirectionalTo(AcGeVector3d::kYAxis))
{
AcGeMatrix3d xform;
xform.setToMirroring(AcGeLine3d::kXAxis);
ptGe.transformBy(xform);
}
}
else if (vtNorm.isParallelTo(AcGeVector3d::kZAxis)) //XY 面
{
ptGeT.x = ptGe.x;
ptGeT.y = ptGe.y;
ptGeT.z = 0.0;
ptGe = ptGeT;
if (!vtNorm.isCodirectionalTo(AcGeVector3d::kZAxis))
{
//正视图不变
}
else
{
AcGeMatrix3d xform;
xform.setToMirroring(AcGeLine3d::kYAxis);
ptGe.transformBy(xform);
}
}
return TRUE;
}
BOOL KTGeUtility::ToPlaneInWcs2D(AcGeVector3d& vt,const AcGePlane& plane)
{
AcGeVector3d vtNorm = plane.normal();
if (vtNorm.isParallelTo(AcGeVector3d::kXAxis)) //YZ 面
{
AcGePoint3d ptT;
ptT.x = vt.z;
ptT.y = vt.y;
ptT.z = vt.x;
vt = ptT.asVector();
if (!vtNorm.isCodirectionalTo(AcGeVector3d::kXAxis))
{
AcGeMatrix3d xform;
xform.setToMirroring(AcGeLine3d::kYAxis);
vt.transformBy(xform);
}
}
else if(vtNorm.isParallelTo(AcGeVector3d::kYAxis))//XZ 面
{
AcGePoint3d ptT;
ptT.x = vt.x;
ptT.y = vt.z;
ptT.z = vt.y;
vt = ptT.asVector();
if (!vtNorm.isCodirectionalTo(AcGeVector3d::kYAxis))
{
AcGeMatrix3d xform;
xform.setToMirroring(AcGeLine3d::kXAxis);
vt.transformBy(xform);
}
}
else if(vtNorm.isParallelTo(AcGeVector3d::kZAxis)) //XY 面
{
if (vtNorm.isCodirectionalTo(AcGeVector3d::kZAxis))
{
AcGeMatrix3d xform;
xform.setToMirroring(AcGeLine3d::kYAxis);
vt.transformBy(xform);
}
}
return TRUE;
}
typedef struct PointParam
{
AcGePoint3d ptGe;
double dParam;
}POINTPARAM;
static bool ComparePtparam(PointParam ptParam1,PointParam ptParam2)
{
if (ptParam1.dParam - ptParam2.dParam < 1.e-10)
{
return true;
}
return false;
}
void KTGeUtility::SortPoints(AcGePoint3dArray& points,AcDbCurve* pLine)
{
PointParam ptParam;
std::vector<PointParam> points2;
for (int i = 0;i < points.length();i++)
{
ptParam.ptGe = points.at(i);
pLine->getParamAtPoint(points.at(i),ptParam.dParam);
points2.push_back(ptParam);
}
std::sort(points2.begin(),points2.end(),ComparePtparam);
points.setLogicalLength(0);
std::vector<PointParam>::iterator it;
for (it = points2.begin(); it < points2.end(); it++)
{
points.append((*it).ptGe);
}
}
BOOL KTGeUtility::ParallelLinesHasCommon(AcDbLine* pLine1,AcDbLine* pLine2)
{
if (pLine1 == NULL || pLine2 == NULL) return FALSE;
double dL1 = pLine1->endPoint().distanceTo(pLine1->startPoint());
double dL2 = pLine2->endPoint().distanceTo(pLine2->startPoint());
//过短线的中点的垂直于两线的线和第二根线相交,不延长对方求交
AcGeVector3d vt = pLine1->endPoint() - pLine1->startPoint();
vt.rotateBy(PI / 2.0,pLine1->normal());
AcDbLine* pLong = (dL1 - dL2 > 1.e-10) ? pLine1 : pLine2;
AcDbLine* pShort= (dL1 - dL2 > 1.e-10) ? pLine2 : pLine1;
AcGePoint3d ptGeMid = Mid(pShort->endPoint(),pShort->startPoint());
AcGePoint3d ptGeOth = ptGeMid + vt * 2.0;
AcDbLine lineT(ptGeMid,ptGeOth);
lineT.setNormal(pLine1->normal());
AcGePoint3dArray pts;
lineT.intersectWith(pLong,AcDb::kExtendThis,pts);
if (pts.length() > 0)
{
return TRUE;
}
return FALSE;
}
BOOL KTGeUtility::BreakLine(AcDbObjectId& id,AcGePoint3d& ptGeNearCen,double dHalfWidth)
{
BOOL bSuccess = FALSE;
AcDbEntity* pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForWrite))
{
bSuccess = BreakLine(pEnt,ptGeNearCen,dHalfWidth);
pEnt->close();
return bSuccess;
}
return FALSE;
}
BOOL KTGeUtility::BreakLine(AcDbEntity* pEnt,AcGePoint3d& ptGeNearCen,double dHalfWidth)
{
BOOL bSuccess = FALSE;
if (pEnt == NULL) return FALSE;
AcDbLine* pLine = AcDbLine::cast(pEnt);
if (pLine != NULL)
{
AcDbLine* pLine2 = NULL;
AcGeVector3d vtLine = pLine->endPoint() - pLine->startPoint();
AcGePoint3d ptGeOn;
vtLine.normalize();
pLine->getClosestPointTo(ptGeNearCen,ptGeOn,Adesk::kTrue);
AcGePoint3d ptGe1,ptGe2;
ptGe1 = ptGeOn - vtLine * dHalfWidth;
ptGe2 = ptGeOn + vtLine * dHalfWidth;
AcGeVector3d vt1,vt2;
double dSta = 0.0,dEnd = 0.0,dPar1 = 0.0,dPar2 = 0.0;
pLine->getStartParam(dSta);
pLine->getEndParam(dEnd);
pLine->getParamAtPoint(ptGe1,dPar1);
pLine->getParamAtPoint(ptGe2,dPar2);
//1.两点都在直线上
if ( (dPar1 - dSta) > 1.e-10 &&
(dPar1 - dEnd) < 1.e-10 &&
(dPar2 - dSta) > 1.e-10 &&
(dPar2 - dEnd) < 1.e-10)
{
double dDist = ptGe2.distanceTo(pLine->endPoint());
if (dDist > MIN_DN)//至少 预留与管径一样长的段
{
pLine2 = new AcDbLine;
pLine2->setStartPoint(ptGe2);
pLine2->setEndPoint(pLine->endPoint());
AecDbObjXDataMap xData1;
if (xData1.Read(pLine,PIDPIPE_APP))
{
xData1.Write(pLine2,PIDPIPE_APP);
}
pLine2->setLayer(pLine->layer());
pLine2->setColorIndex(pLine->colorIndex());
}
pLine->setEndPoint(ptGe1);
bSuccess = TRUE;
}
else if ( (dPar1 - dSta) > 1.e-10 &&
(dPar1 - dEnd) < 1.e-10 &&
(dPar2 - dEnd) > -1.e-10)//2.ptGe1 在直线上
{
pLine->setEndPoint(ptGe1);
}
else if ( (dPar2 - dSta) > 1.e-10 &&
(dPar2 - dEnd) < 1.e-10 &&
(dPar1 - dSta) < 1.e-10)//3.ptGe2 在直线上
{
pLine->setStartPoint(ptGe2);
bSuccess = TRUE;
}
else //两点都在直线外
{
pLine->erase();
bSuccess = TRUE;
}
if (pLine2 != NULL)
{
CKTCadUtility::AddToBlockTableRecord(pLine2);
pLine2->close();
}
}
AcDbPolyline* pPl = AcDbPolyline::cast(pEnt);;
if (pPl != NULL)
{
AcDbPolyline* pPl2 = NULL;
AcGePoint3d ptGeSta,ptGeEnd;
pPl->getStartPoint(ptGeSta);
pPl->getEndPoint(ptGeEnd);
AcGeVector3d vtLine = ptGeEnd - ptGeSta;
AcGePoint3d ptGeOn;
vtLine.normalize();
pPl->getClosestPointTo(ptGeNearCen,ptGeOn,Adesk::kTrue);
AcGePoint3d ptGe1,ptGe2,ptGe3;
ptGe1 = ptGeOn - vtLine * dHalfWidth;
ptGe2 = ptGeOn + vtLine * dHalfWidth;
AcGeVector3d vt1,vt2;
AcGePlane plane(AcGePoint3d::kOrigin+pPl->normal()*pPl->elevation(), pPl->normal());
AcGePoint2d ptGe2d;
double dSta = 0.0,dEnd = 0.0,dPar1 = 0.0,dPar2 = 0.0;
pPl->getStartParam(dSta);
pPl->getEndParam(dEnd);
pPl->getParamAtPoint(ptGe1,dPar1);
pPl->getParamAtPoint(ptGe2,dPar2);
//1.两点都在直线上
if ( (dPar1 - dSta) > 1.e-10 &&
(dPar1 - dEnd) < 1.e-10 &&
(dPar2 - dSta) > 1.e-10 &&
(dPar2 - dEnd) < 1.e-10)
{
//判断有一点在末端
if (fabs(dPar1 - dSta) < 1.e-6) //ptGe1 在 start
{
pPl->setPointAt(0,ptGe2.convert2d(plane));
}
else if(fabs(dPar2 - dEnd) < 1.e-6)//ptGe2 在 end
{
pPl->setPointAt(1,ptGe1.convert2d(plane));
}
else
{
pPl->getEndPoint(ptGe3);
double dDist = ptGe2.distanceTo(ptGe3);
if (dDist > MIN_DN)//至少 预留与管径一样长的段
{
pPl2 = new AcDbPolyline;
AecDbObjXDataMap xData1;
if (xData1.Read(pPl,PIDPIPE_APP))
{
xData1.Write(pPl2,PIDPIPE_APP);
}
AcGePoint2d pt2d1 = ptGe2.convert2d(plane);
AcGePoint2d pt2d2 = ptGeEnd.convert2d(plane);
pPl2->addVertexAt(0,pt2d1);
pPl2->addVertexAt(1,pt2d2);
pPl2->setElevation(pPl->elevation());
pPl2->setNormal(plane.normal());
pPl2->setLayer(pPl->layer());
pPl2->setColorIndex(pPl->colorIndex());
double dWidth = 0.0;
pPl->getConstantWidth(dWidth);
pPl2->setConstantWidth(dWidth);
}
ptGe2d = ptGe1.convert2d(plane);
pPl->setPointAt(1,ptGe2d);
}
bSuccess = TRUE;
}
else if ( (dPar1 - dSta) > 1.e-10 &&
(dPar1 - dEnd) < 1.e-10 &&
(dPar2 - dEnd) > -1.e-10)//2.ptGe1 在直线上
{
//判断有一点在末端
if (fabs(dPar1 - dSta) < 1.e-6) //ptGe1 在 start
{
pPl->setPointAt(0,ptGe2.convert2d(plane));
}
else if(fabs(dPar2 - dEnd) < 1.e-6)//ptGe2 在 end
{
pPl->setPointAt(1,ptGe1.convert2d(plane));
}
else
{
pPl->setPointAt(1,ptGe1.convert2d(plane));
}
bSuccess = TRUE;
}
else if ( (dPar2 - dSta) > 1.e-10 &&
(dPar2 - dEnd) < 1.e-10 &&
(dPar1 - dSta) < 1.e-10)//3.ptGe2 在直线上
{
//判断有一点在末端
if (fabs(dPar1 - dSta) < 1.e-6) //ptGe1 在 start
{
pPl->setPointAt(0,ptGe2.convert2d(plane));
}
else if(fabs(dPar2 - dEnd) < 1.e-6)//ptGe2 在 end
{
pPl->setPointAt(1,ptGe1.convert2d(plane));
}
else
{
pPl->setPointAt(1,ptGe2.convert2d(plane));
}
bSuccess = TRUE;
}
else //两点都在直线外
{
pPl->erase();
bSuccess = TRUE;
}
if (pPl2 != NULL)
{
CKTCadUtility::AddToBlockTableRecord(pPl2);
pPl2->close();
}
}
return bSuccess;
}
BOOL KTGeUtility::MidBreakLine(AcDbEntity* pEnt,AcGePoint3d& ptGeOn,double dHalfWidth)
{
if (pEnt == NULL) return FALSE;
AcDbLine* pLine = AcDbLine::cast(pEnt);
if (pLine != NULL)
{
pLine->getClosestPointTo(ptGeOn,ptGeOn,Adesk::kTrue);
AcGeVector3d vt = pLine->endPoint() - pLine->startPoint();
vt.normalize();
AcGePoint3d ptGe1,ptGe2;
ptGe1 = ptGeOn - vt * dHalfWidth;
ptGe2 = ptGeOn + vt * dHalfWidth;
AcGePoint3d ptGeSta = pLine->startPoint();
AcGePoint3d ptGeEnd = pLine->endPoint();
AcGeVector3d vt1 = ptGe1 - pLine->startPoint();
AcGeVector3d vt2 = pLine->endPoint() - ptGe2;
if (vt1.isCodirectionalTo(vt2))
{
AcDbLine* pLine2 = new AcDbLine(pLine->startPoint(),ptGe1);
pLine->setStartPoint(ptGe2);
pLine2->setLayer(pEnt->layer());
pLine2->setColorIndex(pEnt->colorIndex());
CKTCadUtility::AddToBlockTableRecord(pLine2);
pLine2->close();
return TRUE;
}
}
return FALSE;
}
BOOL KTGeUtility::FindClosestLineParallelTo(AcDbObjectIdArray& arIds,AcDbLine* pLineCen,int& nIndex)
{
if (pLineCen == NULL) return FALSE;
AcGeVector3d vtCen = pLineCen->endPoint() - pLineCen->startPoint();
double dDistRef = -1.0,dDist = 0.0;
AcDbEntity* pEnt = NULL;
AcGeVector3d vt;
AcGePoint3d ptGe,ptGe1;
int nFind = -1;
KTTempTol tol(1.E-6);
for(int i = 0;i < arIds.length();i++)
{
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,arIds.at(i),AcDb::kForRead))
{
AcDbLine* pLine = AcDbLine::cast(pEnt);
if (pLine != NULL)
{
vt = pLine->endPoint() - pLine->startPoint();
if (vt.isParallelTo(vtCen))
{
pLineCen->getClosestPointTo(pLine->endPoint(),ptGe,Adesk::kTrue);
dDist = ptGe.distanceTo(pLine->endPoint());
//并且line和linecen有共同的部分
if ( KTGeUtility::ParallelLinesHasCommon(pLineCen,pLine))
{
if (dDistRef < -1.E-6)//first
{
dDistRef = dDist;
nFind = i;
}
else
{
if (dDist - dDistRef < 1.E-6)//second
{
dDistRef = dDist;
nFind = i;
}
}
}
}
}
pEnt->close();
}
}
nIndex = nFind;
return (nFind != -1);
}
BOOL KTGeUtility::PickDir(LPCTSTR pszTip,const AcGePoint3d& ptGeBase,AcGeVector3d& vtDir)
{
ads_point ptBase,ptTo;
ptBase[X] = ptGeBase.x;ptBase[Y] = ptGeBase.y;ptBase[Z] = ptGeBase.z;
acdbWcs2Ucs(ptBase,ptBase,false);
//CString sText = _T("\n指定弯头拐角方向[向上(U)/向下(D)/辅助线(L)]<退出>:");
acedInitGet(RSG_NONULL,_T("U D L"));
int nRes = acedGetPoint(ptBase,pszTip,ptTo);
switch(nRes)
{
case RTNORM:
{
vtDir.set(ptTo[X] - ptBase[X],ptTo[Y] - ptBase[Y],ptTo[Z] - ptBase[Z]);
vtDir = vtDir.orthoProject(AcGeVector3d::kZAxis);//默认按xy面操作
break;
}
case RTKWORD:
{
TCHAR szKey[2];
szKey[0] = _T('0');
acedGetInput(szKey);
switch(szKey[0])
{
case _T('U'):
case _T('u'):
{
vtDir = AcGeVector3d::kZAxis;
break;
}
case _T('D'):
case _T('d'):
{
vtDir = -AcGeVector3d::kZAxis;
break;
}
case _T('L'):
case _T('l'):
{
ads_name ent;
ads_point ptOn;
AcDbObjectId id;
AcDbEntity* pEnt = NULL;
while(TRUE)
{
nRes = acedEntSel(_T("\n选择作为方向的辅助线<退出>:"),ent,ptOn);
if (nRes == RTNONE ||
nRes == RTCAN )
{
return 0;
}
if (nRes == RTNORM)
{
acdbGetObjectId(id,ent);
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead))
{
AcDbLine* pLine = AcDbLine::cast(pEnt);
if (pLine != NULL)
{
vtDir = pLine->endPoint() - pLine->startPoint();
}
else
{
acutPrintf(_T("\n选择实体不是直线!"));
}
pEnt->close();
}
if (!vtDir.isZeroLength())
break;
}
}
break;
}
default:
break;
}
}
default:
{
break;
}
}
return !vtDir.isZeroLength();
}
BOOL KTGeUtility::FindHitEnt(AcDbObjectIdArray& ids,AcGePoint3d& ptGe,AcDbObjectId& idHit)
{
int i = 0,bFind = FALSE;
AcDbEntity* pEnt = NULL;
AcDbCurve* pCurve = NULL;
AcGePoint3d ptGeT;
AcDbObjectId idNear;
double dDisRef = 1.0, dDis = 0.0;
for (i = 0;i < ids.length();i++)
{
if (Acad::eOk == acdbOpenAcDbEntity(pEnt,ids.at(i),AcDb::kForRead))
{
pCurve = AcDbCurve::cast(pEnt);
if (pCurve!=NULL)
{
pCurve->getClosestPointTo(ptGe,ptGeT);
dDis = ptGeT.distanceTo(ptGe);
if (dDis < 1.e-10 && dDis < dDisRef)
{
dDisRef = dDis;
idNear = ids.at(i);
bFind = TRUE;
}
}
pEnt->close();
}
}
idHit = idNear;
return bFind;
}
AcGePoint2d KTGeUtility::P3d_to_P2d(AcGePoint3d pt)
{
AcGePoint2d P2d;
for(int i=0;i<2;i++)
{
P2d.operator[](i)=pt.operator[](i);
}
return P2d;
}
//获取对应样式的文字高度,宽度,角度
void KTGeUtility::KTGetTextstyle(CString sStyle,double& dHeight,double& dWidth,double& dAngle)
{
AcDbObjectId idTxtStyle = AcDbObjectId::kNull;
AcDbSymbolUtilities::getTextStyleId(idTxtStyle,sStyle,acdbCurDwg());
if(idTxtStyle == AcDbObjectId::kNull) return;
Acad::ErrorStatus es;
AcDbTextStyleTableRecord * pTextStyleRc = NULL;
es = acdbOpenObject(pTextStyleRc, idTxtStyle, AcDb::kForRead);
if(es == Acad::eOk)
{
LPTSTR pBigFont = NULL;
LPTSTR pfileName = NULL;
LPTSTR pTypeface = NULL;
pTextStyleRc->bigFontFileName(pBigFont);
pTextStyleRc->fileName(pfileName);
#if ARX < 21
Adesk::Boolean bold,italic;
int charset,pitch;
pTextStyleRc->font(pTypeface,bold,italic,charset,pitch);
#else
bool bold, italic;
Autodesk::AutoCAD::PAL::FontUtils::FontPitch pitch;
Autodesk::AutoCAD::PAL::FontUtils::FontFamily family;
Charset charset;
pTextStyleRc->font(pTypeface,bold,italic,charset,pitch, family);
#endif
dHeight = pTextStyleRc->textSize();
dWidth = pTextStyleRc->xScale();
dAngle = pTextStyleRc->obliquingAngle();
pTextStyleRc->close();
}
return;
}
void KTGeUtility::MisicellaElbow(AcGePoint3d ptBase,AcGeVector3d vM,AcGeVector3d vS,double dA,double dB,double dC,double dD)
{
AcGePoint3d ptCenter,ptCEnd,ptCEndU,ptCEndD;
AcGePoint3dArray ptArray,ptArrayU,ptArrayD;
AcGeVector3d vUse,vUseU,vUseD;
AcDbObjectId id = AcDbObjectId::kNull;
AcDbObjectId idLayerC = KTSetting::InitLayer(_T("LAY_CL"));
AcDbObjectId idLayer = KTSetting::InitLayer(_T("LAY_FITTING"));
ptCEnd = ptBase;
ptCenter = ptBase + vS*dB;
vUse = ptCEnd - ptCenter;
ptArray.setLogicalLength(0);
ptArrayU.setLogicalLength(0);
ptArrayD.setLogicalLength(0);
ptArray.append(ptCEnd);
ptCEndU = ptCenter - vS*(dB+dA/2);
vUseU = ptCEndU - ptCenter;
ptArrayU.append(ptCEndU);
ptCEndD = ptCenter - vS*(dB-dA/2);
vUseD = ptCEndD - ptCenter;
ptArrayD.append(ptCEndD);
double dAng = dD/dC*0.5/180*PI;
vUse.rotateBy(-dAng,AcGeVector3d::kZAxis);
ptCEnd = ptCenter +vUse;
ptArray.append(ptCEnd);
vUseU.rotateBy(-dAng,AcGeVector3d::kZAxis);
ptCEndU = ptCenter +vUseU;
ptArrayU.append(ptCEndU);
vUseD.rotateBy(-dAng,AcGeVector3d::kZAxis);
ptCEndD = ptCenter +vUseD;
ptArrayD.append(ptCEndD);
for (int i= 0;i<dC-1;i++)
{
dAng = dD/dC/180*PI;
vUse.rotateBy(-dAng,AcGeVector3d::kZAxis);
ptCEnd = ptCenter +vUse;
ptArray.append(ptCEnd);
vUseU.rotateBy(-dAng,AcGeVector3d::kZAxis);
ptCEndU = ptCenter +vUseU;
ptArrayU.append(ptCEndU);
vUseD.rotateBy(-dAng,AcGeVector3d::kZAxis);
ptCEndD = ptCenter +vUseD;
ptArrayD.append(ptCEndD);
}
dAng = dD/dC*0.5/180*PI;
vUse.rotateBy(-dAng,AcGeVector3d::kZAxis);
ptCEnd = ptCenter +vUse;
ptArray.append(ptCEnd);
vUseU.rotateBy(-dAng,AcGeVector3d::kZAxis);
ptCEndU = ptCenter +vUseU;
ptArrayU.append(ptCEndU);
vUseD.rotateBy(-dAng,AcGeVector3d::kZAxis);
ptCEndD = ptCenter +vUseD;
ptArrayD.append(ptCEndD);
int nLen = ptArray.length();
AcDbPolyline * pLine = new AcDbPolyline();
AcDbPolyline * pLineU = new AcDbPolyline();
AcDbPolyline * pLineD = new AcDbPolyline();
for (i =0;i<nLen;i++)
{
pLine->addVertexAt(i,ptArray.at(i).convert2d(AcGePlane::kXYPlane));
pLineU->addVertexAt(i,ptArrayU.at(i).convert2d(AcGePlane::kXYPlane));
pLineD->addVertexAt(i,ptArrayD.at(i).convert2d(AcGePlane::kXYPlane));
}
AcDbPolyline * pLineL = new AcDbPolyline();
AcDbPolyline * pLineR = new AcDbPolyline();
pLineL->addVertexAt(0,ptArrayU.at(0).convert2d(AcGePlane::kXYPlane));
pLineL->addVertexAt(1,ptArrayD.at(0).convert2d(AcGePlane::kXYPlane));
pLineR->addVertexAt(0,ptArrayU.at(nLen-1).convert2d(AcGePlane::kXYPlane));
pLineR->addVertexAt(1,ptArrayD.at(nLen-1).convert2d(AcGePlane::kXYPlane));
AcDbPolyline * pLineUD;
if (idLayerC != AcDbObjectId::kNull)
{
pLine->setLayer(idLayerC);
//pLine->setLinetypeScale(1);
}
if (idLayer != AcDbObjectId::kNull)
{
pLineL->setLayer(idLayer);
pLineR->setLayer(idLayer);
pLineU->setLayer(idLayer);
pLineD->setLayer(idLayer);
}
for (i =0;i<nLen;i++)
{
pLineUD = new AcDbPolyline();
pLineUD->addVertexAt(0,ptArrayU.at(i).convert2d(AcGePlane::kXYPlane));
pLineUD->addVertexAt(1,ptArrayD.at(i).convert2d(AcGePlane::kXYPlane));
if (idLayer != AcDbObjectId::kNull)
{
pLineUD->setLayer(idLayerC);
}
CKTCadUtility::AddToBlockTableRecord(pLineUD);
pLineUD->close();
}
CKTCadUtility::AddToBlockTableRecord(pLineL);
pLineL->close();
CKTCadUtility::AddToBlockTableRecord(pLineR);
pLineR->close();
CKTCadUtility::AddToBlockTableRecord(pLine);
pLine->close();
CKTCadUtility::AddToBlockTableRecord(pLineU);
pLineU->close();
CKTCadUtility::AddToBlockTableRecord(pLineD);
pLineD->close();
}
//////////////////////////////////////////
void KTGeUtility::BatchBreak(AcDbObjectId idDraw,AcDbObjectId idOld,int nNo,AcGePoint3d ptStart,AcGePoint3d ptEnd,double dBreakDis,int nDraw,int nCross)
{
ads_name ssname;
acedSSGet(_T("C"), asDblArray(ptStart),asDblArray(ptEnd), NULL, ssname);
ads_name adsLine;
acdbGetAdsName(adsLine,idDraw);
acedSSDel(adsLine,ssname);
Adesk::Int32 lLen = 0;
acedSSLength(ssname,&lLen);
if (lLen == 0)
{
acedSSFree(ssname);
return;
}
ads_name ssResult;
acedSSAdd(NULL, NULL, ssResult);
acedSSAdd(adsLine, NULL, ssResult);
Adesk::Int32 lSize = 0,lIndex = 0;
while(lLen > 0)
{
ads_name ename1,ename2;
acedSSName(ssname,0,ename1);
acedSSLength(ssResult,&lSize);
bool bBreaked = false;
for(lIndex = 0;lIndex<lSize;lIndex++)
{
acedSSName(ssResult,lIndex,ename2);
bBreaked = LineBreak(ename1,ename2,ssResult,dBreakDis,nDraw,nCross);
if(bBreaked == true)
{
break;
}
}
acedSSDel(ename1,ssname);
acedSSLength(ssname,&lLen);
}
acedSSFree(ssResult);
acedSSFree(ssname);
}
bool KTGeUtility::LineBreak(ads_name ename,ads_name adsLine,ads_name ssResult,double dBreakDis,int nDraw,int nCross)
{
AcDbObjectId idName,idLine;
acdbGetObjectId(idName, ename);
acdbGetObjectId(idLine,adsLine);
int nDrawNo = 0;
int nCrossNo = 0;
AcGePoint3d ptSCross,ptECross,ptSDraw,ptEDraw;
AcGeVector3d vCross,vcLine;
double dCrossAngle =0.0;
double dDrawAngle =0.0;
AecDbObjXDataMap objXData;
if (objXData.Read(idName,PIDPIPE_APP)==FALSE)
{
return false;
}
int nKind = -1;
objXData.GetAt(PIPE_FITTING,nKind);
if (nKind == 0) //是pipe
{
AcDbPolyline* pEnt1;
AcDbPolyline* pEnt2;
AcGePoint3dArray points;
if (acdbOpenObject(pEnt1,idName, AcDb::kForRead)!= Acad::eOk) return false;
if (acdbOpenObject(pEnt2,idLine, AcDb::kForRead)!= Acad::eOk) return false;
pEnt1->getStartPoint(ptSCross);
pEnt1->getEndPoint(ptECross);
pEnt2->getStartPoint(ptSDraw);
pEnt2->getEndPoint(ptEDraw);
points.setLogicalLength (0);
pEnt1->intersectWith(pEnt2,AcDb::kOnBothOperands,points);
pEnt1->close();
pEnt2->close();
vCross = ptECross - ptSCross;
vCross.normalize();
vcLine = ptEDraw - ptSDraw;
vcLine.normalize();
if(points.length() == 1)
{
AcGePoint3d ptIntersect = points.at(0);
AcGePoint3d ptInter;
AcGePoint3d ptOther;
if (ptIntersect == ptSDraw || ptIntersect == ptEDraw)
{
return false;
}
struct resbuf *result = NULL,Var;
acedGetVar(_T("OSMODE"),&Var);
acedSetVar(_T("OSMODE"),acutBuildList(RTSHORT,0,RTNONE));
ads_name ssline1,ssline2;
nDrawNo=nDraw;
nCrossNo=nCross;
if (nDrawNo == nCrossNo)
{
dCrossAngle =KTGeUtility::AngleToXAxis(ptSCross,ptECross);
dDrawAngle =KTGeUtility::AngleToXAxis(ptSDraw,ptEDraw);
if (dCrossAngle > PI/2)
{
dCrossAngle = PI - dCrossAngle;
}
if (dDrawAngle > PI/2)
{
dDrawAngle = PI - dDrawAngle;
}
if (dCrossAngle > dDrawAngle)
{
ptOther = ptIntersect + dBreakDis*vCross;
ptInter = ptIntersect - dBreakDis*vCross;
SHads_command(RTSTR,"break",RTLB,RTENAME,ename,RT3DPOINT,asDblArray(ptInter),RTLE,RT3DPOINT,asDblArray(ptOther),RTNONE);
}
else
{
ptOther = ptIntersect + dBreakDis*vcLine;
ptInter = ptIntersect - dBreakDis*vcLine;
SHads_command(RTSTR,"break",RTLB,RTENAME,adsLine,RT3DPOINT,asDblArray(ptInter),RTLE,RT3DPOINT,asDblArray(ptOther),RTNONE);
}
}
else if (nDrawNo > nCrossNo)
{
ptOther = ptIntersect + dBreakDis*vcLine;
ptInter = ptIntersect - dBreakDis*vcLine;
SHads_command(RTSTR,"break",RTLB,RTENAME,adsLine,RT3DPOINT,asDblArray(ptInter),RTLE,RT3DPOINT,asDblArray(ptOther),RTNONE);
}
else if (nDrawNo < nCrossNo)
{
ptOther = ptIntersect + dBreakDis*vCross;
ptInter = ptIntersect - dBreakDis*vCross;
SHads_command(RTSTR,"break",RTLB,RTENAME,ename,RT3DPOINT,asDblArray(ptInter),RTLE,RT3DPOINT,asDblArray(ptOther),RTNONE);
}
acdbEntNext(NULL,ssline1);
acdbEntLast(ssline2);
acedSSAdd(ssline1, ssResult, ssResult);
acedSSAdd(ssline2, ssResult, ssResult);
acedSetVar(_T("OSMODE"),&Var);
return true;
}
}
return false;
}
double KTGeUtility::AngleToXAxis(AcGePoint3d pt1,AcGePoint3d pt2)
{
AcGeVector3d vector1;
vector1 = pt2 - pt1;
double dAngle = vector1.angleTo(AcGeVector3d::kXAxis);
return dAngle;
}