Saturday, April 19, 2014

Gradient look-up

Implemented gradient look-up from the river slope map this week, which lets us determine where a newly generated node should be positioned. I also added a horizontal jitter to handle the case where a parent node splits off into two children nodes with the same starting point and gradient vector. The sample river slope map I'm working off of at the moment is a simple radial gradient (lighter values designate higher elevation).




Nodes seem to be coming along nicely. Next steps are to implement geometry compatibility checks to determine when expansion should terminate. After that I'll be working on defining different river types and adding that to the final output.

Monday, April 7, 2014

Trouble with bounding boxes

Currently I'm stuck on querying the bounding box for the CV curve. This will be needed to fit the river slope image map onto the curve in order to retrieve the slope value at a specific position.

In my compute() function, I have my MFnNurbsCurve object, via
MObject curve = inputCurveData.asNurbsCurve();
MFnNurbsCurve curveFn (curve, &returnStatus); // Can also set as MItCurveCV
McheckErr(returnStatus, "ERROR creating curve function set\n");

And I've tried directly calling boundingBox() on it (which should work since MFnNurbsCurve inherits from MFnDagNode), but I get a return status code of 1 (kFailure), and internal status code of 6 (kNotImplemented), which isn't very helpful. I still don't know why it's not working.

An alternate method I tried was to query the bounding box attribute, as follows:
MObject boundingBoxObj = curveFn.attribute(MString("boundingBox"), &returnStatus); 
I get the same error with this method.

I know the bounding box is definitely queryable because the MEL command getAttr curve1.boundingBoxMin returns a valid value. Though I would rather not resort to that if I don't have to.

EDIT:
Per this answer, it seems like the reason why boundingbox() has been failing is because it will only work if the MFnNurbsCurve is attached to a dagNode, rather than curve data coming through the DG. I'm just going to manually calculate the bounding box.

Tuesday, April 1, 2014

Updates 4/1: Expansion Algorithm

Currently I'm still working on implementing the expansion algorithm, which is described as a grammar-like rewriting process. The system uses two non-terminal symbols to denote the candidate node and an instantiated node, and a terminal symbol that represents a node that has been added to the graph and that cannot be expanded.


While stepping through the algorithm, I realized that while the paper indicated how to calculate the elevation (y) of each newly created node, there was nothing for their (x, z) positions. I emailed one of the authors, Dr. Bene, and was told that the main direction is given by the direction to the previous node and is modified by the gradient of the river slope and other factors. I'm still using dummy constants for the river slope values, but it looks like I will either have to find an image processing library that covers gradients, or roll it out myself (which someone recommended in conjunction with using stb_img.c to read in the slope map).

Here is what one step 2.2 in the expansion chart looks like (this is with dummy slope and gradient values. You can tell by how the river pretty much aims straight to the origin)

Bird's eye view down y-axis

Breaking the next few weeks down into chunks, I have the following tasks left:

  • Implement function that reads in an image map describing the slope values in grey scale and scales it to fit the bounding box of the CV curve in order to determine the elevation of every node.
  • Calculate the gradient of the river slope map to determine expansion direction of newly instantiated nodes. 
  • Finish implementing expansion with symmetric Horton-Strahler junction creation 
  • Implement expansion with asymmetric Horton-Strahler junction creation
  • Implement expansion with just river growth
  • Implement compatibility check, which determines if a node is able to be expanded
  • Design and implement expansion loop
  • Calculate distance between edge and all other edges to avoid collisions in the graph
  • Calculate distance between a river node (point) and the contour curve
  • Check if a point lies within a curve (this is to ensure no nodes are created beyond the river contour)
  • Create a user interface in MEL