How to correctly create an elliptic surface?

Hello, buddy, recently I have a problem in building an ellipsoid, want to ask you.

gp_Pnt TargetPoint(0, 0, 0); // The center point of ellipse
gp_Dir xdir(1, 0, 0); // motion along the long axis
gp_Ax2 axis(TargetPoint, gp::DZ(), xdir);
Handle_Geom_Ellipse ellipse = new Geom_Ellipse(axis, 30, 10);
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(ellipse);
gp_Dir vector_1;
gp_Ax1 revolAxis(TargetPoint, vector_1); // Define an axis of rotation
TopoDS_Shape ellipsoid = BRepPrimAPI_MakeRevol(edge, revolAxis); //An ellipsoid is obtained about the axis of rotation

In theory, my vector_1 should be a perpendicular axis intersecting with axis, such as gp::DX() or gp::DY(). However, this implementation will report an error, I do not know why?
When I set vector_1 to gp::DZ(), there is no error, but the ellipsoid shape obtained is only a plane ring obtained by the long axis and the short axis as the radius, and it is not the ellipsoid I want.
Because, I would like to ask you, what might be the problem?

Dmitrii Pasukhin's picture

Hello,

There is some sample, please check.

  //! Data struct for create sphere
  struct Sphere
  {
    Standard_Real Radius = 0.0;
  };

  //=======================================================================
  // function : isUniformScale
  // purpose  :
  //=======================================================================
  static bool isUniformScale(const gp_XYZ& thePnt)
  {
    return (abs(thePnt.X() - thePnt.Y()) <= Precision::Confusion() &&
            abs(thePnt.X() - thePnt.Z()) <= Precision::Confusion() &&
            abs(thePnt.Y() - thePnt.Z()) <= Precision::Confusion());
  }

  //=======================================================================
  //function : rotateSingleCurve
  //purpose  :
  //=======================================================================
  TopoDS_Shape rotateSingleCurve(Handle(Geom_Curve)& theContour,
                                 const gp_Ax1& theAxis)
  {
    TopoDS_Shape aSolid;

    if (theContour.IsNull())
    {
      return aSolid;
    }
      BRepBuilderAPI_MakeEdge anEdgeMaker(theContour);
      if (!anEdgeMaker.IsDone())
      {
        return aSolid;
      }
    BRepPrimAPI_MakeRevol aRevolver(anEdgeMaker.Shape(), theAxis);
    if (!aRevolver.IsDone())
    {
      return aSolid;
    }
    return aRevolver.Shape();
  }

//=======================================================================
// function : MakeSphere
// purpose  :
//=======================================================================
TopoDS_Shape MakeSphere(const Sphere& theSphere,
                        const gp_XYZ& theScale)
{
  if (isUniformScale(theScale))
  {
    BRepPrimAPI_MakeSphere aSphere(theSphere.Radius * theScale.X());
    aSphere.Build();
    if (aSphere.IsDone())
    {
      return aSphere.Shape();
    }
    return TopoDS_Shape();
  }
  const double aMajorRScale = std::max(theScale.X(), theScale.Z());
  const double aMinorRScale = theScale.Y() > aMajorRScale ? aMajorRScale : theScale.Y();
  // TODO: make scaling into OX/OZ directions
  const gp_Pnt aCircleCenter(0, 0., 0);
  const gp_Dir aCircNormal(1, 0., 0.);
  const gp_Dir aCircStartDirection(0., 0., 1.);
  const gp_Ax2 anCircAxis(aCircleCenter, aCircNormal, aCircStartDirection);
  const Handle(Geom_Ellipse) aCircle = new Geom_Ellipse(anCircAxis, theSphere.Radius * aMajorRScale,
                                                        theSphere.Radius * aMinorRScale);
  const double aStartParam = M_PI_2;
  Handle(Geom_TrimmedCurve) anArc = new Geom_TrimmedCurve(aCircle, 0, aStartParam);
  gp_Ax1 anAxisOfRevolution(gp_Pnt(0, 0, 0), gp_Dir(0, 1, 0));
  return rotateSingleCurve(anArc, anAxisOfRevolution);
}

Best regards, Dmitrii.

Guido-X's picture

Hello, first of all, thank you very much for your reply!
I have adjusted the code structure according to your ideas, and the good thing is that the direction of the rotation axis is now on the theoretical corresponding. The bad thing is that the resulting model is still a flat ring structure, rather than a three-dimensional ellipse structure.

Dmitrii Pasukhin's picture

The problem is - you need to trim rotated countour/ You will have self intersection in another case.

Best regards, Dmitrii.

Guido-X's picture

Hello, do you mean that there may be conflicts when modeling in this way?

Dmitrii Pasukhin's picture

Try to rotate circle along axis. It will be double surface on one point. You need to rotate circle only on 180 degree instead of 360. To make sphere you need to rotate a half of circle for 360 or whole circle for 180.

Best regards, Dmitrii.

Guido-X's picture

It is true that the Angle of rotation of the model needs to be defined, as you said. I thought it would be OK to follow the default model.
Thank you very much!