[v8i] Fence.GetContents enumeration slowdown vs v8XM

Hi all,

I'm hoping someone might be able to suggest a simple fix to an issue I'm experiencing.

My current task is generating a dataset for viewing at 1:25,000 scale from our base mapping which is created for main viewing at 1:250 - 1:1250 when printed.

This involves a fair bit of "clash detection" for placing text at the new size / locations and spatial analysis for grouping elements with matching attribution.

During this process I've been using (very successfully under v8 XM) a lot of fence.GetContents, with fences defined from elements created in VBA, but not added to the ActiveModel. This has been working brilliantly under v8 XM, but unfortunately v8 XM won't start unless there is an "active screen" it appears, i.e. a live user - not at the Logon Screen or connected via Remote Desktop (it otherwise crashes with a DirectX initialisation error - This "build" process must run nightly on a headless machine, which unfortunately we cannot leave "logged in" with screensaver disabled.).

v8i seems happy to start without such a live session, but when running the exact  same VBA code under v8i any sections which rely on fence scanning run at 1/4 - 1/5th the speed as v8 XM - timed by wrapping kernel32 to get a Millisecs counter in VBA.

Essentially I'm asking if there any additional settings introduced in v8i to control Fences and enumeration of their contents?

Or is slowness of fence enumeration a known issue?


  • A code snippet would help.

    • What type of element defines a fence?
    • How do you call Fence.GetContents?

    Regards, Jon Summers
    LA Solutions

  • Hi Jon,

    Thanks for jumping in on this one.

    A code snippet of the relevant section - typed not copied from the code as not on my PC.

    This is an iterative function placing text with a leaderline and a background shape.

    It is placing asset numbers / codes over a map background - the text mustn't intersect other text or the map, etc.

    <-- Fence activesettings set to overlap, no clip or void -->

    <-- [1] -->

    dim oFence as fence

    set oFence = Activedesignfile.Fence


    oFence.definefromelement view1, outlineShp

    <-- outlineShp is a bounding shape (4 verts) generated from text boundary or textnode size -->

    dim ee as elementenumerator

    set ee = oFence.getContents

    <-- [2] -->

    do while ee.movenext

       <-- something in the fence, change position and try again -->


    Putting a timer around this code from [1] to [2] using a millisec count from kernel32 returns an average time of ~40 millisecs under v8i SS2.

    Using v8 XM this returns ~1-2 milliseconds.

    Would anything is SS3 be likely to change this? I believe we have access to SS3 under our SELECT agreement, but getting IT to test and install it will take a while and this task is fairly pressing!

    Many thanks,


  • I don't see you define the fence mode.  If left void from a previous operation, that could be time consuming.

    Unknown said:
    <-- Fence activesettings set to overlap, no clip or void -->

    Is that assumption or fact? 

    What happens if you explicitly set the fence mode before getting its contents?

    Sub CartoFenceMode ()
      With ActiveSettings
        .FenceOverlap = True
        .FenceVoid = False
        .FenceClip = False
      End With
    End Sub

    Regards, Jon Summers
    LA Solutions

  • Jon,

    Hi - yes, that is a fact. I was typing the previous code from another PC (workstations are "off the net") and I just inserted the "<-- Fence activesettings set to overlap, no clip or void -->" section to avoid typing.

    I'm absolutely convinced that there is an actual slowdown between versions, I've been through every Config Var and Workspace preference I can find and everything is comparable between both installations.



  • Unknown said:
    I'm absolutely convinced that there is an actual slowdown between versions

    I suggest that you prepare a simple test case: a VBA project that does nothing more than your timed code and a sample DGN model for it to work with.

    Then submit a Trouble Report (TR) to Bentley Systems with that evidence.

    Alternative Approach

    Since you're using a rectangular fence, another approach would be to use ModelReference.Scan to find elements.  Scanning is often the fastest way to find something in a DGN model.

    The ElementScanCriteria object passed to the scan method has a method IncludeOnlyWithinRange, which would accept the range of your text element. 

    The results of the scan is an ElementEnumerator, so there would be minimal changes in your code.

    Regards, Jon Summers
    LA Solutions

  • Hi Jon,

    Thanks for the suggestion of using ModelReference.Scan, I was unaware of the IncludeOnlyWithinRange method.

    Whilst this is potentially a fix in this case, it does limit to checking against rectangles. There are places in my code where I am using ellipse elements to find objects within a radius of each other. (I'd rather not have to do a 2D distance check against this many objects - although I could use ModelReference.Scan and return a Enumerator of elements in a bounding box and then check against them I guess).

    The attached ZIP contains test code and 2 DGN's - I'd appreciate it if someone could try this on other versions to see if they see similar results to my times below.

    SAMPLE.dgn - Illustrates the number of annotations placed and how many clash detections I'm doing

    TEST.dgn + FenceTest.mvba - Enumerates each cell, places a fence using a shape element at it's co-ordinates, does a GetContents. At the end it displays a MsgBox with the total time taken in Millisecs by the DefineFromElement and GetContents

    This code was tested on the following machine:

    Dell Optiplex 990 (Core i5-2500 @ 3.30Ghz, 4GB RAM, Intel Integrated Gfx, Windows 7 Enterprise 32-bit)

    Microstation versions: v8 XM and v8i 


    Test Run v8 XM v8i
    1 6675 Msecs Aborted @ 1180212 Msecs
    2 6707 Msecs Aborted
    3 6744 Msecs Aborted
    4 6922 Msecs Aborted

    As you can see v8i seems incredibly slow in comparison. I'll modify the code to use ModelReference.Scan and give it a try.

    Where do I submit a TR?

    Many thanks,


  • Just a quick follow up.

    Using ModelReference.Scan with IncludeOnlyWithinRange is considerably quicker, but as I stated above it limits me to using non-rotated rectangles only. This is workable is a few cases, but there are cases where I am working with rotated text. In this case a Range3d is inappropriate.

    I'd really like to see if other people get the same results as I, running on v8i SS2 or SS3.



  • Another bump to hopefully get someone to try this (ZIP file in my previous post).


    Once again - thanks for your suggestion for ModelReference.Scan with the OnlyIncludeWithinRange, unfortunately it appears that this is comparing the test Range against element Range, not test Range against  element Geometry.

    This leaves lots of areas where labels aren't placed due to range clashes, but would be placed if compared to geometry (i.e. an L shaped linestring or large diagonal line).



  • Just wanted raise the profile of this one again, could anyone with v8XM and v8i compare my results?

  • Unknown said:

    Is that really your name?  I suggest you apply for a new set of parents  8-)

    Unknown said:
    Where do I submit a TR?

    Be Communities provides, in general, peer-to-peer help.  If you have a problem with a Bentley Systems product, such as MicroStation, then submit a formal Trouble Report (TR) to Bentley Systems. 

    Assuming your organisation has a SELECT contract, then your SELECT administrator should know all about submitting a TR.  Otherwise, search Bentley Systems website.

    Regards, Jon Summers
    LA Solutions