Сущности внутри EXPRESS схемы описываются с помощью типа ENTITY, в стандарте 10303-22 ему соответствует название класса entity_definition, а в имплементации СИДД с привязкой к языку C++ используется класс Entity. Наиболее близким к Entity понятием, например, в языке C++ является класс. Entity так же может быть абстрактной (атрибут instantiable в состоянии TRUE будет указывать на то что внутри модели можно создать объекты этого типа, а значение FALSE говорит о том, что это абстрактный тип данных, объекты которого не могут быть созданы и добавлены в модель). Распространённой ошибкой бесплатных СИДД-подобных реализаций является возможность создания абстрактных объектов и размещение их внутри модели, что влечёт за собой распространение ошибочных с этой точки зрения STEP-файлов, например, это частая проблема для файлов формата IFC для которого существует множество открытых реализаций.
У каждой entity_definition может быть набор атрибутов трёх видов:
- Явные атрибуты (explicit_attribute) – атрибуты указанного типа которые можно назначить и получить с помощью функций sdaiGetAttr/sdaiGetAttrBN и назначить с помощью функций sdaiPutAttr/sdaiPutAttrBN в реализации СИДД для языка C и с помощью методов Application_instance getAttr(BN) и putAttr(BN).
- Инверсные атрибуты (inverse_attribute) – всегда являются обратными ссылками на другие объекты в модели. Инверсный атрибут может быть как просто ссылкой на другой объект, так и аггрегейтом таких ссылок (SET или BAG). После загрузки модели из файла происходит решение инверсных атрибутов, т.е. объекты проставляют ссылку на самих себя в инверсные атрибуты тех объектов, на которые они ссылаются напрямую из своих явных (explicit) атрибутов.
- Вычисляемы атрибуты (derived_attribute) – атрибуты, вычисляемые интерпретатором подмножества языка EXPRESS в момент вызова getAttr, если конкретная имплементация СИДД поддерживает вычисляемые атрибуты и интерпретацию исходного кода EXPRESS.
Для примера, рассмотрим описание двухмерной точки на языке EXPRESS, у объектов Point будет всего две координаты, X и Y вещественного типа:
ENTITY Point; X : REAL; Y : REAL; END_ENTITY;
Геометрические объекты будут располагаться на холсте (Canvas), у которого обязательно должно быть название, строка длиной не более 64 символов:
ENTITY Canvas; Name : STRING (64); Curves : LIST [?:?] OF Curve; END_ENTITY;
Следующая запись является описанием базовой сущности для всех объектов геометрических кривых. У каждого из наследников этого класса будет явное, но опциональное, строковое поле Name для хранения имени и инверсный атрибут Context, в который каждое из хранилищ для геометрических кривых будет самостоятельно проставлять обратную ссылку на самого себя сразу после загрузки STEP-файла. Флаг OPTIONAL строкового поля Name означает, что значение данному атрибуту может остаться не назначенным (unset). Т.к. тип помечен как абстрактный, объекты этого типа не могут быть созданы в модели, чего нельзя сказать о его наследниках:
ENTITY Curve ABSTRACT SUPERTYPE OF (ONEOF(Polyline, Circle)); Name : OPTIONAL STRING; INVERSE Context : Canvas FOR Curves; END_ENTITY;
Первый наследник Curve, класс Polyline, будет задаваться двумя и более точками, ссылки на которые будут храниться в упорядоченном контейнере типа LIST, так как важна последовательность их отрисовки:
ENTITY Polyline SUBTYPE OF (Curve); Points : LIST [2:?] OF Point; END_ENTITY;
И наиболее интересным объектом из всей иерархии станет описание для окружностей (Circle). У каждой окружности будет следующие явные атрибуты: Center – ссылка на объект Point, соответствующий центру окружности, и радиус в поле Radius. Вычисляемый атрибут Diameter может быть использован для расчёта диаметра окружности средствами языка EXPRESS (если они поддерживаются в имплементации СИДД), а атрибут Len при запросе вернёт рассчитанную интерпретатором EXPRESS длину окружности. Кроме явных и рассчитываемых атрибутов на объекты класса Circle наложено ограничение Where Rule с идентификатором RadiusMoreThanZero, которое утверждает, что у валидной окружности значение её поля Radius должно быть строго больше нуля. На работу с объектом это не влияет, но нарушение данного ограничения может быть обнаружено в процессе валидации модели, но, опять же, если данная функциональность поддерживается реализацией СИДД:
ENTITY Circle SUBTYPE OF (Curve); Center : Point; Radius : REAL; DERIVE Diameter : REAL := Radius * 2.; Len : REAL := Diameter * PI; WHERE RadiusMoreThanZero : Radius > 0.; END_ENTITY;
После манипуляций над моделью с помощью СИДД, можно получить, например, вот такой набор данных в STEP-файле, после загрузки которого из инверсного атрибута Curve.Context будет храниться ссылка на объект #8. Инверсные атрибуты не сохраняются в обменной структуре (впрочем, как и рассчитываемые атрибуты), но вычисляются сразу после загрузки модели из файла:
DATA; #1=POINT(0.,0.); #2=POINT(1.,0.); #3=POINT(1.,1.); #4=POINT(0.,1.); #5=POLYLINE('Square',(#1,#2,#3,#4,#1)); #6=POINT(0.5,0.5); #7=CIRCLE('Circle within square',#6,0.5); #8=CANVAS('Square with internal circle',(#5,#7)); ENDSEC;
Глядя на содержимое секции данных не трудно догадаться, что данная модель описывает геометрию квадрата со стороной 1 со вписанной в него окружностью радиуса 0.5.
В данной статье представлено описание простой иерархии объектов с помощью языка EXPRESS. В одном из следующих материалов будет рассказано как создавать более сложные иерархии типов с использованием сложных сущностей (Complex Entity).