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

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> &sectionRecord, 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;
}