#include "stdafx.h" #include "TCoverReleationManager.h" #include "dbxutil.h" #include "acedads.h" #include "dbregion.h" #include #include #include "math.h" #include "actrans.h" #include "TTempZoom.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #define _EL_EQUAL_ 0.19 //1.5 2010年03月24日,为了支持单线法兰遮挡立管 static void FreeBuffer(AcDbVoidPtrArray& arCurves) { for (int i = 0;i < arCurves.length();i++) { AcDbEntity* pEnt = (AcDbEntity*)arCurves.at(i); if (pEnt != NULL) { delete pEnt; } } arCurves.setLogicalLength(0); } TCoverReleationManager::TCoverReleationManager() { } TCoverReleationManager::~TCoverReleationManager() { } BOOL TCoverReleationManager::UpdateCoverDisplay(AcDbObjectIdArray& arIds) { // mcl 改用进度条提示,不限数量。2010.05.21 数量多有停顿感时,加进度条 int nLen = arIds.length(); acedSetStatusBarProgressMeter(_T("管线关系处理中..."), 0, nLen); for (int i = 0;i < nLen;i++) { UpdateCoverDisplay(arIds.at(i)); acedSetStatusBarProgressMeterPos(i); } acedRestoreStatusBar(); return TRUE; } static BOOL HasIntersectWith(AcDbExtents& exObj,AcDbExtents& exOth) { //判断两个矩形框有交集 AcGePoint3d ptMin1 = exObj.minPoint(); ptMin1.z = 0.0; AcGePoint3d ptMax1 = exObj.maxPoint(); ptMax1.z = 0.0; AcGePoint3d ptMin2 = exOth.minPoint(); ptMin2.z = 0.0; AcGePoint3d ptMax2 = exOth.maxPoint(); ptMax2.z = 0.0; double dXTol1 = ptMax1.x - ptMin1.x; double dXTol2 = ptMax2.x - ptMin2.x; double dXTol = __max(ptMax2.x,ptMax1.x) - __min(ptMin1.x,ptMin2.x); double dYTol1 = ptMax1.y - ptMin1.y; double dYTol2 = ptMax2.y - ptMin2.y; double dYTol = __max(ptMax2.y,ptMax1.y) - __min(ptMin1.y,ptMin2.y); if ( ( dXTol - dXTol1 - dXTol2) < 1.e-10 && ( dYTol - dYTol1 - dYTol2) < 1.e-10) { return TRUE; } return FALSE; } BOOL TCoverReleationManager::UpdateCoverDisplay(TDbInterfacesObj* pObj) { /* a b +-------+ A / / ______________/_______/____________ B | / 1 / 2 | | / / | D |___________/_______/_______________+ C / 3 / 4 /_______/ d c 遮挡算法设计 对方边界 = abcd 自身边界 = ABCD 1.pObj 自身对象保留 多个被对方的遮挡的 [id - (12,34)] 配对组 2.pObj 自身保存被我遮挡的底标高对象,即自身高标高,对方低标高 该算法设计主要是计算 [id - (12,34)] 配对组,以为实体的自画做布尔运算; 3.该算法对圆弧同样有效; */ //1. 自身范围内有相交关系的实体 TComplexCurve extObj,extObjInSide; pObj->GetGeomExtentsEdge(extObj); pObj->GetCurvesInSide(extObjInSide); //1.1 按标高分出 标高大于自身 : 标高小于自身 AcDbObjectIdArray arIDs; SelectEntityByExt(pObj,arIDs); //1.2 取出pObj被pOtherObj遮挡的部分 //1.3 取出pOtherObj被pObj遮挡的部分 TComplexCurve extOther,extOtherInside; AcDbEntity* pEnt = NULL; TDbInterfacesObj* pOtherObj = NULL; TComplexCurve extThisCovered,extOtherCovered; AcDbVoidPtrArray arThisFaces,arOtherFaces; pObj->MakePolyCurveFaces(arThisFaces); //1.4 去除没有遮挡自己id,不在arIDs 中的元素 BOOL bWrite = pObj->isWriteEnabled(); // 标示原来状态 if (!bWrite) pObj->upgradeOpen(); if (pObj->isWriteEnabled()) // if (pObj->upgradeOpen() == Acad::eOk) { AcDbObjectIdArray arIDsOld; pObj->GetCoverEdgeIds(arIDsOld); int nFoundAt = 0; for (int i = 0;i < arIDsOld.length();i++) { if (!arIDs.find(arIDsOld.at(i),nFoundAt)) { pObj->RemoveCoverEdge(arIDsOld.at(i)); } } AcDbExtents extObj1,extOth1; pObj->getGeomExtents(extObj1); //1.5 更新被pObj 遮挡的元素 AcDbObjectIdArray arByMeIds; pObj->GetIdsCoverByMe(arByMeIds); for (i = 0;i < arByMeIds.length();i++) { if (arByMeIds.at(i).isValid() && Acad::eOk == acdbOpenAcDbEntity(pEnt,arByMeIds.at(i),AcDb::kForWrite)) { pOtherObj = TDbInterfacesObj::cast(pEnt); if (pOtherObj != NULL) { //如果other 不在 arIds 中 if (!arIDs.find(arByMeIds.at(i),nFoundAt)) { pOtherObj->getGeomExtents(extOth1); //如果exoth和 extobj投影有交,说明是有遮挡关系, //通常是SelectEntityByExt由于遮挡设置不显示遮挡线漏选.此处补上到arIDs中 if ( HasIntersectWith(extObj1,extOth1) ) { arIDs.append(arByMeIds.at(i)); } pEnt->close(); continue; } pOtherObj->RemoveCoverEdge(pObj->objectId()); } pEnt->recordGraphicsModified(); pEnt->close(); } } // 如果实体是被删除的, 则不用更新与pObj产生的新遮挡关系 if (pObj->isErased()) { FreeBuffer(arThisFaces); if (!bWrite) pObj->downgradeOpen(); return TRUE; } // add by hh 2014.8.7 确定是否要处理水管风管遮挡 BOOL bBreak = FALSE; if(!TAuxTools::GetTHvacDataFromDwg(HVAC_PIPEDUCTBREAK, bBreak)) GetGlobalContext()->GetAt(HVAC_PIPEDUCTBREAK, bBreak); //1.6 更新与pObj产生的新遮挡关系 for (i = 0;i < arIDs.length();i++) { if (arIDs.at(i).isValid() && Acad::eOk == acdbOpenAcDbEntity(pEnt,arIDs.at(i),AcDb::kForRead)) { pOtherObj = TDbInterfacesObj::cast(pEnt); if (pOtherObj != NULL) { extOther.setLogicalLength(0); extOtherInside.setLogicalLength(0); pOtherObj->GetGeomExtentsEdge(extOther); pOtherObj->GetCurvesInSide(extOtherInside); // 1.2 取出pObj被pOtherObj遮挡的部分 arOtherFaces.setLogicalLength(0); pOtherObj->MakePolyCurveFaces(arOtherFaces); extThisCovered.setLogicalLength(0); extOtherCovered.setLogicalLength(0); // 1.3 计算双方的遮挡关系. 空间投影法 BOOL nSingleLine = 0; pOtherObj->GetSpecialtyData()->GetAt(KEY_SINGLE,nSingleLine); if (!nSingleLine) CoverIntersectWith(extObj,extOther,extThisCovered,extOtherCovered,arThisFaces,arOtherFaces,TRUE,FALSE); CoverIntersectWith(extObjInSide,extOther,extThisCovered,extOtherCovered,arThisFaces,arOtherFaces,FALSE,TRUE); CoverIntersectWith(extOtherInside,extObj,extOtherCovered,extThisCovered,arOtherFaces,arThisFaces,FALSE,TRUE); FreeBuffer(arOtherFaces); // 1.4处理自身 if (extThisCovered.length() > 0) { pObj->RemoveCoverEdge(arIDs.at(i));//先移出遮挡 pObj->AddCoverEdge(arIDs.at(i),extThisCovered);//增加遮挡 // pOtherObj->upgradeOpen(); if (pOtherObj->upgradeOpen() == Acad::eOk) { pOtherObj->AddIdsCoverByMe(pObj->objectId()); pOtherObj->downgradeOpen(); } } else { pObj->RemoveCoverEdge(arIDs.at(i));//移出遮挡 } // 1.5处理对方 if (extOtherCovered.length() > 0) { // pOtherObj->upgradeOpen(); if (pOtherObj->upgradeOpen() == Acad::eOk) { pOtherObj->RemoveCoverEdge(pObj->objectId());//先移出遮挡 pOtherObj->AddCoverEdge(pObj->objectId(),extOtherCovered);//增加遮挡 pOtherObj->downgradeOpen(); } pObj->AddIdsCoverByMe(arIDs.at(i)); } else { if (pOtherObj->upgradeOpen() == Acad::eOk) { pOtherObj->RemoveCoverEdge(pObj->objectId());//移除遮挡 pOtherObj->downgradeOpen(); } } } // add by hh 2014.8.5 支持水管与风管遮挡 else { // 水管实体在pipewire中,无法访问,使用类名进行判断 if(bBreak && 0 == _tcscmp(_T("TDbPipe"), pEnt->isA()->name())) { // 取得水管的遮挡边界 extOther.setLogicalLength(0); TAuxTools::GetCurveGeomExtentsEdge(pEnt, extOther); // 取得水管的遮挡面 arOtherFaces.setLogicalLength(0); TAuxTools::MakeCurvePolyFaces(pEnt, arOtherFaces); extThisCovered.setLogicalLength(0); extOtherCovered.setLogicalLength(0); // 计算双方的遮挡关系. 空间投影法 CoverIntersectWith(extObj,extOther,extThisCovered,extOtherCovered,arThisFaces,arOtherFaces,TRUE,FALSE); CoverIntersectWith(extObjInSide,extOther,extThisCovered,extOtherCovered,arThisFaces,arOtherFaces,FALSE,TRUE); FreeBuffer(arOtherFaces); // 1.4处理自身 if (extThisCovered.length() > 0) { pObj->RemoveCoverEdge(arIDs.at(i));//先移出遮挡 pObj->AddCoverEdge(arIDs.at(i),extThisCovered);//增加遮挡 } else { pObj->RemoveCoverEdge(arIDs.at(i));//移出遮挡 } } else if(!bBreak) { pObj->RemoveCoverEdge(arIDs.at(i));//移出遮挡 } } pEnt->close(); } } if (!bWrite) pObj->downgradeOpen(); } FreeBuffer(arThisFaces); return TRUE; } //X积求面积 static double Area(AcGePoint3d& ptGe1,AcGePoint3d& ptGe2,AcGePoint3d& ptGe3) { AcGeVector3d vt1 = ptGe2 - ptGe1; AcGeVector3d vt2 = ptGe3 - ptGe1; double dArea = 0.5 * vt1.crossProduct(vt2).length(); return dArea; } static BOOL PointInsideTriangle(const AcGePoint3d& ptGe1,const AcGePoint3d& ptGe2,const AcGePoint3d& ptGe3, const AcGePoint3d& ptGeT) { AcGeLineSeg3d line1(ptGe1,ptGe2); AcGeLineSeg3d line2(ptGe1,ptGe3); AcGeLineSeg3d line3(ptGe3,ptGe2); AcGePoint3d ptGeMid1 = TSupportFunc::Mid(ptGe1,ptGe2); AcGeLineSeg3d line11(ptGe3,ptGeMid1); AcGePoint3d ptGeMid2 = TSupportFunc::Mid(ptGe3,ptGe2); AcGeLineSeg3d line12(ptGe1,ptGeMid1); AcGePoint3d ptInt; line11.intersectWith(line12,ptInt); AcGeLineSeg3d line13(ptGeT,ptInt); if (line13.intersectWith(line1,ptInt)) { return FALSE; } if (line13.intersectWith(line2,ptInt)) { return FALSE; } if (line13.intersectWith(line3,ptInt)) { return FALSE; } return TRUE; } static BOOL PointThroughFaceAtZ(const AcGePoint3d& ptMid,AcDbFace* pFace,AcGePoint3d& ptGeT) { AcGePlane plane; AcGePoint3d ptGe1,ptGe2,ptGe3,ptGe4,ptGe5; pFace->getVertexAt(0,ptGe1); pFace->getVertexAt(1,ptGe2); pFace->getVertexAt(2,ptGe3); pFace->getVertexAt(3,ptGe4); AcGePoint3dArray arPts; arPts.append(ptGe1); int nFind = -1; if (!arPts.find(ptGe2,nFind)) { arPts.append(ptGe2); } if (!arPts.find(ptGe3,nFind)) { arPts.append(ptGe3); } if (!arPts.find(ptGe4,nFind)) { arPts.append(ptGe4); } if (arPts.length() < 3) return FALSE; plane.set(ptGe1,ptGe2,ptGe3); ptGe5 = ptMid.orthoProject(plane); AcGeLine3d lineT(ptGe5,ptGe5 + 1000 * AcGeVector3d::kZAxis); if (plane.intersectWith(lineT,ptGeT)) { //面积法,有误差 double dArea1 = Area(ptGe1,ptGe2,ptGe3) + Area(ptGe3,ptGe4,ptGe1); double dArea2 = Area(ptGeT,ptGe1,ptGe2) + Area(ptGeT,ptGe2,ptGe3) + Area(ptGeT,ptGe3,ptGe4) + Area(ptGeT,ptGe4,ptGe1); if (fabs(dArea1 - dArea2) < 1.0) { return TRUE; } } return FALSE; } void TCoverReleationManager::OrthProject2ThisPlane(AcGePoint3d& ptGeT,AcDbFace* pFace) { if (pFace != NULL) { AcGePlane plane; AcGePoint3d ptGe1,ptGe2,ptGe3,ptGe5; pFace->getVertexAt(0,ptGe1); pFace->getVertexAt(1,ptGe2); pFace->getVertexAt(2,ptGe3); plane.set(ptGe1,ptGe2,ptGe3); ptGeT = ptGeT.orthoProject(plane); } } BOOL TCoverReleationManager::CoverIntersectWith(TComplexCurve& extThisComplex,TComplexCurve& extOtherComplex, TComplexCurve& extThisCovered,TComplexCurve& extOtherCovered, AcDbVoidPtrArray& arThisFaces,AcDbVoidPtrArray& arOtherFaces, BOOL bThisCoverByOther,BOOL bIsInsideCurves) { //1. this TComplexCurve 到曲线集合 AcDbVoidPtrArray arThisCurs; AcDbIntArray arGsMarksThis; ComplexCurve2DbCurves(extThisComplex,arThisCurs,arGsMarksThis); //2. other TComplexCurve 到曲线集合 AcDbVoidPtrArray arOtherCurs; AcDbIntArray arGsMarksOther; ComplexCurve2DbCurves(extOtherComplex,arOtherCurs,arGsMarksOther); AcGePoint3d ptGeT,ptSta,ptEnd,ptMid; AcDbCurve* pCurveThis = NULL; AcDbCurve* pCurveOther = NULL; AcGePoint3dArray pts1; BOOL bIntersectWithFace = FALSE; double dParSta = 0.0,dParEnd = 0.0; //3. this 被遮挡情况 . 曲线集合投影到xy 面求交 for (int i = 0;i < arThisCurs.length();i++) { pts1.setLogicalLength(0); pCurveThis = (AcDbCurve*)arThisCurs.at(i); //3.1 和othercurs 求交 for (int j = 0;j < arOtherCurs.length();j++) { pCurveOther = (AcDbCurve*)arOtherCurs.at(j); pCurveThis->intersectWith(pCurveOther,AcDb::kOnBothOperands,AcGePlane::kXYPlane,pts1); } //3.2 把这些交点排序 if (pts1.length() > 0) //相交 { SortPointsProjectZ(pts1,pCurveThis); //3.3 把pCurveT 分割成线段集 TComplexCurve AcDbVoidPtrArray arSplitCurs; pCurveThis->getSplitCurves(pts1,arSplitCurs); // BEGIN=========================================================== if (arSplitCurs.length() < 1) { continue; } /* if (arSplitCurs.length() == 1) //只有一段,在端点相交 { delete (AcDbCurve*)arSplitCurs.at(0); continue; } */ // 修改时间:2010-04-07 // 修改人 :孟常亮 // 修改原因:即使只分割为一段也存在遮挡情况,比如完全在另一个边界内部 // END=============================================================== for (int k = 0;k < arSplitCurs.length();k++) { AcDbCurve* pCurveT = (AcDbCurve*)arSplitCurs.at(k); AcDbLine* pLine = AcDbLine::cast(pCurveT); if (pLine != NULL) { //3.3.1 判断该段的中点 的 z 方向直线是否和 FACE 相交 pLine->getStartPoint(ptSta); pLine->getEndPoint(ptEnd); bIntersectWithFace = FALSE; ptMid = TSupportFunc::Mid(ptSta,ptEnd); for (int kk = 0;kk < arOtherFaces.length();kk++) { AcDbFace* pFace = (AcDbFace*)arOtherFaces.at(kk); if (pFace != NULL && PointThroughFaceAtZ(ptMid,pFace,ptGeT)) { bIntersectWithFace = TRUE; break; // mcl add.2010.03.26 } } if (bIntersectWithFace) //判断影响的标高方向 { AcGeVector3d vtT = ptGeT - ptMid; if (vtT.dotProduct(AcGeVector3d::kZAxis) > _EL_EQUAL_) //说明被遮挡 { TDb::TCurveElement el; memset(&el,0,sizeof(TDb::TCurveElement)); el.bHided = TRUE; el.ptGe[0] = ptSta; el.ptGe[1] = ptEnd; el.ptGe[2] = ptEnd; if (i < arGsMarksThis.length()) el.gsMark = arGsMarksThis.at(i); //el.gsMark = bIsInsideCurves ? -1 : 0; extThisCovered.append(el); } } continue; } AcDbArc* pArc = AcDbArc::cast(pCurveT); if (pArc != NULL) { //对圆弧 pArc->getStartPoint(ptSta); pArc->getEndPoint(ptEnd); //3.3.1 判断该段的中点 的 z 方向直线是否和 FACE 相交 bIntersectWithFace = FALSE; pArc->getStartParam(dParSta); pArc->getEndParam(dParEnd); pArc->getPointAtParam((dParSta + dParEnd) / 2.0,ptMid); for (int kk = 0;kk < arOtherFaces.length();kk++) { AcDbFace* pFace = (AcDbFace*)arOtherFaces.at(kk); if (pFace != NULL && PointThroughFaceAtZ(ptMid,pFace,ptGeT)) { bIntersectWithFace = TRUE; } } if (bIntersectWithFace) //判断影响的标高方向 { AcGeVector3d vtT = ptGeT - ptMid; if (vtT.dotProduct(AcGeVector3d::kZAxis) > _EL_EQUAL_) //说明被遮挡 { TDb::TCurveElement el; memset(&el,0,sizeof(TDb::TCurveElement)); el.bHided = TRUE; el.ptGe[0] = ptSta; el.ptGe[1] = ptMid; el.ptGe[2] = ptEnd; if (i < arGsMarksThis.length()) el.gsMark = arGsMarksThis.at(i); //el.gsMark = bIsInsideCurves ? -1 : 0; extThisCovered.append(el); } } } } FreeBuffer(arSplitCurs); } else // 两boundary不相交,判断是否投影在对方的面内 [包含关系] { //直接判断曲线是否投影落在面内即可. //判断方法以曲线中点作z方向直线和面相交 AcDbLine* pLine = AcDbLine::cast(pCurveThis); if (pLine != NULL) { //3.3.1 判断该段的中点 的 z 方向直线是否和 FACE 相交 bIntersectWithFace = FALSE; pLine->getStartPoint(ptSta); pLine->getEndPoint(ptEnd); ptMid = TSupportFunc::Mid(ptSta,ptEnd); for (int kk = 0;kk < arOtherFaces.length();kk++) { AcDbFace* pFace = (AcDbFace*)arOtherFaces.at(kk); if (pFace != NULL && PointThroughFaceAtZ(ptMid,pFace,ptGeT)) { bIntersectWithFace = TRUE; } } if (bIntersectWithFace) //判断影响的标高方向 { AcGeVector3d vtT = ptGeT - ptMid; if (vtT.dotProduct(AcGeVector3d::kZAxis) > _EL_EQUAL_) //说明被遮挡 { TDb::TCurveElement el; memset(&el,0,sizeof(TDb::TCurveElement)); el.bHided = TRUE; el.ptGe[0] = ptSta; el.ptGe[1] = ptEnd; el.ptGe[2] = ptEnd; if (i < arGsMarksThis.length()) el.gsMark = arGsMarksThis.at(i); //el.gsMark = bIsInsideCurves ? -1 : 0; extThisCovered.append(el); } } continue; } AcDbArc* pArc = AcDbArc::cast(pCurveThis); if (pArc != NULL) { //对圆弧 pArc->getStartPoint(ptSta); pArc->getEndPoint(ptEnd); //3.3.1 判断该段的中点 的 z 方向直线是否和 FACE 相交 bIntersectWithFace = FALSE; pArc->getStartParam(dParSta); pArc->getEndParam(dParEnd); pArc->getPointAtParam((dParSta + dParEnd) / 2.0,ptMid); for (int kk = 0;kk < arOtherFaces.length();kk++) { AcDbFace* pFace = (AcDbFace*)arOtherFaces.at(kk); if (pFace != NULL && PointThroughFaceAtZ(ptMid,pFace,ptGeT)) { bIntersectWithFace = TRUE; } } if (bIntersectWithFace) //判断影响的标高方向 { AcGeVector3d vtT = ptGeT - ptMid; if (vtT.dotProduct(AcGeVector3d::kZAxis) > _EL_EQUAL_) //说明被遮挡 { TDb::TCurveElement el; memset(&el,0,sizeof(TDb::TCurveElement)); el.bHided = TRUE; el.ptGe[0] = ptSta; el.ptGe[1] = ptMid; el.ptGe[2] = ptEnd; if (i < arGsMarksThis.length()) el.gsMark = arGsMarksThis.at(i); //el.gsMark = bIsInsideCurves ? -1 : 0; extThisCovered.append(el); } } } } } //4. 反过来计算 other 被 this 遮挡情况 if (bThisCoverByOther) { CoverIntersectWith(extOtherComplex,extThisComplex,extOtherCovered,extThisCovered,arOtherFaces,arThisFaces,FALSE,bIsInsideCurves); } FreeBuffer(arThisCurs); FreeBuffer(arOtherCurs); return TRUE; } BOOL TCoverReleationManager::SelectEntityByExt(TDbInterfacesObj* pObj,AcDbObjectIdArray& arIDs) { AcDbPolyline* pPl = pObj->MakePolyCurve(); if (pPl != NULL) { AcDbExtents exts; pPl->getGeomExtents(exts); AcGePoint3d ptGe1,ptGe2; ptGe1 = exts.minPoint(); ptGe2 = exts.maxPoint(); ptGe1.x -= 10.0; ptGe1.y -= 10.0; ptGe1.z = 0.0; ptGe2.x += 10.0; ptGe2.y += 10.0; ptGe2.z = 0.0; ads_point pt1,pt2; acdbWcs2Ucs(asDblArray(ptGe1),pt1,false); acdbWcs2Ucs(asDblArray(ptGe2),pt2,false); //[注: 本地需要考虑其他专业的组码过滤问题] struct resbuf* pRb = acutBuildList(100, _T("TDbInterfacesObj"),0); AcDbObjectId idT; ads_name ss,ent; //去掉交点捕捉 struct resbuf rb1,rb2; acedGetVar(_T("OSMODE"),&rb1); acedGetVar(_T("OSMODE"),&rb2); rb2.resval.rint = 0; acedSetVar(_T("OSMODE"),&rb2); //确保选择范围在可见区域内 //zoom 对象可能在部分桥架在屏幕外 //而拉伸中点时,拉伸夹点后不刷新 //这个原因已经修复,zoom版本 //TTempZoom zoom(pt1,pt2); actrTransactionManager->flushGraphics(); acedSSGet(_T("C"),pt1,pt2,pRb,ss); acutRelRb(pRb); acedSetVar(_T("OSMODE"),&rb1); #if ADS > 20 int lLen = 0; #else long lLen = 0; #endif acedSSLength(ss,&lLen); for (long i = 0;i < lLen;i++) { acedSSName(ss,i,ent); acdbGetObjectId(idT,ent); if (pObj->objectId() != idT) { arIDs.append(idT); } } delete pPl; acedSSFree(ss); } return arIDs.length() > 0; } BOOL TCoverReleationManager::UpdateCoverDisplay(AcDbObjectId& id) { AcDbEntity* pEnt = NULL; // mcl changed by below 2010.05.24. 支持删除时,自动更新遮挡 // if (id.isValid() && Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead)) if (id.isValid() && Acad::eOk == acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead,true)) { TDbInterfacesObj* pObj = TDbInterfacesObj::cast(pEnt); if (pObj != NULL) { UpdateCoverDisplay(pObj); } pEnt->close(); } return TRUE; } static AcDbArc* FormatArc(AcGePoint3d& ptGe1,AcGePoint3d& ptGe2,AcGePoint3d& ptGe3) { AcDbArc* pArcThis = NULL; AcGeCircArc3d cirArc3d; cirArc3d.set(ptGe1,ptGe2,ptGe3); AcDbCircle cir; cir.setCenter(cirArc3d.center()); cir.setRadius(cirArc3d.radius()); cir.setNormal(cirArc3d.normal()); 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(arCurPtrs); return pArcThis; } BOOL TCoverReleationManager::ComplexCurve2DbCurves(TComplexCurve& ext,AcDbVoidPtrArray& arThisCurs,AcDbIntArray& arGsMarks) { TDb::TCurveElement el; memset(&el,0,sizeof(TDb::TCurveElement)); for (int i = 0;i < ext.length();i++) { el = ext.at(i); //if (el.ptGe[1].distanceTo(el.ptGe[2]) < AcGeContext::gTol.equalPoint()) //直线 if (el.ptGe[1].distanceTo(el.ptGe[2]) < g_globalTol.equalPoint() ) // modify by cq TFS8208 { AcDbLine* pLine = new AcDbLine(el.ptGe[0],el.ptGe[1]); arThisCurs.append(pLine); arGsMarks.append(el.gsMark); } else //圆弧 { AcDbArc* pArc = FormatArc(ext.at(i).ptGe[0],ext.at(i).ptGe[1],ext.at(i).ptGe[2]); if (pArc != NULL) { arThisCurs.append(pArc); arGsMarks.append(el.gsMark); } } } return arThisCurs.length() > 0; } static bool GreaterCoord(TCoverReleationManager::PTONCRITEM item1,TCoverReleationManager::PTONCRITEM item2) { AcDbCurve * pCurve = item1.m_pCurve; AcGePoint3d ptGe1 = item1.m_ptGeOn; AcGePoint3d ptGe2 = item2.m_ptGeOn; double dDis1 = 0.0,dDis2 = 0.0; pCurve->getClosestPointTo(ptGe1,ptGe1); pCurve->getClosestPointTo(ptGe2,ptGe2); pCurve->getParamAtPoint(ptGe1,dDis1); pCurve->getParamAtPoint(ptGe2,dDis2); //if(dDis1 - dDis2 > AcGeContext::gTol.equalPoint()) if(dDis1 - dDis2 > g_globalTol.equalPoint()) // modify by cq TFS8208 { return false;//up sort } return true;//down sort } BOOL TCoverReleationManager::SortPointsProjectZ(AcGePoint3dArray& points,AcDbCurve * pCurve) { AcGePoint3d ptGeOn; for (int i = 0;i < points.length();i++) { pCurve->getClosestPointTo(points.at(i),AcGeVector3d::kZAxis,ptGeOn); points.setAt(i,ptGeOn); } TCoverReleationManager::PTONCRITEM ptOnCrItem; typedef std::vector PtOnCrItemVector; //排序 AcGePoint3d ptGeSta,ptGeEnd; pCurve->getStartPoint(ptGeSta); pCurve->getEndPoint(ptGeEnd); PtOnCrItemVector vectorItems; ptOnCrItem.m_pCurve = pCurve; AcGePoint3d ptGeT; int nLength = points.length(); for(i = 0;i < nLength;i++) { ptGeT = points.at(i); pCurve->getClosestPointTo(ptGeT,ptGeT,Adesk::kTrue); ptOnCrItem.m_ptGeOn = ptGeT; vectorItems.push_back(ptOnCrItem); } PtOnCrItemVector::iterator itHead = vectorItems.begin(); PtOnCrItemVector::iterator itTail = vectorItems.end(); std::sort(itHead,itTail,GreaterCoord); itHead = vectorItems.begin(); itTail = vectorItems.end(); points.removeSubArray(0,nLength - 1); AcGePoint3d ptGe; for(;itHead != itTail;++itHead) { ptGe = (*itHead).m_ptGeOn; points.append(ptGe); } return TRUE; }