https://wiki.freecad.org/TopoShape_API
上記にあるfreecadのdocumentによれば、 部品形状の同一性判定には、isSame()、isEqual()、isPartner()の メソッドがあるようですが、 私の環境?ではなぜか False ばかりになってしまいます。
なので、以下のように自作
#!/usr/bin/python # -*- coding: utf-8 -*- import FreeCAD tolerance = 0.0005 # 許容差 def main(): doc = FreeCAD.ActiveDocument objs = doc.findObjects('Part::FeaturePython') chk_result = is_same_shape(objs[0], objs[1] ) print( "is_same_shape()=",chk_result ) def is_same_shape(obj_1,obj_2): # 元のobjectを壊さない様、copy shp_1 = obj_1.Shape.copy() shp_2 = obj_2.Shape.copy() # 体積と表面積を比較 for (val_1,val_2) in [(shp_1.Volume,shp_2.Volume), (shp_1.Area, shp_2.Area )]: if abs(val_1 - val_2) > tolerance: return False # boundary boxの中心を原点へ移動 move_to_origin(shp_1) move_to_origin(shp_2) # 同じ向きに回転 rot_same_dir(shp_1, shp_2) # 互いをboolean減算し、差がなければ、同一形状と判定 ret_obj = shp_1.cut(shp_2 ) if ret_obj.Volume < tolerance: return True return False def rot_same_dir(shp_1, shp_2): x_1 = shp_1.CenterOfMass.x y_1 = shp_1.CenterOfMass.y z_1 = shp_1.CenterOfMass.z x_2 = shp_2.CenterOfMass.x y_2 = shp_2.CenterOfMass.y z_2 = shp_2.CenterOfMass.z # 回転角算出。が、判定式は怪しい。TODO pitch = 0 if abs(z_1 - z_2) < tolerance: pitch = 0 elif abs(z_1 + z_2) < tolerance: pitch = 180 elif abs(z_1 + x_2) < tolerance: pitch = 90 elif abs(z_1 - x_2) < tolerance: pitch = -90 yaw = 0 if abs(x_1 - x_2) < tolerance: yaw = 0 elif abs(x_1 + x_2) < tolerance: yaw = 180 elif abs(x_1 + y_2) < tolerance: yaw = 180 elif abs(x_1 - y_2) < tolerance: yaw = 180 # https://blog.freecad.org/2023/01/16/the-rotation-api-in-freecad/ shp_2.Placement = App.Placement(shp_2.Placement.Base, App.Rotation(yaw, pitch, 0), shp_2.Placement.Base.negative()) def move_to_origin(shp): shp.Placement = App.Placement(App.Vector(0,0,0), App.Rotation(App.Vector(1,0,0),0)) shp.Placement = App.Placement(shp.BoundBox.Center.negative(), App.Rotation(App.Vector(1,0,0),0)) return shp if __name__ == '__main__': main()
↑こう書くと、以下のようにA2PLUSでアセンブルしたパーツに対し、True が返ります