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

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;
}