904 lines
23 KiB
C++
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;
|
|
}
|