Files
envi-code/SourceCode/Code2026/tg_shs/shs_pipewire/DbPipeFitting.cpp
T
2026-09-28 15:28:50 +08:00

1276 lines
33 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "stdafx.h"
#include <DbPolyMesh.h>
#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; i<m_lstInterface.Length(); i++) {
const TPipeInterface &iFace=m_lstInterface[i];
bShow = bShow || config.m_pConfig->IsSystemShow(iFace.m_sysType);
}
if(!bShow) return es;
}
}
if(m_visibility == TPipeSys::kVisible) {
double nDist=1.0*GetPScale();
for(int i=0; i<m_lstInterface.Length(); i++) {
const TPipeInterface &iFace=m_lstInterface[i];
XVector3D vt=iFace.m_vtLocation;
vt.Normalize();
vt *= nDist;
XPoint pt = m_ptLocation + vt;
if(pt.Distance2d(m_ptLocation)>_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<XPoly2D> lstShapePloy;
// DList<XPoint> 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;i<num;i++){
TPipeInterface face;
GetInterface(i, face);
AcDbObjectId nextPipeId = face.m_idPipe;
AcDbCurve *pCurve1 = NULL;
OPENOBJ_BEGIN(nextPipeId, AcDb::kForRead, TDbPipe, pPipe);
if(pPipe){
if(pPipe->GetModelType() == 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()<dArea)
return Acad::eOk;
XPoly2D *polyShape1=new XPoly2D(1);
XCircle cir2(pt3, nDn1*nFactor);
XCurveSegment seg2;
seg2 = cir2;
seg2.AsPoly2D(*polyShape1);
if(polyShape1->IsSelfIntersect()||polyShape1->Area()<dArea)
return Acad::eOk;
XPoly2D *polyShape2=new XPoly2D(1);
XCircle cir3(pt4, nDn2*nFactor);
XCurveSegment seg3;
seg3 = cir3;
seg3.AsPoly2D(*polyShape2);
if(polyShape2->IsSelfIntersect()||polyShape2->Area()<dArea)
return Acad::eOk;
DList<XPoly2D> lstShapePloy;
DList<XPoint> 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()<dArea)
return Acad::eOk;
XPoly2D *polyShape2=new XPoly2D(1);
XCircle cir3(pt4, nDn2*nFactor);
XCurveSegment seg3;
seg3 = cir3;
seg3.AsPoly2D(*polyShape2);
if(polyShape2->IsSelfIntersect()||polyShape2->Area()<dArea)
return Acad::eOk;
// cet 2011.7.22 modify 立管情况单独处理
if (bIsVer1 && bIsVer2)
{
dc.DrawMesh(*polyShape2, *polyShape1);
delete polyShape1;
delete polyShape2;
}
else
{
DList<XPoly2D> lstShapePloy;
DList<XPoint> 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<TObjInfoUnit> &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<AcDbObjectId> &idPipes)
{
assertWriteEnabled();
m_ptLocation = ptAt;
TDbPipeNode::UpdateLinkage(ptAt,st,idPipes);
/*//m_lstInterface.Reset();
RemoveInterface(st);
for(int i=0; i<idPipes.Length(); i++) {
const AcDbObjectId &id=idPipes[i];
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbPipe, pPipe);
if(pPipe) {
TPipeInterface iFace;
iFace.m_sysType = st;
iFace.m_faceType = TPipeInterface::kNodeLocation;
iFace.m_sSysLabel = pPipe->GetSysLabel();
iFace.m_idPipe = id;
if(m_ptLocation.Distance(pPipe->startPoint)<PS_SNAP) {
iFace.m_ptLocation = pPipe->startPoint;
AcGeVector3d vt;
pPipe->getFirstDeriv(pPipe->startPoint, vt);
iFace.m_vtLocation = vt;
AddInterface(iFace);
} else if(m_ptLocation.Distance(pPipe->endPoint)<PS_SNAP) {
iFace.m_ptLocation = pPipe->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("</ATS_PIPEFITTING>"));
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;
}