#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.xptMax.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 &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;ksubEntityTraits().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 &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 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 &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 &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 &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 lstLocation; DList 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 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 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 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(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(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 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::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 &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(_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; }