Как поворачивать (перемещать) детали в сборке с помощью макроса SW
Условие. Открыт файл сборки. В нем есть свободный компонент (незафиксированная деталь). Выделяем эту деталь, запускаем макрос, и она становится в нужное нам положение.
Для изменения положения (поворота или перемещения) компонента в сборке существует свойство Transform2 интерфейса IComponent2. Свойство позволяет работать с так называемой математической матрицей трансформации. Звучит серьезно, но на самом деле ничего сложного нет.
Матрица Трансформации (MathTransform) – массив чисел, которые определяют положение детали в сборке.
В представлении SW api это выглядит следующим образом.
Первые 9 элементов (a, b, c, d, e, f, g, h, i) отвечают за поворот детали, следующие 3 (j, k, l) за перемещение. Следующий m – масштабный фактор. Последние (n, o, p) – не используются в данном контексте.
Теперь подробнее.
Поворот
Первые три числа (a, b, c) – поворот детали относительно оси X. Или, что более правильно, положение осей детали относительно оси X сборки. Другими словами:
o a – это косинус угла между осью X детали и осью X сборки.
o b – это косинус угла между осью Y детали и осью X сборки.
o c – это косинус угла между осью Z детали и осью X сборки.
Следующий ряд (d, e, f) – аналогично.
o d – это косинус угла между осью X детали и осью Y сборки.
o e – это косинус угла между осью Y детали и осью Y сборки.
o f – это косинус угла между осью Z детали и осью Y сборки.
Наконец, ряд3 (g, h, i).
o g – это косинус угла между осью X детали и осью Z сборки.
o h – это косинус угла между осью Y детали и осью Z сборки.
o i – это косинус угла между осью Z детали и осью Z сборки.
Перемещение
Числа j, k, l (9, 10, 11 элементы массива) определяют вектор перемещения нулевой точки детали, относительно нулевой точки сборки. Или сказать по-другому, вектор перемещения это – вектор, направленный от нулевой точки сборки к нулевой точке детали, а числа j, k и l – это проекции данного вектора на оси X, Y, Z сборки.
o j – косинус угла между вектором перемещения и осью X сборки.
o k – косинус угла между вектором перемещения и осью Y сборки.
o l – косинус угла между вектором перемещения и осью Z сборки.
Свойство Transform2 позволяет прочитать или записать матрицу трансформации компонента, как объект класса IMathTransform.
Чтобы прочитать данные с этого объекта (массив тех самых чисел), надо воспользоваться свойством ArrayData интерфейса IMathTransform.
Свойство позволяет получить или передать массив чисел для матрицы трансформации компонента.
Примерный порядок работы для изменения положения детали в сборке.
· Получить доступ к компоненту.
· Получить его матрицу трансформации (Transform2)
· Прочитать данные с матрицы (ArrayData)
· Поменять те значения, которые нам нужны и переписать матрицу (ArrayData)
· Передать новую матрицу трансформации в компонент (Transform2)
Рассмотрим пример.
Задача. Есть деталь в свободном положении в сборке. Она выделена. Надо чтобы она встала точно по центру. Точка ноль детали – совпадает с нулевой точкой сборки. Ось X детали совпадает по на правлению с осью X сборки и т. д.)
Visual Basic
Option Explicit Dim swApp As SldWorks.SldWorks Dim model As ModelDoc2 Dim assem As AssemblyDoc Dim sel As SelectionMgr Dim comp As Component2 Dim transform As MathTransform Dim dataTransform As Variant
Option Explicit Dim swApp As SldWorks.SldWorks Dim model As ModelDoc2 Dim assem As AssemblyDoc Dim sel As SelectionMgr Dim comp As Component2 Dim transform As MathTransform Dim dataTransform As Variant |
Объявляем необходимые переменные.
o comp – объект для хранения компонента (детали) сборки.
o transform – объект для хранения матрицы трансформации компонента сборки.
o dataTransform – объект для хранения массива значений матрицы трансформации.
Visual Basic
Sub main() Set swApp = Application.SldWorks Set model = swApp.ActiveDoc Set assem = model Set sel = model.SelectionManager Set comp = sel.GetSelectedObjectsComponent3(1, -1)
Sub main() Set swApp = Application.SldWorks Set model = swApp.ActiveDoc Set assem = model Set sel = model.SelectionManager Set comp = sel.GetSelectedObjectsComponent3(1, -1) |
Получаем доступ с компоненту.
Метод GetSelectedObjectsComponent3(1, -1) интерфейса ISelectionMgr, похож на метод GetSelectedObject6, только предназначен для работы с компонентами сборки.
[IComponent2] = [ISelectionMgr]. GetSelectedObjectsComponent3(Index, Mark)
o Index – номер выделенного элемента. Отсчет начинается с 1.
o Mark – числовая отметка объекта.
§ -1 – выделять все объекты, несмотря на марки
§ 0 – выделять только объекты без марок
Visual Basic
Set transform = comp.Transform2 dataTransform = transform.ArrayData
Set transform = comp.Transform2 dataTransform = transform.ArrayData |
Получаем объект матрицы трансформации компонента и считываем с него данные.
Теперь надо записать новые значения для матрицы:
Положение осей детали относительно оси X сборки:
Visual Basic
dataTransform(0) = 1 dataTransform(1) = 0 dataTransform(2) = 0
dataTransform(0) = 1 dataTransform(1) = 0 dataTransform(2) = 0 |
Положение осей детали относительно оси Y сборки:
Visual Basic
dataTransform(3) = 0 dataTransform(4) = 1 dataTransform(5) = 0
dataTransform(3) = 0 dataTransform(4) = 1 dataTransform(5) = 0 |
Положение осей детали относительно оси Z сборки:
Visual Basic
dataTransform(6) = 0 dataTransform(7) = 0 dataTransform(8) = 1
dataTransform(6) = 0 dataTransform(7) = 0 dataTransform(8) = 1 |
Координаты вектора перемещения (0, 0, 0) – нулевая точка детали совпадает с нулевой точкой сборки.
Visual Basic
dataTransform(9) = 0 dataTransform(10) = 0 dataTransform(11) = 0
dataTransform(9) = 0 dataTransform(10) = 0 dataTransform(11) = 0 |
Записываем новые данные в матрицу и передаем матрицу в компонент.
Visual Basic
transform.ArrayData = dataTransform comp.Transform2 = transform End Sub
transform.ArrayData = dataTransform comp.Transform2 = transform End Sub |
Итого. Положение компонента в сборке полностью определяется матрицей трансформации.
Определить в уме как должна поменяться матрица трансформации в зависимости от положения детали достаточно сложно. Потому что изменение положения относительно одной оси ведет к изменениям относительно других осей.
Проще, наверное, вручную расположить деталь нужным образом и затем прочитать её матрицу трансформации. Например, так:
Visual Basic
Set comp = sel.GetSelectedObjectsComponent3(1, -1) Set transform = comp.Transform2 dataTransform = transform.ArrayData Dim el For Each el In dataTransform Debug.Print el Next el
Set comp = sel.GetSelectedObjectsComponent3(1, -1) Set transform = comp.Transform2 dataTransform = transform.ArrayData Dim el For Each el In dataTransform Debug.Print el Next el |
Как получить список всех деталей в сборке с помощью макроса
Условие. Открыт файл сборки. Запускаем макрос и в Immediate окне появляется список всех деталей сборки.
В справке SW api рекомендуется следующая последовательность действий для обхода деталей сборки.
1. Получаем доступ к определенной конфигурации сборки. Например с помощью метода GetConfigurationByName интерфейса IModelDoc
2. Получаем доступ к корневому элементу дерева сборки. Метод GetRootComponent3 интерфейса IConfiguration.
3. Получаем все дочерние элементы от корневого. Метод GetChildren интерфейса IComponent2.
Попробуем реализовать все это в коде.
Visual Basic
Option Explicit Dim swApp As SldWorks.SldWorks Dim model As ModelDoc2 Dim assem As AssemblyDoc Dim rootComp As Component2 Dim config As Configuration
Option Explicit Dim swApp As SldWorks.SldWorks Dim model As ModelDoc2 Dim assem As AssemblyDoc Dim rootComp As Component2 Dim config As Configuration |
Объявляем переменные.
rootComp – объект класса Component2. Для хранения корневого элемента сборки.
Visual Basic
Sub main() Set swApp = Application.SldWorks Set model = swApp.ActiveDoc Set assem = model
Sub main() Set swApp = Application.SldWorks Set model = swApp.ActiveDoc Set assem = model |
Получаем доступ к интерфейсу сборки.
Visual Basic
Set config = model.ConfigurationManager.ActiveConfiguration
Set config = model.ConfigurationManager.ActiveConfiguration |
Получаем доступ к активной конфигурации сборки.
Visual Basic
Set rootComp = config.GetRootComponent3(True) Debug.Print rootComp.Name2
Set rootComp = config.GetRootComponent3(True) Debug.Print rootComp.Name2 |
Получаем корневой элемент сборки. Узнаем его имя с помощью свойства Name2 интерфейса IComponent2.
Visual Basic
Call infoParts(rootComp)
Call infoParts(rootComp) |
Вызываем функцию для обхода дочерних компонентов корневого элемента.
Visual Basic
Function infoParts(comp As Component2) Dim varComp As Variant Dim elem varComp = comp.getChildren If arrIsEmpty(varComp) = False Then Debug.Print "под-сборка:" For Each elem In varComp If elem.GetSuppression <> 0 And elem.IsPatternInstance = False Then Debug.Print elem.Name2 End If Set comp = elem infoParts comp Next End If End Function
Function infoParts(comp As Component2) Dim varComp As Variant Dim elem varComp = comp.getChildren If arrIsEmpty(varComp) = False Then Debug.Print "под-сборка:" For Each elem In varComp If elem.GetSuppression <> 0 And elem.IsPatternInstance = False Then Debug.Print elem.Name2 End If Set comp = elem infoParts comp Next End If End Function |
Функция infoParts в качестве параметра принимает ссылку на компонент сборки. Рассмотрим её код:
Visual Basic
Dim varComp As Variant Dim elem
Dim varComp As Variant Dim elem |
varComp – объект для хранения массива компонентов
Visual Basic
varComp = comp.getChildren
varComp = comp.getChildren |
Метод getChildren позволяет получить все дочерние элементы указанного компонента. Возвращает массив компонентов. Дети детей (если они есть) не передаются. Для каждой подсборки надо вызывать этот метод снова.
Visual Basic
If arrIsEmpty(varComp) = False Then
If arrIsEmpty(varComp) = False Then |
Для определения не пустоты массива используем функцию:
Visual Basic
Function arrIsEmpty(arr As Variant) As Boolean Dim u As Integer On Error Resume Next u = UBound(arr) If Err = 0 And UBound(arr) <> -1 Then arrIsEmpty = False Else arrIsEmpty = True End If End Function
Function arrIsEmpty(arr As Variant) As Boolean Dim u As Integer On Error Resume Next u = UBound(arr) If Err = 0 And UBound(arr) <> -1 Then arrIsEmpty = False Else arrIsEmpty = True End If End Function |
Подробнее см. пост: Работа с массивами в VBA.
Visual Basic
For Each elem In varComp If elem.GetSuppression <> 0 And elem.IsPatternInstance = False Then Debug.Print elem.Name2 End If Set comp = elem infoParts comp Next
For Each elem In varComp If elem.GetSuppression <> 0 And elem.IsPatternInstance = False Then Debug.Print elem.Name2 End If Set comp = elem infoParts comp Next |
Если массив «детей» не пустой, тогда обходим его с помощью цикла for Each.
Visual Basic
If elem.GetSuppression <> 0 And elem.IsPatternInstance = False Then
If elem.GetSuppression <> 0 And elem.IsPatternInstance = False Then |
Проверяем, что компонент не погашен и не является элементом массива.
Для каждого компонента снова вызываем нашу функцию infoParts. Получается рекурсивный вызов.
В итоге должно получиться что-то вроде этого:
Обратите внимание, как указывается имя детали в подсборке.