【VM服务管家】VM4.2平台SDK_6.4 结果获取类

2.4.1 数据结果:通过流程输出或者模块输出获取数据结果的方法

描述
环境:VM4.2 + VS2013及以上
现象:方案或流程运行执行之后,就可以获取结果(建议将结果获取写在回调函数里),可以通过流程或者模块的输出获取渲染结果和数据结果,推荐使用流程的输出,符合高内聚低耦合,渲染结果通过绑定渲染控件进行显示,数据结果分为整型、浮点型、字符串型和图像型等等,VM二次开发如何获取数据结果?
解答
数据结果的获取可以通过流程的输出或者模块的输出,推荐使用通过流程的输出,符合高内聚低耦合的思想,VM4.2二次开发相比较VM4.0二次开发获取数据结果有一些更新,详细介绍如下所示:
1 通过流程的输出获取数据结果
1.1 流程配置-输出设置
在这里插入图片描述

1.2 获取整型、浮点型、字符串型数据

C#
VmProcedure vmprocess = (VmProcedure)VmSolution.Instance["流程1"];
var moduResult = vmprocess.ModuResult;
string str = moduResult.GetOutputInt(“out”).pIntVal[0].ToString();                
string str1 = moduResult.GetOutputFloat(“out0”).pFloatVal[0].ToString();
string str2 = moduResult.GetOutputString("out1").astStringVal[0].strValue;
//获取流程结果列表,str3与str2结果一致
List<VmDynamicIODefine.IoNameInfo> ioNameInfos = VmProcess.ModuResult.GetAllOutputNameInfo();
string str3 = VmProcess.ModuResult.GetOutputString(ioNameInfos[2].Name).astStringVal[0].strValue;

1.3 获取图像数据
流程输出设置中输出IMAGE类型的图像数据,能通过前面参数名称ImageD直接获取。

C#
ImageBaseData_V2 processImageData = VmProcess1.ModuResult.GetOutputImageV2("ImageD");
int width = processImageData.Width;//宽
int height = processImageData.Height;//高
IntPtr imageByte = processImageData.ImageData;//数据
VMPixelFormat pixelformat = processImageData.Pixelformat;//格式

2 通过模块的输出获取数据结果 (与4.0二次开发相比无变化)
2.1 获取模块的浮点型数据

C#
IMVSCircleFindModuTool tool = (IMVSCircleFindModuTool)VmSolution.Instance["流程1.圆查找1"];
var moduResult = tool.ModuResult;
string circleX = moduResult.OutputCircle.CenterPoint.X.ToString();
string circleY = moduResult.OutputCircle.CenterPoint.Y.ToString();
string circleR = moduResult.OutputCircle.Radius.ToString();

2.2 获取图像数据,针对有图像输出的模块,例如,输出图像模块,注意像素格式17301505为MONO8灰度图,像素格式 35127316为RGB24彩色图。

C#
SaveImageTool saveImage=(SaveImageTool)VmSolution.Instance[“流程1.输出图像1”];
Var saveImageResult=saveIamge.ModuResult.OutputImage;
byte[] imageData= saveImageResult.ImageData;
int imagePixelformat= saveImageResult.Pixelformat;

问题根因
不熟悉如何获取数据结果。

2.4.2 流程回调:某个流程运行开始与结束的回调方法

描述
环境:VM4.2 + VS2013及以上
现象:除了所有流程运行结束的回调方法,如何注册某一流程开始与结束回调函数。
解答
1、C#中调用某个流程的开始与结束回调
加载sol文件后,根据流程名称注册流程开始和结束回调函数代码如下,其中textBoxProcessName.Text为流程名。

c#
try  
{  
    m_VmPrc = (VmProcedure)VmSolution.Instance[textBoxProcessName.Text];  
    if (null == m_VmPrc)  
    {  
        MessageBoxButtons msgType = MessageBoxButtons.OK;  
        DialogResult diagMsg = MessageBox.Show(textBoxProcessName.Text + " name procedure does't exist", "Prompt", msgType);  
        if (diagMsg == DialogResult.OK)  
        {  
            return;  
        }  
    }  
    m_VmPrc.OnWorkBeginStatusCallBack += M_VmPrc_OnWorkBeginStatusCallBack;  
    m_VmPrc.OnWorkEndStatusCallBack += M_VmPrc_OnWorkEndStatusCallBack;  
}  
catch (VmException ex)  
{  
    string strMsg = "Process failed. Error Code: " + Convert.ToString(ex.errorCode, 16);  
    listBoxMsg.Items.Add(strMsg);  
    listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;  
    return;  
}  

注消流程开始和结束回调函数代码如下。

try  
{  
    m_VmPrc = (VmProcedure)VmSolution.Instance[textBoxProcessName.Text];  
    if (null == m_VmPrc)  
    {  
        MessageBoxButtons msgType = MessageBoxButtons.OK;  
        DialogResult diagMsg = MessageBox.Show(textBoxProcessName.Text + " name procedure does't exist", "Prompt", msgType);  
        if (diagMsg == DialogResult.OK)  
        {  
            return;  
        }  
    }  
   m_VmPrc.OnWorkBeginStatusCallBack -= M_VmPrc_OnWorkBeginStatusCallBack;  
   m_VmPrc.OnWorkEndStatusCallBack -= M_VmPrc_OnWorkEndStatusCallBack;  
}  
catch (VmException ex)  
{  
    string strMsg = "Process failed. Error Code: " + Convert.ToString(ex.errorCode, 16);  
    listBoxMsg.Items.Add(strMsg);  
    listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;  
    return;  
} 

测试用回调函数如下。

private void M_VmPrc_OnWorkBeginStatusCallBack(object sender, EventArgs e)  
{  
    Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} 流程开始");  
    //获取此流程中的模块结果
} 
private void M_VmPrc_OnWorkEndStatusCallBack(object sender, EventArgs e)  
{  
    Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} 流程结束");  
}

单次运行流程 m_VmPrc.Run(),执行效果如下,说明首先执行的是M_VmPrc_OnWorkBeginStatusCallBack函数,然后执行的是M_VmPrc_OnWorkEndStatusCallBack函数;
2、C++ 中调用某个流程的开始与结束回调
注册回调,只需要创建一个流程事件类,这个流程事件类继承IVmProcedureEvent,代码如下所示:

class MyProcedureEvent :public  IVmProcedureEvent
{
public:
	virtual void  OnWorkBeginStatusCallBack(IN const IMVS_PF_MODULE_WORK_STAUS *const pstWorkStatus, IN void *const pUser) override;
	virtual void  OnWorkEndStatusCallBack(IN const IMVS_PF_MODULE_WORK_STAUS *const pstWorkStatus, IN void *const pUser) override;

};

然后用户程序在主窗口类中,创建一个MyProcedureEvent实例,如下:

MyProcedureEvent myProcedureEvent;
例如:我们要注册流程1的结果回调,只需要在流程1加载完成的地方插入代码,调用注册回调的接口,典型的代码如下:

IVmSolution* vmSolution = LoadSolution(solPath, "");
IVmProcedure* vmProcedure = (IVmProcedure*)((*vmSolution)["流程1"]);
vmProcedure->RegisterCallBackEvent((IVmProcedureEvent*)&myProcedureEvent,this);

剩下就是用户在MyProcedureEvent类中,实现OnWorkEndStatusCallBack方法即可,比如在OnWorkEndStatusCallBack中获取流程1的运行结果,代码如下:

vector matchX;
vector matchY;
vector matchR;

void MyProcedureEvent::OnWorkEndStatusCallBack(IN const IMVS_PF_MODULE_WORK_STAUS * const pstWorkStatus, IN void * const pUser)
{
	try
	{
		CMFCVM42DemoDlg* pDlg = (CMFCVM42DemoDlg*)pUser;
		ObjectList list = pDlg->m_pSolution->GetAllProcedureObjects();  //获取当前方案的所有流程
		IVmProcedure* procedure1 = (IVmProcedure*)(list.pObjects[0]);   //获取第一个流程
		//获取配置的matchX,matchY,matchR 输出
		FloatDataArray matchXArray = procedure1->GetResult()->GetOutputFloat("matchX");
		FloatDataArray matchYArray = procedure1->GetResult()->GetOutputFloat("matchY");
		FloatDataArray matchRArray = procedure1->GetResult()->GetOutputFloat("matchR");
		
		for (int i = 0; i < matchXArray.nValueNum; i++)
		{
			matchX.push_back(matchXArray.pFloatVal[i]);
			matchY.push_back(matchYArray.pFloatVal[i]);
			matchR.push_back(matchRArray.pFloatVal[i]);
		}
	}
	catch (CVmException ex)
	{
		throw CVmException(ex);
	}
}

问题根因
不熟悉流程相关回调函。

猜你喜欢

转载自blog.csdn.net/MVExpert/article/details/130413541