//-------------------------------------------------------------------------------------------------------+ // Copyright (C), 1998-2007, SH Software Co. Ltd. // = FileName : Entity 类 // = Version : ver2.0 // = Author : zjq // = CreateDate : 2002-09-09 // = Description: Entity 定义 // = Maintainers: // //-------------------------------------------------------------------------------------------------------+ #include "StdAfx.h" #include "Entity.h" #include "XArc.h" #include "XAString.h" #include "PickSet.h" #include "DragPickEntSet.h" #include "XPoly2D.h" #include "XDbObject.h" #include "X3DFace.h" #include "XPushVar.h" #include "SymbolTable.h" #include "DragPickEntSet.h" #include "XBlockTable.h" #include "XGlobalFunc.h" #include "XPrivateGlobalFunc.h" static const TCHAR *sMsgPrompt[] = { /*MSG0*/ _T("\n选择无效, 重新选择!"), /*MSG1*/ _T("\n请重新选择!"), /*MSG2*/ _T("\n发现不可变形的对象: "), /*MSG3*/ _T("\n图块内有延伸方向不同于Z轴的对象,不能打散!"), /*MSG4*/ _T("\n是否为该对象"), }; const TCHAR* Entity::ApplicationName=_T("_ASH"); Entity::~Entity() { } int Entity::MatchEx(int tag, const Groups *data) { if (!groups) { GetGroups(); } if (!groupsEx || !data) { return 0; } Groups *rbData = SearchDataByTag(tag); if (!rbData) { return 0; } return (*rbData) == (*data); } int Entity::MatchEx(int tag, int data) { if (!groups) { GetGroups(); } if (!groupsEx) { return 0; } Groups *rbData = SearchDataByTag(tag); if (!rbData || rbData->code != XD_SHORT) { return 0; } return (rbData->shortInt == data); } int Entity::MatchEx(int tag, const TCHAR *data) { if (!groups) { GetGroups(); } if (!groupsEx || !data) { return 0; } Groups *rbData = SearchDataByTag(tag); if (!rbData || rbData->code != XD_STR || !rbData->string) { return 0; } return !_tcscmp(rbData->string, data); } int Entity::MatchEx(int tag, ads_real data) { if (!groups) { GetGroups(); } if (!groupsEx) { return 0; } Groups *rbData = SearchDataByTag(tag); if (!rbData || rbData->code != XD_REAL) { return 0; } return rbData->real == data; } int Entity::MatchEx(const Groups *tag, const Groups *data) { if (!tag || tag->code != XD_SHORT) { return 0; } return MatchEx(tag->shortInt, data); } int Entity::MatchBase(const Groups &rb) { if (rb.code == 1001) { OPENOBJ_BEGIN(*this, AcDb::kForRead, AcDbEntity, pEnt); if (pEnt) { resbuf *xData = pEnt->xData(rb.string); if (xData) { ads_relrb(xData); return 1; } else { return 0; } } else { return 0; } OPENOBJ_END(); } if (!groups) { GetGroups(0); } Groups *pg = SearchNode(rb.code); if (!pg) { return 0; } if (TypeOfCode(rb.code) == RTSTR) { XString s1, s2; s1 = pg->string; s2 = rb.string; _tcsupr(s1); _tcsupr(s2); return (ads_wcmatch(s1, s2) == RTNORM); } return *pg == rb; } int Entity::SetData(int code,...) { if (!groups) _GetGroups(); #ifdef _WIN64 va_list args; va_start(args, code); int rc = _SetData(code, args); va_end(args); return rc; #else void *buf=(char *)&code+sizeof(int); return _SetData(code,buf); #endif /*if (!groups) { _GetGroups(); } void *buf = (TCHAR *)&code + sizeof(int); return _SetData(code,buf);*/ } // 两个Resubf 节点成对的Match方可以 int Entity::Match(const RBList &exlist) { if (!groups) { GetGroups(); } Groups *exList = exlist.groups; if (!groupsEx || !exList || !exList->next) { return 0; } Groups *rb1 = exList, *rb2 = exList->next; while(MatchEx(rb1, rb2)) { rb1 = rb2->next; if (!rb1) { return 1; } rb2 = rb1->next; if (!rb2) { ads_fail(_T("\nBad Extend data list!")); return 0; } if (ads_usrbrk()) { return 0; } } return 0; } int Entity::_GetGroups() { if (groups) { Release(groups); groups = groupsEx = NULL; } // else groupsEx set to NULL ?? groups = (PGroups)ads_entget(name); return (groups ? RTNORM : RTERROR); } int Entity::FilterSelect(const TCHAR *prompt, const RBList &mask) { const TCHAR *szPrompts[2] = { prompt, _T("") }; PickSet ss(SS_FREE); int nRet = ss.Get(_T(":S:$"), szPrompts, NULL, mask); if (nRet == RTNORM) { long lCount = ss.Length(); if (lCount == 1) { *this = ss[0L]; } else { for (long i = 0; i < lCount; i++) { Entity ent = ss[i]; ent.Redraw(3); int rc = YesNoQuestion(sMsgPrompt[4], Q_YES); ent.Redraw(4); if (rc == RTCAN) { return rc; } else if (rc == Q_YES) { *this = ent; return RTNORM; } } return RTNONE; } } return nRet; } int Entity::FilterSelect(const TCHAR *prompt, const RBList &mask, ads_point res) { do { Entity ent; int rc = res ? ent.UserSelect(prompt, res) : ent.UserSelect(prompt); if (rc != RTNORM) { return rc; } if (ent.MatchBase(mask)) { *this = ent; return RTNORM; } XGeLib::adsout << sMsgPrompt[0]; } while(1); } int Entity::FilterSelect1(ads_real distPrec, const TCHAR *prompt, const RBList &mask, ads_point res) { XPushVar osmode(_T("OSMODE"), 512); do { XPoint pickPt; int rc = ads_getpoint(NULL, prompt, pickPt); if (rc != RTNORM) { return rc; } XPoint lowCorner = pickPt - XPoint(distPrec, distPrec); XPoint upCorner = pickPt + XPoint(distPrec, distPrec); PickSet ss(SS_FREE); if (ss.Get(_T("C"), &lowCorner, upCorner, mask) != RTNORM) { XGeLib::adsout << sMsgPrompt[0]; continue; } if (ss.Length() == 1) { *this = ss[0L]; if (res) { pickPt > res; } return RTNORM; } long len = ss.Length(); for (long i = 0; i < len; i++) { Entity ent = ss[i]; ent.Redraw(3); rc = YesNoQuestion(sMsgPrompt[4]); ent.Redraw(4); if (rc == RTCAN) { return rc; } else if (rc == Q_YES) { *this = ent; if (res) { pickPt > res; } return RTNORM; } } XGeLib::adsout << sMsgPrompt[1]; } while(1); } int Entity::RedrawAll(int mode) const { int nTileMode = 0; xg_getvar(_T("TILEMODE"), &nTileMode); resbuf * rbViewports = NULL; VERIFY(ads_vports(&rbViewports) == RTNORM && rbViewports); int nCurVp = rbViewports->rbnext->resval.rint; resbuf *rbNext = rbViewports->rbnext->rbnext->rbnext->rbnext->rbnext; while(rbNext && !(nTileMode == 0 && nCurVp == 1)) { ASSERT(rbNext->restype == RTLB && rbNext->rbnext->restype == RTSHORT); if (xg_setvar(_T("CVPORT"), rbNext->rbnext->resval.rint) == RTNORM) { Redraw(mode); } rbNext = rbNext->rbnext->rbnext->rbnext->rbnext->rbnext; } ads_relrb(rbViewports); xg_setvar(_T("CVPORT"), nCurVp); int nRet = Redraw(mode); return nRet; } int Entity::Move(const XPoint & basept, XPoint & res) const { if (!name[0] && !name[1]) { return RTERROR; } DragPickEntSet picks(basept); picks += *this; return picks.Move(basept, res); } int Entity::Rotate(const XPoint & basept, ads_real *res) const { if (!name[0] && !name[1]) { return RTERROR; } DragPickEntSet picks(basept); picks += *this; return picks.Rotate(basept, res); } int Entity::Scale(const XPoint & basept, ads_real *res) const { if (!name[0] && !name[1]) { return RTERROR; } DragPickEntSet picks(basept); picks += *this; return picks.Scale(basept, res); } int Entity::AssignAppName(const TCHAR *s) { if (s && s[0]) { ApplicationName = s; XSymbolTable appId(_T("APPID"), ApplicationName); if (!appId) { return ads_regapp(ApplicationName); } return RTNORM; } ApplicationError(_T("Bad Application Name\n")); return RTERROR; } // 创建扩充实体数据 void Entity::_MakeExGroups() { if (groups) { groupsEx = groups; while (groupsEx->next && (groupsEx->code != -3)) { groupsEx = groupsEx->next; } if (groupsEx->next) { // I got it; code = -3 groupsEx = groupsEx->next; } else { // make a -3 head groupsEx->next = (PGroups)ads_buildlist(-3,1001,ApplicationName,0); if (!groupsEx->next) { ApplicationError(_T("Error in Ex::GetGroups\n")); return; } groupsEx = (groupsEx->next)->next; } } } int Entity::GetGroups(int getEx) { if (groups) { Release(groups); groups = groupsEx = 0; } if (getEx && ApplicationName) { PGroups agroup = (PGroups)ads_newrb(RTSTR); if (!agroup) { return RTERROR; } agroup->string = _tcsdup(ApplicationName); groups = (PGroups)ads_entgetx(name,(struct resbuf*)agroup); ads_relrb((resbuf *)agroup); if (!groups) { return RTERROR; } else { _MakeExGroups(); } return RTNORM; } return _GetGroups(); } int Entity::GetGroups(const TCHAR *appname) { const TCHAR *oldApp = ApplicationName; ApplicationName = appname; int rc = GetGroups(); ApplicationName = oldApp; if (!groupsEx) { rc = RTERROR; } return rc; } PGroups Entity::SearchByTagCode(int tagCode) { PGroups group; group = groupsEx; while (group) { if (group->code == 1070 && group->shortInt == tagCode) { return group; } group = group->next; } return NULL; } int Entity::RemoveXData() { GetGroups(0); _MakeExGroups(); Modify(); return RTNORM; } int Entity::Erase() const { XDbObject dbObj(name, AcDb::kForWrite); if (!dbObj) { ; } else { AcDbEntity &dbEnt = dbObj; if (dbEnt.erase() == Acad::eOk) { return RTNORM; } } return RTERROR; } int Entity::DeleteTag(int tagCode) { PGroups g = groupsEx,g1,g2,g3; if (!g) { return RTERROR; } g1 = g; while (g) { if (g->code == 1070 && g->shortInt == tagCode) { break; } g1 = g; g = g->next; } if (!g) { return RTERROR; } g2 = g->next; if (!g2) { return RTERROR; } if (g2->code == 1002 && g2->string[0] == _T('{')) { while (g2) { if (g2->code == 1002 && g2->string[0] == _T('}')) { break; } g2 = g2->next; } if (!g2) { return RTERROR; } } g3 = g2->next; g2->next = 0; g1->next = g3; Release(g); return RTNORM; } int Entity::CreateTag(void *buf,int tagCode,int type) { PGroups list = groupsEx; if (!list) { ApplicationError(_T("Error in ::CreateTag")); return RTERROR; } while (list->next) { list = list->next; } list->next = (PGroups)ads_newrb(1070); if (!list->next) { ApplicationError(_T("Error in ::CreateTag")); return RTERROR; } list = list->next; list->shortInt = tagCode; list->next = (PGroups)ads_newrb(0); if (!list->next) { ApplicationError(_T("Error in ::CreateTag")); return RTERROR; } list = list->next; list->next = NULL; if (type == RTSTR) { list->code = XD_STR; list->string = _tcsdup(*(TCHAR **)buf); } else if (type == RTREAL) { // real list->code = XD_REAL; list->real = *((ads_real *)buf); } else { // int list->code = XD_SHORT; list->shortInt = *((short *)buf); } return RTNORM; } int Entity::SetExData(int tagCode,...) { if (!groups || !groupsEx) { GetGroups(); } int type = TypeOfCode(tagCode); void *buf = (int *)&tagCode + 1; if (type != RTSTR && type != RTREAL && type != RTSHORT) { ApplicationError(_T("This tag code %d is not support by the::SetExdata.\n"),tagCode); return RTERROR; } PGroups group = SearchByTagCode(tagCode); if (!group) { // add on the whole thing CreateTag(buf,tagCode,type); } else { // replace it PGroups list = group->next; int t1 = TypeOfCode(list->code); if (t1 != type) { ApplicationError(_T("Tag Code type does not match the group code type.::SetExData\n")); return RTERROR; } if (type == RTSTR) { free(list->string); list->string = _tcsdup(*(TCHAR **)buf); } else if (type == RTREAL) { // real list->real = *((ads_real *)buf); } else { //int list->shortInt = *((short *)buf); } } return RTNORM; } int Entity::GetExData(int tagCode,void *buf) { if (!groups || !groupsEx) { GetGroups(); } int type = TypeOfCode(tagCode); if (type != RTSTR && type != RTREAL && type != RTSHORT) { ApplicationError(_T("This tag code %d is not support by the::GetExdata.\n"),tagCode); return RTERROR; } PGroups group = SearchByTagCode(tagCode); if (group) { // replace it PGroups list = group->next; int t1 = TypeOfCode(list->code); if (t1 != type) { ApplicationError(_T("Tag Code type does not match the group code type.::SetExData\n")); return RTERROR; } if (type == RTSTR) { _tcscpy((TCHAR *)buf,list->string); } else if (type == RTREAL) { // real *((ads_real *)buf) = list->real; } else { //int *((short *)buf) = list->shortInt; } return RTNORM; } return RTERROR; } // Get 系列都没有检查类型的匹配 ------------------------------------!!! int Entity::GetInt(int tag_code,int &buf) { if (!groups || !groupsEx) { GetGroups(); } Groups *list; if ((list = (PGroups)XPrivate::get_xdata_tag_item((resbuf *)groupsEx, tag_code, NULL)) == NULL) { return RTERROR; } list = list->next; buf = list->shortInt; return RTNORM; } int Entity::GetReal(int tag_code,ads_real &buf) { if (!groups || !groupsEx) { GetGroups(); } Groups *list; if ((list = (PGroups)XPrivate::get_xdata_tag_item((resbuf *)groupsEx, tag_code, NULL)) == NULL) { return RTERROR; } list = list->next; buf = list->real; return RTNORM; } // don't free buf int Entity::GetRBinary(int tag_code, short &nBufLen, const char * &buf) { if (!groups || !groupsEx) { GetGroups(); } Groups *list; if ((list = (PGroups)XPrivate::get_xdata_tag_item((resbuf *)groupsEx, tag_code, NULL)) == NULL) { return RTERROR; } list = list->next; nBufLen = list->binary.length; buf = list->binary.buffer; return RTNORM; } // NOTE: // This function return a pointer equal to string pointer in the resbuf // When the Groups released,referrence to that string would be a disaster. int Entity::GetRString(int tag_code,TCHAR *&buf) { if (!groups || !groupsEx) { GetGroups(); } Groups *list; if ((list = (PGroups)XPrivate::get_xdata_tag_item((resbuf *)groupsEx, tag_code, NULL)) == NULL) { return RTERROR; } list = list->next; buf = list->string; return RTNORM; } int Entity::GetString(int tag_code,TCHAR *buf) { if (!groups || !groupsEx) { GetGroups(); } TCHAR *temp; int rt = GetRString(tag_code,temp); if (rt == RTNORM) { _tcscpy(buf,temp); } return rt; } int Entity::GetPoint(int tag_code, XPoint &res) { if (!groups || !groupsEx) { GetGroups(); } Groups *list; if ((list = (PGroups)XPrivate::get_xdata_tag_item((resbuf *)groupsEx, tag_code, NULL)) == NULL) { return RTERROR; } list = list->next; res = list->point; return RTNORM; } int Entity::SetReal(int tag_code,ads_real val) { if (!groups || !groupsEx) { GetGroups(); } PGroups tag_xdata = (PGroups)ads_newrb(XD_REAL); tag_xdata->real = val; XPrivate::set_xdata_tag_item((resbuf **)&groupsEx, tag_code, (resbuf*)tag_xdata, Entity::ApplicationName); return RTNORM; } int Entity::SetInt(int tag_code,int val) { if (!groups || !groupsEx) { GetGroups(); } PGroups tag_xdata = (PGroups)ads_newrb(XD_INT); tag_xdata->shortInt = val; XPrivate::set_xdata_tag_item((resbuf **)&groupsEx, tag_code, (resbuf*)tag_xdata, Entity::ApplicationName); return RTNORM; } int Entity::SetString(int tag_code, const TCHAR *val, int isHandle) { if (!groups || !groupsEx) { GetGroups(); } int xdCode = isHandle ? XD_HANDLE : XD_STR; PGroups tag_xdata = (PGroups)ads_newrb(xdCode); tag_xdata->string = _tcsdup(val); XPrivate::set_xdata_tag_item((resbuf **)&groupsEx, tag_code, (resbuf*)tag_xdata, Entity::ApplicationName); return RTNORM; } int Entity::SetPoint(int tag_code, const XPoint &pt) { if (!groups || !groupsEx) { GetGroups(); } PGroups tag_xdata = (PGroups)ads_newrb(XD_POINT); pt > tag_xdata->point; XPrivate::set_xdata_tag_item((resbuf **)&groupsEx, tag_code, (resbuf*)tag_xdata, Entity::ApplicationName); return RTNORM; } int Entity::SetBinary(int tag_code, short nBufLen, const char *buf) { assert(nBufLen<128 && nBufLen>0); if (!groups || !groupsEx) { GetGroups(); } PGroups tag_xdata = (PGroups)ads_newrb(1004); tag_xdata->binary.length = nBufLen; tag_xdata->binary.buffer = new char [nBufLen]; memcpy(tag_xdata->binary.buffer, buf, nBufLen); XPrivate::set_xdata_tag_item((resbuf **)&groupsEx, tag_code, (resbuf*)tag_xdata, Entity::ApplicationName); return RTNORM; } // API 2.0 int Entity::SetStruct(void *buf,int len, int tagCode) { if (!groups || !groupsEx) { GetGroups(); } long *lp; int v; long ll; TCHAR *p; int base; int i; if (len <= 0) { return RTERROR; } DeleteTag(tagCode); PGroups l = groupsEx; if (!l) { ApplicationError(_T("Error in ::SetStruct.\n")); return RTERROR; } while (l->next) { l = l->next; } l->next = (PGroups)ads_newrb(1070); if (!l->next) { ApplicationError(_T("Error in ::SetStruct.\n")); return RTERROR; } l = l->next; l->shortInt = tagCode; l->next = (PGroups)ads_newrb(1002); if (!l->next) { ApplicationError(_T("Error in ::SetStruct.\n")); return RTERROR; } l = l->next; l->string = _tcsdup(_T("{")); l->next = (PGroups)ads_newrb(XD_INT); if (!l->next) { ApplicationError(_T("Error in ::SetStruct.\n")); return RTERROR; } l = l->next; l->shortInt = len; lp = (long *)buf; for (i = 0; i < len / 4; i++) { l->next = (PGroups)ads_newrb(XD_LONG); if (!l->next) { ApplicationError(_T("Error in ::SetStruct.\n")); return RTERROR; } l = l->next; l->longInt = lp[i]; } v = len % 4; if (v) { //v = 1,2,3 p = (TCHAR *)≪ base = len / 4 * 4; for (i = 0; i < v; i++) { p[i] = ((TCHAR *)buf)[base + i]; } l->next = (PGroups)ads_newrb(XD_LONG); if (!l->next) { ApplicationError(_T("Error in ::SetStruct.\n")); return RTERROR; } l = l->next; l->longInt = ll; } l->next = (PGroups)ads_newrb(1002); if (!l->next) { ApplicationError(_T("Error in ::SetStruct.\n")); return RTERROR; } l = l->next; l->string = _tcsdup(_T("}")); l->next = 0; return RTNORM; } int Entity::GetStruct(void *buf,int len, int tagCode) { if (!groups || !groupsEx) { GetGroups(); } PGroups l = SearchByTagCode(tagCode); if (!l) { return RTERROR; } l = l->next; if (!l) { ApplicationError(_T("Error in ::GetStruct\n")); return RTERROR; } if (l->code == 1002 && l->string[0] == _T('{')) { l = l->next; if (!l) { ApplicationError(_T("Error in ::GetStruct\n")); return RTERROR; } // get the len int len1; if (l->code != XD_INT) { ApplicationError(_T("Error in ::GetStruct\n")); return RTERROR; } len1 = l->shortInt; len = len < len1 ? len : len1; l = l->next; if (!l) { ApplicationError(_T("Error in ::GetStruct\n")); return RTERROR; } long *lp = (long *)buf; while (len && l->code == XD_LONG) { if (len >= 4) { *lp = l->longInt; lp++; len -= 4; } else { TCHAR *cp1 = (TCHAR *)lp; TCHAR *cp2 = (TCHAR *)&l->longInt; for (int i = 0; i < len; i++) { cp1[i] = cp2[i]; } len = 0; } l = l->next; if (!l) { ApplicationError(_T("Error in ::GetStruct\n")); return RTERROR; } } return RTNORM; } return RTERROR; } int Entity::Make() { if (!groups) { GetGroups(0); } if (groups) { return (ads_entmake((struct resbuf *)groups)); } else { ApplicationError(_T("\nError in Entity::Make().\nZero groups.\n")); return RTERROR; } } int Entity::Make(int type,...) { if (groups) { Release(groups); groups = groupsEx = NULL; } groups = VBuildList(&type); if (!groups) { return RTERROR; } if (ads_entmake((struct resbuf *)groups) != RTNORM || GetLast() != RTNORM) { ads_printf(_T("\nEntity::Make(...) Error!")); return RTERROR; } return RTNORM; } int Entity::MakeEx(int type,...) { if (groups) { Release(groups); groups = groupsEx = NULL; } groups = VBuildList(&type); if (!groups) return RTERROR; if (ads_entmake((struct resbuf *)groups) == RTERROR || GetLast() != RTNORM) { ads_printf(_T("\nEntity::Make(...) Error!")); return RTERROR; } _MakeExGroups(); return RTNORM; } // 求模型的边界(忽略图纸实体: POINT, TEXT, ATTRIB, ATTDEF, DIMENSION) // tranMat -- 当前实体为图块中的子实体时,需左乘的变换矩阵 // Status: When it's POLYLINE, the result still not verified // return: RTNORM--确切求得边界; RTERROR--不能确切求得边界; RTNONE--模型边界不可求 int Entity::GetExtend(ads_point lowPt, ads_point upPt, ads_matrix tranMat) { if (!tranMat) { AcDbExtents geomExt; XDbObject obj(name, AcDb::kForRead); if (!obj) { return RTNONE; } AcDbEntity &objEnt = obj; Acad::ErrorStatus es = objEnt.getGeomExtents(geomExt); if (es == Acad::eOk) { XPoint ptLow = geomExt.minPoint(); XPoint ptUp = geomExt.maxPoint(); ptLow > lowPt; ptUp > upPt; return RTNORM; } } if (!(*this)) { return RTNONE; } XString eType; if (GetData(0, eType) != RTNORM) { return RTNONE; } XPoint extrusion(0, 0, 1); ads_real thickness = 0; GetData(210, extrusion); if (!(extrusion == Point(0,0,1))) { return RTNONE; } GetData(39, &thickness); if (eType == _T("LINE")) { XLine aLine(*this, LS_FINITE, tranMat); *(XPoint *)lowPt = Min(aLine.StartPoint(), aLine.EndPoint()); *(XPoint *)upPt = Max(aLine.StartPoint(), aLine.EndPoint()); upPt[Z] += thickness; if (fabs(thickness) > 1E-6 && tranMat) { return RTERROR; } } else if (eType == _T("3DFACE")) { X3DFace face(*this, tranMat); return face.GetExtend(lowPt, upPt); } else if (eType == _T("ATTDEF") || eType == _T("ATTRIB") || eType == _T("TEXT") || eType == _T("DIMENSION")) { return RTNONE; } else if (eType == _T("ARC")) { XArc arc(*this, tranMat); arc.GetExtend(lowPt, upPt); upPt[Z] += thickness; if (fabs(thickness) > 1E-6 && tranMat) { return RTERROR; } } else if (eType == _T("CIRCLE")) { XCircle cir(*this, tranMat); cir.GetExtend(lowPt, upPt); upPt[Z] += thickness; if (fabs(thickness) > 1E-6 && tranMat) { return RTERROR; } } else if (eType == _T("INSERT")) { ads_matrix mat, mat1; if (GetInsertMatrix(*this, mat) != RTNORM) { return RTNONE; } TCHAR blk[80]=_T(""); GetData(2, blk); XBlockTable blkTab(blk); if (tranMat) { AT_multiply_matrix(tranMat, mat, mat1); } else { memcpy(mat1, mat, sizeof(ads_matrix)); } return blkTab.GetExtend(lowPt, upPt, mat1); } else if (eType == _T("POINT")) { return RTNONE; } else if (eType == _T("POLYLINE")) { // 不包含弧段时可求 int polyFlag; GetData(70, &polyFlag); if (polyFlag <= 1 && !tranMat) { // do not take ECS-Vertex into account XPoly2D poly(*this); poly.GetExtend(lowPt, upPt); upPt[Z] += thickness; return RTNORM; } Entity subEnt, nextEnt; ads_entnext(*this, nextEnt); XPoint ptm, ptn; int rt = RTNORM; int index = 0; do { nextEnt.GetGroups(0); if (!nextEnt.Is(_T("VERTEX"))) { break; } int flg = 0; ads_real bulge = 0; nextEnt.GetData(70, &flg); if ((flg&128) && !(flg&64)) { break; } if (nextEnt.GetData(42, &bulge) == RTNORM && fabs(bulge)>0.0001) { rt = RTERROR; } XPoint vertex; nextEnt.GetData(10, vertex); { XPoint vtPt = vertex; if (tranMat) { AT_xformpt(tranMat, vtPt, vertex); } else { vertex = vtPt; } } if (!index) { ptm = ptn = vertex; } else { ptm = Max(ptm, vertex); ptn = Min(ptn, vertex); } subEnt = nextEnt; index ++; } while(ads_entnext(subEnt, nextEnt) == RTNORM); ptm.z += thickness; ptm > upPt; ptn > lowPt; return rt; } else if (eType == _T("SOLID") || eType == _T("TRACE")) { X3DFace notFace; for (int i = 0; i < 4; i++) { XPoint vertex; GetData(10+i, vertex); if (tranMat) { XPoint ptNew; AT_xformpt(tranMat, vertex, ptNew); notFace.SetVertex(i,ptNew); } else { notFace.SetVertex(i, vertex); } } return notFace.GetExtend(lowPt, upPt); } else { return RTNONE; } return RTNORM; } // 实体变换: 允许不等比缩放 int Entity::XTransform(ads_matrix mat) { XString eType; ads_real thickness; XPoint extrusion; if (!(*this) || GetData(0, eType) != RTNORM) { return RTERROR; } if (eType == _T("LWPOLYLINE")) { XDbObject obj(name, AcDb::kForWrite); if (!!obj) { AcDbPolyline *pline = AcDbPolyline::cast(obj.m_pObject); if (pline) { //只对顶点进行变换, 不考虑弧度的变化 int nVerts = pline->numVerts(); for (int i = 0; i < nVerts; i++) { AcGePoint2d pt; if (pline->getPointAt(i, pt) == Acad::eOk) { XPoint pt1 = pt; XPoint pt2; AT_xformpt(mat, pt1, pt2); pline->setPointAt(i, pt2); } } return RTNORM; } } return RTERROR; } if (GetData(39, &thickness) == RTNORM || (GetData(210, extrusion) == RTNORM && !(extrusion == XPoint(0,0,1)))) { return RTERROR; } if (eType == _T("LINE")) { XLine aLine(*this, LS_FINITE, mat); return aLine.Modify(this); } else if (eType == _T("3DFACE")) { X3DFace face(*this, mat); return face.Modify(*this); } else if (eType == _T("POINT")) { XPoint pt, npt; GetData(10, &pt.x); AT_xformpt(mat, pt, npt); SetData(10, &npt.x); return Modify(); } else if (eType == _T("SOLID") || eType == _T("TRACE")) { for (int i = 0; i < 4; i++) { XPoint vertex, nVertex; GetData(10 + i, (ads_real *)vertex); AT_xformpt(mat, vertex, nVertex); SetData(10 + i, (ads_real *)nVertex); } return Modify(); } else if (eType == _T("POLYLINE")) { Entity subEnt, nextEnt; XPoint base, nBase; ads_entnext(*this, nextEnt); GetData(10, base); AT_xformpt(mat, base, nBase); XPoint ptm, ptn; int rt = RTNORM; do { nextEnt.GetGroups(0); if (!nextEnt.Is(_T("VERTEX"))) break; int flg = 0; ads_real bulge = 0; nextEnt.GetData(70, &flg); if ((flg&128) && !(flg&64)) { break; } if (nextEnt.GetData(42, &bulge) == RTNORM && fabs(bulge) > 0.0001) { rt = RTERROR; } XPoint vertex, nVertex; nextEnt.GetData(10, vertex); AT_xformpt(mat, vertex, nVertex); nextEnt.SetData(10, &nVertex.x); nextEnt.Modify(); subEnt = nextEnt; } while(ads_entnext(subEnt, nextEnt) == RTNORM); SetData(10, &nBase); Modify(); return rt; } else if (eType == _T("ARC")) { XArc ar(*this); XPoint ptStart, ptEnd, ptMid; ar.GetStartPoint(ptStart); ar.GetEndPoint(ptEnd); ar.MidPoint(ptMid); XPoint ptNewStart, ptNewEnd, ptNewMid; AT_xformpt(mat, ptStart, ptNewStart); AT_xformpt(mat, ptEnd, ptNewEnd); AT_xformpt(mat, ptMid, ptNewMid); XArc arNew(ptNewStart, ptNewMid, ptNewEnd); arNew.Modify(this); return RTERROR; } XGeLib::adsout << sMsgPrompt[2] << eType; return RTERROR; } // 求实体的范围 int Entity::GetExtend(ads_point cen, ads_real *x, ads_real *y, ads_real *z) { XPoint lowPt, upPt; int rc = GetExtend(lowPt, upPt); if (rc == RTNONE) { return rc; } XPoint extSize = upPt-lowPt; if (cen) { Midpoint(lowPt, upPt, cen); } if (x) { *x = extSize.x; } if (y) { *y = extSize.y; } if (z) { *z = extSize.z; } return rc; } int Entity::MatchBase(const RBList &baseList) { for (Groups *rb = baseList.groups; rb != NULL; rb = rb->next) { if (!MatchBase(*rb)) { return 0; } } return 1; } int Entity::In(const PickSet *pSelectionSet) { ASSERT(pSelectionSet != NULL); ads_name entT; Adesk::Int32 lLen = 0L; acedSSLength(pSelectionSet->name,&lLen); for (long j = 0;j < lLen;j++) { acedSSName(pSelectionSet->name,j,entT); if (entT[0] == name[0] && entT[1] == name[1]) { return TRUE; } } return FALSE; // return (ads_ssmemb(name,pSelectionSet->name) == RTNORM ? TRACE:FALSE); }