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

471 lines
13 KiB
C++

#include "stdafx.h"
#include "Elevator.h"
// Add by Zyu on 100323
#define SYS_LD12D _T("DORLIB2D(00000128)") // 旁开电梯门
#define SYS_LD22D _T("DORLIB2D(00000127)") // 中分电梯门
// Add by Zyu on 100323
// 保证门对象绘制在正确的位置上
// Begin
extern TARCH_IMPEXP void CheckOp3dStyle(AcDbObjectId idStyle3d);
extern TARCH_IMPEXP void CheckOp2dStyle(AcDbObjectId idStyle2d);
// End
// 插洞口
int InsertHole(int nType, ads_real nWidth, TDbWall *pWall, const XPoint &ptNew, const XPoint &ptIn)
{
// 问题描述:插入的电梯门其实是一个窗
// 解决方法:改为以门的方式插入
// Zyu modify on 100323
// TOpeningData::OpeningKind nK = TOpeningData::OP_WINDOW;
TOpeningData::OpeningKind nK = TOpeningData::OP_DOOR;
XPoint ptLoc1;
if (!pWall->GetOpeningLocation(ptNew, nK, nWidth, ptLoc1) || //投影到墙心上
!pWall->CanInsertOpening(ptLoc1, 0.0, nWidth, 2100, nK))
{
ads_printf(_T("\n插入后, 该墙上的洞口将发生干涉! 拒绝插入!"));
return RTERROR;
}
// 问题描述:使用了DORLIB2D图库中的电梯门
// 修改人,修改时间:Zyu modify on 100323
// const TCHAR *pszDoor2d=nType? SYS_LDOR12D : SYS_LDOR22D; //, *pszDoor3d=_T("DOOR(_door001)");
const TCHAR *pszDoor2d=nType? SYS_LD12D : SYS_LD22D;
XString sDoorDwg;
sDoorDwg << g_sDwbPath << pszDoor2d;
XString szDoor2d(256), szDoor3d(256);
AcDbObjectId idStyle2d, idStyle3d;
if (LoadDwbBlock(sDoorDwg, szDoor2d)!=RTNORM)
return RTERROR;
idStyle2d = InitBlock(szDoor2d);
if (LoadDwbBlock(XString(_T("%s%s"), g_sDwbPath, SYS_LDOOR3D), szDoor3d)!=RTNORM)
return RTERROR;
idStyle3d = InitBlock(szDoor3d);
// Add by Zyu on 100323
// 保证门对象绘制在正确的位置上
// Begin
CheckOp3dStyle(idStyle3d);
CheckOp2dStyle(idStyle2d);
// End
TDbOpening *pOpening = new TDbOpening(pWall->objectId(), idStyle2d, idStyle3d);
pOpening->InitHardPointerId();
pOpening->m_ptLocation = ptLoc1;
pOpening->SetWidth(nWidth);
pOpening->SetHeight(2100);
pOpening->SetThickness(60);
// Zyu modify on 100323
//pOpening->SetKind(TOpeningData::OP_WINDOW);
pOpening->SetKind(TOpeningData::OP_DOOR);
pOpening->m_nOpStyle |= OPS_LIFTDOOR;
// add by xly on 110314 设置电梯门的类型
pOpening->SetSubKind(_T("电梯门"));
pOpening->AddToMSpace(Adesk::kFalse);
pWall->InsertOpening(pOpening);
XCurveSegment segCen = pWall->OffsetGeomCenter();
int nSide = segCen.OnWhichSide(ptIn);
if (nSide == OFFSET_LEFT)
{
if (pOpening->m_nQuadrant == 2)
pOpening->m_nQuadrant = 1;
else if (pOpening->m_nQuadrant == 3)
pOpening->m_nQuadrant = 0;
}
else if (nSide==OFFSET_RIGHT)
{
if (pOpening->m_nQuadrant == 1)
pOpening->m_nQuadrant = 2;
else if (pOpening->m_nQuadrant == 0)
pOpening->m_nQuadrant = 3;
}
pOpening->close();
return RTNORM;
}
int GetClosestEdge(const XPoly2D &poly, XPoint ptPick)
{
int nDoorEdge = -1;
double nMinDist = 0.0;
for (int n=0; n<4; n++)
{
XLine ln;
poly.Nth(n, ln, XArc());
XPoint ptOnEdge;
if (ptPick.Project(&ln, ptOnEdge)!=RTNORM || (ptOnEdge&ln)!=PR_INSIDE)
continue;
if (nDoorEdge<0)
{
nMinDist = ptPick.Distance2d(ptOnEdge);
nDoorEdge = n;
}
else
{
double nDist = ptPick.Distance2d(ptOnEdge);
if (nDist<nMinDist)
{
nMinDist = nDist;
nDoorEdge = n;
}
}
}
return nDoorEdge;
}
// Add by Zyu on 100402
// 获得电梯间的边框
bool GetElevtorRect(TADSGePoint3d &ptCorn1, TADSGePoint3d &ptCorn2)
{
int nOsMode = 0;
xg_getvar(_T("OSMODE"), &nOsMode);
nOsMode &= ~0x4000;
nOsMode |= OS_END;
XPushVar<int> osmode(_T("OSMODE"), nOsMode);
if (XGetPoint(NULL, _T("\n请给出电梯间的一个角点"), ptCorn1) != RTNORM ||
XGetCorner(ptCorn1, _T("\n再给出上一角点的对角点: "), ptCorn2)!=RTNORM)
{
return false;
}
ptCorn1 = Ucs2Wcs(ptCorn1);
ptCorn2 = Ucs2Wcs(ptCorn2);
ptCorn1.z = ptCorn2.z = 0;
return true;
}
// 获取门所在的墙体上一点ptPick,并返回这面墙的角度dRot和这个墙对象
bool GetPntOnWall(TADSGePoint3d &ptPick, double &dRot, Entity &entSel)
{
RBList rbWallFilter(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL); // 过滤器
if (entSel.FilterSelect(_T("\n请点取开电梯门的墙线<退出>: "), rbWallFilter, ptPick) != RTNORM)
{
return false;
}
ptPick = Ucs2Wcs(ptPick);
// Modify on 2002/2/25 by ZJQ 支持转角的墙
OPENOBJ_BEGIN(entSel, AcDb::kForRead, TDbWall, pWall);
if (!pWall || !pWall->Is(CURVE_LINE))
{
adsout << _T("\n请正确点取开电梯门的墙!");
return false;
}
dRot = pWall->XLine::Direction();
OPENOBJ_END();
return true;
}
// 得到所有组成平衡块和轿厢的点
void GetCrossPnts(const TGGeLine *lnBalSides, const TGGeLine *lnOtherSides,
TADSGePoint3d *ptBalances, TADSGePoint3d *ptTanks)
{
lnBalSides[0].Intersection(&lnOtherSides[0], ptBalances[0]);
lnBalSides[1].Intersection(&lnOtherSides[0], ptBalances[1]);
lnBalSides[1].Intersection(&lnOtherSides[1], ptBalances[2]);
lnBalSides[0].Intersection(&lnOtherSides[1], ptBalances[3]);
lnBalSides[2].Intersection(&lnOtherSides[2], ptTanks[0]);
lnBalSides[3].Intersection(&lnOtherSides[2], ptTanks[1]);
lnBalSides[3].Intersection(&lnOtherSides[3], ptTanks[2]);
lnBalSides[2].Intersection(&lnOtherSides[3], ptTanks[3]);
}
// 画平衡块和轿厢
void DrawBalAndTank(const TADSGePoint3d *ptBalances, const TADSGePoint3d *ptTanks)
{
XWcsStream dc;
// Zyu modify on 100401
// dc.sLayer = LAY_STAIR;
dc.sLayer = LAY_ELEVATOR;
dc << XLine(ptBalances[0], ptBalances[1])
<< XLine(ptBalances[1], ptBalances[2])
<< XLine(ptBalances[2], ptBalances[3])
<< XLine(ptBalances[3], ptBalances[0])
<< XLine(ptTanks[0], ptTanks[1])
<< XLine(ptTanks[1], ptTanks[2])
<< XLine(ptTanks[2], ptTanks[3])
<< XLine(ptTanks[3], ptTanks[0])
<< XLine(ptTanks[0], ptTanks[2])
<< XLine(ptTanks[1], ptTanks[3]);
}
// 获得门在轿厢上的插入点
void GetPntDoorOnTank(const TGGeLine &lnDoorEdge, const TADSGePoint3d *ptTanks,
TADSGePoint3d &ptDoorOnTank)
{
if (IsSameDrt(ads_angle(ptTanks[0], ptTanks[1]), lnDoorEdge.Direction(), _angSnap))
{
Midpoint(ptTanks[0], ptTanks[1], ptDoorOnTank);
}
else
{
Midpoint(ptTanks[1], ptTanks[2], ptDoorOnTank);
}
}
// End
//画电梯
void Elevator()
{
// 修改描述:原来的轿厢和平衡块是画在楼梯层的,现在改为画在电梯层
// 修改人,修改时间:Zyu modify on 100401
// InitLayer(LAY_STAIR, TRUE);
InitLayer(LAY_ELEVATOR, TRUE);
CAcModuleResourceOverride vTemp;
CElevatorDlg dlg;
dlg.Create(dlg.IDD, acedGetAcadFrame());
acedGetAcadDwgView()->SetFocus();
while(1)
{
XPoint ptCorn1, ptCorn2, ptIn;
if (!GetElevtorRect(ptCorn1, ptCorn2))
{ // 获得电梯间的边框
break ;
}
XPoint ptPick; // 门所在的墙体上一点
double dRot; // 墙的旋转角度
Entity entSel; // 选择到的实体
if (!GetPntOnWall(ptPick, dRot, entSel))
{ // 获取门所在的墙体上一点ptPickt和这面墙的角度dRot
break ;
}
// 根据墙线的角度,旋转电梯间的对角点ptCorn1,ptCorn2
ads_matrix matRot, matRev;
XPoint().GetRotationMatrix(-dRot, matRot);
ptCorn1.TransformBy(matRot);
ptCorn2.TransformBy(matRot);
AT_amatrix(matRot, matRev);
XPoly2D poly(1); // 电梯间的边框线
XRectAngle box(ptCorn1, ptCorn2);
box.AsPoly2D(poly);
// poly.TransUCS(Groups(1), Groups(0));
poly.TransUCS(matRev);
poly.Center(ptIn);
// 电梯门在矩形的哪一边
int nDoorEdge = GetClosestEdge(poly, ptPick);
if (nDoorEdge<0)
{
adsout << _T("\n请正确点取开电梯门的墙线!");
continue;
}
int nBalanceEdge = -1;
{
XPushVar<int> osmode(_T("OSMODE"), OS_NEA);
if (ads_getpoint(NULL, _T("\n请点取平衡块的所在的一侧<退出>: "), ptPick) != RTNORM)
break;
ptPick = Ucs2Wcs(ptPick);
nBalanceEdge = GetClosestEdge(poly, ptPick);
if (nBalanceEdge<0 || nBalanceEdge==nDoorEdge)
{
adsout << _T("\n请正确点取平衡块位置!");
continue;
}
}
dlg.UpdateData(TRUE);
// 修改描述:根据是否使用"按井道决定轿厢尺寸"一项设置调整相应参数的值
// 修改人,修改时间: Zyu modify on 100401
// Begin
double nDoorWidth = dlg.m_dDoorWidth;
// double nTankDeep = dlg.m_Room_Deep;
// double nTankWidth = dlg.m_dRoomWidth;
double nTankDeep = 0;
double nTankWidth = 0;
int nDeepEdge = 0;
XLine lnWidth, lnDeep;
if (dlg.IsUseDefault())
{
nDeepEdge = DePeriod(4, nBalanceEdge+1);
poly.Nth(nBalanceEdge, lnWidth, XArc());
poly.Nth(nDeepEdge, lnDeep, XArc());
if (lnWidth.GetLength() < 500 + _DIST_SNAP || lnDeep.GetLength() < 450 + _DIST_SNAP)
{
adsout << _T("\n井道尺寸过小无法容纳轿厢和平衡块!");
continue ;
}
else
{
nTankDeep = (lnDeep.GetLength() - 450) * 0.8;
nTankWidth = lnWidth.GetLength() - 500;
}
}
else
{
nTankDeep = dlg.m_dRoomDeep;
nTankWidth = dlg.m_dRoomWidth;
nDeepEdge = DePeriod(4, nDoorEdge+1);
poly.Nth(nDoorEdge, lnWidth, XArc());
poly.Nth(nDeepEdge, lnDeep, XArc());
if (nTankDeep>lnDeep.GetLength() || nTankWidth>lnWidth.GetLength())
{
// 修改描述:调整提示信息
// 修改人,修改时间:Zyu modify on 100401
// adsout << _T("\n电梯井无法容纳桥箱!")
adsout << _T("\n井道尺寸过小无法容纳轿厢和平衡块!")
<< _T("\n井宽=") << lnWidth.GetLength() << _T("; 井深=") << lnDeep.GetLength()
<< _T("; 轿箱宽=") << nTankWidth << _T("; 轿箱深=") << nTankDeep;
continue;
}
}
int nDirFlag = (nBalanceEdge-nDeepEdge)%2; // 0--宽度方向: 1--深度方向
XLine lnBal, lnBalSides[4];
poly.Nth(nBalanceEdge, lnBal, XArc());
int nSideFlag = lnBal.OnWhichSide(ptIn);
double nFactor = nSideFlag==OFFSET_RIGHT? 1.0 : -1.0;
if (dlg.IsUseDefault())
{
lnBalSides[0] = lnBal.Offset(225*nFactor);
lnBalSides[1] = lnBal.Offset((225 + (lnDeep.GetLength() - 450) * 0.1) * nFactor);
lnBalSides[2] = lnBal.Offset((225 + (lnDeep.GetLength() - 450) * 0.2) * nFactor);
lnBalSides[3] = lnBalSides[2].Offset((nDirFlag ? nTankDeep : nTankWidth) * nFactor);
}
else
{
double nBalWidth = nDirFlag?
(lnDeep.GetLength()-nTankDeep)/4 : (lnWidth.GetLength()-nTankWidth)/4;
lnBalSides[0] = lnBal.Offset(nBalWidth*nFactor);
lnBalSides[1] = lnBal.Offset(nBalWidth*nFactor*2);
lnBalSides[2] = lnBal.Offset(nBalWidth*nFactor*3);
lnBalSides[3] = lnBalSides[2].Offset((nDirFlag? nTankDeep : nTankWidth)*nFactor);
}
XLine &lnOther = nDirFlag? lnDeep : lnWidth;
nSideFlag = lnOther.OnWhichSide(ptIn);
nFactor = nSideFlag==OFFSET_RIGHT? 1.0 : -1.0;
XLine lnOtherSides[4];
if (dlg.IsUseDefault())
{
lnOtherSides[0] = lnOther.Offset((nDirFlag? (lnWidth.GetLength() - 500) / 5 + 250 : (lnDeep.GetLength() - 500) / 5 + 250) * nFactor);
lnOtherSides[1] = lnOtherSides[0].Offset((nDirFlag? (lnWidth.GetLength() - 500) * 0.6 : (lnDeep.GetLength() - 500) * 0.6) * nFactor);
lnOtherSides[2] = lnOther.Offset(250 * nFactor);
lnOtherSides[3] = lnOtherSides[2].Offset((nDirFlag? nTankWidth : nTankDeep)*nFactor);
}
else
{
lnOtherSides[0] = lnOther.Offset((nDirFlag? lnWidth.GetLength()/4 : lnDeep.GetLength()/4)*nFactor);
lnOtherSides[1] = lnOtherSides[0].Offset((nDirFlag? lnWidth.GetLength()/2 : lnDeep.GetLength()/2)*nFactor);
lnOtherSides[2] = lnOther.Offset((nDirFlag? lnWidth.GetLength()-nTankWidth : lnDeep.GetLength()-nTankDeep)*nFactor/2);
lnOtherSides[3] = lnOtherSides[2].Offset((nDirFlag? nTankWidth : nTankDeep)*nFactor);
}
// End
for (int i=0; i<4; i++)
{
// 2010-3-15 17:20 wubo
// 移植Geo
// lnOtherSides[i].flag=lnBalSides[i].flag=LS_INFINITE;
lnOtherSides[i].SetLineFlag(LS_INFINITE);
lnBalSides[i].SetLineFlag(LS_INFINITE);
}
// 根据lnBalSides和lnOtherSides两组线,取得组成平衡块和电梯的点.
XPoint ptBalances[4], ptTanks[4];
GetCrossPnts(lnBalSides, lnOtherSides, ptBalances, ptTanks);
// 画平衡块和轿厢
DrawBalAndTank(ptBalances, ptTanks);
XPoint ptDoorOnTank;
// 获得门在轿厢上的插入点
if (dlg.IsUseDefault())
{
TGGeLine lnDoorEdge;
poly.Nth(nDoorEdge, lnDoorEdge, XArc());
GetPntDoorOnTank(lnDoorEdge, ptTanks, ptDoorOnTank);
}
else
{
GetPntDoorOnTank(lnWidth, ptTanks, ptDoorOnTank);
}
OPENOBJ_BEGIN(entSel, AcDb::kForWrite, TDbWall, pWall1);
if (!pWall1)
break;
XPoint ptDoor;
pWall1->ProjectToMe(ptDoorOnTank, ptDoor);
// 问题描述:InsertHole的第一个参数使用错误,导致住宅梯、医梯、货梯三种电梯门的中分样式不对
// 修改人,修改时间:Zyu modify on 100323
//if (InsertHole(dlg.m_iType, nDoorWidth, pWall1, ptDoor, ptIn) != RTNORM) {
if (InsertHole(dlg.m_iForm, nDoorWidth, pWall1, ptDoor, ptIn) != RTNORM)
{
adsout << _T("\n不能插入电梯门!");
continue;
}
OPENOBJ_END();
XPoint ptPick1;
Entity entSel1;
RBList rbWallFilter(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL); // 过滤器
if (entSel1.FilterSelect(_T("\n请点取其他开电梯门的墙线<无>: "), rbWallFilter, ptPick1) != RTNORM)
continue;
ptPick1 = Ucs2Wcs(ptPick1);
// 电梯门在矩形的哪一边
int nDoorEdge1 = GetClosestEdge(poly, ptPick1);
if (nDoorEdge1<0 || nDoorEdge1==nDoorEdge || nDoorEdge1==nBalanceEdge)
{
adsout << _T("\n点取的墙线不合适!");
continue;
}
poly.Nth(nDoorEdge1, lnWidth, XArc());
// 获得门在轿厢上的插入点
GetPntDoorOnTank(lnWidth, ptTanks, ptDoorOnTank);
OPENOBJ_BEGIN(entSel1, AcDb::kForWrite, TDbWall, pWall1);
if (!pWall1)
break;
XPoint ptDoor;
pWall1->ProjectToMe(Ucs2Wcs(ptDoorOnTank), ptDoor);
// Zyu modify on 100323
// if (InsertHole(dlg.m_iType, nDoorWidth, pWall1, ptDoor, ptIn) != RTNORM) {
if (InsertHole(dlg.m_iForm, nDoorWidth, pWall1, ptDoor, ptIn) != RTNORM)
{
adsout << _T("\n不能插入电梯门!");
continue;
}
OPENOBJ_END();
}
dlg.DestroyWindow();
}