ozRocker

How to get circumference of mesh?

Recommended Posts

Does anyone know of a way to get the circumference of a mesh at any point on the Y-axis in realtime?

I've attached an image below as an example.  I'd like to find the circumference around the shoulders, like I wrapped string around it then measured that length of string.

I suppose you could measure the distance from one point to the next, then add them all up for total circumference but there's 2 things I'm unsure of:

  • how to get points from exactly the same place on the Y-axis
  • how to take into account smooth-shading 

circumference.jpg.0fde9ee07c9403a38a48c46955f15d4a.jpg

Share this post


Link to post
Share on other sites

I played with Blender to create an edge-loop at the area I want to measure.  I figured that I could somehow save that as a vertex group, but the Babylon.js exporter doesn't store that info.  I tried separating those vertices into a separate mesh, but I think Babylon.js exporter will only save mesh data if it creates a polygon, 'cos that separate mesh just ended up as an empty array.  I don't think its possible with Blender to store a set of vertices as a "group" which the exporter will also convert

Share this post


Link to post
Share on other sites

Hi Oz. 

Um... at any level of Y,  surround the model with tiny planes... positioned and Y-rotated into a circle.  Perhaps 16 of them, and you can scale their X-axes so that they DON'T OVERLAP each other.  As you reduce the diameter of the circle-of-planes, you will need to down-scale each plane's X. 

IF they overlap whatsoever, you will not get an accurate circumference at the end of the procedure.

Keep reducing the diameter of the circle-of-planes until one of them has an intersectsMesh with the model.  Then "undo"... positioning/scaling planes at the previous diameter/scale of the circle-of-planes, when there was NO intersect.  You are seeking "just barely NOT intersecting" with the primary model.

Next, merge all the tiny planes together, and make sure you have good refreshBoundingInfo() (probably automatically done in merge code).  Then... use mergedMesh.getBoundingInfo().boundingBox.extendsSizeWorld to get a diameter. 

(You can also subtract primary model position... from ANY tiny-plane position, and that will be circle radius.  Double it for diameter, of course.)

Then, circumference = diameter * PI.

How's that for a ridiculous way of doing it?  :)  Edge-loop, the hard way. 

Share this post


Link to post
Share on other sites
20 minutes ago, Wingnut said:

Hi Oz. 

Um... at any level of Y,  surround the model with tiny planes... positioned and Y-rotated into a circle.  Perhaps 16 of them, and you can scale their X-axes so that they DON'T OVERLAP each other.  As you reduce the diameter of the circle-of-planes, you will need to down-scale each plane's X. 

IF they overlap whatsoever, you will not get an accurate circumference at the end of the procedure.

Keep reducing the diameter of the circle-of-planes until one of them has an intersectsMesh with the model.  Then "undo"... positioning/scaling planes at the previous diameter/scale of the circle-of-planes, when there was NO intersect.  You are seeking "just barely NOT intersecting" with the primary model.

Next, merge all the tiny planes together, and make sure you have good refreshBoundingInfo() (probably automatically done in merge code).  Then... use mergedMesh.getBoundingInfo().boundingBox.extendsSizeWorld to get a diameter.  Then, circumference = diameter * PI.

How's that for a ridiculous way of doing it?  :)  Edge-loop, the hard way. 

That's an interesting way of doing it.

Isn't diameter * PI for circles only?  I will have meshes of all kinds of shape

Share this post


Link to post
Share on other sites

(The term should be perimeter not circumference but no nit picking among friends). At first I thought I had a solution but it does not seem to generalize.

Using raycasting I obtained an acceptable result. Taking a box of side 4 I got 15.9 as the circumference which is pretty close to 16. The lower the increment the more accurate the result. Here is the PG, check console for circumference.

https://www.babylonjs-playground.com/#KNE0O#48

However when I tried to do the same thing with the skull the individual picked point results and the circumference do not make sense. According to the boundingInfo the skull is about 46 across which gives a ball park figure of 90 for the circumference at the chosen Y point but I get 9.7.

Perhaps I am on the right track and just do not know enough about raycasting to do it properly or maybe it is not the way to do it. Anyway here is PG with skull for what it is worth. (by the way with the skull an increment of 0.01 for the skull locks the browser for a long time).

https://www.babylonjs-playground.com/#KNE0O#51

EDIT

When I showed the rays I found the mistake, the rays were not in the direction I expected. I had modified another playground but found to get rays in right direction I should just use the forward vector not the calculated direction vector.

So this might work

https://www.babylonjs-playground.com/#KNE0O#52

Share this post


Link to post
Share on other sites

Hi,

As far as I've tried, it might be expensive to cast multiple rays each frame on a high-poly mesh (it loops through triangles when the ray hit the bounding box). A solution in cases you may take an approximation as a result is to use a low-poly (very low-poly) version of your mesh to do it.

For example, draw your skull with 60 vertices on Blender, attach the Mesh to the high-poly skull, hide it, and raycast on the low poly version.

(also, once you have a 60 triangles mesh, it's not that expensive to loop through the vertices to evaluate the diameter, and you may drop the use of raycast, you have an "exact result based on approximate mesh", which might be better than "approximate result on exact mesh").

 

 

Share this post


Link to post
Share on other sites
1 hour ago, SvenFrankson said:

once you have a 60 triangles mesh, it's not that expensive to loop through the vertices

Presuming you mean at least a 60 triangles mesh since in that case the facet triangles are small enough to give a good approximation then how expensive is it to determine the the vertices with a y value close enough to the given y value and that the vertices are consecutive by increasing angle. Remember that the contour of the slice at y may not be anywhere close to a circle and so just finding the diameter is not good enough.

Share this post


Link to post
Share on other sites
On 07/08/2017 at 2:10 PM, JohnK said:

(The term should be perimeter not circumference but no nit picking among friends). At first I thought I had a solution but it does not seem to generalize.

Using raycasting I obtained an acceptable result. Taking a box of side 4 I got 15.9 as the circumference which is pretty close to 16. The lower the increment the more accurate the result. Here is the PG, check console for circumference.

https://www.babylonjs-playground.com/#KNE0O#48

However when I tried to do the same thing with the skull the individual picked point results and the circumference do not make sense. According to the boundingInfo the skull is about 46 across which gives a ball park figure of 90 for the circumference at the chosen Y point but I get 9.7.

Perhaps I am on the right track and just do not know enough about raycasting to do it properly or maybe it is not the way to do it. Anyway here is PG with skull for what it is worth. (by the way with the skull an increment of 0.01 for the skull locks the browser for a long time).

https://www.babylonjs-playground.com/#KNE0O#51

EDIT

When I showed the rays I found the mistake, the rays were not in the direction I expected. I had modified another playground but found to get rays in right direction I should just use the forward vector not the calculated direction vector.

So this might work

https://www.babylonjs-playground.com/#KNE0O#52

This seems to work best.  Thanx mate! :D

Share this post


Link to post
Share on other sites

@ozRocker

You always have interesting challenges. However, if this were my challenge, I would use a small texture of a known length to wrap around any specific area of the mesh. Then since it's tiled and I know the PX length, I can handle the rest of the calculations based upon how many times the image is tiled. You can attach this to any event, and hide the texture when you don't need it. That's my thought of the day ('night').

DB

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.