#include "StdAfx.h" #include "itemmesh.h" #include "SigmaView.h" #include "DCHelp.h" #include "String.h" #include "ActionListItem.h" #include "ActionBackupItem.h" #include wchar_t * AsciiToUnicodeChar(const char * str); static void Kit_StringTool_Split(const std::string & s, std::vector & tokens, const std::string & delimiters); //BOOL IsVisible(CWnd* pWnd); CItemMesh::CItemMesh(CSigmaDoc * ppDoc) : CItem(ppDoc) , m_smthtimes(0) , m_smoothcoef(0.0) { SetType(ITEM_MESH); m_bRuler = TRUE; m_nSelect = MESH_DEFAULT; pDrawerDC = nullptr; typeIndex = 0; m_levelAlpha = 0; modeFun = 0; m_nDimensionSel = 0; m_RulerIdea = 0; m_contourStep = 20; m_contourMarkStep = 5; m_strLayerMark = _T("Layer:\\Contour\\Mark"); m_strLayerOther = _T("Layer:\\Contour\\Other"); m_nFaultageMode = 0; m_strFaultageFile = _T(""); m_strFaultageLayer = _T(""); m_bDrawPrevPoint = FALSE; //m_pHistogramDlg = NULL; m_bDrawRangeZ = FALSE; m_bShowColorPane = FALSE; //CMainFrame* pmf = (CMainFrame*)GetDoc()->GetMainFrame(); //if (pmf)m_bShowColorPane = IsVisible(&(pmf->m_paneColorRuler)); } CItemMesh::~CItemMesh(void) { if (m_nSelect == MESH_EDIT_NODE) { //GetDoc()->Invalidate(); } /*if (!m_bShowColorPane) { CMainFrame* pmf = (CMainFrame*)GetDoc()->GetMainFrame(); if (pmf)pmf->ClosePane(COMMAND_BAR_COLOR_BAR); }*/ } void CItemMesh::SetPos(POSITION pos) { CItem::SetPos(pos); //CMainFrame* pmf = (CMainFrame*)GetDoc()->GetMainFrame(); /*if (pmf != NULL && pos != NULL) { CMesh* pValue = GetMesh(); if (pValue) { pmf->m_colorBar = pValue->color; pmf->m_paneColorRuler.Invalidate(); pmf->ShowPane(COMMAND_BAR_COLOR_BAR); } }*/ } //BOOL CItemMesh::InitPropertyGrid(CXTPPropertyGrid& grid) //{ // ////////////////////////////////////////////////////////////////////////////////////////////////// // //生成等值线的属性 // switch (m_nSelect) // { // case MESH_CREATE_CONTOUR: // return InitPropertyGridForContour(grid); // case MESH_GET_RANGE: // return InitPropertyGridGetRangeZ(grid); // case MESH_GRID_SMOOTH: // return InitPropertyGridSmooth(grid); // default: // return InitPropertyGridMesh(grid); // } // return TRUE; //} /*BOOL CItemMesh::OnGridItemChangeValue(CXTPPropertyGridItem* pItem) { switch (m_nSelect) { case MESH_CREATE_CONTOUR: return OnGridItemChangeValueForContour(pItem); case MESH_GET_RANGE: break; default: return OnGridItemChangeValueMesh(pItem); } return FALSE; }*/ //BOOL CItemMesh::InitPropertyGridGetRangeZ(CXTPPropertyGrid& grid) //{ // CPropertyGridItemAdd ItemAdd(NULL); // CXTPPropertyGridItem* pItem = grid.AddCategory(IDS_STRING_MESH); // ItemAdd.SetItem(pItem); pItem->Expand(); // COne* pOne = (COne*)GetDoc()->GetDraw()->GetAt(GetPos()); // CMesh* pValue = (CMesh*)pOne->GetValue(); // CString strFormat = GetFloatFormatString(); // m_szInvalidateValueZ.SetSize(-99999999, 99999999); // ItemAdd.AddItemSize8(IDS_STRING_INVALIDATE_Z, m_szInvalidateValueZ, &m_szInvalidateValueZ, IDS_STRING_MESH_CONTOUR_MIN, IDS_STRING_MESH_CONTOUR_MAX); // m_bResetZ = TRUE; // ItemAdd.AddItemBool(IDS_GI_TEXT_EDIT_UPDATE_COLOR, m_bResetZ, &m_bResetZ); // return TRUE; //} /* BOOL CItemMesh::InitPropertyGridMesh(CXTPPropertyGrid& grid) { ////////////////////////////////////////////////////////////////////////////////////////////////// //曲面属性 CPropertyGridItemAdd ItemAdd(NULL); CXTPPropertyGridItem* pItem = grid.AddCategory(IDS_STRING_MESH); ItemAdd.SetItem(pItem); pItem->Expand(); COne* pOne = (COne*)GetDoc()->GetDraw()->GetAt(GetPos()); CMesh* pValue = (CMesh*)pOne->GetValue(); CString strFormat = GetFloatFormatString(); //文件名称 DWORD nType = pValue->GetMeshType(); name = pValue->GetName(); CString strFilter = _T("DoubleFox Files (*.dfg;*.fxy;*.f(x,y))|*.dfg;*.fxy;*.f(x,y)|All Files (*.*)|*.*||"); pItem = ItemAdd.AddItemFileBox(TRUE, IDS_STRING_FILE_NAME, NULL, name, &name, strFilter, FALSE); //pItem->SetReadOnly(TRUE); pItem = ItemAdd.AddItemLong(IDS_GI_MESH_TIMES, pValue->m_nTimes, NULL//&pValue->m_nTimes); color = pValue->color; CCustomItemMeshColor* pItemMeshColor = new CCustomItemMeshColor(IDS_GI_COLOR, &color); pItemMeshColor->EnableWizardMode(FALSE); pItemMeshColor->m_pMeshForApply = pValue; ItemAdd.AddItem(pItemMeshColor); switch (pValue->GetTransparentMode()) { case IMAGE_TRANSPARENT_ALPHA: typeIndex = 1; break; //透明度 case IMAGE_TRANSPARENT_COLOR: typeIndex = 2; break; //透明颜色 default: typeIndex = 0; break; //原始 } ItemAdd.AddItemCombo(IDS_STRING_TRANSPARENT, IDS_TRANSPARENT_MODE, typeIndex, &typeIndex); //显示方式 m_levelAlpha = pValue->GetTransparentColor(); pItem = ItemAdd.AddItemLong(ID_IMAGE_TRANSPARENT_COLOR, m_levelAlpha, &m_levelAlpha); //透明度 pItem->SetReadOnly(!typeIndex); modeFun = GetFunctionIdea(pValue->GetMeshFunction()); pItem = ItemAdd.AddItemCombo(IDS_GI_MESH_FUNCTION, IDS_GI_MESH_FUNCTION_MODE, modeFun, &modeFun); //处理方式 if (pValue->GetMeshType() == MESH_FUN_2D) pItem->SetReadOnly(TRUE); //Z值范围 m_zrange.SetSize(0, 0); pValue->GetM(m_zrange.cx, m_zrange.cy); pItem = ItemAdd.AddItemSize8(IDS_STRING_ZRANGE, m_zrange, &m_zrange, IDS_STRING_MINIMUM, IDS_STRING_MAXIMAL); if (pValue->GetMeshFunction() != 0) pItem->SetReadOnly(TRUE); pItem->SetFlags(pItem->GetFlags() | xtpGridItemHasExpandButton); //设置按钮,为了可以根据人工定制的 ((CCustomItemPoint*)pItem)->SetItem(this); //为了可以触发按钮按下的事件 //坐标 m_point.SetPoint(pValue->left, pValue->bottom); pItem = ItemAdd.AddItemPoint(IDS_GI_COORDINATE, m_point, &m_point); pItem->SetReadOnly(TRUE); if (pValue->m_pImage) { pItem = ItemAdd.AddItemSize8(IDS_STRING_SIZE, pValue->m_pImage->m_size, &pValue->m_pImage->m_size, IDS_STRING_WIDTH, IDS_STRING_HEIGHT); pItem->SetReadOnly(TRUE); } //网格数目 long numx = 0, numy = 0, numz = 0; CString smn; int dem = pValue->GetNumber(numx, numy, &numz); switch (dem) { case 2: case 0: smn.Format("%ld, %ld", numx, numy); break; case 3: smn.Format("%ld, %ld, %ld", numx, numy, numz); break; } pItem = ItemAdd.AddItemString(IDS_GI_MESH_MN, smn); pItem->SetReadOnly(TRUE); //维数 m_nDimensionSel = 0; if (dem == 3) m_nDimensionSel = 1; pItem = ItemAdd.AddItemCombo(IDS_STRING_GRID_DIMENSION, IDS_STRING_GRID_DIMENSION_MODE, m_nDimensionSel, &m_nDimensionSel); pItem->SetReadOnly(TRUE); pItem = grid.AddCategory(IDS_MESH_COLOR_RULER); ItemAdd.SetItem(pItem); pItem->Expand(); m_bRuler = pValue->IsDrawRuler(); ItemAdd.AddItemBool(IDS_GI_MESH_RULER, m_bRuler, &m_bRuler); //是否显示标尺 m_bUpdateRuler = pValue->IsUpdateRuler(); ItemAdd.AddItemBool(IDS_MESH_COLOR_RULER_UPDATE, m_bUpdateRuler, &m_bUpdateRuler); //是否更新标尺 m_bReversal = pValue->m_pRuler->IsReversal(); ItemAdd.AddItemBool(IDS_GI_MESH_REVERSAL, m_bReversal, &m_bReversal); //是否反转显示标尺 CColorRuler* pRuler = pValue->m_pRuler; m_RulerIdea = GetRulerIdea(pRuler->GetMode()); pItem = ItemAdd.AddItemCombo(IDS_GI_NET_VIEW_IDEA, IDS_MESH_COLOR_RULER_MODE, m_RulerIdea, &m_RulerIdea); //坐标 m_point.SetPoint(pRuler->x0, pRuler->y0); pItem = ItemAdd.AddItemPoint(IDS_GI_COORDINATE, m_point, &m_point); pItem->SetReadOnly(m_bUpdateRuler); //高宽 pItem = ItemAdd.AddItemSize8(IDS_STRING_SIZE, pRuler->m_size, NULL, IDS_STRING_WIDTH, IDS_STRING_HEIGHT); pItem->SetReadOnly(m_bUpdateRuler); pItem = ItemAdd.AddItemDouble(IDS_STRING_TEXT_HEIGHT, pRuler->TextHeight, strFormat, NULL); pItem->SetReadOnly(m_bUpdateRuler); pItem = ItemAdd.AddItemDouble(IDS_STRING_MAXIMAL, pRuler->zmax, strFormat, NULL); pItem->SetReadOnly(m_bUpdateRuler); pItem = ItemAdd.AddItemDouble(IDS_STRING_MINIMUM, pRuler->zmin, strFormat, NULL); pItem->SetReadOnly(m_bUpdateRuler); pItem = ItemAdd.AddItemDouble(IDS_GI_STEP, pRuler->delt, strFormat, NULL); //pItem->SetReadOnly(m_bUpdateRuler); pItem = ItemAdd.AddItemLong(IDS_TREE_GI_SAVE_DECIMAL_DIGITS, pRuler->DecimalFraction, NULL); //pItem->SetReadOnly(m_bUpdateRuler); pItem = ItemAdd.AddItemLong(IDS_GI_PROPORTION_NUMBER, pRuler->num, NULL); CItem::InitPropertyGrid(grid); return TRUE; } */ /*BOOL CItemMesh::OnGridItemChangeValueMesh(CXTPPropertyGridItem* pItem) { COne* pOne = (COne*)GetDoc()->GetDraw()->GetAt(GetPos()); CMesh* pValue = (CMesh*)pOne->GetValue(); BOOL bUpdate = FALSE; switch (pItem->GetID()) { case IDS_GI_MESH_FUNCTION: pValue->SetMeshFunction(this->GetFunctionMode(modeFun)); GetDoc()->BeginProgress(IDS_GI_MESH_FUNCTION); pValue->GetBitmap(); GetDoc()->EndProgress(); bUpdate = TRUE; break; case IDS_STRING_ZRANGE: if (pValue->GetMesh()) { pValue->SetM(m_zrange.cx, m_zrange.cy); GetDoc()->BeginProgress(IDS_STRING_ZRANGE); pValue->GetBitmap(); GetDoc()->EndProgress(); bUpdate = TRUE; } break; case IDS_STRING_FILE_NAME: if (pValue->AutoReadFile(name)) pValue->SetName(name); bUpdate = TRUE; break; case IDS_GI_COLOR: pValue->color = color; GetDoc()->BeginProgress(IDS_GI_COLOR); pValue->GetBitmap(); GetDoc()->EndProgress(); bUpdate = TRUE; break; case IDS_GI_MESH_TIMES: pValue->m_nTimes = ((CXTPPropertyGridItemNumber*)pItem)->GetNumber(); GetDoc()->BeginProgress(IDS_GI_MESH_TIMES); pValue->GetBitmap(); GetDoc()->EndProgress(); bUpdate = TRUE; break; case IDS_STRING_TRANSPARENT: switch (typeIndex) { case 0: pValue->SetTransparentMode(0); pValue->RemoveAlpha(); break; case 1: pValue->SetTransparentMode(IMAGE_TRANSPARENT_ALPHA); pValue->SetTransparentColor(m_levelAlpha); break; case 2: pValue->SetTransparentMode(IMAGE_TRANSPARENT_COLOR); pValue->SetTransparentColor(m_levelAlpha); break; } { CXTPPropertyGridItem* pFindItem = this->FindItem(pItem, ID_IMAGE_TRANSPARENT_COLOR); if (pFindItem) pFindItem->SetReadOnly(!pValue->IsTransparent()); } bUpdate = TRUE; break; case ID_IMAGE_TRANSPARENT_COLOR: if (pValue->GetTransparentMode() == IMAGE_TRANSPARENT_ALPHA) { if (m_levelAlpha > 255) m_levelAlpha = 255; } else if (pValue->GetTransparentMode() == IMAGE_TRANSPARENT_COLOR) { if (m_levelAlpha > RGB(255, 255, 255)) m_levelAlpha = RGB(255, 255, 255); } if (m_levelAlpha < 0) m_levelAlpha = 0; pValue->SetTransparentColor(m_levelAlpha); bUpdate = TRUE; break; case IDS_GI_COORDINATE: pValue->m_pRuler->x0 = m_point.x0; pValue->m_pRuler->y0 = m_point.y0; bUpdate = TRUE; break; case IDS_GI_MESH_RULER: pValue->EnableDrawRuler(m_bRuler); { CRect8 rt = pValue->GetRulerRange(); CRect rect = GetDC()->GetScreen(rt); rect.InflateRect(2, 2); GetDoc()->CDrawDoc::Invalidate(rect); } bUpdate = TRUE; break; case IDS_MESH_COLOR_RULER_UPDATE: pValue->EnableUpdateRuler(m_bUpdateRuler); pValue->UpdateColorRuler(); bUpdate = TRUE; break; case IDS_GI_MESH_REVERSAL: pValue->m_pRuler->EnableReversal(m_bReversal ? true : false); bUpdate = TRUE; break; case IDS_STRING_SIZE: pValue->m_pRuler->m_size = ((CCustomItemPoint*)pItem)->GetValuePoint(); bUpdate = TRUE; break; case IDS_GI_NET_VIEW_IDEA: { DWORD orm = pValue->m_pRuler->GetMode(); DWORD rm = GetRulerMode(m_RulerIdea); pValue->m_pRuler->SetMode(rm); if (((rm == COLOR_RULER_H_SMOOTH || rm == COLOR_RULER_H_GRID) && (orm == COLOR_RULER_V_SMOOTH || orm == COLOR_RULER_V_GRID)) || ((orm == COLOR_RULER_H_SMOOTH || orm == COLOR_RULER_H_GRID) && (rm == COLOR_RULER_V_SMOOTH || rm == COLOR_RULER_V_GRID))) AfxGetPublicFunction()->ExchangeXY(pValue->m_pRuler->m_size.cx, pValue->m_pRuler->m_size.cy); } bUpdate = TRUE; break; case IDS_STRING_TEXT_HEIGHT: pValue->m_pRuler->TextHeight = ((CXTPPropertyGridItemDouble*)pItem)->GetDouble(); bUpdate = TRUE; break; case IDS_STRING_MAXIMAL: pValue->m_pRuler->zmax = ((CXTPPropertyGridItemDouble*)pItem)->GetDouble(); bUpdate = TRUE; break; case IDS_STRING_MINIMUM: pValue->m_pRuler->zmin = ((CXTPPropertyGridItemDouble*)pItem)->GetDouble(); bUpdate = TRUE; break; case IDS_GI_STEP: pValue->m_pRuler->delt = ((CXTPPropertyGridItemDouble*)pItem)->GetDouble(); bUpdate = TRUE; break; case IDS_TREE_GI_SAVE_DECIMAL_DIGITS: pValue->m_pRuler->DecimalFraction = atol(pItem->GetValue());; bUpdate = TRUE; break; case IDS_GI_PROPORTION_NUMBER: pValue->m_pRuler->num = atol(pItem->GetValue());; bUpdate = TRUE; break; } return bUpdate | CItem::OnGridItemChangeValue(pItem); }*/ int CItemMesh::GetFunctionIdea(DWORD nFunMode) { switch (nFunMode) { case MESH_DIFFERENTIAL_X: return 1; case MESH_DIFFERENTIAL_Y: return 2; case MESH_DIFFERENTIAL_XY: return 3; case MESH_DIFFERENTIAL_X2: return 4; case MESH_DIFFERENTIAL_Y2: return 5; case MESH_DIFFERENTIAL_XY2: return 6; } return 0; } DWORD CItemMesh::GetFunctionMode(int nFunIdea) { switch (nFunIdea) { case 1: return MESH_DIFFERENTIAL_X; case 2: return MESH_DIFFERENTIAL_Y; case 3: return MESH_DIFFERENTIAL_XY; case 4: return MESH_DIFFERENTIAL_X2; case 5: return MESH_DIFFERENTIAL_Y2; case 6: return MESH_DIFFERENTIAL_XY2; } return 0; } int CItemMesh::GetRulerIdea(DWORD nMode) { switch (nMode) { case COLOR_RULER_H_SMOOTH: return 0; case COLOR_RULER_H_GRID: return 1; case COLOR_RULER_V_SMOOTH: return 2; case COLOR_RULER_V_GRID: return 3; } return 0; } DWORD CItemMesh::GetRulerMode(int nIdea) { switch (nIdea) { default: case 0: return COLOR_RULER_H_SMOOTH; case 1: return COLOR_RULER_H_GRID; case 2: return COLOR_RULER_V_SMOOTH; case 3: return COLOR_RULER_V_GRID; } return COLOR_RULER_H_SMOOTH; } void CItemMesh::SaveAs(COne* pOne, LPCTSTR filePath, int index) { if (pOne == NULL) return; CString name = filePath; if (index < 0) { name += _T(".keg"); index = 0; } CMesh* pMesh = (CMesh*)pOne->GetValue(); if (pMesh->GetMesh() == NULL || name == "") return; switch (index) { case 0://*.keg pMesh->WriteMesh(name, MESH_DFG); break; case 1://*.grd pMesh->WriteGrid_SurferAscii(name); break; case 2://*.grd pMesh->WriteGrid_SurferBinary6(name); break; case 3: pMesh->WriteGrid_GeoFrameAscii(name); break; default: case 4://*.jpg, *.tif case 5: if (pMesh->GetImage() != NULL) pMesh->GetImage()->SaveAs(name); else ::AfxMessageBox("ERROR: NULL Image Data"); break; } } void CItemMesh::SaveAsOnlyData(COne* pOne, LPCTSTR filePath) { if (pOne == NULL) return; CMesh* pMesh = (CMesh*)pOne->GetValue(); if (pMesh->GetMesh() == NULL) return; CFile fw; if (!fw.Open(filePath, CFile::modeCreate | CFile::modeWrite)) { ::AfxMessageBox("Open file to write error!"); return; } pMesh->WriteOnlyDataToXYZ(fw, pMesh->m_nTimes, CUR_VERSION); fw.Close(); } CItemMesh* _pItemMeshContour_Only = NULL; POSITION posCurrent = nullptr; POSITION AddContourCurve(CCurve *curve, CString strLayer) { if (curve == NULL)return NULL; if (_pItemMeshContour_Only == NULL) return NULL; CCurveEx *ce = new CCurveEx(curve->num); for (int i = 0; i < ce->num; i++) { ce->x[i] = curve->x[i]; ce->y[i] = curve->y[i]; ce->z[i] = curve->z[i]; } ce->nPoint = curve->nPoint; ce->GetLocation(); //POSITION pos = NULL; if (curve->name) ce->SetName(curve->name); //pos = _pItemMeshContour_Only->AddElement(ce, DOUBLEFOX_CURVE, true, false); posCurrent = _pItemMeshContour_Only->GetDoc()->GetDraw()->InsertElementAfter(posCurrent, ce, DOUBLEFOX_CURVE); _pItemMeshContour_Only->GetDoc()->GetDraw()->SetElementLayer(posCurrent, strLayer); _pItemMeshContour_Only->m_posAddList.AddTail(posCurrent); return posCurrent; } //平滑操作 bool CItemMesh::GridSmooth(COne* pOne, double coefficient, int smoothNumber) { if (pOne == NULL) return false; m_nSelect = MESH_GRID_SMOOTH; POSITION pos = GetDoc()->GetDraw()->Find(pOne); if (pos == NULL) return false; //POSITION bkpos = GetPos(); //SetPos(pos); //CPropertiesSheet sheet(IDS_STRING_MESH_SMOOTH, GetView(), 0, FALSE); //sheet.SetItem(this); //if (sheet.DoModal() != IDOK) //{ //(bkpos); //m_nSelect = 0; //return; //} //SetPos(bkpos); m_nSelect = MESH_DEFAULT; CMesh* pMesh = (CMesh*)pOne->GetValue(); if (pMesh == NULL) return false; CActionBackupItem *pAction = new CActionBackupItem(GetDoc(), IDS_STRING_MESH_SMOOTH); pAction->Backup(pOne); //GetDoc()->BeginProgress(IDS_STRING_MESH_SMOOTH); pMesh->Smooth(coefficient, smoothNumber); //GetDoc()->EndProgress(); //GetDoc()->Invalidate(pos); pAction->BackupNew(); GetDoc()->SetActionItem(pAction); return true; } wchar_t * CItemMesh::GetInformationForGeneratingContour() { POSITION pos = GetPos(); if (pos == nullptr) return nullptr; COne* pOne = (COne*)GetDoc()->GetDraw()->GetAt(pos); CMesh* pValue = (CMesh*)pOne->GetValue(); CString strFormat = GetFloatFormatString(); m_zrange.SetSize(0, 0); pValue->GetM(m_zrange.cx, m_zrange.cy); m_contourStep = (m_zrange.cy - m_zrange.cx) / 20; m_contourStep = AfxGetPublicFunction()->ContourStep(m_contourStep); m_contourMarkStep = 5; CString infoStr; infoStr.Format("%.8lf;%d;%.8lf;%.8lf;%s;%s", m_contourStep, m_contourMarkStep, m_zrange.cx, m_zrange.cy, m_strLayerMark, m_strLayerOther); return AsciiToUnicodeChar(infoStr.GetBuffer()); //pItem = grid.AddCategory(IDS_STRING_TOOLBAR_LAYER); //ItemAdd.SetItem(pItem); pItem->Expand(); //pItem = ItemAdd.AddItemString(IDS_STRING_MESH_CONTOUR_MARK_LAYER, m_strLayerMark, &m_strLayerMark); //pItem = ItemAdd.AddItemString(IDS_STRING_MESH_CONTOUR_OTHER_LAYER, m_strLayerOther, &m_strLayerOther); //if (pValue->GetMeshType() == MESH_TEXT || // pValue->GetMeshType() == MESH_DFG || // pValue->GetMeshType() == MESH_FXY) //{ //pItem = grid.AddCategory(IDS_STRING_FAULTAGE); //ItemAdd.SetItem(pItem); pItem->Expand(); //pItem = ItemAdd.AddItemCombo(IDS_STRING_FAULTAGE_MODE_SEL, IDS_STRING_FAULTAGE_MODE, m_nFaultageMode, &m_nFaultageMode); //ItemAdd.SetItem(pItem); pItem->Expand(); //CString strFilter = _T("DoubleFox Files (*.dfd)|*.dfd|All Files (*.*)|*.*||"); //pItem = ItemAdd.AddItemFileBox(TRUE, IDS_FAULTAGE_FILE, NULL, m_strFaultageFile, &m_strFaultageFile, strFilter, FALSE); //pItem->SetReadOnly(TRUE); //CString layer = GetGridItemComboLayer(); //pItem = ItemAdd.AddItemCombo(IDS_FAULTAGE_LAYER, layer, m_strFaultageLayer, &m_strFaultageLayer); //pItem->SetReadOnly(TRUE); //} } bool CItemMesh::CreateContour(COne* pOne, char * infoString) { if (pOne == NULL) return false; if (!ParseInformationOfCreatingContour(infoString)) return false; m_nSelect = MESH_CREATE_CONTOUR; POSITION pos = GetDoc()->GetDraw()->Find(pOne); if (pos == NULL) return false; //POSITION bkpos = GetPos(); //SetPos(pos); //CPropertiesSheet sheet(IDS_STRING_MESH, GetView(), 0, FALSE); //sheet.SetItem(this); //if (sheet.DoModal() != IDOK) //{ // SetPos(bkpos); // m_nSelect = 0; // return; //} //SetPos(bkpos); m_nSelect = MESH_DEFAULT; _pItemMeshContour_Only = this; m_posAddList.RemoveAll(); CMesh* pMesh = (CMesh*)pOne->GetValue(); if (m_strLayerMark.IsEmpty()) m_strLayerMark = _T("Layer:\\Contour\\Mark"); if (m_strLayerOther.IsEmpty()) m_strLayerOther = _T("Layer:\\Contour\\Other"); CString curLayerName = GetDoc()->GetDraw()->GetCurrentLayer()->GetPathName(); CLayer* pMarkLayer = GetDoc()->GetDraw()->FindLayer(m_strLayerMark); CLayer* pOtherLayer = GetDoc()->GetDraw()->FindLayer(m_strLayerOther); BOOL bAddMarkLayer = FALSE; BOOL bAddOtherLayer = FALSE; if (pMarkLayer == NULL) { bAddMarkLayer = TRUE; pMarkLayer = GetDoc()->GetDraw()->FindAddLayer(m_strLayerMark); pMarkLayer->HowToViewCurve = new CHowToViewCurve(); pMarkLayer->HowToViewCurve->EnableDrawSourceCurve(FALSE); CCurveInName* pInName = new CCurveInName(); CRect8 rect = pMesh->GetRect(); pInName->text_h = rect.Width() / 300; pInName->m_size.cx = pInName->text_h*0.06; pMarkLayer->HowToViewCurve->Add(pInName); } if (pOtherLayer == NULL) { bAddOtherLayer = TRUE; pOtherLayer = GetDoc()->GetDraw()->FindAddLayer(m_strLayerOther); pOtherLayer->HowToViewCurve = new CHowToViewCurve(); pOtherLayer->HowToViewCurve->EnableDrawSourceCurve(FALSE); CCurveProperties* pview = new CCurveProperties(); pview->color = RGB(0, 255, 0); pOtherLayer->HowToViewCurve->Add(pview); } //设置断层信息 CDimension3D* pDfg = (CDimension3D*)pMesh->GetMesh(); switch (m_nFaultageMode) { case 0://没有断层 break; case 1://断层在文件中 pDfg->CDimensionBase::EmptyLink();//清空已有的断层信息 switch (pMesh->GetMeshType()) { case MESH_TEXT: case MESH_DFG: case MESH_FXY: pDfg->Faultage(m_strFaultageFile); break; case MESH_FUN_2D: default: break; } break; case 2://断层在类别中 switch (pMesh->GetMeshType()) { case MESH_TEXT: case MESH_DFG: case MESH_FXY: pDfg->CDimensionBase::EmptyLink();//清空已有的断层信息 { CCurveEx* pCurve; COne* pOne; CPositionList select; if (GetDoc()->GetDraw()->GetElement(m_strFaultageLayer, select, FALSE) > 0) { POSITION pt; POSITION pos = select.GetHeadPosition(); while (pos) { pt = select.GetNext(pos); pOne = GetDoc()->GetDraw()->GetAt(pt); if (pOne->GetType() != DOUBLEFOX_CURVE) continue; pCurve = (CCurveEx*)pOne->GetValue(); pDfg->Faultage(*(CCurve*)pCurve); } } } break; case MESH_FUN_2D: default: break; } break; } //生成等值线 posCurrent = pos; pMesh->ContourCreate(AddContourCurve, m_contourStep, m_contourMarkStep, m_strLayerMark, m_strLayerOther, m_zrange.cx, m_zrange.cy); if (m_posAddList.GetCount() > 0) { CActionListItem* pAction = new CActionListItem(GetDoc(), ID_MESH_CREATE_CONTOUR); if (bAddMarkLayer) pAction->AddLayerAddItem(pMarkLayer, curLayerName); if (bAddOtherLayer) pAction->AddLayerAddItem(pOtherLayer, curLayerName); pAction->AddAddItem(m_posAddList); GetDoc()->SetActionItem(pAction); m_posAddList.RemoveAll(); } _pItemMeshContour_Only = NULL; return true; } //初始化网格平滑属性框 /*BOOL CItemMesh::InitPropertyGridSmooth(CXTPPropertyGrid& grid) { ASSERT(GetPos()); CPropertyGridItemAdd ItemAdd(NULL); CXTPPropertyGridItem* pItem = grid.AddCategory(IDS_STRING_MESH); ItemAdd.SetItem(pItem); pItem->Expand(); COne* pOne = (COne*)GetDoc()->GetDraw()->GetAt(GetPos()); CString strFormat = GetFloatFormatString(); m_smoothcoef = 1.0; m_smthtimes = 10; pItem = ItemAdd.AddItemDouble(IDS_STRING_MESH_SMOOTH_COEFFICIENT, m_smoothcoef, strFormat, &m_smoothcoef); pItem = ItemAdd.AddItemLong(IDS_STRING_MESH_SMOOTH_TIMES, m_smthtimes, &m_smthtimes); return TRUE; }*/ //BOOL CItemMesh::OnGridItemChangeValueForContour(CXTPPropertyGridItem* pItem) //{ // COne* pOne = (COne*)GetDoc()->GetDraw()->GetAt(GetPos()); // CMesh* pValue = (CMesh*)pOne->GetValue(); // CXTPPropertyGridItem* pFind; // BOOL bUpdate = FALSE; // switch (pItem->GetID()) // { // case IDS_STRING_FAULTAGE_MODE_SEL: // bUpdate = TRUE; // switch (m_nFaultageMode) // { // case 0: //没有断层 // pFind = FindItem(pItem, IDS_FAULTAGE_FILE); // if (pFind)pFind->SetReadOnly(TRUE); // pFind = FindItem(pItem, IDS_FAULTAGE_LAYER); // if (pFind)pFind->SetReadOnly(TRUE); // break; // case 1: //断层数据在文件中 // pFind = FindItem(pItem, IDS_FAULTAGE_FILE); // if (pFind)pFind->SetReadOnly(FALSE); // pFind = FindItem(pItem, IDS_FAULTAGE_LAYER); // if (pFind)pFind->SetReadOnly(TRUE); // break; // case 2: //断层数据在类别中 // pFind = FindItem(pItem, IDS_FAULTAGE_FILE); // if (pFind)pFind->SetReadOnly(TRUE); // pFind = FindItem(pItem, IDS_FAULTAGE_LAYER); // if (pFind)pFind->SetReadOnly(FALSE); // break; // } // break; // default: // break; // } // return bUpdate; //} void CItemMesh::OnDraw(CXyDC* pXyDC, CDC* pDC) { OnDraw(pXyDC); } void CItemMesh::OnDraw(CXyDC* pDC) { if (!IsEditState()) return; switch (m_nSelect) { case MESH_EDIT_NODE: DrawNode(pDC); break; case MESH_HISTOGRAM: DrawHistogram(pDC); break; } } void CItemMesh::EditNode(CSigmaView* pView, CDC *pDC, CRect rt) { pDrawerDC = pDC; //GetDC()->Create(pDC); m_nSelect = MESH_EDIT_NODE; clientRect = rt; } void CItemMesh::DrawNode(CXyDC* pDC, CRect rt) { CMesh* pValue = (CMesh*)GetDoc()->GetDraw()->GetAtValue(GetPos()); //CRect rt; ////rt = GetView()->GetClientRect(); //CSigmaView* pView = GetView(); //rt = pView->m_client; long numx, numy; pValue->GetNumber(numx, numy); double ddx, ddy; pValue->GetDelt(ddx, ddy); long sx = 3; int od = pDC->GetDC()->SetROP2(R2_NOTXORPEN); CPen* pb = (CPen*)pDC->GetDC()->SelectStockObject(BLACK_PEN); CPoint pt; int dx = (int)(pDC->GetRealWidth(sx * 2) / ddx) + 1; int dy = (int)fabs(pDC->GetRealHeight(sx * 2) / ddy) + 1; for (int i = 0; i < numx; i += dx) { for (int j = 0; j < numy; j += dy) { pt = pDC->GetScreen(pValue->x(i), pValue->y(j)); if (!rt.PtInRect(pt))continue; pDC->GetDC()->MoveTo(pt.x - sx + 1, pt.y); pDC->GetDC()->LineTo(pt.x + sx, pt.y); pDC->GetDC()->MoveTo(pt.x, pt.y - sx + 1); pDC->GetDC()->LineTo(pt.x, pt.y + sx); } } pDC->GetDC()->SetROP2(od); pDC->GetDC()->SelectObject(pb); if (m_bDrawPrevPoint) DrawFocus(m_ptPrevPoint); } void CItemMesh::DrawNode(CXyDC* pDC) { CMesh* pValue = (CMesh*)GetDoc()->GetDraw()->GetAtValue(GetPos()); CRect rt; //rt = GetView()->GetClientRect(); CSigmaView* pView = GetView(); //rt = pView->m_client; rt = clientRect; long numx, numy; pValue->GetNumber(numx, numy); double ddx, ddy; pValue->GetDelt(ddx, ddy); long sx = 3; int od = pDC->GetDC()->SetROP2(R2_NOTXORPEN); CPen* pb = (CPen*)pDC->GetDC()->SelectStockObject(BLACK_PEN); CPoint pt; int dx = (int)(pDC->GetRealWidth(sx * 2) / ddx) + 1; int dy = (int)fabs(pDC->GetRealHeight(sx * 2) / ddy) + 1; for (int i = 0; i < numx; i += dx) { for (int j = 0; j < numy; j += dy) { pt = pDC->GetScreen(pValue->x(i), pValue->y(j)); if (!rt.PtInRect(pt))continue; pDC->GetDC()->MoveTo(pt.x - sx + 1, pt.y); pDC->GetDC()->LineTo(pt.x + sx, pt.y); pDC->GetDC()->MoveTo(pt.x, pt.y - sx + 1); pDC->GetDC()->LineTo(pt.x, pt.y + sx); } } pDC->GetDC()->SetROP2(od); pDC->GetDC()->SelectObject(pb); if (m_bDrawPrevPoint) DrawFocus(m_ptPrevPoint); } void CItemMesh::DrawFocus(CPoint2D point) { int od = GetDC()->GetDC()->SetROP2(R2_NOTXORPEN); CPen* pb = (CPen*)GetDC()->GetDC()->SelectStockObject(BLACK_PEN); long sx = 3; double dx = GetDC()->GetRealWidth(sx * 2); double dy = GetDC()->GetRealHeight(sx * 2); CCurveEx cu(5); cu.x[0] = point.x0 - dx; cu.y[0] = point.y0; cu.x[1] = point.x0; cu.y[1] = point.y0 - dy; cu.x[2] = point.x0 + dx; cu.y[2] = point.y0; cu.x[3] = point.x0; cu.y[3] = point.y0 + dy; cu.x[4] = point.x0 - dx; cu.y[4] = point.y0; cu.GetLocation(); cu.m_type = PLINE_SOLID; GetDC()->Draw(cu, RGB(255, 0, 0)); //GetDC()->Draw(cu, RGB(0, 255, 0)); GetDC()->GetDC()->SetROP2(od); GetDC()->GetDC()->SelectObject(pb); } int CItemMesh::OnMouseMove(CDC *pDC, UINT nFlags, CPoint point) { if (m_nSelect == MESH_EDIT_NODE) { if (!IsEditState()) return 1; CPoint2D dp = GetDC()->GetReal(point); CMesh* pValue = (CMesh*)GetDoc()->GetDraw()->GetAtValue(GetPos()); long numx, numy; pValue->GetNumber(numx, numy); double ddx, ddy; pValue->GetDelt(ddx, ddy); double x0, y0; pValue->GetOrg(x0, y0); long i = AfxGetPublicFunction()->FloatToLong((dp.x0 - x0) / ddx); long j = AfxGetPublicFunction()->FloatToLong((dp.y0 - y0) / ddy); if (m_bDrawPrevPoint) { //DrawFocus(m_ptPrevPoint); m_bDrawPrevPoint = FALSE; } if (i < 0 || i >= numx || j < 0 || j >= numy) return 1; m_ptPrevPoint.x0 = pValue->x(i); m_ptPrevPoint.y0 = pValue->y(j); m_bDrawPrevPoint = TRUE; GetDC()->Create(pDC); DrawFocus(m_ptPrevPoint); TRACE("draw pt.x=%f,pt.y=%f\n", m_ptPrevPoint.x0, m_ptPrevPoint.y0); } return 1; } bool CItemMesh::FindNodeLocation(CDC *pDC, CPoint point, int& locationX, int& locationY) { if (m_nSelect == MESH_EDIT_NODE) { if (!IsEditState()) return false; GetDC()->Create(pDC); CPoint2D dp = GetDC()->GetReal(point); CMesh* pValue = (CMesh*)GetDoc()->GetDraw()->GetAtValue(GetPos()); long numx, numy; pValue->GetNumber(numx, numy); double ddx, ddy; pValue->GetDelt(ddx, ddy); double x0, y0; pValue->GetOrg(x0, y0); long i = AfxGetPublicFunction()->FloatToLong((dp.x0 - x0) / ddx); long j = AfxGetPublicFunction()->FloatToLong((dp.y0 - y0) / ddy); if (i < 0 || i >= numx || j < 0 || j >= numy) { return false; } CPoint ptSc = GetDC()->GetScreen(pValue->x(i), pValue->y(j)); locationX = ptSc.x; locationY = ptSc.y; //TRACE("draw locationX=%f,locationY=%f\n", locationX, locationY); return true; } else { return false; } } CMesh* CItemMesh::GetMesh(void) { if (GetPos() == NULL) return NULL; /*COne* pOne = (COne*)GetDoc()->GetDraw()->GetAt(GetPos()); if (pOne->GetType() != DOUBLEFOX_MESH) return NULL; return (CMesh*)pOne->GetValue();*/ return NULL; } bool CItemMesh::GridPointNoExist(UINT nFlags, CPoint point) { if (m_nSelect == MESH_EDIT_NODE) { if (!IsEditState()) return false; CPoint2D dp = GetDC()->GetReal(point); COne* pOne = (COne*)GetDoc()->GetDraw()->GetAt(GetPos()); CMesh* pValue = (CMesh*)pOne->GetValue(); long numx, numy; pValue->GetNumber(numx, numy); double ddx, ddy; pValue->GetDelt(ddx, ddy); double x0, y0; pValue->GetOrg(x0, y0); long i = AfxGetPublicFunction()->FloatToLong((dp.x0 - x0) / ddx); long j = AfxGetPublicFunction()->FloatToLong((dp.y0 - y0) / ddy); if (i < 0 || i >= numx) return false; if (j < 0 || j >= numy) return false; return true; } return false; } CString CItemMesh::GetGridValue(UINT nFlags, CPoint point) { if (m_nSelect == MESH_EDIT_NODE) { if (!IsEditState()) return ""; CPoint2D dp = GetDC()->GetReal(point); COne* pOne = (COne*)GetDoc()->GetDraw()->GetAt(GetPos()); CMesh* pValue = (CMesh*)pOne->GetValue(); long numx, numy; pValue->GetNumber(numx, numy); double ddx, ddy; pValue->GetDelt(ddx, ddy); double x0, y0; pValue->GetOrg(x0, y0); long i = AfxGetPublicFunction()->FloatToLong((dp.x0 - x0) / ddx); long j = AfxGetPublicFunction()->FloatToLong((dp.y0 - y0) / ddy); CString cStrX, cStrY, cStrZ, cStrRow, cStrCol, zMin, zMax, rtnValue; double zmin, zmax; pValue->GetM(zmin, zmax); cStrX.Format(_T("%lf"), pValue->x(i)); cStrY.Format(_T("%lf"), pValue->y(j)); cStrZ.Format(_T("%lf"), pValue->GetValue(i, j)); cStrRow.Format("%ud ", i); cStrCol.Format("%ud ", j); zMin.Format(_T("%lf"), zmin); zMax.Format(_T("%lf"), zmax); rtnValue = cStrX + "," + cStrY + "," + cStrZ + "," + cStrRow + "," + cStrCol + "," + zMin + "," + zMax; return rtnValue; } return _T(""); } void CItemMesh::ConfirmGridBtn() { } void CItemMesh::OnLButtonDown(CDC *pDC, UINT nFlags, CPoint point, int vk) { if (m_nSelect == MESH_EDIT_NODE) { if (!IsEditState()) return; CPoint2D dp = GetDC()->GetReal(point); COne* pOne = (COne*)GetDoc()->GetDraw()->GetAt(GetPos()); CMesh* pValue = (CMesh*)pOne->GetValue(); long numx, numy; pValue->GetNumber(numx, numy); double ddx, ddy; pValue->GetDelt(ddx, ddy); double x0, y0; pValue->GetOrg(x0, y0); long i = AfxGetPublicFunction()->FloatToLong((dp.x0 - x0) / ddx); long j = AfxGetPublicFunction()->FloatToLong((dp.y0 - y0) / ddy); if (i < 0 || i >= numx) return; if (j < 0 || j >= numy) return; //CDlgGridNodeEdit dlg; //double ov = pValue->GetValue(i, j); //dlg.x = pValue->x(i); //dlg.y = pValue->y(j); //dlg.z = ov; //dlg.m_row = i; //dlg.m_col = j; //pValue->GetM(dlg.zmin, dlg.zmax); //if (dlg.DoModal() != IDOK) return; //double nv = dlg.z; //pValue->SetZ(i, j, nv); //CRect8 rt; //rt.SetRect(pValue->x(i - 1), pValue->y(j - 1), pValue->x(i + 2), pValue->y(j + 2)); //CRect rect = GetDC()->GetScreen(rt); //GetDoc()->CDrawDoc::Invalidate(&rect); //GetDoc()->SetModifiedFlag(); //m_bDrawPrevPoint = FALSE; ////for undo/redo //point.x = i; //point.y = j; //GetDoc()->SetActionItem(new CActionGridNodeEditItem(GetDoc(), ID_MESH_EDIT_NODE, pOne, point, ov, nv)); } } int CItemMesh::GetEditMode(void) { return m_nSelect; } void CItemMesh::Histogram(void) { m_nSelect = MESH_HISTOGRAM; /* m_pHistogramDlg = new CDlgHistogram(GetView()); m_pHistogramDlg->m_pItemMesh = this; m_pHistogramDlg->Create(GetView());*/ } void CItemMesh::SetZValueOfNodeSelected(double v) { if (!m_bDrawRangeZ) { return; } CMesh* pValue = (CMesh*)GetDoc()->GetDraw()->GetAtValue(GetPos()); CRect rt = GetView()->GetClientRect(); long sx = 3; CPoint pt; double z; long numx, numy; pValue->GetNumber(numx, numy); for (int i = 0; i < numx; i++) { for (int j = 0; j < numy; j++) { z = pValue->GetValue(i, j); if (zm_zrange.cy) continue; pValue->SetZ(i, j, v); } } } bool CItemMesh::SetZOfGridPoint(double z, int row, int column) { COne* pOne = (COne*)m_pDoc->GetDraw()->GetAt(GetPos()); if (!pOne) { return false; } CMesh* pValue = (CMesh*)pOne->GetValue(); long numx, numy; pValue->GetNumber(numx, numy); if (row < 0 || row >= numx) return false; if (column < 0 || column >= numy) return false; pValue->SetZ(row, column, z); return true; } void CItemMesh::GetAreaAndValueForSelected(double minZ, double maxZ, double * areaOut, double * volumeOut) { CMesh* pValue = (CMesh*)GetDoc()->GetDraw()->GetAtValue(GetPos()); long sx = 3; CPoint pt; double dx = 0; double dy = 0; pValue->GetDelt(dx, dy); double cellOfArea = dx * dy; *areaOut = 0; *volumeOut = 0; double area = 0; double volume = 0; double z; long numx, numy; pValue->GetNumber(numx, numy); for (int i = 0; i < numx; i++) { for (int j = 0; j < numy; j++) { z = pValue->GetValue(i, j); if (zmaxZ) continue; area = cellOfArea + area; volume = volume + (z - minZ)*cellOfArea; } } *areaOut = area; *volumeOut = volume; } void CItemMesh::DrawHistogram(CXyDC* pDC) { if (!m_bDrawRangeZ) return; CMesh* pValue = (CMesh*)GetDoc()->GetDraw()->GetAtValue(GetPos()); CRect rt = GetView()->GetClientRect(); long sx = 3; int od = pDC->GetDC()->SetROP2(R2_NOTXORPEN); CPen* pb = (CPen*)pDC->GetDC()->SelectStockObject(BLACK_PEN); CPoint pt; double z; long numx, numy; pValue->GetNumber(numx, numy); for (int i = 0; i < numx; i++) { for (int j = 0; j < numy; j++) { z = pValue->GetValue(i, j); if (zm_zrange.cy) continue; pt = pDC->GetScreen(pValue->x(i), pValue->y(j)); if (!rt.PtInRect(pt)) continue; pDC->GetDC()->MoveTo(pt.x - sx + 1, pt.y); pDC->GetDC()->LineTo(pt.x + sx, pt.y); pDC->GetDC()->MoveTo(pt.x, pt.y - sx + 1); pDC->GetDC()->LineTo(pt.x, pt.y + sx); } } pDC->GetDC()->SetROP2(od); pDC->GetDC()->SelectObject(pb); } bool CItemMesh::ParseInformationOfCreatingContour(char * infoStr) { if (infoStr == 0) return false; std::string infoString(infoStr); std::vector tokens; Kit_StringTool_Split(infoString, tokens, ";"); if (tokens.size() != 9) return false; try { m_contourStep = std::stod(tokens[0]); m_contourMarkStep = std::stol(tokens[1]); m_zrange.cx = std::stod(tokens[2]); m_zrange.cy = std::stod(tokens[3]); m_strLayerMark = tokens[4].c_str(); m_strLayerOther = tokens[5].c_str(); m_nFaultageMode = std::stoi(tokens[6]); m_strFaultageFile = tokens[7].c_str(); m_strFaultageLayer = tokens[8].c_str(); } catch (std::exception ex) { std::cout << ex.what() << std::endl; } return true; } int CItemMesh::DeleteSelected(void) { if (!m_bDrawRangeZ) return 0; CMesh* pValue = (CMesh*)GetDoc()->GetDraw()->GetAtValue(GetPos()); //for redo/undo CPositionList select; select.AddTail(GetPos()); CActionBackupItem* pItem = new CActionBackupItem(GetDoc(), ID_MESH_HISTOGRAM, select); double zmin, zmax; pValue->GetM(zmin, zmax); zmin = (zmax - zmin) * 2; int count = pValue->DeleteValue(m_zrange.cx, m_zrange.cy, zmin); if (count > 0) { pValue->GetBitmap(); pItem->BackupNew(); GetDoc()->SetActionItem(pItem); } else delete pItem; return count; } void CItemMesh::SetHistogramRange(double zmin, double zmax) { m_bDrawRangeZ = TRUE; if (fabs(zmax - zmin) < 1e-10) m_bDrawRangeZ = FALSE; m_zrange.cx = zmin; m_zrange.cy = zmax; //GetDoc()->Invalidate(GetPos()); } /*void CItemMesh::OnInplaceButtonDown(CXTPPropertyGridItem* pItem) { if (pItem->GetID() != IDS_STRING_ZRANGE) return; int bakSelected = m_nSelect; m_nSelect = MESH_GET_RANGE; CPropertiesSheet sheet(IDS_STRING_ZRANGE, GetView(), 0, FALSE); sheet.SetItem(this); INT_PTR rt = sheet.DoModal(); m_nSelect = bakSelected; if (rt == IDOK) { CMesh* pValue = (CMesh*)GetDoc()->GetDraw()->GetAtValue(GetPos()); double zmin, zmax; pValue->GetM(zmin, zmax, TRUE, m_szInvalidateValueZ.cx, m_szInvalidateValueZ.cy); SetHistogramRange(zmin, zmax); if (m_bResetZ) { pValue->color.CreateZAverage(zmin, zmax); GetDoc()->BeginProgress(IDS_STRING_ZRANGE); pValue->GetBitmap(); GetDoc()->EndProgress(); } } }*/ static void Kit_StringTool_Split(const std::string & s, std::vector & tokens, const std::string & delimiters) { if (delimiters.size() == 0) { tokens.push_back(s); return; } //在字符串中查找第一个与str中的字符都不匹配的字符,返回它的位置。搜索从index开始。如果没找到就返回string::nops std::string::size_type lastPos = s.find_first_not_of(delimiters, 0); std::string::size_type pos = s.find_first_of(delimiters, lastPos); while (std::string::npos != pos || std::string::npos != lastPos) { tokens.push_back(s.substr(lastPos, pos - lastPos)); lastPos = s.find_first_not_of(delimiters, pos); pos = s.find_first_of(delimiters, lastPos); } }