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

1110 lines
35 KiB
C++

#include "stdafx.h"
#include "TDbColumn.h"
#include "TDbWallPatch.h"
const Adesk::UInt8 TDbCurveMesh2::g_nVersion = 1;
ACRX_DXF_DEFINE_MEMBERS(ATSCurveMesh2, ATSPolyCurveEnt, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, ATS_CURVEMESH2, "ATS_CURVEMESH2图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(TDbCurveMesh2);
TDbCurveMesh2::TDbCurveMesh2()
:m_nCMFlag(0)
{
}
TDbCurveMesh2::~TDbCurveMesh2()
{
}
BOOL TDbCurveMesh2::IsValid() const
{
BOOL bRet=TDbPolyCurveEnt::IsValid();
if(!bRet)
return bRet;
bRet=(m_polyBase.Length()>1 &&
m_polyShape.Length()>1);
return bRet;
}
// 提供对格式刷的支持
void TDbCurveMesh2::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
TDbPolyCurveEnt::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbCurveMesh2 *pSrc=TDbCurveMesh2::cast(pSrcEntity);
if(pSrc) {
m_nCMFlag=pSrc->m_nCMFlag;
}
}
Acad::ErrorStatus
TDbCurveMesh2::subGetClassID(CLSID* pClsid) const
{
return Acad::eOk;
}
// 从DWG读入数据:
Acad::ErrorStatus TDbCurveMesh2::dwgInFields (AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbPolyCurveEnt::dwgInFields(pFiler);
if(es != Acad::eOk) return es;
Adesk::UInt8 nVer;
pFiler->readItem(&nVer);
if(nVer>g_nVersion) {// Version is too new
return Acad::eMakeMeProxy;
}
pFiler->readItem(&m_nCMFlag);
// Read ShapePoly
AcGePoint2d ptBase;
pFiler->readItem(&ptBase);
m_ptShapeBase=ptBase;
ReadPoly2D(pFiler, m_polyShape);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbCurveMesh2::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbPolyCurveEnt::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
pFiler->writeItem(g_nVersion);
pFiler->writeItem(m_nCMFlag);
// Write ShapePoly
pFiler->writeItem((AcGePoint2d &)m_ptShapeBase);
WritePoly2D(pFiler, m_polyShape);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbCurveMesh2::dxfInFields (AcDbDxfFiler* pFiler)
{
Acad::ErrorStatus es= TDbPolyCurveEnt::dxfInFields(pFiler);
if(es!=Acad::eOk)
return es;
if (!pFiler->atSubclassData(_T("TDbCurveMesh2"))) {
return Acad::eBadDxfSequence;
}
int fieldsFlags=0;
resbuf rb;
int n1,n3;
DList<XPoint> pts2;
XPoint pt;
DList<double> bulges1, bulges2;
while ((es == Acad::eOk)
&& ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) {
switch (rb.restype) {
case AcDb::kDxfXCoord+2:
pt=rb.resval.rpoint;
fieldsFlags |= 0x01;
break;
case AcDb::kDxfInt16:
n1=rb.resval.rint;
fieldsFlags |= 0x02;
break;
case AcDb::kDxfInt16+2:
n3=rb.resval.rint;
fieldsFlags |= 0x08;
break;
case AcDb::kDxfXCoord+1:
pts2.Append(new XPoint(rb.resval.rpoint));
break;
case AcDb::kDxfAngle+1:
bulges2.Append(new double(rb.resval.rreal));
break;
//fall through intentional
default:
// An unrecognized group. Push it back so that
// the subclass can read it again.
pFiler->pushBackItem();
es = Acad::eEndOfFile;
break;
}
}
// At this point the es variable must contain eEndOfFile
// - either from readResBuf() or from pushback. If not,
// it indicates that an error happened and we should
// return immediately.
//
if (es != Acad::eEndOfFile)
return Acad::eInvalidResBuf;
if (!(fieldsFlags&0x01)) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nMissing DXF group code: 12"));
return Acad::eMissingDxfField;
}
if(pts2.Length()<2 || pts2.Length()!=bulges2.Length()) {
pFiler->setError(_T("\nError DXF group code: 11, 51"));
return Acad::eMissingDxfField;
}
m_ptShapeBase=pt;
if(fieldsFlags&0x02)
m_nCMFlag=n1;
if(fieldsFlags&0x08)
m_polyShape.SetFlag(n3);
m_polyShape.Reset();
for(long i=0; i<pts2.Length(); i++) {
m_polyShape.AppendNode(*pts2[i], *bulges2[i]);
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbCurveMesh2::dxfOutFields(AcDbDxfFiler* pFiler) const
{
Acad::ErrorStatus es;
es = TDbPolyCurveEnt::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbCurveMesh2"));
assert(es == Acad::eOk);
pFiler->writePoint2d(AcDb::kDxfXCoord+2, m_ptShapeBase);
pFiler->writeInt16(AcDb::kDxfInt16, m_nCMFlag);
pFiler->writeInt16(AcDb::kDxfInt16+2, m_polyShape.GetFlag());
for(long i=0; i<m_polyShape.Length(); i++) {
pFiler->writePoint2d(AcDb::kDxfXCoord+1, m_polyShape[i]);
pFiler->writeDouble(AcDb::kDxfAngle+1, m_polyShape.GetBulge(i));
}
return es;
}
Acad::ErrorStatus
TDbCurveMesh2::subGetOsnapPoints(
AcDb::OsnapMode osnapMode,
INT_PTR gsSelectionMark,
const AcGePoint3d& ptPick,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcGePoint3dArray& snapPoints,
AcDbIntArray& geomIds) const
{
if(osnapMode==AcDb::kOsModeIns) {
snapPoints.append(Ecs2Wcs(m_ptShapeBase, m_vtNormal).AsAcGePoint3d());
return Acad::eOk;
}
return TDbPolyCurveEnt::subGetOsnapPoints(osnapMode, gsSelectionMark,
ptPick, lastPoint, viewXform, snapPoints, geomIds);
}
// -----------------------------------------------------------------------
// Overriden functions for edit
// to do:
// 对于自定义柱子,应当允许通过夹点改变边界
Acad::ErrorStatus TDbCurveMesh2::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
TDbPolyCurveEnt::subGetGripPoints(gripPoints, osnapModes, geomIds);
//形状上的夹点
if(IsShapeShow()) {
for(int i=0; i<m_polyShape.Length(); i++){
XPoint ptWcs=Ecs2Wcs(m_polyShape[i], m_vtNormal);
gripPoints.append(ptWcs);
}
gripPoints.append(Ecs2Wcs(m_ptShapeBase, m_vtNormal).AsAcGePoint3d());
}
return Acad::eOk;
}
//////////////////////////////////////////////////////////////
// Active when being rotated, scaled, moved, etc.
Acad::ErrorStatus TDbCurveMesh2::subTransformBy(const AcGeMatrix3d& xform)
{
extern XString GetCurCommand();
assertWriteEnabled();
if(!IsBind())
{
XVector3D vtNormalOld=GetNormal();
TDbPolyCurveEnt::subTransformBy(xform);
XVector3D vtNormalNew=GetNormal();
ads_matrix mat;
GetLocalMatrix(xform, mat);
XPoint ptOldBase=m_ptShapeBase;
m_ptShapeBase.TransformBy(mat);
m_ptShapeBase.z=0;
//add by whl on 060227
if(IsMirrorMatrix(xform))
{
XVector3D vt=m_ptShapeBase-ptOldBase;
for(int i=0; i<m_polyShape.Length(); i++)
*m_polyShape[i] += vt;
m_polyShape.SetElevation(0.0);
m_polyBase.Reverse();
return Acad::eOk;
}
if(vtNormalNew.AsAcGeVector3d()==vtNormalOld.AsAcGeVector3d() &&
_tcsicmp(GetCurCommand(), _T("ROTATE"))==0)
{
XVector3D vt=m_ptShapeBase-ptOldBase;
for(int i=0; i<m_polyShape.Length(); i++)
*m_polyShape[i] += vt;
m_polyShape.SetElevation(0.0);
}
else
{
for(int i=0; i<m_polyShape.Length(); i++)
m_polyShape[i]->TransformBy(mat);
m_polyShape.SetElevation(0.0);
}
}
return Acad::eOk;
}
///////////////////////////////////////////
// 功能: 夹点操作
// 状态: 有待完成修改相关墙体的操作
Acad::ErrorStatus TDbCurveMesh2::subMoveGripPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
TDbPolyCurveEnt::subMoveGripPointsAt(indices, offset);
int nVertexCount=m_polyBase.Length();
XPoint vtOffset=Wcs2Ecs(*(XPoint *)&offset, m_vtNormal);
//vtOffset.z=0;
for (int i = 0; i < indices.length(); i++) {
int idx = indices[i];
if(!IsBind()) {
if(idx<nVertexCount) { // Move vertex
#if 0
*m_polyBase[idx] += vtOffset;
#endif
} else { // Move Edge or Shape
XPoly2D poly2d(m_polyBase);
poly2d.SetElevation(0.0);
int nEdgeIndex=idx-nVertexCount;
int nTotalEdge=poly2d.TotalSegments();
if(nEdgeIndex<nTotalEdge) { //移动边
#if 0
XDirectionCurve cv;
poly2d.Nth(nEdgeIndex, cv);
ASSERT(!!cv);
if(cv.Is(CURVE_LINE)) { // Move
XLine ln=cv.GetLine();
ln.StartPoint() += vtOffset;
ln.EndPoint() += vtOffset;
ln.flag = LS_INFINITE;
XDirectionCurve prevSeg, nextSeg;
int nPrev=nEdgeIndex-1, nNext=nEdgeIndex+1;
if(poly2d.IsClosed()) {
nPrev=DePeriod(nTotalEdge, nPrev);
nNext=DePeriod(nTotalEdge, nNext);
}
XPoint ptStart, ptEnd;
BOOL bUpdateIt=TRUE;
//更新起点
if(nPrev>=0 && nPrev<nTotalEdge) {
poly2d.Nth(nPrev, prevSeg);
prevSeg.flag = LS_INFINITE;
XPoint ptInt[2];
int nIntNum=prevSeg.Intersection(ln, ptInt[0], ptInt[1]);
if(nIntNum==1) ptStart=ptInt[0];
else if(nIntNum==2) {
ptStart=XLine(ptInt[0], ptInt[1]).NearPoint(ln.StartPoint());
} else bUpdateIt=FALSE;
} else {
ptStart = *poly2d[nEdgeIndex] + vtOffset;
}
// 更新下一点
if(nNext>=0 && nNext<nTotalEdge) {
poly2d.Nth(nNext, nextSeg);
nextSeg.flag = LS_INFINITE;
XPoint ptInt[2];
int nIntNum=nextSeg.Intersection(ln, ptInt[0], ptInt[1]);
if(nIntNum==1) ptEnd=ptInt[0];
else if(nIntNum==2) {
ptEnd=XLine(ptInt[0], ptInt[1]).NearPoint(ln.EndPoint());
} else bUpdateIt=FALSE;
} else {
ptEnd = *poly2d[nEdgeIndex+1] + vtOffset;
}
if(bUpdateIt) {
double nPrevBulge=0.0, nNextBulge=0.0;
if(fabs(prevSeg.bulge)>1.0E-5) {
XArc prevArc=prevSeg.GetArc();
double nAngBeg=ads_angle(prevArc.center, prevSeg.StartPoint());
double nAngEnd=ads_angle(prevArc.center, ptStart);
if(prevSeg.IsMinusArc()) {
nPrevBulge=-CT_std_angle(nAngBeg-nAngEnd);
} else {
nPrevBulge=CT_std_angle(nAngEnd-nAngBeg);
}
}
if(fabs(nextSeg.bulge)>1.0E-5) {
XArc nextArc=nextSeg.GetArc();
double nAngBeg=ads_angle(nextArc.center, ptEnd);
double nAngEnd=ads_angle(nextArc.center, nextSeg.EndPoint());
if(nextSeg.IsMinusArc()) {
nNextBulge=-CT_std_angle(nAngBeg-nAngEnd);
} else {
nNextBulge=CT_std_angle(nAngEnd-nAngBeg);
}
}
*poly2d[nEdgeIndex] = ptStart;
if(nNext>=0 && nNext<poly2d.Length()) {
*poly2d[nNext] = ptEnd;
*poly2d.bulges[nNext] = nNextBulge;
}
if(nPrev>=0 && nPrev<poly2d.Length())
*poly2d.bulges[nPrev] = nPrevBulge;
}
} else { // Change Arc Segment--bulge
XPoint ptMid=cv.MidPoint();
XPoint ptMidNew= ptMid + vtOffset;
XArc arNew(cv.StartPoint(), ptMidNew, cv.EndPoint());
if(!!arNew) { //新的弧有效
XCurveSegment cvLine(cv.StartPoint(), cv.EndPoint(), 0.0);
int nSideOld=cvLine.OnWhichSide(ptMid);
int nSideNew=cvLine.OnWhichSide(ptMidNew);
double nSignal=cv.bulge/fabs(cv.bulge);
if(nSideOld==nSideNew) {
*poly2d.bulges[nEdgeIndex] = nSignal*arNew.Bulge();
} else {
*poly2d.bulges[nEdgeIndex] = -nSignal*arNew.Bulge();
}
}
}
for(int n=0; n<poly2d.Length(); n++) {
poly2d[n]->z = m_polyBase[n]->z;
}
m_polyBase = poly2d;
#endif
} else { // 移动形状
int nShapeIndex=nEdgeIndex-nTotalEdge;
MoveShapeGripPoint(nShapeIndex, vtOffset);
}
}
} else {
MoveShapeGripPoint(idx, vtOffset);
}
}
return Acad::eOk;
}
Acad::ErrorStatus TDbCurveMesh2::MoveShapeGripPoint(int nShapeIndex, const XVector3D &vtOffset0)
{
if(IsShapeShow()) {
XVector3D vtOffset(vtOffset0);
vtOffset.z=0;
if(nShapeIndex==m_polyShape.Length()) { //改变基点
m_ptShapeBase += vtOffset;
} else if(nShapeIndex<m_polyShape.Length()) { //移动其他顶点
*m_polyShape[nShapeIndex] += vtOffset;
}
}
return Acad::eOk;
}
// 取得夹点说明
Acad::ErrorStatus TDbCurveMesh2::GetGripText(int idx, CString &cs) const
{
Acad::ErrorStatus es=TDbPolyCurveEnt::GetGripText(idx, cs);
if(es==Acad::eOk)
return es;
int nVertexCount=m_polyBase.Length();
if(!IsBind()) {
if(idx<nVertexCount) { // Move vertex
#if 0
cs.Format(_T("移动第%d个顶点"), idx+1);
#endif
} else { // Move Edge or Shape
int nEdgeIndex=idx-nVertexCount;
int nTotalEdge=m_polyBase.TotalSegments();
if(nEdgeIndex<nTotalEdge) { //移动边
#if 0
cs.Format(_T("移动第%d条边"), nEdgeIndex+1);
#endif
} else { // 移动形状
int nShapeIndex=nEdgeIndex-nTotalEdge;
cs = nShapeIndex<m_polyShape.Length()? _T("改变断面形状线") : _T("改变形状基点");
}
}
} else {
cs = idx<m_polyShape.Length()? _T("改变断面形状线") : _T("改变形状基点");
}
return Acad::eOk;
}
// Helper functions
bool TDbCurveMesh2::IsClipMe(const TEntityBase* pEnt)const//适应散水和踢脚线
{
if(TEntityBase::IsClipMe(pEnt))
return true;
if(pEnt->GetMe()->isKindOf(TDbColumn::desc())||
pEnt->GetMe()->isKindOf(TDbWallPatch::desc()))
return true;
TDbWall*pWall=TDbWall::cast(pEnt->GetMe());
if(pWall!=NULL)
{
if(pWall->HasOpeningOutWall())
return true;
}
else if(HasDivide2D())//散水
{
TDbOpening* pOpen=TDbOpening::cast(pEnt->GetMe());
if(pOpen!=NULL)
{
//未处理组合门窗...
if(pOpen->GetKind()==TOpeningData::OP_PROWIN)
return true;
}
else
{
TDbCornerWin* pCornerWin=TDbCornerWin::cast(pEnt->GetMe());
if(pCornerWin!=NULL&&pCornerWin->IsProtrude())
return true;
else
{
TDbBalcony*pBalcony=TDbBalcony::cast(pEnt->GetMe());
if(pBalcony!=NULL)
return true;
else
{
TDbAscent *pAscent=TDbAscent::cast(pEnt->GetMe());
if(pAscent!=NULL)
return true;
else
{
TDbStep *pStep=TDbStep::cast(pEnt->GetMe());
if(pStep!=NULL)
return true;
}
}
}
}
}
return false;
}
// 绘制2D的显示, 二维显示网格
Acad::ErrorStatus TDbCurveMesh2::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
//TPushProperty vProp(this, dc);
assertReadEnabled();
if(Has2D()) {
AcGeVector3d vt;
vt=m_vtNormal;
if(vt==AcGeVector3d(0,0,1)) {
XPoint ptLow, ptUp;
m_polyShape.GetExtend(ptLow, ptUp);
double nOffset1=ptLow.x-m_ptShapeBase.x;
double nOffset2=ptUp.x - m_ptShapeBase.x;
XPoly2D polyBase(m_polyBase);
polyBase.SetElevation(0.0);
XPoly2D poly1, poly2;
polyBase.QuickOffset(nOffset1, poly1);
polyBase.QuickOffset(nOffset2, poly2);
dc << poly1 << poly2;
if(HasDivide2D()&&poly1.Length()==poly2.Length())//add by whl on 050608,转角线
{
for(long i=0;i<poly1.Length();i++)
dc<< XLine(*poly1[i],*poly2[i]);
}
else if(!polyBase.IsClosed()) { //Modify by ZJQ 2001/11/12
dc << XLine(*poly1.Head(), *poly2.Head()) << XLine(*poly1.Tail(), *poly2.Tail());
}
// 绘制断面形状
if(IsShapeShow() && _tcsicmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0) {
Adesk::UInt16 nColor=dc.GetColor();
dc.SetColor(1);
double ptSize=m_polyShape.Distance2d()/20.0;
dc << XLine(Ecs2Wcs(m_ptShapeBase+XPoint(ptSize, ptSize), m_vtNormal),
Ecs2Wcs(m_ptShapeBase-XPoint(ptSize, ptSize), m_vtNormal))
<< XLine(Ecs2Wcs(m_ptShapeBase+XPoint(ptSize, -ptSize), m_vtNormal),
Ecs2Wcs(m_ptShapeBase+XPoint(-ptSize, ptSize), m_vtNormal));
AcDbPolyline pline;
PolyConvert(m_polyShape, pline);
pline.setElevation(m_ptShapeBase.z);
pline.setNormal(m_vtNormal);
XAcGiViewDraw &viewDraw = (XAcGiViewDraw &)dc;
if(viewDraw.m_pWd)
pline.worldDraw(viewDraw.m_pWd);
else
pline.viewportDraw(viewDraw.m_pVd);
dc.SetColor(nColor);
}
} else
ExplodeOrDraw3d(dc);
}
return Acad::eOk;
}
// 绘制3d的显示
Acad::ErrorStatus
TDbCurveMesh2::ExplodeOrDraw3d(XExplodeDraw &dc) const
{
extern int GetCirDivNum(double r, double h);
extern double g_nCirDeviation;
//TPushProperty vProp(this, dc);
XPoly2D poly2d(m_polyBase);
DList<XPoly2D> lstPolys;
DList<Adesk::UInt8> lstColVis;
poly2d.SetElevation(0.0);
{
XVector3D vtOff=m_polyShape[0]-m_ptShapeBase;
XPoly2D polyNew;
poly2d.Offset(vtOff.x, polyNew);
if(polyNew.Length()!=poly2d.Length())
return Acad::eInvalidInput;
polyNew.SetElevation(vtOff.y);
lstPolys.Append(new XPoly2D(polyNew));
lstColVis.Append(new Adesk::UInt8(TRUE));
}
for(int i=0; i<m_polyShape.TotalSegments(); i++) {
XDirectionCurve cv;
m_polyShape.Nth(i, cv);
if(cv.Is(CURVE_LINE)) {
XVector3D vtOff=cv.EndPoint()-m_ptShapeBase;
XPoly2D polyNew;
poly2d.Offset(vtOff.x, polyNew);
if(polyNew.Length()!=poly2d.Length())
return Acad::eInvalidInput;
polyNew.SetElevation(vtOff.y);
lstPolys.Append(new XPoly2D(polyNew));
lstColVis.Append(new Adesk::UInt8(TRUE));
} else {
double intAng=cv.GetBulge();
int nDiv=30;
if(cv.Is(CURVE_ARC))
nDiv= TchExport::GetCirDivNum(cv.GetArc().GetRadius(), _AS_SYS_UNIT(TchGeLib::g_nCirDeviation));
int nStep=AS_INT(fabs(intAng)/PI/2.0*nDiv); // how much section
double nDistStep=cv.GetLength()/nStep;
for(int j=0; j<nStep; j++) {
XPointDir2d ptE;
cv.Polar(nDistStep*(j+1), ptE);
XVector3D vtOff=(XPoint &)ptE - m_ptShapeBase;
XPoly2D polyNew;
poly2d.Offset(vtOff.x, polyNew);
if(polyNew.Length()!=poly2d.Length())
return Acad::eInvalidInput;
polyNew.SetElevation(vtOff.y);
lstPolys.Append(new XPoly2D(polyNew));
lstColVis.Append(new Adesk::UInt8(j==nStep-1));
}
}
}
int nVertex=m_polyBase.Length();
for(i=0; i<lstPolys.Length(); i++) {
XPoly2D &rPoly=*lstPolys[i];
for(int j=0; j<nVertex; j++)
rPoly[j]->z += m_polyBase[j].z;
}
int nTotalSeg=m_polyBase.TotalSegments();
for(int n=0; n<nTotalSeg; n++) {
DList<XDirectionCurve> lstCurves;
for(int j=0; j<lstPolys.Length(); j++) {
XDirectionCurve *pCurve=new XDirectionCurve;
lstPolys[j]->Nth(n, *pCurve);
lstCurves.Append(pCurve);
}
XDirectionCurve mSeg;
poly2d.Nth(n, mSeg);
int nDiv=30;
if(mSeg.Is(CURVE_ARC))
nDiv= TchExport::GetCirDivNum(mSeg.GetArc().GetRadius(), _AS_SYS_UNIT(TchGeLib::g_nCirDeviation));
int nStep=AS_INT(fabs(mSeg.GetBulge())/PI/2.0*nDiv); // how much section
if(nStep<=0) nStep=1;
int nCol=lstCurves.Length();
int nRow=nStep+1;
XPoint *ptArray=new XPoint[nCol*nRow];
for(int col=0; col<nCol; col++) {
XDirectionCurve &segThis=*lstCurves[col];
XDirectionCurve seg2d=segThis;
seg2d.SetElevation(segThis.StartPoint().z);
double nElevStep=(segThis.EndPoint().z - segThis.StartPoint().z)/nStep;
double nDistStep=seg2d.GetLength()/nStep;
for(int row=0; row<nRow; row++) {
XPointDir2d ptDir2d;
seg2d.Polar(nDistStep*row, ptDir2d);
ptDir2d.z += nElevStep*row;
ptArray[row*nCol+col]=ptDir2d;
}
}
// 设置边的可见性
int nEdgeNum=nRow*(nCol-1)+nCol*(nRow-1);
Adesk::UInt8 *pVisArray=new Adesk::UInt8[nEdgeNum];
for(int k=0; k<nEdgeNum; k++)
pVisArray[k]=kAcGiVisible;
for(k=1; k<nRow-1; k++) { //除首末行外,其余各行的边均不可见
for(int j=0; j<nCol-1; j++)
pVisArray[k*(nCol-1)+j] = kAcGiInvisible;
}
int nIndexBase=nRow*(nCol-1);
for(col=0; col<nCol; col++) {
Adesk::UInt8 bVis=*lstColVis[col];
for(int row=0; row<nRow-1; row++) {
pVisArray[nIndexBase+col*(nRow-1)+row]=bVis;
}
}
int nVertexNum=nCol*nRow;
for(k=0; k<nVertexNum; k++)
ptArray[k]=Ecs2Wcs(ptArray[k], m_vtNormal);
AcGiEdgeData edgeInfo;
edgeInfo.setVisibility(pVisArray);
dc.DrawMesh(nRow, nCol, (AcGePoint3d *)ptArray, &edgeInfo);
if(n==0 && !poly2d.IsClosed() && m_polyShape.IsClosed()) {
XPoly2D polyTemp1(1);
for(col=0; col<nCol-1; col++)
polyTemp1.AppendNode(ptArray[col]);
dc.DrawShell(polyTemp1, DList<XPoly2D>());
}
if(n==nTotalSeg-1 && !poly2d.IsClosed() && m_polyShape.IsClosed()) {
XPoly2D polyTemp2(1);
for(col=0; col<nCol-1; col++)
polyTemp2.AppendNode(ptArray[(nRow-1)*nCol+col]);
dc.DrawShell(polyTemp2, DList<XPoly2D>());
}
delete []pVisArray;
delete []ptArray;
}
if(IsShapeShow() && _tcsicmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0) {
Adesk::UInt16 nColor=dc.GetColor();
dc.SetColor(1);
double ptSize=m_polyShape.Distance2d()/20.0;
dc << XLine(Ecs2Wcs(m_ptShapeBase+XPoint(ptSize, ptSize), m_vtNormal),
Ecs2Wcs(m_ptShapeBase-XPoint(ptSize, ptSize), m_vtNormal))
<< XLine(Ecs2Wcs(m_ptShapeBase+XPoint(ptSize, -ptSize), m_vtNormal),
Ecs2Wcs(m_ptShapeBase+XPoint(-ptSize, ptSize), m_vtNormal));
AcDbPolyline pline;
PolyConvert(m_polyShape, pline);
pline.setElevation(m_ptShapeBase.z);
pline.setNormal(m_vtNormal);
XAcGiViewDraw &viewDraw = (XAcGiViewDraw &)dc;
if(viewDraw.m_pWd)
pline.worldDraw(viewDraw.m_pWd);
else
pline.viewportDraw(viewDraw.m_pVd);
dc.SetColor(nColor);
}
return Acad::eOk;
}
/* * * * * * * * * * 取 动 态 属 性 显 示 数 据 的 函 数 * * * * * * * * * */
void TDbCurveMesh2::GetTips(DList<TObjInfoUnit> &lstInfo) const
{
lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("路径曲面")));
lstInfo.Append(new TObjInfoUnit(_T("路径长度"), Dist2Str(GetPathLength())));
lstInfo.Append(new TObjInfoUnit(_T("侧面面积"),
XString(_T("%.2f"), _AS_SQMETER(GetSideArea()))));
lstInfo.Append(new TObjInfoUnit(_T("截面周长"),
Dist2Str(GetShapePerimeter())));
lstInfo.Append(new TObjInfoUnit(_T("截面面积"),
XString(_T("%.2f"), _AS_SQMETER(GetShapeArea()))));
lstInfo.Append(new TObjInfoUnit(_T("体积"),
XString(_T("%.3f"), _AS_CUMETER(GetVolume()))));
}
///////////////////////////////////////////////////////////////
// GetMethos
const XPoly2D &
TDbCurveMesh2::GetShapePoly() const
{
assertReadEnabled();
return m_polyShape;
}
XPoint
TDbCurveMesh2::GetShapeBase() const
{
assertReadEnabled();
return m_ptShapeBase;
}
BOOL
TDbCurveMesh2::IsShapeShow() const
{
assertReadEnabled();
return ((m_nCMFlag&CMF_SHOWSHAPE)!=0);
}
BOOL
TDbCurveMesh2::Has2D() const
{
assertReadEnabled();
return ((m_nCMFlag&CMF_NO2D)==0);
}
BOOL
TDbCurveMesh2::Has3D() const
{
assertReadEnabled();
return ((m_nCMFlag&CMF_NO3D)==0);
}
BOOL
TDbCurveMesh2::HasDivide2D() const
{
assertReadEnabled();
return ((m_nCMFlag&CMF_DIVIDE2D)!=0);
}
void
TDbCurveMesh2::SetShapePoly(const XPoly2D &newShape)
{
assertWriteEnabled();
m_polyShape =newShape;
}
void
TDbCurveMesh2::ShowShape(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue)
m_nCMFlag |= CMF_SHOWSHAPE;
else
m_nCMFlag &= ~CMF_SHOWSHAPE;
}
void
TDbCurveMesh2::SetHas2D(BOOL bTrue)
{
assertWriteEnabled();
if(!bTrue) {
m_nCMFlag |= CMF_NO2D;
if(!Has3D())
m_nCMFlag &= ~CMF_NO3D;
} else {
m_nCMFlag &= ~CMF_NO2D;
}
}
void
TDbCurveMesh2::SetHas3D(BOOL bTrue)
{
assertWriteEnabled();
if(!bTrue) {
m_nCMFlag |= CMF_NO3D;
if(!Has2D())
m_nCMFlag &= ~CMF_NO2D;
} else
m_nCMFlag &= ~CMF_NO3D;
}
void
TDbCurveMesh2::SetHasDivide2D(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue)
m_nCMFlag |= CMF_DIVIDE2D;
else
m_nCMFlag &= ~CMF_DIVIDE2D;
}
void
TDbCurveMesh2::SetShapeBase(const XPoint &ptBase)
{
assertWriteEnabled();
m_ptShapeBase=ptBase;
}
// 工程量
double TDbCurveMesh2::GetPathLength() const
{
return m_polyBase.Distance3d();
}
double TDbCurveMesh2::GetShapePerimeter() const
{
return m_polyShape.Distance2d();
}
double TDbCurveMesh2::GetShapeArea() const
{
if(!m_polyShape.IsClosed())
return 0.0;
return m_polyShape.Area();
}
double TDbCurveMesh2::GetSideArea() const
{
return GetPathLength()*GetShapePerimeter();
}
double TDbCurveMesh2::GetVolume() const
{
return GetShapeArea()*GetPathLength();
}
// 取得二维平面上的投影区域,只针对normal=(0,0,1)。否则返回FALSE
BOOL TDbCurveMesh2::Get2DRegion(XPoly2D &poly2d) const
{
BOOL bRet=FALSE;
AcGeVector3d vt;
vt=m_vtNormal;
if(vt==AcGeVector3d(0,0,1) && !m_polyBase.IsClosed()) {
XPoint ptLow, ptUp;
m_polyShape.GetExtend(ptLow, ptUp);
double nOffset1=ptLow.x-m_ptShapeBase.x;
double nOffset2=ptUp.x - m_ptShapeBase.x;
XPoly2D polyBase(m_polyBase);
polyBase.SetElevation(0.0);
XPoly2D poly1, poly2;
polyBase.QuickOffset(nOffset1, poly1);
polyBase.QuickOffset(nOffset2, poly2);
poly2.Reverse();
for(int i=0; i<poly2.Length(); i++) {
poly1.AppendNode(*poly2[i], poly2.GetBulge(i));
}
poly2d=poly1;
bRet=TRUE;
}
return bRet;
}
void InitDbCurveMesh2(BOOL bTrue)
{
if(bTrue) {
TDbCurveMesh2::rxInit();
TDbCurveMesh2::SetEditMethod(EditCurveMesh2);
acrxBuildClassHierarchy();
TDbCurveMesh2::InitMatchProtocol(TRUE);
} else {
TDbCurveMesh2::InitMatchProtocol(FALSE);
deleteAcRxClass(TDbCurveMesh2::desc());
}
}
// 编辑路径曲面
int EditCurveMesh2(AcDbObjectId id)
{
XVector3D vtNormal=Ucs2Wcs(XVector3D(0,0,1), TRUE);
((AcGeVector3d &)vtNormal).normalize();
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbCurveMesh2, pStep);
if(!pStep)
return RTERROR;
while(1) {
int bBind=pStep->IsBind();
XString sPrompts, sKeywords;
if(bBind) {
sPrompts << _T("\n选择 [解除绊定(B)/截面显示(W)/改截面(H)");
sKeywords << _T("B W H G");
} else {
sPrompts << _T("\n选择 [加顶点(A)/减顶点(D)/设置顶点(S)/截面显示(W)/改截面(H)");
sKeywords << _T("A D S W H G");
}
if(pStep->Has2D())
sPrompts << _T("/关闭二维(G)]<退出>:");
else
sPrompts << _T("/开启二维(G)]<退出>:");
XString sKeyword;
int nRet=0;
INITGET_BEG(0, sKeywords);
nRet=ads_getkword(sPrompts, sKeyword);
INITGET_END();
if(nRet!=RTNORM)
break;
TCHAR cKey=sKeyword[0];
if(cKey==_T('A') || cKey==_T('D') || cKey==_T('S')) {
if(vtNormal.AsAcGeVector3d()!=pStep->GetNormal()) {
adsout << _T("\n当前构造平面与对象的构造平面不一致!");
continue;
}
}
if(sKeyword[0]==_T('A')) {
XPoint ptAdd;
if(XGetPoint(NULL, _T("\n点取新的顶点位置"), ptAdd)==RTNORM) {
ptAdd = Ucs2Ecs(ptAdd, vtNormal);
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
if(!pStep->AddVertex(ptAdd)) {
adsout << _T("\n请正确点取!");
}
pStep->downgradeOpen();
}
} else if(sKeyword[0]==_T('D')) {
XPushVar<int> osmode(_T("OSMODE"), OS_END);
XPushMemVar<BOOL> vTemp(g_bSnapCurveBase,TRUE);
XPoint ptVert;
while(ads_getpoint(NULL, _T("\n选取顶点: "), ptVert)==RTNORM) {
ptVert=Ucs2Ecs(ptVert, vtNormal);
int nPos=pStep->HitTestOnBase2d(ptVert);
if(nPos>0) {
nPos--;
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->RemoveVertexAt(nPos);
pStep->downgradeOpen();
} else {
adsout << _T("\n请正确点取!");
}
}
} else if(sKeyword[0]==_T('S')) {
XPushVar<int> osmode(_T("OSMODE"), OS_END);
XPushMemVar<BOOL> vTemp(g_bSnapCurveBase,TRUE);
XPoint ptVert;
while(ads_getpoint(NULL, _T("\n选取顶点: "), ptVert)==RTNORM) {
int nPos=pStep->HitTestOnBase2d(ptVert);
if(nPos>0) {
nPos--;
double nElev=pStep->GetElevationAt(nPos);
adsout << _T("\n改夹角[A]/点取[P]/输入顶点标高<")
<< Dist2Str(nElev)
<< _T(">: ");
int nCode;
INITGET_BEG(0, _T("A P"));
nCode=ads_getreal(_T(""), &nElev);
INITGET_END();
if(nCode==RTKWORD) {
TCHAR szKey[80]=_T("");
ads_getinput(szKey);
if(szKey[0]==_T('P')) {
XPushVar<int> osMode(_T("OSMODE"), OS_NEA);
XPoint ptElev;
nCode=ads_getpoint(NULL, _T("\n点取参照物:"), ptElev);
if(nCode==RTNORM) {
ptElev = Ucs2Ecs(ptElev, vtNormal);
nElev=ptElev.z;
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->SetElevationAt(nPos, nElev);
pStep->downgradeOpen();
}
} else if(szKey[0]==_T('A')) {
double nOldAng=pStep->GetSweepAngleAt(nPos)*180.0/PI;
nCode=GetReal(_T("\n输入夹角"), nOldAng);
if(nCode==RTNORM) {
nOldAng *= PI/180.0;
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->SetSweepAngleAt(nPos, nOldAng);
pStep->downgradeOpen();
}
}
} else if(nCode==RTNORM) {
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->SetElevationAt(nPos, nElev);
pStep->downgradeOpen();
}
} else {
adsout << _T("\n请正确点取!");
}
}
} else if(sKeyword[0]==_T('W')) {
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->ShowShape(!pStep->IsShapeShow());
pStep->downgradeOpen();
} else if(sKeyword[0]==_T('H')) {
RBList rbMask2(RTDXF0, _T("POLYLINE,LWPOLYLINE"), NULL);
Entity ent2;
if(ent2.FilterSelect(_T("\n请选择作为断面形状的多段线:"), rbMask2)==RTNORM) {
XPoly2D polyShape(ent2);
if(!polyShape) continue;
XVector3D vtPoly;
if(ent2.GetData(210, &vtPoly)!=RTNORM)
vtPoly=XVector3D(0,0,1);
if(vtPoly.AsAcGeVector3d()!=vtNormal.AsAcGeVector3d()) {
adsout << _T("\n所选对象的构造平面与当前构造平面不平行!");
continue;
}
XPoint ptBase;
if(XGetPoint(NULL, _T("\n请点取截面基点"), ptBase)!=RTNORM)
continue;
ptBase=Ucs2Ecs(ptBase, vtNormal);
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->SetShapePoly(polyShape);
pStep->SetShapeBase(ptBase);
pStep->downgradeOpen();
}
} else if(sKeyword[0]==_T('B')) {
if(pStep->IsBind()) {
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->UnBind();
pStep->downgradeOpen();
}
} else if(sKeyword[0]==_T('G')) {
if(pStep->upgradeOpen()==Acad::eOk) {
pStep->SetHas2D(!pStep->Has2D());
pStep->downgradeOpen();
}
}
}
OPENOBJ_END();
return RTNORM;
}