2231 lines
51 KiB
C++
2231 lines
51 KiB
C++
#include "stdafx.h"
|
|
#include "DbGouge.h"
|
|
#include "PipeTools.h"
|
|
#include "DbTrenchFitting.h"
|
|
|
|
extern void DrawWeight(XExplodeDraw &dc,double dWeight,XCurveSegment &seg,int nColorIndex, double nScale);
|
|
|
|
ACRX_DXF_DEFINE_MEMBERS(ATSCableTrench, ATSPipeCanal, AcDb::kDHL_CURRENT,
|
|
AcDb::kMReleaseCurrent, 1, ATS_TRENCH,
|
|
"ATS_TRENCH图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
|
|
IMPLEMENT_TENTBASE(TDbCableTrench);
|
|
|
|
static AcGePoint3d Mid(AcGePoint3d ptGe1, AcGePoint3d ptGe2)
|
|
{
|
|
return AcGePoint3d((ptGe1.x + ptGe2.x) / 2.0,(ptGe1.y + ptGe2.y) / 2.0,(ptGe1.z + ptGe2.z) / 2.0);
|
|
}
|
|
|
|
void InitTDbCableTrench(BOOL bTrue)
|
|
{
|
|
if(bTrue) {
|
|
TDbCableTrench::rxInit();
|
|
TDbCableTrench::InitMatchProtocol(TRUE);
|
|
} else {
|
|
TDbCableTrench::InitMatchProtocol(FALSE);
|
|
deleteAcRxClass(TDbCableTrench::desc());
|
|
}
|
|
}
|
|
|
|
const Adesk::UInt8 TDbCableTrench::g_nVersion = 1;
|
|
|
|
TDbCableTrench::TDbCableTrench()
|
|
{
|
|
m_dGougeLineW = 0.0;
|
|
m_nBracketMode = 0;
|
|
m_dBracketLen = 250.0;
|
|
m_dBracketDis = 1000.0;
|
|
m_dBracketLineW = 0.0;
|
|
m_nCornerType = 0;
|
|
|
|
m_sSpare = _T("");
|
|
m_sTrenchNo = _T("");
|
|
m_dSpare = 0;
|
|
m_nSpare = 0;
|
|
}
|
|
|
|
TDbCableTrench::~TDbCableTrench()
|
|
{
|
|
|
|
}
|
|
|
|
Acad::ErrorStatus TDbCableTrench::subGetClassID(CLSID* pClsid) const
|
|
{
|
|
return Acad::eOk;
|
|
}
|
|
|
|
Acad::ErrorStatus TDbCableTrench::dwgInFields (AcDbDwgFiler* pFiler)
|
|
{
|
|
assertWriteEnabled();
|
|
|
|
Acad::ErrorStatus es = TDbPipeCanal::dwgInFields(pFiler);
|
|
if(es != Acad::eOk) return es;
|
|
Adesk::UInt8 nVer;
|
|
pFiler->readItem(&nVer);
|
|
if(nVer>g_nVersion) {// Version is too new
|
|
return Acad::eMakeMeProxy;
|
|
}
|
|
|
|
pFiler->readItem(&m_dGougeLineW);
|
|
pFiler->readItem(&m_nBracketMode);
|
|
pFiler->readItem(&m_dBracketLen);
|
|
pFiler->readItem(&m_dBracketDis);
|
|
pFiler->readItem(&m_dBracketLineW);
|
|
|
|
//备用
|
|
pFiler->readItem(&m_nSpare);
|
|
pFiler->readItem(&m_dSpare);
|
|
ReadString(pFiler,m_sSpare);
|
|
|
|
ReadString(pFiler,m_sTrenchNo);
|
|
return Acad::eOk;
|
|
}
|
|
|
|
Acad::ErrorStatus TDbCableTrench::dwgOutFields(AcDbDwgFiler*pFiler) const
|
|
{
|
|
assertReadEnabled();
|
|
Acad::ErrorStatus es = TDbPipeCanal::dwgOutFields(pFiler);
|
|
if(es != Acad::eOk) return es;
|
|
|
|
pFiler->writeItem(g_nVersion);
|
|
pFiler->writeItem(m_dGougeLineW);
|
|
pFiler->writeItem(m_nBracketMode);
|
|
pFiler->writeItem(m_dBracketLen);
|
|
pFiler->writeItem(m_dBracketDis);
|
|
pFiler->writeItem(m_dBracketLineW);
|
|
|
|
pFiler->writeItem(m_nSpare);
|
|
pFiler->writeItem(m_dSpare);
|
|
pFiler->writeString(m_sSpare);
|
|
pFiler->writeString(m_sTrenchNo);
|
|
return Acad::eOk;
|
|
}
|
|
|
|
Acad::ErrorStatus TDbCableTrench::dxfInFields (AcDbDxfFiler* pFiler)
|
|
{
|
|
assertWriteEnabled();
|
|
Acad::ErrorStatus es=Acad::eOk;
|
|
es=TDbPipeCanal::dxfInFields(pFiler);
|
|
if(es!=Acad::eOk) return es;
|
|
|
|
if (!pFiler->atSubclassData(_T("TDbCableTrench"))) {
|
|
return Acad::eBadDxfSequence;
|
|
}
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
Acad::ErrorStatus TDbCableTrench::dxfOutFields(AcDbDxfFiler* pFiler) const
|
|
{
|
|
Acad::ErrorStatus es=Acad::eOk;
|
|
es=TDbPipeCanal::dxfOutFields(pFiler);
|
|
assert(es==Acad::eOk);
|
|
es=pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbCableTrench"));
|
|
assert(es==Acad::eOk);
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
void TDbCableTrench::CopyPropertiesFrom(AcDbEntity *pSrc,unsigned gMatchFlag)
|
|
{
|
|
assertWriteEnabled();
|
|
TDbPipeCanal::CopyPropertiesFrom(pSrc, gMatchFlag);
|
|
TDbCableTrench *pGouge = TDbCableTrench::cast(pSrc);
|
|
if(pGouge)
|
|
{
|
|
m_dGougeLineW = pGouge->m_dGougeLineW;
|
|
m_nBracketMode = pGouge->m_nBracketMode;
|
|
m_dBracketLen = pGouge->m_dBracketLen;
|
|
m_dBracketDis = pGouge->m_dBracketDis;
|
|
m_dBracketLineW = pGouge->m_dBracketLineW;
|
|
m_nCornerType = pGouge->m_nCornerType;
|
|
}
|
|
}
|
|
|
|
BOOL TDbCableTrench::CanMergeWith(const TDbPipePrototype &other, int *iPosThis,
|
|
int *iPosOther) const
|
|
{
|
|
if (GetSysType() != other.GetSysType()) // 1、系统类型相同
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// 是否等宽 // 是否向量平行
|
|
TDbCableTrench* pTrench = (TDbCableTrench*)&other;
|
|
if (pTrench != NULL)
|
|
{
|
|
// 向量
|
|
AcGeVector3d vtHor = pTrench->EndPoint() - pTrench->StartPoint();
|
|
AcGeVector3d vtHor2 = EndPoint() - StartPoint();
|
|
|
|
if (!vtHor.isParallelTo(vtHor2))
|
|
{
|
|
return FALSE;
|
|
}
|
|
// 宽
|
|
double dWidth = pTrench->m_nWidth;
|
|
double dHeight = pTrench->GetGougeHeight();
|
|
if (fabs(dWidth-m_nWidth) < 1e-3 && fabs(m_nHeight-dHeight) < 1e-3)
|
|
{
|
|
return TDbPipePrototype::CanMergeWith(other,iPosThis,iPosOther);
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// 自动增加节点到当前数据库,ids-该节点自动连接的管线
|
|
AcDbObjectId TDbCableTrench::AddAutoNodeToDb(const XPoint &ptAt, const DList<AcDbObjectId> &ids) const
|
|
{
|
|
//modify liaoy 2016-8-9
|
|
TDbTrenchFitting *pFitting=new TDbTrenchFitting;
|
|
pFitting->SetVisible(FALSE);
|
|
for(int i=0; i<ids.Length(); i++)
|
|
{
|
|
const AcDbObjectId id=ids[i];
|
|
TPipeInterface iFace;
|
|
iFace.m_idPipe=id;
|
|
iFace.m_ptLocation=ptAt;
|
|
pFitting->AddInterface(iFace);
|
|
}
|
|
pFitting->UpdateLinkage(ptAt, GetSysType(), ids);
|
|
TCHAR *layer;
|
|
layer = this->layer();
|
|
TCHAR szLayer[256];
|
|
_tcscpy(szLayer, layer);
|
|
pFitting->setLayer(szLayer);
|
|
return pFitting->AddToCSpace(Adesk::kTrue);
|
|
/*
|
|
AcDbObjectId id;
|
|
if(ids.Length())
|
|
{
|
|
TDbTrenchFitting *pFitting = new TDbTrenchFitting;
|
|
pFitting->UpdateLinkage(ptAt, GetSysType(), ids);
|
|
TCHAR *layer;
|
|
layer = this->layer();
|
|
TCHAR szLayer[256];
|
|
_tcscpy(szLayer, layer);
|
|
pFitting->setLayer(szLayer);
|
|
|
|
id=AddToCurrentSpace(pFitting, Adesk::kTrue);
|
|
|
|
delete [] layer;
|
|
}
|
|
return id;
|
|
*/
|
|
//modify end
|
|
}
|
|
|
|
Acad::ErrorStatus
|
|
TDbCableTrench::ExplodeOrDraw2d(XExplodeDraw &dc) const
|
|
{
|
|
// cet 2016.10.17 add 图层关闭时,实体不显示,不进行绘制(打印时,也不会绘制)
|
|
AcDbLayerTableRecordPointer player(this->layerId(), AcDb::kForRead);
|
|
if (player.openStatus() == Acad::eOk && player->isOff())
|
|
{
|
|
return Acad::eOk;
|
|
}
|
|
XAcGiViewDraw &viewDraw = (XAcGiViewDraw &)dc;
|
|
//垂直管线
|
|
XVector3D vtLocation=EndPoint()-StartPoint();
|
|
if(fabs(vtLocation.x)<1.0E-6 && fabs(vtLocation.y)<1.0E-6) { //垂直管线
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
//绘制电缆沟上线和下线
|
|
ExplodeOrDrawPipeCanal(dc);
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
//调整电缆沟位置
|
|
void TDbCableTrench::ExplodeOrDrawPipeCanal(XExplodeDraw &dc) const
|
|
{
|
|
switch(m_nCanalType)
|
|
{
|
|
case Canal_Corner1:
|
|
ExplodeOrDrawCanalType1(dc);
|
|
break;
|
|
case Canal_Corner2:
|
|
case Canal_Corner3:
|
|
case Canal_Corner4:
|
|
case Canal_Corner5:
|
|
ExplodeOrDrawCanalType2(dc);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void TDbCableTrench::ExplodeOrDrawCanalType1(XExplodeDraw &dc) const
|
|
{
|
|
//得到电缆沟两端节点
|
|
AcDbObjectId idNode1(NULL), idNode2(NULL);
|
|
|
|
idNode1 = GetNode(0);
|
|
idNode2 = GetNode(1);
|
|
|
|
if (!idNode1.isValid() || !idNode2.isValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
AcGePoint3d pt1,pt2,pt3,pt4;
|
|
//分别得到电缆沟的一端上两点
|
|
AcArray<CornerLine> map1,map2;
|
|
GetCannalPts(idNode1,pt1,pt2,map1);
|
|
GetCannalPts(idNode2,pt3,pt4,map2);
|
|
|
|
XCurveSegment cenCurve = GetCurve();
|
|
XCurveSegment segUp,segDown;
|
|
XDirectionCurve segDir(cenCurve.StartPoint(), cenCurve.EndPoint(), cenCurve.GetBulge());
|
|
segUp = segDir.Offset(m_nWidth/2, LS_FINITE);
|
|
segDown = segDir.Offset(-m_nWidth/2, LS_FINITE);
|
|
segUp.SetPoints(pt1,pt3);
|
|
segDown.SetPoints(pt2,pt4);
|
|
|
|
double dWeight = GetPScale()*m_dGougeLineW;
|
|
if (dWeight > 1e-3)
|
|
{
|
|
DrawWeight(dc, dWeight, segUp, colorIndex(), linetypeScale());
|
|
//绘制电缆沟支架
|
|
DrawWeight(dc, dWeight, segDown, colorIndex(), linetypeScale());
|
|
}
|
|
else
|
|
{
|
|
dc << segUp;
|
|
dc << segDown;
|
|
}
|
|
|
|
for (int i = 0; i < map1.length(); ++i)
|
|
{
|
|
XCurveSegment segCorn(map1[i].pair.second,map1[i].pair.first,map1[i].dAng);
|
|
if(dWeight > 1e-3)
|
|
DrawWeight(dc, dWeight, segCorn, colorIndex(), linetypeScale());
|
|
else
|
|
dc << segCorn;
|
|
}
|
|
|
|
for (int j = 0; j < map2.length(); ++j)
|
|
{
|
|
XCurveSegment segCorn(map2[j].pair.second,map2[j].pair.first,map2[j].dAng);
|
|
if(dWeight > 1e-3)
|
|
DrawWeight(dc, dWeight, segCorn, colorIndex(), linetypeScale());
|
|
else
|
|
dc << segCorn;
|
|
}
|
|
|
|
// 是否需要绘制连接线
|
|
if (IsHasMorePipes(idNode1))
|
|
{
|
|
XCurveSegment segCnt;
|
|
segCnt.SetPoints(pt1,pt2);
|
|
if (dWeight > 1e-3)
|
|
DrawWeight(dc, dWeight, segCnt, colorIndex(), linetypeScale());
|
|
else
|
|
dc << segCnt;
|
|
}
|
|
if (IsHasMorePipes(idNode2))
|
|
{
|
|
XCurveSegment segCnt;
|
|
segCnt.SetPoints(pt3,pt4);
|
|
if(dWeight > 1e-3)
|
|
DrawWeight(dc, dWeight, segCnt, colorIndex(), linetypeScale());
|
|
else
|
|
dc << segCnt;
|
|
}
|
|
//绘制电缆沟支架
|
|
DrawBrackets(dc,cenCurve);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CurveSegmentOffset(const XCurveSegment& seg,double dWidth,XCurveSegment& segUp, XCurveSegment& segDown)
|
|
{
|
|
XDirectionCurve segDir(seg.StartPoint(), seg.EndPoint(), seg.GetBulge());
|
|
segUp = segDir.Offset(dWidth/2, LS_FINITE);
|
|
segDown = segDir.Offset(-dWidth/2, LS_FINITE);
|
|
}
|
|
void TDbCableTrench::SortPipeCanalTrench(const AcGePoint3d &ptOr,const AcDbObjectIdArray &arIds,AcArray<std::pair<AcDbObjectId,XCurveSegment>>& arPairSeg) const
|
|
{
|
|
AcDbObjectId idSelf = GetSelfObjectId();
|
|
AcGeMatrix3d mat;
|
|
ads_matrix matAds;
|
|
GetOffsetMatrix(idSelf, mat);
|
|
AcArray<std::pair<AcDbObjectId,XCurveSegment>> arPairSegTmp;
|
|
for (int i = 0; i < arIds.length(); ++i)
|
|
{
|
|
if (idSelf == arIds[i])
|
|
{
|
|
XCurveSegment seg;
|
|
seg = GetCurve();
|
|
|
|
XCurveSegment segUp, segDown;
|
|
CurveSegmentOffset(seg,GetWidth(),segUp,segDown);
|
|
arPairSegTmp.append(std::make_pair(arIds[i],segUp));
|
|
arPairSegTmp.append(std::make_pair(arIds[i],segDown));
|
|
}
|
|
else
|
|
{
|
|
if (arIds[i].isValid())
|
|
{
|
|
//防止在三维状态下在实体内部自己打开自己
|
|
OPENOBJ_BEGIN(arIds[i], AcDb::kForRead, TDbPipeCanal, pCanal);
|
|
if (pCanal != NULL)
|
|
{
|
|
XCurveSegment seg;
|
|
seg = pCanal->GetCurve();
|
|
|
|
memcpy(matAds, &mat, sizeof(AcGeMatrix3d));
|
|
seg.TransformBy(matAds);
|
|
|
|
XCurveSegment segUp, segDown;
|
|
CurveSegmentOffset(seg,GetWidth(),segUp,segDown);
|
|
arPairSegTmp.append(std::make_pair(arIds[i],segUp));
|
|
arPairSegTmp.append(std::make_pair(arIds[i],segDown));
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
}
|
|
|
|
XPoint pt = ptOr;
|
|
std::map<double,std::pair<AcDbObjectId,XCurveSegment>> map;
|
|
double dPar = 0.0;
|
|
std::vector<double> vecT;
|
|
AcDbCircle circle(ptOr,AcGeVector3d::kZAxis,m_nWidth/5);
|
|
for (int j = 0; j < arPairSegTmp.length(); ++j)
|
|
{
|
|
AcGePoint3d ptNear;
|
|
circle.getClosestPointTo(arPairSegTmp[j].second.MidPoint(),AcGeVector3d::kZAxis,ptNear);
|
|
circle.getParamAtPoint(ptNear,dPar);
|
|
map[dPar] = arPairSegTmp[j];
|
|
vecT.push_back(dPar);
|
|
}
|
|
|
|
std::sort(vecT.begin(),vecT.end());
|
|
for (UINT k = 0; k < vecT.size(); ++k)
|
|
{
|
|
double dT = vecT[k];
|
|
arPairSeg.append(map[dT]);
|
|
}
|
|
}
|
|
void TDbCableTrench::GetCorner2InterPtsTrench(const std::pair<AcDbObjectId,XCurveSegment> &seg1,const const std::pair<AcDbObjectId,XCurveSegment> &seg2,const AcGePoint3d &pt,int nSegCount,AcGePoint3dArray &arPts,AcArray<CornerLine> &map1) const
|
|
{
|
|
BOOL bEqulaWidth = FALSE;
|
|
double dCornerR1(-1),dCornerR2(-1);
|
|
OPENOBJ_BEGIN(seg1.first,AcDb::kForRead,TDbCableTrench,pTrench);
|
|
if (pTrench)
|
|
{
|
|
dCornerR1 = pTrench->GetCornerRadius();
|
|
}
|
|
OPENOBJ_END();
|
|
OPENOBJ_BEGIN(seg2.first,AcDb::kForRead,TDbCableTrench,pTrench);
|
|
if (pTrench)
|
|
{
|
|
dCornerR2 = pTrench->GetCornerRadius();
|
|
}
|
|
OPENOBJ_END();
|
|
if (dCornerR1 > 0 && dCornerR2 > 0 && fabs(dCornerR1 - dCornerR2) > TOL)//不等拐角半径
|
|
{
|
|
//以拐角半径大的为准
|
|
GetCorner2InterPtsTrench(seg1.second,seg2.second,pt,nSegCount,max(dCornerR1,dCornerR2),arPts,map1);
|
|
}
|
|
else
|
|
{
|
|
|
|
GetCorner2InterPtsTrench(seg1.second,seg2.second,pt,nSegCount,GetCornerRadius(),arPts,map1);
|
|
}
|
|
}
|
|
void TDbCableTrench::GetCorner2InterPtsTrench(const XCurveSegment &seg1,const XCurveSegment &seg2,const AcGePoint3d &pt,int nSegCount,double dSpare,AcGePoint3dArray &arPts,AcArray<CornerLine> &map1) const
|
|
{
|
|
XPoint ptInter = pt;
|
|
AcGeVector3d vtDir1,vtDir2;
|
|
AcGePoint3d ptIns1,ptIns2;
|
|
BOOL bMoreLen = FALSE; //用来判断弯头的弧线是朝内还是朝外
|
|
AcGeVector3d vtT;
|
|
XCurveSegment seg1T,seg2T;
|
|
AcGePoint3d ptSegS1,ptSegE1,ptSegS2,ptSegE2;
|
|
//将曲线Z坐标置0
|
|
ptSegS1 = seg1.StartPoint();
|
|
ptSegS2 = seg2.StartPoint();
|
|
ptSegE1 = seg1.EndPoint();
|
|
ptSegE2 = seg2.EndPoint();
|
|
|
|
ptSegS1.z = 0;
|
|
ptSegS2.z = 0;
|
|
ptSegE1.z = 0;
|
|
ptSegE2.z = 0;
|
|
seg1T.SetPoints(ptSegS1,ptSegE1);
|
|
seg2T.SetPoints(ptSegS2,ptSegE2);
|
|
if (seg1T.StartPoint().Distance(ptInter) > seg1T.EndPoint().Distance(ptInter))
|
|
{
|
|
vtDir1 = seg1T.EndPoint() - seg1T.StartPoint();
|
|
vtT = seg1T.StartPoint() - pt;
|
|
}
|
|
else
|
|
{
|
|
vtDir1 = seg1T.StartPoint() - seg1T.EndPoint();
|
|
vtT = seg1T.EndPoint() - pt;
|
|
}
|
|
|
|
if (vtT.length() > seg1T.GetLength())
|
|
bMoreLen = TRUE;
|
|
XPoint ptT1,ptT2;
|
|
vtDir1.normalize();
|
|
//判断是否是无交点的拐角
|
|
if (seg1T.Intersection(seg2T,ptT1,ptT2) == 0)
|
|
// ptIns1 = pt - vtDir1*m_nWidth*tan(PI/8);
|
|
ptIns1 = pt - vtDir1*(m_nWidth+dSpare-m_nWidth*tan(PI/8));
|
|
else
|
|
ptIns1 = pt - vtDir1*dSpare;
|
|
arPts.append(ptIns1);
|
|
|
|
if (seg2T.StartPoint().Distance(ptInter) > seg2T.EndPoint().Distance(ptInter))
|
|
vtDir2 = seg2T.EndPoint() - seg2T.StartPoint();
|
|
else
|
|
vtDir2 = seg2T.StartPoint() - seg2T.EndPoint();
|
|
|
|
vtDir2.normalize();
|
|
//判断是否是无交点的拐角
|
|
if (seg1T.Intersection(seg2T,ptT1,ptT2) == 0)
|
|
// ptIns2 = pt - vtDir2*m_nWidth*tan(PI/8);
|
|
ptIns2 = pt - vtDir2*(m_nWidth+dSpare-m_nWidth*tan(PI/8));
|
|
else
|
|
ptIns2 = pt - vtDir2*dSpare;
|
|
arPts.append(ptIns2);
|
|
|
|
std::pair<AcGePoint3d,AcGePoint3d> pair;
|
|
pair.first = ptIns1;
|
|
pair.second = ptIns2;
|
|
|
|
CornerLine corner;
|
|
corner.pair = pair;
|
|
|
|
if (m_nCanalType == Canal_Corner2 || m_nCanalType == Canal_Corner3)
|
|
{
|
|
corner.dAng = 0.0;
|
|
}
|
|
else
|
|
{
|
|
if (nSegCount > 4)
|
|
{
|
|
corner.dAng = vtDir1.angleTo(vtDir2) - PI;
|
|
}
|
|
else
|
|
{
|
|
if (bMoreLen)
|
|
corner.dAng = PI - vtDir1.angleTo(vtDir2);
|
|
else
|
|
corner.dAng = vtDir1.angleTo(vtDir2) - PI;
|
|
}
|
|
}
|
|
map1.append(corner);
|
|
}
|
|
void TDbCableTrench::GetInterPtsTrench(const AcArray<std::pair<AcDbObjectId,XCurveSegment>> &arSeg,AcArray<AcGePoint3d> &arPts,AcArray<CornerLine> &map1) const
|
|
{
|
|
BOOL bIsInter = FALSE;
|
|
XPoint ptInter1,ptInter2;
|
|
if (arSeg.length() > 1)
|
|
{
|
|
int nNext = 0;
|
|
for (int i = 0; i < arSeg.length(); i++)
|
|
{
|
|
if (i != arSeg.length() - 1)
|
|
nNext = i + 1;
|
|
else
|
|
nNext = 0;
|
|
AcGeVector3d vt1 = arSeg[i].second.StartPoint() - arSeg[i].second.EndPoint();
|
|
AcGeVector3d vt2 = arSeg[nNext].second.StartPoint() - arSeg[nNext].second.EndPoint();
|
|
if (vt1.isParallelTo(vt2))
|
|
continue;
|
|
|
|
AcGePoint3dArray arPtsT;
|
|
AcGePoint3d ptS = arSeg[i].second.StartPoint();
|
|
AcGePoint3d ptST = arSeg[nNext].second.StartPoint();
|
|
AcGePoint3d ptE = arSeg[i].second.EndPoint();
|
|
AcGePoint3d ptET = arSeg[nNext].second.EndPoint();
|
|
|
|
ptS.z = 0.0;
|
|
ptE.z = 0.0;
|
|
ptST.z = 0.0;
|
|
ptET.z = 0.0;
|
|
AcDbLine line1(ptS,ptE);
|
|
AcDbLine line2(ptST,ptET);
|
|
|
|
line1.intersectWith(&line2,AcDb::kOnBothOperands,arPtsT);
|
|
if (arPtsT.length() > 0)
|
|
{
|
|
if(m_nCanalType == Canal_Corner1)
|
|
arPts.append(arPtsT[0]);
|
|
else if (m_nCanalType == Canal_Corner2 || m_nCanalType == Canal_Corner3 || m_nCanalType == Canal_Corner4 || m_nCanalType == Canal_Corner5)
|
|
{
|
|
//得到类型2的交点
|
|
GetCorner2InterPtsTrench(arSeg[i],arSeg[nNext],arPtsT[0],arSeg.length(),arPts,map1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (arSeg.length() == 4)
|
|
{
|
|
arPtsT.removeAll();
|
|
if (line1.intersectWith(&line2,AcDb::kExtendBoth,arPtsT) == Acad::eOk)
|
|
{
|
|
if(m_nCanalType == Canal_Corner1 || m_nCanalType == Canal_Corner3 || m_nCanalType == Canal_Corner4)
|
|
arPts.append(arPtsT[0]);
|
|
else if (m_nCanalType == Canal_Corner2 || m_nCanalType == Canal_Corner5)
|
|
{
|
|
//得到类型2的交点
|
|
GetCorner2InterPtsTrench(arSeg[i],arSeg[nNext],arPtsT[0],arSeg.length(),arPts,map1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
void TDbCableTrench::GetCannalPtsTrench(const AcDbObjectId &id,AcGePoint3d &pt1,AcGePoint3d &pt2,AcArray<CornerLine> &map1) const
|
|
{
|
|
if (id.isValid())
|
|
{
|
|
//通过节点得到几段线
|
|
AcDbObjectIdArray arCanal;
|
|
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPipeNode, pNode);
|
|
if(pNode)
|
|
{
|
|
int num = pNode->GetInterfaceNum();
|
|
if (num > 0)
|
|
{
|
|
for (int i = 0; i < num; ++i)
|
|
{
|
|
TPipeInterface inter;
|
|
// pNode->GetInterface(i,inter);
|
|
AcDbObjectId id = pNode->GetIPipe(i);
|
|
arCanal.append(id);
|
|
}
|
|
|
|
if (num > 3)
|
|
{
|
|
FilterCannal(arCanal);
|
|
}
|
|
|
|
//将线按逆时针排序
|
|
AcArray<std::pair<AcDbObjectId,XCurveSegment>> arPairSeg;
|
|
SortPipeCanalTrench(pNode->GetLocation(),arCanal,arPairSeg);
|
|
AcArray<XCurveSegment, AcArrayObjectCopyReallocator<XCurveSegment> > arSeg;
|
|
for (int i = 0;i < arPairSeg.length();i++)
|
|
arSeg.append(arPairSeg[i].second);
|
|
|
|
//求出排序后线的交点
|
|
AcArray<AcGePoint3d> arPts;
|
|
GetInterPtsTrench(arPairSeg,arPts,map1);
|
|
|
|
//调整方沟位置
|
|
ChangePipeCanalPosition(arPts,pNode->GetLocation(),arSeg.length(),pt1,pt2);
|
|
|
|
// 如果连接点为2则判断是否要添加变径条件:1,vt 2,width
|
|
if (num == 2 && arPts.length() == 0)
|
|
{
|
|
double dLen = 0.0;//变径长度 = b1+b2
|
|
if (MakesureCreateReducer(arCanal,dLen))
|
|
ChangePipeCanalPosition(arCanal,id,pNode->GetLocation(),dLen,pt1,pt2,map1);
|
|
}
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void TDbCableTrench::ExplodeOrDrawCanalType2(XExplodeDraw &dc) const
|
|
{
|
|
//得到电缆沟两端节点
|
|
AcDbObjectId idNode1(NULL), idNode2(NULL);
|
|
|
|
idNode1 = GetNode(0);
|
|
idNode2 = GetNode(1);
|
|
|
|
if (!idNode1.isValid() || !idNode2.isValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
AcGePoint3d pt1,pt2,pt3,pt4;
|
|
//分别得到电缆沟的一端上两点
|
|
AcArray<CornerLine> map1,map2;
|
|
//GetCannalPts(idNode1,pt1,pt2,map1);
|
|
//GetCannalPts(idNode2,pt3,pt4,map2);
|
|
GetCannalPtsTrench(idNode1,pt1,pt2,map1);
|
|
GetCannalPtsTrench(idNode2,pt3,pt4,map2);
|
|
|
|
double dWeight = GetPScale()*m_dGougeLineW;
|
|
XCurveSegment cenCurve = GetCurve();
|
|
XCurveSegment segUp,segDown;
|
|
XDirectionCurve segDir(cenCurve.StartPoint(), cenCurve.EndPoint(), cenCurve.GetBulge());
|
|
segUp = segDir.Offset(m_nWidth/2, LS_FINITE);
|
|
segDown = segDir.Offset(-m_nWidth/2, LS_FINITE);
|
|
segUp.SetPoints(pt1,pt3);
|
|
segDown.SetPoints(pt2,pt4);
|
|
|
|
double dAng = 0.0;
|
|
|
|
if (dWeight > 1e-3)
|
|
{
|
|
DrawWeight(dc, dWeight, segUp, colorIndex(), linetypeScale());
|
|
DrawWeight(dc, dWeight, segDown, colorIndex(), linetypeScale());
|
|
}
|
|
else
|
|
{
|
|
dc << segUp;
|
|
dc << segDown;
|
|
}
|
|
|
|
DrawBrackets(dc,cenCurve);
|
|
|
|
for (int i = 0; i < map1.length(); ++i)
|
|
{
|
|
XCurveSegment segCorn(map1[i].pair.second,map1[i].pair.first,map1[i].dAng);
|
|
if (dWeight > 1e-3)
|
|
DrawWeight(dc, dWeight, segCorn, colorIndex(), linetypeScale());
|
|
else
|
|
dc << segCorn;
|
|
}
|
|
|
|
for (int j = 0; j < map2.length(); ++j)
|
|
{
|
|
XCurveSegment segCorn(map2[j].pair.second,map2[j].pair.first,map2[j].dAng);
|
|
if(dWeight > 1e-3)
|
|
DrawWeight(dc, dWeight, segCorn, colorIndex(), linetypeScale());
|
|
else
|
|
dc << segCorn;
|
|
}
|
|
|
|
// 是否需要绘制连接线
|
|
if (IsHasMorePipes(idNode1))
|
|
{
|
|
XCurveSegment segCnt;
|
|
segCnt.SetPoints(pt1,pt2);
|
|
if(dWeight > 1e-3)
|
|
DrawWeight(dc, dWeight, segCnt, colorIndex(), linetypeScale());
|
|
else
|
|
dc << segCnt;
|
|
}
|
|
if (IsHasMorePipes(idNode2))
|
|
{
|
|
XCurveSegment segCnt;
|
|
segCnt.SetPoints(pt3,pt4);
|
|
if(dWeight > 1e-3)
|
|
DrawWeight(dc, dWeight, segCnt, colorIndex(), linetypeScale());
|
|
else
|
|
dc << segCnt;
|
|
}
|
|
}
|
|
|
|
// 根据连接点点过滤相连接的电缆沟
|
|
BOOL TDbCableTrench::IsHasMorePipes(const AcDbObjectId& idNode) const
|
|
{
|
|
int num = GetNodeCntPipeNumber(idNode);
|
|
|
|
if (num > 1)// 有连接
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// 节点连接的管子个数
|
|
int TDbCableTrench::GetNodeCntPipeNumber(const AcDbObjectId& idNode) const
|
|
{
|
|
int nNum = 0;
|
|
if (idNode.isValid())
|
|
{
|
|
OPENOBJ_BEGIN(idNode, AcDb::kForRead, TDbPipeNode, pNode);
|
|
if(pNode)
|
|
{
|
|
nNum = pNode->GetInterfaceNum();
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
return nNum;
|
|
}
|
|
|
|
// 绘制电缆沟支架
|
|
Acad::ErrorStatus
|
|
TDbCableTrench::DrawBrackets(XExplodeDraw &dc,XCurveSegment& cenSeg) const
|
|
{
|
|
AcArray<XCurveSegment, AcArrayObjectCopyReallocator<XCurveSegment> > arBracket;
|
|
switch(m_nBracketMode)
|
|
{
|
|
case eGNull:
|
|
{
|
|
break;
|
|
}
|
|
case eGCover: // 支架长度等于沟宽
|
|
case eGLSide:
|
|
case eGRSide:
|
|
{
|
|
MakeCurvesOfCableGougeSide(arBracket,cenSeg);
|
|
break;
|
|
}
|
|
case eGOrder:
|
|
{
|
|
MakeCurvesOfCableGougeOrder(arBracket,cenSeg);
|
|
break;
|
|
}
|
|
case eGInter:
|
|
{
|
|
MakeCurvesOfCableGougeInter(arBracket,cenSeg);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// 绘制
|
|
if (arBracket.length() > 0)
|
|
{
|
|
double dWeight = GetPScale() * m_dBracketLineW;
|
|
for (int i = 0;i < arBracket.length();i++)
|
|
{
|
|
if (dWeight > 1e-3)
|
|
DrawWeight(dc, dWeight , arBracket[i], colorIndex(), linetypeScale());
|
|
else
|
|
dc << arBracket[i];
|
|
}
|
|
}
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
// 单边
|
|
BOOL TDbCableTrench::MakeCurvesOfCableGougeSide(AcArray<XCurveSegment, AcArrayObjectCopyReallocator<XCurveSegment> >& arBracket,XCurveSegment& cenSeg) const
|
|
{
|
|
arBracket.setLogicalLength(0);
|
|
|
|
//得到电缆沟两端节点
|
|
AcDbObjectId idNode1(NULL), idNode2(NULL);
|
|
idNode1 = GetNode(0);
|
|
idNode2 = GetNode(1);
|
|
|
|
if (!idNode1.isValid() || !idNode2.isValid())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
AcGeVector3d vtHor = cenSeg.EndPoint() - cenSeg.StartPoint();
|
|
AcGeVector3d vtVer = vtHor;
|
|
vtVer.rotateBy(PI / 2,AcGeVector3d::kZAxis);
|
|
vtHor.normalize();
|
|
vtVer.normalize();
|
|
// 预览还是创建
|
|
if (idNode1 != AcDbObjectId::kNull && idNode2 != AcDbObjectId::kNull) // 创建
|
|
{
|
|
AcGePoint3d pt1,pt2,pt3,pt4;
|
|
//分别得到电缆沟的一端上两点
|
|
AcArray<CornerLine> map1,map2;
|
|
GetCannalPts(idNode1,pt1,pt2,map1);
|
|
GetCannalPts(idNode2,pt3,pt4,map2);
|
|
|
|
AcGePoint3d ptS,ptE;
|
|
if (m_nBracketMode == eGLSide || m_nBracketMode == eGCover)
|
|
{
|
|
ptS = pt2;
|
|
ptE = pt4;
|
|
|
|
int nNum = GetNodeCntPipeNumber(idNode2);
|
|
if (map2.length() > 0 && (nNum > 0 && nNum < 3))
|
|
DrawBracketOfCorner(ptE,map2,arBracket,idNode2);
|
|
}
|
|
else if (m_nBracketMode == eGRSide)
|
|
{
|
|
ptS = pt1;
|
|
ptE = pt3;
|
|
|
|
int nNum = GetNodeCntPipeNumber(idNode2);
|
|
if (map2.length() > 0 && (nNum > 0 && nNum < 3))
|
|
DrawBracketOfCorner(ptE,map2,arBracket,idNode2);
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// 修复开始和结束点
|
|
if (!IsHasMorePipes(idNode1)) // 存在连接
|
|
ReConstructBracketLine(ptS,ptE,idNode1);
|
|
if (!IsHasMorePipes(idNode2))
|
|
ReConstructBracketLine(ptS,ptE,idNode2);
|
|
|
|
if (m_nBracketMode == eGRSide)
|
|
vtVer *= -1;
|
|
|
|
DrawBracketsFun(vtHor,-vtVer,ptS,ptE,arBracket);
|
|
}
|
|
else// 预览
|
|
{
|
|
AcGePoint3d ptS = cenSeg.StartPoint();
|
|
AcGePoint3d ptE = cenSeg.EndPoint();
|
|
if (m_nBracketMode == eGLSide || m_nBracketMode == eGCover)
|
|
{
|
|
ptS += vtVer * m_nWidth / 2;
|
|
ptE += vtVer * m_nWidth / 2;
|
|
DrawBracketsFun(vtHor,-vtVer,ptS,ptE,arBracket);
|
|
}
|
|
else if (m_nBracketMode == eGRSide)
|
|
{
|
|
ptS -= vtVer * m_nWidth / 2;
|
|
ptE -= vtVer * m_nWidth / 2;
|
|
DrawBracketsFun(vtHor,vtVer,ptS,ptE,arBracket);
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// 对立
|
|
BOOL TDbCableTrench::MakeCurvesOfCableGougeOrder(AcArray<XCurveSegment, AcArrayObjectCopyReallocator<XCurveSegment> >& arBracket,XCurveSegment& cenSeg) const
|
|
{
|
|
arBracket.setLogicalLength(0);
|
|
|
|
//得到电缆沟两端节点
|
|
AcDbObjectId idNode1(NULL), idNode2(NULL);
|
|
|
|
idNode1 = GetNode(0);
|
|
idNode2 = GetNode(1);
|
|
|
|
if (!idNode1.isValid() || !idNode2.isValid())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
AcGeVector3d vtHor = cenSeg.EndPoint() - cenSeg.StartPoint();
|
|
AcGeVector3d vtVer = vtHor;
|
|
vtVer.rotateBy(PI / 2,AcGeVector3d::kZAxis);
|
|
vtHor.normalize();
|
|
vtVer.normalize();
|
|
// 预览还是创建
|
|
if (idNode1 != AcDbObjectId::kNull && idNode2 != AcDbObjectId::kNull) // 创建
|
|
{
|
|
AcGePoint3d pt1,pt2,pt3,pt4;
|
|
//分别得到电缆沟的一端上两点
|
|
AcArray<CornerLine> map1,map2;
|
|
GetCannalPts(idNode1,pt1,pt2,map1);
|
|
GetCannalPts(idNode2,pt3,pt4,map2);
|
|
|
|
AcGePoint3d ptS = pt1;
|
|
AcGePoint3d ptE = pt3;
|
|
int nNum = GetNodeCntPipeNumber(idNode2);
|
|
if (map2.length() > 0 && (nNum > 0 && nNum < 3))
|
|
DrawBracketOfCorner(ptE,map2,arBracket,idNode2);
|
|
// 修复开始和结束点
|
|
if (!IsHasMorePipes(idNode1)) // 存在连接
|
|
ReConstructBracketLine(ptS,ptE,idNode1);
|
|
if (!IsHasMorePipes(idNode2))
|
|
ReConstructBracketLine(ptS,ptE,idNode2);
|
|
DrawBracketsFun(vtHor,vtVer,ptS,ptE,arBracket);
|
|
AcDbLine l1(ptS,ptE);
|
|
ptS = pt2;
|
|
ptE = pt4;
|
|
nNum = GetNodeCntPipeNumber(idNode2);
|
|
if (map2.length() > 0 && (nNum > 0 && nNum < 3))
|
|
DrawBracketOfCorner(ptE,map2,arBracket,idNode2);
|
|
// 修复开始和结束点
|
|
if (!IsHasMorePipes(idNode1)) // 存在连接
|
|
ReConstructBracketLine(ptS,ptE,idNode1);
|
|
if (!IsHasMorePipes(idNode2))
|
|
ReConstructBracketLine(ptS,ptE,idNode2);
|
|
|
|
AcGePoint3d ptS1,ptTemp;
|
|
l1.getStartPoint(ptS1);
|
|
l1.getClosestPointTo(ptS,ptTemp,Adesk::kTrue);
|
|
int dDist = ptS1.distanceTo(ptTemp);
|
|
|
|
if (dDist != 0)
|
|
{
|
|
AcGeVector3d vtTemp = ptE - ptS;
|
|
AcGeVector3d vtTemp1 = ptS1 - ptS;
|
|
int dDist1 = 0;
|
|
if (vtTemp1.angleTo(vtTemp) <= PI/2)
|
|
{
|
|
dDist1 = dDist%(int)m_dBracketDis;
|
|
}
|
|
else
|
|
dDist1 = m_dBracketDis - dDist%(int)m_dBracketDis;
|
|
|
|
vtTemp.normalize();
|
|
ptS += dDist1*vtTemp;
|
|
}
|
|
|
|
DrawBracketsFun(vtHor,-vtVer,ptS,ptE,arBracket);
|
|
}
|
|
else//预览
|
|
{
|
|
AcGePoint3d ptS,ptE;
|
|
|
|
ptS = cenSeg.StartPoint() + vtVer * m_nWidth / 2;
|
|
ptE = cenSeg.EndPoint() + vtVer * m_nWidth / 2;
|
|
DrawBracketsFun(vtHor,-vtVer,ptS,ptE,arBracket);
|
|
|
|
ptS = cenSeg.StartPoint() - vtVer * m_nWidth / 2;
|
|
ptE = cenSeg.EndPoint() - vtVer * m_nWidth / 2;
|
|
DrawBracketsFun(vtHor,vtVer,ptS,ptE,arBracket);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// 交错
|
|
BOOL TDbCableTrench::MakeCurvesOfCableGougeInter(AcArray<XCurveSegment, AcArrayObjectCopyReallocator<XCurveSegment> >& arBracket,XCurveSegment& cenSeg) const
|
|
{
|
|
arBracket.setLogicalLength(0);
|
|
|
|
//得到电缆沟两端节点
|
|
AcDbObjectId idNode1(NULL), idNode2(NULL);
|
|
|
|
idNode1 = GetNode(0);
|
|
idNode2 = GetNode(1);
|
|
|
|
if (!idNode1.isValid() || !idNode2.isValid())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
AcGeVector3d vtHor = cenSeg.EndPoint() - cenSeg.StartPoint();
|
|
AcGeVector3d vtVer = vtHor;
|
|
vtVer.rotateBy(PI / 2,AcGeVector3d::kZAxis);
|
|
vtHor.normalize();
|
|
vtVer.normalize();
|
|
// 预览还是创建
|
|
if (idNode1 != AcDbObjectId::kNull && idNode2 != AcDbObjectId::kNull) // 创建
|
|
{
|
|
AcGePoint3d pt1,pt2,pt3,pt4;
|
|
//分别得到电缆沟的一端上两点
|
|
AcArray<CornerLine> map1,map2;
|
|
GetCannalPts(idNode1,pt1,pt2,map1);
|
|
GetCannalPts(idNode2,pt3,pt4,map2);
|
|
|
|
AcGePoint3d ptS = pt2;
|
|
AcGePoint3d ptE = pt4;
|
|
|
|
int nNum = GetNodeCntPipeNumber(idNode2);
|
|
if (map2.length() > 0 && (nNum > 0 && nNum < 3))
|
|
DrawBracketOfCorner(ptE,map2,arBracket,idNode2);
|
|
// 修复开始和结束点
|
|
if (!IsHasMorePipes(idNode1)) // 存在连接
|
|
ReConstructBracketLine(ptS,ptE,idNode1);
|
|
if (!IsHasMorePipes(idNode2))
|
|
ReConstructBracketLine(ptS,ptE,idNode2);
|
|
DrawBracketsFun(vtHor,-vtVer,ptS,ptE,arBracket);
|
|
|
|
// 下边
|
|
AcGePoint3d ptST = ptS;// 用于校正另一边便宜间距的一半
|
|
ptS = pt1;
|
|
ptE = pt3;
|
|
nNum = GetNodeCntPipeNumber(idNode2);
|
|
if (map2.length() > 0 && (nNum > 0 && nNum < 3))
|
|
DrawBracketOfCorner(ptE,map2,arBracket,idNode2);
|
|
// 修复开始和结束点
|
|
if (!IsHasMorePipes(idNode1)) // 存在连接
|
|
ReConstructBracketLine(ptS,ptE,idNode1);
|
|
if (!IsHasMorePipes(idNode2))
|
|
ReConstructBracketLine(ptS,ptE,idNode2);
|
|
// 偏移
|
|
AcGePoint3d ptS2T = ptS + vtVer * m_nWidth;
|
|
double dDist = ptS2T.distanceTo(ptST);
|
|
double dOff = 0.0;
|
|
if (dDist < 1e-2)
|
|
{
|
|
dOff = m_dBracketDis / 2;
|
|
}
|
|
else
|
|
{
|
|
// 剩余
|
|
int nSpareNum = 0;
|
|
if (m_dBracketDis != 0)
|
|
nSpareNum = int(dDist / m_dBracketDis);
|
|
double dSpare = m_dBracketDis * nSpareNum;
|
|
dSpare = dDist - dSpare;
|
|
if (dSpare < (m_dBracketDis / 2))
|
|
{
|
|
dOff = m_dBracketDis / 2 - dSpare;
|
|
}
|
|
else
|
|
{
|
|
dOff = m_dBracketDis * 3 / 2 - dSpare;
|
|
}
|
|
}
|
|
|
|
ptS += vtHor * dOff;
|
|
DrawBracketsFun(vtHor,vtVer,ptS,ptE,arBracket);
|
|
}
|
|
else//预览
|
|
{
|
|
AcGePoint3d ptS,ptE;
|
|
|
|
ptS = cenSeg.StartPoint() + vtVer * m_nWidth / 2;
|
|
ptE = cenSeg.EndPoint() + vtVer * m_nWidth / 2;
|
|
DrawBracketsFun(vtHor,-vtVer,ptS,ptE,arBracket);
|
|
|
|
ptS = cenSeg.StartPoint() - vtVer * m_nWidth / 2;
|
|
ptE = cenSeg.EndPoint() - vtVer * m_nWidth / 2;
|
|
|
|
ptS += vtHor * m_dBracketDis / 2;
|
|
DrawBracketsFun(vtHor,vtVer,ptS,ptE,arBracket);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// 得到相连的另一条沟的宽度和倒角半径
|
|
void TDbCableTrench::GetAnotherTrenchParam(const AcGeVector3d& vtHor,const AcDbObjectId& idNode,double& dWidth,double& dRadius) const
|
|
{
|
|
if (!idNode.isValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
dWidth = 0.0;
|
|
dRadius = 0.0;
|
|
AcDbObjectId id;
|
|
AcDbObjectIdArray arId;
|
|
OPENOBJ_BEGIN(idNode, AcDb::kForRead, TDbPipeNode, pNode);
|
|
if(pNode)
|
|
{
|
|
int nNum = pNode->GetInterfaceNum();
|
|
if (nNum == 2)
|
|
{
|
|
for (int i = 0;i < nNum;i++)
|
|
{
|
|
id = pNode->GetIPipe(i);
|
|
arId.append(id);
|
|
}
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
if (arId.length() != 2)
|
|
return;
|
|
|
|
// 读取另一条沟的数据
|
|
AcGeVector3d vt;
|
|
for (int i = 0;i < arId.length();i++)
|
|
{
|
|
if (arId[i].isValid())
|
|
{
|
|
OPENOBJ_BEGIN(arId[i], AcDb::kForRead, TDbCableTrench, pTrench);
|
|
if(pTrench)
|
|
{
|
|
vt = pTrench->StartPoint() - pTrench->EndPoint();
|
|
if (!vt.isParallelTo(vtHor))
|
|
{
|
|
dWidth = pTrench->m_nWidth;
|
|
dRadius = pTrench->m_dSpare;
|
|
break;
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
}
|
|
|
|
// 重新构建绘制支架的线
|
|
BOOL TDbCableTrench::ReConstructBracketLine(AcGePoint3d& ptS,AcGePoint3d& ptE,const AcDbObjectId& idNode) const
|
|
{
|
|
if (!idNode.isValid())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
AcGePoint3d ptNode;
|
|
OPENOBJ_BEGIN(idNode, AcDb::kForRead, TDbPipeNode, pNode);
|
|
if(pNode)
|
|
{
|
|
ptNode = pNode->GetLocation();
|
|
}
|
|
OPENOBJ_END();
|
|
|
|
// 挑出距离节点较近的点
|
|
double dLn1 = ptS.distanceTo(ptNode);
|
|
double dLn2 = ptE.distanceTo(ptNode);
|
|
|
|
if (dLn1 > dLn2)//ptE
|
|
{
|
|
AcGeVector3d vtHor = ptE - ptS;
|
|
vtHor.normalize();
|
|
|
|
AcGePointOnCurve3d ptT;
|
|
AcGeLine3d line(ptNode,vtHor);
|
|
line.getClosestPointTo(ptE,ptT);
|
|
|
|
AcGeVector3d vtT = ptT.point3d() - ptNode;
|
|
vtT.normalize();
|
|
if (vtT.isCodirectionalTo(vtHor))//同向:一端较长的边
|
|
{
|
|
ptE -= vtHor * MINDIST;
|
|
}
|
|
else// 短线
|
|
{
|
|
switch(m_nCanalType)
|
|
{
|
|
case Canal_Corner1://直角
|
|
{
|
|
double dWidth = 0.0,dRadius = 0.0;
|
|
GetAnotherTrenchParam(vtHor,idNode,dWidth,dRadius);
|
|
|
|
if (dWidth < 500)
|
|
ptE -= vtHor * (MINDIST - dWidth);
|
|
break;
|
|
}
|
|
case Canal_Corner2://双倒角
|
|
case Canal_Corner3://单倒角
|
|
{
|
|
double dWidth = 0.0,dRadius = 0.0;
|
|
GetAnotherTrenchParam(vtHor,idNode,dWidth,dRadius);
|
|
dWidth += dRadius;
|
|
|
|
if (dWidth < 500)
|
|
ptE -= vtHor * (MINDIST - dWidth);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else//ptS
|
|
{
|
|
AcGeVector3d vtHor = ptS - ptE;
|
|
vtHor.normalize();
|
|
|
|
AcGePointOnCurve3d ptT;
|
|
AcGeLine3d line(ptNode,vtHor);
|
|
line.getClosestPointTo(ptS,ptT);
|
|
|
|
AcGePoint3d pp = ptT.point3d();
|
|
AcGeVector3d vtT = ptT.point3d() - ptNode;
|
|
vtT.normalize();
|
|
if (vtT.isCodirectionalTo(vtHor))//同向:一端较长的边
|
|
{
|
|
ptS -= vtHor * MINDIST;
|
|
}
|
|
else// 短线
|
|
{
|
|
switch(m_nCanalType)
|
|
{
|
|
case Canal_Corner1://直角
|
|
{
|
|
double dWidth = 0.0,dRadius = 0.0;
|
|
GetAnotherTrenchParam(vtHor,idNode,dWidth,dRadius);
|
|
|
|
if (dWidth < 500)
|
|
ptS -= vtHor * (MINDIST - dWidth);
|
|
break;
|
|
}
|
|
case Canal_Corner2://双倒角
|
|
case Canal_Corner3://单倒角
|
|
{
|
|
double dWidth = 0.0,dRadius = 0.0;
|
|
GetAnotherTrenchParam(vtHor,idNode,dWidth,dRadius);
|
|
dWidth += dRadius;
|
|
|
|
if (dWidth < 500)
|
|
ptS -= vtHor * (MINDIST - dWidth);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// 绘制拐角处支架
|
|
void TDbCableTrench::DrawBracketOfCorner(const AcGePoint3d& ptRef,AcArray<CornerLine>& mapPt,AcArray<XCurveSegment, AcArrayObjectCopyReallocator<XCurveSegment> >& arBracket,const AcDbObjectId& idNode) const
|
|
{
|
|
// if (mapPt.length() < 1)
|
|
// return;
|
|
//
|
|
// CornerLine cnrLine;
|
|
// if (!GetCornerPtMap(ptRef,mapPt,cnrLine))
|
|
// return;
|
|
//
|
|
// AcGePoint3d ptS = cnrLine.pair.first;
|
|
// AcGePoint3d ptE = cnrLine.pair.second;
|
|
//
|
|
// AcGePoint3d ptLoc;
|
|
// OPENOBJ_BEGIN(idNode, AcDb::kForRead, TDbPipeNode, pNode);
|
|
// if(pNode)
|
|
// {
|
|
// ptLoc = pNode->GetLocation();
|
|
// }
|
|
// OPENOBJ_END();
|
|
//
|
|
// AcDbLine line(ptS,ptE);
|
|
// AcGePoint3d ptT;
|
|
// line.getClosestPointTo(ptLoc,ptT,Adesk::kTrue);
|
|
//
|
|
// AcGeVector3d vtHor = ptE - ptS;
|
|
// AcGeVector3d vtVer = ptLoc - ptT;
|
|
// vtVer.normalize();
|
|
// vtHor.normalize();
|
|
//
|
|
// ptS += vtHor * MINDIST;
|
|
// ptE -= vtHor * MINDIST;
|
|
//
|
|
//
|
|
// DrawBracketsFun(vtHor,vtVer,ptS,ptE,arBracket);
|
|
}
|
|
|
|
// 得到指定连接点的拐角点组
|
|
BOOL TDbCableTrench::GetCornerPtMap(const AcGePoint3d& ptRef,AcArray<CornerLine>& mapPt,CornerLine& temOut) const
|
|
{
|
|
if (mapPt.length() < 1)
|
|
return FALSE;
|
|
|
|
AcGePoint3d ptT;
|
|
for (int i = 0;i < mapPt.length();i++)
|
|
{
|
|
temOut = mapPt[i];
|
|
ptT = temOut.pair.first;
|
|
if (ptT.distanceTo(ptRef) < 1e-3)
|
|
{
|
|
return TRUE;
|
|
}
|
|
ptT = temOut.pair.second;
|
|
if (ptT.distanceTo(ptRef) < 1e-3)
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// 绘制支架
|
|
void TDbCableTrench::DrawBracketsFun(const AcGeVector3d& vtHor,const AcGeVector3d& vtVer,const AcGePoint3d& ptStart,const AcGePoint3d& ptEnd,AcArray<XCurveSegment, AcArrayObjectCopyReallocator<XCurveSegment> >& arBracket) const
|
|
{
|
|
double dLen = ptStart.distanceTo(ptEnd);
|
|
|
|
DrawBracketsFun(vtHor,vtVer,ptStart,dLen,arBracket);
|
|
}
|
|
|
|
void TDbCableTrench::DrawBracketsFun(const AcGeVector3d& vtHor,const AcGeVector3d& vtVer,const AcGePoint3d& ptStart,double dLen,AcArray<XCurveSegment, AcArrayObjectCopyReallocator<XCurveSegment> >& arBracket) const
|
|
{
|
|
double dBLen = m_dBracketLen;
|
|
if (m_nBracketMode == eGCover)
|
|
dBLen = m_nWidth;
|
|
XCurveSegment segTemp;
|
|
AcGePoint3d ptT = ptStart,pt2;
|
|
double dT = 0.0;
|
|
while (TRUE)
|
|
{
|
|
dT = ptT.distanceTo(ptStart);
|
|
if (dT < dLen)
|
|
{
|
|
pt2 = ptT + vtVer * dBLen;
|
|
segTemp.SetPoints(ptT,pt2);
|
|
arBracket.append(segTemp);
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
ptT += vtHor * m_dBracketDis;
|
|
}
|
|
}
|
|
|
|
Acad::ErrorStatus
|
|
TDbCableTrench::ExplodeOrDraw3d(XExplodeDraw &dc) const
|
|
{
|
|
//得到电缆沟两端节点
|
|
//得到方沟两端节点
|
|
AcDbObjectId idNode1(NULL), idNode2(NULL);
|
|
AcDbObjectIdArray arIds;
|
|
idNode1 = GetNode(0);
|
|
idNode2 = GetNode(1);
|
|
|
|
if (!idNode1.isValid() || !idNode2.isValid())
|
|
{
|
|
return Acad::eInvalidInput;
|
|
}
|
|
|
|
arIds.append(idNode1);
|
|
arIds.append(idNode2);
|
|
|
|
AcGePoint3d pt1,pt2,pt3,pt4,ptS,ptE;
|
|
|
|
XCurveSegment cvHide,segUp, segDown;
|
|
cvHide = GetCurve();
|
|
XDirectionCurve segDir(cvHide.StartPoint(), cvHide.EndPoint(), cvHide.GetBulge());
|
|
segUp = segDir.Offset(m_nWidth/2, LS_FINITE);
|
|
segDown = segDir.Offset(-m_nWidth/2, LS_FINITE);
|
|
pt1 = segUp.StartPoint();
|
|
pt3 = segUp.EndPoint();
|
|
pt2 = segDown.StartPoint();
|
|
pt4 = segDown.EndPoint();
|
|
ptS = cvHide.StartPoint();
|
|
ptE = cvHide.EndPoint();
|
|
|
|
double dW = m_nWidth;
|
|
double dH = m_nHeight;
|
|
|
|
AcGeVector3d vtNorm = AcGeVector3d::kZAxis;
|
|
AcGeVector3d vtDir = pt3 - pt1;
|
|
AcArray<CornerLine> map;
|
|
if (!vtDir.isPerpendicularTo(AcGeVector3d::kZAxis))
|
|
{
|
|
AcGeVector3d vtT = vtDir.orthoProject(AcGeVector3d::kZAxis);
|
|
vtT.rotateBy(PI/2,AcGeVector3d::kZAxis);
|
|
AcGeVector3d vtT2 = vtDir.crossProduct(vtT);
|
|
vtNorm = vtT2;
|
|
vtNorm.normalize();
|
|
}
|
|
else
|
|
{
|
|
//分别得到方沟的一端上两点
|
|
GetCannalPts(idNode1,pt1,pt2);
|
|
GetCannalPts(idNode2,pt3,pt4);
|
|
}
|
|
|
|
|
|
|
|
// 下降电缆沟
|
|
double dDeep = GetHeight();
|
|
|
|
pt1 -= vtNorm * dDeep;
|
|
pt2 -= vtNorm * dDeep;
|
|
pt3 -= vtNorm * dDeep;
|
|
pt4 -= vtNorm * dDeep;
|
|
ptS -= vtNorm * dDeep;
|
|
ptE -= vtNorm * dDeep;
|
|
|
|
AcGePoint3d *pVerList = NULL;
|
|
|
|
int nRow = 0;
|
|
int nCol = 0;
|
|
|
|
nRow = 5;
|
|
nCol = 2;
|
|
pVerList = new AcGePoint3d[nRow*nCol];
|
|
if (pVerList != NULL)
|
|
{
|
|
pVerList[0] = pt1 + m_nHeight*vtNorm;
|
|
pVerList[1] = pt3 + m_nHeight*vtNorm;
|
|
pVerList[2] = pt1;
|
|
pVerList[3] = pt3;
|
|
pVerList[4] = ptS;
|
|
pVerList[5] = ptE;
|
|
pVerList[6] = pt2;
|
|
pVerList[7] = pt4;
|
|
pVerList[8] = pt2 + m_nHeight*vtNorm;
|
|
pVerList[9] = pt4 + m_nHeight*vtNorm;
|
|
|
|
dc.DrawMesh(nRow, nCol, pVerList,NULL);
|
|
|
|
delete []pVerList;
|
|
}
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
//宽度
|
|
void TDbCableTrench::SetGougeWidth(double dWidth)
|
|
{
|
|
SetWidth(dWidth);
|
|
}
|
|
|
|
//高度
|
|
void TDbCableTrench::SetGougeHeight(double dHeight)
|
|
{
|
|
assertWriteEnabled();
|
|
SetHeight(dHeight);
|
|
}
|
|
|
|
//倒角半径
|
|
void TDbCableTrench::SetCornerRadius(double dRadius)
|
|
{
|
|
assertWriteEnabled();
|
|
SetSpare(dRadius);
|
|
}
|
|
|
|
//电缆沟线宽
|
|
void TDbCableTrench::SetGougeLineWidth(double dLineW)
|
|
{
|
|
assertWriteEnabled();
|
|
m_dGougeLineW = dLineW;
|
|
}
|
|
|
|
//电缆沟支架形式
|
|
void TDbCableTrench::SetGougeMode(Adesk::UInt16 nType)
|
|
{
|
|
assertWriteEnabled();
|
|
m_nBracketMode = nType;
|
|
}
|
|
|
|
//支架长度
|
|
void TDbCableTrench::SetBracketLen(double dLen)
|
|
{
|
|
assertWriteEnabled();
|
|
m_dBracketLen = dLen;
|
|
}
|
|
|
|
//支架间距
|
|
void TDbCableTrench::SetBracketDis(double dDis)
|
|
{
|
|
assertWriteEnabled();
|
|
m_dBracketDis = dDis;
|
|
}
|
|
|
|
//支架线宽
|
|
void TDbCableTrench::SetBracketLineWidth(double dLineW)
|
|
{
|
|
assertWriteEnabled();
|
|
m_dBracketLineW = dLineW;
|
|
}
|
|
|
|
//宽度
|
|
double TDbCableTrench::GetGougeWidth()
|
|
{
|
|
return GetWidth();
|
|
}
|
|
|
|
//高度
|
|
double TDbCableTrench::GetGougeHeight()
|
|
{
|
|
return GetHeight();
|
|
}
|
|
|
|
//电缆沟线宽
|
|
double TDbCableTrench::GetGougeLineWidth()
|
|
{
|
|
return m_dGougeLineW;
|
|
}
|
|
|
|
//电缆沟支架形式
|
|
Adesk::UInt16 TDbCableTrench::GetGougeMode()
|
|
{
|
|
return m_nBracketMode;
|
|
}
|
|
|
|
//支架长度
|
|
double TDbCableTrench::GetBracketLen()
|
|
{
|
|
return m_dBracketLen;
|
|
}
|
|
|
|
//支架间距
|
|
double TDbCableTrench::GetBracketDis()
|
|
{
|
|
return m_dBracketDis;
|
|
}
|
|
|
|
//支架线宽
|
|
double TDbCableTrench::GetBracketLineWidth()
|
|
{
|
|
return m_dBracketLineW;
|
|
}
|
|
|
|
//拐角类别
|
|
void TDbCableTrench::SetCornerType(Adesk::UInt16 nType)
|
|
{
|
|
assertWriteEnabled();
|
|
|
|
switch(nType)
|
|
{
|
|
case 0:
|
|
SetCanalType(Canal_Corner1);
|
|
break;
|
|
case 1:
|
|
SetCanalType(Canal_Corner3);
|
|
break;
|
|
case 2:
|
|
SetCanalType(Canal_Corner2);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
Adesk::UInt16 TDbCableTrench::GetCornerType()
|
|
{
|
|
Adesk::UInt16 nType = GetCanalType();
|
|
|
|
switch(nType)
|
|
{
|
|
case Canal_Corner1:
|
|
nType = 0;
|
|
break;
|
|
case Canal_Corner2:
|
|
nType = 2;
|
|
break;
|
|
case Canal_Corner3:
|
|
nType = 1;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return nType;
|
|
}
|
|
|
|
//倒角半径
|
|
double TDbCableTrench::GetCornerRadius() const
|
|
{
|
|
return GetSpare();
|
|
}
|
|
|
|
|
|
Acad::ErrorStatus
|
|
TDbCableTrench::subGetOsnapPoints(AcDb::OsnapMode osnapMode,
|
|
INT_PTR gsSelectionMark,
|
|
const AcGePoint3d& ptPick,
|
|
const AcGePoint3d& lastPoint,
|
|
const AcGeMatrix3d& viewXform,
|
|
AcGePoint3dArray& snapPoints,
|
|
AcDbIntArray& geomIds) const
|
|
{
|
|
switch(osnapMode)
|
|
{
|
|
case AcDb::kOsModeEnd:
|
|
{
|
|
AcDbObjectId idNode1(NULL), idNode2(NULL);
|
|
|
|
idNode1 = GetNode(0);
|
|
idNode2 = GetNode(1);
|
|
|
|
if (idNode1.isValid() && idNode2.isValid())
|
|
{
|
|
AcGePoint3d pt1,pt2,pt3,pt4;
|
|
//分别得到电缆沟的一端上两点
|
|
AcArray<CornerLine> map1,map2;
|
|
GetCannalPts(idNode1,pt1,pt2,map1);
|
|
GetCannalPts(idNode2,pt3,pt4,map2);
|
|
|
|
snapPoints.append(pt1);
|
|
snapPoints.append(pt2);
|
|
snapPoints.append(pt3);
|
|
snapPoints.append(pt4);
|
|
snapPoints.append(StartPoint());
|
|
snapPoints.append(EndPoint());
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case AcDb::kOsModeMid:
|
|
{
|
|
AcDbObjectId idNode1(NULL), idNode2(NULL);
|
|
|
|
idNode1 = GetNode(0);
|
|
idNode2 = GetNode(1);
|
|
|
|
if (idNode1.isValid() && idNode2.isValid())
|
|
{
|
|
AcGePoint3d ptMid = Mid(GetStartPoint(),GetEndPoint());
|
|
snapPoints.append(ptMid);
|
|
if (!IsHasMorePipes(idNode1))
|
|
{
|
|
OPENOBJ_BEGIN(idNode1, AcDb::kForRead, TDbPipeNode, pNode);
|
|
if(pNode)
|
|
{
|
|
ptMid = pNode->GetLocation();
|
|
snapPoints.append(ptMid);
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
if (!IsHasMorePipes(idNode2))
|
|
{
|
|
OPENOBJ_BEGIN(idNode2, AcDb::kForRead, TDbPipeNode, pNode);
|
|
if(pNode)
|
|
{
|
|
ptMid = pNode->GetLocation();
|
|
snapPoints.append(ptMid);
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case AcDb::kOsModePerp:
|
|
{
|
|
AcGePoint3d ptVerFoot;
|
|
if (GetVerticalFootPoint(ptPick, lastPoint, ptVerFoot))
|
|
{
|
|
snapPoints.append(ptVerFoot);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case AcDb::kOsModeNear:
|
|
{
|
|
AcGePoint3d ptNear;
|
|
if (GetNearestPoint(ptPick, ptNear))
|
|
{
|
|
snapPoints.append(ptNear);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case AcDb::kOsModeNode:
|
|
break;
|
|
}
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
// 获取垂足点
|
|
BOOL TDbCableTrench::GetVerticalFootPoint(const AcGePoint3d& pickPoint,const AcGePoint3d& lastPoint,AcGePoint3d& ptVerFoot) const
|
|
{
|
|
AcDbObjectId idNode1(NULL), idNode2(NULL);
|
|
|
|
idNode1 = GetNode(0);
|
|
idNode2 = GetNode(1);
|
|
|
|
if (!idNode1.isValid() || !idNode2.isValid())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
AcGePoint3d pt1,pt2,pt3,pt4;
|
|
//分别得到电缆沟的一端上两点
|
|
AcArray<CornerLine> map1,map2;
|
|
GetCannalPts(idNode1,pt1,pt2,map1);
|
|
GetCannalPts(idNode2,pt3,pt4,map2);
|
|
AcArray<AcDbLine*> cplCurve;
|
|
AcDbLine *pLine = NULL;
|
|
|
|
if (!IsHasMorePipes(idNode1))
|
|
{
|
|
pLine = new AcDbLine;
|
|
pLine->setStartPoint(pt1);
|
|
pLine->setEndPoint(pt2);
|
|
cplCurve.append(pLine);
|
|
}
|
|
|
|
pLine = new AcDbLine;
|
|
pLine->setStartPoint(pt1);
|
|
pLine->setEndPoint(pt3);
|
|
cplCurve.append(pLine);
|
|
|
|
if (!IsHasMorePipes(idNode2))
|
|
{
|
|
pLine = new AcDbLine;
|
|
pLine->setStartPoint(pt4);
|
|
pLine->setEndPoint(pt3);
|
|
cplCurve.append(pLine);
|
|
}
|
|
|
|
pLine = new AcDbLine;
|
|
pLine->setStartPoint(pt4);
|
|
pLine->setEndPoint(pt2);
|
|
cplCurve.append(pLine);
|
|
|
|
for (int t = 0;t < map1.length();t++)
|
|
{
|
|
pLine = new AcDbLine;
|
|
pLine->setStartPoint(map1[t].pair.first);
|
|
pLine->setEndPoint(map1[t].pair.second);
|
|
cplCurve.append(pLine);
|
|
}
|
|
|
|
for (int j = 0;j < map2.length();j++)
|
|
{
|
|
pLine = new AcDbLine;
|
|
pLine->setStartPoint(map2[j].pair.first);
|
|
pLine->setEndPoint(map2[j].pair.second);
|
|
cplCurve.append(pLine);
|
|
}
|
|
|
|
BOOL bFind = FALSE;
|
|
if (cplCurve.length() > 0)
|
|
{
|
|
double dDisToLine = 0.0;
|
|
double dDisOld = 100000.0;
|
|
AcGePoint3d ptOnLine;
|
|
int nIndex = -1;
|
|
|
|
// 挑选离pick点最近的线
|
|
for (int i = 0;i < cplCurve.length();i++)
|
|
{
|
|
if (cplCurve[i]->getClosestPointTo(pickPoint, ptOnLine,Adesk::kTrue) == Acad::eOk)
|
|
{
|
|
dDisToLine = pickPoint.distanceTo(ptOnLine);
|
|
if (dDisOld > dDisToLine)
|
|
{
|
|
dDisOld = dDisToLine;
|
|
nIndex = i;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 找到第一次取的点到该线的垂点
|
|
if (nIndex != -1)
|
|
{
|
|
if (cplCurve[nIndex]->getClosestPointTo(lastPoint, ptOnLine,Adesk::kTrue) == Acad::eOk)
|
|
{
|
|
ptVerFoot = ptOnLine;
|
|
bFind = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
FreeBuffer(cplCurve);
|
|
|
|
return bFind;
|
|
}
|
|
|
|
// 获取最近点
|
|
BOOL TDbCableTrench::GetNearestPoint(const AcGePoint3d& pickPoint,AcGePoint3d& ptNear) const
|
|
{
|
|
AcDbObjectId idNode1(NULL), idNode2(NULL);
|
|
|
|
idNode1 = GetNode(0);
|
|
idNode2 = GetNode(1);
|
|
|
|
if (!idNode1.isValid() || !idNode2.isValid())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
AcGePoint3d pt1,pt2,pt3,pt4;
|
|
//分别得到电缆沟的一端上两点
|
|
AcArray<CornerLine> map1,map2;
|
|
GetCannalPts(idNode1,pt1,pt2,map1);
|
|
GetCannalPts(idNode2,pt3,pt4,map2);
|
|
AcArray<AcDbLine*> cplCurve;
|
|
AcDbLine *pLine = NULL;
|
|
|
|
if (!IsHasMorePipes(idNode1))
|
|
{
|
|
pLine = new AcDbLine;
|
|
pLine->setStartPoint(pt1);
|
|
pLine->setEndPoint(pt2);
|
|
cplCurve.append(pLine);
|
|
}
|
|
|
|
pLine = new AcDbLine;
|
|
pLine->setStartPoint(pt1);
|
|
pLine->setEndPoint(pt3);
|
|
cplCurve.append(pLine);
|
|
|
|
if (!IsHasMorePipes(idNode2))
|
|
{
|
|
pLine = new AcDbLine;
|
|
pLine->setStartPoint(pt4);
|
|
pLine->setEndPoint(pt3);
|
|
cplCurve.append(pLine);
|
|
}
|
|
|
|
pLine = new AcDbLine;
|
|
pLine->setStartPoint(pt4);
|
|
pLine->setEndPoint(pt2);
|
|
cplCurve.append(pLine);
|
|
|
|
for (int t = 0;t < map1.length();t++)
|
|
{
|
|
pLine = new AcDbLine;
|
|
pLine->setStartPoint(map1[t].pair.first);
|
|
pLine->setEndPoint(map1[t].pair.second);
|
|
cplCurve.append(pLine);
|
|
}
|
|
|
|
for (int j = 0;j < map2.length();j++)
|
|
{
|
|
pLine = new AcDbLine;
|
|
pLine->setStartPoint(map2[j].pair.first);
|
|
pLine->setEndPoint(map2[j].pair.second);
|
|
cplCurve.append(pLine);
|
|
}
|
|
|
|
BOOL bFind = FALSE;
|
|
if (cplCurve.length() > 0)
|
|
{
|
|
double dDisToLine = 0.0;
|
|
double dDisOld = 100000.0;
|
|
AcGePoint3d ptOnLine;
|
|
// 挑选离pick点最近的线
|
|
|
|
for (int i = 0;i < cplCurve.length();i++)
|
|
{
|
|
if (cplCurve[i]->getClosestPointTo(pickPoint, ptOnLine) == Acad::eOk)
|
|
{
|
|
dDisToLine = pickPoint.distanceTo(ptOnLine);
|
|
if (dDisOld > dDisToLine)
|
|
{
|
|
dDisOld = dDisToLine;
|
|
ptNear = ptOnLine;
|
|
bFind = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
FreeBuffer(cplCurve);
|
|
|
|
return bFind;
|
|
}
|
|
|
|
// 释放内存
|
|
void TDbCableTrench::FreeBuffer(AcArray<AcDbLine*>& cplCurve) const
|
|
{
|
|
for (int i = 0;i < cplCurve.length();i++)
|
|
{
|
|
delete cplCurve[i];
|
|
}
|
|
}
|
|
|
|
//电缆编号
|
|
void TDbCableTrench::SetTrenchNo(LPCTSTR lpNo)
|
|
{
|
|
if (lpNo != NULL)
|
|
m_sTrenchNo = lpNo;
|
|
}
|
|
|
|
//得到电缆编号
|
|
void TDbCableTrench::GetTrenchNo(CString &sNo)
|
|
{
|
|
sNo = m_sTrenchNo;
|
|
}
|
|
|
|
CString TDbCableTrench::GetXml(const AcGeMatrix3d& mat) const
|
|
{
|
|
CString csXml;
|
|
int nValue(0);
|
|
double dValue(0.0);
|
|
int nSizePreci(3), nPtPreci(6); // 尺寸、位置精度
|
|
|
|
TXmlTree xmlTree;
|
|
CString csText;
|
|
CString csX, csY, csZ;
|
|
|
|
AcDbObjectId idNode1(NULL), idNode2(NULL);
|
|
AcDbObjectIdArray arIds;
|
|
idNode1 = GetNode(0);
|
|
idNode2 = GetNode(1);
|
|
|
|
if (!idNode1.isValid() || !idNode2.isValid())
|
|
{
|
|
return csXml;
|
|
}
|
|
|
|
arIds.append(idNode1);
|
|
arIds.append(idNode2);
|
|
|
|
AcGePoint3d pt1,pt2,pt3,pt4,ptS,ptE;
|
|
|
|
XCurveSegment cvHide,segUp, segDown;
|
|
cvHide = GetCurve();
|
|
XDirectionCurve segDir(cvHide.StartPoint(), cvHide.EndPoint(), cvHide.GetBulge());
|
|
segUp = segDir.Offset(m_nWidth/2, LS_FINITE);
|
|
segDown = segDir.Offset(-m_nWidth/2, LS_FINITE);
|
|
pt1 = segUp.StartPoint();
|
|
pt3 = segUp.EndPoint();
|
|
pt2 = segDown.StartPoint();
|
|
pt4 = segDown.EndPoint();
|
|
ptS = cvHide.StartPoint();
|
|
ptE = cvHide.EndPoint();
|
|
|
|
double dW = m_nWidth;
|
|
double dH = m_nHeight;
|
|
|
|
AcGeVector3d vtNorm = AcGeVector3d::kZAxis;
|
|
AcGeVector3d vtDir = pt3 - pt1;
|
|
AcArray<CornerLine> map;
|
|
if (!vtDir.isPerpendicularTo(AcGeVector3d::kZAxis))
|
|
{
|
|
AcGeVector3d vtT = vtDir.orthoProject(AcGeVector3d::kZAxis);
|
|
vtT.rotateBy(PI/2,AcGeVector3d::kZAxis);
|
|
AcGeVector3d vtT2 = vtDir.crossProduct(vtT);
|
|
vtNorm = vtT2;
|
|
vtNorm.normalize();
|
|
}
|
|
else
|
|
{
|
|
//分别得到方沟的一端上两点
|
|
GetCannalPts(idNode1,pt1,pt2);
|
|
GetCannalPts(idNode2,pt3,pt4);
|
|
}
|
|
|
|
// 下降电缆沟
|
|
double dDeep = GetHeight();
|
|
|
|
pt1 -= vtNorm * dDeep;
|
|
pt2 -= vtNorm * dDeep;
|
|
pt3 -= vtNorm * dDeep;
|
|
pt4 -= vtNorm * dDeep;
|
|
ptS -= vtNorm * dDeep;
|
|
ptE -= vtNorm * dDeep;
|
|
|
|
AcGePoint3d *pVerList = NULL;
|
|
|
|
int nRow = 0;
|
|
int nCol = 0;
|
|
|
|
nRow = 5;
|
|
nCol = 2;
|
|
pVerList = new AcGePoint3d[nRow*nCol];
|
|
if (pVerList != NULL)
|
|
{
|
|
pVerList[0] = pt1 + m_nHeight*vtNorm;
|
|
pVerList[1] = pt3 + m_nHeight*vtNorm;
|
|
pVerList[2] = pt1;
|
|
pVerList[3] = pt3;
|
|
pVerList[4] = ptS;
|
|
pVerList[5] = ptE;
|
|
pVerList[6] = pt2;
|
|
pVerList[7] = pt4;
|
|
pVerList[8] = pt2 + m_nHeight*vtNorm;
|
|
pVerList[9] = pt4 + m_nHeight*vtNorm;
|
|
|
|
POSITION posRoot = xmlTree.Insert(_T("TCH_GOUGE"), NULL, NULL);
|
|
{
|
|
xmlTree.SetAttribute(posRoot, _T("name"), _T("电缆沟"));
|
|
xmlTree.SetAttribute(posRoot, _T("comment"), _T("上华对象名称"));
|
|
}
|
|
|
|
// 点组
|
|
POSITION nowPos;
|
|
for (int i = 0; i<(nRow*nCol); i++)
|
|
{
|
|
CString strName, strCName;
|
|
strName.Format(_T("pt_%d"), i);
|
|
strCName.Format(_T("点_%d"), i);
|
|
nowPos = xmlTree.Insert(strName, posRoot,NULL);
|
|
{
|
|
xmlTree.SetAttribute(nowPos, _T("name"),strCName);
|
|
xmlTree.SetAttribute(nowPos, _T("comment"), strCName);
|
|
AcGePoint3d pt = pVerList[i];
|
|
csX.Format(_T("%.6f"),pt.x);
|
|
csY.Format(_T("%.6f"),pt.y);
|
|
csZ.Format(_T("%.6f"),pt.z);
|
|
csText.Format(_T("%s,%s,%s"),csX,csY,csZ);
|
|
xmlTree.SetItemText(nowPos,csText);
|
|
}
|
|
}
|
|
// 宽度
|
|
nowPos = xmlTree.Insert(_T("Width"),posRoot,NULL);
|
|
{
|
|
xmlTree.SetAttribute(nowPos, _T("name"), _T("宽度"));
|
|
xmlTree.SetAttribute(nowPos, _T("comment"), _T("宽度"));
|
|
csText.Format(_T("%.3f"),m_nWidth);
|
|
xmlTree.SetItemText(nowPos,csText);
|
|
}
|
|
// 高度
|
|
nowPos = xmlTree.Insert(_T("Height"),posRoot,NULL);
|
|
{
|
|
xmlTree.SetAttribute(nowPos, _T("name"), _T("高度"));
|
|
xmlTree.SetAttribute(nowPos, _T("comment"), _T("高度"));
|
|
csText.Format(_T("%.3f"),m_nHeight);
|
|
xmlTree.SetItemText(nowPos,csText);
|
|
}
|
|
// id
|
|
nowPos = xmlTree.Insert(_T("Object_ID"),posRoot,NULL);
|
|
{
|
|
xmlTree.SetAttribute(nowPos, _T("name"), _T("ID"));
|
|
xmlTree.SetAttribute(nowPos, _T("comment"), _T("电缆沟ID"));
|
|
csText.Format(_T("%ld"), objectId().asOldId());
|
|
xmlTree.SetItemText(nowPos, csText);
|
|
}
|
|
delete []pVerList;
|
|
}
|
|
|
|
csXml = xmlTree.GetXml();
|
|
int nIndex = -1;
|
|
nIndex = csXml.Find(_T("</TCH_GOUGE>"));
|
|
if (nIndex != -1)
|
|
{
|
|
CString sTemp = TDbCurveEntity::GetXml(mat);
|
|
csXml.Insert(nIndex, sTemp);
|
|
}
|
|
|
|
return csXml;
|
|
}
|
|
|
|
bool TDbCableTrench::GetSection(const AcDbFace &face, const AcGeVector3d &vtPlaneSecDir,
|
|
std::vector<TObjSectionRecord> §ionRecord, AcDbVoidPtrArray& arFillPtrs) const
|
|
{
|
|
// 基本参数
|
|
AcDbObjectId idObj = this->objectId();
|
|
AcDbObjectId idLayer = this->layerId();
|
|
TGGeSectionPlane section_pln(face, vtPlaneSecDir); // 构造一个辅助剖面
|
|
AcDbVoidPtrArray arFaces;
|
|
XExplodeStream dc(arFaces);
|
|
ExplodeOrDraw3d(dc);
|
|
|
|
double dElevation = 0;
|
|
AcDbEntity* pEnt = NULL;
|
|
AcDbFace* pFace = NULL;
|
|
int i = 0;
|
|
for(i = 0; i < arFaces.length(); ++i)
|
|
{
|
|
pEnt = (AcDbEntity*)arFaces[i];
|
|
if (NULL == pEnt)
|
|
continue;
|
|
pFace = AcDbFace::cast(pEnt);
|
|
if (pFace)
|
|
{
|
|
TGGeSectionPlane pln(*pFace, vtPlaneSecDir);
|
|
TGGePoly2D poly;
|
|
dElevation = SectionUtility::Projection_plane2plane(section_pln, pln, poly);
|
|
if (poly.Length() > 0)
|
|
{
|
|
sectionRecord.push_back(TObjSectionRecord(idObj, idLayer, TObjSectionRecord::eTCH_WALL, dElevation, poly));
|
|
}
|
|
}
|
|
delete pEnt;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// 剖切用,返回Z坐标最高、最低点
|
|
Acad::ErrorStatus TDbCableTrench::GetExtents(TADSGePoint3d &ptLow, TADSGePoint3d &ptUp) const
|
|
{
|
|
AcDbObjectId idNode1(NULL), idNode2(NULL);
|
|
AcDbObjectIdArray arIds;
|
|
idNode1 = GetNode(0);
|
|
idNode2 = GetNode(1);
|
|
|
|
if (!idNode1.isValid() || !idNode2.isValid())
|
|
{
|
|
return Acad::eInvalidInput;
|
|
}
|
|
|
|
arIds.append(idNode1);
|
|
arIds.append(idNode2);
|
|
|
|
AcGePoint3d pt1,pt2,pt3,pt4,ptS,ptE;
|
|
|
|
XCurveSegment cvHide,segUp, segDown;
|
|
cvHide = GetCurve();
|
|
ptUp = cvHide.StartPoint();
|
|
ptLow = ptUp;
|
|
ptLow.z -= m_nHeight;
|
|
return Acad::eOk;
|
|
}
|
|
|
|
int TDbCableTrench::GetBodyBox(AcDbExtents& ext)
|
|
{
|
|
//得到电缆沟两端节点
|
|
//得到方沟两端节点
|
|
AcDbObjectId idNode1(NULL), idNode2(NULL);
|
|
AcDbObjectIdArray arIds;
|
|
idNode1 = GetNode(0);
|
|
idNode2 = GetNode(1);
|
|
|
|
if (!idNode1.isValid() || !idNode2.isValid())
|
|
{
|
|
return Acad::eInvalidInput;
|
|
}
|
|
|
|
arIds.append(idNode1);
|
|
arIds.append(idNode2);
|
|
|
|
AcGePoint3d pt1,pt2,pt3,pt4,ptS,ptE;
|
|
|
|
XCurveSegment cvHide,segUp, segDown;
|
|
cvHide = GetCurve();
|
|
XDirectionCurve segDir(cvHide.StartPoint(), cvHide.EndPoint(), cvHide.GetBulge());
|
|
segUp = segDir.Offset(m_nWidth/2, LS_FINITE);
|
|
segDown = segDir.Offset(-m_nWidth/2, LS_FINITE);
|
|
pt1 = segUp.StartPoint();
|
|
pt3 = segUp.EndPoint();
|
|
pt2 = segDown.StartPoint();
|
|
pt4 = segDown.EndPoint();
|
|
ptS = cvHide.StartPoint();
|
|
ptE = cvHide.EndPoint();
|
|
|
|
double dW = m_nWidth;
|
|
double dH = m_nHeight;
|
|
|
|
AcGeVector3d vtNorm = AcGeVector3d::kZAxis;
|
|
AcGeVector3d vtDir = pt3 - pt1;
|
|
AcArray<CornerLine> map;
|
|
if (!vtDir.isPerpendicularTo(AcGeVector3d::kZAxis))
|
|
{
|
|
AcGeVector3d vtT = vtDir.orthoProject(AcGeVector3d::kZAxis);
|
|
vtT.rotateBy(PI/2,AcGeVector3d::kZAxis);
|
|
AcGeVector3d vtT2 = vtDir.crossProduct(vtT);
|
|
vtNorm = vtT2;
|
|
vtNorm.normalize();
|
|
}
|
|
else
|
|
{
|
|
//分别得到方沟的一端上两点
|
|
GetCannalPts(idNode1,pt1,pt2);
|
|
GetCannalPts(idNode2,pt3,pt4);
|
|
}
|
|
|
|
// 下降电缆沟
|
|
double dDeep = GetHeight();
|
|
|
|
pt1 -= vtNorm * dDeep;
|
|
pt2 -= vtNorm * dDeep;
|
|
pt3 -= vtNorm * dDeep;
|
|
pt4 -= vtNorm * dDeep;
|
|
ptS -= vtNorm * dDeep;
|
|
ptE -= vtNorm * dDeep;
|
|
/*
|
|
AcGePoint3d *pVerList = NULL;
|
|
|
|
int nRow = 0;
|
|
int nCol = 0;
|
|
|
|
nRow = 5;
|
|
nCol = 2;
|
|
pVerList = new AcGePoint3d[nRow*nCol];
|
|
*/
|
|
|
|
AcGePoint3d pVerList[10];
|
|
|
|
pVerList[0] = pt1 + m_nHeight*vtNorm;
|
|
pVerList[1] = pt3 + m_nHeight*vtNorm;
|
|
pVerList[2] = pt1;
|
|
pVerList[3] = pt3;
|
|
pVerList[4] = ptS;
|
|
pVerList[5] = ptE;
|
|
pVerList[6] = pt2;
|
|
pVerList[7] = pt4;
|
|
pVerList[8] = pt2 + m_nHeight*vtNorm;
|
|
pVerList[9] = pt4 + m_nHeight*vtNorm;
|
|
|
|
double dMaxX = pVerList[0].x;
|
|
double dMaxY = pVerList[0].y;
|
|
double dMaxZ = pVerList[0].z;
|
|
double dMinX = dMaxX;
|
|
double dMinY = dMaxY;
|
|
double dMinZ = dMaxZ;
|
|
|
|
for (int i = 0; i < 10; ++i)
|
|
{
|
|
if (dMaxX < pVerList[i].x)
|
|
dMaxX = pVerList[i].x;
|
|
|
|
if (dMaxY < pVerList[i].y)
|
|
dMaxY = pVerList[i].y;
|
|
|
|
if (dMaxZ < pVerList[i].z)
|
|
dMaxZ = pVerList[i].z;
|
|
|
|
if (dMinX > pVerList[i].x)
|
|
dMinX = pVerList[i].x;
|
|
|
|
if (dMinY > pVerList[i].y)
|
|
dMinY = pVerList[i].y;
|
|
|
|
if (dMinZ > pVerList[i].z)
|
|
dMinZ = pVerList[i].z;
|
|
}
|
|
|
|
AcGePoint3d ptMax(dMaxX,dMaxY,dMaxZ);
|
|
AcGePoint3d ptMin(dMinX,dMinY,dMinZ);
|
|
|
|
ext.set(ptMin,ptMax);
|
|
|
|
return 1;
|
|
} |