Files
envi-code/SourceCode/Code2026/tg_shs/shs_public/function.cpp
T
2026-09-28 15:28:50 +08:00

3157 lines
82 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.
#include "stdafx.h"
//#include <DbObject.h>
//#include <arxtools.h>
#include <rxregsvc.h>
//#include <ImageDc.h>
#include <actrans.h>
//#include <dbwall.h>
#include <vector>
#include <algorithm>
#include <functional>
#include <dbxline.h>
#include "tapi.h"
#include "TelDef.h"
#include "XBlock.h"
#define TPI 6.283185307
#define MINL 1.0E-6
#define FEQU(a,b) (fabs((a) - (b)) < MINL)
#define E6TOL 1.e-6
//CTemporaryResourceOverride
const char *GetRegLocation1()
{
#if (ADS>14)
return "SoftWare\\Tangent\\Tel2k";
#else
return "SoftWare\\Tangent\\Tel14";
#endif
}
// cet 2016.7.20 add 获得外部参照实体转换矩阵
AcGeMatrix3d GetExternalEntityTransform(Entity ent)
{
AcDbObjectId idTemp;
acdbGetObjectId(idTemp, ent.name);
AcGeMatrix3d matRet = AcGeMatrix3d::kIdentity;
AcDbBlockTable *pTbl = NULL;
acdbCurDwg()->getBlockTable(pTbl, AcDb::kForRead);
if (pTbl != NULL)
{
bool bFlag = false;
AcDbBlockTableIterator *it = NULL;
pTbl->newIterator(it);
for (it->start(); !it->done() && !bFlag; it->step())
{
AcDbBlockTableRecord *pRcd = NULL;
it->getRecord(pRcd, AcDb::kForRead);
if (pRcd != NULL && pRcd->isFromExternalReference())
{
AcGeMatrix3d mat = AcGeMatrix3d::kIdentity;
AcDbObjectIdArray arrId;
pRcd->getBlockReferenceIds(arrId);
if (arrId.length() != 1)
{
pRcd->close();
continue;
}
AcDbBlockReference *pRef = NULL;
acdbOpenObject(pRef, arrId[0], AcDb::kForRead);
if (pRef != NULL)
{
mat = pRef->blockTransform();
pRef->close();
}
else
{
pRcd->close();
continue;
}
AcDbBlockTableRecordIterator *itRec = NULL;
pRcd->newIterator(itRec);
for (itRec->start(); !itRec->done() && !bFlag; itRec->step())
{
AcDbObjectId id;
itRec->getEntityId(id);
if (id = idTemp)
{
matRet = mat;
bFlag = true;
break;
}
}
delete itRec;
}
pRcd->close();
}
delete it;
pTbl->close();
}
return matRet;
}
static XPoint g_ptDragCenter;
static int DragRotationAction(ads_point pt, ads_matrix mt)
{
ads_real nRot=ads_angle(g_ptDragCenter, pt);
Ucs2Wcs(g_ptDragCenter).GetRotationMatrix(nRot, mt);
return RTNORM;
}
int DragRotate(PickSet &ss, XPoint Pt, const TCHAR* szPmt)
{
ss.Redraw(3); // 将实体隐藏
// DragPickSet ssDrag(Pt, ss);
XPoint ptDrag;
g_ptDragCenter = Pt;
ads_initget(RSG_OTHER, NULL);
int rc = ads_draggen(ss, szPmt, 0, DragRotationAction, ptDrag);
if(rc==RTNORM) {
ads_real nRot=CT_std_angle(ads_angle(Ucs2Wcs(g_ptDragCenter), Ucs2Wcs(ptDrag)))*180/PI;
XPushVar<int> vOsMode(_T("OSMODE"), 0);
return ads_command(RTSTR, _T(".ROTATE"), RTPICKS, (TLong_ptr *)ss, RTSTR, _T(""),
RT3DPOINT, &g_ptDragCenter, RTREAL, nRot, RTNONE);
}
else if(rc==RTSTR) {
TCHAR sInput[80]=_T("");
ads_getinput(sInput);
if(!sInput[0])
return RTERROR;
ads_real nRot=_tstof(sInput);
if(fabs(nRot)<_angSnap)
return RTERROR;
XPushVar<int> vOsMode(_T("OSMODE"), 0);
return ads_command(RTSTR, _T(".ROTATE"), RTPICKS, (TLong_ptr *)ss, RTSTR, _T(""),
RT3DPOINT, &g_ptDragCenter, RTREAL, nRot, RTNONE);
}
else
ss.Redraw(4);// 将实体恢复
return RTNORM;
}
static int DragMoveAction(ads_point pt, ads_matrix mt)
{
ads_real nRot=ads_angle(g_ptDragCenter, pt);
Ucs2Wcs(g_ptDragCenter).GetMoveMatrix(pt, mt);
return RTNORM;
}
int DragMove(PickSet &ss, XPoint Pt, const TCHAR* szPmt)
{
ss.Redraw(2); // 将实体隐藏
XPoint ptDrag;
g_ptDragCenter = Pt;
ads_initget(RSG_OTHER, NULL);
int rc = ads_draggen(ss, szPmt, 0, DragMoveAction, ptDrag);
acedGetAcadDwgView()->RedrawWindow();
if(rc==RTNORM) {
XPushVar<int> vOsMode(_T("OSMODE"), 0);
return ads_command(RTSTR, _T(".MOVE"), RTPICKS, (TLong_ptr *)ss, RTSTR, _T(""),
RT3DPOINT, &g_ptDragCenter, RT3DPOINT, &ptDrag, RTNONE);
}
else
ss.Redraw(4);// 将实体恢复
return rc;
}
// 给定1点, 得到该点上的墙
Entity GetPtOnWall(XPoint pt)
{
RBList rbMask = ads_buildlist( -4, _T("<or"),
-4, _T("<and"), RTDXF0, _T("LINE"), 8, LAY_WALL, -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("ARC"), 8, LAY_WALL, -4, _T("and>"),
-4, _T("or>"), NULL);
PickSet ss(SS_FREE);
XPoint ptTemp1, ptTemp2;
ptTemp1.x = pt.x - 5;
ptTemp1.y = pt.y + 5;
ptTemp2.x = pt.x + 5;
ptTemp2.y = pt.y - 5;
ss.Get(_T("C"), ptTemp1, ptTemp2, rbMask);
int len2 = ss.Length();
if(ss.Length() != 1)
return Entity();
return ss[0L];
}
// 给定1点, 得到该点上的窗, 柱
Entity GetPtOnWindow(XPoint pt)
{
RBList rbMask = ads_buildlist( -4, _T("<or"),
-4, _T("<and"), RTDXF0, _T("INSERT"), 8, LAY_WIN, -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("INSERT"), 8, LAY_COLU, -4, _T("and>"),
-4, _T("or>"), NULL);
PickSet ss(SS_FREE);
XPoint ptTemp1, ptTemp2;
ptTemp1.x = pt.x - 5;
ptTemp1.y = pt.y + 5;
ptTemp2.x = pt.x + 5;
ptTemp2.y = pt.y - 5;
ss.Get(_T("C"), ptTemp1, ptTemp2, rbMask);
int len2 = ss.Length();
if(ss.Length() != 1)
return Entity();
return ss[0L];
}
BOOL IsPtOnSegment(XPoint pt, XCurveSegment seg, double nSnap)
{
if(seg.Is(CURVE_LINE)){
XLine line(1);
line = seg.GetLine();
return IsPtOnLine(pt, line, nSnap);
}
else if(seg.Is(CURVE_ARC)){
XArc arc = seg.GetArc();
return IsPtOnArc(pt, arc, nSnap);
}
else if(seg.Is(CURVE_CIRCLE)){
XCircle cir = seg.GetCircle();
return IsPtOnCircle(pt, cir, nSnap);
}
else
return FALSE;
}
BOOL IsPtOnLine(XPoint pt, XLine line, double nSnap)
{
ads_real l1,l2,l12;
double dd = pt.Distance(&line);
if(fabs(pt.Distance(&line)) > nSnap) return FALSE;
l1=ads_distance(pt, line.StartPoint());
l2=ads_distance(pt, line.EndPoint());
l12=line.GetLength();
if(fabs(l1 + l2 - l12) <= nSnap) return TRUE;
return FALSE;
}
BOOL IsPtOnCircle(XPoint pt, XCircle circle, double nSnap)
{
double r=pt.Distance(circle.GetCenterPt()) - circle.GetRadius();
if(fabs(r) < nSnap)
return TRUE;
else
return FALSE;
}
BOOL IsPtOnArc(XPoint pt, XArc arc, double nSnap)
{
double ang = ads_angle(arc.GetCenterPt(), pt);
double rad = arc.GetRadius();
double ff = ads_distance(arc.GetCenterPt(), pt);
if(fabs(ads_distance(arc.GetCenterPt(), pt) - rad) > nSnap)
return FALSE;
if( arc.GetStarAngle() < arc.GetEndAngle() ) {
if(ang>arc.GetStarAngle() && ang<arc.GetEndAngle()) return TRUE;
}
else {
if(ang>arc.GetStarAngle() || ang<arc.GetEndAngle()) return TRUE;
}
return FALSE;
}
//void MakeVisible(PickSet &ss, bool bTrue)
//{
// long len=ss.Length();
// for(long i=0;i<len;i++) {
// Entity ent=ss[i];
// OPENOBJ_BEGIN(ent, AcDb::kForWrite, AcDbEntity, pEnt);
// if(pEnt) pEnt->setVisibility(bTrue? AcDb::kVisible : AcDb::kInvisible);
// OPENOBJ_END();
// }
//}
//***************************************************************
// arx 函数
//****************************************************************
BOOL IsLayerOn(const TCHAR*szLayerName)
{
// 判断图层是开是关
AcDbLayerTable *pLayertable;
AcDbLayerTableRecord *pLayerRec;
acdbCurDwg()->getLayerTable(pLayertable, AcDb::kForRead);
if(!pLayertable)
return FALSE;
if((pLayertable->getAt(szLayerName, pLayerRec, AcDb::kForRead)) == Acad::eOk) {
pLayertable->close();
if (pLayerRec->isOff() == Adesk::kTrue){
pLayerRec->close();
return FALSE;
}
else{
pLayerRec->close();
return TRUE;
}
pLayerRec->close();
}
else
pLayertable->close();
return TRUE;
}
BOOL SetLayerOnOff(const TCHAR*szLayerName, BOOL bOpen)
{
AcDbLayerTable *pLayertable = NULL;
AcDbLayerTableRecord *pLayerRec = NULL;
acdbCurDwg()->getLayerTable(pLayertable, AcDb::kForRead);
if(!pLayertable)
return FALSE;
if((pLayertable->getAt(szLayerName, pLayerRec, AcDb::kForWrite)) == Acad::eOk) {
if(bOpen)
pLayerRec->setIsOff(Adesk::kFalse); // 打开
else
pLayerRec->setIsOff(Adesk::kTrue); // 关
pLayerRec->close();
pLayertable->close();
}
else
pLayertable->close();
return TRUE;
}
BOOL AddLayer(const TCHAR* szLayer, int iColor)
{
BOOL bHasIt;
AcDbLayerTable *pLayerTable;
AcDbLayerTableRecord *pLayerTableRecord = new AcDbLayerTableRecord;
AcCmColor color;
color.setColorIndex(iColor);
acdbCurDwg()->getLayerTable(pLayerTable, AcDb::kForWrite);
bHasIt = pLayerTable->has(szLayer);
if(!bHasIt){
pLayerTableRecord->setName(szLayer);
pLayerTableRecord->setColor(color);
pLayerTable->add(pLayerTableRecord);
}
else{
pLayerTable->getAt(szLayer, pLayerTableRecord, AcDb::kForWrite);
pLayerTableRecord->setColor(color);
}
pLayerTable->close();
pLayerTableRecord->close();
return TRUE;
}
Acad::ErrorStatus PostToDb(AcDbEntity* ent, BOOL bClose)
{
Adesk::Boolean flag;
if(bClose)
flag = Adesk::kTrue;
else
flag = Adesk::kFalse;
AcDbObjectId objId = AddToCurrentSpace(ent, flag);
return Acad::eOk;
}
BOOL CreateTextStyle(const TCHAR*szTextStyle, const TCHAR*szEngShape, const TCHAR*szChnShape)
{
CString csTextStyle(szTextStyle), csEngShape(szEngShape), csChnShape(szChnShape);
AcDbDatabase *pCurDwg=acdbCurDwg();
AcDbTextStyleTable* pTT = NULL;
VERIFY(pCurDwg->getTextStyleTable(pTT, AcDb::kForWrite) == Acad::eOk);
AcDbTextStyleTableRecord* pTTR = new AcDbTextStyleTableRecord;
if(pTTR->setName(csTextStyle) != Acad::eOk) {
AfxMessageBox(_T("文字样式名称不合法!请重新输入。"));
delete pTTR;
pTT->close();
return FALSE;
}
if(csEngShape != _T(""))
pTTR->setFileName((const TCHAR*)csEngShape);
if(csChnShape != _T(""))
pTTR->setBigFontFileName((const TCHAR*)csChnShape);
else
pTTR->setBigFontFileName(NULL);
if(pTT->add(pTTR) != Acad::eOk ) {
pTT->close();
delete pTTR;
return FALSE;
}
pTT->close();
pTTR->close();
return TRUE;
}
BOOL ModifyTextStyle(const TCHAR*szTextStyle, const TCHAR*szEngShape, const TCHAR*szChnShape)
{
CString csTextStyle(szTextStyle), csEngShape(szEngShape), csChnShape(szChnShape);
AcDbTextStyleTableRecord *pRec=NULL;
AcDbObjectId idTextStyle = GetTextStyleId(csTextStyle);
if(!idTextStyle)
return FALSE;
OPENOBJ_BEGIN(idTextStyle, AcDb::kForWrite, AcDbTextStyleTableRecord, pRec);
if(csEngShape != _T(""))
pRec->setFileName((const TCHAR*)csEngShape);
if(csChnShape != _T(""))
pRec->setBigFontFileName((const TCHAR*)csChnShape);
else
pRec->setBigFontFileName(NULL);
OPENOBJ_END();
return TRUE;
}
int DoubleCmp(const double *i, const double *j)
{
if(*i < *j)
return -1;
else if(*i > *j)
return 1;
else
return 0;
}
int DoubleCmp2(const double *i, const double *j)
{
if(*i > *j)
return -1;
else if(*i < *j)
return 1;
else
return 0;
}
//读扩展数据
CString ReadXdata(Entity ent, const TCHAR*szName)
{
AcDbObjectId eId;
AcDbEntity *pEnt = NULL;
acdbGetObjectId(eId, ent);
acdbOpenObject(pEnt, eId, AcDb::kForRead);
if(!pEnt)
return _T("");
resbuf *pRb = pEnt->xData(szName);
CString csRet;
if (pRb != NULL) {
resbuf *pTemp = pRb;
if (pTemp->rbnext != NULL) {
pTemp = pTemp->rbnext;
if (pTemp->restype == 1000)
csRet = pTemp->resval.rstring;
}
}
ads_relrb(pRb);
pEnt->close();
return csRet;
}
//写扩展数据
BOOL WriteXdata(Entity ent, const TCHAR*szName, const TCHAR*szValue)
{
AcDbObjectId eId;
AcDbEntity *pEnt = NULL;
acdbGetObjectId(eId, ent);
if(!XSymbolTable(_T("APPID"), szName))
ads_regapp(szName);
acdbOpenObject(pEnt, eId, AcDb::kForWrite);
if(!pEnt)
return FALSE;
resbuf *pXData = ads_buildlist(1001, szName, 1000, szValue, NULL);
pEnt->setXData(pXData);
ads_relrb(pXData);
pEnt->close();
return TRUE;
}
double GetLineAngle(Entity ent)
{
double ang;
if(ent.Is(_T("LINE"))){
Callme();
return -1;
}
XPoint pt1, pt2;
GetWire2Point(ent, pt1, pt2);
ang = ads_angle(pt1, pt2);
return ang;
}
//注意,调用者自己考虑len比例的问题
void GetPointPickSet(XPoint pt, PickSet &ss, RBList &rbMask, int len)//注意:pt是UCS点
{
double dLen = len;
// if(DocGetMeterUnitDraw())
// dLen = dLen / 100.0;
XPoint ptTemp1, ptTemp2;
ptTemp1.x = pt.x - dLen;
ptTemp1.y = pt.y + dLen;
ptTemp2.x = pt.x + dLen;
ptTemp2.y = pt.y - dLen;
//sr add 2006-4-28 支持三维上插入阀门
ptTemp1.z = pt.z;
ptTemp2.z = pt.z;
XLine line(ptTemp1, ptTemp2, 1);
// line.Make();
ss.Get(_T("C"), ptTemp1, ptTemp2, rbMask);
long len1 = ss.Length();
for(long i=0;i<len1;i++){
Entity ent = ss[i];
}
}
BOOL IsPointLinkNull(XPoint pt)
{
PickSet ss(SS_FREE);
GetPointPickSet(pt, ss);
long len = ss.Length();
if(ss.Length() > 1)
return FALSE;
else
return TRUE;
}
void Get2PtFLinePick(PickSet &ss, XPoint ptStart, XPoint ptEnd, RBList &rbMask, int n)
{
XPoint p1, p2, p3, p4;
double angle = ads_angle(ptStart, ptEnd);
ads_polar(ptStart, (angle + PI/2), n, p1); // p1
ads_polar(ptStart, (angle - PI/2), n, p2); // p2
ads_polar(ptEnd, (angle + PI/2), n, p3); // p3
ads_polar(ptEnd, (angle - PI/2), n, p4); // p4
struct resbuf *list = ads_buildlist( RTPOINT, &p1, RTPOINT, &p2,
RTPOINT, &p4, RTPOINT, &p3,
RTPOINT, &p1, NULL);
ss.Get(_T("F"), list, NULL, rbMask);
ads_relrb(list);
}
//mode == 0 居中对齐,两端留一定距离
//mode == 1 两端对齐
//将一段线均分N个点
void GetPointList(XCurveSegment seg, int iNum, XPointList &lstPt, int mode)
{
double dDist2Wall(0);
if(mode == 0)
dDist2Wall = 0.5;
else if(mode == 1)
dDist2Wall = 0;
else if(mode == 2)
dDist2Wall = 0.25;
double dDistEven(0);
dDistEven = seg.GetLength() / (2*dDist2Wall+iNum-1);
AcGePoint3d ptTmp;
AcDbCurve *pCurve = seg.AsAcDbCurve();
if(seg.Is(CURVE_CIRCLE)){
XCircle ar = seg.GetCircle();
pCurve = new AcDbCircle(ar.GetCenterPt(), AcGeVector3d(0,0,1), ar.GetRadius());
}
if(pCurve == NULL)
return;
int n = 0;
while(n < iNum){
//mod liaoy 避免出现除以0的导致dDistEven无效
double dDist = 0;
if(mode == 1 && iNum == 1)
dDist = seg.GetLength() / 2;
else
dDist = dDist2Wall*dDistEven+n*dDistEven;
//double dDist = dDist2Wall*dDistEven+n*dDistEven;
//mod end
pCurve->getPointAtDist(dDist, ptTmp);
lstPt.NewAppend(ptTmp);
n++;
}
delete pCurve;
return;
}
//将一段线以间距nDist均分N个点
void GetPointList(XCurveSegment seg, double dDist, XPointList &lstPt)
{
double dLen = seg.GetLength();
AcGePoint3d ptTmp;
AcDbCurve *pCurve = seg.AsAcDbCurve();
if(seg.Is(CURVE_CIRCLE)){
XCircle ar = seg.GetCircle();
pCurve = new AcDbCircle(ar.GetCenterPt(), AcGeVector3d(0,0,1), ar.GetRadius());
}
if(pCurve == NULL)
return;
if(dDist < 0){//反向
dDist = fabs(dDist);
double dAllDist = 1;
int n = 0;
while(dAllDist > 0){
dAllDist = dLen - n*dDist;
pCurve->getPointAtDist(dAllDist, ptTmp);
lstPt.NewAppend(ptTmp);
n++;
}
}
else{ //正向
double dAllDist = 0;
int n = 0;
while(dLen > dAllDist){
dAllDist = n*dDist;
pCurve->getPointAtDist(dAllDist, ptTmp);
lstPt.NewAppend(ptTmp);
n++;
}
}
delete pCurve;
return;
}
double GetArcLenByChord(XArc &arc, double nChord)
{
double nRadius = arc.GetRadius();
double nTmp = nChord / (2.0*nRadius);
nTmp = asin(nTmp) * 2.0 * nRadius;
return nTmp;
}
//将一段线均分N个点, 但间距是50倍数(喷淋系统)
void GetPointList(XCurveSegment seg, int iNum, XPointList &lstPt, double nShortDist, double nDist2Wall)
{
if(seg.Is(CURVE_LINE)){
XLine line = seg.GetLine();
double angLine = ads_angle(line.StartPoint(), line.EndPoint());
double distLine = line.GetLength() / iNum / 2;
if(distLine < nShortDist && nShortDist > 0)
distLine = nShortDist;
double nTmp1 = distLine / 100;
double nTmp2 = distLine - ((int)nTmp1)*100;
double nTmp3 = nTmp2 / 25 + 0.5;
int iTmp1 = (int)nTmp3;
distLine = (int)nTmp1 * 100 + iTmp1 * 25;
int n = 1;
XPoint ptTemp;
double nFisrtDist = (line.GetLength() - distLine * (iNum-1) * 2) / 2;
while(nFisrtDist > nDist2Wall){
distLine += 25;
nFisrtDist = nFisrtDist - iNum*25;
}
nTmp1 = nFisrtDist / 100;
nTmp2 = nFisrtDist - ((int)nTmp1)*100;
nTmp3 = nTmp2 / 50 + 0.5;
iTmp1 = (int)nTmp3;
nFisrtDist = (int)nTmp1 * 100 + iTmp1 * 50;
ads_polar(line.StartPoint(), angLine, nFisrtDist, ptTemp);
lstPt.NewAppend(ptTemp);
while(n < iNum){
ads_polar(line.StartPoint(), angLine, (2*n)*distLine + nFisrtDist, ptTemp);
lstPt.NewAppend(ptTemp);
n++;
}
}
else if(seg.Is(CURVE_ARC)){
XArc arc = seg.GetArc();
nShortDist = nShortDist*2;
XPoint ptStart, ptEnd;
arc.GetStartPoint(ptStart);
arc.GetEndPoint(ptEnd);
// arc.GetPoints(ptStart, ptEnd);
double distLine = arc.GetLength() / iNum;
double nTmp1 = distLine / 100;
double nTmp2 = distLine - ((int)nTmp1)*100;
double nTmp3 = nTmp2 / 50 + 0.5;
int iTmp1 = (int)nTmp3;
distLine = (int)nTmp1 * 100 + iTmp1 * 50;
int n = 1;
XPoint ptTemp;
double nFisrtDist = (arc.GetLength() - distLine * (iNum-1)) / 2;
while(nFisrtDist > nDist2Wall){
distLine += 50;
nFisrtDist = nFisrtDist - iNum*25;
}
nTmp1 = nFisrtDist / 100;
nTmp2 = nFisrtDist - ((int)nTmp1)*100;
nTmp3 = nTmp2 / 50 + 0.5;
iTmp1 = (int)nTmp3;
nFisrtDist = (int)nTmp1 * 100 + iTmp1 * 50;
nFisrtDist = GetArcLenByChord(arc, nFisrtDist);
AcDbArc *pArc=new AcDbArc;
pArc->setCenter(arc.GetCenterPt());
pArc->setRadius(arc.GetRadius());
pArc->setStartAngle(arc.GetStarAngle());
pArc->setEndAngle(arc.GetEndAngle());
pArc->getPointAtDist(nFisrtDist, ptTemp);
lstPt.NewAppend(ptTemp);
distLine = GetArcLenByChord(arc, distLine);
if(distLine > 0.001){
while(distLine > 0.001 && n < iNum){
pArc->getPointAtDist(n*distLine + nFisrtDist, ptTemp);
lstPt.NewAppend(ptTemp);
n++;
}
}
delete pArc;
}
}
BOOL Is2LineOnLine(XLine line1, XLine line2)
{
XPoint ptStart, ptEnd;
ptStart = line1.StartPoint();
ptEnd = line1.EndPoint();
double len1 = fabs(ptStart.Distance(&line2));
double len2 = fabs(ptEnd.Distance(&line2));
if(fabs(ptStart.Distance(&line2)) < 2.0 && fabs(ptEnd.Distance(&line2)) < 2.0)
return TRUE;
else
return FALSE;
}
BOOL Is2ArcOnArc(XArc arc1, XArc arc2)
{
XPoint ptCen1, ptCen2;
ptCen1 = arc1.GetCenterPt();
ptCen2 = arc2.GetCenterPt();
double nRadius1, nRadius2;
nRadius1 = arc1.GetRadius();
nRadius2 = arc2.GetRadius();
if(ptCen1 == ptCen2 && (fabs(nRadius1 - nRadius2) < 0.1))
return TRUE;
else
return FALSE;
}
void GetLineMax2Pt(XPoint pt1, XPoint pt2, XPoint &pt3, XPoint &pt4)
{
XLine l1(pt1, pt3, LS_FINITE);
XLine l2(pt2, pt3, LS_FINITE);
XLine l3(pt1, pt4, LS_FINITE);
XLine l4(pt2, pt4, LS_FINITE);
double nMaxLen = 0.0;
XPoint ptStart, ptEnd;
nMaxLen = l1.GetLength() > nMaxLen ? l1.GetLength() : nMaxLen;
nMaxLen = l2.GetLength() > nMaxLen ? l2.GetLength() : nMaxLen;
nMaxLen = l3.GetLength() > nMaxLen ? l3.GetLength() : nMaxLen;
nMaxLen = l4.GetLength() > nMaxLen ? l4.GetLength() : nMaxLen;
if(nMaxLen == l1.GetLength()){
pt3 = l1.StartPoint();
pt4 = l1.EndPoint();
return;
}
if(nMaxLen == l2.GetLength()){
pt3 = l2.StartPoint();
pt4 = l2.EndPoint();
return;
}
if(nMaxLen == l3.GetLength()){
pt3 = l3.StartPoint();
pt4 = l3.EndPoint();
return;
}
if(nMaxLen == l4.GetLength()){
pt3 = l4.StartPoint();
pt4 = l4.EndPoint();
return;
}
}
void DrawSlide(const TCHAR*szPath, CWnd* pWnd)
{
CImageDC img;
CDC *pDC = pWnd->GetDC();
CRect rc;
pWnd->GetClientRect(&rc);
img.InitDC(pDC, rc, GetAcadBackColor());
img.PaintSlide(szPath);
img.SetDC(NULL);
pWnd->ReleaseDC(pDC);
}
void DrawSlide(const TCHAR*szPath, CDC* pDC, CRect rc)
{
CImageDC img;
img.InitDC(pDC, rc, GetAcadBackColor());
img.PaintSlide(szPath);
img.SetDC(NULL);
}
XCurveSegment GetSegByPt(XPoly2D poly, XPoint pt, double &dAngle)
{
XCurveSegment seg;
int m = poly.HitTestOnCurve(pt);
if(m > 0)
m = m - 2;
else if(m < 0)
m = abs(m) -1;
else if(m == 0)
return XCurveSegment();
if(m < 0)
m = 0;
poly.Nth(m, seg);
if(seg.Is(CURVE_LINE))
dAngle= seg.GetLine().Direction();
else if(seg.Is(CURVE_ARC)){
XPoint ptCenter;
seg.GetArc().Center(ptCenter);
dAngle = ads_angle(ptCenter, pt) + PI/2;
}
return seg;
}
XArc GetArcByCir(XPoint ptCen, double nRadius, XPoint ptStart, XPoint ptEnd, BOOL bIsLongArc = TRUE)
{
double startAngle = ads_angle(ptCen, ptStart);
double endAngle = ads_angle(ptCen, ptEnd);
XArc arc1(ptCen, nRadius, startAngle, endAngle);
XArc arc2(ptCen, nRadius, endAngle, startAngle);
if(bIsLongArc){
if(arc1.GetLength() > arc2.GetLength())
return arc1;
else
return arc2;
}
else{
if(arc1.GetLength() > arc2.GetLength())
return arc2;
else
return arc1;
}
}
CString PlusString(const TCHAR* szRes, int step, BOOL bIsPlus)
{
if(_tcsicmp(szRes, _T("")) == 0)
return CString();
XString xsText;
int num, numWith;
StringAnalysis(szRes, xsText, &num, &numWith);
CString csRes = szRes;
CString csRet = csRes;
if(numWith != 0){
if(bIsPlus)
num += step;
else if(num > 1)
num -= step;
if(num < 0)
num = 0;
if(numWith == -1)
csRet.Format(_T("%s%d"), xsText, num);
else{ //需要补0
XString sText;
sText << xsText;
TCHAR szNext[256]=_T("");
_itot(num, szNext, 10);
if(numWith > 0) {
int iZeroNum = numWith - (int)_tcslen(szNext);
for(int kk=0; kk<iZeroNum; kk++)
sText << _T("0");
}
sText << szNext;
csRet = (const TCHAR*)sText;
}
}
if(csRet != csRes)
return csRet;
CString csChinaDigit[] = {_T("一"),_T("二"),_T("三"),_T("四"),_T("五"),_T("六"),_T("七"),_T("八"),_T("九"),_T("十"),};
CString csChinaDigit2[] = {_T("零"),_T("贰"),_T("叁"),_T("肆"),_T("伍"),_T("陆"),_T("柒"),_T("捌"),_T("玖"),_T("拾"),};
CString cs12Digit[] = {_T("Ⅰ"),_T("Ⅱ"),_T("Ⅲ"),_T("Ⅳ"),_T("Ⅴ"),_T("Ⅵ"),_T("Ⅶ"),_T("Ⅷ"),_T("Ⅸ"),_T("Ⅹ"),_T("Ⅺ"),_T("Ⅻ")};
CString csLetter[] = {_T("a"),_T("b"),_T("c"),_T("d"),_T("e"),_T("f"),_T("g"),_T("h"),_T("i"),_T("j"),_T("k"),_T("l"),_T("m"),_T("n"),_T("o"),_T("p"),_T("q"),_T("r"),_T("s"),_T("t"),_T("u"),_T("v"),_T("w"),_T("x"),_T("y"),_T("z")};
CString csLetter2[] = {_T("A"),_T("B"),_T("C"),_T("D"),_T("E"),_T("F"),_T("G"),_T("H"),_T("I"),_T("J"),_T("K"),_T("L"),_T("M"),_T("N"),_T("O"),_T("P"),_T("Q"),_T("R"),_T("S"),_T("T"),_T("U"),_T("V"),_T("W"),_T("X"),_T("Y"),_T("Z")};
CString csRightTmp2, csLeftTmp2;
int len = csRes.GetLength();
int iIdx(0);
TCHAR cUnit = csRes[len-1];
BYTE byte = (BYTE)cUnit;
CString csUnit = cUnit;
#if (ADS<17)
if(IsDBCSLeadByte(byte)){//如果是半个汉字,就再读下1个字符
TCHAR cUnit2 = csRes[len-2];
csUnit.Format(_T("%c%c"),cUnit2, cUnit);
}
#endif
csRightTmp2 = csUnit;
/////////////////////////////////////////////////////////////////////////
//对后面特殊字符进行递增
int iLen = 1;
#if (ADS<17)
iLen = 2;
#endif
for(int m=0;m<10;m++){
if(csRightTmp2 == csChinaDigit[m]){
CString csLeftTmp = csRes.Left(len - iLen);
if(bIsPlus)
iIdx = m + step;
else
iIdx = m - step;
iIdx = (iIdx+10) % 10;
csRightTmp2 = csChinaDigit[iIdx];
csRet.Format(_T("%s%s"), csLeftTmp, csRightTmp2);
return csRet;
}
}
for(m=0;m<10;m++){
if(csRightTmp2 == csChinaDigit2[m]){
CString csLeftTmp = csRes.Left(len - iLen);
if(bIsPlus)
iIdx = m + step;
else
iIdx = m - step;
iIdx = (iIdx+10) % 10;
csRightTmp2 = csChinaDigit2[iIdx];
csRet.Format(_T("%s%s"), csLeftTmp, csRightTmp2);
return csRet;
}
}
for(m=0;m<12;m++){
if(csRightTmp2 == cs12Digit[m]){
CString csLeftTmp = csRes.Left(len - iLen);
if(bIsPlus)
iIdx = m + step;
else
iIdx = m - step;
iIdx = (iIdx+12) % 12;
csRightTmp2 = cs12Digit[iIdx];
csRet.Format(_T("%s%s"), csLeftTmp, csRightTmp2);
return csRet;
}
}
for(m=0;m<26;m++){
csRightTmp2 = csRes.Right(1);
if(csRightTmp2 == csLetter[m]){
CString csLeftTmp = csRes.Left(len - 1);
if(bIsPlus)
iIdx = m + step;
else
iIdx = m - step;
iIdx = (iIdx+26) % 26;
csRightTmp2 = csLetter[iIdx];
csRet.Format(_T("%s%s"), csLeftTmp, csRightTmp2);
return csRet;
}
}
for(m=0;m<26;m++){
csRightTmp2 = csRes.Right(1);
if(csRightTmp2 == csLetter2[m]){
CString csLeftTmp = csRes.Left(len - 1);
if(bIsPlus)
iIdx = m + step;
else
iIdx = m - step;
iIdx = (iIdx+26) % 26;
csRightTmp2 = csLetter2[iIdx];
csRet.Format(_T("%s%s"), csLeftTmp, csRightTmp2);
return csRet;
}
}
/////////////////////////////////////////////////////////////////////////
//对前面特殊字符进行递增
for(m=0;m<10;m++){
if(csLeftTmp2 == csChinaDigit[m]){
CString csRightTmp = csRes.Right(len - 2);
if(bIsPlus)
iIdx = m + step;
else
iIdx = m - step;
iIdx = (iIdx+10) % 10;
csLeftTmp2 = csChinaDigit[iIdx];
csRet.Format(_T("%s%s"), csLeftTmp2, csRightTmp);
return csRet;
}
}
for(m=0;m<10;m++){
if(csLeftTmp2 == csChinaDigit2[m]){
CString csRightTmp = csRes.Right(len - 2);
if(bIsPlus)
iIdx = m + step;
else
iIdx = m - step;
iIdx = (iIdx+10) % 10;
csLeftTmp2 = csChinaDigit2[iIdx];
csRet.Format(_T("%s%s"), csLeftTmp2, csRightTmp);
return csRet;
}
}
for(m=0;m<12;m++){
if(csLeftTmp2 == cs12Digit[m]){
CString csRightTmp = csRes.Right(len - 2);
if(bIsPlus)
iIdx = m + step;
else
iIdx = m - step;
iIdx = (iIdx+12) % 12;
csLeftTmp2 = cs12Digit[iIdx];
csRet.Format(_T("%s%s"), csLeftTmp2, csRightTmp);
return csRet;
}
}
for(m=0;m<26;m++){
csLeftTmp2 = csRes.Left(1);
if(csLeftTmp2 == csLetter[m]){
CString csRightTmp = csRes.Right(len - 1);
if(bIsPlus)
iIdx = m + step;
else
iIdx = m - step;
iIdx = (iIdx+26) % 26;
csLeftTmp2 = csLetter[iIdx];
csRet.Format(_T("%s%s"), csLeftTmp2, csRightTmp);
return csRet;
}
}
for(m=0;m<26;m++){
csLeftTmp2 = csRes.Left(1);
if(csLeftTmp2 == csLetter2[m]){
CString csRightTmp = csRes.Right(len - 1);
if(bIsPlus)
iIdx = m + step;
else
iIdx = m - step;
iIdx = (iIdx+26) % 26;
csLeftTmp2 = csLetter2[iIdx];
csRet.Format(_T("%s%s"), csLeftTmp2, csRightTmp);
return csRet;
}
}
return csRet;
}
CString PlusString2(const TCHAR* szRes, int step, BOOL bIsPlus)//给MYSPIN用,他不需要对前面递增递减
{
CString csRes = szRes;
int len = csRes.GetLength();
int iIdx(0);
CString csRet = csRes;
CString csRightTmp = csRes.Right(2);
CString csChinaDigit[] = {_T("一"),_T("二"),_T("三"),_T("四"),_T("五"),_T("六"),_T("七"),_T("八"),_T("九"),_T("十"),};
CString csChinaDigit2[] = {_T("零"),_T("贰"),_T("叁"),_T("肆"),_T("伍"),_T("陆"),_T("柒"),_T("捌"),_T("玖"),_T("拾"),};
CString cs12Digit[] = {_T("Ⅰ"),_T("Ⅱ"),_T("Ⅲ"),_T("Ⅳ"),_T("Ⅴ"),_T("Ⅵ"),_T("Ⅶ"),_T("Ⅷ"),_T("Ⅸ"),_T("Ⅹ"),_T("Ⅺ"),_T("Ⅻ")};
CString csLetter[] = {_T("a"),_T("b"),_T("c"),_T("d"),_T("e"),_T("f"),_T("g"),_T("h"),_T("i"),_T("j"),_T("k"),_T("l"),_T("m"),_T("n"),_T("o"),_T("p"),_T("q"),_T("r"),_T("s"),_T("t"),_T("u"),_T("v"),_T("w"),_T("x"),_T("y"),_T("z")};
CString csLetter2[] = {_T("A"),_T("B"),_T("C"),_T("D"),_T("E"),_T("F"),_T("G"),_T("H"),_T("I"),_T("J"),_T("K"),_T("L"),_T("M"),_T("N"),_T("O"),_T("P"),_T("Q"),_T("R"),_T("S"),_T("T"),_T("U"),_T("V"),_T("W"),_T("X"),_T("Y"),_T("Z")};
for(int m=0;m<10;m++){
if(csRightTmp == csChinaDigit[m]){
CString csLeftTmp = csRes.Left(len - 2);
if(bIsPlus)
iIdx = m + step;
else
iIdx = m - step;
iIdx = (iIdx+10) % 10;
csRightTmp = csChinaDigit[iIdx];
csRet.Format(_T("%s%s"), csLeftTmp, csRightTmp);
return csRet;
}
}
for(m=0;m<10;m++){
if(csRightTmp == csChinaDigit2[m]){
CString csLeftTmp = csRes.Left(len - 2);
if(bIsPlus)
iIdx = m + step;
else
iIdx = m - step;
iIdx = (iIdx+10) % 10;
csRightTmp = csChinaDigit2[iIdx];
csRet.Format(_T("%s%s"), csLeftTmp, csRightTmp);
return csRet;
}
}
for(m=0;m<12;m++){
if(csRightTmp == cs12Digit[m]){
CString csLeftTmp = csRes.Left(len - 2);
if(bIsPlus)
iIdx = m + step;
else
iIdx = m - step;
iIdx = (iIdx+12) % 12;
csRightTmp = cs12Digit[iIdx];
csRet.Format(_T("%s%s"), csLeftTmp, csRightTmp);
return csRet;
}
}
for(m=0;m<26;m++){
csRightTmp = csRes.Right(1);
if(csRightTmp == csLetter[m]){
CString csLeftTmp = csRes.Left(len - 1);
if(bIsPlus)
iIdx = m + step;
else
iIdx = m - step;
iIdx = (iIdx+26) % 26;
csRightTmp = csLetter[iIdx];
csRet.Format(_T("%s%s"), csLeftTmp, csRightTmp);
return csRet;
}
}
for(m=0;m<26;m++){
csRightTmp = csRes.Right(1);
if(csRightTmp == csLetter2[m]){
CString csLeftTmp = csRes.Left(len - 1);
if(bIsPlus)
iIdx = m + step;
else
iIdx = m - step;
iIdx = (iIdx+26) % 26;
csRightTmp = csLetter2[iIdx];
csRet.Format(_T("%s%s"), csLeftTmp, csRightTmp);
return csRet;
}
}
for(int i=1;i<=len;i++){
CString csRight = csRes.Right(i);
if(i == 1){
TCHAR c = csRight[0];
if(!_istdigit(c))
break;
}
BOOL bIsAllZ = TRUE;
int lenRight = csRight.GetLength();
for(int j=0;j<lenRight;j++){
CString csTmp = csRight[j];
if(csTmp != _T("0")){
bIsAllZ = FALSE;
break;
}
}
if(bIsAllZ)
continue;
CString csLeft = csRes.Left(len - i);
int val = _ttoi(csRight);
if(val <= 0) // SR MODIFY if(val == 0)
break;
if(bIsPlus){
val += step;
if(val < 1)
val = 1;
}
else{
val -= step;
if(val < 1)
val = 1;
}
csRet.Format(_T("%s%d"), csLeft, val);
}
return csRet;
}
void SplitBlkStr(const TCHAR *szInput, CString &csTK, CString &csRecord)
{
// CString csInput = szInput;
// int idx = csInput.Find(_T('$'));
// if(idx > 0)
// {
// CString csTmp;
// csTmp = csInput.Right(csInput.GetLength() - idx);
// SplitBlkStr(csTmp, csTK, csRecord);
// return;
// }//以上几句 沈睿 2011-6-24加,有的图块名是有前缀的。一般都是从$开头
int len = (int)_tcslen(szInput);
TCHAR szTemp[256]=_T("");
int j =0;
BOOL bfisrt = TRUE;
szTemp[0] = _T('\0');
for(int i=0; i<=len; i++)
{
if(szInput[i] != _T('\0') && szInput[i] != _T('$'))
szTemp[j] = szInput[i];
else {
szTemp[j] = _T('\0');
if(szTemp[0] != _T('\0') && bfisrt){
csTK = szTemp;
bfisrt = FALSE;
}
else if(szTemp[0] != _T('\0') && !bfisrt){
csRecord = szTemp;
}
j =-1;
}
j++;
}
}
XCurveSegment GetBlkPickSeg(Entity entBlk, XPoint ptPick)
{
double xscale;
entBlk.GetData(41, &xscale);
xscale = fabs(xscale);
XBlock myBlock(entBlk);
if(!myBlock.m_bInitSuccess)
return XCurveSegment();
AcDbBlockTableRecordIterator *pIterator;
pIterator = myBlock.GetIterator();
for(pIterator->start(); !pIterator->done(); pIterator->step()){
AcDbEntity *pEnt;
pIterator->getEntity(pEnt, AcDb::kForRead);
AcDbCircle *pCir = NULL;
AcDbLine *pLine = NULL;
AcDbPolyline *pPoly = NULL;
AcDbArc *pArc = NULL;
AcDbSolid *pSolid = NULL;
TDbWall *pWall = NULL;
XCurveSegment seg;
if(pCir = AcDbCircle::cast(pEnt)){
AcGePoint3d ptIns = pCir->center();
ptIns = ptIns.transformBy(myBlock.GetMatrix3d());
XCircle cir(asDblArray(ptIns), pCir->radius()*xscale);
seg = cir;
if(IsPtOnCircle(ptPick, cir, 25)){
pEnt->close();
return seg;
}
}
else if(pSolid = AcDbSolid::cast(pEnt)){
AcGePoint3d p1, p2, p3, p4;
pSolid->getPointAt(0, p1);
pSolid->getPointAt(1, p2);
pSolid->getPointAt(2, p3);
pSolid->getPointAt(3, p4);
p1 = p1.transformBy(myBlock.GetMatrix3d());
p2 = p2.transformBy(myBlock.GetMatrix3d());
p3 = p3.transformBy(myBlock.GetMatrix3d());
p4 = p4.transformBy(myBlock.GetMatrix3d());
XLine l1(asDblArray(p1), asDblArray(p2), 1);
XLine l2(asDblArray(p2), asDblArray(p4), 1);
XLine l3(asDblArray(p3), asDblArray(p4), 1);
XLine l4(asDblArray(p3), asDblArray(p1), 1);
if(IsPtOnLine(ptPick, l1, 25)){
pEnt->close();
seg = l1;
return seg;
}
if(IsPtOnLine(ptPick, l2, 25)){
pEnt->close();
seg = l2;
return seg;
}
if(IsPtOnLine(ptPick, l3, 25)){
pEnt->close();
seg = l3;
return seg;
}
if(IsPtOnLine(ptPick, l4, 25)){
pEnt->close();
seg = l4;
return seg;
}
}
else if(pPoly = AcDbPolyline::cast(pEnt)){
XPoly2D poly;
PolyConvert(*pPoly, poly);
poly.TransformBy(myBlock.GetMatrix3d());
double n;
seg = GetSegByPt(poly, ptPick, n);
if(!!seg)
return seg;
}
else if(pLine = AcDbLine::cast(pEnt)){
AcGePoint3d ptStart = pLine->startPoint();
ptStart = ptStart.transformBy(myBlock.GetMatrix3d());
AcGePoint3d ptEnd = pLine->endPoint();
ptEnd = ptEnd.transformBy(myBlock.GetMatrix3d());
XLine line(asDblArray(ptStart), asDblArray(ptEnd), 1);
seg = line;
if(IsPtOnLine(ptPick, line, 25)){
pEnt->close();
return seg;
}
}
else if(pArc = AcDbArc::cast(pEnt)){
AcGePoint3d ptIns = pArc->center();
ptIns = ptIns.transformBy(myBlock.GetMatrix3d());
XArc arc(asDblArray(ptIns), pArc->radius()*xscale, pArc->startAngle(), pArc->endAngle());
seg = arc;
if(IsPtOnArc(ptPick, arc, 25)){
pEnt->close();
return seg;
}
}
else if(pWall = TDbWall::cast(pEnt)){ //特别支持5。0墙体
XCurveSegment lCurve, rCurve;
pWall->GetSideCurve(lCurve, rCurve);
if(lCurve.Is(CURVE_LINE)){
AcGePoint3d ptStart = lCurve.StartPoint();
ptStart = ptStart.transformBy(myBlock.GetMatrix3d());
AcGePoint3d ptEnd = lCurve.EndPoint();
ptEnd = ptEnd.transformBy(myBlock.GetMatrix3d());
XLine line(asDblArray(ptStart), asDblArray(ptEnd), 1);
seg = line;
if(IsPtOnLine(ptPick, line, 25)){
pEnt->close();
return seg;
}
}
if(rCurve.Is(CURVE_LINE)){
AcGePoint3d ptStart = rCurve.StartPoint();
ptStart = ptStart.transformBy(myBlock.GetMatrix3d());
AcGePoint3d ptEnd = rCurve.EndPoint();
ptEnd = ptEnd.transformBy(myBlock.GetMatrix3d());
XLine line(asDblArray(ptStart), asDblArray(ptEnd), 1);
seg = line;
if(IsPtOnLine(ptPick, line, 25)){
pEnt->close();
return seg;
}
}
if(lCurve.Is(CURVE_ARC)){
XArc arcTmp = lCurve.GetArc();
AcGePoint3d ptIns = arcTmp.GetCenterPt();
ptIns = ptIns.transformBy(myBlock.GetMatrix3d());
XArc arc(asDblArray(ptIns), arcTmp.GetRadius()*xscale, arcTmp.GetStarAngle(), arcTmp.GetEndAngle());
seg = arc;
if(IsPtOnArc(ptPick, arc, 25)){
pEnt->close();
return seg;
}
}
if(rCurve.Is(CURVE_ARC)){
XArc arcTmp = rCurve.GetArc();
AcGePoint3d ptIns = arcTmp.GetCenterPt();
ptIns = ptIns.transformBy(myBlock.GetMatrix3d());
XArc arc(asDblArray(ptIns), arcTmp.GetRadius()*xscale, arcTmp.GetStarAngle(), arcTmp.GetEndAngle());
seg = arc;
if(IsPtOnArc(ptPick, arc, 25)){
pEnt->close();
return seg;
}
}
}
pEnt->close();
}
return XCurveSegment();
}
BOOL SetLayerLocked(const TCHAR* szLayerName, BOOL bLock)
{
AcDbLayerTable *pLayertable = NULL;
AcDbLayerTableRecord *pLayerRec = NULL;
acdbCurDwg()->getLayerTable(pLayertable, AcDb::kForRead);
if(!pLayertable)
return FALSE;
if((pLayertable->getAt(szLayerName, pLayerRec, AcDb::kForWrite)) == Acad::eOk) {
if(bLock)
pLayerRec->setIsLocked(true); // 打开
else
pLayerRec->setIsLocked(false); // 关
pLayerRec->close();
pLayertable->close();
}
else
pLayertable->close();
return TRUE;
}
BOOL SetLayer0UnLocked()
{
AcDbLayerTable *pLayertable = NULL;
AcDbLayerTableRecord *pLayerRec = NULL;
acdbCurDwg()->getLayerTable(pLayertable, AcDb::kForRead);
if(!pLayertable)
return FALSE;
if((pLayertable->getAt(_T("0"), pLayerRec, AcDb::kForRead)) == Acad::eOk) {
if(pLayerRec->isLocked() && pLayerRec->upgradeOpen()==Acad::eOk) {
pLayerRec->setIsLocked(false); // 关
pLayerRec->downgradeOpen();
}
pLayerRec->close();
}
pLayertable->close();
return TRUE;
}
void SetBlkAttrText(Entity entBlk, const TCHAR*szText, const TCHAR*szTag, double nHeight, BOOL bVisible, BOOL bDown)
{
SetLayer0UnLocked();
AcDbBlockReference *pBlockRef = NULL;// 定义块表指针
AcDbObjectId eId;
acdbGetObjectId(eId, entBlk);
acdbOpenObject(pBlockRef, eId, AcDb::kForRead);
if(!pBlockRef)
return;
AcDbObjectIterator *pIterator;
pIterator = pBlockRef -> attributeIterator();
for (pIterator -> start(); !pIterator -> done(); pIterator -> step())
{
//遍历块中实体
AcDbObjectId att_id;
att_id = pIterator -> objectId();
AcDbEntity *pEnt;
AcDbAttribute *pAtt;
acdbOpenAcDbEntity(pEnt, att_id, AcDb::kForWrite);
pAtt = AcDbAttribute::cast(pEnt);
if(pAtt != NULL)
{
TCHAR *cname = pAtt->tag();//得到标记
if(_tcsicmp(cname, szTag) == 0){
if(!bVisible)
pAtt->setInvisible(Adesk::kTrue);
else{
pAtt->setTextString(szText);
pAtt->setHeight(nHeight*DocGetPScale());
pAtt->setInvisible(Adesk::kFalse);
if(bDown){
pAtt->setHorizontalMode(AcDb::kTextLeft);
pAtt->setVerticalMode(AcDb::kTextTop);
}
}
}
delete[] cname;
}
pEnt->close();
}
delete pIterator;
pBlockRef->close();
}
int GetLayerColorByDwg(const TCHAR*szLayer)
{
int iRet = -1;
AcDbObjectId idLayer = GetLayerIdFromString(szLayer);
OPENOBJ_BEGIN(idLayer, AcDb::kForRead, AcDbLayerTableRecord, pLayer);
if(pLayer) {
AcCmColor color = pLayer->color();
iRet = color.colorIndex();
}
OPENOBJ_END();
return iRet;
}
void FilletEntity(Entity ent1, Entity ent2, double nRad)
{
XPushVar<int> FilletRad(_T("FilletRad"), (int)nRad);
XLine l1(ent1, 1);
XLine l2(ent2, 1);
XPoint ptMid1, ptMid2;
l1.MidPoint(ptMid1);
l2.MidPoint(ptMid2);
ptMid1 = Wcs2Ucs(ptMid1);
ptMid2 = Wcs2Ucs(ptMid2);
ads_command(RTSTR,_T("FILLET"),
RTLB,RTENAME,(TLong_ptr *)ent1, RT3DPOINT, &ptMid1, RTLE,
RTLB,RTENAME,(TLong_ptr *)ent2, RT3DPOINT, &ptMid2, RTLE, RTNONE);
}
// 2008-6-27 sr 改采用acedNEntSelP的方法,支持嵌套参考
XCurveSegment GetBlkPickSegment(Entity entBlk, XPoint ptPick)
{
XCurveSegment seg;
ads_name ename;
ads_matrix adsmat;
struct resbuf *insStack;
if (acedNEntSelP(NULL, ename, ptPick, TRUE,
adsmat, &insStack) != RTNORM)
{
ads_printf(_T("\nFailure in ads_nentselp"));
return seg;
}
ads_relrb(insStack);
Entity entTemp = ename;
if(entTemp.Is(_T("LINE")) || entTemp.Is(_T("ARC"))){
XCurveSegment seg1(entTemp);
seg1.TransformBy(adsmat);
seg = seg1;
}
else if(entTemp.Is(_T("LWPOLYLINE"))){
double dAngle;
XPoly2D poly(entTemp);
poly.TransformBy(AsAcGeMatrix3d(adsmat));
//poly.Make();
seg = GetSegByPt(poly, ptPick, dAngle);
}
else if(entTemp.Is(_T("ATS_WALL"))){
OPENOBJ_BEGIN(entTemp, AcDb::kForRead, TDbWall, pWall);
XCurveSegment lCurve, rCurve;
XPoint ptNew1, ptNew2;
if(pWall) {
pWall->GetSideCurve(lCurve, rCurve);
lCurve.TransformBy(adsmat);
rCurve.TransformBy(adsmat);
seg = lCurve;
}
OPENOBJ_END();
}
else{
OPENOBJ_BEGIN(ename, AcDb::kForRead, AcDbEntity, pEnt);
if(pEnt != NULL){
ads_printf(_T("\n无法识别: %s"), pEnt->isA()->name());
}
OPENOBJ_END();
}
return seg;
}
/*
XCurveSegment GetBlkPickSegment(Entity entBlk, XPoint ptPick)
{
//第一步,得到块参考矩阵
AcDbBlockReference *pBlkRef = NULL;
AcDbObjectId id = NULL;
acdbGetObjectId(id, entBlk);
acdbOpenObject(pBlkRef, id, AcDb::kForRead);
if(!pBlkRef)
return XCurveSegment();
AcGeMatrix3d mat = pBlkRef->blockTransform();
if(pBlkRef)
pBlkRef->close();
double xscale;
entBlk.GetData(41, &xscale);
xscale = fabs(xscale);
//第二步,得到块记录遍历器
TCHAR szBlkName[256];
entBlk.GetData(2, szBlkName);
AcDbBlockTable* pBlockTable = NULL;
AcDbBlockTableRecord *pRecord = NULL;
acdbCurDwg()->getBlockTable(pBlockTable, AcDb::kForRead);
if(Acad::eOk != pBlockTable->getAt(szBlkName, pRecord, AcDb::kForRead))
return XCurveSegment();
pBlockTable->close();
if(pRecord->isFromExternalReference() == true){
XPoint ptOrigin = pRecord->origin();
AcGeMatrix3d mat2;
mat2.setToTranslation(AcGeVector3d(-ptOrigin[0], -ptOrigin[1], -ptOrigin[2]));
mat *= mat2;
}
AcDbBlockTableRecordIterator *pIterator = NULL;
pRecord->newIterator(pIterator);
if(pRecord)
pRecord->close();
for(pIterator->start(); !pIterator->done(); pIterator->step()){
AcDbEntity *pEnt;
pIterator->getEntity(pEnt, AcDb::kForRead);
AcDbCircle *pCir = NULL;
AcDbLine *pLine = NULL;
AcDbPolyline *pPoly = NULL;
AcDbArc *pArc = NULL;
AcDbSolid *pSolid = NULL;
TDbWall *pWall = NULL;
XCurveSegment seg;
if(pCir = AcDbCircle::cast(pEnt)){
AcGePoint3d ptIns = pCir->center();
ptIns = ptIns.transformBy(mat);
XCircle cir(asDblArray(ptIns), pCir->radius()*xscale);
seg = cir;
if(IsPtOnCircle(ptPick, cir, 500/20)){
pEnt->close();
return seg;
}
}
else if(pSolid = AcDbSolid::cast(pEnt)){
AcGePoint3d p1, p2, p3, p4;
pSolid->getPointAt(0, p1);
pSolid->getPointAt(1, p2);
pSolid->getPointAt(2, p3);
pSolid->getPointAt(3, p4);
p1 = p1.transformBy(mat);
p2 = p2.transformBy(mat);
p3 = p3.transformBy(mat);
p4 = p4.transformBy(mat);
XLine l1(asDblArray(p1), asDblArray(p2), 1);
XLine l2(asDblArray(p2), asDblArray(p4), 1);
XLine l3(asDblArray(p3), asDblArray(p4), 1);
XLine l4(asDblArray(p3), asDblArray(p1), 1);
if(IsPtOnLine(ptPick, l1, 25)){
pEnt->close();
seg = l1;
return seg;
}
if(IsPtOnLine(ptPick, l2, 25)){
pEnt->close();
seg = l2;
return seg;
}
if(IsPtOnLine(ptPick, l3, 25)){
pEnt->close();
seg = l3;
return seg;
}
if(IsPtOnLine(ptPick, l4, 25)){
pEnt->close();
seg = l4;
return seg;
}
}
else if(pPoly = AcDbPolyline::cast(pEnt)){
XPoly2D poly;
PolyConvert(*pPoly, poly);
poly.TransformBy(mat);
double n;
seg = GetSegByPt(poly, ptPick, n);
if(!!seg)
return seg;
}
else if(pLine = AcDbLine::cast(pEnt)){
AcGePoint3d ptStart = pLine->StartPoint()();
ptStart = ptStart.transformBy(mat);
AcGePoint3d ptEnd = pLine->EndPoint()();
ptEnd = ptEnd.transformBy(mat);
XLine line(asDblArray(ptStart), asDblArray(ptEnd), 1);
seg = line;
if(IsPtOnLine(ptPick, line, 500/20)){
pEnt->close();
return seg;
}
}
else if(pArc = AcDbArc::cast(pEnt)){
AcGePoint3d ptIns = pArc->center();
ptIns = ptIns.transformBy(mat);
XArc arc(asDblArray(ptIns), pArc->radius()*xscale, pArc->startAngle(), pArc->endAngle());
seg = arc;
if(IsPtOnArc(ptPick, arc, 500/20)){
pEnt->close();
return seg;
}
}
else if(pWall = TDbWall::cast(pEnt)){ //特别支持5。0墙体
XCurveSegment lCurve, rCurve;
pWall->GetSideCurve(lCurve, rCurve);
if(lCurve.Is(CURVE_LINE)){
AcGePoint3d ptStart = lCurve.StartPoint();
ptStart = ptStart.transformBy(mat);
AcGePoint3d ptEnd = lCurve.EndPoint();
ptEnd = ptEnd.transformBy(mat);
XLine line(asDblArray(ptStart), asDblArray(ptEnd), 1);
seg = line;
if(IsPtOnLine(ptPick, line, 500/20)){
pEnt->close();
return seg;
}
}
if(rCurve.Is(CURVE_LINE)){
AcGePoint3d ptStart = rCurve.StartPoint();
ptStart = ptStart.transformBy(mat);
AcGePoint3d ptEnd = rCurve.EndPoint();
ptEnd = ptEnd.transformBy(mat);
XLine line(asDblArray(ptStart), asDblArray(ptEnd), 1);
seg = line;
if(IsPtOnLine(ptPick, line, 500/20)){
pEnt->close();
return seg;
}
}
if(lCurve.Is(CURVE_ARC)){
XArc arcTmp = lCurve.GetArc();
AcGePoint3d ptIns = arcTmp.center;
ptIns = ptIns.transformBy(mat);
XArc arc(asDblArray(ptIns), arcTmp.radius*xscale, arcTmp.startAngle, arcTmp.endAngle);
seg = arc;
if(IsPtOnArc(ptPick, arc, 500/20)){
pEnt->close();
return seg;
}
}
if(rCurve.Is(CURVE_ARC)){
XArc arcTmp = rCurve.GetArc();
AcGePoint3d ptIns = arcTmp.center;
ptIns = ptIns.transformBy(mat);
XArc arc(asDblArray(ptIns), arcTmp.radius*xscale, arcTmp.startAngle, arcTmp.endAngle);
seg = arc;
if(IsPtOnArc(ptPick, arc, 500/20)){
pEnt->close();
return seg;
}
}
}
pEnt->close();
}
if(pIterator)
delete pIterator;
return XCurveSegment();
}
*/
int get_line_angle(ads_real& line_angle)//得到直线的角度
{
int iLineType = 0;
RBList rbMask = ads_buildlist( -4, _T("<or"),
-4, _T("<and"), RTDXF0, _T("LINE"), 8, _T("*"), -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("LWPOLYLINE"), 8, _T("*"), -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("INSERT"), 8, _T("*"), -4, _T("and>"),
-4, _T("<and"), RTDXF0, _T("ATS_WALL"), -4, _T("and>"),
-4, _T("or>"), NULL);
XPoint ptPick;
Entity entWall;
if(SelectEntity1(_T("\n从当前图中选取行向线<不选取>:"), entWall, ptPick, rbMask) != RTNORM)
return RTNORM;
XCurveSegment lCurve, rCurve, SelCurve;
BOOL bIsLeft = TRUE;
if(entWall.Is(_T("INSERT"))){
SelCurve = GetBlkPickSegment(entWall, ptPick);
if(!SelCurve)
return 0;
iLineType = 0;
}
else if(entWall.Is(_T("LWPOLYLINE"))){
double dAngle;
XPoint ptWcs = Ucs2Wcs(ptPick);
SelCurve = GetSegByPt(XPoly2D(entWall), ptWcs, dAngle);
if(!SelCurve)
return 0;
iLineType = 0;
}
else if(entWall.Is(_T("ATS_WALL"))){
OPENOBJ_BEGIN(entWall, AcDb::kForRead, TDbWall, pWall);
XPoint ptNew1, ptNew2;
if(pWall) {
pWall->GetSideCurve(lCurve, rCurve);
lCurve.ProjectToMe(ptPick, ptNew1);
rCurve.ProjectToMe(ptPick, ptNew2);
if(ads_distance(ptPick, ptNew1) < ads_distance(ptPick, ptNew2)){
SelCurve = lCurve;
bIsLeft = TRUE;
}
else{
SelCurve = rCurve;
bIsLeft = FALSE;
}
}
OPENOBJ_END();
}
else
iLineType = 1;
if(!SelCurve.Is(CURVE_LINE))
return RTCAN;
if(iLineType == 0){
XLine line = SelCurve.GetLine();
//得到直线的角度
line_angle=ads_angle(line.StartPoint(),line.EndPoint());
if(line_angle > PI)
line_angle = line_angle - PI;
}
else if(iLineType == 1){
XPoint ptStart, ptEnd;
entWall.GetData(10, ptStart);
entWall.GetData(11, ptEnd);
line_angle=ads_angle(ptStart, ptEnd);
if(line_angle > PI)
line_angle = line_angle - PI;
}
return RTNORM;
}
AcDbObjectId InitDoteLayer(const TCHAR* szLay)
{
AcDbObjectId idLay=GetLayerIdFromString(szLay);
if(!!idLay)
return idLay;
AcDbObjectId id = InitLayer(szLay);
AddLineType(_T("CENTER2"));
AcDbLinetypeTable *pLinetypeTbl;
AcDbObjectId ltId;
Acad::ErrorStatus es = acdbCurDwg()->getLinetypeTable(pLinetypeTbl, AcDb::kForRead);
if(es != Acad::eOk) {
return NULL;
}
if((pLinetypeTbl->getAt(_T("CENTER2"), ltId)) != Acad::eOk){
pLinetypeTbl->close();
return NULL;
}
pLinetypeTbl->close();
OPENOBJ_BEGIN(id, AcDb::kForWrite, AcDbLayerTableRecord, pRec);
if(pRec){
pRec->setLinetypeObjectId(ltId);
}
OPENOBJ_END();
return id;
}
AcDbObjectId InitGridLayer(const TCHAR* szLay)
{
AcDbObjectId idLay=GetLayerIdFromString(szLay);
if(!!idLay)
return idLay;
AcDbObjectId id = InitLayer(szLay);
AddLineType(_T("DOT"));
AcDbLinetypeTable *pLinetypeTbl;
AcDbObjectId ltId;
Acad::ErrorStatus es = acdbCurDwg()->getLinetypeTable(pLinetypeTbl, AcDb::kForRead);
if(es != Acad::eOk) {
return NULL;
}
if((pLinetypeTbl->getAt(_T("DOT"), ltId)) != Acad::eOk){
pLinetypeTbl->close();
return NULL;
}
pLinetypeTbl->close();
OPENOBJ_BEGIN(id, AcDb::kForWrite, AcDbLayerTableRecord, pRec);
if(pRec){
pRec->setLinetypeObjectId(ltId);
}
OPENOBJ_END();
return id;
}
AcDbObjectId InitDashLayer(const TCHAR* szLay)
{
AcDbObjectId idLay=GetLayerIdFromString(szLay);
if(!!idLay)
return idLay;
AcDbObjectId id = InitLayer(szLay);
AddLineType(_T("DASH"));
AcDbLinetypeTable *pLinetypeTbl;
AcDbObjectId ltId;
Acad::ErrorStatus es = acdbCurDwg()->getLinetypeTable(pLinetypeTbl, AcDb::kForRead);
if(es != Acad::eOk) {
return NULL;
}
if((pLinetypeTbl->getAt(_T("DASH"), ltId)) != Acad::eOk){
pLinetypeTbl->close();
return NULL;
}
pLinetypeTbl->close();
OPENOBJ_BEGIN(id, AcDb::kForWrite, AcDbLayerTableRecord, pRec);
if(pRec){
pRec->setLinetypeObjectId(ltId);
}
OPENOBJ_END();
return id;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//以下是李夫银的AcGePoint3dArray排序函数
typedef struct PtOnCrItem
{
AcGePoint3d m_ptGeOld;
AcGePoint3d m_ptGeOn;
AcDbCurve * m_pCurve;
AcDbObjectId m_ID;
} PTONCRITEM,* PPTONCRITEM;
//回调函数
static bool GreaterCoord(PTONCRITEM item1,PTONCRITEM item2)
{
AcDbCurve * pCurve = item1.m_pCurve;
AcGePoint3d ptGe1 = item1.m_ptGeOn;
AcGePoint3d ptGe2 = item2.m_ptGeOn;
double dDis1 = 0.0,dDis2 = 0.0;
pCurve->getParamAtPoint(ptGe1,dDis1);
pCurve->getParamAtPoint(ptGe2,dDis2);
if(dDis1 - dDis2 > 0.000001)
{
return false;//up sort
}
return true;//down sort
}
void SortPoints(AcGePoint3dArray& points, AcDbCurve * pCurve, BOOL bModifyArray)
{
PTONCRITEM ptOnCrItem;
typedef std::vector<PTONCRITEM> PtOnCrItemVector;
// PtOnCrItemVector::_Tptr p_ptr = (PTONCRITEM *)0;
// PtOnCrItemVector::_Ctptr p_cptr = (const PTONCRITEM *)0;
PtOnCrItemVector::reference p_ref = ptOnCrItem;
PtOnCrItemVector::const_reference p_cref = (const PTONCRITEM&) ptOnCrItem;
PtOnCrItemVector::value_type * p_val = (PTONCRITEM *)0;
PtOnCrItemVector::size_type * p_size = (size_t *)0;
PtOnCrItemVector::difference_type * p_diff = (ptrdiff_t *)0;
PtOnCrItemVector vectorItems;
ptOnCrItem.m_pCurve = pCurve;
AcGePoint3d ptGeT;
int nLength = points.length();
for(int i = 0;i < nLength;i++)
{
ptGeT = points.at(i);
ptOnCrItem.m_ptGeOld = ptGeT;
pCurve->getClosestPointTo(ptGeT,ptGeT);
ptOnCrItem.m_ptGeOn = ptGeT;
vectorItems.push_back(ptOnCrItem);
}
PtOnCrItemVector::iterator itHead = vectorItems.begin();
PtOnCrItemVector::iterator itTail = vectorItems.end();
std::sort(itHead,itTail,GreaterCoord);
itHead = vectorItems.begin();
itTail = vectorItems.end();
points.removeSubArray(0,nLength - 1);
AcGePoint3d ptGe;
for(;itHead != itTail;++itHead)
{
if(bModifyArray)
ptGe = (*itHead).m_ptGeOn;
else
ptGe = (*itHead).m_ptGeOld;
points.append(ptGe);
}
}
void DeleteRepeateWall(AcDbObjectIdArray * pIDWalls)
{
AcDbObjectIdArray idWalls;
AcDbObjectIdArray idErases;
AcDbObjectId id1,id2;
AcDbEntity * pEnt1 = NULL;
AcDbEntity * pEnt2 = NULL;
double dDis1 = 0.0,dDis2 = 0.0;
int nLen = pIDWalls->length();
for(int i = 0;i < nLen;i++)
{
id1 = pIDWalls->at(i);
if (Acad::eOk == acdbOpenAcDbEntity(pEnt1,id1,AcDb::kForRead))
{
for(int j = 0;j < nLen;j++)
{
id2 = pIDWalls->at(j);
if (id1 != id2)
{
if (Acad::eOk == acdbOpenAcDbEntity(pEnt2,id2,AcDb::kForRead))
{
if (pEnt1->isKindOf(pEnt2->desc()))
{
AcDbLine * pLine1 = AcDbLine::cast(pEnt1);
AcDbLine * pLine2 = AcDbLine::cast(pEnt2);
if (pLine1 != NULL && pLine2 != NULL)
{
AcGePoint3d ptGeSta1 = pLine1->startPoint();
AcGePoint3d ptGeEnd1 = pLine1->endPoint();
AcGePoint3d ptGeSta2 = pLine2->startPoint();
AcGePoint3d ptGeEnd2 = pLine2->endPoint();
AcGeVector3d vc1 = ptGeEnd1 - ptGeSta1;
AcGeVector3d vc2 = ptGeEnd2 - ptGeSta2;
if (vc1.isParallelTo(vc2))
{
AcDbXline xline;
xline.setUnitDir(vc1);
xline.setBasePoint(ptGeEnd1);
AcGePoint3d ptGe;
xline.getClosestPointTo(ptGeEnd2,ptGe);
double dDis1 = ptGe.distanceTo(ptGeEnd2);
if (dDis1 < E6TOL)
{
dDis1 = ptGeEnd1.distanceTo(ptGeSta1);
dDis2 = ptGeEnd2.distanceTo(ptGeSta2);
AcGePoint3dArray ptS;
ptS.append(ptGeSta1);
ptS.append(ptGeEnd1);
ptS.append(ptGeSta2);
ptS.append(ptGeEnd2);
SortPoints(ptS,&xline,TRUE);
double dDis3 = ptS.first().distanceTo(ptS.last());
if (dDis1 + dDis2 - dDis3 > E6TOL)
{
if (dDis1 - dDis2 < E6TOL)
{
pLine1->upgradeOpen();
pLine1->erase();
pLine1->downgradeOpen();
idErases.append(id1);
}
else
{
pLine2->upgradeOpen();
pLine2->erase();
pLine2->downgradeOpen();
idErases.append(id2);
}
}
}
}
}
AcDbBlockReference * pBlk1 = AcDbBlockReference::cast(pEnt1);
AcDbBlockReference * pBlk2 = AcDbBlockReference::cast(pEnt2);
if (pBlk1 != NULL && pBlk2 != NULL)
{
AcGePoint3d ptLoc1 = pBlk1->position();
AcGePoint3d ptLoc2 = pBlk2->position();
AcDbObjectId id1 = pBlk1->blockTableRecord();
AcDbObjectId id2 = pBlk2->blockTableRecord();
double dDis1 = ptLoc1.distanceTo(ptLoc2);
if (dDis1 < E6TOL)
{
pBlk1->upgradeOpen();
pBlk1->erase();
pBlk1->downgradeOpen();
idErases.append(id1);
}
}
}
pEnt2->close();
}
}
}
pEnt1->close();
}
}
nLen = idErases.length();
for(i = 0;i < nLen;i++)
{
pIDWalls->remove(idErases.at(i));
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// OFFSET 2008-1-28 沈睿
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//已知1线段,和偏移距离,和线上1点, 返回偏移后的线段
// 注意:调用者自己必须释放返回的AcDbCurve
AcDbCurve* GetOffsetCurve(AcDbCurve *pCurve, double dOffsetDist, XPoint ptPick)
{
if(pCurve == NULL)
return NULL;
//先OFFSET一根曲线过来
AcDbVoidPtrArray arCurves;
pCurve->getOffsetCurves(dOffsetDist, arCurves);
int len = arCurves.length();
if(arCurves.length() > 0){
AcDbCurve *pCurve2;
pCurve2 = (AcDbCurve *)arCurves.first();
XPoint ptOnCurve;
pCurve2->getClosestPointTo(ptPick, ptOnCurve);
double dDist = ads_distance(ptPick, ptOnCurve);
long lNum=arCurves.length();
for(long j=1L; j<lNum; j++) { //必须全部释放
AcDbEntity *pEnt=(AcDbEntity *)arCurves[j];
delete pEnt;
}
if(dDist < 0.001)//通过偏移距离的正负可以得到2根线段,ptPick在哪上就返回哪根
return pCurve2;
else{
delete pCurve2;
AcDbVoidPtrArray arCurves2;
pCurve->getOffsetCurves(-dOffsetDist, arCurves2);
if(arCurves2.length() > 0){
AcDbCurve *pCurve3;
pCurve3 = (AcDbCurve *)arCurves2.first();
long lNum2=arCurves2.length();
for(j=1L; j<lNum2; j++) {//必须全部释放
AcDbEntity *pEnt2=(AcDbEntity *)arCurves2[j];
delete pEnt2;
}
return pCurve3;
}
}
}
return NULL;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 沿线得到PLINE 2008-1-28 沈睿
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct {
XPoint pt;
double dBulge;
}XLinePointAndBulge;
void MakeSimplePloyLine(XCurveSegment seg1, XCurveSegment seg2, XPoint ptPick, XPoint ptPick2,XLinePointAndBulge &linePt1,XLinePointAndBulge &linePt2,XLinePointAndBulge &linePt3,XPoint ptTurn)
{
//判断选中的实体是圆弧还是线
if(seg1.GetCurveType() == CURVE_LINE && seg2.GetCurveType() == CURVE_LINE){
linePt1.pt = ptPick;
linePt2.pt = ptTurn;
linePt3.pt = ptPick2;
linePt1.dBulge = 0;
linePt2.dBulge = 0;
linePt3.dBulge = 0;
}
else if(seg1.GetCurveType() == CURVE_LINE && seg2.GetCurveType() == CURVE_ARC){
XArc arc = seg2.GetArc();
AcGeVector3d vt1(ptPick2-arc.GetCenterPt());
AcGeVector3d vt2(ptTurn-arc.GetCenterPt());
double dAngle = vt1.angleTo(vt2);
double dBulge = tan(0.25 * dAngle);
// 要确定Bulge的正,负。 如果ptTurn点是弧起点,Bulge为正
XPoint ptS, ptE;
arc.GetStartPoint(ptS);
arc.GetEndPoint(ptE);
// arc.GetPoints(ptS, ptE);
if(ptTurn == ptS)
dBulge = fabs(dBulge);
else
dBulge = -fabs(dBulge);
linePt1.pt = ptPick;
linePt2.pt = ptTurn;
linePt3.pt = ptPick2;
linePt1.dBulge = 0;
linePt2.dBulge = dBulge;
linePt3.dBulge = 0;
}
else if(seg2.GetCurveType() == CURVE_LINE && seg1.GetCurveType() == CURVE_ARC){
XArc arc = seg1.GetArc();
AcGeVector3d vt1(ptTurn-arc.GetCenterPt());
AcGeVector3d vt2(ptPick-arc.GetCenterPt());
double dAngle = vt1.angleTo(vt2);
double dBulge = tan(0.25 * dAngle);
XPoint ptS, ptE;
arc.GetStartPoint(ptS);
arc.GetEndPoint(ptE);
// arc.GetPoints(ptS, ptE);
if(ptTurn == ptS)
dBulge = -fabs(dBulge);
else
dBulge = fabs(dBulge);
linePt1.pt = ptPick;
linePt2.pt = ptTurn;
linePt3.pt = ptPick2;
linePt1.dBulge = dBulge;
linePt2.dBulge = 0;
linePt3.dBulge = 0;
}
else if(seg1.GetCurveType() == CURVE_ARC && seg2.GetCurveType() == CURVE_ARC){
XArc arc = seg1.GetArc();
AcGeVector3d vt1(ptTurn-arc.GetCenterPt());
AcGeVector3d vt2(ptPick-arc.GetCenterPt());
double dAngle1 = vt1.angleTo(vt2);
double dBulge1 = tan(0.25 * dAngle1);
XPoint ptS, ptE;
arc.GetStartPoint(ptS);
arc.GetEndPoint(ptE);
// arc.GetPoints(ptS, ptE);
if(ptTurn == ptS)
dBulge1 = -fabs(dBulge1);
else
dBulge1 = fabs(dBulge1);
XArc arc2 = seg2.GetArc();
AcGeVector3d vt3(ptPick2-arc2.GetCenterPt());
AcGeVector3d vt4(ptTurn-arc2.GetCenterPt());
double dAngle2 = vt3.angleTo(vt4);
double dBulge2 = tan(0.25 * dAngle2);
arc2.GetStartPoint(ptS);
arc2.GetEndPoint(ptE);
//arc2.GetPoints(ptS, ptE);
if(ptTurn == ptS)
dBulge2 = fabs(dBulge2);
else
dBulge2 = -fabs(dBulge2);
linePt1.pt = ptPick;
linePt2.pt = ptTurn;
linePt3.pt = ptPick2;
linePt1.dBulge = dBulge1;
linePt2.dBulge = dBulge2;
linePt3.dBulge = 0;
}
}
// 保存PLOYLINE的3点(临时起点 转折点 临时终点)
// 输入ent ent2 ptPick ptPick2
// 输出 linePt1 linePt2 linePt3
// 注意: ent ent2 只能是LINE 或者 ARC
void MakeSimplePloyLine(Entity ent, Entity ent2, XPoint ptPick, XPoint ptPick2,XLinePointAndBulge &linePt1,XLinePointAndBulge &linePt2,XLinePointAndBulge &linePt3,XPoint ptTurn)
{
XCurveSegment seg1(ent);
XCurveSegment seg2(ent2);
MakeSimplePloyLine(seg1, seg2, ptPick, ptPick2, linePt1, linePt2, linePt3, ptTurn);
}
#if ADS <= 17
struct CurveNode
{
XCurveSegment seg;
Entity ent;
AcGeMatrix3d mat;
};
#endif
// 生成POLYLINE
// 输入 ent ent2 ptPick ptPick2 ptFrom 选中的实体和选中的两点 以及寻找的初始点
// 输出 pLine 生成所需要的PLINE线, pline是由调用者new出来的
// 注意: ent ent2 只能是LINE 或者 ARC
BOOL MakeRightPloyLine(AcDbPolyline *pLine,Entity ent, Entity ent2, XPoint ptPick, XPoint ptPick2,XPoint ptFrom)
{
XCurveSegment seg(ent);
XCurveSegment seg2(ent2);
// cet 2016.7.20 add 支持外部参照
AcGeMatrix3d mat1 = GetExternalEntityTransform(ent);
AcGeMatrix3d mat2 = GetExternalEntityTransform(ent2);
ads_matrix matTemp;
memcpy(matTemp, &mat1, sizeof(AcGeMatrix3d));
seg.TransformBy(matTemp);
memcpy(matTemp, &mat2, sizeof(AcGeMatrix3d));
seg2.TransformBy(matTemp);
XLinePointAndBulge linePt1,linePt2,linePt3;//画PLINE线经过的3点
//存放点的容器
std::vector<XLinePointAndBulge> vecPt;
typedef std::vector<XLinePointAndBulge>::iterator iter;
XPoint ptTemp1,ptTemp2;//取两点十字集范围内实体的两个点
XPoint ptPLineStart, ptPLineEnd, ptPLineTurn;//相邻线的起点 拐点 终点
ptPLineStart = ptPick;
Entity entFirst = ent, entNext; //相邻两个实体
//不断的循环查找下一相邻实体
//seg变化 seg2不变化
ptPLineTurn = ptFrom;
// cet 2016.7.20 add 支持外部参照
#if ADS > 17
struct CurveNode
{
XCurveSegment seg;
Entity ent;
AcGeMatrix3d mat;
};
#endif
std::vector<CurveNode> vecCurve;
AcDbBlockTable *pTbl = NULL;
acdbCurDwg()->getBlockTable(pTbl, AcDb::kForRead);
if (pTbl != NULL)
{
AcDbBlockTableIterator *it = NULL;
pTbl->newIterator(it);
for (it->start(); !it->done(); it->step())
{
AcDbBlockTableRecord *pRcd = NULL;
it->getRecord(pRcd, AcDb::kForRead);
if (pRcd != NULL && pRcd->isFromExternalReference())
{
AcGeMatrix3d mat = AcGeMatrix3d::kIdentity;
AcDbObjectIdArray arrId;
pRcd->getBlockReferenceIds(arrId);
if (arrId.length() != 1)
{
pRcd->close();
continue;
}
AcDbBlockReference *pRef = NULL;
acdbOpenObject(pRef, arrId[0], AcDb::kForRead);
if (pRef != NULL)
{
mat = pRef->blockTransform();
pRef->close();
}
else
{
pRcd->close();
continue;
}
ads_matrix matTemp;
memcpy(matTemp, &mat, sizeof(AcGeMatrix3d));
AcDbBlockTableRecordIterator *itRec = NULL;
pRcd->newIterator(itRec);
for (itRec->start(); !itRec->done(); itRec->step())
{
AcDbEntity *pEnt = NULL;
itRec->getEntity(pEnt, AcDb::kForRead);
if (pEnt != NULL)
{
if (pEnt->isKindOf(AcDbLine::desc()))
{
AcDbLine *pLine = (AcDbLine*)pEnt;
AcGePoint3d pt1, pt2;
pLine->getStartPoint(pt1);
pLine->getEndPoint(pt2);
XCurveSegment seg;
seg.SetLine(pt1, pt2);
seg.TransformBy(matTemp);
ads_name name;
acdbGetAdsName(name, pEnt->objectId());
CurveNode node;
node.seg = seg;
node.ent = Entity(name);
node.mat = mat;
vecCurve.push_back(node);
}
else if (pEnt->isKindOf(AcDbArc::desc()))
{
AcDbArc *pArc = (AcDbArc*)pEnt;
XArc arc(XPoint(pArc->center()), pArc->radius(), pArc->startAngle(), pArc->endAngle());
arc.TransformBy(matTemp);
ads_name name;
acdbGetAdsName(name, pEnt->objectId());
CurveNode node;
node.seg = arc;
node.ent = Entity(name);
node.mat = mat;
vecCurve.push_back(node);
}
}
pEnt->close();
}
delete itRec;
}
pRcd->close();
}
delete it;
// 模型空间中的墙体
AcDbBlockTableRecord *pRcd = NULL;
pTbl->getAt(ACDB_MODEL_SPACE, pRcd, AcDb::kForRead);
if (pTbl != NULL)
{
AcGeMatrix3d mat = AcGeMatrix3d::kIdentity;
ads_matrix matTemp;
memcpy(matTemp, &mat, sizeof(AcGeMatrix3d));
AcDbBlockTableRecordIterator *itRec = NULL;
pRcd->newIterator(itRec);
for (itRec->start(); !itRec->done(); itRec->step())
{
AcDbEntity *pEnt = NULL;
itRec->getEntity(pEnt, AcDb::kForRead);
if (pEnt != NULL)
{
if (pEnt->isKindOf(AcDbLine::desc()))
{
AcDbLine *pLine = (AcDbLine*)pEnt;
AcGePoint3d pt1, pt2;
pLine->getStartPoint(pt1);
pLine->getEndPoint(pt2);
XCurveSegment seg;
seg.SetLine(pt1, pt2);
seg.TransformBy(matTemp);
ads_name name;
acdbGetAdsName(name, pEnt->objectId());
CurveNode node;
node.seg = seg;
node.ent = Entity(name);
node.mat = mat;
vecCurve.push_back(node);
}
else if (pEnt->isKindOf(AcDbArc::desc()))
{
AcDbArc *pArc = (AcDbArc*)pEnt;
XArc arc(XPoint(pArc->center()), pArc->radius(), pArc->startAngle(), pArc->endAngle());
arc.TransformBy(matTemp);
ads_name name;
acdbGetAdsName(name, pEnt->objectId());
CurveNode node;
node.seg = arc;
node.ent = Entity(name);
node.mat = mat;
vecCurve.push_back(node);
}
}
pEnt->close();
}
delete itRec;
pRcd->close();
}
pTbl->close();
}
//两个实体相邻则退出
while(seg.EndPoint().Distance(seg2.StartPoint()) > 0.001 && seg.StartPoint().Distance(seg2.EndPoint()) > 0.001
&& seg.EndPoint().Distance(seg2.EndPoint()) > 0.001 && seg.StartPoint().Distance(seg2.StartPoint()) > 0.001)
{
// cet 2016.7.20 modify 支持外部参照
// ptTemp1 = ptPLineTurn;
// ptTemp2 = ptPLineTurn;
// ptTemp1.x += 2;
// ptTemp1.y += 2;
// ptTemp2.x -= 2;
// ptTemp2.y -= 2;
// AssureInCurrentView(ptTemp1, ptTemp2);
// PickSet ssPoint(SS_FREE);
// ssPoint.Get(_T("C"),ptTemp1,ptTemp2, RBList(RTDXF0, _T("LINE,ARC"), NULL));
PickSet ssPoint(SS_FREE);
for (int i = 0; i < vecCurve.size(); ++i)
{
XCurveSegment &segTmp = vecCurve[i].seg;
XPoint pt;
ptPLineTurn.Project(&segTmp, pt);
if (pt.Distance2d(ptPLineTurn) < 0.001)
{
ssPoint += vecCurve[i].ent;
}
}
ssPoint -= entFirst;
if(ssPoint.Length() != 1)
return FALSE;
entNext = ssPoint[0L];
// if(ssPoint.Length() != 2)
// return FALSE;
// //去掉旧的实体 entNext 是循环的下1段线
// Entity entPointTemp1, entPointTemp2;
// entPointTemp1 = ssPoint[0L];
// entPointTemp2 = ssPoint[1L];
//
// if(entPointTemp1 == entFirst)
// entNext = entPointTemp2;
// else if(entPointTemp2 == entFirst)
// entNext = entPointTemp1;
XCurveSegment segNext(entNext);
// cet 2016.7.20 add 支持外部参照
AcGeMatrix3d mat = AcGeMatrix3d::kIdentity;
for (int i = 0; i < vecCurve.size(); ++i)
{
if (vecCurve[i].ent == entNext)
{
mat = vecCurve[i].mat;
break;
}
}
ads_matrix matTemp;
memcpy(matTemp, &mat, sizeof(AcGeMatrix3d));
segNext.TransformBy(matTemp);
seg = segNext; //下一个
if(segNext.StartPoint() == seg.StartPoint() || segNext.StartPoint() == seg.EndPoint())
ptPLineEnd = segNext.EndPoint();
else if(segNext.EndPoint() == seg.StartPoint() || segNext.EndPoint() == seg.EndPoint())
ptPLineEnd = segNext.StartPoint();
else
return FALSE;//确保前后2段线一定首尾相连
MakeSimplePloyLine(entFirst,entNext,ptPLineStart,ptPLineEnd,linePt1,linePt2,linePt3,ptPLineTurn);
//取下1段PLINE的拐点
if (segNext.StartPoint() != ptPLineTurn)
ptPLineTurn = segNext.StartPoint();
else
ptPLineTurn = segNext.EndPoint();
entFirst = entNext;
ptPLineStart = ptPLineEnd;
if (entFirst == ent)//找到自己则退出
return FALSE;
vecPt.push_back(linePt1);
vecPt.push_back(linePt2);
vecPt.push_back(linePt3);
}
MakeSimplePloyLine(entFirst,ent2,ptPLineStart,ptPick2,linePt1,linePt2,linePt3,ptPLineTurn);
vecPt.push_back(linePt1);
vecPt.push_back(linePt2);
vecPt.push_back(linePt3);
//生成PLINE线
for (int it = 0; it < vecPt.size(); ++it)
{
pLine->addVertexAt(it,vecPt[it].pt,vecPt[it].dBulge);
}
return TRUE;
}
// 已知一个曲线,并知道曲线上2点,求这2点围成的中间曲线
// 注意:返回的曲线必须调用者自己释放
AcDbCurve* GetCurveBy2Pt(AcDbCurve *pCurve, XPoint ptOnCurve1, XPoint ptOnCurve2)
{
AcDbVoidPtrArray arSeg;//裁剪后的曲线段
AcGePoint3dArray arPoint(2);//裁剪的点
double dDist1, dDist2;
pCurve->getDistAtPoint(ptOnCurve1, dDist1);
pCurve->getDistAtPoint(ptOnCurve2, dDist2);
if(dDist1 < dDist2){
arPoint.append(ptOnCurve1);
arPoint.append(ptOnCurve2);
}
else{
arPoint.append(ptOnCurve2);
arPoint.append(ptOnCurve1);
}
pCurve->getSplitCurves(arPoint,arSeg);//剪切PLINE线
int nLen = arSeg.length();
// cet 2014.12.1 modify 当点在曲线起始点时结果错误
// if(nLen != 3)
// {
// ReleaseEntSet(arSeg);
// return NULL;
// }
// AcDbCurve *pCurveRet = NULL;
// for (int i = 0; i < nLen; ++i)
// {
// AcDbCurve *pCurve3 = (AcDbCurve*)arSeg[i];
// if (pCurve3 != NULL)
// {
// if(i == 1)
// pCurveRet = pCurve3;
// else
// delete pCurve3;
// }
// }
AcGePoint3d ptS, ptE;
AcDbCurve *pCurveRet = NULL;
for (int i = 0; i < nLen; ++i)
{
AcDbCurve *pCurve3 = (AcDbCurve*)arSeg[i];
if (pCurve3 != NULL)
{
pCurve3->getStartPoint(ptS);
pCurve3->getEndPoint(ptE);
if (ptS.distanceTo(ptOnCurve1) < 0.001 && ptE.distanceTo(ptOnCurve2) < 0.001
|| ptS.distanceTo(ptOnCurve2) < 0.001 && ptE.distanceTo(ptOnCurve1) < 0.001)
{
arSeg.removeAt(i);
pCurveRet = pCurve3;
break;
}
}
}
ReleaseEntSet(arSeg);
return pCurveRet;
}
//已知一个曲线XCurveSegment,以及曲线上2点,返回这2点连成的AcDbPolyline
void GetPLineBySeg(AcDbPolyline *pLine, XCurveSegment seg, XPoint ptPick, XPoint ptPick2)
{
if(seg.Is(CURVE_LINE)){
pLine->addVertexAt(0, ptPick);
pLine->addVertexAt(1, ptPick2);
}
else if(seg.Is(CURVE_ARC)){
//圆弧
XArc arc = seg.GetArc();
AcGeVector3d vt1(ptPick2-arc.GetCenterPt());
AcGeVector3d vt2(ptPick-arc.GetCenterPt());
double dAngle = vt1.angleTo(vt2);
double dBulge = tan(0.25 * dAngle);
// 要确定Bulge的正,负。 如果PLINE起点离弧起点近,Bulge为正
AcDbCurve *pCurve = seg.AsAcDbCurve();
double dDist1(0), dDist2(0);
pCurve->getDistAtPoint(ptPick, dDist1);
pCurve->getDistAtPoint(ptPick2, dDist2);
if(dDist1 < dDist2)
dBulge = fabs(dBulge);
else
dBulge = -fabs(dBulge);
delete pCurve;
pLine->addVertexAt(0, ptPick, dBulge);
pLine->addVertexAt(1, ptPick2);
}
}
//通过在墙上两点得到PLINE线
BOOL MakePolyLineByWall(AcDbPolyline *pLine,Entity ent, Entity ent2, XPoint ptPick, XPoint ptPick2)
{
XCurveSegment lCurve, rCurve,firstSeg,secondSeg;
BOOL bIsLeft = TRUE;
XPoint ptTurn;
//得到墙实体1
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbWall, pWall);
XPoint ptNew1, ptNew2;
if(pWall) {
pWall->GetSideCurve(lCurve, rCurve);
lCurve.ProjectToMe(ptPick, ptNew1);
rCurve.ProjectToMe(ptPick, ptNew2);
if(ads_distance(ptPick, ptNew1) < ads_distance(ptPick, ptNew2)){
firstSeg = lCurve;
bIsLeft = TRUE;
ptPick = ptNew1;
}
else{
firstSeg = rCurve;
bIsLeft = FALSE;
ptPick = ptNew2;
}
}
OPENOBJ_END();
XPoint ptNew3, ptNew4;
//得到墙实体2
OPENOBJ_BEGIN(ent2, AcDb::kForRead, TDbWall, pWall2);
if(pWall2)
{
pWall2->GetSideCurve(lCurve, rCurve);
lCurve.ProjectToMe(ptPick2, ptNew3);
rCurve.ProjectToMe(ptPick2, ptNew4);
//找到相临的CURVE
if(firstSeg.StartPoint() == lCurve.StartPoint() || firstSeg.StartPoint() == lCurve.EndPoint()||firstSeg.EndPoint() == lCurve.StartPoint() || firstSeg.EndPoint() == lCurve.EndPoint())
{
ptPick2 = ptNew3;
secondSeg = lCurve;
}
else
{
ptPick2 = ptNew4;
secondSeg = rCurve;
}
}
OPENOBJ_END();
//得到拐点
if(firstSeg.StartPoint() == secondSeg.StartPoint() || firstSeg.StartPoint() == secondSeg.EndPoint())
ptTurn = firstSeg.StartPoint();
else if(firstSeg.EndPoint() == secondSeg.StartPoint() || firstSeg.EndPoint() == secondSeg.EndPoint())
ptTurn = firstSeg.EndPoint();
else
return FALSE;
XLinePointAndBulge linePoint1,linePoint2,linePoint3;
//得到构成PLINE线的3点
MakeSimplePloyLine(firstSeg,secondSeg,ptPick,ptPick2,linePoint1,linePoint2,linePoint3,ptTurn);
if (pLine != NULL)
{
pLine->addVertexAt(0,linePoint1.pt,linePoint1.dBulge);
pLine->addVertexAt(1,linePoint2.pt,linePoint2.dBulge);
pLine->addVertexAt(2,linePoint3.pt,linePoint3.dBulge);
AssureInCurrentView(ptPick2, ptPick2);
}
return TRUE;
}
// 主函数
// 已知2根相邻的线段,给定2个点,返回一个POLYLINE
// 注意:调用者必须自己delete PLINE
AcDbPolyline* GetNextPloyLine(Entity ent, Entity ent2, XPoint ptPick, XPoint ptPick2)
{
XPoint ptTurn;
XCurveSegment seg(ent);
XCurveSegment seg2(ent2);
// cet 2016.7.20 add 支持外部参照
AcGeMatrix3d mat1 = GetExternalEntityTransform(ent);
AcGeMatrix3d mat2 = GetExternalEntityTransform(ent2);
ads_matrix matTemp;
memcpy(matTemp, &mat1, sizeof(AcGeMatrix3d));
seg.TransformBy(matTemp);
memcpy(matTemp, &mat2, sizeof(AcGeMatrix3d));
seg2.TransformBy(matTemp);
//如果是相邻或同一线段求得转折点
if(seg.StartPoint() == seg2.StartPoint() || seg.StartPoint() == seg2.EndPoint())
ptTurn = seg.StartPoint();
else if(seg.EndPoint() == seg2.StartPoint() || seg.EndPoint() == seg2.EndPoint())
ptTurn = seg.EndPoint();
AcDbPolyline *pLine = new AcDbPolyline;
if(ent == ent2)
{ // 如果用户点在本线段
if(ent.Is(_T("LINE")) || ent.Is(_T("ARC")))
{
GetPLineBySeg(pLine, seg, ptPick, ptPick2);
}
else if (ent.Is(_T("ATS_WALL")))
{
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbWall, pWall);
if(pWall){
XCurveSegment lCurve, rCurve, seg;
XPoint ptNew1, ptNew2;
pWall->GetSideCurve(lCurve, rCurve);
// cet 2016.7.20 add 支持外部参照
ads_matrix matTemp;
memcpy(matTemp, &mat1, sizeof(AcGeMatrix3d));
lCurve.TransformBy(matTemp);
rCurve.TransformBy(matTemp);
lCurve.ProjectToMe(ptPick, ptNew1);
rCurve.ProjectToMe(ptPick, ptNew2);
if(ads_distance(ptPick, ptNew1) < ads_distance(ptPick, ptNew2))
seg = lCurve;
else
seg = rCurve;
GetPLineBySeg(pLine, seg, ptPick, ptPick2);
}
OPENOBJ_END();
}
else if (ent.Is(_T("LWPOLYLINE")))
{
delete pLine;
AcDbPolyline *pLine2 = NULL;
OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbPolyline, pCurve);
if(pCurve)
{
AcDbCurve *pNewCurve = (AcDbCurve*)pCurve->clone();
pNewCurve->transformBy(mat1);
AcDbCurve *pCurve3 = GetCurveBy2Pt(pNewCurve, ptPick, ptPick2);
if(pCurve3 != NULL)
pLine2 = AcDbPolyline::cast(pCurve3);
if(pLine2 == NULL)
delete pCurve3;
delete pNewCurve;
}
OPENOBJ_END();
AssureInCurrentView(ptPick2, ptPick2);
return pLine2;
}
else {
delete pLine;
return NULL;
}
}
else{ // 如果用户点在不同并且不相邻线段
//不支持2个相邻的线段,有1个是PLINE
if (ent.Is(_T("LWPOLYLINE")) || ent2.Is(_T("LWPOLYLINE"))){
delete pLine;
return NULL;
}
if (ptTurn != seg.StartPoint() && ptTurn != seg.EndPoint())
{
//如果是封闭曲线则不画
BOOL bTrue1 = MakeRightPloyLine(pLine,ent,ent2,ptPick,ptPick2,seg.StartPoint());
BOOL bTrue2 = MakeRightPloyLine(pLine,ent,ent2,ptPick,ptPick2,seg.EndPoint());
if (bTrue1 && bTrue2)
{
adsout << _T("所选线段在封闭的环中\n");
delete pLine;
return NULL;
}
if (!bTrue1 && !bTrue2)
{
delete pLine;
XPoint ptInter1,ptInter2;
if (seg.Intersection(seg2,ptInter1,ptInter2) != 1)
{
adsout << _T("所选线段与当前线段没有相连\n");
return NULL;
}
else
{
//实体相邻且只有一个交点
pLine = new AcDbPolyline;
XLinePointAndBulge linePoint1,linePoint2,linePoint3;
//通过给定的实体和点得到构成PLINE线的3点
//ent ent2 ptPick ptPick2 为选中的实体和点 ptInter1 为两实体交点
MakeSimplePloyLine(ent,ent2,ptPick,ptPick2,linePoint1,linePoint2,linePoint3,ptInter1);
if (pLine != NULL)
{
pLine->addVertexAt(0,linePoint1.pt,linePoint1.dBulge);
pLine->addVertexAt(1,linePoint2.pt,linePoint2.dBulge);
pLine->addVertexAt(2,linePoint3.pt,linePoint3.dBulge);
AssureInCurrentView(ptPick2, ptPick2);
}
return pLine;
}
}
}
else
{
if (ent.Is(_T("ATS_WALL")) && ent2.Is(_T("ATS_WALL")))
{
if(!MakePolyLineByWall(pLine,ent,ent2,ptPick,ptPick2)){
delete pLine;
return NULL;
}
return pLine;
}
else
{
BOOL bTrue3 = MakeRightPloyLine(pLine,ent,ent2,ptPick,ptPick2,ptTurn);
if (!bTrue3)
{
delete pLine;
return NULL;
}
}
}
}
AssureInCurrentView(ptPick2, ptPick2);
return pLine;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// 2008-2-25 谢真
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//通过选中的一点和选中的实体生成PLINE线
BOOL GetOneSidePolyLine(Entity ent,XPoint ptPick,AcDbPolyline *pPolyLine,std::vector<XLinePointAndBulge> &vecPt,BOOL bFirst,BOOL &bHasNext)
{
if (pPolyLine == NULL)
return FALSE;
bHasNext = TRUE;
BOOL bClosed = TRUE; //判断是否是闭合的
BOOL bFirstExt = TRUE; //是否是起点
XCurveSegment seg(ent);
XPoint ptTemp1,ptTemp2;//取两点十字集范围内实体的两个点
XPoint ptFirst,ptNext,ptEnd,ptTurn;
Entity entPointTemp1, entPointTemp2,entNext,entFirst;
ptNext = ptPick;
ptTurn = ptPick;
entFirst = ent;
if (ptPick == seg.StartPoint())
ptEnd = seg.EndPoint();
else
ptEnd = seg.StartPoint();
ptFirst = ptEnd;
AcDbObjectIdArray arIDFirst,arIDNext;
AcDbObjectId idTemp;
XLinePointAndBulge linePoint1,linePoint2,linePoint3;
while (ptNext != ptEnd)//不断寻找下一段
{
ptTemp1 = ptTurn;
ptTemp2 = ptTurn;
ptTemp1.x += 2;
ptTemp1.y += 2;
ptTemp2.x -= 2;
ptTemp2.y -= 2;
AssureInCurrentView(ptTemp1, ptTemp2);
PickSet ssPoint(SS_FREE);
ssPoint.Get(_T("C"),ptTemp1,ptTemp2, RBList(RTDXF0, _T("LINE,ARC"), NULL));
if(ssPoint.Length() != 2)
{
bClosed = FALSE;
if (bFirstExt)
bHasNext = FALSE;
break;
}
entPointTemp1 = ssPoint[0L];
entPointTemp2 = ssPoint[1L];
//得到相邻下一段实体
if(entPointTemp1 == entFirst)
entNext = entPointTemp2;
else if(entPointTemp2 == entFirst)
entNext = entPointTemp1;
XCurveSegment segNext(entNext);
if (segNext.StartPoint() == ptNext)
ptNext = segNext.EndPoint();
else if (segNext.EndPoint() == ptNext)
ptNext = segNext.StartPoint();
else
{
bClosed = FALSE;
break;
}
if (bFirst)
{
//第一次寻找则存放实体
acdbGetObjectId(idTemp,entFirst.name);
arIDFirst.append(idTemp);
acdbGetObjectId(idTemp,entNext.name);
arIDNext.append(idTemp);
}
else
{
//第二次则得到寻找的所有点
MakeSimplePloyLine(entFirst,entNext,ptFirst,ptNext,linePoint1,linePoint2,linePoint3,ptTurn);
if (bFirstExt)
{
vecPt.push_back(linePoint1);
bFirstExt = FALSE;
}
//存放拐点
vecPt.push_back(linePoint2);
}
entFirst = entNext;
ptFirst = ptTurn;
ptTurn = ptNext;
}
if (bFirst)
{
// 第一次执行 则将实体排序
int nSize = arIDFirst.length();
ads_name adTempName;
Entity ent1,ent2;
XPoint ptPick1,ptPick2,ptTurn;
for (int i = nSize-1; i >= 0; --i)
{
acdbGetAdsName(adTempName,arIDFirst[i]);
ent2 = adTempName;
acdbGetAdsName(adTempName,arIDNext[i]);
ent1 = adTempName;
XCurveSegment seg(ent1);
XCurveSegment seg2(ent2);
//如果是相邻或同一线段求得转折点
if(seg.StartPoint() == seg2.StartPoint() || seg.StartPoint() == seg2.EndPoint())
{
ptTurn = seg.StartPoint();
ptPick1 = seg.EndPoint();
if (ptTurn == seg2.StartPoint())
ptPick2 = seg2.EndPoint();
else
ptPick2 = seg2.StartPoint();
}
else if(seg.EndPoint() == seg2.StartPoint() || seg.EndPoint() == seg2.EndPoint())
{
ptTurn = seg.EndPoint();
ptPick1 = seg.StartPoint();
if (ptTurn == seg2.StartPoint())
ptPick2 = seg2.EndPoint();
else
ptPick2 = seg2.StartPoint();
}
else
return FALSE;
MakeSimplePloyLine(ent1,ent2,ptPick1,ptPick2,linePoint1,linePoint2,linePoint3,ptTurn);
//存放起点
if (bFirstExt)
{
vecPt.push_back(linePoint1);
bFirstExt = FALSE;
}
//存放拐点
vecPt.push_back(linePoint2);
}
}
else
{
//存放终点
if (bHasNext)
vecPt.push_back(linePoint3);
}
//封闭的则需加入起点
if (bClosed)
vecPt.push_back(vecPt[0]);
return bClosed;
}
// 主函数
// 已知1段LINE或ARC, 返回它所连接所有的线段所组成的PLINE,可能是封闭,也可能不封闭。
// 所有线段必须首尾相连,且不分叉
// 传入:ent 所选取的LINE或ARC 返回:pPolyLine
// 注意:PLINE指针由调用者自己在外面分配空间
void GetLoopPLineBySeg(Entity ent, AcDbPolyline *pPolyLine)
{
if (pPolyLine == NULL)
return;
std::vector<XLinePointAndBulge> vecPt;
typedef std::vector<XLinePointAndBulge>::iterator iter;
XCurveSegment seg(ent);
BOOL bHasNext1,bHasNext2;
if (!GetOneSidePolyLine(ent,seg.StartPoint(),pPolyLine,vecPt,TRUE,bHasNext1))//不是闭合的则需找另外一个方向
{
GetOneSidePolyLine(ent,seg.EndPoint(),pPolyLine,vecPt,FALSE,bHasNext2);
if (!bHasNext1 && !bHasNext2)//实体不连续
{
if (ent.Is(_T("LINE")))
{
pPolyLine->addVertexAt(0, seg.StartPoint());
pPolyLine->addVertexAt(1, seg.EndPoint());
}
else
{
//圆弧
XArc arc(ent);
AcGeVector3d vt1(seg.EndPoint()-arc.GetCenterPt());
AcGeVector3d vt2(seg.StartPoint()-arc.GetCenterPt());
double dAngle = vt1.angleTo(vt2);
double dBulge = tan(0.25 * dAngle);
// 要确定Bulge的正,负。 如果PLINE起点离弧起点近,Bulge为正
OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbCurve, pCurve);
if(pCurve)
{
double dDist1(0), dDist2(0);
pCurve->getDistAtPoint(seg.StartPoint(), dDist1);
pCurve->getDistAtPoint(seg.EndPoint(), dDist2);
if(dDist1 < dDist2)
dBulge = fabs(dBulge);
else
dBulge = -fabs(dBulge);
}
OPENOBJ_END();
pPolyLine->addVertexAt(0, seg.StartPoint(), dBulge);
pPolyLine->addVertexAt(1, seg.EndPoint());
}
}
}
//生成PLINE线
for (int it = 0; it < vecPt.size(); ++it)
{
pPolyLine->addVertexAt(it,vecPt[it].pt,vecPt[it].dBulge);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 获得当前视口的左下角点右上角点 (UCS点)
void GetCurrentViewExtent(XPoint &ptMin, XPoint &ptMax)
{
struct resbuf rb = {NULL, RT3DPOINT, 0};
acedGetVar(_T("VIEWCTR"), &rb);
AcGePoint3d ptView = asPnt3d(rb.resval.rpoint);
acedGetVar(_T("SCREENSIZE"), &rb);
AcGePoint3d ptSize = asPnt3d(rb.resval.rpoint);
double dXSize = ptSize.x;
double dYSize = ptSize.y;
dXSize = PixelToWcs(dXSize);
dYSize = PixelToWcs(dYSize);
ptMin.x = ptView.x - dXSize / 2;
ptMin.y = ptView.y - dYSize / 2;
ptMin.z = ptView.z;
ptMax.x = ptView.x + dXSize / 2;
ptMax.y = ptView.y + dYSize / 2;
ptMax.z = ptView.z;
}
// 根据wcs下外包框的左下角点和右上角点,求得ucs下次外包框的左下角点和右上角点(返回值为ucs点)
void GetUcsExtent(const XPoint &ptLow, const XPoint &ptUp, XPoint &ptNewLow, XPoint &ptNewUp)
{
XPoint pt1; // wcs下外包框的左上点
XPoint pt2; // wcs下外包框的右下点
pt1.x = ptLow.x;
pt1.y = ptUp.y;
pt1.z = ptLow.z;
pt2.x = ptUp.x;
pt2.y = ptLow.y;
pt2.z = ptLow.z;
AcDbExtents ext;
ext.addPoint(Wcs2Ucs(pt1));
ext.addPoint(Wcs2Ucs(pt2));
ext.addPoint(Wcs2Ucs(ptLow));
ext.addPoint(Wcs2Ucs(ptUp));
ptNewLow = ext.minPoint();
ptNewUp = ext.maxPoint();
}
Acad::ErrorStatus AssureInCurrentView_New(const XPoint &ptLow, const XPoint &ptUp)
{
// 当前视口的左下角点右上角点
XPoint lowCorner, upCorner;
GetCurrentViewExtent(lowCorner, upCorner);
// 根据ptLow, ptUp获得ucs下外包框的左下角点和右上角点
XPoint ptUcsLow, ptUcsUp;
GetUcsExtent(ptLow, ptUp, ptUcsLow, ptUcsUp);
ptUcsLow.z = ptUcsUp.z = lowCorner.z;
// 求最大值点,最小值点
XPoint ptMin = Min(ptUcsLow, lowCorner);
XPoint ptMax = Max(ptUcsUp, upCorner);
if (ptMin != lowCorner || ptMax != upCorner) //点不在屏幕当前视图之内
{
//2004下UCS, AssureInCurrentView运行特别慢 2009-8-12 sr
BOOL bIsUcs = FALSE;
XPoint ptUcsLow = Wcs2Ucs(ptLow);
XPoint ptUcsUp = Wcs2Ucs(ptUp);
if(ptUcsLow != ptLow && ptUcsUp != ptUp)
bIsUcs = TRUE;
double dd = g_nAcadVer;
if(g_nAcadVer>15.1 && g_nAcadVer<16.01 && bIsUcs) // sr 2010-2-26 >15.0001 改为 >15.1 (ACAD2002是15.006)
ads_command(RTSTR, _T("ZOOM"), RTSTR, _T("W"), RT3DPOINT, &ptUcsLow, RT3DPOINT, &ptUcsUp, RTNONE);
else
AssureInCurrentView(Ucs2Wcs(ptMin), Ucs2Wcs(ptMax));
}
return Acad::eOk;
}