Files
envi-code/SourceCode/Code2026/CoreLibrary/AecDbOpening.cpp
T
2026-09-28 15:28:50 +08:00

3550 lines
82 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "stdafx.h"
#include "AecDbOpening.h"
#include "AecDbWall.h"
#include "MFCDbDwgFiler.h"
#include "KTCADUtilityEx.h"
#include "dbgrip.h"
#include "AecGripCback.h"
#include "KTSetting.h"
#include "geometry2json.h"
#include "AcGiViewDraw.h"
#include "AcDbX3dSolid.h"
#include "CoreTools.h"
#include "ImpMD5.h"
#include "simpleProperty.h"
extern AcGePoint3d MidPoint(const AcGePoint3d& pt1,const AcGePoint3d& pt2);
extern void transfromRegion(AcDbRegion *pRegion, const AcGePoint3d &ptOnRegion, const AcGeVector3d &vtNormal, const AcGePoint3d &ptOnPlan);
extern void PushGripMessage(GripMessage&);
extern BOOL GetDocScale(double& dPScale);
extern void DLLIMPEXP OrthoProjectedEntity(AcDbEntity *pEnt, const AcGePlane &plan, AcGeMatrix3d &xformPlanToWorld, AcDbVoidPtrArray &arEntPtrs);
extern DLLIMPEXP bool MakeBlockRefSet(AcDbVoidPtrArray &arEntPtrs, const AcDbObjectId &idLay,Adesk::Boolean bDoSubent, LPCTSTR pszName, AcDbDatabase *pDb = NULL);
extern Acad::ErrorStatus AddToModelSpace(AcDbEntity *pEnt, AcDbDatabase *pDb = NULL, bool bClose = true);
ACRX_DXF_DEFINE_MEMBERS(AecDbXOpening, AecDbEntityBase,
AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
AcDbProxyEntity::kNoOperation | AcDbProxyEntity::kDisableProxyWarning,
AEC_DBOPENING,
"AecDbXOpening"
"|Product Desc: shanghua earthworm app obj"
"|Company: shanghua inc"
"|WEB Address: www.shanghuasoft.com")
Adesk::UInt32 AecDbXOpening::kCurrentVersionNumber = 1;
static const Adesk::UInt16 kColorByBlock = 0;
static const Adesk::UInt16 kRed = 1;
static const Adesk::UInt16 kYellow = 2;
static const Adesk::UInt16 kGreen = 3;
static const Adesk::UInt16 kCyan = 4;
static const Adesk::UInt16 kBlue = 5;
static const Adesk::UInt16 kMagenta = 6;
static const Adesk::UInt16 kWhite = 7;
static const Adesk::UInt16 kColorByLayer = 256;
static void FreeBuffer(int n,AcDbVoidPtrArray& arEntPtrs)
{
AcDbEntity* pEnt = NULL;
while(arEntPtrs.length() > n )
{
pEnt = (AcDbEntity*)arEntPtrs.last();
if (pEnt != NULL)
{
pEnt->erase();
pEnt->close();
arEntPtrs.removeLast();
DELETE_PTR(pEnt);
}
}
}
extern CString IDCreate();
AecDbXOpening::AecDbXOpening(void)
{
m_pGripAppData = new AecGripData[10];
m_mapSpecXData.SetAt(KEY_NAME,_T("门窗"));
m_mapSpecXData.SetAt(KEY_NO, IDCreate());
}
AecDbXOpening::~AecDbXOpening(void)
{
delete [] m_pGripAppData;
}
/*
typedef struct OpeningData
{
int nType; //窗:0 门 1
int nFlag; //特殊标记
double dWidth; //门窗宽度
double dHeight; //门窗高度
double dBomEl; //相对墙体底部标高
AcGePoint3d ptPos; //位置,Z是真实标高
TCHAR szBlockName2d[MAX_PATH];//本地文件名2d
TCHAR szBlockName3d[MAX_PATH];//本地文件名3d
TCHAR szName[MAX_PATH]; //名称
TCHAR szSpec[MAX_PATH]; //附属信息
TCHAR szNo[65];//编号
TCHAR szFactory[MAX_PATH];//厂家
}OPENINGDATA;
*/
extern void GetMidPoint(AcDbCurve* pNaCurve,AcGePoint3d& ptMid);
void AecDbXOpening::SetOpeningData( const OpeningData& data,const AcDbObjectId& idWall)
{
AssertWriteEnabled();
m_mapSpecXData.SetAt(KEY_TYPE,data.nType);
m_mapSpecXData.SetAt(KEY_FLAG,data.nFlag);
m_mapSpecXData.SetAt(KEY_Width,data.dWidth);
m_mapSpecXData.SetAt(KEY_HEIGHT,data.dHeight);
m_mapSpecXData.SetAt(KEY_ORGPT,data.ptPos);
m_mapSpecXData.SetAt(KEY_NAME,data.szName);
m_mapSpecXData.SetAt(KEY_BLK2D,data.szBlockName2d);
m_mapSpecXData.SetAt(KEY_BLK3D,data.szBlockName3d);
m_mapSpecXData.SetAt(PIPE_SPEC,data.szSpec);
m_mapSpecXData.SetAt(KEY_BOMEL,data.dBomEl);
m_mapSpecXData.SetAt(KEY_IDCNT1,idWall);
m_mapSpecXData.SetAt(KEY_LabelText,data.szNo);
m_mapSpecXData.SetAt(KEY_FACTORY, data.szFactory);
m_mapSpecXData.SetAt(KEY_ADDBAF1,data.bAddBaf1);
m_mapSpecXData.SetAt(KEY_ADDBAF2,data.bAddBaf2);
AcDbEntity* pEnt = NULL;
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idWall,AcDb::kForRead))
{
AecDbXWall* pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
AcGePoint3d ptOn;
AcGeVector3d vtDir;
BOOL bIsVView = FALSE;
pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_VVIEW,bIsVView);
if (bIsVView)
{
//1.创建整体Solid
AcGePoint3d ptOnRegion;
pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_SECCEN,ptOnRegion);
AcDbCurve* pNaCur = pWall->GetNativeCurve();
AcGePoint3d ptSta,ptEnd;
pNaCur->getStartPoint(ptSta);
pNaCur->getEndPoint(ptEnd);
AcGeVector3d vtNormal(AcGeVector3d::kIdentity);
pNaCur->getFirstDeriv(ptSta, vtNormal);
AcDbRegion* pCloneRegion = pWall->GetSection();
transfromRegion(pCloneRegion, ptOnRegion, vtNormal, ptEnd);
AcDbLine* pLn1 = AecDbXWall::GetOrthoProjectOnXY(pCloneRegion);
if (pLn1 != NULL)
{
AcGePoint3d ptMid,ptMid2;
GetMidPoint(pNaCur,ptMid);
ptMid.z = 0.0;
pLn1->getClosestPointTo(ptMid,ptMid2);
AcGeVector3d vtM = ptMid - ptMid2;
AcGeMatrix3d xM;xM.setToTranslation(vtM);
pLn1->transformBy(vtM);
pLn1->getClosestPointTo(data.ptPos,ptOn);
pLn1->getFirstDeriv(ptOn,vtDir);
delete pLn1;
}
delete pCloneRegion;
}
else
{
pWall->getClosestPointTo(data.ptPos,ptOn);
pWall->getFirstDeriv(ptOn,vtDir);
}
vtDir.normalize();
ptOn.z = 0.0;//以XY面为准
WallData wData;
pWall->GetWallData(wData);
ptOn.z += wData.dBomEl;//真实标高
//记录墙体的走向和宽度
m_mapSpecXData.SetAt(PIPE_DIR,vtDir);
m_mapSpecXData.SetAt(PIPE_TDIR,1);
m_mapSpecXData.SetAt(KEY_PTON,ptOn);
m_mapSpecXData.SetAt(KEY_THICK,wData.dThick);
vtDir.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
vtDir.normalize();
vtDir *= 3.5 * 100.0;
ptOn += vtDir;
m_mapSpecXData.SetAt(KEY_NOPOS,ptOn);
}
pEnt->close();
}
//加载block2d
AcDbObjectId idBlk2d;
idBlk2d = KTCADUtilityEx::InsertBlock(data.szBlockName2d);
m_mapSpecXData.SetAt(KEY_BLK2DID,idBlk2d,FALSE);
AcDbObjectId idBlk3d;
idBlk3d = KTCADUtilityEx::InsertBlock(data.szBlockName3d);
m_mapSpecXData.SetAt(KEY_BLK3DID,idBlk3d,FALSE);
}
void AecDbXOpening::UpdateOpeningData(const OpeningData& data)
{
AssertWriteEnabled();
PreRefreshWallDraw();
//TEST
//TCHAR szH[17];
//objectId().handle().getIntoAsciiBuffer(szH);
//acutPrintf(_T("\n%s"), szH);
m_mapSpecXData.SetAt(KEY_TYPE,data.nType);
m_mapSpecXData.SetAt(KEY_FLAG,data.nFlag);
m_mapSpecXData.SetAt(KEY_Width,data.dWidth);
m_mapSpecXData.SetAt(KEY_HEIGHT,data.dHeight);
m_mapSpecXData.SetAt(KEY_THICK, data.dThick);
m_mapSpecXData.SetAt(KEY_NAME,data.szName);
m_mapSpecXData.SetAt(KEY_BLK2D,data.szBlockName2d);
m_mapSpecXData.SetAt(KEY_BLK3D,data.szBlockName3d);
m_mapSpecXData.SetAt(PIPE_SPEC,data.szSpec);
AcDbObjectId idWall;
m_mapSpecXData.GetAt(KEY_IDCNT1,idWall);
double dBomEl = data.dBomEl;
AcDbEntity* pEnt = NULL;
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idWall,AcDb::kForRead) )
{
AecDbXWall* pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
WallData wdata;
pWall->GetWallData(wdata);
dBomEl += wdata.dBomEl;
}
pEnt->close();
}
m_mapSpecXData.SetAt(KEY_BOMEL,dBomEl);
//m_mapSpecXData.SetAt(KEY_NO,data.szNo);
m_mapSpecXData.SetAt(KEY_LabelText,data.szNo);
m_mapSpecXData.SetAt(KEY_FACTORY,data.szFactory);
//加载block2d
AcDbObjectId idBlk2d;
idBlk2d = KTCADUtilityEx::InsertBlock(data.szBlockName2d);
m_mapSpecXData.SetAt(KEY_BLK2DID,idBlk2d,FALSE);
AcDbObjectId idBlk3d;
idBlk3d = KTCADUtilityEx::InsertBlock(data.szBlockName3d);
m_mapSpecXData.SetAt(KEY_BLK3DID,idBlk3d,FALSE);
RefreshWallDraw();
}
Acad::ErrorStatus AecDbXOpening::SetLabel(const TCHAR* pszLab)
{
assertWriteEnabled();
if (pszLab != NULL)
{
m_mapSpecXData.SetAt(KEY_LabelText,pszLab);
}
return Acad::eOk;
}
CString AecDbXOpening::GetLabel() const
{
assertReadEnabled();
CString sLab;
m_mapSpecXData.GetAt(KEY_LabelText,sLab);
return sLab;
}
void AecDbXOpening::RefreshWallData()
{
assertWriteEnabled();
AcDbObjectId idWall;
m_mapSpecXData.GetAt(KEY_IDCNT1,idWall);
AcGePoint3d ptPos;
m_mapSpecXData.GetAt(KEY_ORGPT,ptPos);
AcDbEntity* pEnt = NULL;
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idWall,AcDb::kForRead))
{
AecDbXWall* pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
AcGePoint3d ptOn;
AcGeVector3d vtDir;
pWall->getClosestPointTo(ptPos,ptOn);
pWall->getFirstDeriv(ptOn,vtDir);
vtDir.normalize();
WallData wData;
pWall->GetWallData(wData);
//记录墙体的走向和宽度
m_mapSpecXData.SetAt(PIPE_DIR,vtDir);
m_mapSpecXData.SetAt(KEY_PTON,ptOn);
m_mapSpecXData.SetAt(KEY_THICK,wData.dThick);
}
pEnt->close();
}
}
bool AecDbXOpening::GetOpeningData(OpeningData& data) const
{
assertReadEnabled();
m_mapSpecXData.GetAt(KEY_TYPE,data.nType);
m_mapSpecXData.GetAt(KEY_FLAG,data.nFlag);
m_mapSpecXData.GetAt(KEY_Width,data.dWidth);
m_mapSpecXData.GetAt(KEY_HEIGHT,data.dHeight);
m_mapSpecXData.GetAt(KEY_THICK,data.dThick);
m_mapSpecXData.GetAt(KEY_ORGPT,data.ptPos);
m_mapSpecXData.GetAt(KEY_BOMEL,data.dBomEl);
//m_mapSpecXData.GetAt(KEY_NO, data.szNo);//内部使用
m_mapSpecXData.GetAt(KEY_LabelText, data.szNo);
if (_tcslen(data.szNo) == 0)
m_mapSpecXData.GetAt(KEY_NO, data.szNo);
AcDbObjectId idWall;
m_mapSpecXData.GetAt(KEY_IDCNT1,idWall);
data.idWall = idWall.asOldId();
data.dParamInWall = 0.0;
AcGePoint3d ptOn;
AcDbEntity* pEnt = NULL;
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idWall,AcDb::kForRead) )
{
AecDbXWall* pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
WallData wdata;
pWall->GetWallData(wdata);
//转为相对标高
data.dBomEl -= wdata.dBomEl;
pWall->getClosestPointTo(data.ptPos,ptOn);
pWall->getParamAtPoint(ptOn,data.dParamInWall);
}
pEnt->close();
}
CString sTmp;
m_mapSpecXData.GetAt(KEY_NAME,sTmp);
_tcscpy(data.szName,(LPCTSTR)sTmp);
m_mapSpecXData.GetAt(KEY_BLK2D,sTmp);
_tcscpy(data.szBlockName2d,(LPCTSTR)sTmp);
m_mapSpecXData.GetAt(KEY_BLK3D,sTmp);
_tcscpy(data.szBlockName3d,(LPCTSTR)sTmp);
m_mapSpecXData.GetAt(PIPE_SPEC,sTmp);
_tcscpy(data.szSpec,(LPCTSTR)sTmp);
m_mapSpecXData.GetAt(KEY_FACTORY, sTmp);
_tcscpy(data.szFactory, (LPCTSTR)sTmp);
CString sKey;
memset(data.dXData,0,sizeof(double) * 16);
for(int i = 0;i < 16;i++)
{
sKey.Format(_T("%s_%d"),KEY_N,i+1);
m_mapSpecXData.GetAt(sKey,data.dXData[i]);
}
m_mapSpecXData.GetAt(KEY_BAYWIN,data.bBayWin);
m_mapSpecXData.GetAt(KEY_FTG,data.bFTG);
m_mapSpecXData.GetAt(KEY_ADDBAF1,data.bAddBaf1);
m_mapSpecXData.GetAt(KEY_ADDBAF2,data.bAddBaf2);
return true;
}
bool AecDbXOpening::GetForHouseSubtract(AcDbVoidPtrArray& arSolidPtrs) const
{
assertReadEnabled();
OpeningData data;
GetOpeningData(data);
AcGeVector3d vtDir;
m_mapSpecXData.GetAt(PIPE_DIR,vtDir);
double dThick = 0.0;
m_mapSpecXData.GetAt(KEY_THICK,dThick);
AcGePoint3d ptOn;
m_mapSpecXData.GetAt(KEY_PTON,ptOn);
double dBomEl = 0.0;
m_mapSpecXData.GetAt(KEY_BOMEL,dBomEl);
ptOn.z = dBomEl;//以门窗保存的标高为准!!!
vtDir.normalize();
AcDb3dSolid* pSolid = new AcDb3dSolid;
pSolid->createBox(data.dWidth,dThick,data.dHeight);
double dAngle = AcGeVector3d::kXAxis.angleTo(vtDir,AcGeVector3d::kZAxis);
AcGeMatrix3d xformR;
xformR.setToRotation(dAngle,AcGeVector3d::kZAxis);
pSolid->transformBy(xformR);
AcGeMatrix3d xform;
ptOn.z += 0.5 * data.dHeight;
xform.setToTranslation(ptOn.asVector());
pSolid->transformBy(xform);
arSolidPtrs.append(pSolid);
return arSolidPtrs.isEmpty();
}
void AecDbXOpening::subList() const
{
acutPrintf(_T("\n门窗"));
AecDbEntityBase::subList();
m_mapSpecXData.List();
}
bool AecDbXOpening::GetBimInfoTip(CString& sInfoTip) const
{
assertReadEnabled();
OpeningData data;
memset(&data,0,sizeof(OpeningData));
GetOpeningData(data);
CString sField,sFmt;
if (data.nType == 1)//门
{
sField = _T("门:\n");
sInfoTip += sField;
MAKEFIELD(_T("宽度"),_T("%.1f"),data.dWidth,sInfoTip);
MAKEFIELD(_T("高度"),_T("%.1f"),data.dHeight,sInfoTip);
MAKEFIELD(_T("相对墙底标高"),_T("%.1f"),data.dBomEl,sInfoTip);
MAKEFIELD(_T("二维块名"),_T("%s"),data.szBlockName2d,sInfoTip);
MAKEFIELD(_T("三维块名"),_T("%s"),data.szBlockName3d,sInfoTip);
MAKEFIELD(_T("名称"),_T("%s"),data.szName,sInfoTip);
MAKEFIELD(_T("编号"),_T("%s"),data.szNo,sInfoTip);
MAKEFIELD(_T("厂家"),_T("%s"),data.szFactory,sInfoTip);
}
else if (data.nType == 2)
{
sField = _T("窗:\n");
sInfoTip += sField;
MAKEFIELD(_T("宽度"),_T("%.1f"),data.dWidth,sInfoTip);
MAKEFIELD(_T("高度"),_T("%.1f"),data.dHeight,sInfoTip);
MAKEFIELD(_T("相对墙底标高"),_T("%.1f"),data.dBomEl,sInfoTip);
MAKEFIELD(_T("二维块名"),_T("%s"),data.szBlockName2d,sInfoTip);
MAKEFIELD(_T("三维块名"),_T("%s"),data.szBlockName3d,sInfoTip);
MAKEFIELD(_T("名称"),_T("%s"),data.szName,sInfoTip);
MAKEFIELD(_T("编号"),_T("%s"),data.szNo,sInfoTip);
MAKEFIELD(_T("厂家"),_T("%s"),data.szFactory,sInfoTip);
}
return true;
}
Acad::ErrorStatus AecDbXOpening::copyFrom(const AcRxObject* pSrc)
{
AecDbEntityBase::copyFrom(pSrc);
AecDbXOpening* pSrcOp = AecDbXOpening::cast(pSrc);
if (pSrcOp != NULL)
{
m_mapSpecXData.CopyFrom(&pSrcOp->m_mapSpecXData);
//发送提资需要相同的ID
Adesk::Int16 nVal = acdbCurDwg()->useri4();
if (nVal != KEY_NOPROTECT)
{
int nVt = 0;
CString sID = IDCreate();
if (m_mapSpecXData.HasKey(KEY_NO, nVt))
m_mapSpecXData.SetAt(KEY_NO, sID);
}
}
return Acad::eOk;
}
int AecDbXOpening::ComparedTo(AecDbEntityBase *pCurOther) const
{
assertReadEnabled();
AecDbXOpening *pOther = AecDbXOpening::cast(pCurOther);
if (pOther != NULL)
{
/*//TEST
AcDbHandle hdO;
pOther->getAcDbHandle(hdO);
AcDbHandle hdT;
getAcDbHandle(hdT);
TCHAR szO[17], szT[17];
hdO.getIntoAsciiBuffer(szO);
hdT.getIntoAsciiBuffer(szT);
acutPrintf(_T("\nThis:%s Other:%s"), szT, szO);
*/
OpeningData data1;
GetOpeningData(data1);
OpeningData data2;
pOther->GetOpeningData(data2);
if (fabs(data1.dWidth - data2.dWidth) > 1.e-1)
return 1;
if (fabs(data1.dHeight - data2.dHeight) > 1.e-1)
return 1;
if (fabs(data1.dThick - data2.dThick) > 1.e-1)
return 1;
if (fabs(data1.dBomEl - data2.dBomEl) > 1.e-1)
return 1;
if (_tcscmp(data1.szBlockName2d, data2.szBlockName2d) != 0)
return 1;
if (_tcscmp(data1.szBlockName3d, data2.szBlockName3d) != 0)
return 1;
if (_tcscmp(data1.szName, data2.szName) != 0)
return 1;
return 0;
}
return -1;
}
void AecDbXOpening::AlignInsPointToMidLine()
{
AcGePoint3d ptHit,ptOn;
m_mapSpecXData.GetAt(KEY_PTON, ptHit);
AcDbObjectId idWall;
m_mapSpecXData.GetAt(KEY_IDCNT1, idWall);
AcDbEntity *pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt, idWall, AcDb::kForRead))
{
AecDbXWall *pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
double dThick = 10.0;
pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_SIZE1,dThick);
AcDbCurve *pNaCur = NULL;
AcDbLine *pNaLine = NULL;
AcGeVector3d vtDir;
AcGePoint3d ptSta, ptEnd, ptFr;
double dDist1 = 0.0, dDist2 = 0.0;
BOOL bIsVView = FALSE;
pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_VVIEW, bIsVView);
if (bIsVView)
{
//1.创建整体Solid
AcGePoint3d ptOnRegion;
pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_SECCEN, ptOnRegion);
pNaCur = pWall->GetNativeCurve();
pNaCur->getStartPoint(ptSta);
pNaCur->getEndPoint(ptEnd);
AcGeVector3d vtNormal(AcGeVector3d::kIdentity);
pNaCur->getFirstDeriv(ptSta, vtNormal);
AcDbRegion *pCloneRegion = pWall->GetSection();
transfromRegion(pCloneRegion, ptOnRegion, vtNormal, ptEnd);
AcDbLine *pLn1 = AecDbXWall::GetOrthoProjectOnXY(pCloneRegion);
if (pLn1 != NULL)
{
AcGePoint3d ptMid, ptMid2;
GetMidPoint(pNaCur, ptMid);
ptMid.z = 0.0;
pLn1->getClosestPointTo(ptMid, ptMid2);
AcGeVector3d vtM = ptMid - ptMid2;
AcGeMatrix3d xM; xM.setToTranslation(vtM);
pLn1->transformBy(vtM);
pLn1->getClosestPointTo(ptHit, ptOn);
ptHit.z = ptOn.z = 0.0;
if (ptHit.distanceTo(ptOn) < dThick)
{
m_mapSpecXData.SetAt(KEY_PTON, ptOn);
}
}
delete pCloneRegion;
}
else
{
pNaCur = pWall->GetNativeCurve();
pNaCur->getClosestPointTo(ptHit, ptOn);
ptHit.z = ptOn.z = 0.0;
if (ptHit.distanceTo(ptOn) < dThick)
{
m_mapSpecXData.SetAt(KEY_PTON, ptOn);
}
}
}
pEnt->close();
}
}
Acad::ErrorStatus AecDbXOpening::subTransformBy(const AcGeMatrix3d& xform)
{
AssertWriteEnabled();
//当前命令如果时复制,不需要墙体原处合并
bool bIsCopy = false;
if (objectId().isValid())
{
struct resbuf rb;
acedGetVar(_T("CMDNAMES"), &rb);
if (_tcscmp(rb.resval.rstring, _T("COPY")) == 0)
{
bIsCopy = true;
}
}
if (!bIsCopy)
{
PreRefreshWallDraw();
}
AcGePoint3d ptPos;
m_mapSpecXData.GetAt(KEY_ORGPT,ptPos);
ptPos.transformBy(xform);
m_mapSpecXData.SetAt(KEY_ORGPT,ptPos);
//标高的变化
ptPos.set(0,0,0);
m_mapSpecXData.GetAt(KEY_BOMEL,ptPos.z);
ptPos.transformBy(xform);
m_mapSpecXData.SetAt(KEY_BOMEL,ptPos.z);
AcGeVector3d vtDir;
m_mapSpecXData.GetAt(PIPE_DIR,vtDir);
vtDir.normalize();
vtDir.transformBy(xform);
m_mapSpecXData.SetAt(PIPE_DIR,vtDir);
AcGePoint3d ptOn;
m_mapSpecXData.GetAt(KEY_PTON,ptOn);
ptOn.transformBy(xform);
m_mapSpecXData.SetAt(KEY_PTON,ptOn);
m_mapSpecXData.GetAt(KEY_NOPOS,ptOn);
ptOn.transformBy(xform);
m_mapSpecXData.SetAt(KEY_NOPOS,ptOn);
if (objectId().isValid())
{
if (objectId().isValid() && bIsCopy)
{
AlignInsPointToMidLine();
}
//co 命令复制的门窗丢失了和墙体关系
//确认重新建立关系
AecComplexCurve win2d;
GetStandardDraw2d(win2d, false);
AcDbObjectId idWall;
m_mapSpecXData.GetAt(KEY_IDCNT1, idWall);
AcDbEntity *pEnt = NULL;
if (Acad::eOk == acdbOpenAcDbEntity(pEnt, idWall, AcDb::kForWrite))
{
AecDbXWall *pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
//pWall->AppendAssocPart(objectId());
}
pEnt->close();
}
}
RefreshWallDraw();
return Acad::eOk;
}
CString AecDbXOpening::getUniqueName() const
{
assertReadEnabled();
CString str(_T(""));
OpeningData data;
::memset(&data, 0, sizeof(OpeningData));
GetOpeningData(data);
::memset(&data.dBomEl, 0, sizeof(double));
::memset(&data.ptPos, 0, sizeof(AcGePoint3d));
::memset(data.szNo, 0, 65 * sizeof(TCHAR));
::memset(data.szFactory, 0, MAX_PATH * sizeof(TCHAR));
byte *pBuf = new byte[sizeof(OpeningData)];
::memset(pBuf, 0, sizeof(OpeningData));
memcpy(pBuf, &data, sizeof(OpeningData));
ImpMD5 md5(pBuf, sizeof(OpeningData));
return md5.toString16W().c_str();
}
Acad::ErrorStatus AecDbXOpening::GetDoorOpenDir(AcGeVector3d& vtOpen) const
{
assertReadEnabled();
AcGeVector3d vtDir;
m_mapSpecXData.GetAt(PIPE_DIR,vtDir);
OpeningData data;
GetOpeningData(data);
//加载block2d
AcDbObjectId idBlk2d;
m_mapSpecXData.GetAt(KEY_BLK2DID,idBlk2d);
AcDbBlockReference bRef;
bRef.setBlockTableRecord(idBlk2d);
bRef.setPosition(data.ptPos);
int nDir = 1;
m_mapSpecXData.GetAt(PIPE_TDIR,nDir);
if (abs(nDir) < 1) nDir = 1;
vtDir *= nDir;
double dRot = AcGeVector3d::kXAxis.angleTo(vtDir,AcGeVector3d::kZAxis);
bRef.setRotation(dRot);
bRef.setScaleFactors( AcGeScale3d(data.dWidth,data.dWidth,1.0));
AcDbExtents ext;
bRef.getGeomExtents(ext);
AcGePoint3d ptMid = MidPoint(ext.minPoint(),ext.maxPoint());
ptMid.z = 0.0;data.ptPos.z = 0.0;
vtOpen = ptMid - data.ptPos;
double dLen = vtOpen.length() * 2.0;
vtOpen.normalize();
vtOpen *= dLen;
return Acad::eOk;
}
Acad::ErrorStatus AecDbXOpening::subGetGripPoints( AcDbGripDataPtrArray& grips,
const double curViewUnitSize,
const int gripSize,
const AcGeVector3d& curViewDir,
const int bitflags) const
{
assertReadEnabled();
AcGePoint3dArray gripPoints;
ImpGetGripPoints(gripPoints,bitflags);
int nColor = kWhite;
AcDbGripData* pGripData = NULL;
EPosition ePos;
CString sTip;
for (int i = 0;i < gripPoints.length();i++)
{
ePos = ExplainGripIndex(i,sTip);
memset(&m_pGripAppData[i],0,sizeof(AecGripData));
m_pGripAppData[i].nIndex = i;
m_pGripAppData[i].nSegIndex = -1;
m_pGripAppData[i].ePos = ePos;
m_pGripAppData[i].nColor = kBlue;
m_pGripAppData[i].ptGrip = gripPoints.at(i);
_tcscpy(m_pGripAppData[i].szTip,sTip);
//_tcscpy(m_pGripAppData[i].szID,m_sGUID);
m_pGripAppData[i].pOwner = (AcDbEntity*)this;
pGripData = new AcDbGripData;
pGripData->setGripPoint(gripPoints.at(i));
pGripData->setAppData((void*)&m_pGripAppData[i]);
pGripData->setWorldDraw(AecGripCback::WorldDrawfunc);
pGripData->setToolTipFunc(AecGripCback::GripToolTipFunc);
grips.append(pGripData);
}
//调用基类加入单击修改
SubAddHitEditGrip(grips);
//动态标注
//直线,半径 标注风格
if (!grips.isEmpty())
{
SubAddDimPoints(grips, curViewDir);
}
return Acad::eOk;
}
Acad::ErrorStatus AecDbXOpening::SubAddDimPoints(AcDbGripDataPtrArray &grips, const AcGeVector3d &curViewDir) const
{
OpeningData opData;
memset(&opData, 0, sizeof(OpeningData));
GetOpeningData(opData);
AcGeVector3d vtDir;
m_mapSpecXData.GetAt(PIPE_DIR, vtDir);
vtDir.normalize();
AcGePoint3d ptS, ptE, ptPs,ptM;
ptPs = opData.ptPos;
//宽度
ptS = ptPs - 0.5 * vtDir * opData.dWidth;
ptE = ptPs + 0.5 * vtDir * opData.dWidth;
ptM = MidPoint(ptS, ptE);
ptM.z -= 5.0 * 100.0;//标注文字位置
AddDimPoints(grips, curViewDir, ptS, ptE, ptM, 0);
//高度
ptS = ptPs + AcGeVector3d::kZAxis * opData.dHeight;
ptE = ptPs;
ptM = MidPoint(ptS, ptE);
ptM += 5.0 * 200.0 * vtDir;//标注文字位置
AddDimPoints(grips, curViewDir, ptS, ptE, ptM, 0);
return Acad::eOk;
}
Acad::ErrorStatus AecDbXOpening::AddDimPoints(AcDbGripDataPtrArray &grips, const AcGeVector3d &curViewDir,
const AcGePoint3d &ptSta, const AcGePoint3d &ptEnd,
const AcGePoint3d &ptMid, int nDimType, double dVal/* = -1.0*/, double dt) const
{
int i = grips.length();
if (i >= GRIP_LENGTH)//多余不显示
return Acad::eOk;
EPosition ePos = eDim0;
memset(&m_pGripAppData[i], 0, sizeof(AecGripData));
m_pGripAppData[i].nIndex = i;
m_pGripAppData[i].ePos = ePos;
m_pGripAppData[i].nColor = kGreen;
m_pGripAppData[i].ptGrip = ptMid;
m_pGripAppData[i].ptDim[0] = ptSta;
m_pGripAppData[i].ptDim[1] = ptEnd;
m_pGripAppData[i].nDimType = nDimType;
if (dVal > 1.e-3)
{
if (nDimType == 1)
{
_stprintf(m_pGripAppData[i].szTip, _T("R%.1f"), dVal);
}
else if (nDimType == 2)//@100 标注
{
_stprintf(m_pGripAppData[i].szTip, _T("Ø%.1f"), dVal);
}
else if (nDimType == 3)//角度标注
{
_stprintf(m_pGripAppData[i].szTip, _T("%.1f°"), dVal);
}
else if (nDimType == 4)//@107x3.5
{
_stprintf(m_pGripAppData[i].szTip, _T("Ø%.1fx%.1f"), dVal, dt);
}
}
else
{
_tcscpy(m_pGripAppData[i].szTip, _T(" "));
}
_tcscpy(m_pGripAppData[i].szID, _T(" "));
m_pGripAppData[i].pOwner = (AcDbEntity *)this;
AcDbGripData *pGripData = new AcDbGripData;
pGripData->setGripPoint(ptMid);
pGripData->setAppData((void *)&m_pGripAppData[i]);
pGripData->setWorldDraw(AecGripCback::WorldDrawfunc);
pGripData->setToolTipFunc(AecGripCback::GripToolTipFunc);
grips.append(pGripData);
return Acad::eOk;
}
Acad::ErrorStatus AecDbXOpening::ImpGetGripPoints(AcGePoint3dArray& gripPoints,const int bitflags) const
{
assertReadEnabled();
AcGePoint3d ptPos;
m_mapSpecXData.GetAt(KEY_ORGPT,ptPos);
ptPos.z = 0.0;
AcGePoint3d ptGe[5];
OpeningData data;
GetOpeningData(data);
ptGe[0] = ptPos;
AcGeVector3d vtDir;
m_mapSpecXData.GetAt(PIPE_DIR,vtDir);
vtDir.normalize();
ptGe[1] = ptGe[0] - data.dWidth * 0.5 * vtDir;
ptGe[2] = ptGe[0] + data.dWidth * 0.5 * vtDir;
AcGeVector3d vtOpen;
GetDoorOpenDir(vtOpen);
ptGe[3] = ptGe[0] + vtOpen;
for (int i = 0;i < 4;i++)
{
gripPoints.append(ptGe[i]);
}
m_mapSpecXData.GetAt(KEY_NOPOS,ptPos);
gripPoints.append(ptPos);
//增加左右,如果是門
if (data.nType == 2)
{
//左右方向
int nLDir = 1;
m_mapSpecXData.GetAt(PIPE_DRAWDIR, nLDir);
if (abs(nLDir) < 1) nLDir = 1;
if (abs(nLDir) > 1)
nLDir = nLDir / abs(nLDir);
vtDir.normalize();
vtDir *= vtOpen.length();
ptGe[4] = ptGe[3] + vtDir * nLDir;
gripPoints.append(ptGe[4]);
}
return Acad::eOk;
}
EPosition AecDbXOpening::ExplainGripIndex(int nIndex,CString& sTip) const
{
assertReadEnabled();
EPosition ePos = eAdjust0;
switch(nIndex)
{
case 0://Mid
{
ePos = eMid;
sTip = _T("门窗的位置点");
break;
}
case 1://Sta
{
ePos = eStart;
sTip = _T("门窗的左侧改宽度点");
break;
}
case 2://End
{
ePos = eEnd;
sTip = _T("门窗的右侧改宽度点");
break;
}
case 3://Open
{
ePos = eAdjust0;
sTip = _T("门窗的开口方向点");
break;
}
case 4:
{
ePos = eAdjust0;
sTip = _T("门窗的编号位置点");
break;
}
case 5:
{
ePos = eAdjust0;
sTip = _T("门窗的左右方向点");
break;
}
default:
break;
}
return ePos;
}
bool AecDbXOpening::GetPositionGrip(int nIndex, AecGripData *&pGrip) const
{
if (nIndex < GRIP_LENGTH && nIndex >= 0)
{
pGrip = &m_pGripAppData[nIndex];
return true;
}
return false;
}
Acad::ErrorStatus AecDbXOpening::subMoveGripPointsAt(const AcDbVoidPtrArray& appData, const AcGeVector3d& offset, const int bitflags)
{
AssertWriteEnabled();
if (!appData.isEmpty())
{
if (HitOnGripEdit(appData))
{
return Acad::eOk;
}
AecGripData* pAppData = NULL;
if ( appData.isEmpty() )
{
return Acad::eOk;
}
AcGeVector3d vtDir,vtOpen;
m_mapSpecXData.GetAt(PIPE_DIR,vtDir);
vtDir.normalize();
double dW = 0.0,dDis1 = 0,dDis2 = 0;
AcGePoint3d ptOn,ptPos,ptTmp;
AcGeVector3d vtOffset;
pAppData = (AecGripData*)appData.first();
AcGePoint3d ptHit = pAppData->ptGrip;
int nGripIndex = pAppData->nIndex;
switch(nGripIndex)
{
case 0://Mid
{
if (bitflags != 999)
PreRefreshWallDraw();
vtDir.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
vtOffset = offset.orthoProject(vtDir);
m_mapSpecXData.GetAt(KEY_PTON,ptOn);
ptOn += vtOffset;
m_mapSpecXData.SetAt(KEY_PTON,ptOn);
m_mapSpecXData.GetAt(KEY_ORGPT,ptPos);
ptPos += vtOffset;
m_mapSpecXData.SetAt(KEY_ORGPT,ptPos);
if (m_mapSpecXData.GetAt(KEY_NOPOS,ptOn))
{
ptOn += vtOffset;
m_mapSpecXData.SetAt(KEY_NOPOS,ptOn);
}
if (bitflags != 999)
RefreshWallDraw();
break;
}
case 1://Sta
case 2://End
{
if (bitflags != 999)
PreRefreshWallDraw();
//宽度变化,位置不变
vtDir.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
vtOffset = offset.orthoProject(vtDir);
m_mapSpecXData.GetAt(KEY_ORGPT,ptPos);
ptTmp = ptPos;
ptPos += 0.5 * vtOffset;
m_mapSpecXData.SetAt(KEY_ORGPT,ptPos);
m_mapSpecXData.GetAt(KEY_PTON,ptOn);
ptOn += 0.5 * vtOffset;
m_mapSpecXData.SetAt(KEY_PTON,ptOn);
//ptPos.z = 0.0;
//ptHit += vtOffset;
//ptHit.z = 0.0;
//dW = 2.0 * ptHit.distanceTo(ptPos);
ptTmp.z = 0.0;
dDis1 = ptHit.distanceTo(ptTmp);
ptHit += vtOffset;
dDis2 = ptHit.distanceTo(ptTmp);
//单边改变宽度
m_mapSpecXData.GetAt(KEY_Width,dW);
dW -= (dDis1 - dDis2);
m_mapSpecXData.SetAt(KEY_Width,dW);
if (bitflags != 999)
RefreshWallDraw();
break;
}
case 3://Open
{
vtOffset = offset.orthoProject(vtDir);
GetDoorOpenDir(vtOpen);
int nDir = 1;
m_mapSpecXData.GetAt(PIPE_TDIR,nDir);
if (abs(nDir) < 1) nDir = 1;
vtOpen *= nDir;
if ( !vtOffset.isZeroLength())
{
if ( vtOffset.isCodirectionalTo(vtOpen) )//同向
{
m_mapSpecXData.SetAt(PIPE_TDIR,1);
}
else
{
m_mapSpecXData.SetAt(PIPE_TDIR,-1);
}
}
break;
}
case 4://lable
{
m_mapSpecXData.GetAt(KEY_NOPOS,ptOn);
ptOn += offset;
m_mapSpecXData.SetAt(KEY_NOPOS,ptOn);
break;
}
case 5:
{
int nDir = 1;
m_mapSpecXData.GetAt(PIPE_DRAWDIR, nDir);
GetDoorOpenDir(vtOpen);
vtOffset = offset.orthoProject(vtOpen);
vtDir *= nDir;
if (!vtOffset.isZeroLength() && vtOffset.dotProduct(vtDir) < 0)
{
nDir *= -1;
}
m_mapSpecXData.SetAt(PIPE_DRAWDIR, nDir);
break;
}
default:
break;
}
}
return Acad::eOk;
}
Acad::ErrorStatus AecDbXOpening::subGetStretchPoints(AcGePoint3dArray& stretchPoints) const
{
assertReadEnabled();
AcGePoint3d ptPos;
m_mapSpecXData.GetAt(KEY_ORGPT,ptPos);
ptPos.z = 0.0;
stretchPoints.append(ptPos);
return Acad::eOk;
}
Acad::ErrorStatus AecDbXOpening::subMoveStretchPointsAt(const AcDbIntArray& indices,const AcGeVector3d& offset)
{
AssertWriteEnabled();
AcGeVector3d vtDir,vtOpen;
m_mapSpecXData.GetAt(PIPE_DIR,vtDir);
vtDir.normalize();
double dW = 0.0;
AcGePoint3d ptOn,ptPos;
AcGeVector3d vtOffset;
int nGripIndex = indices.first();
switch(nGripIndex)
{
case 0://Mid
{
PreRefreshWallDraw();
vtDir.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
vtOffset = offset;//offset.orthoProject(vtDir);
m_mapSpecXData.GetAt(KEY_PTON,ptOn);
ptOn += vtOffset;
m_mapSpecXData.SetAt(KEY_PTON,ptOn);
m_mapSpecXData.GetAt(KEY_ORGPT,ptPos);
ptPos += vtOffset;
m_mapSpecXData.SetAt(KEY_ORGPT,ptPos);
RefreshWallDraw();
break;
}
default:
break;
}
return Acad::eOk;
}
Acad::ErrorStatus AecDbXOpening::PreRefreshWallDraw()
{
if (objectId().isValid())
{
AcDbObjectId idWall;
m_mapSpecXData.GetAt(KEY_IDCNT1,idWall);
Acad::ErrorStatus es;
AcDbEntity* pEnt = NULL;
if ( Acad::eOk == ( es = acdbOpenAcDbEntity(pEnt,idWall,AcDb::kForWrite)))
{
AecDbXWall* pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
AecComplexCurve win2d;
GetStandardDraw2d(win2d,false);
pWall->BoolUniteDraw2d(win2d);
}
pEnt->close();
}
}
return Acad::eOk;
}
void AecDbXOpening::RefreshWallOnOpeningDraw(const AcDbObjectId &idWall )
{
assertReadEnabled();
Acad::ErrorStatus es;
AcDbEntity *pEnt = NULL;
if (Acad::eOk == (es = acdbOpenAcDbEntity(pEnt, idWall, AcDb::kForWrite)))
{
AecDbXWall *pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
AecComplexCurve win2d;
this->GetStandardDraw2d(win2d, false);
pWall->SubtractDraw2d(win2d);
}
pEnt->close();
}
}
Acad::ErrorStatus AecDbXOpening::RefreshWallDraw()
{
if (objectId().isValid())
{
AcDbObjectId idWall;
m_mapSpecXData.GetAt(KEY_IDCNT1,idWall);
//新的更新墙体方式解决co的复制中断
RefreshWallOnOpeningDraw(idWall);
return Acad::eOk;
//消息方式,导致co的复制多次中断
GripMessage msg;
memset(&msg,0,sizeof(GripMessage));
msg.nType = kGripMsgContinue;//跳过 GipCmdEnd,为 PL_MQSX用
msg.idHost = idWall;
msg.idAsso = objectId();
msg.nData = 0;
msg.pParam = NULL;
msg.fData = 0.0;
msg.ptGrip.set(0,0,0);
PushGripMessage(msg);
acedPostCommand(_T("\x03"));
acedPostCommand(_T("PL_MQSX\n"));
}
return Acad::eOk;
}
Acad::ErrorStatus AecDbXOpening::subIntersectWith( const AcDbEntity* pEnt,
AcDb::Intersect intType,
AcGePoint3dArray& points,
INT_PTR thisGsMarker,
INT_PTR otherGsMarker) const
{
assertReadEnabled();
AcDbEntity* pEntT = NULL;
const AcDbVoidPtrArray& ar2D = Get2DBuffer();
AcGePoint3dArray arPts1;
for (int i = 0;i < ar2D.length();i++)
{
pEntT = (AcDbEntity*)ar2D.at(i);
pEntT->intersectWith(pEnt,intType,points,thisGsMarker,otherGsMarker);
}
return Acad::eOk;
}
Acad::ErrorStatus AecDbXOpening::subIntersectWith( const AcDbEntity* pEnt,
AcDb::Intersect intType,
const AcGePlane& projPlane,
AcGePoint3dArray& points,
INT_PTR thisGsMarker,
INT_PTR otherGsMarker) const
{
assertReadEnabled();
AcDbEntity* pEntT = NULL;
const AcDbVoidPtrArray& ar2D = Get2DBuffer();
AcGePoint3dArray arPts1;
for (int i = 0;i < ar2D.length();i++)
{
pEntT = (AcDbEntity*)ar2D.at(i);
pEntT->intersectWith(pEnt,intType,projPlane,points,thisGsMarker,otherGsMarker);
}
return Acad::eOk;
}
AcGeScale3d AecDbXOpening::GetBlockToIdentity(const AcDbObjectId& idRec) const
{
assertReadEnabled();
AcDbBlockReference bRef;
bRef.setBlockTableRecord(idRec);
bRef.setPosition(AcGePoint3d::kOrigin);
bRef.setRotation(0.0);
bRef.setScaleFactors(AcGeScale3d(1,1,1));
AcDbExtents ext;
bRef.getGeomExtents(ext);
AcGeScale3d scale;
scale.sx = 1.0 / (ext.maxPoint().x - ext.minPoint().x);
scale.sy = 1.0 / (ext.maxPoint().y - ext.minPoint().y);
scale.sz = 1.0;
if ( (ext.maxPoint().z - ext.minPoint().z ) > 1.e-6)
{
scale.sz = 1.0 / (ext.maxPoint().z - ext.minPoint().z);
}
return scale;
}
bool AecDbXOpening::GetStandardDraw2d(AecComplexCurve& draw2d,bool bHasEnd/* = true*/) const
{
int nGroup = 0;
m_mapSpecXData.GetAt(KEY_FLAG,nGroup);
int nType = 0;
m_mapSpecXData.GetAt(KEY_TYPE,nType);
double dWidth = 0.0;
m_mapSpecXData.GetAt(KEY_Width,dWidth);
AcGeVector3d vtDir;
m_mapSpecXData.GetAt(PIPE_DIR,vtDir);
AcGePoint3d ptOn;
m_mapSpecXData.GetAt(KEY_PTON,ptOn);
double dThick = 0.0;
m_mapSpecXData.GetAt(KEY_THICK,dThick);
AecEqui::AecCurveElement el;
memset(&el,0,sizeof(AecEqui::AecCurveElement));
AcGeVector3d vtV = vtDir;
vtV.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
ptOn.z = 0.0;
vtDir.normalize();
AcGePoint3d ptGe[5];
ptGe[0] = ptOn;
ptGe[0] -= vtDir * 0.5 * dWidth;
ptGe[0] += vtV * 0.5 * dThick;
ptGe[1] = ptGe[0] + vtDir * dWidth;
ptGe[2] = ptGe[1] - vtV * dThick;
ptGe[3] = ptGe[2] - vtDir * dWidth;
ptGe[4] = ptGe[0];
if (bHasEnd)
{
el.ptGe[0] = ptGe[0];
el.ptGe[1] = ptGe[1];
el.ptGe[2] = ptGe[1];
el.gsMark = 1;
draw2d.append(el);
el.ptGe[0] = ptGe[3];
el.ptGe[1] = ptGe[2];
el.ptGe[2] = ptGe[2];
el.gsMark = 1;
draw2d.append(el);
if (nGroup == 1)// 是组合门窗
{
}
else
{
el.ptGe[0] = ptGe[3];
el.ptGe[1] = ptGe[0];
el.ptGe[2] = ptGe[0];
el.gsMark = 0;
draw2d.append(el);
el.ptGe[0] = ptGe[1];
el.ptGe[1] = ptGe[2];
el.ptGe[2] = ptGe[2];
el.gsMark = 0;
draw2d.append(el);
}
}
else
{
el.ptGe[0] = ptGe[0];
el.ptGe[1] = ptGe[1];
el.ptGe[2] = ptGe[1];
draw2d.append(el);
el.ptGe[0] = ptGe[3];
el.ptGe[1] = ptGe[2];
el.ptGe[2] = ptGe[2];
draw2d.append(el);
}
return true;
}
void AecDbXOpening::GetSideLines(AecComplexCurve& draw2d,const AcGeVector3d& vtDir) const
{
int nGroup = 0;
m_mapSpecXData.GetAt(KEY_FLAG,nGroup);
int nType = 0;
m_mapSpecXData.GetAt(KEY_TYPE,nType);
double dWidth = 0.0;
m_mapSpecXData.GetAt(KEY_Width,dWidth);
AcGePoint3d ptOn;
m_mapSpecXData.GetAt(KEY_PTON,ptOn);
double dThick = 0.0;
m_mapSpecXData.GetAt(KEY_THICK,dThick);
AecEqui::AecCurveElement el;
memset(&el,0,sizeof(AecEqui::AecCurveElement));
AcGeVector3d vtV = vtDir;
vtV.rotateBy(PI / 2.0,AcGeVector3d::kZAxis);
ptOn.z = 0.0;
AcGePoint3d ptGe[5];
ptGe[0] = ptOn;
ptGe[0] -= vtDir * 0.5 * dWidth;
ptGe[0] += vtV * 0.5 * dThick;
ptGe[1] = ptGe[0] + vtDir * dWidth;
ptGe[2] = ptGe[1] - vtV * dThick;
ptGe[3] = ptGe[2] - vtDir * dWidth;
ptGe[4] = ptGe[0];
el.ptGe[0] = ptGe[3];
el.ptGe[1] = ptGe[0];
el.ptGe[2] = ptGe[0];
el.gsMark = 0;
draw2d.append(el);
el.ptGe[0] = ptGe[1];
el.ptGe[1] = ptGe[2];
el.ptGe[2] = ptGe[2];
el.gsMark = 0;
draw2d.append(el);
}
int AecDbXOpening::GetDraw2dables(Adesk::UInt16 nDrawStyle, AcDbVoidPtrArray& arEntPtrs) const
{
assertReadEnabled();
OpeningData data;
GetOpeningData(data);
AcDbObjectId idBlk2d;
m_mapSpecXData.GetAt(KEY_BLK2DID,idBlk2d);
if (idBlk2d.isValid())
{
AcGeVector3d vtDir(1,0,0);
AcGePoint3d ptPos,ptOn;
ptPos = data.ptPos;
ptPos.z = 0.0;
WallData wData;
memset(&wData,0,sizeof(WallData));
AcDbObjectId idWall;
m_mapSpecXData.GetAt(KEY_IDCNT1,idWall);
if (idWall.isValid())
{
AcDbEntity* pEnt = NULL;
AecDbXWall* pWall = NULL;
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idWall,AcDb::kForRead))
{
pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
AcDbCurve* pNaCur = pWall->GetNativeCurve();
if ( pNaCur != NULL)
{
pNaCur->getClosestPointTo(ptPos,ptOn);
pNaCur->getFirstDeriv(ptOn,vtDir);
pWall->GetWallData(wData);
}
}
pEnt->close();
}
}
double dRot = AcGeVector3d::kXAxis.angleTo(vtDir,AcGeVector3d::kZAxis);
//acutPrintf(_T("\nrot = %g"),dRot);
//AcGeScale3d scale = GetBlockToIdentity(idBlk2d);
AcGeScale3d scl2d;
scl2d.set(data.dWidth,wData.dThick,1.0);
if (data.nType == kDoor)
{
scl2d.set(data.dWidth,data.dWidth,1.0);
}
else
{
scl2d.set(data.dWidth,wData.dThick,1.0);
}
//dc.DrawBlock(idBlk2d,ptPos,scl2d,dRot,FALSE);
AcDbBlockReference* pRef = new AcDbBlockReference;
pRef->setBlockTableRecord(idBlk2d);
pRef->setPosition(ptPos);
pRef->setScaleFactors(scl2d);
pRef->setRotation(dRot);
pRef->setLayer(layerId());
arEntPtrs.append(pRef);
AecComplexCurve win2d;
GetStandardDraw2d(win2d,true);
//测试
/*AcDbLine* pLn = NULL;
for (int i = 0;i < win2d.length();i++)
{
AecEqui::AecCurveElement& el = win2d.atByRef(i);
if ( AecComplexCurve::MakeLine(el,pLn) )
{
pLn->setColorIndex(3);
CKTCadUtility::AddToBlockTableRecord(pLn);
pLn->close();
}
}*/
AecComplexCurve win2dEnd;
for (int i = 0;i < win2d.length();i++)
{
AecEqui::AecCurveElement& el = win2d.atByRef(i);
if (el.gsMark == 0)
{
win2dEnd.append(el);
}
}
//设置为墙体的图层
AcDbObjectId idWallLay = KTSetting::InitLayer(_T("LAY_WALL"),true);
AecComplexCurveDraw win2dEndDraw;
win2dEndDraw.SetEdage(win2dEnd);
win2dEndDraw.explode(arEntPtrs,idWallLay,idWallLay,idWallLay);
CString sLable = GetLabel();
if (!sLable.IsEmpty() && sLable.CompareNoCase(_T("No")) != 0 )
{
AcDbObjectId id = acdbCurDwg()->textstyle();
AcDbText* pText = new AcDbText;
pText->setTextStyle(id);
pText->setLayer(layerId());
pText->setWidthFactor(0.75);
double dScale = 100.0;
GetDocScale(dScale);
pText->setHeight(2.5 * dScale);
pText->setTextString(GetLabel());
m_mapSpecXData.GetAt(KEY_NOPOS,ptOn);
pText->setPosition(ptOn);
pText->setHorizontalMode(AcDb::kTextCenter);
pText->setAlignmentPoint(ptOn);
arEntPtrs.append(pText);
}
}
return arEntPtrs.length();
}
AcDbObjectId AecDbXOpening::LoadOpeningBlk2d() const
{
assertReadEnabled();
AcDbObjectId idBlock2d;
CString sBlockName2d;
m_mapSpecXData.GetAt(KEY_BLK2D,sBlockName2d);
CString sBlockName3d;
m_mapSpecXData.GetAt(KEY_BLK3D,sBlockName3d);
OpeningData data;
memset(&data,0,sizeof(OpeningData));
m_mapSpecXData.GetAt(KEY_TYPE,data.nType);
CString sDbtxtFile = _T("DoorDb.txt");
if (data.nType == 1)//窗
{
sDbtxtFile = _T("WindowDb.txt");
}
CString sPath,sPath2,_sDwgFile;
KTSetting::GetKTPsPath(sPath);
sPath += _T("Support\\Cells\\");
sPath2 = sPath;
sPath += sDbtxtFile;
CString sDwgFile,sRecName,sRecName3D;
int nIndex = -1,nIndex2 = -1;
CStdioFile file;
if (file.Open(sPath,CFile::modeRead))
{
CString sText,sTmp;
while(file.ReadString(sText))
{
if (sText.FindOneOf(_T("//")) != -1)
{
continue;
}
nIndex = sText.Find(_T(';'));
if (nIndex != -1)
{
//WIN1.dwg;KTWIN01;KTWIN01_3D
sDwgFile = sText.Mid(0,nIndex);
sTmp = sText.Mid(nIndex + 1);
nIndex2 = sTmp.ReverseFind(_T(';'));
if (nIndex2 != -1)
{
sRecName = sTmp.Mid(0,nIndex2);
}
nIndex = sText.ReverseFind(_T(';'));
if (nIndex != -1)
{
sRecName3D = sText.Mid(nIndex+1);
}
if ( sRecName.CompareNoCase(sBlockName2d) == 0 &&
sRecName3D.CompareNoCase(sBlockName3d) == 0 )
{
_sDwgFile = sDwgFile;
break;
}
}
}
file.Close();
}
if (!_sDwgFile.IsEmpty())
{
sDwgFile = _T("");
KTSetting::GetKTPsPath(sDwgFile);
sDwgFile += _T("Support\\Cells\\");
sDwgFile += _sDwgFile;
AcDbDatabase* pDb = new AcDbDatabase(false);
ASSERT(pDB != NULL);
if (pDb->readDwgFile(sDwgFile, AcDbDatabase::kForReadAndAllShare) != Acad::eOk)
{
delete pDb;
return idBlock2d;
}
AcDbBlockTable* pBT = NULL;
pDb->getSymbolTable(pBT, AcDb::kForRead);
if (pBT == NULL)
{
delete pDb;
return idBlock2d;
}
AcDbObjectId idBlock;
pBT->getAt(sBlockName2d, idBlock);
pBT->close();
AcDbDatabase* pTempDb = NULL;
pDb->wblock(pTempDb, idBlock);
delete pDb;
if (pTempDb == NULL) return FALSE;
AcDbDatabase* pWorkDb = acdbHostApplicationServices()->workingDatabase();
if (pWorkDb->insert(idBlock2d, sBlockName2d, pTempDb) != Acad::eOk)
{
delete pTempDb;
return idBlock2d;
}
delete pTempDb;
}
return idBlock2d;
}
AcDbObjectId AecDbXOpening::LoadOpeningBlk3d() const
{
assertReadEnabled();
AcDbObjectId idBlock3d;
CString sBlockName2d;
m_mapSpecXData.GetAt(KEY_BLK2D,sBlockName2d);
CString sBlockName3d;
m_mapSpecXData.GetAt(KEY_BLK3D,sBlockName3d);
OpeningData data;
memset(&data,0,sizeof(OpeningData));
m_mapSpecXData.GetAt(KEY_TYPE,data.nType);
CString sDbtxtFile = _T("DoorDb.txt");
if (data.nType == 1)//窗
{
sDbtxtFile = _T("WindowDb.txt");
}
CString sPath,sPath2,_sDwgFile,_sDwg3DFile;
KTSetting::GetKTPsPath(sPath);
sPath += _T("Support\\Cells\\");
sPath2 = sPath;
sPath += sDbtxtFile;
CString sDwgFile,sRecName,sRecName3D;
int nIndex = -1,nIndex2 = -1;
CStdioFile file;
if (file.Open(sPath,CFile::modeRead))
{
CString sText,sTmp;
while(file.ReadString(sText))
{
if (sText.FindOneOf(_T("//")) != -1)
{
continue;
}
nIndex = sText.Find(_T(';'));
if (nIndex != -1)
{
//WIN1.dwg;KTWIN01;KTWIN01_3D
sDwgFile = sText.Mid(0,nIndex);
sTmp = sText.Mid(nIndex + 1);
nIndex2 = sTmp.ReverseFind(_T(';'));
if (nIndex2 != -1)
{
sRecName = sTmp.Mid(0,nIndex2);
}
nIndex = sText.ReverseFind(_T(';'));
if (nIndex != -1)
{
sRecName3D = sText.Mid(nIndex+1);
}
if ( sRecName.CompareNoCase(sBlockName2d) == 0 &&
sRecName3D.CompareNoCase(sBlockName3d) == 0 )
{
_sDwg3DFile = sDwgFile;
_sDwg3DFile.MakeLower();
_sDwg3DFile.TrimRight(_T(".dwg"));
_sDwg3DFile += _T("_3D.dwg");
break;
}
}
}
file.Close();
}
if (!_sDwg3DFile.IsEmpty())
{
sDwgFile = _T("");
KTSetting::GetKTPsPath(sDwgFile);
sDwgFile += _T("Support\\Cells\\");
sDwgFile += _sDwg3DFile;
AcDbDatabase* pDb = new AcDbDatabase(false);
ASSERT(pDB != NULL);
if (pDb->readDwgFile(sDwgFile, AcDbDatabase::kForReadAndAllShare) != Acad::eOk)
{
delete pDb;
return FALSE;
}
AcDbBlockTable* pBT = NULL;
pDb->getSymbolTable(pBT, AcDb::kForRead);
if (pBT == NULL)
{
delete pDb;
return idBlock3d;
}
AcDbObjectId idBlock;
pBT->getAt(sBlockName3d, idBlock);
pBT->close();
AcDbDatabase* pTempDb = NULL;
pDb->wblock(pTempDb, idBlock);
delete pDb;
if (pTempDb == NULL) return FALSE;
AcDbDatabase* pWorkDb = acdbHostApplicationServices()->workingDatabase();
if (pWorkDb->insert(idBlock3d, sBlockName3d, pTempDb) != Acad::eOk)
{
delete pTempDb;
return idBlock3d;
}
delete pTempDb;
}
return idBlock3d;
}
AcDbObjectId AecDbXOpening::LoadOpeningSectionDrawBlk2d() const
{
assertReadEnabled();
AcDbObjectId idBlock2d;
OpeningData data;
memset(&data, 0, sizeof(OpeningData));
m_mapSpecXData.GetAt(KEY_TYPE, data.nType);
//固定
CString sBlockName2d = _T("14$墙内推拉门");
if (data.nType == 1)//窗
{
sBlockName2d = _T("0$通用剖面门窗");
}
//先从当前db查
AcDbBlockTable *pBT = NULL;
AcDbDatabase *pDbCur = acdbCurDwg();
pDbCur->getSymbolTable(pBT, AcDb::kForRead);
if (pBT == NULL)
{
return idBlock2d;
}
if (Acad::eOk == pBT->getAt(sBlockName2d, idBlock2d))
{
pBT->close();
return idBlock2d;
}
else
{
pBT->close();
}
//加载
CString sDwgFile = _T("");
KTSetting::GetKTPsPath(sDwgFile);
sDwgFile += _T("Support\\Cells\\剖面门窗.dwg");
AcDbDatabase *pDb = new AcDbDatabase(false);
ASSERT(pDB != NULL);
if (pDb->readDwgFile(sDwgFile, AcDbDatabase::kForReadAndAllShare) != Acad::eOk)
{
delete pDb;
return idBlock2d;
}
pDb->getSymbolTable(pBT, AcDb::kForRead);
if (pBT == NULL)
{
delete pDb;
return idBlock2d;
}
AcDbObjectId idBlock;
pBT->getAt(sBlockName2d, idBlock);
pBT->close();
AcDbDatabase *pTempDb = NULL;
pDb->wblock(pTempDb, idBlock);
delete pDb;
if (pTempDb == NULL) return FALSE;
AcDbDatabase *pWorkDb = acdbHostApplicationServices()->workingDatabase();
if (pWorkDb->insert(idBlock2d, sBlockName2d, pTempDb) != Acad::eOk)
{
delete pTempDb;
return idBlock2d;
}
delete pTempDb;
return idBlock2d;
}
Acad::ErrorStatus AecDbXOpening::Draw2d(AcGiDraw &dc) const
{
assertReadEnabled();
AcDbObjectId idCurLay = dc.GetLayerId();
AcDbObjectId idCurLty = dc.GetLineTypeId();
Adesk::UInt16 nCrBk = colorIndex();
dc.SetLayer(layerId());
int nColor = nCrBk;
if ( m_mapSpecXData.GetAt(_T("COLOR"),nColor) )
{
dc.SetColor(nColor);
}
//二维缓存,未知出错!
if (Has2DBuffer())
{
Draw2DBuffers(dc);
//绘制编号
CString sLable = GetLabel();
sLable.TrimRight(_T(" "));
if (!sLable.IsEmpty() && sLable.CompareNoCase(_T("No")) != 0)
{
if (sLable.GetLength() < 36)//<IDCreate
DrawLabel(dc, sLable);
}
return Acad::eOk;
}
OpeningData data;
GetOpeningData(data);
AcDbObjectId idBlk2d;
m_mapSpecXData.GetAt(KEY_BLK2DID,idBlk2d);
if (!idBlk2d.isValid())
{
idBlk2d = LoadOpeningBlk2d();
}
if (idBlk2d.isValid())
{
AcGeVector3d vtDir(1,0,0);
AcGePoint3d ptPos,ptOn;
ptPos = data.ptPos;
ptPos.z = 0.0;
WallData wData;
memset(&wData,0,sizeof(WallData));
AcDbObjectId idWall;
m_mapSpecXData.GetAt(KEY_IDCNT1,idWall);
if (idWall.isValid())
{
AcDbEntity* pEnt = NULL;
AecDbXWall* pWall = NULL;
AcDbCurve* pNaCur = NULL;
AcDbLine* pNaLine = NULL;
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idWall,AcDb::kForRead))
{
pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
pWall->GetWallData(wData);
BOOL bIsVView = FALSE;
pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_VVIEW,bIsVView);
if (bIsVView)
{
//1.创建整体Solid
AcGePoint3d ptOnRegion;
pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_SECCEN,ptOnRegion);
AcDbCurve* pNaCur = pWall->GetNativeCurve();
AcGePoint3d ptSta,ptEnd;
pNaCur->getStartPoint(ptSta);
pNaCur->getEndPoint(ptEnd);
AcGeVector3d vtNormal(AcGeVector3d::kIdentity);
pNaCur->getFirstDeriv(ptSta, vtNormal);
AcDbRegion* pCloneRegion = pWall->GetSection();
transfromRegion(pCloneRegion, ptOnRegion, vtNormal, ptEnd);
AcDbLine* pLn1 = AecDbXWall::GetOrthoProjectOnXY(pCloneRegion);
if (pLn1 != NULL)
{
AcGePoint3d ptMid,ptMid2;
GetMidPoint(pNaCur,ptMid);
ptMid.z = 0.0;
pLn1->getClosestPointTo(ptMid,ptMid2);
AcGeVector3d vtM = ptMid - ptMid2;
AcGeMatrix3d xM;xM.setToTranslation(vtM);
pLn1->transformBy(vtM);
pNaLine = pLn1;
}
delete pCloneRegion;
}
pNaCur = pWall->GetNativeCurve();
if (pNaLine != NULL)
{
pNaLine->getClosestPointTo(ptPos,ptOn);
pNaLine->getFirstDeriv(ptOn,vtDir);
}
else
{
if ( pNaCur != NULL)
{
pNaCur->getClosestPointTo(ptPos,ptOn);
pNaCur->getFirstDeriv(ptOn,vtDir);
}
}
}
pEnt->close();
}
}
AcGeScale3d scl2d;
scl2d.set(data.dWidth,wData.dThick,1.0);
//开口方向
int nDir = 1;
m_mapSpecXData.GetAt(PIPE_TDIR,nDir);
if (abs(nDir) < 1) nDir = 1;
if (abs(nDir) > 1)
nDir = nDir / abs(nDir);
//左右方向
int nLDir = 1;
m_mapSpecXData.GetAt(PIPE_DRAWDIR, nLDir);
if (abs(nLDir) < 1) nLDir = 1;
if (abs(nLDir) > 1)
nLDir = nLDir / abs(nLDir);
double dRot = AcGeVector3d::kXAxis.angleTo(vtDir,AcGeVector3d::kZAxis);
//acutPrintf(_T("\nrot = %g"),dRot);
//AcGeScale3d scale = GetBlockToIdentity(idBlk2d);
if (data.nType == kDoor)
{
scl2d.set(data.dWidth * nLDir,data.dWidth * nDir,1.0);
dRot = AcGeVector3d::kXAxis.angleTo(vtDir, AcGeVector3d::kZAxis);
}
else
{
scl2d.set(data.dWidth,wData.dThick,1.0);
}
dc.DrawBlock(idBlk2d,ptPos,scl2d,dRot,FALSE);
//块引用分解到体
AcDbBlockReference* pRef = new AcDbBlockReference;
pRef->setBlockTableRecord(idBlk2d);
pRef->setPosition(ptPos);
pRef->setRotation(dRot);
pRef->setScaleFactors(scl2d);
pRef->setLayer(layerId());
if (data.nType == 1)
pRef->setColorIndex(4);
Add2DBuffer(pRef);
//门的裁剪墙线预先在插入门的时候;
AecComplexCurve win2d;
GetStandardDraw2d(win2d,true);
//测试
/*AcDbLine* pLn = NULL;
for (int i = 0;i < win2d.length();i++)
{
AecEqui::AecCurveElement& el = win2d.atByRef(i);
if ( AecComplexCurve::MakeLine(el,pLn) )
{
pLn->setColorIndex(3);
CKTCadUtility::AddToBlockTableRecord(pLn);
pLn->close();
}
}*/
AecComplexCurve win2dEnd;
for (int i = 0;i < win2d.length();i++)
{
AecEqui::AecCurveElement& el = win2d.atByRef(i);
if (el.gsMark == 0)
{
win2dEnd.append(el);
}
}
//设置为墙体的图层
AcDbObjectId idWallLay = KTSetting::InitLayer(_T("LAY_WALL"),true);
AecComplexCurveDraw win2dEndDraw;
win2dEndDraw.SetEdage(win2dEnd);
win2dEndDraw.Draw2d(dc,idWallLay,idWallLay,idWallLay);
AcDbVoidPtrArray arDraw2d;
win2dEndDraw.explode(arDraw2d, idWallLay, idWallLay, idWallLay);
Add2DBuffer(arDraw2d);
//绘制编号
CString sLable = GetLabel();
sLable.TrimRight(_T(" "));
if (!sLable.IsEmpty() && sLable.CompareNoCase(_T("No")) != 0 )
{
if ( sLable.GetLength() < 36)//<IDCreate
DrawLabel(dc,sLable);
}
dc.SetColor(nCrBk);
dc.SetLayer(idCurLay);
dc.SetLineType(idCurLty);
}
return Acad::eOk;
}
Acad::ErrorStatus AecDbXOpening::DrawLabel(AcGiDraw &dc,LPCTSTR pszLab) const
{
BOOL bHideNo = FALSE;
m_mapSpecXData.GetAt(KEY_HIDENO,bHideNo);
if (bHideNo)
return Acad::eOk;
AcDbObjectId id = acdbCurDwg()->textstyle();
AcDbText* pText = new AcDbText;
pText->setTextStyle(id);
pText->setLayer(layerId());
pText->setWidthFactor(0.75);
double dScale = 100.0;
GetDocScale(dScale);
pText->setHeight(2.5 * dScale);
pText->setTextString(pszLab);
AcGePoint3d ptOn;
m_mapSpecXData.GetAt(KEY_NOPOS,ptOn);
pText->setPosition(ptOn);
pText->setHorizontalMode(AcDb::kTextCenter);
pText->setAlignmentPoint(ptOn);
dc.DrawEntity(*pText);
delete pText;//?
return Acad::eOk;
}
AcDb3dSolid* FaceToSolid(AcDbFace* pFace, std::vector<AcDbX3dSolid*> *pSos = NULL)
{
AcDb3dSolid* pSolid = NULL;
if (pFace != NULL)
{
AcGePoint3d pt;
AcGePoint3dArray arPts;
AcDbVoidPtrArray arLnPtrs,arRegPtrs;
for (int i = 0;i < 4;i++)
{
if (Acad::eOk == pFace->getVertexAt(i,pt))
{
if (arPts.isEmpty())
{
arPts.append(pt);
}
else
{
if (pt.distanceTo(arPts.last()) > 1.e-3)
{
AcDbLine* pLn = new AcDbLine(pt,arPts.last());
arLnPtrs.append(pLn);
}
arPts.append(pt);
}
}
}
if (arPts.length() > 2)
{
AcDbLine* pLn = new AcDbLine(arPts.first(),arPts.last());
arLnPtrs.append(pLn);
}
double dthick(5.0);
AcDbRegion::createFromCurves(arLnPtrs,arRegPtrs);
FreeBuffer(0,arLnPtrs);
if (!arRegPtrs.isEmpty())
{
AcDbRegion* pReg = (AcDbRegion*)arRegPtrs.first();
if (pReg && pSos)
{
double d;
AcGePlane pln;
AcGePoint3d pt;
AcGeVector3d vt;
pReg->getNormal(vt);
CoreTools::getRegionInfo(pReg, pt, d, pln);
vt.normalize();
vt *= dthick;
AcDbX3dSolid *pSo = new AcDbX3dSolid();
pSo->CreateExtrude(pReg, AcDbLine(pt, pt + vt));
pSos->push_back(pSo);
}
AcDbSurface* pNewSurface = NULL;
AcDbSurface::createFrom(pReg,pNewSurface);
if (pNewSurface != NULL)
{
pNewSurface->thicken(dthick,false,pSolid);
DELETE_PTR(pNewSurface);
}
deleteArrayVoidPtrs< AcDbEntity>(arRegPtrs);
}
}
return pSolid;
}
void DeepFaceToSolid(AcDbBlockReference* pRef,AcDbVoidPtrArray& arGetSolidPtrs)
{
if (pRef == NULL)
return;
//提取face;
AcDbEntity* pEnt = NULL,*pSubEnt = NULL;
AcDbVoidPtrArray arFacePtrs;
pRef->explode(arFacePtrs);
//face to solid
AcDb3dSolid* pFaceSolid = NULL;
for (int ii = 0;ii < arFacePtrs.length();ii++)
{
pEnt = (AcDbEntity*)arFacePtrs.at(ii);
AcDbFace* pFace = AcDbFace::cast(pEnt);
if (pFace != NULL)
{
pFaceSolid = FaceToSolid(pFace);
if (pFaceSolid != NULL)
{
arGetSolidPtrs.append(pFaceSolid);
}
}
AcDbPolyFaceMesh* pPFM = AcDbPolyFaceMesh::cast(pEnt);
if (pPFM != NULL)
{
AcDbVoidPtrArray arSubFacePtrs;
pPFM->explode(arSubFacePtrs);
for(int jj = 0;jj < arSubFacePtrs.length();jj++)
{
pSubEnt = (AcDbEntity*)arSubFacePtrs.at(jj);
pFace = AcDbFace::cast(pSubEnt);
if (pFace != NULL)
{
pFaceSolid = FaceToSolid(pFace);
if (pFaceSolid != NULL)
{
arGetSolidPtrs.append(pFaceSolid);
}
}
delete pSubEnt;
}
}
AcDbBlockReference* pSubRef = AcDbBlockReference::cast(pEnt);
if (pSubRef != NULL)
{
DeepFaceToSolid(pSubRef,arGetSolidPtrs);
}
delete pEnt;
}
}
int AecDbXOpening::GetDraw3dables(AcDbVoidPtrArray& arEntPtrs,bool bWriteBimInfo/* = false */) const
{
OpeningData data;
GetOpeningData(data);
AcDbObjectId idBlk3d;
m_mapSpecXData.GetAt(KEY_BLK3DID,idBlk3d);
if (idBlk3d.isValid())
{
AcGeVector3d vtDir(1,0,0);
AcGePoint3d ptPos,ptOn;
ptPos = data.ptPos;
double dBomEl = data.dBomEl;
WallData wData;
memset(&wData,0,sizeof(WallData));
AcDbObjectId idWall;
m_mapSpecXData.GetAt(KEY_IDCNT1,idWall);
AcDbEntity* pEnt = NULL;
AecDbXWall* pWall = NULL;
if (idWall.isValid())
{
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idWall,AcDb::kForRead))
{
pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
AcDbCurve* pNaCur = pWall->GetNativeCurve();
if ( pNaCur != NULL)
{
pNaCur->getClosestPointTo(ptPos,ptOn);
pNaCur->getFirstDeriv(ptOn,vtDir);
pWall->GetWallData(wData);
ptOn.z = wData.dBomEl;
ptPos.z = ptOn.z + dBomEl;
}
}
pEnt->close();
}
}
AcGeScale3d scl3d;
scl3d.set(data.dWidth,wData.dThick,data.dHeight);
int nDir = 1;
m_mapSpecXData.GetAt(PIPE_TDIR,nDir);
if (abs(nDir) < 1) nDir = 1;
vtDir *= nDir;
double dRot = AcGeVector3d::kXAxis.angleTo(vtDir,AcGeVector3d::kZAxis);
AcGeScale3d scale = GetBlockToIdentity(idBlk3d);
scl3d.sx *= scale.sx;
scl3d.sy *= scale.sy;
scl3d.sz *= scale.sz;
AcDbBlockReference* pRef = new AcDbBlockReference;
pRef->setBlockTableRecord(idBlk3d);
pRef->setPosition(ptPos);
pRef->setRotation(dRot);
pRef->setScaleFactors(scl3d);
pRef->setLayer(layerId());
arEntPtrs.append(pRef);
}
return arEntPtrs.length();
}
Acad::ErrorStatus AecDbXOpening::Draw3d(AcGiDraw &dc) const
{
assertReadEnabled();
BOOL bHlrCalc(FALSE);
m_mapSpecXData.GetAt(HLR_CALC, bHlrCalc);
if (bHlrCalc)
{
// 如果 bHlrCalc 为真,说明PreprocessForHlr函数要求跳过draw3d函数
// 会在ProcessHlrResult函数设置回来
return Acad::eOk;
}
if ( dc.IsDragging() )
{
//return Acad::eOk;
}
//图层
AcDbObjectId idLay = dc.GetLayerId();
dc.SetLayer(layerId());
int nCrBk = dc.GetColor();
int nColor = nCrBk;
if ( m_mapSpecXData.GetAt(_T("COLOR"),nColor) )
{
dc.SetColor(nColor);
}
if (IsActive())
{
nColor = kMagenta;
m_mapSpecXData.GetAt(KEY_ACTIVECR,nColor);
dc.SetColor(nColor);
}
if (Has3DBuffer())
{
AcDbEntity* pEnt = NULL;
const AcDbVoidPtrArray &ar3D = Get3DBuffer();
for (int i = 0;i < ar3D.length();i++)
{
pEnt = (AcDbEntity*)ar3D.at(i);
if ( IsActive() )
{
BackupColorIndex(pEnt);
pEnt->setColorIndex(nColor);
}
else
{
SetBackupColorIndex(pEnt);
}
dc.DrawEntity(*pEnt);
}
dc.SetLayer(idLay);
dc.SetColor(nCrBk);
return Acad::eOk;
}
OpeningData data;
GetOpeningData(data);
AcDbObjectId idBlk3d;
m_mapSpecXData.GetAt(KEY_BLK3DID,idBlk3d);
if (!idBlk3d.isValid())
{
idBlk3d = LoadOpeningBlk3d();
}
if (idBlk3d.isValid())
{
AcGeVector3d vtDir(1,0,0);
AcGePoint3d ptPos,ptOn;
ptPos = data.ptPos;
double dBomEl = data.dBomEl;
WallData wData;
memset(&wData,0,sizeof(WallData));
AcDbObjectId idWall;
m_mapSpecXData.GetAt(KEY_IDCNT1,idWall);
AcDbEntity* pEnt = NULL;
AcDbEntity* pSubEnt = NULL;
AecDbXWall* pWall = NULL;
if (idWall.isValid())
{
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idWall,AcDb::kForRead))
{
pWall = AecDbXWall::cast(pEnt);
if (pWall != NULL)
{
AcDbLine* pNaLine = NULL;
BOOL bIsVView = FALSE;
pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_VVIEW,bIsVView);
if (bIsVView)
{
//1.创建整体Solid
AcGePoint3d ptOnRegion;
pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_SECCEN,ptOnRegion);
AcDbCurve* pNaCur = pWall->GetNativeCurve();
AcGePoint3d ptSta,ptEnd;
pNaCur->getStartPoint(ptSta);
pNaCur->getEndPoint(ptEnd);
AcGeVector3d vtNormal(AcGeVector3d::kIdentity);
pNaCur->getFirstDeriv(ptSta, vtNormal);
AcDbRegion* pCloneRegion = pWall->GetSection();
transfromRegion(pCloneRegion, ptOnRegion, vtNormal, ptEnd);
AcDbLine* pLn1 = AecDbXWall::GetOrthoProjectOnXY(pCloneRegion);
if (pLn1 != NULL)
{
AcGePoint3d ptMid,ptMid2;
GetMidPoint(pNaCur,ptMid);
ptMid.z = 0.0;
pLn1->getClosestPointTo(ptMid,ptMid2);
AcGeVector3d vtM = ptMid - ptMid2;
AcGeMatrix3d xM;xM.setToTranslation(vtM);
pLn1->transformBy(vtM);
pNaLine = pLn1;
}
delete pCloneRegion;
}
AcDbCurve* pNaCur = pWall->GetNativeCurve();
if (pNaLine != NULL)
{
pNaLine->getClosestPointTo(ptPos,ptOn);
pNaLine->getFirstDeriv(ptOn,vtDir);
pWall->GetWallData(wData);
ptOn.z = wData.dBomEl;
ptPos.z = ptOn.z + dBomEl;
}
else
{
if ( pNaCur != NULL)
{
pNaCur->getClosestPointTo(ptPos,ptOn);
pNaCur->getFirstDeriv(ptOn,vtDir);
pWall->GetWallData(wData);
ptOn.z = wData.dBomEl;
ptPos.z = ptOn.z + dBomEl;
}
}
}
pEnt->close();
}
}
AcGeScale3d scl3d;
scl3d.set(data.dWidth,wData.dThick,data.dHeight);
int nDir = 1;
m_mapSpecXData.GetAt(PIPE_TDIR,nDir);
if (abs(nDir) < 1) nDir = 1;
vtDir *= nDir;
double dRot = AcGeVector3d::kXAxis.angleTo(vtDir,AcGeVector3d::kZAxis);
AcGeScale3d scale = GetBlockToIdentity(idBlk3d);
scl3d.sx *= scale.sx;
scl3d.sy *= scale.sy;
scl3d.sz *= scale.sz;
//绘制
dc.DrawBlock(idBlk3d,ptPos,scl3d,dRot,FALSE);
//块引用分解到体
AcDbBlockReference* pRef = new AcDbBlockReference;
pRef->setTransparency(transparency());
pRef->setBlockTableRecord(idBlk3d);
pRef->setPosition(ptPos);
pRef->setRotation(dRot);
pRef->setScaleFactors(scl3d);
pRef->setLayer(layerId());
if (data.nType == 1)
pRef->setColorIndex(4);
pRef->setTransparency(transparency());
Add3DBuffer(pRef);
}
return Acad::eOk;
}
Acad::ErrorStatus AecDbXOpening::dwgInFields(AcDbDwgFiler* pFiler)
{
AssertWriteEnabled();
//----- Read parent class information first.
Acad::ErrorStatus es = Acad::eOk;
if ( !pFiler->isKindOf(CMFCDbDwgFiler::desc()))
{
es = AecDbEntityBase::dwgInFields (pFiler) ;
if ( es != Acad::eOk )
return (es) ;
}
//----- Object version number needs to be read first
Adesk::UInt32 version =0 ;
if ( (es = pFiler->readUInt32 (&version)) != Acad::eOk )
return (es) ;
if ( version > AecDbXOpening::kCurrentVersionNumber )
return (Acad::eMakeMeProxy) ;
//2D
m_mapSpecXData.dwgInFields(pFiler);
return (pFiler->filerStatus ());
}
Acad::ErrorStatus AecDbXOpening::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
//----- Save parent class information first.
Acad::ErrorStatus es = Acad::eOk;
if ( !pFiler->isKindOf(CMFCDbDwgFiler::desc()))
{
es = AecDbEntityBase::dwgOutFields (pFiler) ;
if ( es != Acad::eOk )
return (es) ;
}
//----- Object version number needs to be saved first
if ( (es =pFiler->writeUInt32 (AecDbXOpening::kCurrentVersionNumber)) != Acad::eOk )
return (es) ;
//2D
m_mapSpecXData.dwgOutFields(pFiler);
return (pFiler->filerStatus ());
}
Acad::ErrorStatus AecDbXOpening::dxfInFields(AcDbDxfFiler* pFiler)
{
return Acad::eOk;
}
Acad::ErrorStatus AecDbXOpening::dxfOutFields(AcDbDxfFiler* pFiler) const
{
return Acad::eOk;
}
Acad::ErrorStatus AecDbXOpening::subErase(Adesk::Boolean erasing)
{
if (erasing)
{
PreRefreshWallDraw();//修复墙体
}
else
{
RefreshWallDraw();//
}
return AcDbEntity::subErase(erasing);
}
AecDbObjXDataMap* AecDbXOpening::GetSpecialtyData(AcDb::OpenMode bMode/* = AcDb::kForWrite*/)
{
switch(bMode)
{
case AcDb::kForRead:
{
assertReadEnabled();
break;
}
case AcDb::kForWrite:
{
if (!isWriteEnabled())
{
upgradeOpen();
}
assertWriteEnabled();
break;
}
case AcDb::kForNotify:
{
assertReadEnabled();
}
default:
break;
}
return &m_mapSpecXData;
}
const AecDbObjXDataMap* AecDbXOpening::GetSpecialtyData() const
{
assertReadEnabled();
return &m_mapSpecXData;
}
//剖切符合draw2d符号
bool AecDbXOpening::SectionAsDraw2d(AcGePlane& plan,AcDbVoidPtrArray &arRegionPtrs) const
{
AcGeVector3d vtZ = plan.normal();
AcDbEntity *pEnt2d = NULL, *pEnt3d = NULL;
const AcDbVoidPtrArray &arDraw2d = Get2DBuffer();
for (int i = 0; i < arDraw2d.length(); i++)
{
pEnt2d = (AcDbEntity *)arDraw2d.at(i);
AcDbBlockReference *pRef2d = AcDbBlockReference::cast(pEnt2d);
if (pRef2d != NULL)
{
double dRot = pRef2d->rotation();
AcGeVector3d vtDir = AcGeVector3d::kXAxis;
vtDir.rotateBy(dRot, AcGeVector3d::kZAxis);
if (vtDir.isParallelTo(vtZ))
{
AecDbXOpening *pFit = (AecDbXOpening *)clone();
if (pFit != NULL)
{
AcGiViewDraw dc(NULL, NULL);
pFit->Draw3d(dc);
AcDbVoidPtrArray arDraw3d;
pFit->GetDraw3dables(arDraw3d, false);
//剖切符号,然后获取3D的位置信息
for (int j = 0; j < arDraw3d.length(); j++)
{
pEnt3d = (AcDbEntity *)arDraw3d.at(j);
AcDbBlockReference *pRef3d = AcDbBlockReference::cast(pEnt3d);
if (pRef3d != NULL)
{
//scl3d.set(data.dWidth, wData.dThick, data.dHeight);
AcGeScale3d scl3d = pRef3d->scaleFactors();
AcGePoint3d ptPos = pRef3d->position();
AcGeScale3d scale = GetBlockToIdentity(pRef3d->blockTableRecord());
scl3d.sx /= scale.sx;
scl3d.sy /= scale.sy;
scl3d.sz /= scale.sz;
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
xform.invert();
ptPos.transformBy(xform);
ptPos.z = 0.0;
//根据 剖面门窗.dwg 库 特殊符号的调整位置
ptPos.x -= scl3d.sy * 0.5;
//vtDir.transformBy(xform);
AcDbObjectId idOpening = LoadOpeningSectionDrawBlk2d();
if (!idOpening.isValid())
{
delete pFit;
return false;
}
scale = GetBlockToIdentity(idOpening);
AcDbBlockReference *pRefNew = new AcDbBlockReference;
pRefNew->setBlockTableRecord(idOpening);
pRefNew->setLayer(pRef2d->layerId());
pRefNew->setPosition(ptPos);
//剖切门窗总是Y方向放置,所以 scl3d.sy,scl3d.sz
AcGeScale3d scale2d;
scale2d.set(scl3d.sy,scl3d.sz,1.0);
int nType = 0;
m_mapSpecXData.GetAt(KEY_TYPE, nType);
scale2d.sx *= scale.sx;
scale2d.sy *= scale.sy;
pRefNew->setScaleFactors(scale2d);
//dRot = AcGeVector3d::kXAxis.angleTo(vtDir, AcGeVector3d::kZAxis);
//根据 剖面门窗.dwg 库 dRot = 0.0
dRot = 0.0;//特殊符号原始角度
pRefNew->setRotation(dRot);
arRegionPtrs.append(pRefNew);
delete pFit;
return true;
}
}
delete pFit;
}
break;
}
if (vtDir.isPerpendicularTo(vtZ))
{
//且剖切面平行 XY 面 取原来符号
if ( vtZ.isParallelTo(AcGeVector3d::kZAxis) )
{
AecDbXOpening *pFit = (AecDbXOpening *)clone();
if (pFit != NULL)
{
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
xform.invert();
pFit->transformBy(xform);
AcGiViewDraw dc(NULL, NULL);
pFit->Draw2d(dc);
arRegionPtrs.append(pFit->Get2DBuffer());
delete pFit;
return true;
}
}
}
}
}
return false;
}
int AecDbXOpening::GetSectionDraw(const AcGePoint3d& ptFr,const AcGePoint3d& ptTo,const AcGeVector3d& vtViewDir,const AcGeVector3d& vtTo, AcDbVoidPtrArray& arRegionPtrs) const
{
assertReadEnabled();
AcDbObjectId idLayer = layerId();
AcGeVector3d vtLn = ptTo - ptFr;
AcGeVector3d vtNorm = vtLn.crossProduct(vtViewDir);
AcGePlane plan;
plan.set(ptFr,vtNorm);
AcGeMatrix3d xform;
xform.setToPlaneToWorld(plan);
xform.invert();
//如果是符合剖切符号
if (SectionAsDraw2d(plan,arRegionPtrs) )
{
return arRegionPtrs.length();
}
AecDbXOpening* pFit = (AecDbXOpening*)clone();
if (pFit != NULL)
{
AcGiViewDraw dc(NULL, NULL);
pFit->Draw3d(dc);
AcDbVoidPtrArray arSubPtrs;
pFit->GetDraw3dables(arSubPtrs,false);
AcDbEntity* pSubEnt = NULL;
if (arSubPtrs.length() >= 1)
{
pSubEnt = (AcDbEntity*)arSubPtrs.first();//就一个
if (pSubEnt != NULL)
{
AcDbVoidPtrArray arEntPtrs;
OrthoProjectedEntity(pSubEnt, plan, xform, arEntPtrs);
CString sName, sNameUq;
m_mapSpecXData.GetAt(KEY_BLK2D, sName);
MakeBlockRefSet(arEntPtrs, layerId(), Adesk::kTrue,sName);
arRegionPtrs.append(arEntPtrs);
}
}
delete pFit;
}
return arRegionPtrs.length();
}
namespace
{
AcDbPolyFaceMesh* DBRegion2PolyFace(AcDbRegion *pReg)
{
if (!pReg) return NULL;
AcDbFaceterSettings faceter = { .0, .0, krAutomatic, .0, false, false };
AcGePoint3dArray vertexArray;
AcArray<Adesk::Int32> faceArray;
AcGiFaceData *faceData(NULL);
if (acdbGetObjectMesh(pReg, &faceter, vertexArray, faceArray, faceData) == Acad::eOk)
{
if (faceData)
{
delete[] faceData->trueColors();
delete[] faceData->materials();
delete faceData;
}
AcDbPolyFaceMesh *pMesh = new AcDbPolyFaceMesh();
int idx1, idx2, idx3, idx0;
for (int i(0); i < vertexArray.length(); ++i)
pMesh->appendVertex(new AcDbPolyFaceMeshVertex(vertexArray[i]));
for (int i(0); i < faceArray.length();)
{
if (faceArray[i] == 3)
{
idx0 = faceArray[i + 1] +1;
idx1 = faceArray[i + 2] +1;
idx2 = faceArray[i + 3] +1;
idx3 = 0;
}
else if (faceArray[i] == 4)
{
idx0 = faceArray[i + 1] +1;
idx1 = faceArray[i + 2] +1;
idx2 = faceArray[i + 3] +1;
idx3 = faceArray[i + 4] +1;
}
pMesh->appendFaceRecord(new AcDbFaceRecord(idx0, idx1, idx2, idx3));
i += faceArray[i] + 1;
}
return pMesh;
}
return NULL;
}
AcDbPolyFaceMesh* DbFace2PolyFace(AcDbFace *pFace)
{
if (!pFace) return NULL;
AcGePoint3d pt0, pt1, pt2, pt3;
pFace->getVertexAt(0, pt0);
pFace->getVertexAt(1, pt1);
pFace->getVertexAt(2, pt2);
pFace->getVertexAt(3, pt3);
AcDbPolyFaceMesh *pMesh = new AcDbPolyFaceMesh();
pMesh->appendVertex(new AcDbPolyFaceMeshVertex(pt0));
pMesh->appendVertex(new AcDbPolyFaceMeshVertex(pt1));
pMesh->appendVertex(new AcDbPolyFaceMeshVertex(pt2));
pMesh->appendVertex(new AcDbPolyFaceMeshVertex(pt3));
if (pt2.distanceTo(pt3) < 1e-6) // 三点
{
pMesh->appendFaceRecord(new AcDbFaceRecord(1, 2, 3, 0));
}
else // 四点
{
pMesh->appendFaceRecord(new AcDbFaceRecord(1, 2, 3, 4));
}
return pMesh;
}
void ExplodeEnt2Face(AcDbEntity *p3DEnt, AcDbVoidPtrArray &arCurPtrs)
{
AcDbVoidPtrArray arEntPtrs;
if (!p3DEnt) return;
if (AcDbFace::cast(p3DEnt))
{
arCurPtrs.append((AcDbFace*)p3DEnt->clone());
return;
}
p3DEnt->explode(arEntPtrs);
for (int k = 0; k < arEntPtrs.length(); k++)
{
AcDbEntity *pEnt = (AcDbEntity *)((AcDbEntity *)arEntPtrs.at(k))->clone();
AcDbFace *pFace = AcDbFace::cast(pEnt);
if (pFace != NULL)
{
arCurPtrs.append(pFace);
}
else
{
ExplodeEnt2Face(pEnt, arCurPtrs);
DELETE_PTR(pEnt);
}
}
deleteArrayVoidPtrs< AcDbEntity>(arEntPtrs);
}
void _explode(AcDbBlockReference *pRef
, AcDbVoidPtrArray &arPtrs
, const AcGeMatrix3d &matParent)
{
OPENOBJ_BEGIN(pRef->blockTableRecord(), AcDb::kForRead, AcDbBlockTableRecord, pRec)
if (pRec)
{
AcString name;
pRec->getName(name);
if (false)
{
pRef->transformBy(matParent);
CoreTools::CloneAndAddToModelSpace(pRef);
return;
}
AcDbBlockTableRecordIterator *pIter(NULL);
if (Acad::eOk == pRec->newIterator(pIter))
{
AcDbEntity *pEnt(NULL);
for (pIter->start(); !pIter->done(); pIter->step())
{
pIter->getEntity(pEnt, AcDb::kForRead);
if (!pEnt) continue;
AcDbBlockReference *p = AcDbBlockReference::cast(pEnt);
if (p)
{
_explode(p, arPtrs, pRef->blockTransform() * matParent);
}
else
{
AcDbEntity *pClone = (AcDbEntity *)pEnt->clone();
if (pClone->transformBy(pRef->blockTransform() * matParent) != Acad::eOk)
{ // 处理一下不支持非均匀缩放的实体
AcDbPolyFaceMesh *pMesh(NULL);
AcDbRegion *pReg = AcDbRegion::cast(pClone);
if (pReg)
pMesh = DBRegion2PolyFace(pReg);
AcDbFace *pFace = AcDbFace::cast(pClone);
if (pFace)
pMesh = DbFace2PolyFace(pFace);
if (pMesh)
{
pMesh->transformBy(pRef->blockTransform() * matParent);
arPtrs.append(pMesh);
}
}
else
arPtrs.append(pClone);
}
pEnt->close();
}
DELETE_PTR(pIter);
pIter = NULL;
}
}
OPENOBJ_END()
}
}
SHJson::WValue & AecDbXOpening::ToJson(bool bExprotGeo) const
{
using namespace SHJson;
WValue &v = AecDbEntityBase::ToJson(bExprotGeo);
if (bExprotGeo)
{
if (!Has3DBuffer())
{
AcGiViewDraw dc;
Draw3d(dc);
}
AcDbVoidPtrArray arptrs = Get3DBuffer(), ents, faces;
for (int i(0); i < arptrs.length(); ++i)
{
ents.removeAll();
AcDbEntity *pEnt = (AcDbEntity *)arptrs[i];
AcDbBlockReference *pRef = AcDbBlockReference::cast(pEnt);
if (!pRef) continue;
pRef = (AcDbBlockReference *)pRef->clone();
pRef->setPosition(AcGePoint3d::kOrigin);
pRef->setRotation(.0);
_explode(pRef, ents, AcGeMatrix3d::kIdentity);
for (int i(0); i < ents.length(); ++i)
ExplodeEnt2Face((AcDbEntity*)ents[i], faces);
deleteArrayVoidPtrs< AcDbEntity>(ents);
DELETE_PTR(pRef);
}
GEO2JSON::tessellations tess;
for (int i(0); i < faces.length(); ++i)
{
AcDbFace *pFace((AcDbFace *)faces[i]);
if (!pFace) continue;
GEO2JSON::tools::fromFace(tess, pFace);
}
deleteArrayVoidPtrs< AcDbEntity>(faces);
WValue ar;
ar.SetArray();
for (size_t i(0); i < tess.size(); ++i)
{
WValue &x = tess[i].ToJson();
pushBack(ar, x);
}
addMember(v, _T("__tessellations__"), ar);
}
OpeningData data;
::memset(&data, 0, sizeof(OpeningData));
GetOpeningData(data);
/*int nType; //窗:2 门 1
int nFlag; //特殊标记
double dWidth; //门窗宽度
double dHeight; //门窗高度
double dBomEl; //相对墙体底部标高
AcGePoint3d ptPos; //位置,Z是真实标高
TCHAR szBlockName2d[MAX_PATH];//本地文件名2d
TCHAR szBlockName3d[MAX_PATH];//本地文件名3d
TCHAR szName[MAX_PATH]; //名称
TCHAR szSpec[MAX_PATH]; //附属信息
TCHAR szNo[65];//编号
TCHAR szFactory[MAX_PATH];//厂家*/
WValue open;
addMember(open, _T("__nType__"), data.nType);
addMember(open, _T("__nFlag__"), data.nFlag);
addMember(open, _T("__dWidth__"), data.dWidth);
addMember(open, _T("__dHeight__"), data.dHeight);
addMember(open, _T("__dBomEl__"), data.dBomEl);
addMember(open, _T("__ptPos__"), GEO2JSON::point(data.ptPos).ToJson());
addMember(open, _T("__szBlockName2d__"), data.szBlockName2d);
addMember(open, _T("__szBlockName3d__"), data.szBlockName3d);
addMember(open, _T("__szName__"), data.szName);
addMember(open, _T("__szSpec__"), data.szSpec);
addMember(open, _T("__szNo__"), data.szNo);
addMember(open, _T("__szFactory__"), data.szFactory);
addMember(v, _T("_open_data_"), open);
return v;
}
bool AecDbXOpening::ByJson(const SHJson::WValue & v)
{
return AecDbEntityBase::ByJson(v);
}
#include "HlrCutOption.h"
void AecDbXOpening::ProcessHlrResult(const AcArray<AcDbEntity *> &ar
, const std::map<AcDbEntity *, AcArray<AcDbEntity *>> &preAr
, AcArray<AcDbEntity *> &output) const
{
const AecDbObjXDataMap *pMap(&m_mapSpecXData);
BOOL b3D(0);
const_cast<AecDbObjXDataMap *>(pMap)->GetAt(HLR_CALC, b3D);
const_cast<AecDbObjXDataMap *>(pMap)->SetAt(HLR_CALC, FALSE);
// 如果b3D==1981,说明是垂直剖切的结果
// 否则是水平剖切的结果
bool bHoriz(b3D != 1981);
if (ar.isEmpty() && preAr.empty()) return;
// preAr 内部可能是两种数据
// 1. 水平剖切的数据
// 2. 垂直剖切(3d下的 blockrefence)
AcArray<AcDbEntity *> _ar(ar);
std::map<AcDbEntity *, AcArray<AcDbEntity *>> _preAr(preAr);
bool bFullMask(true);
if (!preAr.empty() && HlrCutOption::getHlrSTYLE2D_OPEN())
{
_ar.removeAll();
// 把 preAr 中的 region 生成的结果挑出来,不显示
std::map<AcDbEntity *, AcArray<AcDbEntity *>>::iterator it(_preAr.begin());
for (; it != _preAr.end(); ++it)
{
if (AcDbRegion::cast(it->first))
{
_preAr.erase(it);
bFullMask = false;
}
}
}
// 如果是水平剖切,并且没有region,说明实体完全被遮挡
if (bHoriz && bFullMask) return;
HlrCutOption::ProcessHlrResult(this
, FALSE
, .0
, HlrCutOption::getHlrBLK_OPEN()
, _ar
, _preAr
, output);
}
// AecDbXOpening 类的 水平、垂直剖切,都走PreprocessForHlr()函数
void AecDbXOpening::PreprocessForHlr(const AcGePoint3d &ptPlnO
, const AcGeVector3d &vtPlnN
, AcArray<AcDbEntity *> &ar) const
{
// 不是水平剖切时,需要特殊处理3d,hlr引擎不能看到门窗类里面的blockrefrence
// 所以在这里把 blockrefrence 提取出来
if (!vtPlnN.isParallelTo(AcGeVector3d::kZAxis))
{ // 门窗需要特殊处理,门窗的draw3d 内部绘制的是 blockrefrence,
if (!Has3DBuffer())
{
AcGiViewDraw dc;
Draw3d(dc);
}
const AcDbVoidPtrArray ar3ds(Get3DBuffer());
if (ar3ds.isEmpty()) return;
for (int i(0); i < ar3ds.length(); ++i)
ar.append((AcDbEntity *)((AcDbEntity *)ar3ds[i])->clone());
const AecDbObjXDataMap *pMap(&m_mapSpecXData);
const_cast<AecDbObjXDataMap *>(pMap)->SetAt(HLR_CALC, 1981);
return;
}
// 剩下的情况就是时水平剖切
if (!HlrCutOption::getHlrSTYLE2D_VALVE()) return;
const AcDbVoidPtrArray ar2ds = Get2DBuffer();
if (ar2ds.isEmpty()) return;
OpeningData data;
::memset(&data, 0, sizeof(OpeningData));
GetOpeningData(data);
AcDbObjectId idWall;
idWall.setFromOldId(data.idWall);
AcDbObjectPointer<AecDbXWall> wall(idWall, AcDb::kForRead);
WALLDATA wd;
::memset(&wd, 0, sizeof(WALLDATA));
wall->GetWallData(wd);
double dMax(.0), dMin(.0);
if (wall.openStatus() != Acad::eOk) return;
if (data.nType == 2) // 门
{
dMax = wd.dBomEl + data.dHeight;
dMin = wd.dBomEl;
}
if (data.nType == 1) // 窗
{
dMax = wd.dBomEl + data.dBomEl + data.dHeight;
dMin = wd.dBomEl + data.dBomEl;
}
if (!HlrCutOption::isWithinHorizSection(dMax, dMin, ptPlnO, vtPlnN)) return;
double dElev(dMax);
if (ptPlnO.z < dMax)
dElev = ptPlnO.z;
AcGeMatrix3d mat;
mat.setTranslation(AcGeVector3d::kZAxis * (dElev - data.ptPos.z));
AcGeVector3d vtDir(wall->EndPoint() - wall->StartPoint());
AcGeVector3d vtX(vtDir);
vtX.normalize();
AcGeVector3d vtY(vtX);
vtY.rotateBy(PI * .5, AcGeVector3d::kZAxis);
vtY.normalize();
vtX *= data.dWidth * .5;
vtY *= data.dThick * .5;
AcGePoint3d pt0(data.ptPos); pt0 += vtX; pt0 += vtY;
AcGePoint3d pt1(data.ptPos); pt1 += vtX; pt1 -= vtY;
AcGePoint3d pt2(data.ptPos); pt2 -= vtX; pt2 -= vtY;
AcGePoint3d pt3(data.ptPos); pt3 -= vtX; pt3 += vtY;
AcDbVoidPtrArray arLines;
arLines.append(new AcDbLine(pt0, pt1));
arLines.append(new AcDbLine(pt1, pt2));
arLines.append(new AcDbLine(pt2, pt3));
arLines.append(new AcDbLine(pt3, pt0));
AcDbRegion *pReg = CoreTools::createRegion(arLines);
deleteArrayVoidPtrs<AcDbEntity>(arLines);
if (pReg)
{
pReg->transformBy(mat);
ar.append(pReg);
}
for (int i(0); i < ar2ds.length(); ++i)
{
AcDbEntity *pEnt((AcDbEntity *)((AcDbEntity *)ar2ds[i])->clone());
pEnt->transformBy(mat);
ar.append(pEnt);
}
const AecDbObjXDataMap *pMap(&m_mapSpecXData);
const_cast<AecDbObjXDataMap *>(pMap)->SetAt(HLR_CALC, TRUE);
}
namespace
{
typedef std::map<CString, CString> RECMAP;
// std::map<CString, CString>
// 2dRecName-3dRecDWgName
void get2dRecList(const bool &bWin, RECMAP &recMapping)
{
CString sPath, sRoot;
KTSetting::GetKTPsPath(sPath);
sRoot = sPath + _T("Support\\Cells");
if (bWin)
sPath = sRoot + _T("\\WindowDb.txt");
else
sPath = sRoot + _T("\\DoorDb.txt");
int nIndex = -1;
CStdioFile file;
if (file.Open(sPath, CFile::modeRead | CFile::typeText))
{
CString sText
, s2DRecDwgName, s3DRecDwgPath
, s2DRecName, s3DRecName
, s2DRecDwgPath;
while (file.ReadString(sText))
{
if (sText.FindOneOf(_T("//")) != -1)
{
continue;
}
nIndex = sText.Find(_T(';'));
if (nIndex != -1)
{
CStringArray arFields;
CoreTools::SplitStrintToArray(sText, arFields, _T(';'));
if (arFields.GetSize() >= 3)
{
s2DRecDwgName = arFields.GetAt(0);
s2DRecName = arFields.GetAt(1);
s2DRecDwgPath = sRoot + _T("\\") + s2DRecDwgName;
s3DRecName = arFields.GetAt(2);
if (arFields.GetCount() > 3)
s3DRecDwgPath = sRoot + _T("\\") + arFields.GetAt(3);
else
s3DRecDwgPath = sRoot + _T("\\") + s3DRecName + _T(".dwg");
recMapping.insert(std::make_pair(s2DRecName, s3DRecDwgPath));
}
}
}
file.Close();
}
}
void get3dRecList(const bool &bWin, std::vector<CString> &list, LPCTSTR pszPath)
{
AcDbDatabase *pDb(new AcDbDatabase(false));
Acad::ErrorStatus es;
if (Acad::eOk != (es = pDb->readDwgFile(pszPath)))
{
delete pDb;
pDb = NULL;
return;
}
if (pDb != NULL)
{
std::vector<CString> vec;
CoreTools::enumBlockByDWG(pDb, vec);
CString sName;
for (size_t i(0); i < vec.size(); ++i)
{
sName = vec[i];
if (sName.CompareNoCase(_T("*Model_Space")) == 0 ||
sName.CompareNoCase(_T("*Paper_Space")) == 0 ||
sName.CompareNoCase(_T("_ArchTick")) == 0)
{
}
else
{
list.push_back(sName);
}
}
}
}
}
bool AecDbXOpening::GetProperties(SimpleProperty::PropertySetByIndex &properties) const
{
assertReadEnabled();
AecDbEntityBase::GetProperties(properties);
CoreTools::setLayerPorperty(properties);
CoreTools::setSubSystemPorperty(properties);
OpeningData data;
memset(&data, 0, sizeof(OpeningData));
GetOpeningData(data);
if (data.nType == 1)//窗
{
SimpleProperty::makeAndInsert(properties, _T("类型"), _T("窗"), false);
SimpleProperty::makeAndInsert(properties, _T("窗高"), data.dHeight, true);
SimpleProperty::makeAndInsert(properties, _T("窗宽"), data.dWidth, true);
SimpleProperty::makeAndInsert(properties, _T("窗台高"), data.dBomEl, true);
}
else if (data.nType == 2) // 门
{
SimpleProperty::makeAndInsert(properties, _T("类型"), _T("门"), false);
SimpleProperty::makeAndInsert(properties, _T("门高"), data.dHeight, true);
SimpleProperty::makeAndInsert(properties, _T("门宽"), data.dWidth, true);
SimpleProperty::makeAndInsert(properties, _T("门槛高"), data.dBomEl, true);
}
SimpleProperty::makeAndInsert(properties, _T("材质"), data.szSpec, true);
SimpleProperty::makeAndInsert(properties, _T("生产厂家"), data.szFactory, true);
std::vector<CString> recs3d;
RECMAP recmap;
get2dRecList(data.nType == 1, recmap);
std::vector<CString> recs2d;
if (!recmap.empty())
{
for (RECMAP::const_iterator it(recmap.begin()); it != recmap.end(); ++it)
recs2d.push_back(it->first);
}
if (!recs2d.empty())
SimpleProperty::makeAndInsert(properties
, _T("二维样式名称")
, data.szBlockName2d
, true
, recs2d);
else
SimpleProperty::makeAndInsert(properties
, _T("二维样式名称")
, data.szBlockName2d
, false);
RECMAP::const_iterator it = recmap.find(data.szBlockName2d);
if (it != recmap.end())
get3dRecList(data.nType == 1, recs3d, it->second);
if (!recs3d.empty())
SimpleProperty::makeAndInsert(properties
, _T("三维样式名称")
, data.szBlockName3d
, true
, recs3d);
else
SimpleProperty::makeAndInsert(properties
, _T("三维样式名称")
, data.szBlockName3d
, false);
return true;
}
bool AecDbXOpening::SetProperties(SimpleProperty::PropertySetByName & properties)
{
if (properties.m_set.empty())
return false;
AecDbEntityBase::SetProperties(properties);
OpeningData data;
memset(&data, 0, sizeof(OpeningData));
GetOpeningData(data);
properties.findAndSet(_T("窗高"), data.dHeight);
properties.findAndSet(_T("窗宽"), data.dWidth);
properties.findAndSet(_T("窗台高"), data.dBomEl);
properties.findAndSet(_T("门高"), data.dHeight);
properties.findAndSet(_T("门宽"), data.dWidth);
properties.findAndSet(_T("门槛高"), data.dBomEl);
properties.findAndSet(_T("材质"), data.szSpec);
properties.findAndSet(_T("生产厂家"), data.szFactory);
CString sVal(_T(""));
if (properties.findAndSet(_T("二维样式名称"), sVal))
{
_tcscpy_s(data.szBlockName2d, sVal);
_tcscpy_s(data.szName, sVal);
}
properties.findAndSet(_T("三维样式名称"), data.szBlockName3d);
AcDbObjectId idWall;
m_mapSpecXData.GetAt(KEY_IDCNT1,idWall);
SetOpeningData(data, idWall);
return false;
}
Acad::ErrorStatus AecDbXOpening::subWblockClone(AcRxObject * pOwnerObject
, AcDbObject *& pClonedObject
, AcDbIdMapping & idMap
, Adesk::Boolean isPrimary) const
{
// 如果已经克隆过了,就直接返回,避免重复克隆
AcDbIdPair idPairOpening(id(), AcDbObjectId::kNull, false, isPrimary ? true : false);
if (idMap.compute(idPairOpening))
return Acad::eOk;
Acad::ErrorStatus es = AecDbEntityBase::subWblockClone(pOwnerObject, pClonedObject, idMap, isPrimary);
if (es != Acad::eOk) return es;
if (!pClonedObject) return es;
AecDbXOpening *pOpening = AecDbXOpening::cast(pClonedObject);
if (pOpening)
pOpening->SetAt(KEY_IDCNT1, AcDbObjectId::kNull);
return es;
}
Acad::ErrorStatus AecDbXOpening::subDeepClone(AcDbObject * pOwnerObject
, AcDbObject *& pClonedObject
, AcDbIdMapping & idMap
, Adesk::Boolean isPrimary) const
{
// 如果已经克隆过了,就直接返回,避免重复克隆
AcDbIdPair idPairOpening(id(), AcDbObjectId::kNull, false, isPrimary ? true : false);
if (idMap.compute(idPairOpening))
return Acad::eOk;
Acad::ErrorStatus es = AecDbEntityBase::subDeepClone(pOwnerObject, pClonedObject, idMap, isPrimary);
if (es != Acad::eOk) return es;
if (!pClonedObject) return es;
AecDbXOpening *pOpening = AecDbXOpening::cast(pClonedObject);
if (pOpening)
pOpening->SetAt(KEY_IDCNT1, AcDbObjectId::kNull);
return es;
}