在 OpenCASCADE 中创建自定义的 AIS_Ellipse 类,以下是完整的代码实现:

  1. 头文件 AIS_Ellipse.hxx

#ifndef _AIS_Ellipse_HeaderFile
#define _AIS_Ellipse_HeaderFile

#include <AIS_InteractiveObject.hxx>
#include <gp_Elips.hxx>
#include <Prs3d_LineAspect.hxx>

class Geom_Ellipse;

//! 自定义椭圆显示类,继承自 AIS_InteractiveObject
class AIS_Ellipse : public AIS_InteractiveObject
{
DEFINE_STANDARD_RTTI_INLINE(AIS_Ellipse, AIS_InteractiveObject)

public:
//! 构造函数:通过 gp_Elips
Standard_EXPORT AIS_Ellipse(const gp_Elips& theEllipse);

//! 构造函数:通过 Geom_Ellipse
Standard_EXPORT AIS_Ellipse(const Handle(Geom_Ellipse)& theEllipse);

//! 设置椭圆几何定义
Standard_EXPORT void SetEllipse(const gp_Elips& theEllipse);

//! 设置椭圆几何定义(通过句柄)
Standard_EXPORT void SetEllipse(const Handle(Geom_Ellipse)& theEllipse);

//! 获取椭圆几何定义
const gp_Elips& Ellipse() const { return myEllipse; }

//! 设置 U 参数范围
void SetUParam(const Standard_Real theUFirst, const Standard_Real theULast)
{
    myUFirst = theUFirst;
    myULast = theULast;
}

//! 设置是否填充椭圆
void SetFilled(const Standard_Boolean theIsFilled)
{
    myIsFilled = theIsFilled;
}

//! 获取是否填充
Standard_Boolean IsFilled() const { return myIsFilled; }

//! 设置线宽
void SetWidth(const Standard_Real theWidth) { myWidth = theWidth; }

//! 获取线宽
Standard_Real Width() const { return myWidth; }

protected:
//! 计算展示
Standard_EXPORT virtual void Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr,
const Handle(Prs3d_Presentation)& thePrs,
const Standard_Integer theMode) Standard_OVERRIDE;

//! 计算选择
Standard_EXPORT virtual void ComputeSelection(const Handle(SelectMgr_Selection)& theSelection,
                                              const Standard_Integer theMode) Standard_OVERRIDE;

//! 计算几何
Standard_EXPORT void ComputeGeom();

private:
gp_Elips myEllipse; // 椭圆几何定义
Handle(Geom_Ellipse) myGeomEllipse; // 几何椭圆

Standard_Real myUFirst;       // U参数起始值
Standard_Real myULast;        // U参数结束值
Standard_Real myWidth;        // 线宽
Standard_Boolean myIsFilled;  // 是否填充

Handle(Graphic3d_ArrayOfPolylines) myPrimitives; // 图形基元

};

#endif // _AIS_Ellipse_HeaderFile

  1. 实现文件 AIS_Ellipse.cxx

#include “AIS_Ellipse.hxx”

#include <ElCLib.hxx>
#include <Geom_Ellipse.hxx>
#include <Graphic3d_ArrayOfPolylines.hxx>
#include <Prs3d_LineAspect.hxx>
#include <Prs3d_ShadingAspect.hxx>
#include <Select3D_SensitiveCircle.hxx>
#include <StdPrs_ShadedShape.hxx>

// 构造函数:通过 gp_Elips
AIS_Ellipse::AIS_Ellipse(const gp_Elips& theEllipse)
: myEllipse(theEllipse),
myUFirst(0.0),
myULast(2 * M_PI),
myWidth(1.0),
myIsFilled(Standard_False)
{
// 设置显示模式
SetDisplayMode(0);
}

// 构造函数:通过 Geom_Ellipse
AIS_Ellipse::AIS_Ellipse(const Handle(Geom_Ellipse)& theEllipse)
: myEllipse(theEllipse->Elips()),
myGeomEllipse(theEllipse),
myUFirst(0.0),
myULast(2 * M_PI),
myWidth(1.0),
myIsFilled(Standard_False)
{
SetDisplayMode(0);
}

// 设置椭圆几何定义
void AIS_Ellipse::SetEllipse(const gp_Elips& theEllipse)
{
myEllipse = theEllipse;
myGeomEllipse.Nullify();
SetToUpdate();
}

// 设置椭圆几何定义(通过句柄)
void AIS_Ellipse::SetEllipse(const Handle(Geom_Ellipse)& theEllipse)
{
myEllipse = theEllipse->Elips();
myGeomEllipse = theEllipse;
SetToUpdate();
}

// 计算展示
void AIS_Ellipse::Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr,
const Handle(Prs3d_Presentation)& thePrs,
const Standard_Integer theMode)
{
if (theMode != 0) return;

// 设置线宽
Handle(Prs3d_LineAspect) aLineAspect = new Prs3d_LineAspect(Quantity_NOC_YELLOW, Aspect_TOL_SOLID, myWidth);
Handle(Prs3d_Drawer) aDrawer = new Prs3d_Drawer();
aDrawer->SetLineAspect(aLineAspect);

// 计算几何
ComputeGeom();

if (myPrimitives.IsNull()) return;

// 创建图形组
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
aGroup->SetGroupPrimitivesAspect(aLineAspect->Aspect());
aGroup->AddPrimitiveArray(myPrimitives);

// 如果是填充模式,添加填充面
if (myIsFilled && !myGeomEllipse.IsNull())
{
    // 使用 StdPrs_ShadedShape 显示填充的椭圆
    StdPrs_ShadedShape::Add(thePrs, myGeomEllipse, aDrawer);
}

}

// 计算选择
void AIS_Ellipse::ComputeSelection(const Handle(SelectMgr_Selection)& theSelection,
const Standard_Integer theMode)
{
if (theMode != 0) return;

// 创建敏感圆用于选择(椭圆可以近似为圆进行选择检测)
gp_Ax2 anAxis = myEllipse.Position();
Standard_Real aMajorRadius = myEllipse.MajorRadius();
Standard_Real aMinorRadius = myEllipse.MinorRadius();

// 使用平均半径创建选择圆
Standard_Real anAvgRadius = (aMajorRadius + aMinorRadius) / 2.0;

Handle(Select3D_SensitiveCircle) aSensitiveCircle = 
    new Select3D_SensitiveCircle(GetOwner(), 
                               new Geom_Circle(gp_Ax2(anAxis.Location(), anAxis.Direction()), anAvgRadius));

theSelection->Add(aSensitiveCircle);

}

// 计算几何
void AIS_Ellipse::ComputeGeom()
{
const Standard_Integer aNbPoints = 100; // 椭圆分段数

// 创建折线数组
myPrimitives = new Graphic3d_ArrayOfPolylines(aNbPoints + 1);

// 计算椭圆上的点
Standard_Real aParamStep = (myULast - myUFirst) / (aNbPoints - 1);

for (Standard_Integer i = 0; i < aNbPoints; ++i)
{
    Standard_Real aParam = myUFirst + i * aParamStep;
    gp_Pnt aPoint = ElCLib::Value(aParam, myEllipse);
    myPrimitives->AddVertex(aPoint);
}

// 闭合椭圆
gp_Pnt aFirstPoint = ElCLib::Value(myUFirst, myEllipse);
myPrimitives->AddVertex(aFirstPoint);

}

  1. 使用示例

// 创建椭圆示例
void CreateEllipseExample()
{
// 创建椭圆几何定义
gp_Ax2 anAxis(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1));
gp_Elips anEllipse(anAxis, 50.0, 30.0); // 长轴50,短轴30

// 创建自定义椭圆显示对象
Handle(AIS_Ellipse) anAisEllipse = new AIS_Ellipse(anEllipse);

// 设置属性
anAisEllipse->SetWidth(2.0);           // 线宽
anAisEllipse->SetFilled(Standard_True); // 填充

// 添加到显示上下文
myAISContext->Display(anAisEllipse, Standard_True);

}

// 使用 Geom_Ellipse 创建
void CreateEllipseFromGeom()
{
gp_Ax2 anAxis(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1));
Handle(Geom_Ellipse) aGeomEllipse = new Geom_Ellipse(anAxis, 50.0, 30.0);

Handle(AIS_Ellipse) anAisEllipse = new AIS_Ellipse(aGeomEllipse);
myAISContext->Display(anAisEllipse, Standard_True);

}

  1. 关键特性说明

  2. 继承关系:正确继承 AIS_InteractiveObject

  3. 几何定义:支持 gp_Elips 和 Geom_Ellipse 两种构造方式

  4. 显示模式:实现线框显示和填充显示

  5. 选择支持:通过敏感圆实现选择检测

  6. 自定义属性:支持线宽、填充、参数范围等设置

这个实现类似于 AIS_Circle 的结构,但专门针对椭圆进行了优化。你可以根据需要进一步扩展功能,比如添加颜色设置、透明度等属性。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐