Files
envi-code/SourceCode/Code2026/AecRxBase/AecDbCurveBase.cpp
T
company-desktop 7038a98441 diag: 用 PDB 解析栈帧,定位到 AecDbEwPipeBase::copyFrom 里的多余序列化
上一版只给了"模块+RVA"的栈,我据此先后推断成
AecDbCurveBase::subGetTransformedCopy 和 AecDbEntityCommon::base_DeepClone,两者都是错的
(用户在那里下断点不命中;新加的 PerfTraceMark 打点也没有触发)。本次用符号解析定死。

本次改动:
- 新增 inc/PerfTraceMark.h:inline 的"某函数被调用过"打点,Debug 且 AEC_WRITEBACK_TRACE=1
  才生效。AecRxBase.arx 不链接 CoreLibrary(静态库只被 CoreCommand 链接),拿不到 SectionPerf,
  所以做成 header-only。
- 在 5 个候选入口打点:AecDbCurveBase::subGetTransformedCopy / subDeepClone、
  AecDbEntityBase::subDeepClone、AecDbEntityCommon::base_DeepClone、CKTCadUtility::CloneObject。
  跑一次开图,5 个都没触发 —— 这些候选被排除。
- 新增 tools/resolve_rva.ps1:用 dbghelp 的 SymLoadModuleEx / SymFromAddr 配本地 PDB,
  把"模块+RVA"解析成函数名。Windows 没有自带 symbolizer,这个脚本很轻,可反复用。

解析结果(CoreCommand.arx):
  0x58f051  AecDbEwPipeBase::copyFrom+0x41
  0x7e1300  AecDbZLineStair::DrawGuarBar3d+0x2c0
  0x7e09d0  AecDbZLineStair::DrawSteep3d+0xbe0
  0x7ddcef  AecDbZLineStair::Draw3d+0x34f

真实成因:Z 型楼梯画护栏(DrawGuarBar3d)时 copyFrom 一份管道实体,
而 AecDbEwPipeBase::copyFrom 用通用的 CopyObject(inc/AecDbEntityCommon.h:331)
做"整实体 dwgOutFields/dwgInFields 往返"来拷字段,于是截面被写成临时 SAT 文件再读回来。

而且这次序列化是多余的:copyFrom 随后把所有字段又用内存级方式拷了一遍
(曲线 clone/copyFrom、截面 clone/copyFrom、XData CopyFrom、m_arUserInfs append、
标志位/图层/线型/Breaks 逐项赋值),WriteUserInterface 写的也只是 m_arUserInfs。
所以最小修改是把那句 CopyObject 去掉,并补上源为 NULL 时清空目标的分支
(目前这个"清空"是 CopyObject 顺带完成的)。

本次只做定位与记录(分析写进 pipe-section-region-performance-plan.md 并纠正了上一版的误判),
不改 copyFrom 的行为——它影响所有管系实体的复制粘贴/块内拷贝,需要单独验证。
2026-10-28 21:28:00 +08:00

1208 lines
28 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "stdafx.h"
#include <sstream>
#include "AecDbCurveBase.h"
#include "PerfTraceMark.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"
extern CString IDCreate();
ACRX_NO_CONS_DEFINE_MEMBERS(AecDbCurveBase, AcDbCurve);
AecDbCurveBase::AecDbCurveBase(void) : AecDbEntityCommon()
{
}
AecDbCurveBase::~AecDbCurveBase(void) { }
Adesk::UInt32 AecDbCurveBase::subViewportDrawLogicalFlags(AcGiViewportDraw * vd)
{
// 基类实现是 protected,只能在这里取;后续计算交给 Common。
return AecDbEntityCommon::base_ViewportDrawLogicalFlags(
AcDbCurve::subViewportDrawLogicalFlags(vd));
}
Adesk::UInt32 AecDbCurveBase::subSetAttributes(AcGiDrawableTraits * traits)
{
// 基类实现是 protected,只能在这里取;后续计算交给 Common。
return AecDbEntityCommon::base_SetAttributes(
AcDbCurve::subSetAttributes(traits));
}
Adesk::Boolean AecDbCurveBase::subWorldDraw(AcGiWorldDraw *pWd)
{
// 具体实现与另一条根共用 AecDbEntityCommon::base_WorldDraw,
// 这里只保留 AcGiDrawable 虚函数这一侧的入口。
return AecDbEntityCommon::base_WorldDraw(pWd);
}
void AecDbCurveBase::subViewportDraw(AcGiViewportDraw* pMode)
{
// 具体实现与另一条根共用 AecDbEntityCommon::base_ViewportDraw,
// 这里只保留 AcGiDrawable 虚函数这一侧的入口。
AecDbEntityCommon::base_ViewportDraw(pMode);
}
//保存代理实体图元
void AecDbCurveBase::saveAs(AcGiWorldDraw *pWd,AcDb::SaveType saveType)
{
// 具体实现与另一条根共用 AecDbEntityCommon::base_SaveAs,
// 这里只保留 AcGiDrawable 虚函数这一侧的入口。
AecDbEntityCommon::base_SaveAs(pWd, saveType);
}
Adesk::Boolean AecDbCurveBase::CallWorldDraw(AcGiWorldDraw *pWd)
{
// 虚拟调用,回到最派生类的 subWorldDraw
return subWorldDraw(pWd);
}
Acad::ErrorStatus AecDbCurveBase::subExplode(AcDbVoidPtrArray& entitySet) const
{
// 具体实现与另一条根共用 AecDbEntityCommon::base_Explode,
// 这里只保留虚函数这一侧的入口。
return AecDbEntityCommon::base_Explode(entitySet);
}
Acad::ErrorStatus AecDbCurveBase::subGetGeomExtents(AcDbExtents& extents) const
{
// 具体实现与另一条根共用 AecDbEntityCommon::base_GetGeomExtents,
// 这里只保留 AcDbEntity 虚函数这一侧的入口。
return AecDbEntityCommon::base_GetGeomExtents(extents);
}
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
{
return AecDbEntityCommon::base_GetOsnapPoints(osnapMode, gsSelectionMark, ptPick,
lastPoint, viewXform, snapPoints, geomIds);
}
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
{
PerfTraceMark("AecDbCurveBase::subGetTransformedCopy");
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
{
PerfTraceMark("AecDbCurveBase::subDeepClone");
// 具体实现与 AecDbEntityBase 共用 AecDbEntityCommon::base_DeepClone,
// 这里只保留 AcDbObject 虚函数这一侧的入口。
return AecDbEntityCommon::base_DeepClone(pOwner, pClonedObject, idMap, isPrimary);
}
Acad::ErrorStatus AecDbCurveBase::subWblockClone(AcRxObject* pOwner,
AcDbObject*& pClonedObject,
AcDbIdMapping& idMap,
Adesk::Boolean isPrimary) const
{
return AecDbEntityCommon::base_WblockClone(pOwner, pClonedObject, idMap, isPrimary);
}
Acad::ErrorStatus AecDbCurveBase::CallAcDbWblockClone(AcRxObject* pOwner,
AcDbObject*& pClonedObject,
AcDbIdMapping& idMap,
Adesk::Boolean isPrimary) const
{
return AcDbCurve::subWblockClone(pOwner, pClonedObject, idMap, isPrimary);
}
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);
}
deleteArrayVoidPtrs<AcDbEntity>(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);
}
deleteArrayVoidPtrs<AcDbEntity>(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);
}
deleteArrayVoidPtrs<AcDbEntity>(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);
}
deleteArrayVoidPtrs<AcDbEntity>(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;
}
}
}
}
deleteArrayVoidPtrs<AcDbEntity>(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;
}
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 ()) ;
}
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;
}
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;
}
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);
}
typedef AcArray<AcDbEntity*> AcDbEntityArray;
Acad::ErrorStatus AecDbCurveBase::setTransparency(const AcCmTransparency &trans, Adesk::Boolean doSubents)
{
AssertWriteEnabled();
return AcDbEntity::setTransparency(trans, doSubents);
}