Back to MDL blog again.. Today we will do a simple program which will explain you a number of things in MDL programming in a simplified manner.
We will place a line string through a MDL program. Remember that this code is only applicable to the older version (Microstation/J – version 7).
In this program, I am showing how to
1. Show a prompt to the user
2. How to initiate a function on a data click
3. How to initiate a function on the right-click (Reset)
3. How to show a rubber band effect
4. How to generate a linestring in the end
The code is simple and self-explanatory but I will still add some description for you to understand.
In the program a prompt will ask use to give a point, when user gives a point in the view, an array of points will be populated and a counter of the number of vertices will be maintained. When user gives a right-click, the linestring placement will complete and a linestring will be generated. The user will be also see the rubber band dynamic display of the linestring as he gives point.
//include files
#include <mdl.h>
#include <tcb.h>
#include <mselems.h>
#include <userfnc.h>
//variable to create the linestring
MSElementUnion oElm;
//maximum 101 vertices – This is an array of coordinates
Dpoint3d lsPoints[MAX_VERTICES];
//number of vertices for the dynamic display of the linestring
int ntmpcount = 0;
//number of vertices to create a final linestring
int nvertexCount = 0;
//function definitions – if not added then it will not compile
void LS_NextPoint(Dpoint3d *point,int numView);
void LS_Complete(Dpoint3d *point,int numView);
//Dynamic display function, it is passed a cursor coordinate as the //cursor moves in the map
//dgnBuf is used for the dynamic display
//If this function is not defined then user will be able to give a point //in the map as usual but will not see how his linestring is appearing //in the map at the runtime.
int LineStringDynamics(Dpoint3d *ptP,int view)
{
ntmpcount = nvertexCount;
lsPoints[ntmpcount].x = ptP->x;
lsPoints[ntmpcount].y = ptP->y;
mdlLineString_create(dgnBuf, NULL, lsPoints, (ntmpcount+1));
return (SUCCESS);
}
//This is function receives a point on a data click, point array is //populated and vertex counter is incremented. The function calls itself // on a dataclick, it also sets a dynamic display function and complete //function on a right-click
void LS_NextPoint(Dpoint3d *point,int numView)
{
lsPoints[nvertexCount].x=point->x;
lsPoints[nvertexCount].y=point->y;
nvertexCount = nvertexCount+1;
mdlOutput_prompt(“Give the next point”);
mdlState_setFunction (STATE_DATAPOINT,LS_NextPoint);
mdlState_dynamicUpdate (LineStringDynamics, FALSE);
mdlState_setFunction (STATE_RESET,LS_Complete);
}
//When user gives a right-click the complete function is called, line //string is created, added to the file displayed normally, dialog box //shows a message to the user about the completion of the command and a //default command call is made. The Exit function call is made in the //end
void LS_Complete(Dpoint3d *point,int numView)
{
if(nvertexCount<2)
{
mdlOutput_prompt(“Give next point”);
mdlState_setFunction (STATE_DATAPOINT,LS_NextPoint);
}
else
{
mdlLineString_create(&oElm, NULL, lsPoints, nvertexCount);
mdlElement_add (&oElm);
mdlElement_display (&oElm, NORMALDRAW);
mdlOutput_prompt(“”);
mdlDialog_openInfoBox(“Placement is complete”);
mdlState_startDefaultCommand ();
mdlSystem_exit(NULL,1);
}
}
//program entry point – the function prompts user to give a first point
//A function call on a data click is set
int main(int argc, char *argv[])
{
mdlOutput_prompt(“Give the first point”);
mdlState_setFunction (STATE_DATAPOINT,LS_NextPoint);
return 0;
}
As you see the code above can be saved as a whole (with comments) in a file placeline.mc and compile as explained in the blog – Hello World MDL
Open a dgn file and execute the command as
mdl l \placeline
See the dynamic display below:
The linestring placement is complete.
I will add more blogs on MDL, any comments or questions are welcome! Thank you!