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.
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:
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
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
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.
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?
Unknown said: Why do you pass arguments as ref? Are you aware of a difference of passing instances with and without ref?
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);
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.
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.
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);
ShapeElement shapeEl = ustnApp.ActiveModelReference.GetElementByID(510).AsShapeElement();
Point3d[] vertices = shapeEl.GetVertices();
TextElement textEl = ustnApp.ActiveModelReference.GetElementByID(511).AsTextElement();
Point3d textOrigin = textEl.get_Origin();
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:
Returns an array of points. The array contains the vertices of the element.
Syntax
Point3d () = object.GetVertices
The GetVertices method syntax has these parts:
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
Dale am not sure where you are getting your information, but it is incorrect. ShapeElement.GetVertices() returns an array, not a Point3d[] Array.
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.
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."
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.
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,
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.