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