2631 lines
71 KiB
C++
2631 lines
71 KiB
C++
#include "stdafx.h"
|
|
#include "resource.h"
|
|
#include "SetWall.h"
|
|
#include "InsertOpeningDlg.h"
|
|
|
|
// [2010-3-16 10:32 wubo] 移植到新Geo库
|
|
// extern GEOAPI Acad::ErrorStatus GetSafeSelection(PickSet &ss, const XPoint &ptLow, const XPoint &ptUp,
|
|
// DList<AcRxClass> &lstClass, AcDbObjectId idLayer);
|
|
|
|
extern GEOAPI Acad::ErrorStatus
|
|
GetSafeSelection(PickSet &ss, BOOL bCrossing,
|
|
const XPoint &ptLow, const XPoint &ptUp, const AcRxClass *pClass);
|
|
extern TARCH_IMPEXP BOOL g_bShiftToggle;
|
|
// [2010-3-16 10:32 wubo] 移植到新Geo库
|
|
// extern TARCH_IMPEXP BOOL g_bCtrlToggle;
|
|
|
|
// 绘制点的形状
|
|
void DrawOsnapShape(AcGiViewportDraw *pVd, XPoint m_ptLoc, int m_osShape)
|
|
{
|
|
XAcGiViewDraw dc(NULL, pVd);
|
|
AcGePoint2d pixelArea;
|
|
pVd->viewport().getNumPixelsInUnitSquare(m_ptLoc,pixelArea);
|
|
double nAperture = 16/pixelArea.asVector().length();
|
|
if (nAperture<1.0E-6)
|
|
return;
|
|
XRectAngle box(m_ptLoc, nAperture, nAperture);
|
|
AcDbPolyline pline;
|
|
pVd->subEntityTraits().setColor(2);
|
|
double nWidth=1/pixelArea.asVector().length();
|
|
pline.setConstantWidth(nWidth);
|
|
|
|
ads_matrix mat;
|
|
m_ptLoc.GetRotationMatrix(Ucs2Wcs(0.0),mat);
|
|
//dc.SetColor(6); //用粉红色
|
|
switch(m_osShape) {
|
|
case AcDb::kOsMaskEnd: {
|
|
pline.addVertexAt(0, box.GetLowLeft().AsAcGePoint2d());
|
|
pline.addVertexAt(1, box.GetLowRight().AsAcGePoint2d());
|
|
pline.addVertexAt(2, box.GetUpRight().AsAcGePoint2d());
|
|
pline.addVertexAt(3, box.GetUpLeft().AsAcGePoint2d());
|
|
pline.setClosed(Adesk::kTrue);
|
|
//pline.viewportDraw(pVd);
|
|
XPoly2D poly1, poly2, poly;
|
|
PolyConvert(pline, poly);
|
|
poly.TransUCS(mat);//add by whl for ucs
|
|
poly.QuickOffset(-nWidth, poly1);
|
|
poly.QuickOffset(nWidth, poly2);
|
|
dc << poly1 << poly2;
|
|
}
|
|
break;
|
|
case AcDb::kOsMaskInt: {
|
|
pline.setClosed(Adesk::kFalse);
|
|
pline.addVertexAt(0, box.GetLowLeft().AsAcGePoint2d());
|
|
pline.addVertexAt(1, box.GetUpRight().AsAcGePoint2d());
|
|
XPoly2D poly1, poly2, poly;
|
|
PolyConvert(pline, poly);
|
|
poly.TransUCS(mat);//add by whl for ucs
|
|
poly.QuickOffset(-nWidth, poly1);
|
|
poly.QuickOffset(nWidth, poly2);
|
|
dc << poly1 << poly2;
|
|
pline.reset(Adesk::kFalse, 0);
|
|
poly1.Reset(); poly2.Reset(); poly.Reset();
|
|
pline.addVertexAt(0, box.GetLowRight().AsAcGePoint2d());
|
|
pline.addVertexAt(1, box.GetUpLeft().AsAcGePoint2d());
|
|
PolyConvert(pline, poly);
|
|
poly.TransUCS(mat);//add by whl for ucs
|
|
poly.QuickOffset(-nWidth, poly1);
|
|
poly.QuickOffset(nWidth, poly2);
|
|
dc << poly1 << poly2;
|
|
}
|
|
break;
|
|
case AcDb::kOsMaskNear: {
|
|
pline.addVertexAt(0, box.GetLowLeft().AsAcGePoint2d());
|
|
pline.addVertexAt(1, box.GetLowRight().AsAcGePoint2d());
|
|
pline.addVertexAt(2, box.GetUpLeft().AsAcGePoint2d());
|
|
pline.addVertexAt(3, box.GetUpRight().AsAcGePoint2d());
|
|
pline.setClosed(Adesk::kTrue);
|
|
XPoly2D poly1, poly2, poly;
|
|
PolyConvert(pline, poly);
|
|
poly.TransUCS(mat);//add by whl for ucs
|
|
poly.QuickOffset(-nWidth, poly1);
|
|
poly.QuickOffset(nWidth, poly2);
|
|
dc << poly1 << poly2;
|
|
}
|
|
break;
|
|
case AcDb::kOsMaskPerp: {
|
|
pline.addVertexAt(0, box.GetUpLeft().AsAcGePoint2d());
|
|
pline.addVertexAt(1, box.GetLowLeft().AsAcGePoint2d());
|
|
pline.addVertexAt(2, box.GetLowRight().AsAcGePoint2d());
|
|
pline.setClosed(Adesk::kFalse);
|
|
XPoly2D poly1, poly2, poly;
|
|
PolyConvert(pline, poly);
|
|
poly.TransUCS(mat);//add by whl for ucs
|
|
poly.QuickOffset(-nWidth, poly1);
|
|
poly.QuickOffset(nWidth, poly2);
|
|
dc << poly1 << poly2;
|
|
pline.reset(Adesk::kFalse, 0);
|
|
poly1.Reset(); poly2.Reset(); poly.Reset();
|
|
XPoint pt1, pt2;
|
|
Midpoint(box.GetUpLeft(), box.GetLowLeft(), pt1);
|
|
Midpoint(box.GetLowRight(), box.GetLowLeft(), pt2);
|
|
pline.addVertexAt(0, pt1.AsAcGePoint2d());
|
|
pline.addVertexAt(1, m_ptLoc.AsAcGePoint2d());
|
|
pline.addVertexAt(2, pt2.AsAcGePoint2d());
|
|
pline.setClosed(Adesk::kFalse);
|
|
PolyConvert(pline, poly);
|
|
poly.TransUCS(mat);//add by whl for ucs
|
|
poly.QuickOffset(-nWidth, poly1);
|
|
poly.QuickOffset(nWidth, poly2);
|
|
dc << poly1 << poly2;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////
|
|
// 判断给定的点是否在墙体基线上
|
|
// -----------------------by gjm---------------------------//
|
|
/*
|
|
画墙时,如果墙起点与终点都在另一个墙A的轮廓线内,
|
|
并且新墙标高大于等于A墙标高并且小于A墙的标高+墙高,则为重复墙,不会成功。
|
|
以下条件是建立在以上观点上的。
|
|
1.终点在墙A的轮廓线内,起点不在,则将新墙线与A墙线取交点,并用交点替换终点
|
|
2.起点在墙A的轮廓线内,终点不在,则将新墙线与A墙线取交点,并用交点替换起点
|
|
3.弧墙两端点在墙A轮廓线内,而其弧顶点不在,这种情况也要处理,将两端点都替换成墙A基线上的最近点。
|
|
*/
|
|
namespace
|
|
{
|
|
// 返回 TRUE 说明对其中一点有过修改。
|
|
// 返回 FALSE说明对两点都无修改。即两点都在墙的轮廓线之外
|
|
BOOL ModifyPntByWall(TDbWall *pWall, XPoint &ptS, XPoint & ptE)
|
|
{
|
|
if (!pWall) return FALSE;
|
|
|
|
TGGePoly2D poly;
|
|
pWall->GetOutlinePoly(.0, poly, TRUE);
|
|
int nFlagS = ptS & poly ,nFlagE = ptE & poly;
|
|
|
|
bool bAllIn = nFlagE == PR_OUTSIDE && nFlagS == PR_OUTSIDE;
|
|
|
|
// 如果是直墙,且两端点都在pWall轮廓线内,则直接退出
|
|
if (!pWall->IsKindOf(TGGeEntity::eArc))
|
|
if (bAllIn) return FALSE;
|
|
|
|
// 求交点
|
|
TGGeLine line(ptS, ptE, LS_INFINITE);
|
|
TADSGePoint3d pt1, pt2;
|
|
int nCount = pWall->Intersection(line, pt1, pt2);
|
|
|
|
if ((nFlagS == PR_INSIDE) && (nFlagE != PR_INSIDE)) // 起点在内,终点不在
|
|
{
|
|
if (nCount == 1)
|
|
ptS = pt1;
|
|
else if (nCount ==2)
|
|
{
|
|
double d1 = pt1.Distance2d(ptS);
|
|
double d2 = pt2.Distance2d(ptS);
|
|
ptS = d1 < d2 ? pt1 : pt2;
|
|
}
|
|
return FALSE;
|
|
}
|
|
if ((nFlagS != PR_INSIDE) && (nFlagE == PR_INSIDE)) // 终点在内,起点不在
|
|
{
|
|
if (nCount == 1)
|
|
ptE = pt1;
|
|
else if (nCount == 2)
|
|
{
|
|
double d1 = pt1.Distance2d(ptE);
|
|
double d2 = pt2.Distance2d(ptE);
|
|
ptE = d1 < d2 ? pt1 : pt2;
|
|
}
|
|
return TRUE;
|
|
}
|
|
if ((nFlagS == PR_INSIDE) && (nFlagE == PR_INSIDE)) // 这种情况只能是弧墙
|
|
{
|
|
if (nCount == 2)
|
|
{
|
|
double d1 = pt1.Distance2d(ptE);
|
|
double d2 = pt2.Distance2d(ptE);
|
|
ptE = d1 < d2 ? pt1 : pt2;
|
|
d1 = pt1.Distance2d(ptS);
|
|
d2 = pt2.Distance2d(ptS);
|
|
ptS = d1 < d2 ? pt1 : pt2;
|
|
}
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
BOOL IsOnWallBase(const XPoint &pt)
|
|
{
|
|
XPoint ptOnWall=pt;
|
|
PickSet ssWall(SS_FREE);
|
|
if (GetEntByDxf(ssWall, _T("TCH_WALL,TCH_CURTAIN_WALL"),1)==Acad::eOk)
|
|
{
|
|
long lCount=ssWall.Length();
|
|
for(long i=0L; i<lCount; i++)
|
|
{
|
|
Entity e=ssWall[i];
|
|
OPENOBJ_BEGIN(e, AcDb::kForRead, TDbWall, pWall);
|
|
if (pWall) {
|
|
ptOnWall.z=pWall->GetElevation();
|
|
int nPrFlag=ptOnWall&(*pWall);
|
|
if (nPrFlag==PR_INSIDE || nPrFlag==PR_ONPT1 || nPrFlag==PR_ONPT2)
|
|
return TRUE;
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
// 转为画墙而生
|
|
BOOL IsOnWallBaseForDraw(XPoint &ptEnd, XPoint &ptStart)
|
|
{
|
|
PickSet ssWall(SS_FREE);
|
|
if (GetEntByDxf(ssWall, _T("TCH_WALL,TCH_CURTAIN_WALL"),1)==Acad::eOk)
|
|
{
|
|
long lCount=ssWall.Length();
|
|
for(long i=0L; i<lCount; i++)
|
|
{
|
|
Entity e=ssWall[i];
|
|
OPENOBJ_BEGIN(e, AcDb::kForRead, TDbWall, pWall);
|
|
if (pWall)
|
|
{
|
|
if (ModifyPntByWall(pWall, ptStart, ptEnd))
|
|
return TRUE;
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////
|
|
// 捕捉轴线的交点
|
|
BOOL SnapAxisInt(PickSet &ssAxis, XPoint &ptWcs)
|
|
{
|
|
BOOL bRet=FALSE;
|
|
XPoint ptNearest;
|
|
double nMinDist=0.0;
|
|
long lCount=ssAxis.Length();
|
|
if (lCount<2)
|
|
return FALSE;
|
|
|
|
AcGePoint3dArray points;
|
|
AcDb::Intersect intType=AcDb::kOnBothOperands;
|
|
for(long i=0L; i<lCount-1; i++) {
|
|
Entity ent1=ssAxis[i];
|
|
OPENOBJ_BEGIN(ent1, AcDb::kForRead, AcDbCurve, pEnt1);
|
|
if (!pEnt1)
|
|
continue;
|
|
for(long j=i+1; j<lCount; j++) {
|
|
Entity ent2=ssAxis[j];
|
|
OPENOBJ_BEGIN(ent2, AcDb::kForRead, AcDbCurve, pEnt2);
|
|
if (!pEnt2)
|
|
continue;
|
|
|
|
pEnt1->intersectWith(pEnt2, intType, points);
|
|
OPENOBJ_END();
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
int nInters=points.length();
|
|
for(int k=0; k<nInters; k++) {
|
|
XPoint ptCur=points[k];
|
|
double nDist=ptWcs.Distance(ptCur);
|
|
if (bRet) {
|
|
if (nDist<nMinDist) {
|
|
nMinDist=nDist;
|
|
ptNearest=ptCur;
|
|
}
|
|
} else {
|
|
nMinDist=nDist;
|
|
ptNearest=ptCur;
|
|
bRet=TRUE;
|
|
}
|
|
}
|
|
if (bRet)
|
|
ptWcs=ptNearest;
|
|
return bRet;
|
|
}
|
|
|
|
|
|
//////////////////////////
|
|
// 捕捉最近点
|
|
BOOL SnapNear(PickSet &ss, XPoint &ptWcs, Entity &entNear)
|
|
{
|
|
BOOL bRet=FALSE;
|
|
XPoint ptNearest;
|
|
double nMinDist=0.0;
|
|
long lCount=ss.Length();
|
|
|
|
AcDb::Intersect intType=AcDb::kOnBothOperands;
|
|
|
|
// 构造WCS到Dcs的转换矩阵
|
|
AcGeMatrix3d transWcsToDcs;
|
|
XPoint xAxesWcs(1,0,0), yAxesWcs(0,1,0), zAxesWcs(0,0,1),
|
|
xAxesDcs, yAxesDcs, zAxesDcs;
|
|
XPoint ptOrginWcs(0,0,0), ptOrginDcs(0,0,0);
|
|
Groups fromWcs(0), toDcs(2);
|
|
ads_trans(ptOrginWcs, (resbuf *)&fromWcs, (resbuf *)&toDcs, 0, ptOrginDcs);
|
|
ads_trans(xAxesWcs, (resbuf *)&fromWcs, (resbuf *)&toDcs, 1, xAxesDcs);
|
|
ads_trans(yAxesWcs, (resbuf *)&fromWcs, (resbuf *)&toDcs, 1, yAxesDcs);
|
|
ads_trans(zAxesWcs, (resbuf *)&fromWcs, (resbuf *)&toDcs, 1, zAxesDcs);
|
|
transWcsToDcs.setCoordSystem(ptOrginDcs, xAxesDcs, yAxesDcs, zAxesDcs);
|
|
|
|
XPoint ptLast;
|
|
for(long i=0L; i<lCount; i++) {
|
|
Entity ent=ss[i];
|
|
OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbEntity, pEnt);
|
|
if (!pEnt)
|
|
continue;
|
|
AcGePoint3dArray points;
|
|
if (pEnt->getOsnapPoints(AcDb::kOsModeNear, 0, ptWcs, ptLast, transWcsToDcs, points, AcDbIntArray())==Acad::eOk) {
|
|
int numPoints=points.length();
|
|
for(int k=0; k<numPoints; k++) {
|
|
XPoint ptCur=points[k];
|
|
ptCur.z=ptWcs.z;
|
|
double nDist=ptWcs.Distance(ptCur);
|
|
if (bRet) {
|
|
if (nDist<nMinDist) {
|
|
nMinDist=nDist;
|
|
ptNearest=ptCur;
|
|
entNear=ent;
|
|
}
|
|
} else {
|
|
nMinDist=nDist;
|
|
ptNearest=ptCur;
|
|
bRet=TRUE;
|
|
entNear=ent;
|
|
}
|
|
}
|
|
}
|
|
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
if (bRet)
|
|
ptWcs=ptNearest;
|
|
return bRet;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
// 捕捉墙的端点
|
|
BOOL SnapWallEnd(PickSet &ssWall, const XRectAngle &box, XPoint &ptWcs)
|
|
{
|
|
BOOL bRet=FALSE;
|
|
XPoint ptNearest;
|
|
double nMinDist=0.0;
|
|
long lCount=ssWall.Length();
|
|
for(long i=0L; i<lCount; i++) {
|
|
Entity ent=ssWall[i];
|
|
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbWall, pWall);
|
|
if (pWall) {
|
|
XPoint ptEnd[2]={pWall->StartPoint(), pWall->EndPoint()};
|
|
ptEnd[0].z=ptEnd[1].z=ptWcs.z;
|
|
for(int n=0; n<2; n++) {
|
|
if ((ptEnd[n]&box)!=PR_OUTSIDE) {
|
|
double nDist=ptEnd[n].Distance(ptWcs);
|
|
if (bRet) {
|
|
if (nDist<nMinDist) {
|
|
nMinDist=nDist;
|
|
ptNearest=ptEnd[n];
|
|
}
|
|
} else {
|
|
nMinDist=nDist;
|
|
ptNearest=ptEnd[n];
|
|
bRet=TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
if (bRet)
|
|
ptWcs=ptNearest;
|
|
return bRet;
|
|
}
|
|
|
|
|
|
// 为方便从数据库中开窗口搜索AcDbCurve的实体
|
|
class XCurvePickSet: public PickSet {
|
|
protected:
|
|
XStringList m_lstLayerFilter, m_lstDxfNameFilter;
|
|
public:
|
|
XCurvePickSet():PickSet(SS_FREE)
|
|
{}
|
|
void SetLayerFilter(XStringList &lstLay) {
|
|
m_lstLayerFilter=lstLay;
|
|
}
|
|
void SetDxfNameFilter(XStringList &lstDxf) {
|
|
m_lstDxfNameFilter=lstDxf;
|
|
}
|
|
int GetByCrossing(const XPoint &ptLow, const XPoint &ptUp);
|
|
};
|
|
|
|
// 给定窗口进行搜索
|
|
int XCurvePickSet::GetByCrossing(const XPoint &ptLow, const XPoint &ptUp)
|
|
{
|
|
XDbBlockTableRec objMSpace;
|
|
if (!objMSpace)
|
|
return RTERROR;
|
|
int nRet=RTNONE;
|
|
XRectAngle rect(ptLow, ptUp);
|
|
XPoint ptMid;
|
|
Midpoint(ptLow, ptUp, ptMid);
|
|
AcDbBlockTableRecordIterator* pBlockIterator=NULL;
|
|
Acad::ErrorStatus es = objMSpace.m_pBlockTableRec->newIterator(pBlockIterator);
|
|
ASSERT(es==Acad::eOk && pBlockIterator!=NULL);
|
|
|
|
for (pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step()) {
|
|
AcDbEntity *pEntity=NULL;
|
|
es = pBlockIterator->getEntity(pEntity, AcDb::kForRead);
|
|
if (es!=Acad::eOk) continue;
|
|
ASSERT(pEntity);
|
|
XDbObject vTemp(pEntity);
|
|
//不处理不可见的实体
|
|
if (pEntity->visibility() == AcDb::kInvisible) {
|
|
continue;
|
|
}
|
|
AcDbCurve *pCurve=AcDbCurve::cast(pEntity);
|
|
if (!pCurve)
|
|
continue;
|
|
if (!!m_lstDxfNameFilter) {
|
|
const TCHAR *pszDxfName=pEntity->isA()->dxfName();
|
|
if (m_lstDxfNameFilter.Index(pszDxfName, 0)<0)
|
|
continue;
|
|
}
|
|
AcDbObjectId idLayer=pEntity->layerId();
|
|
OPENOBJ_BEGIN(idLayer, AcDb::kForRead, AcDbLayerTableRecord, pLayer);
|
|
if (pLayer) {
|
|
if (pLayer && pLayer->isFrozen() || pLayer->isOff())
|
|
continue;
|
|
}
|
|
OPENOBJ_END();
|
|
if (!!m_lstLayerFilter) {
|
|
TCHAR *pszLayer=pEntity->layer();
|
|
ASSERT(pszLayer);
|
|
if (m_lstLayerFilter.Index(pszLayer, 0)<0) {
|
|
delete pszLayer;
|
|
continue;
|
|
}
|
|
delete pszLayer;
|
|
}
|
|
XPoint ptCloseToCurve;
|
|
if (pCurve->getClosestPointTo(ptMid, ptCloseToCurve)==Acad::eOk &&
|
|
(ptCloseToCurve&rect)==PR_INSIDE) {
|
|
Entity ent;
|
|
VERIFY(acdbGetAdsName(ent.name, pCurve->objectId())==Acad::eOk);
|
|
*this += ent;
|
|
nRet=RTNORM;
|
|
}
|
|
}
|
|
delete pBlockIterator;
|
|
return nRet;
|
|
}
|
|
|
|
// nOsShape: 0--没有捕捉; 1--墙基线端点; 2--轴线交点; 3--墙基线最近点; 4--轴线最近点
|
|
// 对应: 的捕捉代码
|
|
int AsOsnapMask(int nOsShape)
|
|
{
|
|
int nRet=0;
|
|
switch(nOsShape) {
|
|
case 1:
|
|
nRet=AcDb::kOsMaskEnd;
|
|
break;
|
|
case 2:
|
|
nRet=AcDb::kOsMaskInt;
|
|
break;
|
|
case 3:
|
|
case 4:
|
|
nRet=AcDb::kOsMaskNear;
|
|
break;
|
|
case 5:
|
|
case 6:
|
|
nRet=AcDb::kOsMaskPerp;
|
|
break;
|
|
}
|
|
return nRet;
|
|
}
|
|
|
|
// 捕捉顺序: 墙基线端点,轴线交点,墙垂足,轴线垂足,墙基线最近点,轴线最近点
|
|
// ptWcs -- I/O
|
|
// 返回: 0--没有捕捉; 1--墙基线端点; 2--轴线交点; 3--墙基线最近点; 4--轴线最近点
|
|
// 5--墙垂足; 6--轴线垂足
|
|
int AutoSnapWall(XPoint &ptWcs, XPoint *ptBase=NULL)
|
|
{
|
|
double nApertureWcs=GetApertureWcs();
|
|
if (nApertureWcs<1.0E-6)
|
|
return 0;
|
|
int bSnap=0;
|
|
XPoint vtSnap(nApertureWcs, nApertureWcs);
|
|
XPoint ptLow=ptWcs-vtSnap;
|
|
XPoint ptUp = ptWcs+vtSnap;
|
|
|
|
XCurvePickSet ssWall, ssAxis;
|
|
/*
|
|
XStringList lstWallFilter, lstAxisFilter, lstAxisLayerFilter;
|
|
lstWallFilter.Append(strnew(_T("TCH_WALL")));
|
|
lstAxisFilter.Append(strnew(_T("LINE")));
|
|
lstAxisFilter.Append(strnew(_T("ARC")));
|
|
lstAxisFilter.Append(strnew(_T("CIRCLE")));
|
|
lstAxisLayerFilter.Append(strnew(LAY_AXIS));
|
|
|
|
ssWall.SetDxfNameFilter(lstWallFilter);
|
|
ssAxis.SetDxfNameFilter(lstAxisFilter);
|
|
ssAxis.SetLayerFilter(lstAxisLayerFilter);
|
|
|
|
BOOL bNearWall =
|
|
ssWall.GetByCrossing(ptLow, ptUp)==RTNORM;
|
|
BOOL bNearAxis =
|
|
ssAxis.GetByCrossing(ptLow, ptUp)==RTNORM;
|
|
*/
|
|
|
|
BOOL bNearWall = (GetSafeSelectionEx(ssWall, FALSE, ptLow, ptUp, TDbWall::desc())==Acad::eOk);
|
|
|
|
/*
|
|
PickSet ss1(SS_FREE), ss2(SS_FREE), ss3(SS_FREE);
|
|
BOOL bNearAxis1=(GetSafeSelection(ss1, FALSE, ptLow, ptUp, AcDbLine::desc())==Acad::eOk);
|
|
BOOL bNearAxis2=(GetSafeSelection(ss2, FALSE, ptLow, ptUp, AcDbArc::desc())==Acad::eOk);
|
|
BOOL bNearAxis3=(GetSafeSelection(ss3, FALSE, ptLow, ptUp, AcDbCircle::desc())==Acad::eOk);
|
|
BOOL bNearAxis=(bNearAxis1 || bNearAxis2 || bNearAxis3);
|
|
ssAxis += ss1;
|
|
ssAxis += ss2;
|
|
ssAxis += ss3;
|
|
if (bNearAxis) {
|
|
ssAxis.BaseFilter(RBList(8, LAY_AXIS, NULL));
|
|
bNearAxis=(ssAxis.Length()>0);
|
|
}
|
|
*/
|
|
AcDbObjectId idLay=GetLayerIdFromString(LAY_AXIS);
|
|
// sg modify 120305,由于在ARX2013的开发包中,AcRxClass类的构造函数、析构函数变成了保护成员,因此下面的用法是有错误的,换成其他接口
|
|
//DList<AcRxClass> lstClasses(FALSE);
|
|
//lstClasses.Append(AcDbLine::desc());
|
|
//lstClasses.Append(AcDbArc::desc());
|
|
//lstClasses.Append(AcDbCircle::desc());
|
|
//BOOL bNearAxis=(GetSafeSelection(ssAxis, ptLow, ptUp, lstClasses, idLay)==Acad::eOk
|
|
// && ssAxis.Length()>0);
|
|
CStringArray aryDxfNames;
|
|
aryDxfNames.Add(_T("Line"));
|
|
aryDxfNames.Add(_T("Arc"));
|
|
aryDxfNames.Add(_T("Circle"));
|
|
BOOL bNearAxis=(GetSafeSelection(ssAxis, ptLow, ptUp, aryDxfNames, idLay)==Acad::eOk
|
|
&& ssAxis.Length()>0);
|
|
|
|
XRectAngle box(ptLow, ptUp);
|
|
if (bNearWall)
|
|
if (SnapWallEnd(ssWall, box, ptWcs))
|
|
bSnap = 1;
|
|
if (!bSnap && bNearAxis)
|
|
if (SnapAxisInt(ssAxis, ptWcs))
|
|
bSnap = 2;
|
|
if (!bSnap && bNearWall) {
|
|
Entity entNear;
|
|
XPoint ptCursor=ptWcs;
|
|
if (SnapNear(ssWall, ptWcs, entNear)) {
|
|
bSnap = 3;
|
|
OPENOBJ_BEGIN(entNear, AcDb::kForRead, TDbWall, pWall);
|
|
if (pWall && ptBase) {
|
|
if (((*ptBase)&(*pWall))==PR_OUTSIDE) {
|
|
XPoint ptPrj;
|
|
pWall->ProjectToMe(*ptBase, ptPrj);
|
|
double nIntAng=CT_acute_angle(ads_angle(*ptBase, ptPrj)-ads_angle(*ptBase, ptCursor));
|
|
if ((ptPrj&(*pWall))==PR_INSIDE && nIntAng<5.0*PI/180.0) {
|
|
bSnap=5;
|
|
ptWcs=ptPrj;
|
|
}
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
if (!bSnap && bNearAxis) {
|
|
Entity entNear;
|
|
XPoint ptCursor=ptWcs;
|
|
if (SnapNear(ssAxis, ptWcs, entNear)) {
|
|
bSnap = 4;
|
|
XCurveSegment seg(entNear);
|
|
if (ptBase) {
|
|
XPoint ptPrj;
|
|
if (((*ptBase)&seg)==PR_OUTSIDE) {
|
|
seg.ProjectToMe(*ptBase, ptPrj);
|
|
double nIntAng=CT_acute_angle(ads_angle(*ptBase, ptPrj)-ads_angle(*ptBase, ptCursor));
|
|
if ((ptPrj&seg)==PR_INSIDE && nIntAng<5.0*PI/180.0) {
|
|
bSnap=6;
|
|
ptWcs=ptPrj;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return bSnap;
|
|
}
|
|
|
|
|
|
|
|
// 捕捉唯一的最近墙
|
|
// ptWcs(IN) -- 给定的点
|
|
// 返回: 捕捉到的墙体
|
|
AcDbObjectId SnapOnWall(const XPoint &ptWcs)
|
|
{
|
|
AcDbObjectId idRet;
|
|
XDbBlockTableRec objMSpace;
|
|
if (!objMSpace)
|
|
return idRet;
|
|
|
|
AcDbBlockTableRecordIterator* pBlockIterator=NULL;
|
|
Acad::ErrorStatus es = objMSpace.m_pBlockTableRec->newIterator(pBlockIterator);
|
|
ASSERT(es==Acad::eOk && pBlockIterator!=NULL);
|
|
|
|
for (pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step()) {
|
|
AcDbEntity *pEntity=NULL;
|
|
es = pBlockIterator->getEntity(pEntity, AcDb::kForRead);
|
|
if (es!=Acad::eOk) continue;
|
|
ASSERT(pEntity);
|
|
|
|
XDbObject vTemp(pEntity);
|
|
//不处理不可见的实体
|
|
if (pEntity->visibility() == AcDb::kInvisible || !pEntity->isKindOf(TDbWall::desc())) {
|
|
continue;
|
|
}
|
|
TDbWall *pWall=(TDbWall*)pEntity;
|
|
AcDbObjectId idLayer=pWall->layerId();
|
|
OPENOBJ_BEGIN(idLayer, AcDb::kForRead, AcDbLayerTableRecord, pLayer);
|
|
ASSERT(pLayer);
|
|
if (pLayer->isFrozen() || pLayer->isOff())
|
|
continue;
|
|
OPENOBJ_END();
|
|
|
|
XPoint ptPrj;
|
|
if (pWall->ProjectToMe(ptWcs, ptPrj)!=RTNORM)
|
|
continue;
|
|
if ((ptPrj&(*pWall))!=PR_INSIDE)
|
|
continue;
|
|
double nDist2Wall=pWall->GetDist2Me(ptWcs);
|
|
if (nDist2Wall > -pWall->GetWidth(0) - _DIST_SNAP*10 &&
|
|
nDist2Wall < pWall->GetWidth(1)+_DIST_SNAP*10) {
|
|
idRet=pWall->objectId();
|
|
break;
|
|
}
|
|
}
|
|
delete pBlockIterator;
|
|
return idRet;
|
|
|
|
#if 0
|
|
// 不知道是否捕捉速度太慢, 光标移动到墙体内时,捕捉光标出现。
|
|
PickSet ssWall(SS_FREE);
|
|
if (GetEntByDxf(ssWall,_T("TCH_WALL,TCH_CURTAIN_WALL"),1)!=Acad::eOk)
|
|
//if (ssWall.Get(_T("X"), NULL, NULL, RBList(RTDXF0, _T("TCH_WALL"), NULL))!=RTNORM)
|
|
return AcDbObjectId::kNull;
|
|
long lCount=ssWall.Length();
|
|
for(long i=0; i<lCount; i++) {
|
|
Entity ent=ssWall[i];
|
|
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbWall, pWall);
|
|
if (pWall) {
|
|
XPoly2D poly2d(1);
|
|
pWall->GetOutlinePoly(ptWcs.z, poly2d);
|
|
if ((ptWcs&poly2d)!=PR_OUTSIDE) {
|
|
return pWall->objectId();
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
return AcDbObjectId::kNull;
|
|
/*
|
|
AcDbObjectId idRet;
|
|
double nApertureWcs=GetApertureWcs();
|
|
if (nApertureWcs<1.0E-6)
|
|
return idRet;
|
|
|
|
//int bSnap=0;
|
|
XPoint vtSnap(nApertureWcs*4, nApertureWcs*4);
|
|
XPoint ptLow=ptWcs-vtSnap;
|
|
XPoint ptUp = ptWcs+vtSnap;
|
|
|
|
XCurvePickSet ssWall;
|
|
XStringList lstWallFilter;
|
|
lstWallFilter.Append(strnew(_T("TCH_WALL")));
|
|
ssWall.SetDxfNameFilter(lstWallFilter);
|
|
BOOL bNearWall =
|
|
ssWall.GetByCrossing(ptLow, ptUp)==RTNORM;
|
|
|
|
if (bNearWall && ssWall.Length()==1) {
|
|
Entity ent=ssWall[0L];
|
|
acdbGetObjectId(idRet, ent.name);
|
|
}
|
|
return idRet;
|
|
*/
|
|
#endif
|
|
}
|
|
|
|
// 为了绘制Osnap点而构造临时实体
|
|
class XDbOsnapPoint: public AcDbEntity {
|
|
public:
|
|
XPoint m_ptLoc;
|
|
int m_osShape;
|
|
|
|
bool m_bRectCursor;
|
|
XPoint m_ptBase;
|
|
public:
|
|
XDbOsnapPoint(): m_osShape(0), m_bRectCursor(false)
|
|
{}
|
|
Adesk::Boolean subWorldDraw(AcGiWorldDraw *mode);
|
|
void subViewportDraw(AcGiViewportDraw *mode);
|
|
};
|
|
|
|
|
|
Adesk::Boolean XDbOsnapPoint::subWorldDraw(AcGiWorldDraw *mode)
|
|
{
|
|
return Adesk::kFalse;
|
|
}
|
|
|
|
// 由于视窗的实体不能访问, 因此本函数目前没有使用
|
|
|
|
void XDbOsnapPoint::subViewportDraw(AcGiViewportDraw *mode)
|
|
{
|
|
if (m_bRectCursor) {
|
|
XRectAngle box(Wcs2Ucs(m_ptBase), Wcs2Ucs(m_ptLoc));
|
|
XPoly2D poly2d(1);
|
|
box.AsPoly2D(poly2d);
|
|
poly2d.TransUCS(Groups(1), Groups(0));
|
|
AcDbPolyline pline;
|
|
PolyConvert(poly2d, pline);
|
|
pline.viewportDraw(mode);
|
|
}
|
|
|
|
if (CDrawWallDlg::g_bAutoSnap)
|
|
DrawOsnapShape(mode, m_ptLoc, m_osShape);
|
|
}
|
|
|
|
|
|
// 拖曳显示点
|
|
class XOsPointEdJig : public AcEdJig
|
|
{
|
|
public:
|
|
XOsPointEdJig();
|
|
virtual ~XOsPointEdJig();
|
|
void doIt();
|
|
virtual DragStatus sampler();
|
|
virtual Adesk::Boolean update();
|
|
virtual AcDbEntity* entity() const;
|
|
|
|
int GetRetCode(int *kwordId=NULL) const;
|
|
int m_nRetCode; //返回码
|
|
const TCHAR *m_pszPrompt; //提示信息
|
|
const TCHAR *m_pszKeyword; //关键字
|
|
XDbOsnapPoint *m_pDrawEnt; //临时实体
|
|
|
|
XPoint m_ptFrom, m_ptTo;
|
|
int m_osShape;
|
|
int m_nUsageFlag; //0--不带橡皮巾; 1--待橡皮巾; 2--矩形拖曳
|
|
};
|
|
|
|
|
|
|
|
// 转换成ADS代码
|
|
int XOsPointEdJig::GetRetCode(int *kwordId) const
|
|
{
|
|
int ret = m_nRetCode;
|
|
if (ret == AcEdJig::kCancel)
|
|
ret = RTCAN;
|
|
else if (ret == AcEdJig::kNull)
|
|
ret = RTNONE;
|
|
else if (ret <= 0)
|
|
ret = RTNORM;
|
|
else {
|
|
if (kwordId) *kwordId = ret;
|
|
ret = RTKWORD;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
XOsPointEdJig::XOsPointEdJig()
|
|
:m_pszKeyword(NULL), m_pszPrompt(NULL), m_pDrawEnt(NULL),
|
|
m_nRetCode(0), m_osShape(0), m_nUsageFlag(0)
|
|
{
|
|
}
|
|
|
|
XOsPointEdJig::~XOsPointEdJig()
|
|
{
|
|
if (m_pDrawEnt) delete m_pDrawEnt;
|
|
}
|
|
|
|
// 开始执行拖动
|
|
void XOsPointEdJig::doIt()
|
|
{
|
|
m_pDrawEnt = new XDbOsnapPoint;
|
|
m_pDrawEnt->m_osShape=AsOsnapMask(m_osShape);
|
|
m_pDrawEnt->m_ptLoc = m_ptTo;
|
|
m_pDrawEnt->m_bRectCursor = (m_nUsageFlag==2);
|
|
m_pDrawEnt->m_ptBase=m_ptFrom;
|
|
|
|
setDispPrompt(m_pszPrompt);
|
|
if (m_nUsageFlag==2)
|
|
setSpecialCursorType(AcEdJig::kNoSpecialCursor);
|
|
if (m_pszKeyword) {
|
|
INITGET_BEG(-1, m_pszKeyword);
|
|
try {
|
|
m_nRetCode = drag();
|
|
} catch(...) {
|
|
m_nRetCode=AcEdJig::kCancel;
|
|
}
|
|
INITGET_END();
|
|
} else {
|
|
|
|
try {
|
|
m_nRetCode = drag();
|
|
} catch(...) {
|
|
m_nRetCode=AcEdJig::kCancel;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 反馈
|
|
AcEdJig::DragStatus XOsPointEdJig::sampler()
|
|
{
|
|
DragStatus stat;
|
|
|
|
setUserInputControls((UserInputControls)
|
|
(AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted
|
|
| AcEdJig::kNoNegativeResponseAccepted
|
|
| AcEdJig::kNoZeroResponseAccepted));
|
|
|
|
if (m_pszKeyword) setKeywordList(m_pszKeyword);
|
|
XPoint ptTemp;
|
|
XPoint *ptBase=NULL;
|
|
if (m_nUsageFlag==2) {
|
|
setSpecialCursorType(AcEdJig::kNoSpecialCursor);
|
|
stat = acquirePoint(ptTemp, m_ptFrom);
|
|
ptBase=&m_ptFrom;
|
|
} else if (m_nUsageFlag==1) {
|
|
stat = acquirePoint(ptTemp, m_ptFrom);
|
|
ptBase=&m_ptFrom;
|
|
} else {
|
|
stat = acquirePoint(ptTemp);
|
|
}
|
|
if (stat == AcEdJig::kNormal) {
|
|
m_osShape=CDrawWallDlg::g_bAutoSnap? AutoSnapWall(ptTemp, ptBase) : 0;
|
|
if (ads_distance(ptTemp, m_ptTo)>_DIST_SNAP) {
|
|
m_ptTo=ptTemp;
|
|
}
|
|
else
|
|
return AcEdJig::kNoChange;
|
|
}
|
|
|
|
return stat;
|
|
}
|
|
|
|
// 更新实体数据
|
|
Adesk::Boolean XOsPointEdJig::update()
|
|
{
|
|
if (!(m_pDrawEnt->m_ptLoc == m_ptTo)) {
|
|
m_pDrawEnt->m_ptLoc = m_ptTo;
|
|
m_pDrawEnt->m_osShape = AsOsnapMask(m_osShape);
|
|
m_pDrawEnt->m_bRectCursor = (m_nUsageFlag==2);
|
|
m_pDrawEnt->m_ptBase=m_ptFrom;
|
|
}
|
|
return Adesk::kTrue;
|
|
}
|
|
|
|
AcDbEntity* XOsPointEdJig::entity() const
|
|
{
|
|
return m_pDrawEnt;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////
|
|
// 为了拖曳墙体和绘制Osnap点而构造临时实体
|
|
class TDbWallOsnapPoint: public TDbWall {
|
|
public:
|
|
XPoint m_ptLoc;
|
|
int m_osShape;
|
|
public:
|
|
TDbWallOsnapPoint(): m_osShape(0)
|
|
{}
|
|
Adesk::Boolean subWorldDraw(AcGiWorldDraw *mode);
|
|
void subViewportDraw(AcGiViewportDraw *mode);
|
|
};
|
|
|
|
|
|
Adesk::Boolean TDbWallOsnapPoint::subWorldDraw(AcGiWorldDraw *mode)
|
|
{
|
|
return Adesk::kFalse;
|
|
}
|
|
|
|
|
|
void TDbWallOsnapPoint::subViewportDraw(AcGiViewportDraw *mode)
|
|
{
|
|
TDbWall::subViewportDraw(mode);
|
|
if (CDrawWallDlg::g_bAutoSnap)
|
|
DrawOsnapShape(mode, m_ptLoc, m_osShape);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////
|
|
// 拖曳墙体, 并确定半径或者顶点
|
|
class XDrawWallEdJig : public TEdJig
|
|
{
|
|
public:
|
|
XDrawWallEdJig(CDrawWallDlg *pDlg);
|
|
virtual ~XDrawWallEdJig();
|
|
void doIt();
|
|
virtual DragStatus sampler();
|
|
virtual Adesk::Boolean Update();
|
|
virtual AcDbEntity* entity() const;
|
|
|
|
#if ADS>15
|
|
virtual void CreateGrip();
|
|
virtual Acad::ErrorStatus EntityToDim(long iGrip,long iDim);
|
|
virtual Acad::ErrorStatus DimToEntity(long iGrip,long iDim,double newValue);
|
|
#endif
|
|
|
|
int GetRetCode(int *kwordId=NULL) const;
|
|
|
|
int m_nRetCode; //返回码
|
|
const TCHAR *m_pszPrompt; //提示信息
|
|
const TCHAR *m_pszKeyword; //关键字
|
|
TDbWallOsnapPoint *m_pDrawEnt; //临时实体
|
|
|
|
int m_osShape; //捕捉性质
|
|
|
|
XPoint m_ptStart, m_ptEnd, m_ptAny;
|
|
double m_nRadius;
|
|
|
|
|
|
//控制方案
|
|
//int m_bIsDouble; //是否为双线
|
|
|
|
// 0--已知起点, 待定终点
|
|
// 1--已知起点,弧上任意点,待定终点
|
|
// 2--已知起点终点, 待定弧上一点
|
|
// 3--已知起点终点, 待定半径
|
|
int m_nFlag;
|
|
CDrawWallDlg *m_pDlg;
|
|
};
|
|
/* ========================================================== */
|
|
#if ADS>15
|
|
void XDrawWallEdJig::CreateGrip()
|
|
{
|
|
SetGripNum(2);
|
|
|
|
//直墙
|
|
GetGrip(0)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimResultantLength));
|
|
GetGrip(0)->AppendDim(new TDbGripAngleDim(AcDbDimData::kDimResultantAngle));
|
|
|
|
//弧墙
|
|
GetGrip(1)->AppendDim(new TDbGripRadiusDim(AcDbDimData::kDimRadius));
|
|
GetGrip(1)->AppendDim(new TDbGripAngleDim(AcDbDimData::kDimResultantAngle));
|
|
}
|
|
Acad::ErrorStatus XDrawWallEdJig::EntityToDim(long iGrip,long iDim)
|
|
{
|
|
TDbGripDim*pDim=GetGripDim(iGrip,iDim);
|
|
if (pDim==NULL)
|
|
return Acad::eInvalidInput;
|
|
|
|
TDbWall*pWall=m_pDrawEnt;
|
|
double dist=5000;
|
|
switch(iGrip)
|
|
{
|
|
case 0://直墙终点
|
|
switch(iDim)
|
|
{
|
|
case 0://长度
|
|
{
|
|
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
|
|
pDistDim->SetData(pWall->EndPoint().AsAcGePoint3d(),pWall->StartPoint().AsAcGePoint3d(),dist);
|
|
}
|
|
break;
|
|
case 1://角度
|
|
{
|
|
TDbGripAngleDim*pAngleDim=(TDbGripAngleDim*)pDim;
|
|
XPoint ptEnd=pWall->StartPoint()+XPoint(1000,0,0);
|
|
pAngleDim->SetData(pWall->StartPoint().AsAcGePoint3d(),pWall->EndPoint().AsAcGePoint3d(),ptEnd.AsAcGePoint3d());
|
|
}
|
|
break;
|
|
default:
|
|
return Acad::eNotImplementedYet;
|
|
}
|
|
break;
|
|
case 1://中点
|
|
switch(iDim)
|
|
{
|
|
case 0://半径
|
|
{
|
|
TDbGripRadiusDim*pRadiusDim=(TDbGripRadiusDim*)pDim;
|
|
pRadiusDim->SetData(pWall->GetArc().GetCenterPt().AsAcGePoint3d(),pWall->MidPoint().AsAcGePoint3d());
|
|
}
|
|
break;
|
|
case 1://包络角
|
|
{
|
|
TDbGripAngleDim*pAngleDim=(TDbGripAngleDim*)pDim;
|
|
pAngleDim->SetData(*pWall);
|
|
}
|
|
break;
|
|
default:
|
|
return Acad::eNotImplementedYet;
|
|
}
|
|
break;
|
|
default:
|
|
return Acad::eNotImplementedYet;
|
|
}
|
|
return Acad::eOk;
|
|
}
|
|
Acad::ErrorStatus XDrawWallEdJig::DimToEntity(long iGrip,long iDim,double newValue)
|
|
{
|
|
XPoint vt=m_pDrawEnt->EndPoint()-m_pDrawEnt->StartPoint();
|
|
vt.Normalize();
|
|
|
|
switch(iGrip)
|
|
{
|
|
case 0://终点
|
|
switch(iDim)
|
|
{
|
|
case 0://长度
|
|
if (newValue>1E-6)
|
|
{
|
|
vt*=newValue;
|
|
m_ptEnd=m_pDrawEnt->EndPoint()=m_pDrawEnt->StartPoint()+vt;
|
|
}
|
|
break;
|
|
case 1://角度
|
|
{
|
|
if (vt.y<0)
|
|
newValue*=-1;
|
|
XPoint vt2(m_pDrawEnt->GetLength(),0,0);
|
|
vt2.Rotate(newValue);
|
|
m_ptEnd=m_pDrawEnt->EndPoint()=m_pDrawEnt->StartPoint()+vt2;
|
|
}
|
|
break;
|
|
default:
|
|
return Acad::eNotImplementedYet;
|
|
}
|
|
break;
|
|
case 1://中点
|
|
switch(iDim)
|
|
{
|
|
case 0://半径
|
|
{
|
|
XCurveSegment line(m_pDrawEnt->StartPoint(),m_pDrawEnt->EndPoint(),0);
|
|
double len=line.GetLength();
|
|
double as=len*0.5/newValue;
|
|
if (as>1)
|
|
return Acad::eInvalidInput;
|
|
newValue=2*asin(as);
|
|
}
|
|
case 1://包络角
|
|
{
|
|
m_pDrawEnt->SetBulge(CT_std_angle(newValue));
|
|
m_ptAny=m_pDrawEnt->MidPoint();
|
|
}
|
|
break;
|
|
default:
|
|
return Acad::eNotImplementedYet;
|
|
}
|
|
break;
|
|
default:
|
|
return Acad::eNotImplementedYet;
|
|
}
|
|
return Acad::eOk;
|
|
}
|
|
#endif;
|
|
// 转换成ADS代码
|
|
int XDrawWallEdJig::GetRetCode(int *kwordId) const
|
|
{
|
|
int ret = m_nRetCode;
|
|
if (ret == AcEdJig::kCancel)
|
|
ret = RTCAN;
|
|
else if (ret == AcEdJig::kNull)
|
|
ret = RTNONE;
|
|
else if (ret <= 0)
|
|
ret = RTNORM;
|
|
else {
|
|
if (kwordId) *kwordId = ret;
|
|
ret = RTKWORD;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
XDrawWallEdJig::XDrawWallEdJig(CDrawWallDlg *pDlg)
|
|
:m_pDlg(pDlg), m_pszKeyword(NULL), m_pszPrompt(NULL), m_pDrawEnt(NULL), m_nRetCode(0), m_osShape(0)
|
|
{
|
|
#if ADS>15
|
|
CreateGrip();
|
|
#endif
|
|
}
|
|
|
|
XDrawWallEdJig::~XDrawWallEdJig()
|
|
{
|
|
if (m_pDrawEnt) delete m_pDrawEnt;
|
|
}
|
|
|
|
// 开始执行拖动
|
|
void XDrawWallEdJig::doIt()
|
|
{
|
|
m_pDrawEnt = new TDbWallOsnapPoint;
|
|
m_pDrawEnt->StartPoint() = m_ptStart;
|
|
m_pDrawEnt->EndPoint() = m_ptEnd;
|
|
if (m_pDlg) {
|
|
m_pDrawEnt->SetWidth(0, m_pDlg->GetLeftWidth());
|
|
m_pDrawEnt->SetWidth(1, m_pDlg->GetRightWidth());
|
|
} else {
|
|
m_pDrawEnt->SetWidth(0, g_lWallWidth);
|
|
m_pDrawEnt->SetWidth(1, g_rWallWidth);
|
|
}
|
|
TDbWall::Catalog nCatalog;
|
|
m_pDrawEnt->setLayer(m_pDrawEnt->GetDefaultLayer());
|
|
if (m_pDlg==NULL||m_pDlg->GetUsage(nCatalog)!=TWallData::kVirtual)
|
|
m_pDrawEnt->SetUsageFlag(TWallData::kEdJig);
|
|
else
|
|
m_pDrawEnt->SetUsageFlag(TWallData::kVirtual);
|
|
|
|
// Osnap Point member
|
|
m_pDrawEnt->m_osShape=AsOsnapMask(m_osShape);
|
|
if (m_nFlag==0 || m_nFlag==1)
|
|
m_pDrawEnt->m_ptLoc = m_ptEnd;
|
|
else if (m_nFlag==2)
|
|
m_pDrawEnt->m_ptLoc = m_ptAny;
|
|
|
|
|
|
setDispPrompt(m_pszPrompt);
|
|
if (m_pszKeyword) {
|
|
INITGET_BEG(-1, m_pszKeyword);
|
|
try {
|
|
m_nRetCode = drag();
|
|
} catch(...) {
|
|
m_nRetCode=AcEdJig::kCancel;
|
|
}
|
|
INITGET_END();
|
|
} else {
|
|
|
|
try {
|
|
m_nRetCode = drag();
|
|
} catch(...) {
|
|
m_nRetCode=AcEdJig::kCancel;
|
|
}
|
|
} }
|
|
|
|
extern TARCH_IMPEXP void GetWallLengthModel(DList<double> &lstWidth);
|
|
extern TARCH_IMPEXP double GetModelNumber(DList<double> &lstModel, double nNearNumber);
|
|
// 反馈
|
|
AcEdJig::DragStatus XDrawWallEdJig::sampler()
|
|
{
|
|
DragStatus stat;
|
|
|
|
setUserInputControls((UserInputControls)
|
|
(AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted
|
|
| AcEdJig::kNoNegativeResponseAccepted
|
|
| AcEdJig::kNoZeroResponseAccepted));
|
|
|
|
if (m_pszKeyword) setKeywordList(m_pszKeyword);
|
|
XPoint ptTemp;
|
|
if (m_nFlag==0 || m_nFlag==1 || m_nFlag==2) {
|
|
stat = acquirePoint(ptTemp, m_ptStart);
|
|
if (stat == AcEdJig::kNormal) {
|
|
m_osShape=CDrawWallDlg::g_bAutoSnap? AutoSnapWall(ptTemp, &m_ptStart):0;
|
|
if (m_nFlag==0 || m_nFlag==1) { //求终点
|
|
if (m_pDrawEnt->Is(CURVE_LINE) && m_nFlag==0 && g_bModelNumber && !m_osShape) {
|
|
//模数打开
|
|
double nAng=ads_angle(m_ptStart, ptTemp);
|
|
double nSize; //=GetModelNumber(lstSize, );
|
|
nSize = AS_INT(ads_distance(m_ptStart, ptTemp)/g_nWallStep)*g_nWallStep;
|
|
if (nSize>0)
|
|
ads_polar(m_ptStart, nAng, nSize, ptTemp);
|
|
}
|
|
|
|
if (ads_distance(ptTemp, m_ptEnd)>_DIST_SNAP)
|
|
m_ptEnd=ptTemp;
|
|
else return AcEdJig::kNoChange;
|
|
} else if (m_nFlag==2) {
|
|
if (ptTemp.Distance(m_ptAny)>_DIST_SNAP)
|
|
m_ptAny=ptTemp;
|
|
else return AcEdJig::kNoChange;
|
|
}
|
|
}
|
|
} else if (m_nFlag==3) { //已知起点终点, 待定半径
|
|
double nTemp;
|
|
stat = acquireDist(nTemp, m_ptStart);
|
|
if (fabs(nTemp-m_nRadius)>_DIST_SNAP) {
|
|
m_nRadius=nTemp;
|
|
} else if (stat==AcEdJig::kNormal) {
|
|
return AcEdJig::kNoChange;
|
|
}
|
|
}
|
|
|
|
|
|
return stat;
|
|
}
|
|
|
|
|
|
// 更新实体数据
|
|
Adesk::Boolean XDrawWallEdJig::Update()
|
|
{
|
|
extern TARCH_IMPEXP BOOL g_bRevWallFlag;
|
|
m_pDrawEnt->m_osShape = AsOsnapMask(m_osShape);
|
|
if (m_pDlg) {
|
|
m_pDrawEnt->SetWidth(0, m_pDlg->GetLeftWidth());
|
|
m_pDrawEnt->SetWidth(1, m_pDlg->GetRightWidth());
|
|
} else {
|
|
m_pDrawEnt->SetWidth(0, g_lWallWidth);
|
|
m_pDrawEnt->SetWidth(1, g_rWallWidth);
|
|
}
|
|
XCurveSegment seg;
|
|
if (m_nFlag==0) {
|
|
if (m_ptStart==m_ptEnd)
|
|
return Adesk::kFalse;
|
|
seg=XLine(m_ptStart, m_ptEnd);
|
|
m_pDrawEnt->m_ptLoc = m_ptEnd;
|
|
} else if (m_nFlag==1) {//已知起点,弧上任意点,待定终点
|
|
if (m_ptEnd==m_ptStart || m_ptEnd==m_ptAny)
|
|
return Adesk::kFalse;
|
|
seg=XArc(m_ptStart, m_ptAny, m_ptEnd);
|
|
m_pDrawEnt->m_ptLoc = m_ptEnd;
|
|
} else if (m_nFlag==2) { //已知起点终点, 待定弧上一点
|
|
if (m_ptAny==m_ptStart || m_ptEnd==m_ptAny ||
|
|
(m_ptAny&XLine(m_ptStart, m_ptEnd))!=PR_OUTSIDE)
|
|
return Adesk::kFalse;
|
|
seg=XArc(m_ptStart, m_ptAny, m_ptEnd);
|
|
if (seg.StartPoint().Distance(m_ptStart)>seg.StartPoint().Distance(m_ptEnd)) {
|
|
//m_pDrawEnt->SetWidth(0, g_rWallWidth);
|
|
//m_pDrawEnt->SetWidth(1, g_lWallWidth);
|
|
g_bRevWallFlag=TRUE;
|
|
double lWidth=m_pDrawEnt->GetWidth(0);
|
|
double rWidth=m_pDrawEnt->GetWidth(1);
|
|
m_pDrawEnt->SetWidth(0, rWidth);
|
|
m_pDrawEnt->SetWidth(1, lWidth);
|
|
} else {
|
|
//m_pDrawEnt->SetWidth(0, g_lWallWidth);
|
|
//m_pDrawEnt->SetWidth(1, g_rWallWidth);
|
|
g_bRevWallFlag=FALSE;
|
|
}
|
|
m_pDrawEnt->m_ptLoc = m_ptAny;
|
|
} else if (m_nFlag==3) {
|
|
double nChordLen=ads_distance(m_ptStart, m_ptEnd);
|
|
if (nChordLen<2.0*fabs(m_nRadius)-1.0E-6) {
|
|
double bulge=2.0*asin(nChordLen/2.0/m_nRadius);
|
|
seg=XDirectionCurve(m_ptStart, m_ptEnd, bulge, LS_FINITE).GetCurve();
|
|
if (seg.StartPoint().Distance(m_ptStart)>seg.StartPoint().Distance(m_ptEnd)) {
|
|
g_bRevWallFlag=TRUE;
|
|
double lWidth=m_pDrawEnt->GetWidth(0);
|
|
double rWidth=m_pDrawEnt->GetWidth(1);
|
|
m_pDrawEnt->SetWidth(0, rWidth);
|
|
m_pDrawEnt->SetWidth(1, lWidth);
|
|
} else {
|
|
//m_pDrawEnt->SetWidth(0, g_lWallWidth);
|
|
//m_pDrawEnt->SetWidth(1, g_rWallWidth);
|
|
}
|
|
} else {
|
|
return Adesk::kFalse;
|
|
}
|
|
} else {
|
|
return Adesk::kFalse;
|
|
}
|
|
*(XCurveSegment *)m_pDrawEnt = seg;
|
|
|
|
return Adesk::kTrue;
|
|
}
|
|
|
|
AcDbEntity* XDrawWallEdJig::entity() const
|
|
{
|
|
return m_pDrawEnt;
|
|
}
|
|
|
|
|
|
// 给定起点, 终点进行弧上一点拖动绘制弧
|
|
int DragDrawArc_SEP(CDrawWallDlg *pDlg, const XPoint &ptStart, const XPoint &ptEnd, const TCHAR *prompt, XPoint &ptAny, const TCHAR *kword, int *kwordId)
|
|
{
|
|
XDrawWallEdJig jig(pDlg);
|
|
#if ADS>15
|
|
jig.SetCurGrip(1);
|
|
#endif
|
|
jig.m_pszKeyword = kword;
|
|
jig.m_pszPrompt = prompt;
|
|
jig.m_ptStart = ptStart;
|
|
jig.m_ptEnd=ptEnd;
|
|
Midpoint(ptStart, ptEnd, jig.m_ptAny);
|
|
//jig.m_bIsDouble = bDouble;
|
|
jig.m_nFlag=2;
|
|
LAB_REPEAT:
|
|
jig.doIt();
|
|
int nRetCode=jig.GetRetCode(kwordId);
|
|
if (nRetCode==RTNORM && (jig.m_ptAny&XLine(ptStart, ptEnd))!=PR_OUTSIDE)
|
|
goto LAB_REPEAT;
|
|
if (nRetCode==RTNORM)
|
|
ptAny = jig.m_ptAny;
|
|
return nRetCode;
|
|
}
|
|
|
|
|
|
// 给定起点, 弧上一点, 进行终点拖动绘制弧
|
|
int DragDrawArc_SPE(CDrawWallDlg * pDlg, const XPoint &ptStart, const XPoint &ptAny, const TCHAR *prompt, XPoint &ptEnd, const TCHAR *kword, int *kwordId)
|
|
{
|
|
XDrawWallEdJig jig(pDlg);
|
|
#if ADS>15
|
|
jig.SetCurGrip(-1);
|
|
#endif
|
|
jig.m_pszKeyword = kword;
|
|
jig.m_pszPrompt = prompt;
|
|
jig.m_ptStart = ptStart;
|
|
jig.m_ptAny=ptAny;
|
|
//jig.m_bIsDouble = bDouble;
|
|
jig.m_nFlag=1;
|
|
|
|
jig.doIt();
|
|
int nRetCode=jig.GetRetCode(kwordId);
|
|
if (nRetCode==RTNORM)
|
|
ptEnd = jig.m_ptEnd;
|
|
return nRetCode;
|
|
}
|
|
|
|
|
|
// 给定起点, 终点进行拖动半径绘制弧
|
|
int DragDrawArc_SER(CDrawWallDlg *pDlg, const XPoint &ptStart, const XPoint &ptEnd, const TCHAR *prompt, double *nRadius, const TCHAR *kword, int *kwordId)
|
|
{
|
|
XDrawWallEdJig jig(pDlg);
|
|
#if ADS>15
|
|
jig.SetCurGrip(-1);
|
|
#endif
|
|
jig.m_pszKeyword = kword;
|
|
jig.m_pszPrompt = prompt;
|
|
jig.m_ptStart = ptStart;
|
|
jig.m_ptEnd=ptEnd;
|
|
//jig.m_bIsDouble = bDouble;
|
|
jig.m_nFlag=3;
|
|
jig.doIt();
|
|
|
|
int nRetCode=jig.GetRetCode(kwordId);
|
|
if (nRetCode==RTNORM)
|
|
*nRadius = jig.m_nRadius;
|
|
return nRetCode;
|
|
}
|
|
|
|
|
|
// 给定起点, 终点进行拖动半径绘制弧
|
|
int DragDrawLine(CDrawWallDlg *pDlg, XPoint &ptStart, const TCHAR *prompt, XPoint &ptEnd, const TCHAR *kword, int *kwordId, BOOL *bDiscontinue)
|
|
{
|
|
XDrawWallEdJig jig(pDlg);
|
|
jig.m_pszKeyword = kword;
|
|
jig.m_pszPrompt = prompt;
|
|
jig.m_ptStart = ptStart;
|
|
xg_getvar(_T("LASTPOINT"), jig.m_ptEnd);
|
|
jig.m_ptEnd=Ucs2Wcs(jig.m_ptEnd);
|
|
//jig.m_bIsDouble = bDouble;
|
|
jig.m_nFlag=0;
|
|
jig.doIt();
|
|
|
|
int nRetCode=jig.GetRetCode(kwordId);
|
|
if (nRetCode==RTNORM) {
|
|
ptEnd = jig.m_ptEnd;
|
|
if (bDiscontinue)
|
|
*bDiscontinue=IsOnWallBase(ptEnd);
|
|
}
|
|
return nRetCode;
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
// 获取输入点, 自动对墙体/轴线进行模糊捕捉
|
|
int OsGetPointWall(double *ptFrom, const TCHAR *prompt, XPoint &pt, const TCHAR *kword=NULL, int *kwordId=NULL, BOOL *bDiscontinue=NULL)
|
|
{
|
|
XOsPointEdJig jig;
|
|
jig.m_pszKeyword = kword;
|
|
jig.m_pszPrompt = prompt;
|
|
jig.m_ptTo = pt;
|
|
jig.m_osShape=0;
|
|
jig.m_nUsageFlag=ptFrom!=NULL;
|
|
if (ptFrom)
|
|
jig.m_ptFrom = ptFrom;
|
|
jig.doIt();
|
|
|
|
int nKeyword;
|
|
int & kid=kwordId? *kwordId : nKeyword;
|
|
int nRetCode=jig.GetRetCode(&kid);
|
|
if (nRetCode==RTNORM) {
|
|
pt = jig.m_ptTo;
|
|
if (bDiscontinue)
|
|
*bDiscontinue=IsOnWallBase(pt);
|
|
}
|
|
return nRetCode;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
// 获取输入点, 自动对墙体/轴线进行模糊捕捉
|
|
int OsGetCornerWall(double *ptFrom, const TCHAR *prompt, XPoint &pt, const TCHAR *kword=NULL, int *kwordId=NULL)
|
|
{
|
|
XPushVar<int> vOrthoMode(_T("ORTHOMODE"), 0);
|
|
ASSERT(ptFrom);
|
|
XOsPointEdJig jig;
|
|
jig.m_pszKeyword = kword;
|
|
jig.m_pszPrompt = prompt;
|
|
jig.m_ptTo = pt;
|
|
jig.m_osShape=0;
|
|
jig.m_nUsageFlag=2;
|
|
jig.m_ptFrom = ptFrom;
|
|
jig.doIt();
|
|
|
|
int nKeyword;
|
|
int & kid=kwordId? *kwordId : nKeyword;
|
|
int nRetCode=jig.GetRetCode(&kid);
|
|
if (nRetCode==RTNORM)
|
|
pt = jig.m_ptTo;
|
|
return nRetCode;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// 门窗的绘制
|
|
|
|
/////////////////////////////////////////////////////
|
|
// 为了拖曳门窗和绘制Osnap点而构造临时实体
|
|
|
|
class TDbOpeningJig:public AcDbEntity
|
|
{
|
|
public:
|
|
TDbOpening *m_pOpening;
|
|
public:
|
|
TDbOpeningJig() {m_pOpening=NULL;}
|
|
~TDbOpeningJig()
|
|
{
|
|
if (m_pOpening!=NULL)
|
|
delete m_pOpening;
|
|
}
|
|
void SetOpening(TDbOpening*pOpening)
|
|
{
|
|
if (m_pOpening!=NULL)
|
|
delete m_pOpening;
|
|
m_pOpening=(TDbOpening*)pOpening->clone();
|
|
m_pOpening->InitHardPointerId();
|
|
|
|
// add by xly on 1103302设置转角布局
|
|
m_pOpening->SetLayoutRotation(Ucs2Wcs(0));
|
|
TMasterProperties prop;
|
|
prop.SetFrom(pOpening);
|
|
prop.SetTo(this);
|
|
}
|
|
Adesk::Boolean subWorldDraw(AcGiWorldDraw *mode);
|
|
void subViewportDraw(AcGiViewportDraw *mode);
|
|
void SetParameters(const TDbWall *pWall, const XPoint &ptOnWall, const XPoint &ptQuadrant, UINT nInsMode);
|
|
};
|
|
|
|
void TDbOpeningJig::SetParameters(const TDbWall *pWall, const XPoint &ptOnWall, const XPoint &ptQuadrant, UINT nInsMode)
|
|
{
|
|
//SHORT nShiftState=GetKeyState(VK_SHIFT);
|
|
BOOL bShiftPressed = g_bShiftToggle; //(nShiftState&256)!=0;
|
|
|
|
XPoint ptLoc;
|
|
pWall->GetOpeningLocation(ptOnWall, m_pOpening->GetKind(), m_pOpening->GetWidth(), ptLoc);
|
|
ptLoc.z = m_pOpening->GetLocation().z;
|
|
m_pOpening->SetLocation(ptLoc);
|
|
|
|
// add by xly on 110216 8.5需求修改矩形洞,增加是否穿透墙体设置
|
|
//m_pOpening->SetThickness(m_pOpening->GetKind()==TOpeningData::OP_HOLE? pWall->GetWidth() : pWall->GetWidth()/2.0);
|
|
if (m_pOpening->GetKind()==TOpeningData::OP_HOLE)
|
|
{
|
|
m_pOpening->SetThickness(m_pOpening->GetThickness());
|
|
}
|
|
else
|
|
{
|
|
m_pOpening->SetThickness(pWall->GetWidth()/2.0);
|
|
}
|
|
m_pOpening->SetRotation(pWall->Direction(ptOnWall));
|
|
if (m_pOpening->isKindOf(TDbGroupOpening::desc()))
|
|
{
|
|
((TDbGroupOpening*)m_pOpening)->Update(false);
|
|
}
|
|
|
|
ads_real nAng=CT_std_angle(ads_angle(m_pOpening->GetLocation(), ptQuadrant)-m_pOpening->GetRotation());
|
|
if (nAng>=0.0 && nAng<PI) m_pOpening->SetQuadrant(bShiftPressed? 1:0);
|
|
else m_pOpening->SetQuadrant(bShiftPressed? 2:3);
|
|
|
|
m_pOpening->SetLabelPos(m_pOpening->GetDefaultLabPos());
|
|
}
|
|
|
|
|
|
Adesk::Boolean TDbOpeningJig::subWorldDraw(AcGiWorldDraw *mode)
|
|
{
|
|
if (!m_pOpening->GetWallId())
|
|
return Adesk::kTrue; //Draw nothing
|
|
|
|
return Adesk::kFalse;;
|
|
}
|
|
|
|
|
|
void TDbOpeningJig::subViewportDraw(AcGiViewportDraw *mode)
|
|
{
|
|
// modify by xly on 110217 增加同时绘制多个门窗时提供预览
|
|
//m_pOpening->subViewportDraw(mode);
|
|
//DrawOsnapShape(mode, m_pOpening->GetLocation(), AcDb::kOsMaskNear);
|
|
int nNums = CInsertOpeningDlg::g_pCurDlg->GetOpeningNums();
|
|
if (CInsertOpeningDlg::g_nInsertMode==7)
|
|
{
|
|
nNums = 1;
|
|
}
|
|
if (nNums>1)
|
|
{
|
|
XPoint ptLoc = m_pOpening->GetLocation(),
|
|
ptPos;
|
|
double dWidth = m_pOpening->GetWidth();
|
|
double dAngle = m_pOpening->GetRotation();
|
|
double dDist(0.0);
|
|
if (nNums%2 == 0)// 偶数个门
|
|
{
|
|
for (int i=0; i<nNums; i++)
|
|
{
|
|
if (i==0)
|
|
{
|
|
dDist += dWidth/2.0;
|
|
}
|
|
else if (i%2 == 0)
|
|
{
|
|
dDist += dWidth;
|
|
}
|
|
ads_polar(ptLoc,dAngle,dDist,ptPos);
|
|
TDbOpening *pOpening = (TDbOpening*)m_pOpening->clone();
|
|
pOpening->SetLocation(ptPos);
|
|
pOpening->m_ptLabel=pOpening->GetDefaultLabPos();
|
|
pOpening->SetLayoutRotation(Ucs2Wcs(0));
|
|
pOpening->subViewportDraw(mode);
|
|
dAngle = PI+dAngle;
|
|
}
|
|
}
|
|
else// 奇数个门
|
|
{
|
|
m_pOpening->subViewportDraw(mode);
|
|
for (int i=1; i<nNums; i++)
|
|
{
|
|
if (i%2 != 0)
|
|
{
|
|
dDist += dWidth;
|
|
}
|
|
ads_polar(ptLoc,dAngle,dDist,ptPos);
|
|
TDbOpening *pOpening = (TDbOpening*)m_pOpening->clone();
|
|
pOpening->SetLocation(ptPos);
|
|
pOpening->m_ptLabel=pOpening->GetDefaultLabPos();
|
|
pOpening->SetLayoutRotation(Ucs2Wcs(0));
|
|
pOpening->subViewportDraw(mode);
|
|
dAngle = PI+dAngle;
|
|
}
|
|
}
|
|
DrawOsnapShape(mode, ptLoc, AcDb::kOsMaskNear);
|
|
}
|
|
else
|
|
{
|
|
m_pOpening->subViewportDraw(mode);
|
|
DrawOsnapShape(mode, m_pOpening->GetLocation(), AcDb::kOsMaskNear);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////
|
|
// 拖曳墙体, 并确定半径或者顶点
|
|
class XDrawOpeningEdJig : public TEdJig //modified by whl
|
|
{
|
|
public:
|
|
XDrawOpeningEdJig(TDbOpening*pOpening);
|
|
virtual ~XDrawOpeningEdJig();
|
|
void doIt();
|
|
virtual DragStatus sampler();
|
|
virtual Adesk::Boolean Update();
|
|
virtual AcDbEntity* entity() const;
|
|
|
|
#if ADS>15
|
|
virtual void CreateGrip();
|
|
virtual Acad::ErrorStatus EntityToDim(long iGrip,long iDim);
|
|
virtual Acad::ErrorStatus DimToEntity(long iGrip,long iDim,double newValue);
|
|
#endif
|
|
|
|
int GetRetCode(int *kwordId=NULL) const;
|
|
|
|
XPoint m_ptCursor, m_ptOnWall;
|
|
AcDbObjectId m_idWall;
|
|
int m_nRetCode; //返回码
|
|
const TCHAR *m_pszPrompt; //提示信息
|
|
const TCHAR *m_pszKeyword; //关键字
|
|
TDbOpeningJig *m_pDrawEnt; //临时实体
|
|
//CInsertOpeningDlg *m_pDataDlg; replaced by CInsertOpeningDlg::g_pCurDlg
|
|
};
|
|
/* ========================================================== */
|
|
#if ADS>15
|
|
void XDrawOpeningEdJig::CreateGrip()
|
|
{
|
|
SetGripNum(1);
|
|
GetGrip(0)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength));//前垛距
|
|
GetGrip(0)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength));//后垛距
|
|
}
|
|
Acad::ErrorStatus XDrawOpeningEdJig::EntityToDim(long iGrip,long iDim)
|
|
{
|
|
TDbOpeningJig *pEnt=m_pDrawEnt;
|
|
XCurveSegment wall;
|
|
if (!pEnt->m_pOpening->GetCenterCurve(wall))//中线
|
|
return Acad::eInvalidInput;
|
|
|
|
TDbGripDim*pDim=GetGripDim(iGrip,iDim);
|
|
if (pDim==NULL)
|
|
return Acad::eInvalidInput;
|
|
switch(iGrip)
|
|
{
|
|
case 0:
|
|
switch(iDim)
|
|
{
|
|
case 0://前垛距
|
|
{
|
|
XCurveSegment seg;
|
|
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
|
|
XPoint pt;
|
|
if (pEnt->m_pOpening->GetNeighbourPoint(pt,true))
|
|
{
|
|
XPoint ptSideStart,ptSideEnd;
|
|
pEnt->m_pOpening->GetSidePoints(ptSideStart, ptSideEnd);
|
|
wall.ProjectToMe(pt,pt);
|
|
wall.ProjectToMe(ptSideStart,ptSideStart);
|
|
pDistDim->SetData(pt.AsAcGePoint3d(),ptSideStart.AsAcGePoint3d(),1200);
|
|
}
|
|
}
|
|
break;
|
|
case 1://后垛距
|
|
{
|
|
XCurveSegment seg;
|
|
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
|
|
XPoint pt;
|
|
if (pEnt->m_pOpening->GetNeighbourPoint(pt,false))
|
|
{
|
|
XPoint ptSideStart,ptSideEnd;
|
|
pEnt->m_pOpening->GetSidePoints(ptSideStart, ptSideEnd);
|
|
wall.ProjectToMe(pt,pt);
|
|
wall.ProjectToMe(ptSideEnd,ptSideEnd);
|
|
pDistDim->SetData(ptSideEnd.AsAcGePoint3d(),pt.AsAcGePoint3d(),1200);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
return Acad::eNotImplementedYet;
|
|
}
|
|
break;
|
|
default:
|
|
return Acad::eNotImplementedYet;
|
|
}
|
|
return Acad::eOk;
|
|
}
|
|
Acad::ErrorStatus XDrawOpeningEdJig::DimToEntity(long iGrip,long iDim,double newValue)
|
|
{
|
|
XCurveSegment wall;
|
|
m_pDrawEnt->m_pOpening->GetCenterCurve(wall);
|
|
XPoint vt=wall.EndPoint()-wall.StartPoint();
|
|
vt.Normalize();
|
|
switch(iGrip)
|
|
{
|
|
case 0:
|
|
switch(iDim)
|
|
{
|
|
case 0://后垛距
|
|
{
|
|
XCurveSegment seg;
|
|
XPoint pt,pt1,pt2;
|
|
m_pDrawEnt->m_pOpening->GetNeighbourPoint(pt,true);
|
|
wall.ProjectToMe(pt,pt);
|
|
m_pDrawEnt->m_pOpening->GetSidePoints(pt1,pt2);
|
|
double oldValue=pt.Distance2d(pt1.AsAcGePoint3d());
|
|
vt*=(newValue-oldValue);
|
|
m_pDrawEnt->m_pOpening->SetLocation(m_pDrawEnt->m_pOpening->GetLocation()+vt);
|
|
m_pDrawEnt->m_pOpening->SetLabelPos(m_pDrawEnt->m_pOpening->GetDefaultLabPos());//add by whl on 060301
|
|
}
|
|
break;
|
|
case 1://后垛距
|
|
{
|
|
XCurveSegment seg;
|
|
XPoint pt,pt1,pt2;
|
|
m_pDrawEnt->m_pOpening->GetNeighbourPoint(pt,false);
|
|
wall.ProjectToMe(pt,pt);
|
|
m_pDrawEnt->m_pOpening->GetSidePoints(pt1,pt2);
|
|
double oldValue=pt.Distance2d(pt2.AsAcGePoint3d());
|
|
vt*=(oldValue-newValue);
|
|
m_pDrawEnt->m_pOpening->SetLocation(m_pDrawEnt->m_pOpening->GetLocation()+vt);
|
|
m_pDrawEnt->m_pOpening->SetLabelPos(m_pDrawEnt->m_pOpening->GetDefaultLabPos());//add by whl on 060301
|
|
}
|
|
break;
|
|
default:
|
|
return Acad::eNotImplementedYet;
|
|
}
|
|
break;
|
|
default:
|
|
return Acad::eNotImplementedYet;
|
|
}
|
|
return Acad::eOk;
|
|
}
|
|
#endif
|
|
|
|
// 转换成ADS代码
|
|
int XDrawOpeningEdJig::GetRetCode(int *kwordId) const
|
|
{
|
|
int ret = m_nRetCode;
|
|
if (ret == AcEdJig::kCancel)
|
|
ret = RTCAN;
|
|
else if (ret == AcEdJig::kNull)
|
|
ret = RTNONE;
|
|
else if (ret <= 0)
|
|
ret = RTNORM;
|
|
else {
|
|
if (kwordId) *kwordId = ret;
|
|
ret = RTKWORD;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
XDrawOpeningEdJig::XDrawOpeningEdJig(TDbOpening*pOpening)//modified by whl
|
|
:m_pszKeyword(NULL), m_pszPrompt(NULL), m_pDrawEnt(NULL), m_nRetCode(0)//,m_pDataDlg(NULL)
|
|
{
|
|
m_pDrawEnt = new TDbOpeningJig;
|
|
m_pDrawEnt->SetOpening(pOpening);
|
|
#if ADS>15
|
|
CreateGrip();
|
|
#endif
|
|
}
|
|
|
|
XDrawOpeningEdJig::~XDrawOpeningEdJig()
|
|
{
|
|
if (m_pDrawEnt)
|
|
delete m_pDrawEnt;
|
|
}
|
|
|
|
// 开始执行拖动
|
|
void XDrawOpeningEdJig::doIt()
|
|
{
|
|
m_pDrawEnt->m_pOpening->setLayer(m_pDrawEnt->m_pOpening->GetDefaultLayer());
|
|
setDispPrompt(m_pszPrompt);
|
|
if (m_pszKeyword) {
|
|
INITGET_BEG(-1, m_pszKeyword);
|
|
try {
|
|
m_nRetCode = drag();
|
|
} catch(...) {
|
|
m_nRetCode=AcEdJig::kCancel;
|
|
}
|
|
INITGET_END();
|
|
} else {
|
|
try {
|
|
m_nRetCode = drag();
|
|
} catch(...) {
|
|
m_nRetCode=AcEdJig::kCancel;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// 反馈
|
|
AcEdJig::DragStatus XDrawOpeningEdJig::sampler()//modified by whl
|
|
{
|
|
double nIncStep=g_nWinStep;
|
|
DragStatus stat;
|
|
|
|
setUserInputControls((UserInputControls)
|
|
(AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted
|
|
| AcEdJig::kNoNegativeResponseAccepted
|
|
| AcEdJig::kNoZeroResponseAccepted));
|
|
|
|
if (m_pszKeyword) setKeywordList(m_pszKeyword);
|
|
XPoint ptTemp;
|
|
stat = acquirePoint(ptTemp);
|
|
if (stat == AcEdJig::kNormal) {
|
|
if (ptTemp.Distance(m_ptCursor)>_DIST_SNAP) {
|
|
m_ptCursor=ptTemp;
|
|
m_idWall=SnapOnWall(ptTemp);
|
|
if (!!m_idWall) {
|
|
OPENOBJ_BEGIN(m_idWall, AcDb::kForRead, TDbWall, pWall);
|
|
ASSERT(pWall);
|
|
if (pWall->Is(CURVE_LINE) && m_pDrawEnt->m_pOpening->GetKind()==TOpeningData::OP_ARCWIN)
|
|
return AcEdJig::kNoChange;
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
m_ptOnWall=ptTemp;
|
|
if (!!m_idWall && g_bModelNumber && CInsertOpeningDlg::g_pCurDlg->GetInsertMode()==ID_FREE_INSERT) {
|
|
OPENOBJ_BEGIN(m_idWall, AcDb::kForRead, TDbWall, pWall);
|
|
ASSERT(pWall);
|
|
XPoly2D poly(0);
|
|
if (pWall->GetKey3Seg(m_ptOnWall, m_pDrawEnt->m_pOpening->GetWidth(), poly)) {
|
|
ASSERT(poly.TotalSegments()==3);
|
|
XCurveSegment segFirst, segMid, segLast;
|
|
poly.Nth(0, segFirst);
|
|
poly.Nth(1, segMid);
|
|
poly.Nth(2, segLast);
|
|
SHORT nControlState=g_bCtrlToggle; //GetKeyState(VK_CONTROL);
|
|
bool bCtrlPressed = (nControlState&256)!=0;
|
|
if (!bCtrlPressed) {
|
|
double nModelFirst=AS_INT(segFirst.GetLength()/nIncStep)*nIncStep;
|
|
double nDistPos=segMid.GetLength()/2.0 + nModelFirst - segFirst.GetLength();
|
|
if (nDistPos>=0 && nDistPos<=segMid.GetLength()) {
|
|
XPointDir2d ptNewPos;
|
|
segMid.Polar(nDistPos, ptNewPos);
|
|
m_ptOnWall=ptNewPos;
|
|
}
|
|
} else {
|
|
double nModelLast=AS_INT(segLast.GetLength()/nIncStep)*nIncStep;
|
|
double nDistPos=segMid.GetLength()/2.0 + nModelLast - segLast.GetLength();
|
|
if (nDistPos>=0 && nDistPos<=segMid.GetLength()) {
|
|
XPointDir2d ptNewPos;
|
|
segMid.Polar(nDistPos, ptNewPos, FALSE);
|
|
m_ptOnWall=ptNewPos;
|
|
}
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
} else {
|
|
return AcEdJig::kNoChange;
|
|
}
|
|
}
|
|
|
|
return stat;
|
|
}
|
|
|
|
// 更新实体数据
|
|
Adesk::Boolean XDrawOpeningEdJig::Update()//modidfied by whl
|
|
{
|
|
//add by whl
|
|
if (CInsertOpeningDlg::g_pCurDlg!=NULL&&
|
|
CInsertOpeningDlg::g_pCurDlg->IsWindowVisible())
|
|
{
|
|
TDbOpening*pOpening=CInsertOpeningDlg::g_pCurDlg->NewOpening();
|
|
m_pDrawEnt->SetOpening(pOpening);
|
|
delete pOpening;
|
|
}
|
|
|
|
if (!m_idWall) {
|
|
m_pDrawEnt->m_pOpening->SetWallId(m_idWall);
|
|
return Adesk::kTrue;
|
|
}
|
|
OPENOBJ_BEGIN(m_idWall, AcDb::kForRead, TDbWall, pWall);
|
|
if (pWall) {
|
|
if (m_pDrawEnt->m_pOpening->GetKind()==TOpeningData::OP_ARCWIN) {
|
|
if (pWall->Is(CURVE_ARC))
|
|
m_pDrawEnt->m_pOpening->SetWallId(m_idWall);
|
|
} else {
|
|
m_pDrawEnt->m_pOpening->SetWallId(m_idWall);
|
|
}
|
|
m_pDrawEnt->SetParameters(pWall, m_ptOnWall, m_ptCursor,
|
|
CInsertOpeningDlg::g_pCurDlg?CInsertOpeningDlg::g_pCurDlg->GetInsertMode():0);
|
|
}
|
|
OPENOBJ_END();
|
|
return Adesk::kTrue;
|
|
}
|
|
|
|
AcDbEntity* XDrawOpeningEdJig::entity() const
|
|
{
|
|
return m_pDrawEnt;
|
|
}
|
|
|
|
AcDbObjectId GetOpeingLocation(const TCHAR *prompt, TDbOpening *&pWin,bool bFreeInsert)//modified by whl
|
|
{
|
|
int nOsMode=0;
|
|
xg_getvar(_T("OSMODE"), &nOsMode);
|
|
nOsMode |= 0x4000;
|
|
XPushVar<int> osmode(_T("OSMODE"), nOsMode);
|
|
AcDbObjectId idWall;
|
|
|
|
XDrawOpeningEdJig jig(pWin);
|
|
#if ADS>15
|
|
if (!bFreeInsert)
|
|
jig.SetCurGrip(-1);
|
|
#endif
|
|
jig.m_pszPrompt = prompt;
|
|
|
|
LAB_REINPUT:
|
|
jig.doIt();
|
|
|
|
int kwordId;
|
|
int nRetCode=jig.GetRetCode(&kwordId);
|
|
if (nRetCode==RTNORM) {
|
|
idWall = jig.m_idWall;
|
|
if (!!idWall) {
|
|
delete pWin;
|
|
pWin=jig.m_pDrawEnt->m_pOpening;
|
|
jig.m_pDrawEnt->m_pOpening=NULL;
|
|
|
|
//成功的添加了门窗, 那么把最近一次的参数写入注册表
|
|
CInsertOpeningDlg::g_pCurDlg->UpdateOpening(*pWin, TRUE);
|
|
CInsertOpeningDlg::g_pCurDlg->WriteParamToRegistry();
|
|
CInsertOpeningDlg::g_pCurDlg->SetupLabelList();
|
|
} else {
|
|
goto LAB_REINPUT;
|
|
}
|
|
}
|
|
return idWall;
|
|
}
|
|
|
|
|
|
|
|
// add by lgy 20120521,为智能插入门窗jig时的临时实体
|
|
class TDbOpeningAptJig: public AcDbEntity
|
|
{
|
|
public:
|
|
// 门窗对象参数
|
|
TDbOpening *m_pOpening;
|
|
|
|
// 示意短线所用参数
|
|
XCurveSegment m_segWall;
|
|
double m_dWallWidth;
|
|
int m_nLineColor;
|
|
|
|
BOOL m_bShow;
|
|
|
|
public:
|
|
TDbOpeningAptJig()
|
|
{
|
|
m_pOpening = NULL;
|
|
m_bShow = FALSE;
|
|
m_dWallWidth = 0.0;
|
|
m_nLineColor = 6;
|
|
}
|
|
|
|
~TDbOpeningAptJig()
|
|
{
|
|
if (m_pOpening != NULL)
|
|
{
|
|
delete m_pOpening;
|
|
}
|
|
}
|
|
|
|
void SetOpening(TDbOpening *pOpening)
|
|
{
|
|
if (m_pOpening != NULL)
|
|
{
|
|
delete m_pOpening;
|
|
}
|
|
|
|
m_pOpening = (TDbOpening*)pOpening->clone();
|
|
m_pOpening->InitHardPointerId();
|
|
m_pOpening->SetLayoutRotation(Ucs2Wcs(0));
|
|
m_pOpening->setLayer(m_pOpening->GetDefaultLayer());
|
|
|
|
TMasterProperties prop;
|
|
prop.SetFrom(pOpening);
|
|
prop.SetTo(this);
|
|
}
|
|
|
|
void SetOpeningParameters(const TDbWall *pWall, const XPoint &ptOnWall, const XPoint &ptQuadrant, UINT nInsMode);
|
|
void SetLineParameters(const AcDbObjectId &wallId, const XCurveSegment &cvSeg, int nColor);
|
|
|
|
public:
|
|
Adesk::Boolean subWorldDraw(AcGiWorldDraw *mode);
|
|
void subViewportDraw(AcGiViewportDraw *mode);
|
|
};
|
|
|
|
void TDbOpeningAptJig::SetLineParameters(const AcDbObjectId &wallId, const XCurveSegment &cvSeg, int nColor)
|
|
{
|
|
m_segWall = cvSeg;
|
|
m_nLineColor = nColor;
|
|
|
|
OPENOBJ_BEGIN(wallId, AcDb::kForRead, TDbWall, pWall);
|
|
if (pWall != NULL)
|
|
{
|
|
XCurveSegment segGeom;
|
|
segGeom = pWall->OffsetGeomCenter(LS_INFINITE, TRUE);
|
|
|
|
XPoint ptStart, ptEnd;
|
|
if (segGeom.ProjectToMe(cvSeg.StartPoint(), ptStart)==RTNORM &&
|
|
segGeom.ProjectToMe(cvSeg.EndPoint(), ptEnd)==RTNORM)
|
|
m_segWall.SetPoints(ptStart, ptEnd);
|
|
|
|
m_dWallWidth = pWall->GetWidth(4);
|
|
pWall->close();
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
|
|
void TDbOpeningAptJig::SetOpeningParameters(const TDbWall *pWall, const XPoint &ptOnWall, const XPoint &ptQuadrant, UINT nInsMode)
|
|
{
|
|
BOOL bShiftPressed = g_bShiftToggle;
|
|
|
|
XPoint ptLoc;
|
|
pWall->GetOpeningLocation(ptOnWall, m_pOpening->GetKind(), m_pOpening->GetWidth(), ptLoc);
|
|
ptLoc.z = m_pOpening->GetLocation().z;
|
|
m_pOpening->SetLocation(ptLoc);
|
|
|
|
if (m_pOpening->GetKind() == TOpeningData::OP_HOLE)
|
|
{
|
|
m_pOpening->SetThickness(m_pOpening->GetThickness());
|
|
}
|
|
else
|
|
{
|
|
m_pOpening->SetThickness(pWall->GetWidth()/2.0);
|
|
}
|
|
|
|
m_pOpening->SetRotation(pWall->Direction(ptOnWall));
|
|
if (m_pOpening->isKindOf(TDbGroupOpening::desc()))
|
|
{
|
|
((TDbGroupOpening*)m_pOpening)->Update(false);
|
|
}
|
|
|
|
ads_real nAng = CT_std_angle(ads_angle(m_pOpening->GetLocation(), ptQuadrant)-m_pOpening->GetRotation());
|
|
if (nAng>=0.0 && nAng<PI)
|
|
{
|
|
m_pOpening->SetQuadrant(bShiftPressed? 1:0);
|
|
}
|
|
else
|
|
{
|
|
m_pOpening->SetQuadrant(bShiftPressed? 2:3);
|
|
}
|
|
|
|
m_pOpening->SetLabelPos(m_pOpening->GetDefaultLabPos());
|
|
}
|
|
|
|
Adesk::Boolean TDbOpeningAptJig::subWorldDraw(AcGiWorldDraw *mode)
|
|
{
|
|
if (!m_pOpening->GetWallId())
|
|
{
|
|
return Adesk::kTrue;
|
|
}
|
|
|
|
if (m_bShow)
|
|
{
|
|
double dPLWidth = 0.5 * DocGetPScale(); // 默认50线宽
|
|
|
|
TADSGePointDir2d ptDir2d;
|
|
double dLen = m_segWall.GetLength();
|
|
m_segWall.Polar(dLen/3, ptDir2d);
|
|
|
|
XPoint ptTmp1, ptTmp2;
|
|
ptTmp1 = ptDir2d.AsAcGePoint3d();
|
|
|
|
AcDbPolyline pline1, pline2;
|
|
ads_polar(ptTmp1, ptDir2d.nDirection+PI/2, m_dWallWidth*1.5, ptTmp2);
|
|
pline1.addVertexAt(0, ptTmp2.AsAcGePoint2d(), 0, dPLWidth, dPLWidth);
|
|
ads_polar(ptTmp1, ptDir2d.nDirection-PI/2, m_dWallWidth*1.5, ptTmp2);
|
|
pline1.addVertexAt(1, ptTmp2.AsAcGePoint2d(), 0, dPLWidth, dPLWidth);
|
|
|
|
m_segWall.Polar(dLen*2/3, ptDir2d);
|
|
ptTmp1 = ptDir2d.AsAcGePoint3d();
|
|
|
|
ads_polar(ptTmp1, ptDir2d.nDirection+PI/2, m_dWallWidth*1.5, ptTmp2);
|
|
pline2.addVertexAt(0, ptTmp2.AsAcGePoint2d(), 0, dPLWidth, dPLWidth);
|
|
ads_polar(ptTmp1, ptDir2d.nDirection-PI/2, m_dWallWidth*1.5, ptTmp2);
|
|
pline2.addVertexAt(1, ptTmp2.AsAcGePoint2d(), 0, dPLWidth, dPLWidth);
|
|
|
|
int nColor = colorIndex(); // 门窗的颜色
|
|
mode->subEntityTraits().setColor(m_nLineColor);
|
|
mode->geometry().pline(pline1);
|
|
mode->geometry().pline(pline2);
|
|
mode->subEntityTraits().setColor(nColor);
|
|
}
|
|
|
|
return Adesk::kFalse;;
|
|
}
|
|
|
|
|
|
void TDbOpeningAptJig::subViewportDraw(AcGiViewportDraw *mode)
|
|
{
|
|
int nNums = CInsertOpeningDlg::g_pCurDlg->GetOpeningNums();
|
|
if (nNums>1)
|
|
{
|
|
XPoint ptLoc = m_pOpening->GetLocation(),
|
|
ptPos;
|
|
double dWidth = m_pOpening->GetWidth();
|
|
double dAngle = m_pOpening->GetRotation();
|
|
double dDist(0.0);
|
|
if (nNums%2 == 0) // 偶数个门
|
|
{
|
|
for (int i=0; i<nNums; i++)
|
|
{
|
|
if (i==0)
|
|
{
|
|
dDist += dWidth/2.0;
|
|
}
|
|
else if (i%2 == 0)
|
|
{
|
|
dDist += dWidth;
|
|
}
|
|
ads_polar(ptLoc, dAngle, dDist, ptPos);
|
|
|
|
TDbOpening *pOpening = (TDbOpening*)m_pOpening->clone();
|
|
pOpening->SetLocation(ptPos);
|
|
pOpening->m_ptLabel = pOpening->GetDefaultLabPos();
|
|
pOpening->SetLayoutRotation(Ucs2Wcs(0));
|
|
pOpening->subViewportDraw(mode);
|
|
dAngle = PI + dAngle;
|
|
}
|
|
}
|
|
else // 奇数个门
|
|
{
|
|
m_pOpening->subViewportDraw(mode);
|
|
for (int i=1; i<nNums; i++)
|
|
{
|
|
if (i%2 != 0)
|
|
{
|
|
dDist += dWidth;
|
|
}
|
|
ads_polar(ptLoc, dAngle, dDist, ptPos);
|
|
|
|
TDbOpening *pOpening = (TDbOpening*)m_pOpening->clone();
|
|
pOpening->SetLocation(ptPos);
|
|
pOpening->m_ptLabel = pOpening->GetDefaultLabPos();
|
|
pOpening->SetLayoutRotation(Ucs2Wcs(0));
|
|
pOpening->subViewportDraw(mode);
|
|
dAngle = PI + dAngle;
|
|
}
|
|
}
|
|
DrawOsnapShape(mode, ptLoc, AcDb::kOsMaskNear);
|
|
}
|
|
else
|
|
{
|
|
m_pOpening->subViewportDraw(mode);
|
|
DrawOsnapShape(mode, m_pOpening->GetLocation(), AcDb::kOsMaskNear);
|
|
}
|
|
}
|
|
|
|
// add by lgy 20120612,智能插入门窗时由于jig时无法获取墙线两侧的轴线,
|
|
// 此函数根据点,求两侧的轴线
|
|
// ptPick:拾取点, cvBase:基线, cvSeg:所求线段
|
|
//void GetSubSegmentByPoint(XPoint ptPick, XCurveSegment cvBase, XCurveSegment &cvSeg)
|
|
//{
|
|
// XDbBlockTableRec objMSpace;
|
|
// if (!objMSpace)
|
|
// return;
|
|
//
|
|
// AcDbBlockTableRecordIterator *pIterator = NULL;
|
|
// Acad::ErrorStatus es = objMSpace.m_pBlockTableRec->newIterator(pIterator);
|
|
// if (es!=Acad::eOk || pIterator==NULL)
|
|
// return;
|
|
//
|
|
// double dDist = cvBase.PathDistance(ptPick),
|
|
// dDistLeft(0.0),
|
|
// dDistRight = cvBase.GetLength();
|
|
// XPoint ptTempS, ptTempE, ptInt1, ptInt2, ptInters, ptStart, ptEnd;
|
|
//
|
|
// for (pIterator->start(); !pIterator->done(); pIterator->step())
|
|
// {
|
|
// AcDbEntity *pEnt = NULL;
|
|
// es = pIterator->getEntity(pEnt, AcDb::kForRead);
|
|
// if (es!=Acad::eOk || pEnt==NULL)
|
|
// continue;
|
|
//
|
|
// if (pEnt->visibility()==AcDb::kInvisible || _tcsicmp(pEnt->layer(), LAY_AXIS)!=0 || !pEnt->isKindOf(AcDbLine::desc()))
|
|
// continue;
|
|
//
|
|
// AcDbLine *pLine = AcDbLine::cast(pEnt);
|
|
// pLine->getStartPoint(ptTempS);
|
|
// pLine->getEndPoint(ptTempE);
|
|
// pLine->close();
|
|
//
|
|
// XCurveSegment segTemp(ptTempS, ptTempE, 0);
|
|
// segTemp.SetElevation(0.0);
|
|
//
|
|
// int nRet = cvBase.Intersection(segTemp, ptInt1, ptInt2);
|
|
// if (nRet < 1)
|
|
// continue;
|
|
// else if (nRet == 1)
|
|
// ptInters = ptInt1;
|
|
// else
|
|
// ptInters = TGGeLine(ptInt1, ptInt2).NearPoint(ptPick);
|
|
//
|
|
// double dDist0 = cvBase.PathDistance(ptInters);
|
|
// if (dDist0 < dDist + _DIST_SNAP)
|
|
// {
|
|
// if (dDist0 > dDistLeft - _DIST_SNAP)
|
|
// {
|
|
// ptStart = ptInters;
|
|
// dDistLeft = dDist0;
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// if (dDist0 < dDistRight + _DIST_SNAP)
|
|
// {
|
|
// ptEnd = ptInters;
|
|
// dDistRight = dDist0;
|
|
// }
|
|
// }
|
|
// }
|
|
// delete pIterator;
|
|
//
|
|
// XCurveSegment cvTemp(ptStart, ptEnd, cvBase.GetBulge());
|
|
// cvSeg = cvTemp;
|
|
//}
|
|
|
|
BOOL GetSubSegmentByPoint2(AcDbObjectId wallId, DList<TWallAxisData> &lstIds, XPoint ptPick, XCurveSegment cvBase, XCurveSegment &cvSeg,
|
|
XPoint &ptS, XPoint &ptE)
|
|
{
|
|
BOOL bRet(FALSE);
|
|
XPoint ptStart, ptEnd;
|
|
|
|
long lLen = lstIds.Length();
|
|
for (long l=0; l<lLen; l++)
|
|
{
|
|
TWallAxisData data = *lstIds[l];
|
|
if (data.m_idWall != wallId)
|
|
continue;
|
|
|
|
double dDist = cvBase.PathDistance(ptPick),
|
|
dDistLeft(0.0),
|
|
dDistRight = cvBase.GetLength();
|
|
XPoint ptTempS, ptTempE, ptInt1, ptInt2, ptInters;
|
|
|
|
bool bSAxisOk = false,
|
|
bEAxisOk = false;
|
|
|
|
int nAxisLen = data.m_aryAxisIds.logicalLength();
|
|
for (int m=0; m<nAxisLen; m++)
|
|
{
|
|
XCurveSegment segAxis;
|
|
OPENOBJ_BEGIN(data.m_aryAxisIds[m], AcDb::kForRead, AcDbEntity, pEntity);
|
|
if (pEntity != NULL)
|
|
{
|
|
AcDbLine *pLine = AcDbLine::cast(pEntity);
|
|
if (pLine != NULL)
|
|
{
|
|
pLine->getStartPoint(ptTempS);
|
|
pLine->getEndPoint(ptTempE);
|
|
segAxis.SetPoints(ptTempS, ptTempE);
|
|
}
|
|
else
|
|
{
|
|
AcDbArc *pArc = AcDbArc::cast(pEntity);
|
|
if (pArc != NULL)
|
|
{
|
|
pArc->center();
|
|
|
|
TADSGePoint3d ptCen;
|
|
(AcGePoint3d &)ptCen = pArc->center();
|
|
TVector3D vtNormal;
|
|
(AcGeVector3d &)vtNormal = pArc->normal();
|
|
ptCen = TchPrivate::Wcs2Ecs(ptCen, vtNormal);
|
|
|
|
TGGeArc arc(ptCen, pArc->radius(), pArc->startAngle(), pArc->endAngle());
|
|
ads_polar(arc.GetCenterPt(), arc.GetStarAngle(), arc.GetRadius(), segAxis.StartPoint());
|
|
ads_polar(arc.GetCenterPt(), arc.GetEndAngle(), arc.GetRadius(), segAxis.EndPoint());
|
|
segAxis.SetBulge(arc.Bulge());
|
|
}
|
|
}
|
|
pEntity->close();
|
|
}
|
|
OPENOBJ_END();
|
|
|
|
segAxis.SetElevation(0.0);
|
|
segAxis.SetLineFlag(LS_FINITE);
|
|
int nRet = cvBase.Intersection(segAxis, ptInt1, ptInt2);
|
|
if (nRet < 1)
|
|
continue;
|
|
else if (nRet == 1)
|
|
ptInters = ptInt1;
|
|
else
|
|
ptInters = TGGeLine(ptInt1, ptInt2).NearPoint(ptPick);
|
|
|
|
double dDist0 = cvBase.PathDistance(ptInters);
|
|
if (dDist0 < dDist + _DIST_SNAP)
|
|
{
|
|
if (dDist0 > dDistLeft - _DIST_SNAP)
|
|
{
|
|
ptStart = ptInters;
|
|
dDistLeft = dDist0;
|
|
bSAxisOk = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (dDist0 < dDistRight + _DIST_SNAP)
|
|
{
|
|
ptEnd = ptInters;
|
|
dDistRight = dDist0;
|
|
bEAxisOk = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!bEAxisOk || !bSAxisOk) // 两边可能就没有轴线,或者只有1根,总之,只要一边的轴线不OK,那么就使用墙线做为SEG
|
|
{
|
|
ptStart = ptS;
|
|
ptEnd = ptE;
|
|
}
|
|
bRet = TRUE;
|
|
break;
|
|
}
|
|
|
|
XCurveSegment cvTemp(ptStart, ptEnd, cvBase.GetBulge());
|
|
cvSeg = cvTemp;
|
|
return bRet;
|
|
}
|
|
|
|
// add by lgy 20120521 根据jig时的墙的ID和拾取点,得到当前智能分割线
|
|
// add by lgy 20120518 根据墙体id,拾取点,智能插入门窗方式,获取门窗应该插入的位置
|
|
// [wallId]:墙体ID, [ptPick]:拾取点, [cvSeg]:智能插入分割线1, [bAptType]:智能插入方式
|
|
BOOL GetAptitudeLocalPt(AcDbObjectId wallId, XPoint ptPick, XCurveSegment &cvSeg, int nAptType, DList<TWallAxisData> &lstIds)
|
|
{
|
|
PickSet ss;
|
|
XPoly2D poly;
|
|
XCurveSegment cvSegBase;
|
|
TDPtrList<AcDbSoftPointerId> openingList;
|
|
|
|
OPENOBJ_BEGIN(wallId, AcDb::kForRead, TDbWall, pWall);
|
|
if (pWall == NULL)
|
|
return FALSE;
|
|
|
|
if (nAptType == 1) // 轴线定距
|
|
{
|
|
XCurveSegment cvLongBaseLine = pWall->GetLongBaseLine();
|
|
cvLongBaseLine.SetElevation(0.0);
|
|
cvLongBaseLine.SetLineFlag(LS_FINITE);
|
|
|
|
// 不再采用全图搜索的方法,效率差,而且试用起来总有问题
|
|
if (!GetSubSegmentByPoint2(wallId, lstIds, ptPick, cvLongBaseLine, cvSegBase, pWall->StartPoint(), pWall->EndPoint()) ||
|
|
cvSegBase.GetLength()<_DIST_SNAP)
|
|
{
|
|
pWall->close();
|
|
return FALSE;
|
|
}
|
|
|
|
// add by lgy 20120614 轴线定距插入时无法将门窗插入到墙上,关闭墙实体后可以插入,具体原因不清楚
|
|
pWall->close();
|
|
}
|
|
else // 墙线定距
|
|
{
|
|
if (!pWall->GetSubSegmentByPierAt(ptPick, cvSegBase))
|
|
{
|
|
pWall->close();
|
|
return FALSE;
|
|
}
|
|
|
|
const TDPtrList<AcDbSoftPointerId> &openingList = pWall->GetOpeningIdList();
|
|
|
|
ss.Free();
|
|
for (int j = 0; j < openingList.Length(); j ++)
|
|
ss += openingList[j];
|
|
}
|
|
OPENOBJ_END();
|
|
|
|
if (nAptType == 1)
|
|
{
|
|
cvSeg = cvSegBase;
|
|
return TRUE;
|
|
}
|
|
|
|
XPoint ptTemp;
|
|
ads_polar(ptPick, cvSegBase.Direction(ptPick) + PI/2, 1000, ptTemp);
|
|
XCurveSegment segAppeak(ptPick, ptTemp, 0);
|
|
|
|
XPoint ptNear1 = cvSegBase.StartPoint(),
|
|
ptNear2 = cvSegBase.EndPoint(); // 保存离拾取点最近的两个点
|
|
int nSide = segAppeak.OnWhichSide(ptNear1);
|
|
|
|
for (long i = 0; i < ss.Length(); i++)
|
|
{
|
|
Entity ent = ss[i];
|
|
XPoint pt1, pt2;
|
|
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbOpening, pOpening);
|
|
if (pOpening == NULL)
|
|
continue;
|
|
|
|
pOpening->GetSidePoints(pt1, pt2);
|
|
|
|
XPoint ptTemp1;
|
|
cvSegBase.ProjectToMe(pt1, ptTemp1);
|
|
pt1 = ptTemp1;
|
|
cvSegBase.ProjectToMe(pt2, ptTemp1);
|
|
pt2 = ptTemp1;
|
|
|
|
if (segAppeak.OnWhichSide(pt1) == nSide) // 在拾取点的左边
|
|
{
|
|
if (ptNear1.Distance2d(ptPick) > pt2.Distance2d(ptPick))
|
|
ptNear1 = pt2;
|
|
}
|
|
else
|
|
{
|
|
if (ptNear2.Distance2d(ptPick) > pt1.Distance2d(ptPick))
|
|
ptNear2 = pt1;
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
ss.Free();
|
|
cvSeg = XCurveSegment(ptNear1, ptNear2, cvSegBase.GetBulge());
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// add by lgy 20120521 为智能插入门窗添加jig类
|
|
// 没有使用原本的类的原因是智能插入门窗时需要显示两段分割线
|
|
class XDrawAptOpeningEdJig : public TEdJig
|
|
{
|
|
public:
|
|
XDrawAptOpeningEdJig(TDbOpening *pOpening, DList<TWallAxisData> &lstIds);
|
|
virtual ~XDrawAptOpeningEdJig();
|
|
|
|
public:
|
|
void doIt();
|
|
virtual DragStatus sampler();
|
|
virtual Adesk::Boolean Update();
|
|
virtual AcDbEntity *entity() const;
|
|
|
|
int GetRetCode(int *kwordId = NULL) const;
|
|
|
|
public:
|
|
XPoint m_ptOnWall;
|
|
AcDbObjectId m_idWall;
|
|
XCurveSegment m_cvSeg; // 智能分割的线段
|
|
DList<TWallAxisData> m_lstIds; // 提前搜索出来墙和轴网的关系,防止在JIG过程中有对象打开,无法通过SSGET获得轴网
|
|
|
|
XPoint m_ptCursor;
|
|
int m_nRetCode; // 返回码
|
|
const TCHAR* m_pszPrompt; // 提示信息
|
|
const TCHAR* m_pszKeyword; // 关键字
|
|
int m_nAptType; // 智能插入门窗方式
|
|
|
|
public:
|
|
TDbOpeningAptJig *m_pDrawEnt; // 临时实体
|
|
};
|
|
|
|
XDrawAptOpeningEdJig::XDrawAptOpeningEdJig(TDbOpening *pOpening, DList<TWallAxisData> &lstIds)
|
|
: m_pszKeyword(NULL), m_pszPrompt(NULL), m_pDrawEnt(NULL), m_nRetCode(0)
|
|
{
|
|
m_pDrawEnt = new TDbOpeningAptJig;
|
|
m_pDrawEnt->SetOpening(pOpening);
|
|
|
|
// 提前搜索出来墙和轴网的关系,防止在JIG过程中有对象打开,无法通过SSGET获得轴网
|
|
m_lstIds.Reset();
|
|
int nLength = lstIds.Length();
|
|
for (int i=0; i<nLength; i++)
|
|
{
|
|
TWallAxisData data = *lstIds[i];
|
|
m_lstIds.Append(new TWallAxisData(data));
|
|
}
|
|
|
|
m_nAptType = 0; // 墙线定距
|
|
}
|
|
|
|
XDrawAptOpeningEdJig::~XDrawAptOpeningEdJig()
|
|
{
|
|
if (m_pDrawEnt)
|
|
{
|
|
delete m_pDrawEnt;
|
|
}
|
|
}
|
|
|
|
// 转换成ADS代码
|
|
int XDrawAptOpeningEdJig::GetRetCode(int *kwordId) const
|
|
{
|
|
int ret = m_nRetCode;
|
|
if (ret == AcEdJig::kCancel)
|
|
{
|
|
ret = RTCAN;
|
|
}
|
|
else if (ret == AcEdJig::kNull)
|
|
{
|
|
ret = RTNONE;
|
|
}
|
|
else if (ret <= 0)
|
|
{
|
|
ret = RTNORM;
|
|
}
|
|
else
|
|
{
|
|
if (kwordId) *kwordId = ret;
|
|
ret = RTKWORD;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// 开始执行拖动
|
|
void XDrawAptOpeningEdJig::doIt()
|
|
{
|
|
setDispPrompt(m_pszPrompt);
|
|
if (m_pszKeyword) // 存在关键字
|
|
{
|
|
INITGET_BEG(-1, m_pszKeyword);
|
|
try
|
|
{
|
|
m_nRetCode = drag();
|
|
}
|
|
catch(...)
|
|
{
|
|
m_nRetCode = AcEdJig::kCancel;
|
|
}
|
|
INITGET_END();
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
m_nRetCode = drag();
|
|
}
|
|
catch(...)
|
|
{
|
|
m_nRetCode = AcEdJig::kCancel;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 反馈
|
|
AcEdJig::DragStatus XDrawAptOpeningEdJig::sampler()
|
|
{
|
|
double nIncStep = g_nWinStep;
|
|
|
|
DragStatus stat;
|
|
setUserInputControls((UserInputControls)(AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted |
|
|
AcEdJig::kNoNegativeResponseAccepted | AcEdJig::kNoZeroResponseAccepted));
|
|
|
|
if (m_pszKeyword)
|
|
{
|
|
setKeywordList(m_pszKeyword);
|
|
}
|
|
|
|
XPoint ptTemp;
|
|
stat = acquirePoint(ptTemp);
|
|
if (stat == AcEdJig::kNormal)
|
|
{
|
|
if (ptTemp.Distance(m_ptCursor) > _DIST_SNAP)
|
|
{
|
|
m_ptCursor = ptTemp;
|
|
m_idWall = SnapOnWall(ptTemp); // 判断点在墙上的id
|
|
|
|
if (!!m_idWall)
|
|
{
|
|
OPENOBJ_BEGIN(m_idWall, AcDb::kForRead, TDbWall, pWall);
|
|
if (pWall == NULL)
|
|
{
|
|
return AcEdJig::kNoChange;
|
|
}
|
|
|
|
if (pWall->Is(CURVE_LINE) && m_pDrawEnt->m_pOpening->GetKind()==TOpeningData::OP_ARCWIN)
|
|
{
|
|
pWall->close();
|
|
return AcEdJig::kNoChange;
|
|
}
|
|
OPENOBJ_END();
|
|
|
|
if (GetAptitudeLocalPt(m_idWall, m_ptCursor, m_cvSeg, m_nAptType, m_lstIds))
|
|
{
|
|
m_pDrawEnt->m_bShow = TRUE;
|
|
m_pDrawEnt->SetLineParameters(m_idWall, m_cvSeg, (m_nAptType==0)?6:4); // 更新线的参数
|
|
}
|
|
}
|
|
|
|
m_ptOnWall = ptTemp;
|
|
}
|
|
else
|
|
{
|
|
m_pDrawEnt->m_bShow = FALSE;
|
|
return AcEdJig::kNoChange;
|
|
}
|
|
}
|
|
|
|
return stat;
|
|
}
|
|
|
|
// 更新实体数据
|
|
Adesk::Boolean XDrawAptOpeningEdJig::Update()
|
|
{
|
|
if (CInsertOpeningDlg::g_pCurDlg!=NULL &&
|
|
CInsertOpeningDlg::g_pCurDlg->IsWindowVisible())
|
|
{
|
|
TDbOpening *pOpening = CInsertOpeningDlg::g_pCurDlg->NewOpening();
|
|
m_pDrawEnt->SetOpening(pOpening);
|
|
delete pOpening;
|
|
}
|
|
|
|
if (!m_idWall)
|
|
{
|
|
m_pDrawEnt->m_pOpening->SetWallId(m_idWall);
|
|
return Adesk::kTrue;
|
|
}
|
|
|
|
OPENOBJ_BEGIN(m_idWall, AcDb::kForRead, TDbWall, pWall);
|
|
if (pWall)
|
|
{
|
|
if (m_pDrawEnt->m_pOpening->GetKind() == TOpeningData::OP_ARCWIN)
|
|
{
|
|
if (pWall->Is(CURVE_ARC))
|
|
{
|
|
m_pDrawEnt->m_pOpening->SetWallId(m_idWall);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_pDrawEnt->m_pOpening->SetWallId(m_idWall);
|
|
}
|
|
m_pDrawEnt->SetOpeningParameters(pWall, m_ptOnWall, m_ptCursor, CInsertOpeningDlg::g_pCurDlg?CInsertOpeningDlg::g_pCurDlg->GetInsertMode():0);
|
|
}
|
|
OPENOBJ_END();
|
|
return Adesk::kTrue;
|
|
}
|
|
|
|
AcDbEntity* XDrawAptOpeningEdJig::entity() const
|
|
{
|
|
return m_pDrawEnt;
|
|
}
|
|
|
|
//add by lgy 20120517 智能插入门窗
|
|
AcDbObjectId GetOpeingLocationApt(const TCHAR *prompt, TDbOpening *&pWin, XPoint &ptPick, XCurveSegment &cvSeg, int &nRetCode,
|
|
int nAptType, DList<TWallAxisData> &lstIds)
|
|
{
|
|
int nOsMode = 0;
|
|
xg_getvar(_T("OSMODE"), &nOsMode);
|
|
nOsMode |= 0x4000;
|
|
XPushVar<int> osmode(_T("OSMODE"), nOsMode);
|
|
|
|
XDrawAptOpeningEdJig jig(pWin, lstIds);
|
|
jig.m_pszPrompt = prompt;
|
|
jig.m_pszKeyword = _T("Q");
|
|
jig.m_nAptType = nAptType;
|
|
jig.doIt();
|
|
|
|
ptPick = jig.m_ptCursor;
|
|
cvSeg = jig.m_cvSeg;
|
|
|
|
int kwordId;
|
|
AcDbObjectId idWall;
|
|
nRetCode = jig.GetRetCode(&kwordId);
|
|
if (nRetCode == RTNORM)
|
|
{
|
|
idWall = jig.m_idWall;
|
|
if (!!idWall)
|
|
{
|
|
delete pWin;
|
|
pWin = jig.m_pDrawEnt->m_pOpening;
|
|
jig.m_pDrawEnt->m_pOpening = NULL;
|
|
|
|
// 成功的添加了门窗,那么把最近一次的参数写入注册表
|
|
CInsertOpeningDlg::g_pCurDlg->UpdateOpening(*pWin, TRUE);
|
|
CInsertOpeningDlg::g_pCurDlg->WriteParamToRegistry();
|
|
CInsertOpeningDlg::g_pCurDlg->SetupLabelList();
|
|
}
|
|
}
|
|
return idWall;
|
|
}
|