转换Ansys日志文件命令流的小工具:AnsysCommandParser

下载AnsysCommandParser v0.1

 AnsysCommandParser是一个用于清理和转换Ansys日志文件(.log文件),以生成等价的Ansys命令流的小工具。

主要功能:

1.删除"/auto","/dist","/replot"之类因图形界面操作所产生的“无用指令”(对建模和计算本身无影响的指令);
目前程序中所删除的指令包括:
    "/dist",
    "/replot", "/rep", "/replo",
    "/focus", "/foc",
    "kplot", "lplot", "aplot", "gplot", "eplot",
    "/user",
    "/pnum",
    "/input",
    "/number", "/num",
    "/zoom",
    "chkmsh",
    "/auto"

2.将图形界面选择操作所产生的选择操作指令,如:
        FLST,5,8,4,ORDE,5  
        FITEM,5,3  
        FITEM,5,5  
        FITEM,5,-7 
        FITEM,5,46 
        FITEM,5,-49
        CM,_Y,LINE 
        LSEL, , , ,P51X
        CM,_Y1,LINE
        CMSEL,,_Y  
        !* 
        LESIZE,_Y1, , ,10, , , , ,1
转换为等价,但更加简洁、可读性更好、更适合手工输入的选择操作指令,如:
        lsel,s,line,,3
        lsel,a,line,,5,7
        lsel,a,line,,46,49
        lesize,all,,,10,,,,,1
目前程序所转换的选择操作包括:节点选择("nsel")、单元选择("esel")、 关键点选择("ksel")、线选择("lsel")、面选择("asel")

使用说明:

1.解压压缩包到任意目录;
2.启动AnsysCmdParser.exe;
3.将从Ansys日志文件(.log文件)复制出来的命令流记录复制到程序左侧的文本框中,然后点击“Parse”按钮;
4.复制右侧文本框中的生成的内容到你的目标位置(Ansys命令窗口,自己的命令流文件等等)。由于执行第3步后,生成的命令流已自动复制到剪贴板,所以***没有必要手动的进行复制操作***,直接粘贴到目标位置即可。
5.点击Clear按钮可清除两个文本框中的内容。

示例:


下面这段ANSYS日志文件中的命令流:

        EPLOT  
        ALLSEL,ALL 
        LPLOT  
        /AUTO,1
        /REP,FAST  
        /ZOOM,1,RECT,0.0599766,0.0983278 ,0.604427072832 ,0.0105351165784  
        FLST,2,2,4,ORDE,2  
        FITEM,2,57 
        FITEM,2,-58
        LCCAT,P51X 
        FLST,2,2,4,ORDE,2  
        FITEM,2,99 
        FITEM,2,107
        LCCAT,P51X 
        FLST,2,2,4,ORDE,2  
        FITEM,2,97 
        FITEM,2,105
        LCCAT,P51X 
        FLST,2,2,4,ORDE,2  
        FITEM,2,55 
        FITEM,2,-56
        LCCAT,P51X 
        FLST,5,8,5,ORDE,4  
        FITEM,5,31 
        FITEM,5,-36
        FITEM,5,44 
        FITEM,5,-45
        CM,_Y,AREA 
        ASEL, , , ,P51X
        CM,_Y1,AREA
        CHKMSH,'AREA'  
        CMSEL,S,_Y 
        !* 
        AMESH,_Y1  
        !* 
        CMDELE,_Y  
        CMDELE,_Y1 
        CMDELE,_Y2 
        !* 
        LPLOT  
        /DIST,1,1.08222638492,1
        /REP,FAST  
        /AUTO,1
        /REP,FAST  
        /ZOOM,1,RECT,-0.0313506,0.3301 ,0.681703919018 ,0.126421398941 
        FLST,5,8,4,ORDE,5  
        FITEM,5,3  
        FITEM,5,5  
        FITEM,5,-7 
        FITEM,5,46 
        FITEM,5,-49
        CM,_Y,LINE 
        LSEL, , , ,P51X
        CM,_Y1,LINE
        CMSEL,,_Y  
        !* 
        LESIZE,_Y1, , ,10, , , , ,1

经过转换后,得到:

        allsel,all
        lsel,s,line,,57,58
        lccat,all
        lsel,s,line,,99
        lsel,a,line,,107
        lccat,all
        lsel,s,line,,97
        lsel,a,line,,105
        lccat,all
        lsel,s,line,,55,56
        lccat,all
        asel,s,area,,31,36
        asel,a,area,,44,45
        amesh,all

        lsel,s,line,,3
        lsel,a,line,,5,7
        lsel,a,line,,46,49
        lesize,all,,,10,,,,,1

 

源代码(主体部分)

#pragma once
#include "stdafx.h"
#include "resource.h"

#include <atldataobj.h>		// CClipboard class by Bjarke Viksoe

#include <vector>
using std::vector;

#include <string>
using std::wstring;

#include <sstream>
using std::wistringstream;
using std::wostringstream;

#include <iostream>
#include <boost/algorithm/string.hpp>

#include <tuple>
using std::tuple;
using std::make_tuple;

#include <array>
using std::array;

const wchar_t COMMA = L',';
const wstring LINEEND = L"\r\n";

array<wstring,5> SelCmdNames = { 
	L"nsel", L"esel", L"ksel", L"lsel", L"asel" 
};

array<wstring,5> SelItems = { 
	L"node", L"elem", L"kp", L"line", L"area" 
};

array<wstring,20> IgnoredCmds = {
	L"/dist",
	L"/replot", L"/rep", L"/replo", 
	L"/focus", L"/foc",
	L"kplot", L"lplot", L"aplot", L"gplot", L"eplot",
	L"/user",
	//L"/com",
	L"/pnum",
	L"/input",
	L"/number", L"/num",
	L"/zoom",
	L"chkmsh",
	L"/auto"
};

bool IsStrStartWith(const wstring& str, const wstring& start)
{
	return str.substr(0,start.size())==start;
}

template< typename T >
bool StrToNum(const std::wstring& str, T& num)
{
	std::wistringstream iss(str);
	return !(iss>>num).fail();
}

const COLORREF EDIT_BKGND_COLOR = RGB(204,232,207);

class CMainDialog :
	public CDialogImpl<CMainDialog>,
	public CMessageFilter,
	public CWinDataExchange<CMainDialog>,
	public CDialogResize<CMainDialog>
{
public:
	enum { IDD = IDD_MAIN };

	typedef CMainDialog _thisClass;
	typedef CDialogResize<_thisClass> _baseDlgResize;
	BEGIN_MSG_MAP(_thisClass)
		MSG_WM_CTLCOLOREDIT(OnCtlColorEdit)
		COMMAND_HANDLER_EX(IDC_BUTTON_PARSE, BN_CLICKED, OnBnClickedParse)
		COMMAND_HANDLER_EX(IDC_BUTTON_CLEAR, BN_CLICKED, OnBnClickedClear)
		COMMAND_ID_HANDLER_EX(IDCANCEL,OnCancel)
		MSG_WM_INITDIALOG(OnInitDialog)
		MSG_WM_DESTROY(OnDestroy)
		CHAIN_MSG_MAP(_baseDlgResize)
	END_MSG_MAP()

	BEGIN_DDX_MAP(_thisClass)
		DDX_CONTROL_HANDLE(IDC_EDIT_INPUT,	m_EditInput)
		DDX_CONTROL_HANDLE(IDC_EDIT_OUTPUT, m_EditOutput)
	END_DDX_MAP()

	BEGIN_DLGRESIZE_MAP(_thisClass)
		DLGRESIZE_CONTROL(IDC_BUTTON_PARSE,	DLSZ_MOVE_X|DLSZ_MOVE_Y)
		DLGRESIZE_CONTROL(IDC_BUTTON_CLEAR,	DLSZ_MOVE_X|DLSZ_MOVE_Y)
		BEGIN_DLGRESIZE_GROUP()
			DLGRESIZE_CONTROL(IDC_EDIT_INPUT,	DLSZ_SIZE_X)
			DLGRESIZE_CONTROL(IDC_EDIT_OUTPUT,	DLSZ_SIZE_X)			
		END_DLGRESIZE_GROUP()
		DLGRESIZE_CONTROL(IDC_EDIT_INPUT,	DLSZ_SIZE_Y)
		DLGRESIZE_CONTROL(IDC_EDIT_OUTPUT,	DLSZ_SIZE_Y)	
	END_DLGRESIZE_MAP()

public:
	virtual BOOL PreTranslateMessage(MSG* pMsg)
	{
		return CWindow::IsDialogMessage(pMsg);
	}

public:
	BOOL OnInitDialog(CWindow /*wndFocus*/, LPARAM /*lInitParam*/)
	{
		// Initialize dialog resize
		DlgResize_Init();

		// Bind controls to variables
		DoDataExchange(FALSE);

		InitIgnoredCmdList();
		InitControls();

		ResizeClient(800,600);
		CenterWindow();

		return TRUE;
	}

	void InitControls() 
	{
		CLogFont lf;
		TCHAR fontName[] = _T("Courier New");
		SecureHelper::strcpy_x(lf.lfFaceName,32,fontName);
		lf.lfHeight = 18;
		m_FontEdit.CreateFontIndirect(&lf);

		m_EditInput.SetFont(m_FontEdit);
		m_EditInput.SetLimitText(0);
		m_EditOutput.SetFont(m_FontEdit);
		m_EditOutput.SetLimitText(0);

		m_BrushEdit.CreateSolidBrush(EDIT_BKGND_COLOR);
		ATL_CHECK_HANDLE(m_BrushEdit);
	}

	void InitIgnoredCmdList()
	{
		for (auto it=SelCmdNames.cbegin();it!=SelCmdNames.cend();it++)
		{
			m_vecIgnoredSelCmd.push_back(make_tuple( *it, 3, L"p51x" ));
		}
		m_vecIgnoredSelCmd.push_back(make_tuple( L"cm",	    0, L"_y" ));
		m_vecIgnoredSelCmd.push_back(make_tuple( L"cmsel",  1, L"_y" ));
		m_vecIgnoredSelCmd.push_back(make_tuple( L"cmdele", 0, L"_y" ));
	}

	void OnDestroy() { }

	void OnBnClickedParse(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wndCtl*/)
	{
		Parse();
	}

	void OnBnClickedClear(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wndCtl*/)
	{
		m_EditInput.SetWindowText(_T(""));
		m_EditOutput.SetWindowText(_T(""));
	}

	void OnCancel(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wndCtl*/)
	{
		DestroyWindow();
		PostQuitMessage(0);
	}

	HBRUSH OnCtlColorEdit(CDCHandle dc, CEdit edit)
	{
		dc.SetBkColor(EDIT_BKGND_COLOR);
		return m_BrushEdit;
	}

private:
	enum AnsysSelType
	{
		UnknownType = 0,
		NodeNumber = 1,
		ElementNumber,
		KeypointNumber,
		LineNumber,
		AreaNumber
	};

	enum AnsysCmdType
	{
		OrdinaryCmd,
		FLST,
		FITEM,
		IgnoredCmd,
		IgnoredSelCmd,
		DeleLccaCmd,
		Comment,
		BlankLine
	};

	void Parse() 
	{
		ATL::CString text;
		m_EditInput.GetWindowText(text);
		wstring inputStr = text;
		ParseAnsysCmd(inputStr);
	}

	void ParseAnsysCmd(const wstring& inputStr)
	{
		ATLASSERT(inputStr.size()>0);
		wostringstream oss;

		AnsysSelType selType = UnknownType;
		AnsysCmdType lastCmdType = OrdinaryCmd;
		AnsysCmdType thisCmdType = OrdinaryCmd;

		wistringstream iss(inputStr);
		wstring cmdLine;
		while (std::getline(iss,cmdLine))
		{
			wstring cmdName;
			vector<wstring> args;

			boost::trim(cmdLine);
			if (cmdLine.empty())	// blank line
			{
				thisCmdType = BlankLine;
			}
			else if (cmdLine[0]==L'!')	// comments
			{
				thisCmdType = Comment;
			}
			else
			{
				boost::to_lower(cmdLine);
				GetCmdName(cmdLine,cmdName);
				if (IsIgnoredCmd(cmdName))
				{
					ATLASSERT(lastCmdType!=FLST);
					thisCmdType = IgnoredCmd;
				}
				else
				{
					GetCmdArgs(cmdLine,args);
					if (IsIgnoredSelCmd(cmdName,args))	// ignored select command
					{
						ATLASSERT(lastCmdType!=FLST);
						thisCmdType = IgnoredSelCmd;
					}
					else if (cmdName == L"flst")		// "FLST" command
					{
						ATLASSERT(lastCmdType!=FLST);
						thisCmdType = FLST;

						int num = 0;
						bool res = StrToNum(args[2],num);
						ATLASSERT(res && 1<=num && num<=5);
						selType = (AnsysSelType)num;
					}
					else if (cmdName == L"fitem")		// "FITEM" command
					{
						ATLASSERT((lastCmdType==FLST) || (lastCmdType==FITEM));
						thisCmdType = FITEM;

						int selNum = 0;
						bool res = StrToNum(args[1],selNum);
						ATLASSERT(res && selNum!=0);
						if (selNum > 0)
						{
							const wstring&  cmd = SelCmdNames[selType-1];
							wstring        type = (lastCmdType==FLST)? L"s":L"a";
							const wstring& item = SelItems[selType-1];

							oss	<<LINEEND
								<<cmd<<COMMA<<type<<COMMA<<item<<COMMA<<COMMA<<selNum;
						}
						else	// if selNum < 0
						{
							oss<<COMMA<<(-selNum);
						}
					}
					else if (cmdName == L"*set" && IsStrStartWith(args[1],L"lsinqr"))
					{
						ATLASSERT(lastCmdType!=FLST);
						thisCmdType = DeleLccaCmd;

						const int JUMP_LINES = 13;
						for (int i=0;i<JUMP_LINES;++i)
							std::getline(iss,cmdLine);

						oss <<LINEEND<<LINEEND
							<<L"lsel,s,lcca"<<LINEEND
							<<L"ldele,all"<<LINEEND;
					}
					else		// other ordinary command
					{
						ATLASSERT(lastCmdType!=FLST);
						thisCmdType = OrdinaryCmd;

						oss<<LINEEND<<cmdName;
						// replace "p51x" and "_yN" label with "all", 
						// then output all args
						std::for_each(args.begin(),args.end(),[&oss](wstring& arg){
							if (IsStrStartWith(arg,L"p51x")||IsStrStartWith(arg,L"_y")){
								arg = L"all";
							}
							oss<<COMMA<<arg;
						});
					}
				}
				lastCmdType = thisCmdType;
				continue;	// we have output this command here, 
							// then we need to process the next one directly
			}

			ATLASSERT(thisCmdType==BlankLine || thisCmdType==Comment);
			if (lastCmdType==FITEM || lastCmdType==OrdinaryCmd)
			{
				oss<<LINEEND;
			}
			lastCmdType = thisCmdType;
		}

		m_EditOutput.SetWindowText(oss.str().c_str());

		CClipboard clipBoard(NULL);
		ATLASSERT(clipBoard.IsOpen());
		clipBoard.Empty();
		clipBoard.SetUnicodeTextData(oss.str().c_str());
	}

	bool IsSelCmd(const wstring& cmdName)
	{
		return std::any_of(SelCmdNames.cbegin(),SelCmdNames.cend(),
			[&cmdName](const wstring& name)
		{
			return cmdName==name;
		});
	}

	bool IsIgnoredCmd(const wstring& cmdName)
	{
		return std::any_of(IgnoredCmds.cbegin(),IgnoredCmds.cend(),
			[&cmdName](const wstring& name)
		{
			return cmdName==name;
		});
	}

	bool IsIgnoredSelCmd(const wstring& cmdName, const vector<wstring>& args)
	{
		return std::any_of(m_vecIgnoredSelCmd.cbegin(),m_vecIgnoredSelCmd.cend(),
			[&cmdName,&args](const tuple<wstring,int,wstring>& t)->bool
		{
			const wstring& name = std::get<0>(t);
			int i = std::get<1>(t);
			const wstring& arg = std::get<2>(t);
			return (cmdName==name) && (args.size()>i) && IsStrStartWith(args[i],arg);
		});
	}

	void GetCmdName(const wstring& cmdLine, wstring& cmdName)
	{
		ATLASSERT(!cmdLine.empty() && cmdName.empty());

		std::wistringstream iss(cmdLine);
		std::getline(iss,cmdName,COMMA);
		boost::trim(cmdName);
		ATLASSERT(!cmdName.empty());
	}

	void GetCmdArgs(const wstring& cmdLine, vector<wstring>& args)
	{
		ATLASSERT(!cmdLine.empty() && args.empty());

		std::wistringstream iss(cmdLine);
		wstring cmdName;
		std::getline(iss,cmdName,COMMA);
		
		wstring arg;
		while (std::getline(iss,arg,COMMA))
		{
			boost::trim(arg);
			args.push_back(arg);
		}
	}

private:
	CFont m_FontEdit;
	CEdit m_EditInput;
	CEdit m_EditOutput;

	CBrush m_BrushEdit;

	vector<tuple<wstring,int,wstring>> m_vecIgnoredSelCmd;
};

posted on 2011-05-06 23:38  wudong  阅读(7898)  评论(8编辑  收藏  举报

导航