404 lines
8.6 KiB
C++
404 lines
8.6 KiB
C++
//------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2011, Beijing Tangent Software Co. Ltd.
|
|
// = FileName : TDbObjMakeAssoc类
|
|
// = Version : ver1.0
|
|
// = Author : xlc
|
|
// = CreateDate : 2011-08-22
|
|
// = Description: 关联处理类实现
|
|
// = Maintainers:
|
|
//
|
|
//------------------------------------------------------------------------+
|
|
#include "StdAfx.h"
|
|
#ifdef TASD
|
|
#include "TDbObjMakeAssoc.h"
|
|
#include "TDbStruEntityBase.h"
|
|
#include "TDbExtentsZoneTable.h"
|
|
#include "TDbStruFloorSlab.h"
|
|
#include "TDbBaseWall.h"
|
|
|
|
extern TDbExtentsZoneTable* GetGlobalExtZoneTbl(const AcDbDatabase* pDb);
|
|
extern void AddMsg(const TAssocMsg& assocMsg);
|
|
extern BOOL g_bSplitFloor;
|
|
|
|
bool g_bModifyAgain = false;
|
|
|
|
TDbObjMakeAssoc::TDbObjMakeAssoc()
|
|
{
|
|
g_bModifyAgain = false;
|
|
}
|
|
|
|
TDbObjMakeAssoc::~TDbObjMakeAssoc()
|
|
{
|
|
m_arIdsToModify.setLogicalLength(0);
|
|
m_arIdsModified.setLogicalLength(0);
|
|
m_arIdsToUpdate.setLogicalLength(0);
|
|
}
|
|
|
|
//添加,编辑对象消息
|
|
void TDbObjMakeAssoc::TranslateMsg(TAssocMsg& msg)
|
|
{
|
|
//MakeAssocAtNewPosition(msg.GetAssocId());
|
|
BOOL bBaseWall = FALSE;
|
|
TGGeCurveSegment cvCenter;
|
|
AcDbObjectIdArray arIds; //对象关联实体数组
|
|
OPENOBJ_BEGIN(msg.GetAssocId(), AcDb::kForRead, TDbBaseWall, pEnt);
|
|
if (pEnt)
|
|
{
|
|
bBaseWall = TRUE;
|
|
|
|
cvCenter = pEnt->GetLongBaseLine();
|
|
cvCenter.SetElevation(0);
|
|
|
|
AcDbExtents ext;
|
|
if(pEnt->getGeomExtents(ext)==Acad::eOk)
|
|
{
|
|
GetGlobalExtZoneTbl((AcDbDatabase*)(pEnt->database()))->GetSelection(ext.minPoint(), ext.maxPoint(),arIds);
|
|
arIds.remove(msg.GetAssocId());
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
|
|
if (bBaseWall && g_bSplitFloor)
|
|
{
|
|
for(int i = 0; i < arIds.length(); i++)
|
|
{
|
|
OPENOBJ_BEGIN(arIds[i], AcDb::kForRead, TDbStruFloorSlab, pEnt);
|
|
if(pEnt)
|
|
{
|
|
int nType = 0;
|
|
pEnt->GetAt(KEY_KIND, nType);
|
|
if (nType != 0) //只处理楼板,不处理悬挑板
|
|
{
|
|
continue;
|
|
}
|
|
|
|
AcGePoint3d ptPos;
|
|
if(pEnt->GetAt(KEY_POS, ptPos))
|
|
{
|
|
//对位置点进行判断,防止发生只有一端与楼板相交的情况也进行拆分
|
|
TADSGePoint3d ptRes;
|
|
if(cvCenter.ProjectToMe(TADSGePoint3d(ptPos), ptRes)==RTNORM)
|
|
{
|
|
if((ptRes&cvCenter) != PR_INSIDE)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//add by xlc on 120210 解决同时复制时拆分的问题
|
|
//获得同时操作的对象数组
|
|
AcDbObjectIdArray arIdPick;
|
|
g_ssPickFirst.AsIdArray(arIdPick);
|
|
int nIndex;
|
|
if (arIdPick.find(arIds[i], nIndex))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
SplitFloorSlab(cvCenter, pEnt);
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
MakeAssocAtNewPosition(msg.GetAssocId());
|
|
}
|
|
else
|
|
{
|
|
MakeAssocAtNewPosition(msg.GetAssocId());
|
|
}
|
|
}
|
|
|
|
//夹点消息
|
|
void TDbObjMakeAssoc::TranslateGripMsg(TAssocMsg& msg)
|
|
{
|
|
AcDbObjectIdArray arIds; //对象关联实体数组
|
|
OPENOBJ_BEGIN(msg.GetAssocId(), AcDb::kForWrite, TDbStruEntityBase, pEnt);
|
|
if (pEnt)
|
|
{
|
|
pEnt->GetAssocRelation(ASSOC_ALL, arIds);
|
|
pEnt->UpdateMeOnGripMsg(msg); //处理夹点消息后,更新自己的边界
|
|
}
|
|
OPENOBJ_END();
|
|
|
|
m_arIdsModified.append(msg.GetAssocId());
|
|
|
|
for(int i = 0; i < arIds.length(); i++)
|
|
{
|
|
if (m_arIdsModified.contains(arIds[i]))//已经处理完的对象不再处理
|
|
{
|
|
continue;
|
|
}
|
|
|
|
OPENOBJ_BEGIN(arIds[i], AcDb::kForWrite, TDbStruEntityBase, pEnt);
|
|
if (pEnt)
|
|
{
|
|
pEnt->ReceiveAssocMsg(msg);
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
|
|
//移动消息
|
|
void TDbObjMakeAssoc::TranslateTransformMsg(TAssocMsg& msg)
|
|
{
|
|
MakeAssocAtNewPosition(msg.GetAssocId());
|
|
}
|
|
|
|
//新位置创建关联
|
|
void TDbObjMakeAssoc::MakeAssocAtNewPosition(AcDbObjectId idObj)
|
|
{
|
|
AcDbObjectIdArray arIdAssoc; //已有关联数组
|
|
AcDbObjectIdArray arIdNewPos; //新位置关联数组
|
|
AcDbObjectIdArray arIdRemove; //已有关联移除数组
|
|
int nCount =1000;
|
|
OPENOBJ_BEGIN(idObj, AcDb::kForWrite, TDbStruEntityBase, pEnt);
|
|
if (pEnt)
|
|
{
|
|
pEnt->GetAssocRelation(ASSOC_ALL, arIdAssoc);
|
|
|
|
int i = 0;
|
|
AcDbExtents ext;
|
|
|
|
while(TRUE)
|
|
{
|
|
|
|
if(pEnt->getGeomExtents(ext)==Acad::eOk)
|
|
{
|
|
pEnt->downgradeOpen();
|
|
GetGlobalExtZoneTbl((AcDbDatabase*)(pEnt->database()))->GetSelection(ext.minPoint(), ext.maxPoint(),arIdNewPos);
|
|
pEnt->upgradeOpen();
|
|
}
|
|
|
|
//移除自己
|
|
arIdNewPos.remove(idObj);
|
|
|
|
//新位置和已有关联都有的数组当作为变化关联,新位置没有的,解除关联
|
|
for(i = 0; i < arIdAssoc.length(); i++)
|
|
{
|
|
AcDbObjectId id = arIdAssoc[i];
|
|
if (arIdNewPos.contains(id))
|
|
{
|
|
arIdNewPos.remove(id);
|
|
}
|
|
else
|
|
{
|
|
pEnt->RemoveAssocRelation(id);
|
|
arIdRemove.append(id);
|
|
}
|
|
|
|
if (!m_arIdsToUpdate.contains(id))
|
|
{
|
|
m_arIdsToUpdate.append(id);
|
|
}
|
|
}
|
|
|
|
g_bModifyAgain =false;
|
|
//新位置创建新关联
|
|
pEnt->MakeAssocRelation(arIdNewPos);
|
|
|
|
if (g_bModifyAgain)
|
|
{
|
|
nCount--;
|
|
if (nCount<1)
|
|
{
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//处理新位置未处理的关联
|
|
for(i = 0; i < arIdNewPos.length(); i++)
|
|
{
|
|
if (m_arIdsToModify.contains(arIdNewPos[i]))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
TAssocMsg assocMsg;
|
|
assocMsg.SetMethod(TAssocMsg::kEdit);
|
|
assocMsg.SetAssocId(arIdNewPos[i]);
|
|
|
|
AddMsg(assocMsg);
|
|
}
|
|
|
|
//处理解除的关联
|
|
for(i = 0; i < arIdRemove.length(); i++)
|
|
{
|
|
if (m_arIdsToModify.contains(arIdRemove[i]))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
TAssocMsg assocMsg;
|
|
assocMsg.SetMethod(TAssocMsg::kEdit);
|
|
assocMsg.SetAssocId(arIdRemove[i]);
|
|
|
|
AddMsg(assocMsg);
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
|
|
OPENOBJ_BEGIN(idObj, AcDb::kForWrite, TDbColumn, pEnt);
|
|
if (pEnt)
|
|
{
|
|
XPoint ptLoc = pEnt->GetLocation();
|
|
double dHeight = pEnt->GetHeight();
|
|
|
|
int i = 0;
|
|
AcDbExtents ext;
|
|
|
|
if(pEnt->getGeomExtents(ext)==Acad::eOk)
|
|
{
|
|
AcGePoint3d ptMin = ext.minPoint(), ptMax = ext.maxPoint();
|
|
ptMin.z = ptLoc.z;
|
|
ptMax.z = ptLoc.z + dHeight;
|
|
|
|
pEnt->downgradeOpen();
|
|
GetGlobalExtZoneTbl((AcDbDatabase*)(pEnt->database()))->GetSelection(ptMin, ptMax,arIdNewPos);
|
|
pEnt->upgradeOpen();
|
|
|
|
for(i = 0; i < arIdNewPos.length(); i++)
|
|
{
|
|
if (m_arIdsToModify.contains(arIdNewPos[i]))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
TAssocMsg assocMsg;
|
|
assocMsg.SetMethod(TAssocMsg::kEdit);
|
|
assocMsg.SetAssocId(arIdNewPos[i]);
|
|
|
|
AddMsg(assocMsg);
|
|
}
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
void TDbObjMakeAssoc::UpdateAssocByTransform()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
// 参考楼板pSlab,绘制以poly为边界的楼板
|
|
void TDbObjMakeAssoc::CreateNewFloorSlab(const TDbStruFloorSlab* pSlab, TGGePoly2D& poly)
|
|
{
|
|
if (pSlab == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
AcGePoint3d pt;
|
|
pSlab->GetAt(KEY_POS, pt);
|
|
TDbStruFloorSlab *pSlabNew = new TDbStruFloorSlab;
|
|
pSlabNew->copyFrom(pSlab);
|
|
|
|
TADSGePoint3d ptLow, ptUp, ptMid;
|
|
poly.GetExtend(ptLow, ptUp);
|
|
Midpoint(ptLow, ptUp, ptMid);
|
|
ptMid.z = pt.z;
|
|
pSlabNew->SetAt(KEY_POS, ptMid.AsAcGePoint3d());
|
|
if (poly.Area() < _DIST_SNAP)
|
|
{
|
|
delete pSlabNew;
|
|
return;
|
|
}
|
|
|
|
TPushMemVar<BOOL> pushVar(g_bMonitorDbAction, TRUE);
|
|
|
|
pSlabNew->SetOutlinePoly(poly);
|
|
pSlabNew->AddToMSpace(Adesk::kTrue);
|
|
//AddToModelSpace(pSlabNew);
|
|
}
|
|
|
|
// 拆分楼板
|
|
void TDbObjMakeAssoc::SplitFloorSlab(TGGeCurveSegment cvCenter, TDbStruFloorSlab* pFloorSlab)
|
|
{
|
|
if (!pFloorSlab)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// 板的外包线
|
|
TGGePoly2D poly;
|
|
pFloorSlab->GetOutline(poly);
|
|
|
|
double dEle = poly[0]->z;
|
|
poly.SetElevation(0.0);
|
|
|
|
// 求墙中心线与板的交点
|
|
AcDbCurve *pCurve = NULL;
|
|
pCurve = poly.AsAcDbCurve();
|
|
if (pCurve == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
AcDbCurve *pCurve2 = NULL;
|
|
pCurve2 = cvCenter.AsAcDbCurve();
|
|
if (pCurve2 == NULL)
|
|
{
|
|
delete pCurve;
|
|
return;
|
|
}
|
|
|
|
AcGePoint3dArray arrPt;
|
|
pCurve->intersectWith(pCurve2, AcDb::kExtendArg, arrPt);
|
|
delete pCurve2;
|
|
delete pCurve;
|
|
|
|
if (arrPt.length() != 2)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// 分解poly
|
|
TGGePoly2D poly1, poly2;
|
|
SplitPoly2D(poly, asDblArray(arrPt[0]), asDblArray(arrPt[1]), poly1, poly2);
|
|
|
|
if (!!poly1 && !!poly2)
|
|
{
|
|
poly1.SetElevation(dEle);
|
|
poly2.SetElevation(dEle);
|
|
double a1=poly1.Area(),a2=poly2.Area();
|
|
if (poly1.Area() < _DIST_SNAP || poly2.Area() < _DIST_SNAP
|
|
||poly1.Length()<3 || poly2.Length()<3)
|
|
{
|
|
return;
|
|
}
|
|
AcGePoint3d pt;
|
|
pFloorSlab->GetAt(KEY_POS, pt);
|
|
|
|
CreateNewFloorSlab(pFloorSlab, poly1);
|
|
|
|
if(pFloorSlab->upgradeOpen() == Acad::eOk)
|
|
{
|
|
AcDbObjectIdArray arIds;
|
|
pFloorSlab->GetAssocRelation(ASSOC_HOLE, arIds);
|
|
for(int i = 0; i < arIds.length(); i++)
|
|
{
|
|
pFloorSlab->RemoveAssocRelation(arIds[i]);
|
|
}
|
|
pFloorSlab->SetOutlinePoly(poly2);
|
|
|
|
TADSGePoint3d ptLow, ptUp, ptMid;
|
|
poly2.GetExtend(ptLow, ptUp);
|
|
|
|
Midpoint(ptLow, ptUp, ptMid);
|
|
ptMid.z = pt.z;
|
|
pFloorSlab->SetAt(KEY_POS, ptMid.AsAcGePoint3d());
|
|
pFloorSlab->downgradeOpen();
|
|
}
|
|
}
|
|
}
|
|
#endif |