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

1361 lines
27 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//-----------------------------------------------------------------------------+
// Copyright (C), 1998-2007, SH Software Co. Ltd.
// = FileName : CHole.cpp
// = Version : ver2.0
// = Author : zjq
// = CreateDate : 2002-09-09
// = Description: 类的定义
// = Maintainers:
//
//-----------------------------------------------------------------------------+
#include "StdAfx.h"
#include "CHole.h"
#include "XPrivateGlobalFunc.h"
CHole::CHole()
{
}
CHole::~CHole()
{
}
BOOL CHole::ConstructEdgeList(const DList<XPoly2D> &lstHole)
{
int nCount = lstHole.Length();
if(nCount <= 0)
{
return FALSE;
}
for(int i = 0; i < nCount; i++)
{
const XPoly2D &polyTemp = lstHole[i];
if(polyTemp.IsClosed())
{
CPloygon* pSideLine = NULL;
pSideLine = new CPloygon;
if(pSideLine != NULL)
{
pSideLine->Create(polyTemp);
if (pSideLine->m_bClosed && !pSideLine->IsEmpty())
{
m_RegionLst.AddTail(pSideLine);
}
else
{
delete pSideLine;
}
}
}
}
if (m_RegionLst.GetCount() == 0)
{
return 0;
}
if (m_RegionLst.GetCount() == 1)
{
return 1;
}
return FormatEdgeList();
}
BOOL CHole::ConstructEdgeList(const DList<XPolygonEx> &lstHole)
{
int nCount = lstHole.Length();
if(nCount <= 0)
{
return FALSE;
}
for(int i = 0; i < nCount; i++)
{
const XPolygonEx &polyTemp = lstHole[i];
CPloygon* pSideLine = NULL;
pSideLine = new CPloygon;
if(pSideLine != NULL)
{
pSideLine->Create(polyTemp);
if (pSideLine->m_bClosed && !pSideLine->IsEmpty())
{
m_RegionLst.AddTail(pSideLine);
}
else
{
delete pSideLine;
}
}
}
if (m_RegionLst.GetCount() == 0)
{
return 0;
}
if (m_RegionLst.GetCount() == 1)
{
return 1;
}
return FormatEdgeList();
}
BOOL CHole::ConstructEdgeList(const XPolygonEx &out, const DList<XPoly2D> &lstHole)
{
if(out.Length() <= 2)
{
return FALSE;
}
//out放到表首,后面不再判断最外边界,
//仅判断边界边界是否相交和洞中是否有洞
CPloygon* pSideLine = NULL;
pSideLine = new CPloygon;
if(pSideLine != NULL)
{
pSideLine->Create(out);
if (pSideLine->m_bClosed && !pSideLine->IsEmpty())
{
m_RegionLst.AddTail(pSideLine);
}
else
{
delete pSideLine;
return FALSE;
}
}
else
{
return FALSE;
}
int nCount = lstHole.Length();
for(int i=0; i<nCount; i++)
{
const XPoly2D &polyTemp = lstHole[i];
if(polyTemp.IsClosed())
{
CPloygon* pSideLine = NULL;
pSideLine = new CPloygon;
if(pSideLine != NULL)
{
pSideLine->Create(polyTemp);
if (pSideLine->m_bClosed && !pSideLine->IsEmpty())
{
m_RegionLst.AddTail(pSideLine);
}
else
{
delete pSideLine;
}
}
}
}
nCount = m_RegionLst.GetCount();
if (nCount == 0)
{
return 0;
}
if (nCount == 1)
{
return 1;
}
return FormatEdgeListAuto();
}
BOOL CHole::ConstructEdgeList(const XPolygonEx &out, const DList<XPolygonEx> &lstHole)
{
if(out.Length() <= 2)
return FALSE;
//out放到表首,后面不再判断最外边界,
//仅判断边界边界是否相交和洞中是否有洞
CPloygon* pSideLine = NULL;
pSideLine = new CPloygon;
if(pSideLine != NULL)
{
pSideLine->Create(out);
if (pSideLine->m_bClosed && !pSideLine->IsEmpty())
{
m_RegionLst.AddTail(pSideLine);
}
else
{
delete pSideLine;
return FALSE;
}
}
else
{
return FALSE;
}
int nCount = lstHole.Length();
for(int i = 0; i < nCount; i++)
{
const XPolygonEx &polyTemp = lstHole[i];
CPloygon* pSideLine = NULL;
pSideLine = new CPloygon;
if(pSideLine != NULL)
{
pSideLine->Create(polyTemp);
if (pSideLine->m_bClosed && !pSideLine->IsEmpty())
{
m_RegionLst.AddTail(pSideLine);
}
else
{
delete pSideLine;
}
}
}
nCount = m_RegionLst.GetCount();
if (nCount == 0)
{
return 0;
}
if (nCount == 1)
{
return 1;
}
return FormatEdgeListAuto();
}
BOOL CHole::ConstructEdgeList(const XPoly2D &out, const DList<XPoly2D> &lstHole)
{
if(out.Length() <= 2 && !out.IsClosed())
return FALSE;
//out放到表首,后面不再判断最外边界,
//仅判断边界边界是否相交和洞中是否有洞
CPloygon* pSideLine = NULL;
pSideLine = new CPloygon;
if(pSideLine != NULL)
{
pSideLine->Create(out);
if (pSideLine->m_bClosed && !pSideLine->IsEmpty())
{
m_RegionLst.AddTail(pSideLine);
}
else
{
delete pSideLine;
return FALSE;
}
}
else
{
return FALSE;
}
int nCount = lstHole.Length();
for(int i=0; i<nCount; i++)
{
const XPoly2D &polyTemp = lstHole[i];
if(polyTemp.IsClosed())
{
CPloygon* pSideLine = NULL;
pSideLine=new CPloygon;
if(pSideLine != NULL)
{
pSideLine->Create(polyTemp);
if (pSideLine->m_bClosed && !pSideLine->IsEmpty())
{
m_RegionLst.AddTail(pSideLine);
}
else
{
delete pSideLine;
}
}
}
}
nCount = m_RegionLst.GetCount();
if (nCount == 0)
{
return 0;
}
if (nCount == 1)
{
return 1;
}
return FormatEdgeListAuto();
}
//处理边链表(未指定外边界)
BOOL CHole::FormatEdgeList()
{
//判断各封闭多义线是否相交,并找出外边界,放到表首
POSITION pos1 = m_RegionLst.GetHeadPosition();
CPloygon* pSurround = NULL;
int nSrdTot = 0; //总包含次数
while (pos1 != NULL)
{
CPloygon* pPolygon1 = m_RegionLst.GetNext(pos1);
POSITION pos2 = m_RegionLst.GetHeadPosition();
int nSrd = 0; //pPolygon1与其他多边形的包含次数
while (pos2 != NULL)
{
CPloygon* pPolygon2=m_RegionLst.GetNext(pos2);
if (pPolygon1 != pPolygon2)
{
CPloygon* plgTemp = NULL;
int ret = pPolygon1->IsSurrounded(pPolygon2);
if (ret == 0)
{//AfxMessageBox(_T("有边界线相交,无法构造孔板!"));
return 0;
}
else if (ret == 1)
{//包含pPolygon,
nSrd++;
nSrdTot++;
plgTemp = pPolygon1;
if (nSrdTot == 1)
{
pSurround=plgTemp;
}
}
else if (ret == 2)
{//被pPolygon包含
nSrd++;
nSrdTot++;
plgTemp = pPolygon2;
if (nSrdTot == 1)
{
pSurround=plgTemp;
}
}
if (nSrdTot > 1 && plgTemp != NULL && pSurround != plgTemp)
{//AfxMessageBox(_T("孔中包含有孔,不合理!"));
return 0;
}
}
}
if (nSrd == 0)
{//AfxMessageBox(_T("你选择了没有外边界的孔,请重选!"));
return 0;
}
}
if (nSrdTot == 0)
{//AfxMessageBox(_T("你选择了没有外边界的孔,请重选!"));
return Acad::eNotImplementedYet;
}
if (pSurround != NULL)
{
POSITION posSrd = m_RegionLst.Find(pSurround);
m_RegionLst.RemoveAt(posSrd);
m_RegionLst.AddHead(pSurround);
}
else
{
return 0;
}
//改变方向,外边界逆时针,内边界顺时针
POSITION pos = m_RegionLst.GetHeadPosition();
while (pos != NULL)
{
CPloygon* pPolygon = m_RegionLst.GetNext(pos);
BOOL ret = pPolygon->GetClockwise();
if (pPolygon == pSurround&&ret == 1)
{
pPolygon->Reverse();
}
else if (ret == 2)
{
pPolygon->Reverse();
}
}
return TRUE;
}
//处理边链表(已经指定外边界,不再判断)
BOOL CHole::FormatEdgeListAuto()
{
BOOL bRet = FALSE;
int nRet = -1;
//判断所有各封闭多义线是否相交,判断洞中是否有洞
POSITION pos1 = m_RegionLst.GetHeadPosition();
if(pos1 == NULL)
{
return FALSE;
}
CPloygon* pSurround = m_RegionLst.GetNext(pos1);
while (pos1 != NULL)
{//是否与最外边界相交
CPloygon* pPolygon1 = m_RegionLst.GetNext(pos1);
if(pPolygon1 != pSurround)
{
nRet = pSurround->IsSurrounded(pPolygon1);
// 最外边界不包括此洞
if (nRet != 1)
{
return FALSE;
}
}
//洞与洞之间的关系
POSITION pos2 = pos1;
while (pos2 != NULL)
{
CPloygon* pPolygon2 = m_RegionLst.GetNext(pos2);
if (pPolygon1 != pPolygon2)
{
nRet = pPolygon1->IsSurrounded(pPolygon2);
if (nRet == 0 || nRet == 1 || nRet == 2)
{
return FALSE;
}
}
}
}
//改变方向,外边界逆时针,内边界顺时针
POSITION pos=m_RegionLst.GetHeadPosition();
while (pos != NULL)
{
CPloygon* pPolygon = m_RegionLst.GetNext(pos);
bRet = pPolygon->GetClockwise();
if (pPolygon == pSurround && bRet == 1)
{
pPolygon->Reverse();
}
else if (bRet == 2)
{
pPolygon->Reverse();
}
}
return TRUE;
}
BOOL CHole::ConstructEdgeList()
{
ads_name ssname;
struct resbuf* pCondition;
pCondition = acutBuildList(-4,_T("<OR"),RTDXF0,_T("CIRCLE"),RTDXF0,_T("LWPOLYLINE"),
RTDXF0,_T("POLYLINE"),-4,_T("OR>"),0);
const TCHAR* prompts[2];
prompts[0]=_T("\n请选择边界线,(<Enter>结束):");
prompts[1]=_T("\n请选择要剔除的边界线:");
if (acedSSGet(_T(":$"),prompts,NULL,pCondition,ssname) == RTCAN)
{
acedSSFree(ssname);
return 0;
}
acutRelRb(pCondition);
Adesk::Int32 nEnt;
if (acedSSLength(ssname,&nEnt) != RTNORM)
{
acedSSFree(ssname);
return 0;
}
for (long i = 0; i < nEnt; i++)
{
ads_name sEntName;
if (acedSSName(ssname,i,sEntName) != RTNORM)
{
acedSSFree(ssname);
return 0;
}
AcDbObjectId objId;
if (acdbGetObjectId(objId, sEntName) != Acad::eOk)
{
acedSSFree(ssname);
return 0;
}
if (objId == NULL)
{
acedSSFree(ssname);
return 0;
}
CPloygon* pSideLine = new CPloygon;
pSideLine->Create(objId);
if (!pSideLine->m_bClosed)
{
AfxMessageBox(_T("所选图形有非闭合区域!"));
acedSSFree(ssname);
return 0;
}
if (!(pSideLine->IsEmpty()))
{
CPloygon* pRgn=new CPloygon(*pSideLine);
m_RegionLst.AddTail(pRgn);
delete pSideLine;
}
}
acedSSFree(ssname);
if (m_RegionLst.GetCount() == 0)
{
return 0;
}
//平移
CPloygon* pHead = m_RegionLst.GetHead();
CBNode* pNode = pHead->Head();
if (pNode != NULL)
{
m_insertPt = pNode->m_pt;
}
AcGeVector3d disp = AcGePoint3d(0,0,0) - m_insertPt;
POSITION pos = m_RegionLst.GetHeadPosition();
while (pos != NULL)
{//平移
CPloygon* pRgn = m_RegionLst.GetNext(pos);
pRgn->MoveTo(disp);
}
if (m_RegionLst.GetCount() == 1)
{
return 1;
}
//判断各封闭多义线是否相交,并找出外边界,放到表首
POSITION pos1 = m_RegionLst.GetHeadPosition();
CPloygon* pSurround = NULL;
int nSrdTot = 0; //总包含次数
while (pos1 != NULL)
{
CPloygon* pPolygon1 = m_RegionLst.GetNext(pos1);
POSITION pos2 = m_RegionLst.GetHeadPosition();
int nSrd = 0; //pPolygon1与其他多边形的包含次数
while (pos2 != NULL)
{
CPloygon* pPolygon2 = m_RegionLst.GetNext(pos2);
if (pPolygon1 != pPolygon2)
{
CPloygon* plgTemp = NULL;
int ret = pPolygon1->IsSurrounded(pPolygon2);
if (ret == 0)
{
AfxMessageBox(_T("有边界线相交,无法构造孔板!"));
return 0;
}
else if (ret == 1)
{
nSrd++;
nSrdTot++;
plgTemp=pPolygon1;
if (nSrdTot == 1)
{
pSurround = plgTemp;
}
}
else if (ret == 2)
{
nSrd++;
nSrdTot++;
plgTemp = pPolygon2;
if (nSrdTot == 1)
{
pSurround = plgTemp;
}
}
if (nSrdTot > 1 && plgTemp != NULL && pSurround != plgTemp)
{
AfxMessageBox(_T("孔中包含有孔,不合理!"));
return 0;
}
}
}
if (nSrd == 0)
{
AfxMessageBox(_T("你选择了没有外边界的孔,请重选!"));
return 0;
}
}
if (nSrdTot == 0)
{
AfxMessageBox(_T("你选择了没有外边界的孔,请重选!"));
return Acad::eNotImplementedYet;
}
if (pSurround != NULL)
{
POSITION posSrd = m_RegionLst.Find(pSurround);
m_RegionLst.RemoveAt(posSrd);
m_RegionLst.AddHead(pSurround);
}
else
{
return 0;
}
//改变方向,外边界逆时针,内边界顺时针
pos = m_RegionLst.GetHeadPosition();
while (pos != NULL)
{
CPloygon* pPolygon = m_RegionLst.GetNext(pos);
BOOL ret = pPolygon->GetClockwise();
if (pPolygon == pSurround&&ret == 1)
{
pPolygon->Reverse();
}
else if (ret == 2)
{
pPolygon->Reverse();
}
}
return 1;
}
BOOL CHole::GetTriangles(DList<XTriangle> &lstRes)
{
return SimplifyToTriangle(lstRes);
}
void CHole::CreateHoles()
{
if(m_RegionLst.GetCount() == 0)
{
if (!ConstructEdgeList())
{
return;
}
}
//直线段化
POSITION pos = m_RegionLst.GetHeadPosition();
while (pos != NULL)
{
CPloygon* pRgn = m_RegionLst.GetNext(pos);
pRgn->LinearizePLine(1);
}
C3DFaceList face3DList;
if (!SimplifyToFace(face3DList))
{
return;
}
if (m_RegionLst.GetCount() == 0)
{
return;
}
CString blockName_main = _T("Hole");
CEntityList entLst;
AcDbObjectId blockId;
C3DFaceList2EntityList(face3DList,entLst);
SetLayerOfEntities(entLst,_T("1"),1);
if (!CreateBlock(entLst,blockName_main,blockId,AcGePoint3d(0,0,0)))
{
return;
}
ReleaseCEntityList(entLst);
ReleaseC3DFaceList(face3DList);
AcGePoint3d org = m_insertPt;
org.z = 0;
if (!CreateReference(org,blockName_main,0))
{
return;
}
}
BOOL CHole::SimplifyToTriangle(DList<XTriangle> &lstRes)
{
if (m_RegionLst.GetCount() == 0)
{
return 0;
}
if (!SortHolesInXY())
{
return 0;
}
if (!SortNodesAlongClockWise())
{
return 0;
}
//复制一个新链表
TBPolygonList RegionLst;
POSITION pos = m_RegionLst.GetHeadPosition();
while (pos != NULL)
{
CPloygon* pPolygon = m_RegionLst.GetNext(pos);
CPloygon* pPolygonNew = new CPloygon(*pPolygon);
pPolygonNew->ClearUp();
RegionLst.AddTail(pPolygonNew);
}
CPloygon* pHead = RegionLst.GetHead();
pos = RegionLst.GetHeadPosition();
while (pos != NULL)
{
CPloygon* pPolygon = RegionLst.GetNext(pos);
if (pPolygon != pHead)
{
CBNode* pNode = pPolygon->GetMostLeftNode();
CBNode* pNodeSuit = GetADivideNode(pHead,pPolygon,pNode);
if (pNodeSuit != NULL)
{
pHead->InsertBLineInto(pNodeSuit,pPolygon);
}
}
}
//三角化
CPloygon rgn = CPloygon(*pHead);
rgn.ConvertToTriangle(lstRes);
//***** 释放内存
pos = RegionLst.GetHeadPosition();
while (pos != NULL)
{
CPloygon* pPolygon = RegionLst.GetNext(pos);
delete pPolygon;
}
return 1;
}
BOOL CHole::SimplifyToFace(C3DFaceList& face3DList)
{
if (m_RegionLst.GetCount() == 0)
{
return 0;
}
if (!SortHolesInXY())
{
return 0;
}
if (!SortNodesAlongClockWise())
{
return 0;
}
TBPolygonList RegionLst;
POSITION pos = m_RegionLst.GetHeadPosition();
while (pos != NULL)
{
CPloygon* pPolygon = m_RegionLst.GetNext(pos);
CPloygon* pPolygonNew = new CPloygon(*pPolygon);
pPolygonNew->ClearUp();
RegionLst.AddTail(pPolygonNew);
}
CPloygon* pHead = RegionLst.GetHead();
pos = RegionLst.GetHeadPosition();
while (pos != NULL)
{
CPloygon* pPolygon = RegionLst.GetNext(pos);
if (pPolygon != pHead)
{
CBNode* pNode = pPolygon->GetMostLeftNode();
CBNode* pNodeSuit = GetADivideNode(pHead,pPolygon,pNode);
if (pNodeSuit != NULL)
{
pHead->InsertBLineInto(pNodeSuit,pPolygon);
}
}
}
//三角化
CPloygon rgn = CPloygon(*pHead);
rgn.ConvertTo3DFaces(face3DList);
//***** 释放内存
pos = RegionLst.GetHeadPosition();
while (pos != NULL)
{
CPloygon* pPolygon = RegionLst.GetNext(pos);
delete pPolygon;
}
return 1;
}
CBNode* CHole::GetADivideNode(CPloygon* pEdge,CPloygon* pEdge1,CBNode* pNode)
{
//pEdge:外边界
//pEdge1:内边界(孔)
//pNode:内边界上最左边的节点
if (pEdge == NULL || pNode == NULL)
{
return NULL;
}
pEdge->ReCalcSValue();
double limitX = pNode->m_pt.x;//内边界最左边节点的X坐标
CBNode* pTemp = NULL;
POSITION pos = pEdge->m_BNodeList.GetHeadPosition();
while (pos != NULL)
{
CBNode* pNode0 = pEdge->m_BNodeList.GetNext(pos);
//修改: modified on 2003.9.3
//if (pNode0->m_pt.x<=limitX)
if (pNode0->m_pt.x < limitX || fabs(pNode0->m_pt.x - limitX) < fTOL)
{//在外边界上选择X坐标小于或等于内边界上最左边节点的点
CBNode* pPrev = pEdge->GetPreNode(pNode0);
CBNode* pNext = pEdge->GetNextNode(pNode0);
int n = PtAtWhichSide(pPrev->m_pt, pNode0->m_pt, pNext->m_pt);
BOOL bSuitable = 0;
//如果pNode0的后一个节点在有向线段pPrev->pNode0的右侧
if (n == 2)
{//则只要pNode位于pPrev->pNode0的左侧或者pNode0->pNext的左侧,包括边界上,pNode0都是一个合适的节点
if (PtAtWhichSide(pPrev->m_pt,pNode0->m_pt,pNode->m_pt) != 2
||PtAtWhichSide(pNode0->m_pt,pNext->m_pt,pNode->m_pt) != 2)
{
bSuitable = 1;
}
}
else
{ //如果pNode0的后一个节点在有向线段pPrev->pNode0的左侧或线上
//则pNode要同时位于pPrev->pNode0和pNode0->pNext的左侧,
//包括边界上,pNode0才是一个合适的节点
if (PtAtWhichSide(pPrev->m_pt,pNode0->m_pt,pNode->m_pt) != 2
&& PtAtWhichSide(pNode0->m_pt,pNext->m_pt,pNode->m_pt) != 2)
{
bSuitable = 1;
}
}
if (bSuitable)
{//同时,线段pNode0->pNode不与外边界上位于X=limitX左侧的边界相交
if (!(pEdge->IsIntersectWith(limitX,pNode0->m_pt,pNode->m_pt)))
{
return pNode0;
}
}
}
}
return NULL;
}
BOOL CHole::SortHolesInXY()
{
if (m_RegionLst.GetCount() == 0)
{
return 0;
}
CPloygon* pHead = m_RegionLst.GetHead();
TBPolygonList tempList;
tempList.AddTail(pHead);
POSITION pos1 = m_RegionLst.GetHeadPosition();
while (pos1 != NULL)
{
CPloygon* pPolygon1 = m_RegionLst.GetNext(pos1);
if (pPolygon1 == pHead) continue;
CPloygon* pPolygon2 = tempList.GetTail();
double x1 = pPolygon1->GetMinX();
double x2 = pPolygon2->GetMinX();
if (x1 > x2)
{
tempList.AddTail(pPolygon1);
}
else if (fabs(x1 - x2) < fTOL)
{
if (pPolygon2 == pHead)
{
tempList.AddTail(pPolygon1);
}
else
{
double y1 = pPolygon1->GetMaxY();
double y2 = pPolygon2->GetMaxY();
POSITION pos2 = tempList.GetTailPosition();
if (y1 > y2)
{
tempList.AddTail(pPolygon1);
}
else
{
tempList.InsertBefore(pos2,pPolygon1);
}
}
}
else
{
POSITION pos2 = tempList.GetHeadPosition();
while (pos2 != NULL)
{
POSITION posTemp = pos2;
pPolygon2 = tempList.GetNext(pos2);
x2 = pPolygon2->GetMinX();
if (x1 < x2 && pPolygon1 != pHead)
{
tempList.InsertBefore(posTemp,pPolygon1);
break;
}
}
}
}
m_RegionLst.RemoveAll();
m_RegionLst.AddTail(&tempList);
return 1;
}
BOOL CHole::SortNodesAlongClockWise()
{
if (m_RegionLst.GetCount() == 0)
{
return 0;
}
//外边界
CPloygon* pHead = m_RegionLst.GetHead();
if (!(pHead->IsClosed()))
{
return 0;
}
CBNode* pLeft = pHead->GetMostLeftNode();
if (pLeft == NULL)
{
return 0;
}
//将最左边的点设为头
pHead->ResetHead(pLeft);
if (pHead->GetClockwise() == 1)
{//保证逆时针
pHead->Reverse();
}
//处理内边界
POSITION pos = m_RegionLst.GetHeadPosition();
while (pos != NULL)
{
CPloygon* pPolygon = m_RegionLst.GetNext(pos);
if (pPolygon != pHead)
{
CBNode* pLeft = pPolygon->GetMostLeftNode();
if (pLeft != NULL)
{//将最左边的点设为头
pPolygon->ResetHead(pLeft);
if (pPolygon->GetClockwise() == 2)
{ //保证顺时针
pPolygon->Reverse();
}
}
}
}
return 1;
}
BOOL CHole::CreateReference(AcGePoint3d org,CString& BlockTableRecordName,double rotAng,CString layerName)
{
AcDbBlockReference* pNewBlkRef;
AcDbObjectId newEntId;
AcDbObjectId newBlockId;
AcDbBlockTable* pBlockTable;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);
Acad::ErrorStatus es = pBlockTable->getAt(BlockTableRecordName,newBlockId);
if (es != Acad::eOk)
{
pBlockTable->close();
return 0;
}
pBlockTable->close();
AcDbObjectId layerId = NULL;
if (layerName != _T(""))
{
if (!IsLayerExistInDb(layerName))
{
NewLayer(layerName);
}
SetLayerFrozen(layerName,false);
SetLayerOff(layerName,false);
layerId = GetLayerRecordId(layerName);
}
pNewBlkRef = new AcDbBlockReference;
AcGeVector3d normal = AcGeVector3d(0.0,0.0,1.0);
AcGePoint3d basePt = org;
UCS2WCS(basePt);
AcGeMatrix3d mat;
acdbUcsMatrix(mat);
AcGeMatrix3d mat1;
mat1(0,0) = cos(rotAng);
mat1(0,1) = -sin(rotAng);
mat1(1,0) = sin(rotAng);
mat1(1,1) = cos(rotAng);
mat = mat * mat1;
pNewBlkRef->setBlockTableRecord(newBlockId);
pNewBlkRef->setNormal(normal);
pNewBlkRef->setBlockTransform(mat);
pNewBlkRef->setPosition(basePt);
if (layerId != NULL)
{
pNewBlkRef->setLayer(layerId);
}
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbBlockTableRecord* pBlockTableRec;
es = pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRec,AcDb::kForWrite);
if (es != Acad::eOk)
{
pBlockTable->close();
delete pNewBlkRef;
return 0;
}
pBlockTable->close();
es = pBlockTableRec->appendAcDbEntity(newEntId,pNewBlkRef);
if (es != Acad::eOk)
{
pBlockTableRec->close();
return 0;
}
pBlockTableRec->close();
pNewBlkRef->close();
return 1;
}
BOOL CHole::BlockName(CString& blockName)
{
static unsigned long Block_Num = 0;
CString temp;
Block_Num++;
temp.Format(_T("%ld"),Block_Num);
blockName = blockName + temp;
return 1;
}
BOOL CHole::CreateBlock(CEntityList& entLst,CString& blockName,AcDbObjectId& blockId,AcGePoint3d org)
{
if (!BlockName(blockName))
{
return 0;
}
AcDbBlockTable *pBlockTable = NULL;
Acad::ErrorStatus ret = acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForWrite);
if (ret != Acad::eOk)
{
return 0;
}
AcDbBlockTableRecord *pBlockTableRecord = new AcDbBlockTableRecord;
pBlockTableRecord->setOrigin(org);
pBlockTableRecord->setName(blockName);
pBlockTable->add(blockId,pBlockTableRecord);
pBlockTable->close();
POSITION pos = entLst.GetHeadPosition();
while (pos != NULL)
{
CEntity* pEnt = entLst.GetNext(pos);
pBlockTableRecord->appendAcDbEntity(pEnt->m_pAcDbEnt);
pEnt->m_pAcDbEnt->close();
}
pBlockTableRecord->close();
return 1;
}
AcDbObjectId CHole::GetLayerRecordId(CString layerName)
{
layerName.TrimLeft();
layerName.TrimRight();
if (layerName == _T(""))
{
return NULL;
}
AcDbLayerTable *pLayerTable;
if (acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pLayerTable,AcDb::kForRead) != Acad::eOk)
{
return NULL;
}
AcDbObjectId recordId = NULL;
if (pLayerTable->getAt(layerName, recordId) != Acad::eOk)
{
pLayerTable->close();
return NULL;
}
pLayerTable->close();
return recordId;
}
void CHole::ReleaseC3DFaceList(C3DFaceList& c3dfaceLst)
{
POSITION pos = c3dfaceLst.GetHeadPosition();
while (pos != NULL)
{
C3DFace* pC3DFace = c3dfaceLst.GetNext(pos);
delete pC3DFace;
}
c3dfaceLst.RemoveAll();
}
void CHole::ReleaseCEntityList(CEntityList& centityLst)
{
POSITION pos = centityLst.GetHeadPosition();
while (pos != NULL)
{
CEntity* pEnt = centityLst.GetNext(pos);
delete pEnt;
}
centityLst.RemoveAll();
}
void CHole::SetLayerOfEntities(CEntityList& entLst,CString layerName, int colorNum)
{
SetLayer(layerName, colorNum);
POSITION pos = entLst.GetHeadPosition();
while (pos != NULL)
{
CEntity* pEnt = entLst.GetNext(pos);
pEnt->m_pAcDbEnt->setLayer(layerName);
pEnt->m_pAcDbEnt->setColorIndex(256);
}
}
BOOL CHole::IsLayerExistInDb(CString layerName)
{
layerName.TrimLeft();
layerName.TrimRight();
if (layerName == _T(""))
{
return 0;
}
AcDbLayerTable *pLayerTable;
if (acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pLayerTable,AcDb::kForRead) != Acad::eOk)
{
return 0;
}
BOOL ret = pLayerTable->has(layerName);
pLayerTable->close();
return ret;
}
BOOL CHole::SetLayer(CString layerName, int colorNum)
{
layerName.TrimLeft();
layerName.TrimRight();
if (layerName == _T(""))
{
layerName = _T("0");
}
if (IsLayerExistInDb(layerName))
{
AcDbLayerTable *pLayerTable;
if (acdbHostApplicationServices()->workingDatabase()->getLayerTable(pLayerTable, AcDb::kForRead) != Acad::eOk)
{
return 0;
}
AcDbLayerTableRecord* pLayerTableRecord;
if (pLayerTable->getAt(layerName, pLayerTableRecord,AcDb::kForWrite) == Acad::eOk)
{
pLayerTable->close();
if (pLayerTableRecord->isFrozen())
{
pLayerTableRecord->setIsFrozen(false);
}
if (pLayerTableRecord->isOff())
{
pLayerTableRecord->setIsOff(false);
}
if (colorNum > 0 && colorNum < 256)
{
AcCmColor color;
color.setColorIndex(colorNum);
pLayerTableRecord->setColor(color);
}
pLayerTableRecord->close();
return 1;
}
else
{
pLayerTable->close();
return 0;
}
}
return NewLayer(layerName, colorNum);
}
BOOL CHole::NewLayer(CString& layerName, int colorNum, BOOL bFreeze)
{
layerName.TrimLeft();
layerName.TrimRight();
if (layerName == _T(""))
{
layerName = _T("0");
return 0;
}
AcDbLayerTableRecord *pLayerTableRecord = new AcDbLayerTableRecord;
if (!pLayerTableRecord)
{
return 0;
}
pLayerTableRecord->setName(layerName);
if (colorNum > 0 && colorNum < 256)
{
AcCmColor color;
color.setColorIndex(colorNum);
pLayerTableRecord->setColor(color);
}
if (bFreeze)
{
pLayerTableRecord->setIsFrozen(1);
}
AcDbLayerTable *pLayerTable;
if (acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pLayerTable,AcDb::kForWrite) != Acad::eOk)
{
delete pLayerTableRecord;
return 0;
}
AcDbObjectId recordId;
if (pLayerTable->add(recordId,pLayerTableRecord) != Acad::eOk)
{
pLayerTable->close();
delete pLayerTableRecord;
return 0;
}
pLayerTable->close();
pLayerTableRecord->close();
return 1;
}
void CHole::C3DFaceList2EntityList(C3DFaceList& c3dFaceLst,CEntityList& entLst)
{
POSITION pos = c3dFaceLst.GetTailPosition();
while (pos != NULL)
{
C3DFace* pNode = c3dFaceLst.GetPrev(pos);
CEntity* pCEnt = new CEntity(pNode->m_p3DFace);
entLst.AddTail(pCEnt);
}
}
BOOL CHole::SetLayerFrozen(CString layerName, bool bFreeze)
{
layerName.TrimLeft();
layerName.TrimRight();
if (layerName == _T(""))
{
return 0;
}
AcDbLayerTable *pLayerTable;
if (acdbHostApplicationServices()->workingDatabase()->getLayerTable(pLayerTable, AcDb::kForRead) != Acad::eOk)
{
return 0;
}
AcDbLayerTableRecord* pLayerTableRecord;
if (pLayerTable->getAt(layerName, pLayerTableRecord, AcDb::kForWrite) != Acad::eOk)
{
pLayerTable->close();
return 0;
}
pLayerTable->close();
if (bFreeze)
{
if (!pLayerTableRecord->isFrozen())
{
pLayerTableRecord->setIsFrozen(true);
}
}
else
{
if (pLayerTableRecord->isFrozen())
{
pLayerTableRecord->setIsFrozen(false);
}
}
pLayerTableRecord->close();
return 1;
}
BOOL CHole::SetLayerOff(CString layerName, bool bOff)
{
layerName.TrimLeft();
layerName.TrimRight();
if (layerName == _T(""))
{
return 0;
}
AcDbLayerTable *pLayerTable;
if (acdbHostApplicationServices()->workingDatabase()->getLayerTable(pLayerTable, AcDb::kForRead) != Acad::eOk)
{
return 0;
}
AcDbLayerTableRecord* pLayerTableRecord;
if (pLayerTable->getAt(layerName, pLayerTableRecord, AcDb::kForWrite) != Acad::eOk)
{
pLayerTable->close();
return 0;
}
pLayerTable->close();
if (bOff)
{
if (!pLayerTableRecord->isOff())
{
pLayerTableRecord->setIsOff(true);
}
}
else
{
if (pLayerTableRecord->isOff())
{
pLayerTableRecord->setIsOff(false);
}
}
pLayerTableRecord->close();
return 1;
}