00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "findApproxLevelEntry.h"
00016 #include "nodePathCollection.h"
00017 #include "pandaNode.h"
00018 #include "indent.h"
00019
00020 TypeHandle FindApproxLevelEntry::_type_handle;
00021
00022
00023
00024
00025
00026
00027
00028 void FindApproxLevelEntry::
00029 output(ostream &out) const {
00030 out << "(" << _node_path << "):";
00031 if (is_solution(0)) {
00032 out << " solution!";
00033 } else {
00034 out << "(";
00035 _approx_path.output_component(out, _i);
00036 out << ")," << _i;
00037 }
00038 }
00039
00040
00041
00042
00043
00044
00045
00046 void FindApproxLevelEntry::
00047 write_level(ostream &out, int indent_level) const {
00048 for (const FindApproxLevelEntry *entry = this;
00049 entry != (const FindApproxLevelEntry *)NULL;
00050 entry = entry->_next) {
00051 indent(out, indent_level);
00052 out << *entry << "\n";
00053 }
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 bool FindApproxLevelEntry::
00070 consider_node(NodePathCollection &result, FindApproxLevelEntry *&next_level,
00071 int max_matches, int increment) const {
00072 if (is_solution(increment)) {
00073
00074
00075 result.add_path(_node_path.get_node_path());
00076 if (max_matches > 0 && result.get_num_paths() >= max_matches) {
00077 return true;
00078 }
00079
00080 return false;
00081 }
00082
00083
00084
00085 if (_approx_path.is_component_match_many(_i + increment)) {
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 if (consider_node(result, next_level, max_matches, increment + 1)) {
00101 return true;
00102 }
00103 }
00104
00105 PandaNode *this_node = _node_path.node();
00106 nassertr(this_node != (PandaNode *)NULL, false);
00107
00108 bool stashed_only = next_is_stashed(increment);
00109
00110 if (!stashed_only) {
00111
00112 PandaNode::Children children = this_node->get_children();
00113 int num_children = children.get_num_children();
00114 for (int i = 0; i < num_children; i++) {
00115 PandaNode *child_node = children.get_child(i);
00116
00117 consider_next_step(child_node, next_level, increment);
00118 }
00119 }
00120
00121 if (_approx_path.return_stashed() || stashed_only) {
00122
00123 int num_stashed = this_node->get_num_stashed();
00124 for (int i = 0; i < num_stashed; i++) {
00125 PandaNode *stashed_node = this_node->get_stashed(i);
00126
00127 consider_next_step(stashed_node, next_level, increment);
00128 }
00129 }
00130
00131 return false;
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 void FindApproxLevelEntry::
00144 consider_next_step(PandaNode *child_node, FindApproxLevelEntry *&next_level,
00145 int increment) const {
00146 nassertv(child_node != _node_path.node());
00147
00148 if (!_approx_path.return_hidden() && child_node->is_overall_hidden()) {
00149
00150
00151
00152 return;
00153 }
00154
00155 nassertv(_i + increment < _approx_path.get_num_components());
00156
00157 if (_approx_path.is_component_match_many(_i + increment)) {
00158
00159
00160
00161
00162
00163
00164 next_level = new FindApproxLevelEntry
00165 (*this, child_node, _i + increment, next_level);
00166
00167 } else {
00168 if (_approx_path.matches_component(_i + increment, child_node)) {
00169
00170 next_level = new FindApproxLevelEntry
00171 (*this, child_node, _i + increment + 1, next_level);
00172 }
00173 }
00174 }