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}")





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("Тело не найдено в активном документе.")


