瀏覽代碼

added control flags to find() etc.

David Rose 24 年之前
父節點
當前提交
9186df0881

+ 25 - 0
panda/src/sgmanip/findApproxLevel.cxx

@@ -78,6 +78,24 @@ consider_node(NodePathCollection &result, FindApproxLevel &next_level,
       return;
     }
   }
+
+  if (_approx_path.return_stashed() && 
+      next_graph_type != NodeRelation::get_stashed_type()) {
+    // If the approx path allows us to return stashed nodes, and we
+    // didn't just traverse the list of stashed nodes, then traverse
+    // them now.
+    next_graph_type = NodeRelation::get_stashed_type();
+
+    int num_children = bottom_node->get_num_children(next_graph_type);
+    for (int i = 0; i < num_children; i++) {
+      NodeRelation *child_arc = bottom_node->get_child(next_graph_type, i);
+      
+      consider_next_step(result, child_arc, next_level, max_matches, graph_type);
+      if (max_matches > 0 && result.get_num_paths() >= max_matches) {
+        return;
+      }
+    }
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -96,6 +114,13 @@ void FindApproxLevelEntry::
 consider_next_step(NodePathCollection &result,
 		   NodeRelation *arc, FindApproxLevel &next_level, 
 		   int max_matches, TypeHandle graph_type) const {
+  if (!_approx_path.return_hidden() && 
+      arc->has_transition(PruneTransition::get_class_type())) {
+    // If the approx path does not allow us to return hidden nodes,
+    // and this arc has indeed been hidden, then stop here.
+    return;
+  }
+
   nassertv(_i < _approx_path.get_num_components());
 
   FindApproxLevelEntry next(*this);

+ 24 - 0
panda/src/sgmanip/findApproxPath.I

@@ -11,6 +11,8 @@
 ////////////////////////////////////////////////////////////////////
 INLINE FindApproxPath::
 FindApproxPath() {
+  _return_hidden = true;
+  _return_stashed = false;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -166,6 +168,28 @@ matches_stashed(int index) const {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: FindApproxPath::return_hidden
+//       Access: Public
+//  Description: Returns true if this path allows returning of hidden
+//               nodes, false otherwise.
+////////////////////////////////////////////////////////////////////
+INLINE bool FindApproxPath::
+return_hidden() const {
+  return _return_hidden;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FindApproxPath::return_stashed
+//       Access: Public
+//  Description: Returns true if this path allows returning of stashed
+//               nodes, false otherwise.
+////////////////////////////////////////////////////////////////////
+INLINE bool FindApproxPath::
+return_stashed() const {
+  return _return_stashed;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: FindApproxPath::output_component
 //       Access: Public

+ 78 - 4
panda/src/sgmanip/findApproxPath.cxx

@@ -87,9 +87,10 @@ output(ostream &out) const {
 ////////////////////////////////////////////////////////////////////
 //     Function: FindApproxPath::add_string
 //       Access: Public
-//  Description: Adds a sequence of components separated by slashes to
-//               the path sequence.  Returns true if successful, false
-//               if the string contained an error.
+//  Description: Adds a sequence of components separated by slashes,
+//               followed optionally by a semicolon and a sequence of
+//               control flags, to the path sequence.  Returns true if
+//               successful, false if the string contained an error.
 ////////////////////////////////////////////////////////////////////
 bool FindApproxPath::
 add_string(const string &str_path) {
@@ -102,7 +103,80 @@ add_string(const string &str_path) {
     start = slash + 1;
     slash = str_path.find('/', start);
   }
-  return add_component(str_path.substr(start));
+
+  size_t semicolon = str_path.rfind(';');
+
+  // We want to find the *last* semicolon at start or later, if there
+  // happens to be more than one.  rfind will find the rightmost
+  // semicolon in the entire string; if this is less than start, there
+  // is no semicolon right of start.
+  if (semicolon < start) {
+    semicolon = string::npos;
+  }
+
+  if (!add_component(str_path.substr(start, semicolon - start))) {
+    return false;
+  }
+
+  if (semicolon != string::npos) {
+    return add_flags(str_path.substr(semicolon + 1));
+  }
+
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FindApproxPath::add_flags
+//       Access: Public
+//  Description: Adds a sequence of control flags.  This will be a
+//               sequence of letters preceded by either '+' or '-',
+//               with no intervening punctuation.  Returns true if
+//               successful, false otherwise.
+////////////////////////////////////////////////////////////////////
+bool FindApproxPath::
+add_flags(const string &str_flags) {
+  string::const_iterator pi = str_flags.begin();
+  while (pi != str_flags.end()) {
+    bool on;
+    switch (*pi) {
+    case '+':
+      on = true;
+      break;
+    case '-':
+      on = false;
+      break;
+    default:
+      sgmanip_cat.error()
+        << "Invalid control flag string: " << str_flags << "\n";
+      return false;
+    }
+
+    ++pi;
+    if (pi == str_flags.end()) {
+      sgmanip_cat.error()
+        << "Invalid control flag string: " << str_flags << "\n";
+      return false;
+    }
+
+    switch (*pi) {
+    case 'h':
+      _return_hidden = on;
+      break;
+      
+    case 's':
+      _return_stashed = on;
+      break;
+      
+    default:
+      sgmanip_cat.error()
+        << "Invalid control flag string: " << str_flags << "\n";
+      return false;
+    }
+    
+    ++pi;
+  }
+
+  return true;
 }
 
 

+ 7 - 0
panda/src/sgmanip/findApproxPath.h

@@ -28,6 +28,7 @@ public:
   INLINE FindApproxPath();
 
   bool add_string(const string &str_path);
+  bool add_flags(const string &str_flags);
   bool add_component(string str_component);
 
   INLINE void add_match_name(const string &name, int flags);
@@ -43,6 +44,9 @@ public:
   INLINE bool matches_component(int index, NodeRelation *arc) const;
   INLINE bool matches_stashed(int index) const;
 
+  INLINE bool return_hidden() const;
+  INLINE bool return_stashed() const;
+
   void output(ostream &out) const;
   INLINE void output_component(ostream &out, int index) const;
 
@@ -79,6 +83,9 @@ private:
   typedef vector<Component> Path;
   Path _path;
 
+  bool _return_hidden;
+  bool _return_stashed;
+
 friend ostream &operator << (ostream &, FindApproxPath::ComponentType);
 friend INLINE ostream &operator << (ostream &, const FindApproxPath::Component &);
 };