1366 lines
32 KiB
C++
1366 lines
32 KiB
C++
#include "StdAfx.h"
|
|
#include <string>
|
|
#include <set>
|
|
#include "parseFamilyForRevit.h"
|
|
#include "CoreTools.h"
|
|
#include "ktcadutilityex.h"
|
|
#include "_cgal.h"
|
|
#include "shJson.h"
|
|
#include "AecDbEwEquipment.h"
|
|
|
|
using namespace SHJson;
|
|
|
|
namespace
|
|
{
|
|
int initVersion() { return -1; }
|
|
|
|
static int g_nJsonVersion = initVersion();
|
|
static double g_dUnitRate;
|
|
|
|
|
|
long getFileSize(FILE *fp)
|
|
{
|
|
if (!fp) return 0L;
|
|
fseek(fp, 0L, SEEK_END);
|
|
long fSize = ftell(fp);
|
|
fseek(fp, 0L, 0L);
|
|
return fSize;
|
|
}
|
|
|
|
bool isCounterclockwise(const AcGePoint3d &pts
|
|
, const AcGePoint3d &ptm
|
|
, const AcGePoint3d &pte
|
|
, const AcGeVector3d &normal)
|
|
{
|
|
AcGeVector3d vtSM(ptm - pts);
|
|
AcGeVector3d vtME(pte - ptm);
|
|
|
|
if (vtSM.crossProduct(vtME).isCodirectionalTo(normal))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
// 把pReg移动到与pCurve第一点相同的平面,平面特征取自pReg
|
|
void convertRegion(AcDbRegion *pReg, AcDbCurve *pCurve)
|
|
{
|
|
// 第一点的切线
|
|
AcGeVector3d vtTangle;
|
|
AcGePoint3d pts(AcGePoint3d::kOrigin);
|
|
pCurve->getStartPoint(pts);
|
|
pCurve->getFirstDeriv(pts, vtTangle);
|
|
vtTangle.normalize();
|
|
AcGePlane pathPlan(pts, vtTangle);
|
|
|
|
AcGePoint3d pt1;
|
|
AcGeVector3d x1, y1;
|
|
pathPlan.getCoordSystem(pt1, x1, y1);
|
|
|
|
AcGePlane regiPlan;
|
|
pReg->getPlane(regiPlan);
|
|
AcGePoint3d pt2;
|
|
AcGeVector3d x2, y2;
|
|
regiPlan.getCoordSystem(pt2, x2, y2);
|
|
|
|
AcGeMatrix3d mat;
|
|
mat.setToAlignCoordSys(pt1.orthoProject(regiPlan), x2, y2, x2.crossProduct(y2)
|
|
, pt1, x1, y1, x1.crossProduct(y1));
|
|
|
|
pReg->transformBy(mat);
|
|
|
|
}
|
|
|
|
struct RegionGeom
|
|
{
|
|
RegionGeom(AcDbRegion* pReg)
|
|
: m_ptCen(AcGePoint3d::kOrigin)
|
|
, m_dArea(.0)
|
|
, m_bVaild(false)
|
|
, m_bVoid(false)
|
|
, m_pSelf(pReg)
|
|
, m_pMotherShape(NULL)
|
|
{}
|
|
|
|
// 比自己大,且包含自己的截面
|
|
RegionGeom *m_pMotherShape;
|
|
|
|
// 形心
|
|
AcGePoint3d m_ptCen;
|
|
// 面积
|
|
double m_dArea;
|
|
//
|
|
AcDbRegion *m_pSelf;
|
|
// 是否有效
|
|
bool m_bVaild;
|
|
// 是否空心
|
|
bool m_bVoid;
|
|
|
|
// 排序用
|
|
static bool cmp(const RegionGeom *p1, const RegionGeom *p2)
|
|
{
|
|
return p1->m_dArea > p2->m_dArea;
|
|
}
|
|
|
|
};
|
|
|
|
RegionGeom* getRegionGeom(AcDbRegion *pReg)
|
|
{
|
|
RegionGeom *pRg(new RegionGeom(pReg));
|
|
if (!pReg) return pRg;
|
|
|
|
AcGePlane pln;
|
|
if (CoreTools::getRegionInfo(pReg, pRg->m_ptCen, pRg->m_dArea, pln))
|
|
pRg->m_bVaild = true;
|
|
|
|
return pRg;
|
|
}
|
|
|
|
bool regionInRegion(AcDbRegion *pRegSml, AcDbRegion *pRegBig)
|
|
{
|
|
if (!pRegSml || !pRegBig) return false;
|
|
|
|
AcGePlane plnSml, plnBig;
|
|
AcGePoint3d ptSml, ptBig;
|
|
double dSml(.0), dBig(.0);
|
|
|
|
if (!CoreTools::getRegionInfo(pRegSml, ptSml, dSml, plnSml)) return false;
|
|
if (!CoreTools::getRegionInfo(pRegBig, ptBig, dBig, plnBig)) return false;
|
|
|
|
// 不共面
|
|
if (!plnSml.isCoplanarTo(plnBig)) return false;
|
|
|
|
Geometry::Bounded_side bs = (Geometry::Bounded_side)CoreTools::ptInRegion(ptSml.convert2d(plnBig), pRegBig);
|
|
|
|
return bs == Geometry::eInside;
|
|
}
|
|
|
|
void getMotherRegion(RegionGeom &self, const std::vector<RegionGeom*> &rgs)
|
|
{
|
|
std::vector<RegionGeom*>::iterator it;
|
|
std::vector<RegionGeom*> _rgs(rgs);
|
|
|
|
self.m_pMotherShape = NULL;
|
|
|
|
for (it = _rgs.begin(); it != _rgs.end();)
|
|
{
|
|
RegionGeom &rg(**it);
|
|
// 去掉自己
|
|
if (self.m_pSelf == rg.m_pSelf)
|
|
{
|
|
_rgs.erase(it);
|
|
it = _rgs.begin();
|
|
continue;
|
|
}
|
|
|
|
// 比self面积小的,都不要
|
|
if (UPEQUAL(self.m_dArea, rg.m_dArea))
|
|
{
|
|
_rgs.erase(it);
|
|
it = _rgs.begin();
|
|
continue;
|
|
}
|
|
|
|
// self 不在其中的,不要
|
|
if (!regionInRegion(self.m_pSelf, rg.m_pSelf))
|
|
{
|
|
_rgs.erase(it);
|
|
it = _rgs.begin();
|
|
continue;
|
|
}
|
|
|
|
if (self.m_pMotherShape)
|
|
{
|
|
if (self.m_pMotherShape->m_dArea > rg.m_dArea)
|
|
self.m_pMotherShape = &rg;
|
|
}
|
|
else
|
|
self.m_pMotherShape = &rg;
|
|
|
|
_rgs.erase(it);
|
|
it = _rgs.begin();
|
|
}
|
|
return;
|
|
}
|
|
|
|
// 分析截面关系
|
|
void analyRegions(AcDbVoidPtrArray ®s, std::vector<RegionGeom*> &rgs, bool &bCombin)
|
|
{
|
|
// 首先 regs 内的region的轮廓不会相交,只会覆盖
|
|
// 所以只判断其形心是否在另一个region内就可判断是否覆盖
|
|
|
|
// 构建 RegionGeom 结构
|
|
for (int i(0); i < regs.length(); ++i)
|
|
{
|
|
RegionGeom *p = getRegionGeom((AcDbRegion*)regs[i]);
|
|
if (p->m_bVaild)
|
|
rgs.push_back(p);
|
|
}
|
|
|
|
// 分析出位置关系
|
|
for (size_t i(0); i < rgs.size(); ++i)
|
|
{
|
|
getMotherRegion(*rgs[i], rgs);
|
|
}
|
|
|
|
// 根据位置关系,得到 空心/实心 关系
|
|
std::vector<RegionGeom*> mothers;
|
|
for (size_t i(0); i < rgs.size(); ++i)
|
|
{
|
|
mothers.clear();
|
|
RegionGeom &rg(*rgs[i]);
|
|
RegionGeom *pMother(rg.m_pMotherShape);
|
|
while (pMother != NULL)
|
|
{
|
|
mothers.push_back(pMother);
|
|
pMother = pMother->m_pMotherShape;
|
|
}
|
|
|
|
int count((int)mothers.size());
|
|
|
|
if (count % 2)
|
|
rg.m_bVoid = true;
|
|
else
|
|
rg.m_bVoid = false;
|
|
}
|
|
|
|
if (regs.length() == 1)
|
|
bCombin = false;
|
|
else
|
|
{
|
|
for (size_t i(0); i < rgs.size(); ++i)
|
|
{
|
|
if (rgs[i]->m_bVoid)
|
|
{
|
|
bCombin = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
enum GeoType
|
|
{
|
|
// 2D
|
|
__kNone = 0,
|
|
kArc,
|
|
kLine,
|
|
kEllipse,
|
|
kCylindricalHelix,
|
|
kNurbSpline,
|
|
// 3D
|
|
kExtrusion,
|
|
kBlend,
|
|
kRevolution,
|
|
kSweep,
|
|
kSweptBlend,
|
|
// bim
|
|
kBims,
|
|
// 管嘴
|
|
kNozzle,
|
|
};
|
|
|
|
enum RVT_DOMAIN
|
|
{
|
|
kDomainUndefined = 0,
|
|
// 风管连接件
|
|
kDomainHvac = 1,
|
|
// 电气连接件
|
|
kDomainElectrical = 2,
|
|
// 管道连接件
|
|
kDomainPiping = 3,
|
|
// 电缆桥架连接件
|
|
kDomainCableTrayConduit = 4
|
|
};
|
|
|
|
enum RVT_ConnectorProfileType
|
|
{
|
|
kInvalid = -1,
|
|
// 圆
|
|
kRound = 0,
|
|
// 方
|
|
kRectangular = 1,
|
|
// 椭圆
|
|
kOval = 2
|
|
};
|
|
|
|
enum RVT_MEPSystemClassification
|
|
{
|
|
kUndefinedSystemClassification = 0,
|
|
kSupplyAir = 1,
|
|
kReturnAir = 2,
|
|
kExhaustAir = 3,
|
|
kOtherAir = 4,
|
|
kDataCircuit = 5,
|
|
kPowerCircuit = 6,
|
|
kSupplyHydronic = 7,
|
|
kReturnHydronic = 8,
|
|
kTelephone = 9,
|
|
kSecurity = 10,
|
|
kFireAlarm = 11,
|
|
kNurseCall = 12,
|
|
kControls = 13,
|
|
kCommunication = 14,
|
|
kCondensateDrain = 15,
|
|
kSanitary = 16,
|
|
kVent = 17,
|
|
kStorm = 18,
|
|
kDomesticHotWater = 19,
|
|
kDomesticColdWater = 20,
|
|
kRecirculation = 21,
|
|
kOtherPipe = 22,
|
|
kFireProtectWet = 23,
|
|
kFireProtectDry = 24,
|
|
kFireProtectPreaction = 25,
|
|
kFireProtectOther = 26,
|
|
kSwitchTopology = 27,
|
|
kFitting = 28,
|
|
kGlobal = 29,
|
|
kPowerBalanced = 30,
|
|
kPowerUnBalanced = 31,
|
|
kCableTrayConduit = 32
|
|
};
|
|
|
|
#define GET_TYPE(type1, type2) if (type1 == std::wstring(_T("SH")) + _T(#type2)) return k##type2
|
|
GeoType getGeoType(LPCTSTR psz)
|
|
{
|
|
if (!psz) return __kNone;
|
|
std::wstring t(psz);
|
|
GET_TYPE(t, Arc);
|
|
GET_TYPE(t, Line);
|
|
GET_TYPE(t, Ellipse);
|
|
GET_TYPE(t, CylindricalHelix);
|
|
GET_TYPE(t, NurbSpline);
|
|
GET_TYPE(t, Extrusion);
|
|
GET_TYPE(t, Blend);
|
|
GET_TYPE(t, Revolution);
|
|
GET_TYPE(t, Sweep);
|
|
GET_TYPE(t, SweptBlend);
|
|
GET_TYPE(t, Bims);
|
|
GET_TYPE(t, Nozzle);
|
|
return __kNone;
|
|
|
|
}
|
|
|
|
GeoType getGeoType(WCValue &v)
|
|
{
|
|
return getGeoType(v[_T("type")].GetString());
|
|
}
|
|
|
|
bool isGeo2D(const GeoType &type) { if (type == kNone) return false; return type < kExtrusion; }
|
|
|
|
bool isGeo3D(const GeoType &type) { if (type == kNone) return false; return type > kNurbSpline; }
|
|
|
|
template <typename T>
|
|
T parseXYZ(WCValue &v)
|
|
{
|
|
T t;
|
|
t.set(v[_T("X")].GetDouble(), v[_T("Y")].GetDouble(), v[_T("Z")].GetDouble());
|
|
return t;
|
|
}
|
|
|
|
AcGePoint3d parsePoint3D(WCValue &v)
|
|
{
|
|
if (g_nJsonVersion < 2) return AcGePoint3d::kOrigin;
|
|
|
|
return AcGePoint3d(v[_T("X")].GetDouble() * g_dUnitRate
|
|
, v[_T("Y")].GetDouble() * g_dUnitRate
|
|
, v[_T("Z")].GetDouble() * g_dUnitRate);
|
|
}
|
|
|
|
AcGeVector3d parseVector3D(WCValue &v)
|
|
{
|
|
if (g_nJsonVersion < 2) return AcGeVector3d::kIdentity;
|
|
|
|
double dX(v[_T("X")].GetDouble())
|
|
, dY(v[_T("Y")].GetDouble())
|
|
, dZ(v[_T("Z")].GetDouble());
|
|
|
|
AcGeVector3d vt(X, Y, Z);
|
|
if (vt.isUnitLength())
|
|
return vt;
|
|
else
|
|
return AcGeVector3d(dX * g_dUnitRate, dY * g_dUnitRate, dZ * g_dUnitRate);
|
|
}
|
|
|
|
void parsePoints(const CArr &ar, AcGePoint3dArray &pts)
|
|
{
|
|
for (size_t i = 0; i < ar.Size(); ++i)
|
|
{
|
|
WCValue &pt(ar[(rapidjson::SizeType)i]);
|
|
if (g_nJsonVersion < 2)
|
|
pts.append(parseXYZ<AcGePoint3d>(pt));
|
|
else
|
|
pts.append(parsePoint3D(pt));
|
|
}
|
|
}
|
|
|
|
void parseDoubles(const CArr &ar, AcGeDoubleArray &ds)
|
|
{
|
|
for (size_t i = 0; i < ar.Size(); ++i)
|
|
{
|
|
WCValue &d(ar[(rapidjson::SizeType)i]);
|
|
ds.append(d.GetDouble());
|
|
}
|
|
}
|
|
|
|
AcDb3dPolyline* pts2Polyline3D(AcGePoint3dArray &ar)
|
|
{
|
|
AcDb3dPolyline *p = new AcDb3dPolyline;
|
|
if (!p) return NULL;
|
|
for (int i = 0; i < ar.length(); ++i)
|
|
{
|
|
AcDb3dPolylineVertex *pV = new AcDb3dPolylineVertex(ar[(rapidjson::SizeType)i]);
|
|
p->appendVertex(pV);
|
|
}
|
|
return p;
|
|
}
|
|
|
|
AcGePlane parseSHPlane(WCValue &v)
|
|
{
|
|
|
|
AcGePoint3d pt;
|
|
AcGeVector3d normal;
|
|
AcGeVector3d xVec;
|
|
AcGeVector3d yVec;
|
|
if (g_nJsonVersion < 2)
|
|
{
|
|
pt = parseXYZ<AcGePoint3d>(v[_T("Origin")]);
|
|
normal = parseXYZ<AcGeVector3d>(v[_T("Normal")]);
|
|
xVec = parseXYZ<AcGeVector3d>(v[_T("XVec")]);
|
|
yVec = parseXYZ<AcGeVector3d>(v[_T("YVec")]);
|
|
}
|
|
else
|
|
{
|
|
pt = parsePoint3D(v[_T("Origin")]);
|
|
normal = parseVector3D(v[_T("Normal")]);
|
|
xVec = parseVector3D(v[_T("XVec")]);
|
|
yVec = parseVector3D(v[_T("YVec")]);
|
|
}
|
|
|
|
AcGePlane plan;
|
|
plan.set(pt, normal);
|
|
return plan;
|
|
}
|
|
|
|
AcDbEntity* parseSHArc(WCValue &v)
|
|
{
|
|
bool IsBound(v[_T("IsBound")].GetBool());
|
|
|
|
AcGePoint3d ptCenter;
|
|
AcGeVector3d vtNormal, vtYDir, vtXDir;
|
|
double dRadius;
|
|
if (g_nJsonVersion < 2)
|
|
{
|
|
ptCenter = parseXYZ<AcGePoint3d>(v[_T("Center")]);
|
|
vtNormal = parseXYZ<AcGeVector3d>(v[_T("Normal")]);
|
|
vtYDir = parseXYZ<AcGeVector3d>(v[_T("YDirection")]);
|
|
vtXDir = parseXYZ<AcGeVector3d>(v[_T("XDirection")]);
|
|
dRadius = v[_T("Radius")].GetDouble();
|
|
}
|
|
else
|
|
{
|
|
ptCenter = parsePoint3D(v[_T("Center")]);
|
|
vtNormal = parseVector3D(v[_T("Normal")]);
|
|
vtYDir = parseVector3D(v[_T("YDirection")]);
|
|
vtXDir = parseVector3D(v[_T("XDirection")]);
|
|
dRadius = v[_T("Radius")].GetDouble() * g_dUnitRate;
|
|
}
|
|
|
|
if (!IsBound)
|
|
{
|
|
return new AcDbCircle(ptCenter, vtNormal, dRadius);
|
|
}
|
|
else
|
|
{
|
|
double dSAngle(v[_T("startAngle")].GetDouble());
|
|
double dEAngle(v[_T("endAngle")].GetDouble());
|
|
AcGeMatrix3d mat;
|
|
vtXDir.normalize();
|
|
vtYDir.normalize();
|
|
vtNormal.normalize();
|
|
mat.setCoordSystem(ptCenter, vtXDir, vtYDir, vtNormal);
|
|
AcDbArc *pArc = new AcDbArc(ptCenter, AcGeVector3d::kZAxis, dRadius, dSAngle, dEAngle);
|
|
pArc->transformBy(mat);
|
|
AcGePoint3d ptC = pArc->center();
|
|
mat.setToIdentity();
|
|
mat.setTranslation(ptCenter - ptC);
|
|
pArc->transformBy(mat);
|
|
return pArc;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
AcDbEntity* parseSHLine(WCValue &v)
|
|
{
|
|
bool IsBound(v[_T("IsBound")].GetBool());
|
|
|
|
AcGeVector3d vt;
|
|
AcGePoint3d pt, ptS, ptE;
|
|
if (g_nJsonVersion < 2)
|
|
{
|
|
vt = parseXYZ<AcGeVector3d>(v[_T("Direction")]);
|
|
pt = parseXYZ<AcGePoint3d>(v[_T("Origin")]);
|
|
ptS = parseXYZ<AcGePoint3d>(v[_T("start")]);
|
|
ptE = parseXYZ<AcGePoint3d>(v[_T("end")]);
|
|
}
|
|
else
|
|
{
|
|
vt = parseVector3D(v[_T("Direction")]);
|
|
pt = parsePoint3D(v[_T("Origin")]);
|
|
ptS = parsePoint3D(v[_T("start")]);
|
|
ptE = parsePoint3D(v[_T("end")]);
|
|
}
|
|
|
|
if (IsBound)
|
|
return new AcDbLine(ptS, ptE);
|
|
else
|
|
{
|
|
AcDbRay *pRay = new AcDbRay();
|
|
pRay->setUnitDir(vt);
|
|
pRay->setBasePoint(pt);
|
|
return pRay;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
AcDbEntity* parseSHEllipse(WCValue &v)
|
|
{
|
|
bool IsBound(v[_T("IsBound")].GetBool());
|
|
|
|
AcGePoint3d ptCenter;
|
|
AcGeVector3d vtNormal, vtYDir, vtXDir;
|
|
if (g_nJsonVersion < 2)
|
|
{
|
|
ptCenter = parseXYZ<AcGePoint3d>(v[_T("Center")]);
|
|
vtNormal = parseXYZ<AcGeVector3d>(v[_T("Normal")]);
|
|
vtYDir = parseXYZ<AcGeVector3d>(v[_T("YDirection")]);
|
|
vtXDir = parseXYZ<AcGeVector3d>(v[_T("XDirection")]);
|
|
}
|
|
else
|
|
{
|
|
ptCenter = parsePoint3D(v[_T("Center")]);
|
|
vtNormal = parseVector3D(v[_T("Normal")]);
|
|
vtYDir = parseVector3D(v[_T("YDirection")]);
|
|
vtXDir = parseVector3D(v[_T("XDirection")]);
|
|
}
|
|
|
|
vtNormal.normalize();
|
|
vtYDir.normalize();
|
|
vtXDir.normalize();
|
|
|
|
double dRadiusX, dRadiusY;
|
|
if (g_nJsonVersion < 2)
|
|
{
|
|
dRadiusX = v[_T("RadiusX")].GetDouble();
|
|
dRadiusY = v[_T("RadiusY")].GetDouble();
|
|
}
|
|
else
|
|
{
|
|
dRadiusX = v[_T("RadiusX")].GetDouble() * g_dUnitRate;
|
|
dRadiusY = v[_T("RadiusY")].GetDouble() * g_dUnitRate;
|
|
}
|
|
|
|
if (!IsBound)
|
|
{
|
|
return new AcDbEllipse(ptCenter, vtNormal, vtXDir * dRadiusX, dRadiusY / dRadiusX);
|
|
}
|
|
else
|
|
{
|
|
double dSAngle(v[_T("startAngle")].GetDouble());
|
|
double dEAngle(v[_T("endAngle")].GetDouble());
|
|
return new AcDbEllipse(ptCenter, vtNormal, vtXDir * dRadiusX, dRadiusY / dRadiusX, dSAngle, dEAngle);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
AcDbEntity* parseSHCylindricalHelix(WCValue &v)
|
|
{
|
|
AcGePoint3dArray pts;
|
|
parsePoints(v[_T("points")].GetArray(), pts);
|
|
return pts2Polyline3D(pts);
|
|
}
|
|
|
|
AcDbEntity* parseSHNurbSpline(WCValue &v)
|
|
{
|
|
int iDegree(v[_T("Degree")].GetInt());
|
|
bool isClosed(v[_T("isClosed")].GetBool())
|
|
, isRational(v[_T("isRational")].GetBool());
|
|
|
|
AcGePoint3dArray ctrlPts;
|
|
parsePoints(v[_T("CtrlPoints")].GetArray(), ctrlPts);
|
|
if (ctrlPts.isEmpty()) return NULL;
|
|
|
|
AcGeDoubleArray Knots, Weights;
|
|
parseDoubles(v[_T("Knots")].GetArray(), Knots);
|
|
if (Knots.isEmpty()) return NULL;
|
|
|
|
parseDoubles(v[_T("Weights")].GetArray(), Weights);
|
|
if (Weights.isEmpty()) return NULL;
|
|
|
|
return new AcDbSpline(iDegree, isRational, isClosed, false, ctrlPts, Knots, Weights);
|
|
}
|
|
|
|
void parseSHProfile(WCValue&, AcDbVoidPtrArray&, AcGePlane *pPlan = NULL);
|
|
AcDbEntity* parsePath(const CArr&);
|
|
|
|
void parseSHExtrusion(WCValue &v, std::vector<NewSolidBase*> &solids)
|
|
{
|
|
double startOffset, endOffset;
|
|
if (g_nJsonVersion < 2)
|
|
{
|
|
startOffset = v[_T("startOffset")].GetDouble();
|
|
endOffset = v[_T("endOffset")].GetDouble();
|
|
}
|
|
else
|
|
{
|
|
startOffset = v[_T("startOffset")].GetDouble() * g_dUnitRate;
|
|
endOffset = v[_T("endOffset")].GetDouble() * g_dUnitRate;
|
|
}
|
|
|
|
AcGePlane plan;
|
|
AcDbVoidPtrArray regs;
|
|
parseSHProfile(v[_T("curve")], regs, &plan);
|
|
if (regs.isEmpty())
|
|
return;
|
|
|
|
bool bCombin(false);
|
|
std::vector<RegionGeom*> rgs;
|
|
analyRegions(regs, rgs, bCombin);
|
|
|
|
AcGeVector3d vtNormal(plan.normal()), vt;
|
|
vtNormal.normalize();
|
|
AcGePoint3d pts, pte;
|
|
plan.get(pts, vt, vt);
|
|
pte = pts;
|
|
pts += vtNormal * startOffset;
|
|
pte += vtNormal * endOffset;
|
|
|
|
AcGeMatrix3d mat;
|
|
mat.setTranslation(vtNormal * startOffset);
|
|
|
|
bool bSolid(v[_T("isSolid")].GetBool());
|
|
|
|
if (!bCombin)
|
|
{
|
|
for (int i(0); i < regs.length(); ++i)
|
|
{
|
|
AcDbRegion *pReg((AcDbRegion*)regs[i]);
|
|
pReg->transformBy(mat);
|
|
|
|
AcGeVector3d vtReg;
|
|
pReg->getNormal(vtReg);
|
|
vtReg.normalize();
|
|
int iSingle(1);
|
|
if (!vtReg.isCodirectionalTo(pte - pts))
|
|
iSingle = -1;
|
|
|
|
solids.push_back(new NewExtrude(bSolid, pReg, iSingle * pts.distanceTo(pte)));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 对 rgs 按面积从大到小排序
|
|
std::sort(rgs.begin(), rgs.end(), RegionGeom::cmp);
|
|
RevitCombination *pRc = new RevitCombination();
|
|
pRc->m_bSolid = bSolid;
|
|
pRc->m_bOrderDraw = true;
|
|
for (size_t i(0); i < rgs.size(); ++i)
|
|
{
|
|
RegionGeom &rg(*rgs[i]);
|
|
AcDbRegion *pReg(rg.m_pSelf);
|
|
|
|
pReg->transformBy(mat);
|
|
|
|
AcGeVector3d vtReg;
|
|
pReg->getNormal(vtReg);
|
|
vtReg.normalize();
|
|
int iSingle(1);
|
|
if (!vtReg.isCodirectionalTo(pte - pts))
|
|
iSingle = -1;
|
|
|
|
pRc->m_solids.push_back(new NewExtrude(!rg.m_bVoid, pReg, iSingle * pts.distanceTo(pte)));
|
|
}
|
|
solids.push_back(pRc);
|
|
}
|
|
|
|
deleteArrayVoidPtrs< AcDbRegion>(regs);
|
|
deleteContainerOfStd(rgs);
|
|
}
|
|
|
|
void parseSHBlend(WCValue &v, std::vector<NewSolidBase*> &solids)
|
|
{
|
|
bool isSolid = v[_T("isSolid")].GetBool();
|
|
|
|
AcGePlane topPlan, botPlan;
|
|
|
|
AcDbVoidPtrArray topRegs, bottomRegs;
|
|
AcDbRegion *top(NULL), *bottom(NULL);
|
|
parseSHProfile(v[_T("top")], topRegs, &topPlan);
|
|
parseSHProfile(v[_T("bottom")], bottomRegs, &botPlan);
|
|
if (topRegs.isEmpty()) return;
|
|
if (bottomRegs.isEmpty()) return;
|
|
|
|
double topOffset, bottomOffset;
|
|
if (g_nJsonVersion < 2)
|
|
{
|
|
topOffset = v[_T("topOffset")].GetDouble();
|
|
bottomOffset = v[_T("bottomOffset")].GetDouble();
|
|
}
|
|
else
|
|
{
|
|
topOffset = v[_T("topOffset")].GetDouble() * g_dUnitRate;
|
|
bottomOffset = v[_T("bottomOffset")].GetDouble() * g_dUnitRate;
|
|
}
|
|
|
|
AcGeMatrix3d topMat, botMat;
|
|
AcGeVector3d topVt(topPlan.normal()), botVt(botPlan.normal());
|
|
topVt.normalize();
|
|
botVt.normalize();
|
|
topVt *= topOffset;
|
|
botVt *= bottomOffset;
|
|
topMat.setTranslation(topVt);
|
|
botMat.setTranslation(botVt);
|
|
|
|
top = (AcDbRegion*)topRegs[0];
|
|
bottom = (AcDbRegion*)bottomRegs[0];
|
|
|
|
top->transformBy(topMat);
|
|
bottom->transformBy(botMat);
|
|
|
|
AcArray<AcDbRegion*> regs;
|
|
regs.append(top);
|
|
regs.append(bottom);
|
|
|
|
solids.push_back(new NewLoft(isSolid, regs, NULL));
|
|
|
|
deleteArrayVoidPtrs< AcDbRegion>(topRegs);
|
|
deleteArrayVoidPtrs< AcDbRegion>(bottomRegs);
|
|
|
|
}
|
|
|
|
void parseSHSweptBlend(WCValue &v, std::vector<NewSolidBase*> &solids)
|
|
{
|
|
bool isSolid = v[_T("isSolid")].GetBool();
|
|
|
|
AcDbVoidPtrArray topRegs, bottomRegs;
|
|
parseSHProfile(v[_T("top")], topRegs);
|
|
parseSHProfile(v[_T("bottom")], bottomRegs);
|
|
if (topRegs.isEmpty()) return;
|
|
if (bottomRegs.isEmpty()) return;
|
|
|
|
AcArray<AcDbRegion*> regs;
|
|
regs.append((AcDbRegion*)topRegs[0]);
|
|
regs.append((AcDbRegion*)bottomRegs[0]);
|
|
|
|
AcDbPolyline *pPath = (AcDbPolyline*)parsePath((v[_T("path")])[_T("path")].GetArray());
|
|
if (!pPath) return;
|
|
|
|
solids.push_back(new NewLoft(isSolid, regs, pPath));
|
|
|
|
DELETE_PTR(pPath);
|
|
deleteArrayVoidPtrs< AcDbRegion>(topRegs);
|
|
deleteArrayVoidPtrs< AcDbRegion>(bottomRegs);
|
|
}
|
|
|
|
void parseSHRevolution(WCValue &v, std::vector<NewSolidBase*> &solids)
|
|
{
|
|
bool isSolid = v[_T("isSolid")].GetBool();
|
|
|
|
AcGeVector3d vt;
|
|
AcGePoint3d pt;
|
|
if (g_nJsonVersion < 2)
|
|
{
|
|
vt = parseXYZ<AcGeVector3d>(v[_T("direction")]);
|
|
pt = parseXYZ<AcGePoint3d>(v[_T("point")]);
|
|
}
|
|
else
|
|
{
|
|
vt = parseVector3D(v[_T("direction")]);
|
|
pt = parsePoint3D(v[_T("point")]);
|
|
}
|
|
|
|
double dSAngle(v[_T("startAngle")].GetDouble());
|
|
double dEAngle(v[_T("endAngle")].GetDouble());
|
|
double delta(dEAngle - dSAngle);
|
|
|
|
AcDbVoidPtrArray regs;
|
|
parseSHProfile(v[_T("curve")], regs);
|
|
if (regs.isEmpty()) return;
|
|
|
|
bool bCombin(false);
|
|
std::vector<RegionGeom*> rgs;
|
|
analyRegions(regs, rgs, bCombin);
|
|
|
|
if (!bCombin)
|
|
{
|
|
AcDbRevolveOptions op;
|
|
for (int i(0); i < regs.length(); ++i)
|
|
{
|
|
AcDbRegion *pReg((AcDbRegion*)regs[i]);
|
|
solids.push_back(new NewRevolve(isSolid, pReg, pt, vt, delta, dSAngle));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
std::sort(rgs.begin(), rgs.end(), RegionGeom::cmp);
|
|
RevitCombination *pRc = new RevitCombination();
|
|
pRc->m_bSolid = isSolid;
|
|
pRc->m_bOrderDraw = true;
|
|
AcDbRevolveOptions op;
|
|
for (int i(0); i < rgs.size(); ++i)
|
|
{
|
|
RegionGeom &rg(*rgs[i]);
|
|
AcDbRegion *pReg(rg.m_pSelf);
|
|
pRc->m_solids.push_back(new NewRevolve(!rg.m_bVoid, pReg, pt, vt, delta, dSAngle));
|
|
}
|
|
solids.push_back(pRc);
|
|
}
|
|
|
|
deleteArrayVoidPtrs< AcDbRegion>(regs);
|
|
deleteContainerOfStd(rgs);
|
|
}
|
|
|
|
void parseSHSweep(WCValue &v, std::vector<NewSolidBase*> &solids)
|
|
{
|
|
bool isSolid = v[_T("isSolid")].GetBool();
|
|
AcDbVoidPtrArray regs;
|
|
parseSHProfile(v[_T("curve")], regs);
|
|
if (regs.isEmpty()) return;
|
|
|
|
bool bCombin(false);
|
|
std::vector<RegionGeom*> rgs;
|
|
analyRegions(regs, rgs, bCombin);
|
|
|
|
AcDbEntity *pPath = parsePath((v[_T("path")])[_T("path")].GetArray());
|
|
if (!pPath) return;
|
|
|
|
AcDbPolyline *pPoly(AcDbPolyline::cast(pPath));
|
|
if (!pPoly)
|
|
{
|
|
DELETE_PTR(pPath);
|
|
return;
|
|
}
|
|
|
|
if (!bCombin)
|
|
{
|
|
for (int i(0); i < regs.length(); ++i)
|
|
{
|
|
AcDbRegion *pReg((AcDbRegion*)regs[i]);
|
|
solids.push_back(new NewSweepR(isSolid, pReg, pPoly));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
std::sort(rgs.begin(), rgs.end(), RegionGeom::cmp);
|
|
RevitCombination *pRc = new RevitCombination();
|
|
pRc->m_bSolid = isSolid;
|
|
pRc->m_bOrderDraw = true;
|
|
for (int i(0); i < rgs.size(); ++i)
|
|
{
|
|
RegionGeom &rg(*rgs[i]);
|
|
AcDbRegion *pReg(rgs[i]->m_pSelf);
|
|
pRc->m_solids.push_back(new NewSweepR(!rg.m_bVoid, pReg, pPoly));
|
|
}
|
|
solids.push_back(pRc);
|
|
}
|
|
|
|
deleteArrayVoidPtrs< AcDbRegion>(regs);
|
|
deleteContainerOfStd(rgs);
|
|
DELETE_PTR(pPoly);
|
|
}
|
|
|
|
void parseSHNozzle(WCValue &v, std::vector<NewSolidBase*> &solids)
|
|
{
|
|
NewNozzle *pNozz = new NewNozzle;
|
|
pNozz->m_bSolid = true;
|
|
pNozz->m_nozz.bTwoFlags = 2;// 不需要绘制法兰
|
|
|
|
RVT_ConnectorProfileType Shape = (RVT_ConnectorProfileType)v[_T("m_Shape")].GetInt();
|
|
RVT_DOMAIN Domain = (RVT_DOMAIN)v[_T("m_Domain")].GetInt();
|
|
|
|
if (Shape == kRound)
|
|
{
|
|
if (Domain == kDomainHvac)
|
|
pNozz->m_nozz.nType = 2;
|
|
else
|
|
pNozz->m_nozz.nType = 0;
|
|
}
|
|
else if (Shape == kRectangular)
|
|
pNozz->m_nozz.nType = 1;
|
|
else
|
|
{
|
|
pNozz->m_nozz.nType = 0;
|
|
Shape = kRound;
|
|
acutPrintf(_T("\n出现上华软件不支持的管口!"));
|
|
DELETE_PTR(pNozz);
|
|
return;
|
|
}
|
|
|
|
if (Domain == kDomainPiping)
|
|
{
|
|
pNozz->m_nozz.nCmd = 0;
|
|
}
|
|
else if (Domain == kDomainHvac)
|
|
{
|
|
pNozz->m_nozz.nCmd = 1;
|
|
}
|
|
else
|
|
{
|
|
pNozz->m_nozz.nCmd = 0;
|
|
acutPrintf(_T("\n出现上华软件不支持的系统!"));
|
|
DELETE_PTR(pNozz);
|
|
return;
|
|
}
|
|
AcGeVector3d vtDir(parseVector3D(v[_T("m_Direction")]));
|
|
AcGePoint3d ptOrg(parsePoint3D(v[_T("m_Origin")]));
|
|
|
|
pNozz->m_ptOrg = ptOrg;
|
|
pNozz->m_vtDir = vtDir;
|
|
|
|
if (Shape == kRound)
|
|
{
|
|
pNozz->m_nozz.dVal1 = v[_T("m_dRadius")].GetDouble() * 2 * g_dUnitRate;
|
|
pNozz->m_nozz.dVal2 = pNozz->m_nozz.dVal1;
|
|
pNozz->m_nozz.dVal3 = pNozz->m_nozz.dVal1;
|
|
pNozz->m_nozz.dVal4 = pNozz->m_nozz.dVal1;
|
|
pNozz->m_nozz.dVal5 = .0;
|
|
solids.push_back(pNozz);
|
|
}
|
|
else if (Shape == kRectangular)
|
|
{
|
|
pNozz->m_nozz.dVal1 = v[_T("m_dWidth")].GetDouble() * g_dUnitRate;
|
|
pNozz->m_nozz.dVal2 = v[_T("m_dHeight")].GetDouble() * g_dUnitRate;
|
|
pNozz->m_nozz.dVal3 = 0.;
|
|
pNozz->m_nozz.dVal4 = 0.;
|
|
pNozz->m_nozz.dVal5 = 0.;
|
|
solids.push_back(pNozz);
|
|
}
|
|
else
|
|
DELETE_PTR(pNozz);
|
|
}
|
|
|
|
void parseSHGeo3D(WCValue &v, std::vector<NewSolidBase*> &ar)
|
|
{
|
|
std::wstring sType(v[_T("type")].GetString());
|
|
GeoType type = getGeoType(sType.c_str());
|
|
switch (type)
|
|
{
|
|
case kExtrusion:
|
|
return parseSHExtrusion(v, ar);
|
|
case kBlend:
|
|
return parseSHBlend(v, ar);
|
|
case kRevolution:
|
|
return parseSHRevolution(v, ar);
|
|
case kSweep:
|
|
return parseSHSweep(v, ar);
|
|
case kSweptBlend:
|
|
return parseSHSweptBlend(v, ar);
|
|
case kNozzle:
|
|
return parseSHNozzle(v, ar);
|
|
case kArc:
|
|
case kLine:
|
|
case kEllipse:
|
|
case kCylindricalHelix:
|
|
case kNurbSpline:
|
|
break;
|
|
case kBims:
|
|
case kNone:
|
|
default:
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
AcDbEntity* parseSHGeo2D(WCValue &v, GeoType &type, bool &isSolid)
|
|
{
|
|
std::wstring sType(v[_T("type")].GetString());
|
|
type = getGeoType(sType.c_str());
|
|
switch (type)
|
|
{
|
|
case kArc:
|
|
return parseSHArc(v);
|
|
case kLine:
|
|
return parseSHLine(v);
|
|
case kEllipse:
|
|
return parseSHEllipse(v);
|
|
case kCylindricalHelix:
|
|
return parseSHCylindricalHelix(v);
|
|
case kNurbSpline:
|
|
return parseSHNurbSpline(v);
|
|
case kExtrusion:
|
|
case kBlend:
|
|
case kRevolution:
|
|
case kSweep:
|
|
case kSweptBlend:
|
|
case kBims:
|
|
case kNone:
|
|
default:
|
|
break;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void parseSHProfile(WCValue &v, AcDbVoidPtrArray ®s, AcGePlane *pPlan)
|
|
{
|
|
if (pPlan) *pPlan = parseSHPlane(v[_T("plane")]);
|
|
|
|
GeoType type(__kNone);
|
|
bool isSolid(false);
|
|
AcDbVoidPtrArray curves;
|
|
const CArr &loops = v[_T("loops")].GetArray();
|
|
for (int i = 0; i < loops.Size(); ++i)
|
|
{
|
|
deleteArrayVoidPtrs< AcDbEntity>(curves);
|
|
const CArr &loop = loops[i][_T("loop")].GetArray();
|
|
for (int j = 0; j < loop.Size(); ++j)
|
|
{
|
|
WCValue &crv(loop[j]);
|
|
AcDbEntity *pCurve(parseSHGeo2D(crv, type, isSolid));
|
|
if (pCurve) curves.append(pCurve);
|
|
}
|
|
AcDbRegion *pReg(CoreTools::createRegion(curves));
|
|
#ifndef NDEBUG
|
|
if (!pReg)
|
|
{
|
|
for (int i = 0; i < curves.length(); ++i)
|
|
{
|
|
CoreTools::CloneAndAddToModelSpace((AcDbEntity*)curves[i], 1);
|
|
}
|
|
CoreTools::CloneAndAddToModelSpace(pReg, 1);
|
|
}
|
|
#endif // !NDEBUG
|
|
if (pReg)
|
|
regs.append(pReg);
|
|
}
|
|
deleteArrayVoidPtrs< AcDbEntity>(curves);
|
|
}
|
|
|
|
AcDbEntity* parsePath(const CArr &ar)
|
|
{
|
|
GeoType type1(__kNone), type2(__kNone);
|
|
bool isSolid(false);
|
|
|
|
AcDbVoidPtrArray crvs;
|
|
for (size_t i = 0; i < ar.Size(); ++i)
|
|
{
|
|
AcDbEntity *pCurve(parseSHGeo2D(ar[(rapidjson::SizeType)i], type1, isSolid));
|
|
if (!pCurve->isKindOf(AcDbCurve::desc())) continue;
|
|
|
|
AcDbEllipse *pEll(AcDbEllipse::cast(pCurve));
|
|
AcDb3dPolyline *p3dL(AcDb3dPolyline::cast(pCurve));
|
|
AcDbSpline *pSpline(AcDbSpline::cast(pCurve));
|
|
if (pEll || p3dL || pSpline)
|
|
{
|
|
AcDbPolyline *p = CoreTools::spliteCurve((AcDbCurve*)pCurve, 20);
|
|
if (p)
|
|
{
|
|
AcDbVoidPtrArray arr;
|
|
p->explode(arr);
|
|
crvs.append(arr);
|
|
}
|
|
}
|
|
else
|
|
crvs.append(pCurve);
|
|
}
|
|
|
|
|
|
AcDbPolyline *pL(NULL);
|
|
std::vector<AcDbPolyline*> polys;
|
|
if (CoreTools::MakePolyline(crvs, polys))
|
|
pL = (AcDbPolyline*)((AcDbPolyline*)polys[0]->clone());
|
|
|
|
deleteArrayVoidPtrs< AcDbEntity>(crvs);
|
|
deleteContainerOfStd(polys);
|
|
return pL;
|
|
}
|
|
|
|
bool parseJsonConfig(WDocument &doc)
|
|
{
|
|
MIt it = doc.FindMember(_T("Config"));
|
|
if (it == doc.MemberEnd())
|
|
{
|
|
AfxMessageBox(_T("未找到配置信息!"));
|
|
return false;
|
|
}
|
|
int __v(2);
|
|
g_nJsonVersion = it->value[_T("version")].GetInt();
|
|
if (g_nJsonVersion != __v)
|
|
{
|
|
CString str;
|
|
str.Format(_T("文件版本信息错误(当前版本为%d,文件版本为%d)"), __v, g_nJsonVersion);
|
|
AfxMessageBox(str);
|
|
return false;
|
|
}
|
|
|
|
g_dUnitRate = it->value[_T("UnitRate")].GetDouble();
|
|
return true;
|
|
}
|
|
|
|
void parseCombin(WCValue &v, std::vector<std::vector<CString>> &coms)
|
|
{
|
|
if (!v.IsArray()) return;
|
|
std::vector<CString> vec;
|
|
for (VCIt it = v.Begin(); it != v.End(); ++it)
|
|
{
|
|
vec.clear();
|
|
if (!it->IsObject()) continue;
|
|
MCIt itVoids = it->FindMember(_T("Voids"));
|
|
if (itVoids != it->MemberEnd())
|
|
{
|
|
if (itVoids->value.IsArray())
|
|
{
|
|
for (VCIt _it = itVoids->value.Begin(); _it != itVoids->value.End(); ++_it)
|
|
{
|
|
vec.push_back(_it->GetString());
|
|
}
|
|
}
|
|
}
|
|
MCIt itSolids = it->FindMember(_T("Solids"));
|
|
if (itSolids != it->MemberEnd())
|
|
{
|
|
if (itSolids->value.IsArray())
|
|
{
|
|
for (VCIt _it = itSolids->value.Begin(); _it != itSolids->value.End(); ++_it)
|
|
{
|
|
vec.push_back(_it->GetString());
|
|
}
|
|
}
|
|
}
|
|
coms.push_back(vec);
|
|
}
|
|
}
|
|
|
|
void parseGeos(WValue &v
|
|
, const std::vector<std::vector<CString>> &combs
|
|
, std::vector<NewSolidBase*> &geos)
|
|
{
|
|
if (!v.IsArray()) return;
|
|
|
|
// 处理一下combs,得到所有组合要用到的 uid
|
|
std::set<CString> uids;
|
|
for (size_t i(0); i < combs.size(); ++i)
|
|
{
|
|
const std::vector<CString> &vec(combs[i]);
|
|
for (size_t j(0); j < vec.size(); ++j)
|
|
uids.insert(vec[j]);
|
|
}
|
|
|
|
CString uid(_T(""));
|
|
for (VCIt it = v.Begin(); it != v.End();)
|
|
{
|
|
WCValue &va(*it);
|
|
if (!va.IsObject()) continue;
|
|
|
|
MCIt itID = va.FindMember(_T("elementId"));
|
|
if (itID == va.MemberEnd())
|
|
uid = _T("-1");
|
|
else
|
|
uid = itID->value.GetString();
|
|
|
|
if (uids.find(uid) == uids.end())
|
|
{
|
|
parseSHGeo3D(va, geos);
|
|
v.Erase(it);
|
|
it = v.Begin();
|
|
continue;
|
|
}
|
|
++it;
|
|
}
|
|
|
|
for (size_t i(0); i < combs.size(); ++i)
|
|
{
|
|
const std::vector<CString> &vec(combs[i]);
|
|
RevitCombination *pCmb = new RevitCombination();
|
|
for (size_t j(0); j < vec.size(); ++j)
|
|
{
|
|
for (VCIt it = v.Begin(); it != v.End(); ++it)
|
|
{
|
|
WCValue &va(*it);
|
|
if (!va.IsObject()) continue;
|
|
|
|
MCIt itID = va.FindMember(_T("elementId"));
|
|
if (itID == va.MemberEnd())
|
|
uid = _T("-1");
|
|
else
|
|
uid = itID->value.GetString();
|
|
|
|
if (uid != vec[j]) continue;
|
|
|
|
std::vector<NewSolidBase*> subgeos;
|
|
parseSHGeo3D(va, subgeos);
|
|
|
|
if (!subgeos.empty())
|
|
pCmb->m_solids.insert(pCmb->m_solids.end(), subgeos.begin(), subgeos.end());
|
|
|
|
break;
|
|
}
|
|
}
|
|
geos.push_back(pCmb);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void ParseRevitFamily::parseFile2String(LPCTSTR pszJson, std::wstring & json)
|
|
{
|
|
json.clear();
|
|
FILE *fp(NULL);
|
|
char *readBuffer(NULL);
|
|
fp = _tfopen(pszJson, _T("rb"));
|
|
if (!fp) return;
|
|
|
|
long fSize = getFileSize(fp);
|
|
++fSize;
|
|
|
|
readBuffer = new char[fSize];
|
|
::memset(readBuffer, 0, sizeof(char) * (fSize));
|
|
FileReadStream bis(fp, readBuffer, fSize);
|
|
|
|
AutoUTFInputStream<unsigned, FileReadStream> eis(bis);
|
|
|
|
WDocument doc;
|
|
doc.ParseStream<0, AutoUTF<unsigned> >(eis);
|
|
if (readBuffer) delete[] readBuffer;
|
|
if (fp) fclose(fp);
|
|
|
|
if (doc.HasParseError()) return;
|
|
|
|
WStringBuffer buffer;
|
|
Writer<WStringBuffer, UTF16<>, UTF16<>> writer(buffer);
|
|
doc.Accept(writer);
|
|
|
|
json = buffer.GetString();
|
|
}
|
|
|
|
void ParseRevitFamily::parseJson(std::wstring & json, CPtrArray &ar)
|
|
{
|
|
WDocument doc;
|
|
doc.Parse(json);
|
|
|
|
if (doc.HasParseError()) return;
|
|
|
|
if (doc.IsArray())
|
|
{ // 旧版本
|
|
std::vector<NewSolidBase*> _ar;
|
|
parseGeos(doc, std::vector<std::vector<CString>>(), _ar);
|
|
|
|
Adesk::Int32 id = ::_time32(NULL);
|
|
for (int i(0); i < _ar.size(); ++i)
|
|
{
|
|
ar.Add(NewSolidBase::makeXPrimData(_ar[i], id++));
|
|
}
|
|
|
|
deleteContainerOfStd(_ar);
|
|
return;
|
|
}
|
|
|
|
if (!parseJsonConfig(doc)) return;
|
|
|
|
// 先把 GeomCombination 处理一下
|
|
MIt itComs = doc.FindMember(_T("Combin"));
|
|
if (itComs == doc.MemberEnd()) return;
|
|
std::vector<std::vector<CString>> jsoncoms;
|
|
parseCombin(itComs->value, jsoncoms);
|
|
|
|
MIt itGeos = doc.FindMember(_T("Geos"));
|
|
if (itGeos == doc.MemberEnd()) return;
|
|
std::vector<NewSolidBase*> _ar;
|
|
parseGeos(itGeos->value, jsoncoms, _ar);
|
|
|
|
Adesk::Int32 id = ::_time32(NULL);
|
|
for (int i(0); i < _ar.size(); ++i)
|
|
{
|
|
ar.Add(NewSolidBase::makeXPrimData(_ar[i], id++));
|
|
}
|
|
deleteContainerOfStd(_ar);
|
|
}
|
|
|
|
void ParseRevitFamily::parseBimDatas(std::wstring &json, SH_BIM_BLOCK &bims)
|
|
{
|
|
WDocument doc;
|
|
doc.Parse(json);
|
|
|
|
if (doc.HasParseError()) return;
|
|
|
|
if (doc.IsArray())
|
|
{ // 旧版本
|
|
for (VCIt it = doc.Begin(); it != doc.End(); ++it)
|
|
{
|
|
if (!it->IsObject()) continue;
|
|
WCValue &v(*it);
|
|
std::wstring sType(v[_T("type")].GetString());
|
|
GeoType type = getGeoType(sType.c_str());
|
|
if (type != kBims) continue;
|
|
WCValue &jbims = v[_T("bims")];
|
|
WCValue::ConstMemberIterator bit = jbims.MemberBegin();
|
|
std::wstring name, value;
|
|
for (; bit != jbims.MemberEnd(); ++bit)
|
|
{
|
|
name = bit->name.GetString();
|
|
value = bit->value.GetString();
|
|
bims.push_back(std::make_pair(name.c_str(), value.c_str()));
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (!parseJsonConfig(doc)) return;
|
|
|
|
std::map<CString, std::vector<std::pair<CString, CString>>> bimDatas;
|
|
|
|
MIt itBims = doc.FindMember(_T("Bims"));
|
|
if (itBims == doc.MemberEnd()) return;
|
|
WValue &vBims = itBims->value;
|
|
GeoType type = getGeoType(vBims[_T("type")].GetString());
|
|
if (type != kBims) return;
|
|
|
|
WCValue &jbims = vBims[_T("bims")];
|
|
MCIt itGrp = jbims.MemberBegin();
|
|
std::wstring sGrpName, value;
|
|
std::vector<std::pair<CString, CString>> vv;
|
|
for (; itGrp != jbims.MemberEnd(); ++itGrp)
|
|
{
|
|
sGrpName = itGrp->name.GetString();
|
|
WCValue &vGrp(itGrp->value);
|
|
MCIt it = vGrp.MemberBegin();
|
|
vv.clear();
|
|
for (; it != vGrp.MemberEnd(); ++it)
|
|
{
|
|
if (!it->value.IsNull())
|
|
vv.push_back(std::make_pair(it->name.GetString(), it->value.GetString()));
|
|
}
|
|
|
|
bimDatas.insert(std::make_pair(sGrpName.c_str(), vv));
|
|
}
|
|
|
|
// 取 PG_MECHANICAL, PG_MATERIALS, PG_GENERAL, PG_GEOMETRY
|
|
std::map<CString, std::vector<std::pair<CString, CString>>>::const_iterator _it(bimDatas.end());
|
|
_it = bimDatas.find(_T("PG_MECHANICAL"));
|
|
if (_it != bimDatas.end())
|
|
{
|
|
const std::vector<std::pair<CString, CString>> &v(_it->second);
|
|
bims.insert(bims.end(), v.begin(), v.end());
|
|
}
|
|
|
|
_it = bimDatas.find(_T("PG_MATERIALS"));
|
|
if (_it != bimDatas.end())
|
|
{
|
|
const std::vector<std::pair<CString, CString>> &v(_it->second);
|
|
bims.insert(bims.end(), v.begin(), v.end());
|
|
}
|
|
|
|
_it = bimDatas.find(_T("PG_GENERAL"));
|
|
if (_it != bimDatas.end())
|
|
{
|
|
const std::vector<std::pair<CString, CString>> &v(_it->second);
|
|
bims.insert(bims.end(), v.begin(), v.end());
|
|
}
|
|
|
|
_it = bimDatas.find(_T("PG_GEOMETRY"));
|
|
if (_it != bimDatas.end())
|
|
{
|
|
const std::vector<std::pair<CString, CString>> &v(_it->second);
|
|
bims.insert(bims.end(), v.begin(), v.end());
|
|
}
|
|
}
|
|
|