Files
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

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