How calculate a volume of this mesh 3D?
Asked Answered
K

2

5

enter image description hereI work about one project. We generate a mesh 3D and I need to calculate few volumes of an 3D object.

I don't know how to calculate that, too less math knowledge I think. Is there a way to calulate this

EDTI : I am not looking for all the code but the direction or pseudo code

Kala answered 18/12, 2014 at 1:15 Comment(3)
Post your code / information here. No one wants to go to an external site to helpIndoeuropean
@JonathonReinhart pic addedKala
blender.stackexchange.com/questions/63113/…Slopwork
B
8

I believe you would have gotten more response by a title that ask for the calculation of the volume of a boob :).

To start, in order to calculate the volume of a mesh, it should be a closed mesh. So I think that you need to select the faces/vertices that you don't need and remove them from the mesh. Than find a way to close the volume:

  • In Meshlab: Try the poisson option under point set
  • Or use i.e. Blender to close the volume manually

Once this is done, it becomes easy according to this paper.

The trick is to calculate the signed volume of a tetrahedron - based on your triangle and topped off at the origin. The sign of the volume comes from whether your triangle is pointing in the direction of the origin. (The normal of the triangle is itself dependent upon the order of your vertices, which is why you don't see it explicitly referenced below.)

This all boils down to the following simple function:

float signedVolumeOfTriangle(pcl::PointXYZ p1, pcl::PointXYZ p2, pcl::PointXYZ p3) 
{
    float v321 = p3.x*p2.y*p1.z;
    float v231 = p2.x*p3.y*p1.z;
    float v312 = p3.x*p1.y*p2.z;
    float v132 = p1.x*p3.y*p2.z;
    float v213 = p2.x*p1.y*p3.z;
    float v123 = p1.x*p2.y*p3.z;
    return (1.0f/6.0f)*(-v321 + v231 + v312 - v132 - v213 + v123);
}

and then a function to calculate the volume of the mesh:

float volumeOfMesh(pcl::PolygonMesh mesh) 
{
    float vols = 0.0;
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::fromPointCloud2(mesh.cloud,*cloud);
    for(int triangle=0;triangle<mesh.polygons.size();triangle++)
    {
        pcl::PointXYZ pt1 = cloud->points[mesh.polygons[triangle].vertices[0]];
        pcl::PointXYZ pt2 = cloud->points[mesh.polygons[triangle].vertices[1]];
        pcl::PointXYZ pt3 = cloud->points[mesh.polygons[triangle].vertices[2]];
        vols += signedVolumeOfTriangle(pt1, pt2, pt3);
    }
    return Math.Abs(vols.Sum());
}

I didn't test the code and don't know if you can use PCL, but this should get you started.

Binns answered 18/12, 2014 at 8:30 Comment(1)
Only I can't access their site today. Should start working again.Binns
T
0

I have completed the code of @Deepfreeze with pcl-1.8.1 of ubuntu-18.04. The paper's url link updates, click here. Note that the code should be "pcl::fromPCLPointCloud2"

main.cpp

#include <iostream>
#include <pcl/point_types.h>
#include <pcl/io/obj_io.h>
#include <pcl/io/vtk_lib_io.h>
#include <pcl/conversions.h>
#include <cmath>
float signedVolumeOfTriangle (pcl::PointXYZ p1, pcl::PointXYZ p2, pcl::PointXYZ p3) 
{
    float v321 = p3.x*p2.y*p1.z;
    float v231 = p2.x*p3.y*p1.z;
    float v312 = p3.x*p1.y*p2.z;
    float v132 = p1.x*p3.y*p2.z;
    float v213 = p2.x*p1.y*p3.z;
    float v123 = p1.x*p2.y*p3.z;
    return (1.0f/6.0f)*(-v321 + v231 + v312 - v132 - v213 + v123);
}

float volumeOfMesh(pcl::PolygonMesh mesh) 
{
    float vols = 0.0;
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::fromPCLPointCloud2(mesh.cloud, *cloud);
    for(int triangle=0;triangle<mesh.polygons.size();triangle++)
    {
        pcl::PointXYZ pt1 = cloud->points[mesh.polygons[triangle].vertices[0]];
        pcl::PointXYZ pt2 = cloud->points[mesh.polygons[triangle].vertices[1]];
        pcl::PointXYZ pt3 = cloud->points[mesh.polygons[triangle].vertices[2]];
        vols += signedVolumeOfTriangle(pt1, pt2, pt3);
    }
    return abs(vols);
}

int main(int argc, char **argv) {
    pcl::PolygonMesh mesh;
    pcl::io::loadOBJFile(argv[1], mesh);
    std::cout << volumeOfMesh(mesh) << std::endl;
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(mesh_volume)

find_package(PCL 1.8 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

add_executable (${PROJECT_NAME} main.cpp)
target_link_libraries (${PROJECT_NAME} ${PCL_LIBRARIES})
Thorin answered 3/5, 2021 at 10:54 Comment(1)
Thougth six years passed, we still strive hard to get the size of boob. In my oppion, they are no less than B cup.Fuegian

© 2022 - 2024 — McMap. All rights reserved.