Files
envi-code/SourceCode/Code2026/Dimension/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

3136 lines
84 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 "PushProperty.h"
#include "SymbolTableRecord.h"
#include "GeCurveInline.h"
#include "ADSGePointDir2d.h"
#include "AcDbObjectPtr.h"
#include "DbPipe.h"
#include "DbPipeLabel.h"
#include "DbWell.h"
#include "SHAcDbBlockTableRecPtr.h"
static bool g_bSPipeFDir = false;
AcDbObjectId InitTextStyle(const TCHAR *pszStyle, AcDbDatabase *pDb = NULL);
namespace
{
Acad::ErrorStatus DrawPolyMesh(XPoint ptSt, XPoint ptEn, double nRadius, AcGiDraw &dc)
{
AcGePoint3d ptS = ptSt;
AcGePoint3d ptE = ptEn;
AcGeVector3d vtDirect = ptE - ptS;
AcGeVector3d vtNormal = vtDirect.perpVector();
vtDirect.normalize();
double dMinAngle = PI / 15.0;
int nPartNum = int(PI * 2 / dMinAngle) + 1;
dMinAngle = PI * 2.0 / nPartNum;
double dDiaMet = nRadius * 2;
AcGePoint3dArray ptArr, ptArrT, ptArrD;
AcGeVector3d vtNow = vtNormal * -1; // 每组顶点法向
int i(0);
for (i = 0; i < nPartNum * 2; i += 2)
{
ptArr.append(ptS + dDiaMet * 0.5 * vtNow);
ptArr.append(ptE + dDiaMet * 0.5 * vtNow);
ptArrT.append(ptS + dDiaMet * 0.5 * vtNow);
ptArrT.append(ptS);
ptArrD.append(ptE + dDiaMet * 0.5 * vtNow);
ptArrD.append(ptE);
vtNow.rotateBy(dMinAngle, vtDirect);
}
// 单独设置末点,防止误差
ptArr.append(ptArr.at(0));
ptArr.append(ptArr.at(1));
ptArrT.append(ptArrT.at(0));
ptArrT.append(ptArrT.at(1));
ptArrD.append(ptArrD.at(0));
ptArrD.append(ptArrD.at(1));
// 圆柱体
dc.DrawMeshS(nPartNum + 1, 2, ptArr.asArrayPtr());
// 上面
dc.DrawMeshS(nPartNum + 1, 2, ptArrT.asArrayPtr());
// 下面
dc.DrawMeshS(nPartNum + 1, 2, ptArrD.asArrayPtr());
return Acad::eOk;
}
CString I2Str(double i)
{
CString csText;
i = i / 1000;
int iTmp = int(i * 1000) * 10;
int iTmp2 = int(i * 10000);
if (iTmp == iTmp2) {
iTmp = int(i * 100) * 10;
iTmp2 = int(i * 1000);
if (iTmp == iTmp2)
csText.Format(_T("%.2f"), i);
else
csText.Format(_T("%.3f"), i);
}
else
csText.Format(_T("%.4f"), i);
return csText;
}
CString ReadXdata(Entity ent, const TCHAR*szName)
{
AcDbObjectId eId;
AcDbEntity *pEnt = NULL;
acdbGetObjectId(eId, ent);
acdbOpenObject(pEnt, eId, AcDb::kForRead);
if (!pEnt)
return _T("");
resbuf *pRb = pEnt->xData(szName);
CString csRet;
if (pRb != NULL) {
resbuf *pTemp = pRb;
if (pTemp->rbnext != NULL) {
pTemp = pTemp->rbnext;
if (pTemp->restype == 1000)
csRet = pTemp->resval.rstring;
}
}
ads_relrb(pRb);
pEnt->close();
return csRet;
}
//读扩展数据 cet 2014.6.4 add
CString ReadXdata(const AcDbEntity*pEnt, const TCHAR*szName)
{
if (!pEnt)
return _T("");
resbuf *pRb = pEnt->xData(szName);
CString csRet;
if (pRb != NULL) {
resbuf *pTemp = pRb;
if (pTemp->rbnext != NULL) {
pTemp = pTemp->rbnext;
if (pTemp->restype == 1000)
csRet = pTemp->resval.rstring;
}
}
ads_relrb(pRb);
return csRet;
}
BOOL ExtendInBox02d(const XPoint &ptMin, const XPoint &ptMax, const XRectAngle &box)
{
return !(box.upRight.x<ptMin.x || box.upRight.y<ptMin.y ||
box.lowLeft.x>ptMax.x || box.lowLeft.y>ptMax.y);
}
BOOL PointInBox02d(const XPoint &pt, const XRectAngle &box)
{
return(pt.x >= box.lowLeft.x && pt.x <= box.upRight.x &&
pt.y >= box.lowLeft.y && pt.y <= box.upRight.y);
}
BOOL GetPSEntFormBlock(DList<AcDbObjectId> &lstPSEnt,
const XRectAngle& rectBound, const AcRxClass *pClass)
{
lstPSEnt.Reset();
if (pClass == NULL) return FALSE;
SHAcDbBlockTableRecPtr objMSpace;
if (!objMSpace) return FALSE;
XPoint ptExtents(1000, 1000, 0);//加速设备GetExtents
AcDbBlockTableRecordIterator* pBlockIterator = NULL;
Acad::ErrorStatus es = objMSpace.m_pBlockTableRec->newIterator(pBlockIterator);
ASSERT(es == Acad::eOk && pBlockIterator != NULL);
for (pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step()) {
AcDbEntity *pEntity = NULL;
es = pBlockIterator->getEntity(pEntity, AcDb::kForRead);
if (es != Acad::eOk) continue;
ASSERT(pEntity);
AcDbObjectPtr vTemp(pEntity);
if (!pEntity->isKindOf(pClass) || pEntity->visibility() == AcDb::kInvisible)
continue;
AcDbObjectId id = pEntity->objectId();
if (pEntity->isKindOf(CDbPipePrototype::desc())) {//管线(for getGeomExtents 不准确)
CDbPipePrototype *pPipe = (CDbPipePrototype *)pEntity;
if (pPipe != NULL) {
XPoint ptMin, ptMax;
if (pPipe->GetExtend(ptMin, ptMax)) {
if (ExtendInBox02d(ptMin, ptMax, rectBound)) {
lstPSEnt.Append(new AcDbObjectId(id));
}
}
}
}
else if (pEntity->isKindOf(CDbPipeNode::desc())) { //节点
CDbPipeNode *pNode = (CDbPipeNode *)pEntity;
if (pNode != NULL) {
if (pNode->IsVisible()) { //可见节点
if (pNode->IsDrawBlock()) {
XPoint ptLocation = pNode->GetLocation();
XPoint ptMin = ptLocation - ptExtents;
XPoint ptMax = ptLocation + ptExtents;
if (!ExtendInBox02d(ptMin, ptMax, rectBound))
continue;
}
XPoint ptMin, ptMax;
if (pNode->GetExtents(ptMin, ptMax) == Acad::eOk) {
if (ExtendInBox02d(ptMin, ptMax, rectBound)) {
lstPSEnt.Append(new AcDbObjectId(id));
}
}
}
else { //不可见节点
XPoint ptLocation = pNode->GetLocation();
if (PointInBox02d(ptLocation, rectBound)) {
lstPSEnt.Append(new AcDbObjectId(id));
}
}
}
}
else if (pEntity->isKindOf(CDbPipeAttachment::desc())) { // 管线附件
CDbPipeAttachment *pAttach = (CDbPipeAttachment *)pEntity;
if (pAttach != NULL) {
if (pAttach->IsDrawBlock()) {
XPoint ptLocation = pAttach->GetLocation();
XPoint ptMin = ptLocation - ptExtents;
XPoint ptMax = ptLocation + ptExtents;
if (!ExtendInBox02d(ptMin, ptMax, rectBound))
continue;
}
XPoint ptMin, ptMax;
if (pAttach->GetExtents(ptMin, ptMax) == Acad::eOk) {
if (ExtendInBox02d(ptMin, ptMax, rectBound)) {
lstPSEnt.Append(new AcDbObjectId(id));
}
}
}
}
else { // 其他的非上华实体
AcDbExtents ext;
if (pEntity->getGeomExtents(ext) == Acad::eOk) {
XPoint ptMin = ext.minPoint(), ptMax = ext.maxPoint();
if (ExtendInBox02d(ptMin, ptMax, rectBound)) {
lstPSEnt.Append(new AcDbObjectId(id));
}
}
}
}
delete pBlockIterator;
return TRUE;
}
}
// 旋转向量
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(AcGiDraw &dc, double dWeight, AcDbPolyline& pline)
{
AcGiViewDraw &viewDraw = (AcGiViewDraw &)dc;
int nNum = pline.numVerts();
if (nNum > 0) {
// for (int k=0;k<nNum; k++) {
// pline.setWidthsAt(k,dWeight,dWeight);
// }
pline.setConstantWidth(dWeight);
viewDraw.DrawEntity(pline);
// dc << pline;
//dc.DrawEntity(pline);
// if(viewDraw.m_pWd)
// pline.worldDraw(viewDraw.m_pWd);
// else
// pline.viewportDraw(viewDraw.m_pVd);
}
}
//SB2004、6、9修改,增加颜色参数
void DrawWeight(AcGiDraw &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(), AcGiViewDraw::Descriptor())==0) {
AcGiViewDraw &dcDraw = (AcGiViewDraw&)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);
GlobalFunc::PolyConvert(poly, pline);
if (nColorIndex > 0)
pline.setColorIndex(nColorIndex);
DrawWeight(dc, dWeight, pline);
}
void DrawWeight(AcGiDraw &dc, double dWeight, XCurveSegment &seg, int nColorIndex, double nScale)
{
XPoly2D poly;
seg.AsPoly2D(poly);
DrawWeight(dc, dWeight, poly, nColorIndex, nScale);
}
void DrawWeight(AcGiDraw &dc, double dWeight, XCircle &cir, int nColorIndex, double nScale)
{
XCurveSegment seg;
seg = cir;
DrawWeight(dc, dWeight, seg, nColorIndex, nScale);
}
ACRX_DXF_DEFINE_MEMBERS(CDbPipe, CDbPipePrototype, AcDb::kDHL_CURRENT,
AcDb::kMReleaseCurrent, 1, AEC_ZT_PIPE,
"AEC_ZT_PIPE图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
const Adesk::UInt8 CDbPipe::g_nVersion = 2;
CDbPipe::CDbPipe() :
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 CDbPipe::CopyPropertiesFrom(AcDbEntity *pSrc, unsigned gMatchFlag)
{
assertWriteEnabled();
CDbPipePrototype::CopyPropertiesFrom(pSrc, gMatchFlag);
CDbPipe *pPipe = CDbPipe::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 CDbPipe::subGetClassID(CLSID* pClsid) const
//{
// return Acad::eOk;
//}
Acad::ErrorStatus
CDbPipe::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 = CDbPipePrototype::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), CDbPipe::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, CDbPipe, 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
CDbPipe::dwgInFields(AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = CDbPipePrototype::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);
GlobalFunc::ReadString(pFiler, m_sLabel);
pFiler->readItem(&m_dSpeedSubMid);
pFiler->readItem(&m_dSpeedLength);
if (nVer > 1) {
pFiler->readItem(&m_dSpare);
// if (!IsNewDimType())
// {
// GetNewDimType();
// }
GlobalFunc::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
CDbPipe::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = CDbPipePrototype::dwgOutFields(pFiler);
if (es != Acad::eOk) return es;
pFiler->writeItem(g_nVersion);
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);
// 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 CDbPipe::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
CDbPipe::dxfInFields(AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = Acad::eOk;
es = CDbPipePrototype::dxfInFields(pFiler);
if (es != Acad::eOk) return es;
if (!pFiler->atSubclassData(_T("CDbPipe"))) {
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
CDbPipe::dxfOutFields(AcDbDxfFiler* pFiler) const
{
Acad::ErrorStatus es = Acad::eOk;
es = CDbPipePrototype::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass, _T("CDbPipe"));
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 CDbPipe::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 CDbPipe::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const
{
assertReadEnabled();
Acad::ErrorStatus es = Acad::eOk;
es = CDbPipePrototype::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 CDbPipe::subGetGripPoints(AcDbGripDataPtrArray & grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d & curViewDir, const int bitflags) const
{
return Acad::eNotImplementedYet;
}
// 取得夹点说明
Acad::ErrorStatus CDbPipe::GetGripText(int idx, CString &cs) const
{
Acad::ErrorStatus es = Acad::eOk;
es = CDbPipePrototype::GetGripText(idx, cs);
if (es != Acad::eOk && !IsVertical()) {
if (idx == 4 && g_bSPipeFDir)
cs = _T("改变流向");
es = Acad::eOk;
}
return es;
}
// 功能: 夹点操作
Acad::ErrorStatus CDbPipe::subMoveGripPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
Acad::ErrorStatus es = Acad::eOk;
es = CDbPipePrototype::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 CDbPipe::CanMergeWith(const CDbPipePrototype &other, int *iPosThis, int *iPosOther) const
{
if (other.isKindOf(CDbPipe::desc())) {
CDbPipe *pOther = CDbPipe::cast(&other);
if (fabs(m_dRadius - pOther->m_dRadius) > g_DimOption::instance()._distSnap ||
fabs(m_dDnDiameter - pOther->m_dDnDiameter) > g_DimOption::instance()._distSnap)
return FALSE;
}
return CDbPipePrototype::CanMergeWith(other, iPosThis, iPosOther);
}
// 自动增加节点到当前数据库,ids-该节点自动连接的管线,派生类应当重载
AcDbObjectId CDbPipe::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 CDbPipe::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
// 2010-3-18 SR 增加视口显示的判断
void CDbPipe::GetBrokenCurves(AcGiDraw &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, CDbPipeAttachment, 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();
}
AcGiViewDraw &viewDraw = (AcGiViewDraw &)dc;
// 管线的遮挡关系
for (int k = 0; k < nHide; k++) {
OPENOBJ_BEGIN(m_lstHidePipe[k], AcDb::kForRead, CDbPipePrototype, 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;//裁剪后的曲线段
CDbPipePrototype 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, 导致管线无法打断, SB2004-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];
CDbPipePrototype 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];
CDbPipePrototype 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 CDbPipe::GetVerPipeHideLength(const CDbPipeNode* 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, CDbPipe, 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 CDbPipe::ResetDrawSpeed()
{
assertWriteEnabled();
double dSpeedLength = 0, dSpeedSubMid = 0;//初始化
OPENOBJ_BEGIN(m_nodeEnd.m_idNode, AcDb::kForRead, CDbPipeNode, 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, CDbPipeNode, 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 CDbPipe::ResetDrawSpeed(CDbPipeNode *pModifyNode)
{
if (pModifyNode == NULL)
{
return ResetDrawSpeed();
}
// 端点遮挡长度
assertWriteEnabled();
double dSpeedLength = 0, dSpeedSubMid = 0;//初始化
// 终点遮挡长度
bool bFlag = false;
OPENOBJ_BEGIN(m_nodeEnd.m_idNode, AcDb::kForRead, CDbPipeNode, 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)
{
CDbPipeNode *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, CDbPipeNode, 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)
{
CDbPipeNode *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 CDbPipe::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 CDbPipe::GetVerOpenedType(XVector3D &vtDir, int &nOpenType) const
{
BOOL bRet = FALSE;
const AcDbObjectId& idNode = GetVerUpNode();
OPENOBJ_BEGIN(idNode, AcDb::kForRead, CDbPipeNode, 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, CDbPipePrototype, 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, CDbPipePrototype, 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 CDbPipe::DrawVerPipe2d(AcGiDraw &dc) const
{
if (Has2DBuffer())
{
Draw2DBuffers(dc);
return Acad::eOk;
}
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);
DrawArc(dc, arc);
//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);
DrawArc(dc, arc1);
//dc << arc1;
XArc arc2(ptCenter, nRadius, dMiddleAngle2, dEndAngle);
DrawArc(dc, arc2);
//dc << arc2;
}
}
else {
XPoint ptCenter(GetStartPoint().x, GetEndPoint().y);
XCircle cirOut(ptCenter, nRadius);
if (nRadiusIn > 1.0E-3) { //绘制双圆圈 >0
XCircle cirIn(ptCenter, nRadiusIn);
DrawCircle(dc, cirOut);
DrawCircle(dc, cirIn);
//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);
DrawPoly2D(dc, 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;
GlobalFunc::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;
DrawCircle(dc, cirOut);
}
}
return Acad::eOk;
}
// 绘制平面水平管
Acad::ErrorStatus CDbPipe::DrawHorPipe2d(AcGiDraw &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())
//{
// AcGiViewDraw &dcDraw = (AcGiViewDraw&)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(), AcGiViewDraw::Descriptor()) == 0) {
// AcGiViewDraw &dcDraw = (AcGiViewDraw&)dc;
// // cet 2012.12.18 del 用户选择是否随管线比例变化
// // dcDraw.GetCommonDraw()->subEntityTraits().setLineTypeScale(GetPScale()/100*linetypeScale());// SR 2012-6-19 支持线型比例随对象比例发生变化
// dcDraw.GetCommonDraw()->subEntityTraits().setLineTypeScale(nScale);
//}
//dc << seg;
DrawSegment(dc, seg);
//if (_tcsicmp(dc.Desc(), AcGiViewDraw::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 CDbPipe::Length() const
{
double len = CDbPipePrototype::GetLength();
if (GlobalFunc::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 CDbPipe::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 (!GlobalFunc::DocGetMeterUnitDraw())
len = len / 1000.0;
return len;
}
//写扩展数据
BOOL WriteXdata(Entity ent, const TCHAR*szName, const TCHAR*szValue)
{
AcDbObjectId eId;
AcDbEntity *pEnt = NULL;
acdbGetObjectId(eId, ent);
if (!SymbolTableRecord(_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 (!SymbolTableRecord(_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 CDbPipe::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 = (LPCTSTR)m_sLabel;
// 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, GlobalFunc::DoubleToString(dDnDiameter, nPrec, bTrim), GlobalFunc::DoubleToString(GetPipeThick(), nPrec, bTrim));
else
sText.Format(_T("%s%s"), csLable, GlobalFunc::DoubleToString(dDnDiameter, nPrec, bTrim));
}
}
else if (nDnDimType == 2)
{
// cet 2018.2.12 modify 精度有损失,外径可能有小数
// sText.Format(_T("%.0f"), dDnDiameter);
sText.Format(_T("%s"), GlobalFunc::DoubleToString(dDnDiameter, nPrec, bTrim));
}
return sText;
}
// 获取管线长度标注字符 zxl 2012.12.17 add
CString CDbPipe::GetPipeLenDimStr() const
{
int iDimType = GetPipeLenDimType();
if (iDimType == 0)
{
return _T("");
}
int iPre = 2;// 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 CDbPipe::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 CDbPipe::IsNewDimType() const
{
Adesk::Int16 nType = GetPipeDnDimType();
if (nType >= 0)
{
return true;
}
return false;
}
CString CDbPipe::GetNewPipeDimStr() const
{
CString sDn, sLen, sGradient, sLabel, sNote;
sDn = GetPipeDnDimStr();
// cet 2013.2.5 add 标注标高
if (!sDn.IsEmpty() && IsDimEle())
{
double dEle = StartPoint().z;
if (!GlobalFunc::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 CDbPipe::GetLabelText() const
{
//添加多联机标注09.11.19 wlw
if (m_sysType == TPipeSys::kVRVMedia)
{
CString sTmp = _T("%%C");
CString sLabel = (LPCTSTR)m_sLabel, 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 = (LPCTSTR)sLabel;
// 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 (!GlobalFunc::DocGetMeterUnitDraw())
{
dEle *= 0.001;
}
CString sEle;
sEle.Format(_T("(%.2f)"), dEle);
csRet += sEle;
}
}
CString csTmp, csLen;
double len = Length();
int iPre = 2;// GetPipeLenPrecision(this->database());
CString sHead, sFormat;
sHead.Format(_T("%d"), iPre);
sFormat = _T("%.") + sHead + _T("f");
csLen.Format(sFormat, len);
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 CDbPipe::GetMinLabelTextLen() const
//{
// double nVal=0.0;
// AecXDbText 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(AcGiDraw::kMiddleCenter);
// XPoint ptExt=text.GetExtents();
// nVal=max(nVal, ptExt.x);
// return nVal;
Acad::ErrorStatus CDbPipe::DrawLabelText(AcGiDraw &dc) const
{
XPoint ptOnThis;
if (ProjectToMe(m_ptLabel, ptOnThis)) {
double dRotation = 0;
if (!IsVertical()) {
if (Is(CURVE_LINE))
{
dRotation = Direction(ptOnThis);
dRotation = GlobalFunc::Wcs2Ucs(dRotation);
}
else if (Is(CURVE_ARC)) {
XPoint ptCenter;
GetArc().Center(ptCenter);
dRotation = ads_angle(GlobalFunc::Wcs2Ucs(ptCenter), GlobalFunc::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 = GlobalFunc::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();
if (!m_idTextStyle.isValid())
{
const_cast<AcDbHardPointerId&>(m_idTextStyle) = InitTextStyle(_T("Standard"));
}
if (GetPipeLableDrawType() == 0 || !IsNewDimType())// 旧版标注形式或横排
{
AecXDbText 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(AcGiDraw::kMiddleCenter);
PushProperty vProp(&text, dc);
DrawBaseEx(dc, text);
//dc.DrawEntity(text);
}
else// 标注形式为竖排
{
// 竖排时获取每行标注字符
CString sLabel = (LPCTSTR)GetLabelText();
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;
GlobalFunc::WCS2UCS(ptStart);
GlobalFunc::WCS2UCS(ptEnd);
AcDbLine line(ptStart, ptEnd);
AcGePoint3d ptLabel(m_ptLabel.x, m_ptLabel.y, 0), ptOnLine;
GlobalFunc::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++)
{
AecXDbText 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)
{
GlobalFunc::Ucs2Wcs(ptLabel);
text.SetLocation(ptLabel);
GlobalFunc::WCS2UCS(ptLabel);
text.SetAlignment(AcGiDraw::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(GlobalFunc::Wcs2Ucs(dRotation + PI), AcGeVector3d::kZAxis);
ptLabel += vtTemp * dLen * 0.5;
// cet 2016.9.26 add 批量转旧版(T3)时,外包框获取失败, 并排文字没有对齐
if (dLen < 0.001)
{
text.SetAlignment(AcGiDraw::kMiddleLeft);
}
}
else
{
ptLabel += (vtDir * m_dTextHeight * GetPScale() * 4 / 3);
GlobalFunc::Ucs2Wcs(ptLabel);
text.SetLocation(ptLabel);
GlobalFunc::WCS2UCS(ptLabel);
text.SetAlignment(AcGiDraw::kMiddleLeft);
}
text.SetRotation(dRotation);
PushProperty vProp(&text, dc);
DrawBaseEx(dc, text);
i++;
}
}
dc.SetLayer(idLayerOld);
}
return Acad::eOk;
}
//管线加粗后,2段管线连接处,ACAD处理不理想,上华来修补;SB2004/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, CDbPipe, 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, CDbPipe, 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, CDbPipe, 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();
}
}
}
}
Acad::ErrorStatus CDbPipe::Draw2d(AcGiDraw &dc) const
{
Acad::ErrorStatus es;
//以下部分判断本管线所在的dwg是否是粗线模式
BOOL bIsWeight = false;
//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
AcGiDraw &viewDraw = (AcGiDraw &)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;
}
Acad::ErrorStatus CDbPipe::Draw3d(AcGiDraw &dc) const
{
// cet 2018.2.2 modify 通过文件查询外径,对实体绘制效率影响较大
// double dPipeDiameter = m_dDnDiameter;
// dPipeDiameter = GetPipeOutDByDn(m_nMaterial, dPipeDiameter);
double dPipeDiameter = OuterDn();
// double dArea(1);
if (GlobalFunc::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=((AcGiViewDraw &)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 CDbPipe::subOpen(AcDb::OpenMode mode)
{
Acad::ErrorStatus es = CDbPipePrototype::subOpen(mode);
if (es == Acad::eOk/* && g_nCmdReactor != CMD_UPDATE*/) {
if (mode == AcDb::kForWrite && database() == acdbCurDwg()) {
m_dOldRadius = m_dRadius;
}
}
return es;
}
void CDbPipe::ApplyDnDiameterChangeToLabel()
{
XString sCmd = GlobalFunc::getCurrentCmdNames();
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)
{
// CDbPipeLabel
OPENOBJ_BEGIN(*m_lstAttachment[i], AcDb::kForWrite, CDbPipeLabel, pPipeLabel);
if (pPipeLabel != NULL && IsLinkedPipeDnDimText()) // 管线存在关联管径标注文字
{
pPipeLabel->SetPipeType(CDbPipeLabel::kDuct);
pPipeLabel->SetLeftText(sDimText);
continue;
}
OPENOBJ_END();
// CDbPipeText
OPENOBJ_BEGIN(*m_lstAttachment[i], AcDb::kForWrite, CDbPipeText, 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 CDbPipe::GetExtent() const
{
if (IsVertical()) {
return XExtent(m_dRadius * 2, m_dRadius * 2);
}
else
return CDbPipePrototype::GetExtent();
}
XExtent CDbPipe::GetOldExtent() const
{
if (IsVertical())
return XExtent(m_dOldRadius, m_dOldRadius);
else
return CDbPipePrototype::GetOldExtent();
}
int CDbPipe::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 = CDbPipePrototype::GetExtend(low, up);
}
return nRet;
}
double CDbPipe::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 CDbPipe::GetTips(DList<ObjInfoUnit> &lstInfo) const
{
if (IsVertical())
lstInfo.Append(new ObjInfoUnit(_T("对象类型"), _T("立管")));
else
lstInfo.Append(new ObjInfoUnit(_T("对象类型"), _T("管段")));
CDbPipePrototype::GetTips(lstInfo);
// cet 2015.8.24 add 更新基类中设置的系统类型
if (HavePipeSystemName())
{
CString sSysName = GetPipeSystemName();
int nLen = lstInfo.Length();
for (int i = 0; i < nLen; ++i)
{
ObjInfoUnit *pInfo = lstInfo[i];
if (pInfo->m_sLabel == _T("系统类型"))
{
pInfo->m_sValue = sSysName;
break;
}
}
}
lstInfo.Append(new ObjInfoUnit(_T("管径"), GlobalFunc::Dist2Str(m_dDnDiameter)));
if (!IsVertical())
lstInfo.Append(new ObjInfoUnit(_T("坡度"), XString(_T("%0.3f"), m_dRadiusIn)));
//XStringList lstMaterial;
//if (GetPipeMaterial(lstMaterial) && m_nMaterial >= 0
// && m_nMaterial < lstMaterial.Length()) {
// lstInfo.Append(new ObjInfoUnit(_T("材料"), lstMaterial[m_nMaterial]));
//}
if (GetModelType() == TPipeSys::kSystem && _tcsicmp(GetSysLabel(), _T("")) != 0) {
lstInfo.Append(new ObjInfoUnit(_T("楼层"), GetSysLabel()));
lstInfo.Append(new ObjInfoUnit(_T("立管编号"), XString(_T("%.0f"), GetRadiusIn())));
}
}
bool CDbPipe::IsClipMe(const AecXDbEntityBaseEx* pEnt)const
{
// 判断是否处理遮挡
//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")))
//{
// // 获得风管的外包围框
// ADSGePoint3d 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
// {
// ADSGePoint3d ptPipe;
// Midpoint(StartPoint(), EndPoint(), ptPipe);
// if (ptPipe.z < ptMid.z)
// return true;
// }
//}
}
return false;
}
bool CDbPipe::IsMeClip()const
{
return true;
}
//////////////////////////////////////////////////////////////////////////
void InitDbPipe(BOOL bTrue)
{
if (bTrue) {
CDbPipe::rxInit();
//CDbPipe::InitMatchProtocol(TRUE);
}
else {
//CDbPipe::InitMatchProtocol(FALSE);
deleteAcRxClass(CDbPipe::desc());
}
}
Acad::ErrorStatus CDbPipe::GetExtents(ADSGePoint3d &ptLow, ADSGePoint3d &ptUp) const
{
AcDbExtents ent;
ent.addPoint(GetStartPoint());
ent.addPoint(GetEndPoint());
ptLow = ent.minPoint();
ptUp = ent.maxPoint();
return Acad::eOk;
}
void CDbPipe::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 CDbPipe::Draw3dArcPipe(AcGiDraw &dc) const
{
XCurveSegment seg = GetCurve();
if (!seg.Is(CURVE_ARC))
{
return Acad::eOk;
}
double dDist = m_dDnDiameter; // 端点向内缩进距离
double dMeter = 1.0;
if (GlobalFunc::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.DrawMeshS(nSect1 + 2, nSect + 1, arptSides.asArrayPtr());
return Acad::eOk;
}
bool CDbPipe::IsDimEle() const
{
const EntityFields &fd = GetFields();
Adesk::Boolean bDimEle = Adesk::kTrue;
if (!fd.GFD(_T("PIPE_DIM_ELE"), bDimEle))
{
bDimEle = Adesk::kFalse;
}
return bDimEle ? true : false;
}
void CDbPipe::SetDimEle(bool bDim)
{
assertWriteEnabled();
EntityFields &fd = Fields();
fd.SFD(_T("PIPE_DIM_ELE"), bDim ? Adesk::kTrue : Adesk::kFalse);
}
void CDbPipe::SetLinkedPipeDnDimText(const CString &sDimText)
{
assertWriteEnabled();
EntityFields &fd = Fields();
fd.SFD(_T("LINKED_DIM_TEXT"), sDimText);
}
CString CDbPipe::GetLinkedPipeDnDimText()
{
CString sText;
EntityFields &fd = Fields();
fd.GFD(_T("LINKED_DIM_TEXT"), sText);
return sText;
}
bool CDbPipe::IsLinkedPipeDnDimText()
{
CString sText;
EntityFields &fd = Fields();
return fd.GFD(_T("LINKED_DIM_TEXT"), sText);
}
void CDbPipe::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 CDbPipe::IsLinkedPipeText()
{
CString sText;
EntityFields &fd = Fields();
return fd.GFD(_T("PIPE_TEXT"), sText);
}
CString CDbPipe::GetLinkedPipeText()
{
CString sText;
EntityFields &fd = Fields();
fd.GFD(_T("PIPE_TEXT"), sText);
return sText;
}
void CDbPipe::SetLinkedPipeText(const CString &sPipeText)
{
assertWriteEnabled();
EntityFields &fd = Fields();
fd.SFD(_T("PIPE_TEXT"), sPipeText);
}
int CDbPipe::DimDnType() const
{
const EntityFields &fd = GetFields();
Adesk::Int8 nType = -1;
fd.GFD(_T("PIPE_DIM_DN_TYPE"), nType);
return nType == -1 ? 0 : (int)nType;
}
void CDbPipe::SetDimDnType(int nDnType)
{
assertWriteEnabled();
EntityFields &fd = Fields();
fd.SFD(_T("PIPE_DIM_DN_TYPE"), (Adesk::Int8)nDnType);
m_bUpdateLinkedDim = true; // cet 2015.4.14 add
}
double CDbPipe::OuterDn() const
{
const EntityFields &fd = GetFields();
double dDn = m_dDnDiameter;
fd.GFD(_T("PIPE_OUTER_DN"), dDn);
return dDn;
}
void CDbPipe::SetOuterDn(double dDn)
{
assertWriteEnabled();
EntityFields &fd = Fields();
fd.SFD(_T("PIPE_OUTER_DN"), dDn);
m_bUpdateLinkedDim = true; // cet 2015.3.11 add 更新关联标注
}
Acad::ErrorStatus CDbPipe::subClose()
{
// 更新管线关联标注的显示信息
if (m_bUpdateLinkedDim)
{
m_bUpdateLinkedDim = false;
UpdateLinkedPipeDnDimText();
}
return CDbPipePrototype::subClose();
}
Adesk::UInt16 CDbPipe::GetTextColor() const
{
const EntityFields &fd = GetFields();
Adesk::UInt16 color = 256;
fd.GFD(_T("TEXT_COLOR"), color);
return color;
}
void CDbPipe::SetTextColor(Adesk::UInt16 color)
{
assertWriteEnabled();
EntityFields &fd = Fields();
fd.SFD(_T("TEXT_COLOR"), color);
}
CString CDbPipe::GetPipeSystemName() const
{
const EntityFields &fd = GetFields();
CString sName;
if (!fd.GFD(_T("PIPE_SYSTEM_NAME"), sName)) // 没有设置管道系统名时,通过旧系统类型获取
{
sName = GetSystypeName(GetSysType());
}
return sName;
}