Skip to content

Commit

Permalink
Add a drop zone (#827)
Browse files Browse the repository at this point in the history
* Add a drop zone

- Add a new dynamic vtkF3DDropZoneActor (co-author: @snoyer )
- Show the dropzone when no file are loaded
- Remove previous behavior of showing information in the filename info
- Add a test
  • Loading branch information
mwestphal authored May 25, 2023
1 parent def92d6 commit 54216f3
Show file tree
Hide file tree
Showing 12 changed files with 270 additions and 2 deletions.
6 changes: 4 additions & 2 deletions application/F3DStarter.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ class F3DStarter::F3DInternals
F3DStarter::F3DStarter()
: Internals(std::make_unique<F3DStarter::F3DInternals>())
{
// Set option outside of command line and config file
this->Internals->DynamicOptions.set(
"ui.dropzone-info", "Drop a file to open it\nPress H to show cheatsheet");
}

//----------------------------------------------------------------------------
Expand Down Expand Up @@ -381,7 +384,6 @@ void F3DStarter::LoadFile(int index, bool relativeIndex)
else
{
f3d::log::debug("No file to load provided.");
filenameInfo = "No file to load provided, please drop one into this window";
this->Internals->CurrentFileIndex = -1;

// Copy dynamic options into files options to get the global config
Expand Down Expand Up @@ -418,7 +420,6 @@ void F3DStarter::LoadFile(int index, bool relativeIndex)
fs::file_size(filePath) > static_cast<std::uintmax_t>(fileAppOptions.MaxSize * BYTES_IN_MIB))
{
f3d::log::info("No file loaded, file is bigger than max size");
filenameInfo = "No file loaded, file is bigger than max size";
}
else
{
Expand Down Expand Up @@ -493,6 +494,7 @@ void F3DStarter::LoadFile(int index, bool relativeIndex)
loader.loadGeometry("", true);
}

this->Internals->Engine->getOptions().set("ui.dropzone", !this->Internals->LoadedFile);
this->Internals->Engine->getOptions().set("ui.filename-info", filenameInfo);
}

Expand Down
2 changes: 2 additions & 0 deletions doc/libf3d/OPTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,5 @@ ui.font-file|string<br>-<br>render|Use the provided FreeType compatible font fil
ui.fps|bool<br>false<br>render|Display a *frame per second counter*.|\-\-fps
ui.loader-progress|bool<br>false<br>load|Show a *progress bar* when loading the file.|\-\-progress
ui.metadata|bool<br>false<br>render|Display the *metadata*.|\-\-metadata
ui.dropzone|bool<br>false<br>render|Show a drop zone.
ui.dropzone-info|string<br>-<br>render|Content of the drop zone text to display.
1 change: 1 addition & 0 deletions library/VTKExtensions/Rendering/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
set(classes
vtkF3DCachedLUTTexture
vtkF3DCachedSpecularTexture
vtkF3DDropZoneActor
vtkF3DHexagonalBokehBlurPass
vtkF3DInteractorEventRecorder
vtkF3DInteractorStyle
Expand Down
131 changes: 131 additions & 0 deletions library/VTKExtensions/Rendering/vtkF3DDropZoneActor.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#include "vtkF3DDropZoneActor.h"

#include <vtkObjectFactory.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper2D.h>
#include <vtkTextMapper.h>
#include <vtkTextProperty.h>
#include <vtkViewport.h>

vtkStandardNewMacro(vtkF3DDropZoneActor);

//------------------------------------------------------------------------------
vtkF3DDropZoneActor::vtkF3DDropZoneActor()
{
this->TextActor->SetMapper(this->TextMapper);
vtkTextProperty* tProp = this->TextMapper->GetTextProperty();
tProp->SetFontSize(25);
tProp->SetJustificationToCentered();
tProp->SetVerticalJustificationToCentered();

this->BorderMapper->SetInputData(this->BorderPolyData);
this->BorderActor->SetMapper(this->BorderMapper);
}

//------------------------------------------------------------------------------
vtkF3DDropZoneActor::~vtkF3DDropZoneActor() = default;

//------------------------------------------------------------------------------
void vtkF3DDropZoneActor::ReleaseGraphicsResources(vtkWindow* win)
{
this->TextActor->ReleaseGraphicsResources(win);
this->BorderActor->ReleaseGraphicsResources(win);
}

//------------------------------------------------------------------------------
int vtkF3DDropZoneActor::RenderOverlay(vtkViewport* viewport)
{
int* vSize = viewport->GetSize();

// Simply position text actor in the middle
this->TextMapper->SetInput(this->DropText.c_str());
this->TextActor->SetPosition(vSize[0] / 2, vSize[1] / 2);
this->TextActor->RenderOverlay(viewport);

if (this->BuildBorderGeometry(viewport))
{
this->BorderActor->RenderOverlay(viewport);
}
return 1;
}

//------------------------------------------------------------------------------
bool vtkF3DDropZoneActor::BuildBorderGeometry(vtkViewport* viewport)
{
constexpr int tickWidth = 3;
constexpr int tickLength = 10;

int* vSize = viewport->GetSize();
if (vSize[0] == this->ComputedBorderViewportSize[0] &&
vSize[1] == this->ComputedBorderViewportSize[1])
{
return true;
}

// padding is 10% of shortest side
int padding = static_cast<int>(std::min(vSize[0], vSize[1]) * 0.1);
int borderW = vSize[0] - 2 * padding;
int borderH = vSize[1] - 2 * padding;

// number of ticks assuming spacing == tickLength
int nTicksW = static_cast<int>(std::ceil(borderW / (tickLength * 2.0)));
int nTicksH = static_cast<int>(std::ceil(borderH / (tickLength * 2.0)));

// recompute uniform spacing
double spacingW = static_cast<double>(borderW - nTicksW * tickLength) / (nTicksW - 1);
double spacingH = static_cast<double>(borderH - nTicksH * tickLength) / (nTicksH - 1);

vtkNew<vtkPoints> borderPoints;
vtkNew<vtkCellArray> borderCells;
borderPoints->SetNumberOfPoints(4 * (2 * nTicksW + 2 * nTicksH));
vtkIdType index = 0;

// Draw top/bottom
for (int i = 0; i < nTicksW; ++i)
{
int x0 = padding + tickLength * i + spacingW * i;
int x1 = x0 + tickLength;
int y[2] = { padding, vSize[1] - padding };
int h[2] = { +tickWidth, -tickWidth };
for (int j = 0; j < 2; ++j)
{
vtkIdType ids[4] = { index++, index++, index++, index++ };
borderPoints->SetPoint(ids[0], x0, y[j] + h[j], 0.);
borderPoints->SetPoint(ids[1], x1, y[j] + h[j], 0.);
borderPoints->SetPoint(ids[2], x1, y[j], 0.);
borderPoints->SetPoint(ids[3], x0, y[j], 0.);
borderCells->InsertNextCell(4, ids);
}
}

// Draw left/right
for (int i = 0; i < nTicksH; ++i)
{
int y0 = padding + tickLength * i + spacingH * i;
int y1 = y0 + tickLength;
int x[2] = { padding, vSize[0] - padding };
int w[2] = { +tickWidth, -tickWidth };
for (int j = 0; j < 2; ++j)
{
vtkIdType ids[4] = { index++, index++, index++, index++ };
borderPoints->SetPoint(ids[0], x[j], y0, 0.);
borderPoints->SetPoint(ids[1], x[j] + w[j], y0, 0.);
borderPoints->SetPoint(ids[2], x[j] + w[j], y1, 0.);
borderPoints->SetPoint(ids[3], x[j], y1, 0.);
borderCells->InsertNextCell(4, ids);
}
}

this->BorderPolyData->SetPoints(borderPoints);
this->BorderPolyData->SetPolys(borderCells);

this->ComputedBorderViewportSize[0] = vSize[0];
this->ComputedBorderViewportSize[1] = vSize[1];
return true;
}

//------------------------------------------------------------------------------
vtkTextProperty* vtkF3DDropZoneActor::GetTextProperty()
{
return this->TextMapper->GetTextProperty();
}
72 changes: 72 additions & 0 deletions library/VTKExtensions/Rendering/vtkF3DDropZoneActor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* @class vtkF3DDropZoneActor
* @brief A F3D dedicated drop zone actor
*
* This actor show a drop zone with a fixed text
* in the center of the screen. The main feature
* is the geometry of the dropzone that adapts to the size of
* of the viewport.
*/

#ifndef vtkF3DDropZoneActor_h
#define vtkF3DDropZoneActor_h

#include <vtkActor2D.h>

#include <vtkNew.h>

class vtkTextMapper;
class vtkTextProperty;
class vtkPolyData;
class vtkPolyDataMapper2D;

class vtkF3DDropZoneActor : public vtkActor2D
{
public:
static vtkF3DDropZoneActor* New();
vtkTypeMacro(vtkF3DDropZoneActor, vtkActor2D);

/**
* Set the drop text to display
*/
vtkSetMacro(DropText, std::string);

/**
* Get the text property used to display text in this actor
*/
vtkTextProperty* GetTextProperty();

/**
* Release private actor graphic resources
*/
void ReleaseGraphicsResources(vtkWindow*) override;

/**
* Render private actors overlay
*/
int RenderOverlay(vtkViewport* viewport) override;

protected:
vtkF3DDropZoneActor();
~vtkF3DDropZoneActor() override;

private:
vtkF3DDropZoneActor(const vtkF3DDropZoneActor&) = delete;
void operator=(const vtkF3DDropZoneActor&) = delete;

/**
* Build the border geometry if the size of the viewport changed
* Return true on success, false otherwise
*/
bool BuildBorderGeometry(vtkViewport* viewport);

std::string DropText;
vtkNew<vtkActor2D> TextActor;
vtkNew<vtkTextMapper> TextMapper;
int ComputedBorderViewportSize[2] = { -1, -1 };
vtkNew<vtkPolyData> BorderPolyData;
vtkNew<vtkActor2D> BorderActor;
vtkNew<vtkPolyDataMapper2D> BorderMapper;
};

#endif
24 changes: 24 additions & 0 deletions library/VTKExtensions/Rendering/vtkF3DRenderer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "vtkF3DCachedLUTTexture.h"
#include "vtkF3DCachedSpecularTexture.h"
#include "vtkF3DConfigure.h"
#include "vtkF3DDropZoneActor.h"
#include "vtkF3DOpenGLGridMapper.h"
#include "vtkF3DRenderPass.h"

Expand Down Expand Up @@ -143,11 +144,13 @@ vtkF3DRenderer::vtkF3DRenderer()
this->MetaDataActor->GetTextProperty()->SetFontFamilyToCourier();
this->TimerActor->GetTextProperty()->SetFontFamilyToCourier();
this->CheatSheetActor->GetTextProperty()->SetFontFamilyToCourier();
this->DropZoneActor->GetTextProperty()->SetFontFamilyToCourier();

this->FilenameActor->VisibilityOff();
this->MetaDataActor->VisibilityOff();
this->TimerActor->VisibilityOff();
this->CheatSheetActor->VisibilityOff();
this->DropZoneActor->VisibilityOff();
}

//----------------------------------------------------------------------------
Expand Down Expand Up @@ -176,6 +179,7 @@ void vtkF3DRenderer::Initialize(const std::string& up)
this->AddActor(this->TimerActor);
this->AddActor(this->MetaDataActor);
this->AddActor(this->CheatSheetActor);
this->AddActor(this->DropZoneActor);

if (this->HasHDRI)
{
Expand Down Expand Up @@ -698,12 +702,14 @@ void vtkF3DRenderer::ConfigureTextActors()
this->MetaDataActor->GetTextProperty()->SetColor(textColor);
this->TimerActor->GetTextProperty()->SetColor(textColor);
this->CheatSheetActor->GetTextProperty()->SetColor(textColor);
this->DropZoneActor->GetTextProperty()->SetColor(textColor);

// Font
this->FilenameActor->GetTextProperty()->SetFontFamilyToCourier();
this->MetaDataActor->GetTextProperty()->SetFontFamilyToCourier();
this->TimerActor->GetTextProperty()->SetFontFamilyToCourier();
this->CheatSheetActor->GetTextProperty()->SetFontFamilyToCourier();
this->DropZoneActor->GetTextProperty()->SetFontFamilyToCourier();
if (!this->FontFile.empty())
{
std::string tmpFontFile = vtksys::SystemTools::CollapseFullPath(this->FontFile);
Expand All @@ -717,6 +723,8 @@ void vtkF3DRenderer::ConfigureTextActors()
this->TimerActor->GetTextProperty()->SetFontFile(tmpFontFile.c_str());
this->CheatSheetActor->GetTextProperty()->SetFontFamily(VTK_FONT_FILE);
this->CheatSheetActor->GetTextProperty()->SetFontFile(tmpFontFile.c_str());
this->DropZoneActor->GetTextProperty()->SetFontFamily(VTK_FONT_FILE);
this->DropZoneActor->GetTextProperty()->SetFontFile(tmpFontFile.c_str());
}
else
{
Expand Down Expand Up @@ -783,6 +791,12 @@ void vtkF3DRenderer::SetFilenameInfo(const std::string& info)
this->RenderPassesConfigured = false;
}

//----------------------------------------------------------------------------
void vtkF3DRenderer::SetDropZoneInfo(const std::string& info)
{
this->DropZoneActor->SetDropText(info);
}

//----------------------------------------------------------------------------
void vtkF3DRenderer::SetUseDepthPeelingPass(bool use)
{
Expand Down Expand Up @@ -963,6 +977,16 @@ void vtkF3DRenderer::ConfigureCheatSheet()
}
}

//----------------------------------------------------------------------------
void vtkF3DRenderer::ShowDropZone(bool show)
{
if (this->DropZoneVisible != show)
{
this->DropZoneVisible = show;
this->DropZoneActor->SetVisibility(show);
}
}

//----------------------------------------------------------------------------
void vtkF3DRenderer::FillCheatSheetHotkeys(std::stringstream& cheatSheetText)
{
Expand Down
5 changes: 5 additions & 0 deletions library/VTKExtensions/Rendering/vtkF3DRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <map>

class vtkCornerAnnotation;
class vtkF3DDropZoneActor;
class vtkOrientationMarkerWidget;
class vtkSkybox;
class vtkTextActor;
Expand All @@ -38,6 +39,7 @@ class vtkF3DRenderer : public vtkOpenGLRenderer
void ShowMetaData(bool show);
void ShowFilename(bool show);
void ShowCheatSheet(bool show);
void ShowDropZone(bool show);
///@}

using vtkOpenGLRenderer::SetBackground;
Expand All @@ -52,6 +54,7 @@ class vtkF3DRenderer : public vtkOpenGLRenderer
void SetBackground(const double* backgroundColor) override;
void SetLightIntensity(const double intensity);
void SetFilenameInfo(const std::string& info);
void SetDropZoneInfo(const std::string& info);
void SetGridAbsolute(bool absolute);
void SetGridUnitSquare(double unitSquare);
void SetGridSubdivisions(int subdivisions);
Expand Down Expand Up @@ -195,6 +198,7 @@ class vtkF3DRenderer : public vtkOpenGLRenderer
vtkNew<vtkCornerAnnotation> FilenameActor;
vtkNew<vtkCornerAnnotation> MetaDataActor;
vtkNew<vtkCornerAnnotation> CheatSheetActor;
vtkNew<vtkF3DDropZoneActor> DropZoneActor;

// vtkCornerAnnotation building is too slow for the timer
vtkNew<vtkTextActor> TimerActor;
Expand All @@ -216,6 +220,7 @@ class vtkF3DRenderer : public vtkOpenGLRenderer
bool FilenameVisible = false;
bool MetaDataVisible = false;
bool CheatSheetVisible = false;
bool DropZoneVisible = false;
bool UseRaytracing = false;
bool UseRaytracingDenoiser = false;
bool UseDepthPeelingPass = false;
Expand Down
2 changes: 2 additions & 0 deletions library/src/options.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ options::options()
this->Internals->init("ui.filename-info", std::string());
this->Internals->init("ui.fps", false);
this->Internals->init("ui.cheatsheet", false);
this->Internals->init("ui.dropzone", false);
this->Internals->init("ui.dropzone-info", std::string());
this->Internals->init("ui.metadata", false);
this->Internals->init("ui.font-file", std::string());
this->Internals->init("ui.loader-progress", false);
Expand Down
3 changes: 3 additions & 0 deletions library/src/window_impl.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,9 @@ void window_impl::UpdateDynamicOptions()
this->Internals->Options.getAsString("ui.filename-info"));
this->Internals->Renderer->ShowMetaData(this->Internals->Options.getAsBool("ui.metadata"));
this->Internals->Renderer->ShowCheatSheet(this->Internals->Options.getAsBool("ui.cheatsheet"));
this->Internals->Renderer->ShowDropZone(this->Internals->Options.getAsBool("ui.dropzone"));
this->Internals->Renderer->SetDropZoneInfo(
this->Internals->Options.getAsString("ui.dropzone-info"));

this->Internals->Renderer->SetUseRaytracing(
this->Internals->Options.getAsBool("render.raytracing.enable"));
Expand Down
Loading

0 comments on commit 54216f3

Please sign in to comment.