?? dlgbuildtin.cpp
字號(hào):
// DlgBuildTIN.cpp : implementation file
//
#include "stdafx.h"
#include "TinApp.h"
#include "TinFrm.h"
#include "DlgBuildTIN.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDlgBuildTIN dialog
typedef struct tagTIN_WORKER {
TCS_S32 *stop; // 停止標(biāo)志
TCS_V00 *thrd; // 線程句柄
TCS_V00 *nven[2]; // 工作事件
TCS_F64 *P;
TIN_R *R;
} TIN_WORKER;
typedef struct tagTIN_MASTER {
TCS_S32 *stop; // 停止標(biāo)志
TCS_V00 *thrd; // 線程句柄
TCS_S32 onnu; // 線程數(shù)目
TCS_V00 *onpa; // 線程參數(shù)
TCS_F64 *P;
TCS_S32 N;
TIN_R **R;
} TIN_MASTER;
CDlgBuildTIN::CDlgBuildTIN(CWnd* pParent /*=NULL*/)
: CDialog(CDlgBuildTIN::IDD, pParent)
{
m_pts = 0;
m_num = 0;
m_dim = 0;
m_TT = 0;
m_TN = 0;
// 分配線程參數(shù)
m_onnu = 2;
TIN_WORKER *onpa = new TIN_WORKER[m_onnu];
for (long i = 0; i < m_onnu; i++)
{
onpa[i].nven[0] = ::CreateEvent(0, 0, 0, 0);
onpa[i].nven[1] = ::CreateEvent(0, 0, 1, 0);
onpa[i].stop = &m_stop;
onpa[i].thrd = 0;
onpa[i].R = 0;
}
m_onpa = onpa;
TIN_MASTER *mapa = new TIN_MASTER;
mapa->stop = &m_stop;
mapa->onnu = m_onnu;
mapa->onpa = onpa;
mapa->thrd = 0;
m_mapa = mapa;
//{{AFX_DATA_INIT(CDlgBuildTIN)
m_dtm = _T("");
m_dup = 0.01f;
//}}AFX_DATA_INIT
}
CDlgBuildTIN::~CDlgBuildTIN()
{
m_stop = 1;
TIN_MASTER *mapa = (TIN_MASTER*)m_mapa;
// 等待線程結(jié)束
::WaitForSingleObject(mapa->thrd, INFINITE);
// 釋放資源
TIN_WORKER *onpa = (TIN_WORKER*)m_onpa;
for (long i = 0; i < mapa->onnu; i++)
{
::CloseHandle(onpa[i].nven[0]);
::CloseHandle(onpa[i].nven[1]);
}
delete []onpa; delete mapa;
}
void CDlgBuildTIN::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDlgBuildTIN)
DDX_Control(pDX, IDC_PROGRESS, m_progress);
DDX_Text(pDX, IDC_TIME_STATIC, m_dtm);
DDX_Text(pDX, IDC_DUP_EDIT, m_dup);
DDV_MinMaxFloat(pDX, m_dup, 0.f, 10.f);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDlgBuildTIN, CDialog)
//{{AFX_MSG_MAP(CDlgBuildTIN)
ON_BN_CLICKED(IDC_BUILD_BUTTON, OnBUILD)
ON_BN_CLICKED(IDC_STOPB_BUTTON, OnSTOPB)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgBuildTIN message handlers
// 工作線程
TCS_U32 WINAPI WorkerThread(LPVOID lpParam)
{
TIN_WORKER *wopa = (TIN_WORKER*)lpParam;
while (1)
{
::WaitForSingleObject(wopa->nven[0], INFINITE);
if (*(wopa->stop) == 1)
break;
if (wopa->R)
ConTen2(wopa->R, wopa->P, wopa->stop);
wopa->R = 0;
::SetEvent(wopa->nven[1]);
if (*(wopa->stop) == 1)
break;
}
::SetEvent(wopa->nven[1]);
wopa->thrd = 0;
wopa->R = 0;
return 0;
}
// 控制線程
TCS_U32 WINAPI MasterThread(LPVOID lpParam)
{
TIN_MASTER *mapa = (TIN_MASTER*)lpParam;
// 調(diào)度線程
TIN_WORKER *onpa = (TIN_WORKER*)mapa->onpa;
TCS_V00 **nven = new TCS_V00*[mapa->onnu];
for (long i = 0; i < mapa->onnu; i++)
nven[i] = onpa[i].nven[1];
TCS_F64 *P = mapa->P;
TCS_S32 N = mapa->N;
TIN_R **R = mapa->R;
for (long k = 0; k < N; k++)
{
// 等待線程空閑
TCS_U32 idx = ::WaitForMultipleObjects(mapa->onnu, nven, 0, INFINITE);
if (idx >= WAIT_OBJECT_0 && idx < WAIT_OBJECT_0 + mapa->onnu)
{
idx = idx - WAIT_OBJECT_0;
onpa[idx].P = P;
onpa[idx].R = R[k];
::SetEvent(onpa[idx].nven[0]);
}
// 如果中途終止
if (*(mapa->stop) == 1)
break;
}
// 釋放內(nèi)存資源
delete []nven;
// 等待本次任務(wù)完成
for (long i = 0; i < mapa->onnu; i++)
{
while (1)
{
if (onpa[i].R == 0 || onpa[i].thrd == 0)
break;
else
::Sleep(2);
}
}
// 結(jié)束工作線程
*(mapa->stop) = 1;
for (long i = 0; i < mapa->onnu; i++)
{
::SetEvent(onpa[i].nven[0]);
::WaitForSingleObject(onpa[i].thrd, INFINITE);
}
// 本線程結(jié)束
mapa->thrd = 0;
return 0;
}
void CDlgBuildTIN::Init(void *pts, long num, long dim, CTcsTan2 *Tan, TIN_T **TT, long *TN, TIN_R **TR, long *RN)
{
m_pts = pts;
m_num = num;
m_dim = dim;
m_oTan = Tan;
m_TT = TT;
m_TN = TN;
m_TR = TR;
m_RN = RN;
}
void CDlgBuildTIN::OnBUILD()
{
Gray(1);
m_nProc = 1;
Build();
m_nProc = 0;
Gray(0);
}
void CDlgBuildTIN::Gray(BOOL bGray)
{
GetDlgItem(IDC_DUP_EDIT)->EnableWindow(!bGray);
GetDlgItem(IDC_STOPB_BUTTON)->EnableWindow(bGray);
GetDlgItem(IDC_BUILD_BUTTON)->EnableWindow(!bGray);
/* CTinFrm* pFrm = (CTinFrm*)AfxGetMainWnd();
if (pFrm)
{
CMenu* pMenu = pFrm->GetMenu();
long cnt = pMenu->GetMenuItemCount();
for (long i = 0; i < cnt; i++)
{
if (!bGray)
::EnableMenuItem(pMenu->m_hMenu, i, MF_BYPOSITION | MF_ENABLED);
else
::EnableMenuItem(pMenu->m_hMenu, i, MF_BYPOSITION | MF_GRAYED);
}
::DrawMenuBar(pFrm->m_hWnd);
::PeekAndPump();
}
pFrm->HideToolButton(bGray);*/
}
void CDlgBuildTIN::OnSTOPB()
{
m_oTan->Stop();
m_nProc = 0;
m_stop = 1;
}
void CDlgBuildTIN::Build(void)
{
if (!UpdateData(1))
{
AfxMessageBox("請(qǐng)輸入[重合點(diǎn)限差]!");
return;
}
m_progress.SetRange32(0, m_num);
if (m_dim != 2)
return;
m_oTan->Make((TCS_F64*)m_pts, m_num, m_dup);
// 檢測(cè)構(gòu)網(wǎng)分區(qū)是否完成
TCS_S32 TN, PN; TCS_F64 DT;
while (1)
{
if (m_oTan->Done())
break;
::Sleep(10); ::PeekAndPump();
#ifdef TSET_SIN
TN = 0, PN = 0; m_oTan->Proc(PN, TN);
m_dtm.Format("%d/%d", PN, TN); UpdateData(0);
#endif
}
TN = 0, PN = 0; m_oTan->Proc(PN, TN); DT = m_oTan->Time();
m_dtm.Format("%.2lf/%d/%d", DT, PN, TN); UpdateData(0);
TCS_TMB btm; ::_ftime_s(&btm);
if (*m_TR)
delete []*m_TR;
*m_TR = 0; *m_RN = 0;
TCS_S32 RN;
TIN_R **TR = m_oTan->TinR(RN);
if (1)
{
TIN_G *G = m_oTan->TinG();
// 利用線程調(diào)度分區(qū)構(gòu)網(wǎng)
m_stop = 0;
TIN_WORKER *onpa = (TIN_WORKER*)m_onpa;
TIN_MASTER *mapa = (TIN_MASTER*)m_mapa;
for (long i = 0; i < mapa->onnu; i++)
{
onpa[i].R = 0;
::SetEvent(onpa[i].nven[1]);
::ResetEvent(onpa[i].nven[0]);
onpa[i].thrd = ::CreateThread(0, 0, WorkerThread, &onpa[i], 0, 0);
}
mapa->P = (TCS_F64*)m_pts; mapa->N = RN; mapa->R = TR;
mapa->thrd = ::CreateThread(0, 0, MasterThread, mapa, 0, 0);
// 檢測(cè)進(jìn)度:完成點(diǎn)數(shù)與三角形數(shù)
while (1)
{
::Sleep(10); TN = 0, PN = 0; m_oTan->Proc(PN, TN);
m_dtm.Format("%d/%d", PN, TN); UpdateData(0);
if (!mapa->thrd) break;
::PeekAndPump();
}
}
if (RN)
{
TIN_R *R = new TIN_R[RN];
for (long i = 0; i < RN; i++)
{
R[i].ASL = TR[i]->ASL;
R[i].ATL = TR[i]->ATL;
R[i].AXI = TR[i]->AXI;
R[i].AXV = TR[i]->AXV;
R[i].BSL = TR[i]->BSL;
R[i].G = TR[i]->G;
R[i].S = TR[i]->S;
R[i].SCO[0] = TR[i]->SCO[0];
R[i].SCO[1] = TR[i]->SCO[1];
}
*m_TR = R; *m_RN = RN;
}
delete []TR;
TCS_TMB etm; ::_ftime_s(&etm);
// 獲得三角形
if (*m_TT)
delete [](*m_TT);
*m_TN = 0; *m_TT = 0;
*m_TT = m_oTan->TinT(*m_TN);
// 檢查是否存在重復(fù)三角形
if (0)
{
long n = *m_TN;
TIN_T *T = *m_TT;
for (long i = 0; i < n - 1; i++)
{
for (long k = i + 1; k < n; k++)
{
if ((T[i].pid[0] == T[k].pid[0] && T[i].pid[1] == T[k].pid[1] && T[i].pid[2] == T[k].pid[2]) ||
(T[i].pid[1] == T[k].pid[0] && T[i].pid[2] == T[k].pid[1] && T[i].pid[0] == T[k].pid[2]) ||
(T[i].pid[2] == T[k].pid[0] && T[i].pid[0] == T[k].pid[1] && T[i].pid[1] == T[k].pid[2]))
{
AfxMessageBox("重復(fù)三角形!");
return;
}
}
}
}
// 獲得指標(biāo)數(shù)據(jù)
DT += (::difftime(etm.time, btm.time) + (etm.millitm - btm.millitm) / 1000.0);
TN = 0, PN = 0; m_oTan->Proc(PN, TN); m_dtm.Format("%.2lf/%d/%d", DT, PN, TN); UpdateData(0);
if (!m_nProc)
AfxMessageBox("構(gòu)建停止!");
else
AfxMessageBox("構(gòu)建完畢!");
}
void CDlgBuildTIN::OnCancel()
{
if (m_nProc)
return;
CDialog::OnCancel();
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -