import FreeCAD import Part doc = FreeCAD.ActiveDocument def check_capture_positions(): # Получаем активный документ doc = FreeCAD.ActiveDocument # Список тел без позиций захвата bodies_without_capture_positions = [] # Перебираем все объекты в документе for obj in doc.Objects: if obj.isDerivedFrom("Part::Feature"): # Проверяем, есть ли атрибут "Placement" у объекта if not hasattr(obj, "Placement"): # Если нет, добавляем его в список bodies_without_capture_positions.append(obj.Label) # Проверяем результат if len(bodies_without_capture_positions) > 0: print("Следующие тела не имеют позиции захвата:") for body in bodies_without_capture_positions: print(body) else: print("Все тела имеют позиции захвата.") check_capture_positions() import FreeCAD as App doc = App.ActiveDocument def check_capture_positions(): bodies_without_grip_pose = [] solid_bodies_list = [] lcs_list = [] bodies_with_grip_pose = [] for obj in doc.Objects: if hasattr(obj, 'Shape') and hasattr(obj.Shape, 'Volume') and obj.Shape.Volume: # if obj.Shape and obj.Shape.Volume: solid_bodies_list.append(obj) print(solid_bodies_list) for obj in doc.Objects: if obj.TypeId =='PartDesign::CoordinateSystem': lcs_list.append(obj) print(lcs_list) for body in solid_bodies_list: checker = 0 for lcs in lcs_list: print(checker) if lcs.Attachment_ParentObject == body.Label: checker =+1 if checker == 0: bodies_without_grip_pose.append(body) print(bodies_without_grip_pose) if len(bodies_without_grip_pose) == 0: print('Все тела имеют позиции захвата') else: print('Имеются тела без позиций захвата:') for body in bodies_without_grip_pose: print(body.Label) check_capture_positions() def create_grip_positions(obj, face1, face2): if not (face1 and face2): App.Console.PrintError("Не выбраны обе грани\n") return normal1 = face1.normalAt(0, 0) normal2 = face2.normalAt(0, 0) if normal1.isParallel(normal2): # Найдите центры граней center1 = face1.CenterOfMass center2 = face2.CenterOfMass # Вычислите расстояние между центрами граней distance = center2 - center1 distance = distance.Length # Создайте вспомогательную систему координат между гранями coordinate_system = App.ActiveDocument.addObject("Part::CoordinateSystem", "CoordinateSystem") coordinate_system.Placement.Base = center1 + 0.5 * distance * normal1 coordinate_system.Placement.Rotation = normal1.getRotationTo(App.Vector(0, 0, 1)) # Выведите информацию о расстоянии App.Console.PrintMessage(f"Расстояние межу гранью 1 и гранью 2: {distance} мм\n") # Обновите графический интерфейс FreeCAD App.ActiveDocument.recompute() else: App.Console.PrintError("Выбранные грани не являются параллельными\n") create_grip_positions() # Добавление обзервера для касаний v=Gui.activeDocument().activeView() #This class logs any mouse button events. As the registered callback function fires twice for 'down' and #'up' events we need a boolean flag to handle this. class ViewObserver: def __init__(self, view): self.view = view def logPosition(self, info): down = (info["State"] == "DOWN") pos = info["Position"] if (down): FreeCAD.Console.PrintMessage("Clicked on position: ("+str(pos[0])+", "+str(pos[1])+")\n") pnt = self.view.getPoint(pos) FreeCAD.Console.PrintMessage("World coordinates: " + str(pnt) + "\n") info = self.view.getObjectInfo(pos) FreeCAD.Console.PrintMessage("Object info: " + str(info) + "\n") o = ViewObserver(v) c = v.addEventCallback("SoMouseButtonEvent",o.logPosition) ### getObjectInfo работает import FreeCAD as App import FreeCADGui as Gui def getFaceInfo(face): if face: App.Console.PrintMessage(f"Информация о грани: {face}\n") # Получите позицию (Base) и ориентацию (Rotation) грани в глобальных координатах placement = face.Placement position = App.Vector(placement.Base) orientation = App.Rotation(placement.Rotation) App.Console.PrintMessage(f"Позиция грани: {position}\n") App.Console.PrintMessage(f"Ориентация грани: {orientation}\n") def getObjectInfo(): selection = Gui.Selection.getSelectionEx() if selection: selected_object = selection[0].Object if selected_object: subelement_name = selection[0].SubElementNames[0] if "Face" in subelement_name: face = selected_object.Shape.Faces[int(subelement_name.split("Face")[1])] getFaceInfo(face) else: App.Console.PrintError("Выберите грань, а не тело или другой элемент\n") else: App.Console.PrintError("Объект не найден\n") else: App.Console.PrintError("Не выбраны объекты\n") getObjectInfo() import FreeCAD as App import FreeCADGui as Gui import Part # Функция для получения списка всех объектов с заданным свойством def get_objects_with_property(property_name, property_value): result = [] for obj in FreeCAD.ActiveDocument.Objects: if hasattr(obj, "PropertiesList") and property_name in obj.PropertiesList: if obj.getPropertyByName(property_name) == property_value: result.append(obj) return result # Получение списка всех объектов с названием тела в свойстве bodies = get_objects_with_property("BodyName", "Body") # Получение списка всех объектов all_objects = FreeCAD.ActiveDocument.Objects # Поиск и вывод тел, у которых нет связанных вспомогательных объектов for body in bodies: linked_objects = [] for obj in all_objects: if obj.hasLinkOf(body): linked_objects.append(obj.Name) if not linked_objects: print(f"Тело без связанных объектов: {body.Name}") # Пример использования: # Убедитесь, что в FreeCAD активный документ содержит объекты с свойством "BodyName" и значением "Body" # Затем запустите этот скрипт, и он выведет тела без связанных объектов в терминал def create_coordinate_system(surface1, surface2): if surface1 is None or surface2 is None: App.Console.PrintError("Не удалось найти одну из поверхностей\n") return # Проверьте, являются ли поверхности плоскими if surface1.Shape.Faces[0].Surface.TypeId == "Part::Plane" and surface2.Shape.Faces[0].Surface.TypeId == "Part::Plane": # Проверьте, являются ли поверхности параллельными normal1 = surface1.Shape.normalAt(0, 0) normal2 = surface2.Shape.normalAt(0, 0) if normal1.isParallel(normal2): # Найдите центры поверхностей center1 = surface1.Shape.BoundBox.Center center2 = surface2.Shape.BoundBox.Center # Вычислите расстояние между центрами поверхностей distance = center2 - center1 distance = distance.Length # Создайте вспомогательную систему координат между поверхностями coordinate_system = App.ActiveDocument.addObject("Part::CoordinateSystem", "CoordinateSystem") coordinate_system.Placement.Base = center1 + 0.5 * distance * normal1 coordinate_system.Placement.Rotation = normal1.getRotationTo(App.Vector(0, 0, 1)) # Выведите информацию о расстоянии App.Console.PrintMessage(f"Расстояние между поверхностью 1 и поверхностью 2: {distance} мм\n") # Обновите графический интерфейс FreeCAD App.ActiveDocument.recompute() else: App.Console.PrintError("Выбранные поверхности не являются параллельными\n") else: App.Console.PrintError("Выбранные поверхности не являются плоскими\n") # Создайте пользовательский интерфейс кнопки для вызова функции class CoordinateSystemTool: def Activated(self): selection = Gui.Selection.getSelectionEx() if len(selection) == 2: create_coordinate_system(selection[0].Object, selection[1].Object) else: App.Console.PrintError("Выберите две параллельные плоскости\n") def GetResources(self): return { 'Pixmap': 'path/to/your/icon.png', # Замените на путь к значку кнопки 'MenuText': 'Создать вспомогательную систему координат', 'ToolTip': 'Создать вспомогательную систему координат между двумя плоскостями' } # Зарегистрируйте пользовательский инструмент Gui.addCommand('My_Coordinate_System_Tool', CoordinateSystemTool()) #### эта штука работает vvv # Функция для создания вспомогательного объекта и установки свойства "AttachmentType" def create_helper_object_with_attribute(body, attribute_value): helper_object = FreeCAD.ActiveDocument.addObject("App::FeaturePython", "HelperObject") helper_object.addProperty("App::PropertyString", "AttachmentType").AttachmentType = attribute_value helper_object.addProperty("App::PropertyString", "AttachedObject") helper_object.AttachedObject = body.Label # Пример использования: # Замените "MyBody" на имя тела, к которому вы хотите привязать вспомогательный объект body_to_attach = FreeCAD.ActiveDocument.getObjectsByLabel("gear_frame_221213")[0] if body_to_attach: create_helper_object_with_attribute(body_to_attach, "Body") else: print("Тело не найдено в активном документе.") #итого, план такой: 0. Проверяем тело на наличие позиций захвата 0.1. Выводим список всех тел без позиции, иначе говорим что все ок 1. Создаем вспомогательную систему координат. у нее имеется свойство, привязывающее ее к определенному телу 1.1 Создаем ее с помощью выбора двух поверхностей, которые противоположно направлены друг к другу. Все данные вносим в созданный обьект 1.2 Опционально - проверяем ее с помощью призрака захвата 2. Экспортируем ее в json