471 lines
13 KiB
C++
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();
|
|
}
|