Files
envi-code/SourceCode/Code2026/EarthWormCmd/UITools.cpp
T
2026-09-28 15:28:50 +08:00

1833 lines
47 KiB
C++

#include "stdafx.h"
#include "math.h"
#include "UITools.h"
#include <algorithm>
#include <sstream>
#include <fstream>
#include <set>
#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<CString> sections;
GetAllSections(sections, path);
std::vector<CString>::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<std::wstring, type>(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<type, std::wstring>(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<CString> ar(0);
CoreTools::SplitString(str, _T(","), ar);
if (ar.size() != 3) return false;
pt.x = TypeConvert::convert<double, std::wstring>((LPCTSTR)ar[0]);
pt.y = TypeConvert::convert<double, std::wstring>((LPCTSTR)ar[1]);
pt.z = TypeConvert::convert<double, std::wstring>((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<CString> 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<CString> &sections, 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<AecDbEarthWorm>(idSt) ||
GLTools::isThisClass<AecDbShEarthWorm>(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<AecDbEarthWorm>(idEd) ||
GLTools::isThisClass<AecDbShEarthWorm>(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<EWFnctNode> 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<double>(pszDouble);
// std::wstringstream st(pszDouble);
// double d;
// if (!(st >> d))
// return false;
// return true;
}
int getBitsForFloat(const double & d, std::vector<int>& first, std::vector<int>& 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<int> 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<AcDbText>(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<AcDbObjectId> &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<AcDbText>(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<AcDbObjectId> &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<CString> &sections)
{
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<CString, CString> &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<CString, CString>::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<CString, CString> &mapV)
{
if (!szSection) return false;
if (_taccess(szPath, 0x0) != 0x0) return false;
// 拼字符串
std::map<CString, CString>::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<typename T>
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;
}
}