I'm trying to use an example MstnElementSetTool posted by Brien Bastings that demonstrated the use of a IElementState derived class to hold additional info on the "picked" elements. In the original example, the element's HitPath was saved along with the picked element and retrieved later to extracted that selection point for creation of a line/lineString. I'm attempting to extend that example slightly by calculating a line's direction vector as it is picked and saving it. In trying to determine if I've got things correct, I always crash MicroStation.
// IElementState: Interface implemented to hold additional information about an element held by an ElemHandle
struct ExampleLocateInfo : RefCounted <IElementState>
{
private:
HitPathCP m_hitPath;
DVec3dCP m_dirVecCP; // the normalized direction vector for the element
public:
ExampleLocateInfo::ExampleLocateInfo () {m_hitPath = NULL; m_dirVecCP=NULL; }
ExampleLocateInfo::~ExampleLocateInfo () {mdlDisplayPath_release ((DisplayPathP) m_hitPath);}
void SetHitPathCP (HitPathCP hitPath)
{
mdlDisplayPath_release ((DisplayPathP) m_hitPath);
m_hitPath=hitPath;
mdlDisplayPath_addRef ((DisplayPathP) m_hitPath)
}
HitPathCP GetHitPathCP () { return m_hitPath; } void SetDirectionVectorCP ( DVec3dCP pDirVecCP )
{
m_dirVecCP=pDirVecCP;
printf("Set A(ptr): %x: %f %f %f\n",m_dirVecCP, m_dirVecCP->x, m_dirVecCP->y, m_dirVecCP->z);
} DVec3dCP GetDirectionVectorCP ()
{
printf("returning (%x) %f %f %f\n",m_dirVecCP,m_dirVecCP->x, m_dirVecCP->y, m_dirVecCP->z);
return m_dirVecCP;
}
}; // ExampleLocateInfo
I see when SetDirectionVectorCP( &dirVec ) is called that the values printed (x,y,z) in the function are as expected. However, later when I want to use them (by obtaining another reference to the element's IElementState that the value are no longer correct before they are passed back to the MStnElementSetTool. The values printed in GetDirectionVectorCP() do not match those seen in SetDirectionVectorCP().
Here the locateInfo is created (in BuildLocateAgenda() )
EditElemHandleP elHandle = __super::BuildLocateAgenda (path, ev);
if (elHandle)
{
// The ExampleLocateInfo derives from IElementState, so it can be "attached" to the element
ExampleLocateInfo* locateInfo = new ExampleLocateInfo; // RefCounted
locateInfo->SetHitPathCP (path);
elHandle->SetIElementState (locateInfo); // Save the elem's "path" info with the elem
}
In SetupForModify(), the value is stored:
ExampleLocateInfo* info1 = dynamic_cast <ExampleLocateInfo*> ( eeHfirstP->GetIElementState () );
info1->SetDirectionVectorCP( &diff );
And in OnElementModify() I'm trying to "use" it:
ExampleLocateInfo* info = dynamic_cast <ExampleLocateInfo*> ( elHandle.GetIElementState () );
if ( info )
{
DVec3dCP pDirectionVec=info->GetDirectionVectorCP();
if ( pDirectionVec )
printf("A(ptr) pDirectionVec: %f %f %f\n", pDirectionVec->x, pDirectionVec->y, pDirectionVec->z);
}
But as I said, the values are not as expected, and I also get a crash.Could the multiple "references" to it the cause of the problem? Here's an example of some of the output:
Set A(ptr): 28f168: 0.000000 1.000000 0.000000
Set dirVec on eeHfirstP, ID=4052
TwoPickTool::OnElementModify
Get ExampleLocateInfo on elemID=4052
info=13009368
returning (28f168) 0.000000 0.000000 20399936589743884000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000.000000
A(ptr) pDirectionVec: 0.000000 0.000000 0.000000
There seems to be a memory problem with GetDirectionVectorCP() as evidenced by the "funky" value printed for "z".
Bruce