В предыдущей статье мы узнали, как заполнять штамп чертежа КОМПАС-3D средствами API. Код получился достаточно простым, но вполне подходящим для ознакомления с темой и дающим наглядный пример для выполнения собственных проектов.
Сейчас же хотелось бы рассмотреть возможности программирования в среде SolidWorks. Эта тема в русскоязычном интернете освещена достаточно скудно. И совсем мало информации по взаимодействию SolidWorks и Python. Данная статья должна ликвидировать этот недостаток и дать возможность пользователям этой популярной САПР научиться программировать свои собственные приложения.
Стоит сразу оговориться, что статья не претендует на всеобъемлющий охват означенной темы (да это и невозможно), а лишь показывает на конкретном примере, как пользоваться справочной системой SolidWorks API, а также даёт представление о специфике программирования именно в среде Python.
Итак, нами будет рассмотрено построение простого фланца средствами SolidWorks API.
В дереве видно, что фланец сделан путём выдавливания основного тела, затем был произведён вырез на плоской грани фланца, а затем создан круговой массив этих вырезов (отверстий).
Теперь приступим к написанию кода.
Разделим работу на 5 этапов:
- Подключение модулей (библиотек)
- Подключение базовых интерфейсов SliidWorks API
- Построение основного тела фланца
- Построение отверстия во фланце
- Построение кругового массива отверстий
Этап №1. Подключение модулей (библиотек)
Заходим в интерпретатор Python (о том, где его найти, читайте в предыдущей статье).
Начнём с кодировки. Чтобы мы могли пользоваться русским языком, например, в комментариях или в текстовых переменных, используем стандарт кодирования utf-8. Запишем первую строку:# -*- coding: utf-8 -*-
Следующая строка кода задает имя. Пусть будет:#|SolidWorks
Далее нам необходимо подключить все необходимые модули для работы кода. Модуль - это готовая библиотека, которая используется разработчиками для того, чтобы не писать один и тот же код много раз.
Итак, для создания нашего кода нам потребуются:
- для подключения к COM-объектам
import pythoncom
- для работы с приложениями Windows
from win32com.client import Dispatch, gencache import win32com.client as win32
- для преобразования типа Variant в COM-объект
from win32com.client import VARIANT
Также нам потребуется переменнаяVT_DISPATCH = win32.VARIANT(pythoncom.VT_DISPATCH, None)
Этап №2. Подключение базовых интерфейсов SolidWorks API
Теперь подключаемся к самому приложению SolidWorkssw = win32.dynamic.Dispatch('SldWorks.Application')
Далее нам необходимо работать с интерфейсами SolidWorks API. Где нам их найти? Как узнать, какой интерфейс от какого наследуется, какие у него дочерние интерфейсы, какие он имеет свойства и методы?
Для этого обратимся к справочной системе SolidWorks API. Она есть в интернете в открытом доступе. Я использовал для работы SolidWorks 2016, поэтому и справку открыл версии 2016. Вам же необходимо использовать справку актуальную для вашей версии SolidWorks. Это важно учитывать, т.к. некоторые интерфейсы, введенные позже, на более ранних версиях SolidWorks не работают.
Справка естественно англоязычная, тем полезнее будет данная статья для пользователей!
Итак, первым делом нам следует подключиться к активному документу SolidWorks. Для этого в справке вот здесь ищем свойство активного документа
и пишем следующую строку:swDoc = sw.ActiveDoc
Перейдём по ссылке (выделено жёлтым) и увидим, что значение данного свойства – это документ модели:
Перейдём по ссылке и промотаем вниз. Там будет ссылка на свойства и методы данного интерфейса:
Перейдём по ней и попадём на страницу:
Найдём свойство FeatureManager - интерфейс дерева операций (выделено жёлтым). Соответственно пишем:swFeatMgr = swDoc.FeatureManager
У него же получаем интерфейс выделенных объектов и менеджер эскизов:
swSelMgr = swDoc.SelectionManager sketchMan = swDoc.SketchManager
У интерфейса выделенных объектов найдём метод, который используется в качестве аргумента при выборе объектов. Для этого последовательно переходим по ссылкам:
Далее:
Вот данный метод:
Запишем его:swSelData = swSelMgr.CreateSelectData
Мы получили базовые интерфейсы для дальнейшей работы.
Этап №3. Построение основного тела фланца
Теперь осуществим выбор плоскости для эскиза. Для этого возвращаемся в интерфейсу модельного документа и находим у него свойство Extension
Находим у этого интерфейса метод SelectByID2, перейдя последовательно по ссылкам:
Далее:
Метод:
Переходим по ссылке и смотрим параметры данного метода:
Параметры следующие:
- Имя плоскости (указывается именно таким, каким оно отображается в дереве построения).
- Тип объекта (из перечисления). Ставим "PLANE"
- Координата X = 0
- Координата Y = 0
- Координата Z = 0
- Ставим False, чтобы если, что-то было выбрано ранее, было удалено из списка выбранных объектов
- Обозначение. Не нужно. Ставим 0
- Указываем переменную VT_DISPATCH
- Дополнительная опция. Из перечисления выбираем 0.
Запишем:selBool = swDoc.Extension.SelectByID2("Спереди", "PLANE", 0, 0, 0, False, 0, VT_DISPATCH, 0)
Перейдём к менеджеру эскизов и выберем полученный эскиз (подробно сёрфинг по ссылкам показывать уже не буду). В итоге должны попасть на эту страницу:
И записать следующее:sketchMan.InsertSketch(True)
Теперь создадим внутри эскиза две окружности с центром в начале координат и радиусами 0,025 и 0,05 м для формирования тела фланца. Обратите внимание, что в SolidWorks API в отличие от КОМПАС API значения размеров прописываются в метрах.
Выберем метод CreateCircleByRadius (создать окружность по радиусу):
Параметры данного метода достаточно просты – это координаты центра и радиус:
sketchMan.CreateCircleByRadius(0, 0, 0, 0.05) sketchMan.CreateCircleByRadius(0, 0, 0, 0.025)
Далее создадим основное тело фланца - объект выдавливания. У менеджера дерева операций найдём метод FeatureExtrusion2
Его параметры достаточно объемны. Давайте в них разберёмся.
- В одну сторону – True
- С обратной стороны – False
- Обратное направление выреза – False
- Тип выдавливания в одну сторону из перечисления – на расстояние, значение 0
- Тип выдавливания в другую сторону из перечисления – на расстояние, значение 0
- Глубина выдавливания в одну сторону – 0,02 м
- Глубина выдавливания в другую сторону – 0 м
- Угол уклона в одну сторону – False
- Угол уклона в другую сторону – False
- Угол уклона в одну сторону внутрь или наружу (нам без разницы) – False
- Угол уклона в другую сторону внутрь или наружу (нам без разницы) – False
- Угол уклона в одну сторону – 0
- Угол уклона в другую сторону – 0
- Смещение в одну сторону – False
- Смещение в другую сторону – False
- False
- False
- Объединить результат в многотельной детали – True
- Функция влияет на выбранные тела – False
- Автоматический выбор всех тел, на которые влияет данная операция – True
- Начальное положение из перечисления – плоскость эскиза (значение 0)
- Начальное смещение – 0
- Обратное начальное смещение – False
Соответственно, запишем:extrusion = swFeatMgr.FeatureExtrusion2(True, False, False, 0,0,0.02, 0, False, False, False, False, 0, 0, False, False, False, False, True, False, True,0, 0, False)
Снимем все выделенияswDoc.ClearSelection2(True)
Сохраните файл python, запустите SolidWorks, создайте пустую деталь и запустите код. В итоге должно получиться следующее:
Этап №4. Построение отверстия во фланце
Теперь необходимо создать отверстие во фланце. Для этого повторяем все те же самые операции, что и в этапе №3. Соответственно на них я уже так подробно останавливаться не буду.
Выберем плоскость для нового эскиза. Пусть это будет та же самая плоскость "Спереди"selBool = swDoc.Extension.SelectByID2("Спереди", "PLANE", 0, 0, 0, False, 0, VT_DISPATCH, 0)
Выберем полученный эскизsketchMan.InsertSketch(True)
Создадим внутри эскиза окружность с центром X = 0, Y = 0,035 . Радиус пусть будет 0,005 м.sketchMan.CreateCircleByRadius(0, 0.035, 0, 0.005)
Сделаем вырез. У менеджера дерева операций найдём метод FeatureCut3. Он аналогичен методу выдавливания, т.е. имеет те же самые аргументы.extrusion = swFeatMgr.FeatureCut3(False, False, False, 0, 0, 0.02, 0.02, False, False, False, False, 0, 0, False, False, False, False, False, True, True, True, True, False, 0, 0, False)
Снимем все выделенияswDoc.ClearSelection2(True)
Получим:
Этап №5. Построение кругового массива отверстий
Создадим круговой массив элементов. В качестве множимого объекта выберем последний вырез (отверстие). А в качестве объекта, вокруг которого происходит вращение, выберем, например, цилиндрическую наружную грань фланца.
Итак, как же нам правильно выбрать последовательно эти два объекта для создания массива? Для этого пойдём от обратного. Найдём интерфейс кругового массива FeatureCircularPattern4 (можно просто вбить в поисковую строку справки SolidWorks API). Промотав вниз, найдём примечания и увидим, что для выбора элементов нам понадобится интерфейс Select2 . Причём, если мы выбираем элемент, вокруг которого идёт вращение, то аргумент метода будет 1, если выбираем элемент, который множим, то аргумент равен 4.
Итак, запишем:selBool = extrusion.Select2(True, 4)
Теперь пройдёмся по элементам дерева, у каждого найдём грани, и выделим цилиндрическую грань с радиусом 0,05 м - это будет поверхность, вокруг которой создадим круговой массив. Методы и свойства интерфейсов, записанных в циклах, найдите самостоятельно в справке SolidWorks API.
Сперва зададим переменную, при изменении которой сразу выходим из всех цикловboolean = 0
В первом цикле идём по элементам дереваfor i in range(swFeatMgr.FeatureStatistics.FeatureCount): feature = swFeatMgr.FeatureStatistics.Features[i]
Во вложенном цикле идём по граням итерируемого элемента дерева for j in range(feature.GetFaceCount):
Получим интерфейс грани face = feature.GetFaces[j]
У грани получим интерфейс поверхности surface = face.GetSurface
Если поверхность является цилиндром и имеет радиус 0,05 м, то присваиваем переменной boolean значение 1 if surface.IsCylinder == True and surface.CylinderParams[6] == 0.05: boolean = 1
Выделяем грань (ставим 1, т.к. вокруг этой грани идёт вращение) selBool = face.Select2(True, 1)
Выходим из цикла break
Выходим из всех циклов if boolean == 1: break
Создадим круговой массивswFeatMgr.FeatureCircularPattern4(6, 2*3.1416, False, "None", False, True, False)
Аргументы метода: 6 – количество элементов массива; 2*3.1416 – равный шаг по кругу; False – обратное направление; "None" – название углового размера, определяющего направление массива; False – геометрический массив; True – равный шаг; False - изменение размеров или интервалов между отдельными экземплярами
Снимем все выделенияswDoc.ClearSelection2(True)
В итоге получим фланец с отверстиями
Полный код:
# -*- coding: utf-8 -*-
#|SolidWorks
import pythoncom
from win32com.client import Dispatch, gencache
import win32com.client as win32
from win32com.client import VARIANT
VT_DISPATCH = win32.VARIANT(pythoncom.VT_DISPATCH, None)
#подключаемся к приложению SolidWorks
sw = win32.dynamic.Dispatch('SldWorks.Application')
#активный документ
swDoc = sw.ActiveDoc
#Менеджер дерева операций
swFeatMgr = swDoc.FeatureManager
#Менеджер эскизов
sketchMan = swDoc.SketchManager
#Менеджер выделенных объектов
swSelMgr = swDoc.SelectionManager
swSelData = swSelMgr.CreateSelectData
#Зададим плоскость для эскиза
face = "Спереди"
#Осуществим её выбор
selBool = swDoc.Extension.SelectByID2(face, "PLANE", 0, 0, 0, False, 0, VT_DISPATCH, 0)
#Выберем полученный эскиз
sketchMan.InsertSketch(True)
#Создадим внутри эскиза окружность с центром (xc,yc) и радиусом rad
sketchMan.CreateCircleByRadius(0, 0, 0, 0.05)
sketchMan.CreateCircleByRadius(0, 0, 0, 0.05/2)
#Создадим объект выдавливания
extrusion = swFeatMgr.FeatureExtrusion2(True, False, False, 0,0,0.02, 0, False, False, False, False, 0, 0, False,False, False, False, True, False, True,0, 0, False)
#Снимем все выделения
swDoc.ClearSelection2(True)
#Зададим плоскость для эскиза
face = "Спереди"
#Осуществим её выбор
selBool = swDoc.Extension.SelectByID2(face, "PLANE", 0, 0, 0, False, 0, VT_DISPATCH, 0)
#Выберем полученный эскиз
sketchMan.InsertSketch(True)
#Создадим внутри эскиза окружность с центром (xc,yc) и радиусом rad
sketchMan.CreateCircleByRadius(0, 0.035, 0, 0.005)
#Сделаем вырез
extrusion = swFeatMgr.FeatureCut3(False, False, False, 0, 0, 0.02, 0.02, False, False, False, False, 0, 0, False, False, False, False, False, True, True, True, True, False, 0, 0, False)
#Снимем все выделения
swDoc.ClearSelection2(True)
#Создадим круговой массив элементов
#Выделим последний вырез
selBool = extrusion.Select2(True, 4)
#Пройдёмся по элементам дерева, у каждого найдём грани, и выделим цилиндрическую грань с радиусом 0.05 м - это будет поверхность, вокруг которой создадим круговой массив
#Сперва зададим переменную, при изменении которой сразу выходим из всех циклов
boolean = 0
#В первом цикле идём по элементам дерева
for i in range(swFeatMgr.FeatureStatistics.FeatureCount):
feature = swFeatMgr.FeatureStatistics.Features[i]
#Во втором цикле идём по граням итерируемого элемента дерева
for j in range(feature.GetFaceCount):
face = feature.GetFaces[j]
#Получим интерфейс грани
surface = face.GetSurface
#Если поверхность является цилиндром и имеет радиус 0.05 м, то присваиваем переменной boolean значение 1
if surface.IsCylinder == True and surface.CylinderParams[6] == 0.05:
boolean = 1
#Выделяем грань
selBool = face.Select2(True, 1)
#Выходим из цикла
break
#Выходим из первого цикла
if boolean == 1:
break
#Создадим круговой массив
swFeatMgr.FeatureCircularPattern4(6, 2*3.1416, False, "None", False, True, False)
#Снимем все выделения
swDoc.ClearSelection2(True)
(соблюдайте отступы)
Вот интересно, написание таких макросов кому ни будь помогали в работе проектирования? Это наверное для программистов хорошо, для написания программ автоматизации (стороннего софта, на подобие "GearTraх" для шестерен, которая в свою очередь запускает солид в автоматическом режиме и чертит все по выбранным параметрам). Макросы будут работать по идее только с той версией, для которой написаны, по крайней мере тот-же "GearTraх" существует под разные версии, универсального нет и запускает он макросы только того солида для которого написан, вроде как-то так, у меня по крайней мере так, две проги автоматизации и каждая под свою версию солида.
Макрос работает практически на любой версии Компас. Суть в том, что в АПИ есть интерфейсы, которые созданы в ранних версиях, а есть те, которые созданы в поздних версиях. Конечно, если Вы применили какой-то интерфейс, который появился только в 22-й версии, то в 16-й он работать не будет. Но если Вы написали макрос в 16-м солиде, например, то в любом случае он будет работать на всех поздних версиях. И да, мне макросы помогают при проектировании. Я их пишу в основном для КОМПАС. Здесь можно посмотреть примеры https://vkvideo.ru/@python_macros/all
А за статью спасибо!
Макрос работет только с активной версией SolidWorks.
А Вы запустите макрос от имени админа и у вас он не подхватит запущенную версию SolidWorks..
А если в системе несколько версий Солидворкса?