// DbDoubleLinePipe.cpp: implementation of the TDbDoubleLinePipe class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include #include #include "DbDoubleLinePipe.h" #include "PipeTools.h" #include "DbPipeValve.h" #include "DbFlangeFitting.h" #include "DbText.h" #include "TGripImp.h" extern void DrawWeight(XExplodeDraw &dc,double dWeight,XCurveSegment &seg,int nColorIndex, double nScale); Adesk::Boolean acedPostCommand(const TCHAR * ); ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// TWT_GRIPAPPDATA TDbDoubleLinePipe::s_gripAppData[GRIP_MAXNUM_DBPIPE_DBPIPE]; ACRX_DXF_DEFINE_MEMBERS(ATSDoubleLinePipe, ATSPipe, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, ATS_DOUBLELINEPIPE, "ATS_DOUBLELINEPIPE图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com"); IMPLEMENT_TENTBASE(TDbDoubleLinePipe); const Adesk::UInt8 TDbDoubleLinePipe::g_nVersion = 2; TDbDoubleLinePipe::TDbDoubleLinePipe() { m_nWidth = 800; } TDbDoubleLinePipe::~TDbDoubleLinePipe() { } Acad::ErrorStatus TDbDoubleLinePipe::subGetClassID(CLSID* pClsid) const { return Acad::eOk; } void TDbDoubleLinePipe::CopyPropertiesFrom(AcDbEntity *pSrc,unsigned gMatchFlag) { assertWriteEnabled(); TDbPipe::CopyPropertiesFrom(pSrc, gMatchFlag); TDbDoubleLinePipe *pPipe = TDbDoubleLinePipe::cast(pSrc); if(pPipe) { m_nWidth = pPipe->m_nWidth; } } Acad::ErrorStatus TDbDoubleLinePipe::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=TDbPipe::subGetOsnapPoints(osnapMode, gsSelectionMark, ptPick, lastPoint, viewXform, snapPoints, geomIds); // 支持两边线的捕捉 cet 2011.8.18 add if (es != Acad::eOk) { return es; } XPoint ptS = GetStartPoint(), ptE = GetEndPoint(); AcGeVector3d vt = ptS - ptE; vt.normalize(); vt.rotateBy(PI/2, AcGeVector3d::kZAxis); AcDbLine line1(ptS + vt * m_nWidth * 0.5, ptE + vt * m_nWidth * 0.5); es = line1.getOsnapPoints(osnapMode, gsSelectionMark, ptPick, lastPoint, viewXform, snapPoints, geomIds); if (es != Acad::eOk) { return es; } AcDbLine line2(ptS - vt * m_nWidth * 0.5, ptE - vt * m_nWidth * 0.5); es = line2.getOsnapPoints(osnapMode, gsSelectionMark, ptPick, lastPoint, viewXform, snapPoints, geomIds); return es; } // 取得所有的夹点 Acad::ErrorStatus TDbDoubleLinePipe::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const { assertReadEnabled(); Acad::ErrorStatus es=Acad::eOk; es=TDbPipe::subGetGripPoints(gripPoints, osnapModes, geomIds); // cet 2012.11.16 add 立管不添加启动绘制命令 if(IsVertical()) { return es; } // cet 2012.11.7 add 对夹点类型进行区分并添加命令夹点 int nSize = gripPoints.length(); for(int i = 0; i < nSize; i++) { s_gripAppData[i].bCmd = false; } // 命令夹点 XPoint ptS = StartPoint(); XPoint ptE = EndPoint(); AcGeVector3d vt = ptS - ptE; vt.normalize(); double dLen = PixelToWcs(20); gripPoints.append(ptS + vt * dLen); s_gripAppData[nSize].bCmd = true; s_gripAppData[nSize].ptGrip = ptS; s_gripAppData[nSize].id = objectId(); gripPoints.append(ptE - vt * dLen); s_gripAppData[nSize + 1].bCmd = true; s_gripAppData[nSize + 1].ptGrip = ptE; s_gripAppData[nSize + 1].id = objectId(); // 中心点处添加启动命令 AcDbLine line(ptS, ptE); XPoint ptPrj, ptLabel = m_ptLabel; line.getClosestPointTo(ptLabel, ptPrj, Adesk::kTrue); AcGeVector3d vtDir; if (ptLabel.Distance2d(ptPrj) > 0.001) { vtDir = ptPrj - ptLabel; vtDir.z = 0.0; } else { vtDir = ptE - ptS; vtDir.z = 0.0; vtDir.rotateBy(PI / 2, AcGeVector3d::kZAxis); } vtDir.normalize(); XPoint ptMid, ptCmd; line.getPointAtDist(ptS.Distance(ptE) * 0.5, ptMid); ptCmd = ptMid; ptCmd.z = StartPoint().z; double dDn = GetDnDiameter(); if (DocGetCurMeterUnitDraw()) { dDn *= 0.001; } ptCmd += vtDir * dDn * 1.1; gripPoints.append(ptCmd); s_gripAppData[nSize + 2].bCmd = true; s_gripAppData[nSize + 2].ptGrip = ptMid; s_gripAppData[nSize + 2].id = objectId(); return es; } // 取得夹点说明 Acad::ErrorStatus TDbDoubleLinePipe::GetGripText(int idx, CString &cs) const { Acad::ErrorStatus es=Acad::eOk; // cet 2012.11.7 add 处理命令夹点 if (s_gripAppData[idx].bCmd) { cs = _T("启动绘制"); return es; } es = TDbPipe::GetGripText(idx,cs); return es; } // 从DWG读入数据: Acad::ErrorStatus TDbDoubleLinePipe::dwgInFields(AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = TDbPipe::dwgInFields(pFiler); if(es != Acad::eOk) return es; Adesk::UInt8 nVer; pFiler->readItem(&nVer); if(nVer>g_nVersion) {// Version is too new return Acad::eMakeMeProxy; } pFiler->readItem(&m_nWidth); pFiler->readItem(&m_nRate); pFiler->readItem(&m_iFlange); pFiler->readItem(&m_nFlangeDn); pFiler->readItem(&m_nFlangeThick); pFiler->readItem(&m_nSpare); if(nVer > 1) pFiler->readItem(&m_idDoteLayer); else m_idDoteLayer = ::InitLayer(_T("0"), database()); return pFiler->filerStatus(); } Acad::ErrorStatus TDbDoubleLinePipe::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = TDbPipe::dwgOutFields(pFiler); if(es != Acad::eOk) return es; pFiler->writeItem(g_nVersion); pFiler->writeItem(m_nWidth); pFiler->writeItem(m_nRate); pFiler->writeItem(m_iFlange); pFiler->writeItem(m_nFlangeDn); pFiler->writeItem(m_nFlangeThick); pFiler->writeItem(m_nSpare); pFiler->writeItem(m_idDoteLayer); return pFiler->filerStatus(); } Acad::ErrorStatus TDbDoubleLinePipe::dxfInFields(AcDbDxfFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es=Acad::eOk; es=TDbPipe::dxfInFields(pFiler); if(es!=Acad::eOk) return es; if (!pFiler->atSubclassData(_T("TDbDoubleLinePipe"))) { return Acad::eBadDxfSequence; } resbuf rb; while((es==Acad::eOk) && ((es=pFiler->readResBuf(&rb))==Acad::eOk)) { switch (rb.restype) { case AcDb::kDxfXReal: m_nWidth=rb.resval.rreal; break; default: pFiler->pushBackItem(); es = Acad::eEndOfFile; break; } } if(es!=Acad::eEndOfFile) return Acad::eInvalidResBuf; return pFiler->filerStatus(); } Acad::ErrorStatus TDbDoubleLinePipe::dxfOutFields(AcDbDxfFiler* pFiler) const { Acad::ErrorStatus es=Acad::eOk; es=TDbPipe::dxfOutFields(pFiler); assert(es==Acad::eOk); es=pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbDoubleLinePipe")); assert(es==Acad::eOk); pFiler->writeDouble(AcDb::kDxfXReal, m_nWidth); return es; } void TDbDoubleLinePipe::ResetDrawSpeed() { assertWriteEnabled(); double dSpeedLength=0, dSpeedSubMid=0;//初始化 // cet 2012.11.2 add XCurveSegment cv=GetCurve(); double dPipeLen = cv.GetLength(); 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; } // cet 2012.11.2 add 双线水管连接fitting并且通过变径连接 int nNum = pNode->GetInterfaceNum(); TDbFlangeFitting *pFitting = (TDbFlangeFitting*)pNode; if (nNum > 2 && pFitting != NULL) // 三通 四通 { for (int i = 0; i < nNum; i ++) { const TPipeInterface &face = pFitting->GetInterface(i); if (face.m_idPipe == objectId()) { XPoint ptS = StartPoint(); XPoint ptE = EndPoint(); XPoint ptLoc = pFitting->GetLocation(); double dFlangeDn = 0.0, dFlangeThick = 0.0; if (ptS.Distance(ptLoc) < 0.001 && IsLinkReducing(0)) // 起点连接变径 { if (pFitting->GetWidth(objectId(), dWidth, dFlangeDn, dFlangeThick)) { dWidth = dWidth > GetWidth() ? dWidth : GetWidth(); if (DocGetCurMeterUnitDraw()) { dWidth *= 0.001; } if (dPipeLen + dSpeedLength > dWidth) { dSpeedLength -= dWidth; dSpeedSubMid += dWidth/2; } else { SetLinkReducing(0, false); } } } else if (ptE.Distance(ptLoc) < 0.001 && IsLinkReducing(1)) // 终点连接变径 { if (pFitting->GetWidth(objectId(), dWidth, dFlangeDn, dFlangeThick)) { dWidth = dWidth > GetWidth() ? dWidth : GetWidth(); if (DocGetCurMeterUnitDraw()) { dWidth *= 0.001; } if (dPipeLen + dSpeedLength > dWidth) { dSpeedLength -= dWidth; dSpeedSubMid -= dWidth/2; } else { SetLinkReducing(1, false); } } } break; } } } } } 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; } // cet 2012.11.2 add 双线水管连接fitting并且通过变径连接 int nNum = pNode->GetInterfaceNum(); TDbFlangeFitting *pFitting = (TDbFlangeFitting*)pNode; if (nNum > 2 && pFitting != NULL) // 三通 四通 { for (int i = 0; i < nNum; i ++) { const TPipeInterface &face = pFitting->GetInterface(i); if (face.m_idPipe == objectId()) { XPoint ptS = StartPoint(); XPoint ptE = EndPoint(); XPoint ptLoc = pFitting->GetLocation(); double dFlangeDn = 0.0, dFlangeThick = 0.0; if (ptS.Distance(ptLoc) < 0.001 && IsLinkReducing(0)) // 起点连接变径 { if (pFitting->GetWidth(objectId(), dWidth, dFlangeDn, dFlangeThick)) { dWidth = dWidth > GetWidth() ? dWidth : GetWidth(); if (DocGetCurMeterUnitDraw()) { dWidth *= 0.001; } if (dPipeLen + dSpeedLength > dWidth) { dSpeedLength -= dWidth; dSpeedSubMid += dWidth/2; } else { SetLinkReducing(0, false); } } } else if (ptE.Distance(ptLoc) < 0.001 && IsLinkReducing(1)) // 终点连接变径 { if (pFitting->GetWidth(objectId(), dWidth, dFlangeDn, dFlangeThick)) { dWidth = dWidth > GetWidth() ? dWidth : GetWidth(); if (DocGetCurMeterUnitDraw()) { dWidth *= 0.001; } if (dPipeLen + dSpeedLength > dWidth) { dSpeedLength -= dWidth; dSpeedSubMid -= dWidth/2; } else { SetLinkReducing(1, false); } } } break; } } } } } OPENOBJ_END(); if(fabs(dSpeedLength)>1.0E-3 || fabs(dSpeedSubMid)>1.0E-3) { XCurveSegment cv=GetCurve(); cv.SetElevation(0);//设置为二维,z=0 double dLength = cv.GetLength(); m_dSpeedLength = dLength + dSpeedLength; m_dSpeedSubMid = dLength/2 + dSpeedSubMid; } else { m_dSpeedLength = 0; m_dSpeedSubMid = 0; } } void TDbDoubleLinePipe::DisposeBreak(const XCurveSegment &cv, AcGePoint3dArray &arPoint,const XPoint &ptLoc,double dWidth, double dDistance,const AcGeVector3d &vtDir, DList &lstBreakCurve) const { TDbPipe::DisposeBreak(cv, arPoint, ptLoc, dWidth, dDistance, vtDir, lstBreakCurve); return; } // 通过管件附件打断的曲线,二维,z=0 void TDbDoubleLinePipe::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(20);//裁剪的点 DList lstLocation; DList lstBreakCurve; double dDisThis = cv.GetLength(); // 直线段时 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()); cv.ProjectToMe(ptLocation, ptLocation);//2008-4-21 sr add 双线管2边线, 必须重新计算位置点 ptLocation.z=0; lstLocation.Append(new XPoint(ptLocation)); DisposeBreak(cv,arPoint,ptLocation,dWidth,dDisThis,vtAttachment, lstBreakCurve); } } OPENOBJ_END(); } // 管线的遮挡关系 for(int k=0; kGetBreakWidth()/2;//打断间距,如果是单线管,读取系统变量,如果是双线管,按管径。 sr 20061218 if(pPipe->isKindOf(TDbDoubleLinePipe::desc())){ 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; cvPipe.SetElevation(0);//设置标高为0 if(cv.Intersection(cvPipe,ptIntersect,ptTemp)) { // if(fabs(StartPoint().z - EndPoint().z) < 0.01) // 2008-4-21 sr del 双线管2边线, 不能把交点又重新定位到中心线上 // 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){ AcGeMatrix3d mat; mat.setToScaling(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;j1.0E-3 && fabs(m_dSpeedSubMid)>1.0E-3) { double dChordLength = cvHideTemp.GetChordLength(m_dSpeedLength); XPointDir2d ptSubMid; cvHideTemp.Polar(m_dSpeedSubMid,ptSubMid); cvHideTemp.GetSubSegment(ptSubMid,dChordLength,cvHide); return; } cvHide = cvHideTemp; } // 绘制平面立管 Acad::ErrorStatus TDbDoubleLinePipe::DrawVerPipe2d(XExplodeDraw &dc) const { XVector3D vtDirection(1,0,0); BOOL bVerOpened=IsVerOpened() && GetVerOpenDir(vtDirection);//扣弯 // cet 2012.10.19 add double dMeter = 1.0; if (DocGetCurMeterUnitDraw()) { dMeter = 0.001; } BOOL bIsWeight = IsPsLineWeight(this->database()); // cet 2016.9.26 add 获取实体所在数据库数据 if(bVerOpened) {//绘制扣弯 XPoint ptCenter(GetStartPoint().x, GetEndPoint().y); double dAngle = ads_angle(XPoint(),vtDirection); double dStartAngle = CT_std_angle(dAngle+PI/2); double dEndAngle = CT_std_angle(dAngle+PI*3/2); // cet 2012.10.19 modify 支持米单位 // XArc arc(ptCenter,m_nWidth/2,dStartAngle,dEndAngle); XArc arc(ptCenter,m_nWidth * dMeter / 2,dStartAngle,dEndAngle); //cet 2011.11.9 modify 未考虑加粗 //dc << arc; if (bIsWeight) { XCurveSegment seg; seg = arc; double dWeight = GetPScale()*m_dPipeWeight; // cet 2012.10.19 modify 支持米单位 if (DocGetCurMeterUnitDraw()) { dWeight = GetPScale()*m_dPipeWeight * 0.1; } double nScale = linetypeScale(); DrawWeight(dc,dWeight,seg,colorIndex(), nScale); } else { dc << arc; } if(m_iFlange == 0){//法兰连接 dStartAngle = CT_std_angle(dAngle+PI/4); dEndAngle = CT_std_angle(dAngle+PI*7/4); // cet 2012.10.19 modify 支持米单位 // XArc arc2(ptCenter,m_nFlangeDn/2,dStartAngle,dEndAngle); XArc arc2(ptCenter,m_nFlangeDn * dMeter / 2,dStartAngle,dEndAngle); //cet 2011.11.9 modify 未考虑加粗 //dc << arc2; if (bIsWeight) { XCurveSegment seg; seg = arc2; double dWeight = GetPScale()*m_dPipeWeight; // cet 2012.10.19 modify 支持米单位 if (DocGetCurMeterUnitDraw()) { dWeight = GetPScale()*m_dPipeWeight * 0.1; } double nScale = linetypeScale(); DrawWeight(dc,dWeight,seg,colorIndex(), nScale); } else { dc << arc2; } } } else { XPoint ptCenter(GetStartPoint().x, GetEndPoint().y); XCircle cirOut(ptCenter,m_nWidth * dMeter / 2); // cet 2012.10.19 modify 支持米单位 dc << cirOut; if(m_iFlange == 0){//法兰连接 XCircle cirOut2(ptCenter,m_nFlangeDn * dMeter / 2); // cet 2012.10.19 modify 支持米单位 //cet 2011.11.9 modify 未考虑加粗 //dc << cirOut2; if (bIsWeight) { XCurveSegment seg; seg = cirOut2; double dWeight = GetPScale() * m_dPipeWeight; // cet 2012.10.19 modify 支持米单位 if (DocGetCurMeterUnitDraw()) { dWeight = GetPScale()*m_dPipeWeight * 0.1; } double nScale = linetypeScale(); DrawWeight(dc,dWeight,seg,colorIndex(), nScale); } else { dc << cirOut2; } } } return Acad::eOk; } Acad::ErrorStatus TDbDoubleLinePipe::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; XAcGiViewDraw &viewDraw = (XAcGiViewDraw &)dc; //垂直管线 XVector3D vtLocation=EndPoint()-StartPoint(); if(fabs(vtLocation.x)<1.0E-6 && fabs(vtLocation.y)<1.0E-6) { //垂直管线 DrawVerPipe2d(dc); return Acad::eOk; } XCurveSegment cvHide=GetCurve();//二维,z=0 XPoint ptS = cvHide.StartPoint(); XPoint ptE = cvHide.EndPoint(); if(!IsShowPropertyText()) GetHideCurve(cvHide); //动态预览 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(4); } //绘制双线水管中心线 DList lstCurve; GetBrokenCurves(cvHide, lstCurve); int nCount = lstCurve.Length(); //2008-5-28 指定中心线图层,从而改变中心线的线形,这种方法不对,打印的时候仍然是实线 // SR 修改如下: 读取图层的线形,强制设置dc的线形,同时取消中心线图层 // 对于炸开,仍然采用图层 if(_tcsicmp(dc.Desc(), XExplodeStream::Descriptor())==0) { //另存旧版,炸开 2图层 AcDbObjectId idLayerOld=dc.GetLayerId(); AcDbObjectId idDoteLayer=m_idDoteLayer; if(idDoteLayer.isValid()) dc.SetLayer(idDoteLayer); dc.SetColorLayer(colorIndex(), idDoteLayer); for (int i=0; ilinetypeObjectId(); // 单独设置了中心线线型 cet 2018.7.10 add AcDbObjectId idTemp = MidLinetypeId(false); if (idTemp.isValid()) { idLineType = idTemp; } AcCmColor Color = pLayer->color(); int iColIdx = Color.colorIndex(); dc.SetColor(iColIdx); dc.SetLineType(idLineType); } OPENOBJ_END(); for (int i=0; i lstCurve1; DList lstCurve2; XCurveSegment segUp, segDown; XDirectionCurve segDir(cvHide.GetStartPoint(), cvHide.GetEndPoint(), cvHide.GetBulge()); // cet 2012.10.19 modify 支持米单位 // segUp = segDir.Offset(m_nWidth/2, LS_FINITE); // segDown = segDir.Offset(-m_nWidth/2, LS_FINITE); double dWidth = m_nWidth; if (DocGetCurMeterUnitDraw()) { dWidth *= 0.001; } segUp = segDir.Offset(dWidth/2, LS_FINITE); segDown = segDir.Offset(-dWidth/2, LS_FINITE); //绘制双线水管上线 BOOL bIsWeight = IsPsLineWeight(this->database()); // cet 2016.9.26 add 获取实体所在数据库数据 GetBrokenCurves(segUp, lstCurve1); double dWeight = GetPScale()*m_dPipeWeight; // cet 2012.10.19 modify 支持米单位 if (DocGetCurMeterUnitDraw()) { dWeight = GetPScale()*m_dPipeWeight * 0.1; } for (int i=0; i16.01 && g_nAcadVer<17) //在ACAD2006下,如果开1个三维视口,再打开一个新视口,如果设置其为平面,就崩溃(管线粗线) // dc.SetSelectionMarker(1); // if(!dc.IsFullExplode()){ // //如果是动态预演,则简单绘制 // 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(GetStartPoint(), dPipeDiameter/2); XCurveSegment seg2; seg2 = cir; seg2.AsPoly2D(polyShape); AcGeVector3d v3(0,0,1); //绘制3维管道的时候,两边都缩50,目的是留给节点位置 XPoint pt1(GetStartPoint()), pt2(GetEndPoint()), ptTmp(GetStartPoint()); ptTmp.x += dPipeDiameter; XVector3D vtDir(EndPoint() - StartPoint()); XVector3D vtDir2(ptTmp - StartPoint()); //如果管端接设备,则不用缩 AcDbObjectId nodeId1(NULL), nodeId2(NULL); nodeId1 = GetNode(0); nodeId2 = GetNode(1); OPENOBJ_BEGIN(nodeId1, AcDb::kForRead, TDbPipeFitting, pNode); if(pNode){ int num = pNode->GetInterfaceNum(); if(num > 1){ double dWidth = pNode->GetWidth(this); vtDir.Normalize(); vtDir.Scale(dWidth); if(pNode->GetLocation() == StartPoint()) pt1 += vtDir; else pt2 -= vtDir; // cet 2012.11.5 add TDbFlangeFitting *pFitting = (TDbFlangeFitting*)pNode; if (IsLinkReducing(0) && pFitting != NULL) { double dWidth = 0.0; double dFlangeDn = 0.0; double dFlangeThick = 0.0; double dPipeDn = 0.0; if (pFitting->GetWidth(objectId(), dWidth, dFlangeDn, dFlangeThick, &dPipeDn)) { double dLen = dWidth > GetWidth() ? dWidth : GetWidth(); if (DocGetCurMeterUnitDraw()) { dLen *= 0.001; } AcGeVector3d vt = vtDir; vt.normalize(); pt1 += vt * dLen; } } } } OPENOBJ_END(); OPENOBJ_BEGIN(nodeId2, AcDb::kForRead, TDbPipeFitting, pNode); if(pNode){ int num = pNode->GetInterfaceNum(); if(num > 1){ double dWidth = pNode->GetWidth(this); vtDir.Normalize(); vtDir.Scale(dWidth); if(pNode->GetLocation() == StartPoint()) pt1 += vtDir; else pt2 -= vtDir; // cet 2012.11.5 add TDbFlangeFitting *pFitting = (TDbFlangeFitting*)pNode; if (IsLinkReducing(1) && pFitting != NULL) { double dWidth = 0.0; double dFlangeDn = 0.0; double dFlangeThick = 0.0; double dPipeDn = 0.0; if (pFitting->GetWidth(objectId(), dWidth, dFlangeDn, dFlangeThick, &dPipeDn)) { double dLen = dWidth > GetWidth() ? dWidth : GetWidth(); if (DocGetCurMeterUnitDraw()) { dLen *= 0.001; } AcGeVector3d vt = vtDir; vt.normalize(); pt2 -= vt * dLen; } } } } OPENOBJ_END(); //////////////////////////////////////////////////// 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; // cet 2012.10.19 modify 支持米单位 // if(polyShape.Area()<0.1) // return Acad::eOk; double dArea = 0.1; if (DocGetCurMeterUnitDraw()) { dArea *= 0.001; } if (polyShape.Area() < dArea) { return Acad::eOk; } TDbCurveMesh cvMesh; cvMesh.SetNormal(v3);//法向 cvMesh.SetBasePoly(polyBase); cvMesh.SetShapePoly(polyShape); cvMesh.SetShapeBase(GetStartPoint()); if(cvMesh.IsValid()) { if(dc.IsFullExplode()) cvMesh.ExplodeOrDraw3d(dc); else dc.DrawEntity(cvMesh); } return Acad::eOk; } // 自动增加节点到当前数据库,ids-该节点自动连接的管线,派生类应当重载 AcDbObjectId TDbDoubleLinePipe::AddAutoNodeToDb(const XPoint &ptAt, const DList &ids) const { AcDbObjectId id; if(ids.Length()) { TDbFlangeFitting *pFitting = new TDbFlangeFitting; pFitting->UpdateLinkage(ptAt, GetSysType(), ids); TCHAR *layer; layer = this->layer(); TCHAR szLayer[256]; _tcscpy(szLayer, layer); pFitting->SetNumber(XString(_T("%.1f"), m_nRate)); pFitting->SetDoteLayer(m_idDoteLayer); pFitting->setLayer(szLayer); id=AddToCurrentSpace(pFitting, Adesk::kTrue); delete []layer; } return id; } //取动态属性显示数据 void TDbDoubleLinePipe::GetTips(DList &lstInfo) const { if(IsHorizontal()) { lstInfo.Append(new TObjInfoUnit(_T("标高"), Dist2Str(GetStartPoint().z))); } else { lstInfo.Append(new TObjInfoUnit(_T("起点标高"), Dist2Str(GetStartPoint().z))); lstInfo.Append(new TObjInfoUnit(_T("终点标高"), Dist2Str(GetEndPoint().z))); } double nDist=0.0; getDistAtPoint(EndPoint(), nDist); lstInfo.Append(new TObjInfoUnit(_T("长度"), Dist2Str(nDist))); CString csFlange; if(m_iFlange == 0) csFlange = _T("法兰连接"); else if(m_iFlange == 1) csFlange = _T("焊接连接"); lstInfo.Append(new TObjInfoUnit(_T("管径"), Dist2Str(m_nWidth))); lstInfo.Append(new TObjInfoUnit(_T("弯头曲率"), Dist2Str(m_nRate))); lstInfo.Append(new TObjInfoUnit(_T("连接形式"), (const TCHAR*)csFlange)); if(m_iFlange == 0){ lstInfo.Append(new TObjInfoUnit(_T("法兰直径"), Dist2Str(m_nFlangeDn))); lstInfo.Append(new TObjInfoUnit(_T("法兰厚度"), Dist2Str(m_nFlangeThick))); } lstInfo.Append(new TObjInfoUnit(_T("系统类型"), GetPipeSystemName())); } Acad::ErrorStatus TDbDoubleLinePipe::subClose() { Acad::ErrorStatus es = TDbPipePrototype::subClose(); if(es==Acad::eOk && isModified() && database()==acdbCurDwg()) { // 修改管径时同时修改阀门比例 // cet 2012.8.30 add AcDbObjectId idBlock1 = GetBlockIdFromString(_T("$valve$00000547")); AcDbObjectId idBlcok2 = GetBlockIdFromString(_T("$VALVE$00000553")); for(int i=0;iGetScale(); double nTmp = m_nWidth - nScale; if(fabs(nScale - m_nWidth) > 0.001){ if(pAttach->upgradeOpen()==Acad::eOk) { pAttach->assertWriteEnabled(); //pAttach->SetYScale(m_nWidth); // cet 2012.8.30 add 双线水管通过套管插入关联附件时,需单独处理比例系数 AcDbObjectId id = pAttach->GetBlock2d(); if (id == idBlock1 || id == idBlcok2) { //double dDn = GetDnDiameter(); //double dYScale = pAttach->GetScale(); // dYScale *= (dDn / 80) * (DocGetPScale() / 100); // 观察所得比例值,不一定准确 //pAttach->SetYScale(dYScale); } else { pAttach->SetYScale(m_nWidth); } // pAttach->SetFlangeDn(pAttach->GetFlangeDn()+nTmp); pAttach->downgradeOpen(); } } } OPENOBJ_END(); } } return es; } // 功能: 夹点操作 Acad::ErrorStatus TDbDoubleLinePipe::subMoveGripPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset) { assertWriteEnabled(); Acad::ErrorStatus es=Acad::eOk; int nCount=indices.length(); int idx = indices[0]; // cet 2012.11.7 add 处理命令夹点 if (s_gripAppData[idx].bCmd) { SetGripCmdData(s_gripAppData[idx].ptGrip, s_gripAppData[4].id); acedPostCommand(_T("\3\3hsxg\n")); return es; } if(idx == 2 && !IsVertical() && Is(CURVE_LINE)){ //es=MoveGSPointsAt(indices,offset,TRUE); cet 2011.5.13 modify 平移时限制在垂直管线方向平移 XPoint ptMid = MidPoint(); AcGeVector3d vt = StartPoint() - EndPoint(); vt.rotateBy(PI / 2, AcGeVector3d::kZAxis); XLine line(ptMid, ptMid + vt); XPoint pt; (ptMid + offset).Project(&line, pt); es=MoveGSPointsAt(indices,pt - ptMid,TRUE); } else es=TDbPipePrototype::subMoveGripPointsAt(indices, offset); if(es!=Acad::eOk) return es; return es; } Acad::ErrorStatus TDbDoubleLinePipe::MoveGSPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset, BOOL bGrip) { Acad::ErrorStatus es=Acad::eOk; AcGeVector3d vtOffset=offset; AcGeMatrix3d mat; mat.setToTranslation(vtOffset); BOOL bApply=objectId().isValid(); AcGeVector3d vtPipe(GetEndPoint() - GetStartPoint()); XPoint ptStartOld = StartPoint(); XPoint ptEndOld = EndPoint(); Transform(mat, bApply,bGrip); if(bApply == NULL || !vtOffset.isPerpendicularTo(vtPipe)) //如果平移向量不垂直于管线,就返回 return es; XLine line(StartPoint(), EndPoint()); // cet 2011.5.23 add //联动修改所接管线 AcDbObjectId id1 = GetNode(0); AcDbObjectId id2 = GetNode(1); OPENOBJ_BEGIN(id1,AcDb::kForRead,TDbPipeNode,pNode); if(pNode!=NULL) { // 节点 if(pNode->IsAutoLiving()){ // 需自动生成的节点 if(pNode->GetInterfaceNum() == 2){ XPoint ptLoc = pNode->GetLocation(); for(int j=0; j<2; j++) { // 接口 const AcDbObjectId &idPipe=pNode->GetIPipe(j); if(idPipe != objectId()) { XPoint ptStart, ptEnd; OPENOBJ_BEGIN(idPipe,AcDb::kForWrite,TDbDoubleLinePipe,pPipe); if(pPipe != NULL && !pPipe->IsVertical()) { ptStart = pPipe->StartPoint(); ptEnd = pPipe->EndPoint(); // cet 2011.5.23 modify 求管线交点 // if(ptLoc == ptStart){ // XPoint ptOffset=ptStart+offset; // pPipe->SetStartPoint(ptOffset); // } // else if(ptLoc == ptEnd){ // XPoint ptOffset=ptEnd+offset; // pPipe->SetEndPoint(ptOffset); // } XLine line1(ptStart, ptEnd); XPoint pt; line1.Intersection(&line,pt); if (!!pt) { if (ptLoc == ptStart) { pPipe->SetStartPoint(pt); } else { pPipe->SetEndPoint(pt); } if (ptLoc == ptStartOld) { SetStartPoint(pt); } else { SetEndPoint(pt); } } } OPENOBJ_END(); } } } } } OPENOBJ_END(); //同上,代码直接COPY OPENOBJ_BEGIN(id2,AcDb::kForRead,TDbPipeNode,pNode); if(pNode!=NULL) { // 节点 if(pNode->IsAutoLiving()){ // 需自动生成的节点 if(pNode->GetInterfaceNum() == 2){ XPoint ptLoc = pNode->GetLocation(); for(int j=0; j<2; j++) { // 接口 const AcDbObjectId &idPipe=pNode->GetIPipe(j); if(idPipe != objectId()) { XPoint ptStart, ptEnd; OPENOBJ_BEGIN(idPipe,AcDb::kForWrite,TDbDoubleLinePipe,pPipe); if(pPipe != NULL && !pPipe->IsVertical()) { ptStart = pPipe->StartPoint(); ptEnd = pPipe->EndPoint(); // cet 2011.5.23 modify 求管线交点 // if(ptLoc == ptStart){ // XPoint ptOffset=ptStart+offset; // pPipe->SetStartPoint(ptOffset); // } // else if(ptLoc == ptEnd){ // XPoint ptOffset=ptEnd+offset; // pPipe->SetEndPoint(ptOffset); // } XLine line1(ptStart, ptEnd); XPoint pt; line1.Intersection(&line,pt); if (!!pt) { if (ptLoc == ptStart) { pPipe->SetStartPoint(pt); } else { pPipe->SetEndPoint(pt); } if (ptLoc == ptStartOld) { SetStartPoint(pt); } else { SetEndPoint(pt); } } } OPENOBJ_END(); } } } } } OPENOBJ_END(); return es; } void TDbDoubleLinePipe::SetMidLinetype(const AcDbObjectId &idLinetype) { assertWriteEnabled(); TEntityFields &fd = Fields(); fd.SFD(_T("MINLINE_LINETYPE"), AcDbSoftPointerId(idLinetype)); } void TDbDoubleLinePipe::SetMidLinetype(const CString &sLinetypeName) { assertWriteEnabled(); TEntityFields &fd = Fields(); // 线型未随层 if (sLinetypeName.CompareNoCase(_T("BYLAYER")) != 0) { AcDbObjectId idLinetype = GetLinetypeIdFromString(sLinetypeName, this->database()); if (idLinetype.isValid()) // 设置新线型 { fd.SFD(_T("MINLINE_LINETYPE"), AcDbSoftPointerId(idLinetype)); return; } } // 随层 int nIndex = fd.Find(_T("MINLINE_LINETYPE")); if (nIndex != -1) { fd.Del(nIndex); } } AcDbObjectId TDbDoubleLinePipe::MidLinetypeId(bool bLayerWhenNotFound) const { assertReadEnabled(); AcDbSoftPointerId idRet = AcDbSoftPointerId::kNull; const TEntityFields &fd = GetFields(); if (!fd.GFD(_T("MINLINE_LINETYPE"), idRet) && bLayerWhenNotFound) { OPENOBJ_BEGIN(m_idDoteLayer, AcDb::kForRead, AcDbLayerTableRecord, pLayer); if(pLayer != NULL) { idRet = pLayer->linetypeObjectId(); } OPENOBJ_END(); } return idRet; } CString TDbDoubleLinePipe::MidLinetype() const { CString sRet = _T("BYLAYER"); AcDbObjectId id = MidLinetypeId(false); AcDbLinetypeTableRecord *pRec = NULL; acdbOpenObject(pRec, id, AcDb::kForRead); if (pRec != NULL) { TCHAR *pszName = NULL; pRec->getName(pszName); sRet = pszName; pRec->close(); } return sRet; } CString TDbDoubleLinePipe::GetPipeSystemName() const { CString sName = TDbPipe::GetPipeSystemName(); // 5.0以前版本(4.0、3.0 ...)没有划分系统,现在固定为双管系统 // 便于兼容旧版本双线水管 if (sName.IsEmpty()) { sName = _T("双管"); } return sName; } bool TDbDoubleLinePipe::IsLinkReducing( int nSide ) const { assertReadEnabled(); Adesk::Boolean bLink = Adesk::kFalse; const TEntityFields &fd = GetFields(); if (nSide == 0) // 起点 { fd.GFD(_T("StartLinkReduce"), bLink); } else if (nSide == 1) // 终点 { fd.GFD(_T("EndLinkReduce"), bLink); } return bLink ? true : false; } void TDbDoubleLinePipe::SetLinkReducing( int nSide, bool bLink ) { assertWriteEnabled(); TEntityFields &fd = Fields(); if (nSide == 0) // 起点 { bool bst = fd.SFD(_T("StartLinkReduce"), bLink ? Adesk::kTrue : Adesk::kFalse); } else if (nSide == 1) // 终点 { bool bst = fd.SFD(_T("EndLinkReduce"), bLink ? Adesk::kTrue : Adesk::kFalse); } } void TDbDoubleLinePipe::ExplainGripIndex( int nIndex, bool &bCmd, CString &sTip ) const { bCmd = s_gripAppData[nIndex].bCmd; GetGripText(nIndex, sTip); } #if ADS > 15 Acad::ErrorStatus TDbDoubleLinePipe::subGetGripPoints( AcDbGripDataPtrArray& grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d& curViewDir, const int bitflags ) const { assertReadEnabled(); AcDbIntArray osnapModes; AcDbIntArray geomIds; AcGePoint3dArray gripPoints; Acad::ErrorStatus eSta = subGetGripPoints(gripPoints,osnapModes,geomIds); CString sGripTip; for (int i = 0;i < gripPoints.length() && i < GRIP_MAXNUM_DBPIPE_DBPIPE; i++) { bool bCmd = false; ExplainGripIndex(i, bCmd, sGripTip); s_gripAppData[i].nIndex = i; s_gripAppData[i].sGripTip = sGripTip; AcDbGripData *pGripData = new AcDbGripData; pGripData->setAppData((void*)&s_gripAppData[i]); pGripData->setGripPoint(gripPoints.at(i)); // 命令夹点重绘夹点样式 if (bCmd) { pGripData->setWorldDraw(GripCback::WorldDrawfunc); } pGripData->setToolTipFunc(GripCback::GripToolTipFunc); grips.append(pGripData); } return eSta; } Acad::ErrorStatus TDbDoubleLinePipe::subMoveGripPointsAt(const AcDbVoidPtrArray& appData, const AcGeVector3d& offset, const int bitflags) { assertWriteEnabled(); AcDbIntArray arIndex; int nSize = appData.length(); for (int i = 0;i < nSize; i++) { TWT_GRIPAPPDATA *pAppData = (TWT_GRIPAPPDATA*)appData.at(i); if (pAppData != NULL) { arIndex.append(pAppData->nIndex); } } Acad::ErrorStatus eSta = subMoveGripPointsAt(arIndex, offset); return eSta; } #endif ////////////////////////////////////////////////////////////////////////// void IniTDbDoubleLinePipe(BOOL bTrue) { if(bTrue) { TDbDoubleLinePipe::rxInit(); TDbDoubleLinePipe::InitMatchProtocol(TRUE); } else { TDbDoubleLinePipe::InitMatchProtocol(FALSE); deleteAcRxClass(TDbDoubleLinePipe::desc()); } }