Bug caused BY the mdlState_startPrimitive function

Hello

We are a company that uses MICROSTATION software to deploy our own solution “Dkmètre” that we have developed with the C and MDL languages.

 

One of the functionalities that Dkmètre offers is “placing terrain points”.

The user selects this feature from a range of Dkmètre added at MICROSTATION, then, he places a point in the DGN. Later, a command box is automatically opened asking the user to enter the altitude of the point.

This feature works often properly, but when we change the current DGN file without closing Dkmètre (so, not reset variables used in Dkmètre) and we chose this feature in the new DGN file it does not work and it causes a bug.

Debugging Dkmètre code  shows that the bug is launched after executing the mdl function “mdlState_startPrimitive( DkmComposite_FirstPoint, DkmComposite_StartCommand, MesDKM_Place_Courbe_Composite, MesDKM_Entree_le_premier_point_de_la_courbe );”

 I note that the DkmComposite_FirstPoint function is the function called when the user chooses to place a new terrain point.

You find bellow the code source of the functions DkmComposite_FirstPoint and DkmComposite_StartCommand and the values of the constants MesDKM_Place_Courbe_Composite and MesDKM_Entree_le_premier_point_de_la_courbe  

#define MesDKM_Place_Courbe_Composite        1168 

#define MesDKM_Entree_le_premier_point_de_la_courbe       654 

DkmComposite_FirstPoint

void DkmComposite_FirstPoint( Dpoint3d * point, int view )
{
int status = 0;
/**/ST_ARTICLEMETRE articleMetre;/**/

paramEtudeP->recupererSymboDessin = FALSE;

if( glbP->composite.orientationObjets != 2 )
if( DkmComposite_saisieZ( glbP->composite.orientationObjets == 0 ? point : &glbP->composite.dernierPt, status, view ) == ERROR )
return;

if( glbP->composite.orientationObjets != 1 )
{
DkmComposite_forcePlanaire( point, view, TRUE, FALSE );
glbP->composite.dernierPt.x = point->x;
glbP->composite.dernierPt.y = point->y;
glbP->composite.dernierPt.z = 0.0;
glbP->composite.tg.x = glbP->composite.tg.y = 0.0;
glbP->composite.tg.z = 0.0;
}

	glbP->composite.commandeStarted = TRUE;

DkmComposite_enableOptions( NULL );

if( glbP->composite.objets )
{
if( glbP->composite.orientationObjets == 2 )
glbP->composite.orientationObjets = 1;
else
DkmComposite_StartCommand( );
}
else
DkmComposite_StartSegment( );
}

DkmComposite_StartCommand

void DkmComposite_StartCommand( void )
{
mdlOutput_message( DkmMessage( MesDKM_Entree_Le_point_suivant_de_la_courbe ) );

mdlState_startPrimitive( DkmComposite_FirstPoint, DkmComposite_StartCommand, MesDKM_Place_Courbe_Composite, 
MesDKM_Entree_le_premier_point_de_la_courbe );

mdlState_setFunction( STATE_COMPLEX_DYNAMICS, DkmComposite_Curseur );
mdlState_setFunction( STATE_COMMAND_CLEANUP, DkmComposite_CleanUpFunction );
mdlState_setFunction( STATE_RESET, DkmComposite_resetRestartCommand );

mdlSystem_setFunction( SYSTEM_SYMBOLOGY_CHANGE, __DkmComposite_SymbologyChanged__ );
mdlSystem_setFunction( SYSTEM_LEVEL_CHANGE, __DkmComposite_SymbologyChanged__ );

glbP->composite.dgnModelRef = MASTERFILE;
glbP->composite.commandeStarted = FALSE;
glbP->composite.orientationObjets = 0;
glbP->composite.angleObjet = 0.0;

DkmComposite_enableOptions( NULL );

mdlAccuSnap_enableSnap( TRUE );
mdlAccuSnap_enableLocate( TRUE );
}


the bug starts at the code written in red

 

  • You have installed a cleanup function for this, is this called properly ? I assume your application runs vis MS_DGNAPPS, have you installed a callback that informs you about the changing dgn file ?

    i.e. mdlSystem_setFunction (SYSTEM_NEW_DESIGN_FILE, mdl_changeDGNFile);

    with something like that

    Public void mdl_changeDGNFile(char *filename, int state)
    {
        int    i;
        // state SYSTEM_NEWFILE_CLOSE before old dgn is closed
        // state SYSTEM_NEWFILE_COMPLETE after new dgn is opened
        if (state == SYSTEM_NEWFILE_COMPLETE) {
            // tell the dialog(s) that the file has been changed
            dll_changeDGN();
            // reset the value for global access
            gCurrentModel = NULL;
        }
        if (state == SYSTEM_NEWFILE_CLOSE) {
            dll_callFunction(DLL_UNLOADDGN, (void*) filename);
        }
    }

    both the dll_... functions react here on the closing or finished loading of a new designfile. This is the place where you might reset your values. You even have to asure that your global elementDescrP is correctly freed when switching files. Otherwise you will produce memory leaks and/or unconditional behaviour (if mistakenly freed after the corresponding memory was freed. You even have to asure that your cleanup-function works correctly, it might still be installed if you haven't done something to avoid this, and might expect a situation that is (no longer) valid.

    HTH Michael



    Answer Verified By: cdiTech 

  • Unknown said:
    mdlSystem_setFunction( SYSTEM_SYMBOLOGY_CHANGE, __DkmComposite_SymbologyChanged__ );
    mdlSystem_setFunction( SYSTEM_LEVEL_CHANGE, __DkmComposite_SymbologyChanged__ );

    I would remove, at least temporarily, those functions.  They may interfere with MicroStation's primitive state engine.

     
    Regards, Jon Summers
    LA Solutions

  • Hello

    I find in the source code a function similar to the mdl_changeDGNFile function but it does not contains all the necessary code in order to free all the variables. I added the some code and it works fine :)

    thank you for your help.