From 25ba7f73a879c41d24b54f8171e9457ed0a9dc07 Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 14 Jun 2001 01:25:10 +0000 Subject: [PATCH] better system for combining nodes in flattenStrong --- panda/src/graph/graphReducer.cxx | 17 +---------- panda/src/graph/namedNode.cxx | 35 ++++++++++++++++++++++ panda/src/graph/namedNode.h | 1 + panda/src/graph/node.cxx | 30 +++++++++++++++++++ panda/src/graph/node.h | 1 + panda/src/sgraph/geomNode.cxx | 28 +++++++++++++++++ panda/src/sgraph/geomNode.h | 1 + panda/src/sgraphutil/sceneGraphReducer.cxx | 17 ++++------- 8 files changed, 103 insertions(+), 27 deletions(-) diff --git a/panda/src/graph/graphReducer.cxx b/panda/src/graph/graphReducer.cxx index 29b1c98f40..2160ae38de 100644 --- a/panda/src/graph/graphReducer.cxx +++ b/panda/src/graph/graphReducer.cxx @@ -417,22 +417,7 @@ collapse_nodes(Node *node1, Node *node2, bool) { return NULL; } - // We get to choose whether to remove node1 or node2. - if (node2->is_exact_type(Node::get_class_type()) || - node2->is_exact_type(NamedNode::get_class_type())) { - // Node2 isn't anything special, so preserve node1. - return node1; - - } else if (node1->is_exact_type(Node::get_class_type()) || - node1->is_exact_type(NamedNode::get_class_type())) { - // Node1 isn't anything special, so preserve node2. - return node2; - - } else { - // Both node1 and node2 are some special kind of node. Don't - // want to risk removing either of them. - return NULL; - } + return node2->combine_with(node1); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/graph/namedNode.cxx b/panda/src/graph/namedNode.cxx index 0cb213482a..8b094e1266 100644 --- a/panda/src/graph/namedNode.cxx +++ b/panda/src/graph/namedNode.cxx @@ -46,6 +46,41 @@ make_copy() const { return new NamedNode(*this); } +//////////////////////////////////////////////////////////////////// +// Function: NamedNode::combine_with +// Access: Public, Virtual +// Description: Collapses this node with the other node, if possible, +// and returns a pointer to the combined node, or NULL +// if the two nodes cannot safely be combined. +// +// The return value may be this, other, or a new node +// altogether. +// +// This function is called from GraphReducer::flatten(), +// and need not deal with children; its job is just to +// decide whether to collapse the two nodes and what the +// collapsed node should look like. +//////////////////////////////////////////////////////////////////// +Node *NamedNode:: +combine_with(Node *other) { + // An unadorned NamedNode combines with other Nodes by yielding + // completely. However, if we are actually some fancy Node type + // that derives from NamedNode but didn't redefine this function, we + // should refuse to combine. + if (is_exact_type(get_class_type())) { + // No, we're an ordinary NamedNode. + if (other->is_exact_type(Node::get_class_type())) { + // And the other node isn't even named, so we override. + return this; + } + // The other node is also a NamedNode, or better, so it wins. + return other; + } + + // We're something other than an ordinary NamedNode. Don't combine. + return (Node *)NULL; +} + //////////////////////////////////////////////////////////////////// // Function: NamedNode::preserve_name // Access: Public, Virtual diff --git a/panda/src/graph/namedNode.h b/panda/src/graph/namedNode.h index 0b56b6c76f..e8c3347472 100644 --- a/panda/src/graph/namedNode.h +++ b/panda/src/graph/namedNode.h @@ -39,6 +39,7 @@ public: virtual ~NamedNode(); virtual Node *make_copy() const; + virtual Node *combine_with(Node *other); virtual bool preserve_name() const; diff --git a/panda/src/graph/node.cxx b/panda/src/graph/node.cxx index 3c917eb092..75d2a7be6c 100644 --- a/panda/src/graph/node.cxx +++ b/panda/src/graph/node.cxx @@ -184,6 +184,36 @@ void Node:: xform(const LMatrix4f &) { } +//////////////////////////////////////////////////////////////////// +// Function: Node::combine_with +// Access: Public, Virtual +// Description: Collapses this node with the other node, if possible, +// and returns a pointer to the combined node, or NULL +// if the two nodes cannot safely be combined. +// +// The return value may be this, other, or a new node +// altogether. +// +// This function is called from GraphReducer::flatten(), +// and need not deal with children; its job is just to +// decide whether to collapse the two nodes and what the +// collapsed node should look like. +//////////////////////////////////////////////////////////////////// +Node *Node:: +combine_with(Node *other) { + // An unadorned Node always combines with any other Nodes by + // yielding completely. However, if we are actually some fancy Node + // type that derives from Node but didn't redefine this function, we + // should refuse to combine. + if (is_exact_type(get_class_type())) { + // No, we're an ordinary Node. + return other; + } + + // We're something other than an ordinary Node. Don't combine. + return (Node *)NULL; +} + //////////////////////////////////////////////////////////////////// // Function: Node::transform_changed // Access: Public, Virtual diff --git a/panda/src/graph/node.h b/panda/src/graph/node.h index c141ba58ff..8931e5dcd9 100644 --- a/panda/src/graph/node.h +++ b/panda/src/graph/node.h @@ -70,6 +70,7 @@ public: virtual bool safe_to_transform() const; virtual bool safe_to_combine() const; virtual void xform(const LMatrix4f &mat); + virtual Node *combine_with(Node *other); virtual void transform_changed(NodeRelation *arc); diff --git a/panda/src/sgraph/geomNode.cxx b/panda/src/sgraph/geomNode.cxx index dbf0039722..e493d83a12 100644 --- a/panda/src/sgraph/geomNode.cxx +++ b/panda/src/sgraph/geomNode.cxx @@ -111,6 +111,34 @@ xform(const LMatrix4f &mat) { transformer.transform_vertices(this, mat); } +//////////////////////////////////////////////////////////////////// +// Function: GeomNode::combine_with +// Access: Public, Virtual +// Description: Collapses this node with the other node, if possible, +// and returns a pointer to the combined node, or NULL +// if the two nodes cannot safely be combined. +// +// The return value may be this, other, or a new node +// altogether. +// +// This function is called from GraphReducer::flatten(), +// and need not deal with children; its job is just to +// decide whether to collapse the two nodes and what the +// collapsed node should look like. +//////////////////////////////////////////////////////////////////// +Node *GeomNode:: +combine_with(Node *other) { + if (is_exact_type(get_class_type()) && + other->is_exact_type(get_class_type())) { + // Two GeomNodes can combine by moving Geoms from one to the other. + GeomNode *gother = DCAST(GeomNode, other); + add_geoms_from(gother); + return this; + } + + return (Node *)NULL; +} + //////////////////////////////////////////////////////////////////// // Function: GeomNode::write // Access: Public diff --git a/panda/src/sgraph/geomNode.h b/panda/src/sgraph/geomNode.h index 976f522375..c129deaf72 100644 --- a/panda/src/sgraph/geomNode.h +++ b/panda/src/sgraph/geomNode.h @@ -48,6 +48,7 @@ public: virtual Node *make_copy() const; virtual void xform(const LMatrix4f &mat); + virtual Node *combine_with(Node *other); virtual void write(ostream &out, int indent_level = 0) const; diff --git a/panda/src/sgraphutil/sceneGraphReducer.cxx b/panda/src/sgraphutil/sceneGraphReducer.cxx index 071fbf0369..a3cef9982a 100644 --- a/panda/src/sgraphutil/sceneGraphReducer.cxx +++ b/panda/src/sgraphutil/sceneGraphReducer.cxx @@ -304,17 +304,12 @@ collapse_nodes(Node *node1, Node *node2, bool siblings) { // We can collapse two GeomNodes easily, if they're siblings. If // they're parent-child, we'd probably better not (it might // interfere with decaling). - if (siblings && - node1->is_exact_type(GeomNode::get_class_type()) && + if (node1->is_exact_type(GeomNode::get_class_type()) && node2->is_exact_type(GeomNode::get_class_type())) { - GeomNode *gnode1; - DCAST_INTO_R(gnode1, node1, NULL); - GeomNode *gnode2; - DCAST_INTO_R(gnode2, node2, NULL); - gnode1->add_geoms_from(gnode2); - return gnode1; - - } else { - return GraphReducer::collapse_nodes(node1, node2, siblings); + if (!siblings) { + return (Node *)NULL; + } } + + return GraphReducer::collapse_nodes(node1, node2, siblings); }