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

3250 lines
72 KiB
C++

#include "stdafx.h"
#include <sstream>
#include "AecDbCurveBase.h"
#include "AcGiViewDraw.h"
#include "AcGiExplodeDraw.h"
#include "simpleproperty.h"
#include "dbobjptr.h"
#include "AecDbObjXDataMap.h"
#include "AecDbEntityBase.h"
#include "dbgrip.h"
#include "AecGripCback.h"
#include "GrPolyhedronGeometry.h"
using namespace GrPolyhedronGeometry;
static const Adesk::UInt16 kRed = 1;
BOOL ReadModelXData(LPCTSTR pszKey, AecDbObjXDataMap& xDataMap, AcDbDatabase* pDb);
BOOL WriteModelXData(LPCTSTR pszKey, AecDbObjXDataMap& xDataMap, AcDbDatabase* pDb);
extern CString IDCreate();
const Adesk::UInt16 kColorByLayer = 256;
#ifndef _ttof
#define _ttof(pszVal) _tcstod((pszVal), NULL)
#endif
ACRX_NO_CONS_DEFINE_MEMBERS(AecDbCurveBase, AcDbCurve);
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();
}
}
}
AecDbCurveBase::AecDbCurveBase(void)
{
m_eExplodeOrDrawType = kWroldDraw;
m_nDrawDimCur = -1;
}
AecDbCurveBase::~AecDbCurveBase(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 AecDbCurveBase::subViewportDrawLogicalFlags(AcGiViewportDraw * vd)
{
Adesk::UInt32 nRet = AcDbCurve::subViewportDrawLogicalFlags(vd);
Adesk::UInt32 nFlagNew = nRet;
int nDrawMode = GetDrawMode();
DrawModeType nDrawType = k2Dand3D;
int nDraw = GetDrawDimOnType(nDrawMode, nDrawType);
if (nDraw != 3)
{
nFlagNew |= AcGiDrawable::kDrawableViewIndependentViewportDraw;
}
else
{
nFlagNew |= kDrawableRegenDraw;//256
}
return nFlagNew;
}
Adesk::UInt32 AecDbCurveBase::subSetAttributes(AcGiDrawableTraits * traits)
{
Adesk::UInt32 nRet = AcDbCurve::subSetAttributes(traits);
int nDrawMode = GetDrawMode();
DrawModeType nDrawType = k2Dand3D;
int nDraw = GetDrawDimOnType(nDrawMode, nDrawType);
Adesk::UInt32 nFlagNew = nRet;
nFlagNew |= AcGiDrawable::kDrawableViewIndependentViewportDraw;
return nFlagNew;
}
Adesk::Boolean AecDbCurveBase::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 nDrawMode = GetDrawMode();
DrawModeType nDrawType = k2Dand3D;
int nDraw = GetDrawDimOnType(nDrawMode, nDrawType);
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 AecDbCurveBase::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 = GetDrawMode();
DrawModeType nDrawType = k2Dand3D;
int nDraw = GetDrawDimOnType(nDrawMode, nDrawType);
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 AecDbCurveBase::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
{
AcDbCurve::saveAs(pWd, saveType);
}
}
Acad::ErrorStatus AecDbCurveBase::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 AecDbCurveBase::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 AecDbCurveBase::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 AecDbCurveBase::subList() const
{
AcDbCurve::subList();
}
Acad::ErrorStatus AecDbCurveBase::setColorIndex(Adesk::UInt16 color,Adesk::Boolean doSubents/* = true*/)
{
assertWriteEnabled();
AecDbObjXDataMap* pMap = GetSpecialtyData();
if (pMap != NULL)
{
int nCr = 0;
if (pMap->GetAt(_T("COLOR"),nCr))
{
pMap->SetAt(_T("COLOR"),color);
}
}
return AcDbCurve::setColorIndex(color,doSubents);
}
Acad::ErrorStatus AecDbCurveBase::subIntersectWith(const AcDbEntity* ent,
AcDb::Intersect intType,
AcGePoint3dArray& points,
INT_PTR thisGsMarker,
INT_PTR otherGsMarker) const
{
assertReadEnabled();
Acad::ErrorStatus es;
AcDbCurve* pNaCrv = GetNativeCurve();
if (pNaCrv != NULL)
{
//放开后很慢
es = pNaCrv->intersectWith(ent,intType,points,thisGsMarker,otherGsMarker);
}
//EXTEND 仅仅需要 m_pBaseCurve 求交
struct resbuf rb;
acedGetVar(_T("CMDNAMES"),&rb);
if (_tcscmp(rb.resval.rstring,_T("EXTEND")) != 0)
{
int expMode = GetExplodeMode();
if (expMode == 2)
{
return Acad::eNotImplementedYet;
}
const AcDbVoidPtrArray& entSet = Get2DBuffer();
es = Acad::eNotApplicable;
int len = entSet.length();
for(int i = 0; i < len; i++)
{
AcDbEntity *pEnt = (AcDbEntity *)entSet[i];
if (pEnt != NULL && Acad::eOk == pEnt->intersectWith(ent, intType, points, 0, otherGsMarker) )
{
es = Acad::eOk;
}
}
}
return es;
}
Acad::ErrorStatus AecDbCurveBase::subIntersectWith(const AcDbEntity* ent,
AcDb::Intersect intType,
const AcGePlane& projPlane,
AcGePoint3dArray& points,
INT_PTR thisGsMarker,
INT_PTR otherGsMarker) const
{
assertReadEnabled();
Acad::ErrorStatus es;
AcDbCurve* pNaCrv = GetNativeCurve();
if (pNaCrv != NULL)
{
//放开后很慢
es = pNaCrv->intersectWith(ent,intType,points,thisGsMarker,otherGsMarker);
}
int expMode = GetExplodeMode();
if (expMode == 2)
{
return Acad::eNotImplementedYet;
}
//EXTEND 仅仅需要 m_pBaseCurve 求交
struct resbuf rb;
acedGetVar(_T("CMDNAMES"),&rb);
if (_tcscmp(rb.resval.rstring,_T("EXTEND")) != 0)
{
const AcDbVoidPtrArray& entSet = Get2DBuffer();
es = Acad::eNotApplicable;
int len = entSet.length();
for (int i = 0; i < len; i++)
{
AcDbEntity *pEnt = (AcDbEntity *)entSet[i];
if (pEnt != NULL && Acad::eOk == pEnt->intersectWith(ent, intType, projPlane, points, 0, otherGsMarker) )
{
es = Acad::eOk;
}
}
}
return es;
}
Acad::ErrorStatus AecDbCurveBase::subSetPropertiesFrom( const AcDbEntity* pEntity, Adesk::Boolean doSubents/* = Adesk::kTrue*/)
{
assertWriteEnabled();
Acad::ErrorStatus es = AcDbCurve::setPropertiesFrom(pEntity, doSubents);
// 颜色
{
setColorIndex(pEntity->colorIndex());
}
//图层
if (database() == NULL ||
database() == pEntity->database())
{
{
setLayer(layerId());
}
// 线型
{
setLinetype(pEntity->linetypeId());
}
#if ARX > 16
// 材质
{
setMaterial(pEntity->materialId());
}
#endif
}
// 线型比例
{
setLinetypeScale(pEntity->linetypeScale());
}
// 可见性. 总是被复制
setVisibility(pEntity->visibility());
return es;
}
#if (ARX > 15)
Acad::ErrorStatus AecDbCurveBase::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 es;
}
Acad::ErrorStatus AecDbCurveBase::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 AecDbCurveBase::subGripStatus(const AcDb::GripStat status)
{
}
Acad::ErrorStatus AecDbCurveBase::subGetGripPoints ( AcDbGripDataPtrArray& grips,
const double curViewUnitSize,
const int gripSize,
const AcGeVector3d& curViewDir,
const int bitflags) const
{
return Acad::eOk;
}
Acad::ErrorStatus AecDbCurveBase::subMoveGripPointsAt(const AcDbVoidPtrArray& appData,const AcGeVector3d& offset,const int bitflags)
{
return Acad::eOk;
}
#endif
Acad::ErrorStatus AecDbCurveBase::subGetGripPoints (AcGePoint3dArray& gripPoints,AcDbIntArray& osnapModes,AcDbIntArray& geomIds) const
{
assertReadEnabled();
return Acad::eOk;
}
Acad::ErrorStatus AecDbCurveBase::subMoveGripPointsAt(const AcDbIntArray& indices,const AcGeVector3d& offset)
{
assertWriteEnabled();
return Acad::eOk;
}
Acad::ErrorStatus AecDbCurveBase::subGetStretchPoints(AcGePoint3dArray& stretchPoints) const
{
assertReadEnabled();
return Acad::eOk;
}
Acad::ErrorStatus AecDbCurveBase::subMoveStretchPointsAt(const AcDbIntArray& indices,const AcGeVector3d& offset)
{
assertWriteEnabled();
return Acad::eOk;
}
Acad::ErrorStatus AecDbCurveBase::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
return Acad::eOk;
}
Acad::ErrorStatus AecDbCurveBase::subGetTransformedCopy(const AcGeMatrix3d& xform,AcDbEntity*& pEnt) const
{
assertReadEnabled();
AcDbEntity *pCloned = (AcDbEntity *)clone();
pCloned->setLayer(layerId());//
((AecDbCurveBase*)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 AecDbCurveBase::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
//
AecDbCurveBase *pClone = (AecDbCurveBase*)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 AecDbCurveBase::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 AcDbCurve::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
//
AecDbCurveBase *pClone = (AecDbCurveBase*)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;
}
Adesk::Boolean AecDbCurveBase::isClosed() const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Adesk::Boolean bRet = pCurve->isClosed();
return bRet;
}
else
{
return AcDbCurve::isClosed();
}
}
Adesk::Boolean AecDbCurveBase::isPeriodic() const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Adesk::Boolean bRet = pCurve->isPeriodic();
return bRet;
}
else
{
return AcDbCurve::isPeriodic();
}
}
Acad::ErrorStatus AecDbCurveBase::getStartParam(double&pa) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getStartParam(pa);
return bRet;
}
else
{
return AcDbCurve::getStartParam(pa);
}
}
Acad::ErrorStatus AecDbCurveBase::getEndParam (double&pa) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getEndParam(pa);
return bRet;
}
else
{
return AcDbCurve::getEndParam(pa);
}
}
Acad::ErrorStatus AecDbCurveBase::getStartPoint(AcGePoint3d&pt) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getStartPoint(pt);
return bRet;
}
else
{
return AcDbCurve::getStartPoint(pt);
}
}
Acad::ErrorStatus AecDbCurveBase::getEndPoint (AcGePoint3d&pt) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getEndPoint(pt);
return bRet;
}
else
{
return AcDbCurve::getEndPoint(pt);
}
}
Acad::ErrorStatus AecDbCurveBase::getPointAtParam(double pa, AcGePoint3d&pt) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getPointAtParam(pa,pt);
return bRet;
}
else
{
return AcDbCurve::getPointAtParam(pa,pt);
}
}
Acad::ErrorStatus AecDbCurveBase::getParamAtPoint(const AcGePoint3d& pt, double&pa)const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getParamAtPoint(pt,pa);
return bRet;
}
else
{
return AcDbCurve::getParamAtPoint(pt,pa);
}
}
Acad::ErrorStatus AecDbCurveBase::getDistAtParam (double param, double& dist) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getDistAtParam(param,dist);
return bRet;
}
else
{
return AcDbCurve::getDistAtParam(param,dist);
}
}
Acad::ErrorStatus AecDbCurveBase::getParamAtDist (double dist, double& param) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getParamAtDist(dist,param);
return bRet;
}
else
{
return AcDbCurve::getParamAtDist(dist,param);
}
}
Acad::ErrorStatus AecDbCurveBase::getDistAtPoint (const AcGePoint3d&pt, double&dist)const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getDistAtPoint(pt,dist);
return bRet;
}
else
{
return AcDbCurve::getDistAtPoint(pt,dist);
}
}
Acad::ErrorStatus AecDbCurveBase::getPointAtDist (double dist, AcGePoint3d&pt) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getPointAtDist(dist,pt);
return bRet;
}
else
{
return AcDbCurve::getPointAtDist(dist,pt);
}
}
Acad::ErrorStatus AecDbCurveBase::getFirstDeriv (double param,AcGeVector3d& firstDeriv) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getFirstDeriv(param,firstDeriv);
return bRet;
}
else
{
return AcDbCurve::getFirstDeriv(param,firstDeriv);
}
}
Acad::ErrorStatus AecDbCurveBase::getFirstDeriv (const AcGePoint3d&pt,AcGeVector3d& firstDeriv) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getFirstDeriv(pt,firstDeriv);
return bRet;
}
else
{
return AcDbCurve::getFirstDeriv(pt,firstDeriv);
}
}
Acad::ErrorStatus AecDbCurveBase::getSecondDeriv (double param,AcGeVector3d& secDeriv) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getSecondDeriv(param,secDeriv);
return bRet;
}
else
{
return AcDbCurve::getSecondDeriv(param,secDeriv);
}
}
Acad::ErrorStatus AecDbCurveBase::getSecondDeriv (const AcGePoint3d&pt,AcGeVector3d& secDeriv) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getSecondDeriv(pt,secDeriv);
return bRet;
}
else
{
return AcDbCurve::getSecondDeriv(pt,secDeriv);
}
}
Acad::ErrorStatus AecDbCurveBase::getClosestPointTo(const AcGePoint3d& givenPnt,
AcGePoint3d& pointOnCurve,
Adesk::Boolean extend) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getClosestPointTo(givenPnt,pointOnCurve,extend);
return bRet;
}
else
{
return AcDbCurve::getClosestPointTo(givenPnt,pointOnCurve,extend);
}
}
Acad::ErrorStatus AecDbCurveBase::getClosestPointTo(const AcGePoint3d& givenPnt,
const AcGeVector3d& direction,
AcGePoint3d& pointOnCurve,
Adesk::Boolean extend) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getClosestPointTo(givenPnt,direction,pointOnCurve,extend);
return bRet;
}
else
{
return AcDbCurve::getClosestPointTo(givenPnt,direction,pointOnCurve,extend);
}
}
Acad::ErrorStatus AecDbCurveBase::getOrthoProjectedCurve(const AcGePlane& plane,
AcDbCurve*& projCrv) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
AcDbCurve* pCurve1 = NULL;
Acad::ErrorStatus bRet = pCurve->getOrthoProjectedCurve(plane,pCurve1);
if (bRet == Acad::eOk)
{
AecDbCurveBase* pCurveEnt = (AecDbCurveBase*)clone();
bRet = pCurveEnt->SetBaseCurve(pCurve1);
projCrv = pCurveEnt;
DELETE_PTR(pCurve1);
}
return bRet;
}
else
{
return AcDbCurve::getOrthoProjectedCurve(plane,projCrv);
}
}
Acad::ErrorStatus AecDbCurveBase::getProjectedCurve(const AcGePlane& plane,
const AcGeVector3d& projDir,
AcDbCurve*& projCrv) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
AcDbCurve* pCurve1 = NULL;
Acad::ErrorStatus bRet = pCurve->getProjectedCurve(plane,projDir,pCurve1);
if (bRet == Acad::eOk)
{
AecDbCurveBase* pCurveEnt = (AecDbCurveBase*)clone();
bRet = pCurveEnt->SetBaseCurve(pCurve1);
projCrv = pCurveEnt;
DELETE_PTR(pCurve1);
}
return bRet;
}
else
{
return AcDbCurve::getProjectedCurve(plane,projDir,projCrv);
}
}
Acad::ErrorStatus AecDbCurveBase::getOffsetCurves(double offsetDist,
AcDbVoidPtrArray& offsetCurves) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
AcDbVoidPtrArray offsetCurves0;
Acad::ErrorStatus bRet = pCurve->getOffsetCurves(offsetDist,offsetCurves0);
if (bRet == Acad::eOk)
{
for (long i = 0; i < offsetCurves0.length(); i++)
{
AecDbCurveBase*pCurveEnt = (AecDbCurveBase*)clone();
pCurveEnt->SetBaseCurve((AcDbCurve*)offsetCurves0[i]);
offsetCurves.append(pCurveEnt);
}
ReleaseEntSet(offsetCurves0);
}
return bRet;
}
else
{
return AcDbCurve::getOffsetCurves(offsetDist,offsetCurves);
}
}
Acad::ErrorStatus AecDbCurveBase::getOffsetCurvesGivenPlaneNormal(
const AcGeVector3d& normal,
double offsetDist,
AcDbVoidPtrArray& offsetCurves) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
AcDbVoidPtrArray offsetCurves0;
Acad::ErrorStatus bRet = pCurve->getOffsetCurvesGivenPlaneNormal(normal,offsetDist,offsetCurves0);
if (bRet == Acad::eOk)
{
for (long i = 0; i < offsetCurves0.length(); i++)
{
AecDbCurveBase*pCurveEnt = (AecDbCurveBase*)clone();
pCurveEnt->SetBaseCurve((AcDbCurve*)offsetCurves0[i]);
offsetCurves.append(pCurveEnt);
}
ReleaseEntSet(offsetCurves0);
}
return bRet;
}
else
return AcDbCurve::getOffsetCurvesGivenPlaneNormal(normal,offsetDist,offsetCurves);
}
Acad::ErrorStatus AecDbCurveBase::getSpline(AcDbSpline*& spline) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getSpline(spline);
return bRet;
}
else
{
return AcDbCurve::getSpline(spline);
}
}
Acad::ErrorStatus AecDbCurveBase::getSplitCurves (const AcGeDoubleArray& params,
AcDbVoidPtrArray& curveSegments) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
AcDbVoidPtrArray curveSegments0;
Acad::ErrorStatus bRet = pCurve->getSplitCurves(params,curveSegments0);
if (bRet == Acad::eOk)
{
for (long i = 0; i < curveSegments0.length(); i++)
{
AecDbCurveBase*pCurveEnt = (AecDbCurveBase*)clone();
AecDbObjXDataMap* pXDataMap = pCurveEnt->GetSpecialtyData();
if (pXDataMap != NULL)
{
CString sNo;
if (pXDataMap->GetAt(KEY_NO,sNo))
{
sNo = IDCreate();
pXDataMap->SetAt(KEY_NO,sNo);
}
}
pCurveEnt->SetBaseCurve((AcDbCurve*)curveSegments0[i]);
curveSegments.append(pCurveEnt);
}
ReleaseEntSet(curveSegments0);
}
return bRet;
}
else
{
return AcDbCurve::getSplitCurves(params,curveSegments);
}
}
Acad::ErrorStatus AecDbCurveBase::getSplitCurves (const AcGePoint3dArray& points,
AcDbVoidPtrArray& curveSegments) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
AcDbVoidPtrArray curveSegments0;
Acad::ErrorStatus bRet = pCurve->getSplitCurves(points,curveSegments0);
if (bRet == Acad::eOk)
{
for (long i = 0; i < curveSegments0.length(); i++)
{
AecDbCurveBase*pCurveEnt = (AecDbCurveBase*)clone();
AecDbObjXDataMap* pXDataMap = pCurveEnt->GetSpecialtyData();
if (pXDataMap != NULL)
{
CString sNo;
if (pXDataMap->GetAt(KEY_NO,sNo))
{
sNo = IDCreate();
pXDataMap->SetAt(KEY_NO,sNo);
}
}
pCurveEnt->SetBaseCurve((AcDbCurve*)curveSegments0[i]);
curveSegments.append(pCurveEnt);
}
ReleaseEntSet(curveSegments0);
}
return bRet;
}
else
{
return AcDbCurve::getSplitCurves(points,curveSegments);
}
}
Acad::ErrorStatus AecDbCurveBase::extend(double newParam)
{
AssertWriteEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->extend(newParam);
if (bRet == Acad::eOk)
{
//bRet = SetBaseCurve(pCurve);
}
return bRet;
}
else
{
return AcDbCurve::extend(newParam);
}
}
static AcDbArc* FormatArc(const AcGePoint3d& ptGe1,const AcGePoint3d& ptGe2,const AcGePoint3d& ptGe3)
{
AcDbArc* pArcThis = NULL;
AcGeCircArc3d cirArc3d;
cirArc3d.set(ptGe1,ptGe2,ptGe3);//可能逆弧
AcGeVector3d vtNorm = cirArc3d.normal();
if (vtNorm.isParallelTo(AcGeVector3d::kZAxis))
{
if (!vtNorm.isCodirectionalTo(AcGeVector3d::kZAxis))
{
vtNorm.negate();//相反
}
}
AcDbCircle cir;
cir.setCenter(cirArc3d.center());
cir.setRadius(cirArc3d.radius());
cir.setNormal(vtNorm);
AcGePoint3dArray arPts;
arPts.append(ptGe1);
arPts.append(ptGe3);
AcDbVoidPtrArray arCurPtrs;
cir.getSplitCurves(arPts,arCurPtrs);
double dPara = 0.0;
AcDbCurve* pCurve = NULL;
for (int j = 0;j < arCurPtrs.length();j++)
{
pCurve = (AcDbCurve*)arCurPtrs.at(j);
if (pCurve != NULL)
{
if (Acad::eOk == pCurve->getParamAtPoint(ptGe2,dPara))//中点在圆弧上
{
AcDbArc* pArc = AcDbArc::cast(pCurve);
if (pArc != NULL)
{
pArcThis = pArc;
arCurPtrs.removeAt(j);
break;
}
}
}
}
FreeBuffer(0,arCurPtrs);
return pArcThis;
}
static AcGePoint3d GetArcMidPoint(AcDbArc* pArc)
{
double dSta = 0.0,dEnd = 0.0;
pArc->getStartParam(dSta);
pArc->getEndParam(dEnd);
AcGePoint3d ptMid;
pArc->getPointAtParam((dSta + dEnd) / 2.0,ptMid);
return ptMid;
}
Acad::ErrorStatus AecDbCurveBase::extend(Adesk::Boolean extendStart,
const AcGePoint3d& toPoint)
{
AssertWriteEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
AcGePoint3d ptS,ptE;
pCurve->getStartPoint(ptS);
pCurve->getEndPoint(ptE);
if (toPoint.distanceTo(ptS) < toPoint.distanceTo(ptE))
extendStart = Adesk::kTrue;
else
extendStart = Adesk::kFalse;
Acad::ErrorStatus bRet = pCurve->extend(extendStart,toPoint);
if (bRet == Acad::eOk)
{
//延长到外部一点
//GetNativeCurve
//bRet = SetBaseCurve(pCurve);
}
else
{
//内部,缩短到内部一点
AcDbLine* pLn = AcDbLine::cast(pCurve);
if (pLn != NULL)
{
if (extendStart)
{
pLn->setStartPoint(toPoint);
}
else
{
pLn->setEndPoint(toPoint);
}
bRet = Acad::eOk;
}
AcDbArc* pArc = AcDbArc::cast(pCurve);
if (pArc != NULL)
{
if (extendStart)//开始缩短
{
AcGePoint3d ptE,ptM;
pArc->getEndPoint(ptE);
ptM = GetArcMidPoint(pArc);
AcDbArc* pArc2 = FormatArc(toPoint,ptM,ptE);
if (pArc2 != NULL)
{
pArc->setStartAngle(pArc2->startAngle());
pArc->setEndAngle(pArc2->endAngle());
delete pArc2;
}
}
else//末尾缩短
{
AcGePoint3d ptE,ptM;
pArc->getStartPoint(ptE);
ptM = GetArcMidPoint(pArc);
AcDbArc* pArc2 = FormatArc(ptE,ptM,toPoint);
if (pArc2 != NULL)
{
pArc->setStartAngle(pArc2->startAngle());
pArc->setEndAngle(pArc2->endAngle());
delete pArc2;
}
}
bRet = Acad::eOk;
}
}
return bRet;
}
else
{
return AcDbCurve::extend(extendStart,toPoint);
}
}
Acad::ErrorStatus AecDbCurveBase::getArea(double&area) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getArea(area);
return bRet;
}
else
{
return AcDbCurve::getArea(area);
}
}
Adesk::Boolean AecDbCurveBase::isPlanar() const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Adesk::Boolean bRet = pCurve->isPlanar();
return bRet;
}
else
{
return AcDbCurve::isPlanar();
}
}
Acad::ErrorStatus AecDbCurveBase::getPlane(AcGePlane&plane, AcDb::Planarity&pr) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
Acad::ErrorStatus bRet = pCurve->getPlane(plane,pr);
return bRet;
}
else
{
return AcDbCurve::getPlane(plane,pr);
}
}
void AecDbCurveBase::getEcs(AcGeMatrix3d& retVal) const
{
assertReadEnabled();
AcDbCurve* pCurve = GetNativeCurve();
if (pCurve != NULL)
{
pCurve->getEcs(retVal);
}
else
{
AcDbCurve::getEcs(retVal);
}
}
Acad::ErrorStatus AecDbCurveBase::SetBaseCurve(const AcDbCurve* pDbCurve)
{
return Acad::eNotImplementedYet;
}
AcDbCurve* AecDbCurveBase::GetBaseCurve(bool bOrthoProjectToXY) const
{
return NULL;
}
AcDbCurve* AecDbCurveBase::GetNativeCurve() const
{
return NULL;
}
//AEC派生
int AecDbCurveBase::GetDrawMode()
{
int nDrawMode = 3;
//从命名字典中取,默认3
return nDrawMode;
}
void AecDbCurveBase::SetDrawMode(int nMode)
{
//写入命名字典
}
//某些实体只有2D
int AecDbCurveBase::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 AecDbCurveBase::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 AecDbCurveBase::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;
pEnt->setColorIndex(nColor);
// 存在清空
struct resbuf* pTmp = acutNewRb(AcDb::kDxfRegAppName);
pEnt->setXData(pTmp);
acutRelRb(pXData);
acutRelRb(pTmp);
}
}
}
}
return nColor;
}
int AecDbCurveBase::GetExplodeMode() const
{
int nDrawMode = GetDrawMode();
DrawModeType nDrawType = k2Dand3D;
int nDraw = GetDrawDimOnType(nDrawMode, nDrawType);
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 AecDbCurveBase::dwgInFields (AcDbDwgFiler* pFiler)
{
assertWriteEnabled () ;
//----- Read parent class information first.
Acad::ErrorStatus es = AcDbCurve::dwgInFields (pFiler) ;
if ( es != Acad::eOk )
return (es) ;
return (pFiler->filerStatus ()) ;
}
Acad::ErrorStatus AecDbCurveBase::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled () ;
//----- Save parent class information first.
Acad::ErrorStatus es = AcDbCurve::dwgOutFields (pFiler) ;
if ( es != Acad::eOk )
return (es) ;
return (pFiler->filerStatus ()) ;
}
Acad::ErrorStatus AecDbCurveBase::dxfInFields (AcDbDxfFiler* pFiler)
{
assertWriteEnabled () ;
//----- Read parent class information first.
Acad::ErrorStatus es = AcDbCurve::dxfInFields (pFiler) ;
if ( es != Acad::eOk )
return (es) ;
return (pFiler->filerStatus ()) ;
}
Acad::ErrorStatus AecDbCurveBase::dxfOutFields(AcDbDxfFiler* pFiler) const
{
assertReadEnabled () ;
//----- Save parent class information first.
Acad::ErrorStatus es = AcDbCurve::dxfOutFields (pFiler) ;
if ( es != Acad::eOk )
return (es) ;
return (pFiler->filerStatus ()) ;
}
Acad::ErrorStatus AecDbCurveBase::Draw2d(AcGiDraw &dc) const
{
return Acad::eOk;
}
Acad::ErrorStatus AecDbCurveBase::Draw3d(AcGiDraw &dc) const
{
return Acad::eOk;
}
void AecDbCurveBase::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 AecDbCurveBase::GetPositionGrip(int nIndex, AecGripData *&pGrip) const
{
return NULL;
}
extern double PixelToWcs(int nPixel);
bool AecDbCurveBase::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 AecDbCurveBase::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 AecDbCurveBase::Draw3DBuffers(AcGiDraw &dc)const
{
if (m_ar3DDrableBufPtrs_.isEmpty()) return false;
AcDbEntity *pEnt = NULL;
for (int i = 0; i < m_ar3DDrableBufPtrs_.length(); ++i)
{
pEnt = (AcDbEntity *)m_ar3DDrableBufPtrs_[i];
dc.DrawEntity(*pEnt);
}
return true;
}
bool AecDbCurveBase::Draw2DBuffers(AcGiDraw &dc)const
{
if (m_ar2DDrableBufPtrs_.isEmpty())
{
return false;
}
AcDbEntity *pEnt = NULL;
for (int i = 0; i < m_ar2DDrableBufPtrs_.length(); ++i)
{
pEnt = (AcDbEntity *)m_ar2DDrableBufPtrs_[i];
pEnt->setLayer(dc.GetLayerId());
pEnt->setColorIndex(colorIndex());
dc.DrawEntity(*pEnt);
}
return true;
}
const AcDbVoidPtrArray& AecDbCurveBase::Get3DBuffer() const
{
//剖切隐藏
BoolSubtractHide();
return m_ar3DDrableBufPtrs_;
}
const AcDbVoidPtrArray& AecDbCurveBase::Get2DBuffer() const
{
return m_ar2DDrableBufPtrs_;
}
bool AecDbCurveBase::Has3DBuffer() const
{
return !m_ar3DDrableBufPtrs_.isEmpty();
}
bool AecDbCurveBase::Has2DBuffer() const
{
return !m_ar2DDrableBufPtrs_.isEmpty();
}
void AecDbCurveBase::Add3DBuffer(AcDbEntity *pEnt) const
{
if (pEnt) m_ar3DDrableBufPtrs_.append(pEnt);
}
void AecDbCurveBase::Add3DBuffer(const AcDbVoidPtrArray &arr) const
{
m_ar3DDrableBufPtrs_.append(arr);
}
void AecDbCurveBase::Add2DBuffer(AcDbEntity *pEnt) const
{
if (pEnt) m_ar2DDrableBufPtrs_.append(pEnt);
}
void AecDbCurveBase::Add2DBuffer(const AcDbVoidPtrArray &arr) const
{
m_ar2DDrableBufPtrs_.append(arr);
}
bool AecDbCurveBase::IsIn2DBuffer(AcDbEntity* pEnt) const
{
assertReadEnabled();
if (-1 == m_ar2DDrableBufPtrs_.find(pEnt))
return false;
return true;
}
bool AecDbCurveBase::IsIn3DBuffer(AcDbEntity* pEnt) const
{
assertReadEnabled();
if (-1 == m_ar3DDrableBufPtrs_.find(pEnt))
return false;
return true;
}
void AecDbCurveBase::Clean3DBuffer() const
{
FreeBuffer(0, m_ar3DDrableBufPtrs_);
m_ar3DDrableBufPtrs_.removeAll();
}
void AecDbCurveBase::Clean2DBuffer() const
{
FreeBuffer(0, m_ar2DDrableBufPtrs_);
m_ar2DDrableBufPtrs_.removeAll();
}
void AecDbCurveBase::Clean3DBufferNoDel() const
{
m_ar3DDrableBufPtrs_.removeAll();
}
void AecDbCurveBase::Clean2DBufferNoDel() const
{
m_ar2DDrableBufPtrs_.removeAll();
}
int AecDbCurveBase::GetDrawDimCur() const
{
return m_nDrawDimCur;
}
//获取二维视图显示的图形
int AecDbCurveBase::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();
}
//获取三维显示图形
int AecDbCurveBase::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();
}
void AecDbCurveBase::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 AecDbCurveBase::GetBimInfoTip(CString& sInfoTip) const
{
return false;
}
bool AecDbCurveBase::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 AecDbCurveBase::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 AecDbCurveBase::SendUserData(struct resbuf *pRb)
{
return false;
}
Acad::ErrorStatus AecDbCurveBase::ReCreateDraw2d()
{
assertWriteEnabled();
Clean2DBuffer();
return Acad::eOk;
}
Acad::ErrorStatus AecDbCurveBase::ReCreateDraw3d()
{
assertWriteEnabled();
Clean3DBuffer();
return Acad::eOk;
}
int AecDbCurveBase::GetSectionDraw(const AcGePoint3d& ptFr,const AcGePoint3d& ptTo,const AcGeVector3d& vtViewDir,const AcGeVector3d& vtTo, AcDbVoidPtrArray& arRegionPtrs) const
{
return 0;
}
bool AecDbCurveBase::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("玻璃砖墙");
}
}
return true;
}
double AecDbCurveBase::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 AecDbCurveBase::ComparedTo(AecDbCurveBase* pCurOther) const
{
return -1;//不做比较
}
double AecDbCurveBase::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);
}
AcDbRegion* pReg = AcDbRegion::cast(pEnt);
if (pReg != NULL)
{
pReg->getArea(dArea);
dAreaAll += fabs(dArea);
}
}
return dAreaAll;
}
void AecDbCurveBase::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 AecDbCurveBase::Remove3DBoolSubtract()
{
assertWriteEnabled();
//清除3D,重建
Clean3DBuffer();
}
void AecDbCurveBase::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 AecDbCurveBase::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 AecDbCurveBase::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* AecDbCurveBase::GetBlackHole() const
{
return NULL;
}
void AecDbCurveBase::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 * AecDbCurveBase::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 AecDbCurveBase::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;
}
}
}
}
typedef AcArray<AcDbEntity*> AcDbEntityArray;
void AecDbCurveBase::PreprocessForHlr(const AcGePoint3d &ptPlnO
, const AcGeVector3d &vtPlnN
, AcArray<AcDbEntity *> &ar) const
{
assertReadEnabled();
return;
}
void AecDbCurveBase::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);
}
}
}
SHJson::WValue& AecDbCurveBase::ToJson(bool bExprotGeo) const
{
using namespace SHJson;
assertReadEnabled();
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 AecDbCurveBase::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 AecDbCurveBase::setTransparency(const AcCmTransparency &trans, Adesk::Boolean doSubents)
{
AssertWriteEnabled();
return AcDbEntity::setTransparency(trans, doSubents);
}
CString AecDbCurveBase::getUniqueName() const
{
return _T("");
}