#include "stdafx.h" #include "actrans.h" #include "PipeWireMonitor.h" #include "DbPipe.h" #include "SearchPipeSys.h" //#include "DbObject.h" #include #include "DbEquipment.h" #include "DbWell.h" //#include "tdoclock.h" #include "DbFloorRect.h" #include "DbVPipeDim.h" #include "DbPool.h" #include "DbFloorPipe.h" #include "ClipData.h" //剪切板 #include "DbWellDim.h" #include #include "PipeSystemProcessor.h" #include "DbPipeFitting.h" #if ADS > 15 TLayerPane g_LayerPane; //2011-10-11 sr add #endif // sg add #include "DbDuct.h" #include "TDbDuctNode.h" #include "DbDoubleLinePipeReducer.h" #define WM_TCH_DOC_CHANGED (WM_USER+0x0201) Adesk::Boolean acedPostCommand(const TCHAR * ); int g_nCmdReactor=CMD_UNKNOWN;//命令状态 BOOL g_bIsStartMatchProp = FALSE; extern BOOL g_bIsCustomizeVer; extern CString g_sCurrentCmd; // cet 2012.11.16 add 保存命令处理时启动的命令,以便更新双线水管fitting extern double g_dPointToOriginLimitDist; // NO MSG is required //extern TARCH_IMPEXP BOOL g_bMonitorDbAction; //static BOOL g_bMonitorDbAction=TRUE; static TPipeAppDocGlobals *g_pTPipeAppDocGlobals=NULL; /* 说明: 本文件定义Reactor来监测管线的变动,最终的动作在命令结束时发生 TPipeCmdReactor 命令监测 TPipeDbReactor 数据库监测 要使用这两个类,必须在Arx程序入口出注册他们(用Attach) 在DWG结束时要Detach后者,在ARX程序退出时要Detach两者 */ #define OBJ_DELETE 0x01 #define OBJ_APPEND 0x02 #define OBJ_CHANGE 0x04 namespace { // 更新TDbPsConfig到新数据库 cet 2014.12.15 add void UpdatePsConfig(AcDbDatabase *pDb) { // 设置TDbPsConfig到新数据库 TDbPsConfig *pCloneConfig = NULL; TDbPsConfig *pConfig = GetDwgPsGlobal(AcDb::kForRead); if (pConfig != NULL) { pCloneConfig = (TDbPsConfig*)pConfig->clone(); pConfig->close(); } if (pCloneConfig == NULL) { return; } Acad::ErrorStatus es=Acad::eOk; AcDbDictionary* pRootDict=NULL; es=pDb->getNamedObjectsDictionary(pRootDict,AcDb::kForRead); assert(es==Acad::eOk); AcDbObject* pObj; es=pRootDict->getAt(g_sDbPsConfig,pObj,AcDb::kForRead); if (es==Acad::eOk) { pObj->close(); } else //当前数据库未初始化全局变量 { if (pRootDict->upgradeOpen() == Acad::eOk) { pRootDict->assertWriteEnabled(); AcDbObjectId idConfig; es = pRootDict->setAt(g_sDbPsConfig,pCloneConfig,idConfig); if (es == Acad::eOk) { pCloneConfig->close(); } else { delete pCloneConfig; } pCloneConfig = NULL; pRootDict->downgradeOpen(); } } delete pCloneConfig; pRootDict->close(); } // 将当前数据库中的TDbPsConfig值存入新数据库中 cet2014.12.15 add void InitConfigToNewDatabase(AcDbDatabase *pDb) { // 更新TDbPsConfig到新数据库 UpdatePsConfig(pDb); } // cet 2016.7.12 add 管道连接件图层随管道图层 void UpdatePipeFittingLayer(const AcDbDatabase* dwg, const AcDbObject* dbObj) { if (dwg != acdbCurDwg() || !dbObj->isKindOf(TDbPipe::desc())) { return; } TDbPipe *pPipe = TDbPipe::cast(dbObj); for (int i = 0; i < 2; ++i) { AcDbObjectId id = pPipe->GetNode(i); if (!id.isValid()) { continue; } TDbPipeFitting *pFitting = NULL; acdbOpenObject(pFitting, id, AcDb::kForRead); if (pFitting != NULL) { if ((pFitting->layerId() != pPipe->layerId() || pFitting->color() != pPipe->color()) && pFitting->upgradeOpen() == Acad::eOk) { pFitting->setLayer(pPipe->layerId()); pFitting->setColor(pPipe->color()); pFitting->downgradeOpen(); } pFitting->close(); } } } // 管道求交 cet 2017.12.13 add int IntersectionForDbPipePrototype(const TDbPipePrototype *pChangedPipe,const TDbPipePrototype *pPipe, XPoint &ptPipe1, XPoint &ptPipe2) { // 管道距离原点过远计算可能失败,移动到原点附近计算 AcGeVector3d vtMove = pPipe->StartPoint(); if (fabs(vtMove.x) > g_dPointToOriginLimitDist || fabs(vtMove.y) > g_dPointToOriginLimitDist || fabs(vtMove.z) > g_dPointToOriginLimitDist) { TDbPipePrototype *pPipe1 = (TDbPipePrototype*)pChangedPipe->clone(); TDbPipePrototype *pPipe2 = (TDbPipePrototype*)pPipe->clone(); if (pPipe1 != NULL && pPipe2 != NULL) { pPipe1->ResetAllShip(); // 清除关联关系,否则有时克隆出来的管道等执行transformBy pPipe2->ResetAllShip(); // 时,会同时修改原管道关联的对象(如fitting),导致管道等绘制错误 AcGeMatrix3d mat; mat.setToTranslation(vtMove * -1); pPipe1->transformBy(mat); pPipe2->transformBy(mat); int nRet = pPipe1->Intersection(*pPipe2, ptPipe1, ptPipe2); if (nRet > 0) // 有交点 { ptPipe1.TransformBy(mat.inverse()); // 第一个交点 if (nRet > 1) // 第二个交点 { ptPipe2.TransformBy(mat.inverse()); } } return nRet; } } return pChangedPipe->Intersection(*pPipe, ptPipe1, ptPipe2); } } Acad::ErrorStatus GetSafeSelection(PickSet &ss,const XPoint &ptLow, const XPoint &ptUp, const AcRxClass *pClass, BOOL bCrossing=TRUE); BOOL GetPSEntFormBlock(DList &lstPSEnt, const XRectAngle& rectBound,const AcRxClass *pClass) { lstPSEnt.Reset(); if(pClass==NULL) return FALSE; XDbBlockTableRec objMSpace; if(!objMSpace) return FALSE; XPoint ptExtents(1000,1000,0);//加速设备GetExtents AcDbBlockTableRecordIterator* pBlockIterator=NULL; Acad::ErrorStatus es=objMSpace.m_pBlockTableRec->newIterator(pBlockIterator); ASSERT(es==Acad::eOk && pBlockIterator!=NULL); for(pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step()) { AcDbEntity *pEntity=NULL; es=pBlockIterator->getEntity(pEntity, AcDb::kForRead); if(es!=Acad::eOk) continue; ASSERT(pEntity); XDbObject vTemp(pEntity); if(!pEntity->isKindOf(pClass)||pEntity->visibility()==AcDb::kInvisible) continue; AcDbObjectId id=pEntity->objectId(); if(pEntity->isKindOf(TDbPipePrototype::desc())) {//管线(for getGeomExtents 不准确) TDbPipePrototype *pPipe=(TDbPipePrototype *)pEntity; if(pPipe!=NULL) { XPoint ptMin,ptMax; if(pPipe->GetExtend(ptMin,ptMax)) { if(ExtendInBox02d(ptMin,ptMax,rectBound)) { lstPSEnt.Append(new AcDbObjectId(id)); } } } } else if(pEntity->isKindOf(TDbPipeNode::desc())) { //节点 TDbPipeNode *pNode=(TDbPipeNode *)pEntity; if(pNode!=NULL) { if(pNode->IsVisible()) { //可见节点 if(pNode->IsDrawBlock()) { XPoint ptLocation=pNode->GetLocation(); XPoint ptMin=ptLocation-ptExtents; XPoint ptMax=ptLocation+ptExtents; if(!ExtendInBox02d(ptMin,ptMax,rectBound)) continue; } XPoint ptMin,ptMax; if(pNode->GetExtents(ptMin,ptMax)==Acad::eOk) { if(ExtendInBox02d(ptMin,ptMax,rectBound)) { lstPSEnt.Append(new AcDbObjectId(id)); } } } else { //不可见节点 XPoint ptLocation = pNode->GetLocation(); if(PointInBox02d(ptLocation,rectBound)) { lstPSEnt.Append(new AcDbObjectId(id)); } } } } else if(pEntity->isKindOf(TDbPipeAttachment::desc())) { // 管线附件 TDbPipeAttachment *pAttach=(TDbPipeAttachment *)pEntity; if(pAttach!=NULL) { if(pAttach->IsDrawBlock()) { XPoint ptLocation=pAttach->GetLocation(); XPoint ptMin=ptLocation-ptExtents; XPoint ptMax=ptLocation+ptExtents; if(!ExtendInBox02d(ptMin,ptMax,rectBound)) continue; } XPoint ptMin,ptMax; if(pAttach->GetExtents(ptMin,ptMax)==Acad::eOk) { if(ExtendInBox02d(ptMin,ptMax,rectBound)) { lstPSEnt.Append(new AcDbObjectId(id)); } } } } else if(pEntity->isKindOf(TDbEntity::desc())) { // 其他上华实体 TDbEntity *pTEnt=(TDbEntity *)pEntity; if(pTEnt!=NULL) { XPoint ptMin,ptMax; if(pTEnt->GetExtents(ptMin,ptMax)==Acad::eOk) { if(ExtendInBox02d(ptMin,ptMax,rectBound)) { lstPSEnt.Append(new AcDbObjectId(id)); } } } } else { // 其他的非上华实体 AcDbExtents ext; if(pEntity->getGeomExtents(ext)==Acad::eOk) { XPoint ptMin=ext.minPoint(), ptMax=ext.maxPoint(); if(ExtendInBox02d(ptMin,ptMax,rectBound)) { lstPSEnt.Append(new AcDbObjectId(id)); } } } } delete pBlockIterator; return TRUE; } /* int GetPickFirst_New(PickSet &gSet, PickSet &pSet) { resbuf *gset=NULL, *pset=NULL; int nRet=ads_ssgetfirst(&gset, &pset); if(gset) { if(gset->restype==RTPICKS) { PickSet ss0(0); ss0 = gset->resval.rlname; gSet += ss0; ss0.Free(); } ads_relrb(gset); } if(pset) { if(pset->restype==RTPICKS) { PickSet ss0(0); ss0 = pset->resval.rlname; pSet += ss0; ss0.Free(); } ads_relrb(pset); } return nRet; } */ /////////////////////////////////////////////////////////////////// // 文档反应器 void TPipeDocReactor::documentToBeActivated(AcApDocument *pDoc) { ::PostMessage(NULL, WM_TCH_DOC_CHANGED, 0, 0); g_pTPipeAppDocGlobals->InitDocGlobals(pDoc); #if (ADS>15) if (g_bIsCustomizeVer) { g_LayerPane.Update(); } #endif } void TPipeDocReactor::documentCreated(AcApDocument *pDoc) { g_pTPipeAppDocGlobals->InitDocGlobals(pDoc); } void TPipeDocReactor::documentToBeDestroyed(AcApDocument *pDoc) { g_pTPipeAppDocGlobals->RemoveDocGlobals(pDoc); } // 文档反应器结束 /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// // 输入反应器 void TPipeInputReactor::endEntsel(Acad::PromptStatus returnStatus, AcDbObjectId& entPicked, AcGePoint3d& pickPoint, const TCHAR* pKeyword) { if(!g_bIsStartMatchProp) return; OPENOBJ_BEGIN(entPicked, AcDb::kForRead, TDbPipe, pPipe); if(!pPipe){ OPENOBJ_BEGIN(entPicked, AcDb::kForRead, TDbEquipment, pEquip); if(!pEquip){ g_bIsStartMatchProp = FALSE; return; } OPENOBJ_END(); } OPENOBJ_END(); TPipePerDocData *pData = GetCurPipeDocData(); ASSERT(pData); if(pData) { pData->m_idMatchRes = entPicked; } } // 输入反应器结束 /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// // TPipePerDocData TPipePerDocData::TPipePerDocData(AcApDocument *pDoc) :m_rectSysUpdate(XPoint(),XPoint()),m_rectAttachUpdate(XPoint(),XPoint()), m_bWork(TRUE),m_nOptimize(500) { m_pDoc = pDoc; m_pDbReactor=NULL; m_pInputReactor = NULL; m_idMatchRes = NULL; } TPipePerDocData::~TPipePerDocData() { ASSERT(m_pDbReactor==NULL); ASSERT(m_pInputReactor==NULL); } void TPipePerDocData::ResetDocCmdGlobals() { m_lstUpdate.Reset(); m_rectSysUpdate.lowLeft=m_rectSysUpdate.upRight=XPoint(); m_rectAttachUpdate.lowLeft=m_rectAttachUpdate.upRight=XPoint(); m_lstChangedNode.Reset(); m_idMatchRes = NULL; m_lstMatchEntity.Reset(); // m_lstWellArea.Reset(); m_setEntIds.clear(); // cet 2013.1.11 add } int TPipePerDocData::GetChangedNum() const { int nChangedNum=m_lstChangedNode.Length(); for(int i=0; isysType==st) // return info; return info; } return NULL; } BOOL TPipePerDocData:: GetNodeFromBlock(DList &lstNode,const XRectAngle &rect) const { if(IsRectEmpty(rect)) return TRUE; XDbBlockTableRec objMSpace; if(!objMSpace) return FALSE; lstNode.Reset(); XPoint ptExtents(1000,1000,0);//加速设备GetExtents XPoint ptSnap(PS_SNAP,PS_SNAP); XRectAngle rectBound(rect.lowLeft-ptSnap,rect.upRight+ptSnap); AcDbBlockTableRecordIterator* pBlockIterator=NULL; Acad::ErrorStatus es=objMSpace.m_pBlockTableRec->newIterator(pBlockIterator); ASSERT(es==Acad::eOk && pBlockIterator!=NULL); for(pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step()) { AcDbEntity *pEntity=NULL; es=pBlockIterator->getEntity(pEntity, AcDb::kForRead); if(es!=Acad::eOk) continue; ASSERT(pEntity); XDbObject vTemp(pEntity); if(!pEntity->isKindOf(TDbPipeNode::desc())||pEntity->visibility()==AcDb::kInvisible) continue; TDbPipeNode *pNode=(TDbPipeNode *)pEntity; if(pNode!=NULL) { XPoint ptLocation=pNode->GetLocation(); if(pNode->IsVisible()) { //可见节点 if(pNode->IsDrawBlock()) { XPoint ptMin; XPoint ptMax; //2009-8-11 谢真修改以下10行:对于大的化粪池ptExtents(1000,1000,0)太小无法InBox TDbPool *pPool = TDbPool::cast(pNode); TDbDoubleLinePipeReducer *pDLpipeReducer = TDbDoubleLinePipeReducer::cast(pNode); if (pPool != NULL) { double dPoolLen = pPool->GetPoolLength(); double dPoolWidth = pPool->GetPoolWidth(); double dLen = pow(dPoolLen*dPoolLen + dPoolWidth*dPoolWidth,0.5);//double dLen = pow(dPoolLen*dPoolLen + dPoolWidth*dPoolWidth,0.5) + 100; XPoint ptPool(dLen/2.0, dLen/2.0, 0.0); //sr 范围缩小(原先对角线2倍+100为边的正方形) XPoint ptPool(dLen, dLen, 0.0); 2011-11-10 ptMin=ptLocation-ptPool; ptMax=ptLocation+ptPool; } else if (pDLpipeReducer != NULL) // cet 2010.3.5 add { AcDbExtents extends; pDLpipeReducer->getGeomExtents(extends); AcGePoint3d ptTmp(100, 100, 0.0); ptMin = extends.minPoint() - ptTmp; ptMax = extends.maxPoint() + ptTmp; } else { ptMin=ptLocation-ptExtents; ptMax=ptLocation+ptExtents; } ///////////////////////// if(!ExtendInBox02d(ptMin,ptMax,rectBound)) continue; else { lstNode.Append(new TNodeLocation(pNode->objectId(),ptLocation)); continue;//SR ADD 2011-11-10 发现图块设备(化粪池)最大包围盒与rectBound有交集,把设备加入lstNode中 } } XPoint ptMin,ptMax; if(pNode->GetExtents(ptMin,ptMax)==Acad::eOk) { if(ExtendInBox02d(ptMin,ptMax,rectBound)) { lstNode.Append(new TNodeLocation(pNode->objectId(),ptLocation)); } } else { // for上华插件 lstNode.Append(new TNodeLocation(pNode->objectId(),ptLocation)); } } else { //不可见节点 if(PointInBox02d(ptLocation,rectBound)) { lstNode.Append(new TNodeLocation(pNode->objectId(),ptLocation)); } } } } delete pBlockIterator; return TRUE; } BOOL TPipePerDocData::GetEntRectFromBlock(DList &lstEntRect, const AcRxClass *pClass,const XRectAngle &rect) const { if(pClass==NULL) return FALSE; if(IsRectEmpty(rect)) return TRUE; XDbBlockTableRec objMSpace; if(!objMSpace) return FALSE; lstEntRect.Reset(); XPoint ptExtents(1000,1000,0);//加速设备GetExtents XPoint ptSnap(PS_SNAP,PS_SNAP); XRectAngle rectBound(rect.lowLeft-ptSnap,rect.upRight+ptSnap); AcDbBlockTableRecordIterator* pBlockIterator=NULL; Acad::ErrorStatus es=objMSpace.m_pBlockTableRec->newIterator(pBlockIterator); ASSERT(es==Acad::eOk && pBlockIterator!=NULL); for(pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step()) { AcDbEntity *pEntity=NULL; es=pBlockIterator->getEntity(pEntity, AcDb::kForRead); if(es!=Acad::eOk) continue; ASSERT(pEntity); XDbObject vTemp(pEntity); if(!pEntity->isKindOf(pClass)||pEntity->visibility()==AcDb::kInvisible) continue; AcDbObjectId id=pEntity->objectId(); if(pEntity->isKindOf(TDbPipePrototype::desc())) {//管线(for getGeomExtents 不准确) TDbPipePrototype *pPipe=(TDbPipePrototype *)pEntity; if(pPipe!=NULL) { XPoint ptMin,ptMax; if(pPipe->GetExtend(ptMin,ptMax)) { if(ExtendInBox02d(ptMin,ptMax,rectBound)) { lstEntRect.Append(new TEntRect(id,ptMin,ptMax)); } } } } else if(pEntity->isKindOf(TDbPipeNode::desc())) { //节点 TDbPipeNode *pNode=(TDbPipeNode *)pEntity; if(pNode!=NULL) { if(pNode->IsVisible()) { //可见节点 if(pNode->IsDrawBlock()) { XPoint ptLocation=pNode->GetLocation(); XPoint ptMin=ptLocation-ptExtents; XPoint ptMax=ptLocation+ptExtents; if(!ExtendInBox02d(ptMin,ptMax,rectBound)) continue; } XPoint ptMin,ptMax; if(pNode->GetExtents(ptMin,ptMax)==Acad::eOk) { if(ExtendInBox02d(ptMin,ptMax,rectBound)) { lstEntRect.Append(new TEntRect(id,ptMin,ptMax)); } } } else { //不可见节点 XPoint ptLocation = pNode->GetLocation(); if(PointInBox02d(ptLocation,rectBound)) { lstEntRect.Append(new TEntRect(id,ptLocation,ptLocation)); } } } } else if(pEntity->isKindOf(TDbPipeAttachment::desc())) { // 管线附件 TDbPipeAttachment *pAttach=(TDbPipeAttachment *)pEntity; if(pAttach!=NULL) { if(pAttach->IsDrawBlock()) { XPoint ptLocation=pAttach->GetLocation(); XPoint ptMin=ptLocation-ptExtents; XPoint ptMax=ptLocation+ptExtents; if(!ExtendInBox02d(ptMin,ptMax,rectBound)) continue; } XPoint ptMin,ptMax; if(pAttach->GetExtents(ptMin,ptMax)==Acad::eOk) { if(ExtendInBox02d(ptMin,ptMax,rectBound)) { lstEntRect.Append(new TEntRect(id,ptMin,ptMax)); } } } } else if(pEntity->isKindOf(TDbEntity::desc())) { // 其他上华实体 TDbEntity *pTEnt=(TDbEntity *)pEntity; if(pTEnt!=NULL) { XPoint ptMin,ptMax; if(pTEnt->GetExtents(ptMin,ptMax)==Acad::eOk) { if(ExtendInBox02d(ptMin,ptMax,rectBound)) { lstEntRect.Append(new TEntRect(id,ptMin,ptMax)); } } } } else { // 其他的非上华实体 AcDbExtents ext; if(pEntity->getGeomExtents(ext)==Acad::eOk) { XPoint ptMin=ext.minPoint(), ptMax=ext.maxPoint(); if(ExtendInBox02d(ptMin,ptMax,rectBound)) { lstEntRect.Append(new TEntRect(id,ptMin,ptMax)); } } } } delete pBlockIterator; return TRUE; } // 查找并增加包含pNode的管段的需要更新的信息 BOOL TPipePerDocData:: UpdatePipeInfos(const TDbPipeNode *pChangedNode,const TDbPipePrototype *pPipe) { XPoint ptLocation=pChangedNode->GetLocation(); int nFlag = ptLocation&(*pPipe); if(nFlag==PR_INSIDE || nFlag==PR_ONPT1 || nFlag==PR_ONPT2) { if(pChangedNode->HasNodeLocation()) { UpdateInfo *info=NewAppendUpdateInfo(pPipe->GetSysType()); ASSERT(info!=NULL); info->AddPipe(pPipe->objectId()); info->lstVertice.NewAppend(ptLocation); } return TRUE; } return FALSE; } //这里判断是否生成四通,还是置上置下 BOOL TPipePerDocData::UpdatePipeInfos(const TDbPipePrototype *pChangedPipe,const TDbPipePrototype *pPipe) { TPipeSys::SysType sysType; // cet 2015.7.8 modify 按管线系统索引区分管线类型 // if(pPipe->GetHideLevel()!=pChangedPipe->GetHideLevel() || (sysType=pPipe->GetSysType())!=pChangedPipe->GetSysType()) // return FALSE; sysType=pPipe->GetSysType(); if(pPipe->GetHideLevel()!=pChangedPipe->GetHideLevel() || PipeSystemProcessor::GetSysIndex(pChangedPipe) != PipeSystemProcessor::GetSysIndex(pPipe)) { return FALSE; } XPoint pt1,pt2; // cet 2017.8.12.13 modify 管道距离原点过远时,计算可能失败,先优化计算方式 // if(pChangedPipe->Intersection(*pPipe,pt1,pt2)) { int nRet = IntersectionForDbPipePrototype(pChangedPipe, pPipe, pt1, pt2); if (nRet > 0) // 交点个数大于0 { UpdateInfo *info=NULL; if(nRet > 0 && !(pPipe->IsVertex(pt1) && pChangedPipe->IsVertex(pt1))) { // 第一个交点 if(info==NULL) { info=NewAppendUpdateInfo(sysType); ASSERT(info!=NULL); } info->AddBreakPoint(pt1,1); } if(nRet > 1 && !(pPipe->IsVertex(pt2) && pChangedPipe->IsVertex(pt2))) { // 第二个交点 if(info==NULL) { info=NewAppendUpdateInfo(sysType); ASSERT(info!=NULL); } info->AddBreakPoint(pt2,1); } if(info!=NULL) { info->AddPipe(pPipe->objectId()); return TRUE; } } else{ //sr add 2004/10/20 XLine 不支持3维求交,立管与支管相交时,无法生成4通,现在改为AcDbLine,但只处理直线管线 if(pChangedPipe->IsVertical()){ XLine l1 = pChangedPipe->GetLine(); XLine l2 = pPipe->GetLine(); AcDbLine line1((AcGePoint3d)l1.StartPoint(), (AcGePoint3d)l1.EndPoint()); AcDbLine line2((AcGePoint3d)l2.StartPoint(), (AcGePoint3d)l2.EndPoint()); AcGePoint3dArray arPoint; int hit = line1.intersectWith(&line2, AcDb::kOnBothOperands, arPoint); if(arPoint.length() == 1) pt1 = arPoint[0]; UpdateInfo *info=NULL; if(!(pPipe->IsVertex(pt1) && pChangedPipe->IsVertex(pt1))) { if(info==NULL) { info=NewAppendUpdateInfo(sysType); ASSERT(info!=NULL); } info->AddBreakPoint(pt1,1); } if(info!=NULL) { info->AddPipe(pPipe->objectId()); return TRUE; } } ////////////////////////////////////////////////////////////////////////// } return FALSE; } // 0、如果lstVertice存在不再加 // 1、如果lstVertice存在删除,加在lstNeedBreak void TPipePerDocData::UpdateInfo:: AddBreakPoint(const XPoint &ptBreak,int nStytle) { int nCount=lstVertice.Length(); if(nStytle==0) { for(int k=0; kGetLocation(); int nFlag = ptLocation&(*pChangedPipe); if(nFlag==PR_INSIDE) { int nFaceNum=pNode->GetInterfaceNum(); for(int n=0; nGetInterface(n); UpdateInfo *info=NewAppendUpdateInfo(iFace.m_sysType); if(iFace.m_faceType==TPipeInterface::kNodeLocation) { info->lstVertice.NewAppend(ptLocation); } } // 孤立的非自动生成的节点 if(nFaceNum<=0 && !pNode->IsAutoLiving()) { UpdateInfo *info=NewAppendUpdateInfo(pChangedPipe->GetSysType()); ASSERT(info!=NULL); info->AddBreakPoint(ptLocation,1); } } } // 深层次的搜寻管线和管段 void TPipePerDocData::DoDeepSearch(const DList &lstPipe, const DList &lstNode, XRectAngle &rectUpdate) { // 变化的管线 for(int n=0; nlstChangedPipe.Length(); i++) { TEntRect &pipeChanged = *info->lstChangedPipe[i]; OPENOBJ_BEGIN(pipeChanged.id,AcDb::kForRead,TDbPipePrototype,pChangedPipe); if(pChangedPipe!=NULL) { // 管线 for(int k=0; kGetSysType()); ASSERT(info!=NULL); info->lstVertice.NewAppend(nodeChanged.ptLocation); } OPENOBJ_END(); } } } OPENOBJ_END(); } // 释放 m_lstChangedNode.Reset(); for(i=0; ilstChangedPipe.Reset(); } rectUpdate.SetElevation(0); } void TPipePerDocData::ObjectChanged(const AcDbObject *dbObj, int nChangeFlag) { if(!m_bWork) return; if(g_bIsStartMatchProp && nChangeFlag&OBJ_CHANGE){ BOOL bIsPipe = FALSE; BOOL bIsEquip = FALSE; OPENOBJ_BEGIN(m_idMatchRes, AcDb::kForRead, TDbPipe, pPipe); if(pPipe){ bIsPipe = TRUE; } OPENOBJ_END(); OPENOBJ_BEGIN(m_idMatchRes, AcDb::kForRead, TDbEquipment, pEquip); if(pEquip){ bIsEquip = TRUE; } OPENOBJ_END(); if(bIsPipe){ if(dbObj->isKindOf(AcDbLine::desc()) || dbObj->isKindOf(AcDbArc::desc()) || dbObj->isKindOf(AcDbPolyline::desc()) || dbObj->isKindOf(AcDbCircle::desc())) { m_lstMatchEntity.Append(new AcDbObjectId(dbObj->objectId())); } } else if(bIsEquip){ if(dbObj->isKindOf(AcDbBlockReference::desc())) { m_lstMatchEntity.Append(new AcDbObjectId(dbObj->objectId())); } } } if(dbObj->isKindOf(TDbPipeNode::desc()) && !dbObj->isKindOf(TDbDuctNode::desc())) { //节点变化 TDbPipeNode *pNode=(TDbPipeNode *)dbObj; XPoint pt1, pt2; if(pNode->GetExtents(pt1,pt2)==Acad::eOk && !(pt1==XPoint()&&pt2==XPoint())) { UpdateRect(pt1,pt2,m_rectSysUpdate); // cet 2013.1.11 add 黏贴时记录更新区域时,使用的实体 if(IsUpdateSysRect(g_sCurCommand)) { m_setEntIds.insert(dbObj->objectId()); } int nFaceNum=pNode->GetInterfaceNum(); XPoint ptLocation=pNode->GetLocation(); for(int n=0; nGetInterface(n); UpdateInfo *info=NewAppendUpdateInfo(iFace.m_sysType); ASSERT(info!=NULL); if(iFace.m_faceType==TPipeInterface::kNodeLocation) { info->lstVertice.NewAppend(ptLocation); } } if(nChangeFlag&OBJ_CHANGE && m_lstChangedNode.Length()objectId(); if(!m_lstChangedNode.FindNode(&id, TNodeLocation::CompareObjectId)) m_lstChangedNode.Append(new TNodeLocation(id,ptLocation)); } } // cet 2018.7.4 add 更新管道遮挡(通过工具条下方的比例修改井的比例时,管道遮挡需要更新否则遮挡会出错) if (nChangeFlag&OBJ_CHANGE) { m_bWork = FALSE; // 避免修改是调用ObjectChanged int nFaceNum = pNode->GetInterfaceNum(); for(int i = 0; i < nFaceNum; ++i) { const TPipeInterface &iFace=pNode->GetInterface(i); OPENOBJ_BEGIN(iFace.m_idPipe, AcDb::kForWrite, TDbPipePrototype, pPipe); if(pPipe != NULL) { // 有时打开管道连接的节点会失败,可传入pNode解决 pPipe->ResetDrawSpeed(pNode); } OPENOBJ_END(); } m_bWork = TRUE; } } else if(dbObj->isKindOf(TDbPipePrototype::desc()) && !dbObj->isKindOf(TDbDuct::desc())) { TDbPipePrototype *pWire=(TDbPipePrototype *)dbObj; XPoint pt1, pt2; if(pWire->GetExtend(pt1,pt2)) { UpdateInfo *info=NewAppendUpdateInfo(pWire->GetSysType()); ASSERT(info!=NULL); AcDbObjectId id=dbObj->objectId(); if(nChangeFlag&OBJ_CHANGE) {//修改管线 info->AddPipe(id); } if(g_nCmdReactor!=CMD_ATTACHCHANGE){ UpdateRect(pt1,pt2,m_rectSysUpdate); // cet 2013.1.11 add 黏贴时记录更新区域时,使用的实体 if(IsUpdateSysRect(g_sCurCommand)) { m_setEntIds.insert(dbObj->objectId()); } info->lstVertice.NewAppend(pWire->StartPoint()); info->lstVertice.NewAppend(pWire->EndPoint()); if(pWire->m_ptOldStart!=pWire->m_ptOldEnd) { info->lstVertice.NewAppend(pWire->m_ptOldStart); info->lstVertice.NewAppend(pWire->m_ptOldEnd); XPoint ptMin = Min(pWire->m_ptOldStart, pWire->m_ptOldEnd); XPoint ptMax = Max(pWire->m_ptOldStart, pWire->m_ptOldEnd); if(pWire->IsVertical()) { XExtent ex=pWire->GetOldExtent(); ptMin -= ex; ptMax += ex; } m_rectSysUpdate.lowLeft = Min(ptMin, m_rectSysUpdate.lowLeft); m_rectSysUpdate.upRight = Max(ptMax, m_rectSysUpdate.upRight); } if(nChangeFlag&OBJ_CHANGE && info->lstChangedPipe.Length()lstChangedPipe.FindNode(&id,TEntRect::CompareObjectId)) { info->lstChangedPipe.Append(new TEntRect(id,pt1,pt2)); //真正变化的管线 } } } } } else if(dbObj->isKindOf(TDbPipeAttachment::desc())) { if(nChangeFlag&OBJ_CHANGE) { TDbPipeAttachment *pAttach=(TDbPipeAttachment *)dbObj; UpdateInfo *info=NewAppendUpdateInfo(pAttach->GetSysType()); ASSERT(info!=NULL); AcDbObjectId id=dbObj->objectId(); if(!info->lstAttachment.FindNode(&id, CompareObjectId)) { info->lstAttachment.Append(new AcDbObjectId(id)); } XPoint ptLocation=pAttach->GetLocation(); UpdateRect(ptLocation,ptLocation,m_rectAttachUpdate); // cet 2013.1.11 add 黏贴时记录更新区域时,使用的实体 if(IsUpdateSysRect(g_sCurCommand)) { m_setEntIds.insert(dbObj->objectId()); } } } } extern AOLAPI Acad::ErrorStatus GetEntFromBlockByClass(DList &lstObjects, AcRxClass *pClass, int CmpMethod, const TCHAR *pszBlk); BOOL GetBlkRecordMidPt(const TCHAR* szBlkName, double nScale, double nScaleY, XPoint &pt, double nInsBlkRotate) { AcDbBlockReference *pBlkRef = new AcDbBlockReference(); AcDbBlockTable* pBlockTable = NULL; AcDbObjectId recordId = NULL; acdbCurDwg()->getBlockTable(pBlockTable, AcDb::kForRead); #if ADS > 24 if(Acad::eOk != pBlockTable->getAt(szBlkName, recordId)) #else if(Acad::eOk != pBlockTable->getAt(szBlkName, recordId, AcDb::kForRead)) #endif return FALSE; pBlockTable->close(); pBlkRef->setBlockTableRecord(recordId); pBlkRef->setPosition(pt); pBlkRef->setRotation(nInsBlkRotate); pBlkRef->setScaleFactors(AcGeScale3d(nScale, nScaleY, 1)); AcDbExtents extents; pBlkRef->getGeomExtents(extents); AcGePoint3d pMax = extents.maxPoint(); AcGePoint3d pMin = extents.minPoint(); XPoint ptCen; ptCen[0] = (pMax[0] + pMin[0]) / 2; ptCen[1] = (pMax[1] + pMin[1]) / 2; ptCen[2] = 0; AcGeMatrix3d mat; mat.setToTranslation(AcGeVector3d(ptCen[0] - pt[0], ptCen[1] - pt[1], 0)); pt.TransformBy(mat); delete pBlkRef; return TRUE; } // 把圆 和 多线段 分解成为 直线和弧线 zxl 2012.10.30 add void TPipePerDocData::GetMinEntity(std::vector &vecIds) { int len = m_lstMatchEntity.Length(); PickSet ss(SS_FREE); for(int i=0;iIsVertical()) { XPoint ptS = ptCen; XPoint ptE = ptCen; ptS.z = pPipe->StartPoint().z; ptE.z = pPipe->EndPoint().z; AcDbLine *pLine = new AcDbLine; pLine->setStartPoint(ptS); pLine->setEndPoint(ptE); AcDbObjectId idC = AddToCurrentSpace(pLine, Adesk::kTrue); vecIds.push_back(idC); } else { continue; } OPENOBJ_END(); } else if(tgent.Is(_T("LWPOLYLINE"))) { XPoly2D poly(entTag); ss += id; int len = poly.Length(); for(int m=0;msetStartAngle(arc.GetStarAngle()); pArc->setEndAngle(arc.GetEndAngle()); pArc->setCenter(arc.GetCenterPt()); pArc->setRadius(arc.GetRadius()); AcDbObjectId idC = AddToCurrentSpace(pArc, Adesk::kTrue); vecIds.push_back(idC); } else { AcDbLine *pLine = new AcDbLine; pLine->setEndPoint(seg.EndPoint()); pLine->setStartPoint(seg.StartPoint()); AcDbObjectId idL = AddToCurrentSpace(pLine, Adesk::kTrue); vecIds.push_back(idL); } } } } ss.Erase(); } // 对点按照x轴大小排序 zxl 2012.10.30 add bool SortByX(const AcGePoint3d &pt1, const AcGePoint3d &pt2) { if (pt1.x > pt2.x) { return true; } return false; } // 对点按照y轴大小排序 zxl 2012.10.30 add bool SortByY(const AcGePoint3d &pt1, const AcGePoint3d &pt2) { if (pt1.y > pt2.y) { return true; } return false; } // 对弧线上的点 按照其到起点的距离排序 zxl 2012.10.30 add void ModifyPtsArry(const AcGePoint3dArray &arryPts, AcDbArc &arc1, std::vector &vecPts) { std::map mapPt; double dLen = 0.0; for (int i = 0; i < arryPts.length(); i++) { arc1.getDistAtPoint(arryPts[i], dLen); mapPt.insert(std::make_pair(dLen, arryPts[i])); } std::map::iterator itMap; for (itMap = mapPt.begin(); itMap !=mapPt.end(); itMap++) { vecPts.push_back(itMap->second); } } // 去掉容器中重复的点 zxl 2012.10.30 add void CheckPtInVec(std::vector &vecPts) { std::vector::iterator it; std::vector::iterator itOther; AcGePoint3d ptNow, ptOther; for (it = vecPts.begin(); it != vecPts.end();) { ptNow = *it; itOther = it; itOther++; for (;itOther != vecPts.end(); itOther++) { ptOther = *itOther; if (ptNow.distanceTo(ptOther) < 0.001) { it = vecPts.erase(it); break; } } if (itOther == vecPts.end()) { it++; } } } // 根据各个 直线和弧线 的交点, 重新构造 直线和弧线 zxl 2012.10.30 add void TPipePerDocData::GetIntsectEntity(const std::vector &vecIds, std::map > &mapEnt) { std::vector::const_iterator it; std::vector::const_iterator itSec; bool bIsNearXaxis = true; for (it = vecIds.begin(); it!= vecIds.end(); it++) { std::vector vecPts; AcDbObjectId id = *it; ads_name entTag; acdbGetAdsName(entTag, id); Entity tgent = entTag; if(tgent.Is(_T("LINE"))) { XLine line(entTag, 1); vecPts.push_back(line.GetStartPoint()); vecPts.push_back(line.GetEndPoint()); AcGeVector3d vt = line.GetStartPoint() - line.GetEndPoint(); double dAng2Xaxis = vt.angleTo(AcGeVector3d::kXAxis); if (dAng2Xaxis <0) { dAng2Xaxis += PI*2; } if ((dAng2Xaxis >= PI/4 && dAng2Xaxis <= 3*PI/4) || (dAng2Xaxis >= 5*PI/4 && dAng2Xaxis <= 7*PI/4)) { bIsNearXaxis = false; } else { bIsNearXaxis = true; } AcGePoint3dArray arryPts; for (itSec = vecIds.begin(); itSec != vecIds.end(); itSec++) { AcDbObjectId idSec = *itSec; if (id == idSec) { continue; } ads_name entTagSec; acdbGetAdsName(entTagSec, idSec); Entity tgentSec = entTagSec; arryPts.setLogicalLength(0); if(tgentSec.Is(_T("LINE"))) { XLine lineSec(entTagSec, 1); AcDbLine l1(line.GetStartPoint(), line.GetEndPoint()); AcDbLine l2(lineSec.GetStartPoint(), lineSec.GetEndPoint()); Acad::ErrorStatus es = l1.intersectWith(&l2, AcDb::kOnBothOperands, arryPts); } else if(tgentSec.Is(_T("ARC"))) { AcDbLine l1(line.GetStartPoint(), line.GetEndPoint()); XArc arc(entTagSec); AcDbArc arc1; arc1.setStartAngle(arc.GetStarAngle()); arc1.setEndAngle(arc.GetEndAngle()); arc1.setCenter(arc.GetCenterPt()); arc1.setRadius(arc.GetRadius()); l1.intersectWith(&arc1,AcDb::kOnBothOperands, arryPts); } for (int i = 0; i< arryPts.length(); i++) { vecPts.push_back(arryPts[i]); } } if (bIsNearXaxis) { std::sort(vecPts.begin(), vecPts.end(), SortByX); } else { std::sort(vecPts.begin(), vecPts.end(), SortByY); } } else if(tgent.Is(_T("ARC"))) { XArc arc(entTag); XPoint ptS, ptE; arc.GetStartPoint(ptS); arc.GetEndPoint(ptE); vecPts.push_back(ptS); AcDbArc arc1; arc1.setStartAngle(arc.GetStarAngle()); arc1.setEndAngle(arc.GetEndAngle()); arc1.setCenter(arc.GetCenterPt()); arc1.setRadius(arc.GetRadius()); AcGePoint3dArray arryPts, arryAllPts; for (itSec = vecIds.begin(); itSec != vecIds.end(); itSec++) { AcDbObjectId idSec = *itSec; if (id == idSec) { continue; } ads_name entTagSec; acdbGetAdsName(entTagSec, idSec); Entity tgentSec = entTagSec; arryPts.setLogicalLength(0); if(tgentSec.Is(_T("LINE"))) { XLine lineSec(entTagSec, 1); AcDbLine l2(lineSec.GetStartPoint(), lineSec.GetEndPoint()); Acad::ErrorStatus es = arc1.intersectWith(&l2, AcDb::kOnBothOperands, arryPts); } else if(tgentSec.Is(_T("ARC"))) { XArc arc11(entTagSec); AcDbArc arc12; arc12.setStartAngle(arc11.GetStarAngle()); arc12.setEndAngle(arc11.GetEndAngle()); arc12.setCenter(arc11.GetCenterPt()); arc12.setRadius(arc11.GetRadius()); Acad::ErrorStatus es = arc1.intersectWith(&arc12, AcDb::kOnBothOperands, arryPts); } for (int i = 0; i < arryPts.length(); i++) { arryAllPts.append(arryPts[i]); } } ModifyPtsArry(arryAllPts, arc1, vecPts); vecPts.push_back(ptE); } CheckPtInVec(vecPts); mapEnt.insert(std::make_pair(id, vecPts)); } } // 根据交点重新定义匹配实体 zxl 2012.10.29 add void TPipePerDocData::ModifyMatchEntity(std::map > &mapEnt) { std::vector vecIds; GetMinEntity(vecIds); GetIntsectEntity(vecIds, mapEnt); } //格式刷 void TPipePerDocData::DoMatchPipe() { if(!g_bIsStartMatchProp) return; std::map > mapEnt; ModifyMatchEntity(mapEnt); std::map >::iterator itMap; int len = m_lstMatchEntity.Length(); if(len < 1 || m_idMatchRes == NULL) return; PickSet ss(SS_FREE); // 格式刷支持各个直线弧线 多线段 相交时生成多通 的处理 zxl 2012.10.30 modify //for(int i=0;ifirst; ads_name entTag; acdbGetAdsName(entTag, id); Entity tgent = entTag; if(tgent.Is(_T("LINE"))){ XLine line(entTag, 1); ss += id; std::vector::iterator itPt; itPt = itMap->second.begin(); AcGePoint3d ptS = *itPt++; AcGePoint3d ptE; while (itPt != itMap->second.end()) { ptE = *itPt++; OPENOBJ_BEGIN(m_idMatchRes, AcDb::kForRead, TDbPipe, pPipe); if(pPipe) { TDbPipe *pNewPipe = (TDbPipe *)pPipe->clone(); pNewPipe->SetEndPoint(ptS); pNewPipe->SetStartPoint(ptE); pNewPipe->ResetAllShip(); AddToCurrentSpace(pNewPipe, Adesk::kTrue); } OPENOBJ_END(); ptS = ptE; } } else if(tgent.Is(_T("ARC"))){ //弧线重新处理 zxl 2012.10.30 modify // XArc arc(entTag); // ss += id; // XPoint ptArcS, ptArcE; // // arc.GetStartPoint(ptArcS); // // arc.GetEndPoint(ptArcE); // // arc.GetPoints(ptArcS, ptArcE); // OPENOBJ_BEGIN(m_idMatchRes, AcDb::kForRead, TDbPipe, pPipe); // if(pPipe){ // TDbPipe *pNewPipe = (TDbPipe *)pPipe->clone(); // pNewPipe->SetPoints(ptArcS, ptArcE, arc.Bulge()); // pNewPipe->ResetAllShip(); // AddToCurrentSpace(pNewPipe, Adesk::kTrue); // } // OPENOBJ_END(); XArc arc(entTag); AcGePoint3d ptCen = arc.GetCenterPt(); ss += id; std::vector::iterator itPt; itPt = itMap->second.begin(); XPoint ptS = *itPt++, ptE; XPoint ptEnd; arc.GetEndPoint(ptEnd); AcDbArc arc2; double dLenArc = 0.0, dLenOld = 0.0; arc2.setStartAngle(arc.GetStarAngle()); arc2.setEndAngle(arc.GetEndAngle()); arc2.setCenter(arc.GetCenterPt()); arc2.setRadius(arc.GetRadius()); arc2.getDistAtPoint(ptEnd, dLenArc); while (itPt != itMap->second.end()) { ptE = *itPt++; double dMidLen = 0.0; arc2.getDistAtPoint(ptE, dMidLen); dMidLen -= dLenOld; dLenOld += dMidLen; OPENOBJ_BEGIN(m_idMatchRes, AcDb::kForRead, TDbPipe, pPipe); if(pPipe) { TDbPipe *pNewPipe = (TDbPipe *)pPipe->clone(); pNewPipe->SetPoints(ptS, ptE, arc.Bulge() * dMidLen / dLenArc); pNewPipe->ResetAllShip(); AddToCurrentSpace(pNewPipe, Adesk::kTrue); } OPENOBJ_END(); ptS = ptE; } } else if(tgent.Is(_T("CIRCLE"))){ XCircle cir(entTag); XPoint ptCen = cir.GetCenterPt(); double dRadius = cir.GetRadius(); OPENOBJ_BEGIN(m_idMatchRes, AcDb::kForRead, TDbPipe, pPipe); if(pPipe && pPipe->IsVertical()){ ss += id; TDbPipe *pNewPipe = (TDbPipe *)pPipe->clone(); XPoint ptS = ptCen; XPoint ptE = ptCen; ptS.z = pPipe->StartPoint().z; ptE.z = pPipe->EndPoint().z; pNewPipe->SetEndPoint(ptE); pNewPipe->SetStartPoint(ptS); pNewPipe->SetRadius(dRadius / pPipe->GetPScale()); pNewPipe->ResetAllShip(); AddToCurrentSpace(pNewPipe, Adesk::kTrue); } OPENOBJ_END(); } //多线段 分解为 单个直线 弧线 进行处理 zxl 2012.10.30 del // else if(tgent.Is(_T("LWPOLYLINE"))){ // XPoly2D poly(entTag); // ss += id; // int len = poly.Length(); // for(int m=0;mclone(); // if(seg.Is(CURVE_ARC)){ // XArc arc = seg.GetArc(); // XPoint ptArcS, ptArcE; // arc.GetStartPoint(ptArcS); // arc.GetEndPoint(ptArcE); // // arc.GetPoints(ptArcS, ptArcE); // pNewPipe->SetPoints(ptArcS, ptArcE, arc.Bulge()); // } // else{ // pNewPipe->SetEndPoint(seg.EndPoint()); // pNewPipe->SetStartPoint(seg.StartPoint()); // } // pNewPipe->ResetAllShip(); // AddToCurrentSpace(pNewPipe, Adesk::kTrue); // } // OPENOBJ_END(); // } // } else if(tgent.Is(_T("INSERT"))){ // 将普通图块刷成上华设备,如果刷源插入点和接线点不一致,刷目标也这么处理 TCHAR szBlkName[256]; tgent.GetData(2, szBlkName); XPoint ptIns; double nAng(0),nScale(0),nScaleY(0); tgent.GetData(50, &nAng); tgent.GetData(10, ptIns); tgent.GetData(41, &nScale); tgent.GetData(42, &nScaleY); AcDbObjectId idBlk = GetBlockIdFromString(szBlkName); XPoint ptMid = ptIns; GetBlkRecordMidPt(szBlkName, nScale, nScaleY, ptMid, nAng); OPENOBJ_BEGIN(m_idMatchRes, AcDb::kForRead, TDbWell, pWell); if(pWell){ ss += id; AcDbObjectId id2 = pWell->GetBlock2d(); CString csBlkName2 = GetSymbolName(id2).cs(); XPoint ptIns2 = pWell->GetLocation(); XPoint ptMid2 = ptIns2; GetBlkRecordMidPt(csBlkName2, 1, 1, ptMid2, 0); TDbWell *pNewEq = (TDbWell *)pWell->clone(); pNewEq->SetBlock2d(idBlk); pNewEq->SetBlock3d(NULL); pNewEq->SetScale(fabs(nScale) / 100); if(nScale < 0) pNewEq->MirrorByY(TRUE); if(nScaleY < 0) pNewEq->MirrorByX(TRUE); pNewEq->SetAngle(nAng); pNewEq->SetInsert(ptIns); if(ptIns2 == ptMid2) pNewEq->SetLocation(ptIns); else pNewEq->SetLocation(ptMid); pNewEq->SetLabelLocation(XPoint()); pNewEq->EnableDrawLabel(TRUE, 1.5); AddToCurrentSpace(pNewEq, Adesk::kTrue); continue; } OPENOBJ_END(); OPENOBJ_BEGIN(m_idMatchRes, AcDb::kForRead, TDbEquipment, pEquip); if(pEquip){ ss += id; AcDbObjectId id2 = pEquip->GetBlock2d(); CString csBlkName2 = GetSymbolName(id2).cs(); XPoint ptIns2 = pEquip->GetLocation(); XPoint ptMid2 = ptIns2; GetBlkRecordMidPt(csBlkName2, 1, 1, ptMid2, 0); TDbEquipment *pNewEq = (TDbEquipment *)pEquip->clone(); pNewEq->SetBlock2d(idBlk); pNewEq->SetBlock3d(NULL); pNewEq->SetScale(fabs(nScale) / pEquip->GetPScale() * 100); if(nScale < 0) pNewEq->MirrorByY(TRUE); if(nScaleY < 0) pNewEq->MirrorByX(TRUE); pNewEq->SetAngle(nAng); pNewEq->SetInsert(ptIns); if(ptIns2 == ptMid2) pNewEq->SetLocation(ptIns); else pNewEq->SetLocation(ptMid); AddToCurrentSpace(pNewEq, Adesk::kTrue); } OPENOBJ_END(); } } ss.Erase(); } GEOAPI double g_nAcadVer; Acad::ErrorStatus AssureInCurrentView_New(const XPoint &ptLow, const XPoint &ptUp) { XPoint lowCorner, upCorner; AT_ScrCorner(lowCorner, upCorner); XPoint pt1=ptLow, pt2=ptUp; pt1.z=pt2.z=lowCorner.z; XPoint ptMin=Min(pt1, lowCorner), ptMax=Max(pt2, upCorner); Acad::ErrorStatus es=Acad::eNotApplicable; if(ptMin!=lowCorner || ptMax!=upCorner) { //点不在屏幕当前视图之内 //2004下UCS, AssureInCurrentView运行特别慢 2009-8-12 sr BOOL bIsUcs = FALSE; XPoint ptUcsLow = Wcs2Ucs(ptLow); XPoint ptUcsUp = Wcs2Ucs(ptUp); if(ptUcsLow != ptLow && ptUcsUp != ptUp) bIsUcs = TRUE; if(bIsUcs) SHads_command(RTSTR, _T("ZOOM"), RTSTR, _T("W"), RT3DPOINT, &ptUcsLow, RT3DPOINT, &ptUcsUp, RTNONE); else AssureInCurrentView(ptLow, ptUp); } return es; } extern BOOL WriteXdata(AcDbEntity *pEnt, const TCHAR*szName, const TCHAR*szValue); //优化SUBCLOSE, 将可能产生subClose无限调用的功能,转移到命令反应器执行 void TPipePerDocData::ResetCloseEntity() { int len = m_lstCloseEntity.Length(); if(len < 1) return; PickSet ss(SS_FREE); for(int i=0;iGetStartPt(); ptTurn = pDim->GetTurnPt(); pDim->GetNullIdFloorNum(sFloorNum); pDim->GetNullIdNum(sNum); pDim->GetDimTypeText(sMarkText); // cet 2014.6.20 add 代号信息 idPipe = pDim->GetVPipeId(); } OPENOBJ_END(); OPENOBJ_BEGIN(idPipe, AcDb::kForRead, TDbPipe, pPipe); if(pPipe && pPipe->IsVertical()) { ptPipeStart = pPipe->StartPoint(); ptPipeStart.z = 0; } OPENOBJ_END(); if(ptPipeStart != ptStart || idPipe == NULL)//如果发现立管标注所绑定的管线位置发生变化,则进行重新绑定 { ptStart = Wcs2Ucs(ptStart); ptTurn = Wcs2Ucs(ptTurn); RBList rbMak(RTDXF0, _T("ATS_PIPE"),NULL); PickSet ssSel(SS_FREE); XPoint ptTmp = ptStart; AcGeVector3d vt(ptTurn-ptStart); vt.normalize(); vt *= 200; ptTmp += vt; struct resbuf *pointlist = ads_buildlist(RTPOINT, &ptStart, RTPOINT, &ptTmp, NULL); AssureInCurrentView_New(Ucs2Wcs(ptStart), Ucs2Wcs(ptTmp)); ssSel.Get(_T("F"),pointlist,NULL,rbMak); ads_relrb(pointlist); AcGePoint3d ptST; AcDbObjectId idVPipe; AcDbObjectId id; for (long i = 0; i < ssSel.Length(); ++i) { OPENOBJ_BEGIN(ssSel[i], AcDb::kForRead, TDbPipe, pPipe); if(pPipe && pPipe->IsVertical()) { XPoint ptS = pPipe->StartPoint(); ptS.z = 0; // cet 2016.12.8 modify 两点比较有时误差稍大 // if(ptS != Ucs2Wcs(ptStart)) //ssSel.Length()=1才对,偶尔会碰到其他立管,应该过滤一下 // continue; if(ptS.Distance2d(Ucs2Wcs(ptStart)) > 0.001) { continue; } id = pPipe->objectId(); // cet 2014.6.20 add 将标注中的代号信息赋予管线 if (pPipe->upgradeOpen() == Acad::eOk) { WriteXdata(pPipe, _T("PIPE-MARK"), sMarkText); pPipe->downgradeOpen(); } } OPENOBJ_END(); OPENOBJ_BEGIN(tgent, AcDb::kForWrite, TDbVPipeDim, pDim); if(pDim) { pDim->SetVPipeId(id); pDim->SetDimVPipeNum(sNum, id); pDim->SetVPipeFloorNum(sFloorNum, id); } OPENOBJ_END(); } if(ssSel.Length() < 1) { OPENOBJ_BEGIN(tgent, AcDb::kForWrite, TDbVPipeDim, pDim); if(pDim) { pDim->SetVPipeId(NULL); } OPENOBJ_END(); } } } else if(tgent.Is(_T("ATS_PIPE"))) //修改管线标高,更新前后立管标高 { OPENOBJ_BEGIN(tgent, AcDb::kForRead, TDbPipe, pPipeMain); if(pPipeMain) { for(int i=0; i<2; i++) { AcDbObjectId idNode=pPipeMain->GetNode(i); OPENOBJ_BEGIN(idNode,AcDb::kForRead,TDbPipeNode,pNode); if(pNode!=NULL) { // 节点 if(!pNode->IsAutoLiving()) // 需自动生成的节点 continue; int nPipeNum=pNode->GetInterfaceNum(); if(nPipeNum > 2)//sr add 2004/9/15 当一根立管上有接2根不等高支管,当把底管标高升高超过高管,立管会出错 continue; int nVerNum=pNode->GetVerPipeNum(); if(nVerNum == 0) continue; if(nPipeNum-nVerNum > 1) continue; for(int j=0; jGetIPipe(j); if(idPipe != pPipeMain->objectId()) { OPENOBJ_BEGIN(idPipe,AcDb::kForRead,TDbPipePrototype,pPipe); if(pPipe != NULL) { if(pPipe->IsVertical()) { //立管 //立管两端都连接管线 if(!pPipe->IsBothPipesOk()) continue; //sr modify 2004/10/19 如果立管有一端接2根以上管线 for(int m=0; m<2; m++) { AcDbObjectId idNodeTmp=pPipe->GetNode(m); if(idNodeTmp == idNode) continue; OPENOBJ_BEGIN(idNodeTmp,AcDb::kForRead,TDbPipeNode,pNodeTmp); if(pNodeTmp!=NULL) { // 节点 int nPipeNumTmp = pNodeTmp->GetInterfaceNum(); if(nPipeNumTmp > 2){ XPoint ptNode1 = pNode->GetLocation(); XPoint ptNode2 = pNodeTmp->GetLocation(); XVector3D vec1 = ptNode1 - ptNode2; ptNode1.z = pPipeMain->StartPoint().z; XVector3D vec2 = ptNode1 - ptNode2; vec1.Normalize(); vec2.Normalize(); //当前要联动的立管,另一端接2根以上管线,如果修改之后方向与之前一致,允许修改;否则不允许修改 if(vec1 != vec2) return; } } OPENOBJ_END(); } // sr modify 2004/10/19 ////////////////////////////////////////////////////////////////////////////// // 改变立管的标高 XPoint &ptStart = pPipe->StartPoint(); XPoint &ptEnd = pPipe->EndPoint(); const XPoint &ptNode = pNode->GetILocation(j); // 改变立管的标高 XPoint &ptThisSide = (i==0) ? pPipeMain->StartPoint() : pPipeMain->EndPoint(); if(ptNode==ptStart) { if(pPipe->upgradeOpen()==Acad::eOk) { pPipe->assertWriteEnabled(); ptStart.z = ptThisSide.z; pPipe->downgradeOpen(); } } else if(ptNode==ptEnd) { if(pPipe->upgradeOpen()==Acad::eOk) { pPipe->assertWriteEnabled(); ptEnd.z = ptThisSide.z; pPipe->downgradeOpen(); } } } } OPENOBJ_END(); } } } OPENOBJ_END(); } } OPENOBJ_END(); } } m_lstCloseEntity.Reset(); } void TPipePerDocData::ApplyUpdates() { if(!m_bWork) m_lstCloseEntity.Reset(); if(!m_bWork || !g_bDwgBegin || !acdbCurDwg()) return; ResetCloseEntity(); // cet 2015.7.3 add 初始化管线系统索引初始值 PipeSystemProcessor::InitSysInedex(); // cet 2013.1.10 add 黏贴时重新计算更新区域 CalcUpdateSysRect(); XPushMemVar vAction(g_bMonitorDbAction, FALSE); XPushMemVar vReactor(g_nCmdReactor,CMD_UPDATE); m_rectAttachUpdate.SetElevation(0); m_rectSysUpdate.SetElevation(0); BOOL bUpdateSys = !IsRectEmpty(m_rectSysUpdate); DList lstUpdatePipe;// 更新区域(扩大了搜索范围)内的管线 if(bUpdateSys) {// 更新管线与管线、管线与节点的关系 UpdateSystem(lstUpdatePipe); } // 重新验证管线与所属的附件的关系 BOOL bLess=ExtendInBox2d(m_rectAttachUpdate.lowLeft,m_rectAttachUpdate.upRight,m_rectSysUpdate); if(bLess) m_rectAttachUpdate=m_rectSysUpdate; if(!bUpdateSys || !bLess) ValidateAttachships(); else ValidateAttachships(&lstUpdatePipe); ResetDocCmdGlobals(); } // 更新管线系统管线与节点关系(同时更新pipe和rect) void TPipePerDocData::UpdateSystem(DList &lstUpdatePipe) { XRectAngle rectUpdate=m_rectSysUpdate;//需要重新验证遮挡关系的区域 GetEntRectFromBlock(lstUpdatePipe,TDbPipePrototype::desc(),m_rectSysUpdate); BOOL bOptimize = GetChangedNum()>m_nOptimize; //是否优化 DList lstUpdateNode;// 更新区域(扩大了搜索范围)内的节点 if(!bOptimize) { GetNodeFromBlock(lstUpdateNode,m_rectSysUpdate); DoDeepSearch(lstUpdatePipe,lstUpdateNode,rectUpdate); } // 更新管线与管线、管线与节点的关系 for(int i=0; iNeedUpdateSys()) { //if(i>0 || (i==0&&bOptimize)) { // 节点更新 GetNodeFromBlock(lstUpdateNode,m_rectSysUpdate); // } ModifyPipeAtCorner(info,lstUpdatePipe,lstUpdateNode,bOptimize); } } // 处理更新后的管线和节点的管线关系 GetEntRectFromBlock(lstUpdatePipe,TDbPipePrototype::desc(),rectUpdate); ValidateHideships(lstUpdatePipe,rectUpdate); UpdatePoolAngle(lstUpdatePipe); // cet 2016.4.27 add 更新化粪池角度 UpdatePipePoints(lstUpdatePipe);// cet 2016.4.26 add 更新管道端点,以便与端点处的化粪池等相连 UpdateWellInfo(lstUpdatePipe); // cet 2016.9.6 add 更新井数据 ResetDrawSpeed(lstUpdatePipe);//如果涉及到非管线和节点时,应考虑放到适当的位置 } // 重新验证管线与所属的附件的关系 void TPipePerDocData::ValidateAttachships(const DList* pPipes) const { // 一、更新管线:验证管线与附件的配属关系 for(int n=0; nValidateAttachship(); OPENOBJ_END(); } } // 二、更新附件:验证管线和附件的配属关系 // 1、验证原有的管线和附件的配属关系 DList lstAttachment; for(n=0; nValidateAttachship()) { lstAttachment.Append(new AcDbObjectId(pAttach->objectId())); } } OPENOBJ_END(); } } // 2、验证还没有配属的附件与管线的关系 int nAttach=lstAttachment.Length(); if(nAttach>0) { // 加速:边框相交才验证管线和附件的关系 DList lstAttachPipe;//附件变化区域的管线 BOOL bReConstruct = pPipes==NULL; if(bReConstruct) { GetEntRectFromBlock(lstAttachPipe,TDbPipePrototype::desc(),m_rectAttachUpdate); } // DList &lstUpdatePipe = bReConstruct ? lstAttachPipe : * pPipes; // sr removed 2006-7-3 DList &lstUpdatePipe = bReConstruct ? lstAttachPipe : *((DList*)pPipes); int nPipe=lstUpdatePipe.Length();//管线数 double dExtents=_distSnap*500;//简化处理不是采用GetExtents XPoint ptExtents(dExtents,dExtents,0); for(int i=0; iGetLocation(); XRectAngle rcAttach(ptLocation-ptExtents,ptLocation+ptExtents); for(int j=0; jValidateAttachship(pipeRect.id); } } } OPENOBJ_END(); } } /*for(n=0; n lstPipe; for(int i=0; iGetSysType()==info->sysType) lstPipe.Append(pId); } OPENOBJ_END(); } for(i=0; ilstAttachment.Length(); i++) { AcDbObjectId &id = *info->lstAttachment[i]; OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbPipeAttachment, pAttach); if(pAttach!=NULL) { //pAttach->ValidateAttachship(lstPipe);//管线和附件的配属关系 if(pAttach->IsCheckSysType()) pAttach->ValidateAttachship(lstPipe); else pAttach->ValidateAttachship(lstUpdatePipe); } OPENOBJ_END(); } }*/ } // 重新初始化显示加速,目前只有管线二维加速(目前只有节点和管线有关) void TPipePerDocData::ResetDrawSpeed(const DList &lstPipe) const { int nCount = lstPipe.Length(); for(int i=0; iResetDrawSpeed(); } OPENOBJ_END(); } } // 重新验证调整遮挡关系 void TPipePerDocData:: ValidateHideships(const DList &lstPipe,const XRectAngle &rectUpdate) const { // rectUpdate.Make(); DList lstPipe0; int nCount = lstPipe.Length(); for(int i=0; iIsVertical()/* && pPipe->Is(CURVE_LINE)*/) { lstPipe0.Append(new TEntRect(pipeRect)); if(pipeRect.InBox(rectUpdate)) pPipe->RemoveHidePipes();// 区域内删除所有的遮挡关系,重新建立 else pPipe->RemoveHidePipes(&rectUpdate);// 仅删除区域内的遮挡关系 } else { pPipe->RemoveHidePipes(); } } OPENOBJ_END(); } // 确定区域内管线的相互遮挡关系 nCount = lstPipe0.Length(); for(i=0; iValidateHideship(jPipe.id); } } OPENOBJ_END(); } } void TPipePerDocData::AttachReactor() { ASSERT(m_pDoc); if(!m_pDbReactor) { AcDbDatabase *pDb=m_pDoc->database(); ASSERT(pDb!=NULL); m_pDbReactor=new TPipeDbReactor; pDb->addReactor(m_pDbReactor); } if(!m_pInputReactor) { m_pInputReactor = new TPipeInputReactor; m_pDoc->inputPointManager()->addInputContextReactor(m_pInputReactor); } } void TPipePerDocData::DetachReactor() { ASSERT(m_pDoc); AcDbDatabase *pDb=m_pDoc->database(); if(!pDb) return; if(m_pDbReactor) { pDb->removeReactor(m_pDbReactor); delete m_pDbReactor; m_pDbReactor=NULL; } if(m_pInputReactor) { m_pDoc->inputPointManager()->removeInputContextReactor(m_pInputReactor); delete m_pInputReactor; m_pInputReactor=NULL; } } int TPipePerDocData::CompareForFind(const TPipePerDocData *pDoc1, const void *pDoc2) { ASSERT(pDoc1 && pDoc2); if(pDoc1->m_pDoc==pDoc2) return 0; return 1; } // End TPipePerDocData ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // TPipeAppDocGlobals TPipeAppDocGlobals::TPipeAppDocGlobals() { m_pDocReactor = new TPipeDocReactor(); acDocManager->addReactor(m_pDocReactor); } void TPipeAppDocGlobals::InitDocGlobals(AcApDocument *pDoc) { #if ADS > 19 if (NULL == pDoc) return ; // 2016-6-20 cq pDoc为NULL会弹出断言 CAD2016平台关闭最后一个文档 默认激活一个 NULL 文档 没有意义 (Autodesk内部没有处理) #endif ASSERT(pDoc); TPipePerDocData *pData=g_pTPipeAppDocGlobals->FindNode(pDoc, TPipePerDocData::CompareForFind); if(!pData) g_pTPipeAppDocGlobals->Append(new TPipePerDocData(pDoc)); } void TPipeAppDocGlobals::RemoveDocGlobals(AcApDocument *pDoc) { ASSERT(pDoc); TPipePerDocData *pData=g_pTPipeAppDocGlobals->FindNode(pDoc, TPipePerDocData::CompareForFind); if(pData) { pData->DetachReactor(); g_pTPipeAppDocGlobals->Remove(); } } void TPipeAppDocGlobals::OnUnloadApp() { if(m_pDocReactor) { acDocManager->removeReactor(m_pDocReactor); delete m_pDocReactor; m_pDocReactor=NULL; } } void InitAppDocGlobals(BOOL bTrue) { if(bTrue) { ASSERT(g_pTPipeAppDocGlobals==NULL); g_pTPipeAppDocGlobals = new TPipeAppDocGlobals(); g_pTPipeAppDocGlobals->InitDocGlobals(curDoc()); } else { ASSERT(g_pTPipeAppDocGlobals!=NULL); g_pTPipeAppDocGlobals->OnUnloadApp(); delete g_pTPipeAppDocGlobals; g_pTPipeAppDocGlobals = NULL; } } ////////////////////////////////////// // 取得当前文档的全局变量 TPipePerDocData * GetCurPipeDocData() { if(!g_pTPipeAppDocGlobals) return NULL; TPipePerDocData *pData=g_pTPipeAppDocGlobals->FindNode(curDoc(), TPipePerDocData::CompareForFind); //ASSERT(pData); return pData; } /********************* XDbWallCmdReacotor ******************************/ // Global definition TPipeCmdReactor * TPipeCmdReactor::g_pCmdReactor=NULL; TPipeCmdReactor::TPipeCmdReactor() { ASSERT(g_pCmdReactor==NULL); g_pCmdReactor=this; } TPipeCmdReactor::~TPipeCmdReactor() { } // 建立命令的监测 void TPipeCmdReactor::Attach() { if(!g_pCmdReactor) acedEditor->addReactor(new TPipeCmdReactor()); } // 除去命令的监测 void TPipeCmdReactor::Detach() { if(g_pCmdReactor) { acedEditor->removeReactor(g_pCmdReactor); delete g_pCmdReactor; g_pCmdReactor=NULL; } } void TPipeCmdReactor::ResetAll() { TPipePerDocData *pData = GetCurPipeDocData(); //ASSERT(pData); if(pData) { pData->ResetDocCmdGlobals(); pData->EnableWork(TRUE); } } void TPipeCmdReactor::lispWillStart(const TCHAR * firstLine) { if(_tcsicmp(firstLine, _T("!")) == 0) return; ASSERT(firstLine && _tcslen(firstLine)>=3); XString sLispExpr; sLispExpr=firstLine; _tcsupr(sLispExpr); if(sLispExpr[1]==_T('C') && sLispExpr[2]==_T(':')) { TCHAR &cLast=sLispExpr[sLispExpr.Length()-1]; // remove right ')' cLast=EOS; BeginUserCommand(&sLispExpr[3], FALSE); } else { //BeginUserCommand(NULL, FALSE); } } void TPipeCmdReactor::lispEnded() { // 适当的放掉一些命令,如改变比例,可以提速 //... XString sCmdNames; VERIFY(xg_getvar(_T("CMDNAMES"), sCmdNames)==RTNORM); if(!sCmdNames) { EndUserCommand(NULL, FALSE); } } // 双击监测 zxl 2013.12.12 add void TPipeCmdReactor::beginDoubleClick(const AcGePoint3d& clickPoint) { RBList rbMask(RTDXF0, _T("ATS_SPACE"), NULL); PickSet ss(SS_FREE); ss.Get(_T("X"), NULL, NULL, rbMask); ss.Redraw(4); AcEditorReactor::beginDoubleClick(clickPoint); } void TPipeCmdReactor::endWblock( AcDbDatabase* pTo ) { AcEditorReactor::endWblock(pTo); // 执行wblock命令时无法自动将TDbPsConfig存在新数据库中 // 通过以下函数实现此操作,以保证线宽等设置在新数据 // 库中仍然有效 cet 2014.12.11 add InitConfigToNewDatabase(pTo); } //得到本图图块记录列表 void GetCurBlkRecList(XStringList &lstBlk) { AcDbBlockTable* pBlockTable = NULL; acdbCurDwg()->getBlockTable(pBlockTable, AcDb::kForRead); AcDbBlockTableIterator* pBlockIterator=NULL; Acad::ErrorStatus es = pBlockTable->newIterator(pBlockIterator); ASSERT(es==Acad::eOk && pBlockIterator!=NULL); for (pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step()) { AcDbBlockTableRecord *pRec=NULL; if(pBlockIterator->getRecord(pRec, AcDb::kForRead)==Acad::eOk && pRec) { TCHAR *str = NULL; pRec->getName(str); CString csRecordName = str; if(csRecordName.Find(_T("*")) < 0 && csRecordName != _T("_ArchTick")) { lstBlk.Append(tstrnew(csRecordName)); } delete str; pRec->close(); } } delete pBlockIterator; pBlockTable->close(); } void DoClipboardRenameBlk() { if (OpenClipboard(NULL)) { UINT nStart = 0; TCHAR szName[256]; while(TRUE) { nStart = EnumClipboardFormats(nStart); if (nStart == 0) break; GetClipboardFormatName(nStart,szName,256); CString csAcadFormat; #if (ADS==18) csAcadFormat = _T("AutoCAD.r18"); #elif (ADS==17) csAcadFormat = _T("AutoCAD.r17"); #elif (ADS==16) csAcadFormat = _T("AutoCAD.r16"); #elif (ADS==15) csAcadFormat = _T("AutoCAD.r15"); #endif if (_tcscmp(szName, csAcadFormat) == 0)//其他16,17,18 ... { AcApDocument *pDoc=curDoc(); CString csCurFile = pDoc->fileName(); HANDLE hClipboardData = GetClipboardData(nStart); ClipboardInfo *pchData = (ClipboardInfo*)GlobalLock(hClipboardData); CString csTempFile = pchData->szTempFile; CString csSourceFile = pchData->szSourceFile; if(csCurFile == csSourceFile || csTempFile == _T("") || csSourceFile == _T("")) //本图内复制 break; CString csFileName = GetFileName(XString(csSourceFile)); int idx2 = csFileName.Find(_T(".")); if(idx2 > -1) {//发现了,都去掉.后缀 csFileName = csFileName.Left(idx2); } AcDbDatabase dwgDb(false, true); #if ADS > 20 if(dwgDb.readDwgFile((const TCHAR*)csTempFile, AcDbDatabase::OpenMode::kForReadAndAllShare, false)!=Acad::eOk) break; #else if (dwgDb.readDwgFile((const TCHAR*)csTempFile, _SH_DENYNO, false) != Acad::eOk) break; #endif // modify by cq 2017-01-04 支持CAD2017 XStringList lstBlkRec; GetCurBlkRecList(lstBlkRec); AcDbBlockTable *pBlockTable = NULL; Acad::ErrorStatus es = dwgDb.getBlockTable(pBlockTable, AcDb::kForRead); if(!pBlockTable) break; ASSERT(es==Acad::eOk); AcDbBlockTableIterator* pBlockIterator=NULL; es = pBlockTable->newIterator(pBlockIterator); ASSERT(es==Acad::eOk && pBlockIterator!=NULL); for (pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step()) { AcDbBlockTableRecord *pRec=NULL; if(pBlockIterator->getRecord(pRec, AcDb::kForWrite)==Acad::eOk && pRec) { TCHAR *str = NULL; pRec->getName(str); CString csRecordName = str; delete str; if(csRecordName.Find(_T("*")) < 0 && csRecordName.Find(_T("_")) < 0 && csRecordName.Find(_T("-")) < 0 && csRecordName.Find(_T("$")) < 0 )//2011-6-24 sr 忽略上华$图块 { if(lstBlkRec.Index(csRecordName) > -1) { TCHAR chText[256]; CString csTmp; csTmp.Format(_T("\n发现【%s】同名图块,是否忽略?[全部忽略(1)/本块忽略(2)/图块改名(3)]<全部忽略>: "), csRecordName); ads_getstring(NULL, csTmp, chText); if(_tcsicmp(chText, _T("1")) == 0 || _tcsicmp(chText, _T("")) == 0) { pRec->close(); break; } if(_tcsicmp(chText, _T("3")) == 0) { CString csNewBlkName = csFileName + _T("-") + csRecordName; pRec->setName(csNewBlkName); } } } pRec->close(); } } delete pBlockIterator; pBlockTable->close(); dwgDb.saveAs(csTempFile); break; } } CloseClipboard(); } } #ifdef RECORD_CMD_TIME extern void RecordCmdTime(const CString &sCmd); // cet 2012.4.23 add 统计命令执行次数 #endif // 命令开始时初始化 2011-5-9 sr 增加复制粘贴重名块的问题 void TPipeCmdReactor::commandWillStart(const TCHAR * cmdStr) { #ifdef RECORD_CMD_TIME RecordCmdTime(cmdStr); // cet 2012.4.23 add 统计命令执行次数 #endif int nCmdActive=0; xg_getvar(_T("CMDACTIVE"), &nCmdActive); if(nCmdActive==1) { BeginUserCommand(cmdStr, TRUE); if(_tcsicmp(cmdStr, _T("matchprop"))==0) { g_bIsStartMatchProp = FALSE; long len = g_ssPickFirst.Length(); if(len == 1){ Entity ent = g_ssPickFirst[0L]; if(ent.Is(_T("ATS_PIPE")) || ent.Is(_T("ATS_EQUIPMENT")) || ent.Is(_T("ATS_WELL"))){ g_bIsStartMatchProp = TRUE; AcDbObjectId id; acdbGetObjectId(id, ent); TPipePerDocData *pData = GetCurPipeDocData(); if(pData) pData->m_idMatchRes = id; } } else g_bIsStartMatchProp = TRUE; } else if(_tcsicmp(cmdStr, _T("PASTECLIP"))==0 && g_nProductId == 14) // 粘贴 只有给排水软件有效 { DoClipboardRenameBlk(); } } } PickSet & DocGetPickGrip2() { TPipePerDocData *p=GetCurPipeDocData(); ASSERT(p); PickSet ee; if(p!=NULL) return p->m_ssPickGrip; else return ee; } void TPipeCmdReactor::pickfirstModified() { int cvport=0; xg_getvar(_T("CVPORT"), &cvport); if(cvport==1) //图纸空间,运行此函数会崩溃 070117 SR return; XString sCmdName; xg_getvar(_T("CMDNAMES"), sCmdName); if( _tcsicmp(sCmdName, _T("COPYCLIP"))==0) //这个命令受影响,取消检测 return; if( _tcsicmp(sCmdName, _T("ARRAY"))==0 || _tcsicmp(sCmdName, _T("ARRAY-ARRAY"))==0) //这个命令受影响,取消检测 return; // if(!g_bSPipeFDir) // return; //2009-2-29 沈睿增加楼层框 // 2010-11-19,mcl 增加地热盘管 RBList mask(RTDXF0, _T("ATS_PIPE,ATS_FLOORRECT,ATS_FLOORPIPE"), NULL); RBList mask2(RTDXF0, _T("ATS_FLOORPIPE, ATS_FLOORRECT"), NULL); PickSet &ssGrip=DocGetPickGrip2(); PickSet ssTemp(SS_FREE); ssTemp += ssGrip; if(g_bSPipeFDir) ssTemp.BaseFilter(mask); //上次加亮的管线 else ssTemp.BaseFilter(mask2); //上次加亮的管线 ssGrip.Free(); long lenff1 = ssTemp.Length(); PickSet ss(SS_FREE); //本图加亮的全部对象 if(ss.Get(_T("I"))==RTNORM) { long lenSS = ss.Length(); ss.BaseFilter(mask); ssGrip += ss; //保存加亮纪录 PickSet ssInc(SS_FREE), ssDec(SS_FREE); ssInc += ss; ssInc -= ssTemp; //获得新增加加亮的房间 ssDec += ssTemp; ssDec -= ss; //获得取消加亮的房间 long len1 = ssDec.Length(); long len2 = ssInc.Length(); TDocAutoLock vLock; for(long i=0L; iSetHighlight(FALSE); } OPENOBJ_END(); } else if(ent.Is(_T("ATS_FLOORRECT"))) { OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbFloorRect, pPipe); if(pPipe){ pPipe->SetShow(FALSE); } OPENOBJ_END(); } else if(ent.Is(_T("ATS_FLOORPIPE"))) // mcl add 2010.11.19,地热选中时显示出口箭头 { OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbFloorPipe, pFPipe); if(pFPipe){ pFPipe->SetHighlight(FALSE); } OPENOBJ_END(); } } for(i=0L; iSetHighlight(TRUE); } OPENOBJ_END(); } else if(ent.Is(_T("ATS_FLOORRECT"))) { OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbFloorRect, pPipe); if(pPipe){ pPipe->SetShow(TRUE); } OPENOBJ_END(); } else if(ent.Is(_T("ATS_FLOORPIPE"))) // mcl add 2010.11.19,地热选中时显示出口箭头 { OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbFloorPipe, pFPipe); if(pFPipe){ pFPipe->SetHighlight(TRUE); } OPENOBJ_END(); } } } else{ TDocAutoLock vLock; for(long i=0L; iSetHighlight(FALSE); } OPENOBJ_END(); } else if(ent.Is(_T("ATS_FLOORRECT"))) { OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbFloorRect, pPipe); if(pPipe){ pPipe->SetShow(FALSE); } OPENOBJ_END(); } else if(ent.Is(_T("ATS_FLOORPIPE"))) // mcl add 2010.11.19,地热选中时显示出口箭头 { OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbFloorPipe, pFPipe); if(pFPipe){ pFPipe->SetHighlight(FALSE); } OPENOBJ_END(); } } } return; } void TPipeCmdReactor::commandCancelled(const TCHAR * cmdStr) { TPipePerDocData *pCurDocData=GetCurPipeDocData(); ASSERT(pCurDocData!=NULL); if (NULL != pCurDocData) // mcl add 2010.07.13 pCurDocData->ResetCloseEntity(); } void TPipeCmdReactor::commandFailed(const TCHAR * cmdStr) { } // ACAD Bug: 当命令结束时还有没有close的实体, 因此可能需要强制close // to do: 如何判断一个用户命令的真正结束 void TPipeCmdReactor::commandEnded(const TCHAR *cmdStr) { int nCmdActive; xg_getvar(_T("CMDACTIVE"), &nCmdActive); // ASSERT(GetCurPipeDocData()); if(nCmdActive==1) { if(_tcsicmp(cmdStr, _T("xsbg"))==0 || _tcsicmp(cmdStr, _T("gxcx"))==0 || _tcsicmp(cmdStr, _T("options"))==0 || //给排水 _tcsicmp(cmdStr, _T("QUIT"))==0 || _tcsicmp(cmdStr, _T("END"))==0 || _tcsicmp(cmdStr, _T("OPEN"))==0 || _tcsicmp(cmdStr, _T("NEW"))==0 || _tcsicmp(cmdStr, _T("SHADE"))==0 || _tcsicmp(cmdStr, _T("RENDER"))==0 || _tcsicmp(cmdStr, _T("REDRAW"))==0 || _tcsicmp(cmdStr, _T("REGEN"))==0 || // _tcsstr(cmdStr, _T("TCHSCALE"))|| //_tcsstr(cmdStr, _T("UpdateAllLinkage")) || sr removed 2005-4-12 设备比例随出图比例,如果修改比例,遮挡关系必须重新计算 _tcsicmp(cmdStr, _T("UNDO"))==0 || _tcsicmp(cmdStr, _T("REDO"))==0 || _tcsicmp(cmdStr, _T("U"))==0 || _tcsicmp(cmdStr, _T("AUDIT"))==0 || _tcsicmp(cmdStr, _T("CHPROPERTIES"))==0 || _tcsicmp(cmdStr, _T("INSERT"))==0 ) { } else { EndUserCommand(cmdStr, TRUE); } } } ///////////////////////////////////////////// // 开始用户的命令, 包括ARX和ADS void TPipeCmdReactor::BeginUserCommand(const TCHAR *pszCmd, BOOL bIsArxCommand) { ResetAll(); } ///////////////////////////////////////////// // 结束用户的命令, 包括ARX和ADS void TPipeCmdReactor::EndUserCommand(const TCHAR *szCmd, BOOL bIsArxCommand) { XPushMemVar vMonitor(g_bMonitorDbAction, FALSE); XString sCmdNames(256); if(szCmd) sCmdNames=szCmd; if(_tcsicmp(sCmdNames, _T("INSERT"))!=0 && _tcsicmp(sCmdNames, _T("QSAVE"))!=0 && _tcsicmp(sCmdNames, _T("PREVIEW"))!=0 && _tcsicmp(sCmdNames, _T("PLOT"))!=0 && _tcsicmp(sCmdNames, _T("SAVE"))!=0 && _tcsicmp(sCmdNames, _T("SAVEAS"))!=0 && g_bDwgBegin) { //制止对INSERT命令进行处理 BOOL bSpeedUp=FALSE; TPipePerDocData *pCurDocData=GetCurPipeDocData(); ASSERT(pCurDocData!=NULL); if (NULL != pCurDocData) // mcl add judge 2010.07.13 { g_sCurrentCmd = sCmdNames; // cet 2012.11.16 add 保存命令名 // 有待修改 ... int nChanged = pCurDocData->GetChangedNum(); BOOL bSpeedNum = nChanged>pCurDocData->GetOptimize() && nChanged>200; BOOL bSpeedCmd = _tcsicmp(sCmdNames, _T("MOVE"))==0 || _tcsicmp(sCmdNames, _T("ROTATE"))==0 || _tcsicmp(sCmdNames, _T("COPYCLIP"))==0 || _tcsicmp(sCmdNames, _T("COPY"))==0 || _tcsicmp(sCmdNames, _T("ARRAY"))==0 || _tcsicmp(sCmdNames, _T("MIRROR"))==0 || _tcsicmp(sCmdNames, _T("PASTECLIP"))==0; if(bSpeedNum && bSpeedCmd) { // 部分平台该提示出现乱码 //int nAnswer=AfxMessageBox(_T("有大量的对象进行操作, 您是否在进行整体操作?\nYes: 整体操作则无需处理构件关系\nNo: 局部操作则需要处理构件关系,需要一定的等待时间."), MB_YESNO); int nAnswer=AfxMessageBox(_T("有大量的对象进行操作, 您是否在进行整体操作?\r\nYes: 整体操作则无需处理构件关系\r\nNo: 局部操作则需要处理构件关系,需要一定的等待时间."), MB_YESNO); bSpeedUp=(nAnswer==IDYES); } if(_tcsicmp(sCmdNames, _T("matchprop"))==0) { //格式刷 pCurDocData->DoMatchPipe(); g_bIsStartMatchProp = FALSE; } if(!bSpeedUp && sCmdNames != _T("HLMJ")) {//ZXL 2014.02.12 MODIFY HLMJ命令不需要更新管线操作 pCurDocData->ApplyUpdates(); } else { actrTransactionManager->queueForGraphicsFlush(); //flushGraphics(); } g_sCurrentCmd.Empty(); // cet 2012.11.16 add 清除命令名 } } ResetAll(); } // End TPipeCmdReactor ///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// //TPipeDbReactor //处理发生变化的实体(Modified, Erased, Appended) void TPipeDbReactor::ObjectChanged(const AcDbObject *dbObj, int nChgFlag) { XString sCmdNames; xg_getvar(_T("CMDNAMES"), sCmdNames); if( _tcsicmp(sCmdNames, _T("QSAVE"))==0 || _tcsicmp(sCmdNames, _T("SAVE"))==0 || _tcsicmp(sCmdNames, _T("SAVEAS"))==0 || _tcsicmp(sCmdNames, _T("PLOT"))==0 || _tcsicmp(sCmdNames, _T("PREVIEW"))==0) return; TPipePerDocData *pData = GetCurPipeDocData(); ASSERT(pData); if(pData) { pData->ObjectChanged(dbObj, nChgFlag); // cet 2014.7.4 del 有时会造成其他不必要错误的发生 // (如 矩形布置 关闭喷淋图层再打开喷淋图层会导致喷头无故删除) // // zxl 2013.12.20 add 特性表或cad中修改出图比例时,更新设备和管的遮挡关系 // if (dbObj->isKindOf(TDbEquipment::desc()) && sCmdNames == _T("")) // { // pData->ApplyUpdates(); // } } } // 当实体从当前DWG中删除时的处理 void TPipeDbReactor::objectErased(const AcDbDatabase* dwg, const AcDbObject* dbObj, Adesk::Boolean pErased) { if(!g_bMonitorDbAction || !g_bDwgBegin) return; if(dwg==acdbCurDwg()) { ObjectChanged(dbObj, pErased==Adesk::kTrue? OBJ_DELETE:OBJ_APPEND); } } #if(ADS>15) CString GetLayerChnName(const TCHAR *szLayer) { CString csRet = szLayer; XString fullFile; if(FindFile(_T("layerdef.dat"), fullFile)) { FILE *fp=fopen(_AS(fullFile), "r"); if(!fp) return csRet; while(!feof(fp)) { char sBuf[256]=""; TCHAR cName[256]=_T(""), eName[256]=_T(""); fgets(sBuf, 255, fp); if(sBuf[0]) { CT_strnth(TString(sBuf), 1, cName); CT_strnth(TString(sBuf), 2, eName); } if(_tcscmp(szLayer, eName) == 0){ csRet = cName; fclose(fp); return csRet; } } fclose(fp); } return csRet; } void TLayerPane::Init(bool bTrue) { AcApStatusBar *pBar = acedGetApplicationStatusBar(); if (pBar) { if (bTrue) { pBar->RemoveDefaultPane(ACSBPANE_APP_MODEMACRO); pBar->Insert(1,this); SetStyle(ACSB_NORMAL); Update(); } else { pBar->Remove(this); } } } void TLayerPane::Update() { XString xsLayName; xg_getvar(_T("CLAYER"), xsLayName); CString csText = GetLayerChnName((const TCHAR*)xsLayName); SetText((const TCHAR*)csText); acedGetApplicationStatusBar()->Update(); } #endif // ADS>15 void TPipeDbReactor::headerSysVarChanged(const AcDbDatabase* db, const TCHAR* name, Adesk::Boolean bSuccess) { XString xsLayName; if(_tcsicmp(name, _T("CLAYER")) == 0 && g_bIsCustomizeVer) { #if ADS>15 xg_getvar(_T("CLAYER"), xsLayName); AcApStatusBar *pBar = acedGetApplicationStatusBar(); if (pBar) { AcPane *pPane = pBar->GetPane(1); if (pPane != NULL) { pPane->SetVisible(TRUE); CString csText = GetLayerChnName((const TCHAR*)xsLayName); pPane->SetText((const TCHAR*)csText); pBar->Update(); } } #endif } } // 当实体添加到当前DWG时的处理函数 void TPipeDbReactor::objectAppended(const AcDbDatabase* dwg, const AcDbObject* dbObj) { //sr modify 如果格式刷刷出新管线,虽然g_bMonitorDbAction=FALSE,也要执行下去 if((!g_bMonitorDbAction && !g_bIsStartMatchProp) || !g_bDwgBegin) return; if(dwg==acdbCurDwg()) { ObjectChanged(dbObj, OBJ_APPEND); } } // 当墙体修改时,接收消息 void TPipeDbReactor::objectModified(const AcDbDatabase* dwg, const AcDbObject* dbObj) { if(!g_bMonitorDbAction || !g_bDwgBegin) return; UpdatePipeFittingLayer(dwg, dbObj); // cet 2016.7.12 管道连接件图层颜色随管道 if(dwg==acdbCurDwg()) { ObjectChanged(dbObj, OBJ_CHANGE); } } // 建立墙体数据库的监测 void TPipeDbReactor::Attach() { TPipePerDocData *pData=GetCurPipeDocData(); if(pData) pData->AttachReactor(); } // 除去墙体数据库的监测 void TPipeDbReactor::Detach() { TPipePerDocData *pData=GetCurPipeDocData(); if(pData) pData->DetachReactor(); } Acad::ErrorStatus GetSafeSelection(PickSet &ss, const XPoint &ptLow, const XPoint &ptUp, const AcRxClass *pClass,BOOL bCrossing/*=TRUE*/) { Acad::ErrorStatus esRet=Acad::eNotApplicable; XDbBlockTableRec objMSpace; if(!objMSpace) return esRet; /*XPoint ptMid; Midpoint(ptLow, ptUp, ptMid);*/ XRectAngle rect(ptLow, ptUp); //CRect rect0(long(ptLow.x), long(ptLow.y), long(ptUp.x), long(ptUp.y)); AcDbBlockTableRecordIterator* pBlockIterator=NULL; Acad::ErrorStatus es = objMSpace.m_pBlockTableRec->newIterator(pBlockIterator); ASSERT(es==Acad::eOk && pBlockIterator!=NULL); for (pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step()) { AcDbEntity *pEntity=NULL; es = pBlockIterator->getEntity(pEntity, AcDb::kForRead); if(es!=Acad::eOk) continue; ASSERT(pEntity); XDbObject vTemp(pEntity); //不处理不可见的实体 if (pEntity->visibility() == AcDb::kInvisible) { continue; } //AcRxClass *pRxInfo=pEntity->isA(); if(!pClass || pEntity->isKindOf(pClass)) { //用于加速目的,光标移动时自动捕捉时使用 if(!bCrossing && pEntity->isKindOf(AcDbCurve::desc())) { AcDbCurve *pCurve=AcDbCurve::cast(pEntity); XPoint ptCurve,ptMid; Midpoint(ptLow, ptUp, ptMid); if(pCurve->getClosestPointTo(ptMid, ptCurve)==Acad::eOk && ptCurve.x>rect.lowLeft.x && ptCurve.xrect.lowLeft.y && ptCurve.yobjectId())==Acad::eOk); ss += ent; esRet=Acad::eOk; } } else { BOOL bExtent = TRUE; if(pEntity->isKindOf(TDbPipeNode::desc())) {//增加对不可见的节点的处理 TDbPipeNode *pNode=(TDbPipeNode *)pEntity; if(pNode!=NULL) { if(!(pNode->IsVisible())) { bExtent = FALSE; XPoint ptLocation = pNode->GetLocation(); if(PointInBox02d(ptLocation,rect)) { Entity ent; if (acdbGetAdsName(ent.name, pEntity->objectId())==Acad::eOk) { ss += ent; esRet = Acad::eOk; } } } } } if(bExtent) {//可见节点或者管线 AcDbExtents ext; if(pEntity->getGeomExtents(ext)==Acad::eOk) { XPoint ptExtMin=ext.minPoint(), ptExtMax=ext.maxPoint(); ptExtMin.z=ptExtMax.z=0; if(ExtendInBox02d(ptExtMin,ptExtMax,rect)) { Entity ent; if (acdbGetAdsName(ent.name, pEntity->objectId())==Acad::eOk) { ss += ent; esRet = Acad::eOk; } } } } } } } delete pBlockIterator; return esRet; } // 求管线系统的外包 static int GetPSExtend(const PickSet &ss,XPoint &ptLow,XPoint &ptUp) { int nRet=RTNORM; XPoint ptLowNode,ptUpNode; BOOL bHasInvNode=FALSE; PickSet ssOther(SS_FREE); long lCount=ss.Length(); for(long i=0; ivisibility()!=AcDb::kInvisible) { if(pEntity->isKindOf(TDbPipeNode::desc())) { TDbPipeNode *pNode=(TDbPipeNode *)pEntity; if(pNode!=NULL) { if(!(pNode->IsVisible())) { XPoint ptLocation=pNode->GetLocation(); if(!bHasInvNode) { ptLowNode = ptLocation; ptUpNode = ptLocation; bHasInvNode=TRUE; } else { ptLowNode = Min(ptLowNode,ptLocation); ptUpNode = Max(ptUpNode,ptLocation); } continue; } } } ssOther += ent; } OPENOBJ_END(); } BOOL bOther=ssOther.Length()>0; if(bOther) { nRet = ssOther.GetExtend(ptLow,ptUp); } if (bHasInvNode) { if(bOther) { ptLow = Min(ptLow,ptLowNode); ptUp = Max(ptUp,ptUpNode); } else { ptLow = ptLowNode; ptUp = ptUpNode; } } return nRet; } // cet 2015.7.3 modify 重写函数自动生成的节点现在改为全部删除,再重新生成 // 要更新: // 1. 发生变化的管线 // 2. 发生变化前关联的管线和节点 // 3. 发生变化后关联的管线和节点 // 旧位置可能发生合并管段;新位置可能发生断开管段 // 旧位置要更新节点(包括删除隐式);新位置要更新节点(包括新增隐式节点) // 4. 发生变化的节点 // 5. 发生变化前关联的管线(解除关联) // 6. 发生变化后关联的管线(新增关联) // void TPipePerDocData:: // ModifyPipeAtCorner(const UpdateInfo *info,const DList &lstPipe, // const DList& lstNode,BOOL bOptimize) // { // if(info==NULL || (lstPipe.Length()<=0 && lstNode.Length()<=0)) // return; // // XPointList lstCorners,lstNeedBreak;// 复制一份 // for(int idx=0; idxlstVertice.Length(); idx++) { // lstCorners.Append(new XPoint(info->lstVertice[idx])); // } // for(idx=0; idxlstNeedBreak.Length(); idx++) { // lstNeedBreak.Append(new XPoint(info->lstNeedBreak[idx])); // } // // PickSet ssDel(SS_FREE); //被合并的管线 // TSearchPipeSys aSearch(bOptimize); // aSearch.InitStart(info->sysType,lstPipe,lstNode,lstNeedBreak); // try { // aSearch.MergePipes(lstCorners, ssDel); //先尽量合并管段, 只处理发生变化的位置 // aSearch.BreakPipes(lstCorners,TRUE); //在断点处打断管线 // aSearch.BreakPipes(lstNeedBreak,FALSE); // } catch(...) { // ssDel.Erase(); // adsout << /*UMSG*/ _T("\n出现了例外情况!"); // acedPostCommandPrompt(); // return; // } // long lendel = ssDel.Length(); // if(lendel == 0 && lstPipe.Length() == 2){ // TEntRect kPipe1 = lstPipe[0]; // TEntRect kPipe2 = lstPipe[1]; // XPoint p1, p2, p3, p4; // TPipeSys::SysType sys1, sys2; // OPENOBJ_BEGIN(kPipe1.id,AcDb::kForRead,TDbPipePrototype,pPipe); // if(pPipe!=NULL){ // p1 = pPipe->StartPoint(); // p2 = pPipe->EndPoint(); // sys1 = pPipe->GetSysType(); // } // OPENOBJ_END(); // OPENOBJ_BEGIN(kPipe2.id,AcDb::kForRead,TDbPipePrototype,pPipe); // if(pPipe!=NULL){ // p3 = pPipe->StartPoint(); // p4 = pPipe->EndPoint(); // sys2 = pPipe->GetSysType(); // } // OPENOBJ_END(); // if(p1 == p3 && p2 == p4) // ssDel +=kPipe2.id; // } // //////////////////////////////////////////////////////////////////////////////// // //以下2009-4-10 sr 添加,处理立管标注更新绑定的问题. 当2立管合并后,立管标注所绑定的立管id有可能无效,需要重新绑定 // //2009-11-9 删除本段,安工提出p选的时候,总是会选中本图全部立管编号 // /* if(aSearch.m_idMapMergeVPipe.GetCount() > 0) // { // RBList Mask(RTDXF0, _T("ATS_VPIPEDIM"), NULL); // PickSet ssVPipeDim(SS_FREE); // ssVPipeDim.Get(_T("X"), NULL, NULL, Mask); // POSITION pos = aSearch.m_idMapMergeVPipe.GetStartPosition(); // while (pos != NULL) // { // AcDbObjectId idPipe2, idPipe1; //idPipe2被删除了,idPipe1保留了 // long lPipe2, lPipe1; // aSearch.m_idMapMergeVPipe.GetNextAssoc(pos, lPipe2, lPipe1); // idPipe2.setFromOldId(lPipe2); // idPipe1.setFromOldId(lPipe1); // for(long m=0;mGetVPipeId(); // //如果立管标注绑定立管ID刚好是要准备删除的立管 // if(idDim == idPipe2) // { // if (pDim->upgradeOpen() == Acad::eOk) // { // pDim->SetVPipeId(idPipe1); // pDim->downgradeOpen(); // } // break; // } // } // OPENOBJ_END(); // } // } // }*/ // //////////////////////////////////////////////////////////////////////////////// // ssDel.Erase(); // // // 过滤出需要局部更新的范围 // XPoint ptSnap(PS_SNAP,PS_SNAP); // XRectAngle box(m_rectSysUpdate.lowLeft-ptSnap,m_rectSysUpdate.upRight+ptSnap); // aSearch.DelSoleNodeFromDb(info->sysType,&box); //移除孤独隐式节点 // aSearch.AddAutoNodeToDb(&box); //新增加的隐式节点加入DWG // aSearch.DelDupNodeFromDb(box); // aSearch.DelDupPipeFromDb(box); // //aSearch.MergePipes(lstCorners,ssDel); // //ssDel.Erase(); // // aSearch.UpdateNodeLinkage(info->sysType, &box); // aSearch.UpdatePipeLinkage(&box); // // if(ssDel.Length()) { //清除预先选中的物体,以避免崩溃的错误 // PickSet gSet(SS_FREE), pSet(SS_FREE); // if(GetPickFirst(gSet, pSet)==RTNORM) { // if(gSet.Length() || pSet.Length()) { // acedPostCommand(_T("\33")); // } // } // } // } // 要更新: // 1. 发生变化的管线 // 2. 发生变化前关联的管线和节点 // 3. 发生变化后关联的管线和节点 // 旧位置可能发生合并管段;新位置可能发生断开管段 // 旧位置要更新节点(包括删除隐式);新位置要更新节点(包括新增隐式节点) // 4. 发生变化的节点 // 5. 发生变化前关联的管线(解除关联) // 6. 发生变化后关联的管线(新增关联) void TPipePerDocData:: ModifyPipeAtCorner(const UpdateInfo *info,const DList &lstPipe, const DList& lstNode,BOOL bOptimize) { if(info==NULL || (lstPipe.Length()<=0 && lstNode.Length()<=0)) return; XPointList lstCorners,lstNeedBreak;// 复制一份 for(int idx=0; idxlstVertice.Length(); idx++) { lstCorners.Append(new XPoint(info->lstVertice[idx])); } for(idx=0; idxlstNeedBreak.Length(); idx++) { lstNeedBreak.Append(new XPoint(info->lstNeedBreak[idx])); } PickSet ssDel(SS_FREE); //被合并的管线 TSearchPipeSys aSearch(bOptimize); aSearch.InitStart(info->sysType,lstPipe,lstNode,lstNeedBreak); // cet 2015.7.3 add 删除所有隐式节点 XPoint ptSnap(PS_SNAP,PS_SNAP); XRectAngle box(m_rectSysUpdate.lowLeft-ptSnap,m_rectSysUpdate.upRight+ptSnap); // aSearch.DelAllNodeFromDb(&box); try { aSearch.MergePipes(lstCorners, ssDel, false); //先尽量合并管段, 只处理发生变化的位置 aSearch.BreakPipes(lstCorners,TRUE); //在断点处打断管线 aSearch.BreakPipes(lstNeedBreak,FALSE); aSearch.MergePipes(lstCorners, ssDel, true); // 打断后,再次合并管道(第一次合并时,管道间存在重叠的管道为实现合并) } catch(...) { ssDel.Erase(); adsout << /*UMSG*/ _T("\n出现了例外情况!"); acedPostCommandPrompt(); return; } long lendel = ssDel.Length(); if(lendel == 0 && lstPipe.Length() == 2){ TEntRect kPipe1 = lstPipe[0]; TEntRect kPipe2 = lstPipe[1]; XPoint p1, p2, p3, p4; TPipeSys::SysType sys1, sys2; OPENOBJ_BEGIN(kPipe1.id,AcDb::kForRead,TDbPipePrototype,pPipe); if(pPipe!=NULL){ p1 = pPipe->StartPoint(); p2 = pPipe->EndPoint(); sys1 = pPipe->GetSysType(); } OPENOBJ_END(); OPENOBJ_BEGIN(kPipe2.id,AcDb::kForRead,TDbPipePrototype,pPipe); if(pPipe!=NULL){ p3 = pPipe->StartPoint(); p4 = pPipe->EndPoint(); sys2 = pPipe->GetSysType(); } OPENOBJ_END(); if(p1 == p3 && p2 == p4) ssDel +=kPipe2.id; } // cet 2016.10.17 modify 当前选择集只剔除需要删除的实体,否则一些命令如过滤选择等无法正常选中选择实体 // acedSSSetFirst(NULL, NULL); // cet 2016.9.14 add 清除预先选中的物体,以避免删除实体时产生崩溃的错误 if (ssDel.Length() > 0) { PickSet ss(SS_FREE), ss1(SS_FREE|SS_CREATE); resbuf *gset=NULL, *pset=NULL; if (ads_ssgetfirst(&gset, &pset)==RTNORM) { if (gset != NULL) { if (gset->restype == RTPICKS) { PickSet ss0(0); ss0 = gset->resval.rlname; ss += ss0; ss0.Free(); } ads_relrb(gset); } if (pset != NULL) { if (pset->restype == RTPICKS) ads_ssfree(pset->resval.rlname); ads_relrb(pset); } } ss -= ssDel; ads_sssetfirst(ss, ss1); } ssDel.Erase(); aSearch.DelSoleNodeFromDb(info->sysType,&box); //移除孤独隐式节点 aSearch.AddAutoNodeToDb(&box); aSearch.DelDupNodeFromDb(box); aSearch.DelDupPipeFromDb(box); aSearch.UpdateNodeLinkage(info->sysType, &box); aSearch.UpdatePipeLinkage(&box); if(ssDel.Length()) { //清除预先选中的物体,以避免崩溃的错误 PickSet gSet(SS_FREE), pSet(SS_FREE); if(GetPickFirst(gSet, pSet)==RTNORM) { if(gSet.Length() || pSet.Length()) { acedPostCommand(_T("\33")); } } } } //2013-1-11 cet add 复制粘贴之前 重新计算更新RECT void TPipePerDocData::CalcUpdateSysRect() { if(IsUpdateSysRect(g_sCurrentCmd)) { if (m_setEntIds.empty()) { return; } // 获得当前模型空间的实体id std::set setModelSpaceIds; if (!GetEntIdsFromModelSpace(setModelSpaceIds)) { return; } std::set::iterator itNoFind = setModelSpaceIds.end(); // 清空更新区域 m_rectSysUpdate.lowLeft = m_rectSysUpdate.upRight = XPoint(); std::set::iterator it, itEnd = m_setEntIds.end(); XPoint pt1, pt2, ptLocation; for (it = m_setEntIds.begin(); it != itEnd; ++it) { AcDbEntity *pEnt = NULL; acdbOpenObject(pEnt, *it, AcDb::kForRead); if (pEnt != NULL) { if (setModelSpaceIds.find(*it) == itNoFind)//CET 粘贴的时候在原点创建了实体,但不在模型空间中,因此将其过滤掉。 { pEnt->close(); continue; } if(pEnt->isKindOf(TDbPipeNode::desc()) && !pEnt->isKindOf(TDbDuctNode::desc())) //节点变化 { TDbPipeNode *pNode=(TDbPipeNode *)pEnt; if(pNode->GetExtents(pt1, pt2) == Acad::eOk && !(pt1==XPoint() && pt2==XPoint())) { UpdateRect(pt1, pt2, m_rectSysUpdate); } } else if(pEnt->isKindOf(TDbPipePrototype::desc()) && !pEnt->isKindOf(TDbDuct::desc())) { TDbPipePrototype *pWire=(TDbPipePrototype *)pEnt; if(pWire->GetExtend(pt1, pt2)) { UpdateRect(pt1, pt2, m_rectSysUpdate); } } else if(pEnt->isKindOf(TDbPipeAttachment::desc())) { TDbPipeAttachment *pAttach=(TDbPipeAttachment *)pEnt; ptLocation = pAttach->GetLocation(); UpdateRect(ptLocation, ptLocation, m_rectAttachUpdate); } pEnt->close(); } } } } bool TPipePerDocData::GetEntIdsFromModelSpace( std::set &setEntIds ) { setEntIds.clear(); AcDbBlockTableRecord *pRecord = NULL; AcDbBlockTable* pBlockTable = NULL; acdbCurDwg()->getBlockTable(pBlockTable, AcDb::kForRead); if(pBlockTable == NULL) return false; if(Acad::eOk != pBlockTable->getAt(ACDB_MODEL_SPACE, pRecord, AcDb::kForRead)) { pBlockTable->close(); return false; } pBlockTable->close(); AcDbBlockTableRecordIterator *pIterator = NULL; pRecord->newIterator(pIterator); pRecord->close(); for(pIterator->start(); !pIterator->done(); pIterator->step()) { AcDbEntity *pEnt = NULL; pIterator->getEntity(pEnt, AcDb::kForRead); if (pEnt != NULL) { setEntIds.insert(pEnt->objectId()); pEnt->close(); } } delete pIterator; return true; } bool TPipePerDocData::IsUpdateSysRect(const CString &sCmd) { if (_tcscmp(sCmd, _T("PASTECLIP")) == 0 || _tcscmp(sCmd, _T("COPY")) == 0) { return true; } return false; } void TPipePerDocData::UpdatePipePoints(DList &lstUpdatePipe) { int nCount = lstUpdatePipe.Length(); for(int i = 0; i < nCount; i++) { OPENOBJ_BEGIN(lstUpdatePipe[i]->id,AcDb::kForRead,TDbPipePrototype,pPipe); if(pPipe!=NULL) { if (pPipe->GetBulge() > 0.001 || pPipe->IsVertical()) // 不处理弧形管道、立管 { continue; } UpdatePipeLink(pPipe, 0); UpdatePipeLink(pPipe, 1); } OPENOBJ_END(); } } void TPipePerDocData::UpdatePipeLink(TDbPipePrototype *pPipe, int nPos) { AcDbObjectId id = pPipe->GetNode(nPos); // 无效id if (!id.isValid() || id.isErased()) { return; } // 处理管道与化粪池的连接 TDbPool *pPool = NULL; acdbOpenObject(pPool, id, AcDb::kForRead); if (pPool != NULL) { // 管道端点与化粪池接口无误 XPoint pt = nPos == 0 ? pPipe->StartPoint() : pPipe->EndPoint(); int nNum = pPool->GetInterfaceNum(); for (int i = 0; i < nNum; ++i) { if (pPool->GetInterface(i).m_idPipe == pPipe->id() && pt.Distance2d(pPool->GetInterface(i).m_ptLocation) < 0.001 && pPool->GetLocation().Distance2d(pPool->GetInterface(i).m_ptLocation) > 0.001) { pPool->close(); return; } } // 求化粪池与管道交点 AcGePoint3d ptS = pPipe->StartPoint(); AcGePoint3d ptE = pPipe->EndPoint(); //AcDbLine line1 = AcDbLine(ptS, ptE); AcDbLine line1(ptS, ptE); // modify by cq 2017-01-04 支持CAD2017 AcDbVoidPtrArray entSet; XExplodeStream dc(entSet); pPool->ExplodeOrDraw2d(dc); int nLen = entSet.length(); AcGePoint3d pt1, pt2; XPoint ptNear; double dMinDist = -1; for(int n = 0; n < nLen; n++) { AcDbEntity *pEnt=(AcDbEntity *)entSet[n]; if (pEnt->isKindOf(AcDbBlockReference::desc())) { AcDbVoidPtrArray arrExplode; pEnt->explode(arrExplode); for (int i = 0; i < arrExplode.length(); ++i) { AcDbEntity *pTemp = (AcDbEntity*)arrExplode[i]; if(pTemp->isKindOf(AcDbCurve::desc())) { AcDbCurve *pCurve = (AcDbCurve*)pTemp; AcGePoint3d pt; pCurve->getPointAtDist(0.0, pt); ptS.z = pt.z; ptE.z = pt.z; line1.setStartPoint(ptS); line1.setEndPoint(ptE); AcGePoint3dArray arrPoint; line1.intersectWith(pCurve, AcDb::kOnBothOperands, arrPoint); for (int j = 0; j < arrPoint.length(); ++j) { AcGePoint3d ptInt = arrPoint.at(j); // 取距离管道另一端最近的交点 if (dMinDist < 0.0 || ptInt.distanceTo(nPos == 1 ? ptS : ptE) < dMinDist) { dMinDist = ptInt.distanceTo(nPos == 1 ? ptS : ptE); ptNear = ptInt; } } } } ReleaseEntSet(arrExplode); } } ReleaseEntSet(entSet); // 更改管道端点及化粪池接口信息 if (dMinDist > 0.001) { XCurveSegment seg = pPipe->GetCurve(); XPoint ptRet; seg.ProjectToMe(ptNear, ptRet); if (pPipe->upgradeOpen() == Acad::eOk) { if (nPos == 0) { pPipe->SetStartPoint(ptRet); } else { pPipe->SetEndPoint(ptRet); } pPipe->downgradeOpen(); } if (pPool->upgradeOpen() == Acad::eOk) { bool bFlag = false; int nNum = pPool->GetInterfaceNum(); // 更新接口位置 for (int i = 0; i < nNum; ++i) { if (pPool->GetInterface(i).m_idPipe == pPipe->id()) { pPool->SetILocation(i, ptNear); bFlag = true; break; } } // 添加接口 if (!bFlag) { AcGeVector3d vtDir = pPipe->StartPoint() - pPipe->EndPoint(); if (nPos == 0) { vtDir *= -1; } vtDir.normalize(); // 优先使用无用接口 bFlag = false; for (int i = 0; i < nNum; ++i) { AcDbObjectId idTemp = pPool->GetInterface(i).m_idPipe; if (!idTemp.isValid() || idTemp.isErased()) { pPool->SetIPipe(i, pPipe->id()); pPool->SetILocation(i, ptNear); pPool->SetIDirection(i, XVector3D(vtDir)); bFlag = true; break; } } // 创建新接口 if (!bFlag) { TPipeInterface iFace; iFace.m_sysType = pPipe->GetSysType(); iFace.m_faceType = TPipeInterface::kNodeLocation; iFace.m_idPipe = pPipe->id(); iFace.m_ptLocation = ptNear; CString sTip; sTip.Format(_T("%d"), nNum + 1); pPool->AddInterface(sTip, ptNear, XVector3D(vtDir)); } } pPool->downgradeOpen(); } } pPool->close(); } } void TPipePerDocData::UpdatePoolAngle(TDbPool *pPool, AcDbObjectId id1, AcDbObjectId id2) { // 两根管道方向 AcGeVector3d vtDir1, vtDir2; TDbPipe *pPipe1 = NULL, *pPipe2 = NULL; acdbOpenObject(pPipe1, id1, AcDb::kForRead); if (pPipe1 != NULL) { vtDir1 = pPipe1->StartPoint() - pPipe1->EndPoint(); pPipe1->close(); } acdbOpenObject(pPipe2, id2, AcDb::kForRead); if (pPipe2 != NULL) { vtDir2 = pPipe2->StartPoint() - pPipe2->EndPoint(); pPipe2->close(); } // 管道不平行 vtDir1.z = 0.0; vtDir2.z = 0.0; AcGeTol tol; tol.setEqualVector(0.001); if (!vtDir1.isParallelTo(vtDir2)) { return; } // 管道是否与化粪池垂直 double dAngle = pPool->GetAngle(); AcGeVector3d vtPool = AcGeVector3d::kXAxis; vtPool.rotateBy(dAngle, AcGeVector3d::kZAxis); if (vtPool.isPerpendicularTo(vtDir1, tol) || vtPool.isParallelTo(vtDir1, tol)) // 垂直或平行 { return; } // 调整化粪池角度,使其与管道垂直 dAngle = AcGeVector3d::kXAxis.angleTo(vtDir1, AcGeVector3d::kZAxis); if (fabs(dAngle - 2 * PI) < 0.001) { dAngle = 0.0; } else if (dAngle > PI - 0.001) { dAngle -= PI; } if (pPool->upgradeOpen() == Acad::eOk) { pPool->SetAngle(dAngle); pPool->downgradeOpen(); } } void TPipePerDocData::UpdatePoolAngle(DList &lstUpdatePipe) { // 获得化粪池池关联的管道 std::map > mapPool; std::vector vecId, vecTempId; int nCount = lstUpdatePipe.Length(); for(int i = 0; i < nCount; i++) { OPENOBJ_BEGIN(lstUpdatePipe[i]->id,AcDb::kForRead,TDbPipePrototype,pPipe); if(pPipe!=NULL) { if (pPipe->GetBulge() > 0.001 || pPipe->IsVertical()) // 不处理弧形管道、立管 { continue; } vecId.clear(); vecId.push_back(pPipe->GetNode(0)); vecId.push_back(pPipe->GetNode(1)); for (int j = 0; j < vecId.size(); ++j) { TDbPool *pPool = NULL; acdbOpenObject(pPool, vecId[j], AcDb::kForRead); if (pPool != NULL) { if (mapPool.count(pPool->id()) == 1) { mapPool[pPool->id()].push_back(pPipe->id()); } else { vecTempId.clear(); vecTempId.push_back(pPipe->id()); mapPool.insert(std::make_pair(pPool->id(), vecTempId)); } pPool->close(); } } } OPENOBJ_END(); } // 调整角度 std::map >::iterator it, itEnd = mapPool.end(); for (it = mapPool.begin(); it != itEnd; ++it) { if (it->second.size() != 2) { continue; } TDbPool *pPool = NULL; acdbOpenObject(pPool, it->first, AcDb::kForRead); if (pPool != NULL) { UpdatePoolAngle(pPool, it->second[0], it->second[1]); pPool->close(); } } } void TPipePerDocData::UpdateWellInfo(DList &lstUpdatePipe) { bool bUpdate = false; int nCount = lstUpdatePipe.Length(); for(int i = 0; i < nCount; i++) { OPENOBJ_BEGIN(lstUpdatePipe[i]->id, AcDb::kForRead, TDbPipe, pPipe); if(pPipe!=NULL) { for (int j = 0; j < 2; ++j) { OPENOBJ_BEGIN(pPipe->GetNode(j), AcDb::kForRead, TDbWell, pWell); if (pWell != NULL) { int nNum = pWell->GetInterfaceNum(); for (int k = 0; k < nNum; ++k) { const TPipeInterface &face = pWell->GetInterface(k); CString sTemp = face.m_sSysLabel.cs(); if (face.m_idPipe == lstUpdatePipe[i]->id && !sTemp.IsEmpty()) // 井连接着当前管道, 并且井中存在管道标高值 { XPoint ptLoc = pWell->GetLocation(); double dPipeEle = ptLoc.Distance2d(pPipe->StartPoint()) < ptLoc.Distance2d(pPipe->EndPoint()) ? pPipe->StartPoint().z : pPipe->EndPoint().z; if (DocGetCurMeterUnitDraw()) // 米单位 { dPipeEle -= (pPipe->OuterDn() - pPipe->GetPipeThick() * 2) * 0.5 * 0.001; } else // 毫米单位 { dPipeEle -= (pPipe->OuterDn() - pPipe->GetPipeThick() * 2) * 0.5; dPipeEle *= 0.001; } double dOldEle = _tstof(face.m_sSysLabel); if (fabs(dOldEle - dPipeEle) > 0.001 && pWell->upgradeOpen() == Acad::eOk) // 数据改变了,更新井数据 { CString sText; sText.Format(_T("%.3ft"), dPipeEle); pWell->SetISysLabel(k, sText); pWell->downgradeOpen(); bUpdate = true; } break; } } } OPENOBJ_END(); } } OPENOBJ_END(); } // 更新井标注 if (bUpdate) { PickSet ssObj(SS_FREE); if(GetEntByDxf(ssObj, _T("ATS_WELLDIM"), 1) == Acad::eOk) { UpdateGraphic(ssObj); } acedRedraw(NULL, 0); } }