reworking the markup workbench
This commit is contained in:
parent
b07fceca2a
commit
618c08e56e
2 changed files with 326 additions and 0 deletions
297
cg/freecad/Frames/GripPoseGenerator.py
Normal file
297
cg/freecad/Frames/GripPoseGenerator.py
Normal file
|
@ -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
|
29
cg/freecad/Frames/chekingEntities.py
Normal file
29
cg/freecad/Frames/chekingEntities.py
Normal file
|
@ -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"
|
||||||
|
# Затем запустите этот скрипт, и он выведет тела без связанных объектов в терминал
|
Loading…
Add table
Add a link
Reference in a new issue