3582 lines
106 KiB
C++
3582 lines
106 KiB
C++
#include "stdafx.h"
|
||
#include "actrans.h"
|
||
|
||
|
||
#include "PipeWireMonitor.h"
|
||
#include "DbPipe.h"
|
||
#include "SearchPipeSys.h"
|
||
//#include "DbObject.h"
|
||
#include <DbSpace.h>
|
||
#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 <algorithm>
|
||
#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<AcDbObjectId> &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; i<m_lstUpdate.Length(); i++) {
|
||
const UpdateInfo &info=m_lstUpdate[i];
|
||
nChangedNum += info.lstAttachPipe.Length();
|
||
}
|
||
return nChangedNum;
|
||
}
|
||
|
||
TPipePerDocData::UpdateInfo *
|
||
TPipePerDocData::FindUpdateInfo(TPipeSys::SysType st)
|
||
{
|
||
for(int i=0; i<m_lstUpdate.Length(); i++) {
|
||
UpdateInfo *info=m_lstUpdate[i];
|
||
// cet 2015.7.3 modify 不再按管线系统分类处理管线
|
||
// if(info->sysType==st)
|
||
// return info;
|
||
return info;
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
BOOL TPipePerDocData::
|
||
GetNodeFromBlock(DList<TNodeLocation> &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<TEntRect> &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; k<nCount; k++) {
|
||
if(*lstVertice[k]==ptBreak) {
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
else if(nStytle==1) {
|
||
for(int k=0; k<nCount; k++) {
|
||
if(*lstVertice[k]==ptBreak) {
|
||
lstVertice.Remove();
|
||
break;
|
||
}
|
||
}
|
||
lstNeedBreak.NewAppend(ptBreak);
|
||
}
|
||
}
|
||
|
||
// 查找并增加在管段上的节点的需要更新的信息
|
||
void TPipePerDocData::
|
||
UpdateNodeInfos(const TDbPipePrototype *pChangedPipe,const TDbPipeNode *pNode)
|
||
{
|
||
XPoint ptLocation=pNode->GetLocation();
|
||
int nFlag = ptLocation&(*pChangedPipe);
|
||
if(nFlag==PR_INSIDE) {
|
||
int nFaceNum=pNode->GetInterfaceNum();
|
||
for(int n=0; n<nFaceNum; n++) {
|
||
const TPipeInterface &iFace=pNode->GetInterface(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<TEntRect> &lstPipe,
|
||
const DList<TNodeLocation> &lstNode,
|
||
XRectAngle &rectUpdate)
|
||
{
|
||
// 变化的管线
|
||
for(int n=0; n<m_lstUpdate.Length(); n++) {
|
||
UpdateInfo *info=m_lstUpdate[n];
|
||
for(int i=0; i<info->lstChangedPipe.Length(); i++) {
|
||
TEntRect &pipeChanged = *info->lstChangedPipe[i];
|
||
OPENOBJ_BEGIN(pipeChanged.id,AcDb::kForRead,TDbPipePrototype,pChangedPipe);
|
||
if(pChangedPipe!=NULL)
|
||
{
|
||
// 管线
|
||
for(int k=0; k<lstPipe.Length(); k++) {
|
||
const TEntRect &kPipe=lstPipe[k];
|
||
if(pipeChanged.Intersect(kPipe) && pipeChanged.id!=kPipe.id) {
|
||
OPENOBJ_BEGIN(kPipe.id,AcDb::kForRead,TDbPipePrototype,pPipe);
|
||
if(pPipe!=NULL)
|
||
if(UpdatePipeInfos(pChangedPipe,pPipe)) {
|
||
const XRectAngle &rect=kPipe.rect;//更新变化区域
|
||
UpdateRect(rect.lowLeft,rect.upRight,rectUpdate);
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
}
|
||
// 节点
|
||
for(k=0; k<lstNode.Length(); k++) {
|
||
const TNodeLocation &kNode=lstNode[k];
|
||
if(kNode.Intersect(pipeChanged)) {
|
||
OPENOBJ_BEGIN(kNode.id,AcDb::kForRead,TDbPipeNode,pNode);
|
||
if(pNode!=NULL)
|
||
UpdateNodeInfos(pChangedPipe,pNode);
|
||
OPENOBJ_END();
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
}
|
||
|
||
// 变化的节点
|
||
for(int i=0; i<m_lstChangedNode.Length(); i++) {
|
||
TNodeLocation &nodeChanged=*m_lstChangedNode[i];
|
||
OPENOBJ_BEGIN(nodeChanged.id,AcDb::kForRead,TDbPipeNode,pChangedNode);
|
||
if(pChangedNode!=NULL) {
|
||
for(int k=0; k<lstPipe.Length(); k++) {
|
||
const TEntRect &kPipe=lstPipe[k];
|
||
if(nodeChanged.Intersect(kPipe)) {
|
||
OPENOBJ_BEGIN(kPipe.id,AcDb::kForRead,TDbPipePrototype,pPipe);
|
||
if(pPipe!=NULL)
|
||
if(UpdatePipeInfos(pChangedNode,pPipe)) {
|
||
const XRectAngle &rect=kPipe.rect;//更新变化区域
|
||
UpdateRect(rect.lowLeft,rect.upRight,rectUpdate);
|
||
UpdateInfo *info=NewAppendUpdateInfo(pPipe->GetSysType());
|
||
ASSERT(info!=NULL);
|
||
info->lstVertice.NewAppend(nodeChanged.ptLocation);
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
|
||
// 释放
|
||
m_lstChangedNode.Reset();
|
||
for(i=0; i<m_lstUpdate.Length(); i++) {
|
||
m_lstUpdate[i]->lstChangedPipe.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; n<nFaceNum; n++) {
|
||
const TPipeInterface& iFace=pNode->GetInterface(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()<m_nOptimize) {
|
||
AcDbObjectId id = pNode->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()<m_nOptimize) {// 管线变化不是由于附件引起的
|
||
if(!info->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<AcDbObjectId> &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<AcDbObjectId> &vecIds)
|
||
{
|
||
int len = m_lstMatchEntity.Length();
|
||
PickSet ss(SS_FREE);
|
||
for(int i=0;i<len;i++)
|
||
{
|
||
AcDbObjectId id = *m_lstMatchEntity[i];
|
||
ads_name entTag;
|
||
acdbGetAdsName(entTag, id);
|
||
Entity tgent = entTag;
|
||
if(tgent.Is(_T("LINE")))
|
||
{
|
||
vecIds.push_back(id);
|
||
}
|
||
else if(tgent.Is(_T("ARC")))
|
||
{
|
||
vecIds.push_back(id);
|
||
}
|
||
else if(tgent.Is(_T("CIRCLE")))
|
||
{
|
||
vecIds.push_back(id);
|
||
XCircle cir(entTag);
|
||
XPoint ptCen = cir.GetCenterPt();
|
||
OPENOBJ_BEGIN(m_idMatchRes, AcDb::kForRead, TDbPipe, pPipe);
|
||
if(pPipe && pPipe->IsVertical())
|
||
{
|
||
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;m<len-1;m++)
|
||
{
|
||
XCurveSegment seg;
|
||
poly.Nth(m, seg);
|
||
if(seg.Is(CURVE_ARC))
|
||
{
|
||
AcDbArc *pArc = new AcDbArc;
|
||
XArc arc = seg.GetArc();
|
||
pArc->setStartAngle(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<AcGePoint3d> &vecPts)
|
||
{
|
||
std::map<double, AcGePoint3d> 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<double, AcGePoint3d>::iterator itMap;
|
||
for (itMap = mapPt.begin(); itMap !=mapPt.end(); itMap++)
|
||
{
|
||
vecPts.push_back(itMap->second);
|
||
}
|
||
}
|
||
|
||
// 去掉容器中重复的点 zxl 2012.10.30 add
|
||
void CheckPtInVec(std::vector<AcGePoint3d> &vecPts)
|
||
{
|
||
std::vector<AcGePoint3d>::iterator it;
|
||
std::vector<AcGePoint3d>::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<AcDbObjectId> &vecIds, std::map<AcDbObjectId, std::vector<AcGePoint3d> > &mapEnt)
|
||
{
|
||
std::vector<AcDbObjectId>::const_iterator it;
|
||
std::vector<AcDbObjectId>::const_iterator itSec;
|
||
bool bIsNearXaxis = true;
|
||
for (it = vecIds.begin(); it!= vecIds.end(); it++)
|
||
{
|
||
std::vector<AcGePoint3d> 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<AcDbObjectId, std::vector<AcGePoint3d> > &mapEnt)
|
||
{
|
||
std::vector<AcDbObjectId> vecIds;
|
||
GetMinEntity(vecIds);
|
||
GetIntsectEntity(vecIds, mapEnt);
|
||
}
|
||
|
||
//格式刷
|
||
void TPipePerDocData::DoMatchPipe()
|
||
{
|
||
if(!g_bIsStartMatchProp)
|
||
return;
|
||
|
||
std::map<AcDbObjectId, std::vector<AcGePoint3d> > mapEnt;
|
||
ModifyMatchEntity(mapEnt);
|
||
std::map<AcDbObjectId, std::vector<AcGePoint3d> >::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;i<len;i++){
|
||
//AcDbObjectId id = *m_lstMatchEntity[i];
|
||
for (itMap = mapEnt.begin(); itMap != mapEnt.end(); itMap++)
|
||
{
|
||
AcDbObjectId id = itMap->first;
|
||
|
||
ads_name entTag;
|
||
acdbGetAdsName(entTag, id);
|
||
Entity tgent = entTag;
|
||
if(tgent.Is(_T("LINE"))){
|
||
XLine line(entTag, 1);
|
||
ss += id;
|
||
std::vector<AcGePoint3d>::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<AcGePoint3d>::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;m<len-1;m++){
|
||
// XCurveSegment seg;
|
||
// poly.Nth(m, seg);
|
||
// OPENOBJ_BEGIN(m_idMatchRes, AcDb::kForRead, TDbPipe, pPipe);
|
||
// if(pPipe){
|
||
// TDbPipe *pNewPipe = (TDbPipe *)pPipe->clone();
|
||
// 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;i<len;i++)
|
||
{
|
||
AcDbObjectId id = *m_lstCloseEntity[i];
|
||
// cet 2014.8.5 add 判断id有效性,避免崩溃发生(2014.8.5 jzh反馈图崩溃)
|
||
if (!id.isValid() || id.isErased())
|
||
{
|
||
continue;
|
||
}
|
||
ads_name entTag;
|
||
acdbGetAdsName(entTag, id);
|
||
Entity tgent = entTag;
|
||
if(tgent.Is(_T("ATS_VPIPEDIM"))) // 移动立管标注后,重新绑定立管
|
||
{
|
||
XPoint ptStart, ptTurn, ptPipeStart;
|
||
CString sFloorNum,sNum;
|
||
CString sMarkText; // cet 2014.6.20 add 代号信息
|
||
AcDbObjectId idPipe = NULL;
|
||
OPENOBJ_BEGIN(tgent, AcDb::kForRead, TDbVPipeDim, pDim);
|
||
if(pDim)
|
||
{
|
||
ptStart = pDim->GetStartPt();
|
||
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; j<nPipeNum; j++) { // 接口
|
||
const AcDbObjectId &idPipe=pNode->GetIPipe(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<BOOL> vAction(g_bMonitorDbAction, FALSE);
|
||
XPushMemVar<int> vReactor(g_nCmdReactor,CMD_UPDATE);
|
||
m_rectAttachUpdate.SetElevation(0);
|
||
m_rectSysUpdate.SetElevation(0);
|
||
|
||
BOOL bUpdateSys = !IsRectEmpty(m_rectSysUpdate);
|
||
DList<TEntRect> 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<TEntRect> &lstUpdatePipe)
|
||
{
|
||
XRectAngle rectUpdate=m_rectSysUpdate;//需要重新验证遮挡关系的区域
|
||
GetEntRectFromBlock(lstUpdatePipe,TDbPipePrototype::desc(),m_rectSysUpdate);
|
||
|
||
BOOL bOptimize = GetChangedNum()>m_nOptimize; //是否优化
|
||
DList<TNodeLocation> lstUpdateNode;// 更新区域(扩大了搜索范围)内的节点
|
||
if(!bOptimize) {
|
||
GetNodeFromBlock(lstUpdateNode,m_rectSysUpdate);
|
||
DoDeepSearch(lstUpdatePipe,lstUpdateNode,rectUpdate);
|
||
|
||
}
|
||
|
||
// 更新管线与管线、管线与节点的关系
|
||
for(int i=0; i<m_lstUpdate.Length(); i++) {// Update Corners
|
||
UpdateInfo *info=m_lstUpdate[i];
|
||
if(info->NeedUpdateSys()) {
|
||
//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<TEntRect>* pPipes) const
|
||
{
|
||
// 一、更新管线:验证管线与附件的配属关系
|
||
for(int n=0; n<m_lstUpdate.Length(); n++) {
|
||
const UpdateInfo& info=m_lstUpdate[n];
|
||
for(int i=0; i<info.lstAttachPipe.Length(); i++) {
|
||
const AcDbObjectId &id = info.lstAttachPipe[i];
|
||
OPENOBJ_BEGIN(id, AcDb::kForWrite, TDbPipePrototype, pPipe);
|
||
if(pPipe)
|
||
pPipe->ValidateAttachship();
|
||
OPENOBJ_END();
|
||
}
|
||
}
|
||
|
||
// 二、更新附件:验证管线和附件的配属关系
|
||
// 1、验证原有的管线和附件的配属关系
|
||
DList<AcDbObjectId> lstAttachment;
|
||
for(n=0; n<m_lstUpdate.Length(); n++) {
|
||
const UpdateInfo& info=m_lstUpdate[n];
|
||
for(int i=0; i<info.lstAttachment.Length(); i++) {
|
||
const AcDbObjectId &id = info.lstAttachment[i];
|
||
OPENOBJ_BEGIN(id,AcDb::kForWrite,TDbPipeAttachment,pAttach);
|
||
if(pAttach!=NULL) {
|
||
if(!pAttach->ValidateAttachship()) {
|
||
lstAttachment.Append(new AcDbObjectId(pAttach->objectId()));
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
}
|
||
// 2、验证还没有配属的附件与管线的关系
|
||
int nAttach=lstAttachment.Length();
|
||
if(nAttach>0) {
|
||
// 加速:边框相交才验证管线和附件的关系
|
||
DList<TEntRect> lstAttachPipe;//附件变化区域的管线
|
||
BOOL bReConstruct = pPipes==NULL;
|
||
if(bReConstruct) {
|
||
GetEntRectFromBlock(lstAttachPipe,TDbPipePrototype::desc(),m_rectAttachUpdate);
|
||
}
|
||
// DList<TEntRect> &lstUpdatePipe = bReConstruct ? lstAttachPipe : * pPipes; // sr removed 2006-7-3
|
||
DList<TEntRect> &lstUpdatePipe = bReConstruct ? lstAttachPipe : *((DList<TEntRect>*)pPipes);
|
||
|
||
|
||
int nPipe=lstUpdatePipe.Length();//管线数
|
||
double dExtents=_distSnap*500;//简化处理不是采用GetExtents
|
||
XPoint ptExtents(dExtents,dExtents,0);
|
||
|
||
for(int i=0; i<nAttach; i++) {
|
||
OPENOBJ_BEGIN(*lstAttachment[i],AcDb::kForWrite,TDbPipeAttachment,pAttach);
|
||
if(pAttach!=NULL) {
|
||
XPoint ptLocation=pAttach->GetLocation();
|
||
XRectAngle rcAttach(ptLocation-ptExtents,ptLocation+ptExtents);
|
||
for(int j=0; j<nPipe; j++) {
|
||
TEntRect &pipeRect=*lstUpdatePipe[j];
|
||
if(pipeRect.Intersect(rcAttach)) {
|
||
pAttach->ValidateAttachship(pipeRect.id);
|
||
}
|
||
}
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
}
|
||
/*for(n=0; n<m_lstUpdate.Length(); n++) {
|
||
UpdateInfo *info=m_lstUpdate[n];
|
||
DStack<AcDbObjectId> lstPipe;
|
||
for(int i=0; i<lstUpdatePipe.Length(); i++) {
|
||
AcDbObjectId *pId=lstUpdatePipe[i];
|
||
OPENOBJ_BEGIN(*pId, AcDb::kForRead, TDbPipePrototype, pPipe);
|
||
if(pPipe!=NULL) {
|
||
if(pPipe->GetSysType()==info->sysType)
|
||
lstPipe.Append(pId);
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
for(i=0; i<info->lstAttachment.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<TEntRect> &lstPipe) const
|
||
{
|
||
int nCount = lstPipe.Length();
|
||
for(int i=0; i<nCount; i++) {
|
||
OPENOBJ_BEGIN(lstPipe[i].id,AcDb::kForWrite,TDbPipePrototype,pPipe);
|
||
if(pPipe!=NULL) {
|
||
pPipe->ResetDrawSpeed();
|
||
}
|
||
OPENOBJ_END();
|
||
}
|
||
}
|
||
|
||
// 重新验证调整遮挡关系
|
||
void TPipePerDocData::
|
||
ValidateHideships(const DList<TEntRect> &lstPipe,const XRectAngle &rectUpdate) const
|
||
{
|
||
// rectUpdate.Make();
|
||
DList<TEntRect> lstPipe0;
|
||
int nCount = lstPipe.Length();
|
||
for(int i=0; i<nCount; i++) {
|
||
const TEntRect& pipeRect=lstPipe[i];
|
||
OPENOBJ_BEGIN(pipeRect.id,AcDb::kForWrite,TDbPipePrototype,pPipe);
|
||
if(pPipe!=NULL) {
|
||
if(!pPipe->IsVertical()/* && 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; i<nCount; i++) {
|
||
TEntRect& iPipe=*lstPipe0[i];
|
||
OPENOBJ_BEGIN(iPipe.id,AcDb::kForWrite,TDbPipePrototype,pPipe);
|
||
if(pPipe!=NULL) {
|
||
for(int j=i+1; j<nCount; j++) {
|
||
TEntRect& jPipe=*lstPipe0[j];
|
||
if(iPipe.Intersect(jPipe))
|
||
pPipe->ValidateHideship(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; i<len1; i++) {
|
||
Entity ent=ssDec[i];
|
||
if(ent.Is(_T("ATS_PIPE")))
|
||
{
|
||
OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbPipe, pPipe);
|
||
if(pPipe){
|
||
pPipe->SetHighlight(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; i<len2; i++) {
|
||
Entity ent=ssInc[i];
|
||
if(ent.Is(_T("ATS_PIPE")))
|
||
{
|
||
OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbPipe, pPipe);
|
||
if(pPipe){
|
||
pPipe->SetHighlight(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; i<ssTemp.Length(); i++) {
|
||
Entity ent=ssTemp[i];
|
||
if(ent.Is(_T("ATS_PIPE")))
|
||
{
|
||
OPENOBJ_BEGIN(ent, AcDb::kForWrite, TDbPipe, pPipe);
|
||
if(pPipe){
|
||
pPipe->SetHighlight(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<BOOL> 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.x<rect.upRight.x &&
|
||
ptCurve.y>rect.lowLeft.y && ptCurve.y<rect.upRight.y) {
|
||
//(ptCloseToCurve&rect)==PR_INSIDE) {
|
||
Entity ent;
|
||
VERIFY(acdbGetAdsName(ent.name, pCurve->objectId())==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; i<lCount; i++) {
|
||
Entity ent = ss[i];
|
||
OPENOBJ_BEGIN(ent,AcDb::kForRead,AcDbEntity,pEntity);
|
||
if(pEntity!=NULL && pEntity->visibility()!=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<TEntRect> &lstPipe,
|
||
// const DList<TNodeLocation>& lstNode,BOOL bOptimize)
|
||
// {
|
||
// if(info==NULL || (lstPipe.Length()<=0 && lstNode.Length()<=0))
|
||
// return;
|
||
//
|
||
// XPointList lstCorners,lstNeedBreak;// 复制一份
|
||
// for(int idx=0; idx<info->lstVertice.Length(); idx++) {
|
||
// lstCorners.Append(new XPoint(info->lstVertice[idx]));
|
||
// }
|
||
// for(idx=0; idx<info->lstNeedBreak.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;m<ssVPipeDim.Length();m++)
|
||
// {
|
||
// Entity entTmp = ssVPipeDim[m];
|
||
// OPENOBJ_BEGIN(entTmp,AcDb::kForRead,TDbVPipeDim,pDim);
|
||
// if(pDim!=NULL){
|
||
// AcDbObjectId idDim = pDim->GetVPipeId();
|
||
// //如果立管标注绑定立管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<TEntRect> &lstPipe,
|
||
const DList<TNodeLocation>& lstNode,BOOL bOptimize)
|
||
{
|
||
if(info==NULL || (lstPipe.Length()<=0 && lstNode.Length()<=0))
|
||
return;
|
||
|
||
XPointList lstCorners,lstNeedBreak;// 复制一份
|
||
for(int idx=0; idx<info->lstVertice.Length(); idx++) {
|
||
lstCorners.Append(new XPoint(info->lstVertice[idx]));
|
||
}
|
||
for(idx=0; idx<info->lstNeedBreak.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<AcDbObjectId> setModelSpaceIds;
|
||
if (!GetEntIdsFromModelSpace(setModelSpaceIds))
|
||
{
|
||
return;
|
||
}
|
||
std::set<AcDbObjectId>::iterator itNoFind = setModelSpaceIds.end();
|
||
// 清空更新区域
|
||
m_rectSysUpdate.lowLeft = m_rectSysUpdate.upRight = XPoint();
|
||
|
||
std::set<AcDbObjectId>::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<AcDbObjectId> &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<TEntRect> &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<TEntRect> &lstUpdatePipe)
|
||
{
|
||
// 获得化粪池池关联的管道
|
||
std::map<AcDbObjectId, std::vector<AcDbObjectId> > mapPool;
|
||
std::vector<AcDbObjectId> 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<AcDbObjectId, std::vector<AcDbObjectId> >::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<TEntRect> &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);
|
||
}
|
||
}
|
||
|