void LayerDlg::OnLayerLoad( wxCommandEvent &event ) { VTLOG1("LayerDlg::OnLayerLoad\n"); wxString filter = _("Layer Formats|"); AddType(filter, FSTRING_SHP); if (g_App.m_state == AS_Terrain) { AddType(filter, FSTRING_VTST); AddType(filter, FSTRING_VF); AddType(filter, FSTRING_TIN); } wxFileDialog loadFile(NULL, _("Load Layer"), _T(""), _T(""), filter, wxFD_OPEN); bool bResult = (loadFile.ShowModal() == wxID_OK); if (!bResult) return; wxString str = loadFile.GetPath(); vtString fname = (const char *) str.mb_str(wxConvUTF8); VTLOG1(" File dialog: "); VTLOG1(fname); VTLOG1("\n"); GetFrame()->LoadLayer(fname); }
///////////////////////////////////////////////////////////////////////////// // // Frame constructor // EnviroFrame::EnviroFrame(wxFrame *parent, const wxString& title, const wxPoint& pos, const wxSize& size, long style, bool bVerticalToolbar, bool bEnableEarth) : wxFrame(parent, -1, title, pos, size, style) { VTLOG1("Frame constructor.\n"); m_bCloseOnIdle = false; // tell wxAuiManager to manage this frame m_mgr.SetManagedWindow(this); // Give the frame an icon VTLOG1(" Setting icon\n"); #ifdef ICON_NAME SetIcon(wxIcon(wxString(ICON_NAME, wxConvUTF8))); #else SetIcon(wxICON(Enviro)); #endif #if wxUSE_DRAG_AND_DROP SetDropTarget(new DnDFile); #endif m_bCulleveryframe = true; m_bAlwaysMove = false; m_bFullscreen = false; m_bTopDown = false; m_ToggledMode = MM_SELECT; m_bEnableEarth = bEnableEarth; m_bEarthLines = false; m_bVerticalToolbar = bVerticalToolbar; m_pStatusBar = NULL; m_pToolbar = NULL; }
void EnviroGUI::ShowMessage(const vtString &str) { VTLOG1("EnviroGUI::ShowMessage '"); VTLOG1(str); VTLOG1("'\n"); EnableContinuousRendering(false); wxString str2(str, wxConvUTF8); wxMessageBox(str2); EnableContinuousRendering(true); }
/** * Use the height data in the grid to fill a bitmap with colors. * * \param pBM The bitmap to be colored. * \param cmap The mapping of elevation values to colors. * \param iGranularity The smoothness of the mapping, expressed as the size * of the internal mapping table. 2000 is a generally good value. * \param nodata The color to use for NODATA areas, where there are no elevation values. * \param progress_callback If supplied, this function will be called back * with a value of 0 to 100 as the operation progresses. * * \return true if any invalid elevation values were encountered. */ bool vtHeightFieldGrid3d::ColorDibFromElevation(vtBitmapBase *pBM, ColorMap *cmap, int iGranularity, const RGBAi &nodata, bool progress_callback(int)) const { if (!pBM || !cmap) return false; VTLOG1("ColorDibFromElevation:"); float fMin, fMax; GetHeightExtents(fMin, fMax); float fRange = fMax - fMin; bool bFlat = (fRange < 0.0001f); if (bFlat) { // avoid numeric trouble with flat terrains by growing range fMin -= 1; fMax += 1; fRange = fMax - fMin; } VTLOG(" table of %d values, first [%d %d %d],\n", cmap->Num(), cmap->Color(0).r, cmap->Color(0).g, cmap->Color(0).b); VTLOG("\tmin %g, max %g, range %g, granularity %d\n", fMin, fMax, fRange, iGranularity); // Rather than look through the color map for each pixel, pre-build // a color lookup table once - should be faster in nearly all cases. cmap->GenerateColorTable(iGranularity, fMin, fMax); return ColorDibFromTable(pBM, cmap, nodata, progress_callback); }
void MapServerDlg::OnQueryLayers( wxCommandEvent &event ) { #if SUPPORT_CURL VTLOG1("OnQueryLayers\n"); wxString val = GetBaseUrl()->GetValue(); vtString url = (const char *) val.mb_str(wxConvUTF8); OpenProgressDialog(_("Querying server..."), val, false, this); VTLOG(" from base URL: %s\n", (const char *)url); vtString msg; bool success = GetLayersFromWMS(url, m_pServers->at(m_iServer).m_layers, msg, progress_callback); CloseProgressDialog(); if (success) { UpdateLayerList(); UpdateLayerDescription(); UpdateURL(); } else { VTLOG("Error: '%s'\n", (const char *)msg); wxString str(msg, wxConvUTF8); wxMessageBox(str); } #endif // SUPPORT_CURL }
void EnviroCanvas::OnAfterUpdate() { #ifndef __WXMAC__ if (m_bFirstPaint) VTLOG1("EnviroCanvas: update status bar\n"); #endif EnviroFrame *frame = (EnviroFrame*) GetParent(); // update the status bar every 1/10 of a second static float last_stat = 0.0f; static vtString last_msg; vtString current_msg = g_App.GetMessage1() + g_App.GetMessage2(); float cur = vtGetTime(); if (cur - last_stat > 0.1f || current_msg != last_msg) { last_msg = current_msg; last_stat = cur; frame->UpdateStatus(); } frame->UpdateLODInfo(); g_App.UpdateCompass(); }
void EnviroFrame::SetMode(MouseMode mode) { // Show/hide the modeless dialogs as appropriate m_pUtilDlg->Show(mode == MM_POWER); m_pInstanceDlg->Show(mode == MM_INSTANCES); m_pDistanceDlg->Show(mode == MM_MEASURE); m_pVehicleDlg->Show(mode == MM_VEHICLES); g_App.SetMode(mode); if (mode == MM_LINEARS) OpenFenceDialog(); else m_pFenceDlg->Show(false); // Show/hide plant dialog if (mode == MM_PLANTS) { VTLOG1("Calling Plant dialog\n"); // Make sure the species file and appearances are available g_App.LoadSpeciesList(); g_App.GetCurrentTerrain()->SetSpeciesList(g_App.GetSpeciesList()); g_App.ActivateAVegetationLayer(); m_pPlantDlg->SetSpeciesList(g_App.GetSpeciesList()); m_pPlantDlg->SetDlgPlantOptions(g_App.GetPlantOptions()); } m_pPlantDlg->Show(mode == MM_PLANTS); if (mode == MM_LINEARS || mode == MM_BUILDINGS || mode == MM_INSTANCES) { g_App.ActivateAStructureLayer(); } }
/** * Use the height data in the grid and a colormap fill a bitmap with colors. * Any undefined heixels in the source will be fill with red (255,0,0). * * \param pBM The bitmap to be colored. * \param color_map A ColorMap which has already had GenerateColorTable() called. * \param nodata The color to use for NODATA areas, where there are no elevation values. * \param progress_callback If supplied, this function will be called back * with a value of 0 to 100 as the operation progresses. * * \return true if any invalid elevation values were encountered. */ bool vtHeightFieldGrid3d::ColorDibFromTable(vtBitmapBase *pBM, const ColorMap *color_map, const RGBAi &nodata, bool progress_callback(int)) const { VTLOG1(" ColorDibFromTable:"); const IPoint2 bitmap_size = pBM->GetSize(); int depth = pBM->GetDepth(); VTLOG(" dib size %d x %d, grid %d x %d.. ", bitmap_size.x, bitmap_size.y, m_iSize.x, m_iSize.y); const bool bExact = (bitmap_size == m_iSize); double ratiox = (double)(m_iSize.x - 1)/(bitmap_size.x - 1), ratioy = (double)(m_iSize.y - 1)/(bitmap_size.y - 1); bool has_invalid = false; const RGBi nodata_24bit(nodata.r, nodata.g, nodata.b); float elev; // now iterate over the texels for (int i = 0; i < bitmap_size.x; i++) { if (progress_callback != NULL && (i&40) == 0) progress_callback(i * 100 / bitmap_size.x); // find the corresponding location in the height grid const double x = i * ratiox; for (int j = 0; j < bitmap_size.y; j++) { const double y = j * ratioy; if (bExact) elev = GetElevation(i, j, true); // Always use true elevation else elev = GetInterpolatedElevation(x, y, true); // Always use true elevation if (elev == INVALID_ELEVATION) { if (depth == 32) pBM->SetPixel32(i, bitmap_size.y - 1 - j, nodata); else pBM->SetPixel24(i, bitmap_size.y - 1 - j, nodata_24bit); has_invalid = true; continue; } const RGBi &rgb = color_map->ColorFromTable(elev); if (depth == 32) pBM->SetPixel32(i, bitmap_size.y - 1 - j, rgb); else pBM->SetPixel24(i, bitmap_size.y - 1 - j, rgb); } } VTLOG("Done.\n"); return has_invalid; }
// // A single thin strip polygon with a single texture. // void vtFence3d::AddFlatConnectionMesh(const FLine3 &p3) { vtMesh *pMesh = new vtMesh(osg::PrimitiveSet::TRIANGLE_STRIP, VT_TexCoords, 100); vtMaterialDescriptor *desc = GetMatDescriptor(m_Params.m_ConnectMaterial); if (!desc) { VTLOG1("Warning: could not find material:"); VTLOG1(m_Params.m_ConnectMaterial); VTLOG1("\n"); return; } FPoint2 uvscale = desc->GetUVScale(); float u = 0.0f; float vertical_meters = m_Params.m_fConnectTop - m_Params.m_fConnectBottom; float v_top; if (uvscale.y == -1) v_top = 1.0f; else v_top = vertical_meters / uvscale.y; uint i, npoints = p3.GetSize(); int vidx = 0; for (i = 0; i < npoints; i++) { pMesh->SetVtxPUV(vidx++, p3[i] + FPoint3(0, m_Params.m_fConnectBottom, 0), u, 0.0); pMesh->SetVtxPUV(vidx++, p3[i] + FPoint3(0, m_Params.m_fConnectTop, 0), u, v_top); if (i < npoints-1) { // increment u based on the length of each fence segment float length_meters = (p3[i+1] - p3[i]).Length(); u += (length_meters / desc->GetUVScale().x); } } pMesh->AddStrip2(npoints * 2, 0); m_pFenceGeom->AddMesh(pMesh, GetMatIndex(desc)); }
void App::display() { static int frame = 0; if (frame < 10) { frame++; VTLOG("Frame %d: ", frame); const GLubyte *ver = glGetString(GL_VERSION); if (ver != NULL) VTLOG1("Has context\n"); else { VTLOG1("No context\n"); return; } } vtGetScene()->DoUpdate(); // calls viewer->frame, etc. SDL_GL_SwapBuffers(); }
vtElevLayer::vtElevLayer(const DRECT &area, const IPoint2 &size, bool bFloats, float fScale, const vtProjection &proj) : vtLayer(LT_ELEVATION) { SetupDefaults(); VTLOG(" Constructing vtElevLayer of size %d x %d, floats %d\n", size.x, size.y, bFloats); m_pTin = NULL; m_pGrid = new vtElevationGrid(area, size, bFloats, proj); if (!m_pGrid->HasData()) VTLOG1(" Grid allocation failed.\n"); m_pGrid->SetScale(fScale); }
bool vtUtilityMap::ReadOSM(const char *pathname, bool progress_callback(int)) { // Avoid trouble with '.' and ',' in Europe // OSM always has English punctuation ScopedLocale normal_numbers(LC_NUMERIC, "C"); UtilOSMVisitor visitor(this); try { readXML(pathname, visitor, progress_callback); } catch (xh_exception &ex) { VTLOG1(ex.getFormattedMessage().c_str()); return false; } return true; }
void EnviroFrame::Snapshot(bool bNumbered) { VTLOG1("EnviroFrame::Snapshot\n"); wxString use_name; if (!bNumbered || (bNumbered && m_strSnapshotFilename == _T(""))) { // save current directory wxString path = wxGetCwd(); wxString filter = FSTRING_JPEG _T("|") FSTRING_BMP _T("|") FSTRING_PNG _T("|") FSTRING_TIF; EnableContinuousRendering(false); wxFileDialog saveFile(NULL, _("Save View Snapshot"), _T(""), _T(""), filter, wxFD_SAVE); bool bResult = (saveFile.ShowModal() == wxID_OK); EnableContinuousRendering(true); if (!bResult) { wxSetWorkingDirectory(path); // restore return; } if (bNumbered) { m_strSnapshotFilename = saveFile.GetPath(); m_iSnapshotNumber = 0; } else use_name = saveFile.GetPath(); } if (bNumbered) { // Append the number of the snapshot to the filename wxString start, number, extension; start = m_strSnapshotFilename.BeforeLast(_T('.')); extension = m_strSnapshotFilename.AfterLast(_T('.')); number.Printf(_T("_%03d."), m_iSnapshotNumber); m_iSnapshotNumber++; use_name = start + number + extension; } std::string Filename(use_name.mb_str(wxConvUTF8)); CScreenCaptureHandler::SetupScreenCapture(Filename); }
bool EnviroGUI::SaveStructures(bool bAskFilename) { VTLOG1("EnviroGUI::SaveStructures\n"); vtStructureLayer *st_layer = GetCurrentTerrain()->GetStructureLayer(); vtString fname = st_layer->GetFilename(); if (bAskFilename) { // save current directory wxString path = wxGetCwd(); wxString default_file(StartOfFilename(fname), wxConvUTF8); wxString default_dir(ExtractPath(fname, false), wxConvUTF8); EnableContinuousRendering(false); wxFileDialog saveFile(NULL, _("Save Built Structures Data"), default_dir, default_file, FSTRING_VTST, wxFD_SAVE | wxFD_OVERWRITE_PROMPT); bool bResult = (saveFile.ShowModal() == wxID_OK); EnableContinuousRendering(true); if (!bResult) { wxSetWorkingDirectory(path); // restore return false; } wxString str = saveFile.GetPath(); fname = str.mb_str(wxConvUTF8); st_layer->SetFilename(fname); } bool success = false; try { success = st_layer->WriteXML(fname); } catch (xh_io_exception &e) { string str = e.getFormattedMessage(); VTLOG(" Error: %s\n", str.c_str()); wxMessageBox(wxString(str.c_str(), wxConvUTF8), _("Error")); } if (success) st_layer->SetModified(false); return success; }
// Frame constructor vtFrame::vtFrame(wxFrame *parent, const wxString& title, const wxPoint& pos, const wxSize& size, long style): wxFrame(parent, -1, title, pos, size, style) { VTLOG(" constructing Frame (%x, title, pos, size, %x)\n", parent, style); m_bCloseOnIdle = false; // We definitely want full color and a 24-bit Z-buffer! int gl_attrib[7] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_BUFFER_SIZE, 24, WX_GL_DEPTH_SIZE, 24, 0 }; // Make a vtGLCanvas VTLOG1(" creating canvas\n"); m_canvas = new SimpleCanvas(this, -1, wxPoint(0, 0), wxSize(-1, -1), 0, _T("SimpleCanvas"), gl_attrib); // Show the frame Show(true); }
bool vtUtilityMap::TransformTo(vtProjection &proj) { // Convert from (usually, Wgs84 Geographic) to what we need. ScopedOCTransform trans(CreateCoordTransform(&m_proj, &proj)); if (!trans) { VTLOG1(" Couldn't transform coordinates\n"); return false; } for (uint i = 0; i < m_Poles.size(); i++) { vtPole *pole = m_Poles[i]; trans->Transform(1, &pole->m_p.x, &pole->m_p.y); } // Adopt new projection m_proj = proj; return true; }
void LayerDlg::OnZoomTo( wxCommandEvent &event ) { VTLOG1("LayerDlg::OnZoomTo\n"); osg::Node *pThing = GetNodeFromItem(m_item, true); // get container if (pThing) { FSphere sphere = GetGlobalBoundSphere(pThing); // get global bounds vtCamera *pCam = vtGetScene()->GetCamera(); // Put the camera a bit back from the sphere; sufficiently so that // the whole volume of the bounding sphere is visible. float smallest = min(pCam->GetFOV(), pCam->GetVertFOV()); float alpha = smallest / 2.0f; float distance = sphere.radius / tanf(alpha); pCam->Identity(); pCam->Rotate(FPoint3(1,0,0), -PID2f/2); // tilt down a little pCam->Translate(sphere.center); pCam->TranslateLocal(FPoint3(0.0f, 0.0f, distance)); } }
bool EnviroGUI::SaveVegetation(bool bAskFilename) { VTLOG1("EnviroGUI::SaveVegetation\n"); vtTerrain *pTerr = GetCurrentTerrain(); vtVegLayer *vlay = pTerr->GetVegLayer(); if (!vlay) return false; vtString fname = vlay->GetFilename(); if (bAskFilename) { // save current directory wxString path = wxGetCwd(); wxString default_file(StartOfFilename(fname), wxConvUTF8); wxString default_dir(ExtractPath(fname, false), wxConvUTF8); EnableContinuousRendering(false); wxFileDialog saveFile(NULL, _("Save Vegetation Data"), default_dir, default_file, FSTRING_VF, wxFD_SAVE); bool bResult = (saveFile.ShowModal() == wxID_OK); EnableContinuousRendering(true); if (!bResult) { wxSetWorkingDirectory(path); // restore return false; } wxString str = saveFile.GetPath(); fname = str.mb_str(wxConvUTF8); vlay->SetFilename(fname); } bool success = vlay->WriteVF(fname); if (success) vlay->SetModified(false); return true; }
void LayerDlg::OnLayerSaveAs( wxCommandEvent &event ) { VTLOG1("LayerDlg::OnLayerSaveAs\n"); LayerItemData *data = GetLayerDataFromItem(m_item); if (!data) return; bool bSaved = false; if (data->m_type == LT_STRUCTURE) bSaved = g_App.SaveStructures(true); // ask for filename if (data->m_type == LT_VEG) bSaved = g_App.SaveVegetation(true); // ask for filename if (data->m_type == LT_ABSTRACT) bSaved = SaveAbstractLayer(data->m_alay, true); // ask for filename // The filename may have changed if (bSaved) RefreshTreeContents(); }
void LayerDlg::OnLayerSave( wxCommandEvent &event ) { VTLOG1("LayerDlg::OnLayerSave\n"); LayerItemData *data = GetLayerDataFromItem(m_item); if (!data) return; bool bSaved = false; if (data->m_type == LT_STRUCTURE && data->m_slay != NULL) bSaved = g_App.SaveStructures(false); // don't ask for filename if (data->m_type == LT_VEG) bSaved = g_App.SaveVegetation(false); // don't ask for filename if (data->m_type == LT_ABSTRACT) bSaved = SaveAbstractLayer(data->m_alay, false); // don't ask for filename // Update the (*) next to the modified layer name if (bSaved) RefreshTreeContents(); }
void EnviroFrame::OnClose(wxCloseEvent &event) { VTLOG1("Got Close event.\n"); bool bReally = true; bool bUnsavedChanges = false; vtTerrain *terr = g_App.GetCurrentTerrain(); if (terr) { LayerSet &set = terr->GetLayers(); for (uint i = 0; i < set.size(); i++) { vtLayer *lay = set[i]; if (lay->GetModified()) bUnsavedChanges = true; } } if (event.CanVeto() && bUnsavedChanges) { // Pause rendering m_canvas->m_bRunning = false; int ret = wxMessageBox(_("Really Exit?"), _T("Enviro"), wxYES_NO); if (ret == wxNO) { event.Veto(); bReally = false; // Resume rendering m_canvas->m_bRunning = true; } } if (bReally) { DeleteCanvas(); Destroy(); } }
void MyTreeCtrl::RefreshTreeItems(Builder *pBuilder) { VTLOG1("Refreshing Tree Items:"); // Deleting the previous items can call OnSelChanged, which can cause VTB // to forget the active layer, so indicate that this is not user input. m_bUser = false; DeleteAllItems(); m_bUser = true; rootId = AddRoot(_("Layers")); SetItemBold(rootId); int image, imageSel; wxTreeItemId elevId = AddRootItem(MyTreeCtrl::TreeCtrlIcon_Grid, _("Elevation")); SetItemData(elevId, new MyTreeItemData(LT_ELEVATION)); wxTreeItemId imageId = AddRootItem(MyTreeCtrl::TreeCtrlIcon_Image, _("Images")); SetItemData(imageId, new MyTreeItemData(LT_IMAGE)); wxTreeItemId buildId = AddRootItem(MyTreeCtrl::TreeCtrlIcon_Building, _("Structures")); SetItemData(buildId, new MyTreeItemData(LT_STRUCTURE)); wxTreeItemId roadId = AddRootItem(MyTreeCtrl::TreeCtrlIcon_Road, _("Roads")); SetItemData(roadId, new MyTreeItemData(LT_ROAD)); wxTreeItemId vegId = AddRootItem(MyTreeCtrl::TreeCtrlIcon_Veg1, _("Vegetation")); SetItemData(vegId, new MyTreeItemData(LT_VEG)); wxTreeItemId waterId = AddRootItem(MyTreeCtrl::TreeCtrlIcon_Water, _("Water")); SetItemData(waterId, new MyTreeItemData(LT_WATER)); wxTreeItemId utilityId = AddRootItem(MyTreeCtrl::TreeCtrlIcon_Utility, _("Utilities")); SetItemData(utilityId, new MyTreeItemData(LT_UTILITY)); wxTreeItemId rawId = AddRootItem(MyTreeCtrl::TreeCtrlIcon_Raw, _("Raw")); SetItemData(rawId, new MyTreeItemData(LT_RAW)); image = TreeCtrlIcon_File; imageSel = TreeCtrlIcon_FileSelected; vtLayerPtr lp; int iLayers = 0; if (pBuilder) iLayers = pBuilder->NumLayers(); wxTreeItemId hSelectedItem; for (int i = 0; i < iLayers; i++) { lp = pBuilder->GetLayer(i); wxString str = MakeItemName(lp); wxTreeItemId hItem; switch (lp->GetType()) { case LT_ELEVATION: hItem = AppendItem(elevId, str, image, imageSel); break; case LT_IMAGE: hItem = AppendItem(imageId, str, image, imageSel); break; case LT_ROAD: hItem = AppendItem(roadId, str, image, imageSel); break; case LT_STRUCTURE: hItem = AppendItem(buildId, str, image, imageSel); break; case LT_VEG: hItem = AppendItem(vegId, str, image, imageSel); break; case LT_WATER: hItem = AppendItem(waterId, str, image, imageSel); break; case LT_UTILITY: hItem = AppendItem(utilityId, str, image, imageSel); break; case LT_RAW: hItem = AppendItem(rawId, str, image, imageSel); break; case LT_UNKNOWN: case LAYER_TYPES: // Keep picky compilers quiet. break; } if (hItem.IsOk()) { SetItemData(hItem, new MyTreeItemData(lp)); if (lp == pBuilder->GetActiveLayer()) hSelectedItem = hItem; if (!lp->GetVisible()) { SetItemFont(hItem, *wxITALIC_FONT); SetItemTextColour(hItem, wxColour(80,80,80)); } } } VTLOG(" %d layers.\n", iLayers); // Expand the groups after they have all their items. It doesn't work // to expand before, because then not all items are shown. Expand(elevId); Expand(imageId); Expand(roadId); Expand(buildId); Expand(vegId); Expand(waterId); Expand(utilityId); Expand(rawId); // Wait until all the groups are expanded, before highlighting the // selected item, so that it will definitely be in view. if (hSelectedItem.IsOk()) SelectItem(hSelectedItem); }
void vtFence3d::AddThickConnectionMesh(const FLine3 &p3) { vtMesh *pMesh = new vtMesh(osg::PrimitiveSet::TRIANGLE_STRIP, VT_TexCoords | VT_Normals, 100); // a solid block, with top/left/right sides, made of 3 strips vtMaterialDescriptor *desc = GetMatDescriptor(m_Params.m_ConnectMaterial); if (!desc) { VTLOG1("Warning: could not find material: "); VTLOG1(m_Params.m_ConnectMaterial); VTLOG1("\n"); return; } FPoint2 uvscale = desc->GetUVScale(); float vertical_meters = m_Params.m_fConnectTop - m_Params.m_fConnectBottom; float fWidthTop = m_Params.m_fConnectWidth / 2; float slope = m_Params.m_iConnectSlope / 180.0f * PIf; uint i, j, npoints = p3.GetSize(); float u = 0.0f; float v1, v2; for (i = 0; i < 3; i++) { float y1, y2; float z1, z2; FPoint3 pos, sideways, normal; int start = pMesh->NumVertices(); for (j = 0; j < npoints; j++) { // determine side-pointing vector if (j == 0) sideways = SidewaysVector(p3[j], p3[j+1]); else if (j > 0 && j < npoints-1) { AngleSideVector(p3[j-1], p3[j], p3[j+1], sideways); sideways = -sideways; // We want a vector pointing left, not right } else if (j == npoints-1) sideways = SidewaysVector(p3[j-1], p3[j]); // 'extra' elevation is added to maintain a constant top float fExtraElevation = 0.0f; if (m_Params.m_bConstantTop) fExtraElevation = m_fMaxGroundY - p3[j].y; float fVertical = vertical_meters + fExtraElevation; float fWidthBottom = fWidthTop + fVertical / tan(slope); // determine v texture coordinate switch (i) { case 0: // right side v1 = 0.0f; if (uvscale.y == -1) v2 = 1.0f; else v2 = fVertical / uvscale.y; break; case 1: // top v1 = 0.0f; if (uvscale.y == -1) v2 = 1.0f; else v2 = m_Params.m_fConnectWidth / uvscale.y; break; case 2: // left side v2 = 0.0f; if (uvscale.y == -1) v1 = 1.0f; else v1 = fVertical / uvscale.y; break; } // determine Y and Z values switch (i) { case 0: // right side y1 = m_Params.m_fConnectBottom; y2 = m_Params.m_fConnectTop + fExtraElevation; z1 = fWidthBottom; z2 = fWidthTop; break; case 1: // top y1 = m_Params.m_fConnectTop + fExtraElevation; y2 = m_Params.m_fConnectTop + fExtraElevation; z1 = fWidthTop; z2 = -fWidthTop; break; case 2: // left side y1 = m_Params.m_fConnectTop + fExtraElevation; y2 = m_Params.m_fConnectBottom; z1 = -fWidthTop; z2 = -fWidthBottom; break; } // determine vertex normal (used for shading and thickness) switch (i) { case 0: normal = sideways; break; // right case 1: normal.Set(0,1,0); break; // top: up case 2: normal = -sideways; break; // left } pos = p3[j]; pos.y += y2; pos += (sideways * z2); pMesh->AddVertexNUV(pos, normal, FPoint2(u, v2)); pos = p3[j]; pos.y += y1; pos += (sideways * z1); pMesh->AddVertexNUV(pos, normal, FPoint2(u, v1)); if (j < npoints-1) { // increment u based on the length of each fence segment float length_meters = (p3[j+1] - p3[j]).Length(); u += (length_meters / uvscale.x); } } pMesh->AddStrip2(npoints * 2, start); } // add cap at beginning u = m_Params.m_fConnectWidth / desc->GetUVScale().x; v2 = vertical_meters / uvscale.y; int start = pMesh->AddVertex(pMesh->GetVtxPos(npoints*2*2+1)); pMesh->AddVertex(pMesh->GetVtxPos(npoints*2*2)); pMesh->AddVertex(pMesh->GetVtxPos(0)); pMesh->AddVertex(pMesh->GetVtxPos(1)); pMesh->SetVtxNormal(start+0, p3[0] - p3[1]); pMesh->SetVtxNormal(start+1, p3[0] - p3[1]); pMesh->SetVtxNormal(start+2, p3[0] - p3[1]); pMesh->SetVtxNormal(start+3, p3[0] - p3[1]); pMesh->SetVtxTexCoord(start+0, FPoint2(u, 0.0f)); pMesh->SetVtxTexCoord(start+1, FPoint2(u, v2)); pMesh->SetVtxTexCoord(start+2, FPoint2(0.0f, 0.0f)); pMesh->SetVtxTexCoord(start+3, FPoint2(0.0f, v2)); pMesh->AddStrip2(4, start); // add cap at end start = pMesh->AddVertex(pMesh->GetVtxPos(npoints*2-2)); pMesh->AddVertex(pMesh->GetVtxPos(npoints*2-1)); pMesh->AddVertex(pMesh->GetVtxPos(npoints*3*2-1)); pMesh->AddVertex(pMesh->GetVtxPos(npoints*3*2-2)); pMesh->SetVtxNormal(start+0, p3[npoints-1] - p3[npoints-2]); pMesh->SetVtxNormal(start+1, p3[npoints-1] - p3[npoints-2]); pMesh->SetVtxNormal(start+2, p3[npoints-1] - p3[npoints-2]); pMesh->SetVtxNormal(start+3, p3[npoints-1] - p3[npoints-2]); pMesh->SetVtxTexCoord(start+0, FPoint2(0.0f, 0.0f)); pMesh->SetVtxTexCoord(start+1, FPoint2(0.0f, v2)); pMesh->SetVtxTexCoord(start+2, FPoint2(u, 0.0f)); pMesh->SetVtxTexCoord(start+3, FPoint2(u, v2)); pMesh->AddStrip2(4, start); m_pFenceGeom->AddMesh(pMesh, GetMatIndex(desc)); }
void EnviroFrame::RefreshToolbar() { if (!m_pToolbar) // safety check return; // remove any existing buttons int count = m_pToolbar->GetToolsCount(); #ifdef __WXMAC__ // Nino says: I spent a long time with this one, the issue was definitely // deep in wxMac, but I don't remember, nor want to repeat it :). Can we // #ifdef __WXMAC__ for the time being to revisit it after Xcode is working? while (count >= 1) { m_pToolbar->DeleteToolByPos(count-1); count = m_pToolbar->GetToolsCount(); } m_pToolbar->Realize(); AddTool(ID_TOOLS_SELECT, wxBITMAP(select), _("Select"), true); #else if (!count) { AddTool(ID_TOOLS_SELECT, wxBITMAP(select), _("Select"), true); count = 1; } while (count > 1) { m_pToolbar->DeleteToolByPos(count-1); count = m_pToolbar->GetToolsCount(); } #endif bool bEarth = (g_App.m_state == AS_Orbit); bool bTerr = (g_App.m_state == AS_Terrain); if (bTerr) { AddTool(ID_TOOLS_SELECT_BOX, wxBITMAP(select_box), _("Select Box"), true); if (g_Options.m_bShowToolsCulture) { AddTool(ID_TOOLS_SELECT_MOVE, wxBITMAP(select_move), _("Select and Move"), true); AddTool(ID_TOOLS_MOVE, wxBITMAP(move), _("Move Objects"), true); AddTool(ID_TOOLS_FENCES, wxBITMAP(fence), _("Create Fences"), true); AddTool(ID_TOOLS_BUILDINGS, wxBITMAP(building), _("Create Buildings"), true); AddTool(ID_TOOLS_POWER, wxBITMAP(route), _("Create Powerlines"), true); AddTool(ID_TOOLS_PLANTS, wxBITMAP(tree), _("Create Plants"), true); } AddTool(ID_TOOLS_POINTS, wxBITMAP(placemark), _("Create Points"), true); if (g_Options.m_bShowToolsCulture) { AddTool(ID_TOOLS_INSTANCES, wxBITMAP(instances), _("Create Instances"), true); AddTool(ID_TOOLS_VEHICLES, wxBITMAP(vehicles), _("Create Vehicles"), true); } AddTool(ID_TOOLS_NAVIGATE, wxBITMAP(nav), _("Navigate"), true); } if (bTerr || bEarth) { AddTool(ID_TOOLS_MEASURE, wxBITMAP(distance), _("Measure Distance"), true); } if (bTerr) { m_pToolbar->AddSeparator(); AddTool(ID_VIEW_PROFILE, wxBITMAP(view_profile), _("Elevation Profile"), true); AddTool(ID_TOOLS_CONSTRAIN, wxBITMAP(bld_corner), _("Constrain Angles"), true); } if (g_Options.m_bShowToolsSnapshot) { m_pToolbar->AddSeparator(); AddTool(ID_VIEW_SNAPSHOT, wxBITMAP(snap), _("Snapshot"), false); AddTool(ID_VIEW_SNAP_AGAIN, wxBITMAP(snap_num), _("Numbered Snapshot"), false); } if (bTerr || bEarth) { m_pToolbar->AddSeparator(); AddTool(ID_FILE_LAYERS, wxBITMAP(layers), _("Show Layer Dialog"), false); } if (bTerr) { m_pToolbar->AddSeparator(); AddTool(ID_VIEW_MAINTAIN, wxBITMAP(maintain), _("Maintain Height"), true); AddTool(ID_VIEW_FASTER, wxBITMAP(nav_fast), _("Fly Faster"), false); AddTool(ID_VIEW_SLOWER, wxBITMAP(nav_slow), _("Fly Slower"), false); AddTool(ID_VIEW_SETTINGS, wxBITMAP(nav_set), _("Camera Dialog"), false); AddTool(ID_VIEW_LOCATIONS, wxBITMAP(loc), _("Locations"), false); } if (m_bEnableEarth) { m_pToolbar->AddSeparator(); if (bTerr) { AddTool(ID_SCENE_EPHEMERIS, wxBITMAP(ephemeris), _("Ephemeris"), false); AddTool(ID_SCENE_SPACE, wxBITMAP(space), _("Go to Space"), false); } AddTool(ID_SCENE_TERRAIN, wxBITMAP(terrain), _("Go to Terrain"), false); if (bEarth) { m_pToolbar->AddSeparator(); AddTool(ID_EARTH_SHOWSHADING, wxBITMAP(sun), _("Show Sunlight"), true); AddTool(ID_EARTH_SHOWAXES, wxBITMAP(axes), _("Axes"), true); AddTool(ID_EARTH_TILT, wxBITMAP(tilt), _("Tilt"), true); AddTool(ID_EARTH_UNFOLD, wxBITMAP(unfold), _("Unfold"), true); } } if (g_Options.m_bShowToolsTime) { m_pToolbar->AddSeparator(); AddTool(ID_TIME_DIALOG, wxBITMAP(time), _("Time"), false); AddTool(ID_TIME_FASTER, wxBITMAP(faster), _("Time Faster"), false); AddTool(ID_TIME_STOP, wxBITMAP(stop), _("Time Stop"), false); } m_pToolbar->AddSeparator(); AddTool(ID_SCENE_SCENEGRAPH, wxBITMAP(sgraph), _("Scene Graph"), false); VTLOG1("Realize toolbar.\n"); m_pToolbar->Realize(); // "commit" all changes made to wxAuiManager wxAuiPaneInfo &api = m_mgr.GetPane(wxT("toolbar")); if (api.IsOk()) { wxSize best = m_pToolbar->GetBestSize(); api.MinSize(best); m_mgr.Update(); } }
void EnviroFrame::CreateUI() { VTLOG1("Frame window: creating menus and toolbars.\n"); CreateMenus(); // Create StatusBar m_pStatusBar = new MyStatusBar(this); SetStatusBar(m_pStatusBar); m_pStatusBar->Show(); m_pStatusBar->UpdateText(); PositionStatusBar(); #ifdef VTP_NVIDIA_PERFORMANCE_MONITORING // Stop crash in update toolbar m_pCameraDlg = NULL; m_pLocationDlg = NULL; m_pLODDlg = NULL; m_pPerformanceMonitorDlg = NULL; #endif // An array of values to tell wxWidgets how to make our OpenGL context. std::vector<int> gl_attribs; gl_attribs.push_back(WX_GL_RGBA); // Full color gl_attribs.push_back(WX_GL_DOUBLEBUFFER); gl_attribs.push_back(WX_GL_BUFFER_SIZE); // 24-bit Z-buffer gl_attribs.push_back(24); gl_attribs.push_back(WX_GL_DEPTH_SIZE); gl_attribs.push_back(24); VTLOG("Anti-aliasing multisamples: %d\n", g_Options.m_iMultiSamples); #if wxCHECK_VERSION(2, 9, 0) if (g_Options.m_iMultiSamples > 0) { gl_attribs.push_back(WX_GL_SAMPLE_BUFFERS); gl_attribs.push_back(1); gl_attribs.push_back(WX_GL_SAMPLES); gl_attribs.push_back(g_Options.m_iMultiSamples); } #endif if (g_Options.m_bStereo && g_Options.m_iStereoMode == 1) // 1 = Quad-buffer stereo { gl_attribs.push_back(WX_GL_STEREO); } // Zero terminates the array gl_attribs.push_back(0); VTLOG("Frame window: creating view canvas.\n"); m_canvas = new EnviroCanvas(this, -1, wxPoint(0, 0), wxSize(-1, -1), 0, _T("vtGLCanvas"), &gl_attribs.front()); // Show the frame VTLOG("Showing the main frame\n"); Show(true); VTLOG("Constructing dialogs\n"); m_pBuildingDlg = new BuildingDlg3d(this, -1, _("Building Properties")); m_pCameraDlg = new CameraDlg(this, -1, _("Camera-View")); m_pDistanceDlg = new DistanceDlg3d(this, -1, _("Distance")); m_pEphemDlg = new EphemDlg(this, -1, _("Ephemeris")); m_pFenceDlg = new LinearStructureDlg3d(this, -1, _("Linear Structures")); m_pInstanceDlg = new InstanceDlg3d(this, this, -1, _("Instances"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); m_pTagDlg = new TagDlg(this, -1, _("Tags"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); m_pTagDlg->SetSize(440,80); m_pLODDlg = new LODDlg(this, -1, _("Terrain LOD Info"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); // m_pLODDlg->Show(); // Enable this to see the LOD dialog immediately m_pPlantDlg = new PlantDlg(this, -1, _("Plants")); m_pPlantDlg->ShowOnlyAvailableSpecies(g_Options.m_bOnlyAvailableSpecies); m_pPlantDlg->SetLang(wxGetApp().GetLanguageCode()); m_pLocationDlg = new LocationDlg(this, -1, _("Locations"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); m_pSceneGraphDlg = new SceneGraphDlg(this, -1, _("Scene Graph"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); m_pSceneGraphDlg->SetSize(450, 600); m_pTimeDlg = new TimeDlg(this, -1, _("Time")); m_pUtilDlg = new UtilDlg(this, -1, _("Utility Poles")); m_pScenarioSelectDialog = new ScenarioSelectDialog(this, -1, _("Scenarios")); m_pVehicleDlg = new VehicleDlg(this, -1, _("Vehicles")); m_pDriveDlg = new DriveDlg(this); m_pProfileDlg = NULL; #ifdef VTP_NVIDIA_PERFORMANCE_MONITORING m_pPerformanceMonitorDlg = new CPerformanceMonitorDialog(this, wxID_ANY, _("Performance Monitor")); #endif m_pVIADlg = new VIADlg(this); #if wxVERSION_NUMBER < 2900 // before 2.9.0 if (m_canvas) m_canvas->SetCurrent(); #else // Still need to do a "SetCurrent" here? It's more complicated now in wx 2.9.x, // and it's probably already taken care of by GraphicsWindowWX? #endif m_mgr.AddPane(m_canvas, wxAuiPaneInfo(). Name(wxT("canvas")).Caption(wxT("Canvas")). CenterPane()); m_mgr.Update(); m_pLayerDlg = new LayerDlg(this, -1, _("Layers"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); m_pLayerDlg->SetSize(500, -1); m_mgr.AddPane(m_pLayerDlg, wxAuiPaneInfo(). Name(_T("layers")).Caption(_("Layers")). Left()); m_mgr.Update(); }
void vtFence3d::AddProfileConnectionMesh(const FLine3 &p3) { uint i, j, npoints = p3.GetSize(), prof_points = m_Profile.GetSize(); // Must have at least 2 points in the profile if (prof_points < 2) return; // Each segment of the profile becomes a long triangle strip. // If there are no shared vertices between segments, the number of // vertices is, for a profile of N points and a line of P points: // P * (N-1) * 2, for the sides // N*2, for the end caps (or more if we have to tessellate) // int iEstimateVerts = npoints * (prof_points-1) * 2 + (prof_points * 2); vtMesh *pMesh = new vtMesh(osg::PrimitiveSet::TRIANGLE_STRIP, VT_TexCoords | VT_Normals, iEstimateVerts); vtMaterialDescriptor *desc = GetMatDescriptor(m_Params.m_ConnectMaterial); if (!desc) { VTLOG1("Warning: could not find material: "); VTLOG1(m_Params.m_ConnectMaterial); VTLOG1("\n"); return; } FPoint2 uvscale = desc->GetUVScale(); // determine side-pointing vector vtArray<float> ExtraElevation(npoints); FLine3 sideways(npoints); for (j = 0; j < npoints; j++) { // determine side-pointing vector if (j == 0) sideways[j] = SidewaysVector(p3[j], p3[j+1]); else if (j > 0 && j < npoints-1) { AngleSideVector(p3[j-1], p3[j], p3[j+1], sideways[j]); sideways[j] = -sideways[j]; // We want a vector pointing left, not right } else if (j == npoints-1) sideways[j] = SidewaysVector(p3[j-1], p3[j]); ExtraElevation[j] = 0.0f; if (m_Params.m_bConstantTop) ExtraElevation[j] = m_fMaxGroundY - p3[j].y; } float u; float v1, v2; for (i = 0; i < prof_points-1; i++) { float y1, y2; float z1, z2; FPoint3 pos, normal; // determine v texture coordinate float seg_length = m_Profile.SegmentLength(i); if (uvscale.y == -1) { v1 = 0.0f; v2 = 1.0f; } else { if (i == 0) { v1 = 0.0f; v2 = seg_length / uvscale.y; } else { v1 = v2; v2 += seg_length / uvscale.y; } } // determine Y and Z values y1 = m_Profile[i].y; y2 = m_Profile[i+1].y; z1 = m_Profile[i].x; z2 = m_Profile[i+1].x; u = 0.0f; int start = pMesh->NumVertices(); for (j = 0; j < npoints; j++) { // determine vertex normal (for shading) float diffy = y2-y1; float diffz = z2-z1; float dy = -diffz; float dz = diffy; FPoint3 n1, n2; n1.Set(0, y1, 0); n1 += (sideways[j] * z1); n2.Set(0, y1 + dy, 0); n2 += (sideways[j] * (z1 + dz)); normal = n2 - n1; normal.Normalize(); // determine the two points of this segment edge, and add them pos = p3[j]; pos.y += y2; pos.y += ExtraElevation[j]; pos += (sideways[j] * z2); pMesh->AddVertexNUV(pos, normal, FPoint2(u, v2)); pos = p3[j]; pos.y += y1; pos.y += ExtraElevation[j]; pos += (sideways[j] * z1); pMesh->AddVertexNUV(pos, normal, FPoint2(u, v1)); if (j < npoints-1) { // increment u based on the length of each fence segment float length_meters = (p3[j+1] - p3[j]).Length(); u += (length_meters / uvscale.x); } } pMesh->AddStrip2(npoints * 2, start); } // We must assume the profile is interpreted as a closed polygon, which // may not be convex. Hence it must be triangulated. FLine2 result; Triangulate_f::Process(m_Profile, result); uint tcount = result.GetSize()/3; int ind[3]; int line_point; FPoint3 normal; // add cap at beginning line_point = 0; normal = p3[0] - p3[1]; normal.Normalize(); for (i=0; i<tcount; i++) { for (j = 0; j < 3; j++) { FPoint2 p2 = result[i*3+j]; FPoint3 pos = p3[line_point]; pos.y += p2.y; pos.y += ExtraElevation[line_point]; pos += (sideways[line_point] * p2.x); FPoint2 uv = p2; if (uvscale.y != -1) uv.Div(uvscale); // divide meters by [meters/uv] to get uv ind[j] = pMesh->AddVertexNUV(pos, normal, uv); } pMesh->AddTri(ind[0], ind[1], ind[2]); } // add cap at end line_point = npoints-1; normal = p3[npoints-1] - p3[npoints-2]; normal.Normalize(); for (i=0; i<tcount; i++) { for (j = 0; j < 3; j++) { FPoint2 p2 = result[i*3+j]; FPoint3 pos = p3[line_point]; pos.y += p2.y; pos.y += ExtraElevation[line_point]; pos += (sideways[line_point] * p2.x); FPoint2 uv = p2; if (uvscale.y != -1) uv.Div(uvscale); // divide meters by [meters/uv] to get uv ind[j] = pMesh->AddVertexNUV(pos, normal, uv); } pMesh->AddTri(ind[0], ind[2], ind[1]); } m_pFenceGeom->AddMesh(pMesh, GetMatIndex(desc)); }
bool EnviroFrame::LoadTerrainLayer(vtString &fname) { VTLOG("LoadTerrainLayer '%s'\n", (const char *) fname); vtTerrain *pTerr = g_App.GetCurrentTerrain(); bool success = false; vtString ext = GetExtension(fname); if (!ext.CompareNoCase(".vtst")) { MakeRelativeToDataPath(fname, "BuildingData"); vtStructureLayer *st_layer = pTerr->NewStructureLayer(); st_layer->SetLayerName(fname); if (!st_layer->Load()) { VTLOG("\tCouldn't load structures.\n"); // Removing the layer deletes it, by dereference. pTerr->GetLayers().Remove(st_layer); } else { pTerr->CreateStructures(st_layer); success = true; } } else if (!ext.CompareNoCase(".vf")) { MakeRelativeToDataPath(fname, "PlantData"); vtVegLayer *v_layer = pTerr->LoadVegetation(fname); if (v_layer) success = true; } else if (!ext.CompareNoCase(".shp")) { bool bRelative = MakeRelativeToDataPath(fname, "PointData"); if (!bRelative) bRelative = MakeRelativeToDataPath(fname, ""); if (bRelative) VTLOG("Shortened path to '%s'\n", (const char *) fname); vtAbstractLayer *ab_layer = pTerr->NewAbstractLayer(); ab_layer->SetLayerName(fname); // TODO here: progress dialog on load? if (ab_layer->Load(pTerr->GetProjection(), NULL)) { VTLOG("Successfully read features from file '%s'\n", (const char *) fname); // Abstract layers aren't constructed yet, giving us a chance to ask // for styling. vtTagArray &props = ab_layer->Props(); StyleDlg dlg(NULL, -1, _("Style"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); dlg.SetFeatureSet(ab_layer->GetFeatureSet()); dlg.SetOptions(props); if (dlg.ShowModal() == wxID_OK) { // Copy all the style attributes to the new featureset VTLOG1(" Setting featureset properties.\n"); dlg.GetOptions(props); pTerr->CreateAbstractLayerVisuals(ab_layer); success = true; } } if (!success) { VTLOG("Couldn't read features from file '%s'\n", (const char *) fname); pTerr->RemoveLayer(ab_layer); } } else if (!ext.CompareNoCase(".itf")) { MakeRelativeToDataPath(fname, "Elevation"); vtTagArray tags; tags.SetValueString("Type", TERR_LTYPE_ELEVATION); tags.SetValueString("Filename", fname); tags.SetValueFloat(STR_OPACITY, 1.0f); tags.SetValueFloat(STR_GEOTYPICAL_SCALE, 10.0f); TinTextureDlg dlg(this, -1, _("TIN Texture")); dlg.SetOptions(tags); if (dlg.ShowModal() == wxID_OK) { dlg.GetOptions(tags); success = pTerr->CreateElevLayerFromTags(tags); } } else if (!ext.CompareNoCase(".tif")) { MakeRelativeToDataPath(fname, "GeoSpecific"); vtImageLayer *im_layer = pTerr->NewImageLayer(); im_layer->Props().SetValueString("Filename", fname); if (!im_layer->Load()) { VTLOG("\tCouldn't load image layer.\n"); // Removing the layer deletes it, by dereference. pTerr->GetLayers().Remove(im_layer); } else { pTerr->AddMultiTextureOverlay(im_layer); success = true; } } return success; }
EnviroCanvas::EnviroCanvas(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name, int *gl_attrib): vtGLCanvas(parent, id, pos, size, style, name, gl_attrib) { VTLOG1("EnviroCanvas constructor\n"); }
/** Diagnostic function to help debugging: Log the scene graph from a given node downwards. */ void vtLogGraph(osg::Node *node, bool bExtents, bool bRefCounts, int indent) { for (int i = 0; i < indent; i++) VTLOG1(" "); if (node) { VTLOG("<%x>", node); if (dynamic_cast<osg::PositionAttitudeTransform*>(node)) VTLOG1(" (PositionAttitudeTransform)"); else if (dynamic_cast<osg::MatrixTransform*>(node)) VTLOG1(" (MatrixTransform)"); else if (dynamic_cast<osg::AutoTransform*>(node)) VTLOG1(" (AutoTransform)"); else if (dynamic_cast<osg::Transform*>(node)) VTLOG1(" (Transform)"); else if (dynamic_cast<osg::TexGenNode*>(node)) VTLOG1(" (TexGenNode)"); else if (dynamic_cast<osg::Switch*>(node)) VTLOG1(" (Switch)"); else if (dynamic_cast<osg::Sequence*>(node)) VTLOG1(" (Sequence)"); else if (dynamic_cast<osg::Projection*>(node)) VTLOG1(" (Projection)"); else if (dynamic_cast<osg::OccluderNode*>(node)) VTLOG1(" (OccluderNode)"); else if (dynamic_cast<osg::LightSource*>(node)) VTLOG1(" (LightSource)"); else if (dynamic_cast<osg::LOD*>(node)) VTLOG1(" (LOD)"); else if (dynamic_cast<osg::CoordinateSystemNode*>(node)) VTLOG1(" (CoordinateSystemNode)"); else if (dynamic_cast<osg::ClipNode*>(node)) VTLOG1(" (ClipNode)"); else if (dynamic_cast<osg::ClearNode*>(node)) VTLOG1(" (ClearNode)"); else if (dynamic_cast<osg::Group*>(node)) VTLOG1(" (Group)"); else if (dynamic_cast<osg::Billboard*>(node)) VTLOG1(" (Billboard)"); else if (dynamic_cast<osg::Geode*>(node)) VTLOG1(" (Geode)"); else if (dynamic_cast<osgParticle::ModularEmitter*>(node)) VTLOG1(" (Geode)"); else if (dynamic_cast<osgParticle::ParticleSystemUpdater*>(node)) VTLOG1(" (Geode)"); else VTLOG1(" (non-node!)"); VTLOG(" '%s'", node->getName().c_str()); if (node->getNodeMask() != 0xffffffff) VTLOG(" mask=%x", node->getNodeMask()); if (node->getStateSet() != NULL) VTLOG(" (has stateset)"); if (bExtents) { const osg::BoundingSphere &bs = node->getBound(); if (bs._radius != -1) VTLOG(" (bs: %.1f %.1f %.1f %1.f)", bs._center[0], bs._center[1], bs._center[2], bs._radius); } if (bRefCounts) { VTLOG(" {rc:%d}", node->referenceCount()); } VTLOG1("\n"); } else VTLOG1("<null>\n"); osg::MatrixTransform *mt = dynamic_cast<osg::MatrixTransform*>(node); if (mt) { for (int i = 0; i < indent+1; i++) VTLOG1(" "); osg::Vec3 v = mt->getMatrix().getTrans(); VTLOG("[Pos %.2f %.2f %.2f]\n", v.x(), v.y(), v.z()); } osg::Group *grp = dynamic_cast<osg::Group*>(node); if (grp) { for (uint i = 0; i < grp->getNumChildren(); i++) vtLogGraph(grp->getChild(i), bExtents, bRefCounts, indent+2); } osg::Geode *geode = dynamic_cast<osg::Geode*>(node); if (geode) { for (uint i = 0; i < geode->getNumDrawables(); i++) { osg::Geometry *geo = dynamic_cast<osg::Geometry *>(geode->getDrawable(i)); if (!geo) continue; osg::StateSet *stateset = geo->getStateSet(); if (!stateset) continue; for (int j = 0; j < indent+3; j++) VTLOG1(" "); VTLOG("drawable %d: geometry %x, stateset %x", i, geo, stateset); osg::StateAttribute *state = stateset->getAttribute(osg::StateAttribute::MATERIAL); if (state) { osg::Material *mat = dynamic_cast<osg::Material *>(state); if (mat) VTLOG(", mat %x", mat); } VTLOG1("\n"); } } }
bool vtImageGeo::ReadTIF(const char *filename, bool progress_callback(int)) { // Use GDAL to read a TIF file (or any other format that GDAL is // configured to read) into this OSG image. bool bRet = true; vtString message; setFileName(filename); g_GDALWrapper.RequestGDALFormats(); GDALDataset *pDataset = NULL; GDALRasterBand *pBand; GDALRasterBand *pRed = NULL; GDALRasterBand *pGreen = NULL; GDALRasterBand *pBlue = NULL; GDALRasterBand *pAlpha = NULL; GDALColorTable *pTable; uchar *pScanline = NULL; uchar *pRedline = NULL; uchar *pGreenline = NULL; uchar *pBlueline = NULL; uchar *pAlphaline = NULL; CPLErr Err; bool bColorPalette = false; int iXSize, iYSize; int nxBlocks, nyBlocks; int xBlockSize, yBlockSize; try { pDataset = (GDALDataset *) GDALOpen(filename, GA_ReadOnly); if(pDataset == NULL ) throw "Couldn't open that file."; // Get size iXSize = pDataset->GetRasterXSize(); iYSize = pDataset->GetRasterYSize(); // Try getting CRS vtProjection temp; bool bHaveProj = false; const char *pProjectionString = pDataset->GetProjectionRef(); if (pProjectionString) { OGRErr err = temp.importFromWkt((char**)&pProjectionString); if (err == OGRERR_NONE) { m_proj = temp; bHaveProj = true; } } if (!bHaveProj) { // check for existence of .prj file bool bSuccess = temp.ReadProjFile(filename); if (bSuccess) { m_proj = temp; bHaveProj = true; } } // Try getting extents double affineTransform[6]; if (pDataset->GetGeoTransform(affineTransform) == CE_None) { m_extents.left = affineTransform[0]; m_extents.right = m_extents.left + affineTransform[1] * iXSize; m_extents.top = affineTransform[3]; m_extents.bottom = m_extents.top + affineTransform[5] * iYSize; } // Raster count should be 3 for colour images (assume RGB) int iRasterCount = pDataset->GetRasterCount(); if (iRasterCount != 1 && iRasterCount != 3 && iRasterCount != 4) { message.Format("Image has %d bands (not 1, 3, or 4).", iRasterCount); throw (const char *)message; } if (iRasterCount == 1) { pBand = pDataset->GetRasterBand(1); // Check the band's data type GDALDataType dtype = pBand->GetRasterDataType(); if (dtype != GDT_Byte) { message.Format("Band is of type %s, but we support type Byte.", GDALGetDataTypeName(dtype)); throw (const char *)message; } GDALColorInterp ci = pBand->GetColorInterpretation(); if (ci == GCI_PaletteIndex) { if (NULL == (pTable = pBand->GetColorTable())) throw "Couldn't get color table."; bColorPalette = true; } else if (ci == GCI_GrayIndex) { // we will assume 0-255 is black to white } else throw "Unsupported color interpretation."; pBand->GetBlockSize(&xBlockSize, &yBlockSize); nxBlocks = (iXSize + xBlockSize - 1) / xBlockSize; nyBlocks = (iYSize + yBlockSize - 1) / yBlockSize; if (NULL == (pScanline = new uchar[xBlockSize * yBlockSize])) throw "Couldnt allocate scan line."; } if (iRasterCount == 3) { for (int i = 1; i <= 3; i++) { pBand = pDataset->GetRasterBand(i); // Check the band's data type GDALDataType dtype = pBand->GetRasterDataType(); if (dtype != GDT_Byte) { message.Format("Band is of type %s, but we support type Byte.", GDALGetDataTypeName(dtype)); throw (const char *)message; } switch (pBand->GetColorInterpretation()) { case GCI_RedBand: pRed = pBand; break; case GCI_GreenBand: pGreen = pBand; break; case GCI_BlueBand: pBlue = pBand; break; } } if ((NULL == pRed) || (NULL == pGreen) || (NULL == pBlue)) throw "Couldn't find bands for Red, Green, Blue."; pRed->GetBlockSize(&xBlockSize, &yBlockSize); nxBlocks = (iXSize + xBlockSize - 1) / xBlockSize; nyBlocks = (iYSize + yBlockSize - 1) / yBlockSize; pRedline = new uchar[xBlockSize * yBlockSize]; pGreenline = new uchar[xBlockSize * yBlockSize]; pBlueline = new uchar[xBlockSize * yBlockSize]; } if (iRasterCount == 4) { #if VTDEBUG VTLOG1("Band interpretations:"); #endif for (int i = 1; i <= 4; i++) { pBand = pDataset->GetRasterBand(i); // Check the band's data type GDALDataType dtype = pBand->GetRasterDataType(); if (dtype != GDT_Byte) { message.Format("Band is of type %s, but we support type Byte.", GDALGetDataTypeName(dtype)); throw (const char *)message; } GDALColorInterp ci = pBand->GetColorInterpretation(); #if VTDEBUG VTLOG(" %d", ci); #endif switch (ci) { case GCI_RedBand: pRed = pBand; break; case GCI_GreenBand: pGreen = pBand; break; case GCI_BlueBand: pBlue = pBand; break; case GCI_AlphaBand: pAlpha = pBand; break; case GCI_Undefined: // If we have four bands: R,G,B,undefined, then assume that // the undefined one is actually alpha if (pRed && pGreen && pBlue && !pAlpha) pAlpha = pBand; break; } } #if VTDEBUG VTLOG1("\n"); #endif if ((NULL == pRed) || (NULL == pGreen) || (NULL == pBlue) || (NULL == pAlpha)) throw "Couldn't find bands for Red, Green, Blue, Alpha."; pRed->GetBlockSize(&xBlockSize, &yBlockSize); nxBlocks = (iXSize + xBlockSize - 1) / xBlockSize; nyBlocks = (iYSize + yBlockSize - 1) / yBlockSize; pRedline = new uchar[xBlockSize * yBlockSize]; pGreenline = new uchar[xBlockSize * yBlockSize]; pBlueline = new uchar[xBlockSize * yBlockSize]; pAlphaline = new uchar[xBlockSize * yBlockSize]; } // Allocate the image buffer if (iRasterCount == 4) { Create(iXSize, iYSize, 32); } else if (iRasterCount == 3 || bColorPalette) { Create(iXSize, iYSize, 24); } else if (iRasterCount == 1) Create(iXSize, iYSize, 8); // Read the data #if LOG_IMAGE_LOAD VTLOG("Reading the image data (%d x %d pixels)\n", iXSize, iYSize); #endif int x, y; int ixBlock, iyBlock; int nxValid, nyValid; int iY, iX; RGBi rgb; RGBAi rgba; if (iRasterCount == 1) { GDALColorEntry Ent; for (iyBlock = 0; iyBlock < nyBlocks; iyBlock++) { if (progress_callback != NULL) progress_callback(iyBlock * 100 / nyBlocks); y = iyBlock * yBlockSize; for (ixBlock = 0; ixBlock < nxBlocks; ixBlock++) { x = ixBlock * xBlockSize; Err = pBand->ReadBlock(ixBlock, iyBlock, pScanline); if (Err != CE_None) throw "Problem reading the image data."; // Compute the portion of the block that is valid // for partial edge blocks. if ((ixBlock+1) * xBlockSize > iXSize) nxValid = iXSize - ixBlock * xBlockSize; else nxValid = xBlockSize; if( (iyBlock+1) * yBlockSize > iYSize) nyValid = iYSize - iyBlock * yBlockSize; else nyValid = yBlockSize; for( iY = 0; iY < nyValid; iY++ ) { for( iX = 0; iX < nxValid; iX++ ) { if (bColorPalette) { pTable->GetColorEntryAsRGB(pScanline[iY * xBlockSize + iX], &Ent); rgb.r = (uchar) Ent.c1; rgb.g = (uchar) Ent.c2; rgb.b = (uchar) Ent.c3; SetPixel24(x + iX, y + iY, rgb); } else SetPixel8(x + iX, y + iY, pScanline[iY * xBlockSize + iX]); } } } } } if (iRasterCount >= 3) { for (iyBlock = 0; iyBlock < nyBlocks; iyBlock++) { if (progress_callback != NULL) progress_callback(iyBlock * 100 / nyBlocks); y = iyBlock * yBlockSize; for (ixBlock = 0; ixBlock < nxBlocks; ixBlock++) { x = ixBlock * xBlockSize; Err = pRed->ReadBlock(ixBlock, iyBlock, pRedline); if (Err != CE_None) throw "Cannot read data."; Err = pGreen->ReadBlock(ixBlock, iyBlock, pGreenline); if (Err != CE_None) throw "Cannot read data."; Err = pBlue->ReadBlock(ixBlock, iyBlock, pBlueline); if (Err != CE_None) throw "Cannot read data."; if (iRasterCount == 4) { Err = pAlpha->ReadBlock(ixBlock, iyBlock, pAlphaline); if (Err != CE_None) throw "Cannot read data."; } // Compute the portion of the block that is valid // for partial edge blocks. if ((ixBlock+1) * xBlockSize > iXSize) nxValid = iXSize - ixBlock * xBlockSize; else nxValid = xBlockSize; if( (iyBlock+1) * yBlockSize > iYSize) nyValid = iYSize - iyBlock * yBlockSize; else nyValid = yBlockSize; for (int iY = 0; iY < nyValid; iY++) { for (int iX = 0; iX < nxValid; iX++) { if (iRasterCount == 3) { rgb.r = pRedline[iY * xBlockSize + iX]; rgb.g = pGreenline[iY * xBlockSize + iX]; rgb.b = pBlueline[iY * xBlockSize + iX]; SetPixel24(x + iX, y + iY, rgb); } else if (iRasterCount == 4) { rgba.r = pRedline[iY * xBlockSize + iX]; rgba.g = pGreenline[iY * xBlockSize + iX]; rgba.b = pBlueline[iY * xBlockSize + iX]; rgba.a = pAlphaline[iY * xBlockSize + iX]; SetPixel32(x + iX, y + iY, rgba); } } } } } } } catch (const char *msg) { VTLOG1("Problem: "); VTLOG1(msg); VTLOG1("\n"); bRet = false; } if (NULL != pDataset) GDALClose(pDataset); if (NULL != pScanline) delete pScanline; if (NULL != pRedline) delete pRedline; if (NULL != pGreenline) delete pGreenline; if (NULL != pBlueline) delete pBlueline; if (NULL != pAlphaline) delete pAlphaline; return bRet; }