« Предыдущая Следующая »

4. Технологическая часть

4.1 Методика подготовки к ИЭТР

В связи с ориентацией разрабатываемых в рамках проекта средств ИЭТР на работу в сетях Internet / Intranet и так называемую технологию «тонкого клиента» возникают две проблемы – проблема работы с большими файлами модели, связанная с ограниченной скоростью передачи данных по сетевым каналам и проблема отображения комплексных моделей, имеющих огромное число геометрических примитивов, в сетевых клиентских приложениях, связанная с спецификой работы стандартных браузеров.

Особенно остро эти проблемы стоят при работе с комплексными трехмерными моделями зданий. Существуют комплексные методы решения данных проблем, которые с одной стороны заключаются в оптимизации алгоритмов отображения трехмерной графики, а с другой стороны заключаются в оптимизации самих трехмерных моделей. Оптимизация моделей состоит в упрощении ее геометрии, и исключении из нее мелких объектов, необходимость работы с которыми возникает только в конкретных и достаточно редких случаях. Таким образом идея оптимизации сводится к созданию нескольких вариантов одной и той же модели, имеющих различную степень детализации (см. рисунок).

При работе с такой моделью в рамках конкретного ИЭТР приложения в общем случае для поверхностной навигации может использоваться наименее детализированная, грубая модель, имеющая только внешние контуры здания упрощенной формы (набор призм формирующих его основные геометрические формы, с наложенными на них текстурами фасадов), далее при приближении камеры к конкретному зданию может подгружаться следующая степень детализации модели (детальный внешний вид здания, содержащий точные модели окон, дверей, крыш, фронтонов и т.д.), при выборе же здания должна подгружаться наиболее детальная его модель, содержащая внутреннюю планировку, отделку и объектное наполнение, при этом модели остальных зданий комплекса могут вообще выгружаться из сцены и из памяти.

ИЭТР

Исходя из функционально-логической организации разрабатываемых в рамках данной работы приложений ИЭТР наиболее оптимальной оказалась модель имеющая три степени детализации:

  • Точная модель.
  • Не детализированная модель.
  • Масс модель.

4.2 Обзор используемых форматов данных

4.2.1 Формат XML

4.2.1.1  Описание формата

Расширяемый язык разметки (Extensible Markup Language, аббревиатура - XML) описывает класс объектов XML document, а также частично описывает работу компьютерных программ, обрабатывающих объекты с данными, реализующими этот класс. XML - это прикладной уровень или усеченная форма SGML, Стандартного Обобщенного языка разметки [ISO 8879]. По своему построению, XML документ является полноценным SGML документом.

Язык XML был разработан группой XML Working Group (первоначально называемой SGML Editorial Review Board), сформированной в 1996 году под патронажем World Wide Web Consortium (W3C). Председательствует в группе Jon Bosak из Sun Microsystems, принимающий также активное участие в работе группы XML Special Interest Group (ранее известной как SGML Working Group), которая тоже была сформирована W3C. Список членов XML Working Group представлен в Приложении. Связь группы с W3C обеспечивает Dan Connolly.

При разработке языка XML ставились следующие задачи:

  1. XML должен быть пригоден для непосредственного использования в Интернет.
  2. XML должен иметь широкий круг применения.
  3. XML должен быть совместим с SGML.
  4. Обработчики документов XML должны быть просты в написании.
  5. Количество факультативных свойств в XML должно быть сведено к абсолютному минимуму, в идеале число их вообще должно быть нулевым.
  6. XML документы должны быть удобны для чтения и достаточно понятны.
  7. Подготовка XML документа должна осуществляться быстро.
  8. Процедура построения XML документа должна быть формальной и точной.
  9. Процедура создания XML документов должна быть проста.
  10. Краткость при разметке XML документа имеет минимальное значение.
4.2.1.1.2  Документы

Объект данных становится XML документом если, в соответствии с определениями обсуждаемой спецификации, он является корректным. Корректный XML документ также может стать действительным, если отвечает некоторым дополнительным ограничениям.

Каждый XML имеет логическую и физическую структуру. Физически документ состоит из элементов, называемых сущностями. Любая сущность может ссылаться на другие сущности, обеспечивая их включение в данный документ. Документ начинается с "корня" или сущности документа. С логической точки зрения, документ строится из деклараций, элементов, комментариев, ссылок на символ и инструкций обработки. Все они размечаются в документе явным образом.

4.2.1.1.2.1  Корректные XML документы

Текстовый объект становится корректным (well-formed) XML документом, если:

  1. как единое целое, он соответствует сценарию document
  2. отвечает всем ограничениям корректности
  3. Все разобранные сущности, на которые в данном документе прямо или косвенно делается ссылка, являются корректными (well-formed)
  • Документ

document           ::=   prolog element Misc

Соответствие сценарию document подразумевает следующее

  1. В данном объекте содержится один или несколько элементов
  2. В объекте имеется в точности один элемент, называемый корневым или элементом документа, ни одна из частей которого не попадает в содержимое какого-либо еще элемента. Для всех остальных элементов действует правило, что если начальный тэг находится в содержимом некого элемента, то и конечный тэг должен находиться среди содержимого того же элемента. Проще говоря, элементы, маркируемые начальными и конечными тэгами, должны быть вложены друг в друга правильным образом.

Из вышесказанного следует, что в документе для любого некорневого элемента C имеется другой элемент P из этого же документа, такой, что C находится в содержимом P, но при этом не попадает в содержимое какого-либо третьего элемента, также находящегося в содержимом элемента P. В таком случае об элементе P говорят как о родителе элемента C, а элемент C называют непосредственным потомком элемента P.

4.2.1.1.2.2  Символы

Разобранная сущность (parsed entity) содержит текст - последовательности символов, образующие разметку и символьные данные. Символ - это элементарная единица текста, описанная в ISO/IEC 10646 [ISO/IEC 10646] (см. также [ISO/IEC 10646-2000]). Допустимы символы табуляции, возврата каретки, конца строки, а также разрешенные символы из наборов Unicode и ISO/IEC 10646.

  • Диапазон символов

Char       ::=   #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]

- любой символ Unicode, исключая суррогатные блоки, FFFE и FFFF.

Механизм шифрования символьных кодов использует битовые шаблоны, которые могут меняться от сущности к сущности. Все XML процессоры должны иметь возможность работать с кодировками UTF-8 и UTF-16 из набора 10646

4.2.1.1.2.3      Общие синтаксические конструкции

В данной главе определяются некоторые символы, широко используемые в грамматике XML.

S (пробельный символ, white space) состоит из одного или нескольких символов пробела (#x20), возврата каретки, конца строки или табулятора.

  • Пробельный символ

S             ::=   (#x20 | #x9 | #xD | #xA)+

Для удобства символы делятся на буквы, цифры и остальные символы. Буквы состоят из алфавитных, слоговых и идеографических символов.

Имя (name) - это лексема (token), начинающаяся с буквы, либо одного из нескольких символов пунктуации, за которыми следуют буквы, цифры, дефисы, символы подчеркивания, двоеточия или точки (все они называются name character - символами имени). Имена, начинающиеся с комбинации "xml" или какой-либо из строк, соответствующих шаблону (('X'|'x') ('M'|'m') ('L'|'l')), зарезервированы под стандартизацию в этой спецификации и ее последующих версиях.

Замечание:

Интерпретация имен, содержащих символ двоеточия, задается в документе Namespaces in XML Recommendation [XML Names]. Поэтому авторам не следует использовать символ двоеточия в именах XML, если это не связано с обращением к пространству имен. Вместе с тем, сами XML процессоры должны воспринимать двоеточие в имени как обычный символ.

Nmtoken (лексема имени) - это произвольное сочетание символов имени.

  • Имена и лексемы

NameChar         ::=    Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender
Name     ::=   (Letter | '_' | ':') (NameChar)*
Names    ::=   Name (S Name)*
Nmtoken            ::=   (NameChar)+
Nmtokens          ::=   Nmtoken (S Nmtoken)*

Строковые данные (literal data) - это любая заключенная в кавычки строка, внутри которой нет кавычек, которые можно было бы принять за разделители этой строки. Строковые данные, или литералы (literals), применяются для указания содержимого внутренних сущностей (EntityValue), значений атрибутов (AttValue) и внешних идентификаторов (SystemLiteral). Заметим, что идентификатор SystemLiteral может быть обработан без проверки разметки.

  • Литералы

EntityValue       ::=   '"' ([^%&"] | PEReference | Reference)* '"'
|  "'" ([^%&'] | PEReference | Reference)* "'"
AttValue            ::=   '"' ([^<&"] | Reference)* '"'
|  "'" ([^<&'] | Reference)* "'"
SystemLiteral    ::=   ('"' [^"]* '"') | ("'" [^']* "'")
PubidLiteral      ::=   '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
PubidChar         ::=   #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]

Замечание:

Хотя сценарий EntityValue и позволяет определить сущность, состоящую из одного единственного простого символа < в строке данных (имеется ввиду <!ENTITY mylt "<">), настоятельно рекомендуется избегать подобной практики, поскольку любая ссылка на указанную сущность приведет к появлению ошибки корректности.

4.2.1.1.2.4   Символьные данные и разметка

Текст документа образуется сочетанием символьных данных и разметки. Разметка принимает форму начальных тэгов, конечных тэгов, тэгов пустых элементов, ссылок на сущности, ссылок на символы, комментариев, разделителей секций CDATA, объявлений типов документов, инструкций обработки, деклараций XML, деклараций текста и любых пробельных символов, которые располагаются на верхнем уровне сущности документа (то есть, вне элемента document и за пределами иных элементов разметки).

Текст, который не относится к разметке, формирует символьные данные документа (character data).

Символ амперсанта (&) и левая угловая скобка (<) могут появиться в своем обычном текстовом виде только в том случае, если используются в качестве ограничителя разметки, либо находятся в пределах комментария, инструкции обработки или секции CDATA. Если же эти символы потребовались в документе где-либо еще, их следует маскировать, воспользовавшись для этого либо соответствующей числовой ссылкой на символ (numeric character reference), либо строками "&amp;" и "&lt;" соответственно. Правая угловая скобка (>) может быть представлена в виде строки "&gt;". Кроме того, если правая угловая скобка в содержимом элемента попадает в комбинацию символов "]]>", которая не соответствует окончанию секции CDATA, то, в целях совместимости, эту скобку необходимо заменить ссылкой на символ либо комбинацией "&gt;".

Символьные данные в содержимом элемента - это любая строка символов, которая не содержит начальных ограничителей какой-либо разметки. Символьные данные в секции CDATA - это любая строка символов, которая не содержит закрывающего ограничителя секции CDATA (комбинации символов "]]>").

Если в значение атрибута необходимо поместить символ одинарной или двойной кавычки, то апостроф или символ одинарной кавычки (') следует представить комбинацией "&apos;", а символ двойной кавычки (") - как "&quot;".

  • Символьные данные

CharData           ::=   [^<&]* - ([^<&]* ']]>' [^<&]*)

4.2.1.1.2.5  Комментарии

Комментарий может размещаться в любом месте документа при условии, что он не попадает в границы какого-либо элемента разметки. Комментаций может также появляться в тех местах декларации типа документа, где это разрешено грамматикой. Комментарии не относятся к символьным данным документа, однако XML процессоры могут (но не обязаны) передавать приложению текст полученных комментариев. Для сохранения совместимости, в комментарии не следует пользоваться комбинацей символов "--" (двойной дефис). Ссылка на сущность параметра в комментариях не распознается.

  • Комментарии

Comment           ::=   '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'

Пример комментария:

<!-- declarations for <head> & <body> -->

Заметим, что, согласно требованиям обсуждаемой грамматики, комментарий не может завершаться комбинацией символов --->. Поэтому следующий пример корректным уже не будет.

<!-- B+, B, or B--->

4.2.1.1.2.6  Инструкции обработки

Инструкции обработки (processing instruction, PI) позволяют размещать в документе инструкции для приложений.

  • Инструкции обработки

PI           ::=   '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
PITarget             ::=   Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))

Хотя PI не относятся к символьным данным документа, они точно так же должны быть переданы приложению. Инструкция PI начинается с указания адреса (PITarget), используемого для идентификации приложения, которому предназначается эта инструкция. Адреса с названиями "XML", "xml" и аналогичными зарезервированы для стандартизации в текущей и последующих версиях спецификации. Для формального декларирования адресата инструкции PI может использоваться механизм нотаций XML. Ссылки на сущность параметра в инструкциях обработки не распознаются.

4.2.1.1.2.7  Секции CDATA

Секция CDATA может находиться повсюду, где могут размещаться символьные данные. Использование секции CDATA позволяет избежать обработки блока текста, содержащего символы, которые в других случаях распознавались бы как разметка. Секция CDATA начинается со строки "<![CDATA[" и заканчивается строкой "]]>".

  • Секции CDATA

CDSect              ::=   CDStart CData CDEnd
CDStart             ::=   '<![CDATA['
CData     ::=   (Char* - (Char* ']]>' Char*))
CDEnd               ::=   ']]>'

В секции CDATA распознается только один элемент разметки - строка CDEnd. Поэтому все символы левой угловой скобки и амперсанта могут предстать здесь в своем обычном текстовом виде. Эти символы не нужно (да и невозможно) маскировать с помощью комбинаций "&lt;" и "&amp;". Секции CDATA не могут быть вложенными.

Пример секции CDATA, в которой строки "<greeting>" и "</greeting>" будут распознаваться не как разметка, а как обычные символьные данные:

<![CDATA[<greeting>Hello, world!</greeting>]]>

4.2.1.1.2.8  Пролог и декларация типа документа

Документ XML должен начинаться с декларации XML, указывающей версию используемого языка XML. Например, в следующем примере представлен полноценный XML документ, корректный, но недействительный:

<?xml version="1.0"?> <greeting>Hello, world!</greeting>

таким образом, имеем

<greeting>Hello, world!</greeting>

Для обозначения совместимости с данной версией спецификации, необходимо указывать номер версии "1.0". Если в документе используется значение "1.0", но он не отвечает требованиям данной версии спецификации, это будет ошибкой. Выбор номера для тех версий спецификации XML, которые последуют за "1.0", остается за рабочей группой по XML, однако это не подразумевает что она обязуется разработать новые версии языка XML или придерживаться какой-либо конкретной схемы при их нумерации, если таковые будут созданы. Поскольку появление новых версий не исключается, то принятие упомянутой схемы нумерации позволило бы реализовать автоматическое распознавание версии, которое должно стать необходимым. Если получен документ с меткой о версии, которую процессор не в состоянии поддерживать, последний может сигнализировать об ошибке.

Задачей разметки XML документа должно быть описание схемы его размещения и логической структуры, а также связывание пар атрибут-значение с их логической структурой. XML предоставляет механизм для определения логических ограничений для логической структуры и формирования предопределенных единиц размещения - декларацию типа документа. XML документ является действительным, если с ним связана декларация типа документа и если этот документ отвечает представленным в ней ограничениям.

Декларация типа должна располагаться в документе до первого элемента.

  • Пролог

prolog    ::=   XMLDecl? Misc* (doctypedecl Misc*)?
XMLDecl          ::=   '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
VersionInfo       ::=   S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"')/* */
Eq          ::=   S? '=' S?
VersionNum      ::=   ([a-zA-Z0-9_.:] | '-')+
Misc       ::=   Comment | PI | S

В языке XML декларация типа документа либо сама содержит, либо ссылается на декларации разметки, которые определяют грамматику некого класса документов. Такую грамматику называют декларацией типа документа, или DTD (document type definition). Декларация типа документа может ссылаться на внешний набор, который также содержит декларацию разметки (специальный тип - внешняя сущность), может содержать свой внутренний набор деклараций разметки, а может сочетать оба варианта. DTD документа формируется из обоих этих наборов, обрабатываемых совместно.

Декларация разметки - это декларация типа документа, декларация списка атрибутов, декларация сущности или декларация нотации. Перечисленные декларации могут целиком, либо частично располагаться в сущности параметра в соответствии с приводимыми далее ограничениями корректности и действительности.

  • Декларация типа документа

doctypedecl       ::=   '<!DOCTYPE' S Name (S ExternalID)? S? ('[' (markupdecl | DeclSep)* ']' S?)? '>'
DeclSep             ::=   PEReference | S
markupdecl       ::=   elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment

Отметим, что можно создать корректный документ, который включал бы doctypedecl, не ссылающийся на внешний набор деклараций и не содержащий своего внутреннего набора.

Декларации разметки могут полностью или частично состоять из текста замены для сущностей параметров. Сценарии, приводимые далее в спецификации для конкретных неграничных элементов (elementdecl, AttlistDecl и так далее), описывают декларации уже после подстановки всех сущностей параметров.

Ссылка на сущность параметра распознается в любом месте DTD (внутреннем и внешнем наборах, внешних сущностях параметров) за исключением текстовых данных, инструкций обработки, комментариев и содержимого игнорируемых условных секций. Распознается она также и в тексте значения сущности. Использование сущностей параметров во внутреннем наборе деклараций подчиняется следующим ограничениям:

Ограничение действительности: тип корневого элемента

Параметр Name в декларации типа документа должен соответствовать типу корневого элемента.

Ограничение действительности: Правильная декларация/вложенность сущности параметра

Текст замены для сущности параметра должен быть правильным образом вложен в декларации разметки. Иначе говоря, если первый или последний символ декларации разметки находится в тексте замены для ссылки на сущность параметра, то в этом тексте должен находиться и второй из указанных символов.

Ограничение корректности: Сущности параметров во внутреннем наборе

Во внутреннем наборе DTD ссылка на сущность параметра может появляться только в тех местах, где могут расположиться декларации разметки, но не в самой декларации разметки. (Это не относится к ссылкам во внешних сущностях параметров или во внешнем наборе.)

Ограничение корректности: Внешний набор

Внешний набор, если таковой имеется, должен соответствовать сценарию для extSubset.

Ограничение корректности: Сущность параметра между декларациями

Текст замены для ссылки на сущность параметра в DeclSep должен соответствовать сценарию extSubsetDecl.

Вслед за внутренним набором, внешний набор и любые внешние сущности параметров, на которые делается ссылка в DeclSep, должны состоять из полных наборов деклараций разметки для типов, которые разрешены неграничным символом markupdecl, в сочетании с пробельными символами и ссылками на сущности параметров. При этом отдельные фрагменты содержимого внешнего набора или сущностей внешних параметров при определенных условиях могут игнорироваться в случае построения условных секций. Во внутреннем наборе использовать такие секции не разрешается.

  • Внешний набор

extSubset           ::=   TextDecl? extSubsetDecl
extSubsetDecl    ::=   ( markupdecl | conditionalSect | DeclSep)

Внешний набор и внешние сущности параметров отличаются от внутреннего набора также и тем, что для них ссылка на сущность параметра может появляться не только в интервалах между декларациями разметки, но и в границах самих этих деклараций.

Пример XML документа с декларацией типа документа:

<?xml version="1.0"?>
<!DOCTYPE greeting SYSTEM "hello.dtd">
<greeting>Hello, world!</greeting>

Системный идентификатор "hello.dtd" указывает адрес DTD этого документа (ссылку URI).

Декларации также могут быть представлены локально, как это делается в следующем примере:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE greeting [
<!ELEMENT greeting (#PCDATA)>
]>
<greeting>Hello, world!</greeting>

Если используются и внешний, и внутренний наборы деклараций, то внутренний набор рассматривается прежде внешнего. Как следствие этого, декларации сущностей и списка атрибутов во внутреннем наборе имеют приоритет над аналогичными декларациями во внешнем наборе.

4.2.1.1.2.9  Декларация одиночного документа

Декларации разметки, которые XML процессор передает приложению, могут оказывать влияние на содержимое документа. Примером могут служить атрибуты по умолчанию и декларации сущностей. Декларация одиночного документа, которая может быть представлена в составе XML декларации, указывает, могут ли возникать декларации в сущностях параметров, а также декларации, внешние по отношению к сущности документа. Внешняя декларация разметки определяется как декларация разметки, встретившаяся во внешнем наборе или в сущности параметра (внешней или внутренней, последний вариант был включен в спецификацию только потому, что непроверяющие процессоры читать их не обязаны).

  • Декларация одиночного документа

SDDecl              ::=   S 'standalone' Eq (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"'))

Значение "yes" в декларации одиночного документа говорит об отсутствии внешних деклараций разметки, которые оказывали бы влияние на информацию, которую XML процессор передает приложению. Значение "no" указывает на то, что такие внешние декларации разметки имеются, либо могут быть появиться. Заметим, что декларация одиночного документа всего лишь свидетельствует о присутствии внешних деклараций. Наличие же в документе ссылок на внешние сущности, если последние уже были декларированы в самом документе, статуса одиночного документа не отменяет.

Если внешние декларации разметки отсутствуют, то декларация одиночного документа теряет смысл. Если присутствуют внешние декларации разметки, но отсутствует декларация одиночного документа, подразумевается что она имеет значение "no".

Любой XML документ, для которого было указано standalone="no", может быть алгоритмическим путем приведен к одиночному документу, что может потребоваться для некоторых приложений, получающих данные по сети.

Ограничение действительности: Декларация одиночного документа

Декларация одиночного документа должна иметь значение "no", если какие-либо внешние декларации разметки включают декларацию для:

  • атрибутов со значением по умолчанию, если элементы, к которым эти атрибуты относятся, были представлены в документе без уточнения значений для указанных атрибутов,
  • сущностей (кроме amp, lt, gt, apos и quot), если в документе встретились ссылки на эти сущности,
  • атрибутов со значением, подлежащим нормализации, если этот атрибут появился в документе со значением, которое в результате этой нормализации будет изменено,
  • типов элементов с содержимым, если в каком-либо экземпляре такого типа был обнаружен пробельный символ.

Пример декларации XML с декларированием одиночного документа:

<?xml version="1.0" standalone='yes'?>

4.2.1.1.2.10 Обработка пробельных символов

В ходе редактирования XML документов часто бывает удобно воспользоваться "пробельными символами" (white space - пробелы, табуляторы и пустые строки) для выделения разметки для лучшей читаемости. Такие пробельные символы обычно не должны попадать в ту версию документа, которая передается в приложение. С другой стороны, часто встречаются "значимые" пробельные символы, которые должны быть оставлены в передаваемом документе, например, если это стихи или исходный код программы.

XML процессор должен всегда передавать приложению все символы документа, не относящиеся к разметке. Проверяющий XML процессор дополнительно должен проинформировать приложение о том, какие из этих символов соответствуют пробельным символам в содержимом элемента.

К элементу может быть приставлен специальный атрибут, называемый xml:space, для того чтобы показать, что пробельные символы в этом элементе должны быть сохранены. Если этот атрибут используется в действительных документах, то, как и любой другой, он должен быть декларирован. Будучи декларирован, он должен быть представлен как перечислимый тип, значениями которого являются одно или оба значения "default" и "preserve". Например:

<!ATTLIST poem  xml:space (default|preserve) 'preserve'>
<!-- -->
<!ATTLIST pre xml:space (preserve) #FIXED 'preserve'>

Значение атрибута "default" говорит о том, что для данного элемента используется режим обработки пробельных символов, применяемый в приложениях по умолчанию. Значение "preserve" говорит о том, что приложения должны сохранить все пробельные символы. Декларированное таким образом правило относится ко всем элементам, находящимся среди содержимого того элемента, которому был назначен данный атрибут (при условии что это правило не было затем переопределено другим экземпляром атрибута xml:space).

Считается, что корневой элемент любого документа не имеет указаний о том, каким образом приложение будет обрабатывать пробелы, если для этого атрибута не было дано соответствующего значения, и этот атрибут не был представлен среди значений по умолчанию.

4.2.1.1.2.11  Обработка концов строк

Часто разобранные сущности XML, помещенные в компьютерные файлы, для удобства редактирования представляются в виде набора строк. В качестве разделителя для таких строк обычно используется некая комбинация символов возврата каретки (#xD) и конца строки (#xA).

Чтобы облегчить работу приложений, текст, который им передает XML процессор, должен быть таким, как если бы этот процессор при выводе перед обработкой нормализовал все концы строк во внешних разобранных сущностях (а также сущности самого документа). Осуществляться это должно путем замены последовательности из двух символов #xD #xA (а также одиночного #xD, за которым не следует #xA) одним символом #xA.

4.2.1.1.2.12   Идентификация языка

В ходе обработки документа часто бывает полезным идентифицировать, на каком из естественных или формальных языков он был записан. Для идентификации языка, который использовался при записи содержимого и значений атрибутов любого элемента, в документе может быть указан специальный атрибут с названием xml:lang. Если этот атрибут используется в действительном документе, то, как и любой другой, он должен быть декларирован. Значением этого атрибута являются идентификаторы языков, определенные в документе [IETF RFC 1766] (Тэги для идентификации языков) или наследующих его стандартах IETF.

Например:

<p xml:lang="en">The quick brown fox jumps over the lazy dog.</p>

<p xml:lang="en-GB">What colour is it?</p>

<p xml:lang="en-US">What color is it?</p>

<sp who="Faust" desc='leise' xml:lang="de">

<l>Habe nun, ach! Philosophie,</l>

<l>Juristerei, und Medizin</l>

<l>und leider auch Theologie</l>

<l>durchaus studiert mit heiЯem Bemьh'n.</l>

</sp>

Предполагается, что информация, представленная в xml:lang, относится ко всем атрибутам и всему содержимому элемента, где этот атрибут был указан (при условии, что в содержимом этого элемента она не была затем переопределена новым экземпляром атрибута xml:lang в другом элементе).

Простая декларация атрибута xml:lang может иметь вид

xml:lang NMTOKEN #IMPLIED

Если это необходимо, для этого атрибута могут быть представлены значения по умолчанию. В сборнике французской поэзии (poem) для английских студентов, содержащем глоссарий (gloss) и пометки на английском языке (note), атрибут xml:lang может быть декларирован следующим образом:

<!ATTLIST poem   xml:lang NMTOKEN 'fr'>

<!ATTLIST gloss  xml:lang NMTOKEN 'en'>

<!ATTLIST note   xml:lang NMTOKEN 'en'>

4.2.1.1.3  Логические структуры

Каждый XML документ содержит один или несколько элементов, границы каждого из которых обозначены либо парой начальный тэг - конечный тэг, либо (если это пустой элемент) тэгом пустого элемента. Каждый элемент имеет определенный тип, который идентифицируется по имени и иногда называется "общим идентификатором" этого элемента (generic identifier - GI), а также может иметь набор спецификаций к атрибутам. Каждая спецификация атрибута содержит его имя и значение.

  • Элемент

element              ::=   EmptyElemTag | STag content ETag

Данная спецификация не ограничивает семантику, порядок использования (за исключением синтаксиса), выбор имен для атрибутов и типов элементов. Ограничение заключается в том, что имена, чье начало соответствует шаблону (('X'|'x')('M'|'m')('L'|'l')), зарезервированы для стандартизации в текущей и последующих версиях данной спецификации.

Ограничение корректности: Соответствие типов элементов

Параметр Name в конечном тэге элемента должен соответствовать типу элемента в начальном тэге.

Ограничение действительности: Действительность элемента

Элемент считается действительным, если имеется декларация, соответствующая elementdecl, в которой параметр Name соответствует типу элемента, а также выполняется одно из следующих условий:

  1. Декларация соответствует EMPTY, а элемент не имеет содержимого.
  2. Декларация соответствует непосредственному потомку элемента, а последовательность его непосредственных элементов - потомков, принадлежит языку, генерируемому регулярным выражением в модели содержимого с необязательным пробельным символом (символами, соответствующими неграничному S) между начальным тэгом и первым из непосредственных элементов-потомков, между элементами-потомками, между последним элементом-потомком и закрывающим тэгом. Заметим, что в секция CDATA, содержащая лишь пробельный символ, не соответствуют нетерминальному S, а следовательно в указанных позициях появиться не может.
  3. Декларация соответствует Mixed, а содержимое состоит из символьных данных и элементов-потомков, тип которых соответствует именам в модели содержимого.
  4. Декларация соответствует ANY, и был декларирован тип всех элементов-потомков.
4.2.1.1.3.2      Начальные тэги, конечные тэги и тэги пустых элементов

Начало любого непустого XML элемента помечается начальным тэгом.

  • Начальный тэг

STag      ::=   '<' Name (S Attribute)* S? '>'

Attribute            ::=   Name Eq AttValue

Параметр Name в начальном и конечном тэгах определяет тип элемента. Пара Name - AttValue называется спецификацией атрибута для данного элемента, Параметр Name в каждой такой паре называется именем атрибута, а содержимое поля AttValue - текст в одинарных (') или двойных (") кавычках - называется значением атрибута. Заметим, что очередность появления спецификаций атрибутов в начальном тэге или тэге пустого элемента значения не имеет.

Ограничение корректности: Уникальность спецификации атрибута

В границах одного начального тэга (или тэга пустого элемента) одно и то же имя атрибута не может появляться более одного раза.

Ограничение действительности: Тип значения атрибута

Атрибут должен быть декларирован, его значение должно иметь тот тип, который был декларирован для него. (Описание типов атрибутов см. в главе 3.3 Декларации списков атрибутов.)

Ограничение корректности: Отсутствие ссылок на внешние сущности

Значение атрибута не может иметь содержать прямых или косвенных ссылок на внешние сущности.

Ограничение корректности: Отсутствие символов < в значениях атрибута

Символ < не может содержаться в тексте замены для сущностей, на которые в значении атрибута прямо или косвенно дается ссылка.

Пример начального тэга:

<termdef id="dt-dog" term="dog">

Любой элемент, чье начало отмечено начальным тэгом, должен завершиться конечным тэгом, имя которого повторяет тип элемента, указанный в начальном тэге:

  • Конечный тэг

ETag      ::=   '</' Name S? '>'

Пример конечного тэга:

</termdef>

Текст, заключенный между начальным и конечным тэгами, называется содержимым элемента:

  • Содержимое элементов

content               ::=   CharData? ((element | Reference | CDSect | PI | Comment) CharData?)

Элемент без содержимого называется пустым элементом. Пустой элемент может быть представлен либо в виде начального тэга, за которым сразу же следует конечный тэг, либо как тэг пустого элемента. Тэг пустого элемента имеет специальный формат:

  • Тэги пустых элементов

EmptyElemTag             ::=   '<' Name (S Attribute)* S? '/>'

Тэг пустого элемента может быть использован для любого элемента, не имеющего содержимого, независимо от того, был ли последний декларирован с ключевым словом EMPTY. В целях совместимости, тэг пустого элемента должен использоваться для элементов, которые были декларированы как EMPTY, и только для них.

Примеры пустых элементов:

<IMG align="left"

src="http://www.w3.org/Icons/WWW/w3c_home" />

<br></br>

<br/>

4.2.1.1.3.3  Декларации типа элемента

Для достижения действительности, на структуру элементов в XML документе могут быть наложены ограничения в виде деклараций типов используемых элементов и списков атрибутов. Декларирование типа элемента накладывает ограничение на его содержание.

Декларация типа элемента часто конкретизирует тип его непосредственных потомков. По выбору пользователя, XML процессор может генерировать предупреждение если в декларации был упомянут тип элемента, для которого не было предоставлено соответствующей декларации, однако ошибочной эта ситуация не считается.

Декларация типа элемента имеет вид:

  • Декларация типа элемента

elementdecl       ::=   '<!ELEMENT' S Name S contentspec S? '>'

contentspec       ::=   'EMPTY' | 'ANY' | Mixed | children

где параметр Name определяет декларируемый тип элемента.

Ограничение действительности: Уникальность декларации типа элемента

Ни один тип элемента не может быть декларирован более одного раза.

Примеры деклараций типа элемента:

<!ELEMENT br EMPTY>

<!ELEMENT p (#PCDATA|emph)* >

<!ELEMENT %name.para; %content.para; >

<!ELEMENT container ANY>

  • Содержимое элемента

Тип элемента определяет содержимое элемента, если элементы указанного типа обязаны не иметь символьных данных, а только непосредственные элементы-потомки, которые могут отделяться друг от друга пробельными символами (символами, соответствующими неграничному S). В этом случае накладываемое на элемент ограничение содержит модель содержимого - простую грамматику, управляющую допустимыми типами непосредственных элементов-потомков и порядком, в котором им разрешено появляться. Указанная грамматика строится из фрагментов содержания (cp), которые содержат название, списки выбора и последовательные списки фрагментов содержания:

Модели содержимого элемента

children             ::=   (choice | seq) ('?' | '*' | '+')?

cp           ::=   (Name | choice | seq) ('?' | '*' | '+')?

choice    ::=   '(' S? cp ( S? '|' S? cp )+ S? ')'

seq         ::=   '(' S? cp ( S? ',' S? cp )* S? ')'

где каждая запись Name - это тип элемента, который может выступить в роли непосредственного потомка. Любой фрагмент содержимого в списке выбора может быть помещен в содержимое элемента в то место, где согласно грамматике располагался соответствующий список выбора. Все фрагменты содержимого в последовательном списке должны быть вставлены в содержимое элемента и именно в том прядке, как они были представлены в исходном списке. Необязательный символ, следующий за именем (или списком), указывает, должен ли данный элемент (или фрагменты из данного списка) быть повторен один или более раз (+), нуль или более раз (*), либо нуль или один раз (?). Отсутствие такого оператора означает, что данный элемент (или фрагмент) должен появиться ровно один раз. Представленный синтаксис и его значение те же самые, что используются в сценариях самой спецификации.

Содержимое элемента соответствует модели содержания тогда и только тогда, когда можно проследить способ его получения из этой модели в соответствии с операторами последовательности, выбора и повторения, а также такой, что каждый элемент в содержании соответствует типу элемента в модели содержания. Если какой-либо элемент в документе может быть сопоставлен нескольким типам элементов в модели содержания, то для сохранения совместимости процессор должен фиксировать ошибку. За дополнительной информацией обращайтесь к Приложению E Детерминистические модели содержания.

Ограничение действительности: Правильная вложенность Group/PE

Текст замены для сущности параметра должен иметь правильно вложенные группы скобок. Иными словами, если в конструкциях choice, seq или Mixed открывающая или закрывающая скобка была включена в текст замены для сущности параметра, то в этот текст должна попадать и вторая парная скобка.

Если в конструкциях choice, seq или Mixed обнаружена ссылка на сущность параметра, то, для совместимости, ее текст замены должен содержать хотя бы один символ, отличный от пробела. И ни первый, ни последний символ в тексте замены, отличный от пробела, не должен быть соединителем (| или ,).

Примеры моделей содержимого элемента:

<!ELEMENT spec (front, body, back?)>

<!ELEMENT div1 (head, (p | list | note)*, div2*)>

<!ELEMENT dictionary-body (%div.mix; | %dict.mix;)*>

Смешанный контент

Какой-либо тип элемента имеет смешанный контент, если элементы этого типа могут содержать символьные данные, возможно чередуемые с элементами-потомками. В таком случае ограничения модели могут касаться лишь типа непосредственных элементов-потомков, но не порядка их следования и количества экземпляров:

Декларация смешанного контента

Mixed    ::=   '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' | '(' S? '#PCDATA' S? ')'

где параметр Name определяет тип элементов, которые могут быть использованы в роли непосредственных потомков. Ключевое слово #PCDATA исторически унаследовано от термина "parsed character data".

Ограничение действительности: Отсутствие дублирования типов

Одно и то же имя не может быть представлено в декларации смешанного контента более одного раза.

Примеры деклараций смешанного контента:

<!ELEMENT p (#PCDATA|a|ul|b|i|em)*>

<!ELEMENT p (#PCDATA | %font; | %phrase; | %special; | %form;)* >

<!ELEMENT b (#PCDATA)>

4.2.1.1.3.4  Декларации списка атрибутов

Атрибут используется для того, чтобы связать с элементом пару имя-значение. Спецификация атрибута может быть дана только в начальном тэге, либо тэге пустого элемента. Декларация списка атрибутов может быть использована для:

  • формирования перечня атрибутов, относящихся к определенному типу элементов.
  • ограничения по типу атрибутов.
  • формирования значений по умолчанию для атрибутов.

Для каждого атрибута, относящегося к элементам определенного типа, в соответствующей декларации списка атрибутов определяются имя, тип данных и, возможно, значение по умолчанию:

  • Декларация списка атрибутов

AttlistDecl         ::=   '<!ATTLIST' S Name AttDef* S? '>'

AttDef    ::=   S Name S AttType S DefaultDecl

В поле Name в правиле AttlistDecl указывается тип элемента. По выбору пользователя, XML процессор может генерировать предупреждение, если атрибуты, декларированные для такого типа элементов, сами декларированы не были, однако ошибкой такая ситуация не считается. Параметр Name в правиле AttDef соответствует имени описываемого атрибута.

Если для какого-либо из типов элементов было дано несколько деклараций AttlistDecl, то содержимое всех их суммируется. Если для некого типа элементов было дано несколько деклараций одного и того же атрибута, то использоваться должна только первая декларация, а все последующие будут игнорироваться.

Для сохранения совместимости, авторы DTD могут придерживаться правила давать для любого типа элементов не более одной декларации списка атрибутов, не более одной декларации для каждого имени атрибута, представленного в декларации списка атрибутов и, по крайней мере, одну декларацию атрибута в каждой из деклараций списка атрибутов. В целях совместимости, XML процессор по выбору пользователя может генерировать предупреждение, если для какого-либо типа элементов было представлено более одной декларации списка атрибутов, или для какого-либо атрибута было представлено более одной декларации, однако описанные ситуации ошибочными не являются.

  • Типы атрибутов

Все типы XML атрибутов делятся на три класса: строковый тип, набор символьных (tokenized) типов и перечислимые (enumerated) типы. Строковый тип может иметь в качестве значения одну строку. Символьные типы содержат различные лексические и семантические ограничения.

Типы атрибутов

AttType             ::=   StringType | TokenizedType | EnumeratedType

StringType        ::=   'CDATA'

TokenizedType             ::=   'ID' | 'IDREF'  | 'IDREFS' | 'ENTITY' | 'ENTITIES'     | 'NMTOKEN' | 'NMTOKENS'

Ограничение действительности: ID

Значения типа ID должны соответствовать сценарию для Name. Имя, соответствующее значению этого типа, должно появляться в XML документе не более одного раза. Иными словами, значения ID должны уникальным образом идентифицировать элементы, в которых они находятся.

Ограничение действительности: Один ID для каждого типа элементов

Любой тип элемента не может иметь более одного атрибута ID.

Ограничение действительности: Значение по умолчанию для атрибута ID

Для атрибута ID должно быть декларировано значение по умолчанию #IMPLIED или #REQUIRED.

Ограничение действительности: IDREF

Значения типа IDREF должны соответствовать сценарию Name, а значения типа IDREFS должны соответствовать Names. При этом каждое Name должно соответствовать значению атрибута ID в каком-либо элементе XML документа, то есть, значение IDREF должно соответствовать значению какого-либо из атрибутов ID.

Ограничение действительности: Имя сущности

Значения типа ENTITY должны соответствовать сценарию Name, значения типа ENTITIES должны соответствовать Names. Каждое Name при этом должно соответствовать названию одной из неразобранных сущностей, декларированных в DTD.

Ограничение действительности: Лексема имени

Значения типа NMTOKEN должны соответствовать сценарию Nmtoken, значения типа NMTOKENS должны соответствовать Nmtokens.

Перечислимый атрибут может выбирать одно значение из перечня, предоставленного в декларации. Существует два вида перечислимых типов:

Типы перечислимых атрибутов

EnumeratedType           ::=   NotationType | Enumeration

NotationType    ::=   'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'

Enumeration      ::=   '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'

Атрибут NOTATION идентифицирует нотацию, которая была декларирована в DTD вместе с ассоциированными с нею системными и/или общими (public) идентификаторами, и которую следует использовать для интерпретации элемента, в котором был указан данный атрибут.

Ограничение действительности: Атрибуты нотации

Значения указанного типа должны соответствовать одному из представленных в декларации названий нотации. Все названия нотаций в декларации в свою очередь также должны быть декларированы.

Ограничение действительности: Одна нотация для каждого типа элемента

Для типа элемента не может указываться более одного атрибута NOTATION.

Ограничение действительности: Отсутствие нотаций для пустого элемента

Для сохранения совместимости, для элемента, объявленного как EMPTY, атрибут типа NOTATION декларироваться не должен.

Ограничение действительности: Перечисление

Значения этого типа должны соответствовать одной из лексем Nmtoken, указанных в декларации.

Чтобы обеспечить взаимодействие, один и тот же Nmtoken должен появляться среди перечислимых типов атрибутов, относящихся к одному типу элементов, не более одного раза.

  • Значения атрибутов по умолчанию

Декларация атрибута предоставляет сведения о том, обязательно ли присутствие в элементе данного атрибута и, если нет, то как XML процессор должен реагировать на отсутствие в документе декларированного атрибута.

Значение атрибута по умолчанию

DefaultDecl       ::=   '#REQUIRED' | '#IMPLIED'  | (('#FIXED' S)? AttValue)

Запись #REQUIRED в декларации атрибута означает, что этот атрибут должен присутствовать в элементе всегда, #IMPLIED означает, что значения по умолчанию для атрибута не предоставляется. Если в декларации нет ни #REQUIRED, ни #IMPLIED, то значение AttValue содержит значение, декларированное по умолчанию. Ключевое слово #FIXED устанавливает, что данный атрибут обязан всегда иметь значение по умолчанию. Если было декларировано значение по умолчанию, то когда XML процессор не обнаруживает этого атрибута, он должен поступать так, словно атрибут присутствует и имеет значение, декларированное по умолчанию.

Ограничение действительности: Обязательный атрибут

Если для атрибута декларировано по умолчанию ключевое слово #REQUIRED, то в декларации списка атрибутов этот атрибут должен быть указан во всех элементах указанного типа.

Ограничение действительности: Допустимость значения по умолчанию для атрибута

Декларированное значение по умолчанию должно отвечать всем лексическим ограничениям для декларируемого типа атрибута.

Ограничение действительности: Фиксированное значение атрибута по умолчанию

Если атрибут по умолчанию имеет значение, декларированное с ключевым словом #FIXED, то все экземпляры данного атрибута должны соответствовать этому значению по умолчанию.

Примеры деклараций списка атрибутов:

<!ATTLIST termdef
id      ID      #REQUIRED
name    CDATA   #IMPLIED>
<!ATTLIST list
type    (bullets|ordered|glossary)  "ordered">
<!ATTLIST form
method  CDATA   #FIXED "POST">

  • Нормализация значения атрибута

Перед передачей значения атрибута приложению или проверкой его корректности XML процессор должен выполнить нормализацию полученного значения атрибута по описанному далее алгоритму либо как-нибудь иначе, например передав это значение отдельному приложению, реализующему указанный алгоритм.

Все концы строк при выводе должны быть приведены к #xA, поэтому остальная часть данного алгоритма оперирует текстом, уже нормализованным подобным образом.

Начинается с нормализованного значения, состоящего из пустой строки.

Для каждого символа, ссылки на сущность и ссылки на символ в ненормализованном значении атрибута, с первого до последнего, должны выполняться следующие действия:

Для ссылки на символ к нормализованное значение поместить символ, на который делалась ссылка.

Для ссылки на сущность над текстом замены для указанной сущности рекурсивно выполнять третий шаг обсуждаемого алгоритма.

В случае пробельного символа (#x20, #xD, #xA, #x9) в нормализованное значение помещать символ пробела (#x20).

Остальные символы просто помещать в нормализованное значение.

Если тип атрибута - не CDATA, то следующим шагом XML процессор должен обработать нормализованное значение атрибута, отбросив начальные и заключительные символы пробела (#x20), а также заменив любую встреченную последовательность пробелов (#x20) одним символом пробела (#x20).

Заметим, что если ненормализованное значение атрибута имело ссылку на пробельный символ, иной нежели символ пробела (#x20), то его нормализованное значение будет содержать сам символ, на который делалась ссылка (т.е. #xD, #xA или #x9). Это иной случай, чем когда в ненормализованном значении атрибута обнаружен пробельный символ (а не просто ссылка на него), который в нормализованном значении будет заменен символом пробела (#x20), а также когда в ненормализованном значении имеется ссылка на сущность, чей текст замены содержит пробельный символ, который в ходе рекурсивной обработки тоже будет заменен в нормализованном значении пробелом (#x20).

Все атрибуты, для которых не было представлено декларации, должна обрабатываться непроверяющим процессором так, как если бы были декларированы CDATA.

Далее следуют примеры нормализации атрибутов. Даны следующие декларации:

<!ENTITY d "&#xD;">
<!ENTITY a "&#xA;">
<!ENTITY da "&#xD;&#xA;">

Атрибут, указанный в левой колонке следующей таблицы, в ходе нормализации будет преобразован в последовательность символов, представленную в средней колонке, если атрибут a был декларирован как NMTOKENS, или же в последовательность символов из правой колонки, если a декларирован как CDATA.

4.2.1.1.3.5  Условные секции

Условная секция является фрагментом внешнего набора для декларации типа документа, которая включается или исключается из логической структуры DTD в зависимости от значения управляющего ею ключевого слова.

  • Условная секция

conditionalSect             ::=   includeSect | ignoreSect
includeSect        ::=   '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
ignoreSect         ::=   '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'            ignoreSectContents       ::=   Ignore ('<![' ignoreSectContents ']]>' Ignore)*
Ignore    ::=   Char* - (Char* ('<![' | ']]>') Char*)

Ограничение действительности: Правильная вложенность условной секции/PE

Если какая-либо из конструкций условной секции ("<![", "[" или "]]>") находится в тексте замены для ссылки на сущность параметра, то в этом тексте должны находиться и все остальные конструкции.

Подобно внутреннему и внешнему наборам DTD, условная секция тоже может содержать одну или несколько полных деклараций, комментариев, инструкций обработки или же вложенных условных секций, перемежаемых пробельным символом.

Если ключевым словом условной секции является INCLUDE, то содержимое этой секции становится частью DTD. Если же ключевым словом условной секции является IGNORE, то содержимое секции логической частью DTD не становится. Если условная секция с ключевым словом INCLUDE была представлена в составе более крупной условной секции с ключевым словом IGNORE, то игнорируются обе внутренняя и внешняя секции. Содержимое игнорируемой условной секции обрабатывается путем изъятия всех символов, стоящих после скобки "[", следующей за ключевым словом, и до того как будет найден конец условной секции (исключение составляет условная секция, начинающияся с "<![" и заканчивающаяся "]]>"). При этом ссылки на сущности параметров не распознаются.

Если ключевое слово условной секции является ссылкой на сущность параметра, то данную сущность параметра необходимо заменить его содержимым до того, как процессор будет решать, включать или игнорировать данную условную секцию.

Например:

<!ENTITY % draft 'INCLUDE' >
<!ENTITY % final 'IGNORE' >
<![%draft;[
<!ELEMENT book (comments*, title, body, supplements?)>
]]>
<![%final;[
<!ELEMENT book (title, body, supplements?)>
]]>

4.2.1.1.4  Физические структуры

XML документ может состоять из одной или нескольких единиц размещения, называемых сущностями. Все сущности имеют содержание (исключение составляют сущность документа и внешний набор DTD) и идентифицируются по имени. Каждый XML документ имеет ровно одну сущность, называемую сущностью документа, которая служит стартовой точкой для XML процессора и может содержать документ целиком.

Сущности могут быть разобранными либо неразобранными. Содержимое разобранной сущности (parsed entity) называется ее текстом замены. Этот текст рассматривается как составная часть документа.

Неразобранная сущность (unparsed entity) - это ресурс, содержимым которого может быть текст, либо что-нибудь другое. Даже если это текст, это не обязательно должно быть XML. С каждой неразобранной сущностью связана нотация, идентифицируемая по имени. Помимо того, что XML процессор должен предоставить приложению идентификаторы сущности и ее нотацию, спецификация XML не предъявляет никаких требований к содержимому неразобранной сущности.

Разобранные сущности вызываются по имени посредством ссылки на сущность, а неразобранные сущности - по имени, указанному в значении атрибута ENTITY или ENTITIES.

Общая сущность (general entity) - это сущность для использования в содержимом документа. В рамках данной спецификации общие сущности часто обозначаются неформальным термином сущность (entity), если это не приводит к двусмысленности. Сущность параметра - это разобранная сущность для использования в DTD. Существует два типа сущностей, использующих различный формат ссылки и распознаваемых в различном контексте. Более того, эти типы занимают разные пространства имен. Сущность параметра и общая сущность с тем же самым именем в действительности являются различными сущностями.

4.2.1.1.4.1  Ссылки на символ и сущность

Ссылка на символ относится к определенному символу из набора ISO/IEC 10646, например, к такому символу, который невозможно получить непосредственно с имеющихся устройств ввода.

  • Ссылка на символ

CharRef             ::=   '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'

Ограничение корректности: Допустимый символ

Символ, на который дается ссылка, должен отвечать сценарию Char.

Если ссылка на символ начинается с комбинации "&#x", то все последующие цифры и буквы вплоть до завершающего символа ; образуют шестнадцатеричное представление для кода этого символа, указанного в ISO/IEC 10646. Если же ссылка начинается с комбинации "&#", то все последующие цифры вплоть до завершающего; образуют десятичное представление кода символа.

Ссылка на сущность обращается к содержимому именованной сущности. Ссылка на разобранные общие сущности использует в качестве ограничителей амперсант (&) и символ точки с запятой (;). Ссылка на сущность параметра используют в качестве ограничителей символы процента (%) и точки с запятой (;).

  • Ссылка на сущность

Reference          ::=   EntityRef | CharRef
EntityRef           ::=   '&' Name ';'
PEReference      ::=   '%' Name ';'

Ограничение корректности: Декларированная сущность

Для документа без какого-либо DTD, для документа, имеющего лишь внутренний набор DTD, который не содержит ссылок на сущность параметра, а также для документа с декларацией "standalone='yes'": для каждого Name в ссылке на сущность, которая не попадает ни во внешний набор, ни в сущность параметра, должен иметься соответствующий Name в одной из деклараций сущности, которые также не располагаются ни во внешнем наборе, ни в сущности параметра. Исключение составляют корректные (well-formed) документы, для которых нет нужды декларировать сущности amp, lt, gt, apos и quot. Декларация общей сущности должна предшествовать всем ссылкам на нее, которые могут иметься в декларации списка атрибутов в составе значения по умолчанию.

Заметим, что если сущность была декларирована во внешнем наборе или во внешней сущности параметра, то непроверяющий процессор не обязан читать и обрабатывать ее декларацию. Для подобных документов требование декларировать сущности становится условием корректности только если было указано standalone='yes'.

Ограничение действительности: Декларированная сущность

В документе с внешним набором или внешними сущностями параметра, который имеет декларацию "standalone='no'", лексема Name в ссылке на сущность должна соответствовать Name в одной из деклараций сущности. Чтобы обеспечить взаимодействие, действительные документы должны декларировать сущности amp, lt, gt, apos, quot в том формате, который описан в главе 4.6 Предопределенные сущности. Декларация сущности параметра должна предшествовать любым ссылкам на нее. Точно так же декларация общей сущности должна предшествовать любым декларациям списка атрибута, содержащим значение по умолчанию с прямой либо косвенной ссылкой на эту общую сущность.

Ограничение корректности: Разобранная сущность

Ссылка на сущность не должна содержать имени неразобранной сущности. Ссылаться на неразобранные сущности можно только в тех значениях атрибута, которые были декларированы как имеющие тип ENTITY или ENTITIES.

Ограничение корректности: Отсутствие рекурсии

Разобранная сущность не должна иметь рекурсивной ссылки саму на себя, прямой либо косвенной.

Ограничение корректности: В DTD

Ссылка на сущность параметра может присутствовать только в DTD.

Примеры ссылок на символ и сущность:

Type <key>less-than</key> (&#x3C;) to save options.
This document was prepared on &docdate; and
is classified &security-level;.

Пример ссылки на сущность параметра:

<!-- declare the parameter entity "ISOLat2"... -->
<!ENTITY % ISOLat2
SYSTEM "http://www.xml.com/iso/isolat2-xml.entities" >
<!-- ... now reference it. -->
%ISOLat2;

4.2.1.1.4.2 Декларации сущности

Сущности декларируются следующим образом:

  • Декларация сущности

EntityDecl         ::=   GEDecl | PEDecl
GEDecl              ::=   '<!ENTITY' S Name S EntityDef S? '>'
PEDecl              ::=   '<!ENTITY' S '%' S Name S PEDef S? '>'
EntityDef           ::=   EntityValue | (ExternalID NDataDecl?)
PEDef    ::=   EntityValue | ExternalID

Name используется для идентификации сущности в соответствующей ссылке на сущность, а также идентифицирует неразобранную сущность в значении атрибута ENTITY или ENTITIES. Если одна и та же сущность была декларирована несколько раз, то используется лишь первая из найденых деклараций. По выбору пользователя, XML процессор может генерировать предупреждение в случае, если имеет место многократное декларирование сущностей.

  • Внутренние сущности

Если сущность декларирована как EntityValue, то она называется внутренней сущностью. Для этой сущности отсутствует размещаемый отдельно физический объект, а нее содержание определяется в декларации.

Внутренняя сущность является разобранной сущностью.

Пример декларации внутренней сущности:

<!ENTITY Pub-Status "This is a pre-release of the specification.">

  • Внешние сущности

Если сущность не является внутренней, это внешняя сущность, декларируемая следующим образом:

Декларация внешней сущности

ExternalID         ::=   'SYSTEM' S SystemLiteral | 'PUBLIC' S PubidLiteral S SystemLiteral
NDataDecl         ::=   S 'NDATA' S Name

Если в декларации присутствует NDataDecl, то это общая неразобранная сущность. В противном случае, сущность является разобранной.

Ограничение действительности: Декларированная нотация

Name должно соответствовать декларированному имени нотации.

Литерал SystemLiteral называется системным идентификатором сущности. Он представляет собой ссылку URI (чье определение было дано в [IETF RFC 2396], а затем дополнено в [IETF RFC 2732]), которую необходимо разобрать, чтобы получить данные на вход XML процессора и сформировать текст замены для указанной сущности. Если идентификатор фрагмента (начинающийся с символа #) окажется в составе системного идентификатора, фиксируется ошибка.

Для обработки относительных адресов URI в качестве базового берется адрес того источника, в котором была обнаружена декларация данной сущности, если обратное не было указано в ином источнике информации помимо данной спецификация (например, когда специальный тип XML элемента был определен в отдельном DTD или инструкция обработки определена спецификацией конкретного приложения). Таким образом, URI может вычисляться относительно сущности документа, относительно сущности, содержащей внешний набор DTD, или какой-либо другой внешней сущности параметра.

Ссылки URI требуют кодирования и маскирования (escaping) определенных символов. Среди запрещенных символов числятся все не-ASCII символы, а также исключенные символы, перечисленные в главе 2.4 документа [IETF RFC 2396]. Исключение составляют символы решетки (#) и процента (%), а также символы квадратных скобок, разрешенные документом [IETF RFC 2732]. Запрещенные символы необходимо маскировать следующим образом:

Каждый из запрещенных символов преобразуется в один или два байта в кодировке UTF-8 [IETF RFC 2279].

Все октеты, относящиеся к запрещенным символам, маскируются с помощью соответствующего механизма URI (то есть преобразуются в формат %HH, где HH - шестнадцатеричное представление для соответствующего байтового значения).

Исходный символ замещается полученной последовательностью символов.

Помимо системного, внешний идентификатор может включать также и публичный идентификатор. XML процессор, пытающийся извлечь содержимое сущности, может воспользоваться публичным идентификатором с тем, чтобы сгенерировать альтернативную ссылку URI. Если процессор не сможет сделать этого, он должен воспользоваться ссылкой URI, указанной в системном литерале. Перед проверкой все сочетания пробельных символов в публичном идентификаторе должны быть нормализированы, т.е. заменены на одиночные символы пробела (#x20), начальные и завершающие пробельные символы должны быть удалены.

Примеры деклараций внешней сущности:

<!ENTITY open-hatch
SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">
<!ENTITY open-hatch
PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN"
"http://www.textuality.com/boilerplate/OpenHatch.xml">
<!ENTITY hatch-pic
SYSTEM "../grafix/OpenHatch.gif"
NDATA gif >

4.2.1.1.4.3  Разобранные сущности
  • Декларация текста

Каждая внешняя разобранная сущность должна начинаться с декларации текста.

Декларация текста

TextDecl            ::=   '<?xml' VersionInfo? EncodingDecl S? '?>'

Декларация текста должна быть предоставлена строкой, а не ссылкой на разобранную сущность. Декларация текста не может находиться где-либо еще, кроме как в начале внешней разобранной сущности. Декларация текста во внешней разобранной сущности не является частью текста замены последней.

  • Корректные разобранные сущности

Сущность документа является корректной, если она соответствует сценарию document. Внешняя общая разобранная сущность является корректной, если она соответствует сценарию extParsedEnt. Все внешние сущности параметров являются корректными по определению.

Корректная внешняя разобранная сущность

extParsedEnt     ::=   TextDecl? content

Внутренняя общая разобранная сущность является корректной если ее текст замены соответствует сценарию content. Все внутренние сущности параметров являются корректными по определению.

Следствием корректности сущностей является правильная вложенность логических и физических структур в XML документе: начальный тэг и конечный тэг, тэг пустого элемента, элемент, комментарий, инструкция обработки, ссылка на символ, а также ссылка на сущность не могут начинаться в одной сущности и заканчиваться в другой.

  • Кодирование символов в сущностях

Каждая из внешних разобранных сущностей в XML документе для своих символов может использовать собственную кодировку. Все XML процессоры должны уметь читать сущности в кодировках UTF-8 и UTF-16. В данной спецификации термины "UTF-8" и "UTF-16" не имеют отношения к кодировкам символов с какими-либо иными названиями, даже если эти кодировки и названия очень похожи на UTF-8 или UTF-16.

Сущности с кодировкой UTF-16 должны начинаться с Byte Order Mark, описанного в Приложении F документа [ISO/IEC 10646], Приложении H документа [ISO/IEC 10646-2000], главе 2.4 документа [Unicode] и главе 2.7 документа [Unicode3] (символ ZERO WIDTH NO-BREAK SPACE, #xFEFF). Причем это сигнатура кодировки, а не фрагмент разметки или символьных данных XML документа. XML процессоры должны уметь с помощью этого символа различать документы в кодировках UTF-8 и UTF-16.

Хотя от XML процессор обязуется читать сущности в кодировках UTF-8 и UTF-16, в мире существует и иные кодировки. Поэтому XML процессору потребуется читать сущности и в других кодировках. В отсутствие внешней информации о кодировке символа (например, в MIME заголовке), разобранные сущности, представленные в иной кодировке, нежели UTF-8 и UTF-16, должны начинаться с декларации текста, содержащей декларацию кодировки:

Декларация кодировки

EncodingDecl    ::=   S 'encoding' Eq ('"' EncName '"' | "'" EncName "'" )
EncName           ::=   [A-Za-z] ([A-Za-z0-9._] | '-')*

В сущности document декларация кодировки является частью декларации XML. EncName здесь - название используемой кодировки.

Значения "UTF-8", "UTF-16", "ISO-10646-UCS-2" и "ISO-10646-UCS-4" в декларации кодировки должны относиться к различным кодировкам и трансформациям из набора Unicode / ISO/IEC 10646, значения "ISO-8859-1", "ISO-8859-2", ... "ISO-8859-n" (где n - номер раздела) - к соответствующим разделам кодировки ISO 8859, а значения "ISO-2022-JP", "Shift_JIS" и "EUC-JP" - к различным кодированным формам набора JIS X-0208-1997. Желательно, чтобы обращение к остальным кодировкам символов, зарегистрированным (как наборы символов) в Internet Assigned Numbers Authority [IANA-CHARSETS], осуществлялось через официальное название.

Для названий остальных кодировок должны использоваться префиксы "x-". XML процессоры должны игнорировать верхний и нижний регистр в названии кодировки. Процессор должен либо интерпретировать зарегистрированное в IANA название как указание на использование зарегистрированной под этом именем кодировки, либо считать кодировку неизвестной (разумеется, один процессор не обязуется поддерживать все кодировки, которые были зарегистрированы в IANA).

Если сущность, содержащая декларацию кодировки, предоставлена XML процессору в иной кодировке, чем было заявлено в этой декларации, или сущность, которая не начинается ни с Byte Order Mark, ни с декларации кодировки, была представлена в иной кодировке, нежели UTF-8, а внешний транспортный протокол (например, HTTP или MIME) не предоставил требуемой информации, будет зафиксирована ошибка. Заметим, что поскольку ASCII - является подмножеством UTF-8, то ASCII сущности обычно не нуждаются в декларации кодировки.

Если TextDecl обнаружена не в начале внешней сущности, фиксируется фатальная ошибка.

Если XML процессор сталкивается с сущностью, чью кодировку он не может обработать, фиксируется фатальная ошибка. Фатальная ошибка фиксируется также если было указано (значением по умолчанию, декларацией кодировки или протоколом верхнего уровня), что XML сущность использует определенную кодировку, но в то же время содержит последовательности октетов, которые для этой кодировки недопустимы. Ну и наконец, фатальная ошибка фиксируется, если XML сущность не имеет декларации кодировки, а ее содержимое не относится ни к UTF-8, ни к UTF-16.

Примеры деклараций текста, содержащих декларацию кодировки:

<?xml encoding='UTF-8'?>
<?xml encoding='EUC-JP'?>

4.2.1.1.4.4  Обработка XML процессором сущностей и ссылок

В представленной далее таблице собраны сведения о контексте, в котором могут появиться ссылки на символы, ссылки на сущность, а также вызовы неразобранных сущностей, и какая в каждом случае потребуется реакция от XML процессора. Записи в левой колонке описывают распознаваемый контекст:

Ссылка в содержимом

Ссылка в любом месте элемента в интервале между начальным и конечным тэгами. Соответствует незавершенному (nonterminal) контенту.

Ссылка в значении атрибута

Ссылка либо в значении атрибута начального тэга, либо в значении по умолчанию из декларации атрибута. Соответствует незавершенному AttValue.

Значение атрибута

Это не ссылка, а лексема типа Name. Выступает либо как значение атрибута, декларированного с типом ENTITY, либо как одна из лексем, перечисленных через пробел в значении атрибута, декларированного с типом ENTITIES.

Ссылка в значении сущности

Ссылка из параметра или строкового значения внутренней сущности, находящихся в декларации сущности. Соответствует незавершенной EntityValue.

Ссылка в DTD

Ссылка во внутреннем или внешнем наборе DTD, не попавшая в конструкции EntityValue, AttValue, PI, Comment, SystemLiteral, PubidLiteral, а также содержимое игнорируемой условной секции

  • Не распознается

За пределами DTD символ % теряет специальное значение, поэтому в DTD могут появляться ссылки на сущность параметра, которые в содержимом элемента не распознаются как разметка. Аналогично, названия неразобранных сущностей распознается только в значении соответствующим образом декларированного атрибута.

  • Включается

Сущность называется включенной, если вместо первоначальной ссылки был взят соответствующий текст замены и затем обработан так, словно это был фрагмент документа, находящийся в том месте, где располагалась исходная ссылка. Текст замены может включать и символьные данные, и (за исключением сущностей параметров) разметку, которые должны распознаваться обычным образом. (Например, строка "AT&amp;T;" преобразуется в "AT&T;", а оставшийся в ней амперсант рассматривается не как ограничитель ссылки на сущность.) Ссылка на символ считается включенной, если вместо этой ссылки обрабатывается указываемый ею символ.

  • Включается при проверке

Если XML процессор обнаруживает ссылку на разобранную сущность, то для проверки действительности документа, он должен осуществить подстановку соответствующего текста замены. Если же сущность является внешней, и процессор не предпринимает попыток проверить XML документ, то он хотя и может, но уже не обязан включать в документ текст замены для этой сущности. Если непроверяющий процессор не выполнял подстановки текста замены, он должен информировать приложение о том, что данную сущность он обнаружил, но не прочел.

Представленное положение исходит из того, что автоматическая подстановка, предоставляемая механизмом обработки сущностей SGML и XML, первоначально предназначалась для поддержки модульности при авторизации и не должен был использоваться другими приложениями, например для просмотра данного документа. Например, программа просмотра, встречаясь со ссылкой на внешнюю разобранную сущность, может использовать визуальную индикацию имеющейся ссылки, а саму сущность выводить на экран только по требованию пользователя.

  • Запрещен

Следующие ситуации относятся к разряду запрещенных и соответствуют фатальной ошибке:

  • появление ссылки на неразобранную сущность.
  • появление в DTD символа или ссылки на общую сущность за пределами EntityValue и AttValue.
  • ссылка на внешнюю сущность в значении атрибута.
  • Включается как строка

Если в значении атрибута обнаружена ссылка на сущность, или в строчном значении сущности обнаружена ссылка на сущность параметра, то вместо этой ссылки обрабатывается ее текст замены, словно это был фрагмент документа, находившийся в том месте, где была обнаружена исходная ссылка. Исключение составляют символы одинарной или двойной кавычки, которые в тексте замены всегда воспринимаются как обычный символ данных, а не как завершение соответствующей строки. Например, следующий пример является корректным:

<!--  -->
<!ENTITY % YN '"Yes"' >
<!ENTITY WhatHeSaid "He said %YN;" >

а этот - нет:

<!ENTITY EndAttr "27'" >
<element attribute='a-&EndAttr;>

  • Уведомление

Если название неразобранной сущности было представлено в качестве лексемы в значении атрибута с декларированным типом ENTITY или ENTITIES, то проверяющий процессор должен передать приложению сведения о системных и публичных (если таковые имеются) идентификаторах данной сущности и связанной с нею нотации.

  • Пропускается

Если в декларации сущности в поле EntityValue обнаружена ссылка на общую сущность, она пропускается и оставляется без изменений.

  • Включается как сущность параметра

Поскольку это внешняя разобранная сущность, то потребность в подстановке сущности параметра должна появляться только при проверке. Если в DTD обнаружена ссылка на сущность параметра и выполняется подстановка ее текста замены, то к последнему в начале и конце должно быть приставлено по одному символу пробела (#x20). Этим гарантируется, что текст замены для сущностей параметров будет содержать полный набор грамматических лексем DTD. Описанное положение не относится к ссылкам на сущность параметра в значении сущности - ситуации, описанной в главе 4.4.5 Включается как строка.

4.2.1.1.4.5  Построение текста замены для внутренней сущности

Обсуждая процедуру обработки внутренних сущностей, полезно различать два вида значений сущности. Строковое значение сущности - это строка в кавычках, которая реально присутствует в декларации сущности и соответствует незавершенному EntityValue. Текст замены - это содержимое сущности после подстановки всех ссылок на символ и сущность параметра.

Строковое значение сущности, данное в декларации внутренней сущности (EntityValue), может содержать ссылки на символ, на сущность параметра и на общую сущность. Такие ссылки должны целиком содержаться в строковом значении сущности. Реально подставляемый текст замены должен содержать текст замены для всех сущностей параметров и все символы, на которые делалась ссылка, причем в тех местах строкового значения сущности, где эти ссылки находились. Вместе с тем, ссылки на общие сущности должны оставаться без изменений. Например, даны следующие декларации:

<!ENTITY % pub    "&#xc9;ditions Gallimard" >
<!ENTITY   rights "All rights reserved" >
<!ENTITY   book   "La Peste: Albert Camus,
&#xA9; 1947 %pub;. &rights;" >

тогда текст замены для сущности "book":

La Peste: Albert Camus,
© 1947 Éditions Gallimard. &rights;

Ссылка на общую сущность "&rights;" должна расшифроваться только тогда, когда ссылка "&book;" попадает в содержимое документа или значение атрибута.

Эти простые правила могут иметь сложные взаимоотношения. Детальное обсуждение сложного примера этого см. в Приложении D Обработка ссылок на сущность и символ.

4.2.1.1.4.6  Предопределенные сущности

Ссылки на сущность и символ могут быть использованы для маскирования левой угловой скобки, амперсанта и других ограничителей. Для этой цели сформирован целый набор общих сущностей (amp, lt, gt, apos, quot). Также может использоваться числовая ссылка на символ, которая должна обрабатываться как символьные данные и заменяться соответствующим символом сразу по обнаружении. Таким образом, числовые ссылки "&#60;" и "&#38;" могут быть использованы для маскирования символов < и &, встречающихся среди символьных данных.

Независимо от того, были ли указанные сущности декларированы, они должны распознаваться всеми XML процессорами. Чтобы обеспечить взаимодействие, действительные XML документы перед использованием должны декларировать эти сущности, как и любые другие.

Если сущности lt или amp были декларированы, то они должны быть объявлены как внутренняя сущность, чей текст замены - это ссылка на соответствующий маскируемый символ (знак меньше или амперсант). Для этих сущностей необходимо двойное маскирование, чтобы ссылка на них давала корректный результат. Если декларируются сущности gt, apos или quot, то они должны быть представлены как внутренняя сущность, текст замены которой - это одиночный маскируемый символ (либо ссылка на этот символ, двойное маскирование здесь хотя и допустимо, но необязательно). Например:

<!ENTITY lt     "&#38;#60;">
<!ENTITY gt     "&#62;">
<!ENTITY amp    "&#38;#38;">
<!ENTITY apos   "&#39;">
<!ENTITY quot   "&#34;">

4.2.1.1.4.7  Декларирование нотаций

Нотация идентифицирует по имени формат неразобранных сущностей, формат элементов, обеспечивающих атрибут нотации, или же приложение, которому адресуется инструкция обработки.

Декларация нотации дает этой нотации название, используемое при декларировании сущности, списка атрибутов или в спецификациях атрибутов, а также внешний идентификатор этой нотации, который может позволить XML процессору или его клиентскому приложению найти вспомогательную программу, способную обработать данные, представленные в этой нотации.

  • Декларации нотации

NotationDecl     ::=   '<!NOTATION' S Name S (ExternalID | PublicID) S? '>'
PublicID            ::=   'PUBLIC' S PubidLiteral

Ограничение действительности: Уникальность имени нотации

Любое Name может быть использовано только в одной декларации.

XML процессор должен передать приложению название и внешний идентификатор(ы) всех нотаций, которые были декларированы и на которые имеется ссылка в значениях атрибутов, определениях атрибутов, либо декларациях сущностей. Кроме того, процессор может преобразовывать внешний идентификатор в системный идентификатор, имя файла или иную информацию, необходимую приложению чтобы вызвать процессор для обработки данных в описываемой нотации. (Впрочем, ситуация, когда XML документ декларирует и ссылается на нотацию, для которой не имеется соответствующего процессора обработки в системе, где работают XML процессор или приложение ошибочной не будет.)

4.2.1.1.4.8  Сущность документа

Сущность документа выступает в качестве корня дерева сущностей, а также как стартовая точка для XML процессора. В данной спецификации не конкретизируется, каким именно образом XML процессор должен находить сущность документа - в отличие от других сущностей, сущность документа не имеет имени и вполне может появиться во входном потоке процессора вообще без какого-либо идентификатора.

4.2.2 Формат SVG

Разработка формата SVG представляет собой новейший проект W3C по Web графике. Как только он будет окончательно стандартизован и адаптирован производителями браузеров и программного обеспечения, это будет означать гигантский скачок вперед, от сегодняшних ограничений Web - графики. Формат является открытым стандартом, основанным на языке XML. SVG позволяет описывать графические объекты трех типов: векторные графические фигуры (контуры, состоящие из линейных отрезков и кривых), встроенные растровые изображения и текст.

SVG изображения могут быть динамическими и интерактивными. Объектная модель документа Document Object Model (DOM) для SVG, позволяет создавать впечатляющую и эффективную анимацию, основанную на использовании скриптов на XML. Обеспечивается богатый набор поддержки событий, таких, например, как перемещение курсора мыши над объектом или щелчок мыши. События могут быть назначены на различные элементы SVG изображения.

Другие преимущества SVG - графики: Меньший размер файлов, чем при использовании полностью растровых форматов GIF и JPEG Независимость разрешения изображения от масштаба, так, что изображения могут уменьшаться или увеличиваться для пропорционального отображения в соответствии с размером дисплея на различных типах сетевых устройств, таких как палмтопы, GPS, сотовые телефоны Возможность редактирования и поиска текста в изображении Возможность применения градиентных заливок высокого разрешения, теней и других растровых фильтров Улучшенное управление цветом и точность представления цвета Улучшенный типографский контроль, включая кернинг, текст по кривой и неограниченное использование шрифтов; поддержка каскадных таблиц стилей, делающая возможным глобальные изменения Web сайта многослойная прозрачность.

4.2.2.1  Описание формата

Масштабируемая векторная графика (Scalable Vector Graphics) — XML-язык для описания двумерной векторной графики. SVG был разработан с учетом других стандартов W3C, таких как XLink, XML Namespaces, DOM, CSS и XSL. В SVG-файлах, так же как и в HTML, могут использоваться таблицы стилей для оформления внешнего вида и скрипты для создания динамических эффектов. Специально для мобильных устройств, которые не обладают значительными вычислительными мощностями, были разработаны два варианта стандарта: SVG Tiny (SVGT) и SVG Basic (SVGB).

4.2.2.1.1 Спецификации

В настоящий момент актуальны следующие спецификации:

  • SVG 1.1 (http://www.w3.org/TR/SVG11/)
  • SVG Mobile (http://www.w3.org/TR/SVGMobile/)
4.2.2.1.2  MIME-тип, пространство имен, etc.
MIME-тип image/svg+xml
Пространство имен http://www.w3.org/2000/svg
Публичный идентификатор PUBLIC "-//W3C//DTD SVG 1.1//EN"
Системный идентификатор http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd
4.2.2.1.3 Типы графических объектов

В SVG определены три типа объектов:

  • Векторные, состоящие из прямых линий и кривых
  • Растровая графика
  • Текст

4.2.2.2  Современное состояние дел

В самом начале внедрения формата SVG в практическое использование были следующие возможности:

  • Использования SVG на сервере, а передача пользователю в виде растровых данных. Этот способ имел определенные преимущества (и легко реализовывался с помощью библиотеки Apache Batic), но он не раскрывал всего потенциала, заложенного в векторный формат.
  • Использование плагинов третьих фирм для популярных веб клиентов. Наиболее известные среди все были плагины от Adobe и Corel (Adobe реализовал плагин, по моему мнению, качественнее). Недостатком данного подхода является необходимость доустановки плагина (правда, в некоторых случаях, она могла происходить без участия пользователя).

В настоящий момент ситуация начинает меняться. Начинает появляться встроенная в веб клиенты поддержка SVG.

Самые новые браузеры — Firefox 1.5 (http://developer.mozilla.org/en/docs/SVG_in_Firefox_1.5), Opera 8 (http://www.opera.com/features/svg/index.dml), а теперь еще и тестовые билды Safari (http://webkit.opendarwin.org/blog/?p=35) стали поддерживать SVG.

4.2.3  Формат Adobe Flash (SWF)

В начале 90-х годов Macromedia разработала продукт под названием Shockwave. Shockwave позволял разработчикам мультимедийных программ создавать анимации и даже программировать их, что открывало невиданные до сих пор возможности в интерактивной анимации.

Браузеры тех времен стали поддерживать Shockwave с помощью plug-in-ов, и вскоре Macromedia осознала, что необходимо создать облегченную вер-сию Shockwave, которая будет предназначена исключительно для браузеров. В 1996 году Macromedia приобрела компанию FutureWave software, чей продукт - FutureSplash - стал тем, что мы знаем как Flash 1.0.

Формат Macromedia Flash (SWF) предназначен для представления векторной графики и анимации через интернет для Macromedia Flash. Формат SWF разработан быть эффективным для доставки, а не как формат обмена между разными редакторами.

Основные цели разработки формата:

  • Отображение на экране. Формат в первую очередь предназначен для отображения на экране и поддерживает анти-ализинг, быстрое отображение для любого количества цветов, анимацию и интерактивные кнопки.
  • Расширяемость. Это теговой формат, таким образом можно внедрять новые возможности с сохранением обратной совместимости с ранними версиями Flash Player.
  • Сетевая доставка. Формат может быть доставлен через сеть с ограниченной и нестабильной полосой пропускания. Файлы сжаты и используется инкрементная потоковая визуализация. SWF двоичный формат и использует такие технологии, как упаковка битов и структуры с необязательными полями, для минимизации размера файла.
  • Простота. Формат прост, так что Flash Player мал и легко портируемый. Еще Flash Player зависит от ограниченного числа системных вызовов операционной системы.
  • Файловая независимость. Файлы отображаются, без каких либо зависимостей от внешних ресурсов, таких как шрифты.
  • Расширяемость. Файлы отображаются на ограниченном оборудовании, но также могут на лучшем оборудовании лучше отображаться. Это очень важно, так как разные компьютеры имеют мониторы с разным разрешением и разным количеством цветов.
  • Скорость. Файлы визуализируются с очень высоким качеством с большой скоростью.
  • Скриптуются. Формат включает теги, которые представляют байты, которые могут быть интерпретированы стековой машиной. Эти байтовые коды поддерживаются языком ActionScript. Flash Player предоставляет во время выполнения ActionScript объектную модель, которая позволяет взаимодействовать с графическими примитивами, серверами и возможностями Flash Player’а.

SWF файлы имеют расширение .swf и MIME тип application/x-shockwave-flash.

4.2.3.1 Структура файла SWF

Структура файла довольно проста. В начале, идет заголовок, далее идет последовательность тегов, завершающаяся специальным завершающим тегом.

Все теги имеют стандартный формат, так что, программа, разбирающая SWF файл, может пропустить неизвестные ей теги. Данные внутри тега могу ссылаться внутри данного тега, но не как на данные другого тега, так что можно безболезненно удалять, вставлять и модифицировать SWF файлы довольно легко.

Теги бывают двух типов:

  • Описывающие теги. Данные теги определяют содержимое SWF файла – фигуры, текст, картинки, звуки и так далее. Каждый описывающий тег имеет уникальный идентификатор - character ID. Flash Player хранит данные теги в специальным репозитории, который называется словарем. Описывающие теги не вызывают никого отображения.
  • Управляющие теги. Данные теги создают и управляют отображаемыми экземплярами, которые хранятся в словаре, и контролируют последовательность отображения.

Теги, в общем, могут быть в файле в любой последовательности. Тем не менее, есть ряд правил, которые должны выполняться:

  1. Тег должен зависеть только предстоящих ему тегов. Тег не должен ссылаться на теги, которые идет после него в файле.
  2. Описывающий тег, определяющий графический элемент, должен идти до любого управляющего тега, ссылающегося на него.
  3. Звуковые потоки должны идти по порядку.
  4. Заключающий тег должен быть всегда последним тегом файла.

4.2.3.2 Словарь

Словарь представляет собой хранилище объектов, которые были объявлены и готовы для использования управляющими тегами.  Процесс заполнения репозитория и его использования может быть представлен следующим образом:

  1. Описывающий тег определяет элемент, такой как фигура, шрифт, картинка или звук.
  2. Уникальный CharacterId берется из описывающего тега.
  3. Данные сохраняются в словаре под соответствующим идентификатором.
  4. Управляющий тег извлекает данные из словаря используя идентификатор и выполняет определенные действия, такие как отображение фигуры или проигрывание звука.

Каждый описывающий тег должен содержать уникальный идентификатор. Повторение идентификаторов не допускается. Обычно идентификаторы идут последовательно. Управляющие теги не являются единственными, которые ссылаются на словарь. Определяющие теги могут также использовать элементы из словаря для определения сложных элементов.

4.2.3.3  Обработка SWF файла

Flash Player обрабатывает все теги в SWF файле, до появления ShowFrame тега. В этот момент, список отображения копируется на экран и Flash Player ждет до обработки следующего кадра. Последующие кадры накладываются на предыдущие.

4.2.3.4  Стратегия сжатия файлов

Поскольку SWF файлы часто передаются через сетевое соединение очень важно, чтобы они имели как можно меньший размер. Используются несколько технологий для достижения этого. Перечислим некоторые из них:

  • Повторное использование. Структура словаря позволяет очень легко повторно использовать элементы SWF файла. Например, фигуры, кнопки, звуки, шрифты или картинки могут быть один раз записаны и много раз использованы.
  • Сжатие. Фигуры сжаты благодаря использованию очень эффективной разностной схемы кодирования.
  • Значения по умолчанию. Многие структуры, такие как матрицы координатного и цветового преобразования, имеют поля, которые используются чаще других. В этом случае использование значений по умолчанию помогает минимизировать размер файла.
  • Хранение изменений. В SWF файле сохраняются только изменения между кадрами. Это реализовано в виде хранения графических примитивов и в положить/переместить/убрать модели, используемой списком отображения.

4.2.4 Формат X3D(VRML)

VRML: аббревиатура от Virtual Reality Modeling Language (по отечественному ЯМВР, Язык Моделирования Виртуальной Реальности). Стандарт языка описания трехмерных сцен, содержащих объекты, а также возможных взаимодействий между объектами и наблюдателем. Основное назначение - описание набора объектов (сцены) в системах виртуальной реальности. Основное на данный момент применение - представление статической и интерактивной информации в сети интернет, в виде виртуальной трехмерной среды содержащей различные объекты. Существует три распространенных версии языка: VRML 1.0, 2.0 и VRML 97. На данный момент самой широко поддерживаемой версией является VRML 2.0. Развитие языка координируется VRML Architecture (по другим источникам Advisory) Group (перевод - Группа Архитектуры VRML), известной под аббревиатурой VAG.

4.2.4.1  История

Все началось 27 октября 1969 года, с первого TCP пакета. Затем были "telnet 1.0.0.2" и "ftp 1.0.0.2". Еще позже появился "ftp.cc.mil" и прочие DNS. В 1989 году начал развиваться WWW. Впрочем, все это события глубоко довиртуальной эры. В январе 1994 года, Mark Pesce и Tony Parisi придумывают концепцию трехмерного HTML, своеобразного языка описания трехмерных сцен с поддержкой гиперссылок, и создают пакет программ и экспериментальный формат, названные ими Labyrinth - первый прообраз VRML. В апреле 1994 года их проект участвует в First International Conference on the World Wide Web (Первой Интернациональной Конференции по WWW), где и звучит впервые термин VRML. Кстати, тогда он расшифровывался как Virtual Reality Markup Language, и лишь позже "markup" был заменен на более научно-звучное "modeling".

В июне 1994 года известный журнал WIRED создает список рассылки, посвященной проблеме создания VRML, в течение недели на него подписываются около 1000 специалистов, что в 1994 году было крайне серьезным числом. Они и определяют направление развития концепции, придавая ей, в ходе многочисленных письменных обсуждений, первые очертания. До сих пор соблюдается хорошая традиция совершенствования языка: постоянный поиск решений удовлетворяющих большинство участвующих в обсуждении добровольцев, т.е. столь любимый первым президентом нашей родины консенсус.

Практически сразу решено не заниматься изобретением велосипеда, а взять за основу какой либо существующий язык описания трехмерных сцен. Коим становится разработанный в Silicon Graphics Incorporation формат файлов программной библиотеки Open Inventor. Gavin Bell, инженер SGI модифицировал формат Open Inventor, создав первый вариант языка VRML, который был анонсирован в октябре 1994 года на "Второй Всемирной Конференции по WWW" и 5 ноября превратился в официальный проект стандарта VRML 1.0. Его коллега, Paul Strauss, написал первый VRML 1.0 клиент, назвав его трудно произносимым именем QvLib.

Клиент был впервые представлен для платформы SGI, в январе 1995 года. Печальная легенда гласит, что столь неудобоваримое название программы было придумано, дабы постоянно напоминать авторам о необходимости создать, чуть позже, название гораздо более удобное и красивое. Что, в полном согласии с известной пословицей, так и не было никогда сделано. Позже исходные тексты QvLib были предоставлены всем желающим, вызвав неконтролируемое распространение VRML по аппаратным платформам, сайтам и многочисленным сознаниям людей. Вскоре Parsi создает свою собственную компанию, Intervista, и начинает разработку трехмерного … как это лучше перевести … обозревателя, основанного на VRML. Который был назван WorldView и успешно существует до сих пор.

Тогда же Parsi, Pesce и один известный архитектор из Сан-Франциско осуществляют проект Virtual SOMA - VRML модель южной части пригорода, призванной стать центром мультимедиа и интернет бизнеса, первое масштабное наполовину коммерческое применение VRML технологии. В апреле 1995 года SGI анонсирует новую программу просмотра WebSpace, открывая широкую кампанию по продвижению VRML. В ней принимаю участие такие фирмы, как Netscape, DEC, Spyglass, и NEC. Начинается рекламная шумиха в компьютерной (и не очень) прессе.

На конференции SIGGRAPH'95 язык VRML, несомненно, является основной темой. С этого момента следует стремительная лавина анонсов новых обозревателей, средств создания VRML сцен и просто содержащих VRML контент сайтов. В августе 1995 года Pesce анонсирует создание VAG, начинается разработка проекта стандарта VRML 2.0. Первоначальный проект забит и затоптан в ходе обсуждения, но присланы шесть новых вариантов от ведущих компьютерных фирм:

  • Active VRML от Microsoft
  • Dynamic Worlds от GMD сотоварищи
  • HoloWeb от Sun
  • Moving Worlds от Silicon Graphics сотоварищи
  • Out of this World от Apple
  • Reactive Virtual Environment от IBM Japan

В ходе обсуждений выявляется лидер - Moving Worlds. Вскоре, благородная Apple отказывается от своего проекта в пользу Moving Worlds, остальные гиганты продолжают настаивать на своих вариантах. Некоторое время Moving Worlds шлифуется, постепенно становясь проектом стандарта VRML 2.0. В июне 1996 представители VAG договариваются, подписывая окончательное соглашение, считать работы над VRML 2.0 завершенными.

Кстати, несмотря на поиск консенсуса, работа по созданию и принятию стандарта продвигается невероятно быстро. В декабре 1996 стандарт ISO/IEC DIS 14772-1 (VRML 2.0) принят окончательно. А в октябре 1997 года был завершен проект стандарта новой, расширенной версии языка, названной, в соответствии с последними веяниями, VRML 97. Следует отметить, что VRML абсолютный рекордсмен по скорости разработки и принятия официального стандарта, среди всех компьютерных языков. Развитие VRML продолжается, хоть и не столь бурно, по сей день.

В 1998 году на конференции SIGGRAPH было принято решение о необходимости создания стандартной архитектуры интеграции систем и документов с VRML-сценами, что привело к задаче создания структуры взаимодействия с другими стандартами, такими, например, как XML и MPEG-4.

В сентябре 1999 года был начат проект VRML New Generation, давший возможность использовать не только VRML, но и другие технологии для 3D-Web, после чего VRML-консорциум был переименован в Web3D Consortium и открыл дорогу технологиям, не базирующимся на VRML.

Web3D Consortium объявил своей задачей разработку стандартов в области 3D-Web независимо от VRML и по сути дела стал единственным официальным отраслевым форумом, обладающим механизмом разработки и сконцентрированной технической квалификацией, необходимой для создания таких стандартов. Наличие различных игроков на рынке производства трехмерного контента для Интернета требует развития открытых стандартов. Определенные надежды вселяет разрабатываемый консорциумом стандарт X3D, который должен придать новый импульс развитию стандартов для 3D-Web.

4.2.4.2  Устройство VRML

Итак, необходимо обеспечить выполнение двух основных действий:

  • Описать виртуальный мир.
  • Предъявить этот мир пользователю, позволив ему взаимодействовать с ним.

Решим эти задачи, попробовав себя в непростой роли создателей VRML. В первую очередь необходимо создать информационную структуру, описывающую мир. Чрезвычайно гибкая и удобная структура - граф. То есть набор узлов (в терминологии VRML - node) дополненный информацией о связях между ними. Узлы похожи на обычные структуры данных, они содержат поля (fields) и события (events). Связи между узлами реализуются с помощью полей, имеющих тип указателя (на узел). Фактически, события также представляют собою указатель на объект способный эти события генерировать, или воспринимать, что сразу разделяет их на два типа - исходящие (EventOut) и входящие (EvevnIn), соответственно.

Благодаря подобной концепции, VRML, несомненно, может считаться объектно-ориентированным языком. Все это безобразие, схематически изображенное на рисунке 1, в сумме описывает мир*, в VRML понимании этого слова. Поля Field 1 и 2 представляют собою первичные параметры (например, цвет или точка в трехмерном пространстве), Field 3 является набором указателей на другие узлы, а Event 1 событием, поступающим от двух узлов.

VRML

Структура есть, предположим, что основные типы узлов, событий и полей также определены. Но, пока, это лишь на бумаге и в мыслях, нам же необходимо создать синтаксис языка - формальное описание возможного содержимого файла, в рамках которого наш мир будет формулироваться человеком или редактором. А затем, возможно, он будет интерпретироваться и демонстрироваться программой клиентом (так "успешно" обозванной мною обозревателем).

Разумеется, обозревателя также необходимо разработать и написать, хотя, формально, рамки стандарта заканчиваются уже на этапе формулировки синтаксиса и описания функционирования определенных заранее узлов. Конкретная реализация программы, то, как она будет представлять информацию пользователю и то, как она будет обеспечивать его взаимодействие с виртуальным миром, остаются на совести разработчиков.

Впрочем, этот факт совершенно не спасает от стойкого ощущения дежавю во время работы с большинством распространенных на данный момент клиентов. Достаточное ограничение в простор реализации вносят четкие правила относительно генерации событий и строго фиксированный набор параметров, определяющих визуальное (геометрия, материал и освещение) описание объектов.

4.2.4.3  VRML технология

Стратегия Описание трехмерного виртуального мира, возможность взаимодействия с объектами.
Понятийный уровень Понятие узла, набора, поля, события.
Событийный уровень Правила генерации событий.
Структурный уровень Конкретные типы полей и событий (точка, число, цвет, URL,…).

Конкретные типы узлов, их структура (источник,…).

Языковой уровень Синтаксис описания структур ([], {}, ROUTE, DEF,…).

Синтаксис описания узлов (Field, EventIn,…).

Имена предопределенных типов полей (SFColor, SFBool,…).

Имена предопределенных типов событий (addChildren,…).

Имена предопределенных типов узлов (Anchor, Material,…).

Клиентский уровень Среда распространения VRML описаний (файлы, HTTP,…).

Среда визуализации (OpenGL устройства, принтер,…).

Интерфейс навигации и взаимодействия (мышь, вид из глаз,…).

4.2.4.4  Типы

Разберемся с первичными типами, основными строительными кирпичиками языка VRML. Все типы полей делятся на два класса, содержащие одно значение (так называемые SF типы) и наборы (MF). Для пущей простоты, имена первых всегда начинаются с букв SF, а вторых, как Вы, наверное, уже догадались, с MF. Для записи элементов набора используются квадратные скобки. Например, если у нас есть поле, набор целого типа MFInt32, под названием MyIntegerSet, мы можем описать его следующим образом:

MFInt32 MyIntegerSet

Кстати, VRML болезненно чувствителен к разнице между заглавными и строчными буквами. Поэтому, sfint32 и SFInt32 - два различных идентификатора. Это к слову, а теперь, попробуем заполнить наш набор значениями:

MyIntegerSet [ 1, 0, 0, 1 ]

В одной очень известной трехмерной игре, помнится, как раз подобной комбинацией и открывалась крайне важная дверь. Разумеется, еще мы можем оставить набор пустым или записать в него лишь одно значение:

MyIntegerSet [ ]

MyIntegerSet [ 1 ] или MyIntegerSet 0

И, даже, поступить так:

MyIntegerSet [ 0, ]

Некоторые первичные типы имеют как SF так и MF разновидность, например, если тип называется Color то соответствующие имена записываются как SFColor и MFColor,. Следующая таблица претендует на некоторую долю информативности:

4.2.4.5  Первичные типы данных

Имена типов Описание Пример значения
SFBool Логический тип TRUE
FALSE
SFColor
MFColor
Цвет (три плавающих числа из диапазона 0.0…1.0) 0.1 1.0 0.0
[ 0.1 0.2 0.3, 0.3 0.2 0.1 ]
SFFloat
MFFloat
Плавающее число (IEEE, 32 бит, С нотация) 1.1
[ 3.1415926, .01e-22, 1. ]
SFImage Изображение в виде X Y NC <данные> NC=1 - 255 градаций серого на одну точку
2 - по 255 градаций серого и прозрачности на точку.
3 - по 255 градаций RGB на одну точку.
4 - по 255 градаций RGB и прозрачности на точку.
320 200 1 0xff 0xff 0x00 0x2f… <Сер.>20 30 2 0x1200 0x1300 0x00ff…<Сер.><Проз.>

30 20 3 0xff00ff 0x00ff00… <Кр.><Син.><Зел.>
25 25 4 0xff00ff00 0x000000ff… <Кр.><Син.><Зел.><Проз.>

SFInt32
MFInt32
Целый тип (со знаком, 32 бит, С нотация) 0x33
[ 0xffabcd9, 1, 2, -555555 ]
SFNode
MFNode
Определяет ссылку на узел. В качестве значения можно использовать экземпляр узла. Anchor { … }
[ Anchor { … }, Material {…} ]
SFRotation
MFRotation
Поворот. (ось поворота и угол, X Y Z Alpha). 0 1 0.0 3.1415926
[0 1 0 1.1, 1.0 .0 .0 1.0, …]
SFString
MFString
Строка. (код UTF-8, в C нотации). "Hello, world!\n"
["\"Sam\" it's me", "www.microsoft.com"]
SFTime Время, секунд с 1 января 1970 года. (UNIX формат, плавающее число, 64 бит, в С нотации). 1.34343454545e20
SFVec2f
MFVec2f
Двумерный вектор. (Плавающие числа 32 бита, в С нотации). 0.0 1.0
[ 1.0 2.0, 1.0 0.0 ]
SFVec3f
MFVec3f
Трехмерный вектор. (Плавающие числа 32 бита, в С нотации). 0.0 1.0 2.0
[1.0 1.0 2.0, 1.0 1.0 0.0 ]

Засим, первичные типы успешно закончились.

4.2.4.6 Узлы, связи

А теперь посмотрим все остальное. Основной объект языка - узел. VRML файл (программа) состоит из некоторого количества прототипов (определений новых типов узлов), некоторого количества узлов, заполненных конкретной информацией, и не менее некоторого количества событийных связей между узлами. Все эти элементы могут быть расположены в произвольном порядке.

Экземпляры узлов описываются и заполняются так:

<Название существующего типа> {
<тип поля> <значение>

}

Где специальное слово ROUTE позволяет установить автоматическую отправку конкретного исходящего события одного узла в конкретное входящее событие другого. Также, можно создавать именованyые экземпляры узлов, с возможностью их одновременного использования в нескольких местах программы:

DEF <Имя узла> <Экземпляр узла>

Подобный именованный узел может быть далее использован с помощью другого ключевого слова:

USE <Имя узла>

Заполним, для примера, узел предопределенного типа Anchor, попутно продемонстрировав использование неразлучной парочки DEF/USE:

# Простой красный материал
DEF SimplyRedMaterial Material {
diffuseColor 1 0 0
}

# Ссылка в виде шарика
Anchor {
url "http://www.microsoft.com/"
children [
Shape {
geometry Sphere {
radius 2.0
}
appearance Appearance {
material USE SimplyRedMaterial
}
}
]
}

Определяет ссылку на сайт всеми любимой компании, которая (ссылка, не компания) содержит объект, содержащий, в свою очередь, геометрическую информацию (сфера единичного радиуса) и описание материала имеющего красный цвет в рассеянном свете. Уф… Вот такая вложенная структура данных понадобилась ради одного маленького красненького шарика, неправда ли, это эффективное средство убийства времени набирающего подобные программы человека? Шутки в сторону, вернемся к примеру. Поле children является стандартным для всех узлов, содержащих подчиненные узлы (так называемые "дети") и представляет собою набор типа MFNode. Как правило, узел каким то образом влияет на всех своих детей, например, перемещая их в пространстве, масштабируя, или придавая им какие либо общие свойства. В действительности, узел типа Material имеет множество других параметров, но, в данном примере, мы полагаемся на их значения по умолчанию, определенные где-то в недрах языка. Обратите внимание на комментарий, который обозначается символом # и продолжается до конца строки включительно. Кстати, если добавить в предыдущий пример такую вот первую строчку:

#VRML V2.0 utf8

обязательную для всех VRML 2.0 программ, мы получим полноценный файл, который можно назвать "КакВамУгодно.wrl", открыть в соответствующем обозревателе и даже кликнуть (по красному шарику). До сих пор, мы имели дело с заранее определенными, в языке, типами узлов Anchor, Shape, Sphere и Material. Но, если мы того пожелаем, можно легко определить новый тип узла. Делается это следующим образом:

PROTO <Название нового типа> [
<классификатор>

] {
<Экземпляр узла на основе которого строится новый тип>
<Экземпляры других используемых узлов>
<Описание пути событий>
<Прототип>

}

Классификатор определяет каждый конкретный член нового типа узла. Возможны следующие классификаторы:

field <Тип> <Имя> <Значение> Обычное поле данных
exposedField <Тип> <Имя> <Значение> Поле данных, реагирующее на события
eventIn <Тип> <Имя> Входящее событие
eventOut <Тип> <Имя> Исходящее событие

Поле данных, реагирующее на события (exposedField) порождает исходящее событие <Имя поля>_changed, которое генерируется при изменении значения данного поля каким либо образом и входящее событие set_<Имя поля>, генерируя которое, значение поля можно менять. Разумеется, тип данных этих событий совпадает с типом обслуживаемого или поля. В квадратных скобках оператора PROTO задается интерфейс нового типа узла (доступные для использования поля и события), а в фигурных описывается его реализация. События представляют собою данные, какого либо типа, передаваемые от узла к узлу. Причем, настройка путей передачи происходит специальным ключевым словом ROUTE:

ROUTE <Имя узла>.<Имя исходящего события> TO <Имя узла>.<Имя входящего события>

Вот пример использования ROUTE - столь любимый мною красный шарик, издающий звук, когда с ним сталкивается наблюдатель:

DEF SphereWithSound Collision {
children [
Shape {
geometry Sphere { }
appearance Appearance {
material USE SimplyRedMaterial
}
}
Sound {
source DEF BoomSound AudioClip {
url "boom.wav"
}
}
]
}

 

ROUTE SphereWithSound.collideTime TO BoomSound.startTime

Подобным образом можно легко строить сложно связанные иерархии объектов, в которых изменение каких либо параметров одного узла вызывает незамедлительную реакцию всей системы. Толкнул кубик, а с ним двинулся и шарик, и все такое… Приведу небольшую VRML программу, демонстрирующую не только определение новых типов узлов, но и другие возможностями языка:

#VRML V2.0 utf8

 

PROTO TwoColorStool [
field SFColor legColor  .8 .4 .7
field SFColor seatColor .6 .6 .1
] {
Transform { children [
# Сиденье стула
Transform {
translation 0 0.6 0
children Shape {
appearance Appearance {
material Material { diffuseColor IS seatColor }
}
geometry Box { size 1.2 0.2 1.2 }
}
}
# Первая нога
Transform {
translation -.5 0 -.5
children DEF Leg Shape {
appearance Appearance {
material Material { diffuseColor IS legColor }
}
geometry Cylinder { height 1 radius .1 }
}
}
# Вторая нога
Transform {
translation .5 0 -.5
children USE Leg
}
# Третья
Transform {
translation -.5 0 .5
children USE Leg
}
# Последняя
Transform {
translation .5 0 .5
children USE Leg
}
]}
}

Это определение нового типа узла - двухцветной табуретки. У нее есть два поля определяющие цвет сиденья и ножек соответственно. Давайте внимательно посмотрим на использованные для ее создания узлы:

Transform - осуществляет геометрическое преобразование своих детей, например сдвиг, поворот или масштабирование.

Shape - видимый объект, состоит из описания геометрии и параметров ее отображения, таких как материал, текстура и т.д.

Box, Cylinder - прямоугольник и цилиндр, соответственно.

Также, нам встретился новый оператор IS:

<Имя поля> IS <Имя поля декларируемого типа узла>

<Имя события> IS <Имя события декларируемого типа узла>

Который позволяет связывать параметры и сообщения узлов, из которых состоит реализация создаваемого нами типа, с его интерфейсными параметрами и сообщениями.

Продолжим:

DEF XForm Transform { children [
TwoColorStool { legColor 1 0 0 seatColor 0 0 1 }
DEF Clicker TouchSensor {}
DEF TimeSource TimeSensor { cycleInterval 2.0 }
# Animate one full turn about Y axis:
DEF Animation OrientationInterpolator {
key      [ 0,      .33,       .66,        1.0 ]
keyValue [ 0 1 0 0, 0 1 0 2.1, 0 1 0 4.2, 0 1 0 0 ]
}
]}
ROUTE Clicker.touchTime TO TimeSource.startTime
ROUTE TimeSource.fraction_changed TO Animation.set_fraction
ROUTE Animation.value_changed TO XForm.rotation
NavigationInfo { type "EXAMINE" }

Здесь, мы определяем новый узел XForm типа Transform, который кроме уже описанной нами табуретки (синего цвета с зелеными ножками, рисунок 2) содержит датчик прикосновений TouchSensor, порождающий событие, когда в обозревателе по нашей табуретке щелкают мышкой (т.е. касаются) и таймер TimeSensor. Таймер настроен таким образом, что постоянно генерирует событие fraction_changed значение которого пробегает значение от 0 до 1 за две секунды. Также используется узел OrientationInterpolator, интерполирующий значение типа SFRotation по таблице в зависимости от значения поля fraction. Затем соответствующим образом построено взаимодействие между датчиком прикосновений, таймером, интерполятором и трансформатором позиции табуретки (три ROUTE). В итоге мы получили объект (в нашем случае табуретку, но на ее месте может быть узел любого заранее определенного типа) способный повернуться вокруг себя за две секунды, если к нему прикоснулись. Избушка, избушка, встань к монитору… Последняя строчка переводит обозреватель перейти в режим изучения объекта, в котором наблюдатель не двигается, а просто рассматривает и трогает предмет.

Небольшое продолжение к нашему примеру демонстрирует возможность использования Java Script (если быть корректным - ECMA Script) в VRML программах:

DEF Sizer Script {
eventIn SFTime startSizing
eventOut SFVec3f scale
field SFFloat sc 1.0
field SFBool sizeUp TRUE
url "javascript:
function startSizing() {
if(sizeUp) sc+=0.04;
else sc-=0.04;
if(sc<0.8||sc>1.3) sizeUp=!sizeUp;
scale[0]=sc;
scale[1]=sc;
scale[2]=sc;
}
"
}

 

DEF Ticker TimeSensor {
cycleInterval 0.05
loop TRUE
enabled FALSE
}

 

ROUTE Clicker.isOver TO Ticker.set_enabled
ROUTE Ticker.cycleTime TO Sizer.startSizing
ROUTE Sizer.scale TO XForm.scale

Вот так, с помощью предопределенного узла Script мы получаем практически безграничные возможности в определении правил, по которым будет жить наш мир. В данном примере мы заставляем нашу табуретку циклически менять размер (дышать), пока над ней находится курсор обозревателя, вне зависимости от того, прикоснулись мы к ней или нет. Для этого используется событие isOver узла TouchSenser, реагирующее на описанную выше ситуацию с мышиным курсором, таймер генерирующий 20 раз в секунду событие cycleTime и небольшой скрипт, создающий масштабирование, которое затем применяется к объекту.

4.2.4.7  Дополнения

Список некоторых предопределенных узлов VRML 2.0, отметив, где и как их можно использовать:

Группировка объектов:

Anchor Ссылка на URL или URN (альтернативная форма URL)
Billboard Модификатор осей координат
Collision Обработка столкновений
Group Простая группа
Transform Различные преобразования систем координат

Специальные группы:

Inline Вставка VRML текста из любого URL
LOD Управление уровнем детализации объекта при отрисовке
Switch Управляемый выбор одного ребенка

Общие узлы:

AudioClip Аудио, MIDI или WAV
DirectionalLight Направленный источник света
PointLight Точечный источник света
Script Поддержка внешних языков (ECMA Script, Java,…)
Shape Отображаемый объект
Sound Источник 3D звука
SpotLight Источник света типа прожектор
WorldInfo Дополнительная текстовая информация про данный мир

Генераторы событий:

CylinderSensor Преобразует движения мыши в координаты на поверхности цилиндра
PlaneSensor То же, но в плоскости
ProximitySensor Регион в пространстве чувствительный к проникновению в него
SphereSensor Преобразует движения мыши в координаты на поверхности сферы
TimeSensor Таймер
TouchSensor Датчик прикосновений
VisibilitySensor Датчик видимости

Геометрическая информация:

Box Прямоугольник
Cone Конус
Cylinder Цилиндр
ElevationGrid Поверхность вида z=f(x,y)
Extrusion Фигура образованная 2D контуром, протянутым вдоль кривой
IndexedFaceSet Набор точек и построенных по ним граней
IndexedLineSet Набор точек и построенных по ним линий
PointSet Набор точек
Sphere Сфера
Text Текст

Дополнительная информация:

Color Набор цветов для каждой вершины объекта
Coordinate Набор координат
Normal Набор векторов нормалей
TextureCoordinate Привязка текстуры

Свойства внешнего вида:

Appearance Все в купе для отображаемого объекта
FontStyle Параметры шрифта
ImageTexture Текстура, в виде URL на изображение
Material Материал
MovieTexture Анимационная текстура, URL на клип
PixelTexture Текстура, задаваемая прямо в программе
TextureTransform Дополнительное преобразование текстурных координат

Интерполяторы по таблице значений:

ColorInterpolator Цвета
CoordinateInterpolator Координат
NormalInterpolator Векторов нормалей
OrientationInterpolator Ориентации (поворота)
PositionInterpolator Позиции
ScalarInterpolator Любого плавающего значения

Управление глобальными параметрами обозревателя:

Background Фон изображения
Fog Характеристики атмосферы
NavigationInfo Режим навигации и взаимодействия
Viewpoint Точка обзора

4.2.4.8  X3D (Extensible 3D)

При активной поддержке Web3D-консорциума в 1998 году была образована группа разработки X3D, целью которой было создание расширяемой трехмерной графической спецификации следующего поколения. X3D, по сути, является расширением языка VRML 97 с использованием возможностей расширяемого языка описания Web-страниц XML (Extensible Markup Language).

Из последних изменений нового языка можно отметить принятие в июне 2000 года совместной предварительной спецификации VRML 200x и появление расширения для X3D, предложенного фирмой Lattice Technology, Inc. Таким образом, в недалеком будущем ожидается преобразование всех существующих применений VRML 97 в X3D.

Значительные функциональные возможности X3D были продемонстрированы на симпозиуме Web3D-VRML 2000 в феврале 2000 года. Там же был представлен инструментальный комплект для разработчиков (SDK).

Методы моделирования и представления в VRML-формате с использованием расширений X3D применяются сегодня для представления сложного трехмерного Интернет-контента (вплоть до промышленных моделей систем автоматизированного проектирования CAD/CAM). Соответственно, модели высокого качества и сложные формы создают большие файлы данных, которые трудно передавать по Сети. Можно, конечно, пожертвовать точностью и подробностью представления и для повышения быстродействия уменьшить размер файла, но тогда мы лишимся большой части приложений.

Предложенная фирмой Lattice структура и новый XVL-формат (eXtensible Virtual world description Language), который описывает XML-расширение для X3D — это новая форма описания трехмерной модели, предназначенная для решения вышеупомянутых проблем. Lattice-структура состоит, собственно, из Lattice Surface (поверхности из сплайновых «заплаток» — Gregory patch) или Lattice Mesh (полигональной каркасной сетки).

Использование Lattice-структуры и описывающего ее формата XVL как расширения X3D-стандарта для создания сложных трехмерных сцен в сети Интернет позволяет обходиться маленькими файлами, которые быстро передаются по Сети, но тем не менее сохраняют достаточную точность отображения и большое количество деталей в представляемых моделях.

Это достигается следующим образом: изначально моделируется произвольная сплайновая форма — Lattice-поверхность (очевидно, что даже само представление модели в виде сплайновой поверхности значительно экономичнее), а затем, уже после передачи данных на компьютер пользователя, Lattice-поверхности преобразуются браузером в полигональные сетки для последующей VRML-визуализации. Между Lattice-поверхностью и Lattice-сеткой — взаимно однозначное соответствие (они имеют ту же самую топологию и структуру), и специальный алгоритм может быстро переводить одно в другое. Каркасное представление Lattice-сетей обеспечивает пользователей простым в использовании и легко масштабируемым решением для отображения трехмерных моделей с поддержкой их целостности, а Lattice-поверхность гарантирует гладкость и высокую достоверность при отображении мелких деталей.

При этом использование Lattice-структуры как открытого расширения X3D уже поддержано целым рядом производителей, которые стремятся получить быстрый и эффективный способ для передачи и представления высококачественной 3D-графики в сети Интернет.

Итак, Lattice Mesh позволяет создавать маленькие файлы, а Lattice Surface представляет точные поверхности. Формат XVL может описывать и Lattice Surface, и Lattice Mesh, облегчая эффективную передачу данных и высокую точность представления

4.2.5  Формат XML2D

Формат хранения  объектов разработан на основе языка расширения разметки XML.

XML - это язык разметки(eXtensible Markup Language), описывающий целый класс объектов данных, называемых XML- документами. Этот язык используется в качестве средства для описания грамматики других языков и контроля за правильностью составления документов. Т.е. сам по себе XML не содержит никаких тэгов, предназначенных для разметки, он просто определяет порядок их создания.

Данный стандарт является технической рекомендацией Консорциума W3C и имеет огромную популярность, обусловленную целым рядом своих достоинств:

  • это открытый стандарт, не принадлежащий какой либо конкретной фирме-производителю;
  • не связан с конкретным обработчиком и языкам программирования, в силу своего открытого статуса;
  • не привязан к конкретной платформе;
  • очень простой синтаксис (вся спецификация занимает не более 30 страниц текста);
  • компактность;
  • лаконичность;
  • оптимизирован для использования в Интернете;
  • представляет собой текстовые файлы, которые свободно проходят сквозь прокси серверы и передаются по любым существующим сетям;
  • бесплатен;
  • возможность контроля корректности данных;
  • объектная модель документа(DOM);
  • наличие стандартного механизма преобразования и форматирования XML документов (eXtensible Stylesheet Language, XSL)

По сути XML не исполняет ни каких функций – это просто синтаксис, обеспечивающий представление произвольных данных. То есть позволяющий создавать языки разметки(схемы), которые описывают данные.

XML позволяет также осуществлять контроль за корректностью данных, хранящихся в документах, производить проверки иерархических соотношений внутри документа и устанавливать единый стандарт на структуру документов, содержимым которых могут быть самые различные данные.

Еще одно очень важное достоинство XML документов связано с удобством их программирования, которое обусловлено использованием  DOM технологии.

DOM – это Объектная Модель Документа(Document Object Model),она открывает доступ к документу XML как к древовидной структуре в памяти и обеспечивает удобную среду для программиста. DOM представляет XML документ в виде объекта, доступного как любой другой объект в современных языках программирования, с которым можно работать посредством хорошо документированного интерфейса прикладного программирования, описывающего свойства и методы объекта.

DOM описывает стандартный набор объектов и интерфейсов, обеспечивающих работу с XML документом, его элементами и их атрибутами.

Не маловажным фактом является наличие стандартного механизма преобразования и форматирования XML документов при помощи расширяемого языка стилей(eXtensible Stylesheet Language, XSL). Под преобразованием понимается превращение одного XML документа в другой с изменением структуры. Таблица стилей, или шаблон XSL, позволяет, например, отформатировать документ XML в HTML-представление для последующего отображения на экране.

В данной разработке эта технология позволит в последствии существенно облегчить работу, автоматизируя перевод XML документа разработанного нами формата в формат векторной графики SVG, упомянутый выше.

Представление разработанного формата описывается следующей структурой, хранящейся в файле floor.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<!-- edited with XMLSPY v2004 rel. 2 U (http://www.xmlspy.com) by Mh (Hole) -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault= "qualified" attributeFormDefault="unqualified">
<xs:element name="Object">
<xs:complexType>
<xs:sequence>
<xs:element name="Line" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="X0" type="xs:double"/>
<xs:element name="Y0" type="xs:double"/>
<xs:element name="X1" type="xs:double"/>
<xs:element name="Y1" type="xs:double"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Shape" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Point" minOccurs="3" maxOccurs="unbounded">                              <xs:complexType>
<xs:attribute name="X" type="xs:double" use="required"/>
<xs:attribute name="Y" type="xs:double" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="Filled" type="xs:boolean" default="false"/>
<xs:element name="Border" type="xs:boolean" default="true"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="FillColor">
<xs:complexType>
<xs:attribute name="FR" type="xs:double" use="optional" default="0.0"/>
<xs:attribute name="FG" type="xs:double" use="optional" default="0.0"/>
<xs:attribute name="FB" type="xs:double" use="optional" default="0.0"/>
</xs:complexType>
</xs:element>
<xs:element name="BColor">
<xs:complexType>
<xs:attribute name="BR" type="xs:double" use="optional" default="0.0"/>
<xs:attribute name="BG" type="xs:double" use="optional" default="0.0"/>
<xs:attribute name="BB" type="xs:double" use="optional" default="0.0"/>
</xs:complexType>
</xs:element>
<xs:element name="Text" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Contents" type="xs:string"/>
</xs:sequence>
<xs:attribute name="TX" type="xs:double" use="required"/>
<xs:attribute name="TY" type="xs:double" use="required"/>
<xs:attribute name="TH" type="xs:double" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="Border"/>
<xs:element name="Filled"/>
</xs:sequence>
<xs:attribute name="Layer" type="xs:int" use="required"/>
<xs:attribute name="Priority" type="xs:int" use="optional" default="0"/>
<xs:attribute name="ID" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="Floor">
<xs:complexType>
<xs:sequence>
<xs:element ref="Object" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="Border">
<xs:complexType>
<xs:attribute name="MaxX" type="xs:double" use="required"/>
<xs:attribute name="MaxY" type="xs:double" use="required"/>
<xs:attribute name="MinX" type="xs:double" use="required"/>
<xs:attribute name="MinY" type="xs:double" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

Данная структура автоматически сгенерирована с использованием редактора XMLSpy Schema Editor на основании следующей структуры:

XMLSpy Schema Editor

Описания полей:

Border (атрибуты MinX, MinY, MaxX, MaxY типа double) – границы области видимого изображения;

Object (атрибуты Layer (double) – слой, Priority (double) – приоритет, ID (string) – индивидуальный идентификационный номер объекта служащий первичным ключем для поиска в базе данных;

FillColor (атрибуты FR, FG, FB типа double) – цвет заливки;

BColor (атрибуты BR, BG, BB типа double) – цвет линий и границ областей;

Text (атрибуты TX, TY, TH (double) – положение и высота текста) - содержание находится в поле Contents;

Line – линия;

Shape – область – содержит массив точек и параметры: закрашен/нет и есть граница/нет;

Filled  (объект типа boolean) – означает закрашены или нет объекты типа Shape;

Border (объект типа boolean) – означает ограничены или нет объекты типа Shape.

4.2.6 Формат Shockwave 3D (W3D)

Для пользователей фирма Macromedia (Adobe) предоставляет только «Shockwave 3D Exporter SDK», с помощью которого возможно создание файлов Shockwave 3D.

4.2.6.1  Обзор процесса экспорта

Рисунок. Общий процесс экспорта.

Общий процесс экспорта

4.2.6.1.1  Средство создания трехмерной сцены (3-D Authoring Tool)

Вначале работы необходимо создать иерархическую трехмерную модель и подготовить базу данных для трехмерной сцены.

4.2.6.1.2  Плагин для экспорта (Exporter Plug-In)

Плагин инициализирует процесс экспорта. Он инициализирует внутренние объекты.

4.2.6.1.3  Преобразование сцены (Scenegraph Conversion)

На этом этапе необходимо преобразовать всю иерархию объектов сцены, проанализировать ее и сконвертировать все элементы сцены в следующие базовые типы:

  • узел иерархии
  • ресурс источника света
  • ресурс шейдера
  • ресурс материала
  • ресурс текстуры
  • ресурс модели
  • ресурс микшера
  • ресурс движения
4.2.6.1.4  Преобразования меша (Mesh Conversion)

Элементы модели/геометрии еще подвергаются дополнительному шагу обработки, до того, как процесс преобразования полностью завершился. Экспортер преобразует меш, полученный из средства создания трехмерной модели к структуре IFXAuthorMesh. Далее эта структура будет скомпилирована с помощью IFXAuthorMeshCompiler для создания IFXMesh/Shockwave 3D структуры данных, в которой материалы будут разделены на части, для обеспечения наибыстрейшего отображения данной геометрии во время визуализации.

4.2.6.1.5  Shockwave 3D сцена (Shockwave 3D Scenegraph)

На данном этапе мы получаем Shockwave 3D базу данных сцены. Эта база данных является некоторым упрощением исходной модели для обеспечения наибыстрейшей визуализации. Сцена теряет иерархические связи (потомок-отец) и многое другое.

4.2.6.1.6  Менеджер записи (WriteManager)

Экспортер вызывает WriteManager, который записывает находящуюся в памяти базу данных Shockwave 3D в буфер записи и далее в .W3D файл.

4.2.6.1.7  Итог

Таким образом, процесс экспорта в первом приближении состоит из четырех шагов:

  • Передача графической информации между средством создания трехмерной модели и экспортером
  • Преобразование графической модели и преобразование геометрии модели в формат Shockwave 3D
  • Создание базы данных Shockwave 3D
  • Запись базы данных Shockwave 3D в .W3D файл

4.2.6.2  Структуры W3D файла.

4.2.6.2.1  Граф сцены Shockwave 3D.

Shockwave 3D это высокоуровневый граф сцены, спроектированный для оптимизации и визуализации в реальном времени сцен с объемным и гибким (интерактивно управляемым) трехмерным содержимым.

Граф сцены служит для отображаения палитры ресурсов в иерархии сцены.

4.2.6.2.2  Структура графа сцены.

Shockwave 3D это база данных которая описывает трехмерную сцену. Она использует палитры (индексные таблицы) для описания содержимого сцены (модели, источники свнта, движения, изображения) и их взаимоотношения. Политры указывают на ресурсы (объекты данных),  которые содержат информацию о конкретном объекте. После занесения данных сцены в базу данных на них могут быть наложены новые взаимосвязи. Например, ресурс движения может совместно использоваться различными ресурсами моделей или модели может быть присвоен любой материал из базы данных.

4.2.6.2.3  Иерархия сцены.

Иерархия сцены включает узлы которые преобразуют и группируют объекты в сцене. Эти узлы поддерживают произвольное количество дочерних объектов и ссылку на единственный родительский объект.

Существует четыре базовых узла сцены:

  • Group - групповые узлы, определяют позиции дочерних объектов в пределах мирового пространства и ассоциативную информацию.
  • Light – источники света, определяют освещенность сцены.
  • Model - узлы модели, которые определяют геометрию, представляемую в виде полигональной сетки, модификаторы полигональной сетки, модели остова для анимации (bones), ключевые кадры анимации (keyframes), и материалы.
  • View - узлы вида, определяют информацию о камерах в сцене.

Хотя иерархию сцены можно изменят и после конвертации с использованием специального API предоставляемого системой Macromedia Director, гораздо эффективнее создавать иерархию сцены в процессе конвертации, иначе каждый раз при запуске приложения содержащего w3d файл будет тратится значительное время на создание данной структуры. Такая экономия очень существенна, так как загрузка сложных трехмерных моделей сама по себе занимает довольно длительное время, тем более, что разрабатываемая технология рассчитывается на работу в сетях Internet, Ethernet.

4.2.6.2.4  База данных графа сцены.

Существуют четыре основных категории Shockwave 3D объектов представляемых в базе данных графа сцены:

  • Палитры (группы, источники света, стили …)
  • Геометрия модели
  • Анимация с использованием модели остова (bones)
  • Анимация по ключевым кадрам

Палитры и ключевые кадры анимации конвертируются непосредственно в структуры данных Shockwave 3D. Модели и анимируемая геометрия, однако требует дополнительного шага. Так как Shockwave 3D представляет модель и анимацию в виде быстродействующих структур данных которые не могут просто конвертироваться непосредственно из исходной сцены.

4.2.6.2.5  Менеджер записи.

После создания графа сцены Shockwave 3D конвертер вызывает WriteManager, который ссылается на граф сцены в памяти и переводит его в буфер записи для создания .W3D файла.

4.2.6.2.6  Палитры и ресурсы.

Палитры лежат в основе графа сцены, они упорядочевают объекты сцены и ссылаются на различные ресурсы  необходимые для отображения сцены. Ресурсы включают в себя: ресурсы материалов (шейдеры, материалы, текстуры), ресурсы моделей (геометрия и модификаторы), ресурсы моделей движения (ключевые кадры).

4.2.6.2.6.1  Палитры графа сцены

Палитры являются базовыми элементами Shockwave 3D сцены, они включают все разделяемые данные Shockwave 3D сцены. Запись в индексной таблице палитры содержит базовую информацию о данном элементе палитры  и указатели на другие палитры ресурсов которые полностью описывают объект.

Данные добавляются и извлекаются из палитры по имени. Запрос к палитре по имени возвращает идентификатор (ID) объекта в палитре, который собственно является индексом объекта в сцене. Каждая палитра содержит запись по умолчанию с ID=0. Например в палитре иерархии узлов эта запись характеризует корень (базовый узел) сцены.

4.2.6.2.6.2  Палитра узлов.

Каждая запись в этой палитре содержит информацию о иерархии графа сцены Shockwave 3D. Сюда включаются узлы производные от  IFXNode:

  • Группы : Пустые узлы для трансформации, которые создают и поддерживают иерархию сцены. Они объединяют дочерние узлы вместе, благодаря чему ими можно манипулировать одновременно с использованием общей трансформации. По умолчанию существует единственная группа с именем World (корень сцены). Она не имеет родительских узлов и не может быть удалена из сцены.
  • Модель: Позиционный узел который задает расположение объекта в сцене. Так же модель содержит информацию, определяющую ресурс модели и параметры всех объектов модификаторов подключенных к модели, как и параметры собственно ресурса модели.
  • Источники света: Позиционные узлы, определяющие позицию, ориентацию, и состояние Ресурсов источников света.
  • Виды: Это камера в Shockwave 3D эквиваленте. Эти узлы не имеют ресурсов, таким образом вся информация о видах изолируется в этих узлах. Сюда входит размер, позиция, направление вида и характеристики очистки буфера.

Каждый узел определяет своего родителя, свой тип (свет, вид, группа, модель), и матрицу локальных преобразований.

Палитра иерархии узлов так же хранит идентификаторы (ID) палитры ресурсов соответствующих узлов (за исключением узлов групп и видов, которые существуют только в палитре иерархии узлов), и указатели на списки свойств пользователя и списки параметров модификаторов узлов.

4.2.6.2.6.3   Палитра ресурсов источников света.

Эта палитра содержит все источники света сцены. Так как палитра иерархии узлов содержит всю информацию сцены о источниках света,  палитра ресурсов источников света содержит просто указатель на объект ресурса источника света, который хранит тип, цвет, и эффекты производимые светом.

4.2.6.2.6.4   Палитра ресурсов шейдеров.

Эта палитра содержит все шейдеры сцены и указывает на объект ресурса шейдера, который в свою очередь указывает на данные палитры материалов и палитры текстур. В ней содержатся записи о идентификаторе материала (Material ID) и несколько идентификаторов текстур (Texture ID) (базовая текстура, текстура отражения , bump, и др).

4.2.6.2.6.5  Палитра ресурсов материалов.

Эта палитра содержит все различные именованные наборы базовых свойств материалов. Которые хранятся в объекте ресурса материала, задающем следующие свойства рассеиваемый цвет, цвет окружающей среды, цвет бликов, прозрачность, эластичность, и светимость.

4.2.6.2.6.6  Палитра ресурсов текстур.

Эта палитра содержит все объекты текстур, высокоуровневые структуры, которые задают параметры текстуры. Включая идентификатор текстуры (ID), прозрачность и глубину. Объект текстуры является родителем источника текстуры, и может быть скомбинирован с другим объектом текстуры с использованием операторов текстур.

Существует два типа ресурсов текстур: сжатый  JPEG файл, который декомпрессируется и инициализируется по запросу графа сцены и необработанные данные изображения, которые обрабатываются и инициализируются в процессе экспорта. Параметры источника текстуры определяют то, как текстура будет сжата и как она будет храниться и впоследствии записываться Shockwave 3D файл.

Операторы текстур объединяет различные источники текстуры в единый объект. Операторы включают в себя насыщенность, размытие, смешивание, маскирование. Эти операторы могут быть анимированы для создания различных эффектов.

4.2.6.2.6.7  Палитра ресурсов перемещения.

Эта палитра содержит все перемещения которые используются в сцене, указывая на объект ресурса перемещения. Перемещение состоит из нескольких именованых треков перемещения, каждый из которых содержит несколько ключевых кадров перемещения.

4.2.6.2.6.8  Палитра ресурсов миксера.

Эта палитра содержит все миксеры используемые в сцене, ссылаясь на объект IFXMixerConstruct. Миксер отвечает за распределение именованных перемещений хранящихся в объекте ресурса перемещения на именованные модели остова хранящиеся в объекте ресурса модели.

4.2.6.2.6.9  Палитра ресурсов модели.

Эта палитра содержит все объекты содержащие геометрию, указывая на объект ресурса модели.

Объект ресурса модели содержит многочисленные указатели на другие палитры и объекты. Он указывает на цепь модификаторов (например, UV координаты, остов, ключевые кадры, генераторы примитивов) контролируемых списком параметров модификаторов связанных с узлом данной модели, которые задают деформацию и перемещение объекта во времени. Так же он ссылается на объект IFXModelData, который содержит:

Геометрию объекта, хранящуюся в форме оптимизированной для отображения (IFXMeshGroup).Структуры данных IFXMeshGroup и IFXMesh содержат набор вершин и граней которые используют общий материал. С использованием этой структуры графическое ядро может отображать все полигоны использующие общий материал последовательно. Благодаря этому минимизируются  затраты процессорного времени и памяти на изменение состояния материала.

Набор коррекции для полигональной сетки который позволяет уменьшить ее, вершину за вершиной, до пустой сетки (IFXUpdatesGroup).

Описание связности полигональной сетки модели (IFXNeighborMesh).

Характерная для модели палитра стиля. Которая содержит список различных "стилей" или "групп шейдеров" используемых объектом. Стиль это структура используемая для того чтобы задать какой шейдер используется для отображения каждого полигона ресурса модели.

Палитра ресурсов модели

4.2.6.2.7  Модели и шейдеры

Многие среды моделирования присваивают моделям свойства поверхностей, например прозрачность, выпуклость, рассеиваемый цвет. Эти свойства называются шейдерами, материалами, текстурами в зависимости от среды моделирования. В Shockwave 3D используются следующие понятия:

  • Шейдер: атрибуты поверхности на высшем уровне.
  • Материал: атрибуты поверхности на низшем уровне, включая рассеиваимый цвет, прозрачность, цвет бликов.
  • Текстура: изображение или битовая карта которая применяется к каналам рассеивания, бликов, выпуклости и отражения объектов.
  • Стиль: Набор шейдеров, используемых моделью.

Важно следить, чтобы существовала только одна копия каждой уникальной записи палитр свойств поверхностей. Когда шейдер применяется к поверхности, индекс соответствующей записи в палитре ресурсов шейдера добавляется в стиль в палитре стилей ресурсов модели.

4.2.6.2.8  Текстурные слои

Shockwave 3D, как и многие системы реального времени отображения трехмерных сцен, используют аппаратные текстурные слои, для симуляции различных эффектов освещения. Формат поддерживает следующие текстурные слои:

  • BASE – базовая текстура
  • REFLECTION - текстура отражения
  • GLOSS – текстура глянцевости
  • DIFFUSE - текстура рассеивания
  • SPECULAR – бликовая текстура
4.2.6.2.9  Анимация

Shockwave 3D  предоставляет простое представление перемещений объектов в пространстве в течении времени. Каждый уникальный трек перемещения полигональной сетки в сцене и внутреннее движение любых фигур имеющих остов хронятся как отдельные объекты – ресурсы перемещения в палитре ресурсов.

Группы, источники света и виды не могут анимироваться непосредственно, для анимации их перемещений необходимо создать для них родительский объект в виде полигональной сетки (который можно сделать невидимым с использованием свойства пользователя sw3d_visibility) и применять анимацию к этому объекту

Если ресурс модели использует модификатор анимации по ключевым кадрам и модификатор анимации остова последний должен идти до модификатора анимации по ключевым кадрам.

Ресурс перемещения хранит данные о анимации в одном или нескольких именованых объектах – треках перемещения. Трек перемещения содержит массив объектов ключевых кадров которые задают серии позиций, вращений, масштабов и времен, которые контролируются треками перемещений.

Такое представление анимации помогает избегать избыточности. Движение задаваемое одной моделью может быть применено к любой другой другой.

4.2.6.3  Повышение производительности.

4.2.6.3.1  Совместное использование ресурсов.

При просмотре 3-D сцены, данные о ее содержимом должны передаваться от сервера браузеру пользователя предположительно по Internet соединению. Сжатие данных сцены это один из способов ускорить данный процесс. Разделение ресурсов, которое сокращает количество данных в сцене еще один путь уменьшения времени загрузки.

При разделении ресурсов важно то, что любые элементы сцены хранятся только в единственном экземпляре в базе данных графа сцены Shockwave3D. То есть, например если несколько объектов используют  одну и ту же текстуру, она будет храниться в единственном экземпляре, а материалы моделей будут содержать лишь ссылки на эти текстуры. Это существенно уменьшает размеры w3d файла, так как около 90% от его общего размера занимают текстуры. В среднем размер файла сокращается на 80-85%.

4.2.6.3.2  Упрощение (выравнивание) иерархии

Для дальнейшего увеличения эффективности, необходимо при экспорте максимально уменьшить общее количество узлов сцены, объединяя отдельные полигональные сетки в одну где это возможно в исходной сцене. Например можно объединить дочерние полигональные сетки общего родительского узла.  Уменьшение числа узлов которые  Shockwave3D должен будет отследить, визуализировать, и проверить на коллизии позволяет значительно быстрее отображать граф сцены

4.2.6.3.3  Сжатие

Сжатие не удаляет никакие грани из модели, но приводит к тому что позиции вершин (включая нормали и тексурные координаты) представляются с меньшей точностью, что приводит к тому, что они меняют свои действительные позиции. Этот дрейф вершин увеличивается с ростом степени сжатия, что может привести к заметному съеживанию объекты. Установка качества равная 1000 означает наименьшее сжатие полигональной сетки и отображение ее с максимально возможной точностью. Позиции вершин все равно не соответствуют своим действительным координатам, но они максимально близки к ним.

Упрощение не создает промежутки в модели, однако это приводит к тому, что существующие в модели становятся все больше с ростом степени сжатия. Степень до которой автоматически упрощается модель зависит от фреймрейта, который использует система, сложности модели, дистанции между моделью и камерой, и сложности всей сцены вцелом. Очень сложные модели требуют большего упрощения для получения приблизительно 30 кадров в секунду, даже при использовании высоко производительных машин.

4.2.6.3.4  Использование различных степеней детализации

Уменьшение степени детализации (LOD) удаляет вершины из модели. Это осуществляется на основании локальной гладкости или негладкостии поверхности в окрестности каждой вершины. Гладкие поверхности остаются, а зубчатые удаляются.

Острые но важные нюансы модели, как например антена транспортного средства, могут быть сохранены от удаления путем объявления их базовыми.

Степень сжатия может регулироваться следующими записями списка свойств пользователя: sw3d_lod_adjust_normals, sw3d_lod_minimum_crease_angle, и sw3d_lod_max_normal_error.

Установки свойств пользователя по умолчанию может привести к удалению вершин которое резко изменит нормали поверхности, что чревато появлением отверстий в модели. Грани модели с противоречивым направлением нормалей, или грани нулевой площади, например, может привести к разделению модели. Уменьшение sw3d_lod_max_normal_error или увеличение sw3d_lod_minimum_crease_angle свойств пользователя обычно позволяет избежать появления отверстий при упрощении модели.

4.2.6.3.5  Свойства пользователя

Это произвольные текстовые данные, ассоциируемые с любым объектом Shockwave 3D сцены.

4.2.6.3.5.1   Задание видимости моделей

Для задания видимости модели при конвертации необходимо присвоить значение полю sw3d_visibility списка свойств пользователя одно из следующих значений: front/back/

none/both. Значение по умолчанию front

4.2.6.3.5.2   Приоритеты потоковой загрузки

Приоритет загрузки это метод используемый .w3d файлом для определения общего порядка загрузки моделей и текстур в поток. Приоритет загрузки модели лежит в диапазоне 0 to 256, а текстур в диапазоне 0 to 1024. Объекты с высоким приоритетом загружаются быстрее.

Для задания приоритета при конвертации необходимо присвоить значение полю sw3d_stream_priority списка свойств пользователя.

Приоритет загрузки моделей по умолчанию равен 256. Приоритет загрузки текстур по умолчанию определяется как наибольший приоритет из всех моделей содержащих текстуры умноженный на 4.

4.2.7  Формат Mesh3D

Оригинальный формат, разработанный специально для поддержки предлагаемой методики. Формат оптимизирован для хранения и обработки трехмерной геометрии, представленной в виде полигональной сетки.

4.3 Краткий обзор неиспользуемых форматов и технологий

4.3.1 Java3D

Многообещающая технология от Sun. Кажется весьма перспективной (в особенности, что касается мобильного применения – 3D игры для сотовых телефонов). Но по ряду причин в данном проекте была не востребована.

4.3.2 Технологии Right Hemisphere

Фирма специализируется на выпуске программного обеспечения и технологий для Product Graphics Management.

Технологии Right Hemisphere

Наибольший интерес, с точки зрения разрабатываемой технологии, для нас имеет:

  • Deep Server
  • Deep Paint 3D
  • Deep UV
  • Deep Publish/Deep View

По оценке автора диплома технологии, предлагаемые этой фирмой, являются наиболее прогрессивными и привлекательными для использования. Компания развивается довольно стабильно, в особенности после лицензирования Adobe технологии Pdf 3D.

4.3.3  Blender

GNU трехмерный редактор. Реализует оригинальный подход к редактированию моделей, к которому после таких систем как 3ds Max или Maya, привыкнуть довольно трудно. Имеет хороший инструментарий для написания дополнений. Планировалось использовать как основное средство постобработки моделей, но по временным причинам не получилось.

В целом программный продукт оставил о себе весьма благоприятные впечатления.

4.3.4 Autodesk DWF

Формат DWF был разработан как независимый векторный формат для обмена двумерными чертежами в сети Интернет. В отличие от растровых форматов DWF включает в себя средства задания информации о слоях и видах,  предусматривает наличие в чертеже гиперссылок и URL (Universal Resource Locator), поддерживает информацию о единицах измерения чертежа и включает в себя некоторые другие специфические возможности.

Данный формат имеет следующие достоинства:

  • Независимость от платформы и приложений. DWF формат специфицирует набор примитивов, типичный для большинства коммерческих приложений, оперирующих 2D-графикой
  • Совместимость. DWF предоставляет общий синтаксис для обмена 2D-чертежами между теми приложениями, которые генерируют чертежи и теми приложениями, которые предоставляют средства просмотра чертежей.
  • Простота. DWF предоставляет гибкий синтаксис описания примитивов, то есть в простых случаях допустимо определять минимум информации о примитивах, но в случае необходимости синтаксис формата позволяет описывать достаточно широкий набор аттрибутов.
  • Расширяемость. Формат предусматривает возможность расширения синтаксиса и описывает правила для програм чтения DWF для распознавания привнесённых синтаксических конструкций. В частности, расширение спецификации формата не влияет на обработку новых DWF файлов старыми приложениями.
  • Стабильность. DWF остаётся относительно неизменным достаточно длительное время в следствие своей независимости от приложений и расширяемости синтаксиса.
  • Широкий набор примитивов. Формат поддерживает как простые примитивы (линии, многоугольники, кривые 2-го порядка), так и более сложные (Текст, кривые Безье, растровые данный), а также достаточный набор аттрибутивной информации (такой как видимость объектов, прозрачность, кодовые страницы и т.д.)
  • Компактный размер. DWF-файл может существовать в доступном для чтения ASCII формате, в двоичном формате, а также в двоичном формате с использованием сжатия.
  • Механизм встраивания. DWF предусматривает возможность “вложения” данных прочих форматов, например растровый рисунок может быть легко выделен из DWF файла и передан другому приложению.
  • Поддержка URL. В описание чертежа к любому объекту могут быть добавлены интернет-ссылки, таким образом пользователь может перемещаться, например, к более детальным видам или получать связанную с объектом информацию в виде других форматов (текст, звук, видео и т.д.)

Последние время эта технология начинает на себя обращать все больше внимания. Основные преимущества:

  • Поддержка 2D/3D векторных данных;
  • Наличие кросс-платформенного объектно-ориентированного (С++) SDK, позволяющего читать/писать DWF файлы.
  • Наличие интерфейса, позволяющего расширять стандартный просмоторщик своей функциональностью.
  • Наличие спецификаций на сам формат.

По состоянию на сегодняшний день этот формат в скором времени может вырасти до уровня, когда с его помощью можно будет решать задачи, которые возникали при разработке данной методики.

4.3.5  VML

Vector Markup Language (VML) - векторный формат представления двумерных данный для Internet. Разработан корпорацией Microsoft. Основан на XML. Поддерживается всеми новыми продуктами Microsoft. Microsoft передал в мае 1998 г. спецификацию этого языка W3C в качестве предложения для стандартизации, однако W3C предложил в качестве стандарта собственную спецификацию SVG (Scalable Vector Graphics).

« Предыдущая Следующая »
Информация о файле
Похожие публикации
Похожих публикаций не обнаружено.