911 lines
29 KiB
C++
911 lines
29 KiB
C++
#include "stdafx.h"
|
|
#include "EdJigEx.h"
|
|
#include "DbMultiViewInsert.h"
|
|
#include "resource.h"
|
|
#include "InsertBlockDlg.h"
|
|
#include "imgdef.h" // AcDbRasterImageDef and reactors,
|
|
#include "imgent.h"
|
|
#include "actrans.h"
|
|
|
|
|
|
// 转换成ADS代码
|
|
int TSymbEdJig::GetRetCode(int retCode, int *kwordId) const
|
|
{
|
|
int ret = retCode;
|
|
if (ret == AcEdJig::kCancel)
|
|
ret = RTCAN;
|
|
else if(ret == AcEdJig::kNull)
|
|
ret = RTNONE;
|
|
else if (ret <= 0)
|
|
ret = RTNORM;
|
|
else {
|
|
if(kwordId) *kwordId = ret-1;
|
|
ret = RTKWORD;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
// 开始执行拖动
|
|
int TSymbEdJig::DoIt(int *keyIndex)
|
|
{
|
|
int nRetCode=0;
|
|
acedGetAcadDwgView()->SetFocus(); //屏幕菜单点取时, 命令焦点没有在图形窗口
|
|
setDispPrompt(m_sPrompt);
|
|
if(!!m_sKeyword && keyIndex) {
|
|
INITGET_BEG(-1, m_sKeyword);
|
|
try {
|
|
nRetCode = drag();
|
|
} catch(...) {
|
|
nRetCode=AcEdJig::kCancel;
|
|
}
|
|
INITGET_END();
|
|
} else {
|
|
try {
|
|
nRetCode = drag();
|
|
} catch(...) {
|
|
nRetCode=AcEdJig::kCancel;
|
|
}
|
|
}
|
|
nRetCode=GetRetCode(nRetCode, keyIndex);
|
|
return nRetCode;
|
|
}
|
|
|
|
AcEdJig::DragStatus TSymbEdJig::GetPoint(XPoint &pt)
|
|
{
|
|
return acquirePoint(pt);
|
|
}
|
|
|
|
// 反馈
|
|
AcEdJig::DragStatus TSymbEdJig::sampler()
|
|
{
|
|
DragStatus stat;
|
|
setUserInputControls((UserInputControls)
|
|
(AcEdJig::kAccept3dCoordinates|AcEdJig::kNullResponseAccepted));
|
|
if (!!m_sKeyword) setKeywordList(m_sKeyword);
|
|
else setKeywordList(NULL);
|
|
|
|
XPoint ptTemp;
|
|
stat=GetPoint(ptTemp);
|
|
|
|
if(stat == AcEdJig::kNormal) {
|
|
if (IsPosChanged(ptTemp)) {
|
|
m_ptResult=ptTemp;
|
|
} else
|
|
return AcEdJig::kNoChange;
|
|
}
|
|
|
|
return stat;
|
|
}
|
|
|
|
BOOL TSymbEdJig::IsPosChanged(XPoint ptNew) const
|
|
{
|
|
return (ptNew.Distance(m_ptResult)>_DIST_SNAP);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
TPolyEdJig::TPolyEdJig(AcDbPolyline *pElev)
|
|
{
|
|
m_pDrawEnt=pElev;
|
|
}
|
|
|
|
|
|
AcEdJig::DragStatus
|
|
TPolyEdJig::GetPoint(XPoint &pt)
|
|
{
|
|
AcGePoint3d ptBase;
|
|
m_pDrawEnt->getPointAt(m_pDrawEnt->numVerts()-1, ptBase);
|
|
//if(m_nOperCode!=kArcMidPoint m_nOperCode!=kArcRadius)
|
|
// return acquirePoint(pt);
|
|
return acquirePoint(pt, ptBase);
|
|
}
|
|
|
|
// 开始执行拖动
|
|
int TPolyEdJig::DoIt(int *keyIndex)
|
|
{
|
|
XPoly2D poly2d;
|
|
PolyConvert(*m_pDrawEnt, poly2d);
|
|
if(m_nOperCode==kLinePoint || m_nOperCode==kArcPoint) {
|
|
m_ptResult=*poly2d.Tail();
|
|
} else if(m_nOperCode==kArcMidPoint) { // MidPoint
|
|
XCurveSegment cv;
|
|
poly2d.Nth(poly2d.TotalSegments()-1, cv);
|
|
m_ptResult=cv.MidPoint();
|
|
}
|
|
int nRet = TSymbEdJig::DoIt(keyIndex);
|
|
return nRet;
|
|
}
|
|
|
|
|
|
// 更新实体数据
|
|
Adesk::Boolean TPolyEdJig::update()
|
|
{
|
|
Adesk::Boolean bRet=Adesk::kTrue;
|
|
XPoly2D poly2d;
|
|
PolyConvert(*m_pDrawEnt, poly2d);
|
|
if(m_nOperCode==kLinePoint || m_nOperCode==kArcPoint) {
|
|
//*poly2d.Tail()=m_ptResult;
|
|
} else if(m_nOperCode==kArcMidPoint) {
|
|
XDirectionCurve cv;
|
|
poly2d.Nth(poly2d.TotalSegments()-1, cv);
|
|
XCurveSegment seg;
|
|
seg = XArc(cv.StartPoint(), m_ptResult, cv.EndPoint());
|
|
if(!!seg) {
|
|
if(seg.StartPoint().Distance(cv.StartPoint())>_DIST_SNAP)
|
|
seg.SetBulge(-seg.GetBulge());
|
|
poly2d.SetBulge(poly2d.Length()-2, seg.GetBulge());
|
|
}
|
|
} else if(m_nOperCode==kArcRadius) {
|
|
XPoint ptBase, ptPrev;
|
|
int numVert=m_pDrawEnt->numVerts();
|
|
m_pDrawEnt->getPointAt(numVert-1, (AcGePoint3d &)ptBase);
|
|
m_pDrawEnt->getPointAt(numVert-2, (AcGePoint3d &)ptPrev);
|
|
double nChordLen=ptBase.Distance2d(ptPrev);
|
|
double nRadius=ptBase.Distance2d(m_ptResult);
|
|
if(nChordLen<2.0*nRadius+1.0E-6) {
|
|
double bulge=2.0*asin(nChordLen/2.0/nRadius);
|
|
if(XLine(ptPrev, ptBase).OnWhichSide(m_ptResult)==OFFSET_LEFT)
|
|
bulge = -bulge;
|
|
poly2d.SetBulge(poly2d.Length()-2, bulge);
|
|
}
|
|
}
|
|
PolyConvert(poly2d, *m_pDrawEnt);
|
|
return bRet;
|
|
}
|
|
|
|
AcDbEntity* TPolyEdJig::entity() const
|
|
{
|
|
|
|
return (AcDbEntity *)m_pDrawEnt;
|
|
}
|
|
|
|
|
|
|
|
int DragInputPoly2d(XPoint ptStart, XPoly2D &poly2dRet)
|
|
{
|
|
AcDbPolyline pline;
|
|
pline.addVertexAt(0, ptStart);
|
|
TPolyEdJig jig(&pline);
|
|
jig.SetPrompt(_T("\n直段下一点或 [弧段(A)/回退(U)]<结束>: "));
|
|
jig.SetOperCode(TPolyEdJig::kLinePoint);
|
|
jig.SetKeyword(_T("A U"));
|
|
while(1) {
|
|
int nKeyIndex=0;
|
|
int nRetCode=jig.DoIt(&nKeyIndex);
|
|
if(nRetCode==RTNORM) {
|
|
pline.addVertexAt(pline.numVerts(), (AcGePoint2d &)jig.GetPickPoint());
|
|
if(jig.GetOperCode()==TPolyEdJig::kArcPoint) {
|
|
TPolyEdJig jig1(&pline);
|
|
jig1.SetOperCode(TPolyEdJig::kArcMidPoint);
|
|
jig1.SetPrompt(_T("\n点取弧上一点或 [输入半径(R)]:"));
|
|
jig1.SetKeyword(_T("R"));
|
|
int nKeyIdx;
|
|
int nRetCode1=jig1.DoIt(&nKeyIdx);
|
|
if(nRetCode1==RTKWORD) {
|
|
TPolyEdJig jig2(&pline);
|
|
jig2.SetOperCode(TPolyEdJig::kArcRadius);
|
|
jig2.SetPrompt(_T("\n输入半径(光标位置确定弧的方向):"));
|
|
jig2.DoIt();
|
|
}
|
|
} //else { //直段
|
|
jig.SetPrompt(_T("\n直段下一点或 [弧段(A)/回退(U)]<结束>: "));
|
|
jig.SetOperCode(TPolyEdJig::kLinePoint);
|
|
jig.SetKeyword(_T("A U"));
|
|
//}
|
|
} else if(nRetCode==RTKWORD) {
|
|
if(jig.GetOperCode()==TPolyEdJig::kLinePoint) {
|
|
if(nKeyIndex==0) {
|
|
jig.SetOperCode(TPolyEdJig::kArcPoint);
|
|
jig.SetPrompt(_T("\n弧段下一点或 [直段(L)/回退(U)]<结束>: "));
|
|
jig.SetKeyword(_T("L U"));
|
|
} else if(nKeyIndex==1) {
|
|
int numVert=pline.numVerts();
|
|
if(numVert>1) {
|
|
pline.removeVertexAt(numVert-1);
|
|
pline.setBulgeAt(numVert-2, 0.0);
|
|
}
|
|
}
|
|
} else if(jig.GetOperCode()==TPolyEdJig::kArcPoint) {
|
|
if(nKeyIndex==0) {
|
|
jig.SetOperCode(TPolyEdJig::kLinePoint);
|
|
jig.SetPrompt(_T("\n直段下一点或 [弧段(A)/回退(U)]<结束>: "));
|
|
jig.SetKeyword(_T("A U"));
|
|
} else if(nKeyIndex==1) {
|
|
int numVert=pline.numVerts();
|
|
if(numVert>1) {
|
|
pline.removeVertexAt(numVert-1);
|
|
pline.setBulgeAt(numVert-2, 0.0);
|
|
}
|
|
}
|
|
}
|
|
} else if(nRetCode==RTNONE) {
|
|
break;
|
|
} else if(nRetCode==RTCAN) {
|
|
return RTERROR;
|
|
}
|
|
}
|
|
|
|
int numVert=pline.numVerts();
|
|
if(numVert<2)
|
|
return RTERROR;
|
|
PolyConvert(pline, poly2dRet);
|
|
return RTNORM;
|
|
}
|
|
|
|
// 输入多段线
|
|
TUTIL_IMPEXP int GetOpenPoly2D(const TCHAR *pMsg, XPoly2D &poly2d, Entity &entRet)
|
|
{
|
|
XString szPrompt;
|
|
if(pMsg)
|
|
szPrompt << pMsg;
|
|
else szPrompt << _T("\n曲线起点");
|
|
szPrompt << _T("或 [点取图中曲线(P)/点取参考点(R)]<退出>:");
|
|
XPoint ptStart;
|
|
|
|
int nCode;
|
|
INITGET_BEG(0, _T("P R"));
|
|
nCode=ads_getpoint(NULL, szPrompt, ptStart);
|
|
INITGET_END();
|
|
if(nCode==RTKWORD) {
|
|
XString sKeyword;
|
|
VERIFY(ads_getinput(sKeyword)==RTNORM);
|
|
if(sKeyword[0]==_T('R')) {
|
|
XPoint ptRef;
|
|
if(ads_getpoint(NULL, _T("\n输入参考点<退出>:"), ptRef)!=RTNORM)
|
|
return RTERROR;
|
|
if(ads_getpoint(ptRef, _T("\n曲线起点<退出>:"), ptStart)!=RTNORM)
|
|
return RTERROR;
|
|
ptStart=Ucs2Wcs(ptStart);
|
|
nCode=DragInputPoly2d(ptStart, poly2d);
|
|
} else {
|
|
RBList mask(RTDXF0, _T("POLYLINE,LWPOLYLINE,LINE,ARC"), NULL);
|
|
Entity ent;
|
|
LAB_RESELECT:
|
|
if((nCode=ent.FilterSelect(_T("\n选择一曲线(LINE/ARC/PLINE):"), mask))!=RTNORM)
|
|
return RTERROR;
|
|
if(ent.Is(_T("LINE")) || ent.Is(_T("ARC"))) {
|
|
XCurveSegment cv(ent);
|
|
poly2d.Reset();
|
|
cv.AsPoly2D(poly2d);
|
|
} else {
|
|
XPoly2D poly(ent);
|
|
if(!!poly) {
|
|
poly2d=poly;
|
|
} else {
|
|
adsout << _T("\n无效的选择!");
|
|
goto LAB_RESELECT;
|
|
}
|
|
}
|
|
entRet=ent;
|
|
}
|
|
} else if(nCode==RTNORM) {
|
|
ptStart=Ucs2Wcs(ptStart);
|
|
nCode=DragInputPoly2d(ptStart, poly2d);
|
|
} else { //
|
|
return nCode;
|
|
}
|
|
|
|
return nCode;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// 图块拖动
|
|
|
|
|
|
|
|
TBlockInsertEdJig::TBlockInsertEdJig(AcDbEntity *pDrag, XPoint ptRef)
|
|
{
|
|
m_pDrawEnt=pDrag;
|
|
m_pBackup=(AcDbEntity *)pDrag->clone();
|
|
m_ptRef=ptRef;
|
|
}
|
|
|
|
|
|
// 开始执行拖动
|
|
int TBlockInsertEdJig::DoIt(int *keyIndex)
|
|
{
|
|
m_ptResult=m_ptRef;
|
|
int nRet = TSymbEdJig::DoIt(keyIndex);
|
|
return nRet;
|
|
}
|
|
|
|
// 反馈
|
|
AcEdJig::DragStatus TBlockInsertEdJig::GetPoint(XPoint &pt)
|
|
{
|
|
DragStatus stat;
|
|
if(m_nOperCode==kRotate) {
|
|
double nAngle=0.0;
|
|
stat=acquireAngle(nAngle, m_ptRef);
|
|
ads_polar(m_ptRef, nAngle, 100.0, pt);
|
|
} else {
|
|
stat=acquirePoint(pt);
|
|
}
|
|
return stat;
|
|
}
|
|
//以外边框方式拖制图块时,起点为基点,终点为右上角点(如:立面门窗使用这种方法)
|
|
TUTIL_IMPEXP bool g_bDragBlkCtrlPoint=false;//add by whl
|
|
// 更新实体数据
|
|
Adesk::Boolean TBlockInsertEdJig::update()
|
|
{
|
|
//ASSERT(m_pBackup->isA()==TDbBlockInsert::desc()
|
|
// && m_pDrawEnt->isA()==TDbBlockInsert::desc());
|
|
Adesk::Boolean bRet=Adesk::kTrue;
|
|
AcGeMatrix3d mat;
|
|
if(m_nOperCode==kMove) {
|
|
//m_ptRef.GetMoveMatrix(m_ptResult, mat);
|
|
XVector3D vtMove=m_ptResult-m_ptRef;
|
|
mat.setToTranslation(vtMove);
|
|
CopyObject(*m_pBackup, *m_pDrawEnt);
|
|
m_pDrawEnt->transformBy(mat);
|
|
} else if(m_nOperCode==kRotate) {
|
|
CopyObject(*m_pBackup, *m_pDrawEnt);
|
|
XVector3D vtNormal(0,0,1);
|
|
if(m_pDrawEnt->isKindOf(AcDbBlockReference::desc())) {
|
|
(AcGeVector3d &)vtNormal=AcDbBlockReference::cast(m_pDrawEnt)->normal();
|
|
}
|
|
double nRot=ads_angle(Wcs2Ecs(m_ptRef, vtNormal), Wcs2Ecs(m_ptResult, vtNormal));
|
|
mat.setToRotation(nRot, vtNormal, m_ptRef);
|
|
m_pDrawEnt->transformBy(mat);
|
|
} else if(m_nOperCode==kDragCorner) {
|
|
CopyObject(*m_pBackup, *m_pDrawEnt);
|
|
AcDbBlockReference *pInsert=AcDbBlockReference::cast(m_pDrawEnt);
|
|
BOOL bDelete=FALSE;
|
|
if(!pInsert) {
|
|
pInsert=TDbMultiViewInsert::cast(m_pDrawEnt)->NewBlock(TRUE);
|
|
bDelete=TRUE;
|
|
}
|
|
|
|
double m_nRot=pInsert->rotation();
|
|
XPoint ptCorn1=m_ptRef;
|
|
XPoint ptCorn2=m_ptResult;
|
|
double nAngle1=CT_std_angle(ads_angle(ptCorn1, ptCorn2)-m_nRot);
|
|
double nDist=ptCorn1.Distance2d(ptCorn2);
|
|
XPoint m_ptCen;
|
|
Midpoint(ptCorn1, ptCorn2, m_ptCen);
|
|
double m_nSizeX=nDist*fabs(cos(nAngle1));
|
|
double m_nSizeY=nDist*fabs(sin(nAngle1));
|
|
|
|
ads_matrix matRotOld, matMove, matScale, matRotNew, matTransform;
|
|
double nSizeX, nSizeY, nSizeZ, nRot;
|
|
XPoint ptCen, ptNewCen;
|
|
XPoint ptIns;
|
|
VERIFY(GetBlockRefSizeInfo(pInsert, ptIns, &nRot, ptCen, &nSizeX, &nSizeY, &nSizeZ)==RTNORM);
|
|
|
|
//add by whl on 040814 for insert elev win
|
|
if(g_bDragBlkCtrlPoint)
|
|
{
|
|
XPoint ptCtrl;
|
|
GetBlcCtrlPoint(pInsert->blockTableRecord(),ptCtrl);
|
|
AcGeScale3d scale1=pInsert->scaleFactors();
|
|
ptCtrl.x*=scale1[0];
|
|
ptCtrl.y*=scale1[1];
|
|
ptCen.x=ptCtrl.x/2+ptIns.x;
|
|
ptCen.y=ptCtrl.y/2+ptIns.y;
|
|
nSizeX=ptCtrl.x;
|
|
nSizeY=ptCtrl.y;
|
|
ads_matrix matRot0;
|
|
ptIns.GetRotationMatrix(nRot, matRot0);
|
|
ptCen.TransformBy(matRot0);
|
|
}
|
|
|
|
ptNewCen = m_ptCen;
|
|
ptNewCen.z += nSizeZ/2.0;
|
|
|
|
ptNewCen = m_ptCen;
|
|
ptNewCen.z += nSizeZ/2.0;
|
|
|
|
// 绕旧中心旋转-nRotOld -> 绕旧中心Scale -> 平移到新中心 -> 旋转 RotNew
|
|
// or
|
|
// 绕旧中心旋转-nRotOld -> 绕旧中心Scale -> 旋转 RotNew -> 平移到新中心 (Current Method)
|
|
AcGeScale3d bScale = pInsert->scaleFactors();
|
|
double sx=1, sy=1, sz=1;
|
|
if(fabs(nSizeX)>1.0E-6) bScale[0] *= sx = m_nSizeX/nSizeX;
|
|
if(fabs(nSizeY)>1.0E-6) bScale[1] *= sy = m_nSizeY/nSizeY;
|
|
//if(fabs(nSizeZ)>1.0E-6) bScale[2] *= sz = m_nSizeZ/nSizeZ;
|
|
|
|
ptCen.GetRotationMatrix(-nRot, matRotOld);
|
|
ptCen.GetScaleMatrix(sx, sy, sz, matScale);
|
|
ptCen.GetRotationMatrix(m_nRot, matRotNew);
|
|
ptCen.GetMoveMatrix(ptNewCen, matMove);
|
|
|
|
MatrixMultiply(matTransform, matMove, matRotNew, matScale, matRotOld, NULL);
|
|
ptIns.TransformBy(matTransform); //换算新的基点位置
|
|
|
|
if(bDelete) {
|
|
delete pInsert;
|
|
TDbMultiViewInsert *pMv=TDbMultiViewInsert::cast(m_pDrawEnt);
|
|
ASSERT(pMv);
|
|
pMv->SetLocation(ptIns);
|
|
pMv->SetScaleFactors(bScale);
|
|
} else {
|
|
pInsert->setPosition(ptIns);
|
|
pInsert->setScaleFactors(bScale);
|
|
}
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
AcDbEntity* TBlockInsertEdJig::entity() const
|
|
{
|
|
|
|
return (AcDbEntity *)m_pDrawEnt;
|
|
}
|
|
|
|
|
|
|
|
static void InitPrompt(int nFlag, XString &sKeywords, XString &sKeywordNoSpace, XString &szPrompt)
|
|
{
|
|
int nOptFlag=IBF_ROT90|IBF_MIRLR|IBF_MIRUD|IBF_FRAME|IBF_ROTATE|IBF_ALIGN|IBF_BASEPT|IBF_RESEL;
|
|
szPrompt << _T("\n点取插入点");
|
|
if(nFlag&nOptFlag)
|
|
szPrompt << _T("[");
|
|
BOOL bInitOption=FALSE;
|
|
int nOptionArray[8]={IBF_ROT90,IBF_MIRLR,IBF_MIRUD,IBF_ALIGN,IBF_FRAME,IBF_ROTATE,IBF_BASEPT,IBF_RESEL};
|
|
const TCHAR * szOptionPrompt[8]={_T("转90(A)"), _T("左右(S)"), _T("上下(D)"), _T("对齐(F)"),
|
|
_T("外框(E)"), _T("转角(R)"), _T("基点(T)"), _T("更换(C)"),};
|
|
TCHAR szKeywordArray[9]=_T("ASDFERTC");
|
|
|
|
for(int n=0;n<8;n++) {
|
|
if(nFlag&nOptionArray[n]) {
|
|
if(bInitOption) {
|
|
szPrompt << _T("/");
|
|
sKeywords << _T(" ");
|
|
}
|
|
bInitOption=TRUE;
|
|
szPrompt << szOptionPrompt[n];
|
|
TCHAR szTemp[2]=_T("");
|
|
szTemp[0]=szKeywordArray[n];
|
|
szTemp[1]=EOS;
|
|
sKeywords << szTemp;
|
|
sKeywordNoSpace << szTemp;
|
|
}
|
|
}
|
|
if(nFlag&nOptFlag)
|
|
szPrompt << _T("]");
|
|
szPrompt << _T("<退出>:");
|
|
}
|
|
|
|
static void MakeInsert(BOOL bAsTInsert, const TDbBlockInsert *pInsert)
|
|
{
|
|
if(bAsTInsert) {
|
|
AddToCurrentSpace((AcDbEntity *)pInsert->clone(), Adesk::kTrue);
|
|
} else {
|
|
AcDbVoidPtrArray entSet;
|
|
if(pInsert->explode(entSet)==Acad::eOk && entSet.length()==1) {
|
|
AcDbEntity *pEnt=(AcDbEntity *)entSet[0];
|
|
AddToCurrentSpace(pEnt, Adesk::kTrue);
|
|
}
|
|
}
|
|
}
|
|
|
|
int DragInsertBlockNew(const TCHAR *szBlock, int nFlag, AcGeScale3d scales)
|
|
{
|
|
XPoint ptInsert;
|
|
VERIFY(xg_getvar(_T("VIEWCTR"), &ptInsert)==RTNORM);
|
|
|
|
AcDbObjectId idInsert=(nFlag&IBF_TINSERT)?
|
|
MakeTBlockInsert(szBlock,ptInsert, scales[0], scales[1], scales[2],Ucs2Wcs(0),0) :
|
|
MakeBlockInsert(szBlock,ptInsert, scales[0], scales[1], scales[2], Ucs2Wcs(0));
|
|
if(!idInsert)
|
|
return RTERROR;
|
|
Entity ent;
|
|
VERIFY(acdbGetAdsName(ent.name, idInsert)==Acad::eOk);
|
|
OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbEntity, pEnt);
|
|
ASSERT(pEnt);
|
|
pEnt->draw();
|
|
OPENOBJ_END();
|
|
|
|
CWnd *pWnd=acedGetAcadFrame();
|
|
CInsertBlockDlg dlg(idInsert, pWnd);
|
|
{
|
|
CTemporaryResourceOverride vTemp;
|
|
dlg.Create(dlg.IDD, pWnd);
|
|
acedGetAcadDwgView()->SetFocus();
|
|
}
|
|
|
|
int rc=RTNORM;
|
|
ptInsert=Wcs2Ucs(ptInsert);
|
|
while(rc==RTNORM)
|
|
{
|
|
rc=IDragInsertBlock(ptInsert, ent, nFlag);
|
|
if(rc==RTNORM && (nFlag&IBF_MINSERT))
|
|
{
|
|
XPushVar<int> osmode(_T("OSMODE"), 0);
|
|
SHads_command(RTSTR, _T(".COPY"), RTENAME, (TLong_ptr *)ent, RTSTR, _T(""),
|
|
RT3DPOINT, &ptInsert,RT3DPOINT, &ptInsert, RTNONE);
|
|
ent.FreeGroups();
|
|
ent.GetLast();
|
|
dlg.SetFromBlockInfo();
|
|
dlg.UpdateData(FALSE);
|
|
}
|
|
else if(rc==RTNIL)
|
|
{
|
|
AcDbEntity *pInsert=NULL;
|
|
acdbOpenObject(pInsert,idInsert,AcDb::kForWrite,true);
|
|
if(pInsert!=NULL)
|
|
{
|
|
dlg.m_pInsert=pInsert;
|
|
dlg.UpdateInsert();
|
|
dlg.m_pInsert=NULL;
|
|
|
|
AcDbBlockReference *pTInsert=TDbBlockInsert::cast(pInsert);
|
|
if(pTInsert!=NULL)
|
|
pTInsert->setPosition(ptInsert);
|
|
else
|
|
{
|
|
TDbMultiViewInsert *pMview=TDbMultiViewInsert::cast(pInsert);
|
|
if(pMview!=NULL)
|
|
pMview->SetLocation(ptInsert);
|
|
}
|
|
pInsert->close();
|
|
|
|
rc=RTNORM;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
|
|
if(::IsWindow(dlg.m_hWnd))
|
|
dlg.DestroyWindow();
|
|
|
|
return rc;
|
|
}
|
|
|
|
// sg delete 100311,与TchKernalGlobalFunc.h里重定义,且函数实现相同,直接调用tch_kernal中的
|
|
/*
|
|
TUTIL_IMPEXP AcDbObjectId GetBlock2dFromBlock3d(AcDbObjectId idBlock)
|
|
{
|
|
AcDbObjectId idBlock2d;
|
|
OPENOBJ_BEGIN(idBlock, AcDb::kForRead, AcDbBlockTableRecord, pBlock);
|
|
if(pBlock) {
|
|
resbuf *pxData = pBlock->xData(TCHXD); // 读扩展数据
|
|
if(pxData) {
|
|
// RBList rbList(pxData);
|
|
// Groups *group=rbList.SearchNode(1005);
|
|
// if(group) {
|
|
// AcDbHandle handle(pNext->resval.rstring);
|
|
// pBlock->database()->getAcDbObjectId(idBlock2d, false, handle);
|
|
// }
|
|
resbuf *pNext = pxData->rbnext;
|
|
if(pNext && pNext->restype == 1005) {
|
|
AcDbHandle handle(pNext->resval.rstring);
|
|
pBlock->database()->getAcDbObjectId(idBlock2d, false, handle);
|
|
}
|
|
ads_relrb(pxData);
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
return idBlock2d;
|
|
}
|
|
*/
|
|
|
|
#define SAFE_DELETE(pEnt) \
|
|
if (NULL != pEnt) \
|
|
{ \
|
|
delete pEnt; \
|
|
pEnt = NULL; \
|
|
}
|
|
|
|
// Zyu add on 100819,转换成适当类型的实体
|
|
bool ConvertToProperEntity(AcDbEntity*& pEnt, bool bToACADBlock)
|
|
{
|
|
bool bExplode = false; // 是否需要进一步炸开
|
|
bool bIsTDbInsert = false; // 入库时是否是上华块
|
|
bool bIsOnlyInsert = false; // 入库时是单个块
|
|
|
|
// 转换指针类型
|
|
TDbBlockInsert *pBlkIns = TDbBlockInsert::cast(pEnt);
|
|
// 如果为空指针,说明传入的不是上华块,直接返回
|
|
if (NULL != pBlkIns)
|
|
{
|
|
// 得到上华图块中包含的ACAD图块
|
|
AcDbBlockReference *pBlkRef = pBlkIns->NewBlockInsert();
|
|
// 获得块参照对应的块表记录的ID
|
|
AcDbObjectId idBlkRec = pBlkRef->blockTableRecord();
|
|
// 打开块表记录,查看入库时的对象是否是单个上华图块
|
|
OPENOBJ_BEGIN(idBlkRec, AcDb::kForRead, AcDbBlockTableRecord, pBlkRec);
|
|
AcDbBlockTableRecordIterator *pIterator = NULL;
|
|
// 得到块表记录的遍历器
|
|
if (Acad::eOk == pBlkRec->newIterator(pIterator))
|
|
{
|
|
pIterator->start();
|
|
AcDbEntity *pEntity = NULL;
|
|
// 得到迭代器指向的实体
|
|
if (Acad::eOk == pIterator->getEntity(pEntity, AcDb::kForRead))
|
|
{
|
|
pIterator->step();
|
|
bIsOnlyInsert = (pEntity->isKindOf(AcDbBlockReference::desc()) && pIterator->done());
|
|
// 如果该实体是一个块,并且块表记录中只有这一个实体
|
|
if (bIsOnlyInsert)
|
|
{
|
|
// 能够转换,说明是入库时是上华块
|
|
bIsTDbInsert = (NULL != TDbBlockInsert::cast(pEntity));
|
|
}
|
|
pEntity->close();
|
|
}
|
|
SAFE_DELETE(pIterator);
|
|
}
|
|
OPENOBJ_END();
|
|
|
|
// 要转成Acad块
|
|
if (bToACADBlock)
|
|
{
|
|
SAFE_DELETE(pEnt);
|
|
pEnt = pBlkRef;
|
|
// 如果包含的是一个Acad块,继续炸开
|
|
bExplode = (bIsOnlyInsert && !bIsTDbInsert);
|
|
}
|
|
// 要转成上华图块
|
|
else
|
|
{
|
|
// 如果包含的是一个上华块
|
|
if (bIsOnlyInsert && bIsTDbInsert)
|
|
{
|
|
// 对于做过非等比例拉伸的块,是不能炸开的,所以先做判断
|
|
AcDbVoidPtrArray arEnts;
|
|
if (Acad::eOk == pBlkRef->explode(arEnts))
|
|
{
|
|
ReleaseEntSet(arEnts);
|
|
|
|
// pEnt指向新实体,并且继续炸开
|
|
SAFE_DELETE(pEnt);
|
|
pEnt = pBlkRef;
|
|
bExplode = true;
|
|
}
|
|
else
|
|
{
|
|
SAFE_DELETE(pBlkRef);
|
|
bExplode = false;
|
|
}
|
|
}
|
|
// 不做处理,回收内存
|
|
else
|
|
{
|
|
SAFE_DELETE(pBlkRef);
|
|
bExplode = false;
|
|
}
|
|
}
|
|
}
|
|
return bExplode;
|
|
}
|
|
|
|
int DragInsertBlock(const TCHAR *szBlock, int nFlag, const AcGeScale3d &scales)
|
|
{
|
|
//if(!(nFlag&IBF_MULTVIEW))//不是多视图块
|
|
// return DragInsertBlockNew(szBlock,nFlag|IBF_TINSERT,scales);
|
|
|
|
XPoint ptInsert;
|
|
xg_getvar(_T("VIEWCTR"), ptInsert);
|
|
ptInsert=Ucs2Wcs(ptInsert);
|
|
|
|
AcDbObjectId idBlock=InitBlock(szBlock);
|
|
if(!idBlock)
|
|
return RTERROR;
|
|
|
|
XVector3D vtNormal=Ucs2Wcs(XVector3D(0,0,1), TRUE);
|
|
((AcGeVector3d &)vtNormal).normalize();
|
|
|
|
PickSet ss(SS_FREE);
|
|
XString sKeywords, sKeywordNoSpace, sPrompt;
|
|
InitPrompt(nFlag, sKeywords, sKeywordNoSpace, sPrompt);
|
|
|
|
AcDbEntity *pDragEnt=NULL;
|
|
if(nFlag&IBF_MULTVIEW) {
|
|
AcDbObjectId idBlock2d = GetBlock2dFromBlock3d(idBlock);
|
|
if(!idBlock2d.isValid())
|
|
return RTERROR;
|
|
TDbMultiViewInsert *pInsert=new TDbMultiViewInsert;
|
|
pInsert->SetLocation(ptInsert);
|
|
pInsert->SetBlockId(TRUE, idBlock);
|
|
pInsert->SetBlockId(FALSE, idBlock2d);
|
|
pInsert->SetRotation(Ucs2Wcs(0));//add by whl on 050725
|
|
pInsert->SetScaleFactors(scales);
|
|
pDragEnt=pInsert;
|
|
} else {
|
|
XPoint ptEcsIns=Wcs2Ecs(ptInsert, vtNormal);
|
|
TDbBlockInsert *pInsert=new TDbBlockInsert;
|
|
pInsert->setBlockTableRecord(idBlock);
|
|
pInsert->setPosition(ptEcsIns);
|
|
pInsert->setScaleFactors(scales);
|
|
pInsert->setRotation(ads_angle(XPoint(), Ucs2Ecs(XVector3D(1,0,0), vtNormal, TRUE)));
|
|
pInsert->setNormal(vtNormal);
|
|
|
|
if(g_nAcadVer>16.11)
|
|
{
|
|
if(g_nAcadVer<16.3||//2006 NO SP1有时会崩溃
|
|
g_nAcadVer>17.01)//2008插有color随块对象的块又会有问题,真受不了!//add by whl on 070510
|
|
{
|
|
TCHAR sLayer[1024]=_T("0");
|
|
xg_getvar(_T("CLAYER"),sLayer);
|
|
pInsert->setLayer(sLayer);
|
|
}
|
|
|
|
pInsert->setColorIndex(256);
|
|
}
|
|
|
|
pDragEnt=pInsert;
|
|
}
|
|
//if(nFlag&IBF_MULTVIEW) {
|
|
// pInsert->Set2DBlockId(pInsert->_Get2DBlockId());
|
|
// pInsert->SetMultiView(TRUE);
|
|
//}
|
|
|
|
TBlockInsertEdJig jig(pDragEnt, ptInsert);
|
|
|
|
CWnd *pWnd=acedGetAcadFrame();
|
|
CInsertBlockDlg dlg(jig.GetBackup(), pWnd);
|
|
{
|
|
CTemporaryResourceOverride vTemp;
|
|
// Zyu add on 100819,设置是否是多视图块
|
|
dlg.m_bMultiView = (nFlag & IBF_MULTVIEW);
|
|
dlg.Create(dlg.IDD, pWnd);
|
|
}
|
|
acedGetAcadDwgView()->SetFocus();
|
|
|
|
jig.SetPrompt(sPrompt);
|
|
jig.SetKeyword(sKeywords);
|
|
jig.SetOperCode(TBlockInsertEdJig::kMove);
|
|
int nRet;
|
|
do {
|
|
int nKeyIndex=0;
|
|
nRet=jig.DoIt(&nKeyIndex);
|
|
ptInsert=jig.GetPickPoint();
|
|
jig.Backup();
|
|
jig.SetRefPoint(ptInsert);
|
|
if(nRet==RTKWORD) {
|
|
ads_printf(_T("%c%c %c"), 8,8,8); //消除回答的字符
|
|
TCHAR cKey=sKeywordNoSpace[nKeyIndex];
|
|
if(cKey==_T('A') || cKey==_T('S') || cKey==_T('D')) {
|
|
if(cKey==_T('S')) {
|
|
AcGeMatrix3d mat;
|
|
XVector3D vt=Ucs2Wcs(XVector3D(0,1,0),TRUE);
|
|
mat.setToMirroring(AcGeLine3d((AcGePoint3d &)ptInsert, (AcGeVector3d &)vt));
|
|
mat(2,2)=1;
|
|
pDragEnt->transformBy(mat);
|
|
} else if(cKey==_T('D')) {
|
|
AcGeMatrix3d mat;
|
|
XVector3D vt=Ucs2Wcs(XVector3D(1,0,0),TRUE);
|
|
mat.setToMirroring(AcGeLine3d((AcGePoint3d &)ptInsert, (AcGeVector3d &)vt));
|
|
mat(2,2)=1;
|
|
pDragEnt->transformBy(mat);
|
|
} else if(cKey==_T('A')) {
|
|
AcGeMatrix3d mat;
|
|
mat.setToRotation(PI/2.0, vtNormal, ptInsert);
|
|
//ptInsert.GetRotationMatrix(PI/2.0, mat);
|
|
pDragEnt->transformBy(mat);
|
|
}
|
|
nRet=RTNORM;
|
|
} else if(cKey==_T('C')) {
|
|
nRet=IBF_RESEL;
|
|
} else if(cKey==_T('R')) {
|
|
TBlockInsertEdJig jig1(pDragEnt, ptInsert);
|
|
jig1.SetPrompt(_T("\n旋转角度<0.0>:"));
|
|
jig1.SetOperCode(TBlockInsertEdJig::kRotate);
|
|
nRet=jig1.DoIt();
|
|
//if(nRet==RTNORM)
|
|
// adsout << sPrompt;
|
|
} else if(cKey==_T('T')) {
|
|
int nOsMode=0;
|
|
xg_getvar(_T("OSMODE"), &nOsMode);
|
|
nOsMode &= ~0x4000;
|
|
nOsMode |= OS_INT|OS_NEA|OS_PER|OS_END|OS_MID|OS_CEN;
|
|
XPushVar<int> vOsMode(_T("OSMODE"), nOsMode);
|
|
AcDbEntity *pTempEnt=(AcDbEntity *)pDragEnt->clone();
|
|
// Zyu add on 100819,转换成合适类型的对象
|
|
ConvertToProperEntity(pTempEnt, dlg.GetBlockType() == 0);
|
|
AcDbObjectId idTemp=AddToCurrentSpace(pTempEnt, Adesk::kTrue);
|
|
nRet=XGetPoint(NULL, _T("\n输入插入点"), ptInsert);
|
|
OPENOBJ_BEGIN(idTemp, AcDb::kForWrite, AcDbEntity, pEnt);
|
|
if(pEnt) pEnt->erase();
|
|
OPENOBJ_END();
|
|
if(nRet==RTNORM)
|
|
ptInsert=Ucs2Wcs(ptInsert);
|
|
} else if(cKey==_T('E')) {
|
|
XPoint ptCorn1, ptCorn2;
|
|
nRet=XGetPoint(NULL, _T("\n第一个角点"), ptCorn1);
|
|
ptCorn1=Ucs2Wcs(ptCorn1);
|
|
if(nRet==RTNORM) {
|
|
TBlockInsertEdJig jig1(pDragEnt, ptCorn1);
|
|
jig1.SetPrompt(_T("\n另一个角点"));
|
|
jig1.SetOperCode(TBlockInsertEdJig::kDragCorner);
|
|
nRet=jig1.DoIt();
|
|
if(nRet==RTNORM) {
|
|
// Zyu modify on 100819,转换成合适类型的对象
|
|
//AcDbObjectId idNew=AddToCurrentSpace((AcDbEntity *)pDragEnt->clone(), Adesk::kTrue);
|
|
AcDbEntity *pTempEnt = (AcDbEntity *)pDragEnt->clone();
|
|
bool bExplode = ConvertToProperEntity(pTempEnt, dlg.GetBlockType() == 0);
|
|
AcDbObjectId idNew=AddToCurrentSpace(pTempEnt, Adesk::kTrue);
|
|
// Zyu modify on 100908,如果块需要炸开,添加到选择集
|
|
//if(!!idNew)
|
|
// ss += idNew;
|
|
if (idNew.isValid() && bExplode)
|
|
{
|
|
ss += idNew;
|
|
}
|
|
}
|
|
}
|
|
ptInsert=ptCorn1;
|
|
} else if(cKey==_T('F')) { //对齐
|
|
int nOsMode=0;
|
|
xg_getvar(_T("OSMODE"), &nOsMode);
|
|
nOsMode &= ~0x4000;
|
|
nOsMode |= OS_INT|OS_NEA|OS_PER|OS_END|OS_MID|OS_CEN;
|
|
XPushVar<int> vOsMode(_T("OSMODE"), nOsMode);
|
|
AcDbEntity *pTempEnt=(AcDbEntity *)pDragEnt->clone();
|
|
// Zyu add on 100819,转换成合适类型的对象
|
|
ConvertToProperEntity(pTempEnt, dlg.GetBlockType() == 0);
|
|
AcDbObjectId idTemp=AddToCurrentSpace(pTempEnt, Adesk::kTrue);
|
|
XPoint pt1, pt2, qt1, qt2;
|
|
if(ads_getpoint(NULL, _T("\n对齐参考点:"), pt1)==RTNORM &&
|
|
ads_getpoint(pt1, _T("\n对齐参考轴:"), pt2)==RTNORM &&
|
|
ads_getpoint(NULL, _T("\n对齐目标点:"), qt1)==RTNORM &&
|
|
ads_getpoint(qt1, _T("\n对齐目标轴:"), qt2)==RTNORM) {
|
|
pt1=Ucs2Wcs(pt1);
|
|
pt2=Ucs2Wcs(pt2);
|
|
qt1=Ucs2Wcs(qt1);
|
|
qt2=Ucs2Wcs(qt2);
|
|
|
|
double nRot=CT_std_angle(ads_angle(qt1, qt2)-ads_angle(pt1, pt2));
|
|
ads_matrix matMov, matRot;
|
|
pt1.GetMoveMatrix(qt1, matMov);
|
|
qt1.GetRotationMatrix(nRot, matRot);
|
|
pDragEnt->transformBy(AsAcGeMatrix3d(matMov));
|
|
pDragEnt->transformBy(AsAcGeMatrix3d(matRot));
|
|
ptInsert=qt1;
|
|
|
|
// Zyu modify on 100819,转换成合适类型的对象
|
|
//AcDbObjectId idNew=AddToCurrentSpace((AcDbEntity *)pDragEnt->clone(), Adesk::kTrue);
|
|
AcDbEntity *pTmpEnt = (AcDbEntity *)pDragEnt->clone();
|
|
bool bExplode = ConvertToProperEntity(pTmpEnt, dlg.GetBlockType() == 0);
|
|
AcDbObjectId idNew=AddToCurrentSpace(pTmpEnt, Adesk::kTrue);
|
|
|
|
// Zyu modify on 100908,如果块需要炸开,添加到选择集
|
|
//if(!!idNew)
|
|
// ss += idNew;
|
|
if (idNew.isValid() && bExplode)
|
|
{
|
|
ss += idNew;
|
|
}
|
|
nRet=RTNORM;
|
|
}
|
|
OPENOBJ_BEGIN(idTemp, AcDb::kForWrite, AcDbEntity, pEnt);
|
|
if(pEnt) pEnt->erase();
|
|
OPENOBJ_END();
|
|
}
|
|
} else if(nRet==RTNORM) {
|
|
AcDbEntity *pNew=(AcDbEntity *)pDragEnt->clone();
|
|
// Zyu modify on 100819,转换成合适类型的对象
|
|
bool bExplode = ConvertToProperEntity(pNew, dlg.GetBlockType() == 0);
|
|
AcDbObjectId idNew=AddToCurrentSpace(pNew, Adesk::kTrue);
|
|
// Zyu modify on 100908,如果块需要炸开,添加到选择集
|
|
//if(!!idNew)
|
|
// ss += idNew;
|
|
if (idNew.isValid() && bExplode)
|
|
{
|
|
ss += idNew;
|
|
}
|
|
}
|
|
jig.Backup();
|
|
jig.SetRefPoint(ptInsert);
|
|
dlg.SetFromBlockInfo();
|
|
dlg.UpdateData(FALSE);
|
|
} while(nRet==RTNORM && (nFlag&IBF_MINSERT)!=0);
|
|
delete pDragEnt;
|
|
|
|
// Zyu modify on 100908,炸开选择集内的块对象
|
|
int iLen = ss.Length();
|
|
for (int i = 0; i < iLen; i++)
|
|
{
|
|
TEntitySet ent = ss[(long)i];
|
|
SHacedCommand(RTSTR, _T(".EXPLODE"), RTENAME, (TLong_ptr*)ent, NULL);
|
|
}
|
|
|
|
if(::IsWindow(dlg.m_hWnd))
|
|
dlg.DestroyWindow();
|
|
return nRet;
|
|
}
|
|
|