#include <Inventor/actions/SoSearchAction.h>SoSearchAction - класс, выполняющий поиск по графу-сцене с учётом заданных параметров. Поиск может выполняться по указателю, типу, имени или по комбинации этих критериев. Можно искать первое, последнее или все вхождения, удовлетворяющие заданному критерию поиска.Данный класс не просто находит желаемый объект, но и возвращает полный путь до него, от корня графа. Полученный путь можно использовать для выполнения различных действий, например, для визуализации только этого найденного объекта (в пути содержатся все узлы, от корня дерева, которые необходимо пройти прежде чем будет достигнут заданный узел, включая узлы координат, цветов и всех остальных свойств).В качестве примера я приведу реализации функций, используемых мной для поиска в граф-сценах. Проверку входных данных и файл заголовка я стёр, чтобы уменьшить размер кода. SoSearchAction.cpp 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <Inventor/actions/SoSearchAction.h>
#include <Inventor/nodes/SoGroup.h>
// Поиск пути к узлу по имени узла
SoPath * SearchPath( SoGroup * group, const SbName & name )
{
SoPath * path = 0;
group->ref();
{
SoSearchAction sa;
sa.setFind( SoSearchAction::NAME ); // Поиск по имени
sa.setSearchingAll( TRUE ); // Поиск во всех путях, включая отключенные(SoSwitch)
sa.setInterest( SoSearchAction::Interest::FIRST ); // Искать первое вхождение
sa.setName( name ); // Имя узела для поиска
sa.apply( group ); // Выполняем поиск
path = sa.getPath();
if( !path )
{
group->unrefNoDelete();
return NULL;
}
path->ref();
}
group->unrefNoDelete();
return path;
}
// Поиск пути по типу узла
SoPath * SearchPath( SoGroup * group, const SoType & type )
{
SoPath * path = 0;
group->ref();
{
SoSearchAction sa;
sa.setFind( SoSearchAction::TYPE ); // Поиск по типу
sa.setSearchingAll( TRUE ); // Поиск во всех путях, включая отключенные(SoSwitch)
sa.setInterest( SoSearchAction::Interest::FIRST ); // Искать перое вхождение
sa.setType( type ); // Узел для поиска
sa.apply( group ); // Выполняем поиск
path = sa.getPath();
if( !path )
{
group->unrefNoDelete();
return NULL;
}
path->ref();
}
group->unrefNoDelete();
return path;
}
// Поиск пути до конкретного узла
SoPath * SearchPath( SoGroup * group, SoNode * node )
{
SoPath * path = 0;
group->ref();
{
SoSearchAction sa;
sa.setFind( SoSearchAction::NODE ); // Поиск по типу
sa.setSearchingAll( TRUE ); // Поиск во всех путях, включая отключенные(SoSwitch)
sa.setInterest( SoSearchAction::Interest::FIRST ); // Искать перое вхождение
sa.setNode( node );
sa.apply( group ); // Выполняем поиск
path = sa.getPath();
if( !path )
{
group->unrefNoDelete();
return NULL;
}
path->ref();
}
group->unrefNoDelete();
return path;
}
// Поиск узла по имени
SoNode * SearchNode( SoGroup * group, const SbName & name )
{
SoNode * node( 0 );
SoPath * path = SearchPath( group, name );
if( path )
{
node = path->getTail();
path->unref(); // объект больше не нужен, удаляем его
}
return node;
}
|