HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GP_DomainDAG.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: Domain pasting Library (C++)
7  *
8  * COMMENTS: Paste DAG class.
9  *
10  */
11 
12 #ifndef __GP_DomainDAG_h__
13 #define __GP_DomainDAG_h__
14 
15 #include "GP_API.h"
16 #include <limits.h>
17 #include "GP_Graph.h"
18 #include "GP_Domain.h"
19 
20 class GP_NodeList;
21 class GP_NodeTree;
22 
24 {
25 public:
26  // C-tor with 0 nodes. Can't paste on it.
27  GP_DomainDAG(void);
28 
29  // The root this c-tor assigns to myRoot cannot be already pasted somewhere
30  // else.
31  GP_DomainDAG(GP_Domain *root);
32 
33  // Shallow copy c-tor: same nodes, but different lists.
34  GP_DomainDAG(const GP_DomainDAG&);
35 
36  // D-tor that destroys all the nodes (thanks to its base class).
37  virtual ~GP_DomainDAG(void);
38 
39  // Clear the graph, ie. shrink the domain list to 0 without deleting
40  // the domains themselves, or destroy the domains as well:
41  virtual void clear(void);
42  virtual void clearAndDestroy(int total = 1);
43 
44  // Copy the source data into us. This is not a complete copy because
45  // it doesn't resolve the issue of domain surface ownership.
46  void copyFrom(const GP_DomainDAG &srcdag);
47 
48  // Copy from the source. Shallow in the nodes. All out nodes are
49  // destroyed first. Be careful.
51 
52  // Check if the domain or the dag would fit into our root domain. "parents"
53  // emerges with a list of would-be top container parents.
54  int canPaste(GP_Domain &d);
55  int canPaste(GP_Domain &d, GP_NodeList &parents);
57  {
58  return dag.myRoot ? canPaste(*dag.myRoot) : 0;
59  }
60  int canPaste(GP_DomainDAG &dag,GP_NodeList &parents)
61  {
62  return dag.myRoot?canPaste(*dag.myRoot,parents):0;
63  }
64  int canPaste(GP_DomainDAG &dag, GP_Domain &parent,
65  const UT_BoundingRect &brect);
66 
67  // Find out if we're in a paste graph, ie. if we have a parent or not:
68  int isPasted() const
69  {
70  return (myRoot && myRoot->isFeature());
71  }
72 
73  // Paste the dag onto us if it fits, and return its root. "parents" holds
74  // the list of would-be to container domains.
75  GP_Domain *paste(GP_DomainDAG &child, int keepshape = 0);
76  GP_Domain *paste(GP_DomainDAG &child, GP_NodeList &parents,
77  int keepshape = 0);
78 
79  // Paste the srcdag onto us after checking if the 4 domain world points
80  // are in our transformed root domain. Return the root of the srdag or 0.
81  GP_Domain *paste(GP_DomainDAG &srcdag,
82  const GP_Point &b1, const GP_Point &b2,
83  const GP_Point &b3, const GP_Point &b4);
84 
85  // Unpaste a domain alone or with all its contained children. If you know
86  // what the contained set is, pass it in for speed. If you unpaste the
87  // root domain, the whole dag goes.
88  GP_Domain *unpasteAt (GP_Domain &child);
89  GP_DomainDAG *unpasteFrom(GP_Domain &child, GP_NodeTree *ctree=0);
90 
91  // Delete a domain alone or with all its contained children. If you know
92  // what the contained set is, pass it in for speed. If you delete the root
93  // domain all the kids will be unpasted. Return 0 upon success, or -1.
94  int destroyAt (GP_Domain &child);
95  int destroyFrom(GP_Domain &child, GP_NodeTree *ctree=0);
96 
97  // Replace a domain alone or with all its contained children with a new
98  // DAG. If you know the domain's contained set, pass it in for speed.
99  // The method returns dag's root or 0.
100  GP_Domain *replaceAt (GP_Domain &child, GP_DomainDAG &dag);
101  GP_Domain *replaceFrom(GP_Domain &child, GP_DomainDAG &dag,
102  GP_NodeTree *ctree = 0);
103 
104  // Similar to paste, only if the child or its contained DAG has bridges,
105  // the bridges will be raised before pasting, then lowered again. If
106  // you know child's contained nodes, pass them in for speed. We return
107  // dag's root or 0.
108  GP_Domain *overlayAt (GP_Domain &child, GP_DomainDAG &dag,
109  int keepshape = 0);
110  GP_Domain *overlayAt (GP_Domain &child, GP_DomainDAG &srcdag,
111  const UT_BoundingRect &brect);
112  GP_Domain *overlayAt (GP_Domain &child, GP_DomainDAG &srcdag,
113  const GP_Point &b1, const GP_Point &b2,
114  const GP_Point &b3, const GP_Point &b4);
115  GP_Domain *overlayFrom(GP_Domain &child, GP_DomainDAG &dag,
116  GP_NodeTree *ctree=0, int keepshape = 0);
117  GP_Domain *overlayFrom(GP_Domain &child, GP_DomainDAG &dag,
118  const GP_Point &b1, const GP_Point &b2,
119  const GP_Point &b3, const GP_Point &b4,
120  GP_NodeTree *ctree=0);
121 
122  // Remove the child. This is an alias for unpasteAt() and doesn't need
123  // to be redefined in the derived classes.
125  {
126  return GP_DomainDAG::unpasteAt(child);
127  }
128 
129  // Anything goes in terms of spline surface changes, especially if it
130  // involves changes of both knots and CVs, as in refinement, unrefinement,
131  // degree elevation, or cutting. If "standalone" is 1, we bring the
132  // child back to its unpasted shape before calling (*apply)().
133  // Return 0 if OK, else -1.
134  int modifyBasis(GP_Domain &child,
135  int (*apply)(void *tpsurf, void *d),
136  void *data = 0,
137  int standalone = 0);
138 
139  // Add a layer by spawning a domain definitely contained within the child.
140  // Return that domain if everything is successful, else 0. The child
141  // in the domain area defined by brect, and the ub/vb stuff are belt
142  // reinforcements.
143  GP_Domain *spawn(GP_Domain &child, const UT_BoundingRect &brect,
144  float ubwidth = 0, float vbwidth = 0,
145  int ubdivs = 2, int vbdivs = 2);
146 
147  // See if we contain this world domain point. A quick check does only a
148  // bbox test:
149  int contains(const GP_Point &worldp, int quick = 0) const
150  {
151  return myRoot ? myRoot->contains(worldp,quick):0;
152  }
153 
154  // See if d is pasted on us by checking its anchor against our root:
155  int contains(const GP_Domain &d) const
156  {
157  return myRoot
158  ? myRoot->frames()==d.frames()->anchor() : 0;
159  }
160 
161  // Method to change the key of a domain while preserving the sanity of the
162  // graph. Return the changed node or 0 if not found. The fast method does
163  // not remove and reinsert the domain.
165  {
166  return (GP_Domain*)rekey(domain, myLabel++);
167  }
168  void keyUpFast(GP_Domain &domain)
169  {
170  domain.key(myLabel++);
171  }
172 
173  // Return top-most domain that worldp lies inside, or 0.
174  GP_Domain *topDomain(const GP_Point &worldp) const;
175 
176  // Change the root transformation given a handle or a domain. This will set
177  // everything dirty. The domain isn't const because it might need to be
178  // updated.
179  void changeRootXform(const GP_XformHandle &handle);
180  void changeRootXform(GP_Domain &d);
181 
182  // Assuming "child" is the root of a newly pasted DAG, link it to its
183  // parent domain(s) (top containers) in our DAG. The methods make sure
184  // everything is (re)pasted and updated accordingly. The bases are
185  // already set at this point by findParents().
186  virtual void link(GP_Domain &child, GP_NodeList &parents,
187  int keepshape = 0);
188  virtual void link(GP_Domain &child, GP_Domain &parent,
189  int withcorrection = 1);
190 
191  // Assuming child is pasted on us, update the pasted image of all of
192  // surf's descendents in pasted order. surf is not updated.
193  // Return 0 upon success, else -1.
194  virtual int updateDescendents(GP_Domain &child,
195  int including_child = 0);
196 
197  // Some vertices (or all) have changed, so reverse engineer the
198  // displacements from the CVs of the spline surface. In other words,
199  // given the local frames and the GEO_Points, build the displacements for
200  // the child node, then update its descendents. Return -1 if not our child.
201  virtual int updateDisplacements(GP_Domain &child,
202  int keepframes = 1);
203 
204  // The public can only look at the root but not change it because things
205  // are tricky in the hierarchy:
206  const GP_Domain *root(void) const { return myRoot; }
207 
208 
209 protected:
210  // Let us know when something has changed in the root domain.
211  virtual void changedRoot(void);
212 
213  // Tell the dag it's obsolete. This will happen when the dag has been
214  // pasted onto some other dag, and should be deleted. This method clears
215  // the nodes. Derived classes will probably "delete this" inside it,
216  // so don't use the dag thereafter.
217  virtual void obsolete(void);
218 
219  // Build a sorted list of nodes representing the contained DAG rooted at
220  // base, base included. You must free it yourself.
221  GP_NodeTree *containedDomains(const GP_Domain& base) const;
222 
223  // root must be stand-alone. Don't do it if we have a root already. Use
224  // modifyAt() instead. The method returns root or 0 if failure.
225  GP_Domain *insertRoot(GP_Domain &root);
226 
227  // Just adds this one to the node, and bumps up our label count.
228  void insertDomain(GP_Domain &domain);
229 
230  // Relabel the whole DAG from a given value and update myLabel.
231  void relabel(int start = INT_MIN);
232 
233  // Use this method after loading to make sure all the proper links are
234  // set. ONLY after loading. Return 0 is OK and -1 otherwise.
235  int pasteInPlace(GP_Domain &child);
236 
237  // Derived classes get a full look at the root with a non-const handle:
238  GP_Domain *root(void) { return myRoot; }
239 
240 
241 private:
242  GP_Domain *myRoot; // root domain
243  int myLabel; // current label for nodes
244 
245 
246  // Private c-tor that assigns "root" to its root and grabs the nodes
247  // from the node tree. The structures will not be the same, but the
248  // nodes will be shared:
249  GP_DomainDAG(GP_Domain *root, GP_NodeTree &cnodes);
250 
251  // Given a domain or its immediate parents, find the root of the shortest
252  // contained DAG that would contain the domain or its given parents.
253  GP_Domain *minContainment(GP_Domain &domain);
254  GP_Domain *minContainment(GP_NodeList &parents);
255 
256 public: // raiseBridges() is called from within a static callback...
257  // Assuming base is in our graph, raise the bridges recursively.
258  void raiseBridges(GP_Domain &d,
259  GP_NodeTree *bridges);
260 
261  // Return a list of domains d would touch if pasted here. We assume d
262  // would fit in the root domain. Unlike canPaste(), this method ignores
263  // nodes currently not linked up. "parents" contains domains in decreasing
264  // key order.
265  GP_NodeList &underDomains(GP_Domain &d, GP_NodeList &parents);
266 private:
267 
268  // This method assumes the child is pasted onto this dag, and removes
269  // its frame links, the node from the graph, and sets its dag pointer
270  // to nil. If this is the root, it sets myRoot to zero.
271  void isolate(GP_Domain &child);
272 
273  // Detach the high bridges (ie. here the immediate children) of the node.
274  // The method returns an ordered list of detached nodes. These nodes will
275  // only have links to the contained DAG they are the roots of. You must
276  // free this list yourself.
277  GP_NodeTree *raiseBridgesAt(GP_Domain &node);
278 
279  // Raise bridges from a base node or from a list of contained nodes.
280  // The resulting nodes will only have links to the contained DAG they are
281  // the roots of. You must free this list yourself.
282  GP_NodeTree *raiseBridgesFrom(GP_Domain &base);
283  GP_NodeTree *raiseBridgesFrom(GP_NodeTree &nodes);
284 
285  // Relink the bridges by pasting them again in the order in which they
286  // had been pasted originally.
287  void lowerBridges(GP_NodeTree &bridges, int relabel = 0);
288 };
289 
290 #endif
int canPaste(GP_DomainDAG &dag)
Definition: GP_DomainDAG.h:56
virtual void clear(void)
#define GP_API
Definition: GP_API.h:10
GP_Node * copyFrom(const GP_Graph &src, const GP_Node *=0)
int key(void) const
Definition: GP_Node.h:54
GLuint start
Definition: glcorearb.h:474
GP_FrameHierarchy * anchor(void) const
int contains(const GP_Domain &d) const
Definition: GP_DomainDAG.h:155
GP_Domain * unpasteAt(GP_Domain &child)
GP_Domain * root(void)
Definition: GP_DomainDAG.h:238
GP_Graph & operator=(const GP_Graph &src)
GP_Node * rekey(GP_Node &node, int newkey)
GP_FrameHierarchy * frames(void) const
Definition: GP_Domain.h:73
GP_Domain * removeAt(GP_Domain &child)
Definition: GP_DomainDAG.h:124
GLboolean * data
Definition: glcorearb.h:130
virtual void clearAndDestroy(int total=1)
GP_Domain * keyUp(GP_Domain &domain)
Definition: GP_DomainDAG.h:164
int contains(const GP_Point &worldp, int quick=0) const
Definition: GP_DomainDAG.h:149
void keyUpFast(GP_Domain &domain)
Definition: GP_DomainDAG.h:168
const GP_Domain * root(void) const
Definition: GP_DomainDAG.h:206
int isPasted() const
Definition: GP_DomainDAG.h:68
int canPaste(GP_DomainDAG &dag, GP_NodeList &parents)
Definition: GP_DomainDAG.h:60
GLenum src
Definition: glcorearb.h:1792