修复 GiDrawUtility 参数校验与规范问题 B7、B9、S1、S3

- B7: DrawPipe(pCurve, dR) 检查 getStartPoint 返回值,避免未定义点传给 getFirstDeriv。
- B9: 补充参数校验:
  DrawDish 大直径为 0 时 2*dH/dD 除零;
  DrawCirTorus / DrawRectTorus 小半径不小于大半径时截面半径为负(RectTorus 另校验高度);
  DrawPipe(ptFrom, ptTo, ...) 零长度路径无法扫掠;
  DrawPipe(pCurve, dR) 半径非正。
- S1: spliteCurve、deleteContainerOfArx 由文件级 static 移入已有的匿名 namespace。
- S3: DELETE_PTR 宏用 do { } while (0) 包裹,避免与 if/else 搭配时悬垂 else。
This commit is contained in:
gjm committed 2026-10-25 19:02:38 +08:00
1 parent 01b21dfa0d
commit abc97f838d
3 files changed
+89 -68

No files matched your search

+75 -60
View File
@@ -154,6 +154,65 @@ namespace
p->makeClosed();
return p;
}
// 分段长度大于max取max,小于max,取min
int spliteCurve(const AcDbCurve *pCurve, const double &max, const double &min, AcDbVoidPtrArray &ar)
{
Acad::ErrorStatus es;
double dEnd = 0.0, dLen = 0.0, dSplitLen = 100000.0;
es = pCurve->getEndParam(dEnd);
if (es != Acad::eOk) return 0;
es = pCurve->getDistAtParam(dEnd, dLen);
if (es != Acad::eOk) return 0;
if (dLen > max)
dSplitLen = max;
else
dSplitLen = min;
double dMax(dSplitLen), dPrec(10e-4);
AcGePoint3d ptStart(AcGePoint3d::kOrigin), ptEnd(AcGePoint3d::kOrigin), pt(AcGePoint3d::kOrigin);
es = pCurve->getPointAtDist(.0, ptStart);
if (es != Acad::eOk) return 0;
es = pCurve->getEndPoint(ptEnd);
if (es != Acad::eOk) return 0;
int quotient((int)(dLen / dMax));
double remainder(fmod(dLen, dMax));
if (remainder < dPrec) quotient -= 1;
AcGePoint3dArray arPts;
if (dLen - dMax > dPrec)
{
for (int i = 0; i < quotient; ++i)
{
if (pCurve->getPointAtDist((i + 1) * dMax, pt) != Acad::eOk) continue;
arPts.append(pt);
}
}
if (arPts.isEmpty()) return 0;
es = pCurve->getSplitCurves(arPts, ar);
return ar.length();
}
void deleteContainerOfArx(AcDbVoidPtrArray &ss)
{
while(!ss.isEmpty())
{
AcDbEntity *p = (AcDbEntity *)ss.last();
ss.removeLast();
delete p;
}
}
}
// 把region变换到以 vtNormal为法向,以ptOnPlan为中心的面上,并且, 将region上的点ptOnRegion与平面中心点ptOnPlan对齐
@@ -642,6 +701,10 @@ AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawCirTorus(const AcGePoint3d &ptCenter
, const double &startAngle
, const double &endAngle)
{
// 小半径须小于大半径,否则截面圆半径为负,ACIS 无法生成
if (DOWNEQUAL_ZERO(minorRadius) || DOWNEQUAL_ZERO(majorRadius - minorRadius))
return NULL;
AcDbArc arc(ptCenter, vtNormal, (majorRadius + minorRadius) * .5, startAngle, endAngle);
AcDbCircle cir(AcGePoint3d::kOrigin, AcGeVector3d::kZAxis, (majorRadius - minorRadius) * .5);
return DrawPipe(&arc, &cir, AcGePoint3d::kOrigin);
@@ -655,6 +718,10 @@ AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawRectTorus(const AcGePoint3d &ptCente
, const double &startAngle
, const double &endAngle)
{
// 小半径须小于大半径、高度须为正,否则截面宽度为负,ACIS 无法生成
if (DOWNEQUAL_ZERO(minorRadius) || DOWNEQUAL_ZERO(majorRadius - minorRadius) || DOWNEQUAL_ZERO(height))
return NULL;
AcDbArc arc(ptCenter, vtNormal, (majorRadius + minorRadius) * .5, startAngle, endAngle);
double dW = (majorRadius - minorRadius) * .5;
@@ -679,6 +746,9 @@ AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawDish(const double &dH /*小半径*/
, const AcGePoint3d &axisPnt
, const AcGeVector3d &axisDir)
{
// 大直径为 0 时椭圆率 2*dH/dD 无意义
if (DOWNEQUAL_ZERO(dD)) return NULL;
// 先构造一个(zox)面, 圆心为原点的1/4椭圆, 然后绕Z轴旋转
// 再转换到 axisPnt点,其中心轴(原Z轴)指向axisDir
AcDbEllipse elArc(AcGePoint3d::kOrigin
@@ -719,6 +789,9 @@ AcDbEntity* GiDrawUtility::DrawPipe(const AcGePoint3d& ptFrom
, const double &dThick
, const int &nSegs /*= 20*/)
{
// 零长度路径无法扫掠
if (EQUAL_ZERO(ptFrom.distanceTo(ptTo))) return NULL;
AcDbCircle Cir1(AcGePoint3d::kOrigin, AcGeVector3d::kZAxis, dRadius);
AcDbRegion *pBig = createRegion(&Cir1);
@@ -769,65 +842,6 @@ AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawPipe(const AcDbCurve* pCurve
return pSolid;
}
// 分段长度大于max取max,小于max,取min
static int spliteCurve(const AcDbCurve *pCurve, const double &max, const double &min, AcDbVoidPtrArray &ar)
{
Acad::ErrorStatus es;
double dEnd = 0.0, dLen = 0.0, dSplitLen = 100000.0;
es = pCurve->getEndParam(dEnd);
if (es != Acad::eOk) return 0;
es = pCurve->getDistAtParam(dEnd, dLen);
if (es != Acad::eOk) return 0;
if (dLen > max)
dSplitLen = max;
else
dSplitLen = min;
double dMax(dSplitLen), dPrec(10e-4);
AcGePoint3d ptStart(AcGePoint3d::kOrigin), ptEnd(AcGePoint3d::kOrigin), pt(AcGePoint3d::kOrigin);
es = pCurve->getPointAtDist(.0, ptStart);
if (es != Acad::eOk) return 0;
es = pCurve->getEndPoint(ptEnd);
if (es != Acad::eOk) return 0;
int quotient((int)(dLen / dMax));
double remainder(fmod(dLen, dMax));
if (remainder < dPrec) quotient -= 1;
AcGePoint3dArray arPts;
if (dLen - dMax > dPrec)
{
for (int i = 0; i < quotient; ++i)
{
if (pCurve->getPointAtDist((i + 1) * dMax, pt) != Acad::eOk) continue;
arPts.append(pt);
}
}
if (arPts.isEmpty()) return 0;
es = pCurve->getSplitCurves(arPts, ar);
return ar.length();
}
static void deleteContainerOfArx(AcDbVoidPtrArray &ss)
{
while(!ss.isEmpty())
{
AcDbEntity *p = (AcDbEntity *)ss.last();
ss.removeLast();
delete p;
}
}
AcDbEntity* GiDrawUtility::DrawPipe(const AcDbCurve* pCurve
, const AcDbPolyline* pPoly
, const AcGePoint3d& ptCenInRgn)
@@ -838,11 +852,12 @@ AcDbEntity* GiDrawUtility::DrawPipe(const AcDbCurve* pCurve
AcDbEntity* GiDrawUtility::DrawPipe(const AcDbCurve *pCurve, double dR)
{
if (!pCurve) return NULL;
if (DOWNEQUAL_ZERO(dR)) return NULL;
//开始切向量,向内
AcGePoint3d ptS;
AcGeVector3d vtS;
pCurve->getStartPoint(ptS);
if (Acad::eOk != pCurve->getStartPoint(ptS)) return NULL;
if (Acad::eOk != pCurve->getFirstDeriv(ptS, vtS)) return NULL;
AcDbCircle cir;
+7 -4
View File
@@ -4,11 +4,14 @@
#include <algorithm>
#define DELETE_PTR(ptr)\
if (ptr)\
do\
{\
delete ptr;\
ptr = NULL;\
}
if (ptr)\
{\
delete ptr;\
ptr = NULL;\
}\
} while (0)
template <class K>
class TDPtrList
@@ -4,11 +4,14 @@
#include <algorithm>
#define DELETE_PTR(ptr)\
if (ptr)\
do\
{\
delete ptr;\
ptr = NULL;\
}
if (ptr)\
{\
delete ptr;\
ptr = NULL;\
}\
} while (0)
template <class K>
class TDPtrList