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

some questions about the MR::computeGeodesicPath function? #1683

Closed
czc98 opened this issue Oct 9, 2023 · 11 comments
Closed

some questions about the MR::computeGeodesicPath function? #1683

czc98 opened this issue Oct 9, 2023 · 11 comments
Assignees

Comments

@czc98
Copy link

czc98 commented Oct 9, 2023

Hi, I want to using the surface path function, but i confused about the use of functions.
I have two point coordinates that on the surface of the mesh, and is it enough to call the function MR::computeGeodesicPath.
MR::computeGeodesicPath function need MeshTriPoint object, but i confused about some concepts, eg. EdgeId.
Hope to get answers, thank you.

@Grantim
Copy link
Contributor

Grantim commented Oct 9, 2023

Hello!
Simple coordinates is not enough for MR::computeGeodesicPat beacuse they are not attached to surface. One way to get MeshTriPoint from Vector3d is to call this function:

/// converts face id and 3d point into barycentric representation
[[nodiscard]] MRMESH_API MeshTriPoint toTriPoint( FaceId f, const Vector3f & p ) const;

another way is this:
/// finds closest point on this mesh (or its region) to given point;
/// xf is mesh-to-point transformation, if not specified then identity transformation is assumed
[[nodiscard]] MRMESH_API bool projectPoint( const Vector3f& point, MeshProjectionResult& res, float maxDistSq = FLT_MAX, const FaceBitSet* region = nullptr, const AffineXf3f * xf = nullptr ) const;

MeshTriPoint is structure that represent point on surface using barycentric coordinates of the face (EdgeId is base edge of the Face)

@czc98
Copy link
Author

czc98 commented Oct 17, 2023

image
I want to achieve the effect in the picture.
As I understand it, it takes two points on the surface to calculate the geodesic.
Whether I need to convert the point to a MeshTriPoint in some way before it can be used to calculate a geodesic.
Looking forward to your reply.

@Grantim
Copy link
Contributor

Grantim commented Oct 17, 2023

Hello!
The path at the picture is build with

/// returns intermediate points of the geodesic path from start to end, where it crosses mesh edges;
/// It is the same as calling computeGeodesicPathApprox() then reducePath()
MRMESH_API Expected<SurfacePath, PathError> computeGeodesicPath( const Mesh & mesh,
const MeshTriPoint & start, const MeshTriPoint & end, GeodesicPathApprox atype,
int maxGeodesicIters = 100 ); ///< the maximum number of iterations to reduce approximate path length and convert it in geodesic path

as you can see this function takes two MeshTriPoints (spheres on the picture) to build the path.

So you need to convert you points to MeshTriPoints to call this function, this comment describes how one can do it.

@czc98
Copy link
Author

czc98 commented Oct 17, 2023

I suddenly understood!
Use the Mesh member function toTriPoint, then find the faceId of the triangle on which the point is on the Mesh, and finally take the faceId and the world coordinates of the point as parameters to get the MeshTriPoint. Am I correct in my understanding?

@Grantim
Copy link
Contributor

Grantim commented Oct 17, 2023

Something like this

Vector3f a,b; // known coordinates
auto projA = mesh.projectPoint( a );
auto projB = mesh.projectPoint( b );

auto surfacePath = computeGeodesicPath( mesh, projA->mtp, projB->mtp, GeodesicPathApprox::DijkstraAStar );

or if you already know faces of a and b

Vector3f a,b;  // known ccordinates
FaceId aF,bF; // known faces of `a` and `b` 

auto surfacePath = computeGeodesicPath( mesh, mesh.toTriPoint( aF, a ), mesh.toTriPoint( bF, b ), GeodesicPathApprox::DijkstraAStar );

@czc98
Copy link
Author

czc98 commented Oct 17, 2023

Something like this

Vector3f a,b; // known coordinates
auto projA = mesh.projectPoint( a );
auto projB = mesh.projectPoint( b );

auto surfacePath = computeGeodesicPath( mesh, projA->mtp, projB->mtp, GeodesicPathApprox::DijkstraAStar );

or if you already know faces of a and b

Vector3f a,b;  // known ccordinates
FaceId aF,bF; // known faces of `a` and `b` 

auto surfacePath = computeGeodesicPath( mesh, mesh.toTriPoint( aF, a ), mesh.toTriPoint( bF, b ), GeodesicPathApprox::DijkstraAStar );

I understand. Thank you!

@Grantim
Copy link
Contributor

Grantim commented Nov 2, 2023

Closing this issue, please reopen it if you have any other related questions

@Grantim Grantim closed this as completed Nov 2, 2023
@albertpaolobugayong
Copy link

Something like this

Vector3f a,b; // known coordinates
auto projA = mesh.projectPoint( a );
auto projB = mesh.projectPoint( b );

auto surfacePath = computeGeodesicPath( mesh, projA->mtp, projB->mtp, GeodesicPathApprox::DijkstraAStar );

or if you already know faces of a and b

Vector3f a,b;  // known ccordinates
FaceId aF,bF; // known faces of `a` and `b` 

auto surfacePath = computeGeodesicPath( mesh, mesh.toTriPoint( aF, a ), mesh.toTriPoint( bF, b ), GeodesicPathApprox::DijkstraAStar );

Hi :) Is the projectPoint() function avaliable in the python API?

@Grantim
Copy link
Contributor

Grantim commented Apr 1, 2024

Hello! There are functions meshlib.mrmeshpy.findProjection and meshlib.mrmeshpy.findSignedDistance available in python.

@albertpaolobugayong
Copy link

Thank you : ) May I also ask if you have a function that outputs the face where the output nearest point from findProjection is located? I am planning to use computeGeodesicPath but I have only points to work with (numpy vector3f from pointcloud)

I'm planning to run this in Python using this method:
auto surfacePath = computeGeodesicPath( mesh, mesh.toTriPoint( aF, a ), mesh.toTriPoint( bF, b ), GeodesicPathApprox::DijkstraAStar );

but from my understanding, mesh.toTriPoint is not available in Python and only Tripointf is only available but requires me to already know the face on which the point from findProjection belongs to?

From:
TriPoint (const Vector3< T > &p, const Vector3< T > &v0, const Vector3< T > &v1, const Vector3< T > &v2)given a point coordinates and triangle (v0,v1,v2) computes barycentric coordinates of the point

My apologies, I'm not too familiar with EdgeId's and FaceId's, thus I couldn't understand how the arguments for the tripoint was set?

From: https://github.com/MeshInspector/MeshLib/blob/a1214ffdf41d6417dca6a092a4a95312cdc9435c/test_python/test_meshProjections.py
mtp1 = mrmesh.MeshTriPoint(mrmesh.EdgeId(0), mrmesh.TriPointf(0.2, 0.2))
mtp2 = mrmesh.MeshTriPoint(mrmesh.EdgeId(10), mrmesh.TriPointf(0.2, 0.2))

@Grantim
Copy link
Contributor

Grantim commented Apr 1, 2024

Now we don't have toTriPoint function exposed to python, so easiest way to get MeshTriPoint is to call findProjection. Also, you read this discussion, it can be helpful in understanding Mesh structure.

but from my understanding, mesh.toTriPoint is not available in Python and only Tripointf is only available but requires me to already know the face on which the point from findProjection belongs to?

If you want to create MeshTriPoint with toTriPoint you will still need to know exact FaceId point is

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants