2380 lines
58 KiB
C++
2380 lines
58 KiB
C++
#include "stdafx.h"
|
|
//#include "resource.h"
|
|
#include "KTCADUtilityEx.h"
|
|
#include "KTCadUtility.h"
|
|
#include "KTTempTol.h"
|
|
#include "KTCADSysVar.h"
|
|
#include "KTSetting.h"
|
|
#include "EarThwormDef.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[]=__FILE__;
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
const double WALLMAXWIDTH = 800.0;
|
|
|
|
#ifndef RT_MANIFEST
|
|
#define RT_MANIFEST MAKEINTRESOURCE(24)
|
|
#endif //RT_MANIFEST
|
|
|
|
template <class K> BOOL CopyObject(const K &src, K &dest)
|
|
{
|
|
AcDbDeepCloneFiler filer;
|
|
BOOL bRet=FALSE;
|
|
if(src.dwgOutFields(&filer)==Acad::eOk)
|
|
{
|
|
filer.seek(0L,0);
|
|
bRet=(dest.dwgInFields(&filer)==Acad::eOk);
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
KTCADUtilityEx::KTCADUtilityEx()
|
|
{
|
|
}
|
|
|
|
KTCADUtilityEx::~KTCADUtilityEx()
|
|
{
|
|
}
|
|
|
|
int KTCADUtilityEx::DoubleCompare(const double& dArg1, const double& dArg2)
|
|
{
|
|
double dValue = dArg1 - dArg2;
|
|
if (fabs(dValue) < 1.e-5)
|
|
return 0;
|
|
else
|
|
return (dValue < 0.0 ? -1 : 1);
|
|
}
|
|
|
|
// 通过一墙线,在给定点附近取得另一墙线和轴线, 1有另一墙线,2墙线轴线都有
|
|
struct KTWallSortData{AcDbObjectId idEnt; AcGePoint3d ptIns; AcGeVector3d vecDir; BOOL bRadius;};
|
|
|
|
int KTCADUtilityEx::GetWallParamByWallLine(AcDbObjectId& idCur,const AcGePoint3d& ptTest,
|
|
AcDbObjectId& idOth,AcDbObjectId& idAxis)
|
|
{
|
|
typedef CSortPair<double, KTWallSortData, DoubleCompare> CWallSortPair;
|
|
KTTempTol tol(1.e-6);
|
|
|
|
BOOL bRadius;
|
|
AcGePoint3d pt;
|
|
AcGeVector3d vec;
|
|
|
|
AcDbCurve* pCurve = NULL;
|
|
AcDbEntity* pEnt = NULL;
|
|
|
|
acdbOpenAcDbEntity(pEnt,idCur,AcDb::kForRead);
|
|
if (pEnt == NULL) return 0;
|
|
|
|
pCurve = AcDbCurve::cast(pEnt);
|
|
if (pCurve == NULL)
|
|
{
|
|
pEnt->close();
|
|
return 0;
|
|
}
|
|
|
|
pCurve->getClosestPointTo(ptTest, pt);
|
|
if (pCurve->isKindOf(AcDbLine::desc()))
|
|
{
|
|
bRadius = FALSE;
|
|
AcDbLine* pLineT = AcDbLine::cast(pCurve);
|
|
vec = pLineT->endPoint() - pLineT->startPoint();
|
|
vec.rotateBy(PI/2.0, ((AcDbLine*)pCurve)->normal());
|
|
}
|
|
else if (pCurve->isKindOf(AcDbArc::desc()))
|
|
{
|
|
bRadius = TRUE;
|
|
vec = pt - ((AcDbArc*)pCurve)->center();
|
|
}
|
|
else if (pCurve->isKindOf(AcDbCircle::desc()))
|
|
{
|
|
bRadius = TRUE;
|
|
vec = pt - ((AcDbCircle*)pCurve)->center();
|
|
}
|
|
else
|
|
{
|
|
pEnt->close();
|
|
return 0;
|
|
}
|
|
pEnt->close();
|
|
|
|
vec.normalize();
|
|
|
|
AcGePoint3d pt1, pt2;
|
|
pt1 = pt + vec * WALLMAXWIDTH;
|
|
pt2 = pt - vec * WALLMAXWIDTH;
|
|
|
|
CString sLayerWall,sTemp;
|
|
KTSetting::GetLayerName(_T("LAY_WALL"),sLayerWall,sTemp);
|
|
|
|
struct resbuf res1,res2;
|
|
res1.restype = 0;
|
|
res1.resval.rstring = (bRadius ? _tcsdup(_T("ARC,CIRCLE")) : _tcsdup(_T("LINE")));
|
|
res2.restype = 8;
|
|
res2.resval.rstring = (LPTSTR)(LPCTSTR)sLayerWall;
|
|
res1.rbnext = &res2;
|
|
res2.rbnext = NULL;
|
|
|
|
struct resbuf resF,resFT;
|
|
resF.restype = RT3DPOINT;
|
|
resF.resval.rpoint[0] = pt1.x;
|
|
resF.resval.rpoint[1] = pt1.y;
|
|
resF.resval.rpoint[2] = pt1.z;
|
|
resFT.restype = RT3DPOINT;
|
|
resFT.resval.rpoint[0] = pt2.x;
|
|
resFT.resval.rpoint[1] = pt2.y;
|
|
resFT.resval.rpoint[2] = pt2.z;
|
|
resF.rbnext = &resFT;
|
|
resFT.rbnext = NULL;
|
|
|
|
AcDbObjectIdArray arIdEnts;
|
|
ads_name ssSet,ent;
|
|
acedSSGet(_T("F"),&resF,NULL,&res1,ssSet);
|
|
|
|
AcDbObjectId idT;
|
|
Adesk::Int32 lLen = 0;
|
|
acedSSLength(ssSet,&lLen);
|
|
|
|
for (long i = 0;i < lLen;i++)
|
|
{
|
|
acedSSName(ssSet,i,ent);
|
|
if (Acad::eOk == acdbGetObjectId(idT,ent))
|
|
{
|
|
arIdEnts.append(idT);
|
|
}
|
|
}
|
|
acedSSFree(ssSet);
|
|
if (arIdEnts.length() == 0) return 0;
|
|
|
|
int nFoundAt = -1;
|
|
arIdEnts.find(idCur,nFoundAt);
|
|
|
|
if (nFoundAt != -1)
|
|
arIdEnts.removeAt(nFoundAt);
|
|
|
|
// 排序数据
|
|
AcArray<CWallSortPair> arWallSort;
|
|
|
|
CWallSortPair data;
|
|
AcDbLine line(pt1, pt2);
|
|
lLen = arIdEnts.length();
|
|
AcDbObjectId idTemp;
|
|
|
|
for (long l = 0l; l < lLen; l++)
|
|
{
|
|
idTemp = arIdEnts.at(l);
|
|
pCurve = NULL;
|
|
pEnt = NULL;
|
|
|
|
acdbOpenAcDbEntity(pEnt,idTemp,AcDb::kForRead);
|
|
if (pEnt == NULL)
|
|
continue;
|
|
|
|
pCurve = AcDbCurve::cast(pEnt);
|
|
if (pCurve == NULL)
|
|
{
|
|
pEnt->close();
|
|
continue;
|
|
}
|
|
|
|
if (bRadius)
|
|
{
|
|
if (pCurve->isKindOf(AcDbArc::desc()))
|
|
{
|
|
if (!vec.isParallelTo(pt - ((AcDbArc*)pCurve)->center()))
|
|
{
|
|
pEnt->close();
|
|
continue;
|
|
}
|
|
}
|
|
else if (pCurve->isKindOf(AcDbCircle::desc()))
|
|
{
|
|
if (!vec.isParallelTo(pt - ((AcDbCircle*)pCurve)->center()))
|
|
{
|
|
pEnt->close();
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pEnt->close();
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pCurve->isKindOf(AcDbLine::desc()))
|
|
{
|
|
AcDbLine* pLineT = AcDbLine::cast(pCurve);
|
|
if (pLineT != NULL)
|
|
{
|
|
AcGeVector3d vcTemp = pLineT->endPoint() - pLineT->startPoint();
|
|
if (!vec.isPerpendicularTo(vcTemp))
|
|
{
|
|
pEnt->close();
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pEnt->close();
|
|
continue;
|
|
}
|
|
}
|
|
|
|
AcGePoint3dArray arpt;
|
|
if (line.intersectWith(pCurve, AcDb::kOnBothOperands, arpt) != Acad::eOk || arpt.length() <= 0)
|
|
{
|
|
pEnt->close();
|
|
continue;
|
|
}
|
|
data.compare = pt.distanceTo(arpt[0]);
|
|
if (data.compare < 1.e-3)
|
|
{
|
|
pEnt->close();
|
|
continue;
|
|
}
|
|
|
|
data.value.idEnt = idTemp;
|
|
data.value.ptIns = arpt[0];
|
|
arWallSort.append(data);
|
|
|
|
pEnt->close();
|
|
}
|
|
|
|
int iLen = arWallSort.length();
|
|
if (iLen <= 0)
|
|
return 0;
|
|
QuickSort(arWallSort.asArrayPtr(), iLen);
|
|
|
|
idOth = arWallSort[0].value.idEnt;
|
|
pt1 = arWallSort[0].value.ptIns;
|
|
|
|
CString sLayerAxis;
|
|
KTSetting::GetLayerName(_T("LAY_AXIS"),sLayerAxis,sTemp);
|
|
|
|
res1.restype = 0;
|
|
res1.resval.rstring = (bRadius ? _tcsdup(_T("ARC,CIRCLE")) : _tcsdup(_T("LINE")));
|
|
res2.restype = 8;
|
|
res2.resval.rstring = (LPTSTR)(LPCTSTR)sLayerAxis;
|
|
res1.rbnext = &res2;
|
|
res2.rbnext = NULL;
|
|
|
|
resF.restype = RT3DPOINT;
|
|
resF.resval.rpoint[0] = pt.x;
|
|
resF.resval.rpoint[1] = pt.y;
|
|
resF.resval.rpoint[2] = pt.z;
|
|
resFT.restype = RT3DPOINT;
|
|
resFT.resval.rpoint[0] = pt1.x;
|
|
resFT.resval.rpoint[1] = pt1.y;
|
|
resFT.resval.rpoint[2] = pt1.z;
|
|
resF.rbnext = &resFT;
|
|
resFT.rbnext = NULL;
|
|
|
|
arIdEnts.setLogicalLength(0);
|
|
acedSSGet(_T("F"),&resF,NULL,&res1,ssSet);
|
|
|
|
lLen = 0;
|
|
acedSSLength(ssSet,&lLen);
|
|
|
|
for (int i = 0;i < lLen;i++)
|
|
{
|
|
acedSSName(ssSet,i,ent);
|
|
if (Acad::eOk == acdbGetObjectId(idT,ent))
|
|
{
|
|
arIdEnts.append(idT);
|
|
}
|
|
}
|
|
acedSSFree(ssSet);
|
|
|
|
arWallSort.setLogicalLength(0);
|
|
line.setStartPoint(pt);
|
|
line.setEndPoint(pt1);
|
|
lLen = arIdEnts.length();
|
|
|
|
for (int l = 0l; l < lLen; l++)
|
|
{
|
|
idTemp = arIdEnts.at(l);
|
|
pEnt = NULL;
|
|
|
|
acdbOpenAcDbEntity(pEnt,idTemp,AcDb::kForRead);
|
|
if (pEnt == NULL)
|
|
continue;
|
|
|
|
pCurve = AcDbCurve::cast(pEnt);
|
|
if (pCurve == NULL)
|
|
{
|
|
pEnt->close();
|
|
continue;
|
|
}
|
|
|
|
if (bRadius)
|
|
{
|
|
if (pCurve->isKindOf(AcDbArc::desc()))
|
|
{
|
|
if (!vec.isParallelTo(pt - ((AcDbArc*)pCurve)->center()))
|
|
{
|
|
pEnt->close();
|
|
continue;
|
|
}
|
|
}
|
|
else if (pCurve->isKindOf(AcDbCircle::desc()))
|
|
{
|
|
if (!vec.isParallelTo(pt - ((AcDbCircle*)pCurve)->center()))
|
|
{
|
|
pEnt->close();
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pEnt->close();
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pCurve->isKindOf(AcDbLine::desc()))
|
|
{
|
|
AcDbLine* pLineT = AcDbLine::cast(pCurve);
|
|
if (pLineT != NULL)
|
|
{
|
|
AcGeVector3d vcTemp = pLineT->endPoint() - pLineT->startPoint();
|
|
if (!vec.isPerpendicularTo(vcTemp))
|
|
{
|
|
pEnt->close();
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pEnt->close();
|
|
continue;
|
|
}
|
|
}
|
|
|
|
AcGePoint3dArray arpt;
|
|
if (line.intersectWith(pCurve, AcDb::kOnBothOperands, arpt) != Acad::eOk || arpt.length() <= 0)
|
|
continue;
|
|
|
|
data.compare = fabs(pt.distanceTo(arpt[0]) - pt1.distanceTo(arpt[0]));
|
|
data.value.idEnt = idTemp;
|
|
data.value.ptIns = arpt[0];
|
|
arWallSort.append(data);
|
|
|
|
pEnt->close();
|
|
}
|
|
|
|
iLen = arWallSort.length();
|
|
if (iLen <= 0)
|
|
return 1;
|
|
|
|
QuickSort(arWallSort.asArrayPtr(), iLen);
|
|
|
|
idAxis = arWallSort[0].value.idEnt;
|
|
|
|
if (arWallSort[0].compare + 0.01 < pt.distanceTo(pt1))
|
|
return 2;
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
// 将一组点在指定的方向上排序
|
|
void KTCADUtilityEx::SortPointByDirect(AcGePoint3dArray& arpt, const AcGeVector3d& vecDir)
|
|
{
|
|
// 排序数据
|
|
typedef CSortPair<double, AcGePoint3d, DoubleCompare> CPointSortPair;
|
|
AcArray<CPointSortPair> arPointSort;
|
|
|
|
AcDbXline xline;
|
|
xline.setBasePoint(arpt[0]);
|
|
xline.setUnitDir(vecDir);
|
|
|
|
AcGePoint3d pt;
|
|
CPointSortPair data;
|
|
int iLen = arpt.length();
|
|
int i = 0;
|
|
for (i = 0; i < iLen; i++)
|
|
{
|
|
xline.getClosestPointTo(arpt[i], pt);
|
|
xline.getParamAtPoint(pt, data.compare);
|
|
data.value = arpt[i];
|
|
arPointSort.append(data);
|
|
}
|
|
|
|
iLen = arPointSort.length();
|
|
QuickSort(arPointSort.asArrayPtr(), iLen);
|
|
|
|
arpt.setLogicalLength(0);
|
|
for (i = 0; i < iLen; i++)
|
|
{
|
|
arpt.append(arPointSort[i].value);
|
|
}
|
|
}
|
|
|
|
// 根据给定的曲线实体,搜索与他相交的平行线的线组中最外的边界实体
|
|
struct CAxisCurveData {ads_name adsEnt; AcGePoint3d ptInt; AcGeVector3d vecRef; AcGeVector3d vecDir;};
|
|
int KTCADUtilityEx::FindMaxBoundAxis(ads_name& entTest, ads_name& ent1, ads_name& ent2, ads_point& pt1, ads_point& pt2)
|
|
{
|
|
// 排序数据
|
|
typedef CSortPair<double, CAxisCurveData, DoubleCompare> CAxisSortPair;
|
|
AcArray<CAxisSortPair> arParamName;
|
|
|
|
// 查找与给定曲线相交的曲线
|
|
AcDbObjectId idEntTest;
|
|
acdbGetObjectId(idEntTest,entTest);
|
|
OPENOBJ_BEGIN(idEntTest, AcDb::kForRead, AcDbCurve, pCurve);
|
|
if (pCurve == NULL)
|
|
return 0;
|
|
|
|
CString sLayer,sTemp;
|
|
KTSetting::InitLayer(_T("LAY_AXIS"));
|
|
KTSetting::GetLayerName(_T("LAY_AXIS"),sLayer,sTemp);
|
|
|
|
ads_name ssSet,ent;
|
|
struct resbuf* pResbuf = acutBuildList(RTDXF0, _T("LINE,ARC,CIRCLE"), 8, sLayer, 0);
|
|
if (RTNORM != acedSSGet(_T("X"),NULL,NULL,pResbuf,ssSet))
|
|
{
|
|
acutRelRb(pResbuf);
|
|
return 0;
|
|
}
|
|
acutRelRb(pResbuf);
|
|
|
|
CAxisSortPair data;
|
|
int i, iLen;
|
|
Adesk::Int32 lLen = 0;
|
|
AcDbObjectId idT;
|
|
acedSSLength(ssSet,&lLen);
|
|
|
|
long l = 0l;
|
|
for (l = 0l; l < lLen; l++)
|
|
{
|
|
AcGePoint3dArray arpt;
|
|
|
|
acedSSName(ssSet,l,ent);
|
|
acdbGetObjectId(idT,ent);
|
|
|
|
OPENOBJ_BEGIN(idT, AcDb::kForRead, AcDbCurve, pCurve1);
|
|
if (pCurve1 == NULL)
|
|
continue;
|
|
|
|
if (pCurve1->visibility() == AcDb::kInvisible)
|
|
{
|
|
pCurve1->close();
|
|
continue;
|
|
}
|
|
|
|
if (pCurve->intersectWith(pCurve1, AcDb::kExtendBoth, arpt) != Acad::eOk || (iLen = arpt.length()) <= 0)
|
|
continue;
|
|
// 找到真正交点,防止刚好相交的边界线无法得到
|
|
for (i = 0; i < iLen; i++)
|
|
{
|
|
pCurve1->getClosestPointTo(arpt[i], data.value.ptInt);
|
|
if (arpt[i].distanceTo(data.value.ptInt) > 1.e-6)
|
|
continue;
|
|
pCurve->getClosestPointTo(arpt[i], data.value.ptInt);
|
|
if (arpt[i].distanceTo(data.value.ptInt) > 1.e-6)
|
|
continue;
|
|
break;
|
|
}
|
|
if (i >= iLen)
|
|
continue;
|
|
// 取出交点处给定曲线法向量
|
|
if (pCurve->isKindOf(AcDbLine::desc()))
|
|
{
|
|
data.value.vecRef = ((AcDbLine*)pCurve)->endPoint() - ((AcDbLine*)pCurve)->startPoint();
|
|
data.value.vecRef.rotateBy(PI/2.0, ((AcDbLine*)pCurve)->normal());
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// 取出交点处曲线切向量
|
|
if (pCurve1->isKindOf(AcDbLine::desc()))
|
|
data.value.vecDir = ((AcDbLine*)pCurve1)->endPoint() - ((AcDbLine*)pCurve1)->startPoint();
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// 取出交点在给定曲线上参数值
|
|
pCurve->getParamAtPoint(data.value.ptInt, data.compare);
|
|
CopyMemory(&data.value.adsEnt, (long*)ssSet[l], sizeof(ads_name));
|
|
arParamName.append(data);
|
|
OPENOBJ_END();
|
|
}
|
|
acedSSFree(ssSet);
|
|
OPENOBJ_END();
|
|
|
|
|
|
int iLen = arParamName.length();
|
|
if (iLen <= 0)
|
|
return 0;
|
|
|
|
// 取出与给定曲线垂直的曲线组
|
|
AcArray<CAxisSortPair> arPerpendicular;
|
|
int i = 0;
|
|
for (i = 0; i < iLen; i++)
|
|
{
|
|
if (arParamName[i].value.vecRef.isParallelTo(arParamName[i].value.vecDir))
|
|
arPerpendicular.append(arParamName[i]);
|
|
}
|
|
int iSelLen = arPerpendicular.length();
|
|
if (iSelLen > 1)
|
|
{
|
|
QuickSort(arPerpendicular.asArrayPtr(), iSelLen);
|
|
ads_name_set(arPerpendicular[0].value.adsEnt,ent1);
|
|
ads_name_set(arPerpendicular[iSelLen-1].value.adsEnt,ent2);
|
|
ads_point_set(asDblArray(arPerpendicular[0].value.ptInt),pt1);
|
|
ads_point_set(asDblArray(arPerpendicular[iSelLen-1].value.ptInt),pt2);
|
|
return 1;
|
|
}
|
|
|
|
// 取出平行曲线组
|
|
AcArray<CAxisSortPair> arParallel;
|
|
int j = 0;
|
|
for (j = 0; j < iLen; j++)
|
|
{
|
|
for (i = j+1; i < iLen; i++)
|
|
{
|
|
if (arParamName[i].value.vecDir.isParallelTo(arParamName[j].value.vecDir))
|
|
arParallel.append(arParamName[i]);
|
|
}
|
|
if (arParallel.length() > 0)
|
|
{
|
|
arParallel.append(arParamName[j]);
|
|
break;
|
|
}
|
|
}
|
|
iSelLen = arParallel.length();
|
|
if (iSelLen > 1)
|
|
{
|
|
QuickSort(arParallel.asArrayPtr(), iSelLen);
|
|
ads_name_set(arParallel[0].value.adsEnt,ent1);
|
|
ads_name_set(arParallel[iSelLen-1].value.adsEnt,ent2);
|
|
ads_point_set(asDblArray(arParallel[0].value.ptInt),pt1);
|
|
ads_point_set(asDblArray(arParallel[iSelLen-1].value.ptInt),pt2);
|
|
return 2;
|
|
}
|
|
|
|
// 取出最外侧的夹角线
|
|
QuickSort(arParamName.asArrayPtr(), iLen);
|
|
ads_name_set(arParamName[0].value.adsEnt,ent1);
|
|
ads_name_set(arParamName[iLen-1].value.adsEnt,ent2);
|
|
ads_point_set(asDblArray(arParamName[0].value.ptInt),pt1);
|
|
ads_point_set(asDblArray(arParamName[iLen-1].value.ptInt),pt2);
|
|
return 3;
|
|
}
|
|
|
|
// 返回给定线关系类型:0--无关线,1--平行线
|
|
int KTCADUtilityEx::GetAxisRelationShip(ads_name ent1, ads_name ent2)
|
|
{
|
|
AcDbObjectId id1,id2;
|
|
acdbGetObjectId(id1,ent1);
|
|
acdbGetObjectId(id2,ent2);
|
|
|
|
OPENOBJ_BEGIN(id1, AcDb::kForRead, AcDbCurve, pCurve1);
|
|
OPENOBJ_BEGIN(id2, AcDb::kForRead, AcDbCurve, pCurve2);
|
|
if (pCurve1 == NULL || pCurve2 == NULL)
|
|
return 0;
|
|
|
|
if (pCurve1->isKindOf(AcDbLine::desc()) && pCurve2->isKindOf(AcDbLine::desc()))
|
|
{
|
|
AcGePoint3d pt1, pt2, pt3, pt4, pt5, pt6;
|
|
pt1 = ((AcDbLine*)pCurve1)->startPoint();
|
|
pt2 = ((AcDbLine*)pCurve1)->endPoint();
|
|
pt3 = ((AcDbLine*)pCurve2)->startPoint();
|
|
pt4 = ((AcDbLine*)pCurve2)->endPoint();
|
|
AcGeVector3d vec1, vec2;
|
|
vec1 = pt2 - pt1;
|
|
vec2 = pt4 - pt3;
|
|
BOOL bCollinear = ((pt4 - pt1).isParallelTo(pt3 - pt1) || (pt4 - pt2).isParallelTo(pt3 - pt2));
|
|
if (vec1.isParallelTo(vec2) && !bCollinear) // 平行且不重合直线
|
|
return 1;
|
|
else
|
|
return 2;
|
|
}
|
|
OPENOBJ_END();
|
|
OPENOBJ_END();
|
|
return 0;
|
|
}
|
|
|
|
int KTCADUtilityEx::SortParallelAxisLine(AcDbObjectIdArray& ssResult)
|
|
{
|
|
// 取得垂直平行线的向量
|
|
AcGePoint3d pt;
|
|
AcGeVector3d vec;
|
|
int lLen = ssResult.length();
|
|
for (int l = 0; l < lLen; l++)
|
|
{
|
|
OPENOBJ_BEGIN(ssResult[l], AcDb::kForRead, AcDbLine, pLine);
|
|
if (pLine == NULL)
|
|
continue;
|
|
pt = pLine->startPoint();
|
|
vec = pLine->endPoint() - pt;
|
|
vec.rotateBy(PI/2.0, pLine->normal());
|
|
if (vec.length() > 1.e-6)
|
|
break;
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
// 排序数据
|
|
typedef CSortPair<double, AcDbObjectId, DoubleCompare> CAxisSortPair;
|
|
AcArray<CAxisSortPair> arParamName;
|
|
CAxisSortPair data;
|
|
|
|
// 从左边到右边,从下边到上边排序
|
|
double dAngle = ads_angle(asDblArray(CKTCadUtility::Wcs2Ucs(pt)),
|
|
asDblArray(CKTCadUtility::Wcs2Ucs(pt + vec)));
|
|
if (dAngle > PI * 3.0 / 4.0 && dAngle <= PI * 7.0 / 4.0)
|
|
vec.negate();
|
|
|
|
AcDbXline xline;
|
|
xline.setBasePoint(pt); xline.setUnitDir(vec);
|
|
for (int l = 0; l < lLen; l++)
|
|
{
|
|
OPENOBJ_BEGIN(ssResult[l], AcDb::kForRead, AcDbLine, pLine);
|
|
AcGePoint3dArray arpt;
|
|
if (xline.intersectWith(pLine, AcDb::kExtendBoth, arpt) != Acad::eOk || arpt.length() <= 0)
|
|
continue;
|
|
xline.getClosestPointTo(arpt[0], pt, Adesk::kTrue);
|
|
xline.getParamAtPoint(pt, data.compare);
|
|
data.value = ssResult[l];
|
|
arParamName.append(data);
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
int iLen = arParamName.length();
|
|
QuickSort(arParamName.asArrayPtr(), iLen);
|
|
|
|
ssResult.setLogicalLength(0);
|
|
for (int i = 0; i < iLen; i++)
|
|
{
|
|
ssResult.append(arParamName[i].value);
|
|
}
|
|
return iLen;
|
|
}
|
|
|
|
// 取得一个块引用属性
|
|
BOOL KTCADUtilityEx::GetAttribute(AcDbBlockReference* pRef, LPCTSTR pszTag, CString& sValue)
|
|
{
|
|
AcDbObjectIterator* pIT = pRef->attributeIterator();
|
|
if (pIT == NULL)
|
|
return FALSE;
|
|
|
|
BOOL bFind = FALSE;
|
|
LPTSTR pszTemp = NULL;
|
|
AcDbObjectId id;
|
|
for (pIT->start(); !pIT->done(); pIT->step())
|
|
{
|
|
id = pIT->objectId();
|
|
if (!id.isValid())
|
|
continue;
|
|
OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbAttribute, pAttr);
|
|
if (pAttr == NULL)
|
|
continue;
|
|
pszTemp = pAttr->tag();
|
|
if (_tcscmp(pszTemp, pszTag) == 0)
|
|
{
|
|
acutDelString(pszTemp);
|
|
pszTemp = pAttr->textString();
|
|
sValue = pszTemp;
|
|
acutDelString(pszTemp);
|
|
bFind = TRUE;
|
|
break;
|
|
}
|
|
acutDelString(pszTemp);
|
|
OPENOBJ_END();
|
|
}
|
|
DELETE_PTR(pIT);
|
|
return bFind;
|
|
}
|
|
|
|
CString KTCADUtilityEx::GetNewAxisLabel(CString sLabel, BOOL bPostfix, int iStep)
|
|
{
|
|
if (sLabel.IsEmpty())
|
|
return sLabel;
|
|
|
|
CString sLabelCharSet = _T("ABCDEFGHJKLMNPQRSTUVWXYabcdefghjklmnpqrstuvwxy");
|
|
|
|
int iFind;
|
|
CString sRet;
|
|
int iLen = sLabel.GetLength() - 1;
|
|
if (bPostfix)
|
|
{
|
|
int i(iLen);
|
|
for (i = iLen; i >= 0 && _istdigit(sLabel[i]); i--) ;
|
|
if (i == iLen) // 是字母
|
|
{
|
|
iFind = sLabelCharSet.Find(sLabel[i]);
|
|
if (iFind < 0)
|
|
sRet = sLabel;
|
|
else
|
|
{
|
|
iFind += iStep;
|
|
if (iFind < 0)
|
|
iFind = 0;
|
|
if (iFind >= sLabelCharSet.GetLength())
|
|
iFind = sLabelCharSet.GetLength() - 1;
|
|
sRet.Format(_T("%s%c"), sLabel.Left(i), sLabelCharSet[iFind]);
|
|
}
|
|
}
|
|
else // 是数字
|
|
{
|
|
i++;
|
|
sRet.Format(_T("%s%d"), sLabel.Left(i), _ttoi(sLabel.Mid(i)) + iStep);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int i(0);
|
|
for (i = 0; i <= iLen && _istdigit(sLabel[i]); i++) ;
|
|
if (i == 0) // 是字母
|
|
{
|
|
iFind = sLabelCharSet.Find(sLabel[i]);
|
|
if (iFind < 0)
|
|
sRet = sLabel;
|
|
else
|
|
{
|
|
iFind += iStep;
|
|
if (iFind < 0)
|
|
iFind = 0;
|
|
if (iFind >= sLabelCharSet.GetLength())
|
|
iFind = sLabelCharSet.GetLength() - 1;
|
|
sRet.Format(_T("%c%s"), sLabelCharSet[iFind], sLabel.Mid(i+1));
|
|
}
|
|
}
|
|
else // 是数字
|
|
{
|
|
sRet.Format(_T("%d%s"), _ttoi(sLabel.Left(i)) + iStep, sLabel.Mid(i));
|
|
}
|
|
}
|
|
return sRet;
|
|
}
|
|
|
|
AcDbObjectId KTCADUtilityEx::InsertBlock(LPCTSTR pszFileName, LPCTSTR pszSrcName, LPCTSTR pszDestName, AcDbDatabase* pDb, BOOL bReplace)
|
|
{
|
|
AcDbObjectId id;
|
|
|
|
CString sBlkName = pszDestName;
|
|
if (sBlkName.IsEmpty())
|
|
{
|
|
sBlkName = pszFileName;
|
|
int iFind = sBlkName.ReverseFind(_T('\\')) + 1;
|
|
if (iFind > 0)
|
|
sBlkName = sBlkName.Mid(iFind);
|
|
iFind = sBlkName.ReverseFind(_T('.'));
|
|
if (iFind >= 0)
|
|
sBlkName = sBlkName.Left(iFind);
|
|
}
|
|
|
|
if (pDb == NULL)
|
|
pDb = acdbCurDwg();
|
|
|
|
AcDbBlockTable* pBT = NULL;
|
|
pDb->getBlockTable(pBT, AcDb::kForRead);
|
|
if (pBT == NULL)
|
|
return id;
|
|
if (pBT->has(sBlkName))
|
|
{
|
|
pBT->getAt(sBlkName, id);
|
|
if (bReplace)
|
|
{
|
|
OPENOBJ_BEGIN(id, AcDb::kForWrite, AcDbBlockTableRecord, pBTR);
|
|
if (pBTR == NULL)
|
|
{
|
|
pBT->close();
|
|
return id;
|
|
}
|
|
pBTR->erase();
|
|
pBTR->close();
|
|
OPENOBJ_END();
|
|
}
|
|
else
|
|
{
|
|
pBT->close();
|
|
return id;
|
|
}
|
|
|
|
}
|
|
pBT->close();
|
|
|
|
CString sPath;
|
|
KTSetting::GetKTPsPath(sPath);
|
|
|
|
CString fullFile = sPath + _T("Support\\Cells\\") + pszFileName;
|
|
|
|
AcDbDatabase db(Adesk::kFalse);
|
|
if (db.readDwgFile(fullFile) != Acad::eOk)
|
|
return id;
|
|
|
|
if (pszSrcName != NULL && _tcslen(pszSrcName) > 0)
|
|
pDb->insert(id, pszSrcName, sBlkName, &db);
|
|
else
|
|
pDb->insert(id, sBlkName, &db);
|
|
|
|
return id;
|
|
}
|
|
|
|
// 取得平行线标注初始参数
|
|
BOOL KTCADUtilityEx::GetParallelAxisLineInitParam(const AcGePoint3d& ptPick, AcDbObjectId& entBL, AcDbObjectId& entTR, BOOL bCrossSelect,
|
|
AcGePoint3d& ptCurStart, AcGePoint3d& ptCurEnd, AcGePoint3d& ptOthStart, AcGePoint3d& ptOthEnd,
|
|
AcGeVector3d& vecCur, AcGeVector3d& vecOth)
|
|
{
|
|
OPENOBJ_BEGIN(entBL, AcDb::kForRead, AcDbLine, pLine1);
|
|
OPENOBJ_BEGIN(entTR, AcDb::kForRead, AcDbLine, pLine2);
|
|
if (pLine1 == NULL || pLine2 == NULL)
|
|
return FALSE;
|
|
|
|
// 求开始方向
|
|
AcGeVector3d vec = pLine1->endPoint() - pLine1->startPoint();
|
|
vec.rotateBy(PI/2.0, pLine1->normal());
|
|
AcDbXline line;
|
|
line.setBasePoint(ptPick);
|
|
line.setUnitDir(vec);
|
|
AcGePoint3dArray arpt1;
|
|
if (line.intersectWith(pLine1, AcDb::kExtendArg, arpt1) != Acad::eOk || arpt1.length() <= 0)
|
|
return FALSE;
|
|
AcGePoint3dArray arpt2;
|
|
if (line.intersectWith(pLine2, AcDb::kExtendArg, arpt2) != Acad::eOk || arpt2.length() <= 0)
|
|
return FALSE;
|
|
double dLen1 = arpt1[0].distanceTo(ptPick);
|
|
double dLen2 = arpt2[0].distanceTo(ptPick);
|
|
// 从左到右,从下往上
|
|
if (bCrossSelect || dLen1 < dLen2)
|
|
{
|
|
if (ptPick.distanceTo(pLine1->startPoint()) < ptPick.distanceTo(pLine1->endPoint()))
|
|
{
|
|
ptCurStart = pLine1->startPoint();
|
|
ptOthStart = pLine1->endPoint();
|
|
}
|
|
else
|
|
{
|
|
ptCurStart = pLine1->endPoint();
|
|
ptOthStart = pLine1->startPoint();
|
|
}
|
|
vec = ptCurStart - ptOthStart;
|
|
vec.rotateBy(PI/2.0, pLine1->normal());
|
|
line.setBasePoint(ptCurStart);
|
|
line.setUnitDir(vec);
|
|
AcGePoint3dArray arpt3;
|
|
if (line.intersectWith(pLine2, AcDb::kExtendArg, arpt3) != Acad::eOk || arpt3.length() <= 0)
|
|
return FALSE;
|
|
ptCurEnd = arpt3[0];
|
|
line.setBasePoint(ptOthStart);
|
|
line.setUnitDir(vec);
|
|
AcGePoint3dArray arpt4;
|
|
if (line.intersectWith(pLine2, AcDb::kExtendArg, arpt4) != Acad::eOk || arpt4.length() <= 0)
|
|
return FALSE;
|
|
ptOthEnd = arpt4[0];
|
|
|
|
vecCur = ptCurStart - ptOthStart;
|
|
vecCur.normalize();
|
|
vecOth = -vecCur;
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
if (ptPick.distanceTo(pLine2->startPoint()) < ptPick.distanceTo(pLine2->endPoint()))
|
|
{
|
|
ptCurStart = pLine2->startPoint();
|
|
ptOthStart = pLine2->endPoint();
|
|
}
|
|
else
|
|
{
|
|
ptCurStart = pLine2->endPoint();
|
|
ptOthStart = pLine2->startPoint();
|
|
}
|
|
vec = ptCurStart - ptOthStart;
|
|
vec.rotateBy(PI/2.0, pLine2->normal());
|
|
line.setBasePoint(ptCurStart);
|
|
line.setUnitDir(vec);
|
|
AcGePoint3dArray arpt3;
|
|
if (line.intersectWith(pLine1, AcDb::kExtendArg, arpt3) != Acad::eOk || arpt3.length() <= 0)
|
|
return FALSE;
|
|
ptCurEnd = arpt3[0];
|
|
line.setBasePoint(ptOthStart);
|
|
line.setUnitDir(vec);
|
|
AcGePoint3dArray arpt4;
|
|
if (line.intersectWith(pLine1, AcDb::kExtendArg, arpt4) != Acad::eOk || arpt4.length() <= 0)
|
|
return FALSE;
|
|
ptOthEnd = arpt4[0];
|
|
|
|
vecCur = ptCurStart - ptOthStart;
|
|
vecCur.normalize();
|
|
vecOth = -vecCur;
|
|
return TRUE;
|
|
}
|
|
OPENOBJ_END();
|
|
OPENOBJ_END();
|
|
return FALSE;
|
|
}
|
|
|
|
AcGePoint3d KTCADUtilityEx::GetCenterPoint(const AcGePoint3d& pt1, const AcGePoint3d& pt2)
|
|
{
|
|
return AcGePoint3d((pt1.x + pt2.x) / 2.0, (pt1.y + pt2.y) / 2.0, (pt1.z + pt2.z) / 2.0);
|
|
}
|
|
|
|
// 求由点和向量给定的直线是否和给定的曲线相交
|
|
BOOL KTCADUtilityEx::IsLinesIntersect(const AcGePoint3d& ptBase, const AcGeVector3d& vecDir, AcDbObjectId& ent)
|
|
{
|
|
OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbCurve, pCurve);
|
|
if (pCurve == NULL)
|
|
return FALSE;
|
|
|
|
AcDbXline xline;
|
|
xline.setBasePoint(ptBase);
|
|
xline.setUnitDir(vecDir);
|
|
AcGePoint3dArray arpt;
|
|
if (xline.intersectWith(pCurve, AcDb::kExtendArg, arpt) != Acad::eOk || arpt.length() <= 0)
|
|
return FALSE;
|
|
|
|
AcGePoint3d pt;
|
|
pCurve->getClosestPointTo(arpt[0], pt);
|
|
return (pt == arpt[0]);
|
|
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
// 求两平行线间的距离
|
|
double KTCADUtilityEx::GetParallelAxisLineInterval(AcDbObjectId& ent1, AcDbObjectId& ent2)
|
|
{
|
|
OPENOBJ_BEGIN(ent1, AcDb::kForRead, AcDbLine, pLine1);
|
|
OPENOBJ_BEGIN(ent2, AcDb::kForRead, AcDbLine, pLine2);
|
|
if (pLine1 == NULL || pLine2 == NULL)
|
|
return 0.0;
|
|
|
|
AcGeVector3d vec = pLine1->endPoint() - pLine1->startPoint();
|
|
vec.rotateBy(PI/2.0, pLine1->normal());
|
|
|
|
AcDbXline xline;
|
|
xline.setBasePoint(pLine1->startPoint());
|
|
xline.setUnitDir(vec);
|
|
|
|
AcGePoint3dArray arpt1;
|
|
if (xline.intersectWith(pLine1, AcDb::kExtendArg, arpt1) != Acad::eOk || arpt1.length() <= 0)
|
|
return 0.0;
|
|
AcGePoint3dArray arpt2;
|
|
if (xline.intersectWith(pLine2, AcDb::kExtendArg, arpt2) != Acad::eOk || arpt2.length() <= 0)
|
|
return 0.0;
|
|
|
|
return arpt1[0].distanceTo(arpt2[0]);
|
|
OPENOBJ_END();
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
DxfList::DxfList(AcDbObjectId id)
|
|
{
|
|
ads_name adsName;
|
|
acdbGetAdsName(adsName, id);
|
|
m_pCur = m_pBuf = acdbEntGet(adsName);
|
|
}
|
|
|
|
DxfList::DxfList(ads_name sName)
|
|
{
|
|
m_pCur = m_pBuf = acdbEntGet(sName);
|
|
}
|
|
DxfList::~DxfList()
|
|
{
|
|
if(m_pBuf != NULL)
|
|
acutRelRb(m_pBuf);
|
|
}
|
|
|
|
bool DxfList::isNull()
|
|
{
|
|
return m_pBuf == NULL;
|
|
}
|
|
|
|
const resbuf* DxfList::getDxfField(AcDb::DxfCode nCode)
|
|
{
|
|
if (m_pBuf == NULL)
|
|
return NULL;
|
|
|
|
resbuf* pBuf = m_pBuf;
|
|
for (; pBuf!=NULL; pBuf=pBuf->rbnext)
|
|
{
|
|
if (pBuf->restype == nCode)
|
|
{
|
|
m_pCur = pBuf;
|
|
return pBuf;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
const resbuf* DxfList::NextDxfField(AcDb::DxfCode nCode)
|
|
{
|
|
if (m_pCur == NULL)
|
|
return NULL;
|
|
|
|
m_pCur = m_pCur->rbnext;
|
|
for (; m_pCur!=NULL; m_pCur=m_pCur->rbnext)
|
|
{
|
|
if (m_pCur->restype == nCode)
|
|
{
|
|
return m_pCur;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
AcDbObjectId KTCADUtilityEx::AppendAttribute(AcDbBlockReference* pRef, LPCTSTR pszTag, LPCTSTR pszValue)
|
|
{
|
|
AcDbObjectId id;
|
|
|
|
OPENOBJ_BEGIN(pRef->blockTableRecord(), AcDb::kForRead, AcDbBlockTableRecord, pBTR);
|
|
if (pBTR == NULL)
|
|
return id;
|
|
|
|
AcDbBlockTableRecordIterator* pIT = NULL;
|
|
pBTR->newIterator(pIT);
|
|
if (pIT == NULL)
|
|
return id;
|
|
|
|
AcGePoint3d pt;
|
|
|
|
BOOL bReadOnly;
|
|
AcDbEntity* pEnt;
|
|
AcDbAttribute* pAttr;
|
|
AcDbAttributeDefinition* pAttDef;
|
|
for (pIT->start(); !pIT->done(); pIT->step())
|
|
{
|
|
if (pIT->getEntity(pEnt, AcDb::kForRead) != Acad::eOk)
|
|
continue;
|
|
|
|
pAttDef = AcDbAttributeDefinition::cast(pEnt);
|
|
if (pAttDef == NULL || pAttDef->isConstant())
|
|
{
|
|
pEnt->close();
|
|
continue;
|
|
}
|
|
|
|
LPTSTR pszTemp = pAttDef->tag();
|
|
if (_tcscmp(pszTemp, pszTag) != 0)
|
|
{
|
|
acutDelString(pszTemp);
|
|
pEnt->close();
|
|
continue;
|
|
}
|
|
acutDelString(pszTemp);
|
|
|
|
bReadOnly = (!pRef->isWriteEnabled());
|
|
if (bReadOnly && pRef->upgradeOpen() != Acad::eOk)
|
|
{
|
|
pEnt->close();
|
|
break;
|
|
}
|
|
|
|
pAttr = new AcDbAttribute(pAttDef->position(), pszValue, pszTag, pAttDef->textStyle());
|
|
pAttr->setPropertiesFrom(pAttDef);
|
|
pAttr->setHeight(pAttDef->height());
|
|
pAttr->setRotation(pAttDef->rotation());
|
|
|
|
pAttr->setHorizontalMode(pAttDef->horizontalMode());
|
|
pAttr->setVerticalMode(pAttDef->verticalMode());
|
|
pt = pAttDef->alignmentPoint();
|
|
pAttr->setAlignmentPoint(pt);
|
|
AcGeMatrix3d mat = pRef->blockTransform();
|
|
pAttr->transformBy(mat);
|
|
|
|
DxfList dxfList(pRef->blockTableRecord());
|
|
const resbuf* pBuf = dxfList.getDxfField(AcDb::kDxfBlockName) ;
|
|
|
|
if(pBuf != NULL)
|
|
{
|
|
int nRes1 = _tcscmp(pBuf->resval.rstring,_T("_AXISO1"));
|
|
int nRes2 = _tcscmp(pBuf->resval.rstring,_T("_AXISO2"));
|
|
|
|
if(nRes1==0 || nRes2==0)
|
|
{
|
|
double dAng = (pRef->rotation());
|
|
dAng = CKTCadUtility::Wcs2Ucs(dAng);
|
|
AcGeVector3d vec = CKTCadUtility::GetUcsYAxis();
|
|
vec.rotateBy(dAng,CKTCadUtility::GetUcsZAxis());
|
|
double dScale = 100.0;
|
|
|
|
double dHeight = 4.0 * dScale;
|
|
AcGeVector3d offset ;
|
|
if(nRes1 ==0)offset = vec*dHeight;
|
|
else offset = -vec*dHeight;
|
|
|
|
mat.setToRotation(-dAng,CKTCadUtility::GetUcsZAxis(),pRef->position()-offset);
|
|
pAttr->transformBy(mat);
|
|
}
|
|
}
|
|
|
|
pAttDef->close();
|
|
pRef->appendAttribute(id, pAttr);
|
|
pAttr->close();
|
|
|
|
if (bReadOnly)
|
|
pRef->downgradeOpen();
|
|
break;
|
|
}
|
|
DELETE_PTR(pIT);
|
|
return id;
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
AcDbObjectId KTCADUtilityEx::CreateGroup(const AcDbObjectIdArray& aridObj,
|
|
LPCTSTR pszGroupName, bool bSelectable,
|
|
BOOL* bOver, AcDbDatabase* pDb)
|
|
{
|
|
BOOL bAnonymous = (pszGroupName == NULL || _tcslen(pszGroupName) <= 0);
|
|
|
|
if (pDb == NULL)
|
|
pDb = acdbCurDwg();
|
|
|
|
AcDbObjectId id;
|
|
AcDbDictionary* pDict = NULL;
|
|
Acad::ErrorStatus es;
|
|
if ( Acad::eOk != (es = pDb->getGroupDictionary(pDict, AcDb::kForRead) ) )
|
|
{
|
|
return AcDbObjectId::kNull;
|
|
}
|
|
|
|
if (!bAnonymous && pDict->has(pszGroupName))
|
|
{
|
|
pDict->getAt(pszGroupName, id);
|
|
AcDbObject* pObj = NULL;
|
|
if (bOver != NULL && (*bOver) && acdbOpenObject(pObj, id, AcDb::kForWrite) == Acad::eOk && pObj != NULL)
|
|
{
|
|
pObj->erase();
|
|
pObj->close();
|
|
}
|
|
else
|
|
{
|
|
if (bOver != NULL)
|
|
*bOver = FALSE;
|
|
|
|
if (pObj != NULL)
|
|
pObj->close();
|
|
|
|
pDict->close();
|
|
|
|
return id;
|
|
}
|
|
}
|
|
|
|
if (pDict->upgradeOpen() != Acad::eOk)
|
|
{
|
|
pDict->close();
|
|
return AcDbObjectId::kNull;
|
|
}
|
|
|
|
if (aridObj.length() == 0)
|
|
{
|
|
pDict->close();
|
|
return AcDbObjectId::kNull;
|
|
}
|
|
|
|
AcDbGroup* pGroup = new AcDbGroup;
|
|
ASSERT(pGroup != NULL);
|
|
|
|
pDict->setAt(_T("*A"), pGroup, id);
|
|
pDict->close();
|
|
pDict->downgradeOpen();
|
|
ASSERT(!id.isNull());
|
|
|
|
pGroup->setSelectable(bSelectable);
|
|
if (bAnonymous)
|
|
pGroup->setAnonymous();
|
|
else
|
|
pGroup->setName((LPTSTR)pszGroupName);
|
|
|
|
Acad::ErrorStatus e = pGroup->append(aridObj);
|
|
|
|
pGroup->close();
|
|
|
|
return id;
|
|
}
|
|
|
|
// 余弦定律求三角形顶角
|
|
static double GetTriangleAngle(const AcGePoint3d ptC, const AcGePoint3d ptA, const AcGePoint3d ptB)
|
|
{
|
|
double dA = ptC.distanceTo(ptB);
|
|
double dB = ptC.distanceTo(ptA);
|
|
double dC = ptA.distanceTo(ptB);
|
|
return acos((dA * dA + dB * dB - dC * dC) / (2.0 * dA * dB));
|
|
}
|
|
|
|
// 海伦公式求三角形面积
|
|
static double GetTriangleArea(const AcGePoint3d ptA, const AcGePoint3d ptB, const AcGePoint3d ptC)
|
|
{
|
|
double dA = ptC.distanceTo(ptB);
|
|
double dB = ptC.distanceTo(ptA);
|
|
double dC = ptA.distanceTo(ptB);
|
|
double dS = (dA + dB + dC) / 2.0;
|
|
double dAll = dS * (dS - dA) * (dS - dB) * (dS - dC);
|
|
return (dAll > 0.0 ? sqrt(dAll) : 0.0);
|
|
}
|
|
|
|
int KTCADUtilityEx::IsPointInPoly(int nvert, float *vertx, float *verty, float testx, float testy)
|
|
{
|
|
int i, j, c = 0;
|
|
for (i = 0, j = nvert-1; i < nvert; j = i++)
|
|
{
|
|
if ( ( ( verty[i] > testy) != (verty[j] > testy)) &&
|
|
(testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i]) )
|
|
c = !c;
|
|
}
|
|
return c;
|
|
}
|
|
|
|
// 判断点是否在边界线内,边界点必须连续
|
|
BOOL KTCADUtilityEx::IsPointInBoundary(const AcGePoint3d& ptTest, const AcGePoint3d& pt1, const AcGePoint3d& pt2, const AcGePoint3d& pt3, const AcGePoint3d& pt4)
|
|
{
|
|
float* pvertx = new float[4];
|
|
float* pverty = new float[4];
|
|
int nvert = 4;
|
|
|
|
pvertx[0] = (float)(pt1.x);
|
|
pvertx[1] = (float)(pt2.x);
|
|
pvertx[2] = (float)(pt3.x);
|
|
pvertx[3] = (float)(pt4.x);
|
|
|
|
pverty[0] = (float)(pt1.y);
|
|
pverty[1] = (float)(pt2.y);
|
|
pverty[2] = (float)(pt3.y);
|
|
pverty[3] = (float)(pt4.y);
|
|
|
|
float ftestX = (float)(ptTest.x);
|
|
float ftestY = (float)(ptTest.y);
|
|
|
|
int nFlag = IsPointInPoly(nvert,pvertx,pverty,ftestX,ftestY);
|
|
|
|
delete [] pvertx;
|
|
delete [] pverty;
|
|
|
|
return nFlag > 0 ? TRUE : FALSE;
|
|
}
|
|
|
|
static AcGePoint3d Min(const AcGePoint3d& pt1,const AcGePoint3d& pt2)
|
|
{
|
|
return AcGePoint3d(__min(pt1.x,pt2.x),__min(pt1.y,pt2.y),__min(pt1.z,pt2.z));
|
|
}
|
|
|
|
static AcGePoint3d Max(const AcGePoint3d& pt1,const AcGePoint3d& pt2)
|
|
{
|
|
return AcGePoint3d(__max(pt1.x,pt2.x),__max(pt1.y,pt2.y),__max(pt1.z,pt2.z));
|
|
}
|
|
|
|
BOOL KTCADUtilityEx::IsPointInBoundary(const AcGePoint3d& ptTest, const AcGePoint3d& pt1, const AcGePoint3d& pt2)
|
|
{
|
|
AcGePoint3d ptMin = Min(pt1, pt2);
|
|
AcGePoint3d ptMax = Max(pt1, pt2);
|
|
return (!(ptTest.x < ptMin.x || ptTest.x > ptMax.x
|
|
|| ptTest.y < ptMin.y || ptTest.y > ptMax.y
|
|
|| ptTest.z < ptMin.z || ptTest.z > ptMax.z));
|
|
}
|
|
|
|
BOOL KTCADUtilityEx::BreakCurve(AcDbObjectId& ent, const AcGePoint3d& pt1, const AcGePoint3d& pt2,
|
|
AcDbObjectIdArray& arid, const AcGePoint3d* ptHit)
|
|
{
|
|
OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbCurve, pCurve);
|
|
if (pCurve == NULL)
|
|
return FALSE;
|
|
|
|
BOOL bClosed = (pCurve->isClosed() && ptHit != NULL);
|
|
|
|
AcGePoint3d ptStart, ptEnd;
|
|
pCurve->getStartPoint(ptStart);
|
|
pCurve->getEndPoint(ptEnd);
|
|
|
|
AcGePoint3dArray arpt;
|
|
if (pt1 != ptStart && pt1 != ptEnd)
|
|
arpt.append(pt1);
|
|
if (bClosed && *ptHit != ptStart && *ptHit != ptEnd)
|
|
arpt.append(*ptHit);
|
|
if (pt2 != ptStart && pt2 != ptEnd)
|
|
arpt.append(pt2);
|
|
|
|
AcDbVoidPtrArray arpCurve;
|
|
if (arpt.length() <= 0 || pCurve->getSplitCurves(arpt, arpCurve) != Acad::eOk)
|
|
return FALSE;
|
|
|
|
BOOL bDelete;
|
|
double dDist;
|
|
AcDbObjectId id;
|
|
AcDbCurve* pSub;
|
|
struct resbuf* rb = pCurve->xData();
|
|
|
|
int iLen = arpCurve.length();
|
|
int i = 0;
|
|
for (i = 0; i < iLen; i++)
|
|
{
|
|
pSub = (AcDbCurve*)arpCurve[i];
|
|
if (pSub == NULL)
|
|
continue;
|
|
|
|
pSub->getStartPoint(ptStart);
|
|
pSub->getEndPoint(ptEnd);
|
|
|
|
dDist = 0.0;
|
|
pSub->getDistAtPoint(ptEnd, dDist);
|
|
|
|
bDelete = FALSE;
|
|
if (dDist < 0.1)
|
|
{
|
|
bDelete = TRUE;
|
|
}
|
|
else if (bClosed)
|
|
{
|
|
if (ptStart == pt1 && ptEnd == *ptHit || ptStart == *ptHit && ptEnd == pt1
|
|
|| ptStart == pt2 && ptEnd == *ptHit || ptStart == *ptHit && ptEnd == pt2)
|
|
bDelete = TRUE;
|
|
}
|
|
else if (ptStart == pt1 && ptEnd == pt2 || ptStart == pt2 && ptEnd == pt1)
|
|
{
|
|
bDelete = TRUE;
|
|
}
|
|
|
|
if (bDelete)
|
|
{
|
|
DELETE_PTR(pSub);
|
|
continue;
|
|
}
|
|
|
|
pSub->setPropertiesFrom(pCurve);
|
|
pSub->setXData(rb);
|
|
CKTCadUtility::AddToBlockTableRecord(id,pSub);
|
|
pSub->close();
|
|
arid.append(id);
|
|
}
|
|
|
|
if (iLen > 0 && pCurve->upgradeOpen() == Acad::eOk)
|
|
pCurve->erase();
|
|
OPENOBJ_END();
|
|
return TRUE;
|
|
}
|
|
|
|
int KTCADUtilityEx::WallParamAngleSortCompare(double* arg1, double* arg2)
|
|
{
|
|
int iRet = KTCADUtilityEx::DoubleCompare(arg1[0], arg2[0]);
|
|
if (iRet == 0)
|
|
iRet = KTCADUtilityEx::DoubleCompare(arg1[1], arg2[1]);
|
|
return iRet;
|
|
}
|
|
|
|
double KTCADUtilityEx::GetBulge(const AcGePoint3d& ptStart, const AcGePoint3d& ptEnd, double dRadius, BOOL bClockWise)
|
|
{
|
|
double dLen = ptStart.distanceTo(ptEnd);
|
|
if (dLen > 2.0 * dRadius)
|
|
return (bClockWise ? -1.0 : 1.0);
|
|
|
|
double dBulge = tan(acos(1 - (dLen * dLen) / (2.0 * dRadius * dRadius)) / 4.0);
|
|
return (bClockWise ? -dBulge : dBulge);
|
|
}
|
|
|
|
BOOL KTCADUtilityEx::IsPointAtSameSide(const AcGePlane& plane, const AcGePoint3d& pt1, const AcGePoint3d& pt2)
|
|
{
|
|
if (plane.isOn(pt1) || plane.isOn(pt2))
|
|
return 1;
|
|
|
|
AcGePoint3d ptPrj1 = pt1.project(plane, plane.normal());
|
|
AcGePoint3d ptPrj2 = pt2.project(plane, plane.normal());
|
|
if ((pt1 - ptPrj1).isCodirectionalTo(pt2 - ptPrj2))
|
|
return 2;
|
|
|
|
return 0;
|
|
}
|
|
|
|
double KTCADUtilityEx::GetBulge(const AcGePoint3d& ptStart, const AcGePoint3d& ptEnd, const AcGePoint3d& ptSample)
|
|
{
|
|
if (ptStart == ptEnd)
|
|
return 0.0;
|
|
if (ptStart == ptSample || ptEnd == ptSample)
|
|
return 1.0;
|
|
|
|
AcGeVector3d vec = ptEnd - ptStart;
|
|
vec.normalize();
|
|
vec.rotateBy(vec.angleTo(ptSample - ptStart), CKTCadUtility::GetUcsZAxis());
|
|
|
|
AcGeCircArc3d arc(ptStart, ptSample, ptEnd);
|
|
AcGePlane plane(ptStart, (ptEnd - ptStart).rotateBy(PI/2.0, CKTCadUtility::GetUcsZAxis()));
|
|
|
|
double dLen = ptStart.distanceTo(ptEnd);
|
|
double dAngle = acos(1 - (dLen * dLen) / (2.0 * arc.radius() * arc.radius()));
|
|
if (IsPointAtSameSide(plane, arc.center(), ptSample))
|
|
dAngle = PI * 2.0 - dAngle;
|
|
|
|
double dBulge = tan(dAngle / 4.0);
|
|
AcGePoint3d ptTmp = ptStart + vec * ptSample.distanceTo(ptStart);
|
|
|
|
return ((ptTmp == ptSample) ? -dBulge : dBulge);
|
|
}
|
|
|
|
static void FreeBuffer(int n,AcDbVoidPtrArray& arEntPtrs)
|
|
{
|
|
AcDbEntity* pEnt = NULL;
|
|
while(arEntPtrs.length() > n )
|
|
{
|
|
pEnt = (AcDbEntity*)arEntPtrs.last();
|
|
if (pEnt != NULL)
|
|
{
|
|
pEnt->erase();
|
|
pEnt->close();
|
|
arEntPtrs.removeLast();
|
|
DELETE_PTR(pEnt);
|
|
}
|
|
}
|
|
}
|
|
|
|
AcDbArc* KTCADUtilityEx::FormatArc(const AcGePoint3d& ptGe1,const AcGePoint3d& ptGe2,const AcGePoint3d& ptGe3)
|
|
{
|
|
AcDbArc* pArcThis = NULL;
|
|
AcGeCircArc3d cirArc3d;
|
|
cirArc3d.set(ptGe1,ptGe2,ptGe3);
|
|
|
|
AcGeVector3d vtNorm = cirArc3d.normal();
|
|
if (vtNorm.isParallelTo(AcGeVector3d::kZAxis))
|
|
{
|
|
if (!vtNorm.isCodirectionalTo(AcGeVector3d::kZAxis))
|
|
{
|
|
vtNorm.negate();//相反
|
|
}
|
|
}
|
|
|
|
AcDbCircle cir;
|
|
cir.setCenter(cirArc3d.center());
|
|
cir.setRadius(cirArc3d.radius());
|
|
cir.setNormal(vtNorm);
|
|
|
|
AcGePoint3dArray arPts;
|
|
arPts.append(ptGe1);
|
|
arPts.append(ptGe3);
|
|
|
|
AcDbVoidPtrArray arCurPtrs;
|
|
cir.getSplitCurves(arPts,arCurPtrs);
|
|
|
|
double dPara = 0.0;
|
|
AcDbCurve* pCurve = NULL;
|
|
for (int j = 0;j < arCurPtrs.length();j++)
|
|
{
|
|
pCurve = (AcDbCurve*)arCurPtrs.at(j);
|
|
if (pCurve != NULL)
|
|
{
|
|
if (Acad::eOk == pCurve->getParamAtPoint(ptGe2,dPara))//中点在圆弧上
|
|
{
|
|
AcDbArc* pArc = AcDbArc::cast(pCurve);
|
|
if (pArc != NULL)
|
|
{
|
|
pArcThis = pArc;
|
|
arCurPtrs.removeAt(j);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
FreeBuffer(0,arCurPtrs);
|
|
return pArcThis;
|
|
}
|
|
|
|
AcDbArc* KTCADUtilityEx::FormatArc(const AcGeVector3d& vtMaj,const AcGeVector3d& vtMin,const AcGePoint3d& ptMid,AcGePoint3d& ptFr,double dSweepAngle,double dR,double dRatio,BOOL bdRisL)
|
|
{
|
|
AcGeVector3d vtLast = vtMaj;
|
|
vtLast.negate();
|
|
vtLast.normalize();
|
|
|
|
AcGeVector3d vtNext = vtMin;
|
|
vtNext.normalize();
|
|
|
|
if (vtLast.isParallelTo(vtNext))
|
|
return NULL;
|
|
|
|
double dAngle = 0, dRR = 0, dL = 0, dX = 0;
|
|
dAngle = dSweepAngle;
|
|
|
|
if (bdRisL)
|
|
{
|
|
dL = dR / cos(0.5 * dAngle);
|
|
dX = dL * sin(0.5 * dAngle);
|
|
dRR = dR;
|
|
}
|
|
else
|
|
{
|
|
dRR = dR * dRatio;
|
|
dL = dRR / cos( 0.5 * dAngle);
|
|
dX = dL * sin( 0.5 * dAngle);
|
|
}
|
|
|
|
AcGeVector3d vtHalf = vtLast + vtNext;
|
|
vtHalf.normalize();
|
|
|
|
AcGeVector3d vtNorm = vtLast.crossProduct(vtNext);
|
|
AcGePoint3d ptCen = ptMid + dL * vtHalf;
|
|
|
|
ptFr = ptMid + dX * vtLast;
|
|
|
|
AcGeVector3d vt1 = vtHalf;
|
|
vt1.negate();
|
|
vt1.rotateBy(dAngle / 2.0,vtNorm);
|
|
|
|
vt1.normalize();
|
|
AcGePoint3d pt1 = ptCen + vt1 * dR;
|
|
|
|
vt1 = vtHalf;
|
|
vt1.negate();
|
|
vt1.rotateBy(-dAngle / 2.0,vtNorm);
|
|
vt1.normalize();
|
|
|
|
AcGePoint3d pt2 = ptCen + vt1 * dR;
|
|
|
|
AcDbCircle cir1;
|
|
cir1.setCenter(ptCen);
|
|
cir1.setRadius(dRR);
|
|
cir1.setNormal(vtNorm);
|
|
|
|
cir1.getClosestPointTo(pt1,pt1);
|
|
cir1.getClosestPointTo(pt2,pt2);
|
|
|
|
AcGePlane plan;
|
|
plan.set(ptCen,vtNorm);
|
|
|
|
AcGePoint3dArray arPts;
|
|
arPts.append(pt1);arPts.append(pt2);
|
|
AcDbVoidPtrArray arArcPtrs;
|
|
cir1.getSplitCurves(arPts,arArcPtrs);
|
|
|
|
AcDbLine ln;
|
|
ln.setStartPoint(ptCen);
|
|
ln.setEndPoint(ptMid);
|
|
|
|
KTTempTol tol(1.e-3);
|
|
AcGePoint3dArray arPts1,arPts2;
|
|
AcDbArc* pArcElbow = NULL;
|
|
if (arArcPtrs.length() == 2)
|
|
{
|
|
AcDbArc* pArc1 = (AcDbArc* )arArcPtrs.first();
|
|
AcDbArc* pArc2 = (AcDbArc* )arArcPtrs.last();
|
|
|
|
pArc1->intersectWith(&ln,AcDb::kOnBothOperands,arPts1);
|
|
pArc2->intersectWith(&ln,AcDb::kOnBothOperands,arPts2);
|
|
|
|
AcDbObjectId id;
|
|
if (!arPts1.isEmpty())
|
|
{
|
|
pArcElbow = pArc1;
|
|
DELETE_PTR(pArc2);
|
|
}
|
|
else//ptmid 距离 pArc2近
|
|
{
|
|
pArcElbow = pArc2;
|
|
DELETE_PTR(pArc1);
|
|
}
|
|
}
|
|
return pArcElbow;
|
|
}
|
|
|
|
AcDbCurve* KTCADUtilityEx::ConvertBoundCurve(const AcDbVoidPtrArray& arpCurve,
|
|
AcDbVoidPtrArray& arpResult)
|
|
{
|
|
if (arpCurve.length() <= 0)
|
|
return NULL;
|
|
|
|
AcDbCurve* pRetCurve = NULL;
|
|
|
|
AcDbVoidPtrArray arpEnt(arpCurve);
|
|
AcDbCurve* pCurve = (AcDbCurve*)arpEnt.first();
|
|
ASSERT(pCurve != NULL && pCurve->isKindOf(AcDbCurve::desc()));
|
|
arpEnt.removeFirst();
|
|
arpResult.append(pCurve);
|
|
if (pCurve->isClosed())
|
|
{
|
|
pRetCurve = (AcDbCurve*)pCurve->isA()->create();
|
|
CopyObject(*pCurve, *pRetCurve); // 复杂实体可能需要Deepclone
|
|
return pRetCurve;
|
|
}
|
|
|
|
AcGePoint3d ptStart, ptEnd;
|
|
pCurve->getStartPoint(ptStart);
|
|
pCurve->getEndPoint(ptEnd);
|
|
|
|
AcGePlane plane;
|
|
AcGePoint3d pt3d;
|
|
AcDbPolyline* pPline = NULL;
|
|
double dParam1, dParam2;
|
|
AcGeVector3d vtNorm;
|
|
|
|
if (pCurve->isKindOf(AcDbLine::desc()))
|
|
{
|
|
vtNorm = ((AcDbLine *)pCurve)->normal();
|
|
plane.set(AcGePoint3d::kOrigin, ((AcDbLine*)pCurve)->normal());
|
|
pPline = new AcDbPolyline;
|
|
ASSERT(pPline != NULL);
|
|
pPline->setNormal(plane.normal());
|
|
pPline->addVertexAt(0, ptStart.convert2d(plane));
|
|
pPline->addVertexAt(1, ptEnd.convert2d(plane));
|
|
}
|
|
else if (pCurve->isKindOf(AcDbArc::desc()))
|
|
{
|
|
vtNorm = ((AcDbArc *)pCurve)->normal();
|
|
plane.set(AcGePoint3d::kOrigin, ((AcDbArc*)pCurve)->normal());
|
|
pPline = new AcDbPolyline;
|
|
ASSERT(pPline != NULL);
|
|
pPline->setNormal(plane.normal());
|
|
pCurve->getStartParam(dParam1);
|
|
pCurve->getEndParam(dParam2);
|
|
pCurve->getPointAtParam((dParam1 + dParam2) / 2.0, pt3d);
|
|
|
|
pPline->addVertexAt(0, ptStart.convert2d(plane),
|
|
KTCADUtilityEx::GetBulge(ptStart, ptEnd, pt3d));
|
|
pPline->addVertexAt(1, ptEnd.convert2d(plane));
|
|
|
|
AcGePoint3d pt3dT;
|
|
pPline->getClosestPointTo(pt3d,pt3dT);
|
|
|
|
//校正
|
|
pt3dT.z = pt3d.z;
|
|
if (pt3d.distanceTo(pt3dT) < 1.e-3)//认为相等
|
|
{
|
|
}
|
|
else
|
|
{
|
|
pPline->removeVertexAt(0);
|
|
pPline->removeVertexAt(0);
|
|
|
|
pPline->addVertexAt(0, ptStart.convert2d(plane),
|
|
-KTCADUtilityEx::GetBulge(ptStart, ptEnd, pt3d));
|
|
pPline->addVertexAt(1, ptEnd.convert2d(plane));
|
|
}
|
|
}
|
|
else if (pCurve->isKindOf(AcDbPolyline::desc()))
|
|
{
|
|
vtNorm = ((AcDbPolyline *)pCurve)->normal();
|
|
plane.set(AcGePoint3d::kOrigin, ((AcDbPolyline*)pCurve)->normal());
|
|
pPline = new AcDbPolyline;
|
|
ASSERT(pPline != NULL);
|
|
CopyObject((const AcDbPolyline&)*pCurve, *pPline);
|
|
}
|
|
else if (pCurve->isKindOf(AcDb2dPolyline::desc()))
|
|
{
|
|
AcDbPolyline* pPl = new AcDbPolyline;
|
|
if ( Acad::eOk == pPl->convertFrom((AcDbEntity*&)pCurve,Adesk::kFalse) )
|
|
{
|
|
pPline = pPl;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pRetCurve = (AcDbCurve*)pCurve->isA()->create();
|
|
CopyObject(*pCurve, *pRetCurve);
|
|
return pRetCurve;
|
|
}
|
|
|
|
pRetCurve = pPline;
|
|
|
|
int iLen;
|
|
double dBulge;
|
|
AcGePoint2d pt2d;
|
|
AcGePoint3d pt1, pt2;
|
|
int n, iNum, iIndex;
|
|
while ((iLen = arpEnt.length()) >= 0)
|
|
{
|
|
int i = 0;
|
|
for (i = 0; i < iLen; i++)
|
|
{
|
|
pCurve = (AcDbCurve*)arpEnt[i];
|
|
ASSERT(pCurve != NULL);
|
|
pCurve->getStartPoint(pt1);
|
|
pCurve->getEndPoint(pt2);
|
|
if (pt1.distanceTo(ptStart) < 1.e-1)
|
|
{
|
|
if (pCurve->isKindOf(AcDbLine::desc()))
|
|
{
|
|
pPline->addVertexAt(0, pt2.convert2d(plane));
|
|
}
|
|
else if (pCurve->isKindOf(AcDbArc::desc()))
|
|
{
|
|
pCurve->getStartParam(dParam1);
|
|
pCurve->getEndParam(dParam2);
|
|
pCurve->getPointAtParam((dParam1 + dParam2) / 2.0, pt3d);
|
|
pPline->addVertexAt(0, pt2.convert2d(plane),
|
|
KTCADUtilityEx::GetBulge(pt2, pt1, pt3d));
|
|
}
|
|
else if (pCurve->isKindOf(AcDbPolyline::desc()))
|
|
{
|
|
iNum = ((AcDbPolyline*)pCurve)->numVerts() - 1;
|
|
for (n = 0; n < iNum; n++)
|
|
{
|
|
((AcDbPolyline*)pCurve)->getBulgeAt(n, dBulge);
|
|
((AcDbPolyline*)pCurve)->getPointAt(n+1, pt2d);
|
|
pPline->addVertexAt(0, pt2d, -dBulge);
|
|
}
|
|
}
|
|
ptStart = pt2;
|
|
arpEnt.removeAt(i);
|
|
arpResult.append(pCurve);
|
|
break;
|
|
}
|
|
else if (pt1.distanceTo(ptEnd) < 1.e-1)
|
|
{
|
|
iIndex = pPline->numVerts();
|
|
if (pCurve->isKindOf(AcDbLine::desc()))
|
|
{
|
|
pPline->setBulgeAt(iIndex - 1,0.0);//?????
|
|
pPline->addVertexAt(iIndex, pt2.convert2d(plane));
|
|
}
|
|
else if (pCurve->isKindOf(AcDbArc::desc()))
|
|
{
|
|
pCurve->getStartParam(dParam1);
|
|
pCurve->getEndParam(dParam2);
|
|
pCurve->getPointAtParam((dParam1 + dParam2) / 2.0, pt3d);
|
|
|
|
pPline->setBulgeAt(iIndex-1, KTCADUtilityEx::GetBulge(pt1, pt2, pt3d));
|
|
pPline->addVertexAt(iIndex, pt2.convert2d(plane),0.0);
|
|
}
|
|
else if (pCurve->isKindOf(AcDbPolyline::desc()))
|
|
{
|
|
iNum = ((AcDbPolyline*)pCurve)->numVerts();
|
|
((AcDbPolyline*)pCurve)->getBulgeAt(0, dBulge);
|
|
pPline->setBulgeAt(iIndex-1, dBulge);
|
|
for (n = 1; n < iNum; n++, iIndex++)
|
|
{
|
|
((AcDbPolyline*)pCurve)->getBulgeAt(n, dBulge);
|
|
((AcDbPolyline*)pCurve)->getPointAt(n, pt2d);
|
|
pPline->addVertexAt(iIndex, pt2d, dBulge);
|
|
}
|
|
}
|
|
ptEnd = pt2;
|
|
arpEnt.removeAt(i);
|
|
arpResult.append(pCurve);
|
|
break;
|
|
}
|
|
else if (pt2.distanceTo(ptStart) < 1.e-1)
|
|
{
|
|
if (pCurve->isKindOf(AcDbLine::desc()))
|
|
{
|
|
pPline->addVertexAt(0, pt1.convert2d(plane));
|
|
}
|
|
else if (pCurve->isKindOf(AcDbArc::desc()))
|
|
{
|
|
pCurve->getStartParam(dParam1);
|
|
pCurve->getEndParam(dParam2);
|
|
pCurve->getPointAtParam((dParam1 + dParam2) / 2.0, pt3d);
|
|
pPline->addVertexAt(0, pt1.convert2d(plane),
|
|
KTCADUtilityEx::GetBulge(pt1, pt2, pt3d));
|
|
}
|
|
else if (pCurve->isKindOf(AcDbPolyline::desc()))
|
|
{
|
|
iNum = ((AcDbPolyline*)pCurve)->numVerts() - 2;
|
|
for (n = iNum; n >= 0; n--)
|
|
{
|
|
((AcDbPolyline*)pCurve)->getBulgeAt(n, dBulge);
|
|
((AcDbPolyline*)pCurve)->getPointAt(n, pt2d);
|
|
pPline->addVertexAt(0, pt2d, dBulge);
|
|
}
|
|
}
|
|
ptStart = pt1;
|
|
arpEnt.removeAt(i);
|
|
arpResult.append(pCurve);
|
|
break;
|
|
}
|
|
else if (pt2.distanceTo(ptEnd) < 1.e-1)
|
|
{
|
|
iIndex = pPline->numVerts();
|
|
if (pCurve->isKindOf(AcDbLine::desc()))
|
|
{
|
|
pPline->addVertexAt(iIndex, pt1.convert2d(plane));
|
|
}
|
|
else if (pCurve->isKindOf(AcDbArc::desc()))
|
|
{
|
|
pCurve->getStartParam(dParam1);
|
|
pCurve->getEndParam(dParam2);
|
|
pCurve->getPointAtParam((dParam1 + dParam2) / 2.0, pt3d);
|
|
pPline->setBulgeAt(iIndex-1, KTCADUtilityEx::GetBulge(pt2, pt1, pt3d));
|
|
pPline->addVertexAt(iIndex, pt1.convert2d(plane));
|
|
}
|
|
else if (pCurve->isKindOf(AcDbPolyline::desc()))
|
|
{
|
|
iNum = ((AcDbPolyline*)pCurve)->numVerts() - 2;
|
|
((AcDbPolyline*)pCurve)->getBulgeAt(iNum, dBulge);
|
|
pPline->setBulgeAt(iIndex-1, -dBulge);
|
|
for (n = iNum; n > 0; n--, iIndex++)
|
|
{
|
|
((AcDbPolyline*)pCurve)->getBulgeAt(n-1, dBulge);
|
|
((AcDbPolyline*)pCurve)->getPointAt(n, pt2d);
|
|
pPline->addVertexAt(iIndex, pt2d, -dBulge);
|
|
}
|
|
((AcDbPolyline*)pCurve)->getPointAt(n, pt2d);
|
|
pPline->addVertexAt(iIndex, pt2d);
|
|
}
|
|
ptEnd = pt1;
|
|
arpEnt.removeAt(i);
|
|
arpResult.append(pCurve);
|
|
break;
|
|
}
|
|
}
|
|
if (i >= iLen) break;
|
|
}
|
|
pPline->setClosed(ptStart == ptEnd);
|
|
return pRetCurve;
|
|
}
|
|
|
|
BOOL KTCADUtilityEx::GetIntsectCurves(AcDbBlockReference* pRef, AcDbObjectIdArray& arRes)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL KTCADUtilityEx::IsConnectToOther(const AcGePoint3d& pt, double dExt,
|
|
AcDbObjectId idEntT, const struct resbuf* pRb)
|
|
{
|
|
AcGePoint3d pt1, pt2;
|
|
AcDbObjectId idEnt;
|
|
ads_name ent;
|
|
acdbGetAdsName(ent,idEntT);
|
|
|
|
OPENOBJ_BEGIN(idEntT, AcDb::kForRead, AcDbCurve, pCurve);
|
|
if (pCurve == NULL)
|
|
return FALSE;
|
|
pCurve->getStartPoint(pt1);
|
|
pCurve->getEndPoint(pt2);
|
|
OPENOBJ_END();
|
|
|
|
AcGePoint3d ptNode;
|
|
if (pt.distanceTo(pt1) < pt.distanceTo(pt2))
|
|
ptNode = pt1;
|
|
else
|
|
ptNode = pt2;
|
|
|
|
struct resbuf* pRb2 = acutBuildList(RTDXF0, _T("LINE,ARC,LWPOLYLINE"), 0);
|
|
if (pRb == NULL) pRb = pRb2;
|
|
|
|
ads_name ssSet;
|
|
{
|
|
pt1 = pt2 = CKTCadUtility::Wcs2Ucs(ptNode);
|
|
pt1.x -= dExt;
|
|
pt1.y -= dExt;
|
|
pt2.x += dExt;
|
|
pt2.y += dExt;
|
|
|
|
if (RTNORM == acedSSGet(_T("C"),asDblArray(pt1), asDblArray(pt2), pRb,ssSet))
|
|
{
|
|
acutRelRb(pRb2);
|
|
return FALSE;
|
|
}
|
|
acedSSDel(ent,ssSet);
|
|
}
|
|
|
|
acutRelRb(pRb2);
|
|
Adesk::Int32 lLen = 0;
|
|
acedSSLength(ssSet,&lLen);
|
|
long l = 0l;
|
|
for (l = 0l; l < lLen; l++)
|
|
{
|
|
acedSSName(ssSet,l,ent);
|
|
acdbGetObjectId(idEnt,ent);
|
|
|
|
OPENOBJ_BEGIN(idEnt, AcDb::kForRead, AcDbCurve, pCurve1);
|
|
if (pCurve1 == NULL)
|
|
continue;
|
|
pCurve1->getStartPoint(pt1);
|
|
pCurve1->getEndPoint(pt2);
|
|
if (ptNode == pt1 || ptNode == pt2)
|
|
return TRUE;
|
|
OPENOBJ_END();
|
|
}
|
|
acedSSFree(ssSet);
|
|
return FALSE;
|
|
}
|
|
|
|
AcDbObjectId KTCADUtilityEx::Connect2CurveNearPt(const AcGePoint3d& pt, AcDbObjectId ent1, AcDbObjectId ent2)
|
|
{
|
|
AcDbObjectId id;
|
|
OPENOBJ_BEGIN(ent1, AcDb::kForRead, AcDbCurve, pCurve1);
|
|
OPENOBJ_BEGIN(ent2, AcDb::kForRead, AcDbCurve, pCurve2);
|
|
if (pCurve1 == NULL || pCurve2 == NULL)
|
|
return id;
|
|
|
|
AcDbCurve* pNewCurve = Connect2CurveNearPt(pt, pCurve1, pCurve2);
|
|
if (pNewCurve != NULL)
|
|
{
|
|
CKTCadUtility::AddToBlockTableRecord(id,pNewCurve);
|
|
pNewCurve->close();
|
|
if (pCurve1->upgradeOpen() == Acad::eOk)
|
|
pCurve1->erase();
|
|
if (pCurve2->upgradeOpen() == Acad::eOk)
|
|
pCurve2->erase();
|
|
|
|
return id;
|
|
}
|
|
|
|
OPENOBJ_END();
|
|
OPENOBJ_END();
|
|
return id;
|
|
}
|
|
|
|
// 将两圆弧点在圆周上排序, 返回1为整圆,2为重弧, 3为单弧,4为在两弧小角处合并排序,5为在两弧大角处合并排序
|
|
BOOL KTCADUtilityEx::Sort2ArcPoint(const AcGePoint3d& ptOrg, const AcGePoint3d& pt1S, const AcGePoint3d& pt1E, const AcGePoint3d& pt1,
|
|
const AcGePoint3d& pt2S, const AcGePoint3d& pt2E, const AcGePoint3d& pt2, AcGePoint3dArray& arpt,
|
|
BOOL bJointAtMinAngle)
|
|
{
|
|
double dRadius = 1000.0;
|
|
AcGePoint3d ptA1S = ptOrg + (pt1S - ptOrg).normal() * dRadius;
|
|
AcGePoint3d ptA1E = ptOrg + (pt1E - ptOrg).normal() * dRadius;
|
|
AcGePoint3d ptA1 = ptOrg + (pt1 - ptOrg).normal() * dRadius;
|
|
AcGePoint3d ptA2S = ptOrg + (pt2S - ptOrg).normal() * dRadius;
|
|
AcGePoint3d ptA2E = ptOrg + (pt2E - ptOrg).normal() * dRadius;
|
|
AcGePoint3d ptA2 = ptOrg + (pt2 - ptOrg).normal() * dRadius;
|
|
|
|
AcGeCircArc3d geArc1(ptA1S, ptA1, ptA1E);
|
|
AcGeCircArc3d geArc2(ptA2S, ptA2, ptA2E);
|
|
|
|
if (GetBulge(geArc1.startPoint(), geArc1.endPoint(), ptA1) < 0.0)
|
|
geArc1.reverseParam();
|
|
if (GetBulge(geArc2.startPoint(), geArc2.endPoint(), ptA2) < 0.0)
|
|
geArc2.reverseParam();
|
|
|
|
AcGePoint3d pt1Sp = geArc1.startPoint();
|
|
AcGePoint3d pt1Ep = geArc1.endPoint();
|
|
AcGePoint3d pt2Sp = geArc2.startPoint();
|
|
AcGePoint3d pt2Ep = geArc2.endPoint();
|
|
|
|
int iType = 0;
|
|
AcGeCircArc3d geArc;
|
|
if (geArc1.isOn(pt2Sp))
|
|
{
|
|
if (geArc1.isOn(pt2Ep))
|
|
{
|
|
if (geArc1.paramOf(pt2Sp) > geArc1.paramOf(pt2Ep))
|
|
{
|
|
iType = 1;
|
|
geArc.set(geArc1.center(), geArc1.normal(), geArc1.radius());
|
|
}
|
|
else
|
|
{
|
|
iType = 2;
|
|
geArc = geArc1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iType = 3;
|
|
geArc.set(pt1Sp, pt1Ep, pt2Ep);
|
|
}
|
|
}
|
|
else if (geArc1.isOn(pt2Ep))
|
|
{
|
|
if (geArc1.isOn(pt2Sp))
|
|
{
|
|
if (geArc1.paramOf(pt2Sp) > geArc1.paramOf(pt2Ep))
|
|
{
|
|
iType = 1;
|
|
geArc.set(geArc1.center(), geArc1.normal(), geArc1.radius());
|
|
}
|
|
else
|
|
{
|
|
iType = 2;
|
|
geArc = geArc1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iType = 3;
|
|
geArc.set(pt2Sp, pt1Sp, pt1Ep);
|
|
}
|
|
}
|
|
else if (geArc2.isOn(pt1Sp))
|
|
{
|
|
if (geArc2.isOn(pt1Ep))
|
|
{
|
|
if (geArc2.paramOf(pt1Sp) > geArc2.paramOf(pt1Ep))
|
|
{
|
|
iType = 1;
|
|
geArc.set(geArc2.center(), geArc2.normal(), geArc2.radius());
|
|
}
|
|
else
|
|
{
|
|
iType = 2;
|
|
geArc = geArc2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iType = 3;
|
|
geArc.set(pt2Sp, pt2Ep, pt1Ep);
|
|
}
|
|
}
|
|
else if (geArc2.isOn(pt1Ep))
|
|
{
|
|
if (geArc2.isOn(pt1Sp))
|
|
{
|
|
if (geArc2.paramOf(pt1Sp) > geArc2.paramOf(pt1Ep))
|
|
{
|
|
iType = 1;
|
|
geArc.set(geArc2.center(), geArc2.normal(), geArc2.radius());
|
|
}
|
|
else
|
|
{
|
|
iType = 2;
|
|
geArc = geArc2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iType = 3;
|
|
geArc.set(pt1Sp, pt2Sp, pt2Ep);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iType = (bJointAtMinAngle ? 4 : 5);
|
|
double dAngle1 = (pt2Sp - ptOrg).angleTo(pt1Ep - ptOrg, geArc1.normal());
|
|
double dAngle2 = (pt1Sp - ptOrg).angleTo(pt2Ep - ptOrg, geArc1.normal());
|
|
if (dAngle1 < 0.0)
|
|
dAngle1 += PI * 2.0;
|
|
if (dAngle2 < 0.0)
|
|
dAngle2 += PI * 2.0;
|
|
if (bJointAtMinAngle && dAngle1 < dAngle2 || !bJointAtMinAngle && dAngle1 > dAngle2)
|
|
{
|
|
geArc.set(pt1Sp, pt1Ep, pt2Ep);
|
|
}
|
|
else
|
|
{
|
|
geArc.set(pt2Sp, pt2Ep, pt1Ep);
|
|
}
|
|
}
|
|
|
|
// 排序数据
|
|
typedef CSortPair<double, AcGePoint3d, DoubleCompare> CPointSortPair;
|
|
AcArray<CPointSortPair> arPointSort;
|
|
|
|
CPointSortPair data;
|
|
data.compare = geArc.paramOf(ptA1S);
|
|
data.value = pt1S;
|
|
arPointSort.append(data);
|
|
data.compare = geArc.paramOf(ptA1E);
|
|
data.value = pt1E;
|
|
arPointSort.append(data);
|
|
data.compare = geArc.paramOf(ptA2S);
|
|
data.value = pt2S;
|
|
arPointSort.append(data);
|
|
data.compare = geArc.paramOf(ptA2E);
|
|
data.value = pt2E;
|
|
arPointSort.append(data);
|
|
|
|
int iLen = arPointSort.length();
|
|
QuickSort(arPointSort.asArrayPtr(), iLen);
|
|
|
|
arpt.setLogicalLength(0);
|
|
int i = 0;
|
|
for (i = 0; i < iLen; i++)
|
|
{
|
|
arpt.append(arPointSort[i].value);
|
|
}
|
|
|
|
return iType;
|
|
}
|
|
|
|
AcDbCurve* KTCADUtilityEx::Connect2CurveNearPt(const AcGePoint3d& pt, AcDbCurve* pCurve1, AcDbCurve* pCurve2)
|
|
{
|
|
ASSERT(pCurve1 != NULL && pCurve2 != NULL);
|
|
|
|
AcDbCurve* pNewCurve = NULL;
|
|
|
|
AcGePoint3d pt1Start, pt1End, pt2Start, pt2End;
|
|
pCurve1->getStartPoint(pt1Start);
|
|
pCurve1->getEndPoint(pt1End);
|
|
pCurve2->getStartPoint(pt2Start);
|
|
pCurve2->getEndPoint(pt2End);
|
|
|
|
if (pCurve1->isKindOf(AcDbLine::desc()) && pCurve2->isKindOf(AcDbLine::desc()))
|
|
{
|
|
// 求重合且方向相反的直线,并将其连成一条直线
|
|
AcGeVector3d vec1 = pt1Start - pt1End;
|
|
if (vec1.isParallelTo(pt2Start - pt2End))
|
|
{
|
|
AcGeVector3d vec2 = pt1Start - pt2Start;
|
|
if (vec2.isZeroLength() || vec2.isParallelTo(vec1))
|
|
{
|
|
AcGePoint3dArray arpt;
|
|
arpt.append(pt1Start);
|
|
arpt.append(pt1End);
|
|
arpt.append(pt2Start);
|
|
arpt.append(pt2End);
|
|
SortPointByDirect(arpt, pt1End - pt1Start);
|
|
//
|
|
AcDbLine* pLine = new AcDbLine(arpt[0], arpt[3]);
|
|
ASSERT(pLine != NULL);
|
|
pLine->setPropertiesFrom(pCurve1);
|
|
struct resbuf* rb = pCurve1->xData();
|
|
if (rb != NULL)
|
|
{
|
|
pLine->setXData(rb);
|
|
acutRelRb(rb);
|
|
}
|
|
pNewCurve = pLine;
|
|
}
|
|
}
|
|
}
|
|
else if (pCurve1->isKindOf(AcDbArc::desc()) && pCurve2->isKindOf(AcDbArc::desc()))
|
|
{
|
|
// 求重合且方向相反的圆弧,并将其连成一个圆弧
|
|
AcGePoint3d ptCenter1, ptCenter2;
|
|
ptCenter1 = ((AcDbArc*)pCurve1)->center();
|
|
ptCenter2 = ((AcDbArc*)pCurve2)->center();
|
|
if (ptCenter1 == ptCenter2)
|
|
{
|
|
if (fabs(((AcDbArc*)pCurve1)->radius() - ((AcDbArc*)pCurve2)->radius()) < 0.1)
|
|
{
|
|
AcGePoint3d ptArc1, ptArc2;
|
|
double dParam1, dParam2;
|
|
((AcDbArc*)pCurve1)->getStartParam(dParam1);
|
|
((AcDbArc*)pCurve1)->getEndParam(dParam2);
|
|
((AcDbArc*)pCurve1)->getPointAtParam((dParam1 + dParam2) / 2.0, ptArc1);
|
|
((AcDbArc*)pCurve2)->getStartParam(dParam1);
|
|
((AcDbArc*)pCurve2)->getEndParam(dParam2);
|
|
((AcDbArc*)pCurve2)->getPointAtParam((dParam1 + dParam2) / 2.0, ptArc2);
|
|
|
|
AcGePoint3d ptNear;
|
|
pCurve1->getClosestPointTo(pt, ptNear, Adesk::kTrue);
|
|
|
|
AcGePoint3dArray arpt1, arpt2;
|
|
int iType = Sort2ArcPoint(ptCenter1, pt1Start, pt1End, ptArc1, pt2Start, pt2End, ptArc2, arpt1, TRUE);
|
|
BOOL bFullCircle = (iType == 1);
|
|
|
|
AcGeCircArc3d arc(arpt1[0], ptArc1, arpt1[3]);
|
|
if (iType > 2)
|
|
{
|
|
if (iType == 3)
|
|
{
|
|
AcGePoint3d ptMid = arc.evalPoint((arc.paramOf(arc.startPoint()) + arc.paramOf(arc.endPoint())) / 2.0);
|
|
arpt2.append(ptMid);
|
|
arpt2.append(arpt1[3]);
|
|
arpt2.append(arpt1[0]);
|
|
arpt2.append(ptMid);
|
|
}
|
|
else
|
|
Sort2ArcPoint(ptCenter1, pt1Start, pt1End, ptArc1, pt2Start, pt2End, ptArc2, arpt2, FALSE);
|
|
|
|
if (ptNear.distanceTo(arpt1[0]) + ptNear.distanceTo(arpt1[3])
|
|
< ptNear.distanceTo(arpt2[0]) + ptNear.distanceTo(arpt2[3]))
|
|
{
|
|
bFullCircle = (arpt2[0].distanceTo(arpt2[3]) < 0.1
|
|
&& (arpt2[0].distanceTo(arpt2[1]) > 0.1 || arpt2[0].distanceTo(arpt2[2]) > 0.1));
|
|
if (!bFullCircle)
|
|
arc.set(arpt2[0], ptArc2, arpt2[3]);
|
|
}
|
|
else
|
|
{
|
|
bFullCircle = (arpt1[0].distanceTo(arpt1[3]) < 0.1
|
|
&& (arpt1[0].distanceTo(arpt1[1]) > 0.1 || arpt1[0].distanceTo(arpt1[2]) > 0.1));
|
|
if (!bFullCircle)
|
|
arc.set(arpt1[0], ptArc1, arpt1[3]);
|
|
}
|
|
}
|
|
|
|
if (bFullCircle)
|
|
{
|
|
pNewCurve = new AcDbCircle(arc.center(), arc.normal(), arc.radius());
|
|
}
|
|
else
|
|
{
|
|
AcGeVector3d vec;
|
|
acdbEcs2Wcs(asDblArray(AcGeVector3d::kXAxis), asDblArray(vec), asDblArray(arc.normal()), true);
|
|
dParam1 = vec.angleTo(arc.startPoint() - arc.center(), arc.normal());
|
|
dParam2 = vec.angleTo(arc.endPoint() - arc.center(), arc.normal());
|
|
|
|
pNewCurve = new AcDbArc(arc.center(), arc.normal(), arc.radius(), dParam1, dParam2);
|
|
}
|
|
|
|
ASSERT(pNewCurve != NULL);
|
|
pNewCurve->setPropertiesFrom(pCurve1);
|
|
|
|
struct resbuf* rb = pCurve1->xData();
|
|
if (rb != NULL)
|
|
{
|
|
pNewCurve->setXData(rb);
|
|
acutRelRb(rb);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (pNewCurve != NULL)
|
|
return pNewCurve;
|
|
|
|
// 求相交曲线,并将其延长到交点
|
|
AcGePoint3dArray arpt;
|
|
if (pCurve1->intersectWith(pCurve2, AcDb::kExtendBoth, arpt) != Acad::eOk || arpt.length() <= 0)
|
|
return NULL;
|
|
|
|
typedef CSortPair<double, AcGePoint3d, DoubleCompare> CGePtSortPair;
|
|
AcArray<CGePtSortPair> arptPair;
|
|
CGePtSortPair data;
|
|
|
|
// 求得与给定点最近的交点
|
|
int iLen = arpt.length();
|
|
int i = 0;
|
|
for (i = 0; i < iLen; i++)
|
|
{
|
|
data.compare = pt.distanceTo(arpt[i]);
|
|
data.value = arpt[i];
|
|
arptPair.append(data);
|
|
}
|
|
if (iLen > 1)
|
|
{
|
|
QuickSort(arptPair.asArrayPtr(), iLen);
|
|
}
|
|
AcGePoint3d ptInt = arptPair[0].value;
|
|
|
|
BOOL bUpgrade = FALSE;
|
|
if (pCurve1->isWriteEnabled() || (bUpgrade = (pCurve1->upgradeOpen() == Acad::eOk)))
|
|
{
|
|
AcGePoint3d ptArc;
|
|
pCurve1->getClosestPointTo(ptInt, ptArc);
|
|
if (ptInt.distanceTo(ptArc) < 0.1) // 点在圆弧上
|
|
{
|
|
double dParam = 0.0;
|
|
pCurve1->getParamAtPoint(ptArc, dParam);
|
|
if (ptInt.distanceTo(pt1Start) < ptInt.distanceTo(pt1End))
|
|
{
|
|
if (pCurve1->isKindOf(AcDbLine::desc()))
|
|
((AcDbLine*)pCurve1)->setStartPoint(ptInt);
|
|
else if (pCurve1->isKindOf(AcDbArc::desc()))
|
|
((AcDbArc*)pCurve1)->setStartAngle(dParam);
|
|
}
|
|
else
|
|
{
|
|
if (pCurve1->isKindOf(AcDbLine::desc()))
|
|
((AcDbLine*)pCurve1)->setEndPoint(ptInt);
|
|
else if (pCurve1->isKindOf(AcDbArc::desc()))
|
|
((AcDbArc*)pCurve1)->setEndAngle(dParam);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (ptInt.distanceTo(pt1Start) < ptInt.distanceTo(pt1End))
|
|
{
|
|
if (pCurve1->isKindOf(AcDbLine::desc()))
|
|
((AcDbLine*)pCurve1)->setStartPoint(ptInt);
|
|
else if (pCurve1->isKindOf(AcDbArc::desc()))
|
|
pCurve1->extend(Adesk::kTrue, ptInt);
|
|
}
|
|
else
|
|
{
|
|
if (pCurve1->isKindOf(AcDbLine::desc()))
|
|
((AcDbLine*)pCurve1)->setEndPoint(ptInt);
|
|
else if (pCurve1->isKindOf(AcDbArc::desc()))
|
|
pCurve1->extend(Adesk::kFalse, ptInt);
|
|
}
|
|
}
|
|
if (bUpgrade)
|
|
pCurve1->downgradeOpen();
|
|
}
|
|
|
|
bUpgrade = FALSE;
|
|
if (pCurve2->isWriteEnabled() || (bUpgrade = (pCurve2->upgradeOpen() == Acad::eOk)))
|
|
{
|
|
AcGePoint3d ptArc;
|
|
pCurve2->getClosestPointTo(ptInt, ptArc);
|
|
if (ptInt.distanceTo(ptArc) < 0.1) // 点在圆弧上
|
|
{
|
|
double dParam = 0.0;
|
|
pCurve2->getParamAtPoint(ptArc, dParam);
|
|
if (ptInt.distanceTo(pt2Start) < ptInt.distanceTo(pt2End))
|
|
{
|
|
if (pCurve2->isKindOf(AcDbLine::desc()))
|
|
((AcDbLine*)pCurve2)->setStartPoint(ptInt);
|
|
else if (pCurve2->isKindOf(AcDbArc::desc()))
|
|
((AcDbArc*)pCurve2)->setStartAngle(dParam);
|
|
}
|
|
else
|
|
{
|
|
if (pCurve2->isKindOf(AcDbLine::desc()))
|
|
((AcDbLine*)pCurve2)->setEndPoint(ptInt);
|
|
else if (pCurve2->isKindOf(AcDbArc::desc()))
|
|
((AcDbArc*)pCurve2)->setEndAngle(dParam);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (ptInt.distanceTo(pt2Start) < ptInt.distanceTo(pt2End))
|
|
{
|
|
if (pCurve2->isKindOf(AcDbLine::desc()))
|
|
((AcDbLine*)pCurve2)->setStartPoint(ptInt);
|
|
else if (pCurve2->isKindOf(AcDbArc::desc()))
|
|
pCurve2->extend(Adesk::kTrue, ptInt);
|
|
}
|
|
else
|
|
{
|
|
if (pCurve2->isKindOf(AcDbLine::desc()))
|
|
((AcDbLine*)pCurve2)->setEndPoint(ptInt);
|
|
else if (pCurve2->isKindOf(AcDbArc::desc()))
|
|
pCurve2->extend(Adesk::kFalse, ptInt);
|
|
}
|
|
}
|
|
if (bUpgrade)
|
|
pCurve2->downgradeOpen();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
BOOL KTCADUtilityEx::IsCurveAreParallel(AcDbObjectId& ent1, AcDbObjectId& ent2)
|
|
{
|
|
OPENOBJ_BEGIN(ent1, AcDb::kForRead, AcDbCurve, pCurve1);
|
|
OPENOBJ_BEGIN(ent2, AcDb::kForRead, AcDbCurve, pCurve2);
|
|
if (pCurve1 == NULL || pCurve2 == NULL)
|
|
return FALSE;
|
|
|
|
double dRadius1;
|
|
AcGePoint3d pt1;
|
|
AcGeVector3d vec1;
|
|
BOOL bLine1 = pCurve1->isKindOf(AcDbLine::desc());
|
|
if (bLine1)
|
|
{
|
|
pt1 = ((AcDbLine*)pCurve1)->startPoint();
|
|
vec1 = ((AcDbLine*)pCurve1)->endPoint() - pt1;
|
|
}
|
|
else if (pCurve1->isKindOf(AcDbArc::desc()))
|
|
{
|
|
dRadius1 = ((AcDbArc*)pCurve1)->radius();
|
|
pt1 = ((AcDbArc*)pCurve1)->center();
|
|
}
|
|
else if (pCurve1->isKindOf(AcDbCircle::desc()))
|
|
{
|
|
dRadius1 = ((AcDbCircle*)pCurve1)->radius();
|
|
pt1 = ((AcDbCircle*)pCurve1)->center();
|
|
}
|
|
else
|
|
return FALSE;
|
|
|
|
double dRadius2;
|
|
AcGePoint3d pt2;
|
|
AcGeVector3d vec2;
|
|
BOOL bLine2 = pCurve2->isKindOf(AcDbLine::desc());
|
|
if (bLine2)
|
|
{
|
|
pt2 = ((AcDbLine*)pCurve2)->startPoint();
|
|
vec2 = ((AcDbLine*)pCurve2)->endPoint() - pt2;
|
|
}
|
|
else if (pCurve2->isKindOf(AcDbArc::desc()))
|
|
{
|
|
dRadius2 = ((AcDbArc*)pCurve2)->radius();
|
|
pt2 = ((AcDbArc*)pCurve2)->center();
|
|
}
|
|
else if (pCurve2->isKindOf(AcDbCircle::desc()))
|
|
{
|
|
dRadius2 = ((AcDbCircle*)pCurve2)->radius();
|
|
pt2 = ((AcDbCircle*)pCurve2)->center();
|
|
}
|
|
else
|
|
return FALSE;
|
|
|
|
if (bLine1 && bLine2)
|
|
return (vec1.isParallelTo(vec2) && pt1 != pt2 && !vec1.isParallelTo(pt1-pt2));
|
|
else
|
|
return (pt1 == pt2 && fabs(dRadius1 - dRadius2) > 0.1);
|
|
|
|
OPENOBJ_END();
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
BOOL KTCADUtilityEx::EraseColumn(ads_name ent)
|
|
{
|
|
return TRUE;
|
|
} |