#include "stdafx.h" #include "math.h" #include "UITools.h" #include #include #include #include #include "sys/stat.h" #include "aecdbObjXDataMap.h" #include "AecDbEwPipe.h" #include "LayerMgr.h" #include "KTSetting.h" #include "GsPreviewCtrlEx.h" #include "AecDbEwEquipment.h" #include "AecDbEarthworm.h" #include "AecDbShEarthWorm.h" #include "aecdbportroom.h" #include "dbobjptr.h" #include "KTCADUtilityEx.h" #include "ImpMD5.h" #include "CoreTools.h" #define FILE_NAME_INI _T("\\uicache.dat") #define LENGTH_NodeDef 64 //#define LENGTH_BUFFER 2*MAX_PATH extern HINSTANCE _hdllInstance; namespace { bool readINIStringField(LPCTSTR path, LPCTSTR section, LPCTSTR key, std::wstring &str) { if (!path || !section || !key) return _T(""); int len = MAX_PATH; TCHAR *psz = new TCHAR[len]; ::memset(psz, 0, sizeof(TCHAR) * len); DWORD dwRel = ::GetPrivateProfileString(section, key, _T(""), psz, len, path); if (!dwRel) return false; while (dwRel == len - 1) { len *= 2; DELETE_ARR_(psz); psz = new TCHAR[len]; ::memset(psz, 0, sizeof(TCHAR)*len); dwRel = ::GetPrivateProfileString(section, key, _T(""), psz, len, path); } str = psz; DELETE_ARR_(psz); psz = NULL; return true; } CString getCatchFilePath(bool bCreate) { CString str = FilePath::getProgramDataFolder() + FILE_NAME_INI; // 如果不存在,则创建 if (_taccess(str, 0x0) != 0x0 && bCreate) { std::fstream fs; fs.open(str, std::ios::out); if (!fs.good()) return _T(""); fs.close(); } return str; } bool createDir(LPCTSTR psz) { if (!psz) return false; // 先判断目录是否存在,如不存在,则新建,如存在,则返回 struct _stat fstat; if ((_tstat(psz, &fstat) == 0) && (fstat.st_mode & _S_IFDIR)) return true; return ::CreateDirectory(psz, NULL) ? true : false; } CString getDbTextString(AcDbObjectId id) { CString s(_T("")); OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbText, pText) if (!pText) return s; s = pText->textString(); OPENOBJ_END() return s; } struct _compare_stake_all_ { _compare_stake_all_(bool bStakeDistBySort) : _bStakeDistBySort(bStakeDistBySort) {} bool _bStakeDistBySort; bool operator () (AcDbObjectId &id1, AcDbObjectId &id2) { AecDbObjXDataMap xmap; double stakeDist1(.0), pointDist1(.0); double stakeDist2(.0), pointDist2(.0); if (xmap.Read(id1, SHS_STAKE)) { xmap.GetAt(SHS_STAKE_DIST, stakeDist1); xmap.GetAt(SHS_STAKE_PT_DIST, pointDist1); } xmap.Empty(); if (xmap.Read(id2, SHS_STAKE)) { xmap.GetAt(SHS_STAKE_DIST, stakeDist2); xmap.GetAt(SHS_STAKE_PT_DIST, pointDist2); } if (_bStakeDistBySort) return stakeDist1 < stakeDist2; else return pointDist1 < pointDist2; } }; Acad::ErrorStatus getDistAtPoint(AcDbObjectId id, const AcGePoint3d &pt, double &dist) { OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbCurve, pPoly) if (pPoly) return pPoly->getDistAtPoint(pt, dist); OPENOBJ_END(); return Acad::eInvalidInput; } void drawGrid(const AcGePoint3d &ptOrig, AcGeVector3d &vt1, AcGeVector3d &vt2, const AcGeVector3d &vtDir, const int &clr, const double &dLen) { double delta = .1; // .1米画一个格 double stake1 = .01; // 刻度长度.02 double stake2 = .04; // 米刻度长度.04 int count = dLen / 2 / delta; AcGePoint3d pt; AcGeVector3d vt(vtDir); bool bM(false); AcDbText Txt; Txt.setHorizontalMode(AcDb::kTextMid); Txt.setVerticalMode(AcDb::kTextVertMid); Txt.setHeight(.05); Txt.setRotation(PI*.5); CString sTxt(_T("")); for (int i = 0; i < count; ++i) { vt = vtDir; vt *= (delta * i); bM = (i % 10 == 0); vt1.normalize(); vt2.normalize(); vt1 *= bM ? stake2 : stake1; vt2 *= bM ? stake2 : stake1; if (bM) { sTxt.Format(_T("%d"), (int)(i* .1)); Txt.setTextString(sTxt); } pt = ptOrig + vt; AcDbLine *pLine = new AcDbLine(pt + vt1, pt - vt1); pLine->setColorIndex(clr); CoreTools::AddToModelSpace(pLine); if (bM) { Txt.setAlignmentPoint(pt); CoreTools::AddToModelSpace((AcDbEntity*)Txt.clone()); } pt = ptOrig - vt; pLine = new AcDbLine(pt + vt1, pt - vt1); pLine->setColorIndex(clr); CoreTools::AddToModelSpace(pLine); if (bM) { Txt.setAlignmentPoint(pt); CoreTools::AddToModelSpace((AcDbEntity*)Txt.clone()); } pt = ptOrig + vt; pLine = new AcDbLine(pt + vt2, pt - vt2); pLine->setColorIndex(clr); CoreTools::AddToModelSpace(pLine); if (bM) { Txt.setAlignmentPoint(pt); CoreTools::AddToModelSpace((AcDbEntity*)Txt.clone()); } pt = ptOrig - vt; pLine = new AcDbLine(pt + vt2, pt - vt2); pLine->setColorIndex(clr); CoreTools::AddToModelSpace(pLine); if (bM) { Txt.setAlignmentPoint(pt); CoreTools::AddToModelSpace((AcDbEntity*)Txt.clone()); } } } } #pragma region UIDataCache bool UIDataCache::FindNode(LPCTSTR pszSection, EWFnctNode *pNode) { if (!pszSection || !pNode) return false; CString path(getCatchFilePath(false)); if (_waccess(path, 0x00) != 0x00) return false; std::vector sections; GetAllSections(sections, path); std::vector::iterator it = std::find(sections.begin(), sections.end(), pszSection); if (it == sections.end()) return false; std::wstring strRes(_T("")); if (readINIStringField(path, pszSection, _T("dDistFromPre"), strRes)) pNode->dDistFromPre = _ttof(strRes.c_str()); if (readINIStringField(path, pszSection, _T("eFnType"), strRes)) pNode->eFnType = (EFnctType)_ttoi(strRes.c_str()); for (int i= 0; i < LENGTH_NodeDef; ++i) { if (readINIStringField(path, pszSection, _T("fNodeDef") + TypeConvert::i2s(i), strRes)) pNode->fNodeDef[i] = _ttof(strRes.c_str()); } if (readINIStringField(path, pszSection, _T("szStake"), strRes)) ::_tcscpy(pNode->szStake, strRes.c_str()); if (readINIStringField(path, pszSection, _T("szNodeSpec"), strRes)) ::_tcscpy(pNode->szNodeSpec, strRes.c_str()); if (readINIStringField(path, pszSection, _T("szNodeDefSpec"), strRes)) ::_tcscpy(pNode->szNodeDefSpec, strRes.c_str()); if (readINIStringField(path, pszSection, _T("nRoomIndex"), strRes)) pNode->nRoomIndex = _ttoi(strRes.c_str()); if (readINIStringField(path, pszSection, _T("nFlag"), strRes)) pNode->nFlag = _ttoi(strRes.c_str()); return true; } bool UIDataCache::WriteNode(LPCTSTR pszSection, EWFnctNode *pNode) { if (!pszSection || !pNode) return false; CString path(getCatchFilePath(true)); if (_waccess(path, 0x00) != 0x00) return false; ::WritePrivateProfileString(pszSection, _T("dDistFromPre"), TypeConvert::f2s(pNode->dDistFromPre), path); ::WritePrivateProfileString(pszSection, _T("eFnType"), TypeConvert::i2s(pNode->eFnType), path); CString key(_T("fNodeDef")); for (int i= 0; i < LENGTH_NodeDef; ++i) { ::WritePrivateProfileString(pszSection, key + TypeConvert::i2s(i), TypeConvert::f2s(pNode->fNodeDef[i]), path); } ::WritePrivateProfileString(pszSection, _T("szStake"), pNode->szStake, path); ::WritePrivateProfileString(pszSection, _T("szNodeSpec"), pNode->szNodeSpec, path); ::WritePrivateProfileString(pszSection, _T("szNodeDefSpec"), pNode->szNodeDefSpec, path); ::WritePrivateProfileString(pszSection, _T("nRoomIndex"), TypeConvert::i2s(pNode->nRoomIndex), path); ::WritePrivateProfileString(pszSection, _T("nFlag"), TypeConvert::i2s(pNode->nFlag), path); return false; } ////////////////////////////////////////////////////////////////////////// #define WRITE_VALUE(type, value)\ std::wstring str = TypeConvert::convert(value);\ return Write(pszSection, pszKye, str.c_str()) #define READ_VALUE(type, value)\ std::wstring str(_T(""));\ if (Read(pszSection, pszKye, str))\ {\ value = TypeConvert::convert(str);\ return true;\ }\ return false\ bool UIDataCache::Write(LPCTSTR pszSection, LPCTSTR pszKye, LPCTSTR pszValue) { if (!pszSection || !pszKye || !pszValue) return false; CString path(getCatchFilePath(true)); if (_waccess(path, 0x00) != 0x00) return false; return ::WritePrivateProfileString(pszSection, pszKye, pszValue, path) ? true : false; } bool UIDataCache::Write(LPCTSTR psz, LPCTSTR pszSection, ...) { if (!psz || !pszSection) return false; va_list vlist; va_start(vlist, pszSection); CString sFormat(psz), sWildCard(_T("")); int idx(sFormat.Find(_T('%'))), i(0); CString strName(_T("")); while (idx != -1) { strName.Format(_T("%d"), i); sWildCard = sFormat.Mid(idx, 2); if (sWildCard.CompareNoCase(_T("%d")) == 0) UIDataCache::Write(pszSection, strName, *va_arg(vlist, double*)); else if (sWildCard.CompareNoCase(_T("%f")) == 0) UIDataCache::Write(pszSection, strName, *va_arg(vlist, float*)); else if (sWildCard.CompareNoCase(_T("%s")) == 0) UIDataCache::Write(pszSection, strName, *va_arg(vlist, CString*)); else if (sWildCard.CompareNoCase(_T("%i")) == 0) UIDataCache::Write(pszSection, strName, *va_arg(vlist, int*)); else if (sWildCard.CompareNoCase(_T("%p")) == 0) UIDataCache::Write(pszSection, strName, *va_arg(vlist, AcGePoint3d*)); else if (sWildCard.CompareNoCase(_T("%a")) == 0) UIDataCache::Write(pszSection, strName, *va_arg(vlist, CStringArray*)); idx = sFormat.Find(_T('%'), idx + 2); strName.Empty(); ++i; } va_end(vlist); return true; } bool UIDataCache::Write(LPCTSTR pszSection, LPCTSTR pszKye, const AcGePoint3d &pt) { std::wstringstream ss; ss << pt.x << _T(",") << pt.y << _T(",") << pt.z; return UIDataCache::Write(pszSection, pszKye, ss.str().c_str()); } bool UIDataCache::Write(LPCTSTR pszSection, LPCTSTR pszKye, const CStringArray &ar) { CString str(_T("")); for (int i = 0; i < ar.GetSize(); ++i) { str += ar[i]; if (i != ar.GetSize() - 1) str += _T(","); } return UIDataCache::Write(pszSection, pszKye, str); } bool UIDataCache::Read(LPCTSTR pszSection, LPCTSTR pszKye, std::wstring &sValue) { if (!pszSection || !pszKye) return false; CString path(getCatchFilePath(false)); if (_waccess(path, 0x00) != 0x00) return false; return readINIStringField(path, pszSection, pszKye, sValue); } bool UIDataCache::Read(LPCTSTR psz, LPCTSTR pszSection, ...) { if (!psz || !pszSection) return false; va_list vlist; va_start(vlist, pszSection); CString sFormat(psz), sWildCard(_T("")); int idx(sFormat.Find(_T('%'))), i(0); CString strName(_T("")); while (idx != -1) { strName.Format(_T("%d"), i); sWildCard = sFormat.Mid(idx, 2); if (sWildCard.CompareNoCase(_T("%d")) == 0) UIDataCache::Read(pszSection, strName, *va_arg(vlist, double*)); else if (sWildCard.CompareNoCase(_T("%f")) == 0) UIDataCache::Read(pszSection, strName, *va_arg(vlist, float*)); else if (sWildCard.CompareNoCase(_T("%s")) == 0) UIDataCache::Read(pszSection, strName, *va_arg(vlist, CString*)); else if (sWildCard.CompareNoCase(_T("%i")) == 0) UIDataCache::Read(pszSection, strName, *va_arg(vlist, int*)); else if (sWildCard.CompareNoCase(_T("%p")) == 0) UIDataCache::Read(pszSection, strName, *va_arg(vlist, AcGePoint3d*)); else if (sWildCard.CompareNoCase(_T("%a")) == 0) UIDataCache::Read(pszSection, strName, *va_arg(vlist, CStringArray*)); idx = sFormat.Find(_T('%'), idx + 2); strName.Empty(); ++i; } va_end(vlist); return true; } bool UIDataCache::Read(LPCTSTR pszSection, LPCTSTR pszKye, AcGePoint3d &pt) { CString str(_T("")); if (!UIDataCache::Read(pszSection, pszKye, str)) return false; std::vector ar(0); CoreTools::SplitString(str, _T(","), ar); if (ar.size() != 3) return false; pt.x = TypeConvert::convert((LPCTSTR)ar[0]); pt.y = TypeConvert::convert((LPCTSTR)ar[1]); pt.z = TypeConvert::convert((LPCTSTR)ar[2]); return true; } bool UIDataCache::Read(LPCTSTR pszSection, LPCTSTR pszKye, CStringArray &ar) { CString str(_T("")); if (!UIDataCache::Read(pszSection, pszKye, str)) return false; std::vector vec(0); CoreTools::SplitString(str, _T(","), vec); ar.RemoveAll(); for (size_t i = 0; i < vec.size(); ++i) ar.Add(vec[i]); return true; } bool UIDataCache::Write(LPCTSTR pszSection, LPCTSTR pszKye, const double &dValue) { WRITE_VALUE(double, dValue); } bool UIDataCache::Write(LPCTSTR pszSection, LPCTSTR pszKye, const float &fValue) { WRITE_VALUE(float, fValue); } bool UIDataCache::Write(LPCTSTR pszSection, LPCTSTR pszKye, const int &iValue) { WRITE_VALUE(int, iValue); } bool UIDataCache::Read(LPCTSTR pszSection, LPCTSTR pszKye, double &dValue) { READ_VALUE(double, dValue); } bool UIDataCache::Read(LPCTSTR pszSection, LPCTSTR pszKye, float &fValue) { READ_VALUE(float, fValue); } bool UIDataCache::Read(LPCTSTR pszSection, LPCTSTR pszKye, int &iValue) { READ_VALUE(int, iValue); } bool UIDataCache::Read(LPCTSTR pszSection, LPCTSTR pszKye, CString &sValue) { std::wstring str(_T("")); if (Read(pszSection, pszKye, str)) { sValue = str.c_str(); return true; } return false; } void UIDataCache::GetAllSections(std::vector §ions, LPCTSTR path) { sections.clear(); int bufLen = 1024; TCHAR *buf = new TCHAR[bufLen]; DWORD dwRes = GetPrivateProfileSectionNames(buf, bufLen, path); //缓冲区过小,重新设置缓冲区 while (dwRes == bufLen - 2) { DELETE_ARR_(buf); bufLen += 1024; buf = new TCHAR[bufLen]; dwRes = GetPrivateProfileSectionNames(buf, bufLen, path); } TCHAR *p = buf; CString strName = p; while (strName.GetLength() != 0) { sections.push_back(strName); p += strName.GetLength() + 1; strName = p; } DELETE_ARR_(buf); } #pragma endregion ////////////////////////////////////////////////////////////////////////// extern void __declspec(dllimport) UnZipFile(LPCTSTR pszSrc, LPCTSTR pszDec); namespace GLTools { CString InitLayer(LPCTSTR pszLayerName) { CString layerName(_T("0")); if (!pszLayerName) return layerName; AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase(); if (!pDb) return layerName; AcDbLayerTable *pTbl(NULL); pDb->getLayerTable(pTbl, AcDb::kForWrite); if (!pTbl) return layerName; if (pTbl->has(pszLayerName)) { pTbl->close(); return pszLayerName; } AcDbLayerTableRecord *pRc = new AcDbLayerTableRecord; pRc->setName(pszLayerName); pTbl->add(pRc); pRc->close(); pTbl->close(); return pszLayerName; } void loadToolbar() { CString sCUI(_T("")); #if ARX >17 sCUI = FilePath::GetSysDir() + _T("\\shs-ew.cuix"); #else sCUI = FilePath::GetSysDir() + _T("\\shs-ew.cui"); #endif if (!acedIsMenuGroupLoaded(_T("SHS-EW"))) SHacedCommand(RTSTR, _T(".MENULOAD"), RTSTR, sCUI, RTNONE); } void drawCoordinate(const AcGePoint3d &ptOrig, const AcGeVector3d &vtEw, const int &MinX, const int &MinY, const int &MinZ) { AcGeVector3d vt1(AcGeVector3d::kXAxis), vt2(AcGeVector3d::kYAxis), vtDir(AcGeVector3d::kZAxis); // 先沿Z车轴画竖线 AcDbXline *pZ = new AcDbXline; pZ->setBasePoint(ptOrig); pZ->setUnitDir(AcGeVector3d::kZAxis); pZ->setColorIndex(2); drawGrid(ptOrig, vt1, vt2, vtDir, 2, MinZ); AcDbXline *pX = new AcDbXline; pX->setBasePoint(ptOrig); pX->setUnitDir(vtEw); pX->setColorIndex(3); vtDir = vtEw; vt1 = vtDir; vt2 = vtDir; vt1.rotateBy(PI*.5, AcGeVector3d::kZAxis); vt2.rotateBy(PI*.5, AcGeVector3d::kYAxis); drawGrid(ptOrig, vt1, vt2, vtDir, 3, MinX); AcGeVector3d vY(vtEw); vY.rotateBy(PI*.5, AcGeVector3d::kZAxis); AcDbXline *pY = new AcDbXline; pY->setBasePoint(ptOrig); pY->setUnitDir(vY); pY->setColorIndex(4); vtDir = vY; vt1 = vtDir; vt2 = vtDir; vt1.rotateBy(PI*.5, AcGeVector3d::kZAxis); vt2.rotateBy(PI*.5, AcGeVector3d::kXAxis); drawGrid(ptOrig, vt1, vt2, vtDir, 4, MinY); CoreTools::AddToModelSpace(pX); CoreTools::AddToModelSpace(pY); CoreTools::AddToModelSpace(pZ); } AcDbObjectId getTextStyle(LPCTSTR style) { if (!style) return AcDbObjectId::kNull; AcDbObjectId id = CoreTools::findTextStyleId(style); if (!id.isValid()) id = KTSetting::InitTextStyle(style); return id; } typedef bool(_cdecl *getEqu)(CString&); bool getPipelineCmdEquipment(CString &path) { #ifndef ZWCAD HINSTANCE hDllInst = ::LoadLibrary(FilePath::GetArxDir() + _T("\\pipelinecmd.arx")); #else HINSTANCE hDllInst = ::LoadLibrary(FilePath::GetArxDir() + _T("\\pipelinecmd.zrx")); #endif if (!hDllInst) { acutPrintf(_T("\n未找到pipelinecmd.arx。")); return false; } getEqu Func = (getEqu)::GetProcAddress(hDllInst, "selectEquipment"); if (Func) { bool bRel = Func(path); ::FreeLibrary(hDllInst); return bRel; } else { acutPrintf(_T("\n函数selectEquipment获取失败。")); return false; } return false; } typedef bool(_cdecl *getEquFromDB)(const int&, CString&); bool getPipelineCmdEquipment(const int &idx, CString &path) { #ifndef ZWCAD HINSTANCE hDllInst = ::LoadLibrary(FilePath::GetArxDir() + _T("\\pipelinecmd.arx")); #else HINSTANCE hDllInst = ::LoadLibrary(FilePath::GetArxDir() + _T("\\pipelinecmd.zrx")); #endif if (!hDllInst) { acutPrintf(_T("\n未找到pipelinecmd.arx。")); return false; } getEquFromDB Func = (getEquFromDB)::GetProcAddress(hDllInst, "getEquipmentFromDB"); if (Func) { bool bRel = Func(idx, path); ::FreeLibrary(hDllInst); return bRel; } else { acutPrintf(_T("\n函数getEquipmentFromDB获取失败。")); return false; } return false; } typedef bool(_cdecl *getEquDBIdx)(int&); bool getPipelineCmdEquipment(int & idx) { #ifndef ZWCAD HINSTANCE hDllInst = ::LoadLibrary(FilePath::GetArxDir() + _T("\\pipelinecmd.arx")); #else HINSTANCE hDllInst = ::LoadLibrary(FilePath::GetArxDir() + _T("\\pipelinecmd.zrx")); #endif if (!hDllInst) { acutPrintf(_T("\n未找到pipelinecmd.arx。")); return false; } getEquDBIdx Func = (getEquDBIdx)::GetProcAddress(hDllInst, "getEquipmentDBIdx"); if (Func) { bool bRel = Func(idx); ::FreeLibrary(hDllInst); return bRel; } else { acutPrintf(_T("\n函数getEquipmentFromDB获取失败。")); return false; } return false; } Acad::ErrorStatus generateGroup(LPCTSTR name, AcDbObjectIdArray & ids) { if (ids.isEmpty()) return Acad::eInvalidInput; Acad::ErrorStatus es; AcDbGroup *pGroup = new AcDbGroup; AcDbObjectId groupObjectId; AcDbDictionary *pGroupDict(NULL); es = acdbCurDwg()->getGroupDictionary(pGroupDict, AcDb::kForWrite); if (es != Acad::eOk) return es; es = pGroupDict->setAt(_T("*A"), pGroup, groupObjectId); if (es != Acad::eOk) { DELETE_PTR(pGroup); return es; } pGroupDict->close(); if (!name) pGroup->setAnonymous(); else pGroup->setName(name); pGroup->setSelectable(true); pGroup->append(ids); pGroup->close(); return es; } double getNodeOffset(const EWFnctNode & node) { double delta(.0); switch (node.eFnType) { case kProModel: delta = .0; break; case kDrainWell: delta = node.fNodeDef[0] * .5; break; case kPipeDoghouse: delta = node.fNodeDef[12] * .5; break; case kCableDoghouse: delta = node.fNodeDef[12] * .5; break; case kEscapeHatch: delta = node.fNodeDef[12] * .5; break; case kFireOutlet: delta = node.fNodeDef[0] * .5; break; case kEWOutLethouse: delta = node.fNodeDef[0] * .5; break; case kHTOutLetHouse: delta = node.fNodeDef[0] * .5; break; case kBDOutLetHouse: delta = node.fNodeDef[3] * .5; break; case kUserDoghouse: delta = node.fNodeDef[0] * .5; break; default: break; } return delta; } bool getConnectWorms(AcDbObjectIdArray & ids, AcDbObjectIdArray *pNextIDs, AcDbObjectIdArray *pPrevIDs) { ads_name ent; ads_point adsPt; AcDbObjectIdArray arIds; AcDbObjectId idSt(AcDbObjectId::kNull), idEd(AcDbObjectId::kNull); int nRes = acedEntSel(_T("\n请选择第一段管廊:"), ent, adsPt); if (nRes != RTNORM) return false; acdbGetObjectId(idSt, ent); if (!idSt.isValid()) return false; if (GLTools::isThisClass(idSt) || GLTools::isThisClass(idSt) ) { } else { acutPrintf(_T("\n所选对象不是管廊。")); return false; } nRes = acedEntSel(_T("\n请选择第二段管廊<右键全选>:"), ent, adsPt); int idx(-1); if (nRes == RTCAN) return false; // esc取消 if (nRes == RTERROR) // 右键,则全选idSt之后的相连管廊 { if (!GetConnectedWorms(idSt, arIds)) { acutPrintf(_T("\n获取相连管廊失败。")); return false; } idx = arIds.find(idSt); if (idx != -1) { for (size_t i = idx; i < arIds.length(); ++i) ids.append(arIds[i]); if (pNextIDs) pNextIDs->removeAll(); if (pPrevIDs) { pPrevIDs->removeAll(); for (size_t i = 0; i < idx; ++i) pPrevIDs->append(arIds[i]); } } else return false; return true; } else { acdbGetObjectId(idEd, ent); if (!idEd.isValid()) return false; if (GLTools::isThisClass(idEd) || GLTools::isThisClass(idEd) ) { } else { acutPrintf(_T("\n所选对象不是管廊。")); return false; } if (idSt == idEd) { ids.append(idSt); } else if (!GetConnectedWorms(idSt, idEd, ids)) { acutPrintf(_T("\n获取相连管廊失败。")); return false; } if ((pNextIDs || pPrevIDs) && GetConnectedWorms(idSt, arIds)) { idx = arIds.find(idEd); if (idx != -1 && pNextIDs) { pNextIDs->removeAll(); for (size_t i = idx + 1; i < arIds.length(); ++i) pNextIDs->append(arIds[i]); } idx = arIds.find(idSt); if (idx != -1 && pPrevIDs) { pPrevIDs->removeAll(); for (size_t i = 0; i < idx; ++i) pPrevIDs->append(arIds[i]); } } return true; } return false; } // 鼠标选中一个管廊节点,返回节点所在管廊id及节点guid void pickEwNode(AcDbObjectId &idPort, AcDbObjectId &idEw, std::string & md5, CString &guid) { ads_name ent; ads_point adsPt; int nRel = acedEntSel(_T("\n请选择一个管廊上的节点:"), ent, adsPt); if (nRel != RTNORM) return; AcDbObjectId id; if (Acad::eOk != acdbGetObjectId(id, ent)) return; AcGePoint3d ptPick = asPnt3d(adsPt); CoreTools::UCS2WCS(ptPick, ptPick); ptPick.z = .0; // 如果是一个 AecDbPortRoom 节点,直接返回 OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbPortRoom, pRo) { if (pRo) { idPort = id; guid.Empty(); md5 = ""; return; } } OPENOBJ_END() // 如果选中了一段管廊,判断一下pick点是否有节点,如果有,节点类型是什么 OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEarthWorm, pEw) { if (!pEw) return; AcArray arNodes; AcGePoint3dArray arNodePnts; AcDbCurve *pCurve = pEw->GetBaseCurve(); if (!pCurve) return; AcGePoint3d ptOn(AcGePoint3d::kOrigin); pCurve->getClosestPointTo(ptPick, ptOn); pEw->GetFncNodeAt(ptOn, 5, arNodes, arNodePnts); for (int nd = 0; nd < arNodes.length(); ++nd) { EWFnctNode &node = arNodes[nd]; // 如果是有PortRoom的节点,直接返回 pEw->GetPortRoomId(node.szLockId, idPort); if (idPort.isValid()) return; if (node.eFnType != kProModel) continue; ImpMD5 MD5(node.pProModelBuffer, node.nProModelBufLen); md5 = MD5.toString(); idEw = id; guid = node.szLockId; } DELETE_PTR(pCurve); } OPENOBJ_END() } } namespace StakeTools { bool analyStakeString(LPCTSTR psz, double &dist, CString *pPrefix /*= NULL*/, bool *pThousands /*= NULL*/) { if (!psz) return false; // 桩号由 “+/-” 号分为两部分 // 符号前为字母和公里数 // 符号后为小于1公里的距离 CString str(psz); bool bPlus(true); int pos = str.Find(_T("+")); if (pos == -1) { pos = str.Find(_T("-")); if (pos == -1) return false; bPlus = false; } CString sFirst(_T("")), sSecond(_T("")); sFirst = str.Left(pos); sSecond = str.Right(str.GetLength() - pos - 1); if (sSecond.IsEmpty()) return false; if (!IsDoubleString(sSecond)) return false; double subDist = _ttof(sSecond); int digitPos(0); for (digitPos = 0; digitPos < sFirst.GetLength(); ++digitPos) { if (isdigit(sFirst[digitPos])) break; } if (sFirst.GetLength() == digitPos) { // 不是 K1+123形式 if (pPrefix) *pPrefix = sFirst; if (pThousands) *pThousands = false; dist = subDist; return true; } if (pPrefix) *pPrefix = sFirst.Left(digitPos); sFirst = sFirst.Right(sFirst.GetLength() - digitPos); if (sFirst.IsEmpty()) return false; int KDist = _ttoi(sFirst); if (bPlus) dist = KDist * 1000 + subDist; else dist = KDist * 1000 - subDist; if (pThousands) *pThousands = true; return true; } bool IsStakeString(LPCTSTR pszStake) { double d; return analyStakeString(pszStake, d); } bool IsDoubleString(LPCTSTR pszDouble) { return CoreTools::isDigitString(pszDouble); // std::wstringstream st(pszDouble); // double d; // if (!(st >> d)) // return false; // return true; } int getBitsForFloat(const double & d, std::vector& first, std::vector& second, const int & prec) { int nRel((d < 1e-6) ? -1 : 1); CString str(TypeConvert::f2s(d, &prec)); first.clear(); second.clear(); int fst(d); int sec((d - fst) * pow(10., prec)); double a(.0); int f(0), s(0); f = fst; while (true) { // 退一位 a = f * .1; f = a; s = (a-f)*10; first.push_back(s); if (f == 0) break; } f = sec; while (true) { // 退一位 a = f * .1; f = a; s = (a - f) * 10; second.push_back(s); if (f == 0) break; } std::reverse(second.begin(), second.end()); return nRel; } CString generateStakeString(const double &dist, LPCTSTR psz /*= _T("K")*/) { std::vector first(0), second(0); int neg = StakeTools::getBitsForFloat(dist, first, second); CString str(psz); int prec(2); if (first.size() < 4) // 不足千位 { str += _T("0") + (neg == 1) ? _T("+") : _T("-"); str += TypeConvert::f2s(dist, &prec); } else { int k(0); for (size_t i = 3; i < first.size(); ++i) { k += first[i] * pow(10., (int)i); } str.Format(_T("%s%d%s%.2f"), psz, int(k / 1000), (neg == 1) ? _T("+") : _T("-"), dist - k); } return str; } bool getSHSStake(LPCTSTR pszPrompt , AcDbObjectId &idTxt , double &dist , CString &prefix , bool &bStart2End , bool &bThousands , AcGePoint3d *ptIns /*= NULL */ , CString *orignString /*= NULL*/) { if (!pszPrompt) return false; ads_name ent; ads_point pt; int nRes = acedEntSel(pszPrompt, ent, pt); if (nRes != RTNORM) return false; acdbGetObjectId(idTxt, ent); if (!GLTools::isThisClass(idTxt)) { acutPrintf(_T("\n选择的不是文字对象。")); return false; } CString sOrignString(_T("")); double d; AcGePoint3d pnt; if (!readSHSStake(idTxt, pnt, bStart2End, sOrignString, d, d)) { acutPrintf(_T("\n选择的桩号对象不是由上华管廊软件生成的。")); return false; } if (ptIns) *ptIns = pnt; if (orignString) *orignString = sOrignString; if (!analyStakeString(sOrignString, dist, &prefix, &bThousands)) { acutPrintf(_T("\n选择的文字对象不是桩号。")); return false; } return true; } bool readSHSStake(AcDbEntity *pEnt, AcGePoint3d &ptIns, bool &bS2E, CString &sStake, double &stakeDist, double &pointDist) { if (!pEnt) return false; AecDbObjXDataMap xmap; int i(0); if (!xmap.Read(pEnt, SHS_STAKE)) return false; if (!xmap.GetAt(SHS_STAKE_PTINS, ptIns)) return false; if (!xmap.GetAt(SHS_STAKE_S2E, i)) return false; if (!xmap.GetAt(SHS_STAKE_DIST, stakeDist)) return false; if (!xmap.GetAt(SHS_STAKE_PT_DIST, pointDist)) return false; if (!xmap.GetAt(SHS_STAKE_NO, sStake)) return false; bS2E = i == 0 ? false : true; return true; } bool readSHSStake(AcDbObjectId id, AcGePoint3d &ptIns, bool &bS2E, CString &sStake, double &stakeDist, double &pointDist) { OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbEntity, pEnt) if (!pEnt) return false; return readSHSStake(pEnt, ptIns, bS2E, sStake, stakeDist, pointDist); OPENOBJ_END() return false; } bool isSHSStake(AcDbObjectId id) { AcGePoint3d pt; bool b; CString str; double d; OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbText, pTxt) if (!pTxt) return false; return readSHSStake(pTxt, pt, b, str, d, d); OPENOBJ_END() return false; } bool isSHSStakeLine(AcDbObjectId id) { AcGePoint3d pt; bool b; CString str; double d; OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbLine, pTxt) if (!pTxt) return false; return readSHSStake(pTxt, pt, b, str, d, d); OPENOBJ_END() return false; } bool writeSHSStakeFlag(AcDbObjectId id, const AcGePoint3d &ptIns, const bool &bS2E, LPCTSTR pszStake, const double &stakeDist, const double &pointDist) { OPENOBJ_BEGIN(id, AcDb::kForWrite, AcDbEntity, pTxt) if (!pTxt) return false; return writeSHSStakeFlag(pTxt, ptIns, bS2E, pszStake, stakeDist, pointDist); OPENOBJ_END() return false; } bool writeSHSStakeFlag(AcDbEntity *pEnt, const AcGePoint3d &ptIns, const bool &bS2E, LPCTSTR pszStake, const double &stakeDist, const double &pointDist) { AecDbObjXDataMap xmap; AcGePoint3d pt(ptIns); if (!pszStake) return false; if (!pEnt) return false; xmap.SetAt(SHS_STAKE_PTINS, pt); xmap.SetAt(SHS_STAKE_S2E, bS2E); xmap.SetAt(SHS_STAKE_NO, pszStake); xmap.SetAt(SHS_STAKE_DIST, stakeDist); xmap.SetAt(SHS_STAKE_PT_DIST, pointDist); return xmap.Write(pEnt, SHS_STAKE) == TRUE ? true : false; } bool getSHSStakeOfAll(std::vector &ids, bool bSortByStakeDist) { ads_name ss, ent; struct resbuf* pRb = acutBuildList(RTDXF0, _T("TEXT"), 0); int nRes = acedSSGet(_T("A"), NULL, NULL, pRb, ss); if (nRes != RTNORM) { acutPrintf(_T("\n没有发现文字对象。")); return false; } AcDbObjectId id; Adesk::Int32 lLen = 0L; acedSSLength(ss, &lLen); for (long i = 0; i < lLen; i++) { if (acedSSName(ss, i, ent) != RTNORM) continue; if (acdbGetObjectId(id, ent) != Acad::eOk) continue; if (!GLTools::isThisClass(id)) continue; if (!isSHSStake(id)) continue; ids.push_back(id); } acedSSFree(ss); std::sort(ids.begin(), ids.end(), _compare_stake_all_(true)); return !ids.empty(); } bool getDistByPointForCenterLine(const std::vector &ids, const AcDbObjectId &polyID, const AcGePoint3d &pt, double &stakeDist) { double dist(.0); if (getDistAtPoint(polyID, pt, dist) != Acad::eOk) return false; AcGePoint3d ptLeft(AcGePoint3d::kOrigin), ptRight(AcGePoint3d::kOrigin); bool bS2E(false); CString strLeft(_T("")), strRight(_T("")); double dLeft(.0), dRight(.0); double stakeDistLeft(.0), stakeDistRight(.0), pointDistLeft(.0), pointDistRight(.0); for (int i = 0; i < ids.size(); ++i) { StakeTools::readSHSStake(ids[i], ptRight, bS2E, strRight, stakeDistRight, pointDistRight); if (EQUAL(pointDistRight, dist)) { stakeDist = stakeDistRight; return true; } if (pointDistRight > dist) { // i 是第一个 if (i == 0) return false; StakeTools::readSHSStake(ids[i - 1], ptLeft, bS2E, strLeft, stakeDistLeft, pointDistLeft); stakeDistLeft += (bS2E ? 1 : -1) * (dist - pointDistLeft); stakeDist = stakeDistLeft; return true; } } return false; } } namespace INITools { bool getSections(LPCTSTR szPath, std::vector §ions) { if (_taccess(szPath, 0x0) != 0x0) return false; DWORD dw(0), len(MAX_PATH); TCHAR *buf = new TCHAR[len]; ::memset(buf, 0, sizeof(TCHAR) * len); dw = ::GetPrivateProfileSectionNames(buf, len, szPath); while (dw == len - 2) { DELETE_ARR_(buf); len += MAX_PATH; buf = new TCHAR[len]; ::memset(buf, 0, sizeof(TCHAR) * len); dw = ::GetPrivateProfileSectionNames(buf, len, szPath); } TCHAR *psz(buf); while ((len = _tcslen(psz))) { sections.push_back(psz); psz += len + 1; } DELETE_ARR_(buf); return !sections.empty(); } bool getSectionContent(LPCTSTR szPath, LPCTSTR szSection, std::map &mapV) { if (_taccess(szPath, 0x0) != 0x0) return false; DWORD dw(0), len(MAX_PATH); TCHAR *buf = new TCHAR[len]; ::memset(buf, 0, sizeof(TCHAR) * len); dw = ::GetPrivateProfileSection(szSection, buf, len, szPath); while (dw == len - 2) { DELETE_ARR_(buf); len += MAX_PATH; buf = new TCHAR[len]; ::memset(buf, 0, sizeof(TCHAR) * len); dw = ::GetPrivateProfileSection(szSection, buf, len, szPath); } TCHAR *psz(buf); mapV.clear(); std::map::const_iterator it; int idx(-1); CString str(_T("")), pre(_T("")), back(_T("")); while ((len = _tcslen(psz))) { str = psz; idx = str.Find(_T('=')); if (idx != -1) { pre = str.Left(idx); back = str.Right(str.GetLength() - idx - 1); mapV.insert(std::make_pair(pre, back)); } psz += len + 1; } DELETE_ARR_(buf); return !mapV.empty(); } bool setSectionContent(LPCTSTR szPath, LPCTSTR szSection, const std::map &mapV) { if (!szSection) return false; if (_taccess(szPath, 0x0) != 0x0) return false; // 拼字符串 std::map::const_iterator it = mapV.begin(); std::wstring ss; for (; it != mapV.end(); ++it) { ss += it->first; ss += _T("="); ss += it->second; ss.push_back(_T('\0')); } ss.push_back(_T('\0')); return ::WritePrivateProfileSection(szSection, ss.c_str(), szPath) == FALSE ? false :true; } } namespace PipeTools { void clearRegionsBuffer(AcDbVoidPtrArray arr) { for (int i = 0; i < arr.length(); ++i) { if (arr[i]) { DELETE_PTR(arr[i]); } } arr.removeAll(); } template void delPtr(T* p) { if (p) { DELETE_PTR(p); } } AcDbRegion* createCircleRegion(const double &R) { AcDbCircle Cir(AcGePoint3d::kOrigin, AcGeVector3d::kZAxis, R); AcDbVoidPtrArray arrIn; AcDbVoidPtrArray regOut; arrIn.append(&Cir); Acad::ErrorStatus es = AcDbRegion::createFromCurves(arrIn, regOut); if (es != Acad::eOk || regOut.length() != 1) { acutPrintf(_T("\nAcDbRegion::createFromCurves失败。")); return NULL; } return (AcDbRegion*)regOut[0]; } AcDbObjectId InitLineStyle(LPCTSTR pszName) { AcDbObjectId idRec = AcDbObjectId::kNull; if (pszName == NULL) return idRec; acdbCurDwg()->loadLineTypeFile(pszName, _T("acadiso.lin")); AcDbLinetypeTable* pTable = NULL; acdbCurDwg()->getLinetypeTable(pTable, AcDb::kForRead); if (pTable != NULL) { pTable->getAt(pszName, idRec); pTable->close(); } return idRec; } AecDbEwPipe* createPipeFromLineSeg(const LineSeg &seg) { AecDbEwPipe *pPipe = new AecDbEwPipe(); if (!pPipe) return NULL; Acad::ErrorStatus es = Acad::eOk; double bigR = seg.dDn * .5;//公称 double smlR = bigR - seg.dt; /*AcDbRegion *pBigRegion = createCircleRegion(bigR); AcDbRegion *pSmlRegion = createCircleRegion(smlR); if (!pBigRegion || !pSmlRegion) { delPtr(pBigRegion); delPtr(pSmlRegion); return NULL; } es = pBigRegion->booleanOper(AcDb::kBoolSubtract, pSmlRegion); if (es != Acad::eOk) { acutPrintf(_T("\n booleanOper error : %d"), es); delPtr(pBigRegion); delPtr(pSmlRegion); return NULL; } delPtr(pSmlRegion);*/ AcDbObjectId layerSingleID(AcDbObjectId::kNull) , layerDoubleID(AcDbObjectId::kNull) , layerID(AcDbObjectId::kNull); g_LayerMgr::instance().getLayer(GLTools::gLayer_PIPE_SINGLE, layerSingleID); g_LayerMgr::instance().getLayer(GLTools::gLayer_PIPE_DOUBLE, layerDoubleID); g_LayerMgr::instance().getLayer(GLTools::gLayer_PIPE, layerID); if (fabs(seg.dBulge ) < 1.e-6) { AcDbLine line(seg.ptFr, seg.ptTo); AcGeVector3d vt(seg.ptTo - seg.ptFr); AcGeVector3d _vt = vt.crossProduct(AcGeVector3d::kZAxis); vt.rotateBy(PI*.5, _vt);// vt.normalize(); vt *= bigR; AcGeMatrix3d mat; mat.setToTranslation(vt); line.transformBy(mat); pPipe->SetBaseCurve(&line); } else { // AcDbLine line(seg.ptFr, seg.ptTo); // AcGeVector3d vt(seg.ptTo - seg.ptFr); // AcGeVector3d _vt = vt.crossProduct(AcGeVector3d::kZAxis); // vt.rotateBy(PI*.5, _vt);// // vt.normalize(); // vt *= bigR; // AcGeMatrix3d mat; // mat.setToTranslation(vt); // line.transformBy(mat); // pPipe->SetBaseCurve(&line); AcDbArc* pArc = KTCADUtilityEx::FormatArc(seg.ptFr,seg.ptOn,seg.ptTo); if (pArc != NULL) { AcGeVector3d vt; pArc->getFirstDeriv(seg.ptFr,vt); AcGeVector3d _vt = vt.crossProduct(AcGeVector3d::kZAxis); vt.rotateBy(PI*.5, _vt);// vt.normalize(); vt *= bigR; AcGeMatrix3d mat; mat.setToTranslation(vt); pArc->transformBy(mat); pPipe->SetBaseCurve(pArc); DELETE_PTR(pArc); //TEST //pArc->setColorIndex(1); //CoreTools::AddToModelSpace(pArc); } } pPipe->SetSection(seg.dDn,0.0); //pPipe->SetSection(pBigRegion, AcGePoint3d(0., 0., 0)); //delPtr(pBigRegion); pPipe->setColorIndex(seg.nColor); pPipe->SetSingleLayer(layerSingleID); pPipe->SetDoubleLayer(layerDoubleID); pPipe->SetSingleLineType(InitLineStyle(seg.szLntype)); pPipe->SetDoubleLineType(InitLineStyle(seg.szLntype)); pPipe->setLayer(layerID); pPipe->setLinetype(InitLineStyle(_T("CENTER"))); pPipe->GetSpecialtyData()->SetAt(KEY_2DSTYLE, 1); pPipe->GetSpecialtyData()->SetAt(PIPE_DN, seg.dDn); pPipe->GetSpecialtyData()->SetAt(PIPE_OD, seg.dD); pPipe->GetSpecialtyData()->SetAt(PIPE_THICK, seg.dt); pPipe->GetSpecialtyData()->SetAt(PIPE_MATERIAL, seg.szMat); pPipe->GetSpecialtyData()->SetAt(PIPE_SYS, seg.szSys); return pPipe; } AecDbEwCable* createCableFromLineSeg(const LineSeg &seg) { AecDbEwCable *pPipe = new AecDbEwCable(); if (!pPipe) return NULL; double dR = seg.dD * .5; AcDbObjectId layerSingleID(AcDbObjectId::kNull) , layerDoubleID(AcDbObjectId::kNull) , layerID(AcDbObjectId::kNull); g_LayerMgr::instance().getLayer(GLTools::gLayer_CABLE_SINGLE, layerSingleID); g_LayerMgr::instance().getLayer(GLTools::gLayer_CABLE_DOUBLE, layerDoubleID); g_LayerMgr::instance().getLayer(GLTools::gLayer_CABLE, layerID); //AcDbRegion *pBigRegion = createCircleRegion(dR); if (fabs(seg.dBulge ) < 1.e-6) { AcDbLine line(seg.ptFr, seg.ptTo); AcGeVector3d vt(seg.ptTo - seg.ptFr); AcGeVector3d _vt = vt.crossProduct(AcGeVector3d::kZAxis); vt.rotateBy(PI*.5, _vt); vt.normalize(); vt *= dR; AcGeMatrix3d mat; mat.setToTranslation(vt); line.transformBy(mat); pPipe->SetBaseCurve(&line); } else { // AcDbLine line(seg.ptFr, seg.ptTo); // AcGeVector3d vt(seg.ptTo - seg.ptFr); // AcGeVector3d _vt = vt.crossProduct(AcGeVector3d::kZAxis); // vt.rotateBy(PI*.5, _vt);// // vt.normalize(); // vt *= bigR; // AcGeMatrix3d mat; // mat.setToTranslation(vt); // line.transformBy(mat); // pPipe->SetBaseCurve(&line); AcDbArc* pArc = KTCADUtilityEx::FormatArc(seg.ptFr,seg.ptOn,seg.ptTo); if (pArc != NULL) { AcGeVector3d vt; pArc->getFirstDeriv(seg.ptFr,vt); AcGeVector3d _vt = vt.crossProduct(AcGeVector3d::kZAxis); vt.rotateBy(PI*.5, _vt);// vt.normalize(); vt *= dR; AcGeMatrix3d mat; mat.setToTranslation(vt); pArc->transformBy(mat); pPipe->SetBaseCurve(pArc); DELETE_PTR(pArc); //TEST //pArc->setColorIndex(1); //CoreTools::AddToModelSpace(pArc); } } //pPipe->SetSection(pBigRegion, AcGePoint3d(0., 0., 0)); //delPtr(pBigRegion); pPipe->SetSection(seg.dD,0.0); pPipe->setColorIndex(seg.nColor); pPipe->GetSpecialtyData()->SetAt(_T("COLOR"), seg.nColor); pPipe->SetSingleLayer(layerSingleID); pPipe->SetDoubleLayer(layerDoubleID); pPipe->SetSingleLineType(InitLineStyle(seg.szLntype)); pPipe->SetDoubleLineType(InitLineStyle(seg.szLntype)); pPipe->setLayer(layerID); pPipe->setLinetype(InitLineStyle(_T("CENTER"))); pPipe->GetSpecialtyData()->SetAt(KEY_2DSTYLE, 1); pPipe->GetSpecialtyData()->SetAt(CABLE_D, seg.dD); pPipe->GetSpecialtyData()->SetAt(CABLE_MODEL, seg.szMat); pPipe->GetSpecialtyData()->SetAt(CABLE_FACTORY, seg.szSys); pPipe->GetSpecialtyData()->SetAt(CABLE_RATIO, seg.dDn); return pPipe; } } namespace EquTools { bool GetActiveViewPortInfo(AcDbDatabase *pDb, ads_real &height, ads_real &width, AcGePoint3d &target, AcGeVector3d &viewDir, ads_real &viewTwist, bool getViewCenter) { // if not ok if (pDb == NULL) return false; // get the current working database as a backup AcDbDatabase *workingDataBase = acdbHostApplicationServices()->workingDatabase(); // now set the working database //将导致渲染错误,文件保存,核查错误提示 LFY 2019-6-3 //acdbHostApplicationServices()->setWorkingDatabase(pDb); // make sure the active view port is uptodate acedVports2VportTableRecords(); // open the view port records AcDbViewportTable *pVTable = NULL; Acad::ErrorStatus es = pDb->getViewportTable(pVTable, AcDb::kForRead); // if we opened them ok if (es == Acad::eOk) { AcDbViewportTableRecord *pViewPortRec = NULL; es = pVTable->getAt(_T("*Active"), pViewPortRec, AcDb::kForRead); if (es == Acad::eOk) { // get the height of the view height = pViewPortRec->height(); // get the width width = pViewPortRec->width(); // if the user wants the center of the viewport used if (getViewCenter == true) { struct resbuf rb; memset(&rb, 0, sizeof(struct resbuf)); // get the system var VIEWCTR acedGetVar(_T("VIEWCTR"), &rb); // set that as the target target = AcGePoint3d(rb.resval.rpoint[X], rb.resval.rpoint[Y], rb.resval.rpoint[Z]); } // we want the viewports camera target setting else { // get the target of the view target = pViewPortRec->target(); } // get the view direction viewDir = pViewPortRec->viewDirection(); // get the view twist of the viewport viewTwist = pViewPortRec->viewTwist(); } // close after use pVTable->close(); pViewPortRec->close(); } // now restore the original working database //将导致渲染错误,文件保存,核查错误提示 LFY 2019-6-3 //acdbHostApplicationServices()->setWorkingDatabase(workingDataBase); return (true); } void SetViewTo(AcGsView *pView, AcDbDatabase *pDb, AcGeMatrix3d& viewMat) { // we are going to set the view to the current view of the drawing // The overall approach is to calculate the extents of the database in the coordinate system of the view // Calculate the extents in WCS // if exmax,exmin too larg or small , view show error!!!! AcGePoint3d extMax(500, 500, 500);// = pDb->extmax(); AcGePoint3d extMin(-500, -500, -500);// = pDb->extmin(); // get the view port information - see parameter list ads_real height = 0.0, width = 0.0, viewTwist = 0.0; AcGePoint3d targetView; AcGeVector3d viewDir; GetActiveViewPortInfo(pDb, height, width, targetView, viewDir, viewTwist, true); // we are only interested in the directions of the view, not the sizes, so we normalise. // set to -1,-1,1 viewDir.set(-1, -1, 1); viewDir = viewDir.normal(); //********************************************** // Our view coordinate space consists of z direction // get a perp vector off the z direction // Make sure its normalised AcGeVector3d viewXDir = viewDir.perpVector().normal(); // correct the x angle by applying the twist viewXDir = viewXDir.rotateBy(viewTwist, -viewDir); // now we can work out y, this is of course perp to the x and z directions. No need to normalise this, // as we know that x and z are of unit length, and perpendicular, so their cross product must be on unit length AcGeVector3d viewYDir = viewDir.crossProduct(viewXDir); // find a nice point around which to transform the view. We'll use the same point as the center of the view. AcGePoint3d boxCenter = extMin + 0.5 * (extMax - extMin); //********************************************** // create a transform from WCS to View space // this represents the transformation from WCS to the view space. (Actually not quite since // we are keeping the fixed point as the center of the box for convenience ) viewMat = AcGeMatrix3d::alignCoordSys(boxCenter, AcGeVector3d::kXAxis, AcGeVector3d::kYAxis, AcGeVector3d::kZAxis, boxCenter, viewXDir, viewYDir, viewDir).inverse(); AcDbExtents wcsExtents(extMin, extMax); // now we have the view Extents AcDbExtents viewExtents = wcsExtents; // transforms the extents in WCS->view space viewExtents.transformBy(viewMat); //********************************************** // get the extents of the AutoCAD view double xMax = fabs(viewExtents.maxPoint().x - viewExtents.minPoint().x); double yMax = fabs(viewExtents.maxPoint().y - viewExtents.minPoint().y); //********************************************** // setup the view AcGePoint3d eye = boxCenter + viewDir; // upvector pView->setView(eye, boxCenter, viewYDir, xMax, yMax); // update the gsView if (pView != NULL) { pView->invalidate(); pView->update(); } } Acad::ErrorStatus InitDrawingControl(CGsPreviewCtrlEx* pPreViewCtrl, AcDbDatabase *pDb, const TCHAR *space) { // have we got a valid drawing if (pDb == NULL) { pDb = acdbCurDwg(); } AcDbBlockTableRecordPointer spaceRec(space, pDb, AcDb::kForRead); // if ok if (spaceRec.openStatus() == Acad::eOk) { // initialize the preview control pPreViewCtrl->init(_hdllInstance, true); // set the view to the *Active* AutoCAD view AcGeMatrix3d xform; SetViewTo(pPreViewCtrl->mpView, pDb, xform); // tell the view to display this space //不显示当前模型空间记录的现有实体!!!![lfy-2013-2-20] //pPreViewCtrl->view()->add(spaceRec.object(), pPreViewCtrl->model()); } return spaceRec.openStatus(); } // 对GsView进行子类化 bool subClassGsView(CGsPreviewCtrlEx *pCtrl, CDialog *pDlg, const UINT &ID) { if (!pCtrl || !pDlg) return false; if (!pCtrl->SubclassDlgItem(ID, pDlg)) return false; pCtrl->clearAll(); InitDrawingControl(pCtrl, NULL, ACDB_MODEL_SPACE); return true; } // 在GsView上显示设备 bool showEquipment(CGsPreviewCtrlEx *pCtrl, const int &idx) { if (!pCtrl) return false; CString equFile(_T("")); if (!GLTools::getPipelineCmdEquipment(idx, equFile)) return false; // 先把文件转为实体 AecDbEwEquipment* pEqu = new AecDbEwEquipment; if (!pEqu->ReadFromFile(equFile)) return false; pCtrl->clearAll(); InitDrawingControl(pCtrl, NULL, ACDB_MODEL_SPACE); pEqu->SetInsert(AcGePoint3d::kOrigin, AcGeVector3d::kXAxis); //AcGeMatrix3d xScale; //xScale.setToScaling(0.001); //pEqu->AddTransform(xScale); pEqu->setColorIndex(6); AcDbExtents ext; pEqu->getGeomExtents(ext); //pCtrl->InitFromCurrentView(ext); AcGsView *pView = pCtrl->view(); if (!pView) return false; #ifndef ZWCAD #if ARX>=20 pView->setVisualStyle(AcGiVisualStyle::kGouraud); #else pView->setMode(AcGsView::kGouraudShaded); #endif #else #if defined(R24) pView->setMode(AcGsView::kGouraudShaded); #else pView->setVisualStyle(AcGiVisualStyle::kGouraud); #endif #endif pView->zoomExtents(ext.minPoint(), ext.maxPoint()); pView->zoom(1.1); pCtrl->view()->add(pEqu, pCtrl->model()); pCtrl->view()->invalidate(); pCtrl->view()->update(); return true; } // 子类化,并根据数据库索引显示图形 bool subClassGsViewAndShow(CGsPreviewCtrlEx *pCtrl, CDialog *pDlg, const UINT &ID, const int &id3D) { bool bRel = subClassGsView(pCtrl, pDlg, ID); if (bRel) { showEquipment(pCtrl, id3D); } return bRel; } // 选择一个3D设备,并显示 bool selectEquAndShow(CGsPreviewCtrlEx *pCtrl, int &idx) { bool bRel(false); if (GLTools::getPipelineCmdEquipment(idx)) { if (EquTools::showEquipment(pCtrl, idx)) bRel = true; } else idx = -1; return bRel; } }