Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tutorial for unicode support in pcl visualizer #4717

Open
jiaobinbin152 opened this issue Apr 22, 2021 · 9 comments
Open

Add tutorial for unicode support in pcl visualizer #4717

jiaobinbin152 opened this issue Apr 22, 2021 · 9 comments
Labels
good first issue Skills/areas of expertise needed to tackle the issue kind: todo Type of issue module: docs

Comments

@jiaobinbin152
Copy link

jiaobinbin152 commented Apr 22, 2021

Original issue:
addText3D(std::string("我是谁"),position,1,255,0,0,"cubeTrackId");

don‘t work!


We can add a simple tutorial for unicode visualization (UTF-8, etc.). Starting link

@jiaobinbin152 jiaobinbin152 added kind: request Type of issue status: triage Labels incomplete labels Apr 22, 2021
@mvieth mvieth added kind: bug Type of issue and removed kind: request Type of issue status: triage Labels incomplete labels Apr 22, 2021
@mvieth
Copy link
Member

mvieth commented Apr 22, 2021

We definitely need more information to help you. In which way does it not work? Do you see an error message? A larger snippet of your code would be helpful. What PCL version do you use and how did you install it? What operating system do you use?

@WangZP10969
Copy link

WangZP10969 commented Apr 22, 2021

@jiaobinbin152 If you mean that Chinese cannot be displayed (nothing), my experience in displaying Chinese on actor2d tells me that you can use the following code to convert string to utf8, and you need to set the font file. But for 3D text display, you can try it, I am not sure if it is feasible.

Conversion function

std::string string_To_UTF8(const std::string& String)
{
long nwLen = MultiByteToWideChar(CP_ACP, 0, String.c_str(), -1, NULL, 0);
wchar_t* pwBuf = new wchar_t[nwLen + 1];
ZeroMemory(pwBuf, nwLen * 2 + 2);
MultiByteToWideChar(CP_ACP, 0, String.c_str(), String.length(), pwBuf, nwLen);
long nLen = WideCharToMultiByte(CP_UTF8, 0, pwBuf, -1, NULL, NULL, NULL, NULL);
char* pBuf = new char[nLen + 1];
ZeroMemory(pBuf, nLen + 1);
WideCharToMultiByte(CP_UTF8, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);
std::string retStr(pBuf);
delete[] pwBuf;
delete[] pBuf;
pwBuf = nullptr;
pBuf = nullptr;
return retStr;
}

Set font file

PointSetToLabelHierarchy->GetTextProperty()->SetFontFamily(VTK_FONT_FILE);
PointSetToLabelHierarchy->GetTextProperty()->SetFontFile("C:\\Windows\\Fonts\\msyh.ttc");

@jiaobinbin152
Copy link
Author

We definitely need more information to help you. In which way does it not work? Do you see an error message? A larger snippet of your code would be helpful. What PCL version do you use and how did you install it? What operating system do you use?

PCL version : 1.10.1
OS : win 10
IDE : Visual Studio 2019
Code :
boost::shared_ptrpcl::visualization::PCLVisualizer viewer (new pcl::visualization::PCLVisualizer ("3D Viewer"));
viewer->removeText3D("sample text UTF8");
viewer->removeText3D("sample text");
viewer->setBackgroundColor (0, 0, 0);
viewer->addPointCloudpcl::PointXYZ (cloud, "sample cloud");
pcl::PointXYZ pointUTF8(1, 1, 1);
std::string str = string_To_UTF8(std::string("我是谁"));
viewer->addText3D(std::string("我是谁"), pointUTF8,1,255,0,0,"sample text UTF8");
pcl::PointXYZ point(1, 1, 0);
viewer->addText3D("hello world", point, 1, 255, 0, 0, "sample text");
viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");
viewer->addCoordinateSystem (1.0);
viewer->initCameraParameters ();

Display:
image

don't find "我是谁" and no error message

@jiaobinbin152
Copy link
Author

@jiaobinbin152 If you mean that Chinese cannot be displayed (nothing), my experience in displaying Chinese on actor2d tells me that you can use the following code to convert string to utf8, and you need to set the font file. But for 3D text display, you can try it, I am not sure if it is feasible.

Conversion function

std::string string_To_UTF8(const std::string& String)
{
long nwLen = MultiByteToWideChar(CP_ACP, 0, String.c_str(), -1, NULL, 0);
wchar_t* pwBuf = new wchar_t[nwLen + 1];
ZeroMemory(pwBuf, nwLen * 2 + 2);
MultiByteToWideChar(CP_ACP, 0, String.c_str(), String.length(), pwBuf, nwLen);
long nLen = WideCharToMultiByte(CP_UTF8, 0, pwBuf, -1, NULL, NULL, NULL, NULL);
char* pBuf = new char[nLen + 1];
ZeroMemory(pBuf, nLen + 1);
WideCharToMultiByte(CP_UTF8, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);
std::string retStr(pBuf);
delete[] pwBuf;
delete[] pBuf;
pwBuf = nullptr;
pBuf = nullptr;
return retStr;
}

Set font file

PointSetToLabelHierarchy->GetTextProperty()->SetFontFamily(VTK_FONT_FILE);
PointSetToLabelHierarchy->GetTextProperty()->SetFontFile("C:\Windows\Fonts\msyh.ttc");

Thanks WangZP10969
try to use string_To_UTF8 , but also don’t work .

about PointSetToLabelHierarchy,I don't konw how to use? I'm only use PCLVisualizer。

@WangZP10969
Copy link

@jiaobinbin152
I saw your program
std::string str = string_To_UTF8(std::string("我是谁"));

But I don’t see "str" being used, the string after string_To_UTF8 conversion needs to be added
viewer->addText3D(str, pointUTF8,1,255,0,0,"sample text UTF8");

If you add it, the display becomes a question mark "?", then I think you need to find a way to set the fontfile.
If you add it and nothing is displayed, I think the problem you encountered is not the same as my experience.

@kunaltyagi
Copy link
Member

@WangZP10969 This is quite a good writeup. Could you clean the code a bit, and add that as a tutorial?

@WangZP10969
Copy link

WangZP10969 commented Apr 23, 2021

@WangZP10969 This is quite a good writeup. Could you clean the code a bit, and add that as a tutorial?

@kunaltyagi In fact, this is my experience of using VTK to display Chinese, and I currently have no experience using PCL for display.

There are two points to note when displaying Chinese in VTK:

  1. std::string needs to be converted to UTF8. I found this method from the Internet, and it works.If you don’t do this, VTK won’t display anything. I guess VTK parses the string in ASCLL mode, and the corresponding characters cannot be displayed.
  2. The default font does not support Chinese, you need to set other fonts, I usually choose Microsoft Yahei(msyh.ttc), which is the font that comes with the system.If you don’t do this, even if UTF8 Chinese is displayed, it will be displayed as a question mark "?".

1.string_to_utf8, use this function for conversion

std::string string_to_utf8(const std::string& String)
{
	long nwLen = MultiByteToWideChar(CP_ACP, 0, String.c_str(), -1, NULL, 0);
	wchar_t* pwBuf = new wchar_t[nwLen + 1];
	ZeroMemory(pwBuf, nwLen * 2 + 2);
	MultiByteToWideChar(CP_ACP, 0, String.c_str(), String.length(), pwBuf, nwLen);
	long nLen = WideCharToMultiByte(CP_UTF8, 0, pwBuf, -1, NULL, NULL, NULL, NULL);
	char* pBuf = new char[nLen + 1];
	ZeroMemory(pBuf, nLen + 1);
	WideCharToMultiByte(CP_UTF8, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);
	std::string retStr(pBuf);
	delete[] pwBuf;
	delete[] pBuf;
	pwBuf = nullptr;
	pBuf = nullptr;
	return retStr;
}

2.The code for displaying TextActor in vtk is for reference only, I don’t know what the corresponding display method is in PCL.

//Initialize window display 
vtkNew<vtkRenderWindow> Window;
vtkNew<vtkRenderer> Renderer;
Window->AddRenderer(Renderer);

//Add Chinese display
vtkNew<vtkTextActor> InformationTextActor;
InformationTextActor->SetInput(string_to_utf8(std::string("测试")).c_str());
InformationTextActor->SetPosition(5, 5);
InformationTextActor->GetTextProperty()->SetColor(1, 1, 1);
InformationTextActor->GetTextProperty()->SetFontFamily(VTK_FONT_FILE);
InformationTextActor->GetTextProperty()->SetFontFile("C:\\Windows\\Fonts\\msyh.ttc");
Renderer->AddActor(InformationTextActor);

//Add interaction and refresh window
vtkNew<vtkRenderWindowInteractor> RenderWindowInteractor ;
RenderWindowInteractor->SetRenderWindow(Window);
RenderWindowInteractor->Initialize();
RenderWindowInteractor->GetRenderWindow()->Render();
RenderWindowInteractor->Start();

@WangZP10969
Copy link

WangZP10969 commented Apr 23, 2021

I referenced the method in the blog and modified addText3D. Currently, the white text can be displayed, but I have no idea how to modify the color.
[VTK] Display Chinese in the 3D scene of VTK 8.2

Modifications in pcl_visualizer.hpp:
line 678:

vtkSmartPointer<vtkVectorText> textSource = vtkSmartPointer<vtkVectorText>::New ();
textSource->SetText (text.c_str());
textSource->Update ();

vtkSmartPointer<vtkPolyDataMapper> textMapper = vtkSmartPointer<vtkPolyDataMapper>::New ();
textMapper->SetInputConnection (textSource->GetOutputPort ());

change into

vtkNew<vtkFreeTypeStringToImage> stringImage;
vtkNew<vtkTextProperty> textProperty;
vtkNew<vtkImageData> imageData;
vtkNew<vtkDataSetMapper> textMapper;
textProperty->SetFontFamily(VTK_FONT_FILE);
textProperty->SetFontFile("C:\\Windows\\Fonts\\msyh.ttc");
stringImage->RenderString(textProperty, vtkUnicodeString::from_utf8(text), 300, imageData);
textMapper->SetInputDataObject(imageData);

image

The test program code is as follows:

#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/common/common_headers.h>

std::string string_to_utf8(const std::string& String)
{
	long nwLen = MultiByteToWideChar(0, 0, String.c_str(), -1, 0, 0);
	wchar_t* pwBuf = new wchar_t[nwLen + 1];
	memset(pwBuf, 0, nwLen * 2 + 2);
	MultiByteToWideChar(0, 0, String.c_str(), String.length(), pwBuf, nwLen);
	long nLen = WideCharToMultiByte(65001, 0, pwBuf, -1, 0, 0, 0, 0);
	char* pBuf = new char[nLen + 1];
	memset(pBuf, 0, nLen + 1);
	WideCharToMultiByte(65001, 0, pwBuf, nwLen, pBuf, nLen, 0, 0);
	std::string retStr(pBuf);
	delete[] pwBuf;
	delete[] pBuf;
	pwBuf = nullptr;
	pBuf = nullptr;
	return retStr;
}

int main(int argc, char* argv[])
{
	pcl::visualization::PCLVisualizer viewer("3D Viewer");
	viewer.setBackgroundColor(0, 0, 0);
	pcl::PointXYZ pointUTF8(1, 1, 1);
	viewer.addText3D(string_to_utf8("Test 测试"), pointUTF8, 0.01, 0, 1, 1, "sample text UTF8");
	viewer.addCoordinateSystem(1.0);
	viewer.initCameraParameters();
	while (!viewer.wasStopped())
	{
		viewer.spinOnce(100);
	}
}

The effect is as follows:
image

@jiaobinbin152
Copy link
Author

jiaobinbin152 commented Apr 26, 2021

I referenced the method in the blog and modified addText3D. Currently, the white text can be displayed, but I have no idea how to modify the color.
[VTK] Display Chinese in the 3D scene of VTK 8.2

Modifications in pcl_visualizer.hpp:
line 678:

vtkSmartPointer<vtkVectorText> textSource = vtkSmartPointer<vtkVectorText>::New ();
textSource->SetText (text.c_str());
textSource->Update ();

vtkSmartPointer<vtkPolyDataMapper> textMapper = vtkSmartPointer<vtkPolyDataMapper>::New ();
textMapper->SetInputConnection (textSource->GetOutputPort ());

change into

vtkNew<vtkFreeTypeStringToImage> stringImage;
vtkNew<vtkTextProperty> textProperty;
vtkNew<vtkImageData> imageData;
vtkNew<vtkDataSetMapper> textMapper;
textProperty->SetFontFamily(VTK_FONT_FILE);
textProperty->SetFontFile("C:\\Windows\\Fonts\\msyh.ttc");
stringImage->RenderString(textProperty, vtkUnicodeString::from_utf8(text), 300, imageData);
textMapper->SetInputDataObject(imageData);

image

The test program code is as follows:

#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/common/common_headers.h>

std::string string_to_utf8(const std::string& String)
{
	long nwLen = MultiByteToWideChar(0, 0, String.c_str(), -1, 0, 0);
	wchar_t* pwBuf = new wchar_t[nwLen + 1];
	memset(pwBuf, 0, nwLen * 2 + 2);
	MultiByteToWideChar(0, 0, String.c_str(), String.length(), pwBuf, nwLen);
	long nLen = WideCharToMultiByte(65001, 0, pwBuf, -1, 0, 0, 0, 0);
	char* pBuf = new char[nLen + 1];
	memset(pBuf, 0, nLen + 1);
	WideCharToMultiByte(65001, 0, pwBuf, nwLen, pBuf, nLen, 0, 0);
	std::string retStr(pBuf);
	delete[] pwBuf;
	delete[] pBuf;
	pwBuf = nullptr;
	pBuf = nullptr;
	return retStr;
}

int main(int argc, char* argv[])
{
	pcl::visualization::PCLVisualizer viewer("3D Viewer");
	viewer.setBackgroundColor(0, 0, 0);
	pcl::PointXYZ pointUTF8(1, 1, 1);
	viewer.addText3D(string_to_utf8("Test 测试"), pointUTF8, 0.01, 0, 1, 1, "sample text UTF8");
	viewer.addCoordinateSystem(1.0);
	viewer.initCameraParameters();
	while (!viewer.wasStopped())
	{
		viewer.spinOnce(100);
	}
}

The effect is as follows:
image

Again Thanks WangZP10969 . This issue has sloved.
note: add #include <vtkImageData.h> in pcl_visualizer.hpp.

@kunaltyagi kunaltyagi changed the title [addText3D] is Support UTF-8 Add tutorial for unicode support in pcl visualizer Apr 27, 2021
@kunaltyagi kunaltyagi added good first issue Skills/areas of expertise needed to tackle the issue kind: todo Type of issue module: docs and removed kind: bug Type of issue labels Apr 27, 2021
@kunaltyagi kunaltyagi reopened this Apr 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Skills/areas of expertise needed to tackle the issue kind: todo Type of issue module: docs
Projects
None yet
Development

No branches or pull requests

4 participants