1000 lines
24 KiB
C++
1000 lines
24 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;
|
|
}
|