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

3582 lines
106 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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);
}
}