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

1151 lines
36 KiB
C++

#include "stdafx.h"
#include "TDbColumn.h"
const Adesk::UInt8 TDbCurveMesh::g_nVersion = 1;
ACRX_DXF_DEFINE_MEMBERS(ATSCurveMesh, ATSPolyPathEnt, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, ATS_CURVEMESH, "ATS_CURVEMESH图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(TDbCurveMesh);
TDbCurveMesh::TDbCurveMesh()
:m_nCMFlag(0), m_vtNormal(0,0,1)
{
}
TDbCurveMesh::~TDbCurveMesh()
{
}
BOOL TDbCurveMesh::IsValid() const
{
BOOL bRet=TDbPolyPathEnt::IsValid();
if(!bRet)
return bRet;
bRet=(m_polyBase.Length()>1 &&
m_polyShape.Length()>1);
return bRet;
}
// 提供对格式刷的支持
void TDbCurveMesh::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
TDbPolyPathEnt::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbCurveMesh *pSrc=TDbCurveMesh::cast(pSrcEntity);
if(pSrc) {
m_nCMFlag=pSrc->m_nCMFlag;
}
}
Acad::ErrorStatus
TDbCurveMesh::subGetClassID(CLSID* pClsid) const
{
return Acad::eOk;
}
// 从DWG读入数据:
Acad::ErrorStatus TDbCurveMesh::dwgInFields (AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbPolyPathEnt::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 Base Poly
pFiler->readItem(&(AcGeVector3d &)m_vtNormal);
m_polyBase.Reset();
Adesk::UInt8 nPolyFlag;
pFiler->readItem(&nPolyFlag);
m_polyBase.SetFlag(nPolyFlag);
Adesk::UInt16 m_nCount=0;
pFiler->readItem(&m_nCount);
for(Adesk::UInt16 i=0; i<m_nCount; i++) {
AcGePoint3d pt;
double nBulge=0.0;
pFiler->readItem(&pt);
pFiler->readItem(&nBulge);
m_polyBase.AppendNode(XPoint(pt), nBulge);
}
// Read ShapePoly
AcGePoint2d ptBase;
pFiler->readItem(&ptBase);
m_ptShapeBase=ptBase;
ReadPoly2D(pFiler, m_polyShape);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbCurveMesh::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbPolyPathEnt::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
pFiler->writeItem(g_nVersion);
pFiler->writeItem(m_nCMFlag);
pFiler->writeItem((AcGeVector3d &)m_vtNormal);
// Write BasePoly
pFiler->writeItem((Adesk::UInt8) m_polyBase.GetFlag());
Adesk::UInt16 nCount=m_polyBase.Length();
pFiler->writeItem(nCount);
for(Adesk::UInt16 i=0; i<nCount; i++) {
pFiler->writeItem((AcGePoint3d &)m_polyBase[i]);
pFiler->writeItem(m_polyBase.GetBulge(i));
}
// Write ShapePoly
pFiler->writeItem((AcGePoint2d &)m_ptShapeBase);
WritePoly2D(pFiler, m_polyShape);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbCurveMesh::dxfInFields (AcDbDxfFiler* pFiler)
{
Acad::ErrorStatus es= TDbPolyPathEnt::dxfInFields(pFiler);
if(es!=Acad::eOk)
return es;
if (!pFiler->atSubclassData(_T("TDbCurveMesh"))) {
return Acad::eBadDxfSequence;
}
int fieldsFlags=0;
resbuf rb;
int n1, n2, n3;
DList<XPoint> pts1, pts2;
XPoint pt;
XVector3D vt;
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+1:
n2=rb.resval.rint;
fieldsFlags |= 0x04;
break;
case AcDb::kDxfInt16+2:
n3=rb.resval.rint;
fieldsFlags |= 0x08;
break;
case AcDb::kDxfNormalX:
vt=rb.resval.rpoint;
fieldsFlags |= 0x10;
break;
case AcDb::kDxfXCoord:
pts1.Append(new XPoint(rb.resval.rpoint));
break;
case AcDb::kDxfAngle:
bulges1.Append(new double(rb.resval.rreal));
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(pts1.Length()<2 || pts1.Length()!=bulges1.Length()) {
pFiler->setError(_T("\nError DXF group code: 10, 50"));
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&0x04)
m_polyBase.SetFlag(n2);
if(fieldsFlags&0x08)
m_polyShape.SetFlag(n3);
m_vtNormal=vt;
m_polyBase.Reset();
for(int i=0; i<pts1.Length(); i++) {
m_polyBase.AppendNode(*pts1[i], *bulges1[i]);
}
m_polyShape.Reset();
for(i=0; i<pts2.Length(); i++) {
m_polyShape.AppendNode(*pts2[i], *bulges2[i]);
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbCurveMesh::dxfOutFields(AcDbDxfFiler* pFiler) const
{
Acad::ErrorStatus es;
es = TDbPolyPathEnt::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbCurveMesh"));
assert(es == Acad::eOk);
pFiler->writePoint2d(AcDb::kDxfXCoord+2, m_ptShapeBase);
pFiler->writeInt16(AcDb::kDxfInt16, m_nCMFlag);
pFiler->writeInt16(AcDb::kDxfInt16+1, m_polyBase.GetFlag());
pFiler->writeInt16(AcDb::kDxfInt16+2, m_polyShape.GetFlag());
pFiler->writeVector3d(AcDb::kDxfNormalX, m_vtNormal);
for(int i=0; i<m_polyBase.Length(); i++) {
pFiler->writePoint3d(AcDb::kDxfXCoord, m_polyBase[i]);
pFiler->writeDouble(AcDb::kDxfAngle, m_polyBase.GetBulge(i));
}
for(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
TDbCurveMesh::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 TDbPolyPathEnt::subGetOsnapPoints(osnapMode, gsSelectionMark,
ptPick, lastPoint, viewXform, snapPoints, geomIds);
}
// Overriden functions for edit
// to do:
// 对于自定义柱子,应当允许通过夹点改变边界
Acad::ErrorStatus TDbCurveMesh::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
TDbPolyPathEnt::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 TDbCurveMesh::subTransformBy(const AcGeMatrix3d& xform)
{
extern XString GetCurCommand();
assertWriteEnabled();
if(!IsBind()) {
#if 0
double nElevOld=m_ptShapeBase.z;
double nElevNew=nElevOld;
AcGeMatrix2d xform2d(xform.convertToLocal(m_vtNormal,nElevNew));
((AcGeVector3d &)m_vtNormal).normalize();
ads_matrix mat={{xform2d(0,0), xform2d(0,1), 0, xform2d(0,2)},
{xform2d(1,0), xform2d(1,1), 0, xform2d(1,2)},
{0,0,1, nElevNew-nElevOld},
{0,0,0,1}};
for(int i=0; i<m_polyBase.Length(); i++)
m_polyBase[i]->TransformBy(mat);
#endif
XVector3D vtNormalOld=GetNormal();
TDbPolyPathEnt::subTransformBy(xform);
XVector3D vtNormalNew=GetNormal();
ads_matrix mat;
GetLocalMatrix(xform, mat);
XPoint ptOldBase=m_ptShapeBase;
m_ptShapeBase.TransformBy(mat);
m_ptShapeBase.z=0;
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);
}
} else {
TDbEntity::subTransformBy(xform);
}
return Acad::eOk;
}
///////////////////////////////////////////
// 功能: 夹点操作
// 状态: 有待完成修改相关墙体的操作
Acad::ErrorStatus TDbCurveMesh::subMoveGripPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
TDbPolyPathEnt::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 TDbCurveMesh::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 TDbCurveMesh::GetGripText(int idx, CString &cs) const
{
Acad::ErrorStatus es=TDbPolyPathEnt::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 TDbCurveMesh::IsClipMe(const TEntityBase* pEnt)const
{
if(TDbEntity::IsClipMe(pEnt))
return true;
if(pEnt->GetMe()->isKindOf(TDbColumn::desc()))
return true;
return false;
}
// 绘制2D的显示, 二维显示网格
Acad::ErrorStatus TDbCurveMesh::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
TDbCurveMesh::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 TDbCurveMesh::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 &
TDbCurveMesh::GetShapePoly() const
{
assertReadEnabled();
return m_polyShape;
}
const XPoly2D &
TDbCurveMesh::GetBasePoly() const
{
assertReadEnabled();
return m_polyBase;
}
XPoint
TDbCurveMesh::GetShapeBase() const
{
assertReadEnabled();
return m_ptShapeBase;
}
XVector3D
TDbCurveMesh::GetNormal() const
{
assertReadEnabled();
return m_vtNormal;
}
BOOL
TDbCurveMesh::IsShapeShow() const
{
assertReadEnabled();
return ((m_nCMFlag&CMF_SHOWSHAPE)!=0);
}
BOOL
TDbCurveMesh::Has2D() const
{
assertReadEnabled();
return ((m_nCMFlag&CMF_NO2D)==0);
}
BOOL
TDbCurveMesh::Has3D() const
{
assertReadEnabled();
return ((m_nCMFlag&CMF_NO3D)==0);
}
BOOL
TDbCurveMesh::HasDivide2D() const
{
assertReadEnabled();
return ((m_nCMFlag&CMF_DIVIDE2D)!=0);
}
void
TDbCurveMesh::SetShapePoly(const XPoly2D &newShape)
{
assertWriteEnabled();
m_polyShape =newShape;
}
void
TDbCurveMesh::SetBasePoly(const XPoly2D &newBase)
{
assertWriteEnabled();
m_polyBase=newBase;
}
void
TDbCurveMesh::SetNormal(const XVector3D &vtNormal)
{
assertWriteEnabled();
m_vtNormal=vtNormal;
((AcGeVector3d &)m_vtNormal).normalize();
}
void
TDbCurveMesh::ShowShape(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue)
m_nCMFlag |= CMF_SHOWSHAPE;
else
m_nCMFlag &= ~CMF_SHOWSHAPE;
}
void
TDbCurveMesh::SetHas2D(BOOL bTrue)
{
assertWriteEnabled();
if(!bTrue) {
m_nCMFlag |= CMF_NO2D;
if(!Has3D())
m_nCMFlag &= ~CMF_NO3D;
} else {
m_nCMFlag &= ~CMF_NO2D;
}
}
void
TDbCurveMesh::SetHas3D(BOOL bTrue)
{
assertWriteEnabled();
if(!bTrue) {
m_nCMFlag |= CMF_NO3D;
if(!Has2D())
m_nCMFlag &= ~CMF_NO2D;
} else
m_nCMFlag &= ~CMF_NO3D;
}
void
TDbCurveMesh::SetHasDivide2D(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue)
m_nCMFlag |= CMF_DIVIDE2D;
else
m_nCMFlag &= ~CMF_DIVIDE2D;
}
void
TDbCurveMesh::SetShapeBase(const XPoint &ptBase)
{
assertWriteEnabled();
m_ptShapeBase=ptBase;
}
// 工程量
double TDbCurveMesh::GetPathLength() const
{
return m_polyBase.Distance3d();
}
double TDbCurveMesh::GetShapePerimeter() const
{
return m_polyShape.Distance2d();
}
double TDbCurveMesh::GetShapeArea() const
{
if(!m_polyShape.IsClosed())
return 0.0;
return m_polyShape.Area();
}
double TDbCurveMesh::GetSideArea() const
{
return GetPathLength()*GetShapePerimeter();
}
double TDbCurveMesh::GetVolume() const
{
return GetShapeArea()*GetPathLength();
}
// 取得二维平面上的投影区域,只针对normal=(0,0,1)。否则返回FALSE
BOOL TDbCurveMesh::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 InitDbCurveMesh(BOOL bTrue)
{
if(bTrue) {
TDbCurveMesh::rxInit();
TDbCurveMesh::SetEditMethod(EditCurveMesh0);
acrxBuildClassHierarchy();
TDbCurveMesh::InitMatchProtocol(TRUE);
} else {
TDbCurveMesh::InitMatchProtocol(FALSE);
deleteAcRxClass(TDbCurveMesh::desc());
}
}
// 编辑路径曲面
int EditCurveMesh0(AcDbObjectId id)
{
XVector3D vtNormal=Ucs2Wcs(XVector3D(0,0,1), TRUE);
((AcGeVector3d &)vtNormal).normalize();
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbCurveMesh, 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().AsAcGeVector3d()) {
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_NOD);
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 if(sKeyword[0]==_T('S')) {
XPushVar<int> osmode(_T("OSMODE"), OS_NOD);
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;
}