#include "StdAfx.h" #include #include #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 &rgs) { std::vector::iterator it; std::vector _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 &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 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 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(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(v[_T("Origin")]); normal = parseXYZ(v[_T("Normal")]); xVec = parseXYZ(v[_T("XVec")]); yVec = parseXYZ(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(v[_T("Center")]); vtNormal = parseXYZ(v[_T("Normal")]); vtYDir = parseXYZ(v[_T("YDirection")]); vtXDir = parseXYZ(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(v[_T("Direction")]); pt = parseXYZ(v[_T("Origin")]); ptS = parseXYZ(v[_T("start")]); ptE = parseXYZ(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(v[_T("Center")]); vtNormal = parseXYZ(v[_T("Normal")]); vtYDir = parseXYZ(v[_T("YDirection")]); vtXDir = parseXYZ(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 &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 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 &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 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 &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 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 &solids) { bool isSolid = v[_T("isSolid")].GetBool(); AcGeVector3d vt; AcGePoint3d pt; if (g_nJsonVersion < 2) { vt = parseXYZ(v[_T("direction")]); pt = parseXYZ(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 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 &solids) { bool isSolid = v[_T("isSolid")].GetBool(); AcDbVoidPtrArray regs; parseSHProfile(v[_T("curve")], regs); if (regs.isEmpty()) return; bool bCombin(false); std::vector 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 &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 &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 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> &coms) { if (!v.IsArray()) return; std::vector 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> &combs , std::vector &geos) { if (!v.IsArray()) return; // 处理一下combs,得到所有组合要用到的 uid std::set uids; for (size_t i(0); i < combs.size(); ++i) { const std::vector &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 &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 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 eis(bis); WDocument doc; doc.ParseStream<0, AutoUTF >(eis); if (readBuffer) delete[] readBuffer; if (fp) fclose(fp); if (doc.HasParseError()) return; WStringBuffer buffer; Writer, 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 _ar; parseGeos(doc, std::vector>(), _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> jsoncoms; parseCombin(itComs->value, jsoncoms); MIt itGeos = doc.FindMember(_T("Geos")); if (itGeos == doc.MemberEnd()) return; std::vector _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>> 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> 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>>::const_iterator _it(bimDatas.end()); _it = bimDatas.find(_T("PG_MECHANICAL")); if (_it != bimDatas.end()) { const std::vector> &v(_it->second); bims.insert(bims.end(), v.begin(), v.end()); } _it = bimDatas.find(_T("PG_MATERIALS")); if (_it != bimDatas.end()) { const std::vector> &v(_it->second); bims.insert(bims.end(), v.begin(), v.end()); } _it = bimDatas.find(_T("PG_GENERAL")); if (_it != bimDatas.end()) { const std::vector> &v(_it->second); bims.insert(bims.end(), v.begin(), v.end()); } _it = bimDatas.find(_T("PG_GEOMETRY")); if (_it != bimDatas.end()) { const std::vector> &v(_it->second); bims.insert(bims.end(), v.begin(), v.end()); } }