Code Monkey home page Code Monkey logo

Comments (6)

user27182 avatar user27182 commented on June 14, 2024 1

Looks like threshold is the likely culprit:

dataset.volume  # 81672476.45755768
dataset.connectivity().volume  # 81672476.45755768
dataset.connectivity().threshold([-1,1]).volume  # 0.0

I'm not sure what the cause is from threshold, perhaps it's a pyvista bug or a bug with the underlying vtk method.

But, as a workaround, the connectivity filter itself can be used to perform a similar operation as threshold, e.g. replace this line

b = labeled.threshold(
[vid - 0.5, vid + 0.5], scalars='RegionId', progress_bar=progress_bar

and redefine the function as:

def split_bodies(mesh, label=False, progress_bar=False):
    conn = mesh.connectivity('all')
    conn_labels = conn.cell_data['RegionId']
    bodies = pyvista.MultiBlock()
    for vid in np.unique(conn_labels):
        # Now extract it:
        b = mesh.connectivity('specified', vid,  progress_bar=progress_bar)
        if not label:
            # strange behavior:
            # must use this method rather than deleting from the point_data
            # or else object is collected.
            b.cell_data.remove('RegionId')
            b.point_data.remove('RegionId')
        bodies.append(b)
    return bodies

calling split_bodies(dataset)[0].volume will return the correct (non-zero) volume

from pyvista.

kretes avatar kretes commented on June 14, 2024 1

@user27182 yes - this is about the result of split_bodies having 0 volume while it should be non-zero.

from pyvista.

user27182 avatar user27182 commented on June 14, 2024 1

I believe the issue stems from two things:

  1. The input mesh is polydata, but threshold returns an unstructured grid
  2. Volume for unstructured grids is calculated as the sum of the size of each cells. But triangle cells are 2D, which have zero volume, so the total volume of any unstructured grid with triangle cells is always zero. Volume for PolyData is therefore calculated differently.

So, there is no bug with the volume property or threshold filter in the sense that I believe they are working correctly. The issue is just that any PolyData -> UnstructuredGrid operation will result in non-zero volume meshes having zero-volume thereafter. Therefore, to preserve the volume we need a PolyData -> PolyData filter.

The reason workaround function above works is because the connectivity filter handles polydata as a special case and is therefore a PolyData -> PolyData filter.

Since threshold and split_bodies return unstructured grids, @kretes you can try calling extract_surface after split_bodies, as suggested here #3009 (comment) . Alternatively, you can use the function suggested above instead of dataset.split_bodies.

from pyvista.

user27182 avatar user27182 commented on June 14, 2024 1

#5950 adds a new method param to split_bodies to allow using the connectivity filter internally. The issue of zero-volume can then be resolved with, e.g.:

import pyvista
from pyvista import examples
dataset = examples.download_lucy()
print(dataset.volume)  # 81672476.45755768

split_dataset = dataset.split_bodies(method='connectivity')
print(split_dataset.volume)  # 81672476.45755768

@kretes does this work for you?

from pyvista.

user27182 avatar user27182 commented on June 14, 2024

Interesting. Checking the actual number of bodies with n_blocks shows that there is only one dataset in the multiblock.

import pyvista
from pyvista import examples
dataset = examples.download_lucy()
bodies = dataset.split_bodies()
print(bodies.n_blocks)  # 1

Also, under the hood this filter uses connectivity to label the regions before splitting. If we do:

np.unique(dataset.connectivity()['RegionId'])

We get [0], which confirms there is only one mesh returned by that function.

We can further confirm that the mesh returned by split_bodies() is that same as the dataset.

np.array_equal(dataset.connectivity().points, dataset.split_bodies()[0].points)  # True

So, it seems that there is definitely just one mesh at the input and output. Perhaps there is a bug with the __contains__ method for pv.MultiBlock?

from pyvista.

user27182 avatar user27182 commented on June 14, 2024

I think I misunderstood the bug, thinking that split_bodies was returning two meshes, one of which had zero volume. But the bug is that mesh.volume returns zero for a single mesh which is expected to have non-zero volume? Is that correct @kretes ?

Edited for clarity.

from pyvista.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.