#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 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 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 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 CPointSortPair; AcArray 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 CAxisSortPair; AcArray 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 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 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 CAxisSortPair; AcArray 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 CPointSortPair; AcArray 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 CGePtSortPair; AcArray 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; }