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

2380 lines
57 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;
}