Text is sometimes rendered incorrectly.
In the code below "0123456789" is supposed to be rendered horizontally, on one line. But depending on values of width_text, rotated_text , fixed_text, and iteration_before_failure some digits become rotated. I suspect this is caused by unhandled cache collisions in vtkFreeTypeTools. Possible solutions I can suggest:
a) use a longer 128 bit hash (not size_t) with a better hashing function (not Jenkins, maybe MurmurHash3). This would make collisions improbable enough to be ignored. But it will be significantly slower.
b) Use a light-weight structure with all relevant font properties and comparison methods as a key, so that the cache lookup vtkTextPropertyLookup (based on std::map) could resolve collisions internally. But due to std::map's log2(N) lookup time this won't be very fast. std::unordered_map (a proper hash table) would've been great here, but it requires C++11.
Code to reproduce:
#include <vtkVersion.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyData.h>
#include <vtkTextActor.h>
#include <vtkTextProperty.h>
#include <vtkTextMapper.h>
int main(int, char *[])
{
const int iteration_before_failure = 80;
const char* width_text = "346";
const char* rotated_text = "any text";
const char* fixed_text = "000";
//const char* width_text = "a few symbols";
//const char* rotated_text = "any text";
//const char* fixed_text = "aaa";
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->SetBackground(1, 1, 1);
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->SetSize(200, 200);
renderWindow->AddRenderer(renderer);
const int mapper_count = 2;
vtkSmartPointer<vtkTextMapper> text_mappers[mapper_count];
vtkSmartPointer<vtkActor2D> text_actors[mapper_count];
for (int i = 0; i < mapper_count; ++i)
{
text_mappers[i] = vtkSmartPointer<vtkTextMapper>::New();
text_mappers[i]->GetTextProperty()->SetFontSize(16);
text_mappers[i]->GetTextProperty()->SetColor(0, 0, 0);
text_mappers[i]->GetTextProperty()->SetOrientation(0);
text_actors[i] = vtkSmartPointer<vtkActor2D>::New();
text_actors[i]->SetMapper(text_mappers[i]);
renderer->AddActor2D(text_actors[i]);
}
for (int j = 0; j < 1000; ++j)
{
text_mappers[0]->SetInput(width_text);
text_mappers[0]->GetTextProperty()->SetOrientation(0.0);
text_mappers[0]->GetWidth(renderer);
double angle_degrees = j * 15.0;
text_actors[0]->SetPosition(20, 20);
text_mappers[0]->SetInput(rotated_text);
text_mappers[0]->GetTextProperty()->SetOrientation(angle_degrees);
if (j > iteration_before_failure)
{
text_mappers[1]->SetInput("0123456789");
}
else
{
text_mappers[1]->SetInput(fixed_text);
}
text_mappers[1]->GetTextProperty()->SetOrientation(0);
text_actors[1]->SetPosition(100, 100);
for (int i = 0; i < mapper_count; ++i)
{
text_actors[i]->Modified();
}
renderWindow->Render();
}
return EXIT_SUCCESS;
}