3157 lines
82 KiB
C++
3157 lines
82 KiB
C++
|
||
#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;
|
||
}
|