mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 17:40:23 +08:00
Added texture/color blending option directly in the app. Added LAZ export option.
This commit is contained in:
@@ -2926,6 +2926,10 @@ void RTABMapApp::setWireframe(bool enabled)
|
||||
{
|
||||
main_scene_.setWireframe(enabled);
|
||||
}
|
||||
void RTABMapApp::setTextureColorSeamsHidden(bool hidden)
|
||||
{
|
||||
main_scene_.setTextureColorSeamsHidden(hidden);
|
||||
}
|
||||
|
||||
void RTABMapApp::setLocalizationMode(bool enabled)
|
||||
{
|
||||
@@ -3113,7 +3117,7 @@ void RTABMapApp::setDepthConfidence(int value)
|
||||
void RTABMapApp::setExportPointCloudFormat(const std::string & format)
|
||||
{
|
||||
#if defined(RTABMAP_PDAL) || defined(RTABMAP_LIBLAS)
|
||||
if(format == "las") {
|
||||
if(format == "las" || format == "laz") {
|
||||
exportPointCloudFormat_ = format;
|
||||
}
|
||||
else
|
||||
@@ -4205,9 +4209,9 @@ bool RTABMapApp::writeExportedMesh(const std::string & directory, const std::str
|
||||
if(polygonMesh->cloud.data.size())
|
||||
{
|
||||
#if defined(RTABMAP_PDAL) || defined(RTABMAP_LIBLAS)
|
||||
if(polygonMesh->polygons.empty() && exportPointCloudFormat_ == "las") {
|
||||
if(polygonMesh->polygons.empty() && (exportPointCloudFormat_ == "las" || exportPointCloudFormat_ == "laz")) {
|
||||
// Point cloud LAS
|
||||
std::string filePath = directory + UDirectory::separator() + name + ".las";
|
||||
std::string filePath = directory + UDirectory::separator() + name + (exportPointCloudFormat_ == "las"? ".las" : ".laz");
|
||||
LOGI("Saving las (%d vertices) to %s.", (int)polygonMesh->cloud.data.size()/polygonMesh->cloud.point_step, filePath.c_str());
|
||||
pcl::PointCloud<pcl::PointXYZRGB> output;
|
||||
pcl::fromPCLPointCloud2(polygonMesh->cloud, output);
|
||||
|
||||
@@ -128,6 +128,7 @@ class RTABMapApp : public UEventsHandler {
|
||||
void setLighting(bool enabled);
|
||||
void setBackfaceCulling(bool enabled);
|
||||
void setWireframe(bool enabled);
|
||||
void setTextureColorSeamsHidden(bool hidden);
|
||||
void setLocalizationMode(bool enabled);
|
||||
void setTrajectoryMode(bool enabled);
|
||||
void setGraphOptimization(bool enabled);
|
||||
|
||||
@@ -231,12 +231,22 @@ const std::string kTextureMeshFragmentShader =
|
||||
"uniform float uGainR;\n"
|
||||
"uniform float uGainG;\n"
|
||||
"uniform float uGainB;\n"
|
||||
"uniform int uHideSeams;\n"
|
||||
"varying vec3 vColor;\n"
|
||||
"varying vec2 vTexCoord;\n"
|
||||
"varying float vLightWeighting;\n"
|
||||
""
|
||||
"void main() {\n"
|
||||
" vec4 textureColor = texture2D(uTexture, vTexCoord) * vec4(vColor.z, vColor.y, vColor.x, 1.0);\n"
|
||||
" vec4 textureColor;\n"
|
||||
" if(uHideSeams==1) {\n"
|
||||
" if(vTexCoord.x>0.99 && vTexCoord.y>0.99) {\n"
|
||||
" textureColor = vec4(vColor.z, vColor.y, vColor.x, 1.0);\n"
|
||||
" } else {\n"
|
||||
" textureColor = texture2D(uTexture, vTexCoord);\n"
|
||||
" }\n"
|
||||
" } else {\n"
|
||||
" textureColor = texture2D(uTexture, vTexCoord) * vec4(vColor.z, vColor.y, vColor.x, 1.0);\n"
|
||||
" }\n"
|
||||
" gl_FragColor = vec4(textureColor.r * uGainR * vLightWeighting, textureColor.g * uGainG * vLightWeighting, textureColor.b * uGainB * vLightWeighting, textureColor.a);\n"
|
||||
"}\n";
|
||||
const std::string kTextureMeshBlendingFragmentShader =
|
||||
@@ -1016,7 +1026,8 @@ void PointCloudDrawable::Render(
|
||||
float nearClipPlane,
|
||||
float farClipPlane,
|
||||
bool packDepthToColorChannel,
|
||||
bool wireFrame) const
|
||||
bool wireFrame,
|
||||
bool hideSeams) const
|
||||
{
|
||||
if(vertex_buffer_ && nPoints_ && visible_ && !shaderPrograms_.empty())
|
||||
{
|
||||
@@ -1135,6 +1146,12 @@ void PointCloudDrawable::Render(
|
||||
|
||||
attribute_texture = glGetAttribLocation(program, "aTexCoord");
|
||||
glEnableVertexAttribArray(attribute_texture);
|
||||
|
||||
if(depthTexture == 0)
|
||||
{
|
||||
GLuint hideSeams_handle = glGetUniformLocation(program, "uHideSeams");
|
||||
glUniform1i(hideSeams_handle, hideSeams?1:0);
|
||||
}
|
||||
}
|
||||
|
||||
attribute_color = glGetAttribLocation(program, "aColor");
|
||||
|
||||
@@ -98,7 +98,8 @@ private:
|
||||
float nearClipPlane = 0, // nonnull if depthTexture>0
|
||||
float farClipPlane = 0, // nonnull if depthTexture>0
|
||||
bool packDepthToColorChannel = false,
|
||||
bool wireFrame = false) const;
|
||||
bool wireFrame = false,
|
||||
bool hideSeams = false) const;
|
||||
|
||||
private:
|
||||
template<class PointT>
|
||||
|
||||
@@ -93,6 +93,7 @@ Scene::Scene() :
|
||||
lighting_(false),
|
||||
backfaceCulling_(true),
|
||||
wireFrame_(false),
|
||||
textureColorSeamsHidden_(false),
|
||||
r_(0.0f),
|
||||
g_(0.0f),
|
||||
b_(0.0f),
|
||||
@@ -674,7 +675,7 @@ int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat
|
||||
cloud->getPose().z() - openglCamera.z());
|
||||
float distanceToCameraSqr = cloudToCamera[0]*cloudToCamera[0] + cloudToCamera[1]*cloudToCamera[1] + cloudToCamera[2]*cloudToCamera[2];
|
||||
|
||||
cloud->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_, meshRenderingTexture_, lighting_, distanceToCameraSqr, onlineBlending?depthTexture_:0, screenWidth_, screenHeight_, gesture_camera_->getNearClipPlane(), gesture_camera_->getFarClipPlane(), false, wireFrame_);
|
||||
cloud->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_, meshRenderingTexture_, lighting_, distanceToCameraSqr, onlineBlending?depthTexture_:0, screenWidth_, screenHeight_, gesture_camera_->getNearClipPlane(), gesture_camera_->getFarClipPlane(), false, wireFrame_, textureColorSeamsHidden_);
|
||||
}
|
||||
|
||||
if(quads_.find(55556)!=quads_.end())
|
||||
|
||||
@@ -193,6 +193,7 @@ class Scene {
|
||||
void setLighting(bool enabled) {lighting_ = enabled;}
|
||||
void setBackfaceCulling(bool enabled) {backfaceCulling_ = enabled;}
|
||||
void setWireframe(bool enabled) {wireFrame_ = enabled;}
|
||||
void setTextureColorSeamsHidden(bool hidden) {textureColorSeamsHidden_ = hidden;}
|
||||
void setBackgroundColor(float r, float g, float b) {r_=r; g_=g; b_=b;} // 0.0f <> 1.0f
|
||||
void setGridColor(float r, float g, float b);
|
||||
|
||||
@@ -255,6 +256,7 @@ class Scene {
|
||||
bool lighting_;
|
||||
bool backfaceCulling_;
|
||||
bool wireFrame_;
|
||||
bool textureColorSeamsHidden_;
|
||||
float r_;
|
||||
float g_;
|
||||
float b_;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
4E2C516825A63119005CEDBD /* VerticalScrollerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E2C516625A63119005CEDBD /* VerticalScrollerView.swift */; };
|
||||
4E8B155426273A580037FC53 /* Zip in Frameworks */ = {isa = PBXBuildFile; productRef = 4E8B155326273A580037FC53 /* Zip */; };
|
||||
4EB1A66625A0D90B0043C7BF /* RTABMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB1A66525A0D90B0043C7BF /* RTABMap.swift */; };
|
||||
4ED73AD12D7FECF3007899C2 /* liblaszip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4ED73AD02D7FECF3007899C2 /* liblaszip.a */; };
|
||||
4EE016B3259BE441008CCE65 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EE016AF259BE441008CCE65 /* ViewController.swift */; };
|
||||
4EE016B4259BE441008CCE65 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EE016B0259BE441008CCE65 /* SceneDelegate.swift */; };
|
||||
4EE016B9259BE449008CCE65 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EE016B8259BE449008CCE65 /* AppDelegate.swift */; };
|
||||
@@ -171,6 +172,7 @@
|
||||
4E2C516625A63119005CEDBD /* VerticalScrollerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = VerticalScrollerView.swift; path = RTABMapApp/VerticalScrollerView.swift; sourceTree = "<group>"; };
|
||||
4E401BE825CC92C100240A56 /* ProgressionStatus.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ProgressionStatus.h; path = ../android/jni/ProgressionStatus.h; sourceTree = "<group>"; };
|
||||
4EB1A66525A0D90B0043C7BF /* RTABMap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RTABMap.swift; path = RTABMapApp/RTABMap.swift; sourceTree = "<group>"; };
|
||||
4ED73AD02D7FECF3007899C2 /* liblaszip.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblaszip.a; path = RTABMapApp/Libraries/lib/liblaszip.a; sourceTree = "<group>"; };
|
||||
4EE015C2259A2AF0008CCE65 /* RTABMapApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RTABMapApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
4EE016AF259BE441008CCE65 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ViewController.swift; path = RTABMapApp/ViewController.swift; sourceTree = "<group>"; };
|
||||
4EE016B0259BE441008CCE65 /* SceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SceneDelegate.swift; path = RTABMapApp/SceneDelegate.swift; sourceTree = "<group>"; };
|
||||
@@ -355,6 +357,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
4EFAA9432CAE4E960055DA51 /* liblas.a in Frameworks */,
|
||||
4ED73AD12D7FECF3007899C2 /* liblaszip.a in Frameworks */,
|
||||
4EFD0F50259D67D900575D88 /* liblibwebp.a in Frameworks */,
|
||||
4EFD0F51259D67D900575D88 /* liblibpng.a in Frameworks */,
|
||||
4EFD0F52259D67D900575D88 /* liblibjpeg-turbo.a in Frameworks */,
|
||||
@@ -506,6 +509,7 @@
|
||||
4EFD0B2A259D4DE900575D88 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4ED73AD02D7FECF3007899C2 /* liblaszip.a */,
|
||||
4EFAA9422CAE4E960055DA51 /* liblas.a */,
|
||||
4EFD0F4D259D67D900575D88 /* liblibjpeg-turbo.a */,
|
||||
4EFD0F4C259D67D900575D88 /* liblibpng.a */,
|
||||
|
||||
@@ -435,6 +435,13 @@ void setWireframeNative(const void *object, bool enabled)
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setTextureColorSeamsHiddenNative(const void *object, bool hidden)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setTextureColorSeamsHidden(hidden);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setLocalizationModeNative(const void *object, bool enabled)
|
||||
{
|
||||
if(object)
|
||||
|
||||
@@ -91,6 +91,7 @@ void setGridRotationNative(const void *object, float value);
|
||||
void setLightingNative(const void *object, bool enabled);
|
||||
void setBackfaceCullingNative(const void *object, bool enabled);
|
||||
void setWireframeNative(const void *object, bool enabled);
|
||||
void setTextureColorSeamsHiddenNative(const void *object, bool hidden);
|
||||
void setLocalizationModeNative(const void *object, bool enabled);
|
||||
void setDataRecorderModeNative(const void *object, bool enabled);
|
||||
void setTrajectoryModeNative(const void *object, bool enabled);
|
||||
|
||||
@@ -426,6 +426,9 @@ class RTABMap {
|
||||
func setWireframe(enabled: Bool) {
|
||||
setWireframeNative(native_rtabmap, enabled)
|
||||
}
|
||||
func setTextureColorSeamsHidden(hidden: Bool) {
|
||||
setTextureColorSeamsHiddenNative(native_rtabmap, hidden)
|
||||
}
|
||||
func setLocalizationMode(enabled: Bool) {
|
||||
setLocalizationModeNative(native_rtabmap, enabled)
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
|
||||
private var wireframeShown: Bool = false
|
||||
private var backfaceShown: Bool = false
|
||||
private var lightingShown: Bool = false
|
||||
private var textureColorSeamsShown: Bool = false
|
||||
private var mHudVisible: Bool = true
|
||||
private var mLastTimeHudShown: DispatchTime = .now()
|
||||
private var mMenuOpened: Bool = false
|
||||
@@ -1030,6 +1031,11 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
|
||||
|
||||
// Camera menu
|
||||
let renderingMenu = UIMenu(title: "Rendering", options: .displayInline, children: [
|
||||
UIAction(title: "Texture/Color Blend", image: self.textureColorSeamsShown ? UIImage(systemName: "checkmark.circle") : UIImage(systemName: "circle"), attributes: self.mState == .STATE_VISUALIZING || self.mState == .STATE_VISUALIZING_CAMERA || self.mState == .STATE_VISUALIZING_AND_MEASURING || self.mState == .STATE_VISUALIZING_WHILE_LOADING ? [] : .disabled, handler: { _ in
|
||||
self.textureColorSeamsShown = !self.textureColorSeamsShown
|
||||
self.rtabmap!.setTextureColorSeamsHidden(hidden: !self.textureColorSeamsShown)
|
||||
self.resetNoTouchTimer(true)
|
||||
}),
|
||||
UIAction(title: "Wireframe", image: self.wireframeShown ? UIImage(systemName: "checkmark.circle") : UIImage(systemName: "circle"), handler: { _ in
|
||||
self.wireframeShown = !self.wireframeShown
|
||||
self.rtabmap!.setWireframe(enabled: self.wireframeShown)
|
||||
@@ -1552,7 +1558,7 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
|
||||
let format = defaults.string(forKey: "ExportPointCloudFormat")!;
|
||||
DispatchQueue.main.async {
|
||||
self.statusLabel.textColor = bgColor>=0.6 ? UIColor(white: 0.0, alpha: 1) : UIColor(white: 1.0, alpha: 1)
|
||||
self.exportOBJPLYButton.setTitle("Export OBJ-\(format == "las" ? "LAS" : "PLY")", for: .normal)
|
||||
self.exportOBJPLYButton.setTitle("Export OBJ-\(format == "las" ? "LAS" : format == "laz" ? "LAZ" : "PLY")", for: .normal)
|
||||
}
|
||||
|
||||
rtabmap!.setClusterRatio(value: defaults.float(forKey: "NoiseFilteringRatio"));
|
||||
|
||||
@@ -222,6 +222,27 @@ cd $pwd
|
||||
#rm -rf opencv opencv_contrib
|
||||
fi
|
||||
|
||||
# LAZ (dependency for liblas)
|
||||
# LAS
|
||||
if [ ! -e $prefix/include/laszip ]
|
||||
then
|
||||
if [ ! -e LASzip ]
|
||||
then
|
||||
git clone https://github.com/LASzip/LASzip.git
|
||||
cd LASzip
|
||||
git checkout 2.0.1
|
||||
else
|
||||
cd LASzip
|
||||
fi
|
||||
sed -i '' 's/add_subdirectory(tools)/#add_subdirectory(tools)/g' CMakeLists.txt
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DCMAKE_FIND_ROOT_PATH=$prefix -DBUILD_STATIC=ON ..
|
||||
cmake --build . --config Release -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
cmake --build . --config Release --target install -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
cd $pwd
|
||||
fi
|
||||
|
||||
# LAS
|
||||
if [ ! -e $prefix/include/liblas ]
|
||||
then
|
||||
@@ -233,7 +254,7 @@ cd libLAS
|
||||
sed -i '' 's/SHARED/STATIC/g' src/CMakeLists.txt
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DCMAKE_FIND_ROOT_PATH=$prefix -DWITH_UTILITIES=OFF -DWITH_TESTS=OFF -DWITH_GEOTIFF=OFF ..
|
||||
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DCMAKE_FIND_ROOT_PATH=$prefix -DWITH_UTILITIES=OFF -DWITH_TESTS=OFF -DWITH_GEOTIFF=OFF -DWITH_LASZIP=ON -DWITH_STATIC_LASZIP=ON ..
|
||||
cmake --build . --config Release -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
cmake --build . --config Release --target install -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
cd $pwd
|
||||
|
||||
@@ -393,11 +393,13 @@
|
||||
<array>
|
||||
<string>PLY</string>
|
||||
<string>LAS</string>
|
||||
<string>LAZ</string>
|
||||
</array>
|
||||
<key>Values</key>
|
||||
<array>
|
||||
<string>ply</string>
|
||||
<string>las</string>
|
||||
<string>laz</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
|
||||
Reference in New Issue
Block a user