//------------------------------------------------------------------------+ // 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 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