854 lines
22 KiB
C++
854 lines
22 KiB
C++
#include "StdAfx.h"
|
|
#include "ent2db.h"
|
|
#include <map>
|
|
#include "TSQLite.h"
|
|
#include "shjson.h"
|
|
#include "KTCADUtilityEx.h"
|
|
#include "KTCadUtility.h"
|
|
#include "geometry2json.h"
|
|
#include "CoreTools.h"
|
|
#include "AecDbWall.h"
|
|
#include "AecDbBeam.h"
|
|
#include "AecDbSlab.h"
|
|
#include "AecDbColumn.h"
|
|
#include "AecDbEwEquipment.h"
|
|
#include "AecDbParamEquipment.h"
|
|
#include "AecDbFlume.h"
|
|
#include "AecDbRiverGroove.h"
|
|
#include "AecDbEwPipe.h"
|
|
#include "aecdbewfitting.h"
|
|
#include "AecDbHvacDuct.h"
|
|
#include "AecDbHvacFitting.h"
|
|
#include "AecDbECableTray.h"
|
|
#include "aecdbecfitting.h"
|
|
#include "AecDbX3dPartEntity.h"
|
|
#include "AecDbOpening.h"
|
|
#include "AecDbHolder.h"
|
|
#include "AecDbBossHolder.h"
|
|
#include "AecDbhanger.h"
|
|
#include "AecDbXEquipment.h"
|
|
#include "AecDbClimbStair.h"
|
|
#include "AecDbZLineStair.h"
|
|
#include "AecDbMRPLineStair.h"
|
|
#include "AecDbCornerStair.h"
|
|
#include "AecDbCrossStair.h"
|
|
#include "AecDbDoubleMulStair.h"
|
|
#include "AecDbLineSegStair.h"
|
|
#include "AecDbParaLlelStair.h"
|
|
#include "AecDbRectCornerStair.h"
|
|
#include "AecDbScissorsStair.h"
|
|
#include "AecDbTriangleStair.h"
|
|
|
|
using namespace SHJson;
|
|
|
|
namespace ENT2DB
|
|
{
|
|
const CString g_dbName(_T("\\sh_export.db"));
|
|
|
|
const CString g_sqlTable =
|
|
_T("create table 'AEC_ENTITIES' (\n")\
|
|
_T("'ID' integer primary key autoincrement not null,\n")\
|
|
_T("'CLASS' text not null,\n")\
|
|
_T("'SELF' integer not null,\n")\
|
|
_T("'OWNER' integer not null,\n")\
|
|
_T("'DATA' text not null);\n");
|
|
|
|
struct SimpleInterface
|
|
{
|
|
AcDbObjectId pid;
|
|
AcGePoint3d ptPos;
|
|
SimpleInterface() {};
|
|
SimpleInterface(const AcDbObjectId &id, const AcGePoint3d &pt): pid(id), ptPos(pt) {};
|
|
bool operator < (SimpleInterface s1) const { return pid < s1.pid; }
|
|
};
|
|
|
|
bool isSameInterface(const AecInterface &inf1, const AecInterface &inf2)
|
|
{
|
|
if (EQUAL_ZERO(inf1.ptPos.distanceTo(inf2.ptPos))) return true;
|
|
|
|
AcGeVector3d vt1(inf1.vtDir), vt2(inf2.vtDir);
|
|
|
|
if (vt1.normalize().negate() == vt2.normalize())
|
|
{
|
|
if (inf1.ptPos.distanceTo(inf2.ptPos) < (inf1.dSize1 + inf2.dSize1) * .5)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// 得到 实体 接口
|
|
bool getInterfaces(AcDbObjectId id, AcArray<AecInterface> &ar)
|
|
{
|
|
OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEwPipe, pEnt)
|
|
if (pEnt)
|
|
{
|
|
pEnt->GetInterface(ar);
|
|
}
|
|
OPENOBJ_END()
|
|
OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEwEquipment, pEnt)
|
|
if (pEnt)
|
|
{
|
|
pEnt->GetInterface(ar);
|
|
}
|
|
OPENOBJ_END()
|
|
OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEwFitting, pEnt)
|
|
if (pEnt)
|
|
{
|
|
pEnt->GetInterface(ar);
|
|
}
|
|
OPENOBJ_END()
|
|
|
|
OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbECableTray, pEnt)
|
|
if (pEnt)
|
|
{
|
|
pEnt->GetInterface(ar);
|
|
}
|
|
OPENOBJ_END()
|
|
OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbHvacDuct, pEnt)
|
|
if (pEnt)
|
|
{
|
|
pEnt->GetInterface(ar);
|
|
}
|
|
OPENOBJ_END()
|
|
OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEcFitting, pEnt)
|
|
if (pEnt)
|
|
{
|
|
pEnt->GetInterface(ar);
|
|
}
|
|
OPENOBJ_END()
|
|
OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbHvacFitting, pEnt)
|
|
if (pEnt)
|
|
{
|
|
pEnt->GetInterface(ar);
|
|
}
|
|
OPENOBJ_END()
|
|
|
|
return !ar.isEmpty();
|
|
}
|
|
|
|
int getMEPType(AcDbObjectId id)
|
|
{
|
|
if (ENT2DB::isEntity<AecDbEwFitting>(id)
|
|
||ENT2DB::isEntity<AecDbEwPipe>(id))
|
|
return 0;
|
|
else if (ENT2DB::isEntity<AecDbHvacFitting>(id)
|
|
||ENT2DB::isEntity<AecDbHvacFitting>(id))
|
|
return 1;
|
|
else if (ENT2DB::isEntity<AecDbEcFitting>(id)
|
|
||ENT2DB::isEntity<AecDbECableTray>(id))
|
|
return 2;
|
|
else if (ENT2DB::isEntity<AecDbEwEquipment>(id))
|
|
{
|
|
AcArray<AecInterface> ar;
|
|
getInterfaces(id, ar);
|
|
if (ar.isEmpty()) return -1;
|
|
AecInterface &inf = ar.first();
|
|
if (inf.nType == 0) return 0;
|
|
else if (inf.nType == 1) return 1;
|
|
return 2;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
// 判断接口 inf 是否已经被实体记录
|
|
// 如果被记录,反回true
|
|
bool hasRecord(AecInterface inf
|
|
, AcDbObjectId id
|
|
, const std::multimap<AcDbObjectId, AecInterface> &ss)
|
|
{
|
|
typedef std::multimap<AcDbObjectId, AecInterface>::const_iterator _IT;
|
|
std::pair<_IT, _IT> pr = ss.equal_range(id);
|
|
for (_IT it = pr.first; it != pr.second; ++it)
|
|
{
|
|
if (it->second.ptPos == inf.ptPos) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// 判断 id1 和 id2 有没有相连的接口
|
|
// 如果找到,将关联信息写到两个实体中
|
|
// 找到返回true
|
|
void findInterface(AcDbObjectId id1
|
|
, AcDbObjectId id2
|
|
, std::multimap<AcDbObjectId, AecInterface> &ss)
|
|
{
|
|
AcArray<AecInterface> ar1(0), ar2(0);
|
|
if (!getInterfaces(id1, ar1)) return;
|
|
if (!getInterfaces(id2, ar2)) return;
|
|
|
|
int nType1(-1), nType2(-1);
|
|
|
|
for (int i = 0; i < ar1.length(); ++i)
|
|
{
|
|
AecInterface &inf1 = ar1[i];
|
|
if (hasRecord(inf1, id1, ss)) continue;
|
|
nType1 = getMEPType(id1);
|
|
|
|
for (int j = 0; j < ar2.length(); ++j)
|
|
{
|
|
AecInterface &inf2 = ar2[j];
|
|
if (hasRecord(inf2, id2, ss)) continue;
|
|
nType2 = getMEPType(id2);
|
|
|
|
if (isSameInterface(inf1, inf2))
|
|
{
|
|
AecInterface inf = inf1;
|
|
inf.nType = nType1;
|
|
inf.idOwner = id2; // 在这里 idOwner 代表所连接的实体ID
|
|
ss.insert(std::make_pair(id1, inf));
|
|
inf = inf2;
|
|
inf.nType = nType2;
|
|
inf.idOwner = id1;
|
|
ss.insert(std::make_pair(id2, inf));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 收集 管道,管件,管道附件 的接口信息
|
|
void collectInterfaceInfo(AcDbObjectIdArray ar
|
|
, std::multimap<AcDbObjectId, AecInterface> &ss)
|
|
{
|
|
for (int i = 0; i < ar.length(); ++i)
|
|
{
|
|
// id 与 其它实体都比较一次
|
|
for (int j = i + 1; j < ar.length(); ++j)
|
|
{
|
|
findInterface(ar[i], ar[j], ss);
|
|
}
|
|
}
|
|
|
|
// 以上代码可以处理互相连接的接口,但是没有连接的接口也需要记录。
|
|
AcArray<AecInterface> infs(0);
|
|
AecInterface inf;
|
|
for (int i = 0; i < ar.length(); ++i)
|
|
{
|
|
infs.removeAll();
|
|
getInterfaces(ar[i], infs);
|
|
if (infs.isEmpty()) continue;
|
|
typedef std::multimap<AcDbObjectId, AecInterface>::const_iterator _IT;
|
|
std::pair<_IT, _IT> pr = ss.equal_range(ar[i]);
|
|
// 如果不在 pr 范围内存在,则说明是空接口,需要记录
|
|
int count = (int)std::distance(pr.first, pr.second);
|
|
// 如果查找出记录的数量与实体本身的数量一致,说明都记录上了
|
|
if (count == infs.length()) continue;
|
|
|
|
for (int j = 0; j < infs.length(); ++j)
|
|
{
|
|
bool isHas(false);
|
|
for (_IT it = pr.first; it != pr.second; ++it)
|
|
{
|
|
if (isSameInterface(it->second, infs[j]))
|
|
{
|
|
isHas = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!isHas)
|
|
{
|
|
inf = infs[j];
|
|
inf.idOwner = AcDbObjectId::kNull;
|
|
inf.nType = getMEPType(ar[i]);
|
|
ss.insert(std::make_pair(ar[i], inf));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
template <class Fi, class Pi>
|
|
void getConnectorForFitting(AcDbObjectId fitID
|
|
, AcDbObjectIdArray pipes
|
|
, std::set<SimpleInterface> &connectors)
|
|
{
|
|
AcArray<AecInterface> aifs;
|
|
AecInterface aif;
|
|
SimpleInterface sinf;
|
|
OPENOBJ_BEGIN(fitID, AcDb::kForRead, Fi, pFit)
|
|
{
|
|
if (!pFit) return;
|
|
|
|
for (int f = 0; f < pFit->GetInterfaceCount(); ++f)
|
|
{
|
|
if (!pFit->GetInterface(f, aif)) continue;
|
|
for (int i = 0; i < pipes.length(); ++i)
|
|
{
|
|
OPENOBJ_BEGIN(pipes[i], AcDb::kForRead, Pi, pPipe)
|
|
{
|
|
aifs.removeAll();
|
|
if (!pPipe) continue;
|
|
if (!pPipe->GetInterface(aifs)) continue;
|
|
if (aifs.length() < 2) continue;
|
|
|
|
if (isSameInterface(aifs[0], aif))
|
|
{
|
|
sinf.pid = pPipe->objectId();
|
|
sinf.ptPos = aifs[0].ptPos;
|
|
connectors.insert(sinf);
|
|
break;
|
|
}
|
|
else if (isSameInterface(aifs[1], aif))
|
|
{
|
|
sinf.pid = pPipe->objectId();
|
|
sinf.ptPos = aifs[1].ptPos;
|
|
connectors.insert(sinf);
|
|
break;
|
|
}
|
|
}
|
|
OPENOBJ_END()
|
|
}
|
|
}
|
|
}
|
|
OPENOBJ_END()
|
|
}
|
|
|
|
template <class Fi, class Pi>
|
|
void writeConnector2Fitting(AcDbObjectIdArray fids, AcDbObjectIdArray pids)
|
|
{
|
|
std::set<SimpleInterface> connectors;
|
|
CString sName(_T(""));
|
|
for (int i = 0; i < fids.length(); ++i)
|
|
{
|
|
connectors.clear();
|
|
getConnectorForFitting<Fi, Pi>(fids[i], pids, connectors);
|
|
OPENOBJ_BEGIN(fids[i], AcDb::kForWrite, Fi, pFit)
|
|
{
|
|
AecDbObjXDataMap *pMap = pFit->GetSpecialtyData(AcDb::kForWrite);
|
|
if (!pMap) continue;
|
|
|
|
if (ENT2DB::isEntity<AecDbEwFitting>(pFit))
|
|
pMap->SetAt(_T("MEP_TYPE"), 0);
|
|
else if (ENT2DB::isEntity<AecDbEcFitting>(pFit))
|
|
pMap->SetAt(_T("MEP_TYPE"), 1);
|
|
else if (ENT2DB::isEntity<AecDbHvacFitting>(pFit))
|
|
pMap->SetAt(_T("MEP_TYPE"), 2);
|
|
|
|
pMap->SetAt(_T("CONNECTOR_COUNT"), (int)connectors.size());
|
|
int idx(0);
|
|
for (std::set<SimpleInterface>::const_iterator it = connectors.begin()
|
|
; it != connectors.end()
|
|
; ++it, ++idx)
|
|
{
|
|
sName.Format(_T("CONNECTOR_Id_%d"), idx);
|
|
pMap->SetAt(sName, it->pid);
|
|
sName.Format(_T("CONNECTOR_Pos_%d"), idx);
|
|
pMap->SetAt(sName, it->ptPos);
|
|
}
|
|
}
|
|
OPENOBJ_END()
|
|
}
|
|
|
|
}
|
|
|
|
bool getSHObjects(LPCTSTR dxf
|
|
, AcDbObjectIdArray &ids
|
|
, AcDbObjectIdArray &idsRepeat
|
|
, std::multimap<AcDbObjectId, AecInterface> &infs)
|
|
{
|
|
resbuf *pRb = acutBuildList(RTDXF0, dxf, 0);
|
|
ads_name ss, ent;
|
|
|
|
if (CKTCadUtility::SelectEntities(_T("\n请选择要导出的上华实体:"), ss, pRb) != RTNORM) return false;
|
|
//int nRes = acedSSGet(_T("A"), NULL, NULL, pRb, ss);
|
|
acutRelRb(pRb);
|
|
|
|
AcDbObjectId id;
|
|
Adesk::Int32 lLen(0L);
|
|
acedSSLength(ss, &lLen);
|
|
|
|
ids.removeAll();
|
|
|
|
AcDbObjectIdArray arPipes, arDucts, arCabletray
|
|
, arEwFits, arHvacFits, arEcFits, arEquis, allEw, allEc, allHv;
|
|
for (long i = 0; i < lLen; ++i)
|
|
{
|
|
if (acedSSName(ss, i, ent) != RTNORM) continue;
|
|
if (acdbGetObjectId(id, ent) != Acad::eOk) continue;
|
|
|
|
OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbEntity, pEnt)
|
|
{
|
|
if (pEnt)
|
|
{
|
|
// 把在revit中可以做族文件的实体都挑出来
|
|
if (AecDbXOpening::cast(pEnt)
|
|
|| AecDbHolder::cast(pEnt)
|
|
|| AecDbHanger::cast(pEnt)
|
|
|| AecDbBossHolder::cast(pEnt)
|
|
|| AecDbClimbStair::cast(pEnt)
|
|
|| AecDbZLineStair::cast(pEnt)
|
|
|| AecDbMRPLineStair::cast(pEnt)
|
|
|| AecDbXEquipment::cast(pEnt)
|
|
|| AecDbCornerStair::cast(pEnt)
|
|
|| AecDbCrossStair::cast(pEnt)
|
|
|| AecDbDoubleMulStair::cast(pEnt)
|
|
|| AecDbLineSegStair::cast(pEnt)
|
|
|| AecDbParaLlelStair::cast(pEnt)
|
|
|| AecDbRectCornerStair::cast(pEnt)
|
|
|| AecDbScissorsStair::cast(pEnt)
|
|
|| AecDbTriangleStair::cast(pEnt)
|
|
)
|
|
idsRepeat.append(id);
|
|
else
|
|
ids.append(id);
|
|
|
|
|
|
// 找出所有的 管实体(管线,风管,桥架)及 管件实体(管件,风管件,电气管件)
|
|
if (AecDbEwPipe::cast(pEnt)) arPipes.append(id);
|
|
else if (AecDbECableTray::cast(pEnt)) arCabletray.append(id);
|
|
else if (AecDbHvacDuct::cast(pEnt)) arDucts.append(id);
|
|
else if (AecDbEwFitting::cast(pEnt)) arEwFits.append(id);
|
|
else if (AecDbEcFitting::cast(pEnt)) arEcFits.append(id);
|
|
else if (AecDbHvacFitting::cast(pEnt)) arHvacFits.append(id);
|
|
else if (AecDbEwEquipment::cast(pEnt)) arEquis.append(id);
|
|
}
|
|
}
|
|
OPENOBJ_END()
|
|
}
|
|
acedSSFree(ss);
|
|
|
|
allEw.append(arPipes);
|
|
allEw.append(arEwFits);
|
|
|
|
allEc.append(arCabletray);
|
|
allEc.append(arEcFits);
|
|
|
|
allHv.append(arDucts);
|
|
allHv.append(arHvacFits);
|
|
|
|
// 设备可能对应着 风管,桥架,管道,所以都放进去
|
|
allEw.append(arEquis);
|
|
allHv.append(arEquis);
|
|
allEc.append(arEquis);
|
|
|
|
collectInterfaceInfo(allEw, infs);
|
|
collectInterfaceInfo(allEc, infs);
|
|
collectInterfaceInfo(allHv, infs);
|
|
|
|
return !(ids.isEmpty() && idsRepeat.isEmpty());
|
|
}
|
|
|
|
CString getTableName(const AcDbEntity *pEnt)
|
|
{
|
|
return _T("AEC_ENTITIES");
|
|
const AecDbXWall *pWall(AecDbXWall::cast(pEnt));
|
|
if (pWall) return _T("AEC_WALL");
|
|
|
|
const AecDbBeam *pBeam(AecDbBeam::cast(pEnt));
|
|
if (pBeam) return _T("AEC_BEAM");
|
|
|
|
const AecDbXSlab *pSlab(AecDbXSlab::cast(pEnt));
|
|
if (pSlab) return _T("AEC_SLAB");
|
|
|
|
const AecDbColumn *pColumn(AecDbColumn::cast(pEnt));
|
|
if (pColumn) return _T("AEC_COLUMN");
|
|
|
|
const AecDbEwEquipment *pEqu(AecDbEwEquipment::cast(pEnt));
|
|
if (pEqu) return _T("AEC_EQU");
|
|
|
|
const AecDbParamEquipment *pParamEqu(AecDbParamEquipment::cast(pEnt));
|
|
if (pParamEqu) return _T("AEC_PARAMEQU");
|
|
|
|
const AecDbFlume *pFlume(AecDbFlume::cast(pEnt));
|
|
if (pFlume) return _T("AEC_FLUME");
|
|
|
|
const AecDbRiverGroove *pGroove(AecDbRiverGroove::cast(pEnt));
|
|
if (pGroove) return _T("AEC_GROOVE");
|
|
|
|
const AecDbEwPipe *pPipe(AecDbEwPipe::cast(pEnt));
|
|
if (pPipe) return _T("AEC_PIPE");
|
|
|
|
const AecDbX3dPartEntity *p3d(AecDbX3dPartEntity::cast(pEnt));
|
|
if (p3d) return _T("AEC_X3DPART");
|
|
|
|
return _T("");
|
|
}
|
|
|
|
CString getUniqueName(AcDbObjectId id)
|
|
{
|
|
CString str(_T(""));
|
|
OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbEntity, pEnt)
|
|
{
|
|
if (pEnt)
|
|
{
|
|
AecDbEntityBase *pBase(AecDbEntityBase::cast(pEnt));
|
|
AecDbCurveBase *pCurve(AecDbCurveBase::cast(pEnt));
|
|
if (pBase)
|
|
return pBase->getUniqueName();
|
|
if (pCurve)
|
|
return pCurve->getUniqueName();
|
|
}
|
|
}
|
|
OPENOBJ_END()
|
|
return str;
|
|
}
|
|
|
|
bool _export(TSQLite &dbSql, const WValue &v, LPCTSTR pszTable, WValue &debug)
|
|
{
|
|
if (!pszTable) return false;
|
|
|
|
WValue vClone;
|
|
vClone.CopyFrom(v, getJsonAllocator());
|
|
|
|
CString sql(_T(""));
|
|
std::wstring self, owner;
|
|
|
|
MCIt itSelf = v.FindMember(_T("__self__"));
|
|
MCIt itOwner = v.FindMember(_T("__owner__"));
|
|
MCIt itClass = v.FindMember(_T("__class__"));
|
|
|
|
Adesk::IntDbId idSelf(0), idOwner(0);
|
|
CString sClass(_T(""));
|
|
if (itSelf != v.MemberEnd()) idSelf = itSelf->value.GetInt64();
|
|
if (itOwner != v.MemberEnd()) idOwner = itOwner->value.GetInt64();
|
|
if (itClass != v.MemberEnd()) sClass = itClass->value.GetString();
|
|
|
|
self = TypeConvert::convert<std::wstring, __int64>(idSelf);
|
|
owner = TypeConvert::convert<std::wstring, __int64>(idOwner);
|
|
|
|
sql.Format(_T("insert into %s ('CLASS','SELF','OWNER','DATA') values('%s','%s','%s','%s')")
|
|
, pszTable
|
|
, sClass
|
|
, self.c_str()
|
|
, owner.c_str()
|
|
, write2Json(v).c_str());
|
|
if (!dbSql.exec(sql)) return false;
|
|
|
|
#ifndef NDEBUG
|
|
if (!debug.IsNull())
|
|
{
|
|
pushBack(debug, vClone);
|
|
}
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
void Export(TSQLite &dbSql
|
|
, AcDbObjectIdArray &ar
|
|
, const AcDbObjectIdArray &arRepeat
|
|
, const std::multimap<AcDbObjectId, AecInterface> &infs
|
|
, WValue &jsonFile)
|
|
{
|
|
/*
|
|
实体的 ToJson()函数返回的 json 结构必须有 __self__,__owner__,两个字段
|
|
如果存在 __attachment__ 结构,则说明存在附着体(目前只有 构筑物上的单体)
|
|
{
|
|
"__self__": AcDbObjectId.asOldId(), 必有
|
|
"__owner__": AcDbObjectId.asOldId(), 必有
|
|
"__xdata__": 实体的AecDbObjXDataMap, 可选
|
|
"__attachment__":{} 可选
|
|
}
|
|
*/
|
|
if (ar.isEmpty() && arRepeat.isEmpty()) return;
|
|
|
|
// 处理一下重复实体
|
|
std::map<CString, AcDbObjectIdArray> mmRepeats;
|
|
std::map<CString, Adesk::IntDbId> mmIds; // 保存了绘制几何信息的实体的id
|
|
CString name;
|
|
AcDbObjectIdArray arids;
|
|
AcDbObjectId idRepeat;
|
|
for (int i(0); i < arRepeat.length(); ++i)
|
|
{
|
|
idRepeat = arRepeat[i];
|
|
name = getUniqueName(idRepeat);
|
|
if (name.IsEmpty())
|
|
{ // 没有直接放到ar里面处理
|
|
ar.append(idRepeat);
|
|
continue;
|
|
}
|
|
else
|
|
{ // 判断名字在不在mm里面
|
|
std::map<CString, AcDbObjectIdArray>::iterator it(mmRepeats.end());
|
|
it = mmRepeats.find(name);
|
|
if (it == mmRepeats.end()) // 不在
|
|
{
|
|
arids.removeAll();
|
|
arids.append(idRepeat);
|
|
mmRepeats.insert(std::make_pair(name, arids));
|
|
// idRepeat 是 这个重复实体中得第一个,放到ar里面处理
|
|
ar.append(idRepeat);
|
|
mmIds.insert(std::make_pair(name, idRepeat.asOldId()));
|
|
}
|
|
else
|
|
{
|
|
it->second.append(idRepeat);
|
|
}
|
|
}
|
|
}
|
|
|
|
AcDbObjectId id;
|
|
WValue v;
|
|
CString table(_T("")), uniqueName(_T(""));
|
|
for (int i = 0; i < ar.length(); ++i)
|
|
{
|
|
v.SetNull();
|
|
id = ar[i];
|
|
OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbEntity, pEnt)
|
|
{
|
|
if (!pEnt) continue;
|
|
|
|
table = getTableName(pEnt);
|
|
if (table.IsEmpty()) continue;
|
|
|
|
AecDbEntityBase *pBase(AecDbEntityBase::cast(pEnt));
|
|
AecDbCurveBase *pCurve(AecDbCurveBase::cast(pEnt));
|
|
if (pBase)
|
|
{
|
|
v.Swap(pBase->ToJson(true));
|
|
uniqueName = pBase->getUniqueName();
|
|
}
|
|
else if (pCurve)
|
|
{
|
|
v.Swap(pCurve->ToJson(true));
|
|
uniqueName = pCurve->getUniqueName();
|
|
}
|
|
else
|
|
continue;
|
|
|
|
addMember(v, _T("_unique_name_"), uniqueName);
|
|
|
|
// 处理一下接口,为v加入接口信息
|
|
typedef std::multimap<AcDbObjectId, AecInterface>::const_iterator _IT;
|
|
std::pair<_IT, _IT> pr = infs.equal_range(id);
|
|
if (pr.first != infs.end())
|
|
{
|
|
WValue jArInf;
|
|
jArInf.SetArray();
|
|
for (_IT it = pr.first; it != pr.second; ++it)
|
|
{
|
|
WValue jInf;
|
|
jInf.SetObject();
|
|
addMember(jInf, _T("__ptPos__"), GEO2JSON::point(it->second.ptPos).ToJson());
|
|
addMember(jInf, _T("__vtDir__"), GEO2JSON::vector(it->second.vtDir).ToJson());
|
|
addMember(jInf, _T("__dSize1__"), it->second.dSize1);
|
|
addMember(jInf, _T("__dSize2__"), it->second.dSize2);
|
|
addMember(jInf, _T("__nSectType__"), (int)it->second.nSectType);
|
|
addMember(jInf, _T("__idConnect__"), it->second.idOwner.asOldId());
|
|
addMember(jInf, _T("__nMEPType__"), (int)it->second.nType);
|
|
pushBack(jArInf, jInf);
|
|
}
|
|
addMember(v, _T("__interfaces__"), jArInf);
|
|
}
|
|
}
|
|
OPENOBJ_END()
|
|
|
|
if (!_export(dbSql, v, table, jsonFile)) continue;
|
|
}
|
|
|
|
std::map<CString, AcDbObjectIdArray>::const_iterator it(mmRepeats.begin());
|
|
for (; it != mmRepeats.end(); ++it)
|
|
{
|
|
// 每种类型得第一个都在 ar 里面处理了
|
|
for (int i(1); i < it->second.length(); ++i)
|
|
{
|
|
|
|
v.SetNull();
|
|
id = it->second[i];
|
|
OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbEntity, pEnt)
|
|
{
|
|
if (!pEnt) continue;
|
|
|
|
table = getTableName(pEnt);
|
|
if (table.IsEmpty()) continue;
|
|
|
|
AecDbEntityBase *pBase(AecDbEntityBase::cast(pEnt));
|
|
AecDbCurveBase *pCurve(AecDbCurveBase::cast(pEnt));
|
|
if (pBase)
|
|
{
|
|
v.Swap(pBase->ToJson(false));
|
|
uniqueName = pBase->getUniqueName();
|
|
}
|
|
else if (pCurve)
|
|
{
|
|
v.Swap(pCurve->ToJson(false));
|
|
uniqueName = pCurve->getUniqueName();
|
|
}
|
|
else
|
|
continue;
|
|
|
|
addMember(v, _T("_unique_name_"), uniqueName);
|
|
// 通过 uniqueName 找到 有几何信息的实体id
|
|
std::map<CString, Adesk::IntDbId>::const_iterator _it = mmIds.find(uniqueName);
|
|
if (_it != mmIds.end())
|
|
{
|
|
addMember(v, _T("_geo_ent_id_"), _it->second);
|
|
}
|
|
}
|
|
OPENOBJ_END()
|
|
|
|
if (!_export(dbSql, v, table, jsonFile)) continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
void export2Db()
|
|
{
|
|
CFileDialog dlg(FALSE, _T("*.she"), NULL, OFN_HIDEREADONLY, _T("导出数据 (*.she)|*.she||"), acedGetAcadFrame());
|
|
if (dlg.DoModal() != IDOK) return;
|
|
CString dbPath = dlg.GetPathName();
|
|
CString jsonPath = dbPath;
|
|
jsonPath.Replace(_T(".she"), _T(".json"));
|
|
|
|
CString dbFile = FilePath::GetSysDir() + g_dbName;
|
|
if (_taccess(dbFile, 0x0) != 0x0)
|
|
{
|
|
AfxMessageBox(_T("未找到导出模板!"));
|
|
return;
|
|
}
|
|
|
|
if (!::CopyFile(dbFile, dbPath, FALSE))
|
|
{
|
|
AfxMessageBox(_T("复制模板文件失败!"));
|
|
return;
|
|
}
|
|
|
|
TSQLite dbSql;
|
|
if (!dbSql.open(dbPath))
|
|
{
|
|
AfxMessageBox(_T("打开数据库失败!"));
|
|
return;
|
|
}
|
|
|
|
if (!dbSql.exec(g_sqlTable))
|
|
{
|
|
AfxMessageBox(_T("初始化表格失败!"));
|
|
return;
|
|
}
|
|
|
|
AcDbObjectIdArray ids, idsRepeat;
|
|
CString psz(_T("AEC_DBWALL")\
|
|
_T(",AEC_DBBEAM")\
|
|
_T(",AEC_DBSLAB")\
|
|
_T(",AEC_DBCOLMN")\
|
|
_T(",AEC_DBWEQUIPMENT")\
|
|
_T(",AEC_DBPARAEQUI")\
|
|
_T(",AEC_DBFLUME")\
|
|
_T(",AEC_RIVERGROOVE")\
|
|
_T(",AEC_EWPIPE")\
|
|
_T(",AEC_DBEWFIT")\
|
|
_T(",AEC_GUARDBAR")\
|
|
_T(",AEC_DBLSTAIR")\
|
|
_T(",AEC_DBASTAIR")\
|
|
_T(",AEC_CLMSTAIR")\
|
|
_T(",AEC_DBHVACFIT")\
|
|
_T(",AEC_DBECFIT")\
|
|
_T(",AEC_DBCABTRY")\
|
|
_T(",AEC_DBDUCT")\
|
|
_T(",AEC_MULTIPARTENT")\
|
|
_T(",AEC_DBWEIR")\
|
|
_T(",AEC_DBEXTENDENT")\
|
|
_T(",AEC_DBXEQUIPMENT")\
|
|
_T(",AEC_DBOPENING")\
|
|
_T(",AEC_DBEWPIPEBASE")\
|
|
_T(",AEC_DBMRPSTAIR")\
|
|
_T(",AEC_DBZSTAIR")\
|
|
_T(",AEC_DBXROOF")\
|
|
_T(",AEC_DBBOSSHOLDER")\
|
|
_T(",AEC_DBHANGER")\
|
|
_T(",AEC_DBHOLDER")\
|
|
_T(",AEC_EWCABLE")\
|
|
_T(",AEC_DBCNRSTAIR")\
|
|
_T(",AEC_CROSSSTAIR")\
|
|
_T(",AEC_DOUBLEMULSTAIR")\
|
|
_T(",AEC_DBLNSTAIR")\
|
|
_T(",AEC_PARALLELSTAIR")\
|
|
_T(",AEC_RECTCORNERSTAIR")\
|
|
_T(",AEC_SCISSORSSTAIR")\
|
|
_T(",AEC_TRIANGLESTAIR")\
|
|
_T(",AEC_X3DPART"));
|
|
WValue jsonFile;
|
|
#ifndef NDEBUG
|
|
jsonFile.SetArray();
|
|
// 此版本后(包括版本2),所有自定义设备(包括revit导入),全部由代码生成,不需要额外rfa文件
|
|
WValue ver;
|
|
SHJson::addMember(ver, _T("_version_"), 2);
|
|
SHJson::pushBack(jsonFile, ver);
|
|
#endif
|
|
std::multimap<AcDbObjectId, AecInterface> ss;
|
|
if (getSHObjects(psz, ids, idsRepeat, ss))
|
|
{
|
|
dbSql.beginTrans();
|
|
// 放入版本
|
|
CString sql;
|
|
sql.Format(_T("insert into AEC_ENTITIES ('CLASS','SELF','OWNER','DATA') values('_version_','0','0','2')"));
|
|
dbSql.exec(sql);
|
|
Export(dbSql, ids, idsRepeat, ss, jsonFile);
|
|
dbSql.commitTrans();
|
|
}
|
|
|
|
#ifndef NDEBUG
|
|
if (!jsonFile.IsNull())
|
|
{
|
|
SHJson::json2File(jsonPath, jsonFile, true);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
void extractSection()
|
|
{
|
|
AcDbObjectIdArray ids;
|
|
CString psz(_T("AEC_DBWALL")\
|
|
_T(",AEC_DBBEAM")\
|
|
_T(",AEC_DBSLAB")\
|
|
_T(",AEC_DBCOLMN"));
|
|
resbuf *pRb = acutBuildList(RTDXF0, psz, 0);
|
|
ads_name ss, ent;
|
|
if (CKTCadUtility::SelectEntities(_T("\n请选择要导出的上华实体:"), ss, pRb) != RTNORM) return;
|
|
acutRelRb(pRb);
|
|
|
|
AcDbObjectId id;
|
|
Adesk::Int32 lLen(0L);
|
|
acedSSLength(ss, &lLen);
|
|
|
|
ids.removeAll();
|
|
for (long i = 0; i < lLen; ++i)
|
|
{
|
|
if (acedSSName(ss, i, ent) != RTNORM) continue;
|
|
if (acdbGetObjectId(id, ent) != Acad::eOk) continue;
|
|
ids.append(id);
|
|
}
|
|
acedSSFree(ss);
|
|
|
|
WValue ar, v;
|
|
ar.SetArray();
|
|
for (int i = 0; i < ids.length(); ++i)
|
|
{
|
|
OPENOBJ_BEGIN(ids[i], AcDb::kForRead, AecDbBDPipeBase, pEnt)
|
|
{
|
|
if (!pEnt) continue;
|
|
v.SetObject();
|
|
AcDbRegion *pReg = pEnt->GetSection();
|
|
AcDbCurve *pCurve = pEnt->GetBaseCurve();
|
|
if (pReg)
|
|
{
|
|
SHJson::addMember(v, _T("section"), GEO2JSON::region(*pReg).ToJson());
|
|
CoreTools::CloneAndAddToModelSpace(pReg);
|
|
DELETE_PTR(pReg);
|
|
}
|
|
if (pCurve)
|
|
{
|
|
SHJson::addMember(v, _T("path"), GEO2JSON::region(*pCurve).ToJson());
|
|
CoreTools::CloneAndAddToModelSpace(pCurve);
|
|
DELETE_PTR(pCurve);
|
|
}
|
|
SHJson::pushBack(ar, v);
|
|
}
|
|
OPENOBJ_END()
|
|
}
|
|
//SHJson::json2File(jsonPath, ar, true);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace
|
|
{
|
|
void polygon_boolean(const int &type
|
|
, const AcDbPolyline *p1
|
|
, const AcDbPolyline *p2
|
|
, AcDbPolyline &pRes)
|
|
{
|
|
|
|
}
|
|
}
|