From 618c08e56e664e61aea97219ae173c70116a2322 Mon Sep 17 00:00:00 2001 From: Mark Voltov Date: Tue, 31 Oct 2023 11:13:43 +0300 Subject: [PATCH] reworking the markup workbench --- cg/freecad/Frames/GripPoseGenerator.py | 297 +++++++++++++++++++++++++ cg/freecad/Frames/chekingEntities.py | 29 +++ 2 files changed, 326 insertions(+) create mode 100644 cg/freecad/Frames/GripPoseGenerator.py create mode 100644 cg/freecad/Frames/chekingEntities.py diff --git a/cg/freecad/Frames/GripPoseGenerator.py b/cg/freecad/Frames/GripPoseGenerator.py new file mode 100644 index 0000000..195014d --- /dev/null +++ b/cg/freecad/Frames/GripPoseGenerator.py @@ -0,0 +1,297 @@ +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 \ No newline at end of file diff --git a/cg/freecad/Frames/chekingEntities.py b/cg/freecad/Frames/chekingEntities.py new file mode 100644 index 0000000..baf69fe --- /dev/null +++ b/cg/freecad/Frames/chekingEntities.py @@ -0,0 +1,29 @@ +import FreeCAD + +# Функция для получения списка всех объектов с заданным свойством +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" +# Затем запустите этот скрипт, и он выведет тела без связанных объектов в терминал