Files
envi-code/SourceCode/Code2026/tg_shs/shs_pipewire/DbPipeCanal.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

3000 lines
78 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// TDbPipeCanal.cpp: implementation of the TDbPipeCanal class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DbPipeCanal.h"
#include <DbCurveMesh.h>
#include <DbPolyMesh.h>
#include "PipeTools.h"
#include "DbFlangeFitting.h"
#include <map>
#include <vector>
#include <Algorithm>
#include "DbCanalFitting.h"
extern void DrawWeight(XExplodeDraw &dc,double dWeight,XCurveSegment &seg,int nColorIndex, double nScale);
// cet 2011.6.27 add
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);
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
ACRX_DXF_DEFINE_MEMBERS(ATSPipeCanal, ATSPipe, AcDb::kDHL_CURRENT,
AcDb::kMReleaseCurrent, 1, ATS_PIPECANAL,
"ATS_PIPECANAL图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(TDbPipeCanal);
const Adesk::UInt8 TDbPipeCanal::g_nVersion = 1;
TDbPipeCanal::TDbPipeCanal()
{
m_nWidth = 800;
m_nHeight = 800;
m_sSpare = _T("");
m_nCanalType = Canal_Corner5;
m_nSpare = 0.0;
m_dRate = 0.0;
m_nCanalType = 0;
m_nEntType = 0;
}
TDbPipeCanal::~TDbPipeCanal()
{
}
Acad::ErrorStatus TDbPipeCanal::subGetClassID(CLSID* pClsid) const
{
return Acad::eOk;
}
void TDbPipeCanal::CopyPropertiesFrom(AcDbEntity *pSrc,unsigned gMatchFlag)
{
assertWriteEnabled();
TDbPipe::CopyPropertiesFrom(pSrc, gMatchFlag);
TDbPipeCanal *pPipe = TDbPipeCanal::cast(pSrc);
if(pPipe) {
m_nWidth = pPipe->m_nWidth;
m_nHeight = pPipe->m_nHeight;
m_nSpare = pPipe->m_nSpare;
m_dRate = pPipe->m_dRate;
m_nCanalType = pPipe->m_nCanalType;
m_nEntType = pPipe->m_nEntType;
m_sSpare = pPipe->m_sSpare;
m_idDoteLayer = pPipe->m_idDoteLayer;
}
}
Acad::ErrorStatus
TDbPipeCanal::subGetOsnapPoints(AcDb::OsnapMode osnapMode,
INT_PTR gsSelectionMark,
const AcGePoint3d& ptPick,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcGePoint3dArray& snapPoints,
AcDbIntArray& geomIds) const
{
if(IsVertical() && Is(CURVE_LINE) && GetExplodeMode()==DRAW_2D) //立管
{
XPoint ptMid = MidPoint();
ptMid.z=0;
snapPoints.append(ptMid);
}
else
{
snapPoints.append(StartPoint());
snapPoints.append(EndPoint());
XPoint ptMid = MidPoint();
snapPoints.append(ptMid);
// 捕捉中线
XCurveSegment seg = this->GetCurve();
AcDbCurve *pCurve = seg.AsAcDbCurve();
if (pCurve != NULL)
{
pCurve->getOsnapPoints(osnapMode, gsSelectionMark, ptPick, lastPoint, viewXform, snapPoints, geomIds, viewXform);
delete pCurve;
}
}
return Acad::eOk;
}
// 取得所有的夹点
Acad::ErrorStatus
TDbPipeCanal::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const
{
assertReadEnabled();
Acad::ErrorStatus es=Acad::eOk;
// es=TDbPipe::subGetGripPoints(gripPoints, osnapModes, geomIds); // cet 2010.6.9 del
// cet 2010.6.9 add 删除标注点夹点
// TDbPipe::subGetGripPoints
if(IsVertical() && Is(CURVE_LINE) && GetExplodeMode()==DRAW_2D) //立管
{
XPoint ptMid = MidPoint();
ptMid.z=0;
gripPoints.append(ptMid);
}
else
{
gripPoints.append(StartPoint());
gripPoints.append(EndPoint());
XPoint ptMid = MidPoint();
gripPoints.append(ptMid);
}
// TDbPipePrototype::subGetGripPoints
if(!IsVertical() && g_bSPipeFDir)
{
XPoint ptMid = MidPoint();
double dDir(0);
if(m_flowDir==TPipeSys::kFromEnd)
dDir = ads_angle(GetEndPoint(), GetStartPoint());
else
dDir = ads_angle(GetStartPoint(), GetEndPoint());
XPoint p1;
ads_polar(ptMid, dDir, GetPScale()*2, p1);
gripPoints.append(p1);
}
return es;
}
// 取得夹点说明
Acad::ErrorStatus TDbPipeCanal::GetGripText(int idx, CString &cs) const
{
Acad::ErrorStatus es=Acad::eOk;
es = TDbPipe::GetGripText(idx,cs);
return es;
}
// 从DWG读入数据:
Acad::ErrorStatus
TDbPipeCanal::dwgInFields(AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbPipe::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_nWidth);
pFiler->readItem(&m_nHeight);
pFiler->readItem(&m_nSpare);
pFiler->readItem(&m_idDoteLayer);
pFiler->readItem(&m_dRate);
pFiler->readUInt16(&m_nCanalType);
pFiler->readUInt16(&m_nEntType);
ReadString(pFiler,m_sSpare);
return pFiler->filerStatus();
}
Acad::ErrorStatus
TDbPipeCanal::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbPipe::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
pFiler->writeItem(g_nVersion);
pFiler->writeItem(m_nWidth);
pFiler->writeItem(m_nHeight);
pFiler->writeItem(m_nSpare);
pFiler->writeItem(m_idDoteLayer);
pFiler->writeItem(m_dRate);
pFiler->writeItem(m_nCanalType);
pFiler->writeItem(m_nEntType);
pFiler->writeString(m_sSpare);
return pFiler->filerStatus();
}
Acad::ErrorStatus
TDbPipeCanal::dxfInFields(AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es=Acad::eOk;
es=TDbPipe::dxfInFields(pFiler);
if(es!=Acad::eOk) return es;
if (!pFiler->atSubclassData(_T("TDbPipeCanal"))) {
return Acad::eBadDxfSequence;
}
resbuf rb;
while((es==Acad::eOk) && ((es=pFiler->readResBuf(&rb))==Acad::eOk)) {
switch (rb.restype) {
case AcDb::kDxfXReal:
m_nWidth=rb.resval.rreal;
break;
default:
pFiler->pushBackItem();
es = Acad::eEndOfFile;
break;
}
}
if(es!=Acad::eEndOfFile)
return Acad::eInvalidResBuf;
return pFiler->filerStatus();
}
Acad::ErrorStatus
TDbPipeCanal::dxfOutFields(AcDbDxfFiler* pFiler) const
{
Acad::ErrorStatus es=Acad::eOk;
es=TDbPipe::dxfOutFields(pFiler);
assert(es==Acad::eOk);
es=pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbPipeCanal"));
assert(es==Acad::eOk);
pFiler->writeDouble(AcDb::kDxfXReal, m_nWidth);
return es;
}
void TDbPipeCanal::ResetDrawSpeed()
{
assertWriteEnabled();
double dSpeedLength=0, dSpeedSubMid=0;//初始化
if (m_nodeEnd.m_idNode.isValid())
{
OPENOBJ_BEGIN(m_nodeEnd.m_idNode,AcDb::kForRead,TDbPipeNode,pNode);
if(pNode!=NULL) {
if(pNode->IsHidePipe()) { //是否节点遮挡管线
double dWidth = pNode->GetWidth(this);
if (dWidth>1.0E-3) {
dSpeedLength -= dWidth;
dSpeedSubMid -= dWidth/2;
}
}
}
OPENOBJ_END();
}
if (m_nodeStart.m_idNode.isValid())
{
OPENOBJ_BEGIN(m_nodeStart.m_idNode,AcDb::kForRead,TDbPipeNode,pNode);
if (pNode!=NULL) {
if (pNode->IsHidePipe()) {
double dWidth = pNode->GetWidth(this);
if (dWidth>1.0E-3) {
dSpeedLength -= dWidth;
dSpeedSubMid += dWidth/2;
}
}
}
OPENOBJ_END();
}
if(fabs(dSpeedLength)>1.0E-3 || fabs(dSpeedSubMid)>1.0E-3) {
XCurveSegment cv=GetCurve();
cv.SetElevation(0);//设置为二维,z=0
double dLength = cv.GetLength();
m_dSpeedLength = dLength + dSpeedLength;
m_dSpeedSubMid = dLength/2 + dSpeedSubMid;
} else {
m_dSpeedLength = 0;
m_dSpeedSubMid = 0;
}
}
// 通过管件附件打断的曲线,二维,z=0
void TDbPipeCanal::GetBrokenCurves(const XCurveSegment &cv,
DList<XCurveSegment> &lstCurve) const
{
lstCurve.Append(new XCurveSegment(cv));
return;
}
// 考虑遮挡的当前曲线,二维,z=0
void TDbPipeCanal::GetHideCurve(XCurveSegment& cvHide) const
{
XCurveSegment cvHideTemp=GetCurve();
cvHideTemp.SetElevation(0);//设置为二维,z=0
//该为将数据写入数据库加速二维显示速度
if (fabs(m_dSpeedLength)>1.0E-3 && fabs(m_dSpeedSubMid)>1.0E-3) {
double dChordLength = cvHideTemp.GetChordLength(m_dSpeedLength);
XPointDir2d ptSubMid;
cvHideTemp.Polar(m_dSpeedSubMid,ptSubMid);
cvHideTemp.GetSubSegment(ptSubMid,dChordLength,cvHide);
return;
}
cvHide = cvHideTemp;
}
void TDbPipeCanal::ExplodeOrDrawPipeCanalCenLine(XExplodeDraw &dc) const
{
// cet 2016.8.15 add 有盖板不绘制中心线
if (GetCoverType() != 0)
{
return;
}
// 判断是否绘制中线 cet 2012.10.11 add
TDbPsConfig *pConfig = GetDwgPsGlobal(AcDb::kForRead);
if (pConfig != NULL && !pConfig->IsShowPipeCanalMidLine())
{
pConfig->close();
return;
}
else if (pConfig != NULL)
{
pConfig->close();
}
XCurveSegment cvHide=GetCurve();//二维,z=0
//绘制中心线
DList<XCurveSegment> lstCurve;
GetBrokenCurves(cvHide, lstCurve);
int nCount = lstCurve.Length();
//2008-5-28 指定中心线图层,从而改变中心线的线形,这种方法不对,打印的时候仍然是实线
// SR 修改如下: 读取图层的线形,强制设置dc的线形,同时取消中心线图层
// 对于炸开,仍然采用图层
if(_tcsicmp(dc.Desc(), XExplodeStream::Descriptor())==0) { //另存旧版,炸开 2图层
AcDbObjectId idLayerOld=dc.GetLayerId();
AcDbObjectId idDoteLayer=m_idDoteLayer;
if(idDoteLayer.isValid())
dc.SetLayer(idDoteLayer);
dc.SetColorLayer(colorIndex(), idDoteLayer);
for (int i=0; i<nCount; i++) {
XCurveSegment &seg = *lstCurve[i];
dc << seg;
}
dc.SetLayer(idLayerOld);
dc.SetColorLayer(colorIndex(), idLayerOld);
}
else{ //自定义实体 1个图层
AcDbObjectId idLineTypeOld = dc.GetLineTypeId();
int iColorOld = dc.GetColor();
AcDbObjectId idLineType = NULL;
if (m_idDoteLayer.isValid())
{
OPENOBJ_BEGIN(m_idDoteLayer,AcDb::kForRead,AcDbLayerTableRecord,pLayer);
if(pLayer){
idLineType = pLayer->linetypeObjectId();
AcCmColor Color = pLayer->color();
int iColIdx = Color.colorIndex();
dc.SetColor(iColIdx);
dc.SetLineType(idLineType);
}
OPENOBJ_END();
}
for (int i=0; i<nCount; i++) {
XCurveSegment &seg = *lstCurve[i];
dc << seg;
}
dc.SetLineType(idLineTypeOld);
dc.SetColor(iColorOld);
}
}
Acad::ErrorStatus
TDbPipeCanal::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
Acad::ErrorStatus es=Acad::eOk;
// 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;
}
//绘制中线
ExplodeOrDrawPipeCanalCenLine(dc);
//绘制方沟上线和下线
ExplodeOrDrawPipeCanal(dc);
return es;
}
AOLAPI double g_nAcadVer;
Acad::ErrorStatus
TDbPipeCanal::ExplodeOrDraw3d(XExplodeDraw &dc) const
{
//垂直管线
XVector3D vtLocation=EndPoint()-StartPoint();
if(fabs(vtLocation.x)<1.0E-6 && fabs(vtLocation.y)<1.0E-6) //垂直管线
{
return Acad::eOk;
}
//绘制
Draw3dType(dc);
return Acad::eOk;
}
//取动态属性显示数据
void TDbPipeCanal::GetTips(DList<TObjInfoUnit> &lstInfo) const
{
if(IsHorizontal()) {
lstInfo.Append(new TObjInfoUnit(_T("标高"), Dist2Str(GetStartPoint().z)));
} else {
lstInfo.Append(new TObjInfoUnit(_T("起点标高"), Dist2Str(GetStartPoint().z)));
lstInfo.Append(new TObjInfoUnit(_T("终点标高"), Dist2Str(GetEndPoint().z)));
}
double nDist=0.0;
getDistAtPoint(EndPoint(), nDist);
lstInfo.Append(new TObjInfoUnit(_T("长度"), Dist2Str(nDist)));
lstInfo.Append(new TObjInfoUnit(_T("宽度"), Dist2Str(m_nWidth)));
lstInfo.Append(new TObjInfoUnit(_T("高度"), Dist2Str(m_nHeight)));
}
// 功能: 夹点操作
Acad::ErrorStatus
TDbPipeCanal::subMoveGripPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
Acad::ErrorStatus es=Acad::eOk;
int nCount=indices.length();
int idx = indices[0];
if(idx == 2 && !IsVertical() && Is(CURVE_LINE)){
es=MoveGSPointsAt(indices,offset,TRUE);
}
else
es=TDbPipePrototype::subMoveGripPointsAt(indices, offset);
if(es!=Acad::eOk) return es;
return es;
}
Acad::ErrorStatus
TDbPipeCanal::MoveGSPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset,
BOOL bGrip)
{
Acad::ErrorStatus es=Acad::eOk;
AcGeVector3d vtOffset=offset;
AcGeMatrix3d mat;
mat.setToTranslation(vtOffset);
BOOL bApply=objectId().isValid();
AcGeVector3d vtPipe(EndPoint() - StartPoint());
XPoint ptStartOld = StartPoint();
XPoint ptEndOld = EndPoint();
Transform(mat, bApply,bGrip);
if(bApply == NULL || !vtOffset.isPerpendicularTo(vtPipe)) //如果平移向量不垂直于管线,就返回
return es;
//联动修改所接管线
AcDbObjectId id1 = GetNode(0);
AcDbObjectId id2 = GetNode(1);
if (id1.isValid() && id2.isValid())
{
OPENOBJ_BEGIN(id1,AcDb::kForRead,TDbPipeNode,pNode);
if(pNode!=NULL) { // 节点
if(pNode->IsAutoLiving()){ // 需自动生成的节点
if(pNode->GetInterfaceNum() == 2){
XPoint ptLoc = pNode->GetLocation();
for(int j=0; j<2; j++) { // 接口
const AcDbObjectId &idPipe=pNode->GetIPipe(j);
if(idPipe != objectId()) {
XPoint ptStart, ptEnd;
OPENOBJ_BEGIN(idPipe,AcDb::kForWrite,TDbPipeCanal,pPipe);
if(pPipe != NULL && !pPipe->IsVertical()) {
ptStart = pPipe->StartPoint();
ptEnd = pPipe->EndPoint();
if(ptLoc == ptStart){
XPoint ptOffset=ptStart+offset;
pPipe->SetStartPoint(ptOffset);
}
else if(ptLoc == ptEnd){
XPoint ptOffset=ptEnd+offset;
pPipe->SetEndPoint(ptOffset);
}
}
OPENOBJ_END();
}
}
}
}
}
OPENOBJ_END();
//同上,代码直接COPY
OPENOBJ_BEGIN(id2,AcDb::kForRead,TDbPipeNode,pNode);
if(pNode!=NULL) { // 节点
if(pNode->IsAutoLiving()){ // 需自动生成的节点
if(pNode->GetInterfaceNum() == 2){
XPoint ptLoc = pNode->GetLocation();
for(int j=0; j<2; j++) { // 接口
const AcDbObjectId &idPipe=pNode->GetIPipe(j);
if(idPipe != objectId()) {
XPoint ptStart, ptEnd;
OPENOBJ_BEGIN(idPipe,AcDb::kForWrite,TDbPipeCanal,pPipe);
if(pPipe != NULL && !pPipe->IsVertical()) {
ptStart = pPipe->StartPoint();
ptEnd = pPipe->EndPoint();
if(ptLoc == ptStart){
XPoint ptOffset=ptStart+offset;
pPipe->SetStartPoint(ptOffset);
}
else if(ptLoc == ptEnd){
XPoint ptOffset=ptEnd+offset;
pPipe->SetEndPoint(ptOffset);
}
}
OPENOBJ_END();
}
}
}
}
}
OPENOBJ_END();
}
return es;
}
//调整方沟位置
void TDbPipeCanal::ExplodeOrDrawPipeCanal(XExplodeDraw &dc) const
{
// ExplodeOrDrawCanalType1(dc);
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 TDbPipeCanal::ExplodeOrDrawCanalType1(XExplodeDraw &dc) const
{
// cet 2016.8.15 modify 重新实现方沟绘制
// //得到方沟两端节点
// AcDbObjectId idNode1(NULL), idNode2(NULL);
// AcDbObjectIdArray arIds;
// idNode1 = GetNode(0);
// idNode2 = GetNode(1);
// arIds.append(idNode1);
// arIds.append(idNode2);
// 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_dPipeWeight;
// if (g_bPipeWeight)
// {
// DrawWeight(dc, dWeight, segUp, colorIndex(), linetypeScale());
// DrawWeight(dc, dWeight, segDown, colorIndex(), linetypeScale());
// }
// else
// {
// dc << segUp;
// dc << segDown;
// }
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);
// 起点方沟边线连接点
XPoint pt1 = segUp.StartPoint();
XPoint pt2 = segDown.StartPoint();
OPENOBJ_BEGIN(GetNode(0), AcDb::kForRead, TDbPipeFitting, pFitting);
if (pFitting != NULL)
{
TDbCanalFitting fitting(pFitting);
fitting.IntersectWith(this->objectId(), pt1, pt2);
}
OPENOBJ_END();
// 终点方沟边线连接点
XPoint pt3 = segUp.EndPoint();
XPoint pt4 = segDown.EndPoint();
OPENOBJ_BEGIN(GetNode(1), AcDb::kForRead, TDbPipeFitting, pFitting);
if (pFitting != NULL)
{
TDbCanalFitting fitting(pFitting);
fitting.IntersectWith(this->objectId(), pt4, pt3);
}
OPENOBJ_END();
segUp.SetPoints(pt1, pt3);
segDown.SetPoints(pt2, pt4);
// 设置线型
AcDbObjectId idLineStyle = GetLinetypeIdFromString(_T("CanalDASH"), database()); // 给排水线型(linetype.dbf中)绘制方沟时已加载
if (idLineStyle.isNull())
{
idLineStyle = InitLineType(_T("DASH"), database());
}
AcDbObjectId idOldStyle = dc.GetLineTypeId();
if (IsBlineDrain() && idLineStyle.isValid()) // 暗沟
{
dc.SetLineType(idLineStyle);
}
// 线宽
double dWeight = GetPScale() * m_dPipeWeight;
if (!IsShowPipeCanalLineWeight(this->database()))
{
dWeight = 0.0;
}
// 绘制边线
DrawWeight(dc, dWeight, segUp, colorIndex(), linetypeScale());
DrawWeight(dc, dWeight, segDown, colorIndex(), linetypeScale());
// 闭合端点 cet 2018.1.16 add
if (LinkedPipeCanalNum(0) == 0 && IsClosePipeCancalPointEnd()) // 闭合起点
{
XCurveSegment seg(pt1, pt2, 0.0);
DrawWeight(dc, dWeight, seg, colorIndex(), linetypeScale());
}
if (LinkedPipeCanalNum(1) == 0 && IsClosePipeCancalPointEnd()) // 闭合终点
{
XCurveSegment seg(pt3, pt4, 0.0);
DrawWeight(dc, dWeight, seg, colorIndex(), linetypeScale());
}
// 恢复线型
if (IsBlineDrain() && idLineStyle.isValid()) // 暗沟
{
dc.SetLineType(idOldStyle);
}
// 绘制盖板
DrawCover(dc, segUp, segDown);
}
void TDbPipeCanal::ExplodeOrDrawCanalType2(XExplodeDraw &dc) const
{
// cet 2016.8.15 modify 重新绘制方沟
// //得到方沟两端节点
// AcDbObjectId idNode1(NULL), idNode2(NULL);
// AcDbObjectIdArray arIds;
// idNode1 = GetNode(0);
// idNode2 = GetNode(1);
// arIds.append(idNode1);
// arIds.append(idNode2);
//
// AcGePoint3d pt1,pt2,pt3,pt4;
// //分别得到方沟的一端上两点
// AcArray<CornerLine> map1,map2;
// GetCannalPts(idNode1,pt1,pt2,map1);
// GetCannalPts(idNode2,pt3,pt4,map2);
//
// double dWeight = GetPScale()*m_dPipeWeight;
// 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 (m_nCanalType == Canal_Corner4 || m_nCanalType == Canal_Corner5)
// // dAng = -PI/4;
// if (g_bPipeWeight)
// {
// DrawWeight(dc, dWeight, segUp, colorIndex(), linetypeScale());
// DrawWeight(dc, dWeight, segDown, colorIndex(), linetypeScale());
// for (int i = 0; i < map1.length(); ++i)
// {
// XCurveSegment segCorn(map1[i].pair.first,map1[i].pair.second,map1[i].dAng);
// DrawWeight(dc, dWeight, segCorn, colorIndex(), linetypeScale());
// }
//
// for (int j = 0; j < map2.length(); ++j)
// {
// XCurveSegment segCorn(map2[j].pair.first,map2[j].pair.second,map2[j].dAng);
// DrawWeight(dc, dWeight, segCorn, colorIndex(), linetypeScale());
// }
// }
// else
// {
// dc << segUp;
// dc << segDown;
// for (int i = 0; i < map1.length(); ++i)
// {
// XCurveSegment segCorn(map1[i].pair.first,map1[i].pair.second,map1[i].dAng);
// dc << segCorn;
// }
//
// for (int j = 0; j < map2.length(); ++j)
// {
// XCurveSegment segCorn(map2[j].pair.first,map2[j].pair.second,map2[j].dAng);
// dc << segCorn;
// }
// }
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);
// 起点方沟边线连接点
int nSLinkedOtherCanalsNum = LinkedPipeCanalNum(0);
int nELinkedOtherCanalsNum = LinkedPipeCanalNum(1);
bool bSLinkedOtherCanals = nSLinkedOtherCanalsNum > 0;
bool bELinkedOtherCanals = nELinkedOtherCanalsNum > 0;
XPoint pt1 = segUp.StartPoint();
XPoint pt2 = segDown.StartPoint();
OPENOBJ_BEGIN(GetNode(0), AcDb::kForRead, TDbPipeFitting, pFitting);
if (pFitting != NULL)
{
TDbCanalFitting fitting(pFitting);
if (fitting.IntersectWith(this->objectId(), pt1, pt2))
{
XPoint pt11 = pt1;
XPoint pt22 = pt2;
if (segUp.Is(CURVE_LINE))
{
AcGeVector3d vtDir1 = segUp.EndPoint() - segUp.StartPoint();
AcGeVector3d vtDir2 = segDown.EndPoint() - segDown.StartPoint();
vtDir1.z = 0.0;
vtDir2.z = 0.0;
vtDir1.normalize();
vtDir2.normalize();
if (bELinkedOtherCanals && bSLinkedOtherCanals && segUp.GetLength() > m_nSpare * 2 + 0.001 && segDown.GetLength() > m_nSpare * 2 + 0.001 || // 两端连接着方沟,倒角半径的2倍应小于曲线长度
(bSLinkedOtherCanals ^ bELinkedOtherCanals) && segUp.GetLength() > m_nSpare + 0.001 && segDown.GetLength() > m_nSpare + 0.001) // 一端连接着方沟,倒角半径应大于曲线长度
{
pt1 += vtDir1 * m_nSpare;
pt2 += vtDir2 * m_nSpare;
}
}
else
{
if (bELinkedOtherCanals && bSLinkedOtherCanals && segUp.GetLength() > m_nSpare * 2 + 0.001 && segDown.GetLength() > m_nSpare * 2 + 0.001 || // 两端连接着方沟,倒角半径的2倍应小于曲线长度
(bSLinkedOtherCanals ^ bELinkedOtherCanals) && segUp.GetLength() > m_nSpare + 0.001 && segDown.GetLength() > m_nSpare + 0.001) // 一端连接着方沟,倒角半径应大于曲线长度
{
XArc arcUp = segUp.GetArc();
XArc arcDown = segDown.GetArc();
AcGeVector3d vtDirUp = pt1 - arcUp.GetCenterPt();
AcGeVector3d vtDirDown = pt2 - arcDown.GetCenterPt();
vtDirUp.normalize();
vtDirDown.normalize();
double dAngleUp = m_nSpare / arcUp.GetRadius();
double dAngleDown = m_nSpare / arcDown.GetRadius();
vtDirUp.rotateBy(dAngleUp, AcGeVector3d::kZAxis);
vtDirDown.rotateBy(dAngleDown, AcGeVector3d::kZAxis);
pt1 = arcUp.GetCenterPt() + vtDirUp * arcUp.GetRadius();
pt2 = arcDown.GetCenterPt() + vtDirDown * arcDown.GetRadius();
}
}
// 样式2和样式3弯头连接时 (端点只和一个方沟有连接),只有一条边线需要创建倒角半径
int nRet = NeedModifyInt(0, pFitting);
if (nRet == 1)
{
pt1 = pt11;
}
else if (nRet == 2)
{
pt2 = pt22;
}
}
}
OPENOBJ_END();
// 终点方沟边线连接点
XPoint pt3 = segUp.EndPoint();
XPoint pt4 = segDown.EndPoint();
OPENOBJ_BEGIN(GetNode(1), AcDb::kForRead, TDbPipeFitting, pFitting);
if (pFitting != NULL)
{
TDbCanalFitting fitting(pFitting);
if (fitting.IntersectWith(this->objectId(), pt4, pt3))
{
XPoint pt33 = pt3;
XPoint pt44 = pt4;
if (segUp.Is(CURVE_LINE))
{
AcGeVector3d vtDir1 = segUp.EndPoint() - segUp.StartPoint();
AcGeVector3d vtDir2 = segDown.EndPoint() - segDown.StartPoint();
vtDir1.z = 0.0;
vtDir2.z = 0.0;
vtDir1.normalize();
vtDir2.normalize();
if (bELinkedOtherCanals && bSLinkedOtherCanals && segUp.GetLength() > m_nSpare * 2 + 0.001 && segDown.GetLength() > m_nSpare * 2 + 0.001 || // 两端连接着方沟,倒角半径的2倍应小于曲线长度
(bSLinkedOtherCanals ^ bELinkedOtherCanals) && segUp.GetLength() > m_nSpare + 0.001 && segDown.GetLength() > m_nSpare + 0.001) // 一端连接着方沟,倒角半径应大于曲线长度
{
pt3 -= vtDir1 * m_nSpare;
pt4 -= vtDir2 * m_nSpare;
}
}
else
{
XArc arcUp = segUp.GetArc();
XArc arcDown = segDown.GetArc();
AcGeVector3d vtDirUp = pt3 - arcUp.GetCenterPt();
AcGeVector3d vtDirDown = pt4 - arcDown.GetCenterPt();
vtDirUp.normalize();
vtDirDown.normalize();
double dAngleUp = m_nSpare / arcUp.GetRadius();
double dAngleDown = m_nSpare / arcDown.GetRadius();
vtDirUp.rotateBy(-dAngleUp, AcGeVector3d::kZAxis);
vtDirDown.rotateBy(-dAngleDown, AcGeVector3d::kZAxis);
pt3 = arcUp.GetCenterPt() + vtDirUp * arcUp.GetRadius();
pt4 = arcDown.GetCenterPt() + vtDirDown * arcDown.GetRadius();
}
// 样式2和样式3弯头连接时 (端点只和一个方沟有连接),只有一条边线需要创建倒角半径
int nRet = NeedModifyInt(1, pFitting);
if (nRet == 1)
{
pt3 = pt33;
}
else if (nRet == 2)
{
pt4 = pt44;
}
}
}
OPENOBJ_END();
segUp.SetPoints(pt1, pt3);
segDown.SetPoints(pt2, pt4);
AcDbObjectId idLineStyle = GetLinetypeIdFromString(_T("CanalDASH"), database()); // 给排水线型(linetype.dbf中)绘制方沟时已加载
if (idLineStyle.isNull())
{
idLineStyle = InitLineType(_T("DASH"), database());
}
AcDbObjectId idOldStyle = dc.GetLineTypeId();
if (IsBlineDrain() && idLineStyle.isValid()) // 暗沟
{
dc.SetLineType(idLineStyle);
}
double dWeight = GetPScale()*m_dPipeWeight;
if (!IsShowPipeCanalLineWeight(this->database()))
{
dWeight = 0.0;
}
DrawWeight(dc, dWeight, segUp, colorIndex(), linetypeScale());
DrawWeight(dc, dWeight, segDown, colorIndex(), linetypeScale());
if (IsBlineDrain() && idLineStyle.isValid()) // 暗沟
{
dc.SetLineType(idOldStyle);
}
// 绘制盖板
DrawCover(dc, segUp, segDown);
}
//对方沟按逆时针排序
void TDbPipeCanal::SortPipeCanal(const AcGePoint3d &ptOr,const AcDbObjectIdArray &arIds,AcArray<XCurveSegment, AcArrayObjectCopyReallocator<XCurveSegment> > &arSeg) const
{
AcDbObjectId idSelf = GetSelfObjectId();
AcGeMatrix3d mat;
ads_matrix matAds;
GetOffsetMatrix(idSelf, mat);
AcArray<XCurveSegment, AcArrayObjectCopyReallocator<XCurveSegment> > arSegSort;
for (int i = 0; i < arIds.length(); ++i)
{
if (idSelf == arIds[i])
{
XCurveSegment seg;
seg = GetCurve();
XCurveSegment segUp, segDown;
XDirectionCurve segDir(seg.StartPoint(), seg.EndPoint(), seg.GetBulge());
segUp = segDir.Offset(GetWidth()/2, LS_FINITE);
segDown = segDir.Offset(-GetWidth()/2, LS_FINITE);
arSegSort.append(segUp);
arSegSort.append(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;
XDirectionCurve segDir(seg.StartPoint(), seg.EndPoint(), seg.GetBulge());
segUp = segDir.Offset(pCanal->GetWidth()/2, LS_FINITE);
segDown = segDir.Offset(-pCanal->GetWidth()/2, LS_FINITE);
arSegSort.append(segUp);
arSegSort.append(segDown);
}
OPENOBJ_END();
}
}
}
XPoint pt = ptOr;
std::map<double,XCurveSegment> map;
double dPar = 0.0;
std::vector<double> vecT;
AcDbCircle circle(ptOr,AcGeVector3d::kZAxis,m_nWidth/5);
for (int j = 0; j < arSegSort.length(); ++j)
{
AcGePoint3d ptNear;
circle.getClosestPointTo(arSegSort[j].MidPoint(),AcGeVector3d::kZAxis,ptNear);
circle.getParamAtPoint(ptNear,dPar);
map[dPar] = arSegSort[j];
vecT.push_back(dPar);
}
std::sort(vecT.begin(),vecT.end());
for (UINT k = 0; k < vecT.size(); ++k)
{
double dT = vecT[k];
XCurveSegment seg = map[dT];
arSeg.append(seg);
}
int nLen = arSeg.length();
}
//求排序后方沟的交点
void TDbPipeCanal::GetInterPts(const AcArray<XCurveSegment, AcArrayObjectCopyReallocator<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].StartPoint() - arSeg[i].EndPoint();
AcGeVector3d vt2 = arSeg[nNext].StartPoint() - arSeg[nNext].EndPoint();
if (vt1.isParallelTo(vt2))
continue;
AcGePoint3dArray arPtsT;
AcGePoint3d ptS = arSeg[i].StartPoint();
AcGePoint3d ptST = arSeg[nNext].StartPoint();
AcGePoint3d ptE = arSeg[i].EndPoint();
AcGePoint3d ptET = arSeg[nNext].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的交点
GetCorner2InterPts(arSeg[i],arSeg[nNext],arPtsT[0],arSeg.length(),arPts,map1);
}
}
else
{
if (arSeg.length() == 4)
{
//弯头
AcGePoint3dArray arPtsT;
AcGePoint3d ptS = arSeg[i].StartPoint();
AcGePoint3d ptST = arSeg[nNext].StartPoint();
AcGePoint3d ptE = arSeg[i].EndPoint();
AcGePoint3d ptET = arSeg[nNext].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);
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的交点
GetCorner2InterPts(arSeg[i],arSeg[nNext],arPtsT[0],arSeg.length(),arPts,map1);
}
}
}
}
}
}
}
void TDbPipeCanal::GetInterPts(const AcArray<XCurveSegment, AcArrayObjectCopyReallocator<XCurveSegment> > &arSeg,AcArray<AcGePoint3d> &arPts) 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].StartPoint() - arSeg[i].EndPoint();
AcGeVector3d vt2 = arSeg[nNext].StartPoint() - arSeg[nNext].EndPoint();
if (vt1.isParallelTo(vt2))
continue;
AcGePoint3dArray arPtsT;
AcGePoint3d ptS = arSeg[i].StartPoint();
AcGePoint3d ptST = arSeg[nNext].StartPoint();
AcGePoint3d ptE = arSeg[i].EndPoint();
AcGePoint3d ptET = arSeg[nNext].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)
{
arPts.append(arPtsT[0]);
}
else
{
if (arSeg.length() == 4)
{
//弯头
AcGePoint3dArray arPtsT;
AcGePoint3d ptS = arSeg[i].StartPoint();
AcGePoint3d ptST = arSeg[nNext].StartPoint();
AcGePoint3d ptE = arSeg[i].EndPoint();
AcGePoint3d ptET = arSeg[nNext].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);
if (line1.intersectWith(&line2,AcDb::kExtendBoth,arPtsT) == Acad::eOk)
{
arPts.append(arPtsT[0]);
}
}
}
}
}
}
//调整方沟位置
void TDbPipeCanal::ChangePipeCanalPosition(const AcArray<AcGePoint3d> &arPts,const AcGePoint3d &ptCen,int nSegLen,AcGePoint3d &pt1,AcGePoint3d &pt2) const
{
double dWeight = GetPScale()*m_dPipeWeight;
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);
AcDbLine lineUp(segUp.StartPoint(),segUp.EndPoint());
AcDbLine lineDown(segDown.StartPoint(),segDown.EndPoint());
if (lineUp.startPoint().distanceTo(ptCen) > lineUp.endPoint().distanceTo(ptCen))
pt1 = lineUp.endPoint();
else
pt1 = lineUp.startPoint();
if (lineDown.startPoint().distanceTo(ptCen) > lineDown.endPoint().distanceTo(ptCen))
pt2 = lineDown.endPoint();
else
pt2 = lineDown.startPoint();
AcGePoint3d ptS = lineUp.startPoint();
AcGePoint3d ptST = lineDown.startPoint();
AcGePoint3d ptE = lineUp.endPoint();
AcGePoint3d ptET = lineDown.endPoint();
ptS.z = 0.0;
ptE.z = 0.0;
ptST.z = 0.0;
ptET.z = 0.0;
lineUp.setStartPoint(ptS);
lineUp.setEndPoint(ptE);
lineDown.setStartPoint(ptST);
lineDown.setEndPoint(ptET);
for (int i = 0; i < arPts.length(); ++i)
{
AcGePoint3d ptNear;
//交点个数为2,边数为4表示生成弯头
//交点个数为4表示四通
AcGePoint3d ptTt = arPts[i];
switch(m_nCanalType)
{
case Canal_Corner1:
if (arPts.length() == 2 && nSegLen == 4)
lineUp.getClosestPointTo(arPts[i],ptNear,Adesk::kTrue);
else
lineUp.getClosestPointTo(arPts[i],ptNear);
break;
case Canal_Corner2:
case Canal_Corner3:
case Canal_Corner4:
case Canal_Corner5:
if (arPts.length() == 3 && nSegLen == 4)
lineUp.getClosestPointTo(arPts[i],ptNear,Adesk::kTrue);
else
lineUp.getClosestPointTo(arPts[i],ptNear);
break;
default:
break;
}
if (arPts[i].distanceTo(ptNear) < 1e-3)
{
pt1 = arPts[i];
}
switch(m_nCanalType)
{
case Canal_Corner1:
if (arPts.length() == 2 && nSegLen == 4)
lineDown.getClosestPointTo(arPts[i],ptNear,Adesk::kTrue);
else
lineDown.getClosestPointTo(arPts[i],ptNear);
break;
case Canal_Corner2:
case Canal_Corner3:
case Canal_Corner4:
case Canal_Corner5:
if (arPts.length() == 3 && nSegLen == 4)
lineDown.getClosestPointTo(arPts[i],ptNear,Adesk::kTrue);
else
lineDown.getClosestPointTo(arPts[i],ptNear);
break;
default:
break;
}
if (arPts[i].distanceTo(ptNear) < 1e-3)
{
pt2 = arPts[i];
}
}
}
//得到NODE方向方沟两点
void TDbPipeCanal::GetCannalPts(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<XCurveSegment, AcArrayObjectCopyReallocator<XCurveSegment> > arSeg;
SortPipeCanal(pNode->GetLocation(),arCanal,arSeg);
//求出排序后线的交点
AcArray<AcGePoint3d> arPts;
GetInterPts(arSeg,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 TDbPipeCanal::ChangePipeCanalPosition(const AcDbObjectIdArray& arId,const AcDbObjectId& idNode,const AcGePoint3d& ptNodeLoc,double dLen,AcGePoint3d& pt1,AcGePoint3d& pt2,AcArray<CornerLine> &map1) const
{
map1.setLogicalLength(0);
if (arId.length() != 2)
return;
AcDbObjectId id1 = GetNode(0);
AcDbObjectId id2 = GetNode(1);
if (!id1.isValid() || !id2.isValid())
{
return;
}
// 处理连接点
AcGeVector3d vtHor;
AcGePoint3d ptT;
if (id1 == idNode)
{
OPENOBJ_BEGIN(id2, AcDb::kForRead, TDbPipeNode, pNode);
if (pNode)
{
ptT = pNode->GetLocation();
}
OPENOBJ_END();
vtHor = ptT - ptNodeLoc;
vtHor.normalize();
pt1 += vtHor * dLen / 2;
pt2 += vtHor * dLen / 2;
}
else if (id2 == idNode)
{
OPENOBJ_BEGIN(id1, AcDb::kForRead, TDbPipeNode, pNode);
if (pNode)
{
ptT = pNode->GetLocation();
}
OPENOBJ_END();
vtHor = ptT - ptNodeLoc;
vtHor.normalize();
pt1 += vtHor * dLen / 2;
pt2 += vtHor * dLen / 2;
}
// 处理变径的边
double dWidth = 0.0;
if (!GetAnotherCanalWidth(ptT,ptNodeLoc,arId,dWidth))
return;
AcGeVector3d vtVer = vtHor;
vtVer.rotateBy(PI / 2,AcGeVector3d::kZAxis);
vtVer.normalize();
AcGePoint3d ptT1,ptT2;
ptT1 = ptNodeLoc - vtVer * dWidth / 2;
ptT1 -= vtHor * dLen / 2;
ptT2 = ptNodeLoc + vtVer * dWidth / 2;
ptT2 -= vtHor * dLen / 2;
AppendMap(pt1,ptT1,ptT2,map1);
AppendMap(pt2,ptT1,ptT2,map1);
}
//添加映射
void TDbPipeCanal::AppendMap(const AcGePoint3d& ptBase,const AcGePoint3d& pt1,const AcGePoint3d& pt2,AcArray<CornerLine> &map1) const
{
double dLen1 = ptBase.distanceTo(pt1);
double dLen2 = ptBase.distanceTo(pt2);
std::pair<AcGePoint3d,AcGePoint3d> pair;
pair.first = ptBase;
if (dLen1 > dLen2)
pair.second = pt2;
else
pair.second = pt1;
CornerLine corner;
corner.pair = pair;
corner.dAng = 0.0;
map1.append(corner);
}
//得到另一个管子的宽度
BOOL TDbPipeCanal::GetAnotherCanalWidth(const AcGePoint3d& pt1,const AcGePoint3d& pt2,const AcDbObjectIdArray& arId,double& dWidth) const
{
BOOL bSuc = FALSE;
AcDbObjectId idT;
AcGePoint3d ptS,ptE;
for (int i = 0;i < arId.length();i++)
{
if (arId[i].isValid())
{
OPENOBJ_BEGIN(arId[i], AcDb::kForRead, TDbPipeCanal, pCanal);
if (pCanal)
{
ptS = pCanal->StartPoint();
ptE = pCanal->EndPoint();
}
OPENOBJ_END();
if (pt1.distanceTo(ptS) < 1e-3 &&
pt2.distanceTo(ptE) < 1e-3 )
{
idT = arId[i];
bSuc = TRUE;
break;
}
else if (pt1.distanceTo(ptE) < 1e-3 &&
pt2.distanceTo(ptS) < 1e-3 )
{
idT = arId[i];
bSuc = TRUE;
break;
}
}
}
AcDbObjectId idOther;
AcDbObjectIdArray arT;
if (bSuc)
{
arT.append(arId);
arT.remove(idT);
if (arT.length() > 0)
idOther = arT[0];
else
bSuc = FALSE;
}
if (bSuc)
{
if (idOther.isValid())
{
OPENOBJ_BEGIN(idOther, AcDb::kForRead, TDbPipeCanal, pCanal);
if (pCanal)
{
dWidth = pCanal->m_nWidth;
}
OPENOBJ_END();
}
}
return dWidth > 0;
}
//是否创建变径
BOOL TDbPipeCanal::MakesureCreateReducer(const AcDbObjectIdArray& arId,double& dTotal) const
{
if (arId.length() != 2)
return FALSE;
AcGeVector3d vt1,vt2;
double dB1 = 0.0,dB2 = 0.0;
if (arId[0].isValid())
{
OPENOBJ_BEGIN(arId[0], AcDb::kForRead, TDbPipeCanal, pCanal);
if (pCanal)
{
dB1 = pCanal->m_nWidth;
vt1 = pCanal->EndPoint() - pCanal->StartPoint();
vt1.normalize();
}
OPENOBJ_END();
}
if (arId[1].isValid())
{
OPENOBJ_BEGIN(arId[1], AcDb::kForRead, TDbPipeCanal, pCanal);
if (pCanal)
{
dB2 = pCanal->m_nWidth;
vt2 = pCanal->EndPoint() - pCanal->StartPoint();
vt2.normalize();
}
OPENOBJ_END();
}
if (fabs(dB1-dB2) < 1e-3)//等宽
return FALSE;
if (!vt1.isParallelTo(vt2))//不平行
return FALSE;
dTotal = dB1 + dB2;
return TRUE;
}
void TDbPipeCanal::GetCannalPts(const AcDbObjectId &id,AcGePoint3d &pt1,AcGePoint3d &pt2) 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<XCurveSegment, AcArrayObjectCopyReallocator<XCurveSegment> > arSeg;
SortPipeCanal(pNode->GetLocation(),arCanal,arSeg);
//求出排序后线的交点
AcArray<AcGePoint3d> arPts;
GetInterPts(arSeg,arPts);
//调整方沟位置
ChangePipeCanalPositionNor(arPts,pNode->GetLocation(),arSeg.length(),pt1,pt2);
}
}
OPENOBJ_END();
}
}
//过滤掉无用的方沟
/*
BOOL TDbPipeCanal::FilterCannal(AcDbObjectIdArray &arIds) const
{
BOOL bFilter = FALSE;
PickSet ssDel(SS_FREE);
for (int i = 0; i < arIds.length(); ++i)
{
if (arIds[i].isValid())
{
OPENOBJ_BEGIN(arIds[i], AcDb::kForRead, TDbPipeCanal, pCanal);
if (pCanal != NULL)
{
XCurveSegment seg1 = pCanal->GetCurve();
for (int j = 0; j < arIds.length(); ++j)
{
if (j == i)
continue;
OPENOBJ_BEGIN(arIds[j], AcDb::kForRead, TDbPipeCanal, pCanT);
if (pCanT != NULL)
{
XCurveSegment seg2 = pCanT->GetCurve();
AcGeVector3d vt1 = seg1.StartPoint() - seg1.EndPoint();
AcGeVector3d vt2 = seg2.StartPoint() - seg2.EndPoint();
if (!vt1.isParallelTo(vt2))
{
XCurveSegment segUp,segDown;
XDirectionCurve segDir(seg2.StartPoint(), seg2.EndPoint(), seg2.bulge);
segUp = segDir.Offset(m_nWidth/2, LS_FINITE);
segDown = segDir.Offset(-m_nWidth/2, LS_FINITE);
XPoint pt1,pt2;
AcGePoint3dArray arPts;
AcDbLine line1(seg1.StartPoint(),seg1.EndPoint());
AcDbLine line2(segUp.StartPoint(),segUp.EndPoint());
AcDbLine line3(segDown.StartPoint(),segDown.EndPoint());
line1.intersectWith(&line2,AcDb::kExtendArg,arPts);
line1.intersectWith(&line3,AcDb::kExtendArg,arPts);
if (arPts.length() < 1)
{
ssDel += arIds[i];
ssDel += pCanal->GetNode(0);
ssDel += pCanal->GetNode(1);
bFilter = TRUE;
}
}
}
OPENOBJ_END();
}
}
OPENOBJ_END();
}
}
for (long l = 0; l < ssDel.Length(); ++l)
ssDel[l].Erase();
return bFilter;
}
*/
//过滤掉无用的方沟
BOOL TDbPipeCanal::FilterCannal(AcDbObjectIdArray &arIds) const
{
BOOL bFilter = FALSE;
PickSet ssDel(SS_FREE);
double dB = 0.0;
for (int i = 0; i < arIds.length(); ++i)
{
if (arIds[i].isValid())
{
OPENOBJ_BEGIN(arIds[i], AcDb::kForRead, TDbPipeCanal, pCanal);
if (pCanal != NULL)
{
XCurveSegment seg1 = pCanal->GetCurve();
dB = pCanal->GetWidth();
if (seg1.GetLength() < dB/2)
{
ssDel += pCanal->objectId();
ssDel += pCanal->GetNode(0);
ssDel += pCanal->GetNode(1);
bFilter = TRUE;
}
}
OPENOBJ_END();
}
}
for (long l = 0; l < ssDel.Length(); ++l)
ssDel[l].Erase();
return bFilter;
}
//得到类型2的交点
void TDbPipeCanal::GetCorner2InterPts(const XCurveSegment &seg1,const XCurveSegment &seg2,const AcGePoint3d &pt,int nSegCount,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+m_nSpare-m_nWidth*tan(PI/8));
else
ptIns1 = pt - vtDir1*m_nSpare;
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+m_nSpare-m_nWidth*tan(PI/8));
else
ptIns2 = pt - vtDir2*m_nSpare;
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 TDbPipeCanal::ChangePipeCanalPositionNor(const AcArray<AcGePoint3d> &arPts,const AcGePoint3d &ptCen,int nSegLen,AcGePoint3d &pt1,AcGePoint3d &pt2) const
{
double dWeight = GetPScale()*m_dPipeWeight;
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);
AcDbLine lineUp(segUp.StartPoint(),segUp.EndPoint());
AcDbLine lineDown(segDown.StartPoint(),segDown.EndPoint());
if (lineUp.startPoint().distanceTo(ptCen) > lineUp.endPoint().distanceTo(ptCen))
pt1 = lineUp.endPoint();
else
pt1 = lineUp.startPoint();
if (lineDown.startPoint().distanceTo(ptCen) > lineDown.endPoint().distanceTo(ptCen))
pt2 = lineDown.endPoint();
else
pt2 = lineDown.startPoint();
AcGePoint3d ptS = lineUp.startPoint();
AcGePoint3d ptST = lineDown.startPoint();
AcGePoint3d ptE = lineUp.endPoint();
AcGePoint3d ptET = lineDown.endPoint();
ptS.z = 0.0;
ptE.z = 0.0;
ptST.z = 0.0;
ptET.z = 0.0;
lineUp.setStartPoint(ptS);
lineUp.setEndPoint(ptE);
lineDown.setStartPoint(ptST);
lineDown.setEndPoint(ptET);
for (int i = 0; i < arPts.length(); ++i)
{
AcGePoint3d ptNear;
//交点个数为2,边数为4表示生成弯头
//交点个数为4表示四通
if (arPts.length() == 2 && nSegLen == 4)
lineUp.getClosestPointTo(arPts[i],ptNear,Adesk::kTrue);
else
lineUp.getClosestPointTo(arPts[i],ptNear);
if (arPts[i].distanceTo(ptNear) < 1e-3)
{
pt1 = arPts[i];
}
if (arPts.length() == 2 && nSegLen == 4)
lineDown.getClosestPointTo(arPts[i],ptNear,Adesk::kTrue);
else
lineDown.getClosestPointTo(arPts[i],ptNear);
if (arPts[i].distanceTo(ptNear) < 1e-3)
{
pt2 = arPts[i];
}
}
}
//设置方沟类型
void TDbPipeCanal::SetCannalSameType(const AcDbObjectIdArray &arIds) const
{
for (int i = 0; i < arIds.length(); ++i)
{
if (arIds[i].isValid())
{
OPENOBJ_BEGIN(arIds[i], AcDb::kForWrite, TDbPipeCanal, pCanal);
if (pCanal != NULL)
{
pCanal->SetCanalType(m_nCanalType);
}
OPENOBJ_END();
}
}
}
//////////////////////////////////////////////////////////////////////////
void IniTDbPipeCanal(BOOL bTrue)
{
if(bTrue) {
TDbPipeCanal::rxInit();
TDbPipeCanal::InitMatchProtocol(TRUE);
} else {
TDbPipeCanal::InitMatchProtocol(FALSE);
deleteAcRxClass(TDbPipeCanal::desc());
}
}
AcDbObjectId TDbPipeCanal::GetSelfObjectId() const
{
AcDbObjectId idSelf = objectId();
if (idSelf.isValid())
{
return idSelf;
}
//挑选
AcDbObjectIdArray arNode1,arNode2;
AcDbObjectId idNode = GetNode(0);
OPENOBJ_BEGIN(idNode, AcDb::kForRead, TDbPipeNode, pNode);
if (pNode != NULL)
{
AcDbObjectId id;
for (int i = 0; i < pNode->GetInterfaceNum(); ++i)
{
id = pNode->GetIPipe(i);
arNode1.append(id);
}
}
OPENOBJ_END();
if (arNode1.length() == 1)
{
idSelf = arNode1.first();
return idSelf;
}
idNode = GetNode(1);
OPENOBJ_BEGIN(idNode, AcDb::kForRead, TDbPipeNode, pNode);
if (pNode != NULL)
{
AcDbObjectId id;
for (int i = 0; i < pNode->GetInterfaceNum(); ++i)
{
id = pNode->GetIPipe(i);
arNode2.append(id);
}
}
OPENOBJ_END();
if (arNode2.length() == 1)
{
idSelf = arNode2.first();
return idSelf;
}
for (int j = 0;j < arNode1.length();++j)
{
for (int p = 0;p < arNode2.length();++p)
{
if (arNode1[j] == arNode2[p])
{
idSelf = arNode1[j];
return idSelf;
}
}
}
return idSelf;
}
void TDbPipeCanal::GetOffsetMatrix(const AcDbObjectId& id, AcGeMatrix3d& matOffset) const
{
matOffset.setToIdentity();
if (id.isValid())
{
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPipeCanal, pPipe);
if (pPipe != NULL)
{
XCurveSegment seg,segSelf;
seg = pPipe->GetCurve();
segSelf = GetCurve();
AcGeVector3d vt = segSelf.MidPoint() - seg.MidPoint();
matOffset.setToTranslation(vt);
}
OPENOBJ_END();
}
}
// 获取指定端坐标
XPoint TDbPipeCanal::GetVertexPt(const TPipeSys::PtLoction nSide) const
{
XPoint pt(GetStartPoint());
if (nSide == TPipeSys::kEndPt)
{
pt = EndPoint();
}
return pt;
}
Acad::ErrorStatus TDbPipeCanal::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbPipe::subTransformBy(xform);
//在transform的时候不停的打开对象,一次命令中以读方式打开超过256次,出现崩溃错误,加次判断条件,jig拖动结束时处理对象更新
if (!acedIsDragging())
{
BOOL bApplyToNode(TRUE); // 是否提供变化给节点
XString &sCmd = GetCurDocData()->m_sCurCommand;
if (_tcsicmp(sCmd, _T("MIRROR"))==0 || _tcsicmp(sCmd, _T("COPY"))==0 ||
_tcsicmp(sCmd, _T("COPYCLIP"))==0 || _tcsicmp(sCmd, _T("PASTECLIP"))==0)
{
bApplyToNode = FALSE; // 管线的复制、镜像操作,不提供变化给节点
}
if (!bApplyToNode)
{
return es;
}
AcDbObjectId idNode;
for (int i = 0;i < 2;++i)
{
idNode = GetNode(i);
if (idNode.isValid())
{
TPipeSys::PtLoction nSide = (TPipeSys::PtLoction)i;
XPoint ptSide = GetVertexPt(nSide);
OPENOBJ_BEGIN(GetNode(i), AcDb::kForRead, TDbPipeFitting, pFit);
if (pFit != NULL)
{
if (pFit->upgradeOpen() == Acad::eOk)
{
// 更新节点
pFit->SetLocation(ptSide); // 修改m_ptLocation
for (int p = 0;p < pFit->GetInterfaceNum();++p)
{
pFit->SetILocation(p,ptSide);
}
pFit->downgradeOpen();
}
}
OPENOBJ_END();
}
}
}
return es;
}
Acad::ErrorStatus TDbPipeCanal::subGetTransformedCopy(const AcGeMatrix3d& xform,
AcDbEntity*& pEnt) const
{
assertReadEnabled();
pEnt = new TDbPipeCanal;
pEnt->copyFrom(this);
pEnt->transformBy(xform);
return Acad::eOk;
}
// 增加Node的wbclone
Acad::ErrorStatus TDbPipeCanal::subWblockClone(AcRxObject* pOwner,
AcDbObject*& pClonedObject,
AcDbIdMapping& idMap,
Adesk::Boolean isPrimary) const
{
Acad::ErrorStatus es=TDbPipe::subWblockClone(pOwner, pClonedObject, idMap, isPrimary);
if(es!=Acad::eOk)
return es;
es=subSubWblockClone(m_nodeStart.m_idNode,pOwner, pClonedObject, idMap, isPrimary);
es=subSubWblockClone(m_nodeEnd.m_idNode,pOwner, pClonedObject, idMap, isPrimary);
return Acad::eOk;
}
Acad::ErrorStatus TDbPipeCanal::subSubWblockClone(const AcDbObjectId& idCloning,
AcRxObject* pOwner,
AcDbObject*& pClonedObject,
AcDbIdMapping& idMap,
Adesk::Boolean isPrimary) const
{
Acad::ErrorStatus es = Acad::eInvalidInput;
if (!idCloning.isValid())
return es;
AcDbIdPair idPairOpening(idCloning, (AcDbObjectId)NULL,false, isPrimary? true : false);
if (idMap.compute(idPairOpening))
return es;
AcDbObject *pSubObject=NULL;
AcDbObject *pClonedSubObject=NULL;
if (acdbOpenAcDbObject(pSubObject, idCloning, AcDb::kForRead) == Acad::eOk)
{
es = pSubObject->wblockClone(pOwner,pClonedSubObject,idMap, isPrimary);
pSubObject->close();
if (es == Acad::eOk)
{
pClonedSubObject->close();
}
}
return Acad::eOk;
}
// 根据连接点点过滤相连接的方沟
BOOL TDbPipeCanal::IsHasMorePipes(const AcDbObjectId& idNode) const
{
int num = GetNodeCntPipeNumber(idNode);
if (num > 1)// 有连接
{
return FALSE;
}
return TRUE;
}
// 节点连接的管子个数
int TDbPipeCanal::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;
}
// 获取垂足点
BOOL TDbPipeCanal::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 TDbPipeCanal::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 TDbPipeCanal::FreeBuffer(AcArray<AcDbLine*>& cplCurve) const
{
for (int i = 0;i < cplCurve.length();i++)
{
delete cplCurve[i];
}
}
void TDbPipeCanal::SetCoverLineWidth(double dLineWidth)
{
assertWriteEnabled();
TEntityFields &fd = Fields();
fd.SFD(_T("COVER_LINEWIDTH"), dLineWidth);
}
double TDbPipeCanal::GetCoverLineWidth() const
{
assertReadEnabled();
const TEntityFields &fd = GetFields();
double dLineWidth = 0.0;
fd.GFD(_T("COVER_LINEWIDTH"), dLineWidth);
return dLineWidth;
}
void TDbPipeCanal::SetBlindDrain(bool bVal)
{
assertWriteEnabled();
TEntityFields &fd = Fields();
fd.SFD(_T("BLIND_DRAIN"), bVal ? Adesk::kTrue : Adesk::kFalse);
}
bool TDbPipeCanal::IsBlineDrain() const
{
assertReadEnabled();
const TEntityFields &fd = GetFields();
Adesk::Boolean bFlag = Adesk::kFalse;
fd.GFD(_T("BLIND_DRAIN"), bFlag);
return bFlag == Adesk::kTrue ? true : false;
}
void TDbPipeCanal::SetCoverType(int nType)
{
assertWriteEnabled();
TEntityFields &fd = Fields();
fd.SFD(_T("COVER_TYPE"), (Adesk::UInt8)nType);
}
int TDbPipeCanal::GetCoverType() const
{
assertReadEnabled();
const TEntityFields &fd = GetFields();
Adesk::UInt8 nType = 0;
fd.GFD(_T("COVER_TYPE"), nType);
return (int)nType;
}
void TDbPipeCanal::SetCoverHorDist(double dDist)
{
assertWriteEnabled();
TEntityFields &fd = Fields();
fd.SFD(_T("COVER_HOR_DIST"), dDist);
}
double TDbPipeCanal::GetCoverHorDist() const
{
assertReadEnabled();
const TEntityFields &fd = GetFields();
double dDist = 0.0;
fd.GFD(_T("COVER_HOR_DIST"), dDist);
return dDist;
}
void TDbPipeCanal::SetCoverVerDist(double dDist)
{
assertWriteEnabled();
TEntityFields &fd = Fields();
fd.SFD(_T("COVER_VER_DIST"), dDist);
}
double TDbPipeCanal::GetCoverVerDist() const
{
assertReadEnabled();
const TEntityFields &fd = GetFields();
double dDist = 0.0;
fd.GFD(_T("COVER_VER_DIST"), dDist);
return dDist;
}
void TDbPipeCanal::DrawCover(XExplodeDraw &dc, XCurveSegment &segUp, XCurveSegment &segDown) const
{
double dWeight = GetPScale() * GetCoverLineWidth();
if (!IsShowPipeCanalLineWeight(this->database()))
{
dWeight = 0.0;
}
AcGePoint3d pt1 = segUp.StartPoint();
AcGePoint3d pt3 = segUp.EndPoint();
AcGePoint3d pt2 = segDown.StartPoint();
AcGePoint3d pt4 = segDown.EndPoint();
pt1.z = 0.0;
pt2.z = 0.0;
pt3.z = 0.0;
pt4.z = 0.0;
int nCoverType = GetCoverType();
if (!IsBlineDrain() && nCoverType != 0)
{
if (segDown.Is(CURVE_LINE)) // 直线型方沟
{
// 获得两条边线平行重叠部分
AcDbLine line(pt1, pt3);
AcGePoint3d pt21, pt41;
line.getClosestPointTo(pt2, pt21);
line.getClosestPointTo(pt4, pt41);
AcGePoint3d ptS = pt1;
if (fabs(pt2.distanceTo(pt21) - m_nWidth) < 0.001)
{
ptS = pt21;
}
AcGePoint3d ptE = pt3;
if (fabs(pt4.distanceTo(pt41) - m_nWidth) < 0.001)
{
ptE = pt41;
}
// 绘制盖板
AcGePoint3d ptTemp;
line.getClosestPointTo(pt2, ptTemp, Adesk::kTrue);
AcGePoint3d ptS1 = ptS, ptS2 = ptS + pt2 - ptTemp;
AcGeVector3d vtDir = pt41 - pt21;
vtDir.normalize();
if (nCoverType == 1)
{
// 纵向
double dLen = ptS.distanceTo(ptE);
double dDist = 0.0, dHorDist = GetCoverHorDist();
XCurveSegment segTemp;
bool bELinkedEntity = IsLinkedEntity(1);
while (dDist < dLen + 0.001)
{
segTemp.SetPoints(ptS1 + vtDir * dDist, ptS2 + vtDir * dDist);
DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale());
if (dDist + dHorDist > dLen + 0.001 && dDist < dLen - 0.001) // 末端
{
if (bELinkedEntity)
{
break;
}
dDist = dLen;
}
else
{
dDist += dHorDist;
}
}
}
else if (nCoverType == 2)
{
// 纵向
XCurveSegment segTemp;
if (!IsLinkedEntity(0)) // 起点未连接实体
{
segTemp.SetPoints(ptS1, ptS2);
DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale());
}
if (!IsLinkedEntity(1)) // 终点未连接实体
{
double dLen = ptS.distanceTo(ptE);
segTemp.SetPoints(ptS1 + vtDir * dLen, ptS2 + vtDir * dLen);
DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale());
}
// 横向
AcDbLine line(pt1, pt3);
AcDbLine lineS(pt1, pt2), lineE(pt3, pt4);
AcGeVector3d vtVer = ptS2 - ptS1;
vtVer.normalize();
double dDist = GetCoverVerDist(), dVerDist = dDist;
AcGePoint3dArray arrPt1, arrPt2;
while (dDist < m_nWidth - 0.001)
{
line.transformBy(vtVer * dVerDist);
line.intersectWith(&lineS, AcDb::kExtendBoth, arrPt1);
line.intersectWith(&lineE, AcDb::kExtendBoth, arrPt2);
if (arrPt1.length() == 1 && arrPt2.length() == 1)
{
segTemp.SetPoints(arrPt1[0], arrPt2[0]);
DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale());
}
arrPt1.setLogicalLength(0);
arrPt2.setLogicalLength(0);
dDist += dVerDist;
}
}
else if (nCoverType == 3)
{
// 纵向
double dLen = ptS.distanceTo(ptE);
double dDist = 0.0, dHorDist = GetCoverHorDist();
XCurveSegment segTemp;
bool bELinkedEntity = IsLinkedEntity(1);
while (dDist < dLen + 0.001)
{
segTemp.SetPoints(ptS1 + vtDir * dDist, ptS2 + vtDir * dDist);
DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale());
if (dDist + dHorDist > dLen + 0.001 && dDist < dLen - 0.001) // 终点
{
if(bELinkedEntity)
{
break;
}
dDist = dLen;
}
else
{
dDist += dHorDist;
}
}
// 横向
AcDbLine line(pt1, pt3);
AcDbLine lineS(pt1, pt2), lineE(pt3, pt4);
AcGeVector3d vtVer = ptS2 - ptS1;
vtVer.normalize();
dDist = GetCoverVerDist();
double dVerDist = dDist;
AcGePoint3dArray arrPt1, arrPt2;
while (dDist < m_nWidth - 0.001)
{
line.transformBy(vtVer * dVerDist);
line.intersectWith(&lineS, AcDb::kExtendBoth, arrPt1);
line.intersectWith(&lineE, AcDb::kExtendBoth, arrPt2);
if (arrPt1.length() == 1 && arrPt2.length() == 1)
{
segTemp.SetPoints(arrPt1[0], arrPt2[0]);
DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale());
}
arrPt1.setLogicalLength(0);
arrPt2.setLogicalLength(0);
dDist += dVerDist;
}
}
}
else // 弧线型方沟
{
// 获得两条边线重叠部分
XArc arcUp = segUp.GetArc();
XArc arcDown = segDown.GetArc();
XArc arcCenter = this->GetCurve().GetArc();
XPoint ptCenter = arcCenter.GetCenterPt();
ptCenter.z = 0.0;
AcDbArc arc(ptCenter, arcUp.GetRadius(), arcUp.GetStarAngle(), arcUp.GetEndAngle());
double dUpRadius = arcUp.GetRadius();
double dDownRadius = arcDown.GetRadius();
double dRadius = (dUpRadius > dDownRadius ? dDownRadius : dUpRadius) + fabs(dUpRadius - dDownRadius) * 0.5;
AcGePoint3d pt21, pt41;
arc.getClosestPointTo(pt2, pt21);
arc.getClosestPointTo(pt4, pt41);
AcGePoint3d ptS = pt1;
if (fabs(pt2.distanceTo(pt21) - m_nWidth) < 0.001)
{
ptS = pt21;
}
AcGePoint3d ptE = pt3;
if (fabs(pt4.distanceTo(pt41) - m_nWidth) < 0.001)
{
ptE = pt41;
}
// 重叠部分端点转换到中心线上
AcGeVector3d vtS = ptS - ptCenter.AsAcGePoint3d();
AcGeVector3d vtE = ptE - ptCenter.AsAcGePoint3d();
vtS.z = 0.0;
vtE.z = 0.0;
vtS.normalize();
vtE.normalize();
ptS = ptCenter + vtS * dRadius;
ptE = ptCenter + vtE * dRadius;
double dAngle = vtS.angleTo(vtE, AcGeVector3d::kZAxis);
// 重叠不错在中线处的弧线及中点
AcGeVector3d vtMid = vtS;
vtMid.rotateBy(dAngle * 0.5, AcGeVector3d::kZAxis);
XPoint ptMid = ptCenter + vtMid * dRadius;
XArc arcTemp(ptS, ptMid, ptE);
AcDbArc arcMid(arcTemp.GetCenterPt(), arcTemp.GetRadius(), arcTemp.GetStarAngle(), arcTemp.GetEndAngle());
// 确定端点node索引
if (nCoverType == 1)
{
// 纵向
double dLen = vtS.angleTo(vtE, AcGeVector3d::kZAxis) * dRadius;
double dDist = 0.0, dHorDist = GetCoverHorDist();
XCurveSegment segTemp;
bool bSLinkeEntity = IsLinkedEntity(StartPoint());
bool bELinkedEntity = IsLinkedEntity(EndPoint());
while (dDist < dLen + 0.001)
{
double dAngle = dDist / dRadius;
AcGeVector3d vtTemp = vtS;
vtTemp.rotateBy(dAngle, AcGeVector3d::kZAxis);
segTemp.SetPoints(ptCenter + vtTemp * dUpRadius, ptCenter + vtTemp * dDownRadius);
DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale());
if (dDist + dHorDist > dLen + 0.001 && dDist < dLen - 0.001) // 终点
{
if(bELinkedEntity)
{
break;
}
dDist = dLen;
}
else
{
dDist += dHorDist;
}
}
}
else if (nCoverType == 2)
{
// 纵向
XCurveSegment segTemp;
if (!IsLinkedEntity(0)) // 起点未连接实体
{
segTemp.SetPoints(ptCenter + vtS * dUpRadius, ptCenter + vtS * dDownRadius);
DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale());
}
if (!IsLinkedEntity(1)) // 终点未连接实体
{
segTemp.SetPoints(ptCenter + vtE * dUpRadius, ptCenter + vtE * dDownRadius);
DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale());
}
// 横向
double dMinRadius = dDownRadius > dUpRadius ? dUpRadius : dDownRadius;
double dDist = GetCoverVerDist(), dVerDist = dDist;
AcGePoint3dArray arrPt1, arrPt2;
while (dDist < m_nWidth - 0.001)
{
double dOffset = dDist + dMinRadius - dRadius;
segTemp = XArc(ptCenter, dMinRadius + dDist, arcMid.startAngle(), arcMid.endAngle());
DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale());
dDist += dVerDist;
}
}
else if (nCoverType == 3)
{
// 纵向
double dLen = vtS.angleTo(vtE, AcGeVector3d::kZAxis) * dRadius;
double dDist = 0.0, dHorDist = GetCoverHorDist();
XCurveSegment segTemp;
bool bSLinkeEntity = IsLinkedEntity(StartPoint());
bool bELinkedEntity = IsLinkedEntity(EndPoint());
while (dDist < dLen + 0.001)
{
double dAngle = dDist / dRadius;
AcGeVector3d vtTemp = vtS;
vtTemp.rotateBy(dAngle, AcGeVector3d::kZAxis);
segTemp.SetPoints(ptCenter + vtTemp * dUpRadius, ptCenter + vtTemp * dDownRadius);
DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale());
if (dDist + dHorDist > dLen + 0.001 && dDist < dLen - 0.001 ) // 终点
{
if(bELinkedEntity)
{
break;
}
dDist = dLen;
}
else
{
dDist += dHorDist;
}
}
// 横向
double dMinRadius = dDownRadius > dUpRadius ? dUpRadius : dDownRadius;
dDist = GetCoverVerDist();
double dVerDist = dDist;
AcGePoint3dArray arrPt1, arrPt2;
while (dDist < m_nWidth - 0.001)
{
double dOffset = dDist + dMinRadius - dRadius;
segTemp = XArc(ptCenter, dMinRadius + dDist, arcMid.startAngle(), arcMid.endAngle());
DrawWeight(dc, dWeight, segTemp, colorIndex(), linetypeScale());
dDist += dVerDist;
}
}
}
}
}
bool TDbPipeCanal::IsLinkedEntity(int nPos) const
{
AcDbObjectId id = GetNode(nPos);
if (!id.isValid())
{
return false;
}
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPipeNode, pNode);
if(pNode != NULL)
{
int num = pNode->GetInterfaceNum();
for (int i = 0; i < num; ++i)
{
const AcDbObjectId &idTemp = pNode->GetIPipe(i);
if (idTemp.isValid() && idTemp != this->id())
{
return true;
}
}
}
OPENOBJ_END();
return false;
}
bool TDbPipeCanal::IsLinkedEntity(XPoint pt) const
{
for (int i = 0; i < 2; ++i)
{
OPENOBJ_BEGIN(GetNode(i), AcDb::kForRead, TDbPipeNode, pNode);
if(pNode != NULL)
{
XPoint ptLoc = pNode->GetLocation();
if (ptLoc.Distance2d(pt) > 0.001)
{
continue;
}
int num = pNode->GetInterfaceNum();
for (int i = 0; i < num; ++i)
{
const AcDbObjectId &idTemp = pNode->GetIPipe(i);
if (idTemp.isValid() && idTemp != this->id())
{
return true;
}
}
}
OPENOBJ_END();
}
return false;
}
int TDbPipeCanal::LinkedPipeCanalNum(int nPos) const
{
AcDbObjectId id = GetNode(nPos);
if (!id.isValid())
{
return 0;
}
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPipeFitting, pNode);
if(pNode != NULL)
{
int num = pNode->GetInterfaceNum();
return num - 1;
}
OPENOBJ_END();
return 0;
}
int TDbPipeCanal::NeedModifyInt(int nPos, const TDbPipeFitting *pFitting) const
{
int nLinkNum = pFitting->GetInterfaceNum() - 1;
// 样式2和样式3弯头连接时 (端点只和一个方沟有连接)
if (nLinkNum == 1 && (m_nCanalType == 2 || m_nCanalType == 3))
{
XPoint pt = nPos == 0 ? StartPoint() : EndPoint();
for (int i = 0; i < pFitting->GetInterfaceNum(); ++i)
{
AcDbObjectId id = pFitting->GetIPipe(i);
if (id == this->objectId())
{
continue;
}
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPipeCanal, pCanal);
if (pCanal != NULL)
{
// 确定方沟间的夹角位置
XCurveSegment segBase = pCanal->GetCurve();
AcGeVector3d vt1;
if (segBase.Is(CURVE_LINE)) // 直线
{
vt1 = segBase.MidPoint() - pt;
}
else // 弧线
{
vt1 = segBase.GetArc().GetCenterPt() - pt;
vt1.z = 0.0;
if (pt.Distance2d(segBase.StartPoint()) < 0.001)
{
vt1.rotateBy(-PI * 0.5, AcGeVector3d::kZAxis);
}
else
{
vt1.rotateBy(PI * 0.5, AcGeVector3d::kZAxis);
}
}
XCurveSegment cenCurve = GetCurve();
AcGeVector3d vt2;
if (cenCurve.Is(CURVE_LINE)) // 直线
{
vt2 = cenCurve.MidPoint() - pt;
}
else // 弧线
{
vt2 = cenCurve.GetArc().GetCenterPt() - pt;
vt2.z = 0.0;
vt2.rotateBy(-PI * 0.5, AcGeVector3d::kZAxis);
}
vt1.z = 0.0;
vt2.z = 0.0;
double dAngle = vt2.angleTo(vt1, AcGeVector3d::kZAxis);
if (nPos == 0) // 起点
{
if (dAngle < PI)
{
return 1;
}
else
{
return 2;
}
}
else // 终点
{
if (dAngle < PI)
{
return 2;
}
else
{
return 1;
}
}
}
OPENOBJ_END();
}
}
return 0;
}
void TDbPipeCanal::Draw3dType(XExplodeDraw &dc) const
{
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);
// 起点方沟边线连接点
XPoint pt1 = segUp.StartPoint();
XPoint pt2 = segDown.StartPoint();
OPENOBJ_BEGIN(GetNode(0), AcDb::kForRead, TDbPipeFitting, pFitting);
if (pFitting != NULL)
{
TDbCanalFitting fitting(pFitting);
fitting.IntersectWith(this->objectId(), pt1, pt2);
}
OPENOBJ_END();
// 终点方沟边线连接点
XPoint pt3 = segUp.EndPoint();
XPoint pt4 = segDown.EndPoint();
OPENOBJ_BEGIN(GetNode(1), AcDb::kForRead, TDbPipeFitting, pFitting);
if (pFitting != NULL)
{
TDbCanalFitting fitting(pFitting);
fitting.IntersectWith(this->objectId(), pt4, pt3);
}
OPENOBJ_END();
if (cenCurve.Is(CURVE_LINE)) // 直线方沟
{
XLine lineUp1 = segUp.GetLine();
XLine lineDown1 = segDown.GetLine();
pt1 = ProjectAlongZAxis(lineUp1, pt1);
pt3 = ProjectAlongZAxis(lineUp1, pt3);
pt2 = ProjectAlongZAxis(lineDown1, pt2);
pt4 = ProjectAlongZAxis(lineDown1, pt4);
// 底面
AcGePoint3dArray arrPts;
arrPts.append(pt1);
arrPts.append(pt3);
arrPts.append(pt2);
arrPts.append(pt4);
dc.DrawMesh(2, 2, arrPts.asArrayPtr());
// 根据起始点高度,计算顶面边线
XPoint ptUpS = segUp.StartPoint(), ptUpE = segUp.EndPoint();
XPoint ptDownS = segDown.StartPoint(), ptDownE = segDown.EndPoint();
ptUpS.z += GetStartHeight();
ptDownS.z = ptUpS.z;
ptUpE.z += GetEndHeight();
ptDownE.z = ptUpE.z;
XLine lineUp2(ptUpS, ptUpE);
XLine lineDown2(ptDownS, ptDownE);
XPoint pt11 = ProjectAlongZAxis(lineUp2, pt1);
XPoint pt33 = ProjectAlongZAxis(lineUp2, pt3);
XPoint pt22 = ProjectAlongZAxis(lineDown2, pt2);
XPoint pt44 = ProjectAlongZAxis(lineDown2, pt4);
// 绘制边界面
arrPts.setLogicalLength(0);
arrPts.append(pt1);
arrPts.append(pt11);
arrPts.append(pt3);
arrPts.append(pt33);
dc.DrawMesh(2, 2, arrPts.asArrayPtr());
arrPts.setLogicalLength(0);
arrPts.append(pt2);
arrPts.append(pt22);
arrPts.append(pt4);
arrPts.append(pt44);
dc.DrawMesh(2, 2, arrPts.asArrayPtr());
}
else // 弧线方沟
{
XArc arcUp1 = segUp.GetArc();
XArc arcDown1 = segDown.GetArc();
// 计算融合前底面边线
XPoint ptUpS1, ptUpE1;
arcUp1.GetStartPoint(ptUpS1);
arcUp1.GetEndPoint(ptUpE1);
XPoint ptUpMid1 = arcUp1.MidPoint();
ptUpS1.z = StartPoint().z;
ptUpE1.z = EndPoint().z;
ptUpMid1.z = (ptUpS1.z + ptUpE1.z) * 0.5;
AcGeCircArc3d cirUp1(ptUpS1, ptUpMid1, ptUpE1);
XPoint ptDownS1, ptDownE1;
arcDown1.GetStartPoint(ptDownS1);
arcDown1.GetEndPoint(ptDownE1);
XPoint ptDownMid1 = arcDown1.MidPoint();
ptDownS1.z = StartPoint().z ;
ptDownE1.z = EndPoint().z;
ptDownMid1.z = (ptDownS1.z + ptDownE1.z) * 0.5;
AcGeCircArc3d cirDown1(ptDownS1, ptDownMid1, ptDownE1);
// 融合后底面边线
pt1 = ProjectAlongZAxis(cirUp1, pt1);
pt3 = ProjectAlongZAxis(cirUp1, pt3);
pt2 = ProjectAlongZAxis(cirDown1, pt2);
pt4 = ProjectAlongZAxis(cirDown1, pt4);
// 中点
AcGeVector3d vt1 = pt1 - arcUp1.GetCenterPt();
AcGeVector3d vt2 = pt3 - arcUp1.GetCenterPt();
vt1.z = 0.0;
vt2.z = 0.0;
double dAngle = vt1.angleTo(vt2, AcGeVector3d::kZAxis);
vt1.rotateBy(dAngle * 0.5, AcGeVector3d::kZAxis);
vt1.normalize();
XPoint pt5 = arcUp1.GetCenterPt() + vt1 * arcUp1.GetRadius();
pt5 = ProjectAlongZAxis(cirUp1, pt5);
AcGeVector3d vt3 = pt2 - arcDown1.GetCenterPt();
AcGeVector3d vt4 = pt4 - arcDown1.GetCenterPt();
vt3.z = 0.0;
vt4.z = 0.0;
dAngle = vt3.angleTo(vt4, AcGeVector3d::kZAxis);
vt3.rotateBy(dAngle * 0.5, AcGeVector3d::kZAxis);
vt3.normalize();
XPoint pt6 = arcDown1.GetCenterPt() + vt3 * arcDown1.GetRadius();
pt6 = ProjectAlongZAxis(cirDown1, pt6);
AcGeCircArc3d arc1(pt1, pt5, pt3);
AcGeCircArc3d arc2(pt2, pt6, pt4);
// 绘制底面
int nSplitNum = 10;
AcGePoint3dArray arr1, arr2, arr;
arc1.getSamplePoints(nSplitNum, arr1);
arc2.getSamplePoints(nSplitNum, arr2);
for (int i = 0; i < arr1.length(); ++i)
{
arr.append(arr1.at(i));
arr.append(arr2.at(i));
}
dc.DrawMesh(arr.length() / 2, 2, arr.asArrayPtr());
// 边界面
XPoint ptUpS2 = ptUpS1;
XPoint ptUpE2 = ptUpE1;
ptUpS2.z += GetStartHeight();
ptUpE2.z += GetEndHeight();
XPoint ptUpMid2 = ptUpMid1;
ptUpMid2.z = (ptUpS2.z + ptUpE2.z) * 0.5;
AcGeCircArc3d cirUp2(ptUpS2, ptUpMid2, ptUpE2);
XPoint ptDownS2 = ptDownS1;
XPoint ptDownE2 = ptDownE1;
ptDownS2.z += GetStartHeight();
ptDownE2.z += GetEndHeight();
XPoint ptDownMid2 = ptDownMid1;
ptDownMid2.z = (ptDownS2.z + ptDownE2.z) * 0.5;
AcGeCircArc3d cirDown2(ptDownS2, ptDownMid2, ptDownE2);
pt1 = ProjectAlongZAxis(cirUp2, pt1);
pt3 = ProjectAlongZAxis(cirUp2, pt3);
pt5 = ProjectAlongZAxis(cirUp2, pt5);
pt2 = ProjectAlongZAxis(cirDown2, pt2);
pt4 = ProjectAlongZAxis(cirDown2, pt4);
pt6 = ProjectAlongZAxis(cirDown2, pt6);
AcGeCircArc3d arc3(pt1, pt5, pt3);
AcGeCircArc3d arc4(pt2, pt6, pt4);
// 绘制边界面
AcGePoint3dArray arr3, arr4;
arc3.getSamplePoints(nSplitNum, arr3);
arc4.getSamplePoints(nSplitNum, arr4);
arr.setLogicalLength(0);
for (int i = 0; i < arr3.length(); ++i)
{
arr.append(arr1.at(i));
arr.append(arr3.at(i));
}
dc.DrawMesh(arr.length() * 0.5, 2, arr.asArrayPtr());
arr.setLogicalLength(0);
for (int i = 0; i < arr4.length(); ++i)
{
arr.append(arr2.at(i));
arr.append(arr4.at(i));
}
dc.DrawMesh(arr.length() * 0.5, 2, arr.asArrayPtr());
}
}
double TDbPipeCanal::GetStartHeight() const
{
assertReadEnabled();
const TEntityFields &fd = GetFields();
double dHeight = m_nHeight;
fd.GFD(_T("START_HEIGHT"), dHeight);
return dHeight;
}
void TDbPipeCanal::SetStartHeight(double dHeight)
{
assertWriteEnabled();
TEntityFields &fd = Fields();
fd.SFD(_T("START_HEIGHT"), dHeight);
}
double TDbPipeCanal::GetEndHeight() const
{
assertReadEnabled();
const TEntityFields &fd = GetFields();
double dHeight = m_nHeight;
fd.GFD(_T("END_HEIGHT"), dHeight);
return dHeight;
}
void TDbPipeCanal::SetEndHeight(double dHeight)
{
assertWriteEnabled();
TEntityFields &fd = Fields();
fd.SFD(_T("END_HEIGHT"), dHeight);
}
XPoint TDbPipeCanal::ProjectAlongZAxis(XLine &line, const XPoint &pt) const
{
XPoint ptRet = pt;
AcDbLine lineTemp(line.StartPoint(), line.EndPoint());
lineTemp.getClosestPointTo(pt, AcGeVector3d::kZAxis, ptRet, Adesk::kTrue);
return ptRet;
}
AcGePoint3d TDbPipeCanal::ProjectAlongZAxis(AcGeCircArc3d &cir, const XPoint &pt) const
{
AcGePoint3d ptRet = pt;
AcGePlane plane(cir.center(), cir.normal());
AcGeLine3d line(pt, AcGeVector3d::kZAxis);
AcGePoint3d ptInt;
if (plane.intersectWith(line, ptInt) == Adesk::kTrue)
{
ptRet = ptInt;
}
return ptRet;
}
double TDbPipeCanal::GetGradient() const
{
assertReadEnabled();
double dSEle = this->StartPoint().z;
double dEEle = this->EndPoint().z;
double dGradient = 0.0;
if (fabs(dSEle - dEEle) > 0.000001)
{
double dLen = this->StartPoint().Distance2d(this->EndPoint());
dGradient = (dSEle - dEEle) / dLen;
}
return dGradient;
}
void TDbPipeCanal::SetGradient(double dGradient)
{
assertWriteEnabled();
if (fabs(dGradient) < 0.000001)
{
EndPoint().z = StartPoint().z;
}
else
{
double dLen = this->StartPoint().Distance2d(this->EndPoint());
if (dGradient > 0.0)
{
EndPoint().z += dLen * dGradient;
}
else
{
StartPoint().z += dLen * dGradient;
}
}
}