Merge pull request '修复 GiDrawUtility 参数校验与规范问题 B7、B9、S1' (#67) from home-lenovo-legion-r9000/fix-gidrawutility-b7-b9-s1 into main

Reviewed-on: #67
Reviewed-by: gjm <littleoldpan@163.com>
This commit was merged in pull request #67.
This commit is contained in:
gjm committed 2026-10-25 19:08:16 +08:00
commit 3e6d7f4dec
1 file changed
+75 -60
+75 -60
View File
@@ -154,6 +154,65 @@ namespace
p->makeClosed(); p->makeClosed();
return p; 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对齐 // 把region变换到以 vtNormal为法向,以ptOnPlan为中心的面上,并且, 将region上的点ptOnRegion与平面中心点ptOnPlan对齐
@@ -642,6 +701,10 @@ AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawCirTorus(const AcGePoint3d &ptCenter
, const double &startAngle , const double &startAngle
, const double &endAngle) , const double &endAngle)
{ {
// 小半径须小于大半径,否则截面圆半径为负,ACIS 无法生成
if (DOWNEQUAL_ZERO(minorRadius) || DOWNEQUAL_ZERO(majorRadius - minorRadius))
return NULL;
AcDbArc arc(ptCenter, vtNormal, (majorRadius + minorRadius) * .5, startAngle, endAngle); AcDbArc arc(ptCenter, vtNormal, (majorRadius + minorRadius) * .5, startAngle, endAngle);
AcDbCircle cir(AcGePoint3d::kOrigin, AcGeVector3d::kZAxis, (majorRadius - minorRadius) * .5); AcDbCircle cir(AcGePoint3d::kOrigin, AcGeVector3d::kZAxis, (majorRadius - minorRadius) * .5);
return DrawPipe(&arc, &cir, AcGePoint3d::kOrigin); return DrawPipe(&arc, &cir, AcGePoint3d::kOrigin);
@@ -655,6 +718,10 @@ AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawRectTorus(const AcGePoint3d &ptCente
, const double &startAngle , const double &startAngle
, const double &endAngle) , 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); AcDbArc arc(ptCenter, vtNormal, (majorRadius + minorRadius) * .5, startAngle, endAngle);
double dW = (majorRadius - minorRadius) * .5; double dW = (majorRadius - minorRadius) * .5;
@@ -679,6 +746,9 @@ AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawDish(const double &dH /*小半径*/
, const AcGePoint3d &axisPnt , const AcGePoint3d &axisPnt
, const AcGeVector3d &axisDir) , const AcGeVector3d &axisDir)
{ {
// 大直径为 0 时椭圆率 2*dH/dD 无意义
if (DOWNEQUAL_ZERO(dD)) return NULL;
// 先构造一个(zox)面, 圆心为原点的1/4椭圆, 然后绕Z轴旋转 // 先构造一个(zox)面, 圆心为原点的1/4椭圆, 然后绕Z轴旋转
// 再转换到 axisPnt点,其中心轴(原Z轴)指向axisDir // 再转换到 axisPnt点,其中心轴(原Z轴)指向axisDir
AcDbEllipse elArc(AcGePoint3d::kOrigin AcDbEllipse elArc(AcGePoint3d::kOrigin
@@ -719,6 +789,9 @@ AcDbEntity* GiDrawUtility::DrawPipe(const AcGePoint3d& ptFrom
, const double &dThick , const double &dThick
, const int &nSegs /*= 20*/) , const int &nSegs /*= 20*/)
{ {
// 零长度路径无法扫掠
if (EQUAL_ZERO(ptFrom.distanceTo(ptTo))) return NULL;
AcDbCircle Cir1(AcGePoint3d::kOrigin, AcGeVector3d::kZAxis, dRadius); AcDbCircle Cir1(AcGePoint3d::kOrigin, AcGeVector3d::kZAxis, dRadius);
AcDbRegion *pBig = createRegion(&Cir1); AcDbRegion *pBig = createRegion(&Cir1);
@@ -769,65 +842,6 @@ AECDLLIMPEXP AcDbEntity* GiDrawUtility::DrawPipe(const AcDbCurve* pCurve
return pSolid; 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 AcDbEntity* GiDrawUtility::DrawPipe(const AcDbCurve* pCurve
, const AcDbPolyline* pPoly , const AcDbPolyline* pPoly
, const AcGePoint3d& ptCenInRgn) , const AcGePoint3d& ptCenInRgn)
@@ -838,11 +852,12 @@ AcDbEntity* GiDrawUtility::DrawPipe(const AcDbCurve* pCurve
AcDbEntity* GiDrawUtility::DrawPipe(const AcDbCurve *pCurve, double dR) AcDbEntity* GiDrawUtility::DrawPipe(const AcDbCurve *pCurve, double dR)
{ {
if (!pCurve) return NULL; if (!pCurve) return NULL;
if (DOWNEQUAL_ZERO(dR)) return NULL;
//开始切向量,向内 //开始切向量,向内
AcGePoint3d ptS; AcGePoint3d ptS;
AcGeVector3d vtS; AcGeVector3d vtS;
pCurve->getStartPoint(ptS); if (Acad::eOk != pCurve->getStartPoint(ptS)) return NULL;
if (Acad::eOk != pCurve->getFirstDeriv(ptS, vtS)) return NULL; if (Acad::eOk != pCurve->getFirstDeriv(ptS, vtS)) return NULL;
AcDbCircle cir; AcDbCircle cir;