3550 lines
82 KiB
C++
3550 lines
82 KiB
C++
#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;
|
||
}
|