857 lines
29 KiB
C++
857 lines
29 KiB
C++
#include "stdafx.h"
|
||
|
||
////////////////////////////////////////////////////////////////////
|
||
// 门窗数据类
|
||
////////////////////////////////////////////////////////////////////
|
||
|
||
TOpeningData::TOpeningData(): m_pBayWin(NULL) {
|
||
m_opKind = OP_DOOR;
|
||
m_nThickness = 120.0;
|
||
m_nWidth=m_nHeight=1500.0;
|
||
m_nRotation=0.0;
|
||
m_nBulge=0.0; // Add on 2003/12/16
|
||
m_nQuadrant = 0;
|
||
m_nOpStyle = 0;
|
||
m_nSlotExt=m_nSlotWidth=0.0; // Add on 2003/12/16
|
||
m_nDoorWidth=m_nWinHeight=0;
|
||
m_nOpStyleEx=0;
|
||
m_nProWinSlabWidth=100;
|
||
m_nCornWinProtrude=0;
|
||
m_dInsWidth = 0.0;
|
||
m_nMaterial = 0;
|
||
m_bSlotInsCap = 1;
|
||
m_dInsBack = 0.0;
|
||
|
||
m_dCornWinTrueProtrude = 0; // sg add 120606,转角窗出挑长度
|
||
}
|
||
// 窗的数据拷贝
|
||
TOpeningData & TOpeningData::operator = (const TOpeningData &src)
|
||
{
|
||
m_ptLocation = src.m_ptLocation;
|
||
m_ptLabel = src.m_ptLabel;
|
||
m_nWidth = src.m_nWidth;
|
||
m_nThickness = src.m_nThickness;
|
||
m_nHeight = src.m_nHeight;
|
||
m_nRotation = src.m_nRotation;
|
||
m_nQuadrant = src.m_nQuadrant;
|
||
m_opKind = src.m_opKind;
|
||
m_nBulge = src.m_nBulge;
|
||
m_sLabel = src.m_sLabel;
|
||
|
||
m_nIdStyle2d = src.m_nIdStyle2d;
|
||
m_nIdStyle3d = src.m_nIdStyle3d;
|
||
m_nIdOfWall = src.m_nIdOfWall;
|
||
|
||
m_nOpStyle = src.m_nOpStyle;
|
||
m_nOpStyleEx =src.m_nOpStyleEx;
|
||
m_nSlotExt = src.m_nSlotExt;
|
||
m_nSlotWidth = src.m_nSlotWidth;
|
||
|
||
if(m_pBayWin) delete m_pBayWin;
|
||
m_pBayWin=NULL;
|
||
if(src.m_pBayWin) {
|
||
m_pBayWin = new XBayWindow(*src.m_pBayWin);
|
||
}
|
||
|
||
m_nDoorWidth=src.m_nDoorWidth;
|
||
m_nWinHeight=src.m_nWinHeight;
|
||
|
||
//add by whl on 081021
|
||
m_nProWinSlabWidth=src.m_nProWinSlabWidth;
|
||
m_nCornWinProtrude=src.m_nCornWinProtrude;
|
||
m_nMaterial = src.m_nMaterial;
|
||
m_dInsWidth = src.m_dInsWidth;
|
||
m_dInsBack = src.m_dInsBack;
|
||
m_bSlotInsCap = src.m_bSlotInsCap;
|
||
|
||
// sg add 120606,转角窗出挑长度
|
||
m_dCornWinTrueProtrude = src.m_dCornWinTrueProtrude;
|
||
|
||
return *this;
|
||
}
|
||
|
||
BOOL TOpeningData::IsLinear() const
|
||
{
|
||
BOOL bFirstCase;
|
||
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
|
||
bFirstCase=(pWall==NULL);
|
||
if(!bFirstCase) {
|
||
if(pWall->Is(CURVE_ARC)) {
|
||
if(GetKind()!=TOpeningData::OP_ARCWIN &&
|
||
GetKind()!=TOpeningData::OP_CORNWIN)
|
||
bFirstCase=TRUE;
|
||
} else
|
||
bFirstCase=TRUE;
|
||
}
|
||
OPENOBJ_END();
|
||
return bFirstCase;
|
||
}
|
||
void TOpeningData::SetHigh(BOOL bTrue)
|
||
{
|
||
m_nOpStyle &= ~OPS_ATHIGH;
|
||
if(bTrue)
|
||
{
|
||
if (m_opKind == OP_WINDOW || m_opKind == OP_ARCWIN)
|
||
{
|
||
m_nOpStyle |= OPS_ATHIGH;
|
||
}
|
||
}
|
||
}
|
||
////////////////////////////////////////////////////////////////////
|
||
// 取得在水平方向上的门窗轮廓
|
||
// nZ--指定的水平标高
|
||
// poly: 一定是4边, 0,2边为侧边, 1,3与墙壁重合, 对于不穿透的洞, 边1在墙体内
|
||
//void TOpeningData::GetOutlinePoly(ads_real nZ, XPoly2D &poly) const
|
||
void TOpeningData::GetOutlinePoly(ads_real nZ, XPoly2D &poly ,BOOL bSubtract) const
|
||
|
||
{
|
||
double nWallThick=GetWallThickness(TRUE); // Modify on 2004/2/23, 考虑保温层厚度
|
||
|
||
// modify by xlc on 110406 解决弧墙上带形窗端头封口问题
|
||
//if(GetKind()!=OP_ARCWIN || !m_nIdOfWall)
|
||
if(IsLinear())
|
||
|
||
{
|
||
XPoint pt[4], ptSide[2];
|
||
XPoint ptLoc=m_ptLocation;
|
||
ptLoc.z = nZ;
|
||
ads_polar(ptLoc, m_nRotation, m_nWidth/2.0, ptSide[0]);
|
||
ads_polar(ptLoc, m_nRotation+PI, m_nWidth/2.0, ptSide[1]);
|
||
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
|
||
if((m_nOpStyle&OPS_NOT_BORE) && pWall) { //不贯穿的洞
|
||
int nSideFlag=(m_nQuadrant<2)? OFFSET_LEFT : OFFSET_RIGHT;
|
||
XCurveSegment curveSide=pWall->GetRelativeSideCurve(nSideFlag, pWall->StartPoint());
|
||
XCurveSegment curveIn=pWall->GetRelativeSideCurve(nSideFlag, pWall->StartPoint(), -m_nThickness);
|
||
curveSide.ProjectToMe(ptSide[1], pt[0]);
|
||
curveIn.ProjectToMe(ptSide[1], pt[1]);
|
||
curveIn.ProjectToMe(ptSide[0], pt[2]);
|
||
curveSide.ProjectToMe(ptSide[0], pt[3]);
|
||
}
|
||
else
|
||
{
|
||
// modify by xlc on 100824 弧墙上的直门窗洞做减法时将窗厚调整1倍,解决与墙线相交误差
|
||
if (bSubtract && pWall && pWall->Is(CURVE_ARC))
|
||
{
|
||
ads_polar(ptSide[0], m_nRotation-PI/2.0, nWallThick, pt[0]);
|
||
ads_polar(ptSide[0], m_nRotation+PI/2.0, nWallThick, pt[1]);
|
||
ads_polar(ptSide[1], m_nRotation+PI/2.0, nWallThick, pt[2]);
|
||
ads_polar(ptSide[1], m_nRotation-PI/2.0, nWallThick, pt[3]);
|
||
}
|
||
else
|
||
|
||
{
|
||
ads_polar(ptSide[0], m_nRotation-PI/2.0, nWallThick/2.0, pt[0]);
|
||
ads_polar(ptSide[0], m_nRotation+PI/2.0, nWallThick/2.0, pt[1]);
|
||
ads_polar(ptSide[1], m_nRotation+PI/2.0, nWallThick/2.0, pt[2]);
|
||
ads_polar(ptSide[1], m_nRotation-PI/2.0, nWallThick/2.0, pt[3]);
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
poly.SetFlag(1);
|
||
for(int i=0; i<4; i++)
|
||
poly.AppendNode(pt[i]);
|
||
} else {
|
||
XDbObject objWall(m_nIdOfWall, AcDb::kForRead);
|
||
if(!!objWall) {
|
||
TDbWall *pDbWall=TDbWall::cast(objWall.m_pObject);
|
||
ASSERT(pDbWall);
|
||
ASSERT(pDbWall->Is(CURVE_ARC));
|
||
XArc ar=pDbWall->GetArc();
|
||
XPoint ptLoc=m_ptLocation;
|
||
ptLoc.z=ar.GetCenterPt().z;
|
||
double nRad=ads_distance(ar.GetCenterPt(), ptLoc);
|
||
double nSweepAng=m_nWidth/nRad;
|
||
double nStartAng=CT_std_angle(ads_angle(ar.GetCenterPt(), ptLoc)-nSweepAng/2.0),
|
||
nEndAng=CT_std_angle(ads_angle(ar.GetCenterPt(), ptLoc)+nSweepAng/2.0);
|
||
XArc arMid(ar.GetCenterPt(), nRad, nStartAng, nEndAng);
|
||
double nThick=pDbWall->GetWidth();
|
||
XArc arLeft=arMid.Offset(-nThick/2), arRight=arMid.Offset(nThick/2);
|
||
XPoint ptStart1, ptStart2, ptEnd1, ptEnd2;
|
||
arLeft.GetStartPoint(ptStart1);
|
||
arLeft.GetEndPoint(ptEnd1);
|
||
arRight.GetStartPoint(ptStart2);
|
||
arRight.GetEndPoint(ptEnd2);
|
||
|
||
poly.AppendNode(ptStart1);
|
||
poly.AppendNode(ptStart2, arRight.Bulge());
|
||
poly.AppendNode(ptEnd2);
|
||
poly.AppendNode(ptEnd1, -arLeft.Bulge());
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
// 判断门窗是否被曲线穿越
|
||
Adesk::Boolean TOpeningData::IsGoThroughBy(const XCurveSegment &segSrc) const
|
||
{
|
||
//add by xlc on 120607 解决带形窗所在墙基线在墙外时判断墙与门窗的关系错误问题
|
||
TGGeCurveSegment seg = segSrc;
|
||
if (m_opKind == OP_CORNWIN)
|
||
{
|
||
TAcDbObjectPtr obj(m_nIdOfWall, AcDb::kForRead);
|
||
if(!obj)
|
||
{
|
||
;
|
||
}
|
||
else
|
||
{
|
||
TDbWall *pWall = TDbWall::cast(obj.m_pObject);
|
||
if(pWall)
|
||
{
|
||
double dWidth = min(pWall->GetWidth(0), pWall->GetWidth(1));
|
||
if (dWidth < _DIST_SNAP) //基线在外侧时,通过墙中心线对带形窗进行校正
|
||
{
|
||
TGGeCurveSegment cvCenter = pWall->OffsetGeomCenter(LS_FINITE);
|
||
cvCenter.SetElevation(seg.StartPoint().z);
|
||
|
||
TADSGePoint3d ptInters[2];
|
||
int nOld = seg.GetLineFlag();
|
||
seg.SetLineFlag(LS_INFINITE);
|
||
int nNum = cvCenter.Intersection(seg, ptInters[0],ptInters[1]);
|
||
if (nNum > 0)
|
||
{
|
||
if (ptInters[0].Distance(seg.StartPoint()) < ptInters[0].Distance(seg.EndPoint()))
|
||
{
|
||
seg.SetStartPoint(ptInters[0]);
|
||
}
|
||
else
|
||
{
|
||
seg.SetEndPoint(ptInters[0]);
|
||
}
|
||
}
|
||
seg.SetLineFlag(nOld);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
XPoly2D poly(1);
|
||
GetOutlinePoly(seg.StartPoint().z, poly);
|
||
PointList pts(seg.StartPoint(), seg.EndPoint(), seg.GetBulge());
|
||
if(Intersect((XCurveSegment &)seg, poly, pts))
|
||
return Adesk::kTrue;
|
||
return Adesk::kFalse;
|
||
}
|
||
|
||
// 求门窗立面转平面的转换矩阵
|
||
// 仅适用与直窗
|
||
void TOpeningData::GetPlanarMatrix(ads_matrix matTrans) const
|
||
{
|
||
XPoint ptSide[2];
|
||
ads_polar(m_ptLocation, m_nRotation, m_nWidth/2.0, ptSide[0]);
|
||
ads_polar(m_ptLocation, m_nRotation+PI, m_nWidth/2.0, ptSide[1]);
|
||
XPoint pt3;
|
||
pt3 = ptSide[0];
|
||
pt3.z += m_nHeight;
|
||
|
||
get_matrix(ptSide[0], ptSide[1], pt3, matTrans);
|
||
}
|
||
|
||
////////////////////////////////////////
|
||
// 取得门窗的边界点(由插入点确定轨迹)
|
||
// Update New: 支持弧门窗
|
||
void TOpeningData::GetSidePoints(XPoint &ptSideBack, XPoint &ptSideFront) const
|
||
{
|
||
BOOL bFirstCase=IsLinear();
|
||
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pDbWall);
|
||
//ASSERT(pDbWall);
|
||
if(bFirstCase) { //直门窗或无墙的窗
|
||
double nRot=m_nRotation;
|
||
if(pDbWall && pDbWall->Is(CURVE_LINE))
|
||
nRot=pDbWall->XLine::Direction();
|
||
else if(pDbWall) // 在切换着色模式时有时导致pDbWall无效指针
|
||
nRot=ads_angle(pDbWall->GetArc().GetCenterPt(), m_ptLocation)+PI/2;
|
||
ads_polar(m_ptLocation, nRot, m_nWidth/2.0, ptSideFront);
|
||
ads_polar(m_ptLocation, nRot+PI, m_nWidth/2.0, ptSideBack);
|
||
} else { //弧墙上的转角窗或弧窗
|
||
XPoint ptLoc=m_ptLocation;
|
||
ptLoc.z = pDbWall->GetElevation();
|
||
XCurveSegment seg=pDbWall->OffsetGeomCenter(LS_INFINITE, TRUE);
|
||
ASSERT(seg.Is(CURVE_ARC));
|
||
double radCen=seg.GetArc().GetRadius(); //中线半径
|
||
double radBase=pDbWall->GetArc().GetRadius(); //基线半径
|
||
double nWidthOnCen=m_nWidth*radCen/radBase; //中线弧长
|
||
double dist1=seg.PathDistance(ptLoc);
|
||
XPointDir2d pt1, pt2;
|
||
seg.Polar(dist1-nWidthOnCen/2.0, pt1);
|
||
seg.Polar(dist1+nWidthOnCen/2.0, pt2);
|
||
ptSideBack=pt1;
|
||
ptSideFront=pt2;
|
||
ptSideBack.z=ptSideFront.z=m_ptLocation.z;
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
bool TOpeningData::GetCenterCurve(XCurveSegment &wall)const
|
||
{
|
||
bool bRet=false;
|
||
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
|
||
if(pWall)
|
||
{
|
||
wall=pWall->OffsetGeomCenter(LS_INFINITE,TRUE);
|
||
bRet=true;
|
||
}
|
||
OPENOBJ_END();
|
||
return bRet;
|
||
}
|
||
|
||
////////////////////////////////////////
|
||
// 取得门窗在基线上的边界点
|
||
void TOpeningData::GetSidePointsOnBase(XPoint &ptSideBack, XPoint &ptSideFront) const
|
||
{
|
||
GetSidePoints(ptSideBack, ptSideFront);
|
||
|
||
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
|
||
//ASSERT(pWall);
|
||
if(pWall) {
|
||
pWall->ProjectToMe(XPoint(ptSideBack), ptSideBack);
|
||
pWall->ProjectToMe(XPoint(ptSideFront), ptSideFront);
|
||
}
|
||
OPENOBJ_END();
|
||
ptSideBack.z=ptSideFront.z=m_ptLocation.z;
|
||
|
||
/*
|
||
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pDbWall);
|
||
BOOL bFirstCase=IsLinear();
|
||
if(bFirstCase) { //直门窗或无墙的窗
|
||
ads_polar(m_ptLocation, m_nRotation, m_nWidth/2.0, ptSideFront);
|
||
ads_polar(m_ptLocation, m_nRotation+PI, m_nWidth/2.0, ptSideBack);
|
||
} else {
|
||
XPoint ptLoc=m_ptLocation;
|
||
ptLoc.z = pDbWall->GetElevation();
|
||
XCurveSegment seg=*pDbWall;
|
||
seg.ProjectToMe(XPoint(ptLoc),ptLoc);
|
||
double dist1=seg.PathDistance(ptLoc);
|
||
XPointDir2d pt1, pt2;
|
||
seg.Polar(dist1-m_nWidth/2.0, pt1);
|
||
seg.Polar(dist1+m_nWidth/2.0, pt2);
|
||
ptSideBack=pt1;
|
||
ptSideFront=pt2;
|
||
ptSideBack.z=ptSideFront.z=m_ptLocation.z;
|
||
}
|
||
OPENOBJ_END()
|
||
*/
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 设置门窗的边界点(由插入点确定轨迹), 更新内部数据,包括宽度和插入点, 和标号位置
|
||
// 传人的点必须在插入点确定的轨迹上
|
||
void TOpeningData::SetSidePoints(const XPoint &ptSideBack, const XPoint &ptSideFront)
|
||
{
|
||
BOOL bLinear=IsLinear();
|
||
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pDbWall);
|
||
if(!pDbWall || bLinear) {
|
||
m_nWidth = ptSideFront.Distance(ptSideBack);
|
||
XPoint ptNewLoc;
|
||
Midpoint(ptSideBack, ptSideFront, ptNewLoc);
|
||
m_ptLabel += ptNewLoc - m_ptLocation;
|
||
m_ptLocation = ptNewLoc;
|
||
} else {
|
||
XCurveSegment seg=pDbWall->OffsetGeomCenter();
|
||
seg.SetElevation(ptSideBack.z);
|
||
double nDist1=seg.PathDistance(ptSideBack);
|
||
double nDist2=seg.PathDistance(ptSideFront);
|
||
double nPathDist=(nDist1+nDist2)/2.0;
|
||
double nWidthCen = fabs(nDist1-nDist2);
|
||
m_nWidth=nWidthCen*pDbWall->GetArc().GetRadius()/seg.GetArc().GetRadius();
|
||
|
||
XPointDir2d ptNewLoc; //对于弧窗, 弧上的中点
|
||
XPoint ptNew;
|
||
seg.Polar(nPathDist, ptNewLoc);
|
||
pDbWall->GetOpeningLocation(ptNewLoc, GetKind(), m_nWidth, ptNew);
|
||
m_ptLabel += ptNew - m_ptLocation;
|
||
m_ptLocation = ptNew;
|
||
}
|
||
if(pDbWall)
|
||
m_nRotation = pDbWall->Direction(m_ptLocation);
|
||
|
||
OPENOBJ_END()
|
||
}
|
||
|
||
|
||
// 在立面上的Outline, 投影到门窗中心面(插入点所在的面)上
|
||
// 实际上, 已经不包含弧段(已经离散化)
|
||
void TOpeningData::GetElevOutline(XPoly2D &poly) const
|
||
{
|
||
if(m_opKind==OP_DOORWIN)
|
||
{
|
||
XPoint ptSide[6];
|
||
GetSidePoints(ptSide[0], ptSide[3]);
|
||
ptSide[4]=ptSide[3]; ptSide[4].z += m_nHeight;
|
||
ptSide[5]=ptSide[0]; ptSide[5].z += m_nHeight;
|
||
if(m_nQuadrant==0 || m_nQuadrant==3) {
|
||
ads_polar(ptSide[0], m_nRotation, m_nWidth-m_nDoorWidth, ptSide[1]);
|
||
ptSide[2]=ptSide[1];
|
||
ptSide[1].z += m_nHeight-m_nWinHeight;
|
||
ptSide[0].z = ptSide[1].z;
|
||
} else {
|
||
ads_polar(ptSide[0], m_nRotation, m_nDoorWidth, ptSide[1]);
|
||
ptSide[2]=ptSide[1];
|
||
ptSide[2].z += m_nHeight-m_nWinHeight;
|
||
ptSide[3].z = ptSide[2].z;
|
||
}
|
||
|
||
poly.Reset();
|
||
poly.SetFlag(1);
|
||
for(int i=0; i<6; i++)
|
||
poly.AppendNode(ptSide[i]);
|
||
}
|
||
else
|
||
{
|
||
XDbObject objBlock(m_nIdStyle3d, AcDb::kForRead);
|
||
if(!(!objBlock)) {
|
||
AcDbBlockTableRecord *pBlock = AcDbBlockTableRecord::cast(objBlock.m_pObject);
|
||
// 从扩展实体数据取出原始尺寸
|
||
resbuf *pxData=pBlock->xData(TCHXD);
|
||
if(pxData) {
|
||
resbuf *pNext=pxData->rbnext;
|
||
if(pNext->restype==1040 && pNext->rbnext && pNext->rbnext->restype==1040) {
|
||
ads_real nScaleX=1.0, nScaleY=1.0, nScaleZ=1.0;
|
||
XPoint origenalSize= XPoint(pNext->resval.rreal, 60.0, pNext->rbnext->resval.rreal);
|
||
assert(origenalSize.x>0.0 && origenalSize.y>0.0 && origenalSize.z>0.0);
|
||
nScaleX = m_nWidth/origenalSize.x;
|
||
nScaleY = m_nThickness/origenalSize.y;
|
||
nScaleZ = m_nHeight/origenalSize.z;
|
||
|
||
pNext=pNext->rbnext->rbnext;
|
||
if(pNext && pNext->restype==1005 && pNext->resval.rstring) {
|
||
Entity entOutline;
|
||
ads_handent(pNext->resval.rstring, entOutline);
|
||
if(pBlock->isDependent() || !entOutline) { //拱型窗在XREF时无法用这个方法获得
|
||
//ads_relrb(pxData);
|
||
//return;
|
||
//遍历块表记录,寻找轮廓的POLYLINE
|
||
AcDbBlockTableRecordIterator* pBlockIterator;
|
||
Acad::ErrorStatus es = pBlock->newIterator(pBlockIterator);
|
||
ASSERT(es==Acad::eOk);
|
||
XString sOutlineEntHandle;
|
||
for (pBlockIterator->start(); !pBlockIterator->done();
|
||
pBlockIterator->step()) {
|
||
AcDbEntity *pEntity;
|
||
VERIFY(pBlockIterator->getEntity(pEntity, AcDb::kForRead, Adesk::kTrue)==Acad::eOk);
|
||
XDbObject obj(pEntity); // So auto close
|
||
if(!pEntity->isKindOf(AcDbPolyline::desc()) &&
|
||
!pEntity->isKindOf(AcDb2dPolyline::desc()) &&
|
||
!pEntity->isKindOf(AcDbCircle::desc()))
|
||
continue;
|
||
|
||
TCHAR *pszLayer=pEntity->layer();
|
||
ASSERT(pszLayer);
|
||
XString sPattern(256);
|
||
sPattern << LAY_BOUNDARY << _T(",*|") << LAY_BOUNDARY;
|
||
if(ads_wcmatch(pszLayer, sPattern)==RTNORM) {
|
||
acdbGetAdsName(entOutline.name, pEntity->objectId());
|
||
delete [] pszLayer;
|
||
break;
|
||
}
|
||
delete [] pszLayer;
|
||
}
|
||
delete pBlockIterator;
|
||
}
|
||
XPoint vtNormal(0,0,1);
|
||
entOutline.GetData(210, &vtNormal);
|
||
|
||
XPoly2D poly2d;
|
||
if(entOutline.Is(_T("CIRCLE")))
|
||
XCurveSegment(entOutline).AsPoly2D(poly2d);
|
||
else
|
||
poly2d=XPoly2D(entOutline);
|
||
if(!poly2d || !poly2d.IsClosed()) ;
|
||
else {
|
||
XPoly poly1;
|
||
poly2d.MapToPolygon1(poly1, _AS_SYS_UNIT(g_nCirDeviation)); //精度应当可以控制
|
||
// 转成世界坐标系
|
||
Groups gv(vtNormal), g0(0);
|
||
poly1.TransUCS((resbuf *)&gv, (resbuf *)&g0);
|
||
|
||
XPoint ptBase=pBlock->origin();
|
||
////////////////////////////////////
|
||
// 让Y坐标同ptBase
|
||
for(int idx=0; idx<poly1.Length(); idx++)
|
||
poly1[idx]->y = ptBase.y;
|
||
|
||
// 镜像情况
|
||
if(m_nQuadrant==1) nScaleX = -nScaleX;
|
||
else if(m_nQuadrant==2) {
|
||
nScaleX = -nScaleX;
|
||
nScaleY = -nScaleY;
|
||
} else if(m_nQuadrant==3) nScaleY = -nScaleY;
|
||
ads_matrix matForInsert;
|
||
ConstructMatrix(ptBase, m_ptLocation, nScaleX, nScaleY, nScaleZ, m_nRotation, matForInsert);
|
||
poly1.TransUCS(matForInsert);
|
||
|
||
poly.Reset();
|
||
poly.SetFlag(1);
|
||
for(int n=0; n<poly1.Length(); n++)
|
||
poly.AppendNode(*poly1[n]);
|
||
ads_relrb(pxData); // Release xdata, add 99/8/8 ZJQ
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
ads_relrb(pxData);
|
||
}
|
||
}
|
||
|
||
//UpdateNew: 现在支持弧型窗
|
||
XPoint ptSide[4];
|
||
GetSidePoints(ptSide[1], ptSide[0]);
|
||
ptSide[2]=ptSide[1]; ptSide[2].z += m_nHeight;
|
||
ptSide[3]=ptSide[0]; ptSide[3].z += m_nHeight;
|
||
|
||
poly.Reset();
|
||
poly.SetFlag(1);
|
||
for(int i=0; i<4; i++)
|
||
poly.AppendNode(ptSide[i]);
|
||
}
|
||
}
|
||
|
||
// 取得立面(三维)上的轮廓线, poly是封闭的
|
||
void TOpeningData::GetOutlinePoly(XPoly &poly, int nCirDiv) const
|
||
{
|
||
XPoly2D poly0;
|
||
GetElevOutline(poly0);
|
||
poly0.MapToPolygon(poly, nCirDiv);
|
||
}
|
||
|
||
|
||
// 求门窗洞的面积, 单位同绘图单位一致, 没有换算成米
|
||
double TOpeningData::GetOutlineArea() const
|
||
{
|
||
XPoly poly;
|
||
GetOutlinePoly(poly);
|
||
ads_matrix matTrans;
|
||
GetPlanarMatrix(matTrans);
|
||
poly.TransUCS(matTrans);
|
||
return fabs(poly.PathArea());
|
||
}
|
||
|
||
// 求门窗洞的周长
|
||
double TOpeningData::GetOutlineLength() const
|
||
{
|
||
XPoly poly;
|
||
GetOutlinePoly(poly);
|
||
double nLen=0.0;
|
||
for(int i=0; i<poly.Length(); i++) {
|
||
XLine ln;
|
||
poly.NthLine(i, ln);
|
||
nLen += ln.GetLength();
|
||
}
|
||
return nLen;
|
||
}
|
||
|
||
|
||
|
||
// 取得所在的墙的基面标高
|
||
// 如果不在任何墙上,则取0
|
||
ads_real TOpeningData::GetWallElevation() const
|
||
{
|
||
ads_real nWallElevation=0.0; //m_ptLocation.z;
|
||
if(!m_nIdOfWall) ;
|
||
else {
|
||
XDbObject obj(m_nIdOfWall, AcDb::kForRead);
|
||
if(!obj) ;
|
||
else {
|
||
TDbWall *pWall = TDbWall::cast(obj.m_pObject);
|
||
if(pWall) {
|
||
nWallElevation = pWall->GetElevation();
|
||
}
|
||
}
|
||
}
|
||
return nWallElevation;
|
||
}
|
||
|
||
// 取得所在的墙的宽度
|
||
// 如果不在任何墙上,则同门窗的厚度
|
||
ads_real TOpeningData::GetWallThickness(BOOL bIncludeInsulateLayer) const
|
||
{
|
||
ads_real nWidthOfWall=m_nThickness;
|
||
if(!m_nIdOfWall) ;
|
||
else {
|
||
XDbObject obj(m_nIdOfWall, AcDb::kForRead);
|
||
if(!obj) ;
|
||
else {
|
||
TDbWall *pWall = TDbWall::cast(obj.m_pObject);
|
||
if(pWall) {
|
||
nWidthOfWall = bIncludeInsulateLayer? pWall->GetWidth(4) : pWall->GetWidth();
|
||
}
|
||
}
|
||
}
|
||
return nWidthOfWall;
|
||
}
|
||
|
||
|
||
// 取三维样式(图块)的名称
|
||
Acad::ErrorStatus TOpeningData::GetStyle3dName(XString &sName) const
|
||
{
|
||
if(!m_nIdStyle3d)
|
||
return Acad::eInvalidInput;
|
||
|
||
OPENOBJ_BEGIN(m_nIdStyle3d, AcDb::kForRead, AcDbBlockTableRecord, rec);
|
||
if(!rec)
|
||
return Acad::eInvalidInput;
|
||
const TCHAR *pszName=NULL;
|
||
Acad::ErrorStatus es = rec->getName(pszName);
|
||
if(es!=Acad::eOk || !pszName)
|
||
return es;
|
||
sName = pszName;
|
||
OPENOBJ_END();
|
||
return Acad::eOk;
|
||
}
|
||
|
||
// 取二维样式(图块)的名称
|
||
Acad::ErrorStatus TOpeningData::GetStyle2dName(XString &sName) const
|
||
{
|
||
if(!m_nIdStyle2d)
|
||
return Acad::eInvalidInput;
|
||
|
||
OPENOBJ_BEGIN(m_nIdStyle2d, AcDb::kForRead, AcDbBlockTableRecord, rec);
|
||
if(!rec)
|
||
return Acad::eInvalidInput;
|
||
const TCHAR *pszName=NULL;
|
||
Acad::ErrorStatus es = rec->getName(pszName);
|
||
if(es!=Acad::eOk || !pszName)
|
||
return es;
|
||
sName = pszName;
|
||
OPENOBJ_END();
|
||
return Acad::eOk;
|
||
}
|
||
|
||
// 取三维样式(图块)的外部名称, 分别指出图库和图块
|
||
Acad::ErrorStatus TOpeningData::GetStyle3dName(XString &sDwb, XString &sDwg) const
|
||
{
|
||
XString sName;
|
||
Acad::ErrorStatus es=GetStyle3dName(sName);
|
||
if(es!=Acad::eOk)
|
||
return es;
|
||
|
||
return SplitBlockName(sName, sDwb, sDwg);
|
||
}
|
||
|
||
// 取三维样式(图块)的外部名称, 分别指出图库和图块
|
||
Acad::ErrorStatus TOpeningData::GetStyle2dName(XString &sDwb, XString &sDwg) const
|
||
{
|
||
XString sName;
|
||
Acad::ErrorStatus es=GetStyle2dName(sName);
|
||
if(es!=Acad::eOk)
|
||
return es;
|
||
|
||
return SplitBlockName(sName, sDwb, sDwg);
|
||
}
|
||
// 取门窗类型的描述名称
|
||
const TCHAR *TOpeningData::GetKindString() const
|
||
{
|
||
const TCHAR *pszKind=NULL;
|
||
if(m_nOpStyle&OPS_LIFTDOOR)
|
||
pszKind=_T("电梯门");
|
||
else if(m_nOpStyle&OPS_LVTRY)
|
||
pszKind=_T("隔断门");
|
||
else {
|
||
switch(GetKind()) {
|
||
case TOpeningData::OP_WINDOW:
|
||
pszKind=_T("窗");
|
||
break;
|
||
case TOpeningData::OP_DOORWIN:
|
||
pszKind=_T("门连窗");//modified by fxj 090622 门联窗-》门连窗
|
||
break;
|
||
case TOpeningData::OP_DOOR:
|
||
pszKind=_T("门");
|
||
break;
|
||
case TOpeningData::OP_TWODOOR:
|
||
pszKind=_T("子母门");
|
||
break;
|
||
case TOpeningData::OP_ARCWIN:
|
||
pszKind=_T("弧窗");
|
||
break;
|
||
case TOpeningData::OP_HOLE:
|
||
pszKind=_T("墙洞");
|
||
break;
|
||
case OP_PROWIN:
|
||
pszKind=_T("凸窗");
|
||
break;
|
||
case OP_CORNWIN:
|
||
pszKind=_T("带型窗");
|
||
break;
|
||
case OP_GROUP:
|
||
pszKind=_T("组合门窗");
|
||
break;
|
||
default:
|
||
pszKind=_T("未知");
|
||
break;
|
||
}
|
||
}
|
||
return pszKind;
|
||
}
|
||
|
||
XPoint TOpeningData::GetDoorPos() const
|
||
{
|
||
XPoint ptLoc=m_ptLocation;
|
||
if(m_opKind==OP_DOORWIN) {
|
||
XPoint ptDoorSide, ptDoorOtherSide;
|
||
if(m_nQuadrant==0 || m_nQuadrant==3) {
|
||
ads_polar(m_ptLocation, m_nRotation, m_nWidth/2, ptDoorSide);
|
||
ads_polar(ptDoorSide, m_nRotation+PI, m_nDoorWidth, ptDoorOtherSide);
|
||
} else {
|
||
ads_polar(m_ptLocation, m_nRotation+PI, m_nWidth/2, ptDoorSide);
|
||
ads_polar(ptDoorSide, m_nRotation, m_nDoorWidth, ptDoorOtherSide);
|
||
}
|
||
Midpoint(ptDoorSide, ptDoorOtherSide, ptLoc);
|
||
}
|
||
return ptLoc;
|
||
}
|
||
|
||
XPoint TOpeningData::GetWinPos() const
|
||
{
|
||
double nWinWidth=m_nWidth-m_nDoorWidth;
|
||
XPoint ptLoc=m_ptLocation;
|
||
if(m_opKind==OP_DOORWIN) {
|
||
XPoint ptWinSide[2];
|
||
if(m_nQuadrant==0 || m_nQuadrant==3) {
|
||
ads_polar(m_ptLocation, m_nRotation+PI, m_nWidth/2, ptWinSide[0]);
|
||
ads_polar(ptWinSide[0], m_nRotation, nWinWidth, ptWinSide[1]);
|
||
ptWinSide[0].z=ptWinSide[1].z=m_ptLocation.z+m_nHeight-m_nWinHeight;
|
||
} else {
|
||
ads_polar(m_ptLocation, m_nRotation, m_nWidth/2, ptWinSide[1]);
|
||
ads_polar(ptWinSide[1], m_nRotation+PI, nWinWidth, ptWinSide[0]);
|
||
ptWinSide[0].z=ptWinSide[1].z=m_ptLocation.z+m_nHeight-m_nWinHeight;
|
||
}
|
||
Midpoint(ptWinSide[0], ptWinSide[1], ptLoc)
|
||
}
|
||
return ptLoc;
|
||
}
|
||
|
||
// 返回值:0x01-lnLeft, 0x02-lnRight,lnLeft/lnRight都是无限长
|
||
int TOpeningData::GetSideLine2d(XLine &lnLeft, XLine& lnRight) const
|
||
{
|
||
XPoint ptOpenLoc = m_ptLocation;
|
||
ptOpenLoc.z=0;
|
||
|
||
ads_real nOrthoDrt=m_nRotation-PI/2;
|
||
OPENOBJ_BEGIN(GetWallId(), AcDb::kForRead, TDbWall, pWall);
|
||
if(pWall) {
|
||
nOrthoDrt = pWall->OrthoDirection(ptOpenLoc);
|
||
}
|
||
OPENOBJ_END();
|
||
|
||
XLine ln(ptOpenLoc, nOrthoDrt+PI);
|
||
// 门窗的左右线, 相对于墙的起点和终点方向而言
|
||
lnLeft=ln.Offset(-fabs(m_nWidth)/2.0),
|
||
lnRight=ln.Offset(fabs(m_nWidth)/2.0);
|
||
|
||
lnLeft.SetLineFlag(LS_INFINITE);
|
||
lnRight.SetLineFlag(LS_FINITE);
|
||
int nRetFlag=0x01|0x02; //左右都有
|
||
OPENOBJ_BEGIN(GetWallId(), AcDb::kForRead, TDbWall, pWall);
|
||
if(pWall) {
|
||
BOOL bIsArc=pWall->Is(CURVE_ARC);
|
||
if(GetKind()==TOpeningData::OP_ARCWIN) { //弧窗的作右线不同于弦窗
|
||
ASSERT(pWall->Is(CURVE_ARC));
|
||
XArc ar=pWall->GetArc();
|
||
|
||
TADSGePoint3d ptCen = ar.GetCenterPt();
|
||
ptCen.z = 0;
|
||
ar.SetCenterPt(ptCen);
|
||
|
||
XPoint ptOnWall=ptOpenLoc;
|
||
pWall->ProjectToMe(ptOpenLoc, ptOnWall);
|
||
double nRad=ar.GetCenterPt().Distance2d(ptOnWall);
|
||
double nSweepAng=GetWidth()/nRad;
|
||
double nStartAng=CT_std_angle(ads_angle(ar.GetCenterPt(), ptOnWall)-nSweepAng/2.0),
|
||
nEndAng=CT_std_angle(ads_angle(ar.GetCenterPt(), ptOnWall)+nSweepAng/2.0);
|
||
XArc arMid(ar.GetCenterPt(), ar.GetCenterPt().Distance2d(ptOpenLoc), nStartAng, nEndAng);
|
||
XArc arRight = arMid.Offset(200),
|
||
arLeft = arMid.Offset(-200);
|
||
arLeft.GetStartPoint(lnLeft.EndPoint());
|
||
arLeft.GetEndPoint(lnRight.EndPoint());
|
||
arRight.GetEndPoint(lnLeft.StartPoint());
|
||
arRight.GetEndPoint(lnRight.StartPoint());
|
||
} else if(GetKind()==TOpeningData::OP_CORNWIN) { //转角窗
|
||
//Status: 墙的基线与边线重合时,判断错误
|
||
XPoint ptOnWall=ptOpenLoc;
|
||
pWall->ProjectToMe(ptOpenLoc, ptOnWall);
|
||
double nPathDistLoc=pWall->PathDistance(ptOnWall);
|
||
XPointDir2d ptStart, ptEnd; //门窗的起始位置和终止位置
|
||
pWall->Polar(nPathDistLoc-GetWidth()/2.0, ptStart);
|
||
pWall->Polar(nPathDistLoc+GetWidth()/2.0, ptEnd);
|
||
ptStart.z = ptEnd.z = 0.0;
|
||
BOOL bStartAtCorn=FALSE;
|
||
BOOL bEndAtCorn=FALSE;
|
||
if(ptStart.Distance2d(pWall->StartPoint())<_DIST_SNAP) {
|
||
//lnLeft.StartPoint() = cvRight.StartPoint();
|
||
//lnLeft.EndPoint() = cvLeft.StartPoint();
|
||
bStartAtCorn=TRUE;
|
||
}
|
||
if(ptEnd.Distance(pWall->EndPoint())<_DIST_SNAP) {
|
||
//lnRight.StartPoint() = cvRight.EndPoint();
|
||
//lnRight.EndPoint() = cvLeft.EndPoint();
|
||
bEndAtCorn=TRUE;
|
||
}
|
||
|
||
if(bIsArc && (!bStartAtCorn || !bEndAtCorn)) { //弧墙上的转角窗
|
||
XArc ar=pWall->GetArc();
|
||
|
||
TADSGePoint3d ptCen = ar.GetCenterPt();
|
||
ptCen.z = 0;
|
||
ar.SetCenterPt(ptCen);
|
||
|
||
XPoint ptOnWall=ptOpenLoc;
|
||
pWall->ProjectToMe(ptOpenLoc, ptOnWall);
|
||
double nRad=ar.GetCenterPt().Distance2d(ptOnWall);
|
||
double nSweepAng=GetWidth()/nRad;
|
||
double nStartAng=CT_std_angle(ads_angle(ar.GetCenterPt(), ptOnWall)-nSweepAng/2.0),
|
||
nEndAng=CT_std_angle(ads_angle(ar.GetCenterPt(), ptOnWall)+nSweepAng/2.0);
|
||
XArc arMid(ar.GetCenterPt(), ar.GetCenterPt().Distance2d(ptOpenLoc), nStartAng, nEndAng);
|
||
XArc arRight = arMid.Offset(200),
|
||
arLeft = arMid.Offset(-200);
|
||
XPoint ptEnd1, ptEnd2;
|
||
XPoint ptStart1, ptStart2;
|
||
arLeft.GetStartPoint(ptEnd1);
|
||
arLeft.GetEndPoint(ptEnd2);
|
||
arRight.GetStartPoint(ptStart1);
|
||
arRight.GetEndPoint(ptStart2);
|
||
if(!bStartAtCorn) {
|
||
lnLeft.StartPoint()=ptStart1;
|
||
lnLeft.EndPoint()=ptEnd1;
|
||
}
|
||
if(!bEndAtCorn) {
|
||
lnRight.StartPoint()=ptStart2;
|
||
lnRight.EndPoint()=ptEnd2;
|
||
}
|
||
}
|
||
if(bStartAtCorn)
|
||
nRetFlag &= ~0x01;
|
||
if(!bEndAtCorn)
|
||
nRetFlag &= ~0x02;
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
|
||
return nRetFlag;
|
||
}
|
||
|
||
//add by xlc on 110131 独立门窗接口
|
||
BOOL TOpeningData::IsLoneOpening() const
|
||
{
|
||
return (m_nOpStyleEx & OPS_LONE) != 0;
|
||
}
|
||
|
||
Adesk::Boolean TOpeningData::IsHigh() const
|
||
{
|
||
//wlw mod 140220 只有窗户和洞才判断
|
||
if (m_opKind == OP_WINDOW || m_opKind == OP_ARCWIN)
|
||
return ((m_nOpStyle&OPS_ATHIGH)!=0);
|
||
else
|
||
return Adesk::kFalse;
|
||
}
|
||
void TOpeningData::SetLoneOpening(BOOL bTrue)
|
||
{
|
||
if (bTrue)
|
||
{
|
||
m_nOpStyleEx |= OPS_LONE;
|
||
}
|
||
else
|
||
{
|
||
m_nOpStyleEx &= ~OPS_LONE;
|
||
}
|
||
}
|