[v8i C#] Creating grouped holes via stdmdlbltin.dll

Hi all,

I'm currently writing an application which is plotting the Environment Agency's surface water flood map (~1.5Gig ShapeFiles) to v8 DGN's, tiled into 20km chunks (a pre-requisite for our internal applications).

This is currently being loaded into a spatial DB (PostGIS) and then queried out via bounding box in a C# application. Many of the geometries are going to be grouped holes, which I need to create.

I've seen this archived thread (https://communities.bentley.com/products/programming/microstation_programming/f/19569/t/59939.aspx) and tried to implement the adjusted mdl call for mdlElmdscr_setProperties.

Unfortunately this is returning "System.AccessViolationException: Attempted to read or write protected memory" whenever calling it.

Any ideas why this might be the case?

Code below:

[DllImport("stdmdlbltin.dll")]

static extern int mdlElmdscr_setProperties(int edP, ref int level, ref int ggNum, ref int elementClass, ref int locked, ref int newElm, ref int modified, ref int viewIndep, ref int solidHole);

int tmp = 0;

int solid = 1;

int hole = 0;

 

ShapeElement myShape1 = oApp.CreateShapeElement1(null, shape1, MsdFillMode.msdFillModeNotFilled);

mdlElmdscr_setProperties(myShape1.MdlElementDescrP(true), ref tmp, ref tmp, ref tmp, ref tmp, ref tmp,ref tmp, ref tmp, ref solid);

Parents
  • Unknown said:
    mdlElmdscr_setProperties(myShape1.MdlElementDescrP(true), ...);

    If you pass true to MdlElementDescrP you are telling the compiler that you will perform memory management in your code.  Furthermore, says VBA help: If a program tries to access any property or method of the element after calling MdlElementDescrP (True), then that method/property will raise an error saying something like "Element has not been initialized".

     
    Regards, Jon Summers
    LA Solutions

  • Hi Jon,

    Many thanks for the response, unfortunately that hasn't remedied the problem.

    I've tried the VBA example from your site, which works correctly. There is obviously something I'm doing incorrectly when calling from C#.

    Regards, Alex

  • Unknown said:
    Unfortunately that hasn't remedied the problem

    Try adding your element to the active model, then read the new element.  Apply new properties to the read element, then rewrite it.

    Set oElement = CreateXxx ()
    ActiveModelReference.AddElement oElement
    Set oElement = ActiveModelReference.GraphicalElementCache.GetLastValidElement
    ... modify element
    oElement.Rewrite

     
    Regards, Jon Summers
    LA Solutions

  • Jon,

    Again, your answer is greatly appreciated. Unfortunately not a fix. Are you able to compile and test the following sample?

    Simply creating a shape and setting it's "Solid property".

    C# Console App, 3.5 Framework.

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Runtime.InteropServices;

    using BCOM = Bentley.Interop.MicroStationDGN;

    using BMI = Bentley.MicroStation.InteropServices;

    namespace ForumTest

    {

       class Program

       {

                   [DllImport("stdmdlbltin.dll")]

           static extern int mdlElmdscr_setProperties(int edP, ref int level, ref int ggNum, ref int elementClass, ref int locked, ref int newElm, ref int modified, ref int viewIndep, ref int solidHole);

           static void Main(string[] args)

           {

               int tmp = 0;

               int solid = 1;

               int hole = 0;

               BCOM.Application oApp = BMI.Utilities.ComApp;

               BCOM.DesignFile oDGN = oApp.OpenDesignFile("C:\\Data\\Blank.dgn", false);

               Console.WriteLine(oApp.Caption);

               BCOM.Point3d[] myShapeVerts = new BCOM.Point3d[5];

               myShapeVerts[0].X = 0; myShapeVerts[0].Y = 0;

               myShapeVerts[1].X = 0; myShapeVerts[1].Y = 10;

               myShapeVerts[2].X = 10; myShapeVerts[2].Y = 10;

               myShapeVerts[3].X = 10; myShapeVerts[3].Y = 0;

               myShapeVerts[4].X = 0; myShapeVerts[4].Y = 0;

               BCOM.ShapeElement myShape = oApp.CreateShapeElement1(null, myShapeVerts, BCOM.MsdFillMode.UseActive);

               int elemDescP = myShape.MdlElementDescrP(false);

               Console.Write("Element DescrP: ");

               Console.Write(Convert.ToString(elemDescP));

               mdlElmdscr_setProperties(elemDescP, ref tmp, ref tmp, ref tmp, ref tmp, ref solid, ref tmp, ref tmp, ref solid);        

               oApp.ActiveModelReference.AddElement(myShape);

               oDGN.Close();

               oApp.Quit();

           }

  • Unknown said:
     BCOM.ShapeElement myShape = oApp.CreateShapeElement1(null, myShapeVerts, BCOM.MsdFillMode.UseActive);

    If you omit mdlElmdscr_setProperties, is your shape created correctly?  You're initialising the X,Y components of your Point3d array, but not the Z component.  Be explicit!

     
    Regards, Jon Summers
    LA Solutions

  • Jon,

    Yes, bar the MDL call everything works as expected.

    In the main app, Z is initialised - apologies for missing it in the snippet posted here.

    Regards, Alex

  • Unknown said:
    [DllImport("stdmdlbltin.dll")]
    static extern int mdlElmdscr_setProperties(int edP, ref int level, ref int ggNum, ref int elementClass, ref int locked, ref int newElm, ref int modified, ref int viewIndep, ref int solidHole);

    The function is going to change the element, which is fine in C/C++ because you're passing a pointer to the function.  But I'm not sure what C# can do with int edP, since it doesn't know about pointers.  Try declaring the function like this...

    [DllImport("stdmdlbltin.dll")]
    static extern int mdlElmdscr_setProperties(ref int edP, ref int level, ref int ggNum, ref int elementClass, ref int locked, ref int newElm, ref int modified, ref int viewIndep, ref int solidHole);

    I have no idea whether that will work. 

     
    Regards, Jon Summers
    LA Solutions

  • Hi Alex,

    Have you tried to call mdlElmdscr_createShapeWithHoles directly in your C# code ?

    HTH, YongAn



  • Unknown said:
    Have you tried to call mdlElmdscr_createShapeWithHoles directly in your C# code?

    I think he's used this article about Creating a Grouped Hole with VBA as his starting point.

     
    Regards, Jon Summers
    LA Solutions

  • Today, another one asked me the same question and I found we can use ClosedElement.GetDifferenceShapes method to create a grouped hole simply.



Reply Children
No Data