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()


