[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?

 

Parents
  • 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.undefine

    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 -->

    loop

    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,

    Alex

  • 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.

    Thanks,

    Alex

  • 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 08.09.04.51 and v8i 08.11.07.443 

    Results:

    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,

    Alex

    FenceTest.zip
  • 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.

    Regards,

    Alex

  • Jon, as always... you are the man!  Your expertise and knowledge continue to benefit me.  Thanks for sharing this alternative spatial search method.  You helped me cleanup a several thousand elements lickety-split.  My deliverable thanks you!  Existing surface colored much nicer now.

    Christopher Johnson
    Technologist/Visualization Specialist
    CH2M HILL
    135 South 84th Street, Suite 400
    Milwaukee, WI 53214
    Office - 414.847.0488
    Mobile - 414.339.9079
    www.ch2mhill.com
     
    Solutions Without Boundaries

Reply
  • Jon, as always... you are the man!  Your expertise and knowledge continue to benefit me.  Thanks for sharing this alternative spatial search method.  You helped me cleanup a several thousand elements lickety-split.  My deliverable thanks you!  Existing surface colored much nicer now.

    Christopher Johnson
    Technologist/Visualization Specialist
    CH2M HILL
    135 South 84th Street, Suite 400
    Milwaukee, WI 53214
    Office - 414.847.0488
    Mobile - 414.339.9079
    www.ch2mhill.com
     
    Solutions Without Boundaries

Children
No Data