#include "stdafx.h" #include #include "DbPipeFitting.h" #include "DbPipe.h" #include "DbPsConfig.h" #include "DbFlangeFitting.h" #include "PipeTools.h" #include "DbCanalFitting.h" #include "DbPipeCanal.h" #include "DbGouge.h" ACRX_DXF_DEFINE_MEMBERS(ATSPipTeFitting, ATSPipeNode, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, ATS_PIPEFITTING, "ATS_PIPEFITTING图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com"); IMPLEMENT_TENTBASE(TDbPipeFitting); const Adesk::UInt8 TDbPipeFitting::g_nVersion = 1; TDbPipeFitting::TDbPipeFitting() { m_visibility=TPipeSys::kInvisible; } void TDbPipeFitting::CopyPropertiesFrom(AcDbEntity *pSrc,unsigned gMatchFlag) { assertWriteEnabled(); TDbPipeNode::CopyPropertiesFrom(pSrc, gMatchFlag); TDbPipeFitting *pFitting = TDbPipeFitting::cast(pSrc); if(pFitting) { } } Acad::ErrorStatus TDbPipeFitting::subGetClassID(CLSID* pClsid) const { return Acad::eOk; } Acad::ErrorStatus TDbPipeFitting::subGetOsnapPoints(AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d& ptPick, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds) const { Acad::ErrorStatus es=Acad::eOk; if( osnapMode == AcDb::kOsModeIns || /*osnapMode == AcDb::kOsModeCen ||*/ osnapMode == AcDb::kOsModeNode) { snapPoints.append(m_ptLocation); } es=TDbPipeNode::subGetOsnapPoints(osnapMode,gsSelectionMark, ptPick,lastPoint,viewXform,snapPoints,geomIds); return es; } // 从DWG读入数据: Acad::ErrorStatus TDbPipeFitting::dwgInFields(AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = TDbPipeNode::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((AcGePoint3d *)&m_ptLocation); return pFiler->filerStatus(); } Acad::ErrorStatus TDbPipeFitting::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = TDbPipeNode::dwgOutFields(pFiler); if(es != Acad::eOk) return es; pFiler->writeItem(g_nVersion); pFiler->writeItem((const AcGePoint3d &)m_ptLocation); return pFiler->filerStatus(); } Acad::ErrorStatus TDbPipeFitting::dxfInFields(AcDbDxfFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es=Acad::eOk; es=TDbPipeNode::dxfInFields(pFiler); if(es!=Acad::eOk) return es; if (!pFiler->atSubclassData(_T("TDbPipeFitting"))) { return Acad::eBadDxfSequence; } return pFiler->filerStatus(); } Acad::ErrorStatus TDbPipeFitting::dxfOutFields(AcDbDxfFiler* pFiler) const { Acad::ErrorStatus es=Acad::eOk; es=TDbPipeNode::dxfOutFields(pFiler); assert(es==Acad::eOk); es=pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbPipeFitting")); assert(es==Acad::eOk); return es; } Acad::ErrorStatus TDbPipeFitting::subTransformBy(const AcGeMatrix3d& xform) { assertWriteEnabled(); TDbPipeNode::subTransformBy(xform); m_ptLocation.TransformBy(xform); return Acad::eOk; } Acad::ErrorStatus TDbPipeFitting::GetGripText(int idx, CString &cs) const { Acad::ErrorStatus es = Acad::eOk; if(IsVisible()) { if(idx==0) { cs=_T("移动节点"); } } return es; } Acad::ErrorStatus TDbPipeFitting::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const { Acad::ErrorStatus es=Acad::eOk; if(IsVisible()) { assertReadEnabled(); GetGSPoints(gripPoints); } return es; } Acad::ErrorStatus TDbPipeFitting::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const { Acad::ErrorStatus es=Acad::eOk; if(IsVisible()) { assertReadEnabled(); GetGSPoints(stretchPoints); } return es; } Acad::ErrorStatus TDbPipeFitting:: GetGSPoints(AcGePoint3dArray &stretchPoints) const { stretchPoints.append(m_ptLocation); return Acad::eOk; } Acad::ErrorStatus TDbPipeFitting:: MoveGSPointsAt(const AcDbIntArray& indices,const AcGeVector3d& offset) { AcGeMatrix3d mat; mat.setToTranslation(offset); return subTransformBy(offset); } Acad::ErrorStatus TDbPipeFitting::subMoveGripPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset) { Acad::ErrorStatus es=Acad::eOk; if(IsVisible()) { assertWriteEnabled(); es=MoveGSPointsAt(indices,offset); } return es; } Acad::ErrorStatus TDbPipeFitting::subMoveStretchPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset) { Acad::ErrorStatus es=Acad::eOk; if(IsVisible()) { assertWriteEnabled(); es=MoveGSPointsAt(indices,offset); } return es; } XPoint TDbPipeFitting::GetLocation() const { return m_ptLocation; } Acad::ErrorStatus TDbPipeFitting::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; } // cet 2016.8.17 add 方沟连接件 if (IsLinkedPipeCanal()) { TDbCanalFitting fitting(this); return fitting.ExplodeOrDraw2d(dc); } Acad::ErrorStatus es=Acad::eOk; if(m_lstInterface.Length()>0) { // 判断系统的显示属性 TPSConfig config; if(!!config) { BOOL bShow=FALSE; for(int i=0; iIsSystemShow(iFace.m_sysType); } if(!bShow) return es; } } if(m_visibility == TPipeSys::kVisible) { double nDist=1.0*GetPScale(); for(int i=0; i_distSnap) { //接口不是垂直方向 pt.z=0; double nAngOut=ads_angle(XPoint(), vt); XPoint pt1, pt2; ads_polar(pt, nAngOut+PI/2, nDist/2, pt1); ads_polar(pt, nAngOut-PI/2, nDist/2, pt2); dc << XLine(pt1, pt2); } } } else if(_tcsicmp(dc.Desc(),XAcGiViewDraw::Descriptor())==0 && !dc.IsPlotGeneration()) { AcGePoint3d pt(m_ptLocation.x,m_ptLocation.y,0); dc.DrawEntity(AcDbPoint(pt)); } return es; } // 绘制弯头 Acad::ErrorStatus DrawPolyMesh(XPoint ptSt, XPoint ptEn, double nRadius, XExplodeDraw &dc) { AcGePoint3d ptS = ptSt; AcGePoint3d ptE = ptEn; AcGeVector3d vtDirect = ptE - ptS; AcGeVector3d vtNormal = vtDirect.perpVector(); vtDirect.normalize(); double dMinAngle = PI / 15.0; int nPartNum = int(PI * 2 / dMinAngle) + 1; dMinAngle = PI * 2.0 / nPartNum; double dDiaMet = nRadius*2; AcGePoint3dArray ptArr,ptArrT,ptArrD; AcGeVector3d vtNow = vtNormal * -1; // 每组顶点法向 int i(0); for (i = 0; i < nPartNum * 2; i += 2) { ptArr.append(ptS + dDiaMet * 0.5 * vtNow); ptArr.append(ptE + dDiaMet * 0.5 * vtNow); ptArrT.append(ptS + dDiaMet * 0.5 * vtNow); ptArrT.append(ptS); ptArrD.append(ptE + dDiaMet * 0.5 * vtNow); ptArrD.append(ptE); vtNow.rotateBy(dMinAngle, vtDirect); } // 单独设置末点,防止误差 ptArr.append(ptArr.at(0)); ptArr.append(ptArr.at(1)); ptArrT.append(ptArrT.at(0)); ptArrT.append(ptArrT.at(1)); ptArrD.append(ptArrD.at(0)); ptArrD.append(ptArrD.at(1)); // 圆柱体 dc.DrawMesh(nPartNum + 1, 2, ptArr.asArrayPtr()); // 上面 dc.DrawMesh(nPartNum + 1, 2, ptArrT.asArrayPtr()); // 下面 dc.DrawMesh(nPartNum + 1, 2, ptArrD.asArrayPtr()); return Acad::eOk; // XPoly2D *polyShape1 = new XPoly2D(1); // XCircle cir1(ptS, nRadius); // XCurveSegment seg1; // seg1 = cir1; // seg1.AsPoly2D(*polyShape1); // // XPoly2D *polyShape2 = new XPoly2D(1); // XCircle cir2(ptE, nRadius); // XCurveSegment seg2; // seg2 = cir2; // seg2.AsPoly2D(*polyShape2); // // // XPoly2D polyPath;//路径 // polyPath.AppendNode(ptS); // polyPath.AppendNode(ptE); // // DList lstShapePloy; // DList lstShapeBase; // lstShapePloy.Append(polyShape1); // lstShapePloy.Append(polyShape2); // lstShapeBase.Append(new XPoint(ptS)); // lstShapeBase.Append(new XPoint(ptE)); // TDbPolyMesh cvMesh; // cvMesh.SetBasePoly(polyPath); // cvMesh.SetAllShapePolys(lstShapePloy); // cvMesh.SetAllShapeBases(lstShapeBase); //指定基点 // if(dc.IsFullExplode()) // cvMesh.ExplodeOrDraw3d(dc); // else // dc.DrawEntity(cvMesh); // return Acad::eOk; } // 绘制三维堵头,三通,四通 Acad::ErrorStatus TDbPipeFitting::Draw3dOther(XExplodeDraw &dc) const { XPoint pt1, pt2; double nDn(0); int num = GetInterfaceNum(); for(int i=0;iGetModelType() == TPipeSys::kSystem) return Acad::eOk; pCurve1 = pPipe->AsAcDbCurve(); // cet 2018.2.2 modify 通过文件查询外径,对实体绘制效率影响较大 // nDn = pPipe->GetDnDiameter(); // nDn = GetPipeOutDByDn(pPipe->GetMaterial(), nDn); nDn = pPipe->OuterDn(); } OPENOBJ_END(); if(DocGetMeterUnitDraw()) nDn = nDn / 1000.0; double nDist = nDn*1.2; double nFactor(1.0); BOOL bOk(FALSE); // mcl,changed 2010-02-03.太短时,会返回零点,所以判断下 // pt1 = GetPointAtDist(pCurve1, nDist*0.8); // pt2 = GetPointAtDist(pCurve1, nDist); bOk = GetPointAtDist(pCurve1, nDist*0.8, pt1); if (bOk) bOk = GetPointAtDist(pCurve1, nDist, pt2); if (!bOk) return Acad::eNotImplementedYet; if(pCurve1 != NULL) delete pCurve1; if(num == 1) DrawPolyMesh(m_ptLocation, pt2, nDn/2*nFactor, dc);//堵头 else { if(!!pt1) DrawPolyMesh(m_ptLocation, pt1, nDn/2*nFactor, dc); if(!!pt2) DrawPolyMesh(pt1, pt2, nDn/2*nFactor*1.1, dc); } } return Acad::eOk; } //sr add 2008-4-14 //已知1个曲线, 给定一个距离dDist, 返回距弯头m_ptLocation点dDist距离的点 // mcl changed 2010-02-03 //XPoint TDbPipeFitting::GetPointAtDist(AcDbCurve *pCurve, double dDist) const BOOL TDbPipeFitting::GetPointAtDist( AcDbCurve *pCurve, double dDist, XPoint &ptGet ) const { if(pCurve == NULL) return FALSE; XPoint ptStart, ptEnd; pCurve->getStartPoint(ptStart); pCurve->getEndPoint(ptEnd); double dDist2Elbow(0.0), dDistCalc(0.0); pCurve->getDistAtPoint(m_ptLocation, dDist2Elbow); if(ptStart == m_ptLocation) dDistCalc = dDist2Elbow + dDist; else dDistCalc = dDist2Elbow - dDist; Acad::ErrorStatus eState = pCurve->getPointAtDist(dDistCalc, ptGet); if (eState == Acad::eOk) return TRUE; return FALSE; } // 绘制三维弯头 Acad::ErrorStatus TDbPipeFitting::Draw3dElbow(XExplodeDraw &dc) const { XPoint pt1, pt2, pt3, pt4, pt5, pt6, pt7, pt8; //1 首先得到弯头连接2管线的管径 double nDn1(0), nDn2(0); BOOL bIsVer1(FALSE), bIsVer2(FALSE); TPipeSys::SysType sys1 = TPipeSys::kUnknownSys; TPipeSys::SysType sys2 = TPipeSys::kUnknownSys; AcDbCurve *pCurve1 = NULL; AcDbCurve *pCurve2 = NULL; double dPipeLen1 = 0.0, dPipeLen2 = 0.0; // cet 2011.5.27 add AcGePoint3d pts,pte,pts1,pte1; for(int i=0;i<2;i++){ TPipeInterface face; GetInterface(i, face); AcDbObjectId nextPipeId = face.m_idPipe; OPENOBJ_BEGIN(nextPipeId, AcDb::kForRead, TDbPipe, pPipe); if(pPipe){ if(pPipe->GetModelType() == TPipeSys::kSystem) return Acad::eOk; if(i == 0){ pCurve1 = pPipe->AsAcDbCurve(); nDn1 = pPipe->GetDnDiameter(); sys1 = face.m_sysType; bIsVer1 = pPipe->IsVertical(); // cet 2018.2.2 modify 通过文件查询外径,对实体绘制效率影响较大 // nDn1 = GetPipeOutDByDn(pPipe->GetMaterial(), nDn1); nDn1 = pPipe->OuterDn(); pPipe->getStartPoint(pts); pPipe->getEndPoint(pte); dPipeLen1 = pPipe->GetLength(); // cet 2011.5.27 add } else{ pCurve2 = pPipe->AsAcDbCurve(); nDn2 = pPipe->GetDnDiameter(); sys2 = face.m_sysType; bIsVer2 = pPipe->IsVertical(); // cet 2018.2.2 modify 通过文件查询外径,对实体绘制效率影响较大 // nDn2 = GetPipeOutDByDn(pPipe->GetMaterial(), nDn2); nDn2 = pPipe->OuterDn(); pPipe->getStartPoint(pts1); pPipe->getEndPoint(pte1); dPipeLen2 = pPipe->GetLength(); // cet 2011.5.27 add } } OPENOBJ_END(); } double dArea(1); if(DocGetMeterUnitDraw()) { nDn1 = nDn1 / 1000.0; nDn2 = nDn2 / 1000.0; dArea = 0.0001; } //2 得到弯头几个参数点. pt1, pt2, pt3, pt4 是中间变截面体的4个路径点, pt5&pt7, pt6&pt8是引申出2段的圆柱的起终点 nDn1 = nDn1 / 2;//转半径 nDn2 = nDn2 / 2; double nDist = nDn1; if (nDn2 > nDn1) // cet 2011.5.27 add { nDist = nDn2; } double nFactor(1); GetPointAtDist(pCurve1, nDist, pt1); GetPointAtDist(pCurve1, nDist*2, pt3); GetPointAtDist(pCurve1, nDist*3, pt5); GetPointAtDist(pCurve2, nDist, pt2); GetPointAtDist(pCurve2, nDist*2, pt4); GetPointAtDist(pCurve2, nDist*3, pt6); AcGePoint3d ptStart,ptEnd; ptStart = pt3; ptEnd = pt4; delete pCurve1; delete pCurve2; if(sys1 != sys2 && bIsVer1 && bIsVer2) return Acad::eOk; if(!pt1 || !pt2 || !pt3 || !pt4 || !pt5 || !pt6){//可能太短了,无法绘制弯头,就简化一下 if(!!pt2 && !!pt4 && !!pt6) DrawPolyMesh(pt6, m_ptLocation, nDn2*nFactor, dc); if(!!pt1 && !!pt3 && !!pt5) DrawPolyMesh(pt5, m_ptLocation, nDn1*nFactor, dc); return Acad::eOk; } AcGeVector3d vtDir1(pt1 - m_ptLocation); AcGeVector3d vtDir2(pt2 - m_ptLocation); // cet 2011.5.27 add 两管平行时单独处理 if (vtDir1.isParallelTo(vtDir2)) { return Draw3dElbow2(dc); } AcGeVector3d v3 = vtDir1.crossProduct(vtDir2); AcGeMatrix3d mat; mat.setToWorldToPlane(v3); v3.normalize(); double nAngTotal = vtDir1.angleTo(vtDir2); // if(nAngTotal > (PI - 0.001)){ //保证都是优弧 nAngTotal -= PI; nAngTotal = nAngTotal * -1; // } XPoly2D polyPath;//路径 pt7 = pt3; pt8 = pt4; if(v3 != AcGeVector3d(0, 0, 0)){ pt1.TransformBy(mat); pt2.TransformBy(mat); pt3.TransformBy(mat); pt4.TransformBy(mat); } else v3 = AcGeVector3d(0, 0, 1); polyPath.AppendNode(pt3); polyPath.AppendNode(pt1, -nAngTotal); polyPath.AppendNode(pt2); polyPath.AppendNode(pt4); if(polyPath.IsSelfIntersect()||polyPath.Area()IsSelfIntersect()||polyShape1->Area()IsSelfIntersect()||polyShape2->Area() lstShapePloy; DList lstShapeBase; lstShapePloy.Append(polyShape1); lstShapePloy.Append(polyShape2); lstShapeBase.Append(new XPoint(pt3)); lstShapeBase.Append(new XPoint(pt4)); //等径用新算法 if (fabs(nDn1 - nDn2) < 1.e-3 )//&& vtDir1.isPerpendicularTo(vtDir2) { //弯头的夹角 double dAngle = PI * 0.5; double dDiameter = nDn1 * 2; AcGePoint3d ptCorOnArc,ptCorner,ptGeCen; vtDir2.normalize(); vtDir1.normalize(); ptCorOnArc = m_ptLocation; AcGeVector3d vtDirv1,vtDirv2,vtNormal,vtCor; vtDirv1 = vtDir1; vtDirv2 = vtDir2; vtDirv1.rotateBy(PI*0.5, v3); vtDirv2.rotateBy(PI*0.5, v3); vtNormal = -v3; AcGeLine3d line1,line2; line1.set(ptStart, vtDirv1); line2.set(ptEnd, vtDirv2); //判断是否相交---找圆心 if(!line1.intersectWith(line2, ptGeCen)) return Acad::eOk; double dBigDia = ptStart.distanceTo(ptGeCen); vtCor = ptGeCen - ptCorOnArc; vtCor.normalize(); //大圆弧上一点 ptCorOnArc = ptGeCen - vtCor * dBigDia; AcGeCircArc3d circArc; circArc.set(ptStart,ptCorOnArc,ptEnd); ptGeCen = circArc.center(); AcDbVoidPtrArray arCurPtr; AcDbCircle cir; AcGePoint3dArray pts; pts.append(ptStart); pts.append(ptEnd); cir.setCenter(ptGeCen); cir.setRadius(circArc.radius()); cir.setNormal(circArc.normal()); cir.getSplitCurves(pts,arCurPtr); //根据ptStart,ptEnd将cir分成两段圆弧 int i = 0,j = 0; for (i = 0;i < arCurPtr.length();i++) { double dPar; AcDbArc * pArc = (AcDbArc*)arCurPtr.at(i); //判断ptCorner在哪一段圆弧上,并重新得到圆弧的ptStart,ptEnd if (pArc->getParamAtPoint(ptCorOnArc,dPar) == Acad::eOk) { pArc->getStartPoint(ptStart); pArc->getEndPoint(ptEnd); vtNormal = pArc->normal(); } delete pArc; } AcGeVector3d vtStr = vtDir1; AcGeVector3d vtEnd = vtDir2; dAngle = fabs(vtStr.angleTo(vtEnd)); dAngle = PI - dAngle; double dDifAng1 = 0.0,dMinDiffAng = PI / 15; //按照90°弯头分成nSect1个圆截面,每个圆截面分成nSect个点 int nSect = int(PI * 2 / dMinDiffAng); int nSect1 = int(dAngle / dMinDiffAng); vtStr.normalize(); vtEnd.normalize(); vtNormal.normalize(); //得到ptStart处的圆截面上nSect个点,使用了vtEnd做为法向量 AcGePoint3dArray arptCircle; AcGePoint3dArray arptSides; AcGePoint3d pt; pt = ptStart + vtNormal * dDiameter* 0.5; AcGePoint3d ptTemp = pt; for (i = 0; i < nSect + 1 ; i++) { arptCircle.append(pt); pt = ptTemp.rotateBy(dMinDiffAng, vtStr, ptStart); } //将ptStart处的圆上nSect个点按照dMinDiffAng旋转出nSect1个圆截面 for (i = 0; i <= nSect1; i++) { dDifAng1 = dMinDiffAng * i; for (j = 0;j < nSect + 1 ;j++) { ptTemp = pt = arptCircle[j]; pt = ptTemp.rotateBy(dDifAng1, vtNormal, ptGeCen); arptSides.append(pt); } } //最后一个圆截面是ptStartt处的圆上nSect个点按照PI/2 90°或者dAngle旋转出来 for (j = 0;j < nSect + 1 ;j++) { pt = arptCircle[j].rotateBy(dAngle, vtNormal, ptGeCen); arptSides.append(pt); } dc.DrawMesh( nSect1 + 2 , nSect + 1, arptSides.asArrayPtr()); } else { TDbPolyMesh cvMesh; cvMesh.setPropertiesFrom(this); cvMesh.SetNormal(v3);//法向 cvMesh.SetBasePoly(polyPath); cvMesh.SetAllShapePolys(lstShapePloy); cvMesh.SetAllShapeBases(lstShapeBase); //指定基点 if(dc.IsFullExplode()) cvMesh.ExplodeOrDraw3d(dc); else dc.DrawEntity(cvMesh); } // cet 2011.5.27 modify // DrawPolyMesh(pt5, pt7, nDn1*nFactor*1.1, dc); // DrawPolyMesh(pt6, pt8, nDn2*nFactor*1.1, dc); if (dPipeLen1 > nDist * 4) { DrawPolyMesh(pt5, pt7, nDn1*nFactor*1.1, dc); } if (dPipeLen2 > nDist * 4) { DrawPolyMesh(pt6, pt8, nDn2*nFactor*1.1, dc); } return Acad::eOk; } Acad::ErrorStatus TDbPipeFitting::Draw3dElbow2(XExplodeDraw &dc) const { XPoint pt1, pt2, pt3, pt4, pt5, pt6, pt7, pt8; //1 首先得到弯头连接2管线的管径 double nDn1(0), nDn2(0); BOOL bIsVer1(FALSE), bIsVer2(FALSE); TPipeSys::SysType sys1 = TPipeSys::kUnknownSys; TPipeSys::SysType sys2 = TPipeSys::kUnknownSys; AcDbCurve *pCurve1 = NULL; AcDbCurve *pCurve2 = NULL; AcGePoint3d pts,pte,pts1,pte1; for(int i=0;i<2;i++){ TPipeInterface face; GetInterface(i, face); AcDbObjectId nextPipeId = face.m_idPipe; OPENOBJ_BEGIN(nextPipeId, AcDb::kForRead, TDbPipe, pPipe); if(pPipe){ if(pPipe->GetModelType() == TPipeSys::kSystem) return Acad::eOk; if(i == 0){ pCurve1 = pPipe->AsAcDbCurve(); nDn1 = pPipe->GetDnDiameter(); sys1 = face.m_sysType; bIsVer1 = pPipe->IsVertical(); // cet 2018.2.2 modify 通过文件查询外径,对实体绘制效率影响较大 // nDn1 = GetPipeOutDByDn(pPipe->GetMaterial(), nDn1); nDn1 = pPipe->OuterDn(); pPipe->getStartPoint(pts); pPipe->getEndPoint(pte); } else{ pCurve2 = pPipe->AsAcDbCurve(); nDn2 = pPipe->GetDnDiameter(); sys2 = face.m_sysType; bIsVer2 = pPipe->IsVertical(); // cet 2018.2.2 modify 通过文件查询外径,对实体绘制效率影响较大 // nDn2 = GetPipeOutDByDn(pPipe->GetMaterial(), nDn2); nDn2 = pPipe->OuterDn(); pPipe->getStartPoint(pts1); pPipe->getEndPoint(pte1); } } OPENOBJ_END(); } double dArea(1); if(DocGetMeterUnitDraw()) { nDn1 = nDn1 / 1000.0; nDn2 = nDn2 / 1000.0; dArea = 0.0001; } //2 得到弯头几个参数点. pt1, pt2, pt3, pt4 是中间变截面体的4个路径点, pt5&pt7, pt6&pt8是引申出2段的圆柱的起终点 nDn1 = nDn1 / 2;//转半径 nDn2 = nDn2 / 2; double nDist = nDn1; if(nDn2 > nDn1) { nDist = nDn2; } double nFactor(1); GetPointAtDist(pCurve1, nDist, pt1); GetPointAtDist(pCurve1, nDist*2, pt3); GetPointAtDist(pCurve1, nDist*3, pt5); GetPointAtDist(pCurve2, nDist, pt2); GetPointAtDist(pCurve2, nDist*2, pt4); GetPointAtDist(pCurve2, nDist*3, pt6); AcGePoint3d ptStart,ptEnd; ptStart = pt3; ptEnd = pt4; delete pCurve1; delete pCurve2; if(sys1 != sys2 && bIsVer1 && bIsVer2) return Acad::eOk; if(!pt1 || !pt2 || !pt3 || !pt4 || !pt5 || !pt6){//可能太短了,无法绘制弯头,就简化一下 if(!!pt2 && !!pt4 && !!pt6) DrawPolyMesh(pt6, m_ptLocation, nDn2*nFactor, dc); if(!!pt1 && !!pt3 && !!pt5) DrawPolyMesh(pt5, m_ptLocation, nDn1*nFactor, dc); return Acad::eOk; } AcGeVector3d vtDir1(pt1 - m_ptLocation); AcGeVector3d vtDir2(pt2 - m_ptLocation); AcGeVector3d v3 = vtDir1.crossProduct(vtDir2); AcGeMatrix3d mat; mat.setToWorldToPlane(v3); v3.normalize(); double nAngTotal = vtDir1.angleTo(vtDir2); nAngTotal -= PI; nAngTotal = nAngTotal * -1; XPoly2D polyPath;//路径 pt7 = pt3; pt8 = pt4; if(v3 != AcGeVector3d(0, 0, 0)){ pt1.TransformBy(mat); pt2.TransformBy(mat); pt3.TransformBy(mat); pt4.TransformBy(mat); } else v3 = AcGeVector3d(0, 0, 1); polyPath.AppendNode(pt3); polyPath.AppendNode(pt1, -nAngTotal); polyPath.AppendNode(pt2); polyPath.AppendNode(pt4); XPoly2D *polyShape1=new XPoly2D(1); XCircle cir2(pt3, nDn1*nFactor); XCurveSegment seg2; seg2 = cir2; seg2.AsPoly2D(*polyShape1); if(polyShape1->IsSelfIntersect()||polyShape1->Area()IsSelfIntersect()||polyShape2->Area() lstShapePloy; DList lstShapeBase; lstShapePloy.Append(polyShape1); lstShapePloy.Append(polyShape2); lstShapeBase.Append(new XPoint(pt3)); lstShapeBase.Append(new XPoint(pt4)); TDbPolyMesh cvMesh; cvMesh.setPropertiesFrom(this); cvMesh.SetNormal(v3);//法向 cvMesh.SetBasePoly(polyPath); cvMesh.SetAllShapePolys(lstShapePloy); cvMesh.SetAllShapeBases(lstShapeBase); //指定基点 if(dc.IsFullExplode()) cvMesh.ExplodeOrDraw3d(dc); else dc.DrawEntity(cvMesh); } DrawPolyMesh(pt5, pt7, nDn1*nFactor*1.1, dc); DrawPolyMesh(pt6, pt8, nDn2*nFactor*1.1, dc); return Acad::eOk; } Acad::ErrorStatus TDbPipeFitting::ExplodeOrDraw3d(XExplodeDraw &dc) const { // cet 2016.8.17 add 方沟连接件 if (IsLinkedPipeCanal()) { TDbCanalFitting fitting(this); return fitting.ExplodeOrDraw3d(dc); } // if(!!objectId()) { AcGePoint3d pt(m_ptLocation.x,m_ptLocation.y,m_ptLocation.z); dc.DrawEntity(AcDbPoint(pt)); //SR ADD 2005-6-10 int num = GetInterfaceNum(); if(num != 2) return Draw3dOther(dc); else return Draw3dElbow(dc); // } return Acad::eOk; } //取动态属性显示数据 void TDbPipeFitting::GetTips(DList &info) const { const TCHAR *szDesc=_T("未知"); int nCount=m_lstInterface.Length(); switch(nCount) { case 1: szDesc=_T("堵头"); break; case 2: szDesc=_T("弯头"); break; case 3: szDesc=_T("三通"); break; case 4: szDesc=_T("四通"); break; } info.Append(new TObjInfoUnit(_T("对象类型"), szDesc)); } // 对st类型的接口进行重新连接 void TDbPipeFitting::UpdateLinkage(const XPoint &ptAt, TPipeSys::SysType st, const DList &idPipes) { assertWriteEnabled(); m_ptLocation = ptAt; TDbPipeNode::UpdateLinkage(ptAt,st,idPipes); /*//m_lstInterface.Reset(); RemoveInterface(st); for(int i=0; iGetSysLabel(); iFace.m_idPipe = id; if(m_ptLocation.Distance(pPipe->startPoint)startPoint; AcGeVector3d vt; pPipe->getFirstDeriv(pPipe->startPoint, vt); iFace.m_vtLocation = vt; AddInterface(iFace); } else if(m_ptLocation.Distance(pPipe->endPoint)endPoint; AcGeVector3d vt; pPipe->getFirstDeriv(pPipe->endPoint, vt); iFace.m_vtLocation = XVector3D(-vt[0], -vt[1], -vt[2]); AddInterface(iFace); } } OPENOBJ_END(); }*/ } Acad::ErrorStatus TDbPipeFitting::GetExtents(XPoint &ptLow, XPoint &ptUp) const { Acad::ErrorStatus es = TDbPipeNode::GetExtents(ptLow,ptUp); if(es==Acad::eOk) { if(ptLow==XPoint()&&ptUp==XPoint()) { ptLow = m_ptLocation; ptUp = m_ptLocation; } else { ptLow = Min(ptLow,m_ptLocation); ptUp = Max(ptUp,m_ptLocation); } } return es; } void InitDbPipeFitting(BOOL bTrue) { if(bTrue) { TDbPipeFitting::rxInit(); TDbPipeFitting::InitMatchProtocol(TRUE); } else { deleteAcRxClass(TDbPipeFitting::desc()); TDbPipeFitting::InitMatchProtocol(FALSE); } } CString TDbPipeFitting::GetXml(const AcGeMatrix3d& mat) const { TPipeSys::ModelType modelType = TPipeSys::kModel; int nMaterial = -1; TPipeSys::SysType sysType = TPipeSys::kUnknownSys; TPipeInterface face; GetInterface(0, face); AcDbObjectId PipeId = face.m_idPipe; OPENOBJ_BEGIN(PipeId, AcDb::kForRead, TDbPipe, pPipe); if(pPipe != NULL) { nMaterial = pPipe->GetMaterial(); sysType = pPipe->GetSysType(); modelType = pPipe->GetModelType(); } OPENOBJ_END(); if (modelType == TPipeSys::kSystem) // 系统图 { return CString(); } TXmlTree xmlTree; CString csText; AcGePoint3d pt; CString csX, csY, csZ; int nPreci = 3; // 精度 POSITION posRoot = xmlTree.Insert(_T("ATS_PIPEFITTING"), 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); if (lst.Length() > 0 && nMaterial != -1) // 获得材质时,进行查找 cet 2013.6.26 add { CString strMat = lst[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("水管所属系统")); if (sysType != TPipeSys::kUnknownSys) { xmlTree.SetItemText(posItemType, GetSystypeName(sysType)); } } POSITION posItemLocPt = xmlTree.Insert(_T("Location"), posRoot, posItemType); { xmlTree.SetAttribute(posItemLocPt, _T("name"), _T("连接点位置")); xmlTree.SetAttribute(posItemLocPt, _T("comment"), _T("中心连接点位置")); XPoint ptLoc = m_ptLocation; ptLoc.TransformBy(mat); csX = DoubleToString(ptLoc.x, nPreci); csY = DoubleToString(ptLoc.y, nPreci); csZ = DoubleToString(ptLoc.z, nPreci); csText.Format(_T("%s,%s,%s"), csX, csY, csZ); xmlTree.SetItemText(posItemLocPt, csText); } POSITION posItemInter = xmlTree.Insert(_T("Interface"), posRoot, posItemLocPt); POSITION posCur = NULL; int nNum = GetInterfaceNum(); if (nNum == 2) // 弯头 { XPoint pt5, pt6; //1 首先得到弯头连接2管线的管径 double dDn1(0), dDn2(0), dDn3(0), dDn4(0); AcDbCurve *pCurve1 = NULL; AcDbCurve *pCurve2 = NULL; for(int i = 0; i < 2; i++) { TPipeInterface face; GetInterface(i, face); AcDbObjectId nextPipeId = face.m_idPipe; OPENOBJ_BEGIN(nextPipeId, AcDb::kForRead, TDbPipe, pPipe); if(pPipe != NULL) { if(i == 0) { pCurve1 = pPipe->AsAcDbCurve(); dDn1 = pPipe->GetDnDiameter(); dDn3 = dDn1; // cet 2018.2.2 modify 通过文件查询外径,对实体绘制效率影响较大 // dDn1 = GetPipeOutDByDn(pPipe->GetMaterial(), dDn1); dDn1 = pPipe->OuterDn(); } else { pCurve2 = pPipe->AsAcDbCurve(); dDn2 = pPipe->GetDnDiameter(); dDn4 = dDn2; // cet 2018.2.2 modify 通过文件查询外径,对实体绘制效率影响较大 // dDn2 = GetPipeOutDByDn(pPipe->GetMaterial(), dDn2); dDn2 = pPipe->OuterDn(); } } OPENOBJ_END(); } if(DocGetMeterUnitDraw()) { dDn1 = dDn1 / 1000.0; dDn2 = dDn2 / 1000.0; } dDn1 = dDn1 / 2;//转半径 dDn2 = dDn2 / 2; double dDist =dDn1; if (dDn1 < dDn2) { dDist = dDn2; } GetPointAtDist(pCurve1, dDist*3, pt5); GetPointAtDist(pCurve2, dDist*3, pt6); POSITION posItemPt1 = xmlTree.Insert(_T("Point1"), posItemInter, NULL); { csText = _T("分支点1位置"); xmlTree.SetAttribute(posItemPt1, _T("name"), csText); pt5.TransformBy(mat); csX = DoubleToString(pt5.x, nPreci); csY = DoubleToString(pt5.y, nPreci); csZ = DoubleToString(pt5.z, nPreci); csText.Format(_T("%s,%s,%s"), csX, csY, csZ); xmlTree.SetItemText(posItemPt1, csText); } POSITION posItemDn1 = xmlTree.Insert(_T("DN1"), posItemInter, posItemPt1); { csText = _T("分支点1管径"); xmlTree.SetAttribute(posItemDn1, _T("name"), csText); csText = DoubleToString(dDn3, nPreci); xmlTree.SetItemText(posItemDn1, csText); } POSITION posItemPt2 = xmlTree.Insert(_T("Point2"), posItemInter, posItemDn1); { csText = _T("分支点2位置"); xmlTree.SetAttribute(posItemPt2, _T("name"), csText); pt6.TransformBy(mat); csX = DoubleToString(pt6.x, nPreci); csY = DoubleToString(pt6.y, nPreci); csZ = DoubleToString(pt6.z, nPreci); csText.Format(_T("%s,%s,%s"), csX, csY, csZ); xmlTree.SetItemText(posItemPt2, csText); } POSITION posItemDn2 = xmlTree.Insert(_T("DN2"), posItemInter, posItemPt2); { csText = _T("分支点2管径"); xmlTree.SetAttribute(posItemDn2, _T("name"), csText); csText = DoubleToString(dDn4, nPreci); xmlTree.SetItemText(posItemDn2, csText); } posCur = posItemDn2; } else { XPoint pt1, pt2; double dDn(0), dDn2(0); for(int i = 0 ; i < nNum; i++) { TPipeInterface face; GetInterface(i, face); AcDbObjectId nextPipeId = face.m_idPipe; AcDbCurve *pCurve1 = NULL; OPENOBJ_BEGIN(nextPipeId, AcDb::kForRead, TDbPipe, pPipe); if(pPipe != NULL) { pCurve1 = pPipe->AsAcDbCurve(); dDn = pPipe->GetDnDiameter(); dDn2 = dDn; // cet 2018.2.2 modify 通过文件查询外径,对实体绘制效率影响较大 // dDn = GetPipeOutDByDn(pPipe->GetMaterial(), dDn); dDn = pPipe->OuterDn(); } OPENOBJ_END(); if(DocGetMeterUnitDraw()) { dDn = dDn * 0.001; } double nDist = dDn * 1.2; double nFactor(1.0); BOOL bOk(FALSE); bOk = GetPointAtDist(pCurve1, nDist*0.8, pt1); if (bOk) { bOk = GetPointAtDist(pCurve1, nDist, pt2); } if (!bOk) { delete pCurve1; // cet 2011.11.21 add return _T(""); } if(pCurve1 != NULL) { delete pCurve1; } pt = pt2; csText.Format(_T("Point%d"), i + 1); POSITION posItemLocPt = xmlTree.Insert(csText, posItemInter, posCur); { csText.Format(_T("分支点%d位置"), i + 1); xmlTree.SetAttribute(posItemLocPt, _T("name"), csText); pt.transformBy(mat); csX = DoubleToString(pt.x, nPreci); csY = DoubleToString(pt.y, nPreci); csZ = DoubleToString(pt.z, nPreci); csText.Format(_T("%s,%s,%s"), csX, csY, csZ); xmlTree.SetItemText(posItemLocPt, csText); } csText.Format(_T("DN%d"), i + 1); POSITION posItemDn = xmlTree.Insert(csText, posItemInter, posItemLocPt); { csText.Format(_T("分支点%d管径"), i + 1); xmlTree.SetAttribute(posItemDn, _T("name"), csText); csText = DoubleToString(dDn2, nPreci); xmlTree.SetItemText(posItemDn, csText); } posCur = posItemDn; } } POSITION posItemId = xmlTree.Insert(_T("Object_ID"), posRoot, posItemInter); { 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 csXml = xmlTree.GetXml(); int nIndex = -1; nIndex = csXml.Find(_T("")); if (nIndex != -1) { CString sTemp = TDbPipeNode::GetXml(mat); csXml.Insert(nIndex, sTemp); } return csXml; } bool TDbPipeFitting::IsLinkedPipeCanal() const { int nNum = GetInterfaceNum(); for (int i = 0; i < nNum; ++i) { OPENOBJ_BEGIN(GetIPipe(i), AcDb::kForRead, TDbPipeCanal, pCanal); if (pCanal != NULL) { if (!pCanal->isKindOf(TDbCableTrench::desc())) { return true; } } OPENOBJ_END(); } return false; }