Files
envi-code/SourceCode/Code2026/Dimension/DbWell.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

975 lines
26 KiB
C++

#include "stdafx.h"
#include "PickEntSet.h"
#include "PushProperty.h"
#include "AecDbText.h"
#include "AcDbObjectPtr.h"
#include "DbWell.h"
#include "DbPipe.h"
#include <actrans.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
{
Acad::ErrorStatus DrawPolyMesh(XPoint ptSt, XPoint ptEn, double nRadius, AcGiDraw &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;
}
// 管道与井求交
bool IntersectWith(const AecXDbWell *pWell, const AcDbEntity* pEntCurve, AcDb::Intersect intType, const AcGePlane& projPlane, AcGePoint3dArray& points)
{
// cet 2018.1.31 modify 只有二维图形计算交点
// pWell->explode(entSet1);
AcGiViewDraw dc;
pWell->Draw2d(dc);
const AcDbVoidPtrArray &entSet1 = pWell->Get2DBuffer();
for (int i = 0; i < entSet1.length(); ++i)
{
AcDbEntity *pEnt = (AcDbEntity *)entSet1[i];
if (pEnt->isKindOf(CDbEquipment::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]);
}
}
}
GlobalFunc::ReleaseEntSet(entSet3);
}
}
GlobalFunc::ReleaseEntSet(entSet2);
}
}
// 交点多于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(AecXDbWell, CDbEquipment, AcDb::kDHL_CURRENT,
AcDb::kMReleaseCurrent, 1, AEC_ZT_WELL,
"AEC_ZT_WELL图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
const Adesk::UInt8 AecXDbWell::g_nVersion = 2;
AecXDbWell::AecXDbWell()
{
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 AecXDbWell::CopyPropertiesFrom(AcDbEntity *pSrc, unsigned gMatchFlag)
{
assertWriteEnabled();
CDbEquipment::CopyPropertiesFrom(pSrc, gMatchFlag);
AecXDbWell *pEqu = AecXDbWell::cast(pSrc);
if (pEqu) {
m_idBlock2d = pEqu->m_idBlock2d;
}
}
//Acad::ErrorStatus AecXDbWell::subGetClassID(CLSID* pClsid) const
//{
// return Acad::eOk;
//}
Acad::ErrorStatus
AecXDbWell::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);
}
}
GlobalFunc::ReleaseEntSet(blockArray);
}
return es;
}
Acad::ErrorStatus
AecXDbWell::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
AecXDbWell::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 AecXDbWell::subGetGripPoints(AcDbGripDataPtrArray & grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d & curViewDir, const int bitflags) const
{
return Acad::eNotImplementedYet;
}
Acad::ErrorStatus
AecXDbWell::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const
{
assertReadEnabled();
stretchPoints.append((AcGePoint3d)m_ptLocation);
stretchPoints.append((AcGePoint3d)m_ptLabel);
return Acad::eOk;
}
Acad::ErrorStatus
AecXDbWell::subMoveGripPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
Acad::ErrorStatus es = Acad::eOk;
es = MoveGSPointsAt(indices, offset);
return es;
}
Acad::ErrorStatus
AecXDbWell::subMoveStretchPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
Acad::ErrorStatus es = Acad::eOk;
es = MoveGSPointsAt(indices, offset, false);
return es;
}
Acad::ErrorStatus
AecXDbWell::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++) {
CPipeInterface face;
GetInterface(m, face);
// cet 2012.4.23 add 管线自身完成拉伸时,不再在此处理
acdbGetAdsName(name, face.m_idPipe);
Entity ent(name);
if (GlobalFunc::DocGetPickFirst().IsInclude(ent))
{
continue;
}
OPENOBJ_BEGIN(face.m_idPipe, AcDb::kForWrite, CDbPipe, 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
AecXDbWell::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
CDbEquipment::subTransformBy(xform);
m_ptLabel.TransformBy(xform);
return Acad::eOk;
}
// 从DWG读入数据:
Acad::ErrorStatus AecXDbWell::dwgInFields(AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = CDbEquipment::dwgInFields(pFiler);
if (es != Acad::eOk) return es;
es = CLabelStyle::dwgInFields(pFiler);
if (es != Acad::eOk) return es;
Adesk::UInt8 nVer;
pFiler->readItem(&nVer);
GlobalFunc::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);
GlobalFunc::FilerRead(pFiler, m_bDrawLabel);
pFiler->readItem(&m_idLabelLayer);
return pFiler->filerStatus();
}
Acad::ErrorStatus AecXDbWell::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = CDbEquipment::dwgOutFields(pFiler);
if (es != Acad::eOk) return es;
es = CLabelStyle::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);
GlobalFunc::FilerWrite(pFiler, m_bDrawLabel);
pFiler->writeItem(m_idLabelLayer);
return pFiler->filerStatus();
}
Acad::ErrorStatus AecXDbWell::dxfInFields(AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = Acad::eOk;
es = CDbEquipment::dxfInFields(pFiler);
if (es != Acad::eOk) return es;
if (!pFiler->atSubclassData(_T("AecXDbWell"))) {
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 AecXDbWell::dxfOutFields(AcDbDxfFiler* pFiler) const
{
Acad::ErrorStatus es = Acad::eOk;
es = CDbEquipment::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass, _T("AecXDbWell"));
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 (GlobalFunc::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;
}
Acad::ErrorStatus AecXDbWell::Draw3d(AcGiDraw &dc) const
{
Acad::ErrorStatus es = Acad::eOk;
XPoint pt1, pt2;
pt1 = pt2 = m_ptLocation;
if (GlobalFunc::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=CDbEquipment::ExplodeOrDraw3d(dc);
return es;
}
Acad::ErrorStatus AecXDbWell::Draw2d(AcGiDraw &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;
CDbEquipment pEquip;
pEquip.SetBlock2d(m_idBlock2d);
pEquip.SetLocation(m_ptLocation);
pEquip.SetDirection(m_vtDirection);
pEquip.SetScale(GetScale() * 100);
pEquip.SetHidePipe(m_bHidePipe);
pEquip.setPropertiesFrom(this);
DrawBaseEx(dc, pEquip);
//dc.DrawEntity(pEquip);
if (m_bDrawLabel) // 绘制标注
DrawLabelText(dc);
return Acad::eOk;
}
Acad::ErrorStatus AecXDbWell::DrawLabelText(AcGiDraw &dc) const
{
AcDbObjectId idLayerOld = dc.GetLayerId();
if (m_idLabelLayer.isValid())
dc.SetLayer(m_idLabelLayer);
CString csDimText = (LPCTSTR)m_sWellName;
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;
}
AecXDbText 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(AcGiDraw::kMiddleCenter);
text.SetRotation(GetDimAngle()); // cet 2011.8.25 add 设置标注角度
PushProperty vProp(&text, dc);
DrawBaseEx(dc, text);
dc.SetLayer(idLayerOld);
return Acad::eOk;
}
// 根据管线初始化管线标注位置
void AecXDbWell::InitLabelLocation(double nScale)
{
assertWriteEnabled();
double Len = GetScale() * GetPScale();
double nLenText = Len / 2 * nScale;
double nAng = GlobalFunc::Ucs2Wcs(PI / 2);
ads_polar(m_ptLocation, nAng, nLenText, m_ptLabel);
}
void AecXDbWell::GetTips(DList<ObjInfoUnit> &info) const
{
info.Append(new ObjInfoUnit(_T("对象类型"), _T("室外井")));
info.Append(new ObjInfoUnit(_T("井编号"), m_sWellName));
info.Append(new ObjInfoUnit(_T("地面标高"), XString(_T("%.3f"), m_nEleUp)));
info.Append(new ObjInfoUnit(_T("井底标高"), XString(_T("%.3f"), m_nEleDown)));
int num = GetInterfaceNum();
info.Append(new ObjInfoUnit(_T("接管"), XString(_T("%d"), num)));
for (int i = 0; i < num; i++) {
CPipeInterface iFace;
GetInterface(i, iFace);
CString csPipeName, csLabel;
csLabel = GetISysLabel(i);
if (csLabel == _T(""))
continue;
OPENOBJ_BEGIN(iFace.m_idPipe, AcDb::kForRead, CDbPipePrototype, pPipe);
if (pPipe) {
csPipeName = pPipe->GetSysLabel();
}
OPENOBJ_END();
csPipeName.Format(_T("%s底标高"), csPipeName);
info.Append(new ObjInfoUnit((const TCHAR*)csPipeName, (const TCHAR*)csLabel));
}
}
//设置室外管道管底标高
void AecXDbWell::SetPipeEndEle(AcDbObjectId id, const TCHAR* szEle)
{
assertWriteEnabled();
int nCount = GetInterfaceNum();
for (int i = 0; i < nCount; i++) {
CPipeInterface iFace;
GetInterface(i, iFace);
if (id == iFace.m_idPipe) {
SetISysLabel(i, szEle);
return;
}
}
}
double AecXDbWell::GetWidth(const CDbPipePrototype* 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 AecXDbWell::CanLinkSide(const AcDbObjectId &idPipe, int nPos) const
{
// cet 2010.8.27 add 点相等误差容许范围
double dTol = GlobalFunc::EqualPointTol();
BOOL bRet = FALSE;
double nRadius = GetScale() * GetPScale();
OPENOBJ_BEGIN(idPipe, AcDb::kForRead, CDbPipePrototype, 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 AecXDbWell::UpdateLinkage(const XPoint &ptAt,
TPipeSys::SysType st,
const DList<AcDbObjectId> &idPipes)
{
assertWriteEnabled();
DList<CPipeInterface> lstInterface;//先保留一份出来,目的是得到各管底标高
for (int j = 0; j < m_lstInterface.Length(); j++) {
CPipeInterface& iFace = *m_lstInterface[j];
lstInterface.Append(new CPipeInterface(iFace));
}
// cet 2010.8.27 add
double dMeter = 1.0;
if (GlobalFunc::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, CDbPipe, pPipe);
if (pPipe) {
CPipeInterface iFace;
iFace.m_sysType = st;
iFace.m_faceType = CPipeInterface::kNodeLocation;
for (j = 0; j < lstInterface.Length(); j++) {
CPipeInterface& 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)
{
CPipeInterface& iFace1 = *lstInterface[i];
bool bFind = false;
for (int j = 0; j < m_lstInterface.Length(); ++j)
{
CPipeInterface& iFace2 = *m_lstInterface[j];
if (iFace1.m_idPipe == iFace2.m_idPipe)
{
bFind = true;
break;
}
}
// 已经添加
if (bFind)
{
continue;
}
// 添加上与井实际相连的接口
OPENOBJ_BEGIN(iFace1.m_idPipe, AcDb::kForRead, CDbPipe, pPipe);
if (pPipe != NULL)
{
if (pPipe->StartPoint().Distance2d(m_ptLocation) < 0.001 ||
pPipe->EndPoint().Distance2d(m_ptLocation) < 0.001)
{
AddInterface(iFace1);
}
}
OPENOBJ_END();
}
}
// zxl 2013.06.07 add 根据管线 获取当前标注位置
XPoint AecXDbWell::GetWellDimPosByPipe(const AcDbObjectId &idPipe)
{
XPoint ptS, ptE, ptLoc, ptTurn;
OPENOBJ_BEGIN(idPipe, AcDb::kForWrite, CDbPipe, 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 AecXDbWell::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 AecXDbWell::subClose()
{
Acad::ErrorStatus es = CDbEquipment::subClose();
if (es != Acad::eOk)
{
return es;
}
// 优化速度,不更新汇流面积和井底标注,此开关在应用层设置
if (!GetUpdatable())
{
SetUpdatable(TRUE);
return es;
}
// zxl 2013.12.12 add
CString sName = (LPCTSTR)m_sWellName;
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 && !GlobalFunc::IsTransformCmd())
{
m_bIsModify = false;
if (isModified() && database() == acdbCurDwg())
{
int nCount = m_lstInterface.Length();
for (int i = 0; i < nCount; i++)
{
CPipeInterface &iFace = *m_lstInterface[i];
AcDbObjectId id = iFace.m_idPipe;
ModifyWellDimPos(id);
}
}
}
return es;
}
Acad::ErrorStatus AecXDbWell::subIntersectWith(const AcDbEntity* pEnt, AcDb::Intersect intType, AcGePoint3dArray& points, INT_PTR thisGsMarker /*= 0*/, INT_PTR otherGsMarker /*= 0*/) const
{
return CDbEquipment::subIntersectWith(pEnt, intType, points, thisGsMarker, otherGsMarker);
}
Acad::ErrorStatus AecXDbWell::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 CDbEquipment::subIntersectWith(pEnt, intType, projPlane, points, thisGsMarker, otherGsMarker);
}
void InitDbWell(BOOL bTrue)
{
if (bTrue) {
AecXDbWell::rxInit();
//AecXDbWell::InitMatchProtocol(TRUE);
}
else {
//AecXDbWell::InitMatchProtocol(FALSE);
deleteAcRxClass(AecXDbWell::desc());
}
}