I have a program that was originally a .NET COM addin that was written for V8i. I've updated the addin to run inside CONNECT 10.08 also as a COM app. This is a QC application that runs thru all the dgn files in a project inspecting all the elements in the files checking things like level name, color, weight, linestyle, etc using the OpenDesignFileForProgram method. Even in V8, checking an element.level.name did not always provide a correct answer although the element.level.number method did always return the correct level number. I'm noticing the same problem in CONNECT where when checking a file created in CONNECT, the element.level.name may return incorrect levelname but the element.level.number is correct.
Here is the root of my problem, if I open a SelectSeries created file inside the CONNECT addin, sometimes both the element.level.name & element.level.number return incorrect results (if I open the file graphically using OpenDesignFile method those properties are returned correctly).
For example I have a single element in a SS10 file who's ID is 4002, looking at the element properties with the file loaded graphically the levelName = "TextMisc" & levelNumber = 212. If I open the same file in CONNECT using OpenDesignFileForProgram it shows levelName = "ActivePts-ConstElements" & levelNumber = 320 (these are levels that are defined in our level library.
Two question:1: has anyone else seen this behavior?2: We don't want to allow mixed platform files within our projects so I can filter by dgn version. I can't find documentation on dgn version numbers but using MicroStationDGN.DesignFile.FormatMajorVersion & FormatMinorVersion it appears V8 files are versioned 8.1XX & CONNECT files are versioned 8.2XX, can anyone confirm this?
Hi Mike Robertson,
When using OpenDesignFileForProgram have you added a call to UpdateElementDependencyState to see if that makes a difference?If this is possibly related to resource loading/timing issue, does adding a pause (e.g. 1 to 3 seconds after opening) make any difference?
Mike Robertson said:using the OpenDesignFileForProgram method
Prefer OpenDesignFile to OpenDesignFileForProgram.
Mike Robertson said:Even in V8, checking an element.level.name did not always provide a correct answer although the element.level.number
Because OpenDesignFileForProgram does not load the same environment as OpenDesignFile. As a user, OpenDesignFile has the correct DGNLibs loaded and synchronised with the active DGN. OpenDesignFileForProgram does not create an active DGN file and consequently has no active DGN models.
A level ID is hard-wired into a DGN element. Depending on what DGNLibs are visible, the level name may be different when the internal logic attempts a lookup using level ID as a key into the available level tables.
Mike Robertson said:If I open the file graphically using OpenDesignFile method those properties are returned correctly
More evidence that OpenDesignFileForProgram doesn't do what you expect.
Mike Robertson said:Has anyone else seen this behavior?
Yes: it's a well-known consequence of using OpenDesignFileForProgram. Prefer OpenDesignFile to OpenDesignFileForProgram. Search this Forum for discussions about OpenDesignFileForProgram.
Mike Robertson said:We don't want to allow mixed platform files within our projects
Whatever those internal format versions are, they're not exposed to users. I suspect that they inform Bentley products to take action. For example, CONNECT brands DGN files with their workspace/workset, which did not happen with V8. MicroStation CONNECT will add branding to a DGN file.
Format types you can detect via the API include DGN7, DGN8, DWG and DXF. As far as I can see, there's no format DGN8½
Regards, Jon Summers LA Solutions
I would prefer to use OpenDesignFile also, the problem is it is very slow and tends to crash MicroStation with large datasets.
Consider my prior suggestions and let us know if either help.
On crashes, those are valuable and can help pinpoint and fix very hard to find problems. Please feel free to report crashes on the community or product support team to help get those resolved.
Mike Robertson said:the problem is it is very slow
well, it's because complete MicroStation is initialized. On the other hand, everything is initialized and loaded properly and available (whereas access to "open for program", especially in COM API, is pretty limited).
An alternative can be to implement INITAPPS and to do not enter graphic mode, so some resources and time is saved, but it still works as a full MicroStation (without GUI). Native code is the right tool to implement INITAPP application.
Mike Robertson said:and tends to crash MicroStation with large datasets.
It's weird and I do not think it's because of MicroStation itself. But what I remember from using Interop API in V8i, it's quite simple crash MicroStation using wrongly implemented code (especially when a huge amount of data is processed).
Robert Hook said:have you added a call to UpdateElementDependencyState to see if that makes a difference?
I like this Bob's idea.
Unfortunately I do not remember all details, but at several V8i projects I had to wait for Idle mode in some situations to ensure everything is initialized properly after a file was opened.
Mike Robertson said:it shows levelName = "ActivePts-ConstElements" & levelNumber = 320
Did you check a content of LevelTable? Whether "correct level" is there, with expected level number? When yes, it seems the link between LevelTable and elements is not updated correctly (yet).
Labyrinth Technology | dev.notes() | cad.point
Jan Šlegr said:Did you check a content of LevelTable? Whether "correct level" is there, with expected level number? When yes, it seems the link between LevelTable and elements is not updated correctly (yet).
Like you said, I'm pretty sure the Element.Level.Name not returning the correct name is because of DGNLIB not being loaded. In V8i the Element.Level.Number was always correct so I could use that instead of name for our QC checks. In CONNECT, if the file was created in CONNECT the Element.Level.Number always returns the correct number, BUT if I check a file that was created in SelectSeries inside my program running in CONNECT, the Element.Level.Number is not always correct.
I've included a screen shot of a watch window where I look at the properties of an element in a SelectSeries created file using SS10 & CE10.08. Same file, only has this one object in the file. Notice the elementId is the same, the Levelnames don't match (due to level library not loaded I assume), BUT notice the LevelNumbers don't match.
Robert Hook said:When using OpenDesignFileForProgram have you added a call to UpdateElementDependencyState to see if that makes a difference?If this is possibly related to resource loading/timing issue, does adding a pause (e.g. 1 to 3 seconds after opening) make any difference?
Using both the UpdateElementDepencyState & a pause seems to help. Not perfect but will do for the time being. I'll continue to look into the issue and post if I can find anything. Hate using a pause because the results can vary from machine to machine.
Mike Robertson said:because of DGNLIB not being loaded
I do not think the problem relates directly to DGNLIB "loading", because when a level is used, complete definition is stored in active file, so to obtain level properties does not require to load original DGNLIB. On the other hand, how LevelTable(s) is stored and managed internally is hidden technical detail.
Mike Robertson said:In V8i the Element.Level.Number was always correct so I could use that instead of name for our QC checks.
I am not sure whether it's right to use LevelID (level number) for anything more than for temporary internal identification of the level. The only safe persistent identification of the level is its name.
But anyway, the number should be always correct.
Mike Robertson said:BUT if I check a file that was created in SelectSeries inside my program running in CONNECT
It seems some internal changes were implemented (probably both to MicroStation itself and DGN format) and older files require extra processing before they are ready to be used.
Mike Robertson said:Hate using a pause because the results can vary from machine to machine.
Why you do not want to use Idle event I mentioned in my previous post? At least I recommend to try it.
From documentation: Since a new MicroStation process does not enter the idle state until it has finished initializing, a program can use this event to be notified when initialization is complete. This is sometimes very important for a program that starts a new MicroStation process.
Even when the new process is mentioned, I am quite sure the same information is also valid when a new design file is opened.
Maybe something like to register for the event, open the file and wait for MicroStation to be idle is the way to go, without explicitly hardcoded pause.
II was using a pause as suggested by Robert Hook. I haven't used MicroStation idle before so will look into the idea.
Mike Robertson said:In V8i the Element.Level.Number was always correct
The level ID (VBA Element.Level.ID) is used internally by MicroStation and by you as a programmer. The level ID is not visible or usable by a MicroStation operator. In two different DGN files using the same level library (DGNLib), it is unlikely that they will have the same set of level IDs. In other words, don't attempt to compare level IDs if they are not in the same DGN file.
The level number (VBA Element.Level.Number) is a user-assigned value. MicroStation does not use it. It's an alias for the level name (VBA Element.Level.Name).
Depending on the loaded level tables, MicroStation may or may not be able to resolve a level name. But, as Jan notes, the level name is the only sure way to identify a level, wherever it's defined.