HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SOP_LightLink.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: SOP_LightLink.h (SOP Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __SOP_LightLink__
12 #define __SOP_LightLink__
13 
14 #include "SOP_API.h"
15 #include <UT/UT_Map.h>
16 #include <UT/UT_WorkBuffer.h>
17 #include <UT/UT_Array.h>
18 #include <UT/UT_Pair.h>
19 #include <UT/UT_Set.h>
20 #include <UT/UT_TagManager.h>
21 #include <GEO/GEO_PackedTypes.h>
22 
23 /// Class to manage visibility/material/light linking for packed primitives.
24 ///
25 /// This class represents the paths for the SOP as a full tree. Operations can
26 /// be performed on branches (including light linking operations). After the
27 /// tree has been edited, you can get the operations by calling one of:
28 /// - getMaterialOps()
29 /// - getExprOps()
30 /// - getVisibleOps()
32 {
33 public:
34  /// Set operations are represented as (path, value), where @c path is the
35  /// path to the node in the tree, and @c value is the value for the
36  /// tree/subtree.
38  {
40  : myVisible(v)
41  , myViewportLOD(l)
42  {
43  }
44  int myVisible;
46  };
49 
51 
52  /// Node to represent paths in the link tree
53  /// Each branch has one or more children.
54  /// If all children of the branch have the same value, the branch will have
55  /// myValue set to the common child value
56  /// myKidsSame set to true
57  class Node
58  {
59  public:
61 
62  /// Visibility states
63  enum
64  {
65  VISIBLE_UNCHANGED = -1,
67  VISIBLE_SHOW
68  };
69 
70  // Flags for common child values
71  enum
72  {
73  COMMON_LOD = 0x01,
74  COMMON_MATERIAL = 0x02,
75  COMMON_EXPR = 0x04,
76 
77  COMMON_ALL = (COMMON_MATERIAL|COMMON_LOD|COMMON_EXPR)
78  };
79 
80 
81  Node(const std::string &name, Node *parent)
82  : myName(name)
83  , myMaterial()
84  , myVisible(VISIBLE_UNCHANGED)
85  , myViewportLOD(GEO_VIEWPORT_INVALID_MODE)
86  , myExpr(theAsterisk)
87  , myParent(parent)
88  , myKids()
89  , myCommonKids(COMMON_ALL)
90  {
91  }
93  {
94  for (NodeSet::iterator it=myKids.begin(); it != myKids.end(); ++it)
95  delete it->second;
96  }
97 
98  // Find or add a node
100  {
101  NodeSet::iterator it = myKids.find(name);
102  if (it == myKids.end())
103  {
104  Node *kid = new Node(name, this);
105  myKids[name] = kid;
106  return kid;
107  }
108  return it->second;
109  }
110  Node *find(const std::string &name) const
111  {
112  NodeSet::const_iterator it = myKids.find(name);
113  if (it == myKids.end())
114  return NULL;
115  return it->second;
116  }
118  {
119  return myKids.size();
120  }
121  void clearValue()
122  {
123  myMaterial = std::string();
124  myVisible = true;
125  myViewportLOD = GEO_VIEWPORT_INVALID_MODE;
126  myExpr = theAsterisk;
127  }
129  {
130  clearValue();
131  for (NodeSet::iterator it=myKids.begin(); it != myKids.end(); ++it)
132  it->second->clearSubtree();
133  }
134  void setMaterial(const std::string &m)
135  {
136  myMaterial = m;
137  for (NodeSet::iterator it=myKids.begin(); it != myKids.end(); ++it)
138  it->second->setMaterial(m);
139  }
140  void setExpr(const std::string &expr)
141  {
142  myExpr = expr;
143  myExprPtr.reset(NULL);
144  for (NodeSet::iterator it=myKids.begin(); it != myKids.end(); ++it)
145  {
146  it->second->setExpr(expr);
147  }
148  }
150  {
151  if (myExprPtr)
152  updateTagExpression();
153  for (NodeSet::iterator it=myKids.begin(); it != myKids.end(); ++it)
154  it->second->clearTagExpressions();
155  }
156  void addTag(UT_TagManager &mgr, const UT_TagList &tags)
157  {
158  createTagExpression(mgr);
159  if (myExprPtr)
160  myExprPtr = myExprPtr->addTags(tags);
161  for (NodeSet::iterator it=myKids.begin(); it != myKids.end(); ++it)
162  it->second->addTag(mgr, tags);
163  }
164  void rmTag(UT_TagManager &mgr, const UT_TagList &tags)
165  {
166  createTagExpression(mgr);
167  if (myExprPtr)
168  myExprPtr = myExprPtr->rmTags(tags);
169  for (NodeSet::iterator it=myKids.begin(); it != myKids.end(); ++it)
170  it->second->rmTag(mgr, tags);
171  }
172  void setVisible(int visibility)
173  {
174  myVisible = visibility;
175  for (NodeSet::iterator it=myKids.begin(); it != myKids.end(); ++it)
176  it->second->setVisible(visibility);
177  }
179  {
180  myViewportLOD = lod;
181  for (NodeSet::iterator it=myKids.begin(); it != myKids.end(); ++it)
182  it->second->setViewportLOD(lod);
183  }
185  {
186  UT_ASSERT(!myParent);
187  pruneBranches();
188  }
189  void extractLeafPaths(UT_WorkBuffer &path, UT_StringArray &paths) const;
190  void getMaterialOps(UT_WorkBuffer &path, UT_Array<SetOp> &ops) const;
191  void getExprOps(UT_WorkBuffer &path, UT_Array<SetOp> &ops) const;
192  void getVisibleOps(UT_WorkBuffer &path, UT_Array<VisibleOp> &ops) const;
193  void getMatchingExpr(UT_WorkBuffer &path,
194  UT_TagManager &mgr,
196  const UT_TagList &tags);
197 
198  const Node *parent() const { return myParent; }
199  const std::string &name() const { return myName; }
200  const std::string &material() const { return myMaterial; }
201  const std::string &expr() const { return myExpr; }
202  int visible() const { return myVisible; }
203  GEO_ViewportLOD viewportLOD() const { return myViewportLOD; }
204 
205  void dump(int indent) const
206  {
207  dumpNode(indent);
208  for (NodeSet::const_iterator it = myKids.begin();
209  it != myKids.end(); ++it)
210  it->second->dump(indent+1);
211  }
212 
213  private:
214  void createTagExpression(UT_TagManager &tags)
215  {
216  if (!myExprPtr && UTisstring(myExpr.c_str()))
217  {
218  UT_String errs;
219  myExprPtr = tags.createExpression(myExpr.c_str(), errs);
220  if (errs.isstring())
221  myExprPtr.reset(NULL);
222  }
223  }
224  void updateTagExpression()
225  {
226  if (myExprPtr)
227  {
228  UT_WorkBuffer expr;
229  myExprPtr->getExpressionString(expr);
230  myExpr = expr.toStdString();
231  myExprPtr.reset(NULL);
232  }
233  }
234 
235  void dumpNode(int indent) const;
236  /// Check to see if all the kids have the same values.
237  int pruneBranches()
238  {
239  Node *kid = NULL;
240 
241  myCommonKids = COMMON_ALL;
242  for (NodeSet::iterator it=myKids.begin(); it != myKids.end(); ++it)
243  {
244  kid = it->second;
245  myCommonKids &= it->second->pruneBranches();
246  }
247  for (NodeSet::iterator it=myKids.begin(); it != myKids.end(); ++it)
248  {
249  if (it->second->myMaterial != kid->myMaterial)
250  myCommonKids &= ~COMMON_MATERIAL;
251  if (it->second->myVisible != kid->myVisible ||
252  it->second->myViewportLOD != kid->myViewportLOD)
253  {
254  myCommonKids &= ~COMMON_LOD;
255  }
256  else if (it->second->myExpr != kid->myExpr)
257  {
258  myCommonKids &= ~COMMON_EXPR;
259  }
260  if (!myCommonKids)
261  break;
262  }
263  if (myCommonKids && kid)
264  {
265  // Propagate up the tree
266  if (myCommonKids & COMMON_LOD)
267  {
268  myVisible = kid->myVisible;
269  myViewportLOD = kid->myViewportLOD;
270  }
271  if (myCommonKids & COMMON_EXPR)
272  myExpr = kid->myExpr;
273  if (myCommonKids & COMMON_MATERIAL)
274  myMaterial = kid->myMaterial;
275  }
276  return myCommonKids;
277  }
278  std::string myName;
279  std::string myMaterial;
280  std::string myExpr;
281  UT_TagExpressionPtr myExprPtr;
282  Node *myParent;
283  NodeSet myKids;
284  int myVisible;
285  GEO_ViewportLOD myViewportLOD;
286  int myCommonKids;
287  };
288 
289 
290  SOP_LightLink();
291  ~SOP_LightLink();
292 
293  /// Add a node to the tree. This will create all intermediate nodes.
294  void addPath(const char *path);
295 
296  /// Set the material for a given subtree. The node specified by the path
297  /// (and all its children) will be set to use the specified material.
298  bool setMaterial(const char *path, const std::string &value);
299  /// Set the visibility for a given subtree
300  bool setVisible(const char *path, int visible);
301  /// Set the viewport LOD for a given subtree
302  bool setViewportLOD(const char *path, GEO_ViewportLOD lod);
303 
304  /// Set the expression string for a given subtree.
305  bool setExpr(const char *path, const std::string &tag_expression);
306 
307  /// Add a light tag to the subtree specified by the given path. This will
308  /// convert a node's expression to a compiled form. Please call
309  /// @c clearTagExpressions() when you're finshed editing the tree.
310  bool addTag(UT_TagManager &m, const char *path, const UT_TagList &t);
311  /// Remove a light tag from the entire subtree specified by the given path.
312  /// This will convert a node's expression to a compiled form. Please call
313  /// @c clearTagExpressions() when you're finshed editing the tree.
314  bool rmTag(UT_TagManager &m, const char *path, const UT_TagList &t);
315 
316  /// Convert any tag expressions to their string values. You must call this
317  /// when you're finished calling addTag()/rmTag().
318  void clearTagExpressions() { myRoot->clearTagExpressions(); }
319  /// Restore tree to default values
320  void clearValues() { myRoot->clearSubtree(); }
321 
322  /// Return a string array of all the unique paths
323  bool extractLeafPaths(UT_StringArray &paths) const;
324 
325  /// Find out which operations will set the appropriate materials
326  void getMaterialOps(UT_Array<SetOp> &ops);
327  /// Find out which operations will set the proper light expressions
328  void getExprOps(UT_Array<SetOp> &ops);
329  /// Find out which operations will set the proper visibility operations
330  void getVisibleOps(UT_Array<VisibleOp> &ops);
331 
332  /// Get the material for the given path
333  bool getMaterial(const char *path, std::string &expr) const;
334  /// Get the expression for the given path
335  bool getExpr(const char *path, std::string &expr) const;
336 
337  /// Match all node expressions against the given tags. The matching nodes
338  /// will have their path's added to the @c selection. Each path will be
339  /// prefixed with the @c prepend text.
340  bool getMatchingExpr(UT_TagManager &tags,
341  const std::string &prepend,
343  const UT_TagList &t) const;
344 
345  void dump(const char *msg);
346  /// @private
347  void optimizeTree()
348  {
349  if (!myOptimized)
350  {
351  myRoot->optimizeTree();
352  myOptimized = true;
353  }
354  }
355 private:
356  Node *findNode(const char *path, bool create) const;
357 
358  Node *myRoot;
359  bool myOptimized;
360 };
361 
362 #endif
GT_API const UT_StringHolder selection
const GLdouble * v
Definition: glcorearb.h:836
GLsizei const GLchar *const * string
Definition: glcorearb.h:813
GLsizei const GLchar *const * path
Definition: glcorearb.h:3340
int64 exint
Definition: SYS_Types.h:116
A comma separated list of tags (i.e. "fill,spot,red")
Definition: UT_TagManager.h:49
Base::iterator iterator
Definition: UT_Map.h:93
std::string toStdString() const
GLuint const GLchar * name
Definition: glcorearb.h:785
GLsizei const GLfloat * value
Definition: glcorearb.h:823
GEO_ViewportLOD
SYS_FORCE_INLINE bool UTisstring(const char *s)
Definition: UT_String.h:57
#define SOP_API
Definition: SOP_API.h:10
bool isstring() const
Definition: UT_String.h:689
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:126
Base::const_iterator const_iterator
Definition: UT_Map.h:94
GLint lod
Definition: glcorearb.h:2764
UT_TagExpressionPtr createExpression(const char *expr, UT_String &errs)