FreeCADで動くPythonスクリプト その1(断面性能)
今回はFreeCADで断面性能を表示させるPythonスクリプトを説明します
AutoCADにはリージョンの断面性能を表示させるマスプロパティ(MASSPROP)というコマンドがあります
複雑な断面形状の図心位置や断面2次モーメント等を知りたいとき大変重宝する機能ですね
これと同じ様なことをFreeCADでもやりたいというお話です(*´ω`*)
前提条件として
FreeCAD上で定義された単一の面(Face)を対象とします
XY平面,XZ平面, YZ平面のいずれかに平行に配置されていることを想定しています
FreeCADのv0.20でしか動作検証してません
# Properties of Section # Show Area, Length, Boundary, Center of mass, Second moment of area, Product of inertia, # Radius of gyration, Principal moments of inertia, Principal axes and Section modulus of Selected-Object # Section must be located on a Cartesian coordinate plane. import Draft def norm(a, b, c=0): """ Return norm of argument numbers """ return (a**2 + b**2 + c**2)**(1/2) def section_modulus(shape): """ Calculate Section modulus from argument shape """ BBx = shape.BoundBox CoM = shape.CenterOfMass # Calculate distance from the neutral axis to the most extreme fibre x1 = abs(BBx.XMax - CoM.x) x2 = abs(BBx.XMin - CoM.x) y1 = abs(BBx.YMax - CoM.y) y2 = abs(BBx.YMin - CoM.y) z1 = abs(BBx.ZMax - CoM.z) z2 = abs(BBx.ZMin - CoM.z) MoI = shape.MatrixOfInertia Ixx = MoI.A11 Iyy = MoI.A22 Izz = MoI.A33 Z1 = FreeCAD.Vector(Ixx/norm(y1, z1), Iyy/norm(x1, z1), Izz/norm(x1, y1)) Z2 = FreeCAD.Vector(Ixx/norm(y2, z2), Iyy/norm(x2, z2), Izz/norm(x2, y2)) return Z1, Z2 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? def plot_line(vector_a, vector_b): """ Plot line from argument vectors """ line = Draft.make_line(vector_a, vector_b) Draft.autogroup(line) # Not required after version 0.19? def plot_principal_axes(shape): """ Plot principal axes from argument shape """ BBx = shape.BoundBox CoM = shape.CenterOfMass length_axis = norm(BBx.XMax-CoM.x, BBx.YMax-CoM.y, BBx.ZMax-CoM.z) I_eivect1 = shp.PrincipalProperties.pop("FirstAxisOfInertia") I_eivect2 = shp.PrincipalProperties.pop("SecondAxisOfInertia") I_eivect3 = shp.PrincipalProperties.pop("ThirdAxisOfInertia") # FreeCAD.Console.PrintMessage("Principal axis 1 = {}\n".format(I_eivect1)) # FreeCAD.Console.PrintMessage("Principal axis 2 = {}\n".format(I_eivect2)) # FreeCAD.Console.PrintMessage("Principal axis 3 = {}\n".format(I_eivect3)) plot_line(CoM, CoM + length_axis*I_eivect1) plot_line(CoM, CoM + length_axis*I_eivect2) plot_line(CoM, CoM + length_axis*I_eivect3) # Get Selected-Object to obj obj = FreeCADGui.Selection.getSelection() if len(obj): shp = obj[0].Shape # Get shp as shape from obj # Show Area of shp FreeCAD.Console.PrintMessage("-------- Properties of Section --------\n") FreeCAD.Console.PrintMessage("Area = %f\n" % shp.Area) # Show Length of shp FreeCAD.Console.PrintMessage("Length = %f\n" % shp.Length) # Show Boundary box of shp BBx = shp.BoundBox FreeCAD.Console.PrintMessage("Boundary box = (%f, %f, %f, %f, %f, %f)\n" % \ (BBx.XMin, BBx.XMax, BBx.YMin, BBx.YMax, BBx.ZMin, BBx.ZMax)) # Show Center of mass of shp CoM = shp.CenterOfMass FreeCAD.Console.PrintMessage("Center of mass = (%f, %f, %f)\n" % (CoM.x, CoM.y, CoM.z)) # Show Second moment of area and Product of inertia of shp MoI = shp.MatrixOfInertia FreeCAD.Console.PrintMessage("Second moment of area = (%f, %f, %f)\n" % (MoI.A11, MoI.A22, MoI.A33)) FreeCAD.Console.PrintMessage("Product of inertia = (%f, %f, %f)\n" % (MoI.A12, MoI.A13, MoI.A23)) # Show Radius of gyration Rg = shp.PrincipalProperties.pop("RadiusOfGyration") FreeCAD.Console.PrintMessage("Radius of gyration = {}\n".format(Rg)) # Show Principal moments of inertia and Principal axes I_eivals = shp.PrincipalProperties.pop("Moments") FreeCAD.Console.PrintMessage("Principal moments of inertia = {}\n".format(I_eivals)) # Plot point as Center of mass plot_point(CoM) FreeCAD.ActiveDocument.Point.Label = "center_of_mass" # Plot lines as Principal axes plot_principal_axes(shp) FreeCAD.ActiveDocument.Line.Label = "principal_axis_1" FreeCAD.ActiveDocument.Line001.Label = "principal_axis_2" FreeCAD.ActiveDocument.Line002.Label = "principal_axis_3" FreeCAD.ActiveDocument.recompute() # Calculate Section modulus Z1, Z2 = section_modulus(shp) FreeCAD.Console.PrintMessage("Section modulus = (%f, %f, %f, %f, %f, %f)\n" % \ (Z1.x, Z2.x, Z1.y, Z2.y, Z1.z, Z2.z)) else: FreeCAD.Console.PrintMessage("-------- No valid setected object! --------\n")
※主軸ベクトル(I_eivect1~3)を表示させる箇所はコメントアウトしてます
【表示項目一覧】
Area 断面積(mm2) Length 周長(mm) Boundary box 境界枠(X1, X2, Y1, Y2, Z1, Z2)(mm) Center of mass 図心(X, Y, Z)(mm) Second moment of area 断面2次モーメント(Ixx, Iyy, Izz)(mm4) Product of inertia 慣性乗積(Ixy, Ixz, Iyz)(mm4) Radius of gyration 回転半径(R1, R2, R3)(mm) Principal moments of inertia 主慣性モーメント(I1, I2, I3)(mm4) Section modulus 断面係数(Zx1, Zx2, Zy1, Zy2, Zz1, Zz2)(mm3)
※断面2次モーメントは図心を通り座標系に平行な各軸回りの値となります
(AutoCADのMASSPROPではワールド座標系の各軸回りの値となっており,挙動が異なるので注意してください)
【使い方】
・対象となるフェースを選択した状態で本スクリプトを実行してください
・何も選択していない状態で実行するとWarningが表示されます
・正常に実行されればReport viewに断面性能が出力されます
・モデルビューに図心を表す点と主軸ベクトルを表す線分が描画されます
FreeCADで具体的な断面に適用した例を2つ示します
矩形断面(50x100)
不等辺山形断面(L200x90x8/14)