566 lines
13 KiB
C++
566 lines
13 KiB
C++
#include "stdafx.h"
|
|
|
|
ACRX_DXF_DEFINE_MEMBERS(ATSRegion, ATSEntity, AcDb::kDHL_CURRENT,
|
|
AcDb::kMReleaseCurrent, 1, ATS_REGION, "ATS_REGION图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
|
|
IMPLEMENT_TENTBASE(TDbRegion);
|
|
|
|
const Adesk::UInt8 TDbRegion::g_nVersion = 1;
|
|
|
|
TDbRegion::TDbRegion():m_nType(TDbRegion::kTotalRegion)
|
|
{
|
|
}
|
|
TDbRegion::TDbRegion(AcDbObjectId idBlock):m_nType(TDbRegion::kAllRegion)
|
|
{
|
|
AcDbBlockTableRecord *pRecord=NULL;
|
|
acdbOpenObject(pRecord,idBlock,AcDb::kForRead);
|
|
if(pRecord==NULL)
|
|
return;
|
|
|
|
AcDbBlockTableRecordIterator* pBlockIterator=NULL;
|
|
pRecord->newIterator(pBlockIterator);
|
|
pRecord->close();
|
|
if(pBlockIterator!=NULL)
|
|
{
|
|
for(pBlockIterator->start();!pBlockIterator->done();pBlockIterator->step())
|
|
{
|
|
AcDbEntity *pEntity=NULL;
|
|
pBlockIterator->getEntity(pEntity, AcDb::kForRead);
|
|
if(pEntity==NULL)
|
|
continue;
|
|
|
|
TDbRegion* pRegion=TDbRegion::cast(pEntity);
|
|
if(pRegion==NULL||
|
|
pRegion->IsErrorRegion()||
|
|
pRegion->IsSubRegion())
|
|
{
|
|
pEntity->close();
|
|
continue;
|
|
}
|
|
|
|
m_lstSubRegion.AddTail(pRegion->objectId());
|
|
|
|
pRegion->close();
|
|
}
|
|
|
|
delete pBlockIterator;
|
|
}
|
|
}
|
|
void TDbRegion::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)//ok
|
|
{
|
|
assertWriteEnabled();
|
|
TDbEntity::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
|
|
TDbRegion *pSrc=TDbRegion::cast(pSrcEntity);
|
|
if(pSrc)
|
|
{
|
|
m_nType=pSrc->m_nType;
|
|
m_sType=pSrc->m_sType;
|
|
}
|
|
}
|
|
BOOL TDbRegion::IsValid() const//ok
|
|
{
|
|
if(!TDbEntity::IsValid())
|
|
return FALSE;
|
|
if(!m_polyOutline||!m_polyOutline.IsClosed()||m_polyOutline.IsSelfIntersect())
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
void TDbRegion::GetAllSubRegionId(AcDbObjectIdArray&ids)const
|
|
{
|
|
assertReadEnabled();
|
|
for(long i=0;i<GetSubRegionNum();i++)
|
|
{
|
|
AcDbObjectId id=GetSubRegionId(i);
|
|
ids.append(id);
|
|
TDbRegion *pChild=NULL;
|
|
acdbOpenObject(pChild,id,AcDb::kForRead);
|
|
if(pChild!=NULL)
|
|
{
|
|
pChild->GetAllSubRegionId(ids);
|
|
pChild->close();
|
|
}
|
|
}
|
|
}
|
|
void TDbRegion::IndicateChild(Adesk::UInt16 color)const
|
|
{
|
|
assertReadEnabled();
|
|
for(long i=0;i<GetSubRegionNum();i++)
|
|
{
|
|
AcDbObjectId id=GetSubRegionId(i);
|
|
TDbRegion *pChild=NULL;
|
|
acdbOpenObject(pChild,id,AcDb::kForWrite);
|
|
if(pChild!=NULL)
|
|
{
|
|
pChild->setColorIndex(color);
|
|
pChild->downgradeOpen();
|
|
pChild->IndicateChild(color+1);
|
|
pChild->close();
|
|
}
|
|
}
|
|
}
|
|
void TDbRegion::ResetRegionShip()
|
|
{
|
|
TDbRegion *pParent=NULL;
|
|
acdbOpenObject(pParent,GetParentId(),AcDb::kForWrite);
|
|
if(pParent!=NULL)
|
|
{
|
|
pParent->RemoveSubRegion(objectId());
|
|
|
|
for(long i=0;i<GetSubRegionNum();i++)
|
|
{
|
|
AcDbObjectId idChild=GetSubRegionId(i);
|
|
TDbRegion*pChild=NULL;
|
|
acdbOpenObject(pChild,idChild,AcDb::kForWrite);
|
|
if(pChild!=NULL)
|
|
{
|
|
pParent->AppendSubRegion(idChild);
|
|
pChild->SetParentId(GetParentId());
|
|
pChild->Close();
|
|
}
|
|
}
|
|
|
|
pParent->close();
|
|
}
|
|
else
|
|
{
|
|
for(long i=0;i<GetSubRegionNum();i++)
|
|
{
|
|
TDbRegion*pChild=NULL;
|
|
acdbOpenObject(pChild,GetSubRegionId(i),AcDb::kForWrite);
|
|
if(pChild!=NULL)
|
|
{
|
|
pChild->SetParentId(AcDbObjectId::kNull);
|
|
pChild->Close();
|
|
}
|
|
}
|
|
}
|
|
|
|
SetParentId(AcDbObjectId::kNull);
|
|
ClearSubRegion();
|
|
}
|
|
void TDbRegion::ValidateRegionShip()
|
|
{
|
|
assertWriteEnabled();
|
|
TDbRegion region(ownerId());
|
|
if(region.CheckIn(this))
|
|
SetErrorFlag(false);
|
|
}
|
|
|
|
bool TDbRegion::CheckIn(TDbRegion*pChild)
|
|
{
|
|
XPoint ptLow,ptUp;
|
|
if(pChild->GetExtents2d(ptLow,ptUp)!=Acad::eOk)
|
|
return false;
|
|
|
|
//1,兄弟包含检测
|
|
for(long i=0;i<GetSubRegionNum();i++)
|
|
{
|
|
TDbRegion* pRegion=NULL;
|
|
acdbOpenObject(pRegion,GetSubRegionId(i),AcDb::kForRead);
|
|
if(pRegion==NULL)
|
|
continue;
|
|
|
|
if(!pRegion->CanInclude(*pChild))
|
|
{
|
|
pRegion->close();
|
|
continue;
|
|
}
|
|
|
|
XPoint ptLow1,ptUp1;
|
|
if(pRegion->GetExtents2d(ptLow1,ptUp1)!=Acad::eOk)
|
|
{
|
|
pRegion->close();
|
|
continue;
|
|
}
|
|
|
|
if(ptLow1.x>ptLow.x+1E-6||
|
|
ptLow1.y>ptLow.y+1E-6||
|
|
ptUp1.x<ptUp.x-1E-6||
|
|
ptUp1.y<ptUp.y-1E-6)
|
|
{
|
|
pRegion->close();
|
|
continue;
|
|
}
|
|
|
|
if(pRegion->IsInclude(*pChild))
|
|
{
|
|
if(pRegion->upgradeOpen()==Acad::eOk)
|
|
{
|
|
bool bRet=pRegion->CheckIn(pChild);
|
|
pRegion->close();
|
|
return bRet;
|
|
}
|
|
}
|
|
|
|
pRegion->close();
|
|
}
|
|
|
|
//2,兄弟重叠检测
|
|
for(i=0;i<GetSubRegionNum();i++)
|
|
{
|
|
TDbRegion* pRegion=NULL;
|
|
acdbOpenObject(pRegion,GetSubRegionId(i),AcDb::kForRead);
|
|
if(pRegion==NULL)
|
|
continue;
|
|
|
|
if(pRegion->CanOverlap(*pChild))
|
|
{
|
|
pRegion->close();
|
|
continue;
|
|
}
|
|
|
|
XPoint ptLow1,ptUp1;
|
|
if(pRegion->GetExtents2d(ptLow1,ptUp1)!=Acad::eOk)
|
|
{
|
|
pRegion->close();
|
|
continue;
|
|
}
|
|
|
|
if(ptLow1.x>ptUp.x+1E-6||
|
|
ptLow1.y>ptUp.y+1E-6||
|
|
ptUp1.x<ptLow.x-1E-6||
|
|
ptUp1.y<ptLow.y-1E-6)
|
|
{
|
|
pRegion->close();
|
|
continue;
|
|
}
|
|
|
|
if(pRegion->IsOverlap(*pChild))
|
|
{
|
|
pRegion->Close();
|
|
return false;
|
|
}
|
|
|
|
pRegion->close();
|
|
}
|
|
|
|
//2,尝试包含兄弟
|
|
for (i=0;i<GetSubRegionNum();i++)
|
|
{
|
|
TDbRegion* pRegion=NULL;
|
|
acdbOpenObject(pRegion,GetSubRegionId(i),AcDb::kForRead);
|
|
if(pRegion==NULL)
|
|
continue;
|
|
|
|
if(!pChild->CanInclude(*pRegion))
|
|
{
|
|
pRegion->close();
|
|
continue;
|
|
}
|
|
|
|
XPoint ptLow1,ptUp1;
|
|
if(pRegion->GetExtents2d(ptLow1,ptUp1)!=Acad::eOk)
|
|
{
|
|
pRegion->close();
|
|
continue;
|
|
}
|
|
|
|
if(ptLow.x>ptLow1.x+1E-6||
|
|
ptLow.y>ptLow1.y+1E-6||
|
|
ptUp.x<ptUp1.x-1E-6||
|
|
ptUp.y<ptUp1.y-1E-6)
|
|
{
|
|
pRegion->close();
|
|
continue;
|
|
}
|
|
|
|
if(pChild->IsInclude(*pRegion))
|
|
{
|
|
if(pRegion->upgradeOpen()==Acad::eOk)
|
|
{
|
|
pRegion->SetParentId(pChild->objectId());
|
|
pChild->AppendSubRegion(pRegion->objectId());
|
|
|
|
m_lstSubRegion.Del(i);
|
|
i--;//循环继续
|
|
}
|
|
}
|
|
|
|
pRegion->close();
|
|
}
|
|
|
|
pChild->SetParentId(objectId());
|
|
AppendSubRegion(pChild->objectId());
|
|
return true;
|
|
}
|
|
bool TDbRegion::CanInclude(const TDbRegion& region)const
|
|
{
|
|
return true;
|
|
|
|
//if(fabs(GetElevation()-region.GetElevation())>1)
|
|
// return false;
|
|
}
|
|
|
|
bool TDbRegion::CanOverlap(const TDbRegion& region)const
|
|
{
|
|
return true;
|
|
}
|
|
Acad::ErrorStatus TDbRegion::dwgInFields (AcDbDwgFiler* pFiler)//ok
|
|
{
|
|
assertWriteEnabled();
|
|
|
|
Acad::ErrorStatus es = TDbEntity::dwgInFields(pFiler);
|
|
if(es != Acad::eOk) return es;
|
|
|
|
Adesk::UInt8 nVer;
|
|
pFiler->readItem(&nVer);
|
|
if(nVer>g_nVersion)
|
|
return Acad::eMakeMeProxy;
|
|
|
|
es=ReadPoly2D(pFiler,m_polyOutline);
|
|
ReadString(pFiler,m_sName);
|
|
ReadString(pFiler,m_sType);
|
|
Adesk::Int32 temp;
|
|
pFiler->readItem(&temp);
|
|
m_nType=(TDbRegion::RegionType)temp;
|
|
pFiler->readItem(&m_nFlag);
|
|
pFiler->readItem(&m_nElevation);
|
|
|
|
pFiler->readItem(&m_idParent);
|
|
Adesk::UInt32 num=0;
|
|
pFiler->readItem(&num);
|
|
m_lstSubRegion.Clear();
|
|
for(Adesk::UInt32 i=0;i<num;i++)
|
|
{
|
|
AcDbSoftPointerId id;
|
|
pFiler->readItem(&id);
|
|
m_lstSubRegion.AddTail(id);
|
|
}
|
|
|
|
return pFiler->filerStatus();
|
|
}
|
|
Acad::ErrorStatus TDbRegion::dwgOutFields(AcDbDwgFiler* pFiler) const//ok
|
|
{
|
|
assertReadEnabled();
|
|
Acad::ErrorStatus es = TDbEntity::dwgOutFields(pFiler);
|
|
if(es != Acad::eOk) return es;
|
|
|
|
pFiler->writeItem(g_nVersion);
|
|
WritePoly2D(pFiler,m_polyOutline);
|
|
pFiler->writeString(m_sName);
|
|
pFiler->writeString(m_sType);
|
|
pFiler->writeItem((Adesk::UInt32)m_nType);
|
|
pFiler->writeItem(m_nFlag);
|
|
pFiler->writeItem(m_nElevation);
|
|
|
|
pFiler->writeItem(m_idParent);
|
|
Adesk::UInt32 num=m_lstSubRegion.GetLength();
|
|
pFiler->writeItem(num);
|
|
for(Adesk::UInt32 i=0;i<num;i++)
|
|
pFiler->writeItem(m_lstSubRegion.GetAt(i));
|
|
|
|
return pFiler->filerStatus();
|
|
}
|
|
Acad::ErrorStatus TDbRegion::dxfInFields (AcDbDxfFiler* pFiler)
|
|
{
|
|
assertWriteEnabled();
|
|
Acad::ErrorStatus es=TDbEntity::dxfInFields(pFiler);
|
|
if(es!=Acad::eOk)
|
|
return es;
|
|
|
|
if (!pFiler->atSubclassData(_T("TDbRegion")))
|
|
return Acad::eBadDxfSequence;
|
|
|
|
XString sType, sName;
|
|
Adesk::UInt32 fieldsFlags = 0;
|
|
resbuf rb;
|
|
while ((es == Acad::eOk)
|
|
&& ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) {
|
|
switch (rb.restype) {
|
|
case AcDb::kDxfText:
|
|
sName=rb.resval.rstring;
|
|
fieldsFlags |= 0x01;
|
|
free(rb.resval.rstring);
|
|
break;
|
|
case AcDb::kDxfDescription:
|
|
sType=rb.resval.rstring;
|
|
fieldsFlags |= 0x02;
|
|
free(rb.resval.rstring);
|
|
break;
|
|
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: 1"));
|
|
return Acad::eMissingDxfField;
|
|
}
|
|
if (!(fieldsFlags & 0x02)) {
|
|
pFiler->setError(Acad::eMissingDxfField,
|
|
_T("\nMissing DXF group code: 3"));
|
|
return Acad::eMissingDxfField;
|
|
}
|
|
|
|
if(fieldsFlags&0x01)
|
|
m_sName=sName;
|
|
if(fieldsFlags&0x02)
|
|
m_sType=sType;
|
|
|
|
return pFiler->filerStatus();
|
|
}
|
|
Acad::ErrorStatus TDbRegion::dxfOutFields(AcDbDxfFiler* pFiler) const
|
|
{
|
|
Acad::ErrorStatus es;
|
|
|
|
es = TDbEntity::dxfOutFields(pFiler);
|
|
assert(es == Acad::eOk);
|
|
|
|
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbRegion"));
|
|
pFiler->writeString(AcDb::kDxfText, (const TCHAR *)m_sName);
|
|
pFiler->writeString(AcDb::kDxfDescription, (const TCHAR *)m_sType);
|
|
return es;
|
|
}
|
|
Acad::ErrorStatus TDbRegion::subGetClassID(CLSID* pClsid) const
|
|
{
|
|
return Acad::eOk;
|
|
}
|
|
Acad::ErrorStatus TDbRegion::subTransformBy(const AcGeMatrix3d& xform)
|
|
{
|
|
assertWriteEnabled();
|
|
TDbEntity::subTransformBy(xform);
|
|
m_polyOutline.TransformBy(xform);
|
|
return Acad::eOk;
|
|
}
|
|
|
|
Acad::ErrorStatus TDbRegion::subGetGripPoints(AcGePoint3dArray& gripPoints,
|
|
AcDbIntArray& osnapModes,
|
|
AcDbIntArray& geomIds) const
|
|
{
|
|
XPoint ptCen,ptLowLeft,ptUpRight;
|
|
m_polyOutline.GetExtend(ptLowLeft,ptUpRight);
|
|
Midpoint(ptLowLeft,ptUpRight,ptCen);
|
|
|
|
double nElev=0;
|
|
gripPoints.append(AcGePoint3d(ptCen.x,ptCen.y,nElev));
|
|
gripPoints.append(AcGePoint3d(ptLowLeft.x,ptLowLeft.y,nElev));
|
|
gripPoints.append(AcGePoint3d(ptUpRight.x,ptLowLeft.y,nElev));
|
|
gripPoints.append(AcGePoint3d(ptUpRight.x,ptUpRight.y,nElev));
|
|
gripPoints.append(AcGePoint3d(ptLowLeft.x,ptUpRight.y,nElev));
|
|
return Acad::eOk;
|
|
}
|
|
Acad::ErrorStatus TDbRegion::subMoveGripPointsAt(
|
|
const AcDbIntArray& indices,
|
|
const AcGeVector3d& offset)
|
|
{
|
|
assertWriteEnabled();
|
|
Acad::ErrorStatus es=Acad::eOk;
|
|
BOOL bCtrlPressed=GetCtrlToggle();
|
|
for(long i=0;i<indices.length();i++)
|
|
{
|
|
if(indices[i]==0&&bCtrlPressed)
|
|
{
|
|
XPoint ptCen;
|
|
m_polyOutline.Center(ptCen);
|
|
ads_matrix mat;
|
|
ptCen.GetRotationMatrix(AcGeVector2d(offset.x,offset.y).angle(),mat);
|
|
es=subTransformBy(AsAcGeMatrix3d(mat));
|
|
}
|
|
else
|
|
{
|
|
AcGeMatrix3d mat;
|
|
mat.setTranslation(offset);
|
|
es=subTransformBy(mat);
|
|
}
|
|
}
|
|
return es;
|
|
}
|
|
Acad::ErrorStatus TDbRegion::GetGripText(int i, CString &cs) const
|
|
{
|
|
Acad::ErrorStatus es=Acad::eOk;
|
|
switch(i)
|
|
{
|
|
case 0:
|
|
cs=GetCtrlToggle()? _T("中心旋转(Ctrl-移动)"):_T("移动(Ctrl-中心旋转)");
|
|
break;
|
|
default:
|
|
cs=_T("移动");
|
|
}
|
|
|
|
return es;
|
|
}
|
|
Acad::ErrorStatus TDbRegion::ExplodeOrDraw2d(XExplodeDraw &dc) const//ok
|
|
{
|
|
if(IsErrorRegion())
|
|
dc.SetColor(1);
|
|
dc<<m_polyOutline;
|
|
return Acad::eOk;
|
|
}
|
|
Acad::ErrorStatus TDbRegion::ExplodeOrDraw3d(XExplodeDraw &dc) const
|
|
{
|
|
return ExplodeOrDraw2d(dc);
|
|
}
|
|
void TDbRegion::GetTips(DList<TObjInfoUnit> &lstInfo) const
|
|
{
|
|
lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("区域")));
|
|
}
|
|
void Region()
|
|
{
|
|
RBList mask=ads_buildlist(-4, _T("<or"),
|
|
-4, _T("<and"),
|
|
RTDXF0, _T("POLYLINE,LWPOLYLINE"),
|
|
-4, _T("and>"),
|
|
RTDXF0, _T("CIRCLE"),
|
|
-4, _T("or>"), NULL);
|
|
PickSet ss(SS_FREE);
|
|
if(SelectEntities(_T("\n选择闭合曲线:"), ss, mask)!=RTNORM)
|
|
return;
|
|
|
|
for(long i=0;i<ss.Length();i++)
|
|
{
|
|
Entity ent=ss[i];
|
|
XPoly2D poly(ent);
|
|
poly.SetFlag(1);
|
|
poly.Compress();
|
|
TDbRegion *pRegion=new TDbRegion;
|
|
pRegion->SetOutline(poly);
|
|
if(pRegion->IsValid())
|
|
AddToModelSpace(pRegion,Adesk::kTrue);
|
|
else
|
|
delete pRegion;
|
|
}
|
|
ss.Delete();
|
|
}
|
|
|
|
// 编辑TDbRegion实体
|
|
int EditRegion(AcDbObjectId id)
|
|
{
|
|
DocSetIsDwgBegin(FALSE);
|
|
|
|
TDbRegion*pRegion=NULL;
|
|
acdbOpenObject(pRegion,id,AcDb::kForRead);
|
|
if(pRegion!=NULL)
|
|
{
|
|
pRegion->IndicateChild(2);
|
|
pRegion->close();
|
|
}
|
|
|
|
DocSetIsDwgBegin(TRUE);
|
|
return RTNORM;
|
|
}
|
|
|
|
void InitDbRegion(BOOL bTrue)
|
|
{
|
|
if(bTrue) {
|
|
TDbRegion::rxInit();
|
|
TDbRegion::SetEditMethod(EditRegion);
|
|
acrxBuildClassHierarchy();
|
|
TDbRegion::InitMatchProtocol(TRUE);
|
|
} else {
|
|
TDbRegion::InitMatchProtocol(FALSE);
|
|
deleteAcRxClass(TDbRegion::desc());
|
|
}
|
|
} |