JMAGの形状エディタに搭載されている形状ライブラリをスクリプトで作成します。
JMAGの形状エディタで解析形状を作ると、ベースとした形状を後で寸法変更してパラメトリックスタディや最適化に用いることが容易です。
このために、寸法、拘束値、またはそれらを算出する変数を方程式に登録した上で作成すると便利に使用できます。
このスクリプトでは、インナロータ型モータに用いられるテーパスロット型ステータの2次元形状を作成します。
JMAGの形状エディタで解析形状を作ると、ベースとした形状を後で寸法変更してパラメトリックスタディや最適化に用いることが容易です。
このために、寸法、拘束値、またはそれらを算出する変数を方程式に登録した上で作成すると便利に使用できます。
このスクリプトでは、インナロータ型モータに用いられるテーパスロット型ステータの2次元形状を作成します。
前提条件
- スロット数24として1/4モデルで作成する
- 7.5degで鏡面対称性があり、15deg周期で同一形状が繰り返されるものとする
- スロット数は方程式としており変更した場合、周期性は追随するが1/4モデルでの作成は固定されている
スクリプトにおける設定内容
- スロット数及びステータ各部の寸法を方程式として登録する
- XY平面上にスケッチを作成し、編集可能ステータスとする
- 円弧と直線で1/2スロットピッチ分のステータコア及びスロットの外形を作成し、拘束を付与する
1/2スロットピッチ分の角度は方程式のスロット数から算出する - スロットの領域を作成し、名前と色を設定する
- ステータコアの領域を作成し、名前と色を設定する
- スロットの領域の鏡面コピーを作成し、円形パターン化して1/4モデルとする
- ステータコアの領域の鏡面コピーを作成し、円形パターン化して1/4モデルとする
円形パターンでの周期角度はスロット数から算出する
円形パターンのインスタンス数はスロット数の1/4とする
# Copyright (c) 2026 JSOL CORPORATION
#
# 本スクリプトはMITライセンスのもとで公開しています。
# ライセンス全文は以下を参照してください。
# https://www.jmag-international.com/jp/scriptlibrary/jmag_script_library_mit/
app = designer.GetApplication()
geomApp = app.CreateGeometryEditor()
geomDoc = geomApp.GetDocument()
# 寸法パラメータ
Slots = 24
StatorOuterDiameter = 204
StatorInnerDiameter = 102
ToothTipThickness = 1.6
SlotWidth1 = 6.0
SlotWidth2 = 3.6
SlotDepthFromOuter = 25.5
# 方程式名
EqSlots = u"SLOTS"
EqStatorOuterDiameter = u"SD1"
EqStatorInnerDiameter = u"SD2"
EqToothTipThickness = u"ST"
EqSlotWidth1 = u"SW1"
EqSlotWidth2 = u"SW2"
EqSlotDepthFromOuter = u"SW4"
def setupEquation(equation, expression, equationType):
"""DesignTableの方程式にタイプと式を設定する。"""
# SetTypeの引数
# 0: 値
# 1: 式
equation.SetType(equationType)
equation.SetExpression(str(expression))
def createStatorEquations():
"""ステータ形状に使用する方程式をDesignTableへ登録する。"""
designTable = geomDoc.GetDesignTable()
equationSettings = [
(EqSlots, Slots, 0),
(EqStatorOuterDiameter, StatorOuterDiameter, 0),
(EqStatorInnerDiameter, StatorInnerDiameter, 0),
(EqToothTipThickness, ToothTipThickness, 0),
(EqSlotWidth1, SlotWidth1, 0),
(EqSlotWidth2, SlotWidth2, 0),
(EqSlotDepthFromOuter, SlotDepthFromOuter, 0),
]
designTable.EditStart()
for equationName, expression, equationType in equationSettings:
designTable.AddEquation(equationName)
equation = designTable.GetEquation(equationName)
setupEquation(equation, expression, equationType)
designTable.EditEnd()
def createReference(item):
"""形状アイテムからReferenceObjectを作成する。"""
return geomDoc.CreateReferenceFromItem(item)
def addItemsToReferenceList(feature, propertyName, itemList):
"""形状アイテムをstringlist型のプロパティへ追加する。"""
for item in itemList:
feature.AddPropertyByReference(propertyName, createReference(item))
def createRegionFromItems(sketch, itemList):
"""引数のitemListすべてからスケッチ上に領域を作成する。"""
selection = geomDoc.GetSelection()
selection.Clear()
for item in itemList:
selection.Add(item)
sketch.CreateRegions()
selection.Clear()
def getRegionItemByOrder(sketch, createdOrder):
"""指定した順番目の領域オブジェクトを取得する。"""
currentCount = 0
for i in range(sketch.NumItems()):
item = sketch.GetItem(i)
if item.GetScriptTypeName() == u"RegionItem":
if currentCount == createdOrder - 1:
return item
currentCount += 1
return sketch
def calculateDirectionByAngle(sketch, angle):
"""X軸から指定した角度方向の単位ベクトルをPoint型で取得する。"""
dummyLine = sketch.CreateLineByLengthAngle(0, 0, 1, angle)
endVertex = dummyLine.GetEndVertex()
direction = geomApp.CreatePoint(endVertex.GetX(), endVertex.GetY(), 0)
selection = geomDoc.GetSelection()
selection.Clear()
selection.Add(dummyLine)
selection.Delete()
selection.Clear()
return direction
def calculatePointOnCircle(radius, y):
"""原点中心の円上で、Y座標を指定した点をPoint型で取得する。"""
x = (radius * radius - y * y) ** 0.5
return geomApp.CreatePoint(x, y, 0)
def calculatePointOnRadialLine(radius, direction):
"""原点中心の円と、原点を通る指定方向の直線との交点を取得する。"""
x = radius * direction.GetX()
y = radius * direction.GetY()
return geomApp.CreatePoint(x, y, 0)
def calculatePointOnOffsetLineAndCircle(radius, offset, direction):
"""指定方向から時計回り側へオフセットした直線と円との交点を取得する。"""
lengthOnDirection = (radius * radius - offset * offset) ** 0.5
x = direction.GetX() * lengthOnDirection + direction.GetY() * offset
y = direction.GetY() * lengthOnDirection - direction.GetX() * offset
return geomApp.CreatePoint(x, y, 0)
def createArc(sketch, startPoint, endPoint):
"""原点を中心として、指定した始点と終点を結ぶ円弧を作成する。"""
return sketch.CreateArc(0, 0, startPoint.GetX(), startPoint.GetY(), endPoint.GetX(), endPoint.GetY())
def createLine(sketch, startPoint, endPoint):
"""指定した始点と終点を結ぶ直線を作成する。"""
return sketch.CreateLine(startPoint.GetX(), startPoint.GetY(), endPoint.GetX(), endPoint.GetY())
def createDiameterConstraint(sketch, arc, expression):
"""円弧に直径拘束を作成し、方程式を設定する。"""
constraint = sketch.CreateMonoConstraint(u"radius", createReference(arc))
# SetTypeの引数
# 0: 半径
# 1: 直径
constraint.SetType(1)
constraint.SetProperty(u"Diameter", expression)
def createDistanceConstraint(sketch, firstItem, secondItem, expression, useDoubleWidth=False):
"""2つの形状間に距離拘束を作成し、方程式を設定する。"""
constraint = sketch.CreateBiConstraint(u"distance", createReference(firstItem), createReference(secondItem))
constraint.SetProperty(u"Distance", expression)
if useDoubleWidth:
constraint.SetProperty(u"UseDoubleWidth", True)
def createAngleConstraint(sketch, firstItem, secondItem, expression):
"""2つの形状間に角度拘束を作成し、方程式を設定する。"""
constraint = sketch.CreateBiConstraint(u"angle", createReference(firstItem), createReference(secondItem))
constraint.SetProperty(u"Angle", expression)
def setRegionAppearance(region, name, color):
"""領域の名前と表示色を設定する。"""
region.SetName(name)
region.SetProperty(u"Color", color)
region.SetProperty(u"UseParentColor", 0)
def createStatorBaseShape(sketch):
"""1/2スロットピッチ分のステータ基本形状と拘束を作成する。"""
statorOuterRadius = StatorOuterDiameter / 2.0
statorInnerRadius = StatorInnerDiameter / 2.0
toothTipOuterRadius = statorInnerRadius + ToothTipThickness
slotBottomRadius = statorOuterRadius - SlotDepthFromOuter
halfSlotAngle = 360.0 / Slots / 2.0
halfSlotWidth1 = SlotWidth1 / 2.0
halfSlotWidth2 = SlotWidth2 / 2.0
slotCenterDirection = calculateDirectionByAngle(sketch, halfSlotAngle)
# 原点を作成して固定する。
originVertex = sketch.CreateVertex(0, 0)
sketch.CreateMonoConstraint(u"fixture", createReference(originVertex))
# 各輪郭の頂点位置を計算する。
pointInnerOnXAxis = geomApp.CreatePoint(statorInnerRadius, 0, 0)
pointOuterOnXAxis = geomApp.CreatePoint(statorOuterRadius, 0, 0)
pointInnerAtSlotOpening = calculatePointOnOffsetLineAndCircle(statorInnerRadius, halfSlotWidth2, slotCenterDirection)
pointToothTipAtSlotOpening = calculatePointOnOffsetLineAndCircle(toothTipOuterRadius, halfSlotWidth2, slotCenterDirection)
pointToothTipAtToothSide = calculatePointOnCircle(toothTipOuterRadius, halfSlotWidth1)
pointSlotBottomAtToothSide = calculatePointOnCircle(slotBottomRadius, halfSlotWidth1)
pointInnerAtSlotCenter = calculatePointOnRadialLine(statorInnerRadius, slotCenterDirection)
pointToothTipAtSlotCenter = calculatePointOnRadialLine(toothTipOuterRadius, slotCenterDirection)
pointSlotBottomAtSlotCenter = calculatePointOnRadialLine(slotBottomRadius, slotCenterDirection)
pointOuterAtSlotCenter = calculatePointOnRadialLine(statorOuterRadius, slotCenterDirection)
# ステータ内径と外径の円弧を作成する。
innerArcForCore = createArc(sketch, pointInnerOnXAxis, pointInnerAtSlotOpening)
createDiameterConstraint(sketch, innerArcForCore, EqStatorInnerDiameter)
outerArc = createArc(sketch, pointOuterOnXAxis, pointOuterAtSlotCenter)
createDiameterConstraint(sketch, outerArc, EqStatorOuterDiameter)
# 歯先とスロット底の円弧を作成する。
toothTipArcForCore = createArc(sketch, pointToothTipAtToothSide, pointToothTipAtSlotOpening)
toothTipArcForSlot = createArc(sketch, pointToothTipAtSlotOpening, pointToothTipAtSlotCenter)
slotBottomArc = createArc(sketch, pointSlotBottomAtToothSide, pointSlotBottomAtSlotCenter)
# スロット開口部と歯側面を作成する。
slotOpeningLine = createLine(sketch, pointInnerAtSlotOpening, pointToothTipAtSlotOpening)
toothSideLine = createLine(sketch, pointToothTipAtToothSide, pointSlotBottomAtToothSide)
sketch.CreateMonoConstraint(u"horizontality", createReference(toothSideLine))
# スロット中心側の境界を作成する。
slotCenterOpeningLine = createLine(sketch, pointInnerAtSlotCenter, pointToothTipAtSlotCenter)
sketch.CreateBiConstraint(u"coincident", createReference(slotCenterOpeningLine), createReference(originVertex))
slotCenterSlotLine = createLine(sketch, pointToothTipAtSlotCenter, pointSlotBottomAtSlotCenter)
sketch.CreateBiConstraint(u"coincident", createReference(slotCenterOpeningLine), createReference(slotCenterSlotLine))
slotCenterOuterLine = createLine(sketch, pointSlotBottomAtSlotCenter, pointOuterAtSlotCenter)
sketch.CreateBiConstraint(u"coincident", createReference(slotCenterSlotLine), createReference(slotCenterOuterLine))
# X軸上にステータコアの境界を作成する。
radialLineOnXAxis = createLine(sketch, pointInnerOnXAxis, pointOuterOnXAxis)
sketch.CreateMonoConstraint(u"horizontality", createReference(radialLineOnXAxis))
sketch.CreateBiConstraint(u"coincident", createReference(radialLineOnXAxis), createReference(originVertex))
# 各円弧を同心に拘束し、ステータ各部の寸法を設定する。
for arc in [toothTipArcForCore, toothTipArcForSlot, slotBottomArc, outerArc]:
sketch.CreateBiConstraint(u"concentricity", createReference(innerArcForCore), createReference(arc))
createDistanceConstraint(sketch, innerArcForCore, toothTipArcForCore, EqToothTipThickness)
createDistanceConstraint(sketch, slotBottomArc, outerArc, EqSlotDepthFromOuter)
createDistanceConstraint(sketch, toothSideLine, radialLineOnXAxis, EqSlotWidth1, useDoubleWidth=True)
# 開口幅は、開口部と同じ半径範囲にある鏡面対称軸との距離で定義する。
createDistanceConstraint(sketch, slotOpeningLine, slotCenterOpeningLine, EqSlotWidth2, useDoubleWidth=True)
createAngleConstraint(sketch, radialLineOnXAxis, slotCenterOuterLine, u"360/{0}/2".format(EqSlots))
# スロット領域の内径側境界には歯先外周の円弧を使用する。
# 内径円弧とスロット開口線はステータコア領域だけに含める。
slotEdgeList = [
toothTipArcForCore,
toothTipArcForSlot,
toothSideLine,
slotBottomArc,
slotCenterSlotLine,
]
statorCoreEdgeList = [
innerArcForCore,
slotOpeningLine,
toothTipArcForCore,
toothSideLine,
slotBottomArc,
slotCenterOuterLine,
outerArc,
radialLineOnXAxis,
]
return slotEdgeList, statorCoreEdgeList, slotCenterSlotLine, slotCenterOuterLine
def createSlotPattern(sketch, slotRegion, slotSymmetryLine):
"""スロット領域を鏡面コピーし、90deg部分モデルへ円形パターン化する。"""
# 1/2スロットピッチの領域を鏡面コピーして1スロット分の形状を作成する。
slotMirror = sketch.CreateRegionMirrorCopy()
slotMirror.SetName(u"SlotMirror1Slot")
addItemsToReferenceList(slotMirror, u"Region", [slotRegion])
slotMirror.SetSymmetry(createReference(slotSymmetryLine))
# 1スロット分の形状を90deg部分モデルのスロット数分だけ円形パターン化する。
slotPattern = sketch.CreateRegionCircularPattern()
slotPattern.SetName(u"SlotCircularPattern")
addItemsToReferenceList(slotPattern, u"Region", [slotRegion])
addItemsToReferenceList(slotPattern, u"Feature", [slotMirror])
slotPattern.SetProperty(u"CenterType", u"DefaultOrigin")
slotPattern.SetProperty(u"Angle", u"360/{0}".format(EqSlots))
slotPattern.SetProperty(u"Instance", u"{0}/4".format(EqSlots))
def createStatorCorePattern(sketch, statorCoreRegion, coreSymmetryLine):
"""ステータコア領域を鏡面コピーし、90deg部分モデルへ円形パターン化する。"""
# 1/2スロットピッチの領域を鏡面コピーして1スロット分の形状を作成する。
statorCoreMirror = sketch.CreateRegionMirrorCopy()
statorCoreMirror.SetName(u"StatorCoreMirror1Slot")
statorCoreMirror.SetMerge(True)
addItemsToReferenceList(statorCoreMirror, u"Region", [statorCoreRegion])
statorCoreMirror.SetProperty(u"OverlappedAreaError", True)
statorCoreMirror.SetSymmetry(createReference(coreSymmetryLine))
# 1スロット分の形状を90deg部分モデルのスロット数分だけ円形パターン化する。
statorCorePattern = sketch.CreateRegionCircularPattern()
statorCorePattern.SetName(u"StatorCoreCircularPattern")
statorCorePattern.SetMerge(True)
addItemsToReferenceList(statorCorePattern, u"Region", [statorCoreRegion])
addItemsToReferenceList(statorCorePattern, u"Feature", [statorCoreMirror])
statorCorePattern.SetProperty(u"CenterType", u"DefaultOrigin")
statorCorePattern.SetProperty(u"Angle", u"360/{0}".format(EqSlots))
statorCorePattern.SetProperty(u"Instance", u"{0}/4".format(EqSlots))
def drawStator(sketch):
"""スケッチにテーパスロット型ステータの2次元形状を作成する。"""
slotEdgeList, statorCoreEdgeList, slotSymmetryLine, coreSymmetryLine = createStatorBaseShape(sketch)
regionOrder = 0
# スロット領域を作成し、名前と色を設定する。
createRegionFromItems(sketch, slotEdgeList)
regionOrder += 1
slotRegion = getRegionItemByOrder(sketch, regionOrder)
if slotRegion.GetScriptTypeName() == u"RegionItem":
setRegionAppearance(slotRegion, u"Slot", u"#a0a0a4")
# ステータコア領域を作成し、名前と色を設定する。
createRegionFromItems(sketch, statorCoreEdgeList)
regionOrder += 1
statorCoreRegion = getRegionItemByOrder(sketch, regionOrder)
if statorCoreRegion.GetScriptTypeName() == u"RegionItem":
setRegionAppearance(statorCoreRegion, u"StatorCore", u"lime")
createSlotPattern(sketch, slotRegion, slotSymmetryLine)
createStatorCorePattern(sketch, statorCoreRegion, coreSymmetryLine)
def drawInSketch(sketch):
"""スケッチを編集可能な状態にして形状を作成する。"""
sketch.OpenSketch()
drawStator(sketch)
sketch.CloseSketch()
def main():
"""テーパスロット型ステータの2次元形状を作成する。"""
createStatorEquations()
assm = geomDoc.GetAssembly()
refXYPlane = assm.GetPlaneXY()
statorSketch = assm.CreateSketch(refXYPlane)
drawInSketch(statorSketch)
main()



