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

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)
{
}
}