vtkHyperTreeGrid Paraview example in 2D

Thanks. That’s pretty consistent with the code I posted above. A question is:

From this cursor, if you were at the north cursor, you go south and extract the leafs interfacing the south

I posted code trying to do that. How do I know that a random child of the neighbour cell, borders the cell I’m interested in? So I know if I’m on the north face I want to compare to the south cell neighbours, how do I get the array of south cell neighbours? I can’t figure that out.

Is there an easier way just to extract all the points the define the perimeter of the red cell? That’s all I’m really trying to do

Right! Now I see your problem…

As an aside:

Why is Moore used Here for the 2D case and not Von Neumann? This is the reference I’ve been using for applicable examples. That’s why my code above uses Moore

You would want to use a Moore cursor if you wanted to turn the bottom left of the screen you shared green. Moore cursor is a 8-neighborhood in 2D (or the unit-disk using the infinity norm), Von Neumann is 4-neighborhood (or the unit-disk using the 0-norm).

Alright, you cannot do the perfect traversal in the current state of the htg library. What you will need to do as a fix in the meanwhile is clone your cursor, calling the Clone method before you go to the children. We’ll come with a better design in the future.

Ideally you would need to create a non oriented geometry cursor. It doesn’t work (if you look at the code, you’ll see an assert(false) which was put here to prevent people from using it) because it would be very expensive to create an actual non oriented cursor having the ability to go to the root of the tree. Ideally, I think we would need to have a cursor that cannot go to the true root, but traverse the subtree freely without the possibility to go to the parent of the neighbor.

We’ll address that, hopefully in the next release.

Ok thank again. I’m not sure I’m going to be able to get this working, I can’t really follow how to collect a list of neighbour cells that touch the perimeter of the cell that interests me; red cell in this case.

Can I just check: Is there an easier way just to extract all the points the define the perimeter of the red cell? That’s all I’m really trying to do, ignoring the code and approach I had posted, I’m open to any suggestions. Upon knowing the perimeter nodes I should be able to turn the red cell into a polygon.

You can induce the 4 points of the red cell from its bounds that are accessible in any geometry cursor.

Yes I know that. But the red cell is made up from a lot more than 4 points. 5 to be exact on the west face alone plus two others = 7 points that defines the red cell. 3 of those on the west face are sub points within the ymin -> ymax range of the west face. I can get the ymin and ymax from the bounds, yes, but not the 3 internal points. Which is why I was trying to iterate over my neighbours.

You’ll have to use the supercursors. On each neighbor oriented cursor you create, before you recurse inside the tree, clone the cursor to keep a track of where you are at each level. This will be equivalent to use a non oriented cursor. The ToParent is equivalent to using your cloned cursor.

Yes I got all of that from your previous posts and that was very helpful thank you. I wrote some code where the cloned cursor acted as a proxy for the missing ToParent. My issue, my only issue, is having traversed into the parent in the figure below that is the West neighbour of the red cell that has 7 children, three of which are at a coarser level to the other four.

Screenshot 2020-06-26 at 17.06.17

Question: How do I iterate over all of the 7 children of this west parent neighbour cell and only identify the green cells, and reject the grey ones. I cannot figure this out. I know in this instance that the green cells touch the red cell, but I do not know how to codify that and how to reject the grey cells. This snap shot is a zoom in of the wider mesh posted earlier just concentrating on the west face.

What logic test am I writing, physical code, to distinguish the three green cells, one of which is at a different level to the other two, and those other two smaller ones are themselves children at a lower level, that says, yes you’re neighbour is the red cell, you boarder the red cell, I’ll store your cursors in a vector, but I’ll reject the grey cells?

Thank you.
Andy

In your example, a cell is green if and only if:

  • It is a leaf
  • Its index iChild called from its parent equals 1 or 3. So you need to keep track of index iChild when you recurse.

For the north case, it would be indices 0 and 1. For the east case, it would be indices 0 and 2, and for the south case, it would be indices 2 and 3.

You can actually make it easier to know: in your example, only recurse in the indices going east. Then you are at the interface with the red cell if you are a leaf.

That’s been extremely helpful, I’ll try this. To close the loop: are the values of indices relating to the position of the children relative to their parent that you’ve just given, unrelated to the values of the following indices?

constexpr int SOUTH = 1;
constexpr int WEST = 3;
constexpr int EAST = 5;
constexpr int NORTH = 7;

Which I got from Here.

The values of the indices look to be different, that was something that was throwing me. So the above constexpr values, are indices for neighbours cells not positional children indices?

Is there anywhere in the source that documents the following?

For the north case, it would be indices 0 and 1. For the east case, it would be indices 0 and 2, and for the south case, it would be indices 2 and 3, and 1 or 3 for west.

Thanks again for your help, I’ll give this all a go now and do my best to post a working example.
Andy

You are using a Moore cursor, I gave you the indices for a Von Neumann cursor. When you don’t need the extra neighbors the Moore cursor gives, you should use Von Neumann: it is ligher / requires less operations.

The documentation is still very light for htg. But let me draw indices in 2D:

     4
   1 2 3
     0

Children indices are:

  2 3
  0 1

@Yohann_Bearzi. Could you briefly explain the usage and relationship between, GetOrigin, GetBounds, GetPoint, and GetSize? And their relationship to the value of GetLevel? I’m trying to assess the size of a given cell in relation to its direct neighbours (same stencil in previous posts, size of red cell compared to size of the green cells).

I have some really weird bugs that I’m trying to get to the bottom of and results of these functions make no sense.

I’ve navigated to a neighbour cell, and the result of HasTree and IsLeaf are both true for that neighbour cell. I’m comparing the results of the above functions from the cursor pointing to the centre cell I was focused on and the neighbour cell of that centre cell that I’ve now navigated to.

However in some cases the results of size is negative, and the maximum of the bounds is zero! I just want a representative length of the cell I’m in, but I find that when Level is zero some of these values are really strange. Why would max( xmax - xmin, ymax - ymin, zmax - zmin) from bounds return zero? Sometimes GetSize is zero. I can’t find a robust way to find the size of the cell I’m in.

If it helps the base mesh is a grid of quite a few cells (with different sizes) (I believe each one of these is a root in the vtkHyperTreeGrid nomenclature), and some have never been refined, including the neighbours. I guess that’s why they are level=0. It’s on a mesh like this that I’m trying to compare the relative size of myself to my neighbour.

Hope that makes sense?

Thanks,
Andy

Hi,

So I figured the bug out, some/most of the oddness has gone. However, in general I’d welcome any help/comments you have on the following as I’m using them a lot without much appreciation of what they do:

Could you briefly explain the usage and relationship between, GetOrigin , GetBounds , GetPoint , and GetSize ? And their relationship to the value of GetLevel ? I’d also like to understand or GetOrientation()

Thanks,
Andy

Hi,

The wording is not explicit indeed, let me go through them:

  • GetOrigin gives you the bottom-left point of the current tree vertex / node.
  • GetBounds returns bounds with the same definition for any VTK data structure, i.e. 6 values (xmin, xmax, ymin, ymax, zmin, zmax) of the current tree vertex.
  • GetPoint returns the center of the current tree vertex.
  • GetSize returns 3 values representing the length of each edge of the tree vertex: (xlength, ylength, zlength).
  • GetLevel tell which level you are at in the hypertree (a quadtree for your case). As it is a quadtree, you refine each dimension by 1/(2^level). You should refer to quadtree literature for this particular aspect if you are not familiar with this kind of structure.

Thank you very much. That is clear. In what context do I use GetOrientation() with these calls? Are the cells not always Cartesian aligned?

Previously you said:

  • GetGlobalIndex() in the cursor is unique.

Do you mean that the index returned from this is unique within the tree associated with the root cell within the grid, but could well be a repeated index globally in the mesh for another child of a different root cell within the grid? Or do you mean it’s unique within the mesh and never repeated regardless of the root cell in the grid? I need an index that conforms to the latter.

Thanks again,
Andy

GetOrientation returns you the dual dimension of the htg when you are in 2D. An htg is always axis-aligned, but it could be (x,y), (y,z), or (z,x).

The global index is unique in the entier htg.

:+1: