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

1103 lines
31 KiB
C++

#include "stdafx.h"
#include "DbWell.h"
#include "DbPipe.h"
#include <DbCurveMesh2.h>
#include <actrans.h>
#include "DbWellDim.h"
#include "PipeWireMonitor.h"
//#include "TAPI.h"
extern BOOL Is2DView();
// cet 2017.8.10 add 彻底炸开实体
void FullExplode(const AcDbEntity *pEnt, AcDbVoidPtrArray &entitySet)
{
AcDbVoidPtrArray arrTemp, arrExplode;
if (pEnt->explode(arrTemp) != Acad::eOk)
{
return;
}
while (!arrTemp.isEmpty())
{
AcDbEntity *pTemp = (AcDbEntity*)arrTemp[0];
arrTemp.removeAt(0);
if (pTemp == NULL)
{
continue;
}
arrExplode.removeAll();
if (pTemp->explode(arrExplode) == Acad::eOk)
{
arrTemp.append(arrExplode);
delete pTemp;
}
else
{
entitySet.append((void*)pTemp);
}
}
}
namespace
{
// 管道与井求交
bool IntersectWith(const TDbWell *pWell, const AcDbEntity* pEntCurve, AcDb::Intersect intType, const AcGePlane& projPlane, AcGePoint3dArray& points)
{
AcDbVoidPtrArray entSet1;
// cet 2018.1.31 modify 只有二维图形计算交点
// pWell->explode(entSet1);
XExplodeStream dc(entSet1);
pWell->ExplodeOrDraw2d(dc);
for(int i = 0; i < entSet1.length(); ++i)
{
AcDbEntity *pEnt = (AcDbEntity *)entSet1[i];
if (pEnt->isKindOf(TDbEquipment::desc()))
{
AcDbVoidPtrArray entSet2;
pEnt->explode(entSet2);
for (int j = 0; j < entSet2.length(); ++j)
{
AcDbBlockReference *pBlkRef = NULL;
if(pBlkRef = AcDbBlockReference::cast((AcDbEntity*)entSet2[j]))
{
AcDbVoidPtrArray entSet3;
pBlkRef->explode(entSet3);
for(int k = 0; k < entSet3.length(); k++)
{
AcDbEntity *pEnt3 = (AcDbEntity *)entSet3[k];
if (pEnt3->isKindOf(AcDbCurve::desc()))
{
AcGePoint3dArray arrPt;
pEntCurve->intersectWith((AcDbCurve*)pEnt3, intType, projPlane, arrPt);
for (int i = 0; i < arrPt.length(); ++i)
{
points.append(arrPt[i]);
}
}
}
ReleaseEntSet(entSet3);
}
}
ReleaseEntSet(entSet2);
}
}
ReleaseEntSet(entSet1);
// 交点多于2个,求最远两点
if (points.length() > 2)
{
AcGePoint3d pt1 = points[0];
AcGePoint3d pt2 = points[1];
double dDist = pt1.distanceTo(pt2);
for (int i = 0; i < points.length(); ++i)
{
for (int j = i + 1; j < points.length(); ++j)
{
if (points[i].distanceTo(points[j]) > dDist)
{
pt1 = points[i];
pt2 = points[j];
dDist = points[i].distanceTo(points[j]);
}
}
}
points.removeAll();
points.append(pt1);
points.append(pt2);
}
return points.length() != 0;
}
}
extern void Matrix3D2String( const AcGeMatrix3d &mat, CString &str );
ACRX_DXF_DEFINE_MEMBERS(ATSWell, ATSEquipment, AcDb::kDHL_CURRENT,
AcDb::kMReleaseCurrent, 1, ATS_WELL,
"ATS_WELL图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(TDbWell);
const Adesk::UInt8 TDbWell::g_nVersion = 2;
TDbWell::TDbWell()
{
m_visibility=TPipeSys::kVisible;
m_bHidePipe = TRUE;
m_bDrawProperty = FALSE;
m_dDang = 0;
m_nWellDn = 8;
m_bIsModify = false;
SetEquipmentType(2); // cet 2014.12.2 设备类型
}
void TDbWell::CopyPropertiesFrom(AcDbEntity *pSrc,unsigned gMatchFlag)
{
assertWriteEnabled();
TDbEquipment::CopyPropertiesFrom(pSrc, gMatchFlag);
TDbWell *pEqu = TDbWell::cast(pSrc);
if(pEqu) {
m_idBlock2d = pEqu->m_idBlock2d;
}
}
Acad::ErrorStatus TDbWell::subGetClassID(CLSID* pClsid) const
{
return Acad::eOk;
}
Acad::ErrorStatus
TDbWell::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);
// }
snapPoints.append(m_ptLocation);
snapPoints.append(m_ptLabel);
// cet 2017.8.9 add 可以捕捉井边界
if (Is2DView())
{
AcDbVoidPtrArray blockArray;
FullExplode(this, blockArray);
int nCount = blockArray.length();
for (int i = 0; i < nCount; ++i)
{
AcDbEntity *pEntity = (AcDbEntity *)blockArray[i];
if (pEntity != NULL)
{
pEntity->getOsnapPoints(osnapMode, gsSelectionMark, ptPick, lastPoint, viewXform, snapPoints, geomIds);
}
}
ReleaseEntSet(blockArray);
}
return es;
}
Acad::ErrorStatus
TDbWell::GetGripText(int idx, CString &cs) const
{
Acad::ErrorStatus es = Acad::eOk;
switch(idx) {
case 0: cs=_T("移动井"); break;
case 1: cs=_T("移动标注"); break;
default: es=Acad::eInvalidInput;
}
return es;
}
Acad::ErrorStatus
TDbWell::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
Acad::ErrorStatus es=Acad::eOk;
gripPoints.append((AcGePoint3d)m_ptLocation);
gripPoints.append((AcGePoint3d)m_ptLabel);
// zxl 2013.12.12 add 虚显Space
acDocManager->lockDocument(curDoc(),AcAp::kWrite,NULL,NULL,true);
Entity ent;
ads_name name;
acdbGetAdsName(name, GetSpaceId());
ent = name;
ent.Redraw(3);
acDocManager->unlockDocument(curDoc());
return es;
}
Acad::ErrorStatus
TDbWell::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const
{
assertReadEnabled();
stretchPoints.append((AcGePoint3d)m_ptLocation);
stretchPoints.append((AcGePoint3d)m_ptLabel);
return Acad::eOk;
}
Acad::ErrorStatus
TDbWell::subMoveGripPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
Acad::ErrorStatus es=Acad::eOk;
es=MoveGSPointsAt(indices,offset);
return es;
}
Acad::ErrorStatus
TDbWell::subMoveStretchPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
Acad::ErrorStatus es=Acad::eOk;
es=MoveGSPointsAt(indices,offset,false);
return es;
}
Acad::ErrorStatus
TDbWell::MoveGSPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset, bool bGripMove)
{
Acad::ErrorStatus es=Acad::eOk;
AcGeMatrix3d mat;
mat.setToTranslation(offset);
BOOL bMove = FALSE;
bool bMovedLabel = false; // cet 2011.5.31 add 记录井标注点是否已经移动一次,避免多次移动标注点
for (int i=0; i<indices.length();i++) {
int idx = indices[i];
switch(idx) {
case 0:
m_ptInsert.TransformBy(mat);
m_ptLocation.TransformBy(mat);
m_ptLabel.TransformBy(mat);
bMove = TRUE;
bMovedLabel = true; // cet 2011.5.31 add
m_bIsModify = true; // zxl 2013.9.29
break;
case 1:
if (bMovedLabel) // cet 2011.5.31 add
{
break;
}
if(m_ptLabel != m_ptLocation)
m_ptLabel.TransformBy(mat);
break;
default:
es=Acad::eInvalidInput;
}
}
// cet 2012.4.23 add 拉伸时不移动关联管线
if (!bGripMove)
{
return es;
}
if(bMove){
int num = GetInterfaceNum();
if(num < 1)
return es;
ads_name name; // cet 2012.4.23 add
for(int m=0;m<num;m++){
TPipeInterface face;
GetInterface(m, face);
// cet 2012.4.23 add 管线自身完成拉伸时,不再在此处理
acdbGetAdsName(name, face.m_idPipe);
Entity ent(name);
if (g_ssPickFirst.IsInclude(ent))
{
continue;
}
OPENOBJ_BEGIN(face.m_idPipe, AcDb::kForWrite, TDbPipe, pPipe);
if(pPipe && !pPipe->IsVertical()){
XPoint ptStart, ptEnd;
pPipe->getStartPoint(ptStart);
pPipe->getEndPoint(ptEnd);
XPoint ptNew = m_ptLocation;
if(pPipe->GetNode(0)==objectId()){
// cet 2016.4.8 modify 偏移管道及管道上的实体,原代码只是修改了管道位置,未处理管道上的实体
// ptNew.z = ptStart.z;
// pPipe->SetStartPoint(ptNew);
AcGePoint3dArray gripPoints;
AcDbIntArray osnapModes;
AcDbIntArray geomIds;
pPipe->subGetGripPoints(gripPoints, osnapModes, geomIds);
for (int i = 0; i < gripPoints.length(); ++i)
{
if (ptStart.Distance(gripPoints[i]) < 0.001)
{
AcDbIntArray arr;
arr.append(i);
pPipe->subMoveGripPointsAt(arr, ptNew - ptStart);
break;
}
}
}
if(pPipe->GetNode(1)==objectId()){
// cet 2016.4.8 modify 偏移管道及管道上的实体,原代码只是修改了管道位置,未处理管道上的实体
// ptNew.z = ptEnd.z;
// pPipe->SetEndPoint(ptNew);
AcGePoint3dArray gripPoints;
AcDbIntArray osnapModes;
AcDbIntArray geomIds;
pPipe->subGetGripPoints(gripPoints, osnapModes, geomIds);
for (int i = 0; i < gripPoints.length(); ++i)
{
if (ptEnd.Distance(gripPoints[i]) < 0.001)
{
AcDbIntArray arr;
arr.append(i);
pPipe->subMoveGripPointsAt(arr, ptNew - ptEnd);
break;
}
}
}
}
OPENOBJ_END();
}
}
return es;
}
//移动夹点管线联动,如果移动井,则管线不联动。因为大量移动井和管线时会出错。
Acad::ErrorStatus
TDbWell::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
TDbEquipment::subTransformBy(xform);
m_ptLabel.TransformBy(xform);
return Acad::eOk;
}
// 从DWG读入数据:
Acad::ErrorStatus TDbWell::dwgInFields(AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbEquipment::dwgInFields(pFiler);
if(es != Acad::eOk) return es;
es = TLabelStyle::dwgInFields(pFiler);
if(es != Acad::eOk) return es;
Adesk::UInt8 nVer;
pFiler->readItem(&nVer);
ReadString(pFiler, m_sWellName);
pFiler->readItem((AcGePoint3d *)&m_ptLabel);
pFiler->readItem(&m_nEleDown);
pFiler->readItem(&m_nEleUp);
pFiler->readItem(&m_nWellDn);
//pFiler->readItem(&m_bDrawLabel);
FilerRead(pFiler, m_bDrawLabel);
pFiler->readItem(&m_idLabelLayer);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbWell::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbEquipment::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
es = TLabelStyle::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
pFiler->writeItem(g_nVersion);
pFiler->writeItem((const TCHAR *)m_sWellName);
pFiler->writeItem((const AcGePoint3d &)m_ptLabel);
pFiler->writeItem(m_nEleDown);
pFiler->writeItem(m_nEleUp);
pFiler->writeItem(m_nWellDn);
//pFiler->writeItem(m_bDrawLabel);
FilerWrite(pFiler, m_bDrawLabel);
pFiler->writeItem(m_idLabelLayer);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbWell::dxfInFields(AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es=Acad::eOk;
es=TDbEquipment::dxfInFields(pFiler);
if(es!=Acad::eOk) return es;
if (!pFiler->atSubclassData(_T("TDbWell"))) {
return Acad::eBadDxfSequence;
}
resbuf rb;
while((es==Acad::eOk) && ((es=pFiler->readResBuf(&rb))==Acad::eOk)) {
switch (rb.restype) {
case AcDb::kDxfXTextString:
m_sWellName=rb.resval.rstring;
break;
case AcDb::kDxfXCoord:
m_ptLabel =rb.resval.rpoint;
break;
case AcDb::kDxfXReal:
m_nWellDn=rb.resval.rreal;
break;
default:
pFiler->pushBackItem();
es = Acad::eEndOfFile;
break;
}
}
if(es!=Acad::eEndOfFile)
return Acad::eInvalidResBuf;
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbWell::dxfOutFields(AcDbDxfFiler* pFiler) const
{
Acad::ErrorStatus es=Acad::eOk;
es=TDbEquipment::dxfOutFields(pFiler);
assert(es==Acad::eOk);
es=pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbWell"));
assert(es==Acad::eOk);
pFiler->writeString(AcDb::kDxfXTextString,(const TCHAR*)m_sWellName);
pFiler->writePoint3d(AcDb::kDxfXCoord,m_ptLabel);
pFiler->writeDouble(AcDb::kDxfXReal,m_nWellDn);
// zxl 2013.12.13 取消虚显
if (IsKeyPressed(VK_ESCAPE))
{
acDocManager->lockDocument(curDoc(),AcAp::kWrite,NULL,NULL,true);
ads_name name;
acdbGetAdsName(name, GetSpaceId());
Entity ent = name;
ent.Redraw(4);
acDocManager->unlockDocument(curDoc());
}
return es;
}
extern Acad::ErrorStatus DrawPolyMesh(XPoint ptS, XPoint ptE, double nRadius, XExplodeDraw &dc);
Acad::ErrorStatus TDbWell::ExplodeOrDraw3d(XExplodeDraw &dc) const
{
Acad::ErrorStatus es=Acad::eOk;
XPoint pt1, pt2;
pt1 = pt2 = m_ptLocation;
if(DocGetMeterUnitDraw())
{
pt1.z = m_nEleDown;
pt2.z = m_nEleUp;
}
else
{
pt1.z = m_nEleDown*1000;
pt2.z = m_nEleUp*1000;
}
if(fabs(m_nEleDown) > 0.01)
DrawPolyMesh(pt1, pt2, GetScale()*GetPScale()/2.0, dc);
//es=TDbEquipment::ExplodeOrDraw3d(dc);
return es;
}
Acad::ErrorStatus TDbWell::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;
TDbEquipment pEquip;
pEquip.SetBlock2d(m_idBlock2d);
pEquip.SetLocation(m_ptLocation);
pEquip.SetDirection(m_vtDirection);
pEquip.SetScale(GetScale()*100);
pEquip.SetHidePipe(m_bHidePipe);
pEquip.setPropertiesFrom(this);
if(dc.IsFullExplode() || g_nSaveTArchVer == 5) // cet 2016.7.25 modify 转T5时,打开图纸报错,解决方法炸开实体
pEquip.ExplodeOrDraw2d(dc);
else
dc.DrawEntity(pEquip);
if(m_bDrawLabel) // 绘制标注
DrawLabelText(dc);
return Acad::eOk;
}
Acad::ErrorStatus TDbWell::DrawLabelText(XExplodeDraw &dc) const
{
AcDbObjectId idLayerOld=dc.GetLayerId();
if(m_idLabelLayer.isValid())
dc.SetLayer(m_idLabelLayer);
CString csDimText = m_sWellName.cs();
if(IsShowPropertyText()){
CString csEle;
csEle.Format(_T("(%.2f,%.2f)"), m_nEleUp, m_nEleDown);
if(fabs(m_nEleUp) < 0.001 && fabs(m_nEleDown) < 0.001)
csEle = _T("(无信息)");
csDimText += csEle;
}
TDbText text;
text.setPropertiesFrom(this);
text.setLayer(m_idLabelLayer);
text.setColorIndex(GetTextColor()); // cet 2018.2.6 add 可修改文字颜色
text.SetStyleId(m_idTextStyle);
text.SetText((const TCHAR*)csDimText);
text.SetLocation(XPoint(m_ptLabel.x,m_ptLabel.y,0));
text.SetHeight(m_dTextHeight);
text.SetAlignment(XExplodeDraw::kMiddleCenter);
text.SetRotation(GetDimAngle()); // cet 2011.8.25 add 设置标注角度
TPushProperty vProp(&text, dc);
if(dc.IsFullExplode())
text.ExplodeOrDraw2d(dc);
else
dc.DrawEntity(text);
dc.SetLayer(idLayerOld);
return Acad::eOk;
}
// 根据管线初始化管线标注位置
void TDbWell::InitLabelLocation(double nScale)
{
assertWriteEnabled();
double Len = GetScale()*GetPScale();
double nLenText = Len/2*nScale;
double nAng = Ucs2Wcs(PI/2);
ads_polar(m_ptLocation,nAng,nLenText,m_ptLabel);
}
void TDbWell::GetTips(DList<TObjInfoUnit> &info) const
{
info.Append(new TObjInfoUnit(_T("对象类型"), _T("室外井")));
info.Append(new TObjInfoUnit(_T("井编号"), m_sWellName));
info.Append(new TObjInfoUnit(_T("地面标高"), XString(_T("%.3f"), m_nEleUp)));
info.Append(new TObjInfoUnit(_T("井底标高"), XString(_T("%.3f"), m_nEleDown)));
int num = GetInterfaceNum();
info.Append(new TObjInfoUnit(_T("接管"), XString(_T("%d"), num)));
for(int i=0;i<num;i++){
TPipeInterface iFace;
GetInterface(i, iFace);
CString csPipeName, csLabel;
csLabel = GetISysLabel(i);
if(csLabel == _T(""))
continue;
OPENOBJ_BEGIN(iFace.m_idPipe,AcDb::kForRead,TDbPipePrototype,pPipe);
if(pPipe) {
csPipeName = pPipe->GetSysLabel();
}
OPENOBJ_END();
csPipeName.Format(_T("%s底标高"), csPipeName);
info.Append(new TObjInfoUnit((const TCHAR*)csPipeName, (const TCHAR*)csLabel));
}
}
//设置室外管道管底标高
void TDbWell::SetPipeEndEle(AcDbObjectId id, const TCHAR* szEle)
{
assertWriteEnabled();
int nCount = GetInterfaceNum();
for(int i=0; i<nCount; i++) {
TPipeInterface iFace;
GetInterface(i, iFace);
if(id == iFace.m_idPipe){
SetISysLabel(i, szEle);
return;
}
}
}
double TDbWell::GetWidth(const TDbPipePrototype* pPipe) const
{
double dWidth = 0.0;
// if (Is2DView()) cet 2018.1.31 del 三维下修改对象时,无法更新该值,会导致二维遮挡错误
{
// 有时管道与井(尤其是圆)有交点却求交失败,先将管道投影到与xy平面上再进行操作
// 可解决一些发现的此类问题
AcDbCurve *pCurve = pPipe->GetCurve().AsAcDbCurve();
AcDbCurve *pRetCurve = NULL;
if (pCurve->getProjectedCurve(AcGePlane::kXYPlane, AcGeVector3d::kZAxis, pRetCurve) == Acad::eOk)
{
delete pCurve;
pCurve = pRetCurve;
pRetCurve = NULL;
}
// 管道与井交点
AcGePoint3dArray arrPt;
::IntersectWith(this, pCurve, AcDb::kOnBothOperands, AcGePlane::kXYPlane, arrPt);
delete pCurve;
// 距离井最远的管道端点
XPoint ptS = pPipe->StartPoint();
XPoint ptE = pPipe->EndPoint();
XPoint ptLoc = m_ptLocation;
XPoint pt = ptS;
if (ptS.Distance2d(ptLoc) < ptE.Distance2d(ptLoc))
{
pt = ptE;
}
// 获得交点距离pt点的最近的点
double dMinDist = -1;
for(int i = 0; i < arrPt.length(); ++i)
{
double dDist = pt.Distance2d(arrPt[i]);
if (dMinDist < 0.0 || dMinDist > dDist)
{
dMinDist = dDist;
}
}
// 遮挡距离
if (dMinDist > 0.0)
{
dWidth = ptS.Distance2d(ptE) - dMinDist;
}
}
return dWidth;
}
// 判断节点是否可以连接管段. nPos: 0--start; 1--end
BOOL TDbWell::CanLinkSide(const AcDbObjectId &idPipe, int nPos) const
{
// cet 2010.8.27 add 点相等误差容许范围
double dTol = EqualPointTol();
BOOL bRet=FALSE;
double nRadius = GetScale() * GetPScale();
OPENOBJ_BEGIN(idPipe, AcDb::kForRead, TDbPipePrototype, pPipe);
if(pPipe) {
XPoint ptRef=nPos? pPipe->EndPoint() : pPipe->StartPoint();
XPoint ptLoc=GetLocation();
ptLoc.z =0;//
ptRef.z = 0;//
if(ptRef.Distance(ptLoc)<dTol)
bRet = TRUE;
double nDist = ptRef.Distance(ptLoc);
if(fabs(nDist - nRadius/2) < dTol)
bRet = TRUE;
}
OPENOBJ_END();
return bRet;
}
// 对st类型的接口进行重新连接
void TDbWell::UpdateLinkage(const XPoint &ptAt,
TPipeSys::SysType st,
const DList<AcDbObjectId> &idPipes)
{
assertWriteEnabled();
DList<TPipeInterface> lstInterface;//先保留一份出来,目的是得到各管底标高
for(int j=0; j<m_lstInterface.Length(); j++) {
TPipeInterface& iFace=*m_lstInterface[j];
lstInterface.Append(new TPipeInterface(iFace));
}
// cet 2010.8.27 add
double dMeter = 1.0;
if(DocGetMeterUnitDraw())
dMeter = 1000.0;
RemoveInterface(st);
double nRadius = GetScale() * GetPScale() * 0.8; // 适当减小半径,避免恰好在半径上的管线自动连接到插入点,以支持管道可直接连接在井边
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;
for(j=0; j<lstInterface.Length(); j++) {
TPipeInterface& iFace2=*lstInterface[j];
if(iFace2.m_idPipe == id){
iFace.m_sSysLabel = iFace2.m_sSysLabel;
break;
}
}
iFace.m_idPipe = id;
XPoint ptS, ptE;
ptS = pPipe->StartPoint();
ptE = pPipe->EndPoint();
ptS.z = 0;
ptE.z = 0;
XPoint ptLoc = m_ptLocation;
ptLoc.z = 0;
double nDist1 = ptLoc.Distance(ptS);
double nDist2 = ptLoc.Distance(ptE);
if(nDist1<PS_SNAP / dMeter || fabs(nDist1 - nRadius/2) < PS_SNAP / dMeter) {
if(fabs(nDist1 - nRadius/2) < PS_SNAP / dMeter){
if(pPipe->upgradeOpen()==Acad::eOk){
pPipe->SetStartPoint(m_ptLocation);
pPipe->downgradeOpen();
}
}
iFace.m_ptLocation = pPipe->StartPoint();
AcGeVector3d vt;
pPipe->getFirstDeriv(pPipe->StartPoint(), vt);
iFace.m_vtLocation = vt;
AddInterface(iFace);
} else if(nDist2<PS_SNAP / dMeter || fabs(nDist2 - nRadius/2) < PS_SNAP / dMeter) {
if(fabs(nDist2 - nRadius/2) < PS_SNAP / dMeter){
if(pPipe->upgradeOpen()==Acad::eOk){
pPipe->SetEndPoint(m_ptLocation);
pPipe->downgradeOpen();
}
}
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();
}
// lstInterface中未加到接口中,但与井实际相连的管线
for(int i = 0; i < lstInterface.Length(); ++i)
{
TPipeInterface& iFace1= *lstInterface[i];
bool bFind = false;
for(int j = 0; j < m_lstInterface.Length(); ++j)
{
TPipeInterface& iFace2 = *m_lstInterface[j];
if (iFace1.m_idPipe == iFace2.m_idPipe)
{
bFind = true;
break;
}
}
// 已经添加
if (bFind)
{
continue;
}
// 添加上与井实际相连的接口
OPENOBJ_BEGIN(iFace1.m_idPipe, AcDb::kForRead, TDbPipe, pPipe);
if(pPipe != NULL)
{
if (pPipe->StartPoint().Distance2d(m_ptLocation) < 0.001 ||
pPipe->EndPoint().Distance2d(m_ptLocation) < 0.001)
{
AddInterface(iFace1);
}
}
OPENOBJ_END();
}
}
extern CString ReadXdata(Entity ent, const TCHAR*szName);
CString TDbWell::GetXml( const AcGeMatrix3d& mat ) const
{
TXmlTree xmlTree;
CString csText, csX, csY, csZ;
int nPre = 3;
POSITION posRoot = xmlTree.Insert(_T("ATS_WELL"), NULL, NULL);
{
xmlTree.SetAttribute(posRoot, _T("name"), _T("井"));
xmlTree.SetAttribute(posRoot, _T("comment"), _T("上华对象名称"));
}
ads_name ent;
acdbGetAdsName(ent, objectId());
double dRadius = _tstof(ReadXdata(ent, _T("TG-WELL-RADIUS")));
if (DocGetMeterUnitDraw())
{
dRadius *= 0.001;
}
POSITION posDiameter = xmlTree.Insert(_T("Diameter"), posRoot, NULL);
{
xmlTree.SetAttribute(posDiameter,_T("name"), _T("井直径"));
csText = DoubleToString(dRadius, nPre);
xmlTree.SetItemText(posDiameter, csText);
}
POSITION posInsert = xmlTree.Insert(_T("Location"),posRoot, posDiameter);
{
xmlTree.SetAttribute(posInsert,_T("name"), _T("插入点"));
AcGePoint3d pt = m_ptLocation;
pt.transformBy(mat);
CString csX, csY, csZ;
csX = DoubleToString(pt.x, nPre);
csY = DoubleToString(pt.y, nPre);
csZ = DoubleToString(pt.z, nPre);
csText.Format(_T("%f,%f,%f"), pt.x, pt.y, pt.z);
xmlTree.SetItemText(posInsert, csText);
}
double dTopEle = m_nEleUp;
if (!DocGetMeterUnitDraw())
{
dTopEle *= 1000;
}
POSITION posTopEle = xmlTree.Insert(_T("TopElevation"),posRoot, posInsert);
{
xmlTree.SetAttribute(posTopEle,_T("name"), _T("井面标高"));
csX = DoubleToString(dTopEle, nPre);
xmlTree.SetItemText(posTopEle, csX);
}
POSITION posButtomEle = xmlTree.Insert(_T("BottomElevation"),posRoot, posTopEle);
{
xmlTree.SetAttribute(posButtomEle,_T("name"), _T("井底标高"));
double dButtomEle = m_nEleDown;
if (!DocGetMeterUnitDraw())
{
dButtomEle *= 1000;
}
csX = DoubleToString(dButtomEle, nPre);
xmlTree.SetItemText(posButtomEle, csX);
}
POSITION posItemId = xmlTree.Insert(_T("Object_ID"), posRoot, posButtomEle);
{
xmlTree.SetAttribute(posItemId, _T("name"), _T("ID"));
xmlTree.SetAttribute(posItemId, _T("comment"), _T("井ID"));
csText.Format(_T("%ld"), objectId().asOldId());
xmlTree.SetItemText(posItemId, csText);
}
AcGePoint3d ptInsert = m_ptLocation;
ptInsert.z = dTopEle;
AcGeMatrix3d mat2;
mat2.setToTranslation(ptInsert - AcGePoint3d::kOrigin);
mat2 = mat * mat2;
AcGeMatrix3d mat1;
mat1.setToScaling(dRadius * 1.2);
mat1 = mat2 * mat1;
CString sMat;
Matrix3D2String(mat1, sMat);
POSITION posItemMat= xmlTree.Insert(_T("Matrix3d"), posRoot, posItemId);
{
xmlTree.SetAttribute(posItemMat, _T("name"), _T("矩阵"));
xmlTree.SetAttribute(posItemMat, _T("comment"), _T("图块转换矩阵"));
xmlTree.SetItemText(posItemMat, sMat);
}
POSITION posItemBlk2D = xmlTree.Insert(_T("Blk2D"), posRoot, posItemMat);
{
xmlTree.SetAttribute(posItemBlk2D, _T("name"), _T("2D图块名"));
const TCHAR *szBlkName = NULL;
OPENOBJ_BEGIN(m_idBlock2d, AcDb::kForRead, AcDbBlockTableRecord, pRecord);
if(pRecord != NULL)
pRecord->getName(szBlkName);
OPENOBJ_END();
csText = szBlkName;
xmlTree.SetItemText(posItemBlk2D, csText);
}
POSITION posItemScale = xmlTree.Insert(_T("Scale"), posRoot, posItemBlk2D);
{
xmlTree.SetAttribute(posItemScale, _T("name"), _T("图块显示比例"));
csText = DoubleToString(m_dScale, nPre);
xmlTree.SetItemText(posItemScale, csText);
}
POSITION posItemLabelDrawalbe = xmlTree.Insert(_T("LabelDrawable"), posRoot, posItemScale);
{
xmlTree.SetAttribute(posItemLabelDrawalbe, _T("name"), _T("是否显示标注"));
csText.Format(_T("%ld"), m_bDrawLabel ? 1 : 0);
xmlTree.SetItemText(posItemLabelDrawalbe, csText);
}
POSITION posItemLabel = xmlTree.Insert(_T("Label"), posRoot, posItemLabelDrawalbe);
{
xmlTree.SetAttribute(posItemLabel, _T("name"), _T("井编号"));
xmlTree.SetItemText(posItemLabel, m_sWellName);
}
POSITION posItemLabelLoc = xmlTree.Insert(_T("LabelLoc"), posRoot, posItemLabel);
{
xmlTree.SetAttribute(posItemLabelLoc, _T("name"), _T("标注位置"));
AcGePoint3d pt = m_ptLabel;
pt.transformBy(mat);
CString csX, csY, csZ;
csX = DoubleToString(pt.x, nPre);
csY = DoubleToString(pt.y, nPre);
csZ = DoubleToString(pt.z, nPre);
csText.Format(_T("%f,%f,%f"), pt.x, pt.y, pt.z);
xmlTree.SetItemText(posItemLabelLoc, csText);
}
POSITION posItemLabelLayer = xmlTree.Insert(_T("LabelLayer"), posRoot, posItemLabelLoc);
{
xmlTree.SetAttribute(posItemLabelLayer, _T("name"), _T("标注图层名"));
csText = GetSymbolName(m_idLabelLayer);
xmlTree.SetItemText(posItemLabelLayer, csText);
}
POSITION posItemLabelTextHeight = xmlTree.Insert(_T("LabelTextHeight"), posRoot, posItemLabelLayer);
{
xmlTree.SetAttribute(posItemLabelTextHeight, _T("name"), _T("标注文字高度"));
csText = DoubleToString(m_dTextHeight, nPre);
xmlTree.SetItemText(posItemLabelTextHeight, csText);
}
POSITION posItemLabelTextStyle = xmlTree.Insert(_T("LabelTextStyle"), posRoot, posItemLabelTextHeight);
{
xmlTree.SetAttribute(posItemLabelTextStyle, _T("name"), _T("标注文字样式"));
AcDbDatabase *pCurDwg = acdbCurDwg();
const TCHAR* pName = NULL;
AcDbTextStyleTable* pTT;
VERIFY(pCurDwg->getSymbolTable(pTT, AcDb::kForRead) == Acad::eOk);
pTT->close();
AcDbTextStyleTableRecord* pTTR;
acdbOpenObject(pTTR, m_idTextStyle, AcDb::kForRead);
if (pTTR->getName(pName) != Acad::eOk)
{
pTTR->close();
}
csText = pName;
pTTR->close();
xmlTree.SetItemText(posItemLabelTextStyle, csText);
}
CString sXml = xmlTree.GetXml();
int nIdex = -1;
nIdex = sXml.Find(_T("</ATS_WELL>"));
if (nIdex != -1)
{
CString sTemp = TDbEntity::GetXml(mat);
sXml.Insert(nIdex, sTemp);
}
return sXml;
}
// zxl 2013.06.07 add 根据管线 获取当前标注位置
XPoint TDbWell::GetWellDimPosByPipe(const AcDbObjectId &idPipe)
{
XPoint ptS, ptE, ptLoc, ptTurn;
OPENOBJ_BEGIN(idPipe, AcDb::kForWrite, TDbPipe, pPipe);
if(pPipe != NULL)
{
ptLoc = GetLocation();
downgradeOpen();
pPipe->ResetDrawSpeed();
upgradeOpen();
XCurveSegment cv;
pPipe->GetHideCurve(cv);
ptS = cv.GetStartPoint();
ptE = cv.GetEndPoint();
if (ptS.Distance2d(ptLoc) < ptE.Distance2d(ptLoc))
{
ptLoc = ptS;
}
else if (ptS.Distance2d(ptLoc) > ptE.Distance2d(ptLoc))
{
ptLoc = ptE;
}
}
OPENOBJ_END();
return ptLoc;
}
// zxl 2013.06.07 add 实时更新单一管底标注位置
void TDbWell::ModifyWellDimPos(const AcDbObjectId &idPipe)
{
XPoint ptLoc = GetWellDimPosByPipe(idPipe);
// 遍历块表记录,获取当前井的管底标注
AcDbBlockTableRecord *pRecord = NULL;
AcDbBlockTable* pBlockTable = NULL;
acdbCurDwg()->getBlockTable(pBlockTable, AcDb::kForRead);
if(pBlockTable == NULL)
return;
if(Acad::eOk != pBlockTable->getAt(ACDB_MODEL_SPACE, pRecord, AcDb::kForRead))
{
pBlockTable->close();
return;
}
pBlockTable->close();
AcDbBlockTableRecordIterator *pIterator = NULL;
pRecord->newIterator(pIterator);
pRecord->close();
AcDbEntity *pEnt = NULL;
TDbWellDim *pDim = NULL;
for(pIterator->start(); !pIterator->done(); pIterator->step())
{
pIterator->getEntity(pEnt, AcDb::kForRead);
if (pEnt != NULL)
{
pDim = TDbWellDim::cast(pEnt);
if(pDim != NULL && pDim->GetIsNewDim() && pDim->GetPipeId() == idPipe && pDim->GetWellId() == id())
{
AcGeVector3d vt = ptLoc - pDim->GetStartPoint();
if (pDim->upgradeOpen() == Acad::eOk)
{
pDim->SetStartPoint(ptLoc);
XPoint ptTurn = pDim->GetTurnPoint() + vt;
pDim->SetTurnPoint(ptTurn);
pDim->downgradeOpen();
}
}
pEnt->close();
}
}
delete pIterator;
}
//zxl 2013.07.23 add
Acad::ErrorStatus TDbWell::subClose()
{
Acad::ErrorStatus es = TDbEquipment::subClose();
if (es != Acad::eOk)
{
return es;
}
// 优化速度,不更新汇流面积和井底标注,此开关在应用层设置
if (!GetUpdatable())
{
SetUpdatable(TRUE);
return es;
}
// zxl 2013.12.12 add
CString sName = m_sWellName.cs();
AcDbObjectId idSpace = GetSpaceId();
if (idSpace != NULL)
{
OPENOBJ_BEGIN(idSpace, AcDb::kForWrite, TDbSpace, pSpace);
if(pSpace != NULL)
{
if (sName.Find(_T("(")) > 0)
{
sName = sName.Left(sName.Find(_T("(")));
}
pSpace->m_sName = sName + _T("汇流面积");
}
OPENOBJ_END();
}
if(m_bIsModify && !IsTransformCmd())
{
m_bIsModify = false;
if(isModified() && database()==acdbCurDwg())
{
int nCount = m_lstInterface.Length();
for (int i=0; i<nCount; i++)
{
TPipeInterface &iFace = *m_lstInterface[i];
AcDbObjectId id = iFace.m_idPipe;
ModifyWellDimPos(id);
}
}
}
return es;
}
Acad::ErrorStatus TDbWell::subIntersectWith(const AcDbEntity* pEnt, AcDb::Intersect intType, AcGePoint3dArray& points,INT_PTR thisGsMarker /*= 0*/, INT_PTR otherGsMarker /*= 0*/) const
{
return TDbEquipment::subIntersectWith(pEnt, intType, points, thisGsMarker, otherGsMarker);
}
Acad::ErrorStatus TDbWell::subIntersectWith(const AcDbEntity* pEnt, AcDb::Intersect intType, const AcGePlane& projPlane, AcGePoint3dArray& points, INT_PTR thisGsMarker /*= 0*/, INT_PTR otherGsMarker /*= 0*/) const
{
if (::IntersectWith(this, pEnt, intType, projPlane, points))
{
return Acad::eOk;
}
return TDbEquipment::subIntersectWith(pEnt, intType, projPlane, points, thisGsMarker, otherGsMarker);
}
void InitDbWell(BOOL bTrue)
{
if(bTrue) {
TDbWell::rxInit();
TDbWell::InitMatchProtocol(TRUE);
} else {
TDbWell::InitMatchProtocol(FALSE);
deleteAcRxClass(TDbWell::desc());
}
}