Дескрипторы операций
Технологическая операция описывается одним большим ComplexType, унаследованным от
существующей операции, плюс небольшой регистрационной записью, объявляющей её системе. Эта
глава показывает анатомию операции на двух реальных файлах:
Operations/MillOperations/FaceMillingOp.xml
(поставляемая операция) и парном примере OperationSimpleNet.xml из репозитория
cam-api-examples (операция, траектория которой вычисляется расширением на C#).
Поставляемые файлы операций лежат в Operations\ и Operations\MillOperations\ и
подключаются через Operations.xml — используйте их как справочник.
Ваша собственная операция туда не помещается. Регистрируйте её одним из двух механизмов из
§7: положите файл
*_ExtOp.xml в общую папку контейнеров (подхватывается автоматически) либо укажите мастеру
Operations Manager (Utilities → Operations Manager) ваш XML‑файл операции. В любом случае
файл — это <SCCollection> в пространстве имён Operations и использует ровно тот
синтаксис, что показан ниже.
1 Две части
Чтобы добавить операцию, вы предоставляете:
- Регистрационную запись в пространстве имён
OperationRegistrator, чейTypeNameравенIDвашего типа операции. - Сам тип операции, унаследованный от существующей базовой операции.
<SCCollection>
<!-- 1. Регистрируем имя типа -->
<SCNameSpace ID="OperationRegistrator">
<SCType ID="RegTSTFaceMillingOp" type="TRegisterOperationRecord" Enabled="True">
<TypeName DefaultValue="TSTFaceMillingOp"/>
</SCType>
</SCNameSpace>
<!-- 2. Тип операции (его ID должен совпадать с TypeName выше) -->
<SCType ID="TSTFaceMillingOp" Caption="FaceMilling" type="TSTMillOp" Enabled="True">
...
</SCType>
</SCCollection>
(реальный пример: Operations/MillOperations/FaceMillingOp.xml)
Зачем нужна регистрационная запись
В системе может быть очень много дескрипторов. Пространство имён OperationRegistrator — это
небольшой быстрый индекс поиска: он перечисляет, какие XML‑типы действительно являются
технологическими операциями, чтобы система находила их напрямую, а не сканировала весь массив
дескрипторов. Запись — это просто TRegisterOperationRecord, чей TypeName указывает на ID
вашего типа операции. Если забыть запись, ваш тип существует, но не распознаётся как операция.
2 Выбор базового типа
Операции наследуют массу структуры (секция инструмента, подачи, врезания, симуляция, состояние станка, …) от цепочки базовых операций. Выберите базу, поведение которой ближе всего к вашему, и переопределяйте/расширяйте от неё:
| Базовый тип | Для чего |
|---|---|
TSTMillOp (семейство фрезерования) |
Фрезерные операции — например, от него наследуется TSTFaceMillingOp |
| База токарных операций | Токарные операции |
| База осевых / сверлильных | Сверление и осевые циклы |
TSTMillExtensionOp |
Операции, траектория которых вычисляется расширением CAM API (см. §3) |
Проще всего найти нужную базу, открыв поставляемую операцию, наиболее похожую на желаемую, и переиспользовав её базовый тип. Полное дерево наследования всех поставляемых операций — ID, подписи, родители, реализующие классы и исходные файлы — сведено в справочнике иерархии операций.
3 Заголовок операции
Ближе к началу типа операции вы переопределяете набор унаследованных «заголовочных» членов, которые идентифицируют и представляют операцию:
<SCType ID="TSTFaceMillingOp" Caption="FaceMilling" type="TSTMillOp" Enabled="True">
<GUID DefaultValue="{9F01E1A0-6F3E-4C7A-9C52-9A024CED54FF}"/>
<ContainerID DefaultValue="{F4DE00D1-7AE3-468E-BA5C-ED3C8275CBF8}"/>
<Name DefaultValue="FaceMilling"/>
<Comment DefaultValue="Face Milling"/>
<OperationGroup DefaultValue="Mill"/>
<Image DefaultValue="Images\FaceMilling.png"/>
<Icon DefaultValue="Images\FaceMilling_Ico.bmp"/>
<Video DefaultValue="Video\FaceMilling.wmv"/>
...
</SCType>
(реальный пример: Operations/MillOperations/FaceMillingOp.xml)
| Заголовочный член | Смысл |
|---|---|
GUID |
Уникальная постоянная идентичность типа операции. Генерируйте новый; никогда не переиспользуйте. |
ContainerID |
GUID класса Delphi‑контейнера, который представляет операцию в дереве операций (см. ниже). Обычно наследуется; переопределяйте только когда вашей операции нужен конкретный класс контейнера. |
SolverID |
Идентифицирует решатель, вычисляющий траекторию (см. ниже). Обычно наследуется. |
Name / Comment |
Имя для отображения и описание по умолчанию. |
OperationGroup |
Широкая технологическая группа, к которой относится операция (Mill, Lathe, …). |
Image / Icon / Video |
Иллюстрация, иконка в списке и обучающий ролик. |
Полезные атрибуты на самом элементе типа:
Enabled="True"— операция доступна. УстановитеFalse, чтобы поставлять её отключённой.DefaultVisibility="False"— специализированная операция остаётся загружаемой, но скрыта из меню по умолчанию.Version— версия схемы; увеличивайте её при изменении структуры операции, чтобы существующие сохранённые данные корректно мигрировали.
ContainerID и SolverID — контейнер, решатель и траектория
Эти два идентификатора описывают, как реализована операция. Понимание этого разделения помогает решить, что наследовать, а что переопределять.
ContainerID— класс контейнера. Это GUID класса Delphi, который представляет операцию в дереве операций CAM‑системы. Система создаёт экземпляр этого класса контейнера; затем контейнер строит экземпляр операции из XML‑дескриптора, владеет им и всеми его параметрами и является объектом, с которым общается остальная система.SolverID— (необязательный) решатель. Когда задан, контейнер создаёт отдельный подкласс‑решатель, идентифицируемыйSolverID, и этот решатель вычисляет траекторию. КогдаSolverIDне задан, отдельного решателя нет и класс контейнера вычисляет траекторию сам.
Почему существует это разделение (история). Изначально не было ни XML‑дескрипторов, ни отдельных решателей — операция была просто классом‑контейнером, определявшим всё своё поведение: свои параметры и вычисление траектории. XML‑дескрипторы (чтобы объявлять параметры декларативно) и решатели (чтобы вынести вычисление траектории, в том числе в расширения CAM API) были добавлены позже. Поэтому операция и сейчас может работать с одним лишь контейнером без решателя.
На практике вы наследуете и ContainerID, и SolverID от своего базового типа. Переопределяйте
ContainerID только когда вашей операции нужен конкретный класс контейнера; задавайте
SolverID, чтобы выбрать движок, вычисляющий траекторию.
SolverID принимает две формы:
GUID существующего встроенного класса‑решателя — переиспользовать движок, который система уже предоставляет:
<SolverID DefaultValue="{301F6C21-2499-4514-83D1-72A4931529BE}"/>Идентификатор написанного вами расширения CAM API — конкретно расширения
OperationSolver. ЗдесьSolverID— это строковыйidрасширения, а не GUID:<!-- из OperationSimpleNet.xml --> <SCType ID="TSimpleNetOP" Caption="Simple .NET" type="TSTMillExtensionOp" Enabled="True"> <GUID DefaultValue="{BDD2CAD7-D2A9-43C4-86E3-399FCB439FC0}"/> <SolverID DefaultValue="Extension.Operation.Simple.Net"/> ... </SCType>Тот же
idобъявлен в файле настроек расширения, в записиOperationSolver:// ExtensionOperationSimpleNet.settings.json "extensions": [ { "OperationSolver": { "id": "Extension.Operation.Simple.Net" } } ]Рабочие компилируемые расширения
OperationSolverлежат в репозиторииcam-api-examplesвOperation/(ExtensionOperationSimpleNet,ExtensionOperationParamsNet). Наследуйте такую операцию отTSTMillExtensionOp(или подходящей базы расширения), чтобы стандартная механика была подключена за вас.
Группировка в меню «новая операция» — MultiGroup
MultiGroup управляет тем, где операция появляется в дереве создания новой операции. Он
позволяет одной операции отображаться в нескольких группах сразу и позволяет разным
конфигурациям интерфейса (например, Beginner и Expert) помещать её в разные группы. Каждая
запись — это TLinkToParentMultiGroup, чей ID — целевая группа; OrderInGroup задаёт её
позицию внутри этой группы.
<MultiGroup>
<SCType ID="Group3DEntry" OrderInGroup="1" type="TLinkToParentMultiGroup"/>
<SCType ID="Roughing" OrderInGroup="1" type="TLinkToParentMultiGroup"/>
</MultiGroup>
(реальный пример: Operations/MillOperations/FaceMillingOp.xml)
Используйте MultiGroup + OrderInGroup для всякого размещения и упорядочивания в меню.
4 Добавление параметров
Параметры — это просто члены типа операции. Группируйте их под плейсхолдерами инспектора через
Parent, упорядочивайте, прикрепляйте иконку через ImageFile и делайте их динамическими
языком выражений из языка выражений.
<!-- перечисление, управляющее стратегией операции -->
<SCType ID="Strategy" Caption="Strategy" type="Enumerated" DefaultValue="Spiral"
ImageFile="$(SUPPLEMENT_FOLDER)\operations\TypeImages\FaceMillingStrategy.bmp">
<SCType ID="Spiral" Caption="Spiral" type="None"/>
<SCType ID="OptimZigzag" Caption="Optimized zigzag" type="None"/>
<SCType ID="Zigzag" Caption="Zigzag" type="None"/>
<SCType ID="OneWay" Caption="One way" type="None"/>
<SCType ID="OnePass" Caption="One pass" type="None"/>
</SCType>
<!-- значение под Strategy, показываемое только для некоторых стратегий -->
<SCType ID="Step" Caption="Step" type="TPercentageValue"
Parent="Strategy" Visible="[Strategy] != 4">
<ValueType DefaultValue="Percent"/>
<PercentValue DefaultValue="75"/>
</SCType>
(реальный пример: Operations/MillOperations/FaceMillingOp.xml)
Категории и плейсхолдеры
Параметры назначаются в категории инспектора и в плейсхолдеры — контейнеры, унаследованные
от базы, — через Category и Parent:
<SCType ID="LeadInDistance" Caption="Lead in" type="TPercentageValue"
Category="TPropertiesCategoryList.Leads" Parent="LeadsPlaceHolder"
ImageFile="$(SUPPLEMENT_FOLDER)\operations\TypeImages\FaceMillingLeadInDistance.bmp">
<PercentValue DefaultValue="10"/>
</SCType>
Parent="LeadsPlaceHolder" помещает эту строку под группирующий узел, заданный базовой
операцией, так что связанные параметры собираются вместе независимо от того, где они объявлены.
Переопределение унаследованных параметров
Поскольку ваша операция наследует полный набор параметров, бóльшая часть файла операции — это
переопределения унаследованных членов: подстройка значений по умолчанию, скрытие неприменимого
или повторное включение вариантов. Используйте форму переопределения (<MemberName .../>) из
§4.2:
<Stock Visible="False"/> <!-- скрыть унаследованный параметр -->
<ConditionsSection>
<Feeds>
<EngageFeed Enabled="False"/> <!-- отключить неприменимые подачи -->
<RetractFeed Enabled="False"/>
</Feeds>
</ConditionsSection>
5 Чек‑лист для новой операции
- Сгенерируйте новый
GUID. - Выберите
SolverID: GUID встроенного решателя илиidвашего расширения CAM APIOperationSolver(в этом случае наследуйте отTSTMillExtensionOp). - Добавьте регистрационную запись в
OperationRegistratorсTypeName=IDвашего типа. - Унаследуйте тип от ближайшей существующей базовой операции.
- Переопределите заголовочные члены (
Name,Comment,OperationGroup,Image,Icon,Video) и задайтеMultiGroupдля размещения в меню. - Объявите свои параметры стратегии и переопределите унаследованные по необходимости;
назначьте
Category/Parent, чтобы они попали в нужную группу инспектора. - Зарегистрируйте операцию — сохраните как
<YourName>_ExtOp.xmlв$(COMMON_CONTAINERS_FOLDER)либо добавьте через мастер Operations Manager (см. §7). Не редактируйте поставляемые файлы вSupplement. - Увеличивайте
Versionвсякий раз, когда позже меняете структуру.
Далее: Дескрипторы станков