3000 lines
78 KiB
C++
3000 lines
78 KiB
C++
// 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;
|
||
}
|
||
}
|
||
}
|