FreeCADで動くPythonスクリプト その2(重心・質量中心)

今回はFreeCADで重心・質量中心を表示させるPythonスクリプトを説明します

前提条件として
 FreeCAD上で定義された単一の形状(Shape)を対象とします
 "重心"はShapeが持つPropertyの"CenterOfGravity"の値を参照しています
 "質量中心"はSubShapes(Shapeの構成要素)が持つPropertyの"CenterOfMass"の値を集計したものとなります
 材質はすべて均一なものを想定し,重みを評価していません
 FEMワークベンチでMaterialSolidを定義していも参照はされない仕様の様です
 FreeCADのv0.20でしか動作検証してません

Pythonスクリプトを以下に示します

props_of_shapes.py

# Properties of Shapes
# Show ShapeType, Number of SubShapes, Area, Volume and Center of gravity,
# Calcurate Mass and Center of mass of Selected-Objects
# Shapes should be grouped into a single object.

import Draft

def total_mass(shape, a=0):
    """ Calcurate Mass and Center of mass of argument shape """
    M = 0
    xx = FreeCAD.Vector(0, 0, 0)
    for i in range(len(shape.SubShapes)):
        st = shape.SubShapes[i].ShapeType
        ms = shape.SubShapes[i].Mass
        cm = shape.SubShapes[i].CenterOfMass
        M += ms
        xx += ms*cm
        if a: # a != 0 -> output breakdown of total mass
            FreeCAD.Console.PrintMessage("%d, %s, %f, %f, %f, %f\n" % (i, st, ms, cm.x, cm.y, cm.z))
    CoM = xx/M
    return M, CoM


def plot_point(vector_a):
    """ Plot point from argument vector """ 
    point = Draft.make_point(vector_a)
    Draft.autogroup(point) # Not required after version 0.19?


# Get Selected-Objects to obj
obj = FreeCADGui.Selection.getSelection()

if len(obj):
    shp = obj[0].Shape # Get shp as shape from obj
    
    FreeCAD.Console.PrintMessage("-------- Properties of Shapes  --------\n")
    
    # Show ShapeType of shp
    FreeCAD.Console.PrintMessage("ShapeType = %s\n" % shp.ShapeType)
    
    # Show Number of faces, shells, solids and subshapes in shp
    FreeCAD.Console.PrintMessage("Number of faces, shells, solids, subshapes = %d, %d, %d, %d\n" \
                        % (len(shp.Faces), len(shp.Shells), len(shp.Solids), len(shp.SubShapes)))
    
    # Show Area of shp
    FreeCAD.Console.PrintMessage("Area = %f\n" % shp.Area)
    
    # Show Volume of shp
    FreeCAD.Console.PrintMessage("Volume = %f\n" % shp.Volume)
    
    # Show Center of gravity of shp
    CoG = shp.CenterOfGravity
    FreeCAD.Console.PrintMessage("Center of gravity = (%f, %f, %f)\n" % (CoG.x, CoG.y, CoG.z))
    
    # Calcurate Mass and Center of mass
    M, CoM = total_mass(shp)
    FreeCAD.Console.PrintMessage("Mass = %f\n" % M)
    FreeCAD.Console.PrintMessage("Center of mass = (%f, %f, %f)\n" % (CoM.x, CoM.y, CoM.z))
    
    # Plot point as Center of gravity
    plot_point(CoG)
    FreeCAD.ActiveDocument.Point.Label = "center_of_gravity"
    
    # Plot point as Center of mass
    plot_point(CoM)
    FreeCAD.ActiveDocument.Point001.Label = "center_of_mass"
    
    FreeCAD.ActiveDocument.recompute()
    
else:
    FreeCAD.Console.PrintMessage("-------- No valid setected objects! --------\n")


【表示項目一覧】

ShapeType			Shapeの種別
Number of faces...		Shapeの内訳(face, shell, solid, subshapeの個数)
Area				断面積(mm2)
Volume				体積(mm3)
Center of gravity		重心(X, Y, Z)(mm)
Mass				質量*
Center of mass			質量中心(X, Y, Z)(mm)

※単位面積質量1として


【使い方】
・対象となる形状を選択した状態で本スクリプトを実行してください
・何も選択していない状態で実行するとWarningが表示されます
・正常に実行されればReport viewに重心・質量中心が出力されます
・モデルビューに重心と質量中心を表す点が描画されます


FreeCADで具体的な形状(高さ10 mmの円錐)に適用した例を示します

ShapeTypeが"Solid"なので重心はSolidモデルとしての値が表示されます
一方でSubShapesは"Shell"が1つなので質量中心はShellモデルとしての値が表示されます


【追記】
円錐の重心位置を一応確認しておきます
center_of_gravity_of _cone.wxm

半径r,高さhの円錐の任意高さxにおける断面積Aは%o1式で表されます
上式を0~hの区間積分した結果を体積Vとして%o2式に示します
%o1式に重みxをかけて積分した結果を1次モーメントSとして%o3式に示します
S/Vを計算した結果を重心高さgとして%o4式に示します


ということで,重心高さ 10/4 = 2.5 mm でスクリプトの値と一致していますね(*´ω`*)