Files
envi-code/SourceCode/Code2026/tg_shs/shs_pipebase/TCoverReleationManager.cpp
T
2026-09-28 15:28:50 +08:00

904 lines
23 KiB
C++

#include "stdafx.h"
#include "TCoverReleationManager.h"
#include "dbxutil.h"
#include "acedads.h"
#include "dbregion.h"
#include <vector>
#include <algorithm>
#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<TCoverReleationManager::PTONCRITEM> 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;
}