[Connect NET vs Interop] Range and Origin results don't make sense comparing to drawing

I think I have a headache trying to figure out how to get the range and origin results consistently. For example here are results from the same textElement but accessing the range from different APIs:

Interop - OpenDesignFileForProgram

Range.High.X = 1198162.033

Interop - OpenDesignFile

Range.High.X = 5.77

.NET on Active Design File

CalElementRange.X = 1198162060

.NET on Loaded Design File

CalElementRange.X = 1198162060

Properties examining in the DGN

Origin.X = 5IN 5TN so that looks to match the Range.High.X of the OpenDesignFile in Interop

UOR = 0.000393700787401

With that, I see some correlation between the Interop OpenDesignFileForProgram and NET results, X1000, but i don't understand how i interpret that value to 5.7... Any help to understand this madness is appreciated.

Parents
  • HI Viktor,

    With that, I see some correlation between the Interop OpenDesignFileForProgram and NET results, X1000

    The range should be consistent, because there is only one source of this value: What is stored in DGN in graphical element header, but it looks like APIs report this value in a different way.

    ...

    Element range is always integer (because stored as integer in DGN file), but COM (so VBA and NET/Interop) reports, when possible, values in master units.

    but i don't understand how i interpret that value to 5.7

    I have zero experience with imperial units, and also I do not know what 5IN 5TN means (5 inches and 5<?>), but I think:

    • Interop - OpenDesignFile reports 5.77 because it is the range, expressed in master units, so 5IN 5TN is recalculated into one decimal number.
    • Interop - OpenDesignFileForProgram reports 1198162.033, because when DGN file is opened using OpenDesignFileForProgram (which is, as Jon explained in another discussion, quite low level raw access to DGN content, opened as work DGN), complete context is not initialized, so also range is "only" recalculated using set resolution, which is probably 1000 in this case.
    Any help to understand this madness is appreciated.

    It may look like madness, but it is not. The "problem" is that you try to merge/compare different worlds: COM working in MUs, raw access to "work DGN", and NET API (wrapped around C++), working consistently in UORs.

    With regards,

      Jan

  • Thank Jan, so believe it or not, TN is actually Tenth, basically at some point someone here thought that fractions were too simple and were likely jealous of the metric system, so they settled with Inches and Tenths of Inches :) I prefer metric system myself as well...

    Anyway, your explanation makes sense overall, but I am still struggling to understand how to implement the translation from the stored value to what the user should see (interpreted value). 

    I'll post back with a more precise comparison later.

Reply
  • Thank Jan, so believe it or not, TN is actually Tenth, basically at some point someone here thought that fractions were too simple and were likely jealous of the metric system, so they settled with Inches and Tenths of Inches :) I prefer metric system myself as well...

    Anyway, your explanation makes sense overall, but I am still struggling to understand how to implement the translation from the stored value to what the user should see (interpreted value). 

    I'll post back with a more precise comparison later.

Children
  • but I am still struggling to understand how to implement the translation from the stored value to what the user should see (interpreted value). 

    If you are interested in "visual user representation", I recommend to test DoubleFormatter class.

    Regards,

      Jan

  • I'll take a look at that, and i guess to be clear, i don't need the same visual representation as shown in the properties, with 5IN 5TN and such, just a double as 5.7 would suffice.

    Meanwhile:

    So let's keep it simple and convert to metric. I have an element with origin of:

    X: 0.5M and Y: 0.5M

    .NET value provided is:

    x: 1198197387

    y: 1200802000

    The UOR on the model is:

    2540

    In my oversimplistic understanding of the UORs, its basically a scaling mechanism? So if you want to draw in miles or in centimeters, you can scale the resolution in a way to allow X number of units to be within a single master unit, such as a centimeter or a mile.

    With that, resolution of 2540 basically means that there are 2540 units within a single subunit? or unit? (lets assume unit). So the above 0.5M should have a value of 50CM X 2540 which is 127,000. 

    I realize my UOR understand is way off here, so if you could point me to an article that explains this a bit better, it would help.

  • The UOR on the model is:

    What do you mean by "UOR is"? Where this value comes from?

    I assume you do not mean URO, but probably UorPerMaster, probably when (quite low) resolution 1000 is set.

    In my oversimplistic understanding of the UORs, its basically a scaling mechanism?

    Not at all. It is one from core model settings (there are several), defining how coordinates are stored. It is not anyhow related to scaling, even when to change UOR setting in existing model leads to change of physical (MU/SU) size, which is usually error.

    you can scale the resolution in a way to allow X number of units to be within a single master unit, such as a centimeter or a mile.

    It is opposite (maybe the main problem is in the used term "scaling", which is wrong in my opinion).

    UORs (units of resolution) are basic units (core grid), how coordinates are stored. In other words, this setting (together with resolution and conversion between units and internal system) defines, when coordinates ares stored in DGN file as floating point with double precision numbers, what is a conversion factor.

    For example, when there is X-value 1.2 meter (master units), it is not stored as (double)1.2, but as 1.2 x resolution x "units conversion factor". By default (in MicroStation seed files) resolution is 10 000, and the conversion factor is 1 (let's think DGN is based on metric, alternatively unit-less, system internally), so 1.2 meter is stored as (double)12000. It is the value reported by C++ and NET API.

    Consequences are:

    • When you change the resolution setting, "size" of existing elements changed accordingly, which is always wrong. Using previous example, X-coordinate 12000 UOR, when resolution changed to be 1000, will be presented to a user as 12 meters (and not original 1.2 meter)
    • When you change master units (from meters to inches), nothing happens (elements remain the same), because this change is done using the unit conversion factor, defined for inches (it changes from 1.0 to 0.0254. because 1 inch = 25.4 mm).
    5IN 5TN and such, just a double as 5.7 would suffice.

    Simple calculation would be enough, I guess something like value / modelInfo.UorPerMaster shoud return 7.75 (maybe multiplied by resolution).

    so if you could point me to an article that explains this a bit better

    A concept of UORs is typically described in CAD admin articles and blogs (e.g. this one), because for developers, it is usually "just a number", passed from one method to another.

    With regards,

      Jan

  • Thanks for clarification Jan. I think "scaling" may be a wrong word to use but the way you explained it aligned mostly with what I was envisioning. So you prompted me to just try a new seed file that's all metric, and the results are as you explained, basically if you take the point data from either CalcRange or GetSnapOrigin and divide it by ModelUOR, you get the actual value you'd expect to see.

    But, apparently that's not happening on some of these files for whatever reason. Even if I move the element to 0,0,0 in the model, then attempt to read that in .net it gives me:

    DPoint3d xyz="1198147387,1200752000,0"

    Which in my understanding should be a zero no matter the resolution.

    Then I decided to create new model and move the content there, but still reporting these large numbers. Then I changed the model resolution and units to metric, but STILL reporting numbers that don't seem to correlate to anything. At this point I am thinking it's something corrupted in the drawing or maybe left over in some settings from the past? What's weird is that the GUI is able to report the right info. So it gives me hope that there's still some way of decoding that.

    But, in the end, as long as the positioning is correct in relationship to other elements, I'm probably going to just go with these large numbers for my purpose.

  • if you take the point data from either CalcRange or GetSnapOrigin and divide it by ModelUOR

    When MU:SU are metric, yes.

    But, apparently that's not happening on some of these files for whatever reason.

    It's hard to say without sharing the file, because I can imagine more reasons why range is not as expected:

    • Range is fixed (pre-calculated) value, so maybe it was calculated wrongly. Using fixrange utility should help there.
    • Range is correct, but looks like not: Can happen in complicated elements, where range was calculated for some "hidden" element.
    • Maybe there is model origin shift (even when I think it should not cause any problem).
    • GCS is assigned?
    • ...
    I'm probably going to just go with these large numbers for my purpose.

    There are only a few "typical"reasons, why to access element range information:

    • Scanning for elements in specific area
    • Analysis of an "element touches themselves" (or similar tasks), when the first step is, again, scanning based on range.

    With regards,

      Jan