Point3dInPolygonXY returns error in C#

I am trying to determine whether or not a text element (or e shape) is placed inside a shape/complexshape. No matter what I try, I get an error.

Here is the code:

Point3d pText = eleText.get_Origin();
Array psShape = e.AsShapeElement.GetVertices();
int inside = ms.Point3dInPolygonXY(ref pText, ref psShape);

Here is the error I get every time:

{"The parameter is incorrect. (Exception from HRESULT: 0x80070057 (E_INVALIDARG))"}

It doesn't matter if I use a shape or complex shape, doesn't matter what point I use, whether it's one inside, outside, or on the shape, doesn't matter if I use ShapeElement.GetVertices() or ShapeElement.AsVertexList.GetVertices(), I receive the same error no matter what I try.

Any thoughts/suggestions?

My work around has been to use the shape to define a fence, then get elements inside the fence. Although this works, it is not ideal. I would also like to test which shapes overlap vs just share an edge, which requires determining if a point lies directly on the edge, which requires Point3dInPolygonXY.

Any help would be greatly appreciated.

For the record, I am developing in C#, Visual Studio 2015 Pro, for MicroStation v8I, and have referenced COM object Bentley MicroStation DGN 8.9 Object Library.

Parents
  • Hi Dave,

    a couple of notes:

    Please read and follow MicroStation Programming forum best practices, which will make your posts better recognizable. So recommend subject of your question is  [V8i C# Point3dInPolygonXY returns error in C#]

    Also use Syntaxhighlighter tool (Yellow pencil icon) when posting any code, in the highlighter choose a proper language, so it will be colorized properly.

    Unknown said:
    returns error in C#

    Strictly speaking the method does not return error, but it throws exception. It's simply visible here and does not cause any problem, but in some situations it's something completely different if e.g. error code is returned or excetion is thrown.

    Unknown said:
    For the record, I am developing in C#...

    It's good summary, but it's recommended to always state if your code is MicroStation addin or it's external process. In your case I guess you access MicroStation externally.

    Unknown said:
    Any thoughts/suggestions?

    There is error in your code and the code itself is not well written in my opinion.

    Array psShape = e.AsShapeElement.GetVertices();

    What is Array psShape? GetVertices returns Point3d[] and Point3dInPolygonXY method requires Point3d[]. Why do you use Array, which is (citation) the base class for language implementations that support arrays?

    My other comments:

    • Why do you pass arguments as ref? Are you aware of a difference of passing instances with and without ref?
    • Try to avoid casting As<ElementType> method in calling element's methods. Better approach is to define variable using specific element type and to call required method using this variable, so there will be one casting only. In the case you are not sure about the type, test for element type is necessary.

    Unknown said:
    Any help

    I guess the code would look like this:

    ShapeElement shapeEl; // and assign somewhere using shapeEl = generalElement.AsShapeElement()
                
    Point3d textOrigin = eleText.get_Origin();
    Point3d[] shapeVertices = shapeEl.GetVertices();
    int inside = ms.Point3dInPolygonXY(textOrigin, shapeVertices);

    With regards,

      Jan

  • Unknown said:

    Strictly speaking the method does not return error, but it throws exception. It's simply visible here and does not cause any problem, but in some situations it's something completely different if e.g. error code is returned or excetion is thrown.

    Correct, but your code actually returns an error. 'Cannot implicitly convert type 'System.Array' to 'MicroStationDGN.Point3d[]'. An explicit conversion exists'

    And that's why I defined my variable as an Array, and not Point3d[], to answer your other question.

    Unknown said:
    There is error in your code and the code itself is not well written in my opinion.
    Thanks for the feedback. This is my first time posting in this forum, but by far not my first time programming. I was unaware that the help forum was actually a gathering place for criticism. Thank you for clearing that up for me.
    Unknown said:
    What is Array psShape? GetVertices returns Point3d[] and Point3dInPolygonXY method requires Point3d[]. Why do you use Array, which is (citation) the base class for language implementations that support arrays?
    Array psShape is an Array of the points returned by the GetVertices function. I thought this was simple enough to understand by anyone with C# experience. If you do not understand basic C# syntax, please don't criticize my code.
    Unknown said:
    Why do you pass arguments as ref? Are you aware of a difference of passing instances with and without ref?
    Because that is what the function is expecting. When you use the Point3dInPolygonXY function, it expects a ref to the arguments. Trust me, it throws an exception no matter which way it is used.

    Unknown said:

    I guess the code would look like this:

    1
    2
    3
    4
    5
    ShapeElement shapeEl; // and assign somewhere using shapeEl = generalElement.AsShapeElement()
                 
    Point3d textOrigin = eleText.get_Origin();
    Point3d[] shapeVertices = shapeEl.GetVertices();
    int inside = ms.Point3dInPolygonXY(textOrigin, shapeVertices);

    Did you try this code, or are you just assuming? This code returns an error because you are using shapeEl.GetVertices() which returns an Array, and trying to cast it as Point3d[] without actually casting it.

  • Jan, thank you for the attempt, but your code is producing more errors than I had to begin with. The second line of your code is an error. 'Cannot implicitly convert type 'System.Array' to 'MicroStationDGN.Point3d[]'. An explicit conversion exists (are you missing a cast?)'
  • Unknown said:
    Dale
    because you are using shapeEl.GetVertices() which returns an Array

    No. It does not return Array instance, but Point3d[] array, which are two different types. Casting is possible, but is not implicit, and there is no reason to use it.

    I am not sure where you are getting your information, but it is incorrect. ShapeElement.GetVertices() returns an array, not a Point3d[] Array. If there is no reason to cast it to a Point3d[] Array like you say, then Visual Studio is giving users incorrect errors, and you should probably notify Microsoft of the bug in C# since you have so much experience.

    Unknown said:
    1
    2
    3
    4
    5
    6
    7
    ShapeElement shapeEl = ustnApp.ActiveModelReference.GetElementByID(510).AsShapeElement();
    Point3d[] vertices = shapeEl.GetVertices();
     
    TextElement textEl = ustnApp.ActiveModelReference.GetElementByID(511).AsTextElement();
    Point3d textOrigin = textEl.get_Origin();
     
    int isTextInShape = ustnApp.Point3dInPolygonXY(textOrigin, vertices);

    This code does not work. Line 2 causes an error and prevents execution since it is trying to convert a System.Array type to a MicroStationDGN.Point3d[] Array type without proper casting. Jan, I appreciate the help, but if you truly don't know the answer, it is ok to just not reply, instead of replying with what you think is right.

  • Unknown said:
    am not sure where you are getting your information, but it is incorrect. ShapeElement.GetVertices() returns an array, not a Point3d[] Array.

    Sorry, but the information of Jan is correct: The MVba help will get you to this:

    GetVertices Method

                              

    Returns an array of points. The array contains the vertices of the element.

    Syntax

    Point3d () = object.GetVertices

    The GetVertices method syntax has these parts:

    PartDescription
    object A valid object.

    Where object may be a shape element or any of the VertexList Objects

    And you will find an example in the VBA help: Vertex List Example  look for it and you get a proof of 

    Dim m_vertexList() As Point3d   (VBA syntax)

    to get

    m_vertexList = m_oVL.GetVertices

    Regards

    Frank

    since 1985: GIS, CAD, Engineering (Civil)  Senior Consultant : [Autodesk Civil 3D , Esri ArcGIS, VertiGIS: in previous days : Bentley MS V4 - V8i, GeoGraphics, Bentley Map V8i, InRoads,  HHK Geograf, IBr DAVID] :  Dev: [C, C++, .NET, Java, SQL, FORTRAN, UML]
    [direct quote by: http://en.wikipedia.org/wiki/Helmut_Schmidt]: "Wer Kritik übel nimmt, hat etwas zu verbergen"
    Wer Grammatik- und/oder Rechtschreibfehler findet, der darf sie behalten :-)

  • Unknown said:

    Dale
    am not sure where you are getting your information, but it is incorrect. ShapeElement.GetVertices() returns an array, not a Point3d[] Array.

    Sorry, but the information of Jan is correct: The MVba help will get you to this:

    GetVertices Method

                              

    Returns an array of points. The array contains the vertices of the element.

    Syntax

    Point3d () = object.GetVertices

    The GetVertices method syntax has these parts:

    PartDescription
    object A valid object.

    Where object may be a shape element or any of the VertexList Objects

    And you will find an example in the VBA help: Vertex List Example  look for it and you get a proof of 

    Dim m_vertexList() As Point3d   (VBA syntax)

    to get

    m_vertexList = m_oVL.GetVertices

    Thanks Frank. As I have already stated previously, I have used Point3dInPolygonXY dozens of times in VBA. The help you provided is related to VBA. That's great, but not related to what I asked. I am currently developing in C#. The Point3dInPolygonXY function is NOT working in C# the way it does in VBA. That is the reason I am here. I assumed that the Bentley forums would be the best place to go to get assistance with this error. I apologize if I made an incorrect assumption.

    If nobody here has any knowledge of actually using Point3dInPolygonXY within C#, then no responses are necessary.

  • you're dealing with the managed Microstation COM API so why should there a difference for
    Point3dInPolygonXY and all the POINT3D Array stuff.
    We are out! Open a service ticket and you will get help from Bentley, hopefully.

    Regards

    Frank

    since 1985: GIS, CAD, Engineering (Civil)  Senior Consultant : [Autodesk Civil 3D , Esri ArcGIS, VertiGIS: in previous days : Bentley MS V4 - V8i, GeoGraphics, Bentley Map V8i, InRoads,  HHK Geograf, IBr DAVID] :  Dev: [C, C++, .NET, Java, SQL, FORTRAN, UML]
    [direct quote by: http://en.wikipedia.org/wiki/Helmut_Schmidt]: "Wer Kritik übel nimmt, hat etwas zu verbergen"
    Wer Grammatik- und/oder Rechtschreibfehler findet, der darf sie behalten :-)

  • Hi Dale,

    Unknown said:
    The Point3dInPolygonXY function is NOT working in C# the way it does in VBA.

    Frank is right, there is no difference between VBA and C#, because it comes from the same basis (COM Interop API). If some differences exist, they are minor and are caused e by language differences. Mehtods, types etc. are the same. If you tell it's not true, please provide some rationale.

    Unknown said:
    If nobody here has any knowledge of actually using Point3dInPolygonXY within C#, then no responses are necessary.

    It's a shame your approach is "I am right, everybody else are wrong.". There are plenty of people using C# every day, not only me and Frank, and we all use MicroStation VBA documentation as reference for C# development, because it's the same. In this community you can find discussions with C# code snippets or attached projects that are the same. If you are so strongly convinved we don't know what we are talking about, I see no way how to change your opinion.

    If you stated that GetVertices() returns Array and not Point3d[], can you provide some examples (screen captures from VS as I did, VS project etc.)? It seems something in your project is different from what is used normally (caused by project type, referenced assembly...?) and such difference cannot be investigated without further details.

    My last try (because I don't see any effort to try to find out why Array is returned as you stated, comparing to effort to explain that we all are wrong) is an attached Visual Studio project. It includes also DGN file, so it should be simple to try it. For a simplicity, it expects MicroStation is running and a correct design file is attached.

    Dot, end.

    vsproject.zip

  • Unknown said:

    It's a shame your approach is "I am right, everybody else are wrong."

    Thank you. Not for any help, but for enlightening me as to what kind of people are here on the Bentley forums. I came here asking for assistance. Not only have you insulted the quality of my code writing, but you have also attributed a quote to me that I never said, and accused me of telling everybody that they are wrong. I never once said what you quoted me as saying. If this is the type of treatment that can be expected on a professional site like this, then it is pretty sad that Bentley associates itself with such individuals. If insulting and misquoting others helps you feel better about yourself, that is pretty sad. It is unfortunate that you have spend so many years programming and still have such disdain for others.

  • In case anyone having the same issue stumbles upon this post, I found the cause and solution.

    As I mentioned in my original post, I was referencing the Bentley MicroStation DGN 8.9 Object Library. My project was also using .NET Framework 4.5.2.

    In order for the code to work as expected, and as specified here by others, the Bentley.Interop.MicroStationDGN dll needs to be referenced instead, and the project needs to be using the .NET Framework 3.5.

    Thank you to those who tried to help.
  • Unknown said:
    My project was also using .NET Framework 4.5.2.

    Ah, this information was not mentioned yet. It makes clearer why probably the exception is reported.

    Unknown said:
    In order for the code to work as expected, and as specified here by others, the Bentley.Interop.MicroStationDGN dll needs to be referenced instead, and the project needs to be using the .NET Framework 3.5.

    It's not quite true. If COM Interop is used to access MicroStation from another process, it's not mandatory to use NET 3.5; newer versions like 4.5.2 can be used. COM is designed to be neutral API and NET itself maintain a high level of backward compatibility also. On Stackoverflow some discussion about this topic (referencing 3.5 from 4.5 NET code) can be found.

    So to use NET 3.5 is one way, probably simpler, but it's still possible to compile code as NET 4.5.2 too. NET 4 introduced some new features and default properties of referenced assemblies are different in NET 4 projects. I suppose in your project Embed Interop Type = True was set for bentley.interop.microstationdgn.dll. It leads to problems with a code (and consequently to pretty complex discussion how Interop types are mananged at compilation and runtime).  If set to False (default NET 3.5 behaviour, where this property does not exist), I am quite sure the code should work fine.

    And yes, I tried it, code similar to the provided sample, but targeting NET 4.5.2, works as expected with MicroStation V8i. No exception reported.

    Regards,

      Jan

  • Unknown said:
    I was referencing the Bentley MicroStation DGN 8.9 Object Library.

    Finally it does make sense to me why types were so strange: Because it's so unusual to use COM objects directly to access MicroStation from C# (I don't know about any such example) I did not thought about difference between these two libraries (and in fact, both are named as Interop dlls). I guess it's possible to use registered COM objects (in the same way as any other COM), but it requires extra effort to do it right. I assume COM access complexity was the reason why Bentley.Interop.MicroStationDGN.dll was created and why it's used as standard way to access MicroStation in all examples.

    Previous information about possibility to use NET 4.5 remains valid, I suppose to use COM directly is the same challenge at 3.5 and 4.5.2.

    Regards,

      Jan

Reply
  • Unknown said:
    I was referencing the Bentley MicroStation DGN 8.9 Object Library.

    Finally it does make sense to me why types were so strange: Because it's so unusual to use COM objects directly to access MicroStation from C# (I don't know about any such example) I did not thought about difference between these two libraries (and in fact, both are named as Interop dlls). I guess it's possible to use registered COM objects (in the same way as any other COM), but it requires extra effort to do it right. I assume COM access complexity was the reason why Bentley.Interop.MicroStationDGN.dll was created and why it's used as standard way to access MicroStation in all examples.

    Previous information about possibility to use NET 4.5 remains valid, I suppose to use COM directly is the same challenge at 3.5 and 4.5.2.

    Regards,

      Jan

Children
No Data