//-----------------------------------------------------------------------------+ // 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 &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 &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 &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; iCreate(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 &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 &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; iCreate(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(""),0); const TCHAR* prompts[2]; prompts[0]=_T("\n请选择边界线,(结束):"); 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 &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 &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; }