Hi,
I'm finding that the ChildElemIter class when applied to a GroupedHole element does not return true for the ChildElemIter.IsValid method; however it does return true for a generic unnamed group (e.g. group together two independent, non-intersecting polygons). Is this expected? The docs don't mention anything about not being able to use this class for GroupedHoles.
My objective is to get the level ID of one of the shapes in the GroupedHole since the parent element just stores the Default level 0.
Thanks,
Martin
Martin Tyberg said:the ChildElemIter class when applied to a GroupedHole element does not return true for the ChildElemIter.IsValid method
A GroupedHole element is an anonymous cell. See the comments here: The complex chain handlers were changed in MicroStation CONNECT Edition compared to their V8-generation predecessors. They no longer expose their child elements to callers. Also, ChildElemIter no longer provides a way to navigate the children of complex elements such as a cell.
Despite the above, this code works for me...
bool LabelHelper::ContainsNestedAnnotation (ElementHandleCR cell, WCharCP innerCellName) { for (ChildElemIter child (cell); child.IsValid (); child = child.ToNext ()) { if (MicroStation::IsNormalCell (child)) { NormalCellHeaderHandler* innerCell = dynamic_cast<NormalCellHeaderHandler*>(child.GetDisplayHandler ()); return MatchCellName (innerCell, child, innerCellName); } if (MicroStation::IsComplex (child)) { if (ContainsNestedAnnotation (child, innerCellName)) return true; } } return false; }
Regards, Jon Summers LA Solutions
Hi Jon,
Thank you for your answer. I had seen your article when I was searching for info on this issue but I couldn't find any reference to this in the official Microstation Docs. Do you know where I could find this?
Your code works for me too on anonymous cells as long as they aren't grouped hole anonymous cells - not sure why.
In any event, do you know of a proper way to get the level of a grouped hole element since this can only be retrieved by its children (the parent cell's level is always 0 - if I change the grouped hole element's level in the Microstation UI to a different level, the cell's level remains 0 and the children elements' level only changes)?
Martin Tyberg said:Do you know of a proper way to get the level of a grouped hole element since this can only be retrieved by its children (the parent cell's level is always 0
A cell header element is not a graphical element and has neither symbology nor level.
The components of a cell are usually graphical, and therefore have both symbology and a level. However, cells may be nested, so when enumerating the contents of a cell you must detect nested cells and enumerate those. Usually a recursive algorithm works.
Each graphic component of a cell may have its own symbology and level. A cell that contains 10 DGN graphic elements could have ten different colours on ten different levels.
Martin Tyberg said:I couldn't find any reference to this in the official Microstation Docs. Do you know where I could find this?
From the MicroStationAPI help: A grouped hole is a sub-type of cell. A grouped hole cell must have a first child that is a closed curve with solid area type followed by at least one closed curve with hole area type. Displays fill using parity rules .
Martin Tyberg said:Your code works for me too on anonymous cells as long as they aren't grouped hole anonymous cells
AFAIK a grouped hole is no more than an anonymous cell. It has topology, defined by its component shapes. There's nothing in a grouped hole that says "I am a grouped hole". The MicroStation tool that creates a grouped hole is responsible for checking that topology.
It's not clear why your code fails. Please post a DGN example of your grouped hole.
Jon Summers said:A cell header element is not a graphical element and has neither symbology nor level. The components of a cell are usually graphical, and therefore have both symbology and a level. However, cells may be nested, so when enumerating the contents of a cell you must detect nested cells and enumerate those. Usually a recursive algorithm works. Each graphic component of a cell may have its own symbology and level. A cell that contains 10 DGN graphic elements could have ten different colours on ten different levels.
Ok, I thought maybe Microstation's algorithm for knowing to categorize an anonymous cell as a grouped hole (when you hover over a grouped hole in the view with the mouse, it tells you it's a grouped hole and on which level it's on which seems to always be the level the last hole added is on) was partly related to checking that all holes and parent polygon are on the same level but I see now that you can create a grouped hole with each hole on a different level. So is there a proper way to get the level of the first child (parent polygon)? For now, I've resorted to getting a MS element descriptor and using the old mdlElement_getProperties function.
Jon Summers said:From the MicroStationAPI help: A grouped hole is a sub-type of cell. A grouped hole cell must have a first child that is a closed curve with solid area type followed by at least one closed curve with hole area type. Displays fill using parity rules
I meant I couldn't find in the docs that ChildElemIter isn't supposed to work anymore on complex elements like cells.
Jon Summers said:It's not clear why your code fails. Please post a DGN example of your grouped hole.
Please find attached a dgn file with a single grouped hole in which ChildElemIter::IsValid() fails.
Test1.dgn
Martin Tyberg said:Test1.dgn
OK: you have a valid grouped hole element. I used MicroStation's hatch tool to achieve this...
Martin Tyberg said:I meant I couldn't find in the docs that ChildElemIter isn't supposed to work anymore on complex elements like cells
Well, it's not formally documented. I think that comment arose from a conversation on this Forum several years ago with one of the Bentley Developers (probably Brien Bastings).
Perhaps Robert Hook can comment?
Jon Summers said:OK: you have a valid grouped hole element. I used MicroStation's hatch tool to achieve this...
Thanks for checking.
Jon Summers said:Well, it's not formatlly documented. I think that comment arose from a conversation on this Forum several years ago with one of the Bentley Developers (probably Brien Bastings).
Ah ok, thanks.
Hi Martin,
finally have some time to read forum posts ;-)
Martin Tyberg said:My objective is to get the level ID of one of the shapes in the GroupedHole since the parent element just stores the Default level 0.
Why you do not use (one from the most) standard solution in MicroStation CE API? ... IElementGraphicsProcessor?
When _AnnounceElemDisplayParams method is overridden, it reports level (and other attributes) of all elements. And in addition, the processor works with all MicroStation elements and does not care about their persistence format (whether they are cells, type 106 etc).
With regards,
Jan
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
Hi Jan,
Thank you for going through this thread. I had seen IElementGraphicsProcessor in my reading but didn't explore it further at the time. I see how it would provide me with the level of the first polygon in the grouped hole after a more detailed look. I will try it out. Thanks for the guidance on this.
Martin Tyberg said:I had seen IElementGraphicsProcessor in my reading but didn't explore it further at the time.
This is really one from core classes in MicroStation API and the standard way how to iterate elements' content regardless of type. Because you use C++, "geometry collectors" ecosystem is richer than in NET, sop to check more specialized classes like DropGeometry and DropGraphics can be useful too.
Martin Tyberg said:I see how it would provide me with the level of the first polygon in the grouped hole after a more detailed look.
It's easy when you are interested in geometry / attributes and not internal element itself.
It's a kind of "paradigm change" that causes troubles for experienced MicroStation developers, because we normally see cells, groped holes etc. as "cells with elements inside", whereas the processor provides information about geometry/topology/... and cannot be used (I think) to enumerate the elements itself..
Jan Šlegr said:This is really one from core classes in MicroStation API and the standard way how to iterate elements' content regardless of type. Because you use C++, "geometry collectors" ecosystem is richer than in NET, sop to check more specialized classes like DropGeometry and DropGraphics can be useful too.
Yah, I started playing with the C# API but I found it much easier to get done what I needed using the C++ API.
Jan Šlegr said:It's a kind of "paradigm change" that causes troubles for experienced MicroStation developers, because we normally see cells, groped holes etc. as "cells with elements inside", whereas the processor provides information about geometry/topology/... and cannot be used (I think) to enumerate the elements itself..
Yah, I tested it out and it gave me what I needed graphically for each of the cell's children.