We use the COM server option, like described here http://www.la-solutions.co.uk/content/DotNet/DotNet-ComServerGuide.htm
I have tried to use Microstation SDK, but with a Microstation PowerDraft Connect Edition I can't run it, isn't it?
We use the COM server option, like described here http://www.la-solutions.co.uk/content/DotNet/DotNet-ComServerGuide.htm
I have tried to use Microstation SDK, but with a Microstation PowerDraft Connect Edition I can't run it, isn't it?
[quote user="Karthik M"]I need to project the points to the Non co-planar shape surface[/quote]
Another approach is to triangulate your surface (facetise the surface as triangles). A triangular facet must be planar, and so it is easy to project a point to the surface of a triangle. Depending on the nature of your surface, it may be easy to triangulate.
Dear all,
I am using Microstation v8i(ss3) with VBA. I have points inside the Non co-planar shape, the points are zero elevation i need to project the points to the Non co-planar shape surface.here i attached my dgn and clearly explain it.
Regards,
Karthik M
[View:/cfs-file/__key/communityserver-discussions-components-files/343173/0407.Testing.dgn:940:0]
[quote user="Jairo Martínez Fernández"]I have tried to use MicroStation SDK, but with MicroStation PowerDraft I can't run it, isn't it?[/quote]
The MicroStation SDK is available and works only with a MicroStation installation. The native-code (DLL) application you create with the SDK may work with PowerDraft, but there is a catch. The catch is that your DLL must be approved by Bentley Systems.
It's easiest to work with MicroStation VBA, because it's available and delivered with both MicroStation and PowerDraft.
I have C# code that works fine since Microstation V8 to Microstation V8i but in new versión Microstation PowerDraft Connect 10.00.00.52 or updated one, 10.02.00.39, not:
Point3d tipoDePlanoPoint = new Point3d(); tipoDePlanoPoint.X = 100; tipoDePlanoPoint.Y = 100; Matrix3d matrizIdentidad = Microstation.App.Matrix3dIdentity(); element = (Element) Microstation.App.CreateTextElement1(null, "PLANO PARCELA", ref tipoDePlanoPoint, ref matrizIdentidad);
...
After element creation, the get_Origing() values X, Y arent 100, 100, they take aleatory values near 100, 100. Why?
I had tried, unsuccesfully:
Here is the DGN containing the points.
(Please visit the site to view this file)
I have a method which takes these point elements and converts them to DPoint3d before passing it to:
Bentley.GeometryNET.ConvexHull.Calculate(points)
That is the extent of the code.
Hi,
[quote user="D C"]Disappointing that the API can't do everything that the UI can though.[/quote]
I agree in some situations it would be great to have full access to MicroStation user tools functionality, but such expectation is not how MicroStation API is designed in my opinion. API allows to access both design file structure and MicroStation general functionality (using CONNEC Edition structure naming it's DgnPlatform and MStnPlatform), but not to user tools build on top of available APIs.
Even simple tools like Place SmartLine or Match element are in fact quite complex code "mini applications" and to design and implement API for every such tool would probably require enormous work.
In my opinion more valuable can be to have a detail description how tools and using what math formulas are implemented, so they will be less black boxes and can be repeated using own code.
With regards,
Jan
Hello Maury,
I can reproduce your issue for this method and file a Defect as below:
Defect 590558:ConvexHull.Calculate method works wrong for duplicated points
With duplicate points:
[View:http://imgur.com/a/XAQI3:940:0]
Duplicates removed:
[View:http://imgur.com/a/SOI4q:940:0]
In Microstation 8.11.09.829 and c# in an AddIn
I tried the following code to generate a tooltip at a screen coordinate.
pushing from 0,0 to 1000,1000 by 100 increments, the tooltip always displays at the upper left corner of the primary screen.
void testDrive() { BIM.Point2d pG = new BIM.Point2d(); for (double x = 0; x < 1000; x += 100) { for (double y = 0; y < 1000; y += 100) { pG.X = x; pG.Y = y; ShowBaloon(pG); } } } void ShowBaloon(BIM.Point2d p) { string msg = "AAA" + Environment.NewLine; msg += "AAA" + Environment.NewLine; msg += "AAA" + Environment.NewLine; string title = "HOWDY"; mdlWindow_showBalloonTooltip( msg.ToCharArray(), 0, title.ToCharArray(), ref p, 0, 500, 0, 0, 0, 0 ); }
What am I doing wrong?
You need TextEDField array as well:
TextEDParam edParam={0}; TextEDField edFields[MAX_EDFIELDS]={0}; edParam.edField = edFields; edParam.numEDFields = 1; edFields[0].start = 1; edFields[0].len = 50; edFields[0].just = TXTJUST_CC;
You need one TextEDField per "Enter Data Field" in the string....
[quote user="John Schenk"]TextEDParam txtEdP;[/quote]
Your naming convention reveals that you are uncertain whether you are passing variables or pointers.
TextEDParam is a data structure, so declare a variable of that type like this...
TextEDParam dataFields; // Not a pointer
Here's its definition...
#include <mdl.h> typedef struct textEDParam { int numEDFields; TextEDField *edField; } TextEDParam;
What it's expecting is an array of TextEDFields and the size of that array. There is no API, so you just have to do things manually...
const int nFields = 3; // Or whatever TextEDField fields [nFields]; for (int i = 0; i != nFields; ++i) { // Initialise fields [i] fields [i].start = 0; fields [i].len = 6; fields [i].just = TXTJUST_XXX; } TextEDParam dataFields; dataFields.numEDFields = nFields; dataFields.edField = fields; // Array degenerates to pointer
Now call mdlText_create passing the address-of your variable...
mdlText_create(..., ..., ..., ..., ..., ..., ..., &dataFields);
Hello, I'm trying to alter existing text into datafields using the command below. If I leave textEdP as NULL, I can write underscores to the design file in the array dataString, but they are line strings and are un-editable. I cannot figure out how to configure textEdP properly to enable me to place a 40 char datafield. Based on the structure in the mdl.h edField is a pointer, but when I try to use (as shown below) it errors and says it can't dereference a non pointer.
the individual elements in the TextEDField structure are "byte" and there seems to be no documentation how to configure this for my purposes.
TextEDParam txtEdP;
textEdP.numEDFields = 1;
//textEdP->edField.just = 1;
//textEdP->edField.len = 50;
//textEdP->edField.start = 1;
mdlText_create(&mytext,NULL,dataString,&XYcoord,&mytextsize,NULL,&mytextparam,&textEdP); <-- how do I configure textEdP to place datafields???
mdlElement_rewrite(&mytext,NULL,elmaddr[jk]);
Thank You
John
Selecting multiple elements can be accomplished with WantAdditionalLocate...
You can set your tool up so that it will complete on an un-qualified data point once a minimum of 2 elements have been selected, but ctrl can be held to locate N additional elements.
What you would want to do, is in your post-locate filter, only accept an element with a data field when the tool's agenda is currently empty (so the first entry in your tool's agenda will be the data field to fill in).
Now, only select text elements that you want to use to fill your data field (don't allow the data field to be selected again). The default tool behavior when selecting an already accepted element with ctrl held is to remove it from the tool agenda.
I cobbled together the snippet below, it should get you started if you want to take this approach. NOTE: This should work fine if you also enable drag select, just be aware that since your post-locate filter isn't called in this case, you'll need to validate the elements that get selected by crossing line or box selection using FilterAgendaEntries.
HTH
-B
/*=================================================================================**//** * Contrived example tool to demonstrate using WantAdditionalLocate. * Tool completes when a minimum of 2 elements are selected. if the control key is * down, then additional elements can be identified. * * @bsiclass +===============+===============+===============+===============+===============+======*/ struct ExampleTool : MstnElementSetTool { public: /*---------------------------------------------------------------------------------**//** * @bsimethod +---------------+---------------+---------------+---------------+---------------+------*/ void ExampleTool::SetupForLocate (int count) { __super::SetLocateCursor (count < 2 ? true : false, -1); UInt32 msgId = PROMPT_ExampleToolComplete; switch (count) { case 0: msgId = PROMPT_ExampleToolFirst; break; case 1: msgId = PROMPT_ExampleToolNext; break; } mdlOutput_rscPrintf (MSG_PROMPT, NULL, STRINGLISTID_Prompts, msgId); } /*---------------------------------------------------------------------------------**//** * @bsimethod +---------------+---------------+---------------+---------------+---------------+------*/ virtual void ExampleTool::SetupAndPromptForNextAction () override {SetupForLocate (GetElemAgendaP ()->GetCount ());} // All changes to auto-locate/accusnap state and user prompts are done here!!! /*---------------------------------------------------------------------------------**//** * @bsimethod +---------------+---------------+---------------+---------------+---------------+------*/ virtual UsesSelection ExampleTool::AllowSelection () override {return USES_SS_None;} // In this example don't support selection sets...(or fences MstnElementSetTool default) virtual bool ExampleTool::DoGroups () override () ooverride {return false;} // For this example don't include graphic/named group members for located element... virtual bool ExampleTool::WantDynamics () override {return false;} // Don't start dynamics... virtual bool ExampleTool::NeedAcceptPoint () override {return true;} // Accept point is required for multi-locate to give the user a chance to identity additional elements... /*---------------------------------------------------------------------------------**//** * @bsimethod +---------------+---------------+---------------+---------------+---------------+------*/ virtual bool ExampleTool::WantAdditionalLocate (MstnButtonEventCP ev) override { if (NULL == ev) return true; // This is a multi-locate tool... // Require a minumum of 2 elements, if control is down select additional elements... return (GetElemAgendaP ()->GetCount () < 2 || ev->IsControlKey ()); } /*---------------------------------------------------------------------------------**//** * @bsimethod +---------------+---------------+---------------+---------------+---------------+------*/ virtual bool ExampleTool::OnModifierKeyTransition (bool wentDown, int key) override { // Control key state change, may need to enable/disable auto-locate, change cursor, prompts. etc. if (TOGGLESELECT_MODKEY != key) return false; if (GetElemAgendaP ()->GetCount () < 2) return false; SetupForLocate (wentDown ? 1 : 2); return true; }
Hi,
I had a few minutes, so I checked how Point2d is defined in MDL API and as I expected it's very different from Interop Point2d:
MDL Point2d is defined as:
struct _point2d { Int32 x; Int32 y; };
while Interop Point2d is defined as
public struct Point2d { public double X; public double Y; }
so they are completely different structures and passing pointer to the different one cannot work.
In fact the structure is described as a part of VBA Wrapper Declaration in MDL help file, so it's already described it's integer (long) not double.
In my opinion the solution is to define own structure with Int32 types and to pass the reference to MDL function.
With regards,
Jan