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

1234 lines
34 KiB
C++

#include "stdafx.h"
#include "AcDbObjectPtr.h"
#include "globalFunc.h"
#include "globalDefine.h"
#include "DbEquipment.h"
#include "DbPipe.h"
#include "PipePrototype.h"
#include <sstream>
static double g_dPointToOriginLimitDist = 1e+6;
void Matrix3D2String(const AcGeMatrix3d &mat, CString &str)
{
#if ADS <= 15
std::ostringstream stream;
#else
std::wostringstream stream;
#endif
for (int ln = 0; ln < 4; ++ln)
{
for (int col = 0; col < 4; ++col)
{
stream << mat.entry[ln][col];
#if ADS <= 15
stream << " ";
#else
stream << L" ";
#endif
}
}
str = stream.str().c_str();
}
// cet2017.3.2 add 设备类型名
CString GetEquipmentName(const CDbEquipment *pEquip)
{
CString sName = _T("普通设备");
if (pEquip == NULL)
{
return sName;
}
if (pEquip->IsSprinkler())
{
sName = _T("喷头");
}
else if (pEquip->IsHydrant())
{
sName = _T("消火栓");
}
int nEquipType = pEquip->GetEquipmentType();
switch (nEquipType)
{
case 0:
{
sName = _T("消火栓");
break;
}
case 1:
{
sName = _T("喷头");
break;
}
case 2:
{
sName = _T("井");
break;
}
case 3:
{
sName = _T("水泵");
break;
}
case 4:
{
sName = _T("雨水口");
break;
}
case 5:
{
sName = _T("大小接头");
break;
}
default:
break;
}
return sName;
}
extern CString ReadXdata(Entity ent, const TCHAR*szName);
ACRX_DXF_DEFINE_MEMBERS(CDbEquipment, CDbPipeNode, AcDb::kDHL_CURRENT,
AcDb::kMReleaseCurrent, 1, AEC_ZT_EQUIPMENT,
"AEC_ZT_EQUIPMENT图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
const Adesk::UInt8 CDbEquipment::g_nVersion = 3;
CDbEquipment::CDbEquipment() :
m_vtDirection(1, 0, 0), m_dScale(1.0), m_dDang(0.5),
m_bHidePipe(TRUE), m_nMirror(0), m_dPipeLength(0)
{
m_visibility = TPipeSys::kVisible;
m_dYScale = 0;
m_dZScale = 0;
m_bAutoScale = TRUE;
}
void CDbEquipment::CopyPropertiesFrom(AcDbEntity *pSrc, unsigned gMatchFlag)
{
assertWriteEnabled();
CDbPipeNode::CopyPropertiesFrom(pSrc, gMatchFlag);
CDbEquipment *pEqu = CDbEquipment::cast(pSrc);
if (pEqu) {
//m_idBlock2d = pEqu->m_idBlock2d;
//m_idBlock3d = pEqu->m_idBlock3d;
//m_sSysBlock = pEqu->m_sSysBlock;
//m_dScale = pEqu->m_dScale;
m_bHidePipe = pEqu->m_bHidePipe;
//m_nMirror = pEqu->m_nMirror;
//m_dPipeLength = pEqu->m_dPipeLength;
//m_dDang = pEqu->m_dDang;
}
}
//Acad::ErrorStatus CDbEquipment::subGetClassID(CLSID* pClsid) const
//{
// return Acad::eOk;
//}
Acad::ErrorStatus
CDbEquipment::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_ptInsert);
snapPoints.append(m_ptLocation);
}
es = CDbPipeNode::subGetOsnapPoints(osnapMode, gsSelectionMark,
ptPick, lastPoint, viewXform, snapPoints, geomIds);
return es;
}
// 从DWG读入数据:
Acad::ErrorStatus CDbEquipment::dwgInFields(AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = CDbPipeNode::dwgInFields(pFiler);
if (es != Acad::eOk) return es;
Adesk::UInt8 nVer;
pFiler->readItem(&nVer);
if (nVer > g_nVersion) {// Version is too new
return Acad::eMakeMeProxy;
}
pFiler->readItem(&m_idBlock2d);
pFiler->readItem(&m_idBlock3d);
GlobalFunc::ReadString(pFiler, m_sSysBlock);
pFiler->readItem((AcGePoint3d *)&m_ptLocation);
pFiler->readItem((AcGePoint3d *)&m_ptInsert);
pFiler->readItem((AcGeVector3d *)&m_vtDirection);
pFiler->readItem(&m_dScale);
//pFiler->readItem(&m_bHidePipe);
GlobalFunc::FilerRead(pFiler, m_bHidePipe);
pFiler->readItem(&m_nMirror);
pFiler->readItem(&m_dPipeLength);
pFiler->readItem(&m_dDang);
if (nVer > 1) {
pFiler->readItem(&m_dCircleRadius);
pFiler->readItem(&m_dYScale);
pFiler->readItem(&m_dZScale);
pFiler->readItem(&m_dSpare);
if (nVer > 2) {
//pFiler->readItem(&m_bAutoScale);
GlobalFunc::FilerRead(pFiler, m_bAutoScale);
}
}
return pFiler->filerStatus();
}
Acad::ErrorStatus CDbEquipment::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = CDbPipeNode::dwgOutFields(pFiler);
if (es != Acad::eOk) return es;
pFiler->writeItem(g_nVersion);
pFiler->writeItem(m_idBlock2d);
pFiler->writeItem(m_idBlock3d);
pFiler->writeItem((const TCHAR *)m_sSysBlock);
pFiler->writeItem((const AcGePoint3d &)m_ptLocation);
pFiler->writeItem((const AcGePoint3d &)m_ptInsert);
pFiler->writeItem((const AcGeVector3d &)m_vtDirection);
pFiler->writeItem(m_dScale);
//pFiler->writeItem(m_bHidePipe);
GlobalFunc::FilerWrite(pFiler, m_bHidePipe);
pFiler->writeItem(m_nMirror);
pFiler->writeItem(m_dPipeLength);
pFiler->writeItem(m_dDang);
pFiler->writeItem(m_dCircleRadius);
pFiler->writeItem(m_dYScale);
pFiler->writeItem(m_dZScale);
pFiler->writeItem(m_dSpare);
GlobalFunc::FilerWrite(pFiler, m_bAutoScale);
return pFiler->filerStatus();
}
Acad::ErrorStatus CDbEquipment::dxfInFields(AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = Acad::eOk;
es = CDbPipeNode::dxfInFields(pFiler);
if (es != Acad::eOk) return es;
if (!pFiler->atSubclassData(_T("CDbEquipment"))) {
return Acad::eBadDxfSequence;
}
resbuf rb;
while ((es == Acad::eOk) && ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) {
switch (rb.restype) {
case AcDb::kDxfXCoord:
m_ptLocation = rb.resval.rpoint;
break;
case AcDb::kDxfXReal:
m_dScale = rb.resval.rreal;
break;
case AcDb::kDxfBlockName:
break;
default:
pFiler->pushBackItem();
es = Acad::eEndOfFile;
break;
}
}
if (es != Acad::eEndOfFile)
return Acad::eInvalidResBuf;
return pFiler->filerStatus();
}
Acad::ErrorStatus CDbEquipment::dxfOutFields(AcDbDxfFiler* pFiler) const
{
Acad::ErrorStatus es = Acad::eOk;
es = CDbPipeNode::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass, _T("CDbEquipment"));
assert(es == Acad::eOk);
pFiler->writePoint3d(AcDb::kDxfXCoord, m_ptLocation);
pFiler->writeDouble(AcDb::kDxfXReal, m_dScale);
CString sBlkName, sDesName;
GlobalFunc::GetBlkNameById(m_idBlock2d, sBlkName, sDesName);
pFiler->writeString(AcDb::kDxfBlockName, (const TCHAR*)sBlkName);
// cet 2017.3.2 add 添加设备类型名,用于识别设备
CString sName = GetEquipmentName(this);
pFiler->writeString(AcDb::kDxfXTextString, (const TCHAR*)sName);
return es;
}
// 图块插入比例
AcGeScale3d CDbEquipment::GetInsertScale() const
{
assertReadEnabled();
double dScale(1), dScaleY(1), dScaleZ(1);
if (m_bAutoScale)
{
dScale = m_dScale * GetPScale() / 100;
dScaleY = m_dYScale * GetPScale() / 100;
dScaleZ = m_dZScale * GetPScale() / 100;
}
else
{
dScale = m_dScale;
dScaleY = m_dYScale;
dScaleZ = m_dZScale;
}
if (fabs(dScaleY) < 0.001)
dScaleY = dScale;
if (fabs(dScaleZ) < 0.001)
dScaleZ = dScale;
AcGeScale3d scale(dScale, dScaleY, fabs(dScaleZ));
if (IsMirrorByY())
scale.sx *= -1;
if (IsMirrorByX())
scale.sy *= -1;
return scale;
}
Acad::ErrorStatus CDbEquipment::Draw2d(AcGiDraw &dc) const
{
if (Has2DBuffer())
{
Draw2DBuffers(dc);
return Acad::eOk;
}
// cet 2016.10.17 add 图层关闭时,实体不显示,不进行绘制(打印时,也不会绘制)
//AcDbLayerTableRecordPointer player(this->layerId(), AcDb::kForRead);
//if (player.openStatus() == Acad::eOk && player->isOff())
//{
// return Acad::eOk;
//}
return _ExplodeOrDraw2d(dc);
}
Acad::ErrorStatus CDbEquipment::_ExplodeOrDraw2d(AcGiDraw &dc, BOOL bZEqual0) const
{
if (!m_idBlock2d.isValid())
return Acad::eInvalidInput;
if (fabs(m_vtDirection.x) < 1.0E-6 && fabs(m_vtDirection.y) < 1.0E-6)
return Acad::eOk; //垂直设备
XPoint ptInsert = m_ptInsert;
if (bZEqual0) ptInsert.z = 0;
double dAngle = ads_angle(XPoint(), m_vtDirection);
DrawBlock(dc, m_idBlock2d, m_ptInsert, GetInsertScale(), dAngle);
OPENOBJ_BEGIN(m_idBlock2d, AcDb::kForRead, AcDbBlockTableRecord, pBlock);
if (pBlock) {
// BOOL bNewMethod=(g_nAcadVer>15.0001 && g_bMakeBlock);
// sg add 091105,强制打印时,不使用新方法
// if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0 && dc.IsPlotGeneration())
// bNewMethod = FALSE;
//2011-9-30 SBdc.DrawBlock(*pBlock,ptInsert,GetInsertScale(),dAngle,TRUE); 采用旧方法,从8.0版本开始,TRUE参数对于打印不起作用。关闭图层,仍然打印
//dc.DrawBlock(*pBlock,ptInsert,GetInsertScale(),dAngle,bNewMethod);
//dc.DrawBlock(*pBlock, ptInsert, GetInsertScale(), dAngle, TRUE);
}
OPENOBJ_END();
return Acad::eOk;
}
Acad::ErrorStatus CDbEquipment::Draw3d(AcGiDraw &dc) const
{
if (!m_idBlock3d.isValid())
return _ExplodeOrDraw2d(dc, FALSE);
OPENOBJ_BEGIN(m_idBlock3d, AcDb::kForRead, AcDbBlockTableRecord, pBlock);
if (pBlock) {
XVector3D vtNormal(0, 0, 1);
if (fabs(m_vtDirection.z) > 1.0E-6)
{ //非水平面,计算法向
vtNormal = GlobalFunc::operator*(XVector3D(1, 0, 0) ,m_vtDirection);
//vtNormal = XVector3D(1, 0, 0) * m_vtDirection;
vtNormal.Normalize();
}
//XPoint ptLoc=GlobalFunc::Wcs2Ecs(m_ptLocation, vtNormal); cet 2011.12.29 modify
XPoint ptInsert = m_ptInsert;
ptInsert.z = m_ptLocation.z;
XPoint ptLoc = GlobalFunc::Wcs2Ecs(ptInsert, vtNormal);
if (IsUpLinkHydrant()) // 上接消火栓补充一段管线
{
ExplodeOrDrawPipe3d(dc);
}
double nRotEcs = ads_angle(XPoint(), m_vtDirection); //计算ECS下的转角
AcDbBlockReference insert(ptLoc, m_idBlock3d);
insert.setRotation(nRotEcs);
insert.setScaleFactors(GetInsertScale());
//if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor()) == 0) {
AcGeMatrix3d mat = insert.blockTransform();
AcGiGeometry *geom = ((AcGiViewDraw &)dc).GetCommonDraw()->rawGeometry();
geom->pushModelTransform(mat);
geom->draw(pBlock);
geom->popModelTransform();
//}
//else if (_tcscmp(dc.Desc(), XExplodeStream::Descriptor()) == 0) {
// ((XExplodeStream &)dc).Append((AcDbEntity *)insert.clone());
//}
}
else {
return Acad::eInvalidInput;
}
OPENOBJ_END();
return Acad::eOk;
}
Acad::ErrorStatus CDbEquipment::ExplodeOrDrawPipe3d(AcGiDraw &dc) const
{
// 获得连接管的id
int nNum = GetInterfaceNum();
CPipeInterface face;
AcDbObjectId idPipe;
for (int i = 0; i < nNum; i++)
{
GetInterface(i, face);
idPipe = face.m_idPipe;
break;
}
OPENOBJ_BEGIN(idPipe, AcDb::kForRead, CDbPipe, pPipe);
if (pPipe != NULL)
{
// 获得管道起点终点
XVector3D vtNormal(0, 0, 1);
if (fabs(m_vtDirection.z) > 1.0E-6) //非水平面,计算法向
{
vtNormal = GlobalFunc::operator*(XVector3D(1, 0, 0) ,m_vtDirection);
//vtNormal = XVector3D(1, 0, 0) * m_vtDirection;
vtNormal.Normalize();
}
XPoint ptInsert = m_ptInsert;
ptInsert.z = m_ptLocation.z;
XPoint pt1 = GlobalFunc::Wcs2Ecs(ptInsert, vtNormal);
XLine line(pPipe->StartPoint(), pPipe->EndPoint());
XPoint pt2 = GlobalFunc::Wcs2Ecs(m_ptLocation, vtNormal);
m_ptLocation.Project(&line, pt2);
CDbPipe *pNewPipe = (CDbPipe *)pPipe->clone();
pNewPipe->SetStartPoint(pt1);
pNewPipe->SetEndPoint(pt2);
pNewPipe->SetNode(0, AcDbObjectId::kNull);
pNewPipe->SetNode(1, AcDbObjectId::kNull);
Adesk::UInt16 color = dc.GetColor();
dc.SetColor(1);
DrawBaseEx(dc, *pNewPipe);
//pNewPipe->Draw3d(dc);
dc.SetColor(color);
}
OPENOBJ_END();
return Acad::eOk;
}
void CDbEquipment::GetTips(DList<ObjInfoUnit> &info) const
{
info.Append(new ObjInfoUnit(_T("对象类型"), _T("设备")));
CString sBlkName, sDesName;
if (GlobalFunc::GetBlkNameById(m_idBlock2d, sBlkName, sDesName) && !sDesName.IsEmpty()) {
info.Append(new ObjInfoUnit(_T("对象名称"), (const TCHAR*)sDesName));
}
// if(sDesName.Find(_T("井")) > -1){ //检查井
// info.Append(new ObjInfoUnit(_T("井编号"), m_sSysBlock));
// info.Append(new ObjInfoUnit(_T("地面标高"), XString(_T("%.3f"), m_dDang)));
// info.Append(new ObjInfoUnit(_T("井底标高"), XString("%.3f", m_dPipeLength)));
// int num = GetInterfaceNum();
// for(int i=0;i<num;i++){
// CPipeInterface iFace;
// GetInterface(i, iFace);
// CString csPipeName, csLabel;
// csLabel = GetISysLabel(i);
// if(csLabel == "")
// continue;
// OPENOBJ_BEGIN(iFace.m_idPipe,AcDb::kForRead,CDbPipePrototype,pPipe);
// if(pPipe) {
// csPipeName = pPipe->GetSysLabel();
// }
// OPENOBJ_END();
// csPipeName.Format("%s底标高", csPipeName);
// info.Append(new ObjInfoUnit((const char*)csPipeName, csLabel));
// }
// }
// else
info.Append(new ObjInfoUnit(_T("当量值"), GlobalFunc::Dist2Str(m_dDang)));
}
Acad::ErrorStatus
CDbEquipment::GetGripText(int idx, CString &cs) const
{
Acad::ErrorStatus es = Acad::eOk;
switch (idx) {
case 0: cs = _T("移动设备"); break;
case 1: cs = _T("移动基点"); break;
case 2: cs = _T("改变消火栓开启方向"); break; // cet 2016.8.3 add
default: es = Acad::eInvalidInput;
}
return es;
}
Acad::ErrorStatus
CDbEquipment::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
Acad::ErrorStatus es = Acad::eOk;
gripPoints.append((AcGePoint3d)m_ptInsert);
gripPoints.append((AcGePoint3d)m_ptLocation);
// cet 2016.8.3 add 增加消火栓右侧夹点,用于实现调整消火栓开启方向
if (m_idBlock2d.isValid() && IsHydrant())
{
double dWidth = GetInsertScale().sx;
double dHeight = GetInsertScale().sy;
double dAngle = ads_angle(XPoint(), m_vtDirection);
AcGeVector3d vtX = AcGeVector3d::kXAxis * dWidth * 0.5 + AcGeVector3d::kYAxis * dHeight * 0.55;
AcGePoint3d pt = m_ptLocation + vtX.rotateBy(dAngle, AcGeVector3d::kZAxis);
gripPoints.append(pt);
}
return es;
}
Acad::ErrorStatus
CDbEquipment::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const
{
assertReadEnabled();
stretchPoints.append((AcGePoint3d)m_ptInsert);
stretchPoints.append((AcGePoint3d)m_ptLocation);
return Acad::eOk;
}
Acad::ErrorStatus
CDbEquipment::subMoveGripPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
Acad::ErrorStatus es = Acad::eOk;
// cet 2016.8.3 add 消火栓夹点,实现调整方向
if (indices.length() == 1 && indices[0] == 2)
{
// 移动前所在象限
double dWidth = GetInsertScale().sx;
double dHeight = GetInsertScale().sy;
double dAngleBeforeMove = AcGeVector3d::kXAxis.angleTo(AcGeVector3d::kXAxis * dWidth * 0.5 + AcGeVector3d::kYAxis * dHeight * 0.55, AcGeVector3d::kZAxis);
int nDirBeforMove = -1;
if (fabs(dAngleBeforeMove - PI * 2) < 0.001)
{
dAngleBeforeMove = 0.0;
}
if (dAngleBeforeMove > 0.0 + 0.001 && dAngleBeforeMove + 0.001 < PI * 0.5) // (0, 90)
{
nDirBeforMove = 0;
}
else if (dAngleBeforeMove > PI * 0.5 + 0.001 && dAngleBeforeMove + 0.001 < PI) // (90, 180)
{
nDirBeforMove = 1;
}
else if (dAngleBeforeMove > PI + 0.001 && dAngleBeforeMove + 0.001 < PI * 1.5) // (180, 270)
{
nDirBeforMove = 2;
}
else if (dAngleBeforeMove > PI * 1.5 + 0.001 && dAngleBeforeMove + 0.001 < PI * 2) // (270, 360)
{
nDirBeforMove = 3;
}
// 移动后点所在象限
AcGeVector3d vtX = AcGeVector3d::kXAxis * dWidth * 0.5 + AcGeVector3d::kYAxis * dHeight * 0.55;
double dAngle = ads_angle(XPoint(), m_vtDirection);
vtX.rotateBy(dAngle, AcGeVector3d::kZAxis);
AcGeVector3d ptMove = m_ptLocation + vtX + offset;
AcGeVector3d vtTemp = ptMove - m_ptLocation.AsAcGePoint3d();
vtTemp.z = 0.0;
vtX = AcGeVector3d::kXAxis;
vtX.rotateBy(dAngle, AcGeVector3d::kZAxis);
double dAngleAfterMove = vtX.angleTo(vtTemp, AcGeVector3d::kZAxis);
if (fabs(dAngleAfterMove - PI * 2) < 0.001)
{
dAngleAfterMove = 0.0;
}
int nDirAfterMove = -1;
if (dAngleAfterMove > 0.0 + 0.001 && dAngleAfterMove + 0.001 < PI * 0.5) // (0, 90)
{
nDirAfterMove = 0;
}
else if (dAngleAfterMove > PI * 0.5 + 0.001 && dAngleAfterMove + 0.001 < PI) // (90, 180)
{
nDirAfterMove = 1;
}
else if (dAngleAfterMove > PI + 0.001 && dAngleAfterMove + 0.001 < PI * 1.5) // (180, 270)
{
nDirAfterMove = 2;
}
else if (dAngleAfterMove > PI * 1.5 + 0.001 && dAngleAfterMove + 0.001 < PI * 2) // (270, 360)
{
nDirAfterMove = 3;
}
// 根据象限变化调整方向
if (nDirAfterMove == nDirBeforMove || nDirBeforMove == -1 || nDirAfterMove == -1)
{
return es;
}
if (nDirBeforMove == 0 && nDirAfterMove == 3 ||
nDirBeforMove == 1 && nDirAfterMove == 2 ||
nDirBeforMove == 2 && nDirAfterMove == 1 ||
nDirBeforMove == 3 && nDirAfterMove == 0) // x轴镜像
{
MirrorByX(IsMirrorByX() ? FALSE : TRUE);
}
else if (nDirBeforMove == 0 && nDirAfterMove == 1 ||
nDirBeforMove == 1 && nDirAfterMove == 0 ||
nDirBeforMove == 2 && nDirAfterMove == 3 ||
nDirBeforMove == 3 && nDirAfterMove == 2) // y轴镜像
{
MirrorByY(IsMirrorByY() ? FALSE : TRUE);
}
else
{
MirrorByY(IsMirrorByY() ? FALSE : TRUE);
MirrorByX(IsMirrorByX() ? FALSE : TRUE);
}
return es;
}
es = MoveGSPointsAt(indices, offset);
return es;
}
Acad::ErrorStatus
CDbEquipment::subMoveStretchPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
Acad::ErrorStatus es = Acad::eOk;
es = MoveGSPointsAt(indices, offset);
return es;
}
Acad::ErrorStatus
CDbEquipment::MoveGSPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
Acad::ErrorStatus es = Acad::eOk;
XPoint vtOffset;
(AcGeVector3d &)vtOffset = offset;
vtOffset.z = 0;
m_ptInsert += vtOffset;
m_ptLocation += vtOffset;
return es;
// SR 2010-6-17 修改 拉伸不考虑z坐标
///////////////////////////////////////////////////////////////////////////////
// Acad::ErrorStatus es=Acad::eOk;
// AcGeMatrix3d mat;
// mat.setToTranslation(offset);
//
// if(m_ptLocation==m_ptInsert) {
// m_ptInsert.TransformBy(mat);
// m_ptLocation.TransformBy(mat);
// }
// else {
// for (int i=0; i<indices.length();i++) {
// int idx = indices[i];
// switch(idx) {
// case 0:
// m_ptInsert.TransformBy(mat);
// m_ptLocation.TransformBy(mat);//sr add 2004/7/27
// break;
// case 1:
// m_ptInsert.TransformBy(mat);
// m_ptLocation.TransformBy(mat);
// break;
// default:
// es=Acad::eInvalidInput;
// }
// }
// }
// return es;
}
Acad::ErrorStatus
CDbEquipment::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
CDbPipeNode::subTransformBy(xform);
m_ptInsert.TransformBy(xform);
m_ptLocation.TransformBy(xform);
/* cet 2012.7.5 modify 原方法镜像错误
if(IsMirrorMatrix(xform))
{//设备镜像 sr modify 2007/3/9
// TCHAR *layer;
// layer = this->layer();
// if(_tcsicmp(layer, LAY_EQUIP_HYDRANT) == 0) // 2009-7-30 SR 取消消火栓限制,其他附件也可以左右翻转了(忘记当初为什么要做这样的限制了)
MirrorByY(!IsMirrorByY()); //消火栓镜像稍微麻烦点
// delete []layer;
((AcGeVector3d &)m_vtDirection).transformBy(xform);
double dAng = ads_angle(XPoint(),m_vtDirection);
dAng = dAng - PI;
SetAngle(fabs(dAng));
return Acad::eOk;
}
((AcGeVector3d &)m_vtDirection).transformBy(xform);
*/
((AcGeVector3d &)m_vtDirection).transformBy(xform);
if (GlobalFunc::IsMirrorMatrix(xform))
{
MirrorByX(!IsMirrorByX());
}
double dScale = xform.scale();
if (fabs(dScale - 1) > 1.0E-5 && fabs(dScale) > 1.0E-5) { // cet 2010.8.27 modify 将1.0E-3 改为 1.0E-5
m_dScale *= dScale;
m_dYScale *= dScale; // 2009-8-3 增加Y,Z 不然用SC变比例,没有变Y,Z方向的比例
m_dZScale *= dScale;
}
return Acad::eOk;
}
void CDbEquipment::MirrorByX(BOOL bFlag)
{
assertWriteEnabled();
if (bFlag)
m_nMirror |= MIRROR_XAXIS;
else
m_nMirror &= ~MIRROR_XAXIS;
}
void CDbEquipment::MirrorByY(BOOL bFlag)
{
assertWriteEnabled();
if (bFlag)
m_nMirror |= MIRROR_YAXIS;
else
m_nMirror &= ~MIRROR_YAXIS;
}
Acad::ErrorStatus CDbEquipment::GetExtents(XPoint &ptLow, XPoint &ptUp) const
{
Acad::ErrorStatus es = Acad::eOk;
es = CDbPipeNode::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;
}
// 判断节点是否可以连接管段. nPos: 0--start; 1--end
BOOL CDbEquipment::CanLinkSide(const AcDbObjectId &idPipe, int nPos) const
{
BOOL bRet = FALSE;
// cet 2016.6.7 modify 自定义实体中不再直接使用图层宏
// // zxl 2014.01.09 add 雨水口特殊处理
// CString sLayer = layer();
// if (sLayer.Compare(LAY_TWT_GULLY) == 0)
if (GetEquipmentType() == 4)
{
double dMeter = 1.0;
if (GlobalFunc::DocGetMeterUnitDraw())
dMeter = 1000.0;
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) < PS_SNAP / dMeter)
bRet = TRUE;
double nDist = ptRef.Distance(ptLoc);
if (fabs(nDist - nRadius / 2) < PS_SNAP / dMeter)
bRet = TRUE;
}
OPENOBJ_END();
return bRet;
}
OPENOBJ_BEGIN(idPipe, AcDb::kForRead, CDbPipePrototype, pPipe);
if (pPipe) {
const XPoint &ptRef = nPos ? pPipe->EndPoint() : pPipe->StartPoint();
XPoint ptLoc = GetLocation();
if (ptRef.Distance(ptLoc) < PS_SNAP)
bRet = TRUE;
}
OPENOBJ_END();
return bRet;
}
//XRectAngle.Intersection 函数有缺陷,无法求交坐标过大的情况
int IntersectionRect2Line(XRectAngle &rect, XLine &line, XPoint &ptInter)
{
AcGeLineSeg2d ln1(line.StartPoint().AsAcGePoint2d(), line.EndPoint().AsAcGePoint2d());
XPoint lowRight(rect.upRight.x, rect.lowLeft.y, rect.upRight.z),
upLeft(rect.lowLeft.x, rect.upRight.y, rect.upRight.z);
XLine line1(rect.lowLeft, lowRight, LS_FINITE),
line2(lowRight, rect.upRight, LS_FINITE),
line3(rect.upRight, upLeft, LS_FINITE),
line4(upLeft, rect.lowLeft, LS_FINITE);
int intersNum = 0;
XPoint intPt;
XLine *ptr[4] = { &line1, &line2, &line3, &line4 };
for (int i = 0; i < 4; i++) {
XPoint p1 = ptr[i]->StartPoint();
XPoint p2 = ptr[i]->EndPoint();
AcGeLineSeg2d ln2(p1.AsAcGePoint2d(), p2.AsAcGePoint2d());
if (ln1.intersectWith(ln2, ptInter))
return 1;
}
return intersNum;
}
double CDbEquipment::GetWidth(const CDbPipePrototype* pPipe) const
{
//待考虑三维图块...
double dWidth = 0;
// cet 2014.5.6 del 管线被设备遮挡的长度,通过炸开二维图块与管线求交获得
// CString csNumber = GetNumber();
//
// if(csNumber.Find(_T("CIRCLE")) >= 0 && IsHidePipe()){//如果是圆设备,返回圆半径×比例
// csNumber = csNumber.Right(csNumber.GetLength() - 7);
// dWidth = _tstof(csNumber)*GetScale();
// return dWidth*GetPScale()/100;
// }
if (m_idBlock2d.isValid()) {// 二维图块
AcDbExtents extents;
AcDbBlockReference insert(AcGePoint3d(0, 0, 0), m_idBlock2d);
double dScaleX(0), dScaleY(0);
if (m_bAutoScale)
{
dScaleX = m_dScale * GetPScale() / 100;
dScaleY = m_dYScale * GetPScale() / 100;
}
else
{
dScaleX = m_dScale;
dScaleY = m_dYScale;
}
if (fabs(dScaleY) < 0.001)
dScaleY = dScaleX;
if (IsMirrorByY())
dScaleX = -dScaleX;
if (IsMirrorByX())
dScaleY = -dScaleY;
insert.setScaleFactors(AcGeScale3d(dScaleX, dScaleY, fabs(dScaleX)));
// cet 2014.5.6 modify 使用外包框算法,结果有时不准备, 改为炸开实体求交 (未考虑图块嵌套情况)
// if(insert.geomExtentsBestFit(extents)==Acad::eOk) {
// XPoint ptMax = extents.maxPoint();
// XPoint ptMin = extents.minPoint();
//
// dWidth = (ptMax.x-ptMin.x)/2;// 第一次求得的宽度值
//
// if(pPipe!=NULL && pPipe->Is(CURVE_LINE)) { // 仅考虑直线管段
// XPoint ptPosition = insert.position();
// XPoint ptPlus = m_ptInsert-ptPosition;
//
// XPoint ptLocation=m_ptLocation;
// XRectAngle rect(ptMin+ptPlus,ptMax+ptPlus);
// XLine line=(XLine)*pPipe;
//
// double dAngle=CT_std_angle(ads_angle(XPoint(),m_vtDirection));
// if(fabs(dAngle)>1.0E-6) {
// ads_matrix mat;
// m_ptInsert.GetRotationMatrix(-dAngle,mat);
// line.TransformBy(mat);
// ptLocation.TransformBy(mat);
// }
// rect.SetElevation(0);
// line.SetElevation(0);
// ptLocation.z=0;
//
// int nFlag = ptLocation&rect;
// if(nFlag != PR_INSIDE) {
// dWidth = 0;
// } else {
// XPoint ptIntersect;
// if(IntersectionRect2Line(rect,line,ptIntersect)){
// dWidth=ptLocation.Distance(ptIntersect);
// }
// // if(rect.Intersection(line,ptIntersect)){//sr remove it 2007-5-9 XRectAngle.Intersection 函数有缺陷,无法求交坐标过大的情况
// // dWidth=ptLocation.Distance(ptIntersect);
// // }
// }
// }
// }
insert.setPosition(m_ptInsert);
double dAngle = ads_angle(XPoint(), m_vtDirection);
insert.setRotation(dAngle);
GeCurveSegment curve = pPipe->GetCurve();
curve.SetElevation(0.0);
AcDbCurve *pPipeCurve = curve.AsAcDbCurve();
// cet 2017.3.8 add 距离原点过远时,移动到原点附近计算,防止计算出错
AcGeMatrix3d mat = AcGeMatrix3d::kIdentity;
if (m_ptInsert.Distance(XPoint()) > g_dPointToOriginLimitDist)
{
XPoint ptTemp = m_ptInsert;
ptTemp.z = 0.0;
mat.setToTranslation(-ptTemp.AsAcGeVector3d());
insert.transformBy(mat);
pPipeCurve->transformBy(mat);
}
AcDbVoidPtrArray arrEnt;
AcGePoint3dArray arrIntPt, arrPoint;
AcGePoint3d pt1, pt2;
if (insert.explode(arrEnt) == Acad::eOk)
{
for (int j = 0; j < arrEnt.length(); ++j)
{
AcDbEntity *pEnt = (AcDbEntity*)(arrEnt[j]);
if (pEnt == NULL)
{
continue;
}
AcDbCurve *pCurve = AcDbCurve::cast(pEnt);
if (pCurve == NULL)
{
continue;
}
Acad::ErrorStatus st = pPipeCurve->intersectWith(pCurve, AcDb::kOnBothOperands, AcGePlane::kXYPlane, arrIntPt);
for (int i = 0; i < arrIntPt.length(); ++i)
{
arrPoint.append(arrIntPt[i]);
}
arrIntPt.setLogicalLength(0);
}
GlobalFunc::ReleaseEntSet(arrEnt);
}
delete pPipeCurve;
pPipeCurve = NULL;
// 设备插入点在管线一端,找到与设备重合的管线端点,求出距该点最用的交点距离
XPoint ptS = pPipe->GetStartPoint();
XPoint ptE = pPipe->GetEndPoint();
AcGePoint3d pt = ptS;
if (ptS.Distance2d(m_ptInsert) > ptE.Distance2d(m_ptInsert))
{
pt = ptE;
}
pt.transformBy(mat); // cet 2017.3.8 add 考虑距离原点过远情况,移动到原点附近计算
pt.z = 0.0;
for (int k = 0; k < arrPoint.length(); ++k)
{
double dDist = pt.distanceTo(arrPoint[k]);
if (k == 0 || dWidth < dDist)
{
dWidth = dDist;
}
}
}
return dWidth;
}
// 对st类型的接口进行重新连接
void CDbEquipment::UpdateLinkage(const XPoint &ptAt,
TPipeSys::SysType st,
const DList<AcDbObjectId> &idPipes)
{
assertWriteEnabled();
m_ptLocation = ptAt;
// cet 2016.6.7 modify 自定义实体中不再直接使用图层宏
// // zxl 2014.01.09 add 雨水口特殊处理
// CString sLayer = layer();
// if (sLayer.Compare(LAY_TWT_GULLY) == 0)
if (GetEquipmentType() == 4)
{
DList<CPipeInterface> lstInterface;//先保留一份出来,目的是得到各管底标高
for (int j = 0; j < m_lstInterface.Length(); j++) {
CPipeInterface& iFace = *m_lstInterface[j];
lstInterface.Append(new CPipeInterface(iFace));
}
double dMeter = 1.0;
if (GlobalFunc::DocGetMeterUnitDraw())
dMeter = 1000.0;
RemoveInterface(st);
double nRadius = GetScale() * GetPScale();
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();
}
return;
}
CDbPipeNode::UpdateLinkage(ptAt, st, idPipes);
/*RemoveInterface(st);
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;
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();
}*/
}
// 2008-2-27 SB add 支持系统图块与不相关但位置贴近的管线,进行裁剪
Acad::ErrorStatus CDbEquipment::GetClipBoundary(XPoly2D& poly)const
{
if (m_idBlock2d.isValid() && IsHidePipe()) {// 二维图块
AcDbExtents extents;
// AcDbBlockReference insert(m_ptLocation, m_idBlock2d);
// double dScaleX(0), dScaleY(0);
// dScaleX = m_dScale*GetPScale()/100;
// dScaleY = m_dYScale*GetPScale()/100;
// if(fabs(dScaleY) < 0.001)
// dScaleY = dScaleX;
//
// if(IsMirrorByY())
// dScaleX = -dScaleX;
// if(IsMirrorByX())
// dScaleY = -dScaleY;
// insert.setScaleFactors(AcGeScale3d(dScaleX, dScaleY, fabs(dScaleX)));
// if(insert.geomExtentsBestFit(extents)==Acad::eOk) {
if (getGeomExtents(extents) == Acad::eOk) {
XPoint ptMax = extents.maxPoint();
XPoint ptMin = extents.minPoint();
ptMax.z = 0;
ptMin.z = 0;
XRectAngle rect(ptMin, ptMax);
rect.AsPoly2D(poly);
poly.SetFlag(1);
//poly.Make();
return Acad::eOk;
}
}
return Acad::eInvalidInput;
}
BOOL CDbEquipment::IsSprinkler() const
{
// cet 2014.12.2 add 根据设备类型判断是否为喷头
if (GetEquipmentType() == 1)
{
return TRUE;
}
XString xsTmp1 = _T("$twtsys$00000125");
XString xsTmp2 = _T("$twtsys$00000128");
XString xsTmp3 = _T("$twtsys$00000129");
XString xsTmp4 = _T("$twtsys$00000131");
// XString xsTmp5 = _T("$twtsys$00000283"); //系统喷头
// XString xsTmp6 = _T("$twtsys$00000126"); //系统喷头
// XString xsTmp7 = _T("$twtsys$00000130"); //系统喷头
AcDbObjectId idBlk = GetBlock2d();
const TCHAR *szBlkName = NULL;
OPENOBJ_BEGIN(idBlk, AcDb::kForRead, AcDbBlockTableRecord, pRecord);
if (pRecord) {
pRecord->getName(szBlkName);
}
OPENOBJ_END();
// cet 2012.6.26 modify 将块名改为小写
CString sBlkName = szBlkName;
sBlkName.MakeLower();
if (_tcsicmp(sBlkName, xsTmp2) == 0 || _tcsicmp(sBlkName, xsTmp1) == 0 ||
_tcsicmp(sBlkName, xsTmp4) == 0 || _tcsicmp(sBlkName, xsTmp3) == 0) //是喷头
return TRUE;
else
return FALSE;
}
BOOL CDbEquipment::IsHydrant() const
{
// cet 2014.12.2 add 根据设备类型判断是否为消火栓
if (GetEquipmentType() == 0)
{
return TRUE;
}
XString xsTmp1 = _T("$twtsys$00000434");
XString xsTmp2 = _T("$twtsys$00000435");
XString xsTmp3 = _T("$twtsys$00000485");
XString xsTmp4 = _T("$twtsys$00000487");
XString xsTmp5 = _T("$twtsys$00000508");
XString xsTmp6 = _T("$twtsys$00000509");
const TCHAR *szBlkName = NULL;
AcDbObjectId idBlk = GetBlock2d();
OPENOBJ_BEGIN(idBlk, AcDb::kForRead, AcDbBlockTableRecord, pRecord);
if (pRecord) {
pRecord->getName(szBlkName);
}
OPENOBJ_END();
// cet 2012.6.26 modify 将块名改为小写
CString sBlkName = szBlkName;
sBlkName.MakeLower();
if (_tcsicmp(sBlkName, xsTmp2) == 0 || _tcsicmp(sBlkName, xsTmp1) == 0 ||
_tcsicmp(sBlkName, xsTmp3) == 0 || _tcsicmp(sBlkName, xsTmp4) == 0 ||
_tcsicmp(sBlkName, xsTmp5) == 0 || _tcsicmp(sBlkName, xsTmp6) == 0)
return TRUE;
else
return FALSE;
}
BOOL CDbEquipment::IsUpLinkHydrant() const
{
XString xsTmp1 = _T("$twtsys$00000441");
const TCHAR *szBlkName = NULL;
AcDbObjectId idBlk = GetBlock3d();
OPENOBJ_BEGIN(idBlk, AcDb::kForRead, AcDbBlockTableRecord, pRecord);
if (pRecord) {
pRecord->getName(szBlkName);
}
OPENOBJ_END();
// cet 2012.6.26 modify 将块名改为小写
CString sBlkName = szBlkName;
sBlkName.MakeLower();
if (_tcsicmp(sBlkName, xsTmp1) == 0)
return TRUE;
else
return FALSE;
}
void InitDbEquipment(BOOL bTrue)
{
if (bTrue) {
CDbEquipment::rxInit();
//CDbEquipment::InitMatchProtocol(TRUE);
}
else {
//CDbEquipment::InitMatchProtocol(FALSE);
deleteAcRxClass(CDbEquipment::desc());
}
}
void CDbEquipment::SetEquipmentType(int nType)
{
assertWriteEnabled();
EntityFields &fd = Fields();
fd.SFD(_T("EquipmentType"), static_cast<Adesk::Int8>(nType));
}
void CDbEquipment::SetEquipmentType(EquipType nType)
{
SetEquipmentType(static_cast<int>(nType));
}
int CDbEquipment::GetEquipmentType() const
{
const EntityFields &fd = GetFields();
Adesk::Int8 nType = -1;
fd.GFD(_T("EquipmentType"), nType);
return static_cast<int>(nType);
}