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

3729 lines
106 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.
#include "stdafx.h"
#include <DbCurveMesh2.h>
#include <DbPolyMesh.h>
#include "DbPipe.h"
#include "DbPipeFitting.h"
#include "DbPipeLabel.h"
#include "DbPipeValve.h"
#include "DbPsConfig.h"
#include "PipeTools.h"
#include "DbWell.h"
#include "DbDoubleLinePipe.h"
#include "DbVPipeDim.h"
#include "SectionUtility.h"
#include "SectionStructDef.h"
#include "TXmlTree.h"
//#include "TwtDef.h"
// 旋转向量
XVector3D RotateBy(const XVector3D& vt,const XVector3D& vtAxis,double dAngle/*弧度值*/)
{
AcGeVector3d vtTemp(vt);
AcGeVector3d vtResult=vtTemp.rotateBy(dAngle,vtAxis);
return XVector3D(vtResult);
}
// 绘制加粗的线(convert to pline)
void DrawWeight(XExplodeDraw &dc,double dWeight,AcDbPolyline& pline)
{
XAcGiViewDraw &viewDraw = (XAcGiViewDraw &)dc;
int nNum = pline.numVerts();
if (nNum > 0) {
// for (int k=0;k<nNum; k++) {
// pline.setWidthsAt(k,dWeight,dWeight);
// }
pline.setConstantWidth(dWeight);
viewDraw.Polyline(pline);
// dc << pline;
//dc.DrawEntity(pline);
// if(viewDraw.m_pWd)
// pline.worldDraw(viewDraw.m_pWd);
// else
// pline.viewportDraw(viewDraw.m_pVd);
}
}
//沈睿2004、6、9修改,增加颜色参数
void DrawWeight(XExplodeDraw &dc,double dWeight,XPoly2D &poly,int nColorIndex, double nScale)
{
//cet 2013.7.18 add 18、19平台粗显时,线型比例设置不正确
//2005/2/25 modify sr 管线支持比例因子,由于DC不直接支持,所以通过修改dc内部参数实现
//其中,绘制是修改DC环境参数,必须先执行,炸开是直接修改新生成的实体,所以后执行
if(_tcsicmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0) {
XAcGiViewDraw &dcDraw = (XAcGiViewDraw&)dc;
// cet 2012.12.18 del 用户选择是否随管线比例变化
// dcDraw.GetCommonDraw()->subEntityTraits().setLineTypeScale(GetPScale()/100*linetypeScale());// SR 2012-6-19 支持线型比例随对象比例发生变化
dcDraw.GetCommonDraw()->subEntityTraits().setLineTypeScale(nScale);
}
AcDbPolyline pline;
pline.setLinetypeScale(nScale);
PolyConvert(poly, pline);
if(nColorIndex>0)
pline.setColorIndex(nColorIndex);
DrawWeight(dc,dWeight,pline);
}
void DrawWeight(XExplodeDraw &dc,double dWeight,XCurveSegment &seg,int nColorIndex, double nScale)
{
XPoly2D poly;
seg.AsPoly2D(poly);
DrawWeight(dc,dWeight,poly, nColorIndex,nScale);
}
void DrawWeight(XExplodeDraw &dc,double dWeight,XCircle &cir,int nColorIndex, double nScale)
{
XCurveSegment seg;
seg = cir;
DrawWeight(dc,dWeight,seg, nColorIndex, nScale);
}
ACRX_DXF_DEFINE_MEMBERS(ATSPipe, ATSPipePrototype, AcDb::kDHL_CURRENT,
AcDb::kMReleaseCurrent, 1, ATS_PIPE,
"ATS_PIPE图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(TDbPipe);
const Adesk::UInt8 TDbPipe::g_nVersion = 2;
TDbPipe::TDbPipe():
m_dRadius(30),m_dRadiusIn(0),m_dOldRadius(0),m_dDnDiameter(0),
m_dPipeWeight(0.35),m_nMaterial(0),m_dSpeedSubMid(0),m_dSpeedLength(0),m_dSpare(0)
{
m_sysType=TPipeSys::kUnknownSys/*kHeatPipe*/;
m_bUpdateLinkedDim = false; // cet 2015.3.11 add 默认不更新关联标注
}
void TDbPipe::CopyPropertiesFrom(AcDbEntity *pSrc,unsigned gMatchFlag)
{
assertWriteEnabled();
TDbPipePrototype::CopyPropertiesFrom(pSrc, gMatchFlag);
TDbPipe *pPipe = TDbPipe::cast(pSrc);
if(pPipe) {
m_dRadius = pPipe->m_dRadius;
m_dRadiusIn = pPipe->m_dRadiusIn;
m_dDnDiameter = pPipe->m_dDnDiameter;
m_dPipeWeight = pPipe->m_dPipeWeight;
m_nMaterial = pPipe->m_nMaterial;
m_sLabel = pPipe->m_sLabel;
SetPipeSystemName(pPipe->GetPipeSystemName()); // cet 2016.8.22 add
UpdateLinkedPipeDnDimText(); // cet 2017.9.19 add 更新相关标注
}
}
Acad::ErrorStatus TDbPipe::subGetClassID(CLSID* pClsid) const
{
return Acad::eOk;
}
Acad::ErrorStatus
TDbPipe::subGetOsnapPoints(AcDb::OsnapMode osnapMode,
INT_PTR gsSelectionMark,
const AcGePoint3d& ptPick,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcGePoint3dArray& snapPoints,
AcDbIntArray& geomIds) const
{
extern BOOL GetPSEntFormBlock(DList<AcDbObjectId> &lstPSEnt,
const XRectAngle& rectBound,const AcRxClass *pClass);
Acad::ErrorStatus es=Acad::eOk;
es=TDbPipePrototype::subGetOsnapPoints(osnapMode, gsSelectionMark,
ptPick, lastPoint, viewXform, snapPoints, geomIds);
if(es!=Acad::eOk) return es;
if(osnapMode==AcDb::kOsModeIns && !IsVertical()) { // 增加插入点
XPoint ptMin,ptMax;
DList<AcDbObjectId> lstPipe;
if(XCurveSegment::GetExtend(ptMin,ptMax)
&& GetPSEntFormBlock(lstPipe,XRectAngle(ptMin,ptMax),TDbPipe::desc())) {
AcDbObjectId idThis=objectId();
int nCount = lstPipe.Length();
for(long i=0;i<nCount;i++) {
AcDbObjectId &idPipe=*lstPipe[i];
if(idPipe==idThis)
continue;
OPENOBJ_BEGIN(idPipe,AcDb::kForRead,TDbPipe,pPipe);
if(pPipe!=NULL && !pPipe->IsVertical()) {
XPoint ptOnThis;
if(::Intersection(this,pPipe,ptOnThis)) {
snapPoints.append((AcGePoint3d)ptOnThis);
}
}
OPENOBJ_END();
}
}
}
if(osnapMode==AcDb::kOsModeQuad && IsVertical()) { //立管 2007-11-23 武汉市院
double dRadius = m_dRadius*GetPScale();
XPoint ptCen = GetVerUpCenter();
XPoint pt1, pt2, pt3, pt4;
ads_polar(ptCen, 0, dRadius, pt1);
ads_polar(ptCen, PI/2.0, dRadius, pt2);
ads_polar(ptCen, PI, dRadius, pt3);
ads_polar(ptCen, PI/2.0*3.0, dRadius, pt4);
snapPoints.append(pt1);
snapPoints.append(pt2);
snapPoints.append(pt3);
snapPoints.append(pt4);
}
return es;
}
// 从DWG读入数据:
Acad::ErrorStatus
TDbPipe::dwgInFields(AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbPipePrototype::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_dRadius);
pFiler->readItem(&m_dRadiusIn);
pFiler->readItem(&m_dDnDiameter);
pFiler->readItem(&m_dPipeWeight);
pFiler->readItem(&m_nMaterial);
ReadString(pFiler,m_sLabel);
pFiler->readItem(&m_dSpeedSubMid);
pFiler->readItem(&m_dSpeedLength);
if(nVer > 1){
pFiler->readItem(&m_dSpare);
// if (!IsNewDimType())
// {
// GetNewDimType();
// }
ReadString(pFiler,m_sSpare);
}
if(nVer == 1){
if(m_dRadius > 20)
m_dRadius = m_dRadius / 100;
if(m_dRadiusIn > 10)
m_dRadiusIn = m_dRadiusIn / 100;
}
return pFiler->filerStatus();
}
Acad::ErrorStatus
TDbPipe::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbPipePrototype::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
if(g_nSaveTArchVer==6)
pFiler->writeItem((Adesk::UInt8)1);
else
pFiler->writeItem(g_nVersion);
if(g_nSaveTArchVer==6){
pFiler->writeItem(m_dRadius*100);
pFiler->writeItem(m_dRadiusIn*100);
}
else{
pFiler->writeItem(m_dRadius);
pFiler->writeItem(m_dRadiusIn);
}
pFiler->writeItem(m_dDnDiameter);
pFiler->writeItem(m_dPipeWeight);
pFiler->writeItem(m_nMaterial);
pFiler->writeItem((const TCHAR *)m_sLabel);
pFiler->writeItem(m_dSpeedSubMid);
pFiler->writeItem(m_dSpeedLength);
if(g_nSaveTArchVer>6){
// zxl 2012.12.25 modify 新标注兼容老标注类型
// pFiler->writeItem(m_dSpare);
double dSpare = GetOldDimType();
pFiler->writeItem(dSpare);
pFiler->writeItem((const TCHAR *)m_sSpare);
}
return pFiler->filerStatus();
}
double TDbPipe::GetOldDimType() const
{
if (!IsNewDimType())
{
return m_dSpare;
}
double dRet = -1;
int nDnType = GetPipeDnDimType();
int nGradientType = GetPipeGradientDimType();
int nLenType = GetPipeLenDimType();
int nLabelType = GetPipeDimLableType();
if (nDnType > 0)
{
if (nGradientType == 1 || nGradientType == 2)
{
if (nLenType > 0)
{
dRet = 1;
}
else
{
dRet = 4;
}
}
else if (nGradientType == 3 || nGradientType == 4)
{
if (nLenType > 0)
{
if (nLabelType == 0)
{
dRet = 3;
}
else
{
dRet = 2;
}
}
else
{
if (nLabelType == 0)
{
dRet = 6;
}
else
{
dRet = 5;
}
}
}
else if (nGradientType == 5 || nGradientType == 6)
{
dRet = 10;
}
else
{
if (nLenType > 0)
{
if (nLabelType == 0)
{
dRet = 7;
}
else if (nLabelType == 1)
{
dRet = 8;
}
else
{
dRet = 9;
}
}
else
{
dRet = 0;
}
}
}
else
{
dRet = 0;
}
return dRet;
}
Acad::ErrorStatus
TDbPipe::dxfInFields(AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es=Acad::eOk;
es=TDbPipePrototype::dxfInFields(pFiler);
if(es!=Acad::eOk) return es;
if (!pFiler->atSubclassData(_T("TDbPipe"))) {
return Acad::eBadDxfSequence;
}
resbuf rb;
while((es==Acad::eOk) && ((es=pFiler->readResBuf(&rb))==Acad::eOk)) {
switch (rb.restype) {
case AcDb::kDxfXTextString+1:
m_sLabel=rb.resval.rstring;
break;
case AcDb::kDxfXReal:
m_dDnDiameter=rb.resval.rreal;
break;
case AcDb::kDxfXReal+1:
m_dTextHeight=rb.resval.rreal;
break;
case AcDb::kDxfXCoord:
m_ptLabel=rb.resval.rpoint;
break;
default:
pFiler->pushBackItem();
es = Acad::eEndOfFile;
break;
}
}
if(es!=Acad::eEndOfFile)
return Acad::eInvalidResBuf;
return pFiler->filerStatus();
}
Acad::ErrorStatus
TDbPipe::dxfOutFields(AcDbDxfFiler* pFiler) const
{
Acad::ErrorStatus es=Acad::eOk;
es=TDbPipePrototype::dxfOutFields(pFiler);
assert(es==Acad::eOk);
es=pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbPipe"));
assert(es==Acad::eOk);
pFiler->writeString(AcDb::kDxfXTextString+1,(const TCHAR*)m_sLabel);
pFiler->writeDouble(AcDb::kDxfXReal,m_dDnDiameter);
pFiler->writeDouble(AcDb::kDxfXReal+1,m_dTextHeight);
pFiler->writePoint3d(AcDb::kDxfXCoord,m_ptLabel);
pFiler->writeUInt8(AcDb::kDxfInt8, IsVertical());
return es;
}
//extern BOOL StringAnalysis(const TCHAR *src, XString &sPrefix, int *num, int *numWidth);
//void TDbPipe::SetSubText(long i,CString sText)
//{
// assertWriteEnabled();
// XString xsText;
// int num, numWith;
// StringAnalysis((const TCHAR*)sText, xsText, &num, &numWith);
// SetLabel((const TCHAR*)xsText);
// SetDnDiameter(num);
//}
// 增加流向夹点
Acad::ErrorStatus TDbPipe::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const
{
assertReadEnabled();
Acad::ErrorStatus es=Acad::eOk;
es=TDbPipePrototype::subGetGripPoints(gripPoints, osnapModes, geomIds);
if(es!=Acad::eOk)
return es;
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 Acad::eOk;
}
// 取得夹点说明
Acad::ErrorStatus TDbPipe::GetGripText(int idx, CString &cs) const
{
Acad::ErrorStatus es=Acad::eOk;
es = TDbPipePrototype::GetGripText(idx,cs);
if(es!=Acad::eOk && !IsVertical()) {
if(idx == 4 && g_bSPipeFDir)
cs=_T("改变流向");
es=Acad::eOk;
}
return es;
}
// 功能: 夹点操作
Acad::ErrorStatus TDbPipe::subMoveGripPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
Acad::ErrorStatus es=Acad::eOk;
es=TDbPipePrototype::subMoveGripPointsAt(indices, offset);
if(es!=Acad::eOk) return es;
if(!IsVertical()){
int idx = indices[0];
if(idx == 4 && 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);
XPoint ptOffset=p1+offset;
double dDist1 = ads_distance(ptOffset, GetStartPoint());
double dDist2 = ads_distance(ptOffset, GetEndPoint());
if(dDist1 < dDist2)
SetFlowDir(TPipeSys::kFromEnd);
else
SetFlowDir(TPipeSys::kFromStart);
}
}
return es;
}
BOOL TDbPipe::CanMergeWith(const TDbPipePrototype &other, int *iPosThis, int *iPosOther) const
{
if(other.isKindOf(TDbPipe::desc())) {
TDbPipe *pOther=TDbPipe::cast(&other);
if(fabs(m_dRadius-pOther->m_dRadius)>_distSnap ||
fabs(m_dDnDiameter-pOther->m_dDnDiameter)>_distSnap)
return FALSE;
}
return TDbPipePrototype::CanMergeWith(other,iPosThis,iPosOther);
}
// 自动增加节点到当前数据库,ids-该节点自动连接的管线,派生类应当重载
AcDbObjectId TDbPipe::AddAutoNodeToDb(const XPoint &ptAt, const DList<AcDbObjectId> &ids) const
{
AcDbObjectId id;
if(ids.Length()) {
TDbPipeFitting *pFitting=new TDbPipeFitting;
pFitting->UpdateLinkage(ptAt, GetSysType(), ids);
pFitting->setLayer(this->layerId());
id=AddToCurrentSpace(pFitting, Adesk::kTrue);
}
return id;
}
void TDbPipe::DisposeBreak(const XCurveSegment &cv,
AcGePoint3dArray &arPoint,const XPoint &ptLoc,double dWidth,
double dDistance,const AcGeVector3d &vtDir, DList<XCurveSegment> &lstBreakCurve) const
{
if(Is(CURVE_ARC)){//sr add
XArc arc2 = GetArc();
XPoint pt3, pt4, ptMid;
arc2.GetStartPoint(pt3);
arc2.GetEndPoint(pt4);
// arc2.GetPoints(pt3, pt4);
arc2.MidPoint(ptMid);
pt3.z = 0;
pt4.z = 0;
ptMid.z = 0;
XArc arc(pt3, ptMid, pt4);//先把arc标高设为0
double nParam(0);
XPoint pt1, pt2;
AcDbArc *pArc=new AcDbArc;
pArc->setCenter(arc.GetCenterPt());
pArc->setRadius(arc.GetRadius());
pArc->setStartAngle(arc.GetStarAngle());
pArc->setEndAngle(arc.GetEndAngle());
// cet 2013.1.22 modify 所求点可能不在弧线上
// pArc->getParamAtPoint(ptLoc, nParam);
// pArc->getPointAtParam(nParam+dWidth/arc.GetRadius(), pt1);
// pArc->getPointAtParam(nParam-dWidth/arc.GetRadius(), pt2);
double dDist = 0.0, dTotalDist = 0.0;
pArc->getDistAtPoint(ptLoc, dDist);
AcGePoint3d ptE;
pArc->getEndPoint(ptE);
pArc->getDistAtPoint(ptE, dTotalDist);
if (dDist + dWidth < dTotalDist) // 所求点在弧线上
{
pArc->getPointAtDist(dDist + dWidth, pt1);
}
else // 所求点不在弧线上
{
pt1 = ptE;
}
if (dDist - dWidth > 0.0) // 所求点在弧线上
{
pArc->getPointAtDist(dDist - dWidth, pt2);
}
else // 所求点不在弧线上
{
pArc->getStartPoint(pt2);
}
delete pArc;
// getPointAtParam(nParam+dWidth/arc.radius, pt1);
// getPointAtParam(nParam-dWidth/arc.radius, pt2);
// cet 2017.11.13 del 二维显示不需要考虑z值;
// 其次求最近点也有问题,应该为z轴方向最近点,不然坡度管交点位置可能改变.
// getClosestPointTo(pt1,pt1);
// getClosestPointTo(pt2,pt2);
pt1.z = 0;
pt2.z = 0;
arPoint.append((AcGePoint3d)pt1);
arPoint.append((AcGePoint3d)pt2);
}
else{
XVector3D vtAdd = vtDir * dWidth;
XPoint ptStart = ptLoc-vtAdd;
XPoint ptEnd = ptLoc+vtAdd;
double dStart = cv.PathDistance(ptStart);
double dEnd = cv.PathDistance(ptEnd);
// cet 2017.11.13 del 二维显示不需要考虑z值;
// 其次求最近点也有问题,应该为z轴方向最近点,不然坡度管交点位置可能改变.
// if(fabs(StartPoint().z - EndPoint().z) < 0.01){
// getClosestPointTo(ptStart,ptStart);
// getClosestPointTo(ptEnd,ptEnd);
// }
ptStart.z = 0;
ptEnd.z = 0;
if (dStart>0 && dStart<dDistance)
arPoint.append((AcGePoint3d)ptStart);
if (dEnd>0 && dEnd<dDistance)
arPoint.append((AcGePoint3d)ptEnd);
XLine line(ptStart, ptEnd, 1);
XCurveSegment seg;
seg = line;
lstBreakCurve.Append(new XCurveSegment(seg));
}
}
//之前采用AOL求交,在坐标太大的情况下,计算失误。 sr 2007-5-9
BOOL Intersection2Curve(XCurveSegment &cvPipe1, XCurveSegment &cvPipe2, XPoint &ptIntersect)
{
cvPipe1.SetElevation(0);
cvPipe2.SetElevation(0);
AcDbCurve *pCurve1 = cvPipe1.AsAcDbCurve();
AcDbCurve *pCurve2 = cvPipe2.AsAcDbCurve();
AcGePoint3dArray points;
Acad::ErrorStatus es = pCurve1->intersectWith(pCurve2, AcDb::kOnBothOperands, points);
delete pCurve1;
delete pCurve2;
int numPoints=points.length();
if(numPoints == 1){ //有1个交点
ptIntersect = points[0];
return TRUE;
}
return FALSE;
}
/*
// 通过管件附件打断的曲线,二维,z=0
void TDbPipe::GetBrokenCurves(const XCurveSegment &cv,
DList<XCurveSegment> &lstCurve) const
{
int nAttach = m_lstAttachment.Length();
int nHide = m_lstHidePipe.Length();
if (nAttach<=0 && nHide<=0){ //没有管件附件
lstCurve.Append(new XCurveSegment(cv));
return;
}
//AcGePoint3dArray arPoint;//裁剪的点
AcGePoint3dArray arPoint(20);//裁剪的点
DList<XPoint> lstLocation;
DList<XCurveSegment> lstBreakCurve;
//double dDisThis = PathDistance(EndPoint());
double dDisThis = cv.Length();
// 直线段时
//XVector3D vtDir(EndPoint()-StartPoint());//以直线段初始化方向
XVector3D vtDir(cv.EndPoint()-cv.StartPoint());//以直线段初始化方向
AcGeVector3d vtAttachment(vtDir);//管线附件在基线上的方向
vtAttachment.z = 0;
vtAttachment.normalize();
//取得临时管线附件和管件附件的在管线上的端点
for(int i=0; i<nAttach; i++) {
const AcDbObjectId &id = m_lstAttachment[i];
OPENOBJ_BEGIN(id,AcDb::kForRead,TDbPipeAttachment,pAttachment);
if(pAttachment!=NULL) {
if(pAttachment->IsCheckSysType() && pAttachment->GetSysType()!=GetSysType())
continue;
double dWidth = pAttachment->GetWidth()/2;
double dScale = pAttachment->GetScale();
dWidth *= dScale;
TDbPipeValve *pValve = NULL;
if(pValve = TDbPipeValve::cast(pAttachment)){
if(pValve->HasFlange())//如果是带法兰的阀门,宽度要增加法兰厚度
dWidth += pValve->GetFlangeWidth()*pValve->GetScale()*GetPScale()/100/2;
}
if (dWidth>1.0E-3) {
XPoint ptLocation(pAttachment->GetLocation());
ptLocation.z=0;
lstLocation.Append(new XPoint(ptLocation));
DisposeBreak(cv,arPoint,ptLocation,dWidth,dDisThis,vtAttachment, lstBreakCurve);
}
}
OPENOBJ_END();
}
// 管线的遮挡关系
for(int k=0; k<nHide; k++) {
OPENOBJ_BEGIN(m_lstHidePipe[k],AcDb::kForRead,TDbPipePrototype,pPipe);
if(pPipe!=NULL && IsPsSystemShow(pPipe->GetSysType())) {
double dWidth=pPipe->GetBreakWidth()/2; //打断间距,如果是单线管,读取系统变量
if(pPipe->isKindOf(TDbDoubleLinePipe::desc())){//如果是双线管,按管径和相交角度计算。2007 1 15
TDbDoubleLinePipe *pDPipe=(TDbDoubleLinePipe *)pPipe;
AcGeVector3d vt1 = pDPipe->Direction3d().AsAcGeVector3d();
AcGeVector3d vt2 = this->Direction3d().AsAcGeVector3d();
double dAng = vt1.angleTo(vt2);
double dDn = pDPipe->GetDnDiameter();
dWidth = dDn / sin(dAng) / 2;
}
if(dWidth>1.0E-3) {
XPoint ptIntersect,ptTemp;
XCurveSegment cvPipe=*pPipe;
XCurveSegment cvPipe2 = cv;
cvPipe.SetElevation(0);//设置标高为0
// if(cv.Intersection(cvPipe,ptIntersect,ptTemp)) {//AOL 计算不精确
if(Intersection2Curve(cvPipe2, cvPipe, ptIntersect)) {
if(fabs(StartPoint().z - EndPoint().z) < 0.01)
getClosestPointTo(ptIntersect,ptIntersect);
ptIntersect.z = 0;
lstLocation.Append(new XPoint(ptIntersect));
DisposeBreak(cv,arPoint,ptIntersect,dWidth,dDisThis,vtAttachment, lstBreakCurve);
}
}
}
OPENOBJ_END();
}
//按定位点到起点的距离快速排序(由小到大)
int nCount = arPoint.length();
if(nCount>1) {
DList<double> lstDist;// 打断点在曲线段上的距离
for(int i=0; i<nCount; i++) { // 为提高效率先计算出距离
XPoint ptTmp = arPoint[i];
double dDist=cv.PathDistance(arPoint[i]);
lstDist.Append(new double(dDist));
}
for(i=0; i<nCount-1; i++) {
for(int j=0; j<nCount-1-i; j++) {
if (*lstDist[j]>*lstDist[j+1]) { //Swap
lstDist.Swap(j,j+1);
arPoint.swap(j,j+1);
}
}
}
}
nCount = arPoint.length();
//得到管线基线,并用管线附件打断管线成AcDbCurve
AcDbVoidPtrArray arSeg;//裁剪后的曲线段
TDbPipePrototype pipeCv;
(XCurveSegment &)pipeCv = cv;
AcDbCurve *pCurve=pipeCv.GetBaseCurve();
Acad::ErrorStatus es2 = pCurve->getSplitCurves(arPoint, arSeg);
if(pCurve && es2 == Acad::eInvalidInput){
double dTmp = 100000.0 / StartPoint().x;
AcGeMatrix3d mat;
mat.setToScaling(dTmp); //之前是固定0.1
pCurve->transformBy(mat);
//在某些特殊情况下(坐标太大), getSplitCurves返回eInvalidInput, 导致管线无法打断, 沈睿2004-5-31
AcGePoint3dArray arPoint2(20);
for(int k=0; k<nCount; k++) {
AcGePoint3d ptCur=arPoint[k];
ptCur.transformBy(mat);
pCurve->getClosestPointTo(ptCur, ptCur);
arPoint2.append(ptCur);
}
es2 = pCurve->getSplitCurves(arPoint2, arSeg);
if(es2 != Acad::eOk) {
lstCurve.Append(new XCurveSegment(cv));
if(pCurve)
delete pCurve;
return;
}
mat.invert();
nCount = arSeg.length();
for(k=0; k<nCount; k++) {
AcDbCurve *pCurve0=(AcDbCurve *)arSeg[k];
pCurve0->transformBy(mat);
}
}
else if(pCurve==NULL || es2!=Acad::eOk) {
lstCurve.Append(new XCurveSegment(cv));
if(pCurve)
delete pCurve;
return;
}
delete pCurve;
nCount = arSeg.length();
int nLocation = lstLocation.Length();
if(nCount == nLocation*2 + 1) { // 正常情况,奇偶性
for(int k=0; k<nCount; k=k+2) {
AcDbCurve *pCurve0=(AcDbCurve *)arSeg[k];
TDbPipePrototype pipe;
pipe.SetBaseCurve(pCurve0);
delete pCurve0;
//判断有没有反方向绘制的线段 sr add 2006-1-10
XCurveSegment *pSeg=new XCurveSegment(pipe.GetCurve());
XPoint ptCurveS = pSeg->StartPoint();
XPoint ptCurveE = pSeg->EndPoint();
BOOL bStartInside = FALSE;
BOOL bEndInside = FALSE;
for(int m=0;m<lstBreakCurve.Length();m++){
XCurveSegment segTmp = *lstBreakCurve[m];
if(segTmp.Is(CURVE_LINE)){
XLine lineTmp = segTmp;
int ret1 = ptCurveS&lineTmp;
int ret2 = ptCurveE&lineTmp;
if(ret1 == PR_INSIDE)
bStartInside = TRUE;
if(ret2 == PR_INSIDE)
bEndInside = TRUE;
}
}
if(!bStartInside || !bEndInside)
lstCurve.Append(pSeg);
}
}
else { // 非正常情况,比如附件的遮挡范围超出基线
for(int k=0; k<nCount; k++) {
//转换成AcDbCurve
AcDbCurve *pCurve0=(AcDbCurve *)arSeg[k];
TDbPipePrototype pipe;
pipe.SetBaseCurve(pCurve0);
delete pCurve0;
//转换成XCurveSegment,并判断是否是附件的基线
XCurveSegment *pSeg=new XCurveSegment(pipe.GetCurve());
XPoint ptS = pSeg->StartPoint();
XPoint ptE = pSeg->EndPoint();
BOOL bAppend=TRUE;
for (int j=0;j<nLocation; j++) {
XPoint &pt = *lstLocation[j];
pt.z = 0;
int nResult = pt&(*pSeg);
if (nResult==PR_EDGE || nResult==PR_INSIDE) {
bAppend = FALSE;
delete pSeg;
break;
}
}
if (bAppend) { //添加用来显示的曲线段
lstCurve.Append(pSeg);
}
}
}
if(lstCurve.Length()<=0)
lstCurve.Append(new XCurveSegment(cv));
}
*/
// 通过管件附件打断的曲线,二维,z=0
// 2010-3-18 SR 增加视口显示的判断
void TDbPipe::GetBrokenCurves(XExplodeDraw &dc, const XCurveSegment &cv,
DList<XCurveSegment> &lstCurve) const
{
int nAttach = m_lstAttachment.Length();
int nHide = m_lstHidePipe.Length();
if (nAttach<=0 && nHide<=0){ //没有管件附件
lstCurve.Append(new XCurveSegment(cv));
return;
}
//AcGePoint3dArray arPoint;//裁剪的点
AcGePoint3dArray arPoint(20);//裁剪的点
DList<XPoint> lstLocation;
DList<XCurveSegment> lstBreakCurve;
//double dDisThis = PathDistance(EndPoint());
double dDisThis = cv.GetLength();
// 直线段时
//XVector3D vtDir(EndPoint()-StartPoint());//以直线段初始化方向
XVector3D vtDir(cv.EndPoint()-cv.StartPoint());//以直线段初始化方向
AcGeVector3d vtAttachment(vtDir);//管线附件在基线上的方向
vtAttachment.z = 0;
vtAttachment.normalize();
//取得临时管线附件和管件附件的在管线上的端点
for(int i=0; i<nAttach; i++) {
const AcDbObjectId &id = m_lstAttachment[i];
OPENOBJ_BEGIN(id,AcDb::kForRead,TDbPipeAttachment,pAttachment);
if(pAttachment!=NULL) {
if(pAttachment->IsCheckSysType() && pAttachment->GetSysType()!=GetSysType())
continue;
double dWidth = pAttachment->GetWidth()/2;
double dScale = pAttachment->GetScale();
dWidth *= dScale;
TDbPipeValve *pValve = NULL;
if(pValve = TDbPipeValve::cast(pAttachment)){
if(pValve->HasFlange())//如果是带法兰的阀门,宽度要增加法兰厚度
dWidth += pValve->GetFlangeWidth()*pValve->GetScale()*GetPScale()/100/2;
}
if (dWidth>1.0E-3) {
XPoint ptLocation(pAttachment->GetLocation());
ptLocation.z=0;
lstLocation.Append(new XPoint(ptLocation));
DisposeBreak(cv,arPoint,ptLocation,dWidth,dDisThis,vtAttachment, lstBreakCurve);
}
}
OPENOBJ_END();
}
XAcGiViewDraw &viewDraw = (XAcGiViewDraw &)dc;
// 管线的遮挡关系
for(int k=0; k<nHide; k++) {
OPENOBJ_BEGIN(m_lstHidePipe[k],AcDb::kForRead,TDbPipePrototype,pPipe);
if(pPipe!=NULL && IsVisibleEntity(pPipe))
{
AcDbObjectId idLay = pPipe->layerId();
if(viewDraw.m_pVd != NULL && _tcsicmp(dc.Desc(), XExplodeStream::Descriptor())!=0)
{
BOOL bFlag = viewDraw.m_pVd->viewport().layerVisible(idLay);// 2010-3-18 sr 增加考虑遮挡管线所在的图层是否被冻结
if(!bFlag)
continue;
}
double dWidth=pPipe->GetBreakWidth()/2; //打断间距,如果是单线管,读取系统变量
if(pPipe->isKindOf(TDbDoubleLinePipe::desc())){//如果是双线管,按管径和相交角度计算。2007 1 15
TDbDoubleLinePipe *pDPipe=(TDbDoubleLinePipe *)pPipe;
AcGeVector3d vt1 = pDPipe->Direction3d().AsAcGeVector3d();
AcGeVector3d vt2 = this->Direction3d().AsAcGeVector3d();
double dAng = vt1.angleTo(vt2);
double dDn = pDPipe->GetDnDiameter();
dWidth = dDn / sin(dAng) / 2;
}
if(dWidth>1.0E-3) {
XPoint ptIntersect,ptTemp;
XCurveSegment cvPipe=*pPipe;
XCurveSegment cvPipe2 = cv;
cvPipe.SetElevation(0);//设置标高为0
// if(cv.Intersection(cvPipe,ptIntersect,ptTemp)) {//AOL 计算不精确
if(Intersection2Curve(cvPipe2, cvPipe, ptIntersect)) {
// cet 2017.11.13 del 二维显示不需要考虑z值;
// 其次求最近点也有问题,应该为z轴方向最近点,不然坡度管交点位置可能改变.
// if(fabs(StartPoint().z - EndPoint().z) < 0.01)
// getClosestPointTo(ptIntersect,ptIntersect);
ptIntersect.z = 0;
lstLocation.Append(new XPoint(ptIntersect));
DisposeBreak(cv,arPoint,ptIntersect,dWidth,dDisThis,vtAttachment, lstBreakCurve);
}
}
}
OPENOBJ_END();
}
// cet 2013.1.22 add 剔除不在cv上的点, 避免打断时出错 正常情况没有问题,在暖通“弧线管连设备”的时候会造成这样的问题。
BOOL bArc = cv.Is(CURVE_ARC);
while(bArc)
{
int nLen = arPoint.length();
XPoint pt;
int i = 0;
for (; i < nLen; ++i)
{
pt = arPoint[i];
if ((pt & cv) != PR_INSIDE)
{
arPoint.removeAt(i);
break;
}
}
if (i >= nLen)
{
break;
}
}
//按定位点到起点的距离快速排序(由小到大)
int nCount = arPoint.length();
if(nCount>1) {
DList<double> lstDist;// 打断点在曲线段上的距离
for(int i=0; i<nCount; i++) { // 为提高效率先计算出距离
XPoint ptTmp = arPoint[i];
double dDist=cv.PathDistance(arPoint[i]);
lstDist.Append(new double(dDist));
}
for(i=0; i<nCount-1; i++) {
for(int j=0; j<nCount-1-i; j++) {
if (*lstDist[j]>*lstDist[j+1]) { //Swap
lstDist.Swap(j,j+1);
arPoint.swap(j,j+1);
}
}
}
}
nCount = arPoint.length();
//得到管线基线,并用管线附件打断管线成AcDbCurve
AcDbVoidPtrArray arSeg;//裁剪后的曲线段
TDbPipePrototype pipeCv;
(XCurveSegment &)pipeCv = cv;
AcDbCurve *pCurve=pipeCv.GetBaseCurve();
Acad::ErrorStatus es2 = pCurve->getSplitCurves(arPoint, arSeg);
if(pCurve && es2 == Acad::eInvalidInput){
double dTmp = 100000.0 / StartPoint().x;
AcGeMatrix3d mat;
mat.setToScaling(dTmp); //之前是固定0.1
pCurve->transformBy(mat);
//在某些特殊情况下(坐标太大), getSplitCurves返回eInvalidInput, 导致管线无法打断, 沈睿2004-5-31
AcGePoint3dArray arPoint2(20);
for(int k=0; k<nCount; k++) {
AcGePoint3d ptCur=arPoint[k];
ptCur.transformBy(mat);
pCurve->getClosestPointTo(ptCur, ptCur);
arPoint2.append(ptCur);
}
es2 = pCurve->getSplitCurves(arPoint2, arSeg);
if(es2 != Acad::eOk) {
lstCurve.Append(new XCurveSegment(cv));
if(pCurve)
delete pCurve;
return;
}
mat.invert();
nCount = arSeg.length();
for(k=0; k<nCount; k++) {
AcDbCurve *pCurve0=(AcDbCurve *)arSeg[k];
pCurve0->transformBy(mat);
}
}
else if(pCurve==NULL || es2!=Acad::eOk) {
lstCurve.Append(new XCurveSegment(cv));
if(pCurve)
delete pCurve;
return;
}
delete pCurve;
nCount = arSeg.length();
int nLocation = lstLocation.Length();
if(nCount == nLocation*2 + 1) { // 正常情况,奇偶性
for(int k=0; k<nCount; k=k+2) {
AcDbCurve *pCurve0=(AcDbCurve *)arSeg[k];
TDbPipePrototype pipe;
pipe.SetBaseCurve(pCurve0);
delete pCurve0;
//判断有没有反方向绘制的线段 sr add 2006-1-10
XCurveSegment *pSeg=new XCurveSegment(pipe.GetCurve());
XPoint ptCurveS = pSeg->StartPoint();
XPoint ptCurveE = pSeg->EndPoint();
BOOL bStartInside = FALSE;
BOOL bEndInside = FALSE;
for(int m=0;m<lstBreakCurve.Length();m++){
XCurveSegment segTmp = *lstBreakCurve[m];
if(segTmp.Is(CURVE_LINE)){
XLine lineTmp = segTmp;
int ret1 = ptCurveS&lineTmp;
int ret2 = ptCurveE&lineTmp;
if(ret1 == PR_INSIDE)
bStartInside = TRUE;
if(ret2 == PR_INSIDE)
bEndInside = TRUE;
}
}
if(!bStartInside || !bEndInside)
lstCurve.Append(pSeg);
}
}
else { // 非正常情况,比如附件的遮挡范围超出基线
for(int k=0; k<nCount; k++) {
//转换成AcDbCurve
AcDbCurve *pCurve0=(AcDbCurve *)arSeg[k];
TDbPipePrototype pipe;
pipe.SetBaseCurve(pCurve0);
delete pCurve0;
//转换成XCurveSegment,并判断是否是附件的基线
XCurveSegment *pSeg=new XCurveSegment(pipe.GetCurve());
XPoint ptS = pSeg->StartPoint();
XPoint ptE = pSeg->EndPoint();
BOOL bAppend=TRUE;
for (int j=0;j<nLocation; j++) {
XPoint &pt = *lstLocation[j];
pt.z = 0;
int nResult = pt&(*pSeg);
if (nResult==PR_EDGE || nResult==PR_INSIDE) {
bAppend = FALSE;
delete pSeg;
break;
}
}
if (bAppend) { //添加用来显示的曲线段
lstCurve.Append(pSeg);
}
}
}
if(lstCurve.Length()<=0)
lstCurve.Append(new XCurveSegment(cv));
}
// 立管遮挡管线的长度
double TDbPipe::GetVerPipeHideLength(const TDbPipeNode* pNode) const
{
double dLength=0;
int nCount=pNode->GetInterfaceNum();
for(int i=0; i<nCount; i++){
const AcDbObjectId &id=pNode->GetIPipe(i);
if(id != objectId()) {
OPENOBJ_BEGIN(id,AcDb::kForRead,TDbPipe,pPipe);
if(pPipe != NULL) {
if(pPipe->IsVerLowNode(pNode->objectId())) {
// if(GetPScale() < 60)//大样立管按管径 2007-1-31 取消
// dLength = pPipe->GetDnDiameter()/2;
// else
dLength = pPipe->GetRadius()*GetPScale();
break;
}
}
OPENOBJ_END();
}
}
return dLength;
}
void TDbPipe::ResetDrawSpeed()
{
assertWriteEnabled();
double dSpeedLength=0, dSpeedSubMid=0;//初始化
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;
}
} else { //是否立管遮挡管线
double dVerLen=GetVerPipeHideLength(pNode);
if(dVerLen>1.0E-3) {
dSpeedLength -= dVerLen;
dSpeedSubMid -= dVerLen/2;
}
}
}
OPENOBJ_END();
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;
}
} else { //是否立管遮挡管线
double dVerLen=GetVerPipeHideLength(pNode);
if(dVerLen>1.0E-3) {
dSpeedLength -= dVerLen;
dSpeedSubMid += dVerLen/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; //起点偏移到最终曲线中点的距离
if(cv.Is(CURVE_ARC)) // 2008-10-10 sr加入以下5行,弧管连接立管,遮挡错误。并补充GetHideCurve注释
{
if(cv.StartPoint() != StartPoint()) //如果弧反了,起点终点互换
m_dSpeedSubMid = dLength/2 - dSpeedSubMid;
}
} else {
m_dSpeedLength = 0;
m_dSpeedSubMid = 0;
}
}
void TDbPipe::ResetDrawSpeed(TDbPipeNode *pModifyNode)
{
if (pModifyNode == NULL)
{
return ResetDrawSpeed();
}
// 端点遮挡长度
assertWriteEnabled();
double dSpeedLength=0, dSpeedSubMid=0;//初始化
// 终点遮挡长度
bool bFlag = false;
OPENOBJ_BEGIN(m_nodeEnd.m_idNode,AcDb::kForRead,TDbPipeNode,pNode);
if(pNode!=NULL) {
bFlag = true;
if (pNode->IsHidePipe()) { //是否节点遮挡管线
double dWidth = pNode->GetWidth(this);
if (dWidth>1.0E-3) {
dSpeedLength -= dWidth;
dSpeedSubMid -= dWidth/2;
}
} else { //是否立管遮挡管线
double dVerLen=GetVerPipeHideLength(pNode);
if(dVerLen>1.0E-3) {
dSpeedLength -= dVerLen;
dSpeedSubMid -= dVerLen/2;
}
}
}
OPENOBJ_END();
if (!bFlag && pModifyNode->objectId() == m_nodeEnd.m_idNode)
{
TDbPipeNode *pNode = pModifyNode;
if (pNode->IsHidePipe()) { //是否节点遮挡管线
double dWidth = pNode->GetWidth(this);
if (dWidth>1.0E-3) {
dSpeedLength -= dWidth;
dSpeedSubMid -= dWidth/2;
}
} else { //是否立管遮挡管线
double dVerLen=GetVerPipeHideLength(pNode);
if(dVerLen>1.0E-3) {
dSpeedLength -= dVerLen;
dSpeedSubMid -= dVerLen/2;
}
}
}
// 起点遮挡长度
bFlag = false;
OPENOBJ_BEGIN(m_nodeStart.m_idNode,AcDb::kForRead,TDbPipeNode,pNode);
if (pNode!=NULL) {
bFlag = true;
if (pNode->IsHidePipe()) {
double dWidth = pNode->GetWidth(this);
if (dWidth>1.0E-3) {
dSpeedLength -= dWidth;
dSpeedSubMid += dWidth/2;
}
} else { //是否立管遮挡管线
double dVerLen=GetVerPipeHideLength(pNode);
if(dVerLen>1.0E-3) {
dSpeedLength -= dVerLen;
dSpeedSubMid += dVerLen/2;
}
}
}
OPENOBJ_END();
if (!bFlag && pModifyNode->objectId() == m_nodeStart.m_idNode)
{
TDbPipeNode *pNode = pModifyNode;
if (pNode->IsHidePipe()) {
double dWidth = pNode->GetWidth(this);
if (dWidth>1.0E-3) {
dSpeedLength -= dWidth;
dSpeedSubMid += dWidth/2;
}
} else { //是否立管遮挡管线
double dVerLen=GetVerPipeHideLength(pNode);
if(dVerLen>1.0E-3) {
dSpeedLength -= dVerLen;
dSpeedSubMid += dVerLen/2;
}
}
}
// 更新管道长度数据
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; //起点偏移到最终曲线中点的距离
if(cv.Is(CURVE_ARC)) // 2008-10-10 sr加入以下5行,弧管连接立管,遮挡错误。并补充GetHideCurve注释
{
if(cv.StartPoint() != StartPoint()) //如果弧反了,起点终点互换
m_dSpeedSubMid = dLength/2 - dSpeedSubMid;
}
}
else
{
m_dSpeedLength = 0;
m_dSpeedSubMid = 0;
}
}
// 考虑遮挡的当前曲线,二维,z=0
void TDbPipe::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) {
//1. 如果是弧管,由弧长(最后实际画的长度m_dSpeedLength)得到眩长
double dChordLength = cvHideTemp.GetChordLength(m_dSpeedLength);
XPointDir2d ptSubMid;
//2. 已知起点偏移到最终曲线中点的距离,得到中点
cvHideTemp.Polar(m_dSpeedSubMid,ptSubMid);
//3. 根据中点,和最终曲线的长度(玄长),得到最终曲线
cvHideTemp.GetSubSegment(ptSubMid,dChordLength,cvHide);
return;
}
cvHide = cvHideTemp;
}
BOOL TDbPipe::GetVerOpenedType(XVector3D &vtDir, int &nOpenType) const
{
BOOL bRet=FALSE;
const AcDbObjectId& idNode=GetVerUpNode();
OPENOBJ_BEGIN(idNode,AcDb::kForRead,TDbPipeNode,pNode);
if(pNode!=NULL)
{
int nPipeNum=pNode->GetInterfaceNum();
if(nPipeNum == 2)
{
for(int i=0; i<nPipeNum; i++)
{
const AcDbObjectId &id=pNode->GetIPipe(i);
if(id != objectId())
{
OPENOBJ_BEGIN(id,AcDb::kForRead,TDbPipePrototype,pPipe);
if(pPipe != NULL)
{
if(!pPipe->IsVertical())
{
AcDbObjectId idStart=pPipe->GetNode(0);
if(idStart==idNode)
vtDir=pPipe->GetDirection();
else
vtDir=pPipe->StartPoint()-pPipe->EndPoint();
bRet = TRUE;
}
}
OPENOBJ_END();
}
}
}
else if (nPipeNum == 3)
{
nOpenType = 1;
std::vector<AcGeVector3d> vecDir;
for(int i=0; i<nPipeNum; i++)
{
const AcDbObjectId &id=pNode->GetIPipe(i);
if(id != objectId())
{
OPENOBJ_BEGIN(id,AcDb::kForRead,TDbPipePrototype,pPipe);
if(pPipe != NULL)
{
if(!pPipe->IsVertical())
{
AcDbObjectId idStart=pPipe->GetNode(0);
if(idStart==idNode)
vtDir=pPipe->GetDirection();
else
vtDir=pPipe->StartPoint()-pPipe->EndPoint();
vecDir.push_back(vtDir);
}
}
OPENOBJ_END();
}
}
if (vecDir.size() > 1 && vecDir[0].isParallelTo(vecDir[1]))
{
bRet = TRUE;
}
}
}
OPENOBJ_END();
return bRet;
}
// 绘制平面立管
Acad::ErrorStatus TDbPipe::DrawVerPipe2d(XExplodeDraw &dc) const
{
XVector3D vtDirection(1,0,0);
// BOOL bVerOpened=IsVerOpened() && GetVerOpenDir(vtDirection);//扣弯
int nOpenType = 0;// 立管扣弯开口方式,0:单侧开口 1:两侧开口 zxl 2012.10.24 modify
BOOL bVerOpened=IsVerOpened() && GetVerOpenedType(vtDirection, nOpenType);//扣弯
double nRadius = m_dRadius*GetPScale();
double nRadiusIn = m_dRadiusIn*GetPScale();
//比例小于60的按大样图,立管直径按管径 20061229取消
// if(GetPScale() < 60){
// nRadius = m_dDnDiameter/2;
// if(nRadiusIn > 0.01)
// nRadiusIn = nRadius/2;
// }
if(bVerOpened) {//绘制扣弯
XPoint ptCenter(GetStartPoint().x,GetEndPoint().y);
double dAngle = ads_angle(XPoint(),vtDirection);
double dStartAngle = CT_std_angle(dAngle+PI/4);
double dEndAngle = CT_std_angle(dAngle+PI*7/4);
// zxl 2012.10.24 modify 增加一种扣弯样式
// XArc arc(ptCenter, nRadius, dStartAngle, dEndAngle);
// dc << arc;
if (nOpenType == 0)
{
XArc arc(ptCenter, nRadius, dStartAngle, dEndAngle);
dc << arc;
}
else if (nOpenType == 1)
{
double dMiddleAngle1 = CT_std_angle(dAngle+PI*3/4);
double dMiddleAngle2 = CT_std_angle(dAngle+PI*5/4);
XArc arc1(ptCenter, nRadius, dStartAngle, dMiddleAngle1);
dc << arc1;
XArc arc2(ptCenter, nRadius, dMiddleAngle2, dEndAngle);
dc << arc2;
}
}
else {
XPoint ptCenter(GetStartPoint().x,GetEndPoint().y);
XCircle cirOut(ptCenter,nRadius);
if(nRadiusIn>1.0E-3) { //绘制双圆圈 >0
XCircle cirIn(ptCenter,nRadiusIn);
dc << cirOut << cirIn;
}
else if(fabs(m_dRadiusIn+1)<=1.0E-3) { //-1时实心
XCurveSegment seg;
seg=cirOut;
XPoly2D poly,polyDisperse;
seg.AsPoly2D(poly);
poly.Disperse(polyDisperse); // cet 2017.9.8 modify 半径太小时,原函数出错
if(dc.IsPlotGeneration()) //02 04 打印预览崩溃,改绘制多个圆
{
dc.DrawHatch(polyDisperse, _T("LINE"), 1);
}
else
{
dc.DrawSolid(polyDisperse);
}
}
else if(fabs(m_dRadiusIn+3)<=1.0E-3) { //-3绘制粗圆圈
cirOut.SetRadius((m_dRadius - m_dPipeWeight * 0.25)*GetPScale()); // cet 2011.4.20 add 使圆加粗部分都在圆内
XCurveSegment seg;
seg=cirOut;
XPoly2D poly,polyDisperse;
seg.AsPoly2D(poly);
AcDbPolyline pline;
PolyConvert(poly, pline);
// cet 2011.4.20 modify 使圆加粗部分都在圆内, 粗度值为m_dPipeWeight一半
//DrawWeight(dc,GetPScale()*m_dPipeWeight,pline);
DrawWeight(dc,GetPScale()*m_dPipeWeight * 0.5,pline);
}
else {
dc << cirOut;
}
}
return Acad::eOk;
}
// 绘制平面水平管
Acad::ErrorStatus TDbPipe::DrawHorPipe2d(XExplodeDraw &dc, BOOL bIsWeight) const
{
XCurveSegment cvHide;//二维,z=0
GetHideCurve(cvHide);
DList<XCurveSegment> lstCurve;
if (IsPsBreakPipe(this->database())) {//打断
GetBrokenCurves(dc, cvHide,lstCurve);
} else {
lstCurve.Append(new XCurveSegment(cvHide));
}
int nCount = lstCurve.Length();
//动态预览 2009-8-18 sr add (wyg 修改随块颜色打印崩溃) 前1个判断是放在explode调用
if(_tcsicmp(dc.Desc(), XExplodeStream::Descriptor())!=0 && !objectId().isValid())
{
XAcGiViewDraw &dcDraw = (XAcGiViewDraw&)dc;
dcDraw.GetCommonDraw()->subEntityTraits().setColor(this->colorIndex());
}
// cet 2012.12.18 add 用户选择线性比例大小设置
double nScale = 0;
if (IsRelatePipeLineTypeToCurPScale())
{
nScale = GetPScale()/100*linetypeScale();
}
else
{
nScale = linetypeScale();
}
for (int i=0; i<nCount; i++) {
XCurveSegment &seg = *lstCurve[i];
if (bIsWeight) {
double dWeight = GetPScale()*m_dPipeWeight;
// double nScale = linetypeScale();
// cet 2012.12.18 del 用户选择是否随管线比例变化
// double nScale = GetPScale()/100*linetypeScale(); //SR 2012-6-19 支持线型比例随对象比例发生变化
DrawWeight(dc,dWeight,seg,colorIndex(), nScale);
} else {
//2005/2/25 modify sr 管线支持比例因子,由于DC不直接支持,所以通过修改dc内部参数实现
//其中,绘制是修改DC环境参数,必须先执行,炸开是直接修改新生成的实体,所以后执行
if(_tcsicmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0) {
XAcGiViewDraw &dcDraw = (XAcGiViewDraw&)dc;
// cet 2012.12.18 del 用户选择是否随管线比例变化
// dcDraw.GetCommonDraw()->subEntityTraits().setLineTypeScale(GetPScale()/100*linetypeScale());// SR 2012-6-19 支持线型比例随对象比例发生变化
dcDraw.GetCommonDraw()->subEntityTraits().setLineTypeScale(nScale);
}
dc << seg;
if(_tcsicmp(dc.Desc(), XAcGiViewDraw::Descriptor())!=0 && dc.IsFullExplode())
{ //自定义实体炸开
XExplodeStream &dcDraw = (XExplodeStream&)dc;
AcDbVoidPtrArray *pEntSet = dcDraw.GetEntitySet();
if(pEntSet != NULL && 0 != pEntSet->length())
{
AcDbEntity *pEnt = (AcDbEntity *)(pEntSet->last());
if(pEnt != NULL)
{
// cet 2012.12.18 del 用户选择是否随管线比例变化
// double nScale = GetPScale()/100*linetypeScale(); //SR 2012-6-19 支持线型比例随对象比例发生变化
pEnt->setLinetypeScale(nScale);
}
}
}
}
}
return Acad::eOk;
}
//得到管子实际长度(单位米)
ads_real TDbPipe::Length() const
{
double len = TDbPipePrototype::GetLength();
if(DocGetMeterUnitDraw())
{
XPoint ptS = StartPoint();
XPoint ptE = EndPoint();
ptS.z = 0;
ptE.z = 0;
// len = ads_distance(ptS, ptE);//2008-11-24 米单位下显示长度是错的,现改为平面投影长度
//2009.2.16 删除上面的一句,室外坐标米单位下z就是米
}
else
len = len / 1000.0;
return len;
}
//得到管子投影长度(单位米)
ads_real TDbPipe::GetPlanLength() const
{
double len(0);
XPoint ptS = StartPoint();
XPoint ptE = EndPoint();
ptS.z = 0;
ptE.z = 0;
len = ads_distance(ptS, ptE);//2008-11-24 米单位下显示长度是错的,现改为平面投影长度
if(!DocGetMeterUnitDraw())
len = len / 1000.0;
return len;
}
extern CString I2Str(double i);
//读扩展数据
extern CString ReadXdata(Entity ent, const TCHAR*szName);
extern CString ReadXdata(const AcDbEntity *pEnt, const TCHAR*szName); // cet 2014.6.4 add
//写扩展数据
BOOL WriteXdata(Entity ent, const TCHAR*szName, const TCHAR*szValue)
{
AcDbObjectId eId;
AcDbEntity *pEnt = NULL;
acdbGetObjectId(eId, ent);
if(!XSymbolTable(_T("APPID"), szName))
ads_regapp(szName);
acdbOpenObject(pEnt, eId, AcDb::kForWrite);
if(!pEnt)
return FALSE;
resbuf *pXData = ads_buildlist(1001, szName, 1000, szValue, NULL);
pEnt->setXData(pXData);
ads_relrb(pXData);
pEnt->close();
return TRUE;
}
//写扩展数据 cet 2014.6.20 add
BOOL WriteXdata(AcDbEntity *pEnt, const TCHAR*szName, const TCHAR*szValue)
{
if(!XSymbolTable(_T("APPID"), szName))
ads_regapp(szName);
if(!pEnt)
return FALSE;
resbuf *pXData = ads_buildlist(1001, szName, 1000, szValue, NULL);
pEnt->setXData(pXData);
ads_relrb(pXData);
return TRUE;
}
// 获取管线管径标注字符 zxl 2012.12.17 add
CString TDbPipe::GetPipeDnDimStr() const
{
// cet 2015.3.6 add 标注中的管径类型(标准管径 外径)
double dDnDiameter = m_dDnDiameter;
if (DimDnType() == 1) // 外径
{
dDnDiameter = OuterDn();
}
CString sText;
int nPrec = 3;
bool bTrim = true;
int nDnDimType = GetPipeDnDimType();
if (nDnDimType == 0)
{
return sText;
}
else if (nDnDimType == 1)
{
if(dDnDiameter>1.0E-3) {
CString csLable = m_sLabel.cs();
// zxl 2014.04.03 modify
//if(csLable.Find(_T("%%c")) > -1 && GetPipeThick() > 0.01)
ads_name name;
acdbGetAdsName(name, this->id());
Entity ent = name;
int nShow = _tstof(ReadXdata(ent, _T("TG_PIPELABEL_THICK_SHOW")));
// cet 2018.2.12 modify 精度有损失,外径可能有小数
// if(nShow == 1 && GetPipeThick() > 0.01)
// sText.Format(_T("%s%.0fx%.1f"), csLable,dDnDiameter, GetPipeThick());
// else
// sText.Format(_T("%s%.0f"), csLable, dDnDiameter);
if(nShow == 1 && GetPipeThick() > 0.01)
sText.Format(_T("%s%sx%s"), csLable, DoubleToString(dDnDiameter, nPrec, bTrim), DoubleToString(GetPipeThick(), nPrec, bTrim));
else
sText.Format(_T("%s%s"), csLable, DoubleToString(dDnDiameter, nPrec, bTrim));
}
}
else if (nDnDimType == 2)
{
// cet 2018.2.12 modify 精度有损失,外径可能有小数
// sText.Format(_T("%.0f"), dDnDiameter);
sText.Format(_T("%s"), DoubleToString(dDnDiameter, nPrec, bTrim));
}
return sText;
}
// 获取管线长度标注字符 zxl 2012.12.17 add
CString TDbPipe::GetPipeLenDimStr() const
{
int iDimType = GetPipeLenDimType();
if (iDimType == 0)
{
return _T("");
}
int iPre = GetPipeLenPrecision(this->database());
CString sHead,sFormat;
sHead.Format(_T("%d"),iPre);
sFormat = _T("%.") + sHead + _T("f");
double len = Length();
CString csLen;
csLen.Format(sFormat, len);
CString sPipeLen;
GetDimPipeLen(sPipeLen, iDimType, csLen);
return sPipeLen;
}
CString I2Str2(double i)
{
CString csText;
int nTmp = i * 10;
if (nTmp % 10 == 0)
{
csText.Format(_T("%.0f"), i);
}
else// 保留小数点后一位
{
csText.Format(_T("%.1f"), i);
}
return csText;
}
// 获取管线坡度标注字符 zxl 2012.12.17 add
CString TDbPipe::GetPipeGradienDimtStr() const
{
CString csTmp;
int nDimType = GetPipeGradientDimType();
if (nDimType == 0)
{
return csTmp;
}
else if(nDimType == 1) //i=0.003
{
csTmp.Format(_T("i=%s"), I2Str(m_dRadiusIn*1000));
}
else if (nDimType == 2)
{
csTmp.Format(_T("i=%s‰"), I2Str2(m_dRadiusIn*1000));
}
else if (nDimType == 3)
{
csTmp.Format(_T("%s"),I2Str(m_dRadiusIn*1000));
}
else if (nDimType == 4)
{
csTmp.Format(_T("%s‰"), I2Str2(m_dRadiusIn*1000));
}
else if(nDimType == 5) //i0.003
{
csTmp.Format(_T("i%s"), I2Str(m_dRadiusIn*1000));
}
else if (nDimType == 6)
{
csTmp.Format(_T("i%s‰"), I2Str2(m_dRadiusIn*1000));
}
return csTmp;
}
// 是否为新标注类型 zxl 2012.12.17 add
bool TDbPipe::IsNewDimType() const
{
Adesk::Int16 nType = GetPipeDnDimType();
if (nType >= 0)
{
return true;
}
return false;
}
CString TDbPipe::GetNewPipeDimStr() const
{
CString sDn, sLen, sGradient, sLabel, sNote;
sDn = GetPipeDnDimStr();
// cet 2013.2.5 add 标注标高
if (!sDn.IsEmpty() && IsDimEle())
{
double dEle = StartPoint().z;
if (!DocGetMeterUnitDraw())
{
dEle *= 0.001;
}
CString sEle;
sEle.Format(_T("(%.2f)"), dEle);
sDn += sEle;
}
sLen = GetPipeLenDimStr();
sGradient = GetPipeGradienDimtStr();
int nLabelType = GetPipeDimLableType();
if (nLabelType == 0)
{
sNote = _T(" ");
}
else if (nLabelType == 1)
{
sNote = _T("-");
}
else
{
sNote = _T("/");
}
if (GetPipeLableDrawType() != 0)
{
sNote = _T("\n");
}
sLabel = sDn;
if (!sDn.IsEmpty() && (!sLen.IsEmpty() || !sGradient.IsEmpty()))
{
sLabel += sNote;
}
sLabel += sGradient;
if (!sLen.IsEmpty() && !sGradient.IsEmpty())
{
sLabel += sNote;
sLabel += sLen;
}
else if (sGradient.IsEmpty())
{
sLabel += sLen;
}
return sLabel;
}
XString TDbPipe::GetLabelText() const
{
//添加多联机标注09.11.19 wlw
if(m_sysType == TPipeSys::kVRVMedia)
{
CString sTmp = _T("%%C");
CString sLabel = m_sLabel.cs(), sGasDn = _T(""),sLiqDn = _T(""),sDGasDn = _T("");
// change by hh 2014.6.24 冷媒管增加两种分隔符
CString sSplit = _T(",");
// int nStr = sLabel.Find(_T(","));
int nStr = sLabel.Find(sSplit);
if(0 > nStr)
{
sSplit = _T("/");
nStr = sLabel.Find(sSplit);
if(0 > nStr)
{
sSplit = _T(" ");
nStr = sLabel.Find(sSplit);
}
}
int nLength = sLabel.GetLength();
if (nStr < 0)
return sLabel;
//液管
sLiqDn = sLabel.Left(nStr);
sGasDn = sLabel.Right(nLength - nStr - 1);
// nStr = sGasDn.Find(_T(","));
nStr = sGasDn.Find(sSplit);
nLength = sGasDn.GetLength();
//气管
if (nStr < 0)
{
// sLabel.Format(_T("%s%s,%s%s"),sTmp,sLiqDn,sTmp,sGasDn);
sLabel.Format(_T("%s%s%s%s%s"),sTmp,sLiqDn,sSplit,sTmp,sGasDn);
}
//低压气管
else
{
CString sGasTmp = sGasDn;
sGasDn = sGasTmp.Left(nStr);
sDGasDn = sGasTmp.Right(nLength - nStr - 1);
// sLabel.Format(_T("%s%s,%s%s,%s%s"),sTmp,sLiqDn,sTmp,sGasDn,sTmp,sDGasDn);
sLabel.Format(_T("%s%s%s%s%s%s%s%s"),sTmp,sLiqDn,sSplit, sTmp,sGasDn,sSplit,sTmp,sDGasDn);
}
return sLabel;
}
// zxl 2012.12.13 add 新标注样式存在时,获取新标注样式
if (IsNewDimType())
{
CString sLabel = GetNewPipeDimStr();
return sLabel;
}
XString sLabel=m_sLabel;
//if(m_dDnDiameter>1.0E-3) {
// sLabel << int(m_dDnDiameter); // sr remove it 20070319 ACAD2008崩溃
//}
// cet 2015.3.6 add 标注中的管径类型(标准管径 外径)
double dDnDiameter = m_dDnDiameter;
if (DimDnType() == 1) // 外径
{
dDnDiameter = OuterDn();
}
CString csRet;
if(dDnDiameter>1.0E-3) {
CString csLable = sLabel.cs();
// zxl 2014.04.03 add
ads_name name;
acdbGetAdsName(name, this->id());
Entity ent = name;
int nShow = _tstof(ReadXdata(this, _T("TG_PIPELABEL_THICK_SHOW")));
if(nShow == 1 && GetPipeThick() > 0.01)//sr 2008-12-16 支持外径x壁厚
//if(csLable.Find(_T("%%c")) > -1 && GetPipeThick() > 0.01)//sr 2008-12-16 支持外径x壁厚
csRet.Format(_T("%s%.0fx%.1f"), sLabel,dDnDiameter, GetPipeThick()); //sr 2009-12-28 由m_dRadiusIn改GetPipeThick存储壁厚信息
else
csRet.Format(_T("%s%.0f"), sLabel, dDnDiameter);
// cet 2013.2.5 add 标注标高
if (IsDimEle())
{
double dEle = StartPoint().z;
if (!DocGetMeterUnitDraw())
{
dEle *= 0.001;
}
CString sEle;
sEle.Format(_T("(%.2f)"), dEle);
csRet += sEle;
}
}
CString csTmp, csLen;
double len = Length();
int iPre = GetPipeLenPrecision(this->database());
CString sHead,sFormat;
sHead.Format(_T("%d"),iPre);
sFormat = _T("%.") + sHead + _T("f");
csLen.Format(sFormat, len);
/* cet 2011.5.20 modify 调整标注
if(fabs(m_dSpare - 1.0) < 0.001) //i=0.003L=12.3m
csTmp.Format(_T(" i=%s L=%sm"),I2Str(m_dRadiusIn*1000), csLen);
else if(fabs(m_dSpare - 2.0) < 0.001) //-0.003-12.3m
csTmp.Format(_T("-%s-%sm"),I2Str(m_dRadiusIn*1000), csLen);
else if(fabs(m_dSpare - 3.0) < 0.001) //0.00312.3m
csTmp.Format(_T(" %s %sm"),I2Str(m_dRadiusIn*1000), csLen);
else if(fabs(m_dSpare - 4.0) < 0.001) //i=0.003
csTmp.Format(_T(" i=%s"),I2Str(m_dRadiusIn*1000));
else if(fabs(m_dSpare - 5.0) < 0.001) //-0.003
csTmp.Format(_T("-%s"),I2Str(m_dRadiusIn*1000));
else if(fabs(m_dSpare - 6.0) < 0.001) //0.003
csTmp.Format(_T(" %s"),I2Str(m_dRadiusIn*1000));
else if(fabs(m_dSpare - 7.0) < 0.001) //L=12.3m
csTmp.Format(_T(" L=%sm"),csLen);
else if(fabs(m_dSpare - 8.0) < 0.001) //-12.3m
csTmp.Format(_T("-%sm"),csLen);
else if(fabs(m_dSpare - 9.0) < 0.001) //12.3m
csTmp.Format(_T(" %sm"),csLen);
else if(fabs(m_dSpare - 10.0) < 0.001) //i0.003 L=12.3m
csTmp.Format(_T(" i%s L%sm"),I2Str(m_dRadiusIn*1000), csLen);
else if(fabs(m_dSpare - 11.0) < 0.001) // /12.3 cet 2011.4.28 add
csTmp.Format(_T("/%s"),csLen);
else if (fabs(m_dSpare - 12.0) < 0.001) // 12.3m cet 2011.5.18 add
{
csRet.Empty();
csTmp.Format(_T("%sm"),csLen);
}
else if (fabs(m_dSpare - 13.0) < 0.001) // 12.3 cet 2011.5.18 add
{
csRet.Empty();
csTmp.Format(_T("%s"),csLen);
}
*/
if (m_dSpare > 100) // 大于100时,十位百位数表示管线长度样式
{
int iDimType = static_cast<int>(m_dSpare);
CString sPipeLen;
GetDimPipeLen(sPipeLen, iDimType, csLen);
--iDimType;
iDimType /= 100;
if(iDimType == 1) //DN500 i=0.003 12.3m
{
csTmp.Format(_T(" i=%s "),I2Str(m_dRadiusIn*1000));
csTmp += sPipeLen;
}
else if(iDimType == 2) //DN500-0.003-12.3m
{
csTmp.Format(_T("-%s-"),I2Str(m_dRadiusIn*1000));
csTmp += sPipeLen;
}
else if(iDimType == 3) //DN500 0.003 12.3m
{
csTmp.Format(_T(" %s "),I2Str(m_dRadiusIn*1000));
csTmp += sPipeLen;
}
else if(iDimType == 4) //DN500 i=0.003
{
csTmp.Format(_T(" i=%s"),I2Str(m_dRadiusIn*1000));
}
else if(iDimType == 5) //DN500-0.003
{
csTmp.Format(_T("-%s"),I2Str(m_dRadiusIn*1000));
}
else if(iDimType == 6) //DN500 0.003
{
csTmp.Format(_T(" %s"),I2Str(m_dRadiusIn*1000));
}
else if(iDimType == 7) //DN500 12.3m
{
csTmp = _T(" ");
csTmp += sPipeLen;
}
else if(iDimType == 8) //DN500-12.3m
{
csTmp = _T("-");
csTmp += sPipeLen;
}
else if(iDimType == 9) //DN500 i0.003 L=12.3m
{
csTmp.Format(_T(" i%s "),I2Str(m_dRadiusIn*1000));
csTmp += sPipeLen;
}
else if(iDimType == 10) //DN500/12.3
{
csTmp = _T("/");
csTmp += sPipeLen;
}
else if (iDimType == 11) // 12.3m
{
csRet.Empty();
csTmp += sPipeLen;
}
}
else
{
if(fabs(m_dSpare - 1.0) < 0.001) //i=0.003L=12.3m
csTmp.Format(_T(" i=%s L=%sm"),I2Str(m_dRadiusIn*1000), csLen);
else if(fabs(m_dSpare - 2.0) < 0.001) //-0.003-12.3m
csTmp.Format(_T("-%s-%sm"),I2Str(m_dRadiusIn*1000), csLen);
else if(fabs(m_dSpare - 3.0) < 0.001) //0.00312.3m
csTmp.Format(_T(" %s %sm"),I2Str(m_dRadiusIn*1000), csLen);
else if(fabs(m_dSpare - 4.0) < 0.001) //i=0.003
csTmp.Format(_T(" i=%s"),I2Str(m_dRadiusIn*1000));
else if(fabs(m_dSpare - 5.0) < 0.001) //-0.003
csTmp.Format(_T("-%s"),I2Str(m_dRadiusIn*1000));
else if(fabs(m_dSpare - 6.0) < 0.001) //0.003
csTmp.Format(_T(" %s"),I2Str(m_dRadiusIn*1000));
else if(fabs(m_dSpare - 7.0) < 0.001) //L=12.3m
csTmp.Format(_T(" L=%sm"),csLen);
else if(fabs(m_dSpare - 8.0) < 0.001) //-12.3m
csTmp.Format(_T("-%sm"),csLen);
else if(fabs(m_dSpare - 9.0) < 0.001) //12.3m
csTmp.Format(_T(" %sm"),csLen);
else if(fabs(m_dSpare - 10.0) < 0.001) //i0.003 L=12.3m
csTmp.Format(_T(" i%s L%sm"),I2Str(m_dRadiusIn*1000), csLen);
else if(fabs(m_dSpare - 11.0) < 0.001) // /12.3 cet 2011.4.28 add
csTmp.Format(_T("/%s"),csLen);
else if (fabs(m_dSpare - 12.0) < 0.001) // 12.3m cet 2011.5.18 add
{
csRet.Empty();
csTmp.Format(_T("%sm"),csLen);
}
else if (fabs(m_dSpare - 13.0) < 0.001) // 12.3 cet 2011.5.18 add
{
csRet.Empty();
csTmp.Format(_T("%s"),csLen);
}
}
/* if(fabs(m_dSpare - 1.0) < 0.001) //i=0.003L=12.3m
csTmp.Format(_T(" i=%s L=%.2fm"),I2Str(m_dRadiusIn*1000), len);
else if(fabs(m_dSpare - 2.0) < 0.001) //-0.003-12.3m
csTmp.Format(_T("-%s-%.2fm"),I2Str(m_dRadiusIn*1000), len);
else if(fabs(m_dSpare - 3.0) < 0.001) //0.00312.3m
csTmp.Format(_T(" %s %.2fm"),I2Str(m_dRadiusIn*1000), len);
else if(fabs(m_dSpare - 4.0) < 0.001) //i=0.003
csTmp.Format(_T(" i=%s"),I2Str(m_dRadiusIn*1000));
else if(fabs(m_dSpare - 5.0) < 0.001) //-0.003
csTmp.Format(_T("-%s"),I2Str(m_dRadiusIn*1000));
else if(fabs(m_dSpare - 6.0) < 0.001) //0.003
csTmp.Format(_T(" %s"),I2Str(m_dRadiusIn*1000));
else if(fabs(m_dSpare - 7.0) < 0.001) //L=12.3m
csTmp.Format(_T(" L=%.2fm"),len);
else if(fabs(m_dSpare - 8.0) < 0.001) //-12.3m
csTmp.Format(_T("-%.2fm"),len);
else if(fabs(m_dSpare - 9.0) < 0.001) //12.3m
csTmp.Format(_T(" %.2fm"),len);
else if(fabs(m_dSpare - 10.0) < 0.001) //i0.003 L=12.3m
csTmp.Format(_T(" i%s L%.2fm"),I2Str(m_dRadiusIn*1000), len);*/
csRet+=csTmp;
sLabel = (const TCHAR*)csRet;
return sLabel;
}
//double TDbPipe::GetMinLabelTextLen() const
//{
// double nVal=0.0;
// TDbText text;
// text.setPropertiesFrom(this);
// text.setLayer(m_idLabelLayer);
// text.SetStyleId(m_idTextStyle);
// text.SetText(GetLabelText());
// text.SetRotation(0);
// text.SetLocation(XPoint(m_ptLabel.x,m_ptLabel.y,0));
// text.SetHeight(m_dTextHeight);
// text.SetAlignment(XExplodeDraw::kMiddleCenter);
// XPoint ptExt=text.GetExtents();
// nVal=max(nVal, ptExt.x);
// return nVal;
Acad::ErrorStatus TDbPipe::DrawLabelText(XExplodeDraw &dc) const
{
XPoint ptOnThis;
if(ProjectToMe(m_ptLabel,ptOnThis)) {
double dRotation=0;
// cet 2011.8.29 modify 在ucs下考虑角度
// if(!IsVertical()) {
// if(Is(CURVE_LINE))
// dRotation = Direction(ptOnThis);
// else if(Is(CURVE_ARC)){
// XPoint ptCenter;
// GetArc().Center(ptCenter);
// dRotation = ads_angle(ptCenter, m_ptLabel) + PI/2;
// }
// dRotation = CT_std_angle(dRotation);
// if(fabs(dRotation) < 1e-2)
// dRotation = 0;
// if(fabs(dRotation - PI/2) < 1e-2)
// dRotation = PI/2;
// if(fabs(dRotation - PI/2*3) < 1e-2)
// dRotation = PI/2*3;
//
// if((dRotation>PI/2 && dRotation<=PI*3/2)) {
// dRotation = CT_std_angle(dRotation+PI);
// }
// }
if(!IsVertical()) {
if(Is(CURVE_LINE))
{
dRotation = Direction(ptOnThis);
dRotation = Wcs2Ucs(dRotation);
}
else if(Is(CURVE_ARC)){
XPoint ptCenter;
GetArc().Center(ptCenter);
dRotation = ads_angle(Wcs2Ucs(ptCenter), Wcs2Ucs(m_ptLabel)) + PI/2;
}
dRotation = CT_std_angle(dRotation);
if(fabs(dRotation) < 1e-2)
dRotation = 0;
if(fabs(dRotation - PI/2) < 1e-2)
dRotation = PI/2;
if(fabs(dRotation - PI/2*3) < 1e-2)
dRotation = PI/2*3;
if((dRotation>PI/2 + 1e-2 && dRotation<=PI*3/2 + 1e-2)) { // cet 2017.3.8 modify 考虑误差影响
dRotation = CT_std_angle(dRotation+PI);
}
dRotation = Ucs2Wcs(dRotation);
}
AcDbObjectId idLayerOld=dc.GetLayerId();
// if(m_idLabelLayer.isValid()){
// dc.SetLayer(m_idLabelLayer);
// }
dc.SetLayer(_T("0")); // 文字图层设置失败时,默认0层
OPENOBJ_BEGIN(m_idLabelLayer, AcDb::kForRead, AcDbLayerTableRecord, pRec);
if(pRec){
dc.SetLayer(m_idLabelLayer);
}
OPENOBJ_END();
// zxl 2012.12.13 modify
// TDbText text;
//
// text.setPropertiesFrom(this);
// text.setLayer(m_idLabelLayer);
// AcCmColor color;
// color.setColorIndex(256);
// text.setColor(color);
// text.SetStyleId(m_idTextStyle);
// text.SetText(GetLabelText());
// text.SetRotation(dRotation);
// text.SetLocation(XPoint(m_ptLabel.x,m_ptLabel.y,0));
// text.SetHeight(m_dTextHeight);
// text.SetAlignment(XExplodeDraw::kMiddleCenter);
//
// TPushProperty vProp(&text, dc);
// if(dc.IsFullExplode())
// text.ExplodeOrDraw2d(dc);
// else
// dc.DrawEntity(text);
//
// dc.SetLayer(idLayerOld);
// cet 2016.4.11 add 文字样式无效时,设置默认样式
if (!m_idTextStyle.isValid())
{
const_cast<AcDbHardPointerId&>(m_idTextStyle) = InitTextStyle(_T("Standard"));
}
if (GetPipeLableDrawType() == 0 || !IsNewDimType())// 旧版标注形式或横排
{
TDbText text;
text.setPropertiesFrom(this);
text.setLayer(dc.GetLayerId()); // 默认图层
text.setLayer(m_idLabelLayer);
AcCmColor color;
// cet 2018.2.1 modify 可修改文字颜色
// color.setColorIndex(256);
color.setColorIndex(GetTextColor());
text.setColor(color);
text.SetStyleId(m_idTextStyle);
text.SetText(GetLabelText());
text.SetRotation(dRotation);
text.SetLocation(XPoint(m_ptLabel.x,m_ptLabel.y,0));
text.SetHeight(m_dTextHeight);
text.SetAlignment(XExplodeDraw::kMiddleCenter);
TPushProperty vProp(&text, dc);
if(dc.IsFullExplode())
text.ExplodeOrDraw2d(dc);
else
dc.DrawEntity(text);
}
else// 标注形式为竖排
{
// 竖排时获取每行标注字符
CString sLabel = GetLabelText().cs();
std::vector<CString> vecText;
while (!sLabel.IsEmpty())
{
int nIndex = sLabel.Find(_T("\n"));
CString sText;
if (nIndex > 0)
{
sText = sLabel.Left(nIndex);
sLabel = sLabel.Right(sLabel.GetLength() - nIndex - 1);
}
else
{
sText = sLabel;
vecText.push_back(sText);
break;
}
vecText.push_back(sText);
}
// 获取 标注点到管线的向量
AcGePoint3d ptStart = GetStartPoint(), ptEnd = GetEndPoint();
ptStart.z = 0;
ptEnd.z = 0;
WCS2UCS(ptStart);
WCS2UCS(ptEnd);
AcDbLine line(ptStart, ptEnd);
AcGePoint3d ptLabel(m_ptLabel.x,m_ptLabel.y,0), ptOnLine;
WCS2UCS(ptLabel);
Acad::ErrorStatus es = line.getClosestPointTo(ptLabel, ptOnLine, Adesk::kTrue);
AcGeVector3d vtDir = ptLabel - ptOnLine;
vtDir.normalize();
// 标注点和管线中点重合时
if (ptLabel.distanceTo(ptOnLine) < 0.001)
{
vtDir = ptStart - ptEnd;
vtDir.rotateBy(-PI / 2, AcGeVector3d::kZAxis);
vtDir.normalize();
}
// cet 2018.6.21 del 根据角度调整向量方向由于误差容易导致错误
// // 标注水平向量
// AcGeVector3d vtLeft = vtDir;
// double dAngle = vtLeft.angleTo(AcGeVector3d::kXAxis, AcGeVector3d::kZAxis);
// // cet 2017.3.8 add 360转化为0度
// if (abs(dAngle - PI * 2) < 0.001)
// {
// dAngle = 0.0;
// }
// if (dAngle > PI - 0.001) // cet 2016.12.13 modify 浮点型数据表示大等于时,有误差
// {
// vtLeft.rotateBy(PI / 2, AcGeVector3d::kZAxis);
// }
// else
// {
// vtLeft.rotateBy(-PI / 2, AcGeVector3d::kZAxis);
// }
// vtLeft.normalize();
// 逐行标注
std::vector<CString>::reverse_iterator itRev;
int i = 0;
for (itRev = vecText.rbegin(); itRev != vecText.rend(); itRev++)
{
TDbText text;
text.setPropertiesFrom(this);
text.setLayer(dc.GetLayerId()); // 默认图层
text.setLayer(m_idLabelLayer);
AcCmColor color;
// cet 2018.2.1 modify 可修改文字颜色
// color.setColorIndex(256);
color.setColorIndex(GetTextColor());
text.setColor(color);
text.SetStyleId(m_idTextStyle);
text.SetText(*itRev);
text.SetRotation(dRotation);
text.SetHeight(m_dTextHeight);
double dLen = 0.0;
if (i == 0)
{
UCS2WCS(ptLabel);
text.SetLocation(ptLabel);
WCS2UCS(ptLabel);
text.SetAlignment(XExplodeDraw::kMiddleCenter);
text.SetRotation(0.0);
XPoint ptMin, ptMax;
text.GetExtents2d(ptMin, ptMax);
dLen = fabs(ptMax.x - ptMin.x);
// cet 2018.6.21 modify 将标注点移到左侧
// ptLabel += vtLeft * dLen / 2;
AcGeVector3d vtTemp = AcGeVector3d::kXAxis;
vtTemp.rotateBy(Wcs2Ucs(dRotation + PI), AcGeVector3d::kZAxis);
ptLabel += vtTemp * dLen * 0.5;
// cet 2016.9.26 add 批量转旧版(T3)时,外包框获取失败, 并排文字没有对齐
if (dLen < 0.001)
{
text.SetAlignment(XExplodeDraw::kMiddleLeft);
}
}
else
{
ptLabel += (vtDir * m_dTextHeight * GetPScale() * 4 / 3);
UCS2WCS(ptLabel);
text.SetLocation(ptLabel);
WCS2UCS(ptLabel);
text.SetAlignment(XExplodeDraw::kMiddleLeft);
}
text.SetRotation(dRotation);
TPushProperty vProp(&text, dc);
if(dc.IsFullExplode())
text.ExplodeOrDraw2d(dc);
else
dc.DrawEntity(text);
i++;
}
}
dc.SetLayer(idLayerOld);
}
return Acad::eOk;
}
//管线加粗后,2段管线连接处,ACAD处理不理想,上华来修补;沈睿2004/8/26
//得到一个管线的下一段管线,必须是Fitting连接的。
AcDbObjectId GetNextPipe(AcDbObjectId idPipe, AcDbObjectId idNode)
{
AcDbObjectId idRet = NULL;
OPENOBJ_BEGIN(idNode, AcDb::kForRead, TDbPipeFitting, pFitting);
if(pFitting){
int num = pFitting->GetInterfaceNum();
if(num != 2)
return idRet;
TPipeInterface face1, face2;
pFitting->GetInterface(0, face1);
pFitting->GetInterface(1, face2);
if(face1.m_idPipe == idPipe)
idRet = face2.m_idPipe;
else
idRet = face1.m_idPipe;
}
OPENOBJ_END();
OPENOBJ_BEGIN(idRet, AcDb::kForRead, TDbPipe, pPipe);
if(pPipe && !pPipe->IsVertical()){
return idRet;//必须是横管
}
OPENOBJ_END();
return NULL;
}
void ChamferPipe(AcDbObjectId idPipe, AcDbObjectId idPipeNext, XPoint &ptInt1, XPoint &ptInt2, XPoint &ptInt3)
{
if(!idPipeNext)
return;
double nWeight(0), nWeightNext(0);
XPoint pt1, pt2, ptNext1, ptNext2;
OPENOBJ_BEGIN(idPipe, AcDb::kForRead, TDbPipe, pPipe);
if(pPipe){
nWeight = pPipe->GetPipeWeight() * pPipe->GetPScale();
pt1 = pPipe->StartPoint();
pt2 = pPipe->EndPoint();
if(fabs(pPipe->GetBulge()) > 0.001)
return;
}
OPENOBJ_END();
OPENOBJ_BEGIN(idPipeNext, AcDb::kForRead, TDbPipe, pPipe);
if(pPipe){
nWeightNext = pPipe->GetPipeWeight() * pPipe->GetPScale();
ptNext1 = pPipe->StartPoint();
ptNext2 = pPipe->EndPoint();
if(fabs(pPipe->GetBulge()) > 0.001)
return;
}
OPENOBJ_END();
XLine l1(pt1, pt2, 1);
XLine l2 = l1.Offset(nWeight/2);
XLine l3 = l1.Offset(-nWeight/2);
l2.SetLineFlag(1);
l3.SetLineFlag(1);
XLine lNext1(ptNext1, ptNext2, 1);
XLine lNext2 = lNext1.Offset(nWeightNext/2);
XLine lNext3 = lNext1.Offset(-nWeightNext/2);
lNext2.SetLineFlag(1);
lNext3.SetLineFlag(1);
l1.Intersection(&lNext1, ptInt1);
int ret1 = l2.Intersection(&lNext2, ptInt2);
int ret2 = l3.Intersection(&lNext3, ptInt3);
if(ret1 == 1 && ret2 == 0){
l3.SetLineFlag(0);
lNext3.SetLineFlag(0);
ret2 = l3.Intersection(&lNext3, ptInt3);
if(ret2 == 1){
double n1 = l3.StartPoint().Distance(ptInt3);
double n2 = l3.EndPoint().Distance(ptInt3);
if(n1 > n2)
ptInt2 = l3.EndPoint();
else
ptInt2 = l3.StartPoint();
}
}
if(ret2 == 1 && ret1 == 0){
l2.SetLineFlag(0);
lNext2.SetLineFlag(0);
ret1 = l2.Intersection(&lNext2, ptInt3);
if(ret1 == 1){
double n1 = l2.StartPoint().Distance(ptInt3);
double n2 = l2.EndPoint().Distance(ptInt3);
if(n1 > n2)
ptInt2 = l2.EndPoint();
else
ptInt2 = l2.StartPoint();
}
}
//2管线不是连续绘制,共同一个起点
if(ret1 == 0 && ret2 == 0){
ret1 = l2.Intersection(&lNext3, ptInt2);
ret2 = l3.Intersection(&lNext2, ptInt3);
if(ret1 == 1 && ret2 == 0){
l3.SetLineFlag(0);
lNext2.SetLineFlag(0);
ret2 = l3.Intersection(&lNext2, ptInt3);
if(ret2 == 1){
double n1 = l3.StartPoint().Distance(ptInt3);
double n2 = l3.EndPoint().Distance(ptInt3);
if(n1 > n2)
ptInt2 = l3.EndPoint();
else
ptInt2 = l3.StartPoint();
}
}
if(ret2 == 1 && ret1 == 0){
l2.SetLineFlag(0);
lNext3.SetLineFlag(0);
ret1 = l2.Intersection(&lNext3, ptInt3);
if(ret1 == 1){
double n1 = l2.StartPoint().Distance(ptInt3);
double n2 = l2.EndPoint().Distance(ptInt3);
if(n1 > n2)
ptInt2 = l2.EndPoint();
else
ptInt2 = l2.StartPoint();
}
}
}
}
AOLAPI double g_nAcadVer;
Acad::ErrorStatus
TDbPipe::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
// cet 2016.10.17 add 图层关闭时,实体不显示,不进行绘制(打印时,也不会绘制)
AcDbLayerTableRecordPointer player(this->layerId(), AcDb::kForRead);
if (player.openStatus() == Acad::eOk && player->isOff())
{
return Acad::eOk;
}
Acad::ErrorStatus es=Acad::eOk;
if(!IsVisibleEntity(this)) return es;
//以下部分判断本管线所在的dwg是否是粗线模式
BOOL bIsWeight = g_bPipeWeight;
if(dc.IsFullExplode()){
AcDbDatabase *pDb = database();
if(pDb){
AcDbDictionary* pRootDict=NULL;
es=pDb->getNamedObjectsDictionary(pRootDict,AcDb::kForRead);
assert(es==Acad::eOk);
AcDbObject* pObj;
es=pRootDict->getAt(g_sDbPsConfig,pObj,AcDb::kForRead);
if (es==Acad::eOk) {
bIsWeight = ((TDbPsConfig *)pObj)->IsLineWeight();
pObj->close();
}
pRootDict->close();
}
}
// sr add 2004/11/2
XExplodeDraw &viewDraw = (XExplodeDraw &)dc;
// 显示管线
if (IsVertical())
es = DrawVerPipe2d(dc);
else {
es = DrawHorPipe2d(viewDraw, bIsWeight);
if(bIsWeight && dc.IsFullExplode()){
//2根加粗的管线中间会留有缝隙,这里弥补一下。不支持弧管
AcDbObjectId idPipe1 = GetNextPipe(objectId(), GetNode(0));
AcDbObjectId idPipe2 = GetNextPipe(objectId(), GetNode(1));
if(idPipe1){
XPoint ptInt1, ptInt2, ptInt3;
ChamferPipe(objectId(), idPipe1, ptInt1, ptInt2, ptInt3);
if(!!ptInt1 && !!ptInt2 && !!ptInt3){
XPoly2D poly;
poly.AppendNode(ptInt1);
poly.AppendNode(ptInt2);
poly.AppendNode(ptInt3);
viewDraw.DrawSolid(poly);
}
}
if(idPipe2){
XPoint ptInt1, ptInt2, ptInt3;
ChamferPipe(objectId(), idPipe2, ptInt1, ptInt2, ptInt3);
if(!!ptInt1 && !!ptInt2 && !!ptInt3){
XPoly2D poly2;
poly2.AppendNode(ptInt1);
poly2.AppendNode(ptInt2);
poly2.AppendNode(ptInt3);
viewDraw.DrawSolid(poly2);
}
}
}
}
//// 输出流向
if(es==Acad::eOk && g_bSPipeFDir)
es = DrawFlowDirection(viewDraw);
// 在管线中点位置显示管线的属性
if(es==Acad::eOk && IsShowPropertyText() && IsModel())
es = DrawPropertyText(viewDraw);
if(IsDrawLabel()) // 显示管线标注
DrawLabelText(viewDraw);
return es;
}
extern Acad::ErrorStatus DrawPolyMesh(XPoint ptS, XPoint ptE, double nRadius, XExplodeDraw &dc);
Acad::ErrorStatus
TDbPipe::ExplodeOrDraw3d(XExplodeDraw &dc) const
{
// cet 2018.2.2 modify 通过文件查询外径,对实体绘制效率影响较大
// double dPipeDiameter = m_dDnDiameter;
// dPipeDiameter = GetPipeOutDByDn(m_nMaterial, dPipeDiameter);
double dPipeDiameter = OuterDn();
// double dArea(1);
if(DocGetMeterUnitDraw())
{
dPipeDiameter = dPipeDiameter / 1000.0;
// dArea = 0.0001;
}
//2007-12-7 sr 删除下面2行 7.5发行版,2005 2006下打开三维,崩溃
// if(g_nAcadVer>16.01 && g_nAcadVer<17) //在ACAD2006下,如果开1个三维视口,再打开一个新视口,如果设置其为平面,就崩溃(管线粗线)建筑楼梯也如此
// dc.SetSelectionMarker(1);
// if(!dc.IsFullExplode()){ 2008-7-21 SR 删除一下几行代码, R16 17下 炸开管线,崩溃
// //如果是动态预演,则简单绘制
// AcGiCommonDraw *dcCommon=((XAcGiViewDraw &)dc).GetCommonDraw();
// if(dcCommon->isDragging()) {
//XCurveSegment segTmp = (*this);
// dc << segTmp;
// return Acad::eOk;
// }
// }
// sr add 2005-6-10
// XPoly2D polyShape(1);
// XCircle cir(StartPoint(), dPipeDiameter/2);
// XCurveSegment seg2;
// seg2 = cir;
// seg2.AsPoly2D(polyShape);
XCurveSegment cv=GetCurve();
// AcGeVector3d v3(0,0,1);
// if(GetModelType() == TPipeSys::kSystem || GetModelType() == TPipeSys::kPrinciple || cv.Is(CURVE_ARC)) {
// XCurveSegment segTmp = (*this);
// dc << segTmp;
// return Acad::eOk;
// }
//绘制3维管道的时候,两边都缩50,目的是留给节点位置
XPoint pt1(GetStartPoint()), pt2(GetEndPoint()), ptTmp(GetStartPoint());
ptTmp.x += dPipeDiameter;
XVector3D vtDir(EndPoint() - StartPoint());
XVector3D vtDir2(ptTmp - StartPoint());
vtDir.Normalize();
vtDir.Scale(dPipeDiameter);
//如果管端接设备,则不用缩
AcDbObjectId nodeId1(NULL), nodeId2(NULL);
nodeId1 = GetNode(0);
nodeId2 = GetNode(1);
OPENOBJ_BEGIN(nodeId1, AcDb::kForRead, TDbPipeFitting, pNode);
if(pNode){
if(pNode->GetLocation() == StartPoint())
pt1 += vtDir;
else
pt2 -= vtDir;
}
OPENOBJ_END();
OPENOBJ_BEGIN(nodeId2, AcDb::kForRead, TDbPipeFitting, pNode);
if(pNode){
if(pNode->GetLocation() == StartPoint())
pt1 += vtDir;
else
pt2 -= vtDir;
}
OPENOBJ_END();
// cet 2011.5.24 modify
// DrawPolyMesh(pt1, pt2, dPipeDiameter/2.0, dc);
if (cv.Is(CURVE_ARC))
{
Draw3dArcPipe(dc);
}
else
{
DrawPolyMesh(pt1, pt2, dPipeDiameter/2.0, dc);
}
return Acad::eOk;
//sr 2009-3-3 删除以下行,改用DrawPolyMesh
/*
////////////////////////////////////////////////////
XPoly2D polyBase;
if(IsVertical()){//立管 TDbCurveMesh本身有bug,无法绘制立管, 所以先把端点横过来,绘制横管,然后cvMesh.SetNormal(v3)设置法向;
AcGeVector3d v1 = vtDir.AsAcGeVector3d();
AcGeVector3d v2 = vtDir2.AsAcGeVector3d();
v3 = v1.crossProduct(v2);
AcGeMatrix3d mat;
mat.setToWorldToPlane(v3);
v3.normalize();
pt1.TransformBy(mat);
pt2.TransformBy(mat);
polyBase.AppendNode(pt1);
polyBase.AppendNode(pt2);
}
else if(Is(CURVE_LINE)){
polyBase.AppendNode(pt1);
polyBase.AppendNode(pt2);
}
else
AsPoly2D(polyBase);//横管用路径曲面
if(polyBase.IsSelfIntersect()||polyShape.IsSelfIntersect())
return Acad::eOk;
if(polyShape.Area() < dArea)
return Acad::eOk;
TDbCurveMesh2 cvMesh;
cvMesh.SetPathPoly(polyBase, cvMesh.GetNormal());
cvMesh.SetShapePoly(polyShape);
cvMesh.SetShapeBase(StartPoint());
if(cvMesh.IsValid())
{
if(dc.IsFullExplode())
cvMesh.ExplodeOrDraw3d(dc);
else
dc.DrawEntity(cvMesh);
}
return Acad::eOk;
*/
}
Acad::ErrorStatus TDbPipe::subOpen(AcDb::OpenMode mode)
{
Acad::ErrorStatus es=TDbPipePrototype::subOpen(mode);
if(es==Acad::eOk && g_nCmdReactor!=CMD_UPDATE) {
if(mode==AcDb::kForWrite && database()==acdbCurDwg()) {
m_dOldRadius=m_dRadius;
}
}
return es;
}
void TDbPipe::ApplyDnDiameterChangeToLabel()
{
// cet 2014.6.3 modify 细化标注更新情况
// for(int i=0;i<m_lstAttachment.Length(); i++) {
// OPENOBJ_BEGIN(*m_lstAttachment[i],AcDb::kForRead,TDbPipeLabel,pLabel);
// if(pLabel!=NULL) {
// double dDia=Length();
// if(GetPScale() > 10)
// dDia = dDia / 1000;
// if(pLabel->upgradeOpen()==Acad::eOk) {
// pLabel->assertWriteEnabled();
// pLabel->SetPipeType(TDbPipeLabel::kCommon);
// pLabel->SetLeftText(m_sLabel);
// pLabel->SetPipeDiameter(m_dDnDiameter);
// pLabel->downgradeOpen();
// }
// }
// OPENOBJ_END();
// }
if (GetCurDocData() != NULL) // cet 2015.7.13 modify 需判断返回值是否有效否则在修复图纸时会产生错误
{
XString &sCmd = GetCurDocData()->m_sCurCommand;
if(0 == _tcsicmp(sCmd, _T("erase"))
|| 0 == _tcsicmp(sCmd,_T("undo"))
|| 0 == _tcsicmp(sCmd,_T("u")))
{
return; // add by hh 2014.7.9 删除和撤销时,不进行处理
}
}
CString sDimText = GetLinkedPipeDnDimText();
CString sPipeText = GetLinkedPipeText();
int nCount = m_lstAttachment.Length();
for (int i = 0; i < nCount; ++i)
{
// TDbPipeLabel
OPENOBJ_BEGIN(*m_lstAttachment[i], AcDb::kForWrite, TDbPipeLabel, pPipeLabel);
if (pPipeLabel != NULL && IsLinkedPipeDnDimText()) // 管线存在关联管径标注文字
{
pPipeLabel->SetPipeType(TDbPipeLabel::kDuct);
pPipeLabel->SetLeftText(sDimText);
continue;
}
OPENOBJ_END();
// TDbPipeText
OPENOBJ_BEGIN(*m_lstAttachment[i], AcDb::kForWrite, TDbPipeText, pPipeText);
if (pPipeText != NULL)
{
int nDimTextType = pPipeText->DimTextType();
// add by hh 2014.6.24 冷媒管单独处理
if(TPipeSys::kVRVMedia == GetSysType())
{
if(1 != nDimTextType && -2 != nDimTextType)
{
pPipeText->SetText(GetLabelText());
}
continue;
}
// add end
if (nDimTextType == 0 && IsLinkedPipeDnDimText()) // 管径标注文字
{
pPipeText->SetText(sDimText);
}
else if (nDimTextType == 1 && IsLinkedPipeText()) // 管线文字
{
pPipeText->SetText(sPipeText);
}
else if (nDimTextType == -1) // 继续分析文字类型
{
CString sTemp, sText;
sText = pPipeText->GetText();
int nIndex = -1;
int nCount = sText.GetLength();
for (int k = 0; k < nCount; ++k)
{
TCHAR ch = sText.GetAt(k);
// 存在数字就当成管径标注
if (ch >= _T('0') && ch <= _T('9'))
{
nIndex = 0;
break;
}
}
if ( nIndex != -1 && IsLinkedPipeDnDimText()) // 管径标注文字
{
pPipeText->SetText(sDimText);
pPipeText->DimTextType(0);
}
else if (nIndex == -1 && IsLinkedPipeText())// 管线文字
{
pPipeText->SetText(sPipeText);
pPipeText->DimTextType(1);
}
}
// add by hh 2014.6.24 DimTextType等于-2时,不进行更新
else if (nDimTextType == -2)
{
;
}
continue;
}
OPENOBJ_END();
}
}
XExtent TDbPipe::GetExtent() const
{
if(IsVertical()) {
return XExtent(m_dRadius*2,m_dRadius*2);
}
else
return TDbPipePrototype::GetExtent();
}
XExtent TDbPipe::GetOldExtent() const
{
if(IsVertical())
return XExtent(m_dOldRadius,m_dOldRadius);
else
return TDbPipePrototype::GetOldExtent();
}
int TDbPipe::GetExtend(XPoint &low, XPoint &up) const
{
int nRet=RTNORM;
if(IsVertical()) {
//if(objectId().isValid()){
// AcDbExtents extents;// 可能是扣弯
// if(getGeomExtents(extents)==Acad::eOk) {
// low=extents.minPoint();
// up=extents.maxPoint();
// } else {
// nRet=RTERROR ;
// }
//} else {
low=up=StartPoint();
XExtent ex=GetExtent();
ex /= 2;
low -= ex;
up += ex;
//}
} else {
nRet=TDbPipePrototype::GetExtend(low,up);
}
return nRet;
}
double TDbPipe::GetBreakWidth() const
{
double dWidth=2;
TPSConfig config(AcDb::kForRead, this->database());
if(!!config) {
dWidth = config.m_pConfig->GetBreakWidth();
if(config.m_pConfig->IsLineWeight()) {
dWidth += m_dPipeWeight;
}
}
dWidth *= GetPScale();
return dWidth;
}
//取动态属性显示数据
void TDbPipe::GetTips(DList<TObjInfoUnit> &lstInfo) const
{
if(IsVertical())
lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("立管")));
else
lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("管段")));
TDbPipePrototype::GetTips(lstInfo);
// cet 2015.8.24 add 更新基类中设置的系统类型
if (HavePipeSystemName())
{
CString sSysName = GetPipeSystemName();
int nLen = lstInfo.Length();
for (int i = 0; i < nLen; ++i)
{
TObjInfoUnit *pInfo = lstInfo[i];
if (pInfo->m_sLabel == _T("系统类型"))
{
pInfo->m_sValue = sSysName;
break;
}
}
}
lstInfo.Append(new TObjInfoUnit(_T("管径"), Dist2Str(m_dDnDiameter)));
if(!IsVertical())
lstInfo.Append(new TObjInfoUnit(_T("坡度"), XString(_T("%0.3f"),m_dRadiusIn)));
XStringList lstMaterial;
if(GetPipeMaterial(lstMaterial) && m_nMaterial>=0
&& m_nMaterial<lstMaterial.Length()) {
lstInfo.Append(new TObjInfoUnit(_T("材料"),lstMaterial[m_nMaterial]));
}
if(GetModelType() == TPipeSys::kSystem && _tcsicmp(GetSysLabel(), _T("")) != 0){
lstInfo.Append(new TObjInfoUnit(_T("楼层"), GetSysLabel()));
lstInfo.Append(new TObjInfoUnit(_T("立管编号"), XString(_T("%.0f"), GetRadiusIn())));
}
}
bool TDbPipe::IsClipMe(const TEntityBase* pEnt)const
{
// if(TEntityBase::IsClipMe(pEnt))
// return true;
// if(pEnt == NULL || pEnt->GetMe()->isKindOf(TDbEquipment::desc()))
// return true;
// if(IsModel())// 2009.7.21 sr 关闭裁剪,速度很慢
// change by hh 2011-09-29 支持水管与风管之间的裁剪 仅限暖通
/* return false;
if(pEnt == NULL)
return true;
if(pEnt != NULL){
AcDbObjectId id = pEnt->GetMe()->objectId();
AcDbObjectId id0 = GetNode(0);
AcDbObjectId id1 = GetNode(1);
if(id == id0 || id == id1)
return false;//如果裁剪对象是管线的节点,就不裁剪了
if(pEnt->GetMe()->isKindOf(TDbEquipment::desc()))
return true;
}*/
if(15 != g_nProductId)
return false;
// 判断是否处理遮挡
TDbConfig* pConfig = GetDwgGlobal(AcDb::kForRead);
if(NULL == pConfig)
return false;
BOOL bBreak = FALSE;
pConfig->GetFields().GFD(_T("THvac_PipeDuctBreak"), bBreak);
pConfig->close();
if(!bBreak)
return false;
if(NULL == pEnt)
return true;
if(NULL != pEnt)
{
// 无法访问到暖通风管系统相关的类 使用类名进行运行时判断
CString sClassName = pEnt->GetMe()->isA()->name();
if(0 == sClassName.Compare(_T("TDbHvacDuct"))
|| 0 == sClassName.Compare(_T("TDbHvacFitting"))
|| 0 == sClassName.Compare(_T("TDbHvacEquipment")))
{
// 获得风管的外包围框
TADSGePoint3d ptLow, ptUp, ptMid;
pEnt->GetExtents(ptLow, ptUp);
Midpoint(ptLow, ptUp, ptMid);
// 立管
if(IsVertical())
{
double dY = max(StartPoint().z, EndPoint().z);
if(dY < ptMid.z)
return true;
}
else
{
TADSGePoint3d ptPipe;
Midpoint(StartPoint(), EndPoint(), ptPipe);
if(ptPipe.z < ptMid.z)
return true;
}
}
}
return false;
}
bool TDbPipe::IsMeClip()const
{
if(15 != g_nProductId)
return false;
return true;
}
//////////////////////////////////////////////////////////////////////////
void InitDbPipe(BOOL bTrue)
{
if(bTrue) {
TDbPipe::rxInit();
TDbPipe::InitMatchProtocol(TRUE);
} else {
TDbPipe::InitMatchProtocol(FALSE);
deleteAcRxClass(TDbPipe::desc());
}
}
bool TDbPipe::GetSection(const AcDbFace &face, const AcGeVector3d& vtPlaneSecDir,
std::vector<TObjSectionRecord> &sectionRecords,
AcDbVoidPtrArray& arFillPtrs) const
{
bool bRet = false;
TGGeSectionPlane section_pln(face, vtPlaneSecDir);
AcGePoint3d ptS = StartPoint(), ptE = EndPoint();
AcGeLineSeg3d line(ptS, ptE);
// 求线与投影面的最短距离
AcGePlane plane = section_pln.AsAcGePlane();
AcGePoint3d pt1 = ptS.project(plane, vtPlaneSecDir);
AcGePoint3d pt2 = ptE.project(plane, vtPlaneSecDir);
double dDist1 = ptS.distanceTo(pt1), dDist2 = ptE.distanceTo(pt2);
double dElev = dDist1 < dDist2 ? dDist1 : dDist2;
dElev *= -1;
AcGeLineSeg3d seg;
AcGePoint3d pt;
short iRet = SectionUtility::Projection_line2plane(section_pln, line, seg, pt);
if (iRet == 1) // 垂直
{
TGGePoly3D poly2d;
int nCount = 40; //平分一个圆的份数
double angle = PI * ( 2.0 / nCount);
AcGeVector3d vtDir, vtAxis = ptE - ptS;
vtDir = vtAxis;
vtDir = vtDir.rotateBy(PI * 0.5, AcGeVector3d::kZAxis);
vtDir.normalize();
vtDir *= m_dRadius*GetPScale(); // cet 2011.8.18 modify 圆半径修改为立管默认绘制半径
for (int i = 0; i < nCount; ++i)
{
poly2d.AppendNode(pt + vtDir.rotateBy(angle, vtAxis), angle);
}
poly2d.AppendNode(*poly2d.Head());
poly2d.SetFlag(0x01);
TObjSectionRecord record(objectId(), layerId(), TObjSectionRecord::eTCH_PIPE, dElev, poly2d);
sectionRecords.push_back(record);
bRet = true;
}
else if (iRet == 0) // 不垂直
{
BOOL bV = IsVertical();
if (m_lstAttachment.Length() == 0) // 无附件
{
TGGePoly2D poly2d;
poly2d.AppendNode(asDblArray(seg.startPoint()));
poly2d.AppendNode(asDblArray(seg.endPoint()));
TObjSectionRecord record(objectId(), layerId(), TObjSectionRecord::eTCH_PIPE, dElev, poly2d);
sectionRecords.push_back(record);
}
else // 有附件打断管
{
// 获得管与附件的交点
AcGeVector3d vt = ptS - ptE;
std::vector<AcGePoint3d> vecPt;
for (int i = 0; i < m_lstAttachment.Length(); i++)
{
vt.normalize();
TDbPipeValve *pValve = NULL;
AcGePoint3d ptLoc;
double dWidth = 0.0;
acdbOpenObject(pValve, m_lstAttachment[i], AcDb::kForRead);
if (pValve != NULL) // 附件
{
ptLoc = pValve->GetLocation();
dWidth = pValve->GetWidth() * pValve->GetScale();
pValve->close();
}
if (ptLoc != AcGePoint3d::kOrigin)
{
double dVal = sin(vt.angleTo(vtPlaneSecDir));
vt *= dWidth / fabs(dVal) / 2;
vecPt.push_back(ptLoc + vt);
vecPt.push_back(ptLoc - vt);
}
}
// 求各点到管起始点的距离, 按从小到大排序
std::map<double, AcGePoint3d> mapPt;
std::vector<AcGePoint3d>::iterator it;
for (it = vecPt.begin(); it != vecPt.end(); it++)
{
mapPt.insert(std::make_pair(ptS.distanceTo(*it), *it));
}
mapPt.insert(std::make_pair(ptS.distanceTo(ptE), ptE));
mapPt.insert(std::make_pair(0, ptS));
// 求出打断后的各段管线并投影
bool bFlag = false;
std::map<double, AcGePoint3d>::iterator it2, it3;
for ( it2 = it3 = mapPt.begin(); it3 != mapPt.end(); it3 = it2, ++it3)
{
bFlag = false;
AcGePoint3d &pt1 = (*it2).second;
++it2;
AcGePoint3d &pt2 = (*it2).second;
for (it = vecPt.begin(); it != vecPt.end(); it++)
{
AcGePoint3d &pt3 = *it;
++it;
AcGePoint3d &pt4 = *it;
if (pt1.distanceTo(pt3) < 1e-3 && pt2.distanceTo(pt4) < 1e-3
|| pt1.distanceTo(pt4) < 1e-3 && pt2.distanceTo(pt3) < 1e-3)
{
bFlag = true;
break;
}
}
if (!bFlag)
{
AcGePoint3d pt5 = pt1.project(plane, vtPlaneSecDir);
AcGePoint3d pt6 = pt2.project(plane, vtPlaneSecDir);
double dDist1 = pt5.distanceTo(pt1), dDist2 = pt6.distanceTo(pt2);
double dElev = dDist1 < dDist2 ? dDist1 : dDist2;
dElev *= -1;
AcGeLineSeg3d seg;
AcGePoint3d pt;
AcGeLineSeg3d line(pt1, pt2);
SectionUtility::Projection_line2plane(section_pln, line, seg, pt);
TGGePoly2D poly2d;
poly2d.AppendNode(asDblArray(seg.startPoint()));
poly2d.AppendNode(asDblArray(seg.endPoint()));
TObjSectionRecord record(objectId(), layerId(), TObjSectionRecord::eTCH_PIPE, dElev, poly2d);
sectionRecords.push_back(record);
}
}
}
//附件
if (IsVertical()) // 立管
{
for(int i = 0; i < m_lstAttachment.Length(); i++)
{
AcDbObjectId id = m_lstAttachment[i];
TDbPipeValve *pValve = NULL;
acdbOpenObject(pValve, id, AcDb::kForRead);
if (pValve != NULL)
{
pValve->GetSection(face,vtPlaneSecDir, sectionRecords, arFillPtrs);
pValve->close();
}
}
}
bRet = true;
}
return bRet;
}
// Acad::ErrorStatus TDbPipe::getGeomExtents( AcDbExtents& extents ) const
// {
// extents.addPoint(GetStartPoint());
// extents.addPoint(GetEndPoint());
//
// return Acad::eOk;
// }
Acad::ErrorStatus TDbPipe::GetExtents(TADSGePoint3d &ptLow, TADSGePoint3d &ptUp) const
{
AcDbExtents ent;
ent.addPoint(GetStartPoint());
ent.addPoint(GetEndPoint());
ptLow = ent.minPoint();
ptUp = ent.maxPoint();
return Acad::eOk;
}
CString TDbPipe::GetXml(const AcGeMatrix3d& mat) const
{
if (m_modelType == TPipeSys::kSystem) // 系统图
{
return CString();
}
TXmlTree xmlTree;
CString csText;
AcGePoint3d pt;
CString csX, csY, csZ;
int nPre = 3; // 精度
double dDnDiameter = m_dDnDiameter;
if (DocGetMeterUnitDraw())
{
dDnDiameter *= 0.001;
}
POSITION posRoot = xmlTree.Insert(_T("ATS_PIPE"), NULL, NULL);
{
xmlTree.SetAttribute(posRoot, _T("name"), _T("水管"));
xmlTree.SetAttribute(posRoot, _T("comment"), _T("上华对象名称"));
}
POSITION posItemMaterial = xmlTree.Insert(_T("Material"),posRoot, NULL);
{
xmlTree.SetAttribute(posItemMaterial, _T("name"), _T("水管材料"));
xmlTree.SetAttribute(posItemMaterial, _T("comment"), _T("水管使用的材料"));
XStringList lst;
GetPipeMaterial(lst);
CString strMat;
if (lst.Length() > 0) // 成功找到材质信息时,进行查找 cet 2013.6.26 add
{
strMat = lst[m_nMaterial];
}
xmlTree.SetItemText(posItemMaterial, strMat);
}
POSITION posItemType = xmlTree.Insert(_T("Style"),posRoot, posItemMaterial);
{
xmlTree.SetAttribute(posItemType, _T("name"), _T("系统类型"));
xmlTree.SetAttribute(posItemType, _T("comment"), _T("水管所属系统"));
xmlTree.SetItemText(posItemType, GetSystypeName(m_sysType));
}
POSITION posItemDn = xmlTree.Insert(_T("Pipe_caliber"),posRoot, posItemType);
{
xmlTree.SetAttribute(posItemDn, _T("name"), _T("外径"));
xmlTree.SetAttribute(posItemDn, _T("comment"), _T("水管公称直径"));
xmlTree.SetItemText(posItemDn, DoubleToString(dDnDiameter, nPre));
}
// 内径
POSITION posInradius = xmlTree.Insert(_T("Pipe_inradius"), posRoot, posItemDn);
{
xmlTree.SetAttribute(posInradius, _T("name"), _T("内径"));
// cet 2018.2.2 modify 通过文件查询内径,对提取信息效率影响较大
// CString csMat = GetPipeMaterialByIdx(GetMaterial());
// double dRadius = GetDnDiameter();
// if (!csMat.IsEmpty()) // 找到材质时,求内径 cet 2013.6.26 add
// {
// dRadius = GetPipeDjByDn(csMat, (int)GetDnDiameter()) * 1000;
// }
double dRadius = OuterDn() - GetPipeThick() * 2;
xmlTree.SetItemText(posInradius, DoubleToString(dRadius, nPre));
}
POSITION posItemPt = xmlTree.Insert(_T("Position"), posRoot, posInradius);
{
xmlTree.SetAttribute(posItemPt, _T("name"), _T("位置参数"));
}
POSITION posItemStaPt1 = xmlTree.Insert(_T("Start_point1"),posItemPt, NULL);
{
xmlTree.SetAttribute(posItemStaPt1, _T("name"), _T("原始起点"));
pt = StartPoint();
pt.transformBy(mat);
csX = DoubleToString(pt.x, nPre);
csY = DoubleToString(pt.y, nPre);
csZ = DoubleToString(pt.z, nPre);
csText.Format(_T("%s,%s,%s"), csX, csY, csZ);
xmlTree.SetItemText(posItemStaPt1, csText);
}
POSITION posItemEndPt1 = xmlTree.Insert(_T("End_point1"),posItemPt, posItemStaPt1);
{
xmlTree.SetAttribute(posItemEndPt1, _T("name"), _T("原始终点"));
pt = EndPoint();
pt.transformBy(mat);
csX = DoubleToString(pt.x, nPre);
csY = DoubleToString(pt.y, nPre);
csZ = DoubleToString(pt.z, nPre);
csText.Format(_T("%s,%s,%s"), csX, csY, csZ);
xmlTree.SetItemText(posItemEndPt1, csText);
}
POSITION posItemMidPt = xmlTree.Insert(_T("Mid_point"),posItemPt, posItemEndPt1);
{
xmlTree.SetAttribute(posItemMidPt, _T("name"), _T("中点"));
pt = MidPoint();
pt.transformBy(mat);
csX = DoubleToString(pt.x, nPre);
csY = DoubleToString(pt.y, nPre);
csZ = DoubleToString(pt.z, nPre);
csText.Format(_T("%s,%s,%s"), csX, csY, csZ);
xmlTree.SetItemText(posItemMidPt, csText);
}
// 计算绘制起点终点
//如果管端接设备,则不用缩
XPoint pt1 = StartPoint();
XPoint pt2 = EndPoint();
XCurveSegment seg = GetCurve();
if (!seg.Is(CURVE_ARC)) // 直管
{
AcDbObjectId nodeId1(NULL), nodeId2(NULL);
nodeId1 = GetNode(0);
nodeId2 = GetNode(1);
XVector3D vtDir(EndPoint() - StartPoint());
vtDir.Normalize();
vtDir.Scale(dDnDiameter);
OPENOBJ_BEGIN(nodeId1, AcDb::kForRead, TDbPipeFitting, pNode);
if(pNode){
if(pNode->GetLocation() == StartPoint())
pt1 += vtDir;
else
pt2 -= vtDir;
}
OPENOBJ_END();
OPENOBJ_BEGIN(nodeId2, AcDb::kForRead, TDbPipeFitting, pNode);
if(pNode){
if(pNode->GetLocation() == StartPoint())
pt1 += vtDir;
else
pt2 -= vtDir;
}
OPENOBJ_END();
}
else // 弧管
{
double dDist = m_dDnDiameter; // 端点向内缩进距离
double dMeter = 1.0;
if (DocGetMeterUnitDraw())
{
dDist *= 0.001;
}
XArc arc1 = seg.GetArc();
AcGePoint3d ptS, ptE;
AcDbArc arc(arc1.GetCenterPt(), arc1.GetRadius(), arc1.GetStarAngle(), arc1.GetEndAngle());
AcGeVector3d vtNormal = arc.normal(); // 法向量
arc.getPointAtDist(dDist, pt1); // 起点向管线内移动
double dArcLen = 0.0;
arc.getDistAtPoint(pt2, dArcLen);
arc.getPointAtDist(dArcLen - dDist, pt2); // 起点向管线内移动
}
POSITION posItemStaPt2 = xmlTree.Insert(_T("Start_point2"),posItemPt, posItemMidPt);
{
xmlTree.SetAttribute(posItemStaPt2, _T("name"), _T("绘制起点"));
pt1.TransformBy(mat);
csX = DoubleToString(pt1.x, nPre);
csY = DoubleToString(pt1.y, nPre);
csZ = DoubleToString(pt1.z, nPre);
csText.Format(_T("%s,%s,%s"), csX, csY, csZ);
xmlTree.SetItemText(posItemStaPt2, csText);
}
POSITION posItemEndPt2 = xmlTree.Insert(_T("End_point2"),posItemPt, posItemStaPt2);
{
xmlTree.SetAttribute(posItemEndPt2, _T("name"), _T("绘制终点"));
pt2.TransformBy(mat);
csX = DoubleToString(pt2.x, nPre);
csY = DoubleToString(pt2.y, nPre);
csZ = DoubleToString(pt2.z, nPre);
csText.Format(_T("%s,%s,%s"), csX, csY, csZ);
xmlTree.SetItemText(posItemEndPt2, csText);
}
// 坡度
POSITION posGradient = xmlTree.Insert(_T("Gradient"), posRoot, posItemPt);
{
xmlTree.SetAttribute(posGradient, _T("name"), _T("坡度"));
xmlTree.SetItemText(posGradient, DoubleToString(GetGradient(), nPre));
}
// 流向
POSITION posFlowDir = xmlTree.Insert(_T("FlowDir"), posRoot, posGradient);
{
xmlTree.SetAttribute(posFlowDir, _T("name"), _T("流向"));
CString sFlowDir;
if (GetFlowDir() == TPipeSys::kFromStart)
{
sFlowDir = _T("从起点到终点");
}
else
{
sFlowDir = _T("从终点到起点");
}
xmlTree.SetItemText(posFlowDir, sFlowDir);
}
// 标注信息 cet 2013.11.19 add
POSITION posDimInfo = xmlTree.Insert(_T("PipeDim"), posRoot, posFlowDir);
{
xmlTree.SetAttribute(posDimInfo, _T("name"), _T("管线标注信息"));
BOOL bDim = IsDrawLabel();
POSITION posIsDim = xmlTree.Insert(_T("IsDim"), posDimInfo, NULL);
{
xmlTree.SetAttribute(posIsDim, _T("name"), _T("是否标注"));
csText.Format(_T("%d"), bDim ? 1 : 0);
xmlTree.SetItemText(posIsDim, csText);
}
if (bDim)
{
POSITION posDimText = xmlTree.Insert(_T("DimText"), posDimInfo, posIsDim);
{
xmlTree.SetAttribute(posDimText, _T("name"), _T("标注文字"));
xmlTree.SetItemText(posDimText, GetLabelText());
}
POSITION posLabel = xmlTree.Insert(_T("DimLabel"), posDimInfo, posDimText);
{
xmlTree.SetAttribute(posLabel, _T("name"), _T("标注前缀"));
xmlTree.SetItemText(posLabel, GetLabel());
}
POSITION posDimFormat = xmlTree.Insert(_T("DimFormat"), posDimInfo, posLabel);
{
xmlTree.SetAttribute(posDimFormat, _T("name"), _T("标注格式"));
POSITION posDnDimType = xmlTree.Insert(_T("DnDimType"), posDimFormat, NULL);
{
xmlTree.SetAttribute(posDnDimType, _T("name"), _T("管径样式"));
csText.Format(_T("%d"), GetPipeDnDimType());
xmlTree.SetItemText(posDnDimType, csText);
}
POSITION posGradientDimType = xmlTree.Insert(_T("GradientDimType"), posDimFormat, posDnDimType);
{
xmlTree.SetAttribute(posGradientDimType, _T("name"), _T("坡度样式"));
csText.Format(_T("%d"), GetPipeGradientDimType());
xmlTree.SetItemText(posGradientDimType, csText);
}
POSITION posLenDimType = xmlTree.Insert(_T("LenDimType"), posDimFormat, posGradientDimType);
{
xmlTree.SetAttribute(posLenDimType, _T("name"), _T("管长样式"));
csText.Format(_T("%d"), GetPipeLenDimType());
xmlTree.SetItemText(posLenDimType, csText);
}
POSITION posLableDrawType = xmlTree.Insert(_T("LableDrawType"), posDimFormat, posLenDimType);
{
xmlTree.SetAttribute(posLableDrawType, _T("name"), _T("排列样式"));
xmlTree.SetAttribute(posLableDrawType, _T("comment"), _T("横排竖排"));
csText.Format(_T("%d"), GetPipeLableDrawType());
xmlTree.SetItemText(posLableDrawType, csText);
}
POSITION posDimLableType = xmlTree.Insert(_T("DimSeparatorType"), posDimFormat, posLableDrawType);
{
xmlTree.SetAttribute(posDimLableType, _T("name"), _T("分隔符号样式"));
csText.Format(_T("%d"), GetPipeDimLableType());
xmlTree.SetItemText(posDimLableType, csText);
}
}
POSITION posDimLoc = xmlTree.Insert(_T("DimLocation"), posDimInfo, posDimFormat);
{
xmlTree.SetAttribute(posDimLoc, _T("name"), _T("标注位置"));
XPoint pt = m_ptLabel;
pt.TransformBy(mat);
csX = DoubleToString(pt.x, nPre);
csY = DoubleToString(pt.y, nPre);
csZ = DoubleToString(pt.z, nPre);
csText.Format(_T("%s,%s,%s"), csX, csY, csZ);
xmlTree.SetItemText(posDimLoc, csText);
}
}
}
POSITION posItemId = xmlTree.Insert(_T("Object_ID"), posRoot, posDimInfo);
{
xmlTree.SetAttribute(posItemId, _T("name"), _T("ID"));
xmlTree.SetAttribute(posItemId, _T("comment"), _T("水管ID"));
csText.Format(_T("%ld"), objectId().asOldId());
xmlTree.SetItemText(posItemId, csText);
}
CString sXml = xmlTree.GetXml();
int nIdex = -1;
nIdex = sXml.Find(_T("</ATS_PIPE>"));
if (nIdex != -1)
{
CString sTemp = TDbPipePrototype::GetXml(mat);
sXml.Insert(nIdex, sTemp);
}
return sXml;
}
void TDbPipe::GetDimPipeLen(CString &sDimPipeLen, int iType, const CString& sLen) const
{
// 获取个位数
CString sTemp;
sTemp.Format(_T("%d"), iType);
int iDimType = static_cast<int>(_tstof(sTemp.Right(2)));
switch(iDimType)
{
case 1: // L=12.3m
{
sDimPipeLen.Format(_T("L=%sm"),sLen);
break;
}
case 2: // L=12.3
{
sDimPipeLen.Format(_T("L=%s"),sLen);
break;
}
case 3: // L12.3m
{
sDimPipeLen.Format(_T("L%sm"),sLen);
break;
}
case 4: // L12.3
{
sDimPipeLen.Format(_T("L%s"),sLen);
break;
}
case 5: // 12.3m
{
sDimPipeLen.Format(_T("%sm"),sLen);
break;
}
case 6: // 12.3
{
sDimPipeLen.Format(_T("%s"),sLen);
break;
}
}
}
// 绘制三维弧管
Acad::ErrorStatus TDbPipe::Draw3dArcPipe(XExplodeDraw &dc) const
{
XCurveSegment seg = GetCurve();
if (!seg.Is(CURVE_ARC))
{
return Acad::eOk;
}
double dDist = m_dDnDiameter; // 端点向内缩进距离
double dMeter = 1.0;
if (DocGetMeterUnitDraw())
{
dDist *= 0.001;
dMeter = 1000;
}
XArc arc1 = seg.GetArc();
AcGePoint3d ptS, ptE;
AcDbArc arc(arc1.GetCenterPt(), arc1.GetRadius(), arc1.GetStarAngle(), arc1.GetEndAngle());
AcGeVector3d vtNormal = arc.normal(); // 法向量
arc.getStartPoint(ptS);
arc.getEndPoint(ptE);
arc.getPointAtDist(dDist, ptS); // 起点向管线内移动25
double dArcLen = 0.0;
arc.getDistAtPoint(ptE, dArcLen);
arc.getPointAtDist(dArcLen - dDist, ptE); // 起点向管线内移动25
double dMinDiffAng = PI / 60;
int nSect = int(PI * 2 / dMinDiffAng); // 圆分成的段数
AcGeVector3d vt1 = ptS - arc.center();
AcGeVector3d vt2 = ptE - arc.center();
double dArcAngle = vt1.angleTo(vt2, vtNormal); // 弧度角度
int nSect1 = int(dArcAngle / dMinDiffAng); // 弧管分成的段数
// 将ptS点的圆划分为nSect份
AcGePoint3dArray arptCircle;
AcGePoint3dArray arptSides;
AcGePoint3d pt = ptS + vtNormal * m_dDnDiameter / dMeter * 0.5;
AcGePoint3d ptTemp;
arc.getPointAtDist(Length() / nSect, ptTemp);
AcGeVector3d vt = ptTemp - ptS;
vt.normal();
ptTemp = pt;
for (int i = 0; i < nSect + 1 ; i++)
{
arptCircle.append(pt);
pt = ptTemp.rotateBy(dMinDiffAng, vt, ptS);
}
//将ptStart处的圆上nSect个点按照dMinDiffAng旋转出nSect1个圆截面
double dAngle = 0.0;
AcGePoint3d ptCen = arc.center();
for (i = 0; i <= nSect1; i++)
{
dAngle = dMinDiffAng * i;
for (int j = 0; j < nSect + 1 ;j++)
{
ptTemp = pt = arptCircle[j];
pt = ptTemp.rotateBy(dAngle, vtNormal, ptCen);
arptSides.append(pt);
}
}
double dAngle2 = 0.0; // 剩余角度
dAngle2 = dArcAngle - dMinDiffAng * nSect1;
if (dAngle2 > 0.0)
{
for (int j = 0; j < nSect + 1 ;j++)
{
ptTemp = pt = arptCircle[j];
pt = ptTemp.rotateBy(dArcAngle, vtNormal, ptCen);
arptSides.append(pt);
}
++nSect1;
}
//最后一个圆截面是ptStart处的圆上nSect个点按照PI/2 90°或者dAngle旋转出来
for (int j = 0; j < nSect + 1 ;j++)
{
pt = arptCircle[j].rotateBy(dAngle, vtNormal, ptCen);
arptSides.append(pt);
}
dc.DrawMesh(nSect1 + 2 , nSect + 1, arptSides.asArrayPtr());
return Acad::eOk;
}
bool TDbPipe::IsDimEle() const
{
const TEntityFields &fd = GetFields();
Adesk::Boolean bDimEle = Adesk::kTrue;
if (!fd.GFD(_T("PIPE_DIM_ELE"), bDimEle))
{
bDimEle = Adesk::kFalse;
}
return bDimEle ? true : false;
}
void TDbPipe::SetDimEle( bool bDim )
{
assertWriteEnabled();
TEntityFields &fd = Fields();
fd.SFD(_T("PIPE_DIM_ELE"), bDim ? Adesk::kTrue : Adesk::kFalse);
}
void TDbPipe::SetLinkedPipeDnDimText( const CString &sDimText )
{
assertWriteEnabled();
TEntityFields &fd = Fields();
fd.SFD(_T("LINKED_DIM_TEXT"), sDimText);
}
CString TDbPipe::GetLinkedPipeDnDimText()
{
CString sText;
TEntityFields &fd = Fields();
fd.GFD(_T("LINKED_DIM_TEXT"), sText);
return sText;
}
bool TDbPipe::IsLinkedPipeDnDimText()
{
CString sText;
TEntityFields &fd = Fields();
return fd.GFD(_T("LINKED_DIM_TEXT"), sText);
}
void TDbPipe::UpdateLinkedPipeDnDimText()
{
// 没有关联标注文字
if (!IsLinkedPipeDnDimText())
{
CString sTemp;
sTemp.Format(_T("%s%.0f"), m_sLabel, m_dDnDiameter);
SetLinkedPipeDnDimText(sTemp);
return;
}
CString sDimText = GetLinkedPipeDnDimText();
int nIndex = sDimText.Find(_T("x"));
CString sTemp;
// cet 2015.3.11 modify 更新外径判断方式
// if (nIndex != -1) // 外径标注如“φ50x2.8”
// {
// sTemp.Format(_T("%s%.0fx%.1f"), m_sLabel, m_dDnDiameter, GetPipeThick());
// }
if (DimDnType() == 1 || nIndex != -1)
{
if (nIndex != -1)
{
sTemp.Format(_T("%s%.0fx%.1f"), m_sLabel, DimDnType() == 1 ? OuterDn() : m_dDnDiameter, GetPipeThick());
}
else
{
sTemp.Format(_T("%s%.0f"), m_sLabel, DimDnType() == 1 ? OuterDn() : m_dDnDiameter);
}
}
else // 内径标注如“DN20”
{
sTemp.Format(_T("%s%.0f"), m_sLabel, m_dDnDiameter);
}
SetLinkedPipeDnDimText(sTemp);
}
bool TDbPipe::IsLinkedPipeText()
{
CString sText;
TEntityFields &fd = Fields();
return fd.GFD(_T("PIPE_TEXT"), sText);
}
CString TDbPipe::GetLinkedPipeText()
{
CString sText;
TEntityFields &fd = Fields();
fd.GFD(_T("PIPE_TEXT"), sText);
return sText;
}
void TDbPipe::SetLinkedPipeText( const CString &sPipeText )
{
assertWriteEnabled();
TEntityFields &fd = Fields();
fd.SFD(_T("PIPE_TEXT"), sPipeText);
}
int TDbPipe::DimDnType() const
{
const TEntityFields &fd = GetFields();
Adesk::Int8 nType = -1;
fd.GFD(_T("PIPE_DIM_DN_TYPE"), nType);
return nType == -1 ? 0 : (int)nType;
}
void TDbPipe::SetDimDnType(int nDnType)
{
assertWriteEnabled();
TEntityFields &fd = Fields();
fd.SFD(_T("PIPE_DIM_DN_TYPE"), (Adesk::Int8)nDnType);
m_bUpdateLinkedDim = true; // cet 2015.4.14 add
}
double TDbPipe::OuterDn() const
{
const TEntityFields &fd = GetFields();
double dDn = m_dDnDiameter;
fd.GFD(_T("PIPE_OUTER_DN"), dDn);
return dDn;
}
void TDbPipe::SetOuterDn(double dDn)
{
assertWriteEnabled();
TEntityFields &fd = Fields();
fd.SFD(_T("PIPE_OUTER_DN"), dDn);
m_bUpdateLinkedDim = true; // cet 2015.3.11 add 更新关联标注
}
Acad::ErrorStatus TDbPipe::subClose()
{
// 更新管线关联标注的显示信息
if (m_bUpdateLinkedDim)
{
m_bUpdateLinkedDim = false;
UpdateLinkedPipeDnDimText();
}
return TDbPipePrototype::subClose();
}
Adesk::UInt16 TDbPipe::GetTextColor() const
{
const TEntityFields &fd = GetFields();
Adesk::UInt16 color = 256;
fd.GFD(_T("TEXT_COLOR"), color);
return color;
}
void TDbPipe::SetTextColor(Adesk::UInt16 color)
{
assertWriteEnabled();
TEntityFields &fd = Fields();
fd.SFD(_T("TEXT_COLOR"), color);
}
CString TDbPipe::GetPipeSystemName() const
{
const TEntityFields &fd = GetFields();
CString sName;
if (!fd.GFD(_T("PIPE_SYSTEM_NAME"), sName)) // 没有设置管道系统名时,通过旧系统类型获取
{
sName = GetSystypeName(GetSysType());
}
return sName;
}