Шаг 16 - Массив трехмерных линий, узел IndexedLineSet

Прежде чем рассматривать основной узел давайте познакомимся с узлом Color:

Color {
	exposedField MFColor color []
}

Этот узел создает массив цветов заданных в виде RGB. Для примера давайте определим массив из красного, зеленого, синего и белого цвета:

Color {
	color [ 1 0 0, 0 1 0, 0 0 1, 1 1 1]
}

Теперь поговорим про узел IndexedLineSet и про то, как с ним связан Color. Опередяется этот узел следующим образом:

IndexedLineSet { 
	eventIn       MFInt32 set_colorIndex
	eventIn       MFInt32 set_coordIndex
	exposedField  SFNode  color             NULL
	exposedField  SFNode  coord             NULL
	field         MFInt32 colorIndex        []
	field         SFBool  colorPerVertex    TRUE
	field         MFInt32 coordIndex        []
}

Данный узел создает трехмерный объект из точек соединенных полиниями. Набор точек задается в поле coord с помощью узла Coordinate, о котором вы можете почитать в предыдущем шаге. Поле coordIndex это массив из номеров трехмерных вершин, которые соединяются отрезками. Одна так называемая полилиния может состоять из большого количества отрезков и для того, чтобы разделить между собой эти линии снова используется признак "-1". Давайте возьмем в качестве примера набор точек из предыдущего шага и соединим их линиями:

#VRML V2.0 utf8
WorldInfo { 
  info  ["IndexedLineSet Example"]
  title "Step 16 Example"
}

Background{
	skyColor 1 1 1
}
Group {
children[
	Shape {
	appearance Appearance {
# нужно назначить излучающий свет материал,
# чтобы линии были видны, т.к. без этого они не
# отображаются, с данными  узлами познакомимся позже
	material Material {
	emissiveColor 0 0 0
	}
}
geometry IndexedLineSet {
# координаты точек 
coord Coordinate {
	point [
		0 0 0	#1 точка
		1 0 0	#2
		0 1 0	#3
		0 0 1	#4
		1 1 1	#5
	]
}

# соединения точек, первая линия из точки 0 в точку 1,
# вторая линия из точки 0 в точку 2 и т.д.
# разделителем для полилиний является "-1"
coordIndex [ 0 1 -1 0 2 -1 0 3 -1 0 4 ]


} # конец IndexedLineSet
} # конец Shape
] # конец children
} # конец Group

В результате данного примера можно увидеть такую катинку:

16_1.gif (425 b)

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

Не зря в начале мы с вами рассмотрели узел Color. Он определяет набор цветов для окраски линий. Сам по себе он не может производить каких-либо действий, потому что жестко контролируется значениями поля colorPerVertex.

Если значение colorPerVertex равно FALSE, то это значит, что цвета определенные узлом Color назначаются полилиниям. При этом анализируется значение поля colorIndex. Этот массив содержит номера цветов из узла Color, которые по порядку назначаются всем полининиям. При этом массив colorIndex должен содержать столько же значений, сколько определено полилиний. Если количество значений меньше, то полилинии будут окрашиваться вне зависимости от номеров цветов. Маленький пример, добавьте эти строки в узел IndexedLineSet в примере приведенном выше:

# опеределяем набор из 4 цветов: красный, зеленый, синий и желтый
color Color{
	color [ 1 0 0, 0 1 0, 0 0 1, 1 1 0]
}  
# устанавливаем окраску для полилиний
colorPerVertex FALSE
# индексы для цветов
colorIndex [ 0 1 2 3 ]

Давайте поиграемся со значениями поля colorIndex, чтобы лучше понять его функцию:

16_2.gif (1973 b)

Вариант под номером 1 демонстрирует нормальную закраску, как мы и определили. Вариант 2 также не имеет ошибок. В вариантах 3 и 4 содержатся ошибки. В первом используется номер цвета 5, которого не существует в наборе, поэтому на рисунке одна из линий окрашена в черный цвет. Во втором количество значений в поле меньше, чем количество полилиний. В этом случае все полилинии приобрели цвета непосредственно из узла Color напрочь игнорируя значения в поле colorIndex. Вариант 4 демонстрирует случай, когда поле indexColor пусто. Таким образом, если количество цветов заданных в indexColor не совпадает с количеством полилиний, то цвета из узла Color назначаются по порядку каждой полилинии. Также, если количество цветов определенных в узле Color меньше количества полилиний, то все остальные полилинии приобретают черный цвет.

Теперь осталось разобраться со случаем, когда поле colorPerVertex равно TRUE. По приблизительному переводу названия поля Вы могли догадаться, что в таком случае цвета из узла Color назначаются не полилиниям, а вершинам их образующим, при этом сами полилинии окрашиваются градиентом из цвета одной вершины в цвет другой. Но это еще не все. Поле colorIndex теперь чуть изменяет свой формат. Теперь оно должно быть похоже на поле coordIndex, т.е. содержать разделители между полилиниями "-1", а вместо номера вершины теперь указывается номер цвета, который принимает эта вершина. Если вдруг вы допустите ошибку в количестве вершин в полилинии, то массив indexColor будет считаться ошибочным и все его значения будут игнорироваться.

Давайте рассмотрим пример:

# опеределяем набор из 5 цветов, т.к. вершин 5 штук
color Color{
	color [ 1 0 0, 0 1 0, 0 0 1, 1 1 0, 1 0 1]
}  
# устанавливаем окраску для вершин
colorPerVertex TRUE
# индексы для цветов вершин (заданы верно)
colorIndex [ 0 1 -1 2 3 -1 3 4 -1 2 2]

На рисунке ниже продемонстрированы два случая, когда поле colorIndex задано верно и когда с ошибками:

16_3.gif (1657 b)

Вы видите, что во втором случае вершинам назначены цвета по порядку из узла Color.

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


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Кузин Андрей.