Система визуализации ориентирована в первую очередь на отображение и визуальное редактирование графов, которые могут представлять из себя семантические сети, интеллект-карты, схемы и другие способы представления информации о предметной области.
Единицей отображаемой информации является СЦЕНА, которая может включать в себя элементы следующих разновидностей:
- кривые (класс TVCurl)
- объекты (класс TVObject) c портами (класс TVPort)
- выноски (класс TVCallout)
- соединения (класс TVConnection) с портами соединений (класс TVConnectionPort)
- группы (класс TVGroup)
- маркеры/метки/ручки/управляющие точки (класс TVSelHandle)
Изображение элемента строится путем выполнения графических команд, хранящихся в дисплейных списках.
Для объектов Дисплейный список генерируется для
Формат представления элементов сцены на диске и в памяти различен:
дисплейный список, артибуты
КРИВЫЕ предназначены для временного хранения информации о графических примитивах, ещё не объединенных в объекты. Предполагается, что в законченном документе кривых не будет.
Класс, описывающий кривую, содержит её имя, оболочку, дисплейный список (список команд которые дожны быть выполнены drawer'ом для отрисовки) и флаги, определяющие необходимость отрисовки - если кривая находится вне экрана или слишком мала.
Модуль TPG определяет структуры данных, описывающие точку в двумерном пространстве и матрицы для преобразований сдвига, поворота, масштабирования и комбинации преобразований, а также объект Drawer, который объединяет в себе полотно для рисования, параметры видового преобразования (между мировой и экранной системами координат), режимы рисования и интерпретатор команд отрисовки.
на данный момент поддерживаются следующие команды
Set имя переменной=значение
Unset имя переменной
SetColor имя цвета - выставляет цвет пера в указанный, если EnforcedPenColor=clNone
SetWidth толщина линии
SetBGColor имя цвета - выставляет цвет фона в указанный, если EnforcedBrushColor=clNone
SetFont имя шрифта,размер,цвет,флаги BIUS
FloodFill x,y,цвет - заливка
Ellipse x1,y1,x2,y2
LineTo x,y
MoveTo x,y
Rect x1,y1,x2,y2
RoundRect x1,y1,x2,y2
Circle x,y,r
TextOut x,y,текст - выводит строку в указанном месте текущим стилем, если EnforcedPenStyle=psClear
Bmp x,y,имя файла
SubPicture x,y,a,s,имя картинки - генерирует дочерний Drawer, с указанным сдвигом/поворотом/масштабом и выполняет прочитанный дисплейный список из файла
SetTextStyle transparent - transparent или opaque
SetPenStyle стиль - если EnforcedPenStyle=psClear, то ставит один из ледующих стилей psSolid,psDash,psDot,psDashDot,psDashDotDot,psinsideFrame,psPattern,psClea;
SetScaledFont имя шрифта, размер,цвет,флаги BIUS - Canvas.Font.Height:=Round(StrToFloat(FontSize)/Self.ViewScale);
Unscaled x,y,Имя,r - должен рисовать немасштабный знак по имени, сейчас рисует желтый квадрат в красной рамке, которым обозначаются порты
TextRect x1,y1,x2,y2,CommaText - выводит многострочный текст, если EnforcedPenStyle=psClear и Canvas.Font.Height>5
TDrawer = Class(TObject)
Updated:Boolean;
AxisMode:Longint; // 0 - math mote (0-center, 0Y - up), 1 - GUI mode (0 left-top corner, 0Y - down)
ViewScale:Extended; // Scale measured in meters per pixel
ViewX,ViewY:Extended; // Origin of view (meters)
ViewAngle:Extended; // -azimuth of view, north by default
TransM,RTransM:TMatrix2D;
Canvas:TCanvas;
Wx,Wy:Longint; // canvas size in pixels used for flip vertical axis
PrintMultiplier:Longint; // multiply pen width for printing
PenColor:TColor;
EnforcedPenColor:TColor;
BrushColor:TColor;
EnforcedBrushColor:TColor;
EnforcedPenStyle:TPenStyle;
PenWidth:Longint;
VarList:TStringList; // list of pairs variable=value
Resolver:TStringList; // convertor of names to displaylists
Constructor Create(wCanvas:TCanvas);
Destructor Destroy;
Procedure RecalcMatrix; //
Procedure StoW(Xs,Ys:Longint;Var Xw,Yw:Extended); //convert screen to world coords
Procedure WtoS(Var Xw,Yw:Extended;Var Xs,Ys:Longint); //convert world to screen coords
Procedure ExecCommand(Command:string;AcceleratedCommand:TAcceleratedCommand);
Function ParseLine(Data:String):String;
End;
Здесь же описана ОБОЛОЧКА - объемлющий прямоугольник, применяемы для оценки видимости
TShell=Record
X1,X2,Y1,Y2:Extended;
End;
и УСКОРИТЕЛЬ - способ избежать многократного разбора строки дисплейного списка и входящего туда преобразования координат из строки в вещественное число
TAcceleratedCommand=Array[1..5] Of Extended;
ZeroAcc: TAcceleratedCommand=(0,0,0,0,0);
Основной способ использования объекта Drawer - исполнение команд дисплейных списков через метод
TDrawer.ExecCommand(Command:String;AcceleratedCommand:TAcceleratedCommand)
Если у нас есть команда которая в дальнейшем будет исполняться многократно - ускорение осуществляется, например, так:
AccObject:=TAccObject.Create;
NonAccCommand:='SetScaledFont '+FontDialog.Font.Name+','+FloatToStr(FontDialog.Font.Height*ScaleEdit.Value)+','+ColorToString(FontDialog.Font.Color)+','+bius;
AccObject.AcceleratedCommand:=AccelerateCommand(NonAccCommand);
Curl.DisplayList.AddObject(NonAccCommand,AccObject);
"Одноразовая" команда, например установка цвета фона при перерисовке может быть выполнена без ускорения следующим образом:
Drawer.ExecCommand('SetBGColor '+ColorToString(Form1.SceneBGColorButton.ButtonColor),ZeroAcc);
Модуль CADEngine определяет структуры данных, позволяющие хранить и оперировать данными о СЦЕНЕ, состоящей из КРИВЫХ, ОБЪЕКТОВ, СВЯЗЕЙ между объектами и ВЫНОСОК - подписей к объектам.
Для связи у другими объектами используется ПОРТ.
Класс, описывающий сцену, содержит флаги, управляющие отображением имен объектов, имен портов, объемлющих прямоугольников, атрибуты управления отсечением невидимых примитивов,
списки кривых, объектов, выносок, связей, шаблонов, групп
объект Drawer и интерпретатор команд отрисовки, который на данный момент
выполняет следующие команды
DrawCurl имя кривой если включено отсечение невидимого, то не рисуются элементы с флагом "вне экрана" и "слишком мелкий" в цикле передает дисплейный список на Drawer Сцены
DrawTemplate имя шаблона,X,Y,A,S - не рисует если уровень вложенности шаблонов больше заданного
порождает временный Drawer, использующий координаты вставки, масштаб и поворот шаблона для всех команд кроме Unscaled
DrawObject имя объекта - не рисует объекты, принадлежащие группам с включенным атрибутом "невидимый", если включено отсечение невидимого - не рисует объекты с флагом "вне экрана" и "слишком мелкий"
порождает временный Drawer, использующий координаты вставки, масштаб и поворот объекта для всех команд кроме DrawTemplate
DrawConnection имя соединения - не рисует соединения, принадлежащие группам с включенным атрибутом "невидимый", если включено отсечение невидимого - не рисует связи к объектам с флагом "вне экрана" и "слишком мелкий"
DrawCallout имя выноски - не рисует выноски, принадлежащие группам с включенным атрибутом "невидимый", если включено отсечение невидимого - не рисует выноски, привязанные к объектам с флагом "вне экрана" и "слишком мелкий"
нераспознанные команды передает интерпретатору Drawer'а
TVScene=Class(TObject)
ShowObjectNames:Boolean;
ShowPortNames:Boolean;
ShowShells:Boolean;
VObjectList:TStringList; // List of Objects
VGroupList:TStringList; // List of groups of display commands - group is that moved together
VTemplateList:TStringList; // List of models - what's the difference between curl and template???
VCurlList:TStringList; // List of uncompleted objects
VConnectionList:TStringList; // List of connections between objects
VCalloutList:TStringList; // List of text comments for objects
VHandleList:TStringList; // List of handles for selected objects
View:TStringList; // Master display list used for visualization - sequence of drawing
Drawer:TDrawer;
Clip:Boolean;
ClipMax:Boolean;
ClipSize:Longint;
MaxDisplayedDepth:Longint;
ScreenShell:TShell;
Constructor Create;
Destructor Destroy;
Procedure SaveFile(FileName:String);
Procedure LoadFile(FileName:string);
Procedure UpdateVisibility;
Procedure Clear;
Procedure ExecCommand(Command:String;Acc:TAcceleratedCommand;Depth:Longint);
Function BuildCurlsUnder(X,Y:Extended):TStringList;
Function BuildObjectsUnder(X,Y:Extended):TStringList;
Function BuildConnectionsUnder(X,Y:Extended):TStringList;
Function BuildCalloutsUnder(X,Y:Extended):TStringList;
end;
КРИВЫЕ предназначены для временного хранения информации о графических примитивах, ещё не объединенных в объекты. Предполагается, что в законченном документе кривых не будет.
Класс, описывающий кривую, содержит её имя, оболочку, дисплейный список (список команд которые дожны быть выполнены drawer'ом для отрисовки) и флаги, определяющие необходимость отрисовки - если кривая находится вне экрана или слишком мала.
TVCurl=Class(TObject)
Name:String;
Shell:TShell;
DisplayList:TStringList;
OffScreen:Boolean;
TooSmall:Boolean;
Constructor Create;
Destructor Destroy;
End;
ОБЪЕКТЫ имеют имя, координаты точки вставки, масштаб, угол поворота и дисплейный список.
Диплейный список может состоять из единственной команды отрисовки шаблона или из автогенерируемого списка, реализующего один из стандартных типов объектов: прямоугольник, прямоугольник со скругленными углами, эллипс.
Стиль объекта "ШАБЛОН"
Object name:Object0
X:0.1778
Y:0.5334
A:0
S:1
DisplayList lines:1
DrawTemplate 2U_Asus_24x25 0,0,0,1
PortList lines:0
NonPortConnectionList lines:0
GroupList lines:0
ActionList lines:0
Стиль объекта - прямоугольник
Object name:Object2
X:0
Y:0
A:720
S:1
DisplayList lines:4
SetColor clBlack
SetBGColor $008F8F8F
SetWidth 1
Rect -0.3556,2.35585,0.3556,2.00025
PortList lines:0
NonPortConnectionList lines:0
GroupList lines:0
ActionList lines:0
Прямоугольник со скругленными углами - 1080
Эллипс - 1440
TVObject=Class(TOBject)
Name:String;
X,Y,A,S:Extended;
DisplayList:TStringList;
OffScreen:Boolean;
TooSmall:Boolean;
Shell:TShell;
OType:Longint; // 0 - just object, 1 - textout, 2 - binary link
PortList:TStringList;
NonPortConnectionList:TStringList;
GroupList:TStringList;
RelatedCAList:TStringList;
ActionList:TStringList;
Constructor Create;
Destructor Destroy;
End;
объект с портами без связи
Object name:Object2
X:0
Y:0
A:720
S:1
DisplayList lines:4
SetColor clBlack
SetBGColor $008F8F8F
SetWidth 1
Rect -0.3556,2.35585,0.3556,2.00025
PortList lines:2
Name=port1 AR=R X=0.1875 Y=0.375 Conn= Port=
Name=port2 AR=R X=0.875 Y=-1.875 Conn= Port=
NonPortConnectionList lines:0
GroupList lines:0
ActionList lines:0
Отличия у объекта с подключенной связью
Name=port1 AR=R X=0.1875 Y=0.375 Conn=Connection0 Port=Start
Name=port2 AR=R X=0.875 Y=-1.875 Conn= Port=
Описание связи
Connection name:Connection0
X:0
Y:0
StartObj:Object2
EndObj:Object3
Style:Color=clBlack BGColor=$008F8F8F Width=1
GroupList lines:0
PortList lines:2
PortType=Start AR=R X=0 Y=0 Conn=Object2:port1
PortType=End AR=R X=100 Y=100 Conn=Object3:port1
Объекты, связи и подписи могут принадлежать к группам, управляющим совместным перемещением, видимостью и возможностью взаимодействовать с мышью для своих членов.
возможно рисование шаблонов, в том числе вложенное
Image1.Paint (описано в основной программе)
DrawScene(Drawer:TDrawer) - рисует на экран или на принтер (описано в основной программе)
Засекает время
Вычисляет оболочку экрана (в мировых координатах)
Устанавливает нормальный режим рисования
Очищает фон
Рисует сетку, если надо
Рисует оси, если надо
Вызывает Scene.ExecCommand для каждой строки в Scene.View
Устанавливает инверсный режим рисования
Повторяет Scene.ExecCommand('DrawCurl ') для выделенных в GUI кривых
Повторяет Scene.ExecCommand('DrawObject ') для выделенных в GUI объектов
Повторяет Scene.ExecCommand('DrawConnection ') для выделенных в GUI соединений
Устанавливает нормальный режим рисования
Рисует связи, вызывая Scene.ExecCommand('DrawConnection ') для каждого из списка соединений
Рисует подписи если надо, вызывая Drawer.ExecCommand('TextOut ') кривых, затем объектов и портов объектов
TVScene.ExecCommand(команда, акселератор, глубина) (описано в модуле CADEngine)
для кривых
отсекает внеэкранные и мелкие, если надо
для каждой команды из дисплейного списка вызывает Drawer.ExecCommand
Если надо - дорисовывает оболочку
для связей
проверяет членство в невидимых группах
если включено отсечение - отсекает связи к невидимым объектам (мелким или принадлежащим к невидимым группам), внеэкранные связи
для каждой команды из дисплейного списка вызывает Drawer.ExecCommand
Если надо - дорисовывает оболочку
для объектов
проверяет членство в невидимых группах
отсекает внеэкранные и мелкие, если надо
применяет опреации поворота-сдвига-масштабирования объекта
для каждой команды из дисплейного списка вызывает Drawer.ExecCommand для команд DrawTemplate - вызывает ExecCommand(DebugC,ZeroAcc,Depth);
Если надо - дорисовывает оболочку
для шаблонов
проверяет предельную глубину
отсекает рисование шаблонов со слишком маленькой оболочкой
для каждой команды из дисплейного списка вызывает Drawer.ExecCommand для команд DrawTemplate - вызывает ExecCommand(DebugC,ZeroAcc,Depth+1);
иначе - передаёт в Drawer.ExecCommand
TVScene.UpdateVisibility (описано в модуле CADEngine)
пересчитывает флаги "слишком мелкий" и "вне экрана" для кривых и объектов
Пересчитать оболчку экрана
Drawer.Canvas.Pen.Mode:=pmCopy;
Drawer.EnforcedPenColor:=clNone;
Drawer.EnforcedPenStyle:=psClear;
Drawer.Canvas.Pen.Style:=psSolid;
Drawer.EnforcedBrushColor:=clNone;
Нарисовать фон
Если надо - то сетку
Если надо - то оси
Выполнить основной дисплейный список (в нём описана последовательность отрисовки только кривых и объектов)
Scene.ExecCommand(Scene.View[I],ZeroAcc,0);
{раньше подсветка выделенный кривых и объектов выполнялась форсированным цветом или режимом NotCopy
теперь вокруг выделенного создаются точки}
Выполнить отрисовку всех выносок по порядку с помощью Scene.ExecCommand('DrawCallout '+Scene.VCalloutList[I],ZeroAcc,0);
Выполнить отрисовку всех связей по порядку с помощью Scene.ExecCommand('DrawConnection '+Scene.VConnectionList[I],ZeroAcc,0);
Подсветить выделенные связи через Drawer.Canvas.Pen.Mode:=pmNotCopy;
Если надо - выполнить отрисовку подписей к кривым и объектам посередине их оболочки
Если надо - выполнить отрисовку подписей к портам объектов
Drawer.Canvas.Pen.Mode:=pmXor;
Нарисовать SelHandle'ы не повторяясь несколько раз по одному месту с помощью Drawer.ExecCommand('Unscaled '+FloatToStr(SelHandle.Xw)+','+FloatToStr(SelHandle.Yw)+',LT,5',ZeroAcc);