[S0052] Create a torus solid in the Geometry Editor

To create a 3D shape in the JMAG-Designer Geometry Editor, first create a 2D sketch on the specified plane.
The cross-sectional shape and plane are determined by considering the construction steps—such as which cross-section of the intended 3D shape to extrude or which parts to cut away later.
This script creates a torus by revolving a circular region around the axis offset from the center of the circle.

Preconditions

  • The center coordinates, torus radius and tube radius of the torus are set using the equation.

Script Function

  • Register variables for the torus' center coordinates, torus radius and tube radius as equation parameters.
  • Create a reference plane offset from the ZX plane along the Y-axis and create a sketch on this plane.
    Set the variable representing the Y-coordinate of the center to the Y-axis offset distance.
    On the sketch plane, the X-direction corresponds to the global Z-direction and the Y-direction corresponds to the global X-direction.
  • Create a circular cross-section, a straight line to be the revolve axis and a construction line based on the specified center position and apply constraints.
    Constrain the center point by distances from the X-axis and Y-axis, assigning the corresponding center coordinate variables to these distances.
    Apply a radius constraint to the circular cross-section and apply a distance constraint—corresponding to the torus radius—to the construction line connecting the center point and the center of the circular cross-section.
  • Create a region defined by the circular cross-section.
  • Revolve the circular region 360 degrees around the line to create a torus shape.
# Copyright (c) 2026 JSOL CORPORATION
#
# This script is released under the MIT License.
# See the full license text at:
# https://www.jmag-international.com/scriptlibrary/jmag_script_library_mit/

app = designer.GetApplication()
geomApp = app.CreateGeometryEditor()
geomDoc = geomApp.GetDocument()

# Dimensional parameters
TorusCenterX = 0
TorusCenterY = 0
TorusCenterZ = 0
TorusRadius = 100
TubeRadius = 20

# Equation names
EqCenterX = u"center_x"
EqCenterY = u"center_y"
EqCenterZ = u"center_z"
EqTorusRadius = u"torus_radius"
EqTubeRadius = u"tube_radius"


def createNewPart():
    """Create a new Part and open it in edit mode."""
    assm = geomDoc.GetAssembly()
    part = assm.CreatePart()
    part.OpenPart()

    return part


def setupEquation(equation, expression):
    """Configure the basic settings for equations in DesignTable."""

    # The argument of SetType
    # 0: Value
    # 1: Expression
    equation.SetType(0)
    equation.SetExpression(str(expression))


def createTorusEquations():
    """Register the center coordinates, major radius, and tube radius of the torus as equations."""
    designTable = geomDoc.GetDesignTable()

    equationDataList = [
        (EqCenterX, TorusCenterX),
        (EqCenterY, TorusCenterY),
        (EqCenterZ, TorusCenterZ),
        (EqTorusRadius, TorusRadius),
        (EqTubeRadius, TubeRadius),
    ]

    designTable.EditStart()

    for equationName, expression in equationDataList:
        designTable.AddEquation(equationName)
        equation = designTable.GetEquation(equationName)
        setupEquation(equation, expression)

    designTable.EditEnd()


def createOffsetZXPlane(part):
    """Create a ZX plane offset by center_y."""
    refZXPlane = part.GetPlaneZX()

    offsetPlane = part.CreateReferencePlane()
    offsetPlane.SetTypeByString(u"Distance")
    offsetPlane.SetPropertyByReference(u"Plane", refZXPlane)
    offsetPlane.SetProperty(u"Distance", EqCenterY)

    return offsetPlane


def createSketchOnTorusPlane(part):
    """Create a sketch on the ZX plane offset by center_y."""
    offsetPlane = createOffsetZXPlane(part)
    offsetPlaneRef = geomDoc.CreateReferenceFromItem(offsetPlane)

    sketch = part.CreateSketch(offsetPlaneRef)

    return sketch


def createRegionFromItems(sketch, itemList):
    """Create a region on the sketch from all items in the argument's itemList."""
    selection = geomDoc.GetSelection()
    selection.Clear()
    for item in itemList:
        selection.Add(item)
    sketch.CreateRegions()
    selection.Clear()


def setConstraintExpression(constraint, propertyName, equationName):
    """Set an equation name to the specified constraint property."""
    constraint.SetProperty(propertyName, equationName)


def getDistanceExpressionFromSignedValue(equationName, value):
    """Return a distance expression for a signed coordinate value."""
    if value < 0:
        return u"-" + equationName

    return equationName


def drawBaseShapeForTorus(sketch, torusRadius, tubeRadius):
    """Create a circle that forms the cross-section of the torus and a revolve axis, then generate a region."""
    sketch.OpenSketch()

    # In a sketch on the ZX plane, the sketch X direction is treated as the Z direction and the sketch Y direction is treated as the X direction.
    sketchCenterX = TorusCenterZ
    sketchCenterY = TorusCenterX

    # Torus center
    centerVertex = sketch.CreateVertex(sketchCenterX, sketchCenterY)
    centerRef = geomDoc.CreateReferenceFromItem(centerVertex)
    # Revolve axis of the torus
    axisLine = sketch.CreateLine(
        sketchCenterX - torusRadius,
        sketchCenterY,
        sketchCenterX + torusRadius,
        sketchCenterY
    )
    axisRef = geomDoc.CreateReferenceFromItem(axisLine)
    # Constrain the revolve axis to be horizontal and to pass through the torus center.
    sketch.CreateMonoConstraint(u"horizontality", axisRef)
    sketch.CreateBiConstraint(u"coincident", axisRef, centerRef)
    # Constrain the X position of the torus center using an equation.
    centerXConstraint = sketch.CreateMonoConstraint(
        u"distancefromxaxis",
        centerRef
    )
    centerXDistanceExpression = getDistanceExpressionFromSignedValue(
        EqCenterX,
        TorusCenterX
    )
    setConstraintExpression(centerXConstraint, u"Distance", centerXDistanceExpression)
    # Constrain the Z position of the torus center using an equation.
    centerZConstraint = sketch.CreateMonoConstraint(
        u"distancefromyaxis",
        centerRef
    )
    centerZDistanceExpression = getDistanceExpressionFromSignedValue(
        EqCenterZ,
        TorusCenterZ
    )
    setConstraintExpression(centerZConstraint, u"Distance", centerZDistanceExpression)

    # Center of the tube cross-section
    tubeCenterVertex = sketch.CreateVertex(
        sketchCenterX,
        sketchCenterY + torusRadius
    )
    tubeCenterRef = geomDoc.CreateReferenceFromItem(tubeCenterVertex)
    # Construction line representing the distance from the torus center to the tube cross-section center.
    radiusLine = sketch.CreateLine(
        sketchCenterX,
        sketchCenterY,
        sketchCenterX,
        sketchCenterY + torusRadius
    )
    radiusLineRef = geomDoc.CreateReferenceFromItem(radiusLine)
    # Constrain the construction line to be perpendicular to the revolve axis, and set the distance to the tube cross-section center using an equation.
    sketch.CreateBiConstraint(u"perpendicularity", axisRef, radiusLineRef)
    sketch.CreateBiConstraint(u"coincident", radiusLineRef, centerRef)
    sketch.CreateBiConstraint(u"coincident", radiusLineRef, tubeCenterRef)
    torusRadiusConstraint = sketch.CreateBiConstraint(
        u"distance",
        centerRef,
        tubeCenterRef
    )
    setConstraintExpression(torusRadiusConstraint, u"Distance", EqTorusRadius)
    # Circle that forms the tube cross-section
    tubeCircle = sketch.CreateCircle(
        sketchCenterX,
        sketchCenterY + torusRadius,
        tubeRadius
    )
    tubeCircleRef = geomDoc.CreateReferenceFromItem(tubeCircle)
    # Constrain the radius of the tube cross-section using an equation.
    tubeRadiusConstraint = sketch.CreateMonoConstraint(
        u"radius",
        tubeCircleRef
    )
    setConstraintExpression(tubeRadiusConstraint, u"Radius", EqTubeRadius)

    # Create a closed region from the tube cross-section circle.
    createRegionFromItems(sketch, [tubeCircle])

    sketch.CloseSketch()

    return axisLine


def createTorusByRevolve(part, sketch, axisLine):
    """Revolve the circular region 360 degrees around the revolve axis to create the torus shape."""
    revolve = part.CreateRevolveSolid(sketch)
    revolve.SetTypeByName(u"OneSide")
    revolve.SetProperty(u"AxisType", u"SelectEntity")

    axisRef = geomDoc.CreateReferenceFromItem(axisLine)
    revolve.SetAxis(axisRef)

    revolve.SetAngle(360.0)

    return revolve


def createTorusPart(part):
    """Create a torus with equations in the specified Part."""
    sketch = createSketchOnTorusPlane(part)
    axisLine = drawBaseShapeForTorus(sketch, TorusRadius, TubeRadius)
    createTorusByRevolve(part, sketch, axisLine)


def main():
    """Create a Part containing a torus with equations."""
    createTorusEquations()

    part = createNewPart()
    createTorusPart(part)
    part.ClosePart()


main()

Download Python source code

How to use script file

Use the JMAG Script Library after reading and agreeing to the following terms of use.

Search Filter
  • All Categories

An engineer's diary
JMAG-Express Online