Files
envi-code/SourceCode/Code2026/tg_shs/shs_kernal/DbSlope.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

1442 lines
33 KiB
C++

#include "stdafx.h"
#include "dbid.h"
extern int GetContourDivNum(double dPerimeter);
static int CompareObjectIds(const AcDbSoftPointerId *p1, const void *p2)
{
if(*p1==*(const AcDbSoftPointerId *)p2)
return 0;
return 1;
}
static int CompareArea(const XPoly2D *p1, const XPoly2D *p2)
{
if(p1->Area()>p2->Area())
return 1;
return -1;
}
TReactor::TReactor()
{
}
TReactor::TReactor(const TReactor& src)
{
int nCount = src.m_lstReactor.Length();
for (int i = 0; i < nCount; i++) {
AcDbSoftPointerId* objId =
new AcDbSoftPointerId(src.m_lstReactor[i]);
m_lstReactor.Append(objId);
}
}
TReactor::~TReactor()
{
}
BOOL TReactor::IsValid() const
{
int nCount = m_lstReactor.Length();
for (int i=0; i<nCount; i++) {
if (m_lstReactor[i].isNull()) {
return FALSE;
}
}
return TRUE;
}
BOOL TReactor::HasReactor() const
{
return m_lstReactor.Length()>0;
}
void TReactor::
GetReactors(DList<AcDbObjectId>& lstReactorId) const
{
lstReactorId.Reset();
int nCount = m_lstReactor.Length();
for (int i=0; i<nCount; i++) {
AcDbObjectId* objId =
new AcDbObjectId(m_lstReactor[i]);
lstReactorId.Append(objId);
}
}
void TReactor::
SetReactors(const DList<AcDbObjectId>& lstReactorId)
{
int nCount = lstReactorId.Length();
for (int i=0; i<nCount; i++) {
AcDbSoftPointerId* objId =
new AcDbSoftPointerId(lstReactorId[i]);
m_lstReactor.Append(objId);
}
}
void TReactor::
GetReactors(AcDbObjectIdArray& arReactorId) const
{
arReactorId.setLogicalLength(0);
int nCount = m_lstReactor.Length();
for (int i=0; i<nCount; i++) {
arReactorId.append(m_lstReactor[i]);
}
}
void TReactor::
SetReactors(const AcDbObjectIdArray& arReactorId)
{
int nCount = arReactorId.length();
for (int i=0; i<nCount; i++) {
AcDbSoftPointerId* objId =
new AcDbSoftPointerId(arReactorId[i]);
m_lstReactor.Append(objId);
}
}
BOOL TReactor::
IsExist(const AcDbObjectId& objId)
{
if(m_lstReactor.FindNode(&objId,CompareObjectIds))
return TRUE;
return FALSE;
}
Acad::ErrorStatus
TReactor::Attach(AcDbObject* pObj)
{
if(pObj==NULL)
return Acad::eNullObjectPointer;
return Attach(pObj->objectId());
}
Acad::ErrorStatus
TReactor::Detach(AcDbObject* pObj)
{
if(pObj==NULL)
return Acad::eNullObjectPointer;
return Detach(pObj->objectId());
}
Acad::ErrorStatus
TReactor::Attach(const AcDbObjectId& objId)
{
if(IsExist(objId))
return Acad::eAlreadyInDb;
m_lstReactor.Append(new AcDbSoftPointerId(objId));
return Acad::eOk;
}
Acad::ErrorStatus
TReactor::Detach(const AcDbObjectId& objId)
{
if (!IsExist(objId))
return Acad::eKeyNotFound;
m_lstReactor.Remove();
return Acad::eOk;
}
void TReactor::DetachAll()
{
m_lstReactor.Reset();
}
Acad::ErrorStatus
TReactor::DwgInFields(AcDbDwgFiler* pFiler)
{
Adesk::Int32 nCount;
pFiler->readItem(&nCount);
m_lstReactor.Reset();
for (int i=0; i<nCount; i++) {
AcDbSoftPointerId idTemp;
pFiler->readItem(&idTemp);
m_lstReactor.Append(new AcDbSoftPointerId(idTemp));
}
return pFiler->filerStatus();
}
Acad::ErrorStatus
TReactor::DwgOutFields(AcDbDwgFiler* pFiler) const
{
int nCount = m_lstReactor.Length();
pFiler->writeInt32(nCount);// nCount of ids
for (int i=0; i<nCount; i++) {
AcDbSoftPointerId idRector = m_lstReactor[i];
pFiler->writeSoftPointerId(idRector);
}
return pFiler->filerStatus();
}
Acad::ErrorStatus
TReactor::DxfInFields(AcDbDxfFiler* pFiler)
{
resbuf rb;
Acad::ErrorStatus es=Acad::eOk;
m_lstReactor.Reset();
while ((es == Acad::eOk) &&
((es=pFiler->readResBuf(&rb)) == Acad::eOk)) {
if (rb.restype == AcDb::kDxfSoftPointerId) {
AcDbSoftPointerId idTemp;
#ifdef _WIN64
idTemp.setFromOldId(rb.resval.mnInt64);
#else
idTemp.setFromOldId(rb.resval.rlong);
#endif
m_lstReactor.Append(new AcDbSoftPointerId(idTemp));
}
else {
pFiler->pushBackItem();
es = Acad::eEndOfFile;
}
}
if (es != Acad::eEndOfFile)
return Acad::eInvalidResBuf;
return pFiler->filerStatus();
}
Acad::ErrorStatus
TReactor::DxfOutFields(AcDbDxfFiler* pFiler) const
{
int nCount = m_lstReactor.Length();
for (int i=0; i<nCount; i++) {
pFiler->writeItem(AcDb::kDxfSoftPointerId,m_lstReactor[i]);
}
return pFiler->filerStatus();
}
void TReactor::TransformBy(const AcGeMatrix3d xform)
{
int nCount = m_lstReactor.Length();
for (int i=0; i<nCount; i++) {
AcDbObjectId &idReactor = *m_lstReactor[i];
OPENOBJ_BEGIN(idReactor,AcDb::kForWrite,AcDbEntity,pEnt);
if (pEnt != NULL) {
pEnt->transformBy(xform);
}
OPENOBJ_END();
}
}
BOOL TReactor::IsShowReactor() const
{
BOOL bShow=TRUE;
int nCount = m_lstReactor.Length();
for(int i=0; i<nCount; i++) {
AcDbObjectId objId = m_lstReactor[i];
OPENOBJ_BEGIN(objId, AcDb::kForRead, AcDbEntity, pEnt);
if (pEnt != NULL) {
AcDb::Visibility oldVas;
oldVas = pEnt->visibility();
if (oldVas == AcDb::kInvisible) {
bShow = FALSE;
break;
}
}
OPENOBJ_END();
}
return bShow;
}
void TReactor::ShowReactor(BOOL bShow)
{
AcDb::Visibility oldVas, newVal =
bShow?AcDb::kVisible:AcDb::kInvisible;
int nCount = m_lstReactor.Length();
for(int i=0; i<nCount; i++) {
AcDbObjectId& objId = *m_lstReactor[i];
OPENOBJ_BEGIN(objId, AcDb::kForRead, AcDbEntity, pEnt);
if (pEnt != NULL) {
oldVas = pEnt->visibility();
if (oldVas != newVal) {
if(pEnt->upgradeOpen()==Acad::eOk) {
pEnt->assertWriteEnabled();
pEnt->setVisibility(newVal);
pEnt->downgradeOpen();
}
}
}
OPENOBJ_END();
}
}
void TReactor::EraseReactor(BOOL bEraseAll)
{
int nCount = m_lstReactor.Length();
if(bEraseAll){
for(int i=0; i<nCount; i++) {
AcDbObjectId& objId = *m_lstReactor[i];
OPENOBJ_BEGIN(objId, AcDb::kForWrite, AcDbObject, pObj);
if (pObj != NULL) {
pObj->erase();
}
OPENOBJ_END();
}
}
else {
for(int i=0; i<nCount; i++) {
AcDbObjectId& objId = *m_lstReactor[i];
OPENOBJ_BEGIN(objId, AcDb::kForRead, AcDbObject, pObj);
if (pObj != NULL) {
//判断有多少永久实体
int nPersistentNum = 0;
const AcDbVoidPtrArray *pReactors;
void *pSomething;
pReactors = pObj->reactors();
if (pReactors != NULL && pReactors->length() > 0) {
for (int j = 0; j < pReactors->length(); j++) {
pSomething = pReactors->at(j);
if (acdbIsPersistentReactor(pSomething)) {
nPersistentNum++;
break;
}
}
}
//如果少于两个,删除
if (nPersistentNum<=0){
if(pObj->upgradeOpen()==Acad::eOk) {
pObj->assertWriteEnabled();
pObj->erase();
pObj->downgradeOpen();
}
}
}
OPENOBJ_END();
}
}
DetachAll();
}
void TReactor::RemovePersistentReactor(const AcDbObjectId& objId)
{
if (objId.isNull())
return;
int nCount = m_lstReactor.Length();
for(int j=0; j<nCount; j++) {
AcDbObjectId& idReactor = *m_lstReactor[j];
OPENOBJ_BEGIN(idReactor, AcDb::kForRead, AcDbObject, pReactor);
if (pReactor==NULL)
continue;
const AcDbVoidPtrArray *pReactors;
void *pSomething;
pReactors = pReactor->reactors();
if (pReactors==NULL || pReactors->length()<=0)
continue;
for (int k = 0; k < pReactors->length(); k++) {
pSomething = pReactors->at(k);
if (acdbIsPersistentReactor(pSomething)) {
AcDbObjectId idPer=acdbPersistentReactorObjectId(pSomething);
if (idPer == objId) {
if(pReactor->upgradeOpen()==Acad::eOk) {
pReactor->assertWriteEnabled();
pReactor->removePersistentReactor(objId);
pReactor->downgradeOpen();
}
break;
}
}
}
OPENOBJ_END();
}
}
///////////////////////////////////////////////////////////////
// 类名 : TReactor END
// 类名 : TSlope BEGIN
///////////////////////////////////////////////////////////////
void TSlope::ResetAll()
{
m_subSlopes.Reset();
Reset();
}
void TSlope::GetPolys(DList<XPoly2D> &lstPoly) const
{
XPoly2D* poly2d = new XPoly2D(*this);
if(poly2d->Length() > 0)
lstPoly.Append(poly2d);
else
delete poly2d;
int nCount = m_subSlopes.Length();
for(int i=0; i<nCount; i++) {
m_subSlopes[i].GetPolys(lstPoly);
}
}
void TSlope::ProcessSlope(DList<XPoly2D> &sortedRegions, TSlope *parent)
{
if(!IsValid())
return;
DList<XPoly2D> lstOutside(FALSE), lstInside(FALSE);
int nRegionNum=sortedRegions.Length();
XPoly2D polyThis=(*this);
polyThis.SetElevation(0.0);
for(int n=nRegionNum-1; n>=0; n--) {
XPoly2D *polyTemp=sortedRegions[n];
XPoly2D &poly2d=(*polyTemp);
XPoint ptMid=poly2d.GetInsidePoint(); //
ptMid.z=0;
int nPrFlag=(ptMid&polyThis); //只有z坐标为0,才能判断正确的关系
DList<XPoly2D> &rList=(nPrFlag==PR_INSIDE? lstInside : lstOutside);
if(!rList)
rList.Append(polyTemp);
else {
rList[0];
rList.Insert(polyTemp);
}
}
if(lstInside.Length()) {
TSlope *pSub=new TSlope;
(XPoly2D &)(*pSub)=*lstInside.Tail();
lstInside.Remove(lstInside.Length()-1); //Remove tail
m_subSlopes.Append(pSub);
if(lstInside.Length())
pSub->ProcessSlope(lstInside, this);
}
if(parent && lstOutside.Length())
parent->ProcessSlope(lstOutside);
}
void TSlope::TransformBy(const AcGeMatrix3d xform)
{
XPoly2D::TransformBy(xform);
for(int i=0; i<m_subSlopes.Length(); i++)
m_subSlopes[i]->TransformBy(xform);
}
Acad::ErrorStatus TSlope::DwgInFields (AcDbDwgFiler* filer)
{
double nElev=0;
filer->readItem(&nElev);
Acad::ErrorStatus es=ReadPoly2D(filer, *this);
if(es!=Acad::eOk)
return es;
SetElevation(nElev);
m_subSlopes.Reset();
Adesk::UInt16 nCount=0;
filer->readItem(&nCount);
for(int i=0; i<nCount; i++) {
TSlope *pSub=new TSlope;
pSub->DwgInFields(filer);
m_subSlopes.Append(pSub);
}
return Acad::eOk;
}
Acad::ErrorStatus TSlope::DwgOutFields(AcDbDwgFiler* filer) const
{
if(Length()<1)
return Acad::eInvalidInput;
double nElev=(*this)[0].z;
filer->writeItem(nElev);
Acad::ErrorStatus es=WritePoly2D(filer, *this);
if(es!=Acad::eOk)
return es;
Adesk::UInt16 nCount=m_subSlopes.Length();
filer->writeItem(nCount);
for(int i=0; i<nCount; i++) {
const TSlope &rSub=m_subSlopes[i];;
es=rSub.DwgOutFields(filer);
if(es!=Acad::eOk)
return es;
}
return Acad::eOk;
}
BOOL TSlope::IsValid() const
{
BOOL bRet=((GetFlag()&0x01) && Length()>=2);
return bRet;
}
// 绘制二维
Acad::ErrorStatus
TSlope::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
XPoly2D poly2d(*this);
poly2d.SetElevation(0.0);
dc << poly2d;
for(int i=0; i<m_subSlopes.Length(); i++) {
m_subSlopes[i].ExplodeOrDraw2d(dc);
}
return Acad::eOk;
}
Acad::ErrorStatus
TSlope::ExplodeOrDraw3d(XExplodeDraw &dc,BOOL bSlope,int nVertexNum) const
{
if(!IsValid())
return Acad::eInvalidInput;
int nCount=m_subSlopes.Length();
XPoly2D polyThis(*this);
if (!polyThis)
return Acad::eOk;
if (bSlope) {//斜坡模式
XContour contourThis(polyThis,nVertexNum);
polyThis.Reset();
polyThis.SetFlag(1);
contourThis.AsPoly2D(polyThis);
dc.DrawShell(polyThis);
for(int i=0; i<nCount; i++) {
XPoly2D polySub(m_subSlopes[i]);
if(!polySub)
continue;
XContour contourSub(polySub,nVertexNum);
if (contourThis.Length()==contourSub.Length()) {
polySub.Reset();
polySub.SetFlag(1);
contourSub.AsPoly2D(polySub);
dc.DrawMesh(polySub, polyThis);
}
}
for(i=0; i<nCount; i++)
m_subSlopes[i].ExplodeOrDraw3d(dc,bSlope,nVertexNum);
}
else {//梯田模式
double nElev=polyThis[0]->z;
dc.DrawShell(polyThis);
for(int i=0; i<nCount; i++) {
XPoly2D polySub(m_subSlopes[i]);
if(!polySub)
continue;
double nElev1=polySub[0]->z;
polySub.SetElevation(nElev);
XVector3D vt(0,0, nElev1-nElev);
dc.DrawMesh(polySub, vt);
}
for(i=0; i<nCount; i++)
m_subSlopes[i].ExplodeOrDraw3d(dc,bSlope,nVertexNum);
}
return Acad::eOk;
}
///////////////////////////////////////////////////////////////
// 类名 : TSlope END
// 类名 : TDbSlope BEGIN
///////////////////////////////////////////////////////////////
ACRX_DXF_DEFINE_MEMBERS(ATSSlope, ATSEntity, AcDb::kDHL_CURRENT,
AcDb::kMReleaseCurrent, 1, ATS_SLOPE, "ATS_SLOPE图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(TDbSlope);
const Adesk::UInt8 TDbSlope::g_nVersion = 1;
TDbSlope::TDbSlope()
:m_nControlFlag(0),m_nVertexNum(0),
m_nCMFlag(0),m_bEnableReact(TRUE),
m_bShowSlope(TRUE),m_bTransformBy(TRUE)
{
}
void TDbSlope::ShowSlope(BOOL bSlope)
{
assertWriteEnabled();
m_bShowSlope = bSlope;
}
BOOL TDbSlope::IsShowSlope() const
{
assertReadEnabled();
return m_bShowSlope;
}
void TDbSlope::EnableReact(BOOL bFlag)
{
assertWriteEnabled();
m_bEnableReact = bFlag;
}
BOOL TDbSlope::IsEnableReact() const
{
assertReadEnabled();
return m_bEnableReact;
}
void TDbSlope::SetVertexNum(int nNum)
{
assertWriteEnabled();
m_nVertexNum = nNum;
}
int TDbSlope::GetVertexNum() const
{
assertReadEnabled();
//未初始化时
if (m_nVertexNum < 3) {
int nVertexNum = 90;
double dPerimeter=m_slope.Distance3d();
if(dPerimeter<=0)
return 0;
nVertexNum=AS_INT(GetContourDivNum(dPerimeter)/2);//减小一倍
return nVertexNum;
}
return m_nVertexNum;
}
BOOL TDbSlope::Has2D() const
{
assertReadEnabled();
return (m_nCMFlag&CMF_NO2D)==0;
}
void TDbSlope::SetHas2D(BOOL bHas)
{
assertWriteEnabled();
if(!bHas) {
m_nCMFlag |= CMF_NO2D;
} else {
m_nCMFlag &= ~CMF_NO2D;
}
}
void TDbSlope::EnableTransformBy(BOOL bFlag)
{
assertWriteEnabled();
m_bTransformBy = bFlag;
}
BOOL TDbSlope::IsTransformBy() const
{
assertReadEnabled();
return m_bTransformBy;
}
void TDbSlope::NewReactor(Adesk::UInt16 color)
{
assertWriteEnabled();
AcDbObjectId idSlope=objectId();
if (idSlope.isNull())
return;
if(Has2D()) {//关闭二维显示
SetHas2D(FALSE);
}
RemovePersistentReactor(idSlope);
EraseReactor();
//得到等高线的XPoly2D
DList<XPoly2D> lstPoly;
m_slope.GetPolys(lstPoly);
int nCount=lstPoly.Length();
if(nCount <= 0)
return;
//生成新的Pline线
PickSet ssPline(SS_FREE);
ssPline.IncludeBegin();
for (int i=0; i<nCount; i++) {
XPoly2D &polyPline = *lstPoly[i];
polyPline.Make();
}
ssPline.IncludeEnd();
long lCount=ssPline.Length();
if(lCount <= 0)
return;
//转换成AcDbObjectId
AcDbObjectIdArray arReactorId;
for(long index=0L; index<lCount; index++) {
Entity objName=ssPline[index];
AcDbObjectId objId;
if(acdbGetObjectId(objId,objName)==Acad::eOk) {
arReactorId.append(objId);
}
}
//构造反应堆(永久响应)
EnableReact(FALSE);
int nLen=arReactorId.length();
for(int j=0; j<lCount; j++) {
AcDbObjectId objId;
objId=arReactorId[j];
//设置响应为不可见、红色、建立永久响应连接
OPENOBJ_BEGIN(objId, AcDb::kForWrite, AcDbEntity, pEnt);
if(pEnt != NULL) {
pEnt->setColorIndex(color);
pEnt->addPersistentReactor(idSlope);
}
OPENOBJ_END();
}
SetReactors(arReactorId);
EnableReact(TRUE);
}
// 提供对格式刷的支持
void TDbSlope::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
TDbEntity::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbSlope *pSrc=TDbSlope::cast(pSrcEntity);
if(pSrc) {
}
}
BOOL TDbSlope::IsValid() const
{
BOOL bValid=TDbEntity::IsValid();
if(!bValid)
return bValid;
bValid=TReactor::IsValid();
if(!bValid)
return bValid;
bValid = m_slope.IsValid();
return bValid;
}
/*
Acad::ErrorStatus
TDbSlope::getClassID(CLSID* pClsid) const
{
return Acad::eOk;
}
*/
// 从DWG读入数据:
Acad::ErrorStatus TDbSlope::dwgInFields (AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbEntity::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;
}
es = pFiler->readItem(&m_nControlFlag);
es = pFiler->readItem(&m_nVertexNum);
es = pFiler->readItem(&m_nCMFlag);
es = pFiler->readItem(&m_bEnableReact);
es = pFiler->readItem(&m_bShowSlope);
es = pFiler->readItem(&m_bTransformBy);
es = TReactor::DwgInFields(pFiler);
if(es != Acad::eOk) return es;
es = m_slope.DwgInFields(pFiler);
if(es != Acad::eOk) return es;
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbSlope::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbEntity::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
es = pFiler->writeItem(g_nVersion);
es = pFiler->writeItem(m_nControlFlag);
es = pFiler->writeItem(m_nVertexNum);
es = pFiler->writeItem(m_nCMFlag);
es = pFiler->writeItem(m_bEnableReact);
es = pFiler->writeItem(m_bShowSlope);
es = pFiler->writeItem(m_bTransformBy);
es = TReactor::DwgOutFields(pFiler);
if(es != Acad::eOk) return es;
es = m_slope.DwgOutFields(pFiler);
if(es != Acad::eOk) return es;
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbSlope::dxfInFields (AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es=TDbEntity::dxfInFields(pFiler);
if(es!=Acad::eOk) return es;
if (!pFiler->atSubclassData(_T("TDbSlope"))) {
return Acad::eBadDxfSequence;
}
es = TReactor::DxfInFields(pFiler);
if(es!=Acad::eOk) return es;
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbSlope::dxfOutFields(AcDbDxfFiler* pFiler) const
{
Acad::ErrorStatus es;
es = TDbEntity::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbSlope"));
assert(es == Acad::eOk);
es = TReactor::DxfOutFields(pFiler);
assert(es == Acad::eOk);
return es;
}
Acad::ErrorStatus
TDbSlope::subGetClassID(CLSID* pClsid) const
{
return Acad::eOk;
}
Acad::ErrorStatus
TDbSlope::subDeepClone(AcDbObject* pOwner,
AcDbObject*& pClonedObject,
AcDbIdMapping& idMap,
Adesk::Boolean isPrimary) const
{
Acad::ErrorStatus es=
TDbEntity::subDeepClone(pOwner, pClonedObject, idMap, isPrimary);
if(es!=Acad::eOk)
return es;
if(!HasReactor())
return Acad::eOk;
TDbSlope *pClonedSlope = TDbSlope::cast(pClonedObject);
ASSERT(pClonedSlope);
pClonedSlope->DetachAll();
return Acad::eOk;
}
Acad::ErrorStatus
TDbSlope::subTransformBy(const AcGeMatrix3d& xform)
{
extern XString GetCurCommand();
assertWriteEnabled();
TDbEntity::subTransformBy(xform);
if (!m_bTransformBy)
return Acad::eOk;
if(HasReactor()) {
if(database()!=NULL) {
EnableReact(FALSE);
TReactor::TransformBy(xform);
EnableReact(TRUE);
}
}
//圆周的分段数
BOOL bComputeVertex=FALSE;
int nVertexOld=0,nVertexNew=0;
if (_tcsicmp(GetCurCommand(), _T("SCALE"))==0 &&
m_nVertexNum>0) {
bComputeVertex=TRUE;
}
if (bComputeVertex) {
double dPerimeter=m_slope.Distance3d();
if(dPerimeter>0) {
nVertexOld=GetContourDivNum(dPerimeter);
}
}
m_slope.TransformBy(xform);
//圆周的分段数
if (bComputeVertex) {
double dPerimeter=m_slope.Distance3d();
if(dPerimeter>0) {
nVertexNew=GetContourDivNum(dPerimeter);
}
if (nVertexOld>0 && nVertexNew>0) {
double dScale = nVertexNew/nVertexOld;
m_nVertexNum = AS_INT(m_nVertexNum*dScale);
}
}
return Acad::eOk;
}
Acad::ErrorStatus
TDbSlope::subGetOsnapPoints(AcDb::OsnapMode osnapMode,
INT_PTR gsSelectionMark,
const AcGePoint3d& ptPick,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcGePoint3dArray& snapPoints,
AcDbIntArray& geomIds) const
{
Acad::ErrorStatus es=Acad::eOk;
int expMode=GetExplodeMode();
if(expMode==DRAW_2D) {
es = TDbEntity::subGetOsnapPoints(osnapMode, gsSelectionMark, ptPick,
lastPoint, viewXform, snapPoints, geomIds);
}
return es;
}
Acad::ErrorStatus TDbSlope::subErase(Adesk::Boolean bErasing)
{
AcDbObjectId idSlope=objectId();
Acad::ErrorStatus es = TDbEntity::subErase(bErasing);
if (es != Acad::eOk)
return es;
RemovePersistentReactor(idSlope);
EraseReactor();
return Acad::eOk;
}
// 绘制二维
Acad::ErrorStatus
TDbSlope::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
if (!Has2D()) {
return Acad::eOk;
} else {
return m_slope.ExplodeOrDraw2d(dc);
}
}
static int CompareByX(const XPoint *p1, const XPoint *p2)
{
if(p1->x<p2->x)
return -1;
return 1;
}
static int CompareByY(const XPoint *p1, const XPoint *p2)
{
if(p1->y<p2->y)
return -1;
return 1;
}
// 由X和Y两个方向进行拟合出高度
Acad::ErrorStatus TDbSlope::DrawSlope3d(XExplodeDraw &dc) const
{
DList<XPoly2D> lstOutlines;
m_slope.GetPolys(lstOutlines);
XPoly2D polyExt=m_slope;
int row=100, col=100;
double nExtElev=polyExt.Head()->z;
XPoint ptLow, ptUp;
polyExt.SetElevation(0.0);
polyExt.GetExtend(ptLow, ptUp);
AcGePoint3d *vertices=new AcGePoint3d[row*col];
XPointList *rowIntPoints=new XPointList[row];
XPointList *colIntPoints=new XPointList[col];
double nRowSpace=(ptUp.y-ptLow.y)/(row-1);
double nColSpace=(ptUp.x-ptLow.x)/(col-1);
// 求行交点,并按x由小到大排序
XLine lnRow;
lnRow.SetLineFlag(LS_FINITE);
lnRow.StartPoint().x=ptLow.x-_DIST_SNAP;
lnRow.EndPoint().x=ptUp.x+_DIST_SNAP;
for(int m=0; m<row; m++) {
lnRow.StartPoint().y=lnRow.EndPoint().y=ptLow.y+m*nRowSpace;
AcDbLine ln2d(lnRow.StartPoint(), lnRow.EndPoint());
for(int i=0; i<lstOutlines.Length(); i++) {
AcGePoint3dArray ptArray;
XPoly2D poly(*lstOutlines[i]);
double nElev=poly.Head()->z;
poly.SetElevation(0.0);
AcDbPolyline pline;
PolyConvert(poly, pline);
ln2d.intersectWith(&pline, AcDb::kOnBothOperands, ptArray);
for(int k=0; k<ptArray.length(); k++) {
XPoint ptInt;
ptInt=ptArray[k];
ptInt.z=nElev;
BOOL bAdd=TRUE;
for(int j=0; j<rowIntPoints[m].Length(); j++) {
XPoint &rpt=*rowIntPoints[m][j];
if(rpt.Distance2d(ptInt)<_DIST_SNAP) {
rpt.z = max(rpt.z, ptInt.z);
bAdd=FALSE;
break;
}
}
if(bAdd)
rowIntPoints[m].Append(new XPoint(ptInt));
}
}
rowIntPoints[m].QuickSort(CompareByX);
}
// 求列交点,并按y由小到大排序
XLine lnCol;
lnCol.SetLineFlag(LS_FINITE);
lnCol.StartPoint().y=ptLow.y-_DIST_SNAP;
lnCol.EndPoint().y=ptUp.y+_DIST_SNAP;
for(int n=0; n<col; n++) {
lnCol.StartPoint().x=lnCol.EndPoint().x=ptLow.x+n*nColSpace;
AcDbLine ln2d(lnCol.StartPoint(), lnCol.EndPoint());
for(int i=0; i<lstOutlines.Length(); i++) {
AcGePoint3dArray ptArray;
XPoly2D poly(*lstOutlines[i]);
double nElev=poly.Head()->z;
poly.SetElevation(0.0);
AcDbPolyline pline;
PolyConvert(poly, pline);
ln2d.intersectWith(&pline, AcDb::kOnBothOperands, ptArray);
for(int k=0; k<ptArray.length(); k++) {
XPoint ptInt;
ptInt=ptArray[k];
ptInt.z=nElev;
BOOL bAdd=TRUE;
for(int j=0; j<colIntPoints[n].Length(); j++) {
XPoint &rpt=*colIntPoints[n][j];
if(rpt.Distance2d(ptInt)<_DIST_SNAP) {
rpt.z = max(rpt.z, ptInt.z);
bAdd=FALSE;
break;
}
}
if(bAdd)
colIntPoints[n].Append(new XPoint(ptInt));
}
}
colIntPoints[n].QuickSort(CompareByY);
}
// 由行列两方向找交点拟合
for(m=0; m<row; m++) {
for(n=0; n<col; n++) {
AcGePoint3d &rPoint=vertices[m*col+n];
rPoint.y = ptLow.y+m*nRowSpace;
rPoint.x = ptLow.x+n*nColSpace;
double zx=nExtElev, zy=nExtElev;
XPointList &rRowList=rowIntPoints[m];
for(int i=0; i<rRowList.Length(); i++) {
XPoint &rInt=*rRowList[i];
if(Equal(rInt.x, rPoint.x, _DIST_SNAP)) {
zx=rInt.z;
break;
} else if(rPoint.x<rInt.x) {
if(!i)
break;
XPoint &rInt1=*rRowList[i-1];
if(Equal(rInt.x, rInt1.x, _DIST_SNAP)) {
zx=(rInt.z+rInt1.z)/2.0;
ASSERT(0);
} else { //线性插值
ASSERT(!Equal(rInt.x, rInt1.x, _DIST_SNAP));
zx = rInt1.z + (rPoint.x-rInt1.x)*(rInt.z-rInt1.z)/(rInt.x-rInt1.x);
}
break;
}
}
XPointList &rColList=colIntPoints[n];
for(i=0; i<rColList.Length(); i++) {
XPoint &rInt=*rColList[i];
if(Equal(rInt.y, rPoint.y, _DIST_SNAP)) {
zy=rInt.z;
break;
} else if(rPoint.y<rInt.y) {
if(!i)
break;
XPoint &rInt1=*rColList[i-1];
if(Equal(rInt.y, rInt1.y, _DIST_SNAP)) {
zy=(rInt.z+rInt1.z)/2.0;
ASSERT(0);
} else { //线性插值
ASSERT(!Equal(rInt.y, rInt1.y, _DIST_SNAP));
zy = rInt1.z + (rPoint.y-rInt1.y)*(rInt.z-rInt1.z)/(rInt.y-rInt1.y);
}
break;
}
}
rPoint.z = (zx+zy)/2.0;
}
}
dc.DrawMesh(m, n, vertices);
delete [] vertices;
delete [] rowIntPoints;
delete [] colIntPoints;
return Acad::eOk;
}
Acad::ErrorStatus
TDbSlope::ExplodeOrDraw3d(XExplodeDraw &dc) const
{
Acad::ErrorStatus es=Acad::eOk;
if (m_bShowSlope) {
if (m_nVertexNum < 3) {
int nVertexNum = 90;
double dPerimeter = m_slope.Distance3d();
if(dPerimeter<=0)
return Acad::eNotApplicable;
nVertexNum = AS_INT(GetContourDivNum(dPerimeter)/2); //减小一倍
if (nVertexNum < 3) {
adsout << _T("\n顶点数太少!请重新设置参数或者增大该实体。");
return Acad::eNotApplicable;
}
//es= m_slope.ExplodeOrDraw3d(dc,TRUE,nVertexNum);
es=DrawSlope3d(dc);
} else {
es=DrawSlope3d(dc);
//es = m_slope.ExplodeOrDraw3d(dc,TRUE,m_nVertexNum);
}
} else {
es = m_slope.ExplodeOrDraw3d(dc);
}
return es;
}
void TDbSlope::GetTips(DList<TObjInfoUnit> &lstInfo) const
{
lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("等高线")));
}
void TDbSlope::erased(const AcDbObject* pObj,Adesk::Boolean bErasing)
{
if (!IsEnableReact())
return;
Adesk::Boolean bWritable;
Acad::ErrorStatus es = upgradeFromNotify(bWritable);
if (es == Acad::eOk) {
AcDbObjectId idReactor = pObj->objectId();
if (bErasing) {
Detach(idReactor);
} else {
Attach(idReactor);
}
downgradeToNotify(bWritable);
}
}
void TDbSlope::modified(const AcDbObject* pObj)
{
if (!IsEnableReact())
return;
if (pObj->database()==NULL)
return;
if (isErased())
return;
ads_name entReactor;
AcDbObjectId idReactor = pObj->objectId();
//当前实体是否是自己的反应器
if(!IsExist(idReactor) ||
acdbGetAdsName(entReactor,idReactor)!=Acad::eOk) {
return;
}
//当前反应器
DList<XPoly2D> lstRegion;
XPoly2D* pReg=new XPoly2D(entReactor);
pReg->Compress();
if (pReg->Length()>0 && pReg->IsClosed()) {
lstRegion.Append(pReg);
} else {
delete pReg;
return;
}
//构造截面
int nCount = m_lstReactor.Length();
for (int i=0; i<nCount; i++) {
ads_name objName;
AcDbObjectId& objId = *m_lstReactor[i];
if(objId!=idReactor && acdbGetAdsName(objName,objId)==Acad::eOk) {
XPoly2D* pReg=new XPoly2D(objName);
pReg->Compress();
if (pReg->Length()>0 && pReg->IsClosed()) {
lstRegion.Append(pReg);
} else {
delete pReg;
}
}
}
if (lstRegion.Length()<=0)
return;
Adesk::Boolean bWritable;
Acad::ErrorStatus es = upgradeFromNotify(bWritable);
if (es == Acad::eOk) {
assertWriteEnabled();
m_slope.ResetAll();
lstRegion.QuickSort(CompareArea);
(XPoly2D &)(m_slope)=*lstRegion.Tail();
lstRegion.Remove(lstRegion.Length()-1);
m_slope.ProcessSlope(lstRegion);
downgradeToNotify(bWritable);
}/*
else {
if(upgradeOpen()==Acad::eOk) {
m_slope.ResetAll();
lstRegion.QuickSort(CompareArea);
(XPoly2D &)(m_slope)=*lstRegion.Tail();
lstRegion.Remove(lstRegion.Length()-1);
m_slope.ProcessSlope(lstRegion);
downgradeOpen();
}
}*/
}
// 创建斜坡等高线
void CreateSlope()
{
RBList mask=ads_buildlist(-4, _T("<or"),
-4, _T("<and"),
RTDXF0, _T("POLYLINE,LWPOLYLINE"),
70, 1,
-4, _T("and>"),
RTDXF0, _T("CIRCLE"),
-4, _T("or>"), NULL);
PickSet ssSelect(SS_FREE);
if(SelectEntities(_T("\n选择闭合曲线"), ssSelect, mask)!=RTNORM)
return;
//**** 以下是未定义永久响应的斜坡实体 ****//
/*DList<XPoly2D> lstRegion;
long lCount=ssSelect.Length();
for(long idx=0L; idx<lCount; idx++) {
Entity ent=ssSelect[idx];
XPoly2D *pReg=new XPoly2D(ent);
if(pReg->IsSelfIntersect())
delete pReg;
else
lstRegion.Append(pReg);
}
int nRegionNum=lstRegion.Length();
if(!nRegionNum) return;
TDbSlope *pSlope=new TDbSlope;
lstRegion.QuickSort(CompareArea);//快速排序(从小到大)
(XPoly2D &)(pSlope->m_slope)=*lstRegion.Tail();
lstRegion.Remove(lstRegion.Length()-1);
pSlope->m_slope.ProcessSlope(lstRegion);
pSlope->AddToMSpace(Adesk::kTrue);*/
//**** 以上是未定义永久响应的斜坡实体 ****//
//**** 以下是定义永久响应的斜坡实体 ****//
//转换成Id,去除不符合的实体
DList<XPoly2D> lstRegion;//截面
AcDbObjectIdArray arReactorId;//id值
long lCount=ssSelect.Length();
for(long index=0L; index<lCount; index++) {
Entity objName=ssSelect[index];
XPoly2D polyTemp(objName);
polyTemp.Compress();
AcDbObjectId objId;
if(polyTemp.Length()<=0 || polyTemp.IsSelfIntersect())
continue;
if(acdbGetObjectId(objId,objName)==Acad::eOk) {
if(!arReactorId.contains(objId)) {
arReactorId.append(objId);//id值
XPoly2D *pReg=new XPoly2D(objName);
lstRegion.Append(pReg);//截面
}
}
}
int nRegionNum=lstRegion.Length();
if(!nRegionNum) return;
//斜坡
AcDbObjectId idSlope;
TDbSlope *pSlope=new TDbSlope;
pSlope->EnableReact(FALSE);
lstRegion.QuickSort(CompareArea);//快速排序(从小到大)
(XPoly2D &)(pSlope->m_slope)=*lstRegion.Tail();
lstRegion.Remove(lstRegion.Length()-1);
pSlope->m_slope.ProcessSlope(lstRegion);
idSlope=pSlope->AddToMSpace(Adesk::kFalse);
//构造斜坡反应堆(永久响应)
if(!idSlope.isNull()) {
int nLen=arReactorId.length();
for(int i=0; i<nLen; i++) {
AcDbObjectId objId;
objId=arReactorId[i];
//设置响应为不可见、红色、建立永久响应连接
OPENOBJ_BEGIN(objId, AcDb::kForWrite, AcDbEntity, pEnt);
if(pEnt != NULL) {
pEnt->setColorIndex(1);
pEnt->setVisibility(AcDb::kInvisible);
pEnt->addPersistentReactor(idSlope);
}
OPENOBJ_END();
}
}
pSlope->SetReactors(arReactorId);
pSlope->EnableReact(TRUE);
pSlope->close();
//**** 以上是定义永久响应的斜坡实体 ****//
}
// 编辑TDbSlope实体
int EditSlope(AcDbObjectId id)
{
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbSlope, pSlope);
if(pSlope == NULL)
return RTERROR;
while(1) {
XString sPrompts, sKeywords;
BOOL bHas2D=pSlope->Has2D();
BOOL bHasReactor=pSlope->HasReactor();
BOOL bShowSlope=pSlope->IsShowSlope();
if(!bHas2D) {
sPrompts << _T("\n选择 [显示二维(S)");
sKeywords << _T("S");
} else {
if(bHasReactor) {
sPrompts << _T("\n选择 [显示响应(S)");
sKeywords << _T("S");
} else {
sPrompts << _T("\n选择 [新建响应(N)");
sKeywords << _T("N");
}
}
//显示模式:梯田和斜坡
if(bShowSlope) {
sPrompts << _T("/改变分段数(C)/显示梯田(M)]<退出>:");
sKeywords << _T(" C M");
}
else {
sPrompts << _T("/显示斜坡(M)]<退出>:");
sKeywords << _T(" M");
}
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('S')) {
if(pSlope->upgradeOpen()==Acad::eOk) {
pSlope->assertWriteEnabled();
pSlope->EnableReact(FALSE);
if(!bHas2D) {
pSlope->SetHas2D(TRUE);
pSlope->ShowReactor(FALSE);
pSlope->EnableTransformBy(TRUE);
} else {
pSlope->SetHas2D(FALSE);
pSlope->ShowReactor(TRUE);
pSlope->EnableTransformBy(FALSE);
}
pSlope->EnableReact(TRUE);
pSlope->downgradeOpen();
}
}
/*else if(cKey==_T('E')){//删除响应
if(pSlope->upgradeOpen()==Acad::eOk) {
pSlope->assertWriteEnabled();
pSlope->EraseReactor();
pSlope->downgradeOpen();
}
}*/
else if(cKey==_T('N')) {//新建响应
if(pSlope->upgradeOpen()==Acad::eOk) {
pSlope->assertWriteEnabled();
pSlope->NewReactor();
pSlope->downgradeOpen();
}
}
else if(cKey==_T('C')) {//顶点数
int nVertexNum=pSlope->GetVertexNum();
while(1) {
XString sPrompts(_T("\n输入圆周上分段数目<%d>:"),nVertexNum);
if (acedGetInt(sPrompts,&nVertexNum)!=RTNORM) {
break;
}
if (nVertexNum<3) {
adsout << _T("\n分段数不能小于3,请重新输入!");
} else {
if(pSlope->upgradeOpen()==Acad::eOk) {
pSlope->assertWriteEnabled();
pSlope->SetVertexNum(nVertexNum);
pSlope->downgradeOpen();
break;
}
}
}
}
else if(cKey==_T('M')) {//显示模式
if(pSlope->upgradeOpen()==Acad::eOk) {
pSlope->assertWriteEnabled();
pSlope->ShowSlope(!bShowSlope);
pSlope->downgradeOpen();
}
}
}
OPENOBJ_END();
return RTNORM;
}
void InitDbSlope(BOOL bTrue)
{
if(bTrue) {
TDbSlope::rxInit();
TDbSlope::SetEditMethod(EditSlope);
acrxBuildClassHierarchy();
TDbSlope::InitMatchProtocol(TRUE);
} else {
TDbSlope::InitMatchProtocol(FALSE);
deleteAcRxClass(TDbSlope::desc());
}
}