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

2459 lines
57 KiB
C++

#include "stdafx.h"
#include "AecDbEntityBase.h"
#include "AcGiViewDraw.h"
#include "AcGiExplodeDraw.h"
#include "simpleproperty.h"
#include "dbobjptr.h"
#include "AecDbObjXDataMap.h"
#include "AecGripCback.h"
#include "GrPolyhedronGeometry.h"
using namespace GrPolyhedronGeometry;
BOOL ReadModelXData(LPCTSTR pszKey, AecDbObjXDataMap& xDataMap, AcDbDatabase* pDb);
BOOL WriteModelXData(LPCTSTR pszKey, AecDbObjXDataMap& xDataMap, AcDbDatabase* pDb);
extern CString IDCreate();
const Adesk::UInt16 kColorByLayer = 256;
static const Adesk::UInt16 kRed = 1;
#ifndef _ttof
#define _ttof(pszVal) _tcstod((pszVal), NULL)
#endif
namespace
{
void FreeBuffer(int n, AcDbVoidPtrArray& arEntPtrs)
{
AcDbEntity* pEnt = NULL;
while (arEntPtrs.length() > n)
{
pEnt = (AcDbEntity*)arEntPtrs.last();
pEnt->erase();
pEnt->close();
DELETE_PTR(pEnt);
arEntPtrs.removeLast();
}
}
}
ACRX_NO_CONS_DEFINE_MEMBERS(AecDbEntityBase, AcDbEntity);
AecDbEntityBase::AecDbEntityBase(void)
{
m_eExplodeOrDrawType = kWroldDraw;
m_nDrawDimCur = -1;
}
AecDbEntityBase::~AecDbEntityBase(void)
{
FreeBuffer(0, m_ar2DDrableBufPtrs_);
FreeBuffer(0, m_ar3DDrableBufPtrs_);
}
static void ReleaseEntSet(AcDbVoidPtrArray &entSet)
{
while(!entSet.isEmpty())
{
AcDbEntity *pEnt = AcDbEntity::cast((AcDbEntity *)entSet[0]);
if (pEnt != NULL)
{
DELETE_PTR(pEnt);
}
entSet.removeAt(0);
}
}
Adesk::UInt32 AecDbEntityBase::subViewportDrawLogicalFlags(AcGiViewportDraw * vd)
{
Adesk::UInt32 nRet = AcDbEntity::subViewportDrawLogicalFlags(vd);
Adesk::UInt32 nFlagNew = nRet;
int nDrawMode = AecDbEntityBase::GetDrawMode();
int nDraw = GetDrawDimOnType(nDrawMode, k2Dand3D);
if (nDraw != 3)
{
nFlagNew |= AcGiDrawable::kDrawableViewIndependentViewportDraw;
}
else
{
nFlagNew |= AcGiDrawable::kDrawableRegenDraw;//256;
}
return nFlagNew;
}
Adesk::UInt32 AecDbEntityBase::subSetAttributes(AcGiDrawableTraits * traits)
{
Adesk::UInt32 nRet = AcDbEntity::subSetAttributes(traits);
int nDrawMode = AecDbEntityBase::GetDrawMode();
int nDraw = GetDrawDimOnType(nDrawMode, k2Dand3D);
Adesk::UInt32 nFlagNew = nRet;
nFlagNew |= AcGiDrawable::kDrawableViewIndependentViewportDraw;
return nFlagNew;
}
Adesk::Boolean AecDbEntityBase::subWorldDraw(AcGiWorldDraw *pWd)
{
assertReadEnabled();
m_eExplodeOrDrawType = kWroldDraw;
AcGiViewDraw dc(pWd, NULL);
dc.SetDrawRaw(this);
//1.如果是保存代理图形
AcGiRegenType nRegenType = pWd->regenType();
if (nRegenType == kAcGiSaveWorldDrawForProxy)
{
ads_point pt;
struct resbuf rb;
acedGetVar(_T("VIEWDIR"),&rb);
ads_point_set(rb.resval.rpoint,pt);
ads_point viewDir;
acdbUcs2Wcs(pt,viewDir,false);
if (fabs(viewDir[X]) > 1.0e-6 || fabs(viewDir[Y]) > 1.0e-6)
{
Draw3d(dc);
m_nDrawDimCur = 3;
}
else
{
Draw2d(dc);
m_nDrawDimCur = 2;
}
return Adesk::kTrue;
}
//设属性
dc.SetLayer(_T("0"));
dc.SetColor(256);
//如果图层关闭
AcDbLayerTableRecordPointer pLayer;
if ( Acad::eOk == pLayer.open(layerId(), AcDb::kForRead) )
{
if ( pLayer->isOff() )
{
return Adesk::kTrue;
}
}
int nDrawType = k2Dand3D;
int nDrawMode = AecDbEntityBase::GetDrawMode();
int nDraw = GetDrawDimOnType(nDrawMode, k2Dand3D);
if (nRegenType == kAcGiSaveWorldDrawForProxy
|| nRegenType == kAcGiSaveWorldDrawForR12)
{
if (!!ownerId())
{
pWd->subEntityTraits().setSelectionMarker(0);
dc.SetColor(colorIndex());
dc.SetLayer(layerId());
}
if ((nDrawMode & DRAW_2D) && (nDrawType != k3DOnly))
{
Draw2d(dc);
m_nDrawDimCur = 2;
}
else if ((nDrawMode & DRAW_3D) && (nDrawType != k2DOnly))
{
Draw3d(dc);
m_nDrawDimCur = 3;
}
return Adesk::kTrue;
}
return Adesk::kFalse;
}
void AecDbEntityBase::subViewportDraw(AcGiViewportDraw* pMode)
{
assertReadEnabled();
m_eExplodeOrDrawType = kViewportDraw;
AcGiRegenType nRegenType = pMode->regenType();
AcGiViewport &vp = pMode->viewport();
AcGePoint3d ptCamera, ptTarget;
vp.getCameraTarget(ptTarget);
vp.getCameraLocation(ptCamera);
AcGeVector3d vtViewDrt = ptCamera-ptTarget;
AcGeVector3d vtViewDir1 = vp.viewDir();
AcGeVector3d vtCamera;
vp.getCameraUpVector(vtCamera);
vtViewDrt.normalize();
AcGiViewDraw dc(NULL, pMode);
dc.SetDrawRaw(this);
// 设属性
dc.SetLayer(_T("0"));
dc.SetColor(256);
//如果图层关闭
AcDbLayerTableRecordPointer pLayer;
if ( Acad::eOk == pLayer.open(layerId(), AcDb::kForRead) )
{
if ( pLayer->isOff() )
{
return;
}
}
if (!!ownerId())
{
pMode->subEntityTraits().setSelectionMarker(0);
dc.SetColor(colorIndex());
dc.SetLayer(layerId());
}
int nDrawMode = AecDbEntityBase::GetDrawMode();
int nDraw = GetDrawDimOnType(nDrawMode, k2Dand3D);
if (nDraw == 3)
{
if ( nRegenType == kAcGiRenderCommand
|| nRegenType == kAcGiHideOrShadeCommand
|| vp.isPerspective()
|| vtViewDrt != AcGeVector3d(0,0,1))
{
Draw3d(dc);
m_nDrawDimCur = 3;
}
else
{
Draw2d(dc);
m_nDrawDimCur = 2;
}
}
else if (nDraw == 1)
{
Draw2d(dc);
m_nDrawDimCur = 2;
}
else if (nDraw == 2)
{
Draw3d(dc);
m_nDrawDimCur = 3;
}
}
//保存代理实体图元
void AecDbEntityBase::saveAs(AcGiWorldDraw *pWd,AcDb::SaveType saveType)
{
AecDbObjXDataMap xDataMap;
ReadModelXData(EW_EARTHWORMINIT, xDataMap, NULL);
int nSaveToProxy(0);
xDataMap.GetAt(_T("SaveToProxy"), nSaveToProxy);
if (nSaveToProxy == 0) // 不保存代理图形
return;
AcGiRegenType rtype = pWd->regenType();
if (rtype == kAcGiSaveWorldDrawForProxy)
{
subWorldDraw(pWd);
}
else
{
AcDbEntity::saveAs(pWd, saveType);
}
}
Acad::ErrorStatus AecDbEntityBase::subExplode(AcDbVoidPtrArray& entitySet) const
{
ExplodeOrDrawType& eExplodeType = (ExplodeOrDrawType&)m_eExplodeOrDrawType;
eExplodeType = kExplode;
int expMode = GetExplodeMode();
if (expMode == 1)
{
GetDraw2dables(0,entitySet);
}
else if (expMode == 2)
{
GetDraw3dables(entitySet);
}
return Acad::eOk;
}
Acad::ErrorStatus AecDbEntityBase::subGetGeomExtents(AcDbExtents& extents) const
{
AcGePoint3d ptLow, ptUp;
AcDbVoidPtrArray entSet;
int expMode = GetExplodeMode();
if (expMode == 1)
{
entSet.append(Get2DBuffer());
}
else if (expMode == 2)
{
entSet.append(Get3DBuffer());
}
BOOL bInit = TRUE;
AcGePoint3d ptMax,ptMin;
AcDbExtents ext,extT;
int len = entSet.length();
for (int i = 0; i < len; i++)
{
AcDbEntity *pEnt = (AcDbEntity *)entSet[i];
if (pEnt->getGeomExtents(extT) == Acad::eOk)
{
ext.addExt(extT);
}
}
ptLow = ext.minPoint();
ptUp = ext.maxPoint();
extents.set(ptLow, ptUp);
return Acad::eOk;
}
Acad::ErrorStatus AecDbEntityBase::subGet3dGeomExtents(AcDbExtents &extents) const
{
AcDbVoidPtrArray entSet;
if (!Has3DBuffer())
{
AcGiViewDraw dc(NULL, NULL);
Draw3d(dc);
}
entSet.append(Get3DBuffer());
if (entSet.isEmpty())
return Acad::eNullExtents;
BOOL bInit = TRUE;
AcGePoint3d ptMax, ptMin;
AcDbExtents ext, extT;
int len = entSet.length();
for (int i = 0; i < len; i++)
{
AcDbEntity *pEnt = (AcDbEntity *)entSet[i];
if (pEnt->getGeomExtents(extT) == Acad::eOk)
{
ext.addExt(extT);
}
}
AcGePoint3d ptLow, ptUp;
ptLow = ext.minPoint();
ptUp = ext.maxPoint();
extents.set(ptLow, ptUp);
return Acad::eOk;
}
void AecDbEntityBase::subList() const
{
AcDbEntity::subList();
}
Acad::ErrorStatus AecDbEntityBase::subIntersectWith(const AcDbEntity* ent,
AcDb::Intersect intType,
AcGePoint3dArray& points,
INT_PTR thisGsMarker,
INT_PTR otherGsMarker) const
{
assertReadEnabled();
int expMode = GetExplodeMode();
if (expMode == 2)
{
return Acad::eNotImplementedYet;
}
const AcDbVoidPtrArray& entSet = Get2DBuffer();
Acad::ErrorStatus es = Acad::eNotApplicable;
int len = entSet.length();
for(int i = 0; i < len; i++)
{
AcDbEntity *pEnt = (AcDbEntity *)entSet[i];
//acutPrintf(_T("\nclass = %s"),pEnt->isA()->name());
if ( pEnt != NULL && Acad::eOk == pEnt->intersectWith(ent, intType, points, 0, otherGsMarker) )
{
es = Acad::eOk;
}
}
return es;
}
Acad::ErrorStatus AecDbEntityBase::subIntersectWith(const AcDbEntity* ent,
AcDb::Intersect intType,
const AcGePlane& projPlane,
AcGePoint3dArray& points,
INT_PTR thisGsMarker,
INT_PTR otherGsMarker) const
{
assertReadEnabled();
int expMode = GetExplodeMode();
if (expMode == 2)
{
return Acad::eNotImplementedYet;
}
const AcDbVoidPtrArray& entSet = Get2DBuffer();
Acad::ErrorStatus es;
es = Acad::eNotApplicable;
int len = entSet.length();
for (int i = 0; i < len; i++)
{
AcDbEntity *pEnt = (AcDbEntity *)entSet[i];
//acutPrintf(_T("\nclass = %s"),pEnt->isA()->name());
if ( pEnt != NULL && Acad::eOk == pEnt->intersectWith(ent, intType, projPlane, points, 0, otherGsMarker) )
{
es = Acad::eOk;
}
}
return Acad::eOk;
}
Acad::ErrorStatus AecDbEntityBase::subSetPropertiesFrom( const AcDbEntity* pEntity, Adesk::Boolean doSubents /*= Adesk::kTrue*/)
{
assertWriteEnabled();
Acad::ErrorStatus es = AcDbEntity::setPropertiesFrom(pEntity, doSubents);
// 颜色
{
setColorIndex(pEntity->colorIndex());
}
//图层
if ( database() == NULL ||
database() == pEntity->database())
{
{
setLayer(pEntity->layerId());
}
// 线型
{
setLinetype(pEntity->linetypeId());
}
#if ARX > 16
// 材质
{
setMaterial(pEntity->materialId());
}
#endif
}
// 线型比例
{
setLinetypeScale(pEntity->linetypeScale());
}
// 可见性. 总是被复制
setVisibility(pEntity->visibility());
return es;
}
#if (ARX > 15)
Acad::ErrorStatus AecDbEntityBase::subGetOsnapPoints( AcDb::OsnapMode osnapMode,
INT_PTR gsSelectionMark,
const AcGePoint3d& ptPick,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcGePoint3dArray& snapPoints,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
AcDbVoidPtrArray entSet;
int expMode = GetExplodeMode();
if (expMode == 1)
{
entSet.append(Get2DBuffer());
}
else if (expMode == 2)
{
entSet.append(Get3DBuffer());
}
Acad::ErrorStatus es = Acad::eOk;
if (es == Acad::eOk)
{
int len = entSet.length();
for (int i = 0; i < len; i++)
{
AcDbEntity *pEnt=(AcDbEntity *)entSet[i];
if (pEnt->isKindOf(AcDbText::desc()))
{
if (osnapMode == AcDb::kOsModeIns)
{
snapPoints.append(AcDbText::cast(pEnt)->position());
}
else
{
continue;
}
}
es = pEnt->getOsnapPoints(osnapMode, 0, ptPick, lastPoint, viewXform,
snapPoints, geomIds);
}
es = Acad::eOk;
}
return Acad::eOk;
}
Acad::ErrorStatus AecDbEntityBase::subGetOsnapPoints( AcDb::OsnapMode osnapMode,
INT_PTR gsSelectionMark,
const AcGePoint3d& ptPick,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcGePoint3dArray& snapPoints,
AcDbIntArray& geomIds,
const AcGeMatrix3d& insersionMat) const
{
assertReadEnabled();
return getOsnapPoints(osnapMode,gsSelectionMark,ptPick,lastPoint,viewXform,snapPoints,geomIds);
}
#endif
#if ARX>15
void AecDbEntityBase::subGripStatus(const AcDb::GripStat status)
{
}
Acad::ErrorStatus AecDbEntityBase::subGetGripPoints ( AcDbGripDataPtrArray& grips,
const double curViewUnitSize,
const int gripSize,
const AcGeVector3d& curViewDir,
const int bitflags) const
{
return Acad::eOk;
}
Acad::ErrorStatus AecDbEntityBase::subMoveGripPointsAt(const AcDbVoidPtrArray& appData,const AcGeVector3d& offset,const int bitflags)
{
return Acad::eOk;
}
#endif
Acad::ErrorStatus AecDbEntityBase::subGetGripPoints (AcGePoint3dArray& gripPoints,AcDbIntArray& osnapModes,AcDbIntArray& geomIds) const
{
assertReadEnabled();
return Acad::eOk;
}
Acad::ErrorStatus AecDbEntityBase::subMoveGripPointsAt(const AcDbIntArray& indices,const AcGeVector3d& offset)
{
assertWriteEnabled();
return Acad::eOk;
}
Acad::ErrorStatus AecDbEntityBase::subGetStretchPoints(AcGePoint3dArray& stretchPoints) const
{
assertReadEnabled();
return Acad::eOk;
}
Acad::ErrorStatus AecDbEntityBase::subMoveStretchPointsAt(const AcDbIntArray& indices,const AcGeVector3d& offset)
{
assertWriteEnabled();
return Acad::eOk;
}
Acad::ErrorStatus AecDbEntityBase::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
return Acad::eOk;
}
Acad::ErrorStatus AecDbEntityBase::subGetTransformedCopy(const AcGeMatrix3d& xform,
AcDbEntity*& pEnt) const
{
assertReadEnabled();
AcDbEntity *pCloned = (AcDbEntity *)clone();
((AecDbEntityBase*)pCloned)->m_nDrawDimCur = m_nDrawDimCur;
Acad::ErrorStatus es = pCloned->transformBy(xform);
if(es == Acad::eOk)
pEnt = pCloned;
else
DELETE_PTR(pCloned);
return es;
}
Acad::ErrorStatus AecDbEntityBase::subDeepClone( AcDbObject* pOwner,
AcDbObject*& pClonedObject,
AcDbIdMapping& idMap,
Adesk::Boolean isPrimary) const
{
// You should always pass back pClonedObject == NULL
// if, for any reason, you do not actually clone it
// during this call. The caller should pass it in
// as NULL, but to be safe, we set it here as well.
//
pClonedObject = NULL;
// If this object is in the idMap and is already
// cloned, then return.
//
bool isPrim = false;
if (isPrimary)
isPrim = true;
AcDbIdPair idPair(objectId(), (AcDbObjectId)NULL,
false, isPrim);
if (idMap.compute(idPair) && (idPair.value() != NULL))
return Acad::eOk;
// Create the clone
//
AecDbEntityBase *pClone = (AecDbEntityBase*)isA()->create();
if (pClone != NULL)
pClonedObject = pClone; // set the return value
else
return Acad::eOutOfMemory;
AcDbDeepCloneFiler filer;
dwgOut(&filer);
filer.seek(0L, AcDb::kSeekFromStart);
pClone->dwgIn(&filer);
pClone->NewGUID();
pClone->setLayer(layerId());
bool bOwnerXlated = false;
if (isPrimary)
{
AcDbBlockTableRecord *pBTR =
AcDbBlockTableRecord::cast(pOwner);
if (pBTR != NULL)
{
pBTR->appendAcDbEntity(pClone);
bOwnerXlated = true;
}
else
{
pOwner->database()->addAcDbObject(pClone);
}
} else {
pOwner->database()->addAcDbObject(pClone);
pClone->setOwnerId(pOwner->objectId());
bOwnerXlated = true;
}
// This must be called for all newly created objects
// in deepClone. It is turned off by endDeepClone()
// after it has translated the references to their
// new values.
//
pClone->setAcDbObjectIdsInFlux();
pClone->disableUndoRecording(true);
// Add the new information to the idMap. We can use
// the idPair started above.
//
idPair.setValue(pClonedObject->objectId());
idPair.setIsCloned(Adesk::kTrue);
idPair.setIsOwnerXlated(bOwnerXlated);
idMap.assign(idPair);
// Using the filer list created above, find and clone
// any owned objects.
//
AcDbObjectId id;
while (filer.getNextOwnedObject(id)) {
AcDbObject *pSubObject;
AcDbObject *pClonedSubObject;
// Some object's references may be set to NULL,
// so don't try to clone them.
//
if (id == NULL)
continue;
// Open the object and clone it. Note that we now
// set "isPrimary" to kFalse here because the object
// is being cloned, not as part of the primary set,
// but because it is owned by something in the
// primary set.
//
acdbOpenAcDbObject(pSubObject, id, AcDb::kForRead);
pClonedSubObject = NULL;
pSubObject->deepClone(pClonedObject,
pClonedSubObject,
idMap, Adesk::kFalse);
// If this is a kDcInsert context, the objects
// may be "cheapCloned". In this case, they are
// "moved" instead of cloned. The result is that
// pSubObject and pClonedSubObject will point to
// the same object. So, we only want to close
// pSubObject if it really is a different object
// than its clone.
//
if (pSubObject != pClonedSubObject)
pSubObject->close();
// The pSubObject may either already have been
// cloned, or for some reason has chosen not to be
// cloned. In that case, the returned pointer will
// be NULL. Otherwise, since we have no immediate
// use for it now, we can close the clone.
//
if (pClonedSubObject != NULL)
pClonedSubObject->close();
}
//xdataMap 复制
//到mep中找建立新的关系
AecDbObjXDataMap* pXDataMapCloned = pClone->GetSpecialtyData();
AecDbObjXDataMap* pXDataMap = (AecDbObjXDataMap*)GetSpecialtyData();
if (pXDataMapCloned != NULL) pXDataMapCloned->CopyFrom(pXDataMap);
if (pXDataMap != NULL && pXDataMapCloned != NULL)
{
//发送提资需要相同的ID
Adesk::Int16 nVal = acdbCurDwg()->useri4();
if (nVal != KEY_NOPROTECT)
{
int nVt = 0;
CString sID = IDCreate();
if (pXDataMapCloned->HasKey(KEY_NO, nVt))
{
pXDataMapCloned->SetAt(KEY_NO, sID);
}
}
AecDbObjXDataMap::It it = pXDataMap->Begin();
AecDbObjXDataMap::It end = pXDataMap->End();
CString sKey;
CStringArray arHandKeys;
AecXData cVal;
memset(&cVal,0,sizeof(AecXData));
AcDbObjectId idSrc,idCloned;
for (; it != end; )
{
if (!pXDataMap->GetNext(it, sKey, cVal)) break;
if (cVal.nVt == VT_UI4 || cVal.nVt == VT_UI8)//soft,hard
{
idSrc.setFromOldId(cVal.nVal);
AcDbObject *pSubObject;
AcDbObject *pClonedSubObject;
// Some object's references may be set to NULL,
// so don't try to clone them.
//
if (idSrc == NULL)
continue;
AcDbIdPair idPair2(idSrc, (AcDbObjectId)NULL,
false, isPrim);
if (idMap.compute(idPair2) && (idPair2.value() != NULL))
{
if (pXDataMapCloned != NULL)
{
pXDataMapCloned->RemoveAt(sKey);
pXDataMapCloned->SetAt(sKey, idPair2.value(), cVal.nVt == VT_UI4 ? TRUE : FALSE);
}
continue;
}
// Open the object and clone it. Note that we now
// set "isPrimary" to kFalse here because the object
// is being cloned, not as part of the primary set,
// but because it is owned by something in the
// primary set.
//
pSubObject = NULL;
acdbOpenAcDbObject(pSubObject, idSrc, AcDb::kForRead);
pClonedSubObject = NULL;
if (pSubObject != NULL)
{
//只考虑上华AEC的实体
LPCTSTR pszDxf = pSubObject->isA()->dxfName();
if (_tcsstr(pszDxf, _T("AEC_'")) != NULL)
{
pSubObject->deepClone(pClonedObject,
pClonedSubObject,
idMap, Adesk::kFalse);
}
else
{
pSubObject->close();
pSubObject = NULL;
}
}
// If this is a kDcInsert context, the objects
// may be "cheapCloned". In this case, they are
// "moved" instead of cloned. The result is that
// pSubObject and pClonedSubObject will point to
// the same object. So, we only want to close
// pSubObject if it really is a different object
// than its clone.
//
if (pSubObject != pClonedSubObject)
pSubObject->close();
// The pSubObject may either already have been
// cloned, or for some reason has chosen not to be
// cloned. In that case, the returned pointer will
// be NULL. Otherwise, since we have no immediate
// use for it now, we can close the clone.
//
if (pClonedSubObject != NULL)
idCloned = pClonedSubObject->objectId();
if (pClonedSubObject != NULL)
pClonedSubObject->close();
if (pXDataMapCloned != NULL)
{
if (idCloned.isValid())
{
pXDataMapCloned->RemoveAt(sKey);
pXDataMapCloned->SetAt(sKey, idCloned, cVal.nVt == VT_UI4 ? TRUE : FALSE);
}
else
{
}
}
}
else if (sKey.Find(_T("$H")) != -1 && cVal.nVt == VT_BSTR)//可能的实体句柄
{
arHandKeys.Add(sKey);
}
}
//2022-05-04 需要测试
CString sHand;
AcDbHandle hd;
for (int n = 0; n < arHandKeys.GetSize(); n++)
{
sKey = arHandKeys.GetAt(n);
sHand = sKey;
sHand.TrimRight(_T("$H"));
AcDbHandle handle(sHand);
AcDbObjectId idSrc;
if (Acad::eOk == acdbCurDwg()->getAcDbObjectId(idSrc, false, handle))
{
AcDbObject *pSubObject;
AcDbObject *pClonedSubObject;
// Some object's references may be set to NULL,
// so don't try to clone them.
//
if (idSrc == NULL)
continue;
AcDbIdPair idPair2(idSrc, (AcDbObjectId)NULL,
false, isPrim);
if (idMap.compute(idPair2) && (idPair2.value() != NULL))
{
CString sKeyNew;
//sKey.Format(_T("%s$H"),szHand);
if (pXDataMapCloned != NULL)
{
TCHAR szHand[19];
memset(szHand, 0, sizeof(szHand));
idPair2.value().handle().getIntoAsciiBuffer(szHand);
sKeyNew.Format(_T("%s$H"), szHand);
pXDataMapCloned->RemoveAt(sKey);
pXDataMapCloned->SetAt(sKeyNew, szHand);
}
continue;
}
// Open the object and clone it. Note that we now
// set "isPrimary" to kFalse here because the object
// is being cloned, not as part of the primary set,
// but because it is owned by something in the
// primary set.
//
pSubObject = NULL;
acdbOpenAcDbObject(pSubObject, idSrc, AcDb::kForRead);
pClonedSubObject = NULL;
if (pSubObject != NULL)
{
//只考虑上华AEC的实体
LPCTSTR pszDxf = pSubObject->isA()->dxfName();
if (_tcsstr(pszDxf, _T("AEC_'")) != NULL)
{
pSubObject->deepClone(pClonedObject,
pClonedSubObject,
idMap, Adesk::kFalse);
}
else
{
pSubObject->close();
pSubObject = NULL;
}
}
// If this is a kDcInsert context, the objects
// may be "cheapCloned". In this case, they are
// "moved" instead of cloned. The result is that
// pSubObject and pClonedSubObject will point to
// the same object. So, we only want to close
// pSubObject if it really is a different object
// than its clone.
//
if (pSubObject != pClonedSubObject)
pSubObject->close();
// The pSubObject may either already have been
// cloned, or for some reason has chosen not to be
// cloned. In that case, the returned pointer will
// be NULL. Otherwise, since we have no immediate
// use for it now, we can close the clone.
//
if (pClonedSubObject != NULL)
idCloned = pClonedSubObject->objectId();
if (pClonedSubObject != NULL)
pClonedSubObject->close();
if (pXDataMapCloned != NULL)
{
CString sKeyNew;
TCHAR szHand[19];
memset(szHand, 0, sizeof(szHand));
idCloned.handle().getIntoAsciiBuffer(szHand);
sKeyNew.Format(_T("%s$H"), szHand);
pXDataMapCloned->RemoveAt(sKey);
pXDataMapCloned->SetAt(sKeyNew, szHand);
}
}
}
}
// Leave pClonedObject open for the caller
return Acad::eOk;
}
Acad::ErrorStatus AecDbEntityBase::subWblockClone(AcRxObject* pOwner,
AcDbObject*& pClonedObject,
AcDbIdMapping& idMap,
Adesk::Boolean isPrimary) const
{
// You should always pass back pClonedObject == NULL
// if, for any reason, you do not actually clone it
// during this call. The caller should pass it in
// as NULL, but to be safe, we set it here as well.
//
pClonedObject = NULL;
// If this is a fast wblock operation then no cloning
// should take place, so we simply call the base class's
// wblockClone() and return whatever it returns.
//
// For fast wblock, the source and destination databases
// are the same, so we can use that as the test to see
// if a fast wblock is in progress.
//
AcDbDatabase *pDest, *pOrig;
idMap.destDb(pDest);
idMap.origDb(pOrig);
if (pDest == pOrig)
return AcDbEntity::subWblockClone(pOwner, pClonedObject,
idMap, isPrimary);
// If this is an Xref bind operation and this AsdkPoly
// entity is in Paper Space, then we don't want to
// clone because Xref bind doesn't support cloning
// entities in Paper Space. So we simply return
// Acad::eOk
//
AcDbObjectId pspace;
AcDbBlockTable *pTable;
database()->getSymbolTable(pTable, AcDb::kForRead);
pTable->getAt(ACDB_PAPER_SPACE, pspace);
pTable->close();
if (idMap.deepCloneContext() == AcDb::kDcXrefBind
&& ownerId() == pspace)
return Acad::eOk;
// If this object is in the idMap and is already
// cloned, then return.
//
bool isPrim = false;
if (isPrimary)
isPrim = true;
AcDbIdPair idPair(objectId(), (AcDbObjectId)NULL,
false, isPrim);
if (idMap.compute(idPair) && (idPair.value() != NULL))
return Acad::eOk;
// The owner object can be either an AcDbObject, or an
// AcDbDatabase. AcDbDatabase is used if the caller is
// not the owner of the object being cloned (because it
// is being cloned as part of an AcDbHardPointerId
// reference). In this case, the correct ownership
// will be set during reference translation. So, if
// the owner is an AcDbDatabase, then pOwn will be left
// NULL here, and is used as a "flag" later.
//
AcDbObject *pOwn = AcDbObject::cast(pOwner);
AcDbDatabase *pDb = AcDbDatabase::cast(pOwner);
if (pDb == NULL)
pDb = pOwn->database();
// STEP 1:
// Create the clone
//
AecDbEntityBase *pClone = (AecDbEntityBase *)isA()->create();
if (pClone != NULL)
pClonedObject = pClone; // set the return value
else
return Acad::eOutOfMemory;
// STEP 2:
// If the owner is an AcDbBlockTableRecord, go ahead
// and append the clone. If not, but we know who the
// owner is, set the clone's ownerId to it. Otherwise,
// we set the clone's ownerId to our own ownerId (in
// other words, the original owner Id). This Id will
// then be used later, in reference translation, as
// a key to finding who the new owner should be. This
// means that the original owner must also be cloned at
// some point during the wblock operation.
// EndDeepClone's reference translation aborts if the
// owner is not found in the idMap.
//
// The most common situation where this happens is
// AcDbEntity references to Symbol Table Records, such
// as the Layer an Entity is on. This is when you will
// have to pass in the destination database as the owner
// of the Layer Table Record. Since all Symbol Tables
// are always cloned in Wblock, you do not need to make
// sure that Symbol Table Record owners are cloned.
//
// However, if the owner is one of your own classes,
// then it is up to you to make sure that it gets
// cloned. This is probably easiest to do at the end
// of this function. Otherwise you may have problems
// with recursion when the owner, in turn, attempts
// to clone this object as one of its subObjects.
//
AcDbBlockTableRecord *pBTR = NULL;
if (pOwn != NULL)
pBTR = AcDbBlockTableRecord::cast(pOwn);
if (pBTR != NULL && isPrimary) {
pBTR->appendAcDbEntity(pClone);
}
else {
pDb->addAcDbObject(pClonedObject);
}
// STEP 3:
// The AcDbWblockCloneFiler makes a list of
// AcDbHardOwnershipIds and AcDbHardPointerIds. These
// are the references which must be cloned during a
// Wblock operation.
//
AcDbWblockCloneFiler filer;
dwgOut(&filer);
// STEP 4:
// Rewind the filer and read the data into the clone.
//
filer.seek(0L, AcDb::kSeekFromStart);
pClone->dwgIn(&filer);
pClone->NewGUID();
idMap.assign(AcDbIdPair(objectId(), pClonedObject->objectId(), Adesk::kTrue,
isPrim, (Adesk::Boolean)(pOwn != NULL)));
pClonedObject->setOwnerId((pOwn != NULL) ?
pOwn->objectId() : ownerId());
// STEP 5:
// This must be called for all newly created objects
// in wblockClone. It is turned off by endDeepClone()
// after it has translated the references to their
// new values.
//
pClone->setAcDbObjectIdsInFlux();
// STEP 6:
// Add the new information to the idMap. We can use
// the idPair started above. We must also let the
// idMap entry know whether the clone's owner is
// correct, or needs to be translated later.
//
// STEP 7:
// Using the filer list created above, find and clone
// any hard references.
//
AcDbObjectId id;
while (filer.getNextHardObject(id))
{
AcDbObject *pSubObject;
AcDbObject *pClonedSubObject;
// Some object's references may be set to NULL,
// so don't try to clone them.
//
if (id == NULL)
continue;
// If the referenced object is from a different
// database, such as an xref, do not clone it.
//
acdbOpenAcDbObject(pSubObject, id, AcDb::kForRead);
if (pSubObject->database() != database()) {
pSubObject->close();
continue;
}
// We can find out if this is an AcDbHardPointerId
// verses an AcDbHardOwnershipId, by seeing if we
// are the owner of the pSubObject. If we are not,
// then we cannot pass our clone in as the owner
// for the pSubObject's clone. In that case, we
// pass in our clone's database (the destination
// database).
//
// Note that we now set "isPrimary" to kFalse here
// because the object is being cloned, not as part
// of the primary set, but because it is owned by
// something in the primary set.
//
pClonedSubObject = NULL;
if (pSubObject->ownerId() == objectId()) {
pSubObject->wblockClone(pClone,
pClonedSubObject,
idMap, Adesk::kFalse);
}
else {
pSubObject->wblockClone(pClone->database(),
pClonedSubObject,
idMap, Adesk::kFalse);
}
pSubObject->close();
// The pSubObject may either already have been
// cloned, or for some reason has chosen not to be
// cloned. In that case, the returned pointer will
// be NULL. Otherwise, since we have no immediate
// use for it now, we can close the clone.
//
if (pClonedSubObject != NULL)
pClonedSubObject->close();
}
//xdataMap 复制
//到mep中找建立新的关系
AecDbObjXDataMap *pXDataMapCloned = pClone->GetSpecialtyData();
AecDbObjXDataMap *pXDataMap = (AecDbObjXDataMap *)GetSpecialtyData();
if (pXDataMap != NULL && pXDataMapCloned != NULL)
{
//发送提资需要相同的ID
Adesk::Int16 nVal = acdbCurDwg()->useri4();
if (nVal != KEY_NOPROTECT)
{
int nVt = 0;
CString sID = IDCreate();
if (pXDataMapCloned->HasKey(KEY_NO, nVt))
{
pXDataMapCloned->SetAt(KEY_NO, sID);
}
}
AecDbObjXDataMap::It it = pXDataMap->Begin();
AecDbObjXDataMap::It end = pXDataMap->End();
CString sKey;
CStringArray arHandKeys;
AecXData cVal;
memset(&cVal, 0, sizeof(AecXData));
AcDbObjectId idSrc, idCloned;
for (; it != end;)
{
if (!pXDataMap->GetNext(it, sKey, cVal)) break;
if (cVal.nVt == VT_UI4 || cVal.nVt == VT_UI8)//soft,hard
{
idSrc.setFromOldId(cVal.nVal);
AcDbObject *pSubObject;
AcDbObject *pClonedSubObject;
// Some object's references may be set to NULL,
// so don't try to clone them.
//
if (idSrc == NULL)
continue;
AcDbIdPair idPair2(idSrc, (AcDbObjectId)NULL,
false, isPrim);
if (idMap.compute(idPair2) && (idPair2.value() != NULL))
{
if (pXDataMapCloned != NULL)
{
pXDataMapCloned->SetAt(sKey, idPair2.value(), cVal.nVt == VT_UI4 ? TRUE : FALSE);
}
continue;
}
// Open the object and clone it. Note that we now
// set "isPrimary" to kFalse here because the object
// is being cloned, not as part of the primary set,
// but because it is owned by something in the
// primary set.
//
acdbOpenAcDbObject(pSubObject, idSrc, AcDb::kForRead);
pClonedSubObject = NULL;
if (pSubObject->ownerId() == objectId()) {
pSubObject->wblockClone(pClone,
pClonedSubObject,
idMap, Adesk::kFalse);
}
else {
pSubObject->wblockClone(pClone->database(),
pClonedSubObject,
idMap, Adesk::kFalse);
}
// If this is a kDcInsert context, the objects
// may be "cheapCloned". In this case, they are
// "moved" instead of cloned. The result is that
// pSubObject and pClonedSubObject will point to
// the same object. So, we only want to close
// pSubObject if it really is a different object
// than its clone.
//
if (pSubObject != pClonedSubObject)
pSubObject->close();
// The pSubObject may either already have been
// cloned, or for some reason has chosen not to be
// cloned. In that case, the returned pointer will
// be NULL. Otherwise, since we have no immediate
// use for it now, we can close the clone.
//
idCloned = pClonedSubObject->objectId();
if (pClonedSubObject != NULL)
pClonedSubObject->close();
if (pXDataMapCloned != NULL)
{
pXDataMapCloned->RemoveAt(sKey);
pXDataMapCloned->SetAt(sKey, idCloned, cVal.nVt == VT_UI4 ? TRUE : FALSE);
}
}
else if (sKey.Find(_T("$H")) != -1 && cVal.nVt == VT_BSTR)//可能的实体句柄
{
arHandKeys.Add(sKey);
}
}
}
return Acad::eOk;
}
//AEC派生
int AecDbEntityBase::GetDrawMode()
{
int nDrawMode = 3;
//从命名字典中取,默认3
return nDrawMode;
}
void AecDbEntityBase::SetDrawMode(int nMode)
{
//写入命名字典
}
//某些实体只有2D
int AecDbEntityBase::GetDrawDimOnType(int nDrawMode, int nDrawType) const
{
int nDraw = 0; //0--NONE; 1--2D; 2--3D; 3--2D&3D;
if (nDrawMode == DRAW_2D && (nDrawType == k2DOnly || nDrawType == k2Dand3D))
{
nDraw = 1;
}
else if (nDrawMode == DRAW_3D && (nDrawType == k3DOnly || nDrawType == k2Dand3D))
{
nDraw = 2;
}
else if (nDrawMode == (DRAW_2D | DRAW_3D) && nDrawType == k2Dand3D)
{
nDraw = 3;//转到viewportdraw
}
else if (nDrawMode == (DRAW_2D | DRAW_3D) && nDrawType == k2DOnly)
{
nDraw = 1;
}
else if (nDrawMode == (DRAW_2D | DRAW_3D) && nDrawType == k3DOnly)
{
nDraw = 2;
}
return nDraw;
}
void AecDbEntityBase::BackupColorIndex(AcDbEntity* pEnt)
{
if (pEnt != NULL)
{
struct resbuf* pXData = NULL;
pXData = pEnt->xData(_T("COLOR_BK"));
if (pXData == NULL)
{
struct resbuf* pTemp = acutNewRb(AcDb::kDxfRegAppName);
acutNewString(_T("COLOR_BK"),pTemp->resval.rstring);
pXData = pTemp;
struct resbuf* pTempNext = NULL;
pTempNext = acutNewRb(AcDb::kDxfXdInteger32);
pTempNext->resval.rlong = pEnt->colorIndex();
pTemp->rbnext = pTempNext;
pTempNext->rbnext = NULL;
acdbRegApp(_T("COLOR_BK"));
pEnt->setXData(pXData);
acutRelRb(pXData);
}
}
}
int AecDbEntityBase::SetBackupColorIndex(AcDbEntity* pEnt)
{
int nColor = kColorByLayer;
if (pEnt != NULL)
{
resbuf* pXData = NULL;
pXData = pEnt->xData(_T("COLOR_BK"));
if (pXData != NULL)
{
struct resbuf* pTempNext = pXData->rbnext;
if (pTempNext != NULL)
{
if (pTempNext->restype == AcDb::kDxfXdInteger32)
{
nColor = pTempNext->resval.rint;
// 存在清空
struct resbuf* pTmp = acutNewRb(AcDb::kDxfRegAppName);
pEnt->setXData(pTmp);
acutRelRb(pXData);
acutRelRb(pTmp);
}
}
}
}
return nColor;
}
int AecDbEntityBase::GetExplodeMode() const
{
int nDrawMode = AecDbEntityBase::GetDrawMode();
int nDraw = GetDrawDimOnType(nDrawMode, k2Dand3D);
if (nDraw == 1)
{
nDraw = DRAW_2D;
}
else if (nDraw == 2)
{
nDraw = DRAW_3D;
}
else if (nDraw == 3)
{
ads_point pt;
struct resbuf rb;
acedGetVar(_T("VIEWDIR"),&rb);
ads_point_set(rb.resval.rpoint,pt);
ads_point viewDir;
acdbUcs2Wcs(pt,viewDir,false);
if (fabs(viewDir[X]) > 1.0e-6 || fabs(viewDir[Y]) > 1.0e-6)
{
nDraw = DRAW_3D;
}
else
{
nDraw = DRAW_2D;
}
}
return nDraw;
}
Acad::ErrorStatus AecDbEntityBase::dwgInFields (AcDbDwgFiler* pFiler)
{
assertWriteEnabled () ;
//----- Read parent class information first.
Acad::ErrorStatus es = AcDbEntity::dwgInFields (pFiler) ;
if ( es != Acad::eOk )
return (es) ;
return (pFiler->filerStatus ()) ;
}
Acad::ErrorStatus AecDbEntityBase::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled () ;
//----- Save parent class information first.
Acad::ErrorStatus es = AcDbEntity::dwgOutFields (pFiler) ;
if ( es != Acad::eOk )
return (es) ;
return (pFiler->filerStatus ()) ;
}
Acad::ErrorStatus AecDbEntityBase::dxfInFields (AcDbDxfFiler* pFiler)
{
assertWriteEnabled () ;
//----- Read parent class information first.
Acad::ErrorStatus es = AcDbEntity::dxfInFields (pFiler) ;
if ( es != Acad::eOk )
return (es) ;
return (pFiler->filerStatus ()) ;
}
Acad::ErrorStatus AecDbEntityBase::dxfOutFields(AcDbDxfFiler* pFiler) const
{
assertReadEnabled () ;
//----- Save parent class information first.
Acad::ErrorStatus es = AcDbEntity::dxfOutFields (pFiler) ;
if ( es != Acad::eOk )
return (es) ;
return (pFiler->filerStatus ()) ;
}
Acad::ErrorStatus AecDbEntityBase::Draw2d(AcGiDraw &dc) const
{
return Acad::eOk;
}
Acad::ErrorStatus AecDbEntityBase::Draw3d(AcGiDraw &dc) const
{
return Acad::eOk;
}
void AecDbEntityBase::AssertWriteEnabled(Adesk::Boolean autoUndo /*= true*/, Adesk::Boolean recordModified /*= true*/)
{
FreeBuffer(0, m_ar2DDrableBufPtrs_);
FreeBuffer(0, m_ar3DDrableBufPtrs_);
m_ar3DDrableBufPtrs_.removeAll();
m_ar2DDrableBufPtrs_.removeAll();
assertWriteEnabled(autoUndo,recordModified);
}
bool AecDbEntityBase::GetPositionGrip(int nIndex, AecGripData *&pGrip) const
{
return NULL;
}
extern double PixelToWcs(int nPixel);
bool AecDbEntityBase::SubAddHitEditGrip(AcDbGripDataPtrArray &grips) const
{
assertReadEnabled();
AecGripData *pGrip = NULL;
GetPositionGrip(grips.length() - 1, pGrip);
if (pGrip != NULL)
{
AcGePoint3d ptHit = pGrip->ptGrip;
ptHit += AcGeVector3d::kXAxis * PixelToWcs(30);
AecGripData *pGrip2 = new AecGripData;
memset(pGrip2, 0, sizeof(AecGripData));
pGrip2->nIndex = grips.length();
pGrip2->ePos = eHitEdit;
pGrip2->nColor = kRed;
pGrip2->ptGrip = ptHit;
_tcscpy(pGrip2->szTip, _T("点击修改"));
_tcscpy(pGrip2->szID, _T("HITEDIT_2023"));
pGrip2->pOwner = (AcDbEntity *)this;
pGrip2->idHost = this->objectId();
AcDbGripData *pGripData = new AcDbGripData;
pGripData->setGripPoint(ptHit);
pGripData->setAppData((void *)pGrip2);
pGripData->setWorldDraw(AecGripCback::WorldDrawfunc);
pGripData->setToolTipFunc(AecGripCback::GripToolTipFunc);
grips.append(pGripData);
return true;
}
return false;
}
//不得导出,需要数据,增加特定的获取函数
extern AecDbObjXDataMap g_mapGlobalData;
bool AecDbEntityBase::HitOnGripEdit(const AcDbVoidPtrArray &gripAppData)
{
AecGripData *pAppData = NULL;
AcDbIntArray arIndex;
if (gripAppData.isEmpty())
{
return Acad::eOk;
}
pAppData = (AecGripData *)gripAppData.first();
if (pAppData->ePos == eHitEdit)
{
//命令名 DBL_DXFNAME
TCHAR szCmd[65];
_tcscpy(szCmd, _T("DBL_"));
_tcscat(szCmd, this->isA()->dxfName());
//判断命令是否存在
AcEdCommand *pCmd = acedRegCmds->lookupLocalCmd(szCmd);
if (pCmd != NULL)
{
//发送ID 到 USERI;
AcDbObjectId id = pAppData->idHost;
g_mapGlobalData.SetAt(szCmd, id);
acedPostCommand(_T("\x03"));
_tcscat(szCmd, _T(" "));
acedPostCommand(szCmd);
}
else
{
acutPrintf(_T("\nLocalCmd %s does not exist!"), szCmd);
}
return true;
}
return false;
}
bool AecDbEntityBase::Draw3DBuffers(AcGiDraw &dc)const
{
if (m_ar3DDrableBufPtrs_.isEmpty()) return false;
for (int i = 0; i < m_ar3DDrableBufPtrs_.length(); ++i)
{
AcDbEntity *pEnt((AcDbEntity*)m_ar3DDrableBufPtrs_[i]);
dc.DrawEntity(*pEnt);
}
return true;
}
bool AecDbEntityBase::Draw2DBuffers(AcGiDraw &dc)const
{
if (m_ar2DDrableBufPtrs_.isEmpty())
return false;
for (int i = 0; i < m_ar2DDrableBufPtrs_.length(); ++i)
{
dc.DrawEntity(*(AcDbEntity*)m_ar2DDrableBufPtrs_[i]);
}
return true;
}
const AcDbVoidPtrArray& AecDbEntityBase::Get3DBuffer() const
{
BoolSubtractHide();
return m_ar3DDrableBufPtrs_;
}
const AcDbVoidPtrArray& AecDbEntityBase::Get2DBuffer() const
{
return m_ar2DDrableBufPtrs_;
}
bool AecDbEntityBase::Has3DBuffer() const
{
return !m_ar3DDrableBufPtrs_.isEmpty();
}
bool AecDbEntityBase::Has2DBuffer() const
{
return !m_ar2DDrableBufPtrs_.isEmpty();
}
void AecDbEntityBase::Add3DBuffer(AcDbEntity *pEnt) const
{
if (pEnt && m_ar3DDrableBufPtrs_.find(pEnt) == -1)
m_ar3DDrableBufPtrs_.append(pEnt);
}
void AecDbEntityBase::Add3DBuffer(const AcDbVoidPtrArray &arr) const
{
for (int i = 0; i < arr.length(); ++i)
Add3DBuffer((AcDbEntity*)arr[i]);
}
void AecDbEntityBase::Add2DBuffer(const AcDbVoidPtrArray &arr) const
{
for (int i = 0; i < arr.length(); ++i)
Add2DBuffer((AcDbEntity*)arr[i]);
}
void AecDbEntityBase::Add2DBuffer(AcDbEntity *pEnt) const
{
if (pEnt && m_ar2DDrableBufPtrs_.find(pEnt) == -1)
m_ar2DDrableBufPtrs_.append(pEnt);
}
bool AecDbEntityBase::IsIn2DBuffer(AcDbEntity* pEnt) const
{
assertReadEnabled();
if (-1 == m_ar2DDrableBufPtrs_.find(pEnt))
return false;
return true;
}
bool AecDbEntityBase::IsIn3DBuffer(AcDbEntity* pEnt) const
{
assertReadEnabled();
if (-1 == m_ar3DDrableBufPtrs_.find(pEnt))
return false;
return true;
}
void AecDbEntityBase::Clean3DBuffer() const
{
FreeBuffer(0, m_ar3DDrableBufPtrs_);
m_ar3DDrableBufPtrs_.removeAll();
}
void AecDbEntityBase::Clean2DBuffer() const
{
FreeBuffer(0, m_ar2DDrableBufPtrs_);
m_ar2DDrableBufPtrs_.removeAll();
}
void AecDbEntityBase::Clean3DBufferNoDel() const
{
m_ar3DDrableBufPtrs_.removeAll();
}
void AecDbEntityBase::Clean2DBufferNoDel() const
{
m_ar2DDrableBufPtrs_.removeAll();
}
int AecDbEntityBase::GetDrawDimCur() const
{
return m_nDrawDimCur;
}
//获取二维视图显示的图形
int AecDbEntityBase::GetDraw2dables(Adesk::UInt16 nDrawStyle, AcDbVoidPtrArray& arEntPtrs) const
{
assertReadEnabled();
AcDbEntity* pEnt = NULL,*pEntT = NULL;
const AcDbVoidPtrArray &ar2D = Get2DBuffer();
for (int i = 0;i < ar2D.length();i++)
{
pEnt = (AcDbEntity*)ar2D.at(i);
pEntT = (AcDbEntity*)pEnt->clone();
pEntT->setLayer(layerId());
arEntPtrs.append(pEntT);
}
return arEntPtrs.length();
}
void AecDbEntityBase::UpdateDrableSpecData(LPCTSTR pszApp,LPCTSTR pszKey,CString& sVal)
{
assertWriteEnabled();
AecDbObjXDataMap xDataMap;
AcDbEntity* pEnt = NULL,*pEntT = NULL;
const AcDbVoidPtrArray &ar2D = Get2DBuffer();
for (int i = 0;i < ar2D.length();i++)
{
pEnt = (AcDbEntity*)ar2D.at(i);
if (xDataMap.Read(pEnt,pszApp))
{
xDataMap.RemoveAt(pszKey);
xDataMap.SetAt(pszKey,sVal);
xDataMap.Write(pEnt,pszApp);
}
}
const AcDbVoidPtrArray &ar3D = Get3DBuffer();
for (int i = 0;i < ar3D.length();i++)
{
pEnt = (AcDbEntity*)ar3D.at(i);
if (xDataMap.Read(pEnt,pszApp))
{
xDataMap.RemoveAt(pszKey);
xDataMap.SetAt(pszKey,sVal);
xDataMap.Write(pEnt,pszApp);
}
}
}
bool AecDbEntityBase::GetBimInfoTip(CString& sInfoTip) const
{
return false;
}
bool AecDbEntityBase::GetProperties(SimpleProperty::PropertySetByIndex &porpertys) const
{
assertReadEnabled();
CString sLayer(_T("0"));
TCHAR *pLayer = layer();
if (pLayer)
{
sLayer = pLayer;
acutDelString(pLayer);
}
SimpleProperty::makeAndInsert(porpertys, _T("图层"), sLayer, false);
const AecDbObjXDataMap *pData = GetSpecialtyData();
CString sys;
if (pData->GetAt(PIPE_SYS, sys))
SimpleProperty::makeAndInsert(porpertys, _T("分系统"), sys, false);
return true;
}
bool AecDbEntityBase::SetProperties(SimpleProperty::PropertySetByName & properties)
{
AssertWriteEnabled();
using namespace SimpleProperty;
CString sVal(_T(""));
if (properties.findAndSet(_T("图层"), sVal))
{
setLayer(sVal);
}
if (properties.findAndSet(_T("分系统"), sVal))
{
AecDbObjXDataMap *pData = GetSpecialtyData(AcDb::kForWrite);
if (pData)
pData->SetAt(PIPE_SYS, sVal);
}
return true;
}
bool AecDbEntityBase::SendUserData(struct resbuf *pRb)
{
return false;
}
//获取三维显示图形
int AecDbEntityBase::GetDraw3dables(AcDbVoidPtrArray& arEntPtrs,bool bWriteBimInfo) const
{
assertReadEnabled();
const AecDbObjXDataMap* pXDataMap = GetSpecialtyData();
if (pXDataMap != NULL)
{
AcDbEntity* pEnt = NULL,*pEntClone = NULL;
if (!Has3DBuffer())
{
AcGiViewDraw dc(NULL, NULL);
Draw3d(dc);
}
const AcDbVoidPtrArray &ar3D = Get3DBuffer();
for (int i = 0;i < ar3D.length();i++)
{
pEnt = (AcDbEntity*)ar3D.at(i);
pEntClone = (AcDbEntity*)pEnt->clone();
int nColor = 0;
if ( pXDataMap->GetAt(_T("COLOR"),nColor) )
{
pEntClone->setColorIndex(nColor);
}
else
{
pEntClone->setColorIndex(colorIndex());
}
pEntClone->setLayer(layerId());
if (bWriteBimInfo)
{
pXDataMap->Write(pEntClone,_T("BIMDATA"));
}
arEntPtrs.append(pEntClone);
}
}
return arEntPtrs.length();
}
int AecDbEntityBase::GetSectionDraw(const AcGePoint3d& ptFr,const AcGePoint3d& ptTo,const AcGeVector3d& vtViewDir,const AcGeVector3d& vtTo, AcDbVoidPtrArray& arRegionPtrs) const
{
return 0;
}
bool AecDbEntityBase::GetSectionHatchPattern(CString& sPattern) const
{
assertReadEnabled();
CString sMat;
if (GetSpecialtyData()->GetAt(KEY_SECTION_HATCH, sMat))
{
sPattern = sMat;
if (sMat == HATCH_NO_NEED)
return false;
if (sMat != HATCH_DEFAULT)
return true;
}
if ( GetSpecialtyData()->GetAt(KEY_MATERIAL,sMat))
{
//以后从外部配置文件中获取
//钢筋混凝土
//石材
//砖墙
//填充墙体
//轻质隔墙
//玻璃幕墙
sPattern = _T("AR-CONC");//默认
if (sMat.CompareNoCase(_T("钢筋混凝土")) == 0)
{
sPattern = _T("钢筋混凝土");
}
else if(sMat.CompareNoCase(_T("混凝土")) == 0)
{
sPattern = _T("混凝土");
}
else if(sMat.CompareNoCase(_T("石材")) == 0)
{
sPattern = _T("天然石材");
}
else if(sMat.CompareNoCase(_T("砖墙")) == 0)
{
sPattern = _T("普通砖");
}
else if(sMat.CompareNoCase(_T("填充墙体")) == 0)
{
sPattern = _T("钢筋混凝土");
}
else if(sMat.CompareNoCase(_T("轻质隔墙")) == 0)
{
sPattern = _T("混凝土");
}
else if(sMat.CompareNoCase(_T("玻璃幕墙")) == 0)
{
sPattern = _T("玻璃砖墙");
}
}
return true;
}
Acad::ErrorStatus AecDbEntityBase::ReCreateDraw2d()
{
assertWriteEnabled();
Clean2DBuffer();
return Acad::eOk;
}
Acad::ErrorStatus AecDbEntityBase::ReCreateDraw3d()
{
assertWriteEnabled();
Clean3DBuffer();
return Acad::eOk;
}
double AecDbEntityBase::GetVolume(bool bIsBody/* = false*/) const
{
assertReadEnabled();
if (!Has3DBuffer())
{
AcGiViewDraw dc(NULL,NULL);
Draw3d(dc);
}
double dVol = 0.0,dVolAll = 0.0,momInertia[3],prodInertia[3],prinMoments[3],radiiGyration[3];
AcGePoint3d ptCen;
AcGeVector3d prinAxes[3];
AcDbExtents extents;
AcDbVoidPtrArray arEntPtrs;
GetDraw3dables(arEntPtrs);
AcDbEntity* pEnt = NULL;
for (int i = 0;i < arEntPtrs.length();i++)
{
pEnt = (AcDbEntity*)arEntPtrs.at(i);
AcDb3dSolid* pSolid = AcDb3dSolid::cast(pEnt);
if (pSolid != NULL)
{
pSolid->getMassProp(dVol,ptCen,momInertia,prodInertia,prinMoments,prinAxes,radiiGyration,extents);
dVolAll += dVol;
}
}
return dVolAll;
}
int AecDbEntityBase::ComparedTo(AecDbEntityBase* pEntOther) const
{
return -1;
}
double AecDbEntityBase::GetArea() const
{
assertReadEnabled();
if (!Has3DBuffer())
{
AcGiViewDraw dc(NULL,NULL);
Draw3d(dc);
}
double dArea = 0.0,dAreaAll = 0.0;
AcDbVoidPtrArray arEntPtrs;
GetDraw3dables(arEntPtrs);
AcDbEntity* pEnt = NULL;
for (int i = 0;i < arEntPtrs.length();i++)
{
pEnt = (AcDbEntity*)arEntPtrs.at(i);
AcDb3dSolid* pSolid = AcDb3dSolid::cast(pEnt);
if (pSolid != NULL)
{
pSolid->getArea(dArea);
dAreaAll += fabs(dArea);
}
}
return dAreaAll;
}
void AecDbEntityBase::Add3DBoolSubtract(AcDb3dSolid* pSolidBlackHole)
{
assertWriteEnabled();
const AcDbVoidPtrArray& ar3D_ = Get3DBuffer();
AcDbVoidPtrArray ar3D;
ar3D.append(ar3D_);
AcDbEntity* pEnt = NULL;
AcDb3dSolid* pSolid = NULL;
AcDb3dSolid* pSolidCln = NULL;
AcDb3dSolid* pSolidNotGet = NULL;
Acad::ErrorStatus es;
Adesk::Boolean bSlidInterface = Adesk::kFalse;
double dArea1 = 0.0,dArea2 = 0.0;
for (int i = 0;i < ar3D.length();i++)
{
pEnt = (AcDbEntity*)ar3D.at(i);
pSolid = AcDb3dSolid::cast(pEnt);
if (pSolid != NULL)
{
pSolidCln = (AcDb3dSolid*)pSolidBlackHole->clone();
//有交集才处理
if ( Acad::eOk == pSolid->checkInterference( pSolidCln,Adesk::kFalse,bSlidInterface,pSolidNotGet))
{
pSolid->getArea(dArea1);
es = pSolid->booleanOper(AcDb::kBoolSubtract,pSolidCln);
pSolid->getArea(dArea2);
if ( es == Acad::eOk)
{
pSolid->recordGraphicsModified(Adesk::kTrue);
if ( fabs(dArea1 - dArea2) < 1.e-3)//没有变化,被包含
{
ar3D.removeAt(i);
i -= 1;
m_ar3DDrableBufPtrs_.removeAt(i);
}
}
else if ( es == Acad::eGeneralModelingFailure )
{
ar3D.removeAt(i);
i -= 1;
m_ar3DDrableBufPtrs_.removeAt(i);
}
//delete pSolidCln;
}
}
}
}
void AecDbEntityBase::Remove3DBoolSubtract()
{
assertWriteEnabled();
//清除3D,重建
Clean3DBuffer();
}
void AecDbEntityBase::AddBlackHole(AcDbObjectId& idHole)
{
AssertWriteEnabled();
AecDbObjXDataMap* pXdataMap = GetSpecialtyData(AcDb::kForWrite);
if (pXdataMap != NULL)
{
TCHAR szHand[19];
memset(szHand,0,sizeof(szHand) );
idHole.handle().getIntoAsciiBuffer(szHand);
CString sKey;
sKey.Format(_T("%s_%s"),KEY_HOLE,szHand);
pXdataMap->SetAt(sKey,idHole.handle());
}
}
void AecDbEntityBase::RemoveBlackHole(AcDbObjectId& idHole)
{
AssertWriteEnabled();
AecDbObjXDataMap* pXdataMap = GetSpecialtyData(AcDb::kForWrite);
if (pXdataMap != NULL)
{
TCHAR szHand[19];
memset(szHand,0,sizeof(szHand) );
idHole.handle().getIntoAsciiBuffer(szHand);
CString sKey;
sKey.Format(_T("%s_%s"),KEY_HOLE,szHand);
pXdataMap->RemoveAt(sKey);
}
}
void AecDbEntityBase::DrawBlackHole(AcDbEntity* pSolidEnt) const
{
AcDb3dSolid* pSolidAll = AcDb3dSolid::cast(pSolidEnt);
if (pSolidAll == NULL)
return;
const AecDbObjXDataMap* pCXDataMap = GetSpecialtyData();
if (pCXDataMap != NULL)
{
AecDbObjXDataMap* pXDataMap = (AecDbObjXDataMap*)pCXDataMap;
AecDbObjXDataMap::It it = pXDataMap->Begin();
AecDbObjXDataMap::It end = pXDataMap->End();
CString sKey;
AecXData cVal;
memset(&cVal,0,sizeof(AecXData));
AcDbEntity* pEnt = NULL;
AcDbHandle hd;
AcDbObjectId idHole;
for (; it != end; )
{
if (!pXDataMap->GetNext(it, sKey, cVal))
break;
if (sKey.Find(KEY_HOLE) != -1)
{
pXDataMap->GetAt(sKey,hd);
if ( Acad::eOk == acdbCurDwg()->getAcDbObjectId(idHole,false,hd) )
{
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idHole,AcDb::kForRead))
{
AecDbEntityBase* pBlackHole = AecDbEntityBase::cast(pEnt);
if (pBlackHole != NULL)
{
AcDb3dSolid* pSolidBlackHold = pBlackHole->GetBlackHole();
if (pSolidBlackHold != NULL)
{
pSolidAll->booleanOper(AcDb::kBoolSubtract,pSolidBlackHold);
}
}
pEnt->close();
}
}
}
}
}
}
AcDb3dSolid* AecDbEntityBase::GetBlackHole() const
{
return NULL;
}
void AecDbEntityBase::SplitStrintToArray(LPCTSTR pszDescr, CStringArray & arInfo, TCHAR tcSpace)
{
if (pszDescr == NULL) return;
CString sDescr = pszDescr;
int nLen = sDescr.GetLength();
int i = 0;
CString sText = _T("");
TCHAR tchar = _T('\0');
for (i = 0; i < nLen; i++)
{
tchar = sDescr.GetAt(i);
if (tchar == tcSpace)
{
if (!sText.IsEmpty())
arInfo.Add(sText);
sText = _T("");
}
else
{
sText += tchar;
}
if (i == nLen - 1 && !sText.IsEmpty())
{
arInfo.Add(sText);
}
}
}
AcDbPolyline * AecDbEntityBase::StringToPolyline(LPCTSTR pszPoint2ds)
{
CString sPlane,sTemp;
CString sAll = pszPoint2ds;
int nPos = sAll.Find(_T("plane="));
if (nPos != -1)
{
sPlane = sAll.Mid(nPos);
sTemp = sAll.Mid(0,nPos);
sAll = sTemp;
}
CStringArray arXYs;
SplitStrintToArray(sAll, arXYs, _T(','));
double dEl = 0.0;
AcGeVector3d vtNorm = AcGeVector3d::kZAxis;
CString sLast;
if (arXYs.GetSize() > 0)
{
sLast = arXYs.GetAt(arXYs.GetSize() - 1);
if (sLast.Find(_T('[')) != -1)
{
sLast.TrimLeft(_T('['));
sLast.TrimRight(_T(']'));
}
CStringArray arVals;
SplitStrintToArray(sLast, arVals, _T(';'));
if (arVals.GetSize() >= 4)
{
dEl = _ttof(arVals.GetAt(0));
vtNorm.set(_ttof(arVals.GetAt(1)), _ttof(arVals.GetAt(2)), _ttof(arVals.GetAt(3)));
}
}
CString sX, sYB, sBulge, sY;
double dBulge = 0.0;
int nFind = -1;
AcGePoint2d pt;
AcDbPolyline pl;
AcDbPolyline* pPl = new AcDbPolyline;
if (!sPlane.IsEmpty())
{
sPlane.TrimLeft(_T("plane="));
sPlane.TrimLeft(_T('('));
sPlane.TrimRight(_T(')'));
CStringArray arVals;
SplitStrintToArray(sPlane,arVals,_T(','));
if (arVals.GetSize() >= 4)
{
vtNorm.set(_ttof(arVals.GetAt(0)),_ttof(arVals.GetAt(1)),_ttof(arVals.GetAt(2)));
dEl = _ttof(arVals.GetAt(3));
pPl->setNormal(vtNorm);
pPl->setElevation(dEl);
}
}
else
{
pPl->setNormal(vtNorm);
pPl->setElevation(dEl);
}
for (int i = 0; i < arXYs.GetSize() / 2; i++)
{
sX = arXYs.GetAt(2 * i);
sYB = arXYs.GetAt(2 * i + 1);
sY = sYB;
dBulge = 0.0;
nFind = sYB.Find(_T('@'));
if (nFind != -1)
{
sBulge = sYB.Mid(nFind + 1);
dBulge = _ttof(sBulge);
sY = sYB.Mid(0, nFind);
}
pt.set(_ttof(sX), _ttof(sY));
pPl->addVertexAt(i, pt, dBulge);
}
return pPl;
}
static AcGePoint3d MidPoint(AcGePoint3d& pt1, AcGePoint3d& pt2)
{
return AcGePoint3d((pt1.x + pt2.x) / 2.0,
(pt1.y + pt2.y) / 2.0,
(pt1.z + pt2.z) / 2.0);
}
//剖切隐藏
void AecDbEntityBase::BoolSubtractHide() const
{
if (m_ar3DDrableBufPtrs_.isEmpty())
return;
const AecDbObjXDataMap* pXDataMap = GetSpecialtyData();
if (pXDataMap != NULL)
{
CString sPl;
double dBomEl = 0.0,dH = 0.0;
if ( pXDataMap->GetAt(KEY_BOOLSPL,sPl) &&
pXDataMap->GetAt(KEY_BOOLBOM,dBomEl) &&
pXDataMap->GetAt(KEY_BOOLH,dH) )
{
AcDbPolyline* pPl = StringToPolyline(sPl);
if (pPl != NULL)
{
AcGePoint3d ptFr,ptTo;
pPl->getPointAt(0,ptFr);
//简单取内一心
if (pPl->numVerts() > 2)
{
AcGePoint3d pt2;
pPl->getPointAt(2,pt2);
ptFr = MidPoint(ptFr,pt2);
}
AcDbLine ln;
ptFr.z = dBomEl;
ptTo = ptFr;
ptTo.z = dH;
ln.setStartPoint(ptFr);
ln.setEndPoint(ptTo);
AcDbRegion* pRegion = NULL;
AcDbVoidPtrArray arCur,arReg;
arCur.append(pPl);
Acad::ErrorStatus es;
if (Acad::eOk == ( es = AcDbRegion::createFromCurves(arCur,arReg) ) )
{
if (!arReg.isEmpty())
{
pRegion = (AcDbRegion*)arReg.first();
AcDb3dSolid* pSoldSub = new AcDb3dSolid;
if ( Acad::eOk == (es = pSoldSub->extrudeAlongPath(pRegion,&ln) ) )
{
AcDb3dSolid* pSolid = NULL;
AcDbEntity* pEnt = NULL;
for (int i = 0;i < m_ar3DDrableBufPtrs_.length();i++)
{
pEnt = (AcDbEntity*)m_ar3DDrableBufPtrs_.at(i);
pSolid = AcDb3dSolid::cast(pEnt);
if (pSolid != NULL)
{
AcDb3dSolid* pSolidSubCln = (AcDb3dSolid*)pSoldSub->clone();
CopyObject(*pSoldSub,*pSolidSubCln);
if ( Acad::eOk != (es = pSolid->booleanOper(AcDb::kBoolSubtract,pSolidSubCln) ) )
{
delete pSolidSubCln;
}
}
}
}
delete pSoldSub;
delete pRegion;
}
}
delete pPl;
}
}
}
}
SHJson::WValue& AecDbEntityBase::ToJson(bool bExprotGeo) const
{
assertReadEnabled();
using namespace SHJson;
WValue &v(m_json);
v.SetObject();
addMember(v, _T("__class__"), isA()->name());
addMember(v, _T("__self__"), objectId().asOldId());
addMember(v, _T("__owner__"), 0);
const AecDbObjXDataMap *pXMap = GetSpecialtyData();
if (pXMap)
{
addMember(v, _T("__xdata__"), pXMap->ToJson());
}
CString sVertices, sIndices;
__int64 dwRgb = 0;
struct resbuf rb;
acedGetVar(_T("useri5"), &rb);
if (rb.resval.rint == 30)//3D导出
{
WValue node;
node.SetObject();
WValue body;
body.SetArray();
AcDbEntity *pE = NULL;
for (int i = 0; i < Get3DBuffer().length(); i++)
{
node.SetNull();
pE = (AcDbEntity *)Get3DBuffer().at(i);
AcDb3dSolid *p3d = AcDb3dSolid::cast(pE);
if (p3d != NULL)
{
dwRgb = RGB(p3d->color().red(), p3d->color().green(), p3d->color().blue());
if (PolyhedronGeometry(p3d, sVertices, sIndices))
{
addMember(node, _T("RGB"), dwRgb);
addMember(node, _T("vertices"), sVertices);
addMember(node, _T("indices"), sIndices);
pushBack(body, node);
}
}
AcDbSubDMesh *pSubMesh = AcDbSubDMesh::cast(pE);
if (pSubMesh != NULL)
{
dwRgb = RGB(pSubMesh->color().red(), pSubMesh->color().green(), pSubMesh->color().blue());
if (PolyhedronGeometry(pSubMesh, sVertices, sIndices))
{
addMember(node, _T("RGB"), dwRgb);
addMember(node, _T("vertices"), sVertices);
addMember(node, _T("indices"), sIndices);
pushBack(body, node);
}
}
}
if (!body.Empty())
addMember(v, _T("__body__"), body);
}
return v;
}
bool AecDbEntityBase::ByJson(const SHJson::WValue &v)
{
using namespace SHJson;
AssertWriteEnabled();
AecDbObjXDataMap *pXMap = GetSpecialtyData(AcDb::kForWrite);
if (pXMap)
{
MCIt it = v.FindMember(_T("__xdata__"));
if (it != v.MemberEnd())
return pXMap->ByJson(it->value);
}
return true;
}
Acad::ErrorStatus AecDbEntityBase::setTransparency(const AcCmTransparency &trans, Adesk::Boolean doSubents)
{
AssertWriteEnabled();
return AcDbEntity::setTransparency(trans, doSubents);
}
CString AecDbEntityBase::getUniqueName() const
{
return _T("");
}
typedef AcArray<AcDbEntity*> AcDbEntityArray;
void AecDbEntityBase::PreprocessForHlr(const AcGePoint3d &ptPlnO
, const AcGeVector3d &vtPlnN
, AcDbEntityArray &ar) const
{
assertReadEnabled();
return;
}
void AecDbEntityBase::ProcessHlrResult(const AcDbEntityArray &ar
, const std::map<AcDbEntity*, AcDbEntityArray> &preAr
, AcDbEntityArray &output) const
{
assertReadEnabled();
AcDbObjectId idLy(layerId()), idLt(linetypeId());
int clr(colorIndex());
const AecDbObjXDataMap *pXData = GetSpecialtyData();
for (int i(0); i < ar.length(); ++i)
{
AcDbEntity *pEnt((AcDbEntity*)ar[i]->clone());
if (pEnt)
{
if (pXData)
pXData->Write(pEnt, BIMDATA_APP);
pEnt->setLayer(idLy);
pEnt->setLinetype(idLt);
pEnt->setColorIndex(clr);
output.append(pEnt);
}
}
}