diff --git a/Examples/Studio/MeshScalars/ellipsoid_01.vtk b/Examples/Studio/MeshScalars/ellipsoid_01.vtk new file mode 100644 index 00000000000..0fa0d493595 --- /dev/null +++ b/Examples/Studio/MeshScalars/ellipsoid_01.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a723102be33dcfd655f251e8c6b20a7fadaa265a4b37eb2f1ebf70d1f279bb7d +size 153824 diff --git a/Examples/Studio/MeshScalars/ellipsoid_02.vtk b/Examples/Studio/MeshScalars/ellipsoid_02.vtk new file mode 100644 index 00000000000..eb8848352b9 --- /dev/null +++ b/Examples/Studio/MeshScalars/ellipsoid_02.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49a3e56b939f1b72c062d354861648800a5e1afe010dea6910163a66e57ac5c8 +size 153824 diff --git a/Examples/Studio/MeshScalars/ellipsoid_03.vtk b/Examples/Studio/MeshScalars/ellipsoid_03.vtk new file mode 100644 index 00000000000..10499b9793f --- /dev/null +++ b/Examples/Studio/MeshScalars/ellipsoid_03.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10b49c6df4bc10f8c2331d7374a368073ca43cd97e31bdb091cfd0f51dba24c9 +size 153824 diff --git a/Examples/Studio/MeshScalars/ellipsoid_04.vtk b/Examples/Studio/MeshScalars/ellipsoid_04.vtk new file mode 100644 index 00000000000..f3b3c58bbba --- /dev/null +++ b/Examples/Studio/MeshScalars/ellipsoid_04.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c9ca56403d27ba81b793b904380b067c6924dcd68884b7513431a38d9e2d98d +size 153824 diff --git a/Examples/Studio/MeshScalars/ellipsoid_05.vtk b/Examples/Studio/MeshScalars/ellipsoid_05.vtk new file mode 100644 index 00000000000..2479be96185 --- /dev/null +++ b/Examples/Studio/MeshScalars/ellipsoid_05.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02bf8d81e4486536bb394b505fb0f9d0a4d63df05b14d58a4c3d300868cf7465 +size 153824 diff --git a/Examples/Studio/MeshScalars/ellipsoid_06.vtk b/Examples/Studio/MeshScalars/ellipsoid_06.vtk new file mode 100644 index 00000000000..908503ad94c --- /dev/null +++ b/Examples/Studio/MeshScalars/ellipsoid_06.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:328b630ef801574f36be595ef1997eaae7a35bc63ce099821b8a1710eb965173 +size 153824 diff --git a/Examples/Studio/MeshScalars/ellipsoid_07.vtk b/Examples/Studio/MeshScalars/ellipsoid_07.vtk new file mode 100644 index 00000000000..f87246a89c6 --- /dev/null +++ b/Examples/Studio/MeshScalars/ellipsoid_07.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf12c2be703eb38609f1296db95bd535a3986651cae2446b57c1fca7bd400b3e +size 153824 diff --git a/Examples/Studio/MeshScalars/ellipsoid_08.vtk b/Examples/Studio/MeshScalars/ellipsoid_08.vtk new file mode 100644 index 00000000000..6323f1029bf --- /dev/null +++ b/Examples/Studio/MeshScalars/ellipsoid_08.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe47ff57fccf5f2fb68002ceb2b449ec5593b73b5d7ac01a84374ef7ffa27db2 +size 153824 diff --git a/Examples/Studio/MeshScalars/ellipsoid_09.vtk b/Examples/Studio/MeshScalars/ellipsoid_09.vtk new file mode 100644 index 00000000000..1130aeeb01c --- /dev/null +++ b/Examples/Studio/MeshScalars/ellipsoid_09.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dbeef3962fb426262a8641cbba9605e8c2e676727e6380ab10e3e2b683fbc05c +size 153824 diff --git a/Examples/Studio/MeshScalars/ellipsoid_10.vtk b/Examples/Studio/MeshScalars/ellipsoid_10.vtk new file mode 100644 index 00000000000..227469d203f --- /dev/null +++ b/Examples/Studio/MeshScalars/ellipsoid_10.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cceb743f2557346de951f8054c43ebf349663c5ece2ca814593afea691557dda +size 153824 diff --git a/Examples/Studio/MeshScalars/groomed/ellipsoid_01_groomed.vtk b/Examples/Studio/MeshScalars/groomed/ellipsoid_01_groomed.vtk new file mode 100644 index 00000000000..0627ee46b6e --- /dev/null +++ b/Examples/Studio/MeshScalars/groomed/ellipsoid_01_groomed.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:684b4469485d9f7746a633e48c4ab651889a6b6e5d305cd4fcda4c8a20797706 +size 178133 diff --git a/Examples/Studio/MeshScalars/groomed/ellipsoid_02_groomed.vtk b/Examples/Studio/MeshScalars/groomed/ellipsoid_02_groomed.vtk new file mode 100644 index 00000000000..f85e051a160 --- /dev/null +++ b/Examples/Studio/MeshScalars/groomed/ellipsoid_02_groomed.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7eca2e146ba1cbfead42e78506f34754c7b8836df1245990d6deb71d3b821449 +size 178139 diff --git a/Examples/Studio/MeshScalars/groomed/ellipsoid_03_groomed.vtk b/Examples/Studio/MeshScalars/groomed/ellipsoid_03_groomed.vtk new file mode 100644 index 00000000000..4500f605fae --- /dev/null +++ b/Examples/Studio/MeshScalars/groomed/ellipsoid_03_groomed.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd45e389ce1a8f6bf477817c38e6104b29f0e14593d6d3a239cdbc2924729fde +size 177872 diff --git a/Examples/Studio/MeshScalars/groomed/ellipsoid_04_groomed.vtk b/Examples/Studio/MeshScalars/groomed/ellipsoid_04_groomed.vtk new file mode 100644 index 00000000000..08f45e370bc --- /dev/null +++ b/Examples/Studio/MeshScalars/groomed/ellipsoid_04_groomed.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e2573562b7dd49677ef38f620bde319cfb3183398c3b67c34d8ab58d85894a1a +size 178007 diff --git a/Examples/Studio/MeshScalars/groomed/ellipsoid_05_groomed.vtk b/Examples/Studio/MeshScalars/groomed/ellipsoid_05_groomed.vtk new file mode 100644 index 00000000000..2707f1c911f --- /dev/null +++ b/Examples/Studio/MeshScalars/groomed/ellipsoid_05_groomed.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2623fe62c3aaba47bd0f0fccf0bc6dfd91325b31067b7aee372f6a14bf914311 +size 178150 diff --git a/Examples/Studio/MeshScalars/groomed/ellipsoid_06_groomed.vtk b/Examples/Studio/MeshScalars/groomed/ellipsoid_06_groomed.vtk new file mode 100644 index 00000000000..3930936eade --- /dev/null +++ b/Examples/Studio/MeshScalars/groomed/ellipsoid_06_groomed.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a9e5063e746bdfb4d674519facbd00c0b4db0521485bcfc85649517932b66c09 +size 178102 diff --git a/Examples/Studio/MeshScalars/groomed/ellipsoid_07_groomed.vtk b/Examples/Studio/MeshScalars/groomed/ellipsoid_07_groomed.vtk new file mode 100644 index 00000000000..112cc39d577 --- /dev/null +++ b/Examples/Studio/MeshScalars/groomed/ellipsoid_07_groomed.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18e21dfc5ff93e877fbb3ea8cbbf13c48d2b63b13c000ffa04733fcb85c396e6 +size 177985 diff --git a/Examples/Studio/MeshScalars/groomed/ellipsoid_08_groomed.vtk b/Examples/Studio/MeshScalars/groomed/ellipsoid_08_groomed.vtk new file mode 100644 index 00000000000..520872f03ad --- /dev/null +++ b/Examples/Studio/MeshScalars/groomed/ellipsoid_08_groomed.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1cda2cbe9ede81edd798f1c5b169a9e11efa3dc5dd33909cc85e292ff3bee572 +size 178040 diff --git a/Examples/Studio/MeshScalars/groomed/ellipsoid_09_groomed.vtk b/Examples/Studio/MeshScalars/groomed/ellipsoid_09_groomed.vtk new file mode 100644 index 00000000000..84ba490110a --- /dev/null +++ b/Examples/Studio/MeshScalars/groomed/ellipsoid_09_groomed.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a9f73156d90fddf2505a56ba60d9a48f14319ed18046351e19d05e8542bc1ae2 +size 178105 diff --git a/Examples/Studio/MeshScalars/groomed/ellipsoid_10_groomed.vtk b/Examples/Studio/MeshScalars/groomed/ellipsoid_10_groomed.vtk new file mode 100644 index 00000000000..8d427104ee1 --- /dev/null +++ b/Examples/Studio/MeshScalars/groomed/ellipsoid_10_groomed.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5970134f440b8bc44a8a01933c5cc79a06609cdea11ac4a50e0e6ec1b0f10f34 +size 178065 diff --git a/Examples/Studio/MeshScalars/make_example.py b/Examples/Studio/MeshScalars/make_example.py new file mode 100644 index 00000000000..24bc26a3f99 --- /dev/null +++ b/Examples/Studio/MeshScalars/make_example.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +""" +Build the Mesh Scalars example: ellipsoids that are nearly the same shape, each carrying a +scalar field ("scalar_value") with a patch whose position differs from subject to subject. + +Geometry alone cannot tell where the patch is, so a model built from position only leaves the +patch smeared across particles. Using the field as a correspondence attribute makes the particles +follow it: untick "scalar_value" under Mesh Scalars in the Optimize panel and run again to compare. + + python make_example.py [output_dir] +""" + +import json +import os +import sys + +import numpy as np +import vtk +from vtk.util.numpy_support import numpy_to_vtk, vtk_to_numpy + +NUM_SUBJECTS = 10 +RADII = np.array([20.0, 14.0, 10.0]) +PATCH_WIDTH = np.radians(25.0) # standard deviation of the patch, as an angle +PATCH_RANGE = np.radians(35.0) # the patch center moves this far either side of the top + + +def ellipsoid(radii, subdivisions=4): + source = vtk.vtkPlatonicSolidSource() + source.SetSolidTypeToIcosahedron() + tri = vtk.vtkTriangleFilter() + tri.SetInputConnection(source.GetOutputPort()) + sub = vtk.vtkLinearSubdivisionFilter() + sub.SetInputConnection(tri.GetOutputPort()) + sub.SetNumberOfSubdivisions(subdivisions) + sub.Update() + out = vtk.vtkPolyData() + out.SetPoints(vtk.vtkPoints()) + out.SetPolys(sub.GetOutput().GetPolys()) + unit = vtk_to_numpy(sub.GetOutput().GetPoints().GetData()).astype(float) + unit /= np.linalg.norm(unit, axis=1, keepdims=True) + out.GetPoints().SetData(numpy_to_vtk(unit * radii, deep=True)) + return out, unit + + +def main(out_dir): + os.makedirs(out_dir, exist_ok=True) + rng = np.random.default_rng(7) + data = [] + angles = np.linspace(-PATCH_RANGE, PATCH_RANGE, NUM_SUBJECTS) + for i, angle in enumerate(angles): + radii = RADII * (1.0 + rng.uniform(-0.06, 0.06, 3)) + mesh, unit = ellipsoid(radii) + # the patch sits on the top of the ellipsoid, shifted along its long axis + center = np.array([np.sin(angle), 0.0, np.cos(angle)]) + separation = np.arccos(np.clip(unit @ center, -1.0, 1.0)) + field = np.exp(-0.5 * (separation / PATCH_WIDTH) ** 2).astype(np.float32) + array = numpy_to_vtk(field, deep=True) + array.SetName("scalar_value") + mesh.GetPointData().SetScalars(array) + name = "ellipsoid_%02d.vtk" % (i + 1) + writer = vtk.vtkPolyDataWriter() + writer.SetFileName(os.path.join(out_dir, name)) + writer.SetInputData(mesh) + writer.SetFileVersion(42) + writer.SetFileTypeToBinary() + writer.Write() + data.append({"name": "ellipsoid_%02d" % (i + 1), "shape_1": name}) + + optimize = { + "number_of_particles": "128", + "initialization_mode": "split", + "iterations_per_split": "1000", + "optimization_iterations": "1000", + "relative_weighting": "10", + "initial_relative_weighting": "0.05", + "starting_regularization": "1000", + "ending_regularization": "10", + "procrustes": "false", + "field_attributes": "scalar_value", + "field_attribute_weights": "100", + } + # the meshes are already clean and aligned; grooming only has to pass them (and the field) through + groom = {"1": {"remesh": "false", "fill_holes": "false", "alignment_enabled": "false"}} + project = {"data": data, "groom": groom, "optimize": optimize} + json.dump(project, open(os.path.join(out_dir, "mesh_scalars.swproj"), "w"), indent=1) + print("wrote %d meshes and mesh_scalars.swproj to %s" % (len(data), out_dir)) + + +if __name__ == "__main__": + main(sys.argv[1] if len(sys.argv) > 1 else ".") diff --git a/Examples/Studio/MeshScalars/mesh_scalars.swproj b/Examples/Studio/MeshScalars/mesh_scalars.swproj new file mode 100644 index 00000000000..65c4cf7b192 --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars.swproj @@ -0,0 +1,64 @@ +{ + "data": [ + { + "name": "ellipsoid_01", + "shape_1": "ellipsoid_01.vtk" + }, + { + "name": "ellipsoid_02", + "shape_1": "ellipsoid_02.vtk" + }, + { + "name": "ellipsoid_03", + "shape_1": "ellipsoid_03.vtk" + }, + { + "name": "ellipsoid_04", + "shape_1": "ellipsoid_04.vtk" + }, + { + "name": "ellipsoid_05", + "shape_1": "ellipsoid_05.vtk" + }, + { + "name": "ellipsoid_06", + "shape_1": "ellipsoid_06.vtk" + }, + { + "name": "ellipsoid_07", + "shape_1": "ellipsoid_07.vtk" + }, + { + "name": "ellipsoid_08", + "shape_1": "ellipsoid_08.vtk" + }, + { + "name": "ellipsoid_09", + "shape_1": "ellipsoid_09.vtk" + }, + { + "name": "ellipsoid_10", + "shape_1": "ellipsoid_10.vtk" + } + ], + "groom": { + "1": { + "remesh": "false", + "fill_holes": "false", + "alignment_enabled": "false" + } + }, + "optimize": { + "number_of_particles": "128", + "initialization_mode": "split", + "iterations_per_split": "1000", + "optimization_iterations": "1000", + "relative_weighting": "10", + "initial_relative_weighting": "0.05", + "starting_regularization": "1000", + "ending_regularization": "10", + "procrustes": "false", + "field_attributes": "scalar_value", + "field_attribute_weights": "100" + } +} \ No newline at end of file diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_01_groomed_local.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_01_groomed_local.particles new file mode 100644 index 00000000000..7209d6de85f --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_01_groomed_local.particles @@ -0,0 +1,128 @@ +-18.7834 -2.22089 -3.56731 +-5.689 14.0233 -0.804953 +-7.20985 -13.6932 -0.314514 +6.50741 -12.8958 3.61539 +-13.8393 3.30333 7.17799 +10.514 5.28448 -8.00475 +-11.4093 0.440759 -8.52961 +5.54925 4.76924 -9.34466 +-18.089 6.62185 -0.252678 +11.4604 11.3095 -3.01659 +-5.10178 -12.0159 5.3135 +12.4556 -2.80567 -7.90269 +-3.24204 7.85374 8.56395 +3.11597 8.37511 -8.32217 +-8.734 -9.41312 -6.54331 +12.9345 -10.0019 3.68552 +-17.2276 1.80864 -5.30108 +-5.75376 4.73467 -9.3192 +-7.76167 -9.34765 6.89982 +16.9932 -6.65357 3.12984 +4.21845 13.283 3.79002 +19.5663 3.61587 0.972713 +2.43851 -9.58221 -7.71541 +7.06192 -8.37709 -7.66897 +-6.04538 12.2801 -4.71955 +-15.6291 8.8059 2.20135 +-2.70049 -8.18103 8.45425 +20.0992 -0.0157727 -1.41258 +-10.7539 0.923604 8.72958 +7.72851 10.674 5.87622 +-18.7904 -2.84626 3.33354 +11.3059 -10.9726 -3.70776 +-16.3385 -5.11809 -4.94151 +-1.66998 10.3604 -7.25187 +-10.5672 -11.7734 -2.97481 +6.31099 -5.01757 9.15725 +-12.683 9.46153 4.52096 +14.9511 9.9028 0.287426 +-4.07872 -3.14883 -9.86737 +4.64553 -0.369171 -10.0441 +-16.9357 6.10356 -3.71736 +8.95859 13.1023 0.799231 +-1.57308 -14.1793 -2.48129 +15.8441 -6.46206 -4.56124 +0.849068 1.65461 10.2485 +1.41344 2.95398 -10.0894 +-12.2662 -4.51939 -7.58508 +10.0762 -12.7112 0.396584 +-9.91731 4.86656 -8.32716 +-2.9139 1.51376 -10.1589 +-13.0287 -9.32465 4.40973 +13.2411 -2.33306 7.64465 +-6.0949 10.2835 6.66632 +16.8101 6.33712 3.67949 +-5.87535 -12.468 -4.53293 +-1.12997 -6.95534 -9.07231 +-9.73607 9.07333 -6.42129 +-10.9889 12.2198 1.12798 +0.796094 -5.80615 9.47189 +17.1979 6.8665 -2.55549 +-6.79897 0.9667 9.70216 +12.1224 10.3165 3.95764 +-12.8435 -11.3174 0.576439 +16.9639 -2.03565 -5.48182 +-19.6109 2.22406 -2.1127 +-1.56774 13.5956 -3.76318 +-9.27562 -12.1668 3.29065 +3.14089 -9.95612 7.4121 +-9.63977 7.6705 7.29808 +13.2536 7.79307 -5.55818 +-8.63301 -4.19428 -8.86255 +8.83019 0.888783 -9.27139 +-19.5351 2.82432 1.96351 +6.90258 12.1462 -4.59496 +-0.345955 -12.2717 5.64078 +13.5562 1.80388 -7.57763 +-0.422288 12.0427 5.87878 +7.8458 8.89018 -7.16928 +-2.80247 -10.7738 -6.85101 +8.5821 -9.69517 6.38917 +-15.0108 -1.2106 -6.89244 +-7.42493 0.217489 -9.60293 +-12.2152 -5.44115 7.30482 +12.3774 -5.89669 7.04078 +0.148608 14.6548 0.198925 +16.7932 1.55347 5.69159 +1.37174 -12.7174 -5.07938 +6.74986 -11.9351 -4.90648 +-5.73138 8.79098 -7.7267 +-14.3711 10.0929 -1.58752 +-5.54598 -3.4003 9.63908 +18.2924 -2.08601 4.21135 +-8.87772 -3.99038 8.85011 +2.7156 9.05503 7.99819 +-20.101 -2.0129 0.0553259 +15.2473 -9.59387 -0.825386 +-18.0872 -6.46832 -1.01909 +2.40004 12.1622 -5.62434 +-15.0972 -9.10502 -2.53737 +2.59258 -1.72449 10.1655 +-16.7557 4.89668 4.68946 +11.8934 6.53202 6.99098 +-5.71987 -7.44127 -8.40292 +8.06883 -4.02188 -9.03537 +-13.4126 8.09135 -5.24562 +4.40946 14.2269 -1.05753 +2.17388 -14.3709 1.68982 +11.7121 -7.36981 -6.64262 +0.115603 5.1379 9.67154 +-1.14358 6.41235 -9.26742 +-12.5728 -8.14338 -5.71713 +4.94715 -14.0185 -1.64361 +-13.8475 4.03459 -6.98599 +0.217728 -2.15301 -10.2145 +-16.0136 -3.52862 5.82789 +7.7776 0.209254 9.53288 +-3.46226 13.6603 3.29215 +12.1051 2.64124 8.07158 +-2.99228 -14.3491 1.46102 +3.44161 -5.20385 -9.49237 +-10.1891 12.0148 -2.84247 +-7.92899 12.4431 3.67686 +-3.1252 -0.970184 10.1773 +17.095 3.07029 -5.12548 +-5.59942 3.70556 9.5732 +6.05598 5.31523 9.11451 +-16.4889 -7.99509 2.10075 +19.1271 -4.75159 -0.753882 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_01_groomed_world.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_01_groomed_world.particles new file mode 100644 index 00000000000..7209d6de85f --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_01_groomed_world.particles @@ -0,0 +1,128 @@ +-18.7834 -2.22089 -3.56731 +-5.689 14.0233 -0.804953 +-7.20985 -13.6932 -0.314514 +6.50741 -12.8958 3.61539 +-13.8393 3.30333 7.17799 +10.514 5.28448 -8.00475 +-11.4093 0.440759 -8.52961 +5.54925 4.76924 -9.34466 +-18.089 6.62185 -0.252678 +11.4604 11.3095 -3.01659 +-5.10178 -12.0159 5.3135 +12.4556 -2.80567 -7.90269 +-3.24204 7.85374 8.56395 +3.11597 8.37511 -8.32217 +-8.734 -9.41312 -6.54331 +12.9345 -10.0019 3.68552 +-17.2276 1.80864 -5.30108 +-5.75376 4.73467 -9.3192 +-7.76167 -9.34765 6.89982 +16.9932 -6.65357 3.12984 +4.21845 13.283 3.79002 +19.5663 3.61587 0.972713 +2.43851 -9.58221 -7.71541 +7.06192 -8.37709 -7.66897 +-6.04538 12.2801 -4.71955 +-15.6291 8.8059 2.20135 +-2.70049 -8.18103 8.45425 +20.0992 -0.0157727 -1.41258 +-10.7539 0.923604 8.72958 +7.72851 10.674 5.87622 +-18.7904 -2.84626 3.33354 +11.3059 -10.9726 -3.70776 +-16.3385 -5.11809 -4.94151 +-1.66998 10.3604 -7.25187 +-10.5672 -11.7734 -2.97481 +6.31099 -5.01757 9.15725 +-12.683 9.46153 4.52096 +14.9511 9.9028 0.287426 +-4.07872 -3.14883 -9.86737 +4.64553 -0.369171 -10.0441 +-16.9357 6.10356 -3.71736 +8.95859 13.1023 0.799231 +-1.57308 -14.1793 -2.48129 +15.8441 -6.46206 -4.56124 +0.849068 1.65461 10.2485 +1.41344 2.95398 -10.0894 +-12.2662 -4.51939 -7.58508 +10.0762 -12.7112 0.396584 +-9.91731 4.86656 -8.32716 +-2.9139 1.51376 -10.1589 +-13.0287 -9.32465 4.40973 +13.2411 -2.33306 7.64465 +-6.0949 10.2835 6.66632 +16.8101 6.33712 3.67949 +-5.87535 -12.468 -4.53293 +-1.12997 -6.95534 -9.07231 +-9.73607 9.07333 -6.42129 +-10.9889 12.2198 1.12798 +0.796094 -5.80615 9.47189 +17.1979 6.8665 -2.55549 +-6.79897 0.9667 9.70216 +12.1224 10.3165 3.95764 +-12.8435 -11.3174 0.576439 +16.9639 -2.03565 -5.48182 +-19.6109 2.22406 -2.1127 +-1.56774 13.5956 -3.76318 +-9.27562 -12.1668 3.29065 +3.14089 -9.95612 7.4121 +-9.63977 7.6705 7.29808 +13.2536 7.79307 -5.55818 +-8.63301 -4.19428 -8.86255 +8.83019 0.888783 -9.27139 +-19.5351 2.82432 1.96351 +6.90258 12.1462 -4.59496 +-0.345955 -12.2717 5.64078 +13.5562 1.80388 -7.57763 +-0.422288 12.0427 5.87878 +7.8458 8.89018 -7.16928 +-2.80247 -10.7738 -6.85101 +8.5821 -9.69517 6.38917 +-15.0108 -1.2106 -6.89244 +-7.42493 0.217489 -9.60293 +-12.2152 -5.44115 7.30482 +12.3774 -5.89669 7.04078 +0.148608 14.6548 0.198925 +16.7932 1.55347 5.69159 +1.37174 -12.7174 -5.07938 +6.74986 -11.9351 -4.90648 +-5.73138 8.79098 -7.7267 +-14.3711 10.0929 -1.58752 +-5.54598 -3.4003 9.63908 +18.2924 -2.08601 4.21135 +-8.87772 -3.99038 8.85011 +2.7156 9.05503 7.99819 +-20.101 -2.0129 0.0553259 +15.2473 -9.59387 -0.825386 +-18.0872 -6.46832 -1.01909 +2.40004 12.1622 -5.62434 +-15.0972 -9.10502 -2.53737 +2.59258 -1.72449 10.1655 +-16.7557 4.89668 4.68946 +11.8934 6.53202 6.99098 +-5.71987 -7.44127 -8.40292 +8.06883 -4.02188 -9.03537 +-13.4126 8.09135 -5.24562 +4.40946 14.2269 -1.05753 +2.17388 -14.3709 1.68982 +11.7121 -7.36981 -6.64262 +0.115603 5.1379 9.67154 +-1.14358 6.41235 -9.26742 +-12.5728 -8.14338 -5.71713 +4.94715 -14.0185 -1.64361 +-13.8475 4.03459 -6.98599 +0.217728 -2.15301 -10.2145 +-16.0136 -3.52862 5.82789 +7.7776 0.209254 9.53288 +-3.46226 13.6603 3.29215 +12.1051 2.64124 8.07158 +-2.99228 -14.3491 1.46102 +3.44161 -5.20385 -9.49237 +-10.1891 12.0148 -2.84247 +-7.92899 12.4431 3.67686 +-3.1252 -0.970184 10.1773 +17.095 3.07029 -5.12548 +-5.59942 3.70556 9.5732 +6.05598 5.31523 9.11451 +-16.4889 -7.99509 2.10075 +19.1271 -4.75159 -0.753882 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_02_groomed_local.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_02_groomed_local.particles new file mode 100644 index 00000000000..c461230b341 --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_02_groomed_local.particles @@ -0,0 +1,128 @@ +-18.4213 -2.08891 -2.71773 +-5.8361 12.9991 -0.49971 +-7.24008 -12.6649 -0.00528667 +6.11077 -12.3123 3.06994 +-11.5797 2.9485 8.05055 +10.1534 5.20271 -7.93946 +-11.6559 0.451543 -8.31993 +5.26935 4.77583 -9.35545 +-17.3061 6.00669 0.673919 +10.7934 10.6869 -2.87308 +-4.84165 -11.3411 5.19423 +12.0698 -2.76434 -7.87548 +-2.20891 7.88707 8.44111 +2.83964 8.2832 -8.15861 +-8.88231 -9.17813 -6.06218 +12.4559 -9.71103 2.95764 +-17.1665 1.75682 -4.61174 +-6.0158 4.72136 -9.24833 +-6.7256 -8.81284 7.09638 +16.4581 -6.45902 2.35005 +3.90839 12.6608 3.2985 +18.6775 3.44853 0.411906 +2.1494 -9.40585 -7.47831 +6.7379 -8.2436 -7.48494 +-6.20574 11.7263 -4.16942 +-14.6543 8.01686 2.95861 +-1.79296 -8.22035 8.28254 +19.1123 -0.00353904 -1.599 +-8.32553 0.990602 9.38875 +7.59231 10.4769 5.2923 +-16.9552 -2.68753 4.5683 +10.6728 -10.4044 -3.5234 +-16.2355 -4.90003 -4.2467 +-1.91842 10.1137 -6.93858 +-10.5632 -11.0032 -2.37382 +7.33234 -5.39424 8.73669 +-11.5476 8.65521 5.12237 +14.1359 9.31105 -0.0590576 +-4.33363 -3.18556 -9.87634 +4.40249 -0.367072 -10.1607 +-16.6623 5.72421 -2.96537 +8.30498 12.3123 0.508984 +-1.86641 -13.2971 -2.14093 +15.1476 -6.16928 -4.44405 +3.10821 2.02846 10.1858 +1.16608 2.98411 -10.1695 +-12.4527 -4.4397 -7.22795 +9.40874 -11.9299 0.126904 +-10.1557 4.83741 -8.07564 +-3.16565 1.51299 -10.2323 +-11.8374 -8.53317 5.05801 +13.7098 -2.59274 7.08663 +-5.44501 9.76002 6.68095 +16.3697 6.2167 2.87846 +-6.06521 -11.8871 -3.97628 +-1.37767 -6.9352 -8.96641 +-9.88318 8.8157 -5.9315 +-10.7286 11.1946 1.46697 +2.16805 -6.24116 9.21414 +16.3115 6.48055 -2.59899 +-4.12408 1.20954 10.1548 +11.6433 10.0287 3.25811 +-12.5006 -10.328 1.06852 +16.3093 -1.9623 -5.40254 +-18.9971 2.04718 -1.0912 +-1.87111 12.8512 -3.37359 +-8.95698 -11.2329 3.43882 +3.36088 -9.92917 6.93535 +-8.19524 7.15669 7.70907 +12.6878 7.51667 -5.38572 +-8.88813 -4.20902 -8.69182 +8.54228 0.878454 -9.3386 +-18.0789 2.57914 3.12296 +6.43435 11.5772 -4.30874 +-0.276431 -11.7671 5.29383 +13.1448 1.78019 -7.53424 +-0.337621 11.5898 5.51914 +7.49778 8.68741 -6.96061 +-3.03824 -10.5077 -6.46794 +8.50651 -9.62147 5.80546 +-15.1621 -1.17748 -6.41421 +-7.69338 0.20149 -9.57832 +-10.2865 -4.97095 7.9776 +12.6058 -6.08872 6.3957 +-0.200499 13.653 0.194729 +16.9247 1.56923 4.90156 +1.03097 -12.1825 -4.68307 +6.282 -11.4324 -4.59384 +-5.96011 8.64706 -7.41106 +-14.0751 9.27849 -0.934823 +-3.44759 -3.68033 9.88305 +18.0449 -2.04227 3.39568 +-6.878 -3.93731 9.27875 +3.08639 9.22038 7.52177 +-19.0273 -1.84826 1.15014 +14.4166 -8.99505 -1.03084 +-17.4369 -5.87945 -0.0905483 +2.05971 11.7026 -5.25785 +-14.824 -8.42747 -1.83026 +4.7407 -1.95094 10.0097 +-14.833 4.44515 5.76271 +12.0703 6.69982 6.34366 +-5.95025 -7.39774 -8.16318 +7.77532 -4.01928 -9.04953 +-13.423 7.79613 -4.57213 +3.88242 13.3062 -1.02232 +1.75955 -13.4645 1.46402 +11.257 -7.18242 -6.46812 +1.68395 5.63504 9.46681 +-1.40532 6.39667 -9.19508 +-12.6327 -7.84835 -5.1382 +4.44016 -13.1476 -1.49105 +-13.9927 3.971 -6.53161 +-0.0129074 -2.17245 -10.3129 +-13.8553 -3.14753 6.87231 +9.13649 0.29161 9.197 +-3.45004 12.8241 3.05803 +12.6397 2.90922 7.57714 +-3.16034 -13.3484 1.41687 +3.20105 -5.2123 -9.49255 +-10.162 11.2281 -2.27413 +-7.6518 11.5485 3.73707 +-0.598829 -1.34156 10.385 +16.4213 2.95114 -5.02091 +-3.61277 4.01733 9.78729 +7.005 5.71301 8.69487 +-15.4017 -7.29151 2.94521 +18.1723 -4.43121 -1.06369 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_02_groomed_world.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_02_groomed_world.particles new file mode 100644 index 00000000000..c461230b341 --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_02_groomed_world.particles @@ -0,0 +1,128 @@ +-18.4213 -2.08891 -2.71773 +-5.8361 12.9991 -0.49971 +-7.24008 -12.6649 -0.00528667 +6.11077 -12.3123 3.06994 +-11.5797 2.9485 8.05055 +10.1534 5.20271 -7.93946 +-11.6559 0.451543 -8.31993 +5.26935 4.77583 -9.35545 +-17.3061 6.00669 0.673919 +10.7934 10.6869 -2.87308 +-4.84165 -11.3411 5.19423 +12.0698 -2.76434 -7.87548 +-2.20891 7.88707 8.44111 +2.83964 8.2832 -8.15861 +-8.88231 -9.17813 -6.06218 +12.4559 -9.71103 2.95764 +-17.1665 1.75682 -4.61174 +-6.0158 4.72136 -9.24833 +-6.7256 -8.81284 7.09638 +16.4581 -6.45902 2.35005 +3.90839 12.6608 3.2985 +18.6775 3.44853 0.411906 +2.1494 -9.40585 -7.47831 +6.7379 -8.2436 -7.48494 +-6.20574 11.7263 -4.16942 +-14.6543 8.01686 2.95861 +-1.79296 -8.22035 8.28254 +19.1123 -0.00353904 -1.599 +-8.32553 0.990602 9.38875 +7.59231 10.4769 5.2923 +-16.9552 -2.68753 4.5683 +10.6728 -10.4044 -3.5234 +-16.2355 -4.90003 -4.2467 +-1.91842 10.1137 -6.93858 +-10.5632 -11.0032 -2.37382 +7.33234 -5.39424 8.73669 +-11.5476 8.65521 5.12237 +14.1359 9.31105 -0.0590576 +-4.33363 -3.18556 -9.87634 +4.40249 -0.367072 -10.1607 +-16.6623 5.72421 -2.96537 +8.30498 12.3123 0.508984 +-1.86641 -13.2971 -2.14093 +15.1476 -6.16928 -4.44405 +3.10821 2.02846 10.1858 +1.16608 2.98411 -10.1695 +-12.4527 -4.4397 -7.22795 +9.40874 -11.9299 0.126904 +-10.1557 4.83741 -8.07564 +-3.16565 1.51299 -10.2323 +-11.8374 -8.53317 5.05801 +13.7098 -2.59274 7.08663 +-5.44501 9.76002 6.68095 +16.3697 6.2167 2.87846 +-6.06521 -11.8871 -3.97628 +-1.37767 -6.9352 -8.96641 +-9.88318 8.8157 -5.9315 +-10.7286 11.1946 1.46697 +2.16805 -6.24116 9.21414 +16.3115 6.48055 -2.59899 +-4.12408 1.20954 10.1548 +11.6433 10.0287 3.25811 +-12.5006 -10.328 1.06852 +16.3093 -1.9623 -5.40254 +-18.9971 2.04718 -1.0912 +-1.87111 12.8512 -3.37359 +-8.95698 -11.2329 3.43882 +3.36088 -9.92917 6.93535 +-8.19524 7.15669 7.70907 +12.6878 7.51667 -5.38572 +-8.88813 -4.20902 -8.69182 +8.54228 0.878454 -9.3386 +-18.0789 2.57914 3.12296 +6.43435 11.5772 -4.30874 +-0.276431 -11.7671 5.29383 +13.1448 1.78019 -7.53424 +-0.337621 11.5898 5.51914 +7.49778 8.68741 -6.96061 +-3.03824 -10.5077 -6.46794 +8.50651 -9.62147 5.80546 +-15.1621 -1.17748 -6.41421 +-7.69338 0.20149 -9.57832 +-10.2865 -4.97095 7.9776 +12.6058 -6.08872 6.3957 +-0.200499 13.653 0.194729 +16.9247 1.56923 4.90156 +1.03097 -12.1825 -4.68307 +6.282 -11.4324 -4.59384 +-5.96011 8.64706 -7.41106 +-14.0751 9.27849 -0.934823 +-3.44759 -3.68033 9.88305 +18.0449 -2.04227 3.39568 +-6.878 -3.93731 9.27875 +3.08639 9.22038 7.52177 +-19.0273 -1.84826 1.15014 +14.4166 -8.99505 -1.03084 +-17.4369 -5.87945 -0.0905483 +2.05971 11.7026 -5.25785 +-14.824 -8.42747 -1.83026 +4.7407 -1.95094 10.0097 +-14.833 4.44515 5.76271 +12.0703 6.69982 6.34366 +-5.95025 -7.39774 -8.16318 +7.77532 -4.01928 -9.04953 +-13.423 7.79613 -4.57213 +3.88242 13.3062 -1.02232 +1.75955 -13.4645 1.46402 +11.257 -7.18242 -6.46812 +1.68395 5.63504 9.46681 +-1.40532 6.39667 -9.19508 +-12.6327 -7.84835 -5.1382 +4.44016 -13.1476 -1.49105 +-13.9927 3.971 -6.53161 +-0.0129074 -2.17245 -10.3129 +-13.8553 -3.14753 6.87231 +9.13649 0.29161 9.197 +-3.45004 12.8241 3.05803 +12.6397 2.90922 7.57714 +-3.16034 -13.3484 1.41687 +3.20105 -5.2123 -9.49255 +-10.162 11.2281 -2.27413 +-7.6518 11.5485 3.73707 +-0.598829 -1.34156 10.385 +16.4213 2.95114 -5.02091 +-3.61277 4.01733 9.78729 +7.005 5.71301 8.69487 +-15.4017 -7.29151 2.94521 +18.1723 -4.43121 -1.06369 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_03_groomed_local.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_03_groomed_local.particles new file mode 100644 index 00000000000..20d43bce980 --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_03_groomed_local.particles @@ -0,0 +1,128 @@ +-18.2947 -2.00696 -1.89792 +-6.35417 13.6677 -0.296579 +-7.75242 -13.2354 0.245047 +6.0794 -13.0861 2.99645 +-9.54913 2.90756 8.66813 +9.87126 5.18415 -7.9954 +-11.8643 0.458018 -8.01982 +5.03327 4.79434 -9.36782 +-17.0211 5.75991 1.59822 +10.6828 11.0703 -3.22045 +-4.72221 -12.057 5.15767 +11.7187 -2.73705 -7.85398 +-1.1914 8.74576 8.24413 +2.61938 8.40231 -8.32223 +-9.23173 -9.3689 -6.05713 +12.5148 -10.1995 2.61082 +-17.2267 1.74754 -3.96334 +-6.25888 4.71891 -9.15952 +-5.90942 -9.33831 7.22716 +16.4098 -6.66404 1.71686 +3.85353 13.4744 3.2434 +18.2529 3.46334 -0.143426 +1.91945 -9.58739 -7.70572 +6.53312 -8.35609 -7.66141 +-6.62253 12.1914 -4.28971 +-14.3333 7.916 3.6206 +-0.838182 -9.10623 8.05244 +18.464 -0.000541991 -1.94685 +-6.10542 1.12933 9.75178 +7.83969 11.1489 5.03623 +-15.425 -2.59042 5.62094 +10.5303 -10.7464 -3.87155 +-16.3945 -4.82639 -3.72137 +-2.19516 10.3478 -7.1649 +-11.0778 -11.3386 -2.16332 +8.52328 -6.12397 8.12443 +-10.9623 8.81652 5.60237 +14.0271 9.6513 -0.461074 +-4.5549 -3.20463 -9.77645 +4.15574 -0.35315 -10.0889 +-16.7906 5.64625 -2.35292 +8.1997 13.0711 0.257137 +-2.25095 -14.0499 -2.31778 +14.8056 -6.15254 -4.6276 +5.20173 2.608 9.76926 +0.939024 2.99466 -10.1152 +-12.6856 -4.41939 -6.9568 +9.35294 -12.6035 -0.150161 +-10.4118 4.85197 -7.89929 +-3.3842 1.49362 -10.1232 +-11.1827 -8.67096 5.57475 +14.3028 -2.91866 6.38748 +-4.90252 10.4311 6.67806 +16.3568 6.45009 2.21999 +-6.50126 -12.3925 -4.04203 +-1.61272 -7.00034 -9.02571 +-10.2297 8.95132 -5.88638 +-11.0571 11.4471 1.89066 +3.52651 -7.21108 8.77188 +15.9727 6.5201 -2.88765 +-1.61251 1.51045 10.255 +11.697 10.59 2.95269 +-12.8042 -10.4121 1.58906 +15.8028 -1.93755 -5.43541 +-18.6404 1.91665 -0.0991406 +-2.25363 13.5035 -3.61323 +-9.11074 -11.6205 3.65897 +3.91999 -10.8422 6.5419 +-7.01957 7.531 7.95824 +12.4272 7.56177 -5.59201 +-9.12595 -4.23113 -8.53022 +8.25182 0.858888 -9.27713 +-16.8971 2.37715 4.21224 +6.28091 12.0197 -4.676 +-0.0835081 -12.6337 5.10386 +12.771 1.76211 -7.49607 +-0.112486 12.4638 5.32198 +7.29988 8.81037 -7.17941 +-3.34571 -10.8133 -6.66126 +8.8267 -10.2586 5.48685 +-15.3215 -1.15758 -5.9412 +-7.91148 0.183128 -9.38707 +-8.68825 -5.10198 8.42575 +13.0743 -6.49964 5.81393 +-0.539544 14.5169 0.235579 +17.1967 1.61667 4.02308 +0.773917 -12.6999 -5.00766 +6.08099 -11.859 -4.95441 +-6.26757 8.78325 -7.48659 +-14.4102 9.31401 -0.34921 +-1.42886 -4.23026 9.86841 +18.0067 -2.04143 2.59373 +-5.0283 -4.33187 9.48284 +3.79127 10.1736 7.08748 +-18.2012 -1.74388 2.27803 +14.2742 -9.23394 -1.45604 +-17.2551 -5.66157 0.815114 +1.81648 12.1374 -5.59955 +-15.1523 -8.40937 -1.31626 +6.78189 -2.25599 9.51397 +-13.363 4.27011 6.6182 +12.536 7.14719 5.79952 +-6.22269 -7.5071 -8.18016 +7.52017 -4.02865 -9.03737 +-13.7735 7.88086 -4.26405 +3.63991 14.1376 -1.28943 +1.51018 -14.3241 1.52436 +11.0024 -7.23825 -6.61961 +3.15942 6.57103 9.06631 +-1.64646 6.44261 -9.2333 +-12.9671 -7.92596 -4.92101 +4.24301 -13.9361 -1.75109 +-14.2073 3.96337 -6.16199 +-0.224008 -2.17115 -10.2351 +-12.0733 -2.90536 7.65626 +10.6404 0.37303 8.52767 +-3.62571 13.5345 3.19091 +13.3427 3.27341 6.91121 +-3.52818 -14.0813 1.63842 +2.9852 -5.23632 -9.51294 +-10.6729 11.5973 -2.10546 +-7.73892 12.0626 3.88476 +1.70811 -1.90995 10.2153 +15.9404 2.90922 -5.08372 +-1.74209 4.63685 9.76171 +8.16793 6.51189 8.08153 +-14.9517 -7.1226 3.69178 +17.7324 -4.3699 -1.44781 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_03_groomed_world.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_03_groomed_world.particles new file mode 100644 index 00000000000..20d43bce980 --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_03_groomed_world.particles @@ -0,0 +1,128 @@ +-18.2947 -2.00696 -1.89792 +-6.35417 13.6677 -0.296579 +-7.75242 -13.2354 0.245047 +6.0794 -13.0861 2.99645 +-9.54913 2.90756 8.66813 +9.87126 5.18415 -7.9954 +-11.8643 0.458018 -8.01982 +5.03327 4.79434 -9.36782 +-17.0211 5.75991 1.59822 +10.6828 11.0703 -3.22045 +-4.72221 -12.057 5.15767 +11.7187 -2.73705 -7.85398 +-1.1914 8.74576 8.24413 +2.61938 8.40231 -8.32223 +-9.23173 -9.3689 -6.05713 +12.5148 -10.1995 2.61082 +-17.2267 1.74754 -3.96334 +-6.25888 4.71891 -9.15952 +-5.90942 -9.33831 7.22716 +16.4098 -6.66404 1.71686 +3.85353 13.4744 3.2434 +18.2529 3.46334 -0.143426 +1.91945 -9.58739 -7.70572 +6.53312 -8.35609 -7.66141 +-6.62253 12.1914 -4.28971 +-14.3333 7.916 3.6206 +-0.838182 -9.10623 8.05244 +18.464 -0.000541991 -1.94685 +-6.10542 1.12933 9.75178 +7.83969 11.1489 5.03623 +-15.425 -2.59042 5.62094 +10.5303 -10.7464 -3.87155 +-16.3945 -4.82639 -3.72137 +-2.19516 10.3478 -7.1649 +-11.0778 -11.3386 -2.16332 +8.52328 -6.12397 8.12443 +-10.9623 8.81652 5.60237 +14.0271 9.6513 -0.461074 +-4.5549 -3.20463 -9.77645 +4.15574 -0.35315 -10.0889 +-16.7906 5.64625 -2.35292 +8.1997 13.0711 0.257137 +-2.25095 -14.0499 -2.31778 +14.8056 -6.15254 -4.6276 +5.20173 2.608 9.76926 +0.939024 2.99466 -10.1152 +-12.6856 -4.41939 -6.9568 +9.35294 -12.6035 -0.150161 +-10.4118 4.85197 -7.89929 +-3.3842 1.49362 -10.1232 +-11.1827 -8.67096 5.57475 +14.3028 -2.91866 6.38748 +-4.90252 10.4311 6.67806 +16.3568 6.45009 2.21999 +-6.50126 -12.3925 -4.04203 +-1.61272 -7.00034 -9.02571 +-10.2297 8.95132 -5.88638 +-11.0571 11.4471 1.89066 +3.52651 -7.21108 8.77188 +15.9727 6.5201 -2.88765 +-1.61251 1.51045 10.255 +11.697 10.59 2.95269 +-12.8042 -10.4121 1.58906 +15.8028 -1.93755 -5.43541 +-18.6404 1.91665 -0.0991406 +-2.25363 13.5035 -3.61323 +-9.11074 -11.6205 3.65897 +3.91999 -10.8422 6.5419 +-7.01957 7.531 7.95824 +12.4272 7.56177 -5.59201 +-9.12595 -4.23113 -8.53022 +8.25182 0.858888 -9.27713 +-16.8971 2.37715 4.21224 +6.28091 12.0197 -4.676 +-0.0835081 -12.6337 5.10386 +12.771 1.76211 -7.49607 +-0.112486 12.4638 5.32198 +7.29988 8.81037 -7.17941 +-3.34571 -10.8133 -6.66126 +8.8267 -10.2586 5.48685 +-15.3215 -1.15758 -5.9412 +-7.91148 0.183128 -9.38707 +-8.68825 -5.10198 8.42575 +13.0743 -6.49964 5.81393 +-0.539544 14.5169 0.235579 +17.1967 1.61667 4.02308 +0.773917 -12.6999 -5.00766 +6.08099 -11.859 -4.95441 +-6.26757 8.78325 -7.48659 +-14.4102 9.31401 -0.34921 +-1.42886 -4.23026 9.86841 +18.0067 -2.04143 2.59373 +-5.0283 -4.33187 9.48284 +3.79127 10.1736 7.08748 +-18.2012 -1.74388 2.27803 +14.2742 -9.23394 -1.45604 +-17.2551 -5.66157 0.815114 +1.81648 12.1374 -5.59955 +-15.1523 -8.40937 -1.31626 +6.78189 -2.25599 9.51397 +-13.363 4.27011 6.6182 +12.536 7.14719 5.79952 +-6.22269 -7.5071 -8.18016 +7.52017 -4.02865 -9.03737 +-13.7735 7.88086 -4.26405 +3.63991 14.1376 -1.28943 +1.51018 -14.3241 1.52436 +11.0024 -7.23825 -6.61961 +3.15942 6.57103 9.06631 +-1.64646 6.44261 -9.2333 +-12.9671 -7.92596 -4.92101 +4.24301 -13.9361 -1.75109 +-14.2073 3.96337 -6.16199 +-0.224008 -2.17115 -10.2351 +-12.0733 -2.90536 7.65626 +10.6404 0.37303 8.52767 +-3.62571 13.5345 3.19091 +13.3427 3.27341 6.91121 +-3.52818 -14.0813 1.63842 +2.9852 -5.23632 -9.51294 +-10.6729 11.5973 -2.10546 +-7.73892 12.0626 3.88476 +1.70811 -1.90995 10.2153 +15.9404 2.90922 -5.08372 +-1.74209 4.63685 9.76171 +8.16793 6.51189 8.08153 +-14.9517 -7.1226 3.69178 +17.7324 -4.3699 -1.44781 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_04_groomed_local.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_04_groomed_local.particles new file mode 100644 index 00000000000..afa2d5f59cb --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_04_groomed_local.particles @@ -0,0 +1,128 @@ +-19.4016 -2.17854 -1.52059 +-6.56213 12.8966 -0.0388075 +-7.89196 -12.5262 0.533264 +5.74899 -12.607 2.47787 +-7.48058 2.96946 8.76065 +9.50229 5.06227 -7.75269 +-12.1054 0.465178 -7.71296 +4.71118 4.66038 -8.8474 +-17.2666 5.82265 2.49551 +10.2735 10.7954 -3.23142 +-4.56407 -11.3369 4.95353 +11.3741 -2.68405 -7.75979 +-0.40173 8.47272 7.62847 +2.33171 8.10076 -7.75269 +-9.39314 -9.13643 -5.58543 +12.3628 -10.2943 2.09495 +-18.0637 1.84548 -3.87115 +-6.41998 4.58411 -8.6109 +-5.03045 -8.75072 7.05075 +16.8186 -7.11528 1.18258 +3.55935 12.8822 2.72435 +19.0467 3.83178 -0.768971 +1.6326 -9.22201 -7.13435 +6.18465 -8.08757 -7.23593 +-6.78591 11.681 -3.79498 +-13.952 7.71636 4.23497 +-0.161557 -8.82322 7.426 +19.0968 -0.0127597 -2.76125 +-3.72798 1.07466 9.52163 +7.80003 11.0348 4.27907 +-14.6312 -2.86447 6.2722 +10.1053 -10.4673 -3.83203 +-17.0566 -4.98215 -3.54806 +-2.40208 9.92379 -6.58719 +-11.2978 -10.9831 -1.73361 +9.62268 -6.76868 7.01659 +-10.087 8.36611 5.89586 +13.8448 9.75058 -0.830105 +-4.72842 -3.13642 -9.18089 +3.86567 -0.343522 -9.5401 +-17.5465 5.83862 -1.94672 +7.71679 12.5942 -0.00154135 +-2.51787 -13.2643 -1.98774 +14.6037 -6.18591 -4.93371 +7.51685 3.12554 8.72865 +0.690931 2.90878 -9.49804 +-12.9741 -4.38801 -6.68759 +8.90247 -12.208 -0.402626 +-10.6231 4.78025 -7.49052 +-3.56103 1.4516 -9.51402 +-10.2672 -8.25333 5.90373 +15.5541 -3.40927 5.56423 +-4.34505 9.79778 6.43553 +16.801 6.90759 1.73935 +-6.68807 -11.8706 -3.52968 +-1.82611 -6.78078 -8.39939 +-10.4212 8.76429 -5.45854 +-11.0445 10.8984 2.29909 +4.60129 -7.48441 7.81941 +15.907 6.70159 -3.38101 +0.609918 1.79054 9.63829 +11.485 10.6251 2.42303 +-12.8516 -9.97999 2.16619 +15.667 -1.96151 -5.84075 +-19.6088 2.06687 0.808498 +-2.51435 12.7787 -3.22619 +-8.94937 -10.9471 3.83106 +4.08452 -10.6524 5.75238 +-5.64526 7.05612 7.85675 +12.0746 7.45188 -5.6343 +-9.30525 -4.1677 -8.06854 +7.90009 0.83039 -8.90869 +-16.7143 2.4983 4.97604 +5.86501 11.5119 -4.38293 +-0.0546208 -12.0138 4.62191 +12.451 1.75481 -7.48586 +-0.0864381 11.8732 4.80235 +6.95778 8.51278 -6.81129 +-3.5412 -10.3905 -6.0741 +8.9038 -10.3054 4.67736 +-15.8374 -1.16242 -5.8414 +-8.07164 0.156417 -8.89334 +-6.83739 -4.87744 8.44804 +13.7419 -6.95014 5.00206 +-0.860366 13.6393 0.246322 +18.2727 1.76649 3.66086 +0.474642 -12.0913 -4.52237 +5.686 -11.3627 -4.62611 +-6.44247 8.50569 -6.92763 +-14.708 9.20225 0.276953 +0.446751 -4.27306 9.2367 +19.0809 -2.25272 2.25524 +-3.11547 -4.1024 9.15118 +4.04504 10.1257 6.22052 +-18.593 -1.84734 3.21692 +14.089 -9.30997 -1.8197 +-17.715 -5.73555 1.73525 +1.50015 11.5846 -5.11023 +-15.5817 -8.41973 -0.846388 +9.18881 -2.61325 8.42888 +-12.0746 4.33634 7.09233 +13.0896 7.54933 4.98337 +-6.38869 -7.30718 -7.6028 +7.17523 -3.93814 -8.62668 +-14.1262 7.91024 -3.89792 +3.16705 13.3805 -1.2501 +1.15069 -13.5154 1.29144 +10.6374 -7.09469 -6.48209 +4.3479 6.91755 8.12201 +-1.86566 6.23215 -8.6077 +-13.2687 -7.87586 -4.59486 +3.80419 -13.2008 -1.66834 +-14.5909 4.00818 -5.96917 +-0.432646 -2.10815 -9.60835 +-10.5516 -2.97614 7.97061 +12.8956 0.483571 7.39985 +-3.67272 12.7229 3.04763 +14.6993 3.82786 5.96349 +-3.70635 -13.2212 1.63743 +2.70794 -5.07656 -8.93518 +-10.8601 11.2038 -1.6822 +-7.57846 11.3432 3.9518 +4.01954 -2.36497 9.37543 +15.8547 2.96319 -5.49331 +1.47719 3.89622 9.2951 +9.16823 7.13746 6.98183 +-14.5758 -7.02099 4.34075 +18.228 -4.64192 -2.09401 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_04_groomed_world.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_04_groomed_world.particles new file mode 100644 index 00000000000..afa2d5f59cb --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_04_groomed_world.particles @@ -0,0 +1,128 @@ +-19.4016 -2.17854 -1.52059 +-6.56213 12.8966 -0.0388075 +-7.89196 -12.5262 0.533264 +5.74899 -12.607 2.47787 +-7.48058 2.96946 8.76065 +9.50229 5.06227 -7.75269 +-12.1054 0.465178 -7.71296 +4.71118 4.66038 -8.8474 +-17.2666 5.82265 2.49551 +10.2735 10.7954 -3.23142 +-4.56407 -11.3369 4.95353 +11.3741 -2.68405 -7.75979 +-0.40173 8.47272 7.62847 +2.33171 8.10076 -7.75269 +-9.39314 -9.13643 -5.58543 +12.3628 -10.2943 2.09495 +-18.0637 1.84548 -3.87115 +-6.41998 4.58411 -8.6109 +-5.03045 -8.75072 7.05075 +16.8186 -7.11528 1.18258 +3.55935 12.8822 2.72435 +19.0467 3.83178 -0.768971 +1.6326 -9.22201 -7.13435 +6.18465 -8.08757 -7.23593 +-6.78591 11.681 -3.79498 +-13.952 7.71636 4.23497 +-0.161557 -8.82322 7.426 +19.0968 -0.0127597 -2.76125 +-3.72798 1.07466 9.52163 +7.80003 11.0348 4.27907 +-14.6312 -2.86447 6.2722 +10.1053 -10.4673 -3.83203 +-17.0566 -4.98215 -3.54806 +-2.40208 9.92379 -6.58719 +-11.2978 -10.9831 -1.73361 +9.62268 -6.76868 7.01659 +-10.087 8.36611 5.89586 +13.8448 9.75058 -0.830105 +-4.72842 -3.13642 -9.18089 +3.86567 -0.343522 -9.5401 +-17.5465 5.83862 -1.94672 +7.71679 12.5942 -0.00154135 +-2.51787 -13.2643 -1.98774 +14.6037 -6.18591 -4.93371 +7.51685 3.12554 8.72865 +0.690931 2.90878 -9.49804 +-12.9741 -4.38801 -6.68759 +8.90247 -12.208 -0.402626 +-10.6231 4.78025 -7.49052 +-3.56103 1.4516 -9.51402 +-10.2672 -8.25333 5.90373 +15.5541 -3.40927 5.56423 +-4.34505 9.79778 6.43553 +16.801 6.90759 1.73935 +-6.68807 -11.8706 -3.52968 +-1.82611 -6.78078 -8.39939 +-10.4212 8.76429 -5.45854 +-11.0445 10.8984 2.29909 +4.60129 -7.48441 7.81941 +15.907 6.70159 -3.38101 +0.609918 1.79054 9.63829 +11.485 10.6251 2.42303 +-12.8516 -9.97999 2.16619 +15.667 -1.96151 -5.84075 +-19.6088 2.06687 0.808498 +-2.51435 12.7787 -3.22619 +-8.94937 -10.9471 3.83106 +4.08452 -10.6524 5.75238 +-5.64526 7.05612 7.85675 +12.0746 7.45188 -5.6343 +-9.30525 -4.1677 -8.06854 +7.90009 0.83039 -8.90869 +-16.7143 2.4983 4.97604 +5.86501 11.5119 -4.38293 +-0.0546208 -12.0138 4.62191 +12.451 1.75481 -7.48586 +-0.0864381 11.8732 4.80235 +6.95778 8.51278 -6.81129 +-3.5412 -10.3905 -6.0741 +8.9038 -10.3054 4.67736 +-15.8374 -1.16242 -5.8414 +-8.07164 0.156417 -8.89334 +-6.83739 -4.87744 8.44804 +13.7419 -6.95014 5.00206 +-0.860366 13.6393 0.246322 +18.2727 1.76649 3.66086 +0.474642 -12.0913 -4.52237 +5.686 -11.3627 -4.62611 +-6.44247 8.50569 -6.92763 +-14.708 9.20225 0.276953 +0.446751 -4.27306 9.2367 +19.0809 -2.25272 2.25524 +-3.11547 -4.1024 9.15118 +4.04504 10.1257 6.22052 +-18.593 -1.84734 3.21692 +14.089 -9.30997 -1.8197 +-17.715 -5.73555 1.73525 +1.50015 11.5846 -5.11023 +-15.5817 -8.41973 -0.846388 +9.18881 -2.61325 8.42888 +-12.0746 4.33634 7.09233 +13.0896 7.54933 4.98337 +-6.38869 -7.30718 -7.6028 +7.17523 -3.93814 -8.62668 +-14.1262 7.91024 -3.89792 +3.16705 13.3805 -1.2501 +1.15069 -13.5154 1.29144 +10.6374 -7.09469 -6.48209 +4.3479 6.91755 8.12201 +-1.86566 6.23215 -8.6077 +-13.2687 -7.87586 -4.59486 +3.80419 -13.2008 -1.66834 +-14.5909 4.00818 -5.96917 +-0.432646 -2.10815 -9.60835 +-10.5516 -2.97614 7.97061 +12.8956 0.483571 7.39985 +-3.67272 12.7229 3.04763 +14.6993 3.82786 5.96349 +-3.70635 -13.2212 1.63743 +2.70794 -5.07656 -8.93518 +-10.8601 11.2038 -1.6822 +-7.57846 11.3432 3.9518 +4.01954 -2.36497 9.37543 +15.8547 2.96319 -5.49331 +1.47719 3.89622 9.2951 +9.16823 7.13746 6.98183 +-14.5758 -7.02099 4.34075 +18.228 -4.64192 -2.09401 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_05_groomed_local.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_05_groomed_local.particles new file mode 100644 index 00000000000..89d9d301254 --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_05_groomed_local.particles @@ -0,0 +1,128 @@ +-19.1189 -2.05997 -0.814118 +-6.9135 12.9869 0.162783 +-8.19381 -12.5484 0.791875 +5.59366 -12.9124 2.30691 +-5.34118 2.74414 9.40371 +9.2756 5.0907 -7.98195 +-12.3922 0.479473 -7.68251 +4.50519 4.73981 -9.10552 +-16.6724 5.34809 3.36308 +10.011 10.9127 -3.42861 +-4.45287 -11.4218 5.21833 +11.1171 -2.70503 -7.96668 +0.420045 8.77833 7.75098 +2.11947 8.24992 -7.97467 +-9.68856 -9.26234 -5.53183 +12.2534 -10.5209 1.70125 +-18.1121 1.82575 -3.32826 +-6.69271 4.6343 -8.7717 +-4.24346 -8.7371 7.45994 +16.6025 -7.13812 0.57209 +3.41516 13.1896 2.6234 +18.5225 3.74422 -1.23235 +1.40354 -9.37092 -7.35015 +5.99118 -8.21443 -7.45421 +-7.10274 11.8474 -3.73685 +-13.3395 7.27847 5.02331 +0.570698 -9.1418 7.52859 +18.5012 -0.00413991 -3.021 +-1.57539 1.11596 9.93008 +7.89464 11.3937 4.02983 +-12.7203 -2.58544 7.31695 +9.8539 -10.5719 -4.0364 +-17.1586 -4.89473 -3.05243 +-2.66873 10.0863 -6.74062 +-11.6024 -10.9686 -1.41097 +10.4871 -7.23571 6.60395 +-9.30304 8.06569 6.57677 +13.5589 9.80044 -1.17947 +-4.97235 -3.20775 -9.38813 +3.66316 -0.336292 -9.81556 +-17.5174 5.64986 -1.37198 +7.44776 12.829 -0.212094 +-2.84006 -13.4645 -1.99584 +14.2742 -6.15532 -5.12537 +9.24807 3.5704 8.4041 +0.479051 2.97123 -9.76515 +-13.2496 -4.39622 -6.5791 +8.66678 -12.4085 -0.620474 +-10.9148 4.83606 -7.49935 +-3.79565 1.45551 -9.75047 +-9.41149 -7.96168 6.60386 +16.1074 -3.6927 4.89979 +-3.87951 9.84944 6.7666 +16.6382 6.96909 1.10567 +-7.02471 -12.0475 -3.4242 +-2.05493 -6.89348 -8.62175 +-10.7207 8.83 -5.38536 +-11.1489 10.6846 2.79804 +5.63226 -8.00029 7.64322 +15.5041 6.65603 -3.62996 +3.04144 2.00448 9.76842 +11.364 10.8979 2.04803 +-12.882 -9.66681 2.74235 +15.2865 -1.94816 -5.99709 +-18.991 1.87945 1.55246 +-2.85044 12.9755 -3.26457 +-8.94543 -10.8064 4.26829 +4.37525 -11.0357 5.64261 +-4.48753 6.96208 8.34177 +11.8052 7.49577 -5.82991 +-9.59297 -4.24766 -8.14048 +7.68747 0.826864 -9.15969 +-15.1506 2.17301 6.04505 +5.63962 11.6711 -4.58518 +0.0276021 -12.274 4.68537 +12.1871 1.7623 -7.67448 +0.00176708 12.1393 4.85994 +6.76148 8.62719 -7.02853 +-3.81872 -10.584 -6.17207 +9.07981 -10.6811 4.35915 +-16.0815 -1.1564 -5.53618 +-8.3436 0.149199 -9.0229 +-5.12278 -4.71874 9.02447 +14.1199 -7.27057 4.42729 +-1.17444 13.8674 0.278978 +18.437 1.77524 2.83478 +0.206001 -12.3022 -4.64876 +5.441 -11.5335 -4.81758 +-6.73349 8.63377 -7.03082 +-14.7816 8.93576 0.799053 +2.21649 -4.60626 9.36347 +18.9294 -2.2135 1.48524 +-1.3641 -4.21355 9.50081 +4.42759 10.5514 6.09942 +-17.407 -1.63198 4.26325 +13.7855 -9.31989 -2.13021 +-17.2494 -5.3078 2.52455 +1.23846 11.7756 -5.27368 +-15.6755 -8.17984 -0.36713 +10.926 -2.83516 8.00924 +-10.2975 3.91186 7.99027 +13.4548 7.87626 4.44446 +-6.65472 -7.44839 -7.71157 +6.97358 -3.99883 -8.87265 +-14.3734 7.91975 -3.54987 +2.8632 13.6077 -1.40626 +0.853673 -13.765 1.30029 +10.4017 -7.15364 -6.68358 +5.50946 7.41186 7.9671 +-2.1077 6.33753 -8.83299 +-13.5291 -7.89962 -4.36316 +3.53521 -13.4421 -1.76444 +-14.8481 4.02888 -5.7444 +-0.639053 -2.14563 -9.87121 +-8.50684 -2.54707 8.79535 +14.1602 0.554711 6.82066 +-3.79802 12.8735 3.22958 +15.354 4.1287 5.33901 +-3.98833 -13.3655 1.82993 +2.52037 -5.16576 -9.19484 +-11.1535 11.2001 -1.42187 +-7.55436 11.2871 4.3409 +6.04195 -2.83535 9.28027 +15.4829 2.94309 -5.6428 +1.7752 4.9193 9.30621 +9.96693 7.62622 6.59269 +-13.8176 -6.5378 5.20473 +17.7453 -4.51114 -2.40103 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_05_groomed_world.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_05_groomed_world.particles new file mode 100644 index 00000000000..89d9d301254 --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_05_groomed_world.particles @@ -0,0 +1,128 @@ +-19.1189 -2.05997 -0.814118 +-6.9135 12.9869 0.162783 +-8.19381 -12.5484 0.791875 +5.59366 -12.9124 2.30691 +-5.34118 2.74414 9.40371 +9.2756 5.0907 -7.98195 +-12.3922 0.479473 -7.68251 +4.50519 4.73981 -9.10552 +-16.6724 5.34809 3.36308 +10.011 10.9127 -3.42861 +-4.45287 -11.4218 5.21833 +11.1171 -2.70503 -7.96668 +0.420045 8.77833 7.75098 +2.11947 8.24992 -7.97467 +-9.68856 -9.26234 -5.53183 +12.2534 -10.5209 1.70125 +-18.1121 1.82575 -3.32826 +-6.69271 4.6343 -8.7717 +-4.24346 -8.7371 7.45994 +16.6025 -7.13812 0.57209 +3.41516 13.1896 2.6234 +18.5225 3.74422 -1.23235 +1.40354 -9.37092 -7.35015 +5.99118 -8.21443 -7.45421 +-7.10274 11.8474 -3.73685 +-13.3395 7.27847 5.02331 +0.570698 -9.1418 7.52859 +18.5012 -0.00413991 -3.021 +-1.57539 1.11596 9.93008 +7.89464 11.3937 4.02983 +-12.7203 -2.58544 7.31695 +9.8539 -10.5719 -4.0364 +-17.1586 -4.89473 -3.05243 +-2.66873 10.0863 -6.74062 +-11.6024 -10.9686 -1.41097 +10.4871 -7.23571 6.60395 +-9.30304 8.06569 6.57677 +13.5589 9.80044 -1.17947 +-4.97235 -3.20775 -9.38813 +3.66316 -0.336292 -9.81556 +-17.5174 5.64986 -1.37198 +7.44776 12.829 -0.212094 +-2.84006 -13.4645 -1.99584 +14.2742 -6.15532 -5.12537 +9.24807 3.5704 8.4041 +0.479051 2.97123 -9.76515 +-13.2496 -4.39622 -6.5791 +8.66678 -12.4085 -0.620474 +-10.9148 4.83606 -7.49935 +-3.79565 1.45551 -9.75047 +-9.41149 -7.96168 6.60386 +16.1074 -3.6927 4.89979 +-3.87951 9.84944 6.7666 +16.6382 6.96909 1.10567 +-7.02471 -12.0475 -3.4242 +-2.05493 -6.89348 -8.62175 +-10.7207 8.83 -5.38536 +-11.1489 10.6846 2.79804 +5.63226 -8.00029 7.64322 +15.5041 6.65603 -3.62996 +3.04144 2.00448 9.76842 +11.364 10.8979 2.04803 +-12.882 -9.66681 2.74235 +15.2865 -1.94816 -5.99709 +-18.991 1.87945 1.55246 +-2.85044 12.9755 -3.26457 +-8.94543 -10.8064 4.26829 +4.37525 -11.0357 5.64261 +-4.48753 6.96208 8.34177 +11.8052 7.49577 -5.82991 +-9.59297 -4.24766 -8.14048 +7.68747 0.826864 -9.15969 +-15.1506 2.17301 6.04505 +5.63962 11.6711 -4.58518 +0.0276021 -12.274 4.68537 +12.1871 1.7623 -7.67448 +0.00176708 12.1393 4.85994 +6.76148 8.62719 -7.02853 +-3.81872 -10.584 -6.17207 +9.07981 -10.6811 4.35915 +-16.0815 -1.1564 -5.53618 +-8.3436 0.149199 -9.0229 +-5.12278 -4.71874 9.02447 +14.1199 -7.27057 4.42729 +-1.17444 13.8674 0.278978 +18.437 1.77524 2.83478 +0.206001 -12.3022 -4.64876 +5.441 -11.5335 -4.81758 +-6.73349 8.63377 -7.03082 +-14.7816 8.93576 0.799053 +2.21649 -4.60626 9.36347 +18.9294 -2.2135 1.48524 +-1.3641 -4.21355 9.50081 +4.42759 10.5514 6.09942 +-17.407 -1.63198 4.26325 +13.7855 -9.31989 -2.13021 +-17.2494 -5.3078 2.52455 +1.23846 11.7756 -5.27368 +-15.6755 -8.17984 -0.36713 +10.926 -2.83516 8.00924 +-10.2975 3.91186 7.99027 +13.4548 7.87626 4.44446 +-6.65472 -7.44839 -7.71157 +6.97358 -3.99883 -8.87265 +-14.3734 7.91975 -3.54987 +2.8632 13.6077 -1.40626 +0.853673 -13.765 1.30029 +10.4017 -7.15364 -6.68358 +5.50946 7.41186 7.9671 +-2.1077 6.33753 -8.83299 +-13.5291 -7.89962 -4.36316 +3.53521 -13.4421 -1.76444 +-14.8481 4.02888 -5.7444 +-0.639053 -2.14563 -9.87121 +-8.50684 -2.54707 8.79535 +14.1602 0.554711 6.82066 +-3.79802 12.8735 3.22958 +15.354 4.1287 5.33901 +-3.98833 -13.3655 1.82993 +2.52037 -5.16576 -9.19484 +-11.1535 11.2001 -1.42187 +-7.55436 11.2871 4.3409 +6.04195 -2.83535 9.28027 +15.4829 2.94309 -5.6428 +1.7752 4.9193 9.30621 +9.96693 7.62622 6.59269 +-13.8176 -6.5378 5.20473 +17.7453 -4.51114 -2.40103 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_06_groomed_local.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_06_groomed_local.particles new file mode 100644 index 00000000000..a0eeb3b1844 --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_06_groomed_local.particles @@ -0,0 +1,128 @@ +-19.8956 -2.15691 -0.178628 +-7.50483 13.7367 0.432752 +-8.78903 -13.2364 1.16381 +5.57725 -13.8663 2.25657 +-3.2346 2.74741 10.0258 +9.12554 5.20666 -8.47221 +-12.8744 0.505428 -7.93737 +4.30659 4.85903 -9.51741 +-16.7288 5.26308 4.41525 +10.0026 11.5274 -3.97898 +-4.47075 -11.9793 5.63733 +10.9628 -2.76522 -8.45316 +1.30248 9.40764 7.96486 +1.90573 8.50651 -8.41394 +-10.1897 -9.70736 -5.8048 +12.5642 -11.4047 1.37445 +-18.9792 1.95962 -3.15392 +-7.03265 4.74341 -9.106 +-3.51506 -9.07107 7.98002 +17.1374 -7.76697 -0.103389 +3.3512 14.1215 2.64409 +18.9624 4.03825 -1.97778 +1.17433 -9.68621 -7.80669 +5.83995 -8.49402 -7.92741 +-7.60558 12.4908 -3.96971 +-13.182 7.254 5.94939 +1.35965 -9.8085 7.72256 +18.7043 -0.0122496 -3.81662 +0.762665 1.15052 10.3027 +8.22186 12.3336 3.87322 +-11.3081 -2.51755 8.36958 +9.82184 -11.1307 -4.59084 +-17.9939 -5.13588 -2.91408 +-2.98386 10.4673 -7.15913 +-12.3224 -11.5826 -1.22798 +11.7274 -8.13533 6.19158 +-8.7668 8.13485 7.37586 +13.7593 10.5208 -1.74082 +-5.26767 -3.29955 -9.71493 +3.45646 -0.326053 -10.1862 +-18.3578 5.94522 -0.881196 +7.38446 13.7675 -0.503432 +-3.26719 -14.2818 -2.18251 +14.2831 -6.39015 -5.7538 +11.4135 4.19726 7.9989 +0.248616 3.04464 -10.1222 +-13.805 -4.55649 -6.81608 +8.66587 -13.3026 -0.983315 +-11.3813 5.00805 -7.78026 +-4.06754 1.46669 -10.0776 +-8.8023 -8.04406 7.41408 +17.4177 -4.28162 4.22691 +-3.48202 10.2916 7.22413 +17.2277 7.60639 0.513156 +-7.55531 -12.7415 -3.58032 +-2.32386 -7.08915 -9.00901 +-11.2686 9.23571 -5.64307 +-11.5939 11.0176 3.5062 +6.86477 -8.86999 7.49524 +15.5986 7.01535 -4.31814 +5.61321 2.29353 9.8043 +11.6278 11.8263 1.77439 +-13.334 -9.86594 3.54296 +15.2134 -2.01589 -6.62016 +-19.3507 1.88556 2.51437 +-3.27524 13.7058 -3.54946 +-9.21011 -11.1448 4.9116 +4.79343 -11.9361 5.61099 +-3.30112 7.16626 8.89566 +11.7463 7.76708 -6.41024 +-9.99618 -4.39238 -8.43861 +7.49824 0.82592 -9.57756 +-14.2722 2.00429 7.15585 +5.50753 12.239 -5.09606 +0.0971899 -13.0659 4.87754 +12.0578 1.81051 -8.18091 +0.0806276 12.9254 5.05425 +6.62499 8.91432 -7.52809 +-4.16935 -11.0477 -6.55289 +9.52895 -11.6143 4.16332 +-16.7771 -1.1904 -5.65144 +-8.69968 0.134123 -9.32244 +-3.43308 -4.79172 9.62672 +15.0564 -8.08418 3.89782 +-1.55918 14.7656 0.351791 +19.506 1.93986 2.127 +-0.0780956 -12.919 -5.06236 +5.28098 -12.0932 -5.32669 +-7.1264 8.94328 -7.39035 +-15.4316 9.27219 1.48377 +4.19436 -5.08665 9.47308 +19.7795 -2.3955 0.824213 +0.506718 -4.45312 9.86233 +4.94615 11.4558 6.04837 +-17.0246 -1.57663 5.39836 +13.9332 -9.92824 -2.7719 +-17.4966 -5.27927 3.52402 +0.97405 12.3147 -5.73007 +-16.4411 -8.53261 0.121036 +13.1729 -3.20751 7.48752 +-8.83197 3.75167 8.91519 +14.3438 8.71337 3.95335 +-7.02233 -7.72477 -8.05557 +6.80619 -4.10717 -9.30275 +-15.1119 8.3751 -3.52856 +2.58353 14.4903 -1.7114 +0.562301 -14.6802 1.38893 +10.3011 -7.40793 -7.22664 +6.85975 8.26248 7.82614 +-2.38546 6.5165 -9.21522 +-14.199 -8.29756 -4.48372 +3.319 -14.3137 -2.06469 +-15.4878 4.21631 -5.90638 +-0.866797 -2.19443 -10.218 +-6.66927 -2.29936 9.62477 +16.141 0.661802 6.15585 +-4.03444 13.5809 3.58586 +16.7061 4.79458 4.68679 +-4.40393 -14.1264 2.15761 +2.3211 -5.29093 -9.58978 +-11.8408 11.8496 -1.27641 +-7.75064 11.7445 4.89614 +8.31982 -3.3994 9.11288 +15.4592 3.0531 -6.26324 +3.58074 5.41775 9.45096 +11.1206 8.55283 6.22073 +-13.5526 -6.44813 6.17919 +18.064 -4.75158 -3.11692 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_06_groomed_world.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_06_groomed_world.particles new file mode 100644 index 00000000000..a0eeb3b1844 --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_06_groomed_world.particles @@ -0,0 +1,128 @@ +-19.8956 -2.15691 -0.178628 +-7.50483 13.7367 0.432752 +-8.78903 -13.2364 1.16381 +5.57725 -13.8663 2.25657 +-3.2346 2.74741 10.0258 +9.12554 5.20666 -8.47221 +-12.8744 0.505428 -7.93737 +4.30659 4.85903 -9.51741 +-16.7288 5.26308 4.41525 +10.0026 11.5274 -3.97898 +-4.47075 -11.9793 5.63733 +10.9628 -2.76522 -8.45316 +1.30248 9.40764 7.96486 +1.90573 8.50651 -8.41394 +-10.1897 -9.70736 -5.8048 +12.5642 -11.4047 1.37445 +-18.9792 1.95962 -3.15392 +-7.03265 4.74341 -9.106 +-3.51506 -9.07107 7.98002 +17.1374 -7.76697 -0.103389 +3.3512 14.1215 2.64409 +18.9624 4.03825 -1.97778 +1.17433 -9.68621 -7.80669 +5.83995 -8.49402 -7.92741 +-7.60558 12.4908 -3.96971 +-13.182 7.254 5.94939 +1.35965 -9.8085 7.72256 +18.7043 -0.0122496 -3.81662 +0.762665 1.15052 10.3027 +8.22186 12.3336 3.87322 +-11.3081 -2.51755 8.36958 +9.82184 -11.1307 -4.59084 +-17.9939 -5.13588 -2.91408 +-2.98386 10.4673 -7.15913 +-12.3224 -11.5826 -1.22798 +11.7274 -8.13533 6.19158 +-8.7668 8.13485 7.37586 +13.7593 10.5208 -1.74082 +-5.26767 -3.29955 -9.71493 +3.45646 -0.326053 -10.1862 +-18.3578 5.94522 -0.881196 +7.38446 13.7675 -0.503432 +-3.26719 -14.2818 -2.18251 +14.2831 -6.39015 -5.7538 +11.4135 4.19726 7.9989 +0.248616 3.04464 -10.1222 +-13.805 -4.55649 -6.81608 +8.66587 -13.3026 -0.983315 +-11.3813 5.00805 -7.78026 +-4.06754 1.46669 -10.0776 +-8.8023 -8.04406 7.41408 +17.4177 -4.28162 4.22691 +-3.48202 10.2916 7.22413 +17.2277 7.60639 0.513156 +-7.55531 -12.7415 -3.58032 +-2.32386 -7.08915 -9.00901 +-11.2686 9.23571 -5.64307 +-11.5939 11.0176 3.5062 +6.86477 -8.86999 7.49524 +15.5986 7.01535 -4.31814 +5.61321 2.29353 9.8043 +11.6278 11.8263 1.77439 +-13.334 -9.86594 3.54296 +15.2134 -2.01589 -6.62016 +-19.3507 1.88556 2.51437 +-3.27524 13.7058 -3.54946 +-9.21011 -11.1448 4.9116 +4.79343 -11.9361 5.61099 +-3.30112 7.16626 8.89566 +11.7463 7.76708 -6.41024 +-9.99618 -4.39238 -8.43861 +7.49824 0.82592 -9.57756 +-14.2722 2.00429 7.15585 +5.50753 12.239 -5.09606 +0.0971899 -13.0659 4.87754 +12.0578 1.81051 -8.18091 +0.0806276 12.9254 5.05425 +6.62499 8.91432 -7.52809 +-4.16935 -11.0477 -6.55289 +9.52895 -11.6143 4.16332 +-16.7771 -1.1904 -5.65144 +-8.69968 0.134123 -9.32244 +-3.43308 -4.79172 9.62672 +15.0564 -8.08418 3.89782 +-1.55918 14.7656 0.351791 +19.506 1.93986 2.127 +-0.0780956 -12.919 -5.06236 +5.28098 -12.0932 -5.32669 +-7.1264 8.94328 -7.39035 +-15.4316 9.27219 1.48377 +4.19436 -5.08665 9.47308 +19.7795 -2.3955 0.824213 +0.506718 -4.45312 9.86233 +4.94615 11.4558 6.04837 +-17.0246 -1.57663 5.39836 +13.9332 -9.92824 -2.7719 +-17.4966 -5.27927 3.52402 +0.97405 12.3147 -5.73007 +-16.4411 -8.53261 0.121036 +13.1729 -3.20751 7.48752 +-8.83197 3.75167 8.91519 +14.3438 8.71337 3.95335 +-7.02233 -7.72477 -8.05557 +6.80619 -4.10717 -9.30275 +-15.1119 8.3751 -3.52856 +2.58353 14.4903 -1.7114 +0.562301 -14.6802 1.38893 +10.3011 -7.40793 -7.22664 +6.85975 8.26248 7.82614 +-2.38546 6.5165 -9.21522 +-14.199 -8.29756 -4.48372 +3.319 -14.3137 -2.06469 +-15.4878 4.21631 -5.90638 +-0.866797 -2.19443 -10.218 +-6.66927 -2.29936 9.62477 +16.141 0.661802 6.15585 +-4.03444 13.5809 3.58586 +16.7061 4.79458 4.68679 +-4.40393 -14.1264 2.15761 +2.3211 -5.29093 -9.58978 +-11.8408 11.8496 -1.27641 +-7.75064 11.7445 4.89614 +8.31982 -3.3994 9.11288 +15.4592 3.0531 -6.26324 +3.58074 5.41775 9.45096 +11.1206 8.55283 6.22073 +-13.5526 -6.44813 6.17919 +18.064 -4.75158 -3.11692 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_07_groomed_local.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_07_groomed_local.particles new file mode 100644 index 00000000000..d433669c949 --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_07_groomed_local.particles @@ -0,0 +1,128 @@ +-20.0344 -2.1463 0.471572 +-7.84423 13.6179 0.701615 +-9.05844 -13.0563 1.47295 +5.34788 -13.9623 1.97758 +-0.908346 2.49243 9.50259 +8.7087 5.05189 -8.07447 +-12.9833 0.504465 -7.4047 +3.98673 4.73407 -8.94529 +-16.1637 4.86455 4.8952 +9.64569 11.433 -4.0716 +-4.3384 -11.6777 5.56649 +10.4988 -2.67448 -8.07254 +2.10233 9.36785 7.41157 +1.636 8.29996 -7.95809 +-10.3828 -9.59157 -5.45728 +12.4353 -11.6219 0.882652 +-19.2518 1.97836 -2.7433 +-7.17904 4.60889 -8.5105 +-2.66147 -8.69007 7.71987 +17.062 -7.92597 -0.755789 +3.13461 14.1612 2.40834 +18.7461 4.08877 -2.53298 +0.900731 -9.4623 -7.41708 +5.51763 -8.29603 -7.55221 +-7.86606 12.3941 -3.73154 +-12.4827 6.71044 6.22013 +2.05256 -9.77534 7.18632 +18.3005 -0.00854596 -4.16681 +3.08196 1.06184 9.51398 +8.21666 12.5352 3.3328 +-9.30799 -2.28295 8.44394 +9.44917 -11.0106 -4.62911 +-18.2693 -5.12014 -2.52985 +-3.21076 10.2483 -6.80117 +-12.6352 -11.508 -0.880285 +12.512 -8.52534 5.173 +-7.85146 7.54853 7.41404 +13.4738 10.5885 -2.12341 +-5.4091 -3.23277 -9.05953 +3.15946 -0.310583 -9.52991 +-18.5838 5.89723 -0.345209 +7.04535 13.8427 -0.747465 +-3.59287 -14.2166 -2.08866 +13.8302 -6.2605 -5.76488 +13.136 4.55268 6.72583 +0.0100755 2.96916 -9.45629 +-13.9486 -4.46539 -6.37207 +8.35338 -13.3592 -1.24834 +-11.511 4.90918 -7.27401 +-4.22191 1.42 -9.39256 +-7.81436 -7.48279 7.45146 +18.1349 -4.66362 3.06828 +-2.96606 9.94859 7.01248 +17.2235 7.8182 -0.155994 +-7.84503 -12.6678 -3.32495 +-2.52028 -6.91585 -8.45062 +-11.4677 9.10872 -5.30397 +-11.6017 10.61 3.85166 +7.79143 -9.14401 6.62141 +15.1645 6.95742 -4.52751 +7.86842 2.57253 8.73798 +11.4647 12.0555 1.29124 +-13.2853 -9.40713 3.95223 +14.6869 -1.96664 -6.53291 +-19.0445 1.77618 3.11279 +-3.59784 13.5887 -3.42904 +-9.12602 -10.7208 5.04432 +4.97712 -12.046 5.09275 +-1.99244 6.77466 8.53019 +11.3099 7.59985 -6.30168 +-10.123 -4.31987 -7.87611 +7.10744 0.786068 -9.02509 +-12.745 1.73099 7.42091 +5.1782 12.057 -5.03356 +0.108001 -12.987 4.63251 +11.5828 1.76511 -7.84235 +0.100208 12.8373 4.80829 +6.29551 8.69484 -7.22181 +-4.39718 -10.8718 -6.20989 +9.62126 -11.8646 3.51754 +-16.9696 -1.17266 -5.23366 +-8.80939 0.116272 -8.68941 +-1.53186 -4.46263 9.17257 +15.4571 -8.43804 2.95853 +-1.89702 14.7303 0.41144 +19.9359 2.01162 1.16943 +-0.363852 -12.7544 -4.90105 +4.94667 -11.92 -5.21933 +-7.31245 8.76487 -6.95632 +-15.517 9.00968 2.03335 +5.95031 -5.24032 8.57212 +19.9958 -2.43857 0.0634197 +2.34579 -4.34587 9.16039 +5.2306 11.5823 5.47979 +-16.0347 -1.41804 5.83709 +13.6008 -9.90845 -3.09733 +-17.1301 -4.9125 4.05156 +0.678612 12.1193 -5.54378 +-16.6368 -8.40763 0.631325 +14.9318 -3.40303 6.14129 +-6.89008 3.26371 8.82386 +14.7038 9.07159 3.04067 +-7.17824 -7.58074 -7.55458 +6.44094 -4.00589 -8.77509 +-15.3726 8.36574 -3.14814 +2.20437 14.4592 -1.81439 +0.234085 -14.6661 1.35124 +9.89069 -7.23255 -6.98038 +7.89409 8.57323 6.91164 +-2.59091 6.34225 -8.63762 +-14.4242 -8.23118 -4.14937 +2.98016 -14.2827 -2.11331 +-15.6588 4.18066 -5.49295 +-1.06885 -2.13112 -9.53641 +-4.42877 -1.87368 9.33826 +17.5501 0.743322 4.8174 +-4.14171 13.3909 3.61318 +17.4794 5.18009 3.54193 +-4.66442 -13.9718 2.30906 +2.06323 -5.1527 -8.99397 +-12.1378 11.7751 -0.965351 +-7.67603 11.3767 4.97965 +10.2589 -3.79301 7.95114 +14.9614 2.98971 -6.21592 +5.23568 5.53135 8.60215 +11.8108 8.96621 5.24571 +-12.7298 -5.92502 6.44336 +17.7606 -4.70993 -3.50777 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_07_groomed_world.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_07_groomed_world.particles new file mode 100644 index 00000000000..d433669c949 --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_07_groomed_world.particles @@ -0,0 +1,128 @@ +-20.0344 -2.1463 0.471572 +-7.84423 13.6179 0.701615 +-9.05844 -13.0563 1.47295 +5.34788 -13.9623 1.97758 +-0.908346 2.49243 9.50259 +8.7087 5.05189 -8.07447 +-12.9833 0.504465 -7.4047 +3.98673 4.73407 -8.94529 +-16.1637 4.86455 4.8952 +9.64569 11.433 -4.0716 +-4.3384 -11.6777 5.56649 +10.4988 -2.67448 -8.07254 +2.10233 9.36785 7.41157 +1.636 8.29996 -7.95809 +-10.3828 -9.59157 -5.45728 +12.4353 -11.6219 0.882652 +-19.2518 1.97836 -2.7433 +-7.17904 4.60889 -8.5105 +-2.66147 -8.69007 7.71987 +17.062 -7.92597 -0.755789 +3.13461 14.1612 2.40834 +18.7461 4.08877 -2.53298 +0.900731 -9.4623 -7.41708 +5.51763 -8.29603 -7.55221 +-7.86606 12.3941 -3.73154 +-12.4827 6.71044 6.22013 +2.05256 -9.77534 7.18632 +18.3005 -0.00854596 -4.16681 +3.08196 1.06184 9.51398 +8.21666 12.5352 3.3328 +-9.30799 -2.28295 8.44394 +9.44917 -11.0106 -4.62911 +-18.2693 -5.12014 -2.52985 +-3.21076 10.2483 -6.80117 +-12.6352 -11.508 -0.880285 +12.512 -8.52534 5.173 +-7.85146 7.54853 7.41404 +13.4738 10.5885 -2.12341 +-5.4091 -3.23277 -9.05953 +3.15946 -0.310583 -9.52991 +-18.5838 5.89723 -0.345209 +7.04535 13.8427 -0.747465 +-3.59287 -14.2166 -2.08866 +13.8302 -6.2605 -5.76488 +13.136 4.55268 6.72583 +0.0100755 2.96916 -9.45629 +-13.9486 -4.46539 -6.37207 +8.35338 -13.3592 -1.24834 +-11.511 4.90918 -7.27401 +-4.22191 1.42 -9.39256 +-7.81436 -7.48279 7.45146 +18.1349 -4.66362 3.06828 +-2.96606 9.94859 7.01248 +17.2235 7.8182 -0.155994 +-7.84503 -12.6678 -3.32495 +-2.52028 -6.91585 -8.45062 +-11.4677 9.10872 -5.30397 +-11.6017 10.61 3.85166 +7.79143 -9.14401 6.62141 +15.1645 6.95742 -4.52751 +7.86842 2.57253 8.73798 +11.4647 12.0555 1.29124 +-13.2853 -9.40713 3.95223 +14.6869 -1.96664 -6.53291 +-19.0445 1.77618 3.11279 +-3.59784 13.5887 -3.42904 +-9.12602 -10.7208 5.04432 +4.97712 -12.046 5.09275 +-1.99244 6.77466 8.53019 +11.3099 7.59985 -6.30168 +-10.123 -4.31987 -7.87611 +7.10744 0.786068 -9.02509 +-12.745 1.73099 7.42091 +5.1782 12.057 -5.03356 +0.108001 -12.987 4.63251 +11.5828 1.76511 -7.84235 +0.100208 12.8373 4.80829 +6.29551 8.69484 -7.22181 +-4.39718 -10.8718 -6.20989 +9.62126 -11.8646 3.51754 +-16.9696 -1.17266 -5.23366 +-8.80939 0.116272 -8.68941 +-1.53186 -4.46263 9.17257 +15.4571 -8.43804 2.95853 +-1.89702 14.7303 0.41144 +19.9359 2.01162 1.16943 +-0.363852 -12.7544 -4.90105 +4.94667 -11.92 -5.21933 +-7.31245 8.76487 -6.95632 +-15.517 9.00968 2.03335 +5.95031 -5.24032 8.57212 +19.9958 -2.43857 0.0634197 +2.34579 -4.34587 9.16039 +5.2306 11.5823 5.47979 +-16.0347 -1.41804 5.83709 +13.6008 -9.90845 -3.09733 +-17.1301 -4.9125 4.05156 +0.678612 12.1193 -5.54378 +-16.6368 -8.40763 0.631325 +14.9318 -3.40303 6.14129 +-6.89008 3.26371 8.82386 +14.7038 9.07159 3.04067 +-7.17824 -7.58074 -7.55458 +6.44094 -4.00589 -8.77509 +-15.3726 8.36574 -3.14814 +2.20437 14.4592 -1.81439 +0.234085 -14.6661 1.35124 +9.89069 -7.23255 -6.98038 +7.89409 8.57323 6.91164 +-2.59091 6.34225 -8.63762 +-14.4242 -8.23118 -4.14937 +2.98016 -14.2827 -2.11331 +-15.6588 4.18066 -5.49295 +-1.06885 -2.13112 -9.53641 +-4.42877 -1.87368 9.33826 +17.5501 0.743322 4.8174 +-4.14171 13.3909 3.61318 +17.4794 5.18009 3.54193 +-4.66442 -13.9718 2.30906 +2.06323 -5.1527 -8.99397 +-12.1378 11.7751 -0.965351 +-7.67603 11.3767 4.97965 +10.2589 -3.79301 7.95114 +14.9614 2.98971 -6.21592 +5.23568 5.53135 8.60215 +11.8108 8.96621 5.24571 +-12.7298 -5.92502 6.44336 +17.7606 -4.70993 -3.50777 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_08_groomed_local.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_08_groomed_local.particles new file mode 100644 index 00000000000..37fdc1c0b06 --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_08_groomed_local.particles @@ -0,0 +1,128 @@ +-18.9181 -1.8953 0.881547 +-7.92704 12.8372 0.909672 +-9.03384 -12.2667 1.6549 +5.01795 -13.4534 1.67251 +1.42664 2.1225 9.31124 +8.35759 4.92059 -7.85147 +-13.025 0.51433 -6.92996 +3.7323 4.6845 -8.72503 +-15.0682 4.24939 5.10465 +9.14475 10.9919 -3.91511 +-3.97877 -10.834 5.76868 +10.0986 -2.60785 -7.83752 +2.85433 8.85175 7.24448 +1.40178 8.16566 -7.69167 +-10.4131 -9.2971 -4.94936 +11.8808 -11.1147 0.357827 +-18.5657 1.82127 -2.02212 +-7.32071 4.51872 -8.20019 +-1.6733 -7.80594 7.84893 +16.1709 -7.39195 -1.21637 +2.88115 13.6329 2.1641 +17.6516 3.8029 -2.66921 +0.668524 -9.26988 -7.14497 +5.23793 -8.13824 -7.28946 +-7.952 11.9237 -3.27746 +-11.1149 5.80726 6.64917 +2.69363 -9.24382 7.03747 +17.3075 0.00210344 -4.07155 +5.18673 0.902867 9.07401 +8.04216 12.1204 2.89933 +-6.7569 -1.88024 8.75018 +8.96661 -10.6053 -4.44818 +-17.682 -4.7513 -1.82912 +-3.39882 10.0255 -6.46826 +-12.473 -10.7539 -0.434863 +12.806 -8.26055 4.3718 +-6.45261 6.47662 7.7806 +12.7713 10.0523 -2.18943 +-5.56575 -3.20309 -8.78238 +2.92859 -0.302306 -9.33131 +-17.7644 5.32228 0.150187 +6.54443 13.2631 -0.859701 +-3.81382 -13.6325 -1.82507 +13.2209 -6.01493 -5.55403 +13.9931 4.41951 5.74287 +-0.188904 2.95234 -9.23899 +-13.9117 -4.30102 -5.83036 +7.84523 -12.7793 -1.33698 +-11.585 4.80218 -6.81219 +-4.38877 1.39459 -9.14626 +-6.38485 -6.42109 7.81297 +17.7014 -4.53575 2.01458 +-2.27944 9.0512 7.18774 +16.3506 7.33323 -0.721034 +-7.94586 -12.1737 -2.87196 +-2.70116 -6.81954 -8.17602 +-11.4758 8.78376 -4.7938 +-11.2754 9.76483 4.02107 +8.4353 -8.8952 6.06572 +14.4252 6.61552 -4.39456 +9.58184 2.53658 8.00384 +10.9453 11.5849 0.771367 +-12.8259 -8.53558 4.11611 +14.0589 -1.88184 -6.30031 +-17.9155 1.57667 3.19096 +-3.83184 13.0957 -3.10685 +-8.66695 -9.84578 5.28545 +5.13424 -11.5688 4.83831 +-0.555113 5.99776 8.55524 +10.818 7.33957 -6.0823 +-10.2175 -4.25273 -7.47121 +6.80921 0.772899 -8.81477 +-10.4628 1.36592 7.86248 +4.82536 11.6754 -4.80826 +0.241039 -12.3712 4.60792 +11.1397 1.71431 -7.60913 +0.228893 12.2034 4.80892 +5.99262 8.49155 -6.96415 +-4.56919 -10.6336 -5.8348 +9.44096 -11.4893 2.99599 +-16.7434 -1.11203 -4.54098 +-8.92903 0.102334 -8.35726 +0.460275 -3.92262 9.07445 +15.148 -8.12369 2.05716 +-2.1503 14.0746 0.476341 +19.0078 1.84529 0.167515 +-0.619428 -12.3849 -4.5873 +4.58025 -11.5716 -4.97188 +-7.44752 8.56574 -6.57153 +-14.972 8.17075 2.26843 +7.37293 -5.09158 8.03181 +18.898 -2.19169 -0.622589 +4.03761 -3.99602 8.84214 +5.41325 11.157 5.18518 +-14.4098 -1.21647 6.17763 +12.9265 -9.40435 -3.07924 +-16.1685 -4.33755 4.17011 +0.407201 11.7816 -5.25074 +-16.0324 -7.63636 0.958081 +15.5913 -3.17183 5.07147 +-4.45859 2.5946 9.02153 +14.4168 8.7565 2.19976 +-7.31213 -7.46318 -7.17605 +6.15999 -3.94638 -8.55733 +-15.0936 7.90405 -2.50359 +1.82363 13.868 -1.73919 +-0.0696923 -14.0552 1.27833 +9.48891 -7.03308 -6.73869 +8.62452 8.35441 6.3362 +-2.78092 6.24544 -8.36867 +-14.2672 -7.82416 -3.54931 +2.60998 -13.7343 -1.9645 +-15.5102 4.01378 -4.8623 +-1.24229 -2.11043 -9.32033 +-1.86865 -1.38816 9.35518 +17.6188 0.73853 3.6995 +-4.0959 12.7081 3.66959 +17.2102 5.00069 2.48968 +-4.76884 -13.266 2.37654 +1.85808 -5.09074 -8.76895 +-11.9862 11.0365 -0.556804 +-7.26909 10.5232 5.21616 +11.5097 -3.78385 7.11859 +14.3304 2.87234 -5.97358 +6.58097 5.33223 8.12865 +12.0798 8.70083 4.49453 +-11.1946 -5.08253 6.88004 +16.7941 -4.39906 -3.49181 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_08_groomed_world.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_08_groomed_world.particles new file mode 100644 index 00000000000..37fdc1c0b06 --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_08_groomed_world.particles @@ -0,0 +1,128 @@ +-18.9181 -1.8953 0.881547 +-7.92704 12.8372 0.909672 +-9.03384 -12.2667 1.6549 +5.01795 -13.4534 1.67251 +1.42664 2.1225 9.31124 +8.35759 4.92059 -7.85147 +-13.025 0.51433 -6.92996 +3.7323 4.6845 -8.72503 +-15.0682 4.24939 5.10465 +9.14475 10.9919 -3.91511 +-3.97877 -10.834 5.76868 +10.0986 -2.60785 -7.83752 +2.85433 8.85175 7.24448 +1.40178 8.16566 -7.69167 +-10.4131 -9.2971 -4.94936 +11.8808 -11.1147 0.357827 +-18.5657 1.82127 -2.02212 +-7.32071 4.51872 -8.20019 +-1.6733 -7.80594 7.84893 +16.1709 -7.39195 -1.21637 +2.88115 13.6329 2.1641 +17.6516 3.8029 -2.66921 +0.668524 -9.26988 -7.14497 +5.23793 -8.13824 -7.28946 +-7.952 11.9237 -3.27746 +-11.1149 5.80726 6.64917 +2.69363 -9.24382 7.03747 +17.3075 0.00210344 -4.07155 +5.18673 0.902867 9.07401 +8.04216 12.1204 2.89933 +-6.7569 -1.88024 8.75018 +8.96661 -10.6053 -4.44818 +-17.682 -4.7513 -1.82912 +-3.39882 10.0255 -6.46826 +-12.473 -10.7539 -0.434863 +12.806 -8.26055 4.3718 +-6.45261 6.47662 7.7806 +12.7713 10.0523 -2.18943 +-5.56575 -3.20309 -8.78238 +2.92859 -0.302306 -9.33131 +-17.7644 5.32228 0.150187 +6.54443 13.2631 -0.859701 +-3.81382 -13.6325 -1.82507 +13.2209 -6.01493 -5.55403 +13.9931 4.41951 5.74287 +-0.188904 2.95234 -9.23899 +-13.9117 -4.30102 -5.83036 +7.84523 -12.7793 -1.33698 +-11.585 4.80218 -6.81219 +-4.38877 1.39459 -9.14626 +-6.38485 -6.42109 7.81297 +17.7014 -4.53575 2.01458 +-2.27944 9.0512 7.18774 +16.3506 7.33323 -0.721034 +-7.94586 -12.1737 -2.87196 +-2.70116 -6.81954 -8.17602 +-11.4758 8.78376 -4.7938 +-11.2754 9.76483 4.02107 +8.4353 -8.8952 6.06572 +14.4252 6.61552 -4.39456 +9.58184 2.53658 8.00384 +10.9453 11.5849 0.771367 +-12.8259 -8.53558 4.11611 +14.0589 -1.88184 -6.30031 +-17.9155 1.57667 3.19096 +-3.83184 13.0957 -3.10685 +-8.66695 -9.84578 5.28545 +5.13424 -11.5688 4.83831 +-0.555113 5.99776 8.55524 +10.818 7.33957 -6.0823 +-10.2175 -4.25273 -7.47121 +6.80921 0.772899 -8.81477 +-10.4628 1.36592 7.86248 +4.82536 11.6754 -4.80826 +0.241039 -12.3712 4.60792 +11.1397 1.71431 -7.60913 +0.228893 12.2034 4.80892 +5.99262 8.49155 -6.96415 +-4.56919 -10.6336 -5.8348 +9.44096 -11.4893 2.99599 +-16.7434 -1.11203 -4.54098 +-8.92903 0.102334 -8.35726 +0.460275 -3.92262 9.07445 +15.148 -8.12369 2.05716 +-2.1503 14.0746 0.476341 +19.0078 1.84529 0.167515 +-0.619428 -12.3849 -4.5873 +4.58025 -11.5716 -4.97188 +-7.44752 8.56574 -6.57153 +-14.972 8.17075 2.26843 +7.37293 -5.09158 8.03181 +18.898 -2.19169 -0.622589 +4.03761 -3.99602 8.84214 +5.41325 11.157 5.18518 +-14.4098 -1.21647 6.17763 +12.9265 -9.40435 -3.07924 +-16.1685 -4.33755 4.17011 +0.407201 11.7816 -5.25074 +-16.0324 -7.63636 0.958081 +15.5913 -3.17183 5.07147 +-4.45859 2.5946 9.02153 +14.4168 8.7565 2.19976 +-7.31213 -7.46318 -7.17605 +6.15999 -3.94638 -8.55733 +-15.0936 7.90405 -2.50359 +1.82363 13.868 -1.73919 +-0.0696923 -14.0552 1.27833 +9.48891 -7.03308 -6.73869 +8.62452 8.35441 6.3362 +-2.78092 6.24544 -8.36867 +-14.2672 -7.82416 -3.54931 +2.60998 -13.7343 -1.9645 +-15.5102 4.01378 -4.8623 +-1.24229 -2.11043 -9.32033 +-1.86865 -1.38816 9.35518 +17.6188 0.73853 3.6995 +-4.0959 12.7081 3.66959 +17.2102 5.00069 2.48968 +-4.76884 -13.266 2.37654 +1.85808 -5.09074 -8.76895 +-11.9862 11.0365 -0.556804 +-7.26909 10.5232 5.21616 +11.5097 -3.78385 7.11859 +14.3304 2.87234 -5.97358 +6.58097 5.33223 8.12865 +12.0798 8.70083 4.49453 +-11.1946 -5.08253 6.88004 +16.7941 -4.39906 -3.49181 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_09_groomed_local.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_09_groomed_local.particles new file mode 100644 index 00000000000..ecb7b60028f --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_09_groomed_local.particles @@ -0,0 +1,128 @@ +-18.5234 -1.80091 1.42569 +-8.17074 12.5386 1.15021 +-9.20247 -11.9367 1.91589 +4.78514 -13.3862 1.51843 +3.73653 1.9602 9.65657 +8.15958 4.989 -8.24922 +-13.3503 0.521981 -7.02271 +3.54957 4.79003 -9.16982 +-14.5714 3.92162 5.6764 +8.83667 10.9823 -4.06525 +-3.60195 -10.3432 6.43977 +9.90678 -2.64646 -8.25767 +3.75596 8.56404 7.62417 +1.18894 8.31825 -7.98912 +-10.6643 -9.33778 -4.84473 +11.5887 -11.0664 -0.0935924 +-18.4866 1.80628 -1.58085 +-7.62851 4.60811 -8.49447 +-0.561079 -7.14046 8.56056 +15.7626 -7.27796 -1.80343 +2.6993 13.5489 2.10278 +17.1886 3.757 -3.12956 +0.434263 -9.40942 -7.37257 +5.04881 -8.27712 -7.57571 +-8.18757 11.8579 -3.08182 +-10.1532 5.26072 7.50938 +3.49835 -8.94203 7.44002 +16.8616 0.00157157 -4.47519 +7.43718 0.841814 9.12637 +8.03629 12.0938 2.70842 +-4.46284 -1.60652 9.59914 +8.67724 -10.6152 -4.61988 +-17.6299 -4.6424 -1.34244 +-3.66219 10.1356 -6.60239 +-12.5951 -10.4365 -0.112799 +13.3499 -8.27927 3.8629 +-5.12416 5.65925 8.69356 +12.3878 9.97936 -2.48083 +-5.84676 -3.30102 -9.16467 +2.75085 -0.309535 -9.84196 +-17.5555 5.07274 0.58277 +6.17508 13.1638 -1.02481 +-4.08681 -13.4718 -1.69524 +12.9502 -6.00455 -5.85971 +15.1011 4.41851 5.07965 +-0.406982 3.02994 -9.71594 +-14.2067 -4.31868 -5.80129 +7.498 -12.6823 -1.51736 +-11.9029 4.87051 -6.90447 +-4.6539 1.41098 -9.59145 +-5.00264 -5.61611 8.72754 +17.7055 -4.61129 1.08352 +-1.51137 8.38496 7.93892 +15.9439 7.23842 -1.38933 +-8.19552 -12.0748 -2.61953 +-2.94098 -6.96523 -8.49553 +-11.7274 8.79729 -4.67921 +-11.2484 9.38463 4.40818 +9.2911 -8.90463 5.91808 +14.0523 6.60475 -4.70175 +11.5316 2.44543 7.68377 +10.6638 11.5654 0.337671 +-12.7409 -8.13411 4.53662 +13.7819 -1.89461 -6.66744 +-17.4272 1.46839 3.67891 +-4.12464 13.0041 -3.00452 +-8.42443 -9.43654 5.87144 +5.42541 -11.4396 4.98845 +0.996681 5.40672 9.16936 +10.5696 7.39195 -6.36081 +-10.5404 -4.35163 -7.65461 +6.66095 0.773323 -9.29521 +-8.5835 1.08114 8.8268 +4.5668 11.6974 -4.92592 +0.418932 -12.1185 4.99051 +10.9465 1.74626 -8.01752 +0.420057 11.9294 5.21942 +5.80022 8.60201 -7.23408 +-4.83849 -10.7372 -5.86334 +9.46706 -11.4859 2.759 +-16.9516 -1.09851 -4.3034 +-9.2577 0.0891387 -8.66838 +2.50118 -3.56953 9.53358 +15.1784 -8.12506 1.31676 +-2.43521 13.879 0.552142 +18.6648 1.82061 -0.79391 +-0.886796 -12.4167 -4.60094 +4.30592 -11.619 -5.08842 +-7.74227 8.67879 -6.66059 +-14.852 7.7896 2.6825 +9.0203 -5.05477 7.97027 +18.4519 -2.11151 -1.4564 +5.8988 -3.80725 9.06204 +5.77631 11.0427 5.31344 +-13.5216 -1.09159 6.90487 +12.5642 -9.34616 -3.33523 +-15.7461 -4.01056 4.69683 +0.13869 11.8482 -5.32048 +-15.9067 -7.28925 1.3785 +16.548 -3.04787 4.26822 +-2.21587 2.0873 9.77364 +14.4454 8.7712 1.53173 +-7.59775 -7.60704 -7.33596 +5.98043 -4.03602 -8.9971 +-15.1929 7.77909 -2.08561 +1.4702 13.7409 -1.77974 +-0.36523 -13.8953 1.29258 +9.27624 -7.11653 -7.03714 +9.57786 8.3618 6.18336 +-3.03776 6.3747 -8.71841 +-14.4425 -7.74015 -3.3033 +2.29345 -13.6456 -1.9573 +-15.7394 4.02659 -4.69643 +-1.4624 -2.17012 -9.79963 +0.52082 -0.988409 9.9229 +18.0998 0.751028 2.77463 +-4.11588 12.5003 3.94132 +17.336 5.04692 1.59883 +-4.96808 -13.0333 2.55775 +1.68142 -5.21632 -9.19401 +-12.1126 10.7471 -0.270809 +-7.01546 10.1264 5.80088 +12.998 -3.83614 6.68014 +14.0518 2.89403 -6.31512 +7.98471 5.26958 8.20327 +12.6 8.73352 4.04948 +-10.0737 -4.54159 7.77275 +16.3847 -4.31758 -3.87475 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_09_groomed_world.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_09_groomed_world.particles new file mode 100644 index 00000000000..ecb7b60028f --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_09_groomed_world.particles @@ -0,0 +1,128 @@ +-18.5234 -1.80091 1.42569 +-8.17074 12.5386 1.15021 +-9.20247 -11.9367 1.91589 +4.78514 -13.3862 1.51843 +3.73653 1.9602 9.65657 +8.15958 4.989 -8.24922 +-13.3503 0.521981 -7.02271 +3.54957 4.79003 -9.16982 +-14.5714 3.92162 5.6764 +8.83667 10.9823 -4.06525 +-3.60195 -10.3432 6.43977 +9.90678 -2.64646 -8.25767 +3.75596 8.56404 7.62417 +1.18894 8.31825 -7.98912 +-10.6643 -9.33778 -4.84473 +11.5887 -11.0664 -0.0935924 +-18.4866 1.80628 -1.58085 +-7.62851 4.60811 -8.49447 +-0.561079 -7.14046 8.56056 +15.7626 -7.27796 -1.80343 +2.6993 13.5489 2.10278 +17.1886 3.757 -3.12956 +0.434263 -9.40942 -7.37257 +5.04881 -8.27712 -7.57571 +-8.18757 11.8579 -3.08182 +-10.1532 5.26072 7.50938 +3.49835 -8.94203 7.44002 +16.8616 0.00157157 -4.47519 +7.43718 0.841814 9.12637 +8.03629 12.0938 2.70842 +-4.46284 -1.60652 9.59914 +8.67724 -10.6152 -4.61988 +-17.6299 -4.6424 -1.34244 +-3.66219 10.1356 -6.60239 +-12.5951 -10.4365 -0.112799 +13.3499 -8.27927 3.8629 +-5.12416 5.65925 8.69356 +12.3878 9.97936 -2.48083 +-5.84676 -3.30102 -9.16467 +2.75085 -0.309535 -9.84196 +-17.5555 5.07274 0.58277 +6.17508 13.1638 -1.02481 +-4.08681 -13.4718 -1.69524 +12.9502 -6.00455 -5.85971 +15.1011 4.41851 5.07965 +-0.406982 3.02994 -9.71594 +-14.2067 -4.31868 -5.80129 +7.498 -12.6823 -1.51736 +-11.9029 4.87051 -6.90447 +-4.6539 1.41098 -9.59145 +-5.00264 -5.61611 8.72754 +17.7055 -4.61129 1.08352 +-1.51137 8.38496 7.93892 +15.9439 7.23842 -1.38933 +-8.19552 -12.0748 -2.61953 +-2.94098 -6.96523 -8.49553 +-11.7274 8.79729 -4.67921 +-11.2484 9.38463 4.40818 +9.2911 -8.90463 5.91808 +14.0523 6.60475 -4.70175 +11.5316 2.44543 7.68377 +10.6638 11.5654 0.337671 +-12.7409 -8.13411 4.53662 +13.7819 -1.89461 -6.66744 +-17.4272 1.46839 3.67891 +-4.12464 13.0041 -3.00452 +-8.42443 -9.43654 5.87144 +5.42541 -11.4396 4.98845 +0.996681 5.40672 9.16936 +10.5696 7.39195 -6.36081 +-10.5404 -4.35163 -7.65461 +6.66095 0.773323 -9.29521 +-8.5835 1.08114 8.8268 +4.5668 11.6974 -4.92592 +0.418932 -12.1185 4.99051 +10.9465 1.74626 -8.01752 +0.420057 11.9294 5.21942 +5.80022 8.60201 -7.23408 +-4.83849 -10.7372 -5.86334 +9.46706 -11.4859 2.759 +-16.9516 -1.09851 -4.3034 +-9.2577 0.0891387 -8.66838 +2.50118 -3.56953 9.53358 +15.1784 -8.12506 1.31676 +-2.43521 13.879 0.552142 +18.6648 1.82061 -0.79391 +-0.886796 -12.4167 -4.60094 +4.30592 -11.619 -5.08842 +-7.74227 8.67879 -6.66059 +-14.852 7.7896 2.6825 +9.0203 -5.05477 7.97027 +18.4519 -2.11151 -1.4564 +5.8988 -3.80725 9.06204 +5.77631 11.0427 5.31344 +-13.5216 -1.09159 6.90487 +12.5642 -9.34616 -3.33523 +-15.7461 -4.01056 4.69683 +0.13869 11.8482 -5.32048 +-15.9067 -7.28925 1.3785 +16.548 -3.04787 4.26822 +-2.21587 2.0873 9.77364 +14.4454 8.7712 1.53173 +-7.59775 -7.60704 -7.33596 +5.98043 -4.03602 -8.9971 +-15.1929 7.77909 -2.08561 +1.4702 13.7409 -1.77974 +-0.36523 -13.8953 1.29258 +9.27624 -7.11653 -7.03714 +9.57786 8.3618 6.18336 +-3.03776 6.3747 -8.71841 +-14.4425 -7.74015 -3.3033 +2.29345 -13.6456 -1.9573 +-15.7394 4.02659 -4.69643 +-1.4624 -2.17012 -9.79963 +0.52082 -0.988409 9.9229 +18.0998 0.751028 2.77463 +-4.11588 12.5003 3.94132 +17.336 5.04692 1.59883 +-4.96808 -13.0333 2.55775 +1.68142 -5.21632 -9.19401 +-12.1126 10.7471 -0.270809 +-7.01546 10.1264 5.80088 +12.998 -3.83614 6.68014 +14.0518 2.89403 -6.31512 +7.98471 5.26958 8.20327 +12.6 8.73352 4.04948 +-10.0737 -4.54159 7.77275 +16.3847 -4.31758 -3.87475 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_10_groomed_local.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_10_groomed_local.particles new file mode 100644 index 00000000000..346511b52b5 --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_10_groomed_local.particles @@ -0,0 +1,128 @@ +-20.0962 -2.03251 2.50357 +-8.70039 12.7594 1.46712 +-9.71824 -12.152 2.32997 +4.64523 -13.7069 1.4244 +6.60486 1.68691 9.42677 +7.88026 5.03849 -8.57202 +-14.0035 0.556801 -7.44592 +3.24422 4.83546 -9.28271 +-14.5625 3.74901 6.70397 +8.62133 11.3018 -4.45578 +-3.35586 -10.104 6.8508 +9.64568 -2.68369 -8.68902 +5.02149 8.31255 7.75535 +0.892816 8.38667 -8.06912 +-11.2177 -9.70985 -4.97518 +11.7578 -11.7508 -0.514705 +-20.4689 2.15638 -1.59815 +-8.00174 4.67557 -8.64966 +0.83991 -6.59231 8.86123 +16.3765 -8.02351 -2.70757 +2.54681 13.8017 2.05569 +17.9071 4.19933 -4.30308 +0.134664 -9.48356 -7.45273 +4.7938 -8.37896 -7.75355 +-8.68404 12.1946 -3.05841 +-9.93176 5.08477 8.0557 +4.64012 -8.70046 7.60036 +17.2707 -0.00731526 -5.68826 +10.533 0.591978 8.6434 +8.29014 12.4807 2.69053 +-2.46195 -1.42566 9.8891 +8.45449 -10.898 -4.99321 +-19.2948 -5.26728 -1.28587 +-3.99937 10.2454 -6.67521 +-13.3769 -10.946 0.253857 +14.6598 -8.92217 3.42728 +-3.88159 5.1905 9.1339 +12.4464 10.5757 -3.07857 +-6.16749 -3.36829 -9.26576 +2.44927 -0.3006 -9.93806 +-19.0394 5.63901 1.39514 +5.88282 13.5156 -1.28155 +-4.51758 -13.6724 -1.65922 +12.8762 -6.2319 -6.56718 +17.5475 5.00709 4.20418 +-0.700276 3.06334 -9.76827 +-15.0023 -4.5677 -6.21235 +7.26719 -13.0805 -1.83447 +-12.4742 5.06459 -7.21632 +-4.9535 1.40625 -9.67554 +-3.70842 -5.16171 9.15722 +19.3977 -5.40375 0.223043 +-0.565733 7.88438 8.32708 +16.6925 8.01255 -2.22003 +-8.71264 -12.4186 -2.52152 +-3.24908 -7.03687 -8.55609 +-12.3618 9.18199 -4.85199 +-11.5818 9.37836 5.10187 +10.6555 -9.18892 5.70307 +14.1075 7.00036 -5.54055 +14.4666 2.82089 6.97418 +10.7622 12.2026 0.0132043 +-13.1037 -8.05908 5.36949 +13.6871 -1.97319 -7.45886 +-18.0689 1.47264 4.9909 +-4.56301 13.1913 -3.01146 +-8.58242 -9.40607 6.28619 +5.94166 -11.4986 5.14817 +2.97257 4.88772 9.28945 +10.3796 7.58789 -6.86146 +-11.0194 -4.50446 -7.9044 +6.34043 0.764801 -9.52434 +-7.61575 0.906086 9.30324 +4.26934 11.8498 -5.13084 +0.633502 -12.0704 5.26912 +10.7155 1.79105 -8.51024 +0.643436 11.8525 5.50537 +5.54802 8.69858 -7.45691 +-5.20533 -10.9169 -5.90438 +9.85845 -11.9524 2.68281 +-18.2628 -1.20099 -4.8591 +-9.65642 0.0687753 -8.88447 +5.00004 -3.20961 9.45471 +16.2209 -8.95782 0.786331 +-2.84475 14.0496 0.633965 +20.3632 2.08333 -1.91125 +-1.23684 -12.557 -4.64779 +3.98588 -11.7723 -5.2673 +-8.15474 8.86007 -6.7847 +-15.574 8.03398 3.59726 +11.301 -5.1463 7.6142 +19.9346 -2.44408 -2.61359 +8.36312 -3.50483 8.84568 +6.41369 11.1017 5.44192 +-13.2194 -1.02713 7.74597 +12.5724 -9.84198 -4.01874 +-16.0196 -3.91733 5.84501 +-0.201167 11.9628 -5.40129 +-16.9933 -7.77832 2.11103 +19.1989 -3.4622 3.23032 +0.0859441 1.71473 9.93582 +15.3852 9.55262 1.04848 +-7.98296 -7.79053 -7.46075 +5.69057 -4.08891 -9.19185 +-16.2766 8.48267 -2.04538 +1.04878 13.9266 -1.9289 +-0.734312 -14.0759 1.30414 +9.0467 -7.26856 -7.43936 +11.0788 8.6749 5.90622 +-3.35539 6.43344 -8.78063 +-15.3763 -8.33178 -3.44923 +1.93422 -13.8374 -2.06177 +-16.7956 4.38041 -5.14621 +-1.7386 -2.18756 -9.85296 +3.22485 -0.652141 9.87688 +20.6503 0.894819 1.67061 +-4.25679 12.5838 4.17087 +19.0641 5.83999 0.790338 +-5.32452 -13.1472 2.81747 +1.39591 -5.25664 -9.27559 +-12.8392 11.2457 0.0559116 +-7.06214 10.1114 6.16804 +15.5563 -4.3493 5.98067 +14.0295 3.03159 -7.13309 +10.1429 5.23239 7.95246 +13.8081 9.32363 3.6923 +-9.74459 -4.32689 8.32211 +16.8663 -4.65873 -4.96894 diff --git a/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_10_groomed_world.particles b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_10_groomed_world.particles new file mode 100644 index 00000000000..346511b52b5 --- /dev/null +++ b/Examples/Studio/MeshScalars/mesh_scalars_particles/ellipsoid_10_groomed_world.particles @@ -0,0 +1,128 @@ +-20.0962 -2.03251 2.50357 +-8.70039 12.7594 1.46712 +-9.71824 -12.152 2.32997 +4.64523 -13.7069 1.4244 +6.60486 1.68691 9.42677 +7.88026 5.03849 -8.57202 +-14.0035 0.556801 -7.44592 +3.24422 4.83546 -9.28271 +-14.5625 3.74901 6.70397 +8.62133 11.3018 -4.45578 +-3.35586 -10.104 6.8508 +9.64568 -2.68369 -8.68902 +5.02149 8.31255 7.75535 +0.892816 8.38667 -8.06912 +-11.2177 -9.70985 -4.97518 +11.7578 -11.7508 -0.514705 +-20.4689 2.15638 -1.59815 +-8.00174 4.67557 -8.64966 +0.83991 -6.59231 8.86123 +16.3765 -8.02351 -2.70757 +2.54681 13.8017 2.05569 +17.9071 4.19933 -4.30308 +0.134664 -9.48356 -7.45273 +4.7938 -8.37896 -7.75355 +-8.68404 12.1946 -3.05841 +-9.93176 5.08477 8.0557 +4.64012 -8.70046 7.60036 +17.2707 -0.00731526 -5.68826 +10.533 0.591978 8.6434 +8.29014 12.4807 2.69053 +-2.46195 -1.42566 9.8891 +8.45449 -10.898 -4.99321 +-19.2948 -5.26728 -1.28587 +-3.99937 10.2454 -6.67521 +-13.3769 -10.946 0.253857 +14.6598 -8.92217 3.42728 +-3.88159 5.1905 9.1339 +12.4464 10.5757 -3.07857 +-6.16749 -3.36829 -9.26576 +2.44927 -0.3006 -9.93806 +-19.0394 5.63901 1.39514 +5.88282 13.5156 -1.28155 +-4.51758 -13.6724 -1.65922 +12.8762 -6.2319 -6.56718 +17.5475 5.00709 4.20418 +-0.700276 3.06334 -9.76827 +-15.0023 -4.5677 -6.21235 +7.26719 -13.0805 -1.83447 +-12.4742 5.06459 -7.21632 +-4.9535 1.40625 -9.67554 +-3.70842 -5.16171 9.15722 +19.3977 -5.40375 0.223043 +-0.565733 7.88438 8.32708 +16.6925 8.01255 -2.22003 +-8.71264 -12.4186 -2.52152 +-3.24908 -7.03687 -8.55609 +-12.3618 9.18199 -4.85199 +-11.5818 9.37836 5.10187 +10.6555 -9.18892 5.70307 +14.1075 7.00036 -5.54055 +14.4666 2.82089 6.97418 +10.7622 12.2026 0.0132043 +-13.1037 -8.05908 5.36949 +13.6871 -1.97319 -7.45886 +-18.0689 1.47264 4.9909 +-4.56301 13.1913 -3.01146 +-8.58242 -9.40607 6.28619 +5.94166 -11.4986 5.14817 +2.97257 4.88772 9.28945 +10.3796 7.58789 -6.86146 +-11.0194 -4.50446 -7.9044 +6.34043 0.764801 -9.52434 +-7.61575 0.906086 9.30324 +4.26934 11.8498 -5.13084 +0.633502 -12.0704 5.26912 +10.7155 1.79105 -8.51024 +0.643436 11.8525 5.50537 +5.54802 8.69858 -7.45691 +-5.20533 -10.9169 -5.90438 +9.85845 -11.9524 2.68281 +-18.2628 -1.20099 -4.8591 +-9.65642 0.0687753 -8.88447 +5.00004 -3.20961 9.45471 +16.2209 -8.95782 0.786331 +-2.84475 14.0496 0.633965 +20.3632 2.08333 -1.91125 +-1.23684 -12.557 -4.64779 +3.98588 -11.7723 -5.2673 +-8.15474 8.86007 -6.7847 +-15.574 8.03398 3.59726 +11.301 -5.1463 7.6142 +19.9346 -2.44408 -2.61359 +8.36312 -3.50483 8.84568 +6.41369 11.1017 5.44192 +-13.2194 -1.02713 7.74597 +12.5724 -9.84198 -4.01874 +-16.0196 -3.91733 5.84501 +-0.201167 11.9628 -5.40129 +-16.9933 -7.77832 2.11103 +19.1989 -3.4622 3.23032 +0.0859441 1.71473 9.93582 +15.3852 9.55262 1.04848 +-7.98296 -7.79053 -7.46075 +5.69057 -4.08891 -9.19185 +-16.2766 8.48267 -2.04538 +1.04878 13.9266 -1.9289 +-0.734312 -14.0759 1.30414 +9.0467 -7.26856 -7.43936 +11.0788 8.6749 5.90622 +-3.35539 6.43344 -8.78063 +-15.3763 -8.33178 -3.44923 +1.93422 -13.8374 -2.06177 +-16.7956 4.38041 -5.14621 +-1.7386 -2.18756 -9.85296 +3.22485 -0.652141 9.87688 +20.6503 0.894819 1.67061 +-4.25679 12.5838 4.17087 +19.0641 5.83999 0.790338 +-5.32452 -13.1472 2.81747 +1.39591 -5.25664 -9.27559 +-12.8392 11.2457 0.0559116 +-7.06214 10.1114 6.16804 +15.5563 -4.3493 5.98067 +14.0295 3.03159 -7.13309 +10.1429 5.23239 7.95246 +13.8081 9.32363 3.6923 +-9.74459 -4.32689 8.32211 +16.8663 -4.65873 -4.96894 diff --git a/Libs/Analyze/CustomSurfaceReconstructionFilter.cpp b/Libs/Analyze/CustomSurfaceReconstructionFilter.cpp index eb55e153bc6..a0479530383 100644 --- a/Libs/Analyze/CustomSurfaceReconstructionFilter.cpp +++ b/Libs/Analyze/CustomSurfaceReconstructionFilter.cpp @@ -437,6 +437,25 @@ int CustomSurfaceReconstructionFilter::RequestData( vtkDebugMacro( << "Created output volume of dimensions: (" << dim[0] << ", " << dim[1] << ", " << dim[2] << ")" ); + // The sample spacing is a fixed length, so data in units where the shape spans a large + // number of them (microns, say) asks for a volume that cannot be allocated. Refuse it + // here: the allocation below throws std::bad_alloc, and this filter runs on a thread pool + // where that would take the whole application down. + const double MAX_VOXELS = 2e8; + double voxels = static_cast( dim[0] ) * dim[1] * dim[2]; + if ( dim[0] < 2 || dim[1] < 2 || dim[2] < 2 || voxels > MAX_VOXELS ) + { + vtkErrorMacro( << "Cannot reconstruct a surface from these points: a sample spacing of " + << this->SampleSpacing << " over a bounding box of " + << ( bottomright[0] - topleft[0] ) << " x " << ( bottomright[1] - topleft[1] ) + << " x " << ( bottomright[2] - topleft[2] ) << " needs a volume of " + << dim[0] << " x " << dim[1] << " x " << dim[2] << " voxels. Check that the " + << "sample spacing suits the units the data is in." ); + output->SetExtent( 0, -1, 0, -1, 0, -1 ); + delete [] surfacePoints; + return 1; + } + // initialise the output volume outInfo->Set( vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), 0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1 ); diff --git a/Libs/Analyze/LegacyMeshGenerator.cpp b/Libs/Analyze/LegacyMeshGenerator.cpp index a4e4257bf4a..efb751915b7 100644 --- a/Libs/Analyze/LegacyMeshGenerator.cpp +++ b/Libs/Analyze/LegacyMeshGenerator.cpp @@ -103,6 +103,13 @@ vtkSmartPointer LegacyMeshGenerator::buildMesh(const Eigen::VectorX { // copy shape points into point set int numPoints = shape.size() / 3; + + // a handful of points has no surface to reconstruct, and the bounding box of a degenerate + // set drives the sampling volume below to nonsense + if (numPoints < 4) { + return vtkSmartPointer(nullptr); + } + this->points->SetNumberOfPoints(numPoints); unsigned int k = 0; for (unsigned int i = 0; i < numPoints; i++) { diff --git a/Libs/Analyze/MeshGenerator.cpp b/Libs/Analyze/MeshGenerator.cpp index 95e3e058c12..5d0fa540efd 100644 --- a/Libs/Analyze/MeshGenerator.cpp +++ b/Libs/Analyze/MeshGenerator.cpp @@ -32,10 +32,27 @@ MeshGenerator::~MeshGenerator() {} //--------------------------------------------------------------------------- MeshHandle MeshGenerator::build_mesh(const MeshWorkItem& item) { - if (item.filename != "") { - return this->build_mesh_from_file(item.filename); - } else { - return this->build_mesh_from_points(item.points, item.domain); + // Meshes are built on a thread pool, and an exception that reaches it takes the whole + // application down rather than losing one mesh. Reconstruction from particles is the + // usual source: a point set the method cannot handle can ask for an impossible volume. + try { + if (item.filename != "") { + return this->build_mesh_from_file(item.filename); + } else { + return this->build_mesh_from_points(item.points, item.domain); + } + } catch (const std::exception& e) { + MeshHandle mesh(new StudioMesh); + std::string message = std::string("Unable to build mesh: ") + e.what(); + SW_ERROR(message); + mesh->set_error_message(message); + return mesh; + } catch (...) { + MeshHandle mesh(new StudioMesh); + std::string message = "Unable to build mesh: unknown error"; + SW_ERROR(message); + mesh->set_error_message(message); + return mesh; } } @@ -87,8 +104,21 @@ MeshHandle MeshGenerator::build_mesh_from_points(const Eigen::VectorXd& shape, i mesh->set_poly_data(poly_data); } else { + if (shape.size() / 3 < 4) { + // the first splits of an optimization have too few particles for a surface: not an error + mesh->set_poly_data(vtkSmartPointer::New()); + return mesh; + } LegacyMeshGenerator legacy; - mesh->set_poly_data(legacy.buildMesh(shape)); + auto poly_data = legacy.buildMesh(shape); + if (!poly_data) { + std::string message = "Unable to reconstruct a surface from the particles"; + SW_ERROR(message); + mesh->set_poly_data(vtkSmartPointer::New()); + mesh->set_error_message(message); + return mesh; + } + mesh->set_poly_data(poly_data); } return mesh; } diff --git a/Libs/Mesh/Mesh.cpp b/Libs/Mesh/Mesh.cpp index e55c79d0fe2..57de5c7877b 100644 --- a/Libs/Mesh/Mesh.cpp +++ b/Libs/Mesh/Mesh.cpp @@ -470,6 +470,18 @@ Mesh& Mesh::remesh(int numVertices, double adaptivity) { // std::cout.setstate(std::ios_base::failbit); auto surf = vtkSmartPointer::New(); auto remesh = vtkSmartPointer::New(); + + // ACVD works on bare geometry, so hold on to the fields and put them back on the new vertices. + // Normals are excluded: they describe the surface, which is what remeshing replaces. + vtkSmartPointer original; + for (const auto& name : getFieldNames()) { + if (name != "Normals" && name != "normals") { + original = vtkSmartPointer::New(); + original->DeepCopy(this->poly_data_); + break; + } + } + surf->CreateFromPolyData(this->poly_data_); surf->GetCellData()->Initialize(); surf->GetPointData()->Initialize(); @@ -501,6 +513,9 @@ Mesh& Mesh::remesh(int numVertices, double adaptivity) { this->poly_data_ = MeshUtils::remove_zero_area_triangles(this->poly_data_); } + // the new vertices are not the old ones, so any scalar field has to be interpolated onto them + MeshUtils::transfer_point_data(original, this->poly_data_); + // must regenerate normals after remeshing computeNormals(); @@ -1102,8 +1117,15 @@ void computeGradient(vtkDataSet* inputDataSet, const char* scalarFieldName, cons gradientData->SetNumberOfTuples(inputDataSet->GetNumberOfPoints()); gradientData->SetName(gradientFieldName); */ - vtkDoubleArray* gradPointArray = vtkArrayDownCast( - vtkDataSet::SafeDownCast(gradientFilter->GetOutput())->GetPointData()->GetArray(gradientFieldName)); + // The gradient comes back in the type of the field it was computed from, so take whatever array + // that is: a float field (a common way for scalars to arrive on a mesh) yields a float gradient, + // and insisting on a double one here left the mesh without a gradient array at all. + auto output = vtkDataSet::SafeDownCast(gradientFilter->GetOutput()); + vtkDataArray* gradPointArray = output ? output->GetPointData()->GetArray(gradientFieldName) : nullptr; + if (!gradPointArray) { + throw std::runtime_error(std::string("Unable to compute the gradient of mesh field \"") + scalarFieldName + + "\""); + } /* for (vtkIdType pointId = 0; pointId < inputDataSet->GetNumberOfPoints(); ++pointId) { diff --git a/Libs/Mesh/MeshUtils.cpp b/Libs/Mesh/MeshUtils.cpp index 25d8bf0dc12..5ebe7ca8f4a 100644 --- a/Libs/Mesh/MeshUtils.cpp +++ b/Libs/Mesh/MeshUtils.cpp @@ -4,8 +4,11 @@ #include #include #include +#include #include #include +#include +#include #include #include #include @@ -1166,6 +1169,8 @@ vtkSmartPointer MeshUtils::recreate_mesh(vtkSmartPointerSetPoints(points); poly_data->SetPolys(polys); + // every point is carried over in the same order, so the fields map straight across + poly_data->GetPointData()->ShallowCopy(mesh->GetPointData()); return poly_data; } @@ -1253,6 +1258,9 @@ vtkSmartPointer MeshUtils::extract_largest_edge_connected_component std::vector point_map(mesh->GetNumberOfPoints(), -1); std::vector new_ids; + // the fields follow their points through the renumbering + result->GetPointData()->CopyAllocate(mesh->GetPointData()); + for (vtkIdType cell_id = 0; cell_id < num_cells; cell_id++) { if (find(cell_id) != largest_group) { continue; @@ -1266,6 +1274,7 @@ vtkSmartPointer MeshUtils::extract_largest_edge_connected_component const vtkIdType old_id = cell_points->GetId(i); if (point_map[old_id] < 0) { point_map[old_id] = points->InsertNextPoint(mesh->GetPoint(old_id)); + result->GetPointData()->CopyData(mesh->GetPointData(), old_id, point_map[old_id]); } new_ids.push_back(point_map[old_id]); } @@ -1278,6 +1287,16 @@ vtkSmartPointer MeshUtils::extract_largest_edge_connected_component } //--------------------------------------------------------------------------- +//! Drop the arrays that do not have one tuple per point (or cell) +static void remove_mismatched_arrays(vtkDataSetAttributes* attributes, vtkIdType count) { + for (int i = attributes->GetNumberOfArrays() - 1; i >= 0; i--) { + auto array = attributes->GetAbstractArray(i); + if (array && array->GetNumberOfTuples() != count) { + attributes->RemoveArray(i); + } + } +} + vtkSmartPointer MeshUtils::repair_mesh(vtkSmartPointer mesh, bool extract_largest) { // Line-only / vertex-only polydata (e.g. contours) has no polygons to repair; // the triangulation and cleanup steps below would discard its cells. @@ -1285,8 +1304,15 @@ vtkSmartPointer MeshUtils::repair_mesh(vtkSmartPointer return mesh; } + // An array without a value for every point cannot follow the mesh through the steps below. They + // copy the fields point by point and would read past the end of it, so leave such arrays behind. + auto input = vtkSmartPointer::New(); + input->ShallowCopy(mesh); + remove_mismatched_arrays(input->GetPointData(), input->GetNumberOfPoints()); + remove_mismatched_arrays(input->GetCellData(), input->GetNumberOfCells()); + auto triangle_filter = vtkSmartPointer::New(); - triangle_filter->SetInputData(mesh); + triangle_filter->SetInputData(input); triangle_filter->PassLinesOff(); triangle_filter->Update(); @@ -1330,4 +1356,89 @@ bool MeshUtils::is_contour(vtkSmartPointer poly_data) { return poly_data->GetNumberOfLines() > 0; } +//--------------------------------------------------------------------------- +void MeshUtils::transfer_point_data(vtkSmartPointer source, vtkSmartPointer target) { + if (!source || !target || source->GetNumberOfCells() == 0 || target->GetNumberOfPoints() == 0) { + return; + } + + auto source_data = source->GetPointData(); + + // Only fields that give one value per source point can be interpolated. Normals are left to the + // caller to recompute from the new geometry. + std::vector names; + for (int i = 0; i < source_data->GetNumberOfArrays(); i++) { + auto array = source_data->GetArray(i); + if (!array || !array->GetName()) { + continue; + } + std::string name = array->GetName(); + if (name == "Normals" || name == "normals") { + continue; + } + if (array->GetNumberOfTuples() != source->GetNumberOfPoints()) { + continue; + } + names.push_back(name); + } + if (names.empty()) { + return; + } + + auto locator = vtkSmartPointer::New(); + locator->SetDataSet(source); + locator->BuildLocator(); + + vtkIdType num_points = target->GetNumberOfPoints(); + + // Gather just the fields to carry, so vtkPointData does the type handling and the per-array + // interpolation without touching the ones that were skipped + auto fields = vtkSmartPointer::New(); + for (const auto& name : names) { + fields->AddArray(source_data->GetArray(name.c_str())); + } + + auto interpolated = vtkSmartPointer::New(); + interpolated->InterpolateAllocate(fields, num_points); + // size the arrays up front: the loop below writes them from several threads at once, so no tuple + // may trigger a reallocation + interpolated->SetNumberOfTuples(num_points); + + tbb::parallel_for(tbb::blocked_range(0, num_points), [&](const tbb::blocked_range& range) { + auto cell = vtkSmartPointer::New(); + auto ids = vtkSmartPointer::New(); + std::vector weights(std::max(3, source->GetMaxCellSize())); + + for (vtkIdType i = range.begin(); i < range.end(); i++) { + double point[3]; + target->GetPoint(i, point); + + double closest[3]; + vtkIdType cell_id = -1; + int sub_id = 0; + double dist2 = 0; + locator->FindClosestPoint(point, closest, cell, cell_id, sub_id, dist2); + if (cell_id < 0) { + continue; + } + + double pcoords[3]; + cell->EvaluatePosition(closest, nullptr, sub_id, pcoords, dist2, weights.data()); + + ids->Reset(); + for (vtkIdType p = 0; p < cell->GetNumberOfPoints(); p++) { + ids->InsertNextId(cell->GetPointId(p)); + } + interpolated->InterpolatePoint(fields, i, ids, weights.data()); + } + }); + + for (const auto& name : names) { + auto array = interpolated->GetArray(name.c_str()); + if (array) { + target->GetPointData()->AddArray(array); + } + } +} + } // namespace shapeworks diff --git a/Libs/Mesh/MeshUtils.h b/Libs/Mesh/MeshUtils.h index 9a003d2362c..fc72264fda6 100644 --- a/Libs/Mesh/MeshUtils.h +++ b/Libs/Mesh/MeshUtils.h @@ -95,5 +95,11 @@ class MeshUtils { /// A surface mesh has polygon or triangle-strip cells; a contour has only line cells. This is more /// robust than inspecting the first cell, whose type/point-count can vary within a mesh. static bool is_contour(vtkSmartPointer poly_data); + + /// Carry the scalar fields of one mesh onto the points of another. Each target point takes the + /// value interpolated across the closest triangle of the source, so the two meshes need not share + /// a vertex count or a topology. Normals are not carried over: they describe the geometry, which + /// is the part that changed. + static void transfer_point_data(vtkSmartPointer source, vtkSmartPointer target); }; } // namespace shapeworks diff --git a/Libs/Optimize/Function/CorrespondenceFunction.cpp b/Libs/Optimize/Function/CorrespondenceFunction.cpp index 8799906551a..1cf32a08a1a 100644 --- a/Libs/Optimize/Function/CorrespondenceFunction.cpp +++ b/Libs/Optimize/Function/CorrespondenceFunction.cpp @@ -3,6 +3,8 @@ #include +#include + #include "Libs/Utils/Utils.h" #include "Profiling.h" #include "vnl/algo/vnl_svd.h" @@ -235,6 +237,12 @@ void CorrespondenceFunction::ComputeUpdates(const ParticleSystem* c) { { vnl_matrix_type Jmatrix; vnl_matrix_type v; + // How much of each particle's update comes from the attribute rows rather than from position. + // A scalar field enters through both its value and its gradient, so its influence is easy to + // get wrong by orders of magnitude; this reports what it actually contributed. + double update_from_position = 0.0; + double update_from_attributes = 0.0; + int update_count = 0; for (int j = 0; j < num_samples; j++) { int num = 0; int num2 = 0; @@ -256,6 +264,7 @@ void CorrespondenceFunction::ComputeUpdates(const ParticleSystem* c) { if (m_UseNormals[d]) { num_attr += 3; } + const int num_geometry = num_attr - m_AttributesPerDomain[d]; Jmatrix.clear(); Jmatrix.set_size(num_attr, VDimension); @@ -272,10 +281,44 @@ void CorrespondenceFunction::ComputeUpdates(const ParticleSystem* c) { for (unsigned int vd = 0; vd < VDimension; vd++) { m_PointsUpdate->put(num2 + p * VDimension + vd, j, dx(vd, 0)); } + + if (m_AttributesPerDomain[d] > 0) { + vnl_matrix_type dx_geometry = + Jmatrix.extract(num_geometry, VDimension, 0, 0).transpose() * v.extract(num_geometry, 1, 0, 0); + vnl_matrix_type dx_attributes = + Jmatrix.extract(m_AttributesPerDomain[d], VDimension, num_geometry, 0).transpose() * + v.extract(m_AttributesPerDomain[d], 1, num_geometry, 0); + update_from_position += dx_geometry.frobenius_norm(); + update_from_attributes += dx_attributes.frobenius_norm(); + update_count++; + } } } } } + + if (update_count > 0 && ++m_UpdateReportCounter % 100 == 1) { + SW_DEBUG("Correspondence update per particle: position {:.4g}, attributes {:.4g} ({:.1f}% of the total)", + update_from_position / update_count, update_from_attributes / update_count, + 100.0 * update_from_attributes / std::max(1e-30, update_from_position + update_from_attributes)); + } + if (++m_ScaleReportCounter % 100 == 1) { + // What sets the size of this term: the ensemble's spread, its covariance eigenvalues, and the + // regularization added to them. None of it is normalized, so the term's magnitude -- and with + // it what relative_weighting means -- moves with the cohort. + const double rms = points_minus_mean.frobenius_norm() / std::sqrt((double)num_dims * num_samples); + double lambda_max = 0.0; + if (!m_UseMeanEnergy) { + for (int i = 0; i < num_samples; i++) { + lambda_max = std::max(lambda_max, W(i)); + } + } + SW_DEBUG( + "Correspondence scale: {} dims x {} samples, rms deviation {:.4g}, max eigenvalue {:.4g}, " + "regularization {:.4g}, update per particle {:.4g}", + num_dims, num_samples, rms, lambda_max, m_MinimumVariance, + (update_from_position + update_from_attributes) / std::max(1, update_count)); + } } m_CurrentEnergy = 0.0; diff --git a/Libs/Optimize/Function/CorrespondenceFunction.h b/Libs/Optimize/Function/CorrespondenceFunction.h index 88bd82efd60..45a95897775 100644 --- a/Libs/Optimize/Function/CorrespondenceFunction.h +++ b/Libs/Optimize/Function/CorrespondenceFunction.h @@ -225,6 +225,8 @@ class CorrespondenceFunction : public VectorFunction { std::shared_ptr m_PointsUpdate; double m_MinimumVariance; + int m_UpdateReportCounter{0}; + int m_ScaleReportCounter{0}; double m_MinimumEigenValue; // double m_MinimumVarianceBase; bool m_HoldMinimumVariance; diff --git a/Libs/Optimize/Function/DualVectorFunction.h b/Libs/Optimize/Function/DualVectorFunction.h index 367994cec36..57951a292c2 100644 --- a/Libs/Optimize/Function/DualVectorFunction.h +++ b/Libs/Optimize/Function/DualVectorFunction.h @@ -1,5 +1,10 @@ #pragma once +#include + +#include +#include + #include "ParticleSystemEvaluation.h" #include "itkLightObject.h" #include "itkObjectFactory.h" @@ -64,6 +69,7 @@ class DualVectorFunction : public VectorFunction { if (a_on_ && b_on_) { maxmove = maxA; // always driven by the sampling to decrease the sensitivity to covariance regularization predictedMove = ansA + relative_gradient_scaling_ * ansB; + report_balance(); return predictedMove; } @@ -190,6 +196,7 @@ class DualVectorFunction : public VectorFunction { maxmove = maxA; // always driven by the sampling to decrease the senstivity to covariance regularization + report_balance(); predictedMove = ansA + relative_gradient_scaling_ * ansB; return (predictedMove); @@ -221,6 +228,21 @@ class DualVectorFunction : public VectorFunction { } } + /// The two terms are gradients of quantities with different units, so how they compare is not + /// fixed by relative_gradient_scaling_ alone: it also moves with the scale of the data. Report + /// it periodically, so that a correspondence term scaled into irrelevance is visible. + void report_balance() const { + // counter_ is cleared every iteration, so pace the report on a count of its own. The count is + // shared with the clones, which are made afresh for every shape on every iteration. + if (!a_on_ || !b_on_ || counter_ < 1.0 || report_counter_->fetch_add(1) % 200000 != 0) { + return; + } + const double mag_a = average_grad_mag_a_ / counter_; + const double mag_b = relative_gradient_scaling_ * average_grad_mag_b_ / counter_; + SW_DEBUG("Per-particle gradient: sampling {:.4g}, correspondence {:.4g} ({:.2g}% of the total)", mag_a, mag_b, + 100.0 * mag_b / std::max(1e-30, mag_a + mag_b)); + } + /// This method is called by a solver after each iteration void after_iteration() override { if (a_on_) { @@ -341,6 +363,7 @@ class DualVectorFunction : public VectorFunction { copy->average_energy_a_ = this->average_energy_a_; copy->average_energy_b_ = this->average_energy_b_; copy->counter_ = this->counter_; + copy->report_counter_ = this->report_counter_; if (this->function_a_) { copy->function_a_ = this->function_a_->clone(); @@ -376,6 +399,7 @@ class DualVectorFunction : public VectorFunction { double relative_energy_scaling_; double average_grad_mag_a_; double average_grad_mag_b_; + std::shared_ptr> report_counter_{std::make_shared>(0)}; double average_energy_a_; double average_energy_b_; double counter_; diff --git a/Libs/Optimize/Function/SamplingFunction.cpp b/Libs/Optimize/Function/SamplingFunction.cpp index a5bd2a5008a..4372f264eaa 100644 --- a/Libs/Optimize/Function/SamplingFunction.cpp +++ b/Libs/Optimize/Function/SamplingFunction.cpp @@ -1,6 +1,9 @@ #include "SamplingFunction.h" +#include +#include + #include "Libs/Common/Logging.h" #include "Libs/Optimize/Domain/DomainType.h" #include "vnl/vnl_vector_fixed.h" @@ -270,6 +273,12 @@ SamplingFunction::VectorType SamplingFunction::evaluate(unsigned int idx, unsign // multiply by scaling value (whether auto is on or off) scale_factor *= m_SamplingScaleValue; + static std::atomic report_counter{0}; + if (++report_counter % 200000 == 1) { + SW_DEBUG("Sampling scale: domain surface area {:.4g}, scale factor {:.4g}", + system->GetDomain(d)->GetSurfaceArea(), scale_factor); + } + gradE = gradE * scale_factor; } diff --git a/Libs/Optimize/Matrix/ShapeGradientMatrix.cpp b/Libs/Optimize/Matrix/ShapeGradientMatrix.cpp index f4b7947ac23..872243550b6 100644 --- a/Libs/Optimize/Matrix/ShapeGradientMatrix.cpp +++ b/Libs/Optimize/Matrix/ShapeGradientMatrix.cpp @@ -136,8 +136,18 @@ void ShapeGradientMatrix::SetValues(const ParticleSystemType* ps, int idx, int d point[2] = pt[2]; Eigen::Vector3d gradient = mesh->computeFieldGradientAtPoint(field_attributes[aa], point); + // The gradient comes out of the mesh in its own frame, but this row of the Jacobian sits + // beside the position rows, which are in world space. Without this the attribute pulls a + // particle in a direction rotated by however the shape was aligned during grooming. + ParticleSystem::VectorType field_gradient; + field_gradient[0] = gradient[0]; + field_gradient[1] = gradient[1]; + field_gradient[2] = gradient[2]; + field_gradient = ps->TransformVector(field_gradient, ps->GetTransform(d) * ps->GetPrefixTransform(d)); + for (int vd = 0; vd < 3; vd++) { - this->operator()(aa + k, vd + 3 * (d / m_DomainsPerShape)) = gradient[vd] * m_AttributeScales[num + aa + s]; + this->operator()(aa + k, vd + 3 * (d / m_DomainsPerShape)) = + field_gradient[vd] * m_AttributeScales[num + aa + s]; } } } diff --git a/Libs/Optimize/OptimizeParameters.cpp b/Libs/Optimize/OptimizeParameters.cpp index 80ba7d1db44..29433498ab4 100644 --- a/Libs/Optimize/OptimizeParameters.cpp +++ b/Libs/Optimize/OptimizeParameters.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -702,6 +703,20 @@ bool OptimizeParameters::set_up_optimize(Optimize* optimize) { throw std::runtime_error("The number of field attribute weights does not match the number of field attributes"); } + // scalar attributes are interpolated from the surface at each particle, so they are only defined + // where the domain is a mesh + if (!field_attributes.empty()) { + auto domain_types = project_->get_groomed_domain_types(); + if (domain_types.empty()) { + domain_types = project_->get_original_domain_types(); + } + for (auto domain_type : domain_types) { + if (domain_type != DomainType::Mesh) { + throw std::invalid_argument("Scalar field attributes are only supported for mesh domains"); + } + } + } + for (int j = 0; j < field_attributes.size(); j++) { SW_LOG("Using scalar field attribute: {} with weight {}", field_attributes[j], field_weights[j]); } @@ -946,6 +961,9 @@ bool OptimizeParameters::set_up_optimize(Optimize* optimize) { double geodesic_remesh_percent = get_geodesic_remesh_percent(); int geodesic_cache_multiplier = get_geodesic_cache_multiplier(); bool use_geodesics_to_landmarks = get_use_geodesics_to_landmarks(); + // the geodesic-to-landmark fields are computed here, but a scalar field the user picked has to + // already be on the mesh + auto required_fields = get_field_attributes(); for (auto s : subjects) { if (abort_load_) { @@ -1028,6 +1046,18 @@ bool OptimizeParameters::set_up_optimize(Optimize* optimize) { // Detect a contour by cell content (line cells, no faces) rather than inspecting the first // cell, whose type can vary within a mesh. (#2457) item.is_contour = MeshUtils::is_contour(pd); + + if (!required_fields.empty() && item.is_contour) { + throw std::invalid_argument("Scalar field attributes are only supported for mesh domains"); + } + for (const auto& field : required_fields) { + if (!pd->GetPointData()->GetArray(field.c_str())) { + throw std::invalid_argument("Groomed mesh has no scalar field \"" + field + "\": " + filename + + ". If the field is on the original meshes, re-run grooming: meshes " + "groomed before 6.9 do not carry their fields"); + } + } + item.poly_data = pd; } else if (domain_type == DomainType::Contour) { Mesh mesh = MeshUtils::threadSafeReadMesh(filename.c_str()); diff --git a/Libs/Project/Project.cpp b/Libs/Project/Project.cpp index db3d28f4f21..18fbf911f98 100644 --- a/Libs/Project/Project.cpp +++ b/Libs/Project/Project.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -335,6 +336,48 @@ void Project::set_default_landmark_colors() { default_landmark_colors_.push_back("#9f8fff"); // light purple } +//--------------------------------------------------------------------------- +//! Read the names of the point data arrays carried by the given meshes, in order and without repeats +static std::vector read_mesh_scalar_names(const std::vector& filenames, + const std::vector& domain_types) { + std::vector names; + + for (size_t d = 0; d < domain_types.size(); d++) { + if (domain_types[d] != DomainType::Mesh) { + continue; + } + if (filenames.size() <= d) { + continue; + } + auto filename = filenames[d]; + if (!ShapeWorksUtils::file_exists(filename)) { + continue; + } + try { + auto poly_data = MeshUtils::threadSafeReadMesh(filename).getVTKMesh(); + if (!poly_data) { + continue; + } + vtkIdType num_arrays = poly_data->GetPointData()->GetNumberOfArrays(); + for (vtkIdType i = 0; i < num_arrays; i++) { + std::string array_name = StringUtils::safeString(poly_data->GetPointData()->GetArrayName(i)); + // ignore "normals" and "Normals" arrays + if (array_name == "normals" || array_name == "Normals") { + continue; + } + // domains often carry the same field, and it is one choice to the user either way + if (std::find(names.begin(), names.end(), array_name) == names.end()) { + names.push_back(array_name); + } + } + } catch (std::exception& e) { + SW_ERROR("Unable to read features from mesh: {}", filename); + } + } + + return names; +} + //--------------------------------------------------------------------------- void Project::determine_feature_names() { if (subjects_.empty()) { @@ -351,32 +394,12 @@ void Project::determine_feature_names() { } image_names_ = feature_names_; - std::vector mesh_scalars; - - for (int d = 0; d < get_original_domain_types().size(); d++) { - if (get_original_domain_types()[d] == DomainType::Mesh) { - if (subject->get_original_filenames().size() > d) { - auto filename = subject->get_original_filenames()[d]; - if (ShapeWorksUtils::file_exists(filename)) { - try { - auto poly_data = MeshUtils::threadSafeReadMesh(filename).getVTKMesh(); - if (poly_data) { - vtkIdType num_arrays = poly_data->GetPointData()->GetNumberOfArrays(); - for (vtkIdType i = 0; i < num_arrays; i++) { - std::string array_name = StringUtils::safeString(poly_data->GetPointData()->GetArrayName(i)); - // ignore "normals" and "Normals" arrays - if (array_name == "normals" || array_name == "Normals") { - continue; - } - mesh_scalars.push_back(StringUtils::safeString(poly_data->GetPointData()->GetArrayName(i))); - } - } - } catch (std::exception& e) { - SW_ERROR("Unable to read features from mesh: {}", filename); - } - } - } - } + auto mesh_scalars = read_mesh_scalar_names(subject->get_original_filenames(), get_original_domain_types()); + + mesh_scalar_names_ = mesh_scalars; + if (mesh_scalar_names_.empty()) { + // a project loaded with only groomed meshes still has scalars to offer + mesh_scalar_names_ = read_mesh_scalar_names(subject->get_groomed_filenames(), get_groomed_domain_types()); } // combine @@ -483,6 +506,9 @@ std::string Project::get_next_landmark_color(int domain_id) { //--------------------------------------------------------------------------- std::vector Project::get_feature_names() { return feature_names_; } +//--------------------------------------------------------------------------- +std::vector Project::get_mesh_scalar_names() { return mesh_scalar_names_; } + //--------------------------------------------------------------------------- std::vector Project::get_image_names() { return image_names_; } diff --git a/Libs/Project/Project.h b/Libs/Project/Project.h index 3677f569050..f819fa5a1a4 100644 --- a/Libs/Project/Project.h +++ b/Libs/Project/Project.h @@ -113,6 +113,9 @@ class Project { //! Get image names std::vector get_image_names(); + //! Get the names of the scalar fields carried by the meshes (e.g. thickness, curvature) + std::vector get_mesh_scalar_names(); + //! Get group names std::vector get_group_names(); @@ -191,6 +194,7 @@ class Project { bool images_present_{false}; std::vector feature_names_; + std::vector mesh_scalar_names_; std::vector image_names_; std::vector> landmark_definitions_; diff --git a/Studio/Analysis/AnalysisTool.cpp b/Studio/Analysis/AnalysisTool.cpp index b93b48b1dae..4e0a3442344 100644 --- a/Studio/Analysis/AnalysisTool.cpp +++ b/Studio/Analysis/AnalysisTool.cpp @@ -1726,7 +1726,8 @@ ShapeHandle AnalysisTool::create_shape_from_points(Particles points) { auto scalars = ShapeScalarJob::predict_scalars(session_, QString::fromStdString(feature_map_), points.get_combined_global_particles()); shape->set_point_features(feature_map_, scalars); - } else { + } else if (computed_scalars_.size() > 0) { + // a shape-only mode has no scalars: the model says nothing about the feature away from the mean shape->set_point_features(feature_map_, computed_scalars_); } } diff --git a/Studio/Optimize/OptimizeTool.cpp b/Studio/Optimize/OptimizeTool.cpp index 0666b9a3ee8..9312c6bda68 100644 --- a/Studio/Optimize/OptimizeTool.cpp +++ b/Studio/Optimize/OptimizeTool.cpp @@ -1,15 +1,20 @@ #include // qt +#include #include #include +#include #include #include +#include #include #include #include #include +#include + // shapeworks #include @@ -27,6 +32,9 @@ using namespace shapeworks; namespace { +//! How far the fields of a section are set in from the checkbox that switches the section on +const int kSubItemIndent = 20; + // QLabel that elides its text with "..." when it's narrower than the text. // The full text is kept as a tooltip so the user can see it on hover. // sizeHint() reports the full-text width so the layout gives the label its natural @@ -79,6 +87,7 @@ OptimizeTool::OptimizeTool(Preferences& prefs, Telemetry& telemetry) : preferenc connect(ui_->procrustes, &QCheckBox::toggled, this, &OptimizeTool::update_ui_elements); connect(ui_->multiscale, &QCheckBox::toggled, this, &OptimizeTool::update_ui_elements); connect(ui_->use_geodesics_from_landmarks, &QCheckBox::toggled, this, &OptimizeTool::update_ui_elements); + connect(ui_->mesh_scalars, &QCheckBox::toggled, this, &OptimizeTool::update_ui_elements); connect(ui_->use_geodesic_distance, &QCheckBox::toggled, this, &OptimizeTool::update_ui_elements); connect(ui_->sampling_scale, &QCheckBox::toggled, this, &OptimizeTool::update_ui_elements); connect(ui_->registration_initialization, &QCheckBox::toggled, this, &OptimizeTool::update_ui_elements); @@ -95,6 +104,10 @@ OptimizeTool::OptimizeTool(Preferences& prefs, Telemetry& telemetry) : preferenc "Requires ~10x more time, and larger memory footprint. Only supported for mesh inputs")); ui_->geodesic_remesh_percent->setToolTip("Percent remesh reduction to use for geodesic distance"); ui_->use_normals->setToolTip("Use surface normals as part of optimization"); + ui_->mesh_scalars->setToolTip(StudioUtils::wrap_tooltip( + "Use scalar fields carried by the meshes (thickness, curvature, and the like) as part of " + "optimization. A selected field is matched across shapes along with position, so particles " + "line up on the values as well as on the surface")); ui_->normals_strength->setToolTip("Strength of surface normals relative to position"); ui_->procrustes->setToolTip("Use procrustes registration during optimization"); ui_->procrustes_interval->setToolTip("How often to run procrustes during optimization (0 = disabled)"); @@ -178,20 +191,13 @@ OptimizeTool::OptimizeTool(Preferences& prefs, Telemetry& telemetry) : preferenc connect(line_edit, &QLineEdit::textChanged, this, &OptimizeTool::update_run_button); } - auto set_session_modified = [this]() { - if (!session_) { - return; - } - session_->set_modified(true); - }; - auto line_edits = findChildren(); for (auto line_edit : line_edits) { - connect(line_edit, &QLineEdit::textChanged, this, set_session_modified); + connect(line_edit, &QLineEdit::textChanged, this, &OptimizeTool::handle_session_modified); } auto check_boxes = findChildren(); for (auto check_box : check_boxes) { - connect(check_box, &QCheckBox::toggled, this, set_session_modified); + connect(check_box, &QCheckBox::toggled, this, &OptimizeTool::handle_session_modified); } Style::apply_normal_button_style(ui_->restoreDefaults); @@ -339,6 +345,7 @@ void OptimizeTool::set_session(QSharedPointer session) { session_ = ses //--------------------------------------------------------------------------- void OptimizeTool::load_params() { setup_domain_boxes(); + setup_mesh_scalar_boxes(); auto params = OptimizeParameters(session_->get_project()); auto num_particles = params.get_number_of_particles(); @@ -363,6 +370,24 @@ void OptimizeTool::load_params() { ui_->normals_strength->setText(QString::number(params.get_normals_strength())); ui_->use_geodesics_from_landmarks->setChecked(params.get_use_geodesics_to_landmarks()); ui_->geodesics_to_landmarks_weight->setText(QString::number(params.get_geodesic_to_landmarks_weight())); + + auto field_attributes = params.get_field_attributes(); + auto field_weights = params.get_field_attribute_weights(); + ui_->mesh_scalars->setChecked(!field_attributes.empty()); + for (int i = 0; i < mesh_scalar_names_.size(); i++) { + auto position = std::find(field_attributes.begin(), field_attributes.end(), mesh_scalar_names_[i]); + bool chosen = position != field_attributes.end(); + double weight = 1.0; + if (chosen) { + size_t index = position - field_attributes.begin(); + if (index < field_weights.size()) { + weight = field_weights[index]; + } + } + mesh_scalar_checks_[i]->setChecked(chosen); + mesh_scalar_weights_[i]->setText(QString::number(weight)); + } + ui_->use_disentangled_ssm->setChecked(params.get_use_disentangled_ssm()); ui_->procrustes->setChecked(params.get_use_procrustes()); @@ -417,6 +442,24 @@ void OptimizeTool::store_params() { params.set_normals_strength(ui_->normals_strength->text().toDouble()); params.set_use_geodesics_to_landmarks(ui_->use_geodesics_from_landmarks->isChecked()); params.set_geodesic_to_landmarks_weight(ui_->geodesics_to_landmarks_weight->text().toDouble()); + + // with no rows there is nothing the user could have chosen here, so leave whatever the project + // was given elsewhere alone + if (!mesh_scalar_names_.empty()) { + std::vector field_attributes; + std::vector field_weights; + if (ui_->mesh_scalars->isChecked()) { + for (int i = 0; i < mesh_scalar_names_.size(); i++) { + if (mesh_scalar_checks_[i]->isChecked()) { + field_attributes.push_back(mesh_scalar_names_[i]); + field_weights.push_back(mesh_scalar_weights_[i]->text().toDouble()); + } + } + } + params.set_field_attributes(field_attributes); + params.set_field_attribute_weights(field_weights); + } + params.set_use_disentangled_ssm(ui_->use_disentangled_ssm->isChecked()); params.set_use_procrustes(ui_->procrustes->isChecked()); @@ -469,6 +512,14 @@ void OptimizeTool::shutdown_threads() { //--------------------------------------------------------------------------- void OptimizeTool::update_ui_elements() { ui_->normals_strength->setEnabled(ui_->use_normals->isChecked()); + bool mesh_scalars_enabled = ui_->mesh_scalars->isChecked(); + for (int i = 0; i < mesh_scalar_weights_.size(); i++) { + bool weight_enabled = mesh_scalars_enabled && mesh_scalar_checks_[i]->isChecked(); + mesh_scalar_checks_[i]->setEnabled(mesh_scalars_enabled); + // the label fades with the box it belongs to + mesh_scalar_weight_labels_[i]->setEnabled(weight_enabled); + mesh_scalar_weights_[i]->setEnabled(weight_enabled); + } ui_->procrustes_scaling->setEnabled(ui_->procrustes->isChecked()); ui_->procrustes_rotation_translation->setEnabled(ui_->procrustes->isChecked()); ui_->procrustes_interval->setEnabled(ui_->procrustes->isChecked()); @@ -516,6 +567,7 @@ bool OptimizeTool::validate_inputs() { std::vector combined = line_edits_; combined.insert(combined.end(), particle_boxes_.begin(), particle_boxes_.end()); + combined.insert(combined.end(), mesh_scalar_weights_.begin(), mesh_scalar_weights_.end()); for (QLineEdit* line_edit : combined) { QString text = line_edit->text(); @@ -533,6 +585,97 @@ bool OptimizeTool::validate_inputs() { return all_valid; } +//--------------------------------------------------------------------------- +void OptimizeTool::setup_mesh_scalar_boxes() { + for (auto* widget : mesh_scalar_widgets_) { + widget->setParent(nullptr); + delete widget; + } + mesh_scalar_widgets_.clear(); + mesh_scalar_checks_.clear(); + mesh_scalar_weight_labels_.clear(); + mesh_scalar_weights_.clear(); + mesh_scalar_names_.clear(); + + auto params = OptimizeParameters(session_->get_project()); + + mesh_scalar_names_ = session_->get_project()->get_mesh_scalar_names(); + + // a field the project already asks for gets a row even when it wasn't found on the meshes, so + // that opening this panel can't quietly drop it + for (const auto& name : params.get_field_attributes()) { + if (std::find(mesh_scalar_names_.begin(), mesh_scalar_names_.end(), name) == mesh_scalar_names_.end()) { + mesh_scalar_names_.push_back(name); + } + } + + // the section is dividers and all, so it disappears completely when there is nothing to show + bool any_scalars = !mesh_scalar_names_.empty(); + ui_->line_mesh_scalars_top->setVisible(any_scalars); + ui_->mesh_scalars->setVisible(any_scalars); + ui_->mesh_scalar_widget->setVisible(any_scalars); + ui_->line_mesh_scalars_bottom->setVisible(any_scalars); + if (!any_scalars) { + return; + } + + auto grid = qobject_cast(ui_->mesh_scalar_widget->layout()); + auto positive = new QDoubleValidator(0, std::numeric_limits::max(), 1000, this); + + // the fields are options of the checkbox above them, so set them in from it + grid->setContentsMargins(kSubItemIndent, 0, 0, 0); + + auto add_widget = [&](QWidget* widget, int row, int column) { + grid->addWidget(widget, row, column); + mesh_scalar_widgets_.push_back(widget); + }; + + for (int i = 0; i < mesh_scalar_names_.size(); i++) { + auto name = QString::fromStdString(mesh_scalar_names_[i]); + + auto check = new QCheckBox(name, this); + check->setToolTip(QString("Use the \"%1\" field as part of optimization").arg(name)); + connect(check, &QCheckBox::toggled, this, &OptimizeTool::update_ui_elements); + connect(check, &QCheckBox::toggled, this, &OptimizeTool::handle_session_modified); + mesh_scalar_checks_.push_back(check); + add_widget(check, i, 0); + + auto weight_label = new QLabel("Weight:", this); + weight_label->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + mesh_scalar_weight_labels_.push_back(weight_label); + add_widget(weight_label, i, 1); + + auto weight = new QLineEdit(this); + weight->setAlignment(Qt::AlignHCenter); + weight->setMinimumWidth(50); + weight->setMaximumWidth(100); + weight->setValidator(positive); + weight->setToolTip("Strength of this field relative to position"); + connect(weight, &QLineEdit::textChanged, this, &OptimizeTool::update_run_button); + connect(weight, &QLineEdit::textChanged, this, &OptimizeTool::handle_session_modified); + mesh_scalar_weights_.push_back(weight); + add_widget(weight, i, 2); + } + + grid->setColumnStretch(0, 1); + + QWidget::setTabOrder(ui_->geodesics_to_landmarks_weight, ui_->mesh_scalars); + QWidget* previous = ui_->mesh_scalars; + for (int i = 0; i < mesh_scalar_checks_.size(); i++) { + QWidget::setTabOrder(previous, mesh_scalar_checks_[i]); + QWidget::setTabOrder(mesh_scalar_checks_[i], mesh_scalar_weights_[i]); + previous = mesh_scalar_weights_[i]; + } + QWidget::setTabOrder(previous, ui_->multiscale); +} + +//--------------------------------------------------------------------------- +void OptimizeTool::handle_session_modified() { + if (session_) { + session_->set_modified(true); + } +} + //--------------------------------------------------------------------------- void OptimizeTool::update_run_button() { bool inputs_valid = validate_inputs(); diff --git a/Studio/Optimize/OptimizeTool.h b/Studio/Optimize/OptimizeTool.h index c06746fa162..03930cd6f39 100644 --- a/Studio/Optimize/OptimizeTool.h +++ b/Studio/Optimize/OptimizeTool.h @@ -12,6 +12,8 @@ class Ui_OptimizeTool; +class QCheckBox; +class QLabel; class QLineEdit; namespace shapeworks { @@ -61,6 +63,8 @@ public Q_SLOTS: void update_ui_elements(); + void handle_session_modified(); + bool validate_inputs(); Q_SIGNALS: @@ -74,6 +78,8 @@ public Q_SLOTS: void setup_domain_boxes(); + void setup_mesh_scalar_boxes(); + void update_run_button(); void handle_load_progress(int count); @@ -81,6 +87,13 @@ public Q_SLOTS: std::vector particle_boxes_; std::vector domain_grid_widgets_; + //! one row per scalar field the meshes carry: name, "use it" box, and its weight + std::vector mesh_scalar_names_; + std::vector mesh_scalar_checks_; + std::vector mesh_scalar_weight_labels_; + std::vector mesh_scalar_weights_; + std::vector mesh_scalar_widgets_; + Preferences& preferences_; Telemetry& telemetry_; diff --git a/Studio/Optimize/OptimizeTool.ui b/Studio/Optimize/OptimizeTool.ui index 469057628e2..ec80f0081b4 100644 --- a/Studio/Optimize/OptimizeTool.ui +++ b/Studio/Optimize/OptimizeTool.ui @@ -645,15 +645,57 @@ QWidget#optimize_panel { - - + + + + + Qt::Horizontal + + + + + + + Mesh Scalars + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + Qt::Horizontal + + + + + Multiscale Mode - + Start: @@ -663,7 +705,7 @@ QWidget#optimize_panel { - + 32 @@ -685,15 +727,15 @@ QWidget#optimize_panel { - - + + Shared Boundary - + Weight: @@ -703,7 +745,7 @@ QWidget#optimize_panel { - + 0.1 @@ -725,23 +767,23 @@ QWidget#optimize_panel { - - + + Use Initial Landmarks - - + + Registration Initialization - + Transform: @@ -751,7 +793,7 @@ QWidget#optimize_panel { - + @@ -782,8 +824,8 @@ QWidget#optimize_panel { - - + + Band: @@ -793,7 +835,7 @@ QWidget#optimize_panel { - + auto @@ -815,8 +857,8 @@ QWidget#optimize_panel { - - + + Grid: @@ -826,7 +868,7 @@ QWidget#optimize_panel { - + 128 @@ -849,22 +891,22 @@ QWidget#optimize_panel { - + Qt::Horizontal - - + + Procrustes - + Interval: @@ -874,7 +916,7 @@ QWidget#optimize_panel { - + 10 @@ -896,8 +938,8 @@ QWidget#optimize_panel { - - + + @@ -943,15 +985,15 @@ QWidget#optimize_panel { - + Qt::Horizontal - - + + Sampling Scale @@ -961,7 +1003,7 @@ QWidget#optimize_panel { - + Multiplier: @@ -971,7 +1013,7 @@ QWidget#optimize_panel { - + 1.0 @@ -993,8 +1035,8 @@ QWidget#optimize_panel { - - + + @@ -1035,8 +1077,8 @@ QWidget#optimize_panel { - - + + Disentangled SSM diff --git a/Studio/Visualization/Viewer.cpp b/Studio/Visualization/Viewer.cpp index ba1c228800c..abd45adb44f 100644 --- a/Studio/Visualization/Viewer.cpp +++ b/Studio/Visualization/Viewer.cpp @@ -1201,6 +1201,10 @@ void Viewer::update_points() { shape_->load_feature(session_->get_display_mode(), feature_map); scalar_values = shape_->get_point_features(feature_map); } + // a shape with no values for the feature (a shape-only PCA mode, say) keeps the usual particle + // colors: an index pushed through the feature's color scale means nothing + glyphs_show_feature_ = + showing_feature_map() && (scalar_values.size() > 0 || session_->should_difference_vectors_show()); auto domain_visibility = visualizer_->get_domain_particle_visibilities(); if (domain_visibility.size() != correspondence_points.size()) { @@ -1243,13 +1247,15 @@ void Viewer::update_points() { } } - if (showing_feature_map()) { + if (glyphs_show_feature_) { glyph_mapper_->SetScalarRange(surface_lut_->GetRange()); glyph_point_set_->GetPointData()->SetScalars(scalars); glyphs_->SetColorModeToColorByScalar(); glyph_mapper_->SetColorModeToMapScalars(); glyph_mapper_->ScalarVisibilityOn(); glyph_mapper_->SetLookupTable(surface_lut_); + } else if (!arrows_visible_) { + glyph_mapper_->SetLookupTable(glyph_lut_); } int alignment_domain = visualizer_->get_alignment_domain(); @@ -1573,7 +1579,7 @@ PickResult Viewer::handle_ctrl_click(int* click_pos) { //----------------------------------------------------------------------------- void Viewer::set_glyph_lut(vtkSmartPointer lut) { glyph_lut_ = lut; - if (!arrows_visible_ && !showing_feature_map()) { + if (!arrows_visible_ && !glyphs_show_feature_) { glyph_mapper_->SetLookupTable(glyph_lut_); } } @@ -1600,7 +1606,9 @@ void Viewer::update_difference_lut(float r0, float r1) { arrow_glyph_mapper_->SetLookupTable(surface_lut_); arrow_glyph_mapper_->SetScalarRange(range); - glyph_mapper_->SetScalarRange(range); + if (glyphs_show_feature_ || arrows_visible_ || !showing_feature_map()) { + glyph_mapper_->SetScalarRange(range); + } scalar_bar_actor_->SetLookupTable(surface_lut_); slice_view_.update_colormap(); if (rd > 100) { diff --git a/Studio/Visualization/Viewer.h b/Studio/Visualization/Viewer.h index 2b5a09ae234..39ac38d8675 100644 --- a/Studio/Visualization/Viewer.h +++ b/Studio/Visualization/Viewer.h @@ -264,6 +264,8 @@ class Viewer { vtkSmartPointer corner_annotation_; bool arrows_visible_ = false; + //! whether the particles are colored by the feature map (false when the shape has no values for it) + bool glyphs_show_feature_ = false; ColorSchemes color_schemes_; int scheme_ = 0; diff --git a/Testing/GroomTests/GroomTests.cpp b/Testing/GroomTests/GroomTests.cpp index 06dabf079f1..25f99190533 100644 --- a/Testing/GroomTests/GroomTests.cpp +++ b/Testing/GroomTests/GroomTests.cpp @@ -3,7 +3,11 @@ #include "Testing.h" #include +#include +#include #include +#include +#include using namespace shapeworks; @@ -31,3 +35,56 @@ TEST(GroomTests, basic_test) ASSERT_TRUE(image == ground_truth); } + +//--------------------------------------------------------------------------- +TEST(GroomTests, mesh_scalars_survive_grooming_test) { + TestUtils::Instance().prep_temp(std::string(TEST_DATA_DIR) + "/optimize/mesh_use_normals", "groom_mesh_scalars"); + + // meshes carrying a scalar field, which grooming has to hand to the optimizer intact + ProjectHandle project = std::make_shared(); + ASSERT_TRUE(project->load("optimize.swproj")); + + for (auto& subject : project->get_subjects()) { + std::vector filenames; + for (const auto& filename : subject->get_original_filenames()) { + Mesh mesh = MeshUtils::threadSafeReadMesh(filename); + + auto height = vtkSmartPointer::New(); + height->SetName("height"); + height->SetNumberOfValues(mesh.numPoints()); + for (int i = 0; i < mesh.numPoints(); i++) { + height->SetValue(i, mesh.getPoint(i)[2]); + } + mesh.setField("height", height, Mesh::Point); + + // .ply cannot carry fields, so keep the copy with the field in a format that can + auto name = StringUtils::getBaseFilenameWithoutExtension(filename) + "_scalars.vtk"; + mesh.write(name); + filenames.push_back(name); + } + subject->set_original_filenames(filenames); + subject->set_groomed_filenames({}); + } + project->update_subjects(); + + // the steps that rebuild the surface: repair runs regardless, then these + GroomParameters params(project); + params.set_fill_mesh_holes_tool(true); + params.set_remesh(true); + params.set_remesh_percent_mode(true); + params.set_remesh_percent(50); + params.set_mesh_smooth(true); + params.save_to_project(); + + Groom app(project); + ASSERT_TRUE(app.run()); + + for (auto& subject : project->get_subjects()) { + for (const auto& filename : subject->get_groomed_filenames()) { + Mesh groomed = MeshUtils::threadSafeReadMesh(filename); + auto names = groomed.getFieldNames(); + ASSERT_NE(std::find(names.begin(), names.end(), "height"), names.end()); + ASSERT_NO_THROW(groomed.getFieldValue("height", groomed.numPoints() - 1)); + } + } +} diff --git a/Testing/MeshTests/MeshTests.cpp b/Testing/MeshTests/MeshTests.cpp index 2e560609c08..59ee0dd0042 100644 --- a/Testing/MeshTests/MeshTests.cpp +++ b/Testing/MeshTests/MeshTests.cpp @@ -1,11 +1,14 @@ #include #include +#include +#include #include #include #include #include #include +#include #include "Image.h" #include "Mesh.h" @@ -355,6 +358,109 @@ TEST(MeshTests, remeshPercentTest2) { ASSERT_TRUE(femur == ground_truth); } +TEST(MeshTests, fieldGradientFloatTest) { + // fields arrive on meshes as floats as often as doubles, and the gradient has to be computed for + // either: a missing gradient array used to be read as a null pointer + Mesh ellipsoid(std::string(TEST_DATA_DIR) + "/ellipsoid_01.vtk"); + + auto height = vtkSmartPointer::New(); + height->SetName("height"); + height->SetNumberOfValues(ellipsoid.numPoints()); + for (int i = 0; i < ellipsoid.numPoints(); i++) { + height->SetValue(i, ellipsoid.getPoint(i)[2]); + } + ellipsoid.setField("height", height, Mesh::Point); + + auto gradient = ellipsoid.computeFieldGradientAtPoint("height", ellipsoid.getPoint(100)); + + ASSERT_TRUE(gradient.allFinite()); + ASSERT_GT(gradient.norm(), 0.0); + + auto names = ellipsoid.getFieldNames(); + ASSERT_NE(std::find(names.begin(), names.end(), "gradient_height"), names.end()); +} + +TEST(MeshTests, repairKeepsFieldsTest) { + // grooming repairs every mesh before anything else, so the fields have to survive it + Mesh femur(std::string(TEST_DATA_DIR) + "/femurThreeFields.vtk"); + + auto values = femur.getField("distance", Mesh::Point); + std::map, double> before; + for (int i = 0; i < femur.numPoints(); i++) { + auto point = femur.getPoint(i); + before[{point[0], point[1], point[2]}] = values->GetTuple1(i); + } + + Mesh repaired(MeshUtils::repair_mesh(femur.getVTKMesh())); + + auto names = repaired.getFieldNames(); + ASSERT_NE(std::find(names.begin(), names.end(), "distance"), names.end()); + ASSERT_NE(std::find(names.begin(), names.end(), "bloop"), names.end()); + // "max" holds a single value, not one per point, so it cannot be carried and must not be read as if it could + ASSERT_EQ(std::find(names.begin(), names.end(), "max"), names.end()); + + // repair renumbers points, so check that each one kept the value belonging to its position + int checked = 0; + for (int i = 0; i < repaired.numPoints(); i++) { + auto point = repaired.getPoint(i); + auto match = before.find({point[0], point[1], point[2]}); + if (match != before.end()) { + ASSERT_EQ(repaired.getFieldValue("distance", i), match->second); + checked++; + } + } + ASSERT_GT(checked, 0); +} + +TEST(MeshTests, remeshKeepsFieldsTest) { + Mesh femur(std::string(TEST_DATA_DIR) + "/femurThreeFields.vtk"); + + // the third field of this mesh holds a single value rather than one per point, so it is not + // something that can be carried onto different vertices + std::vector fields{"distance", "bloop"}; + + std::vector minimums; + std::vector maximums; + for (const auto& field : fields) { + double range[2]; + femur.getField(field, Mesh::Point)->GetRange(range); + minimums.push_back(range[0]); + maximums.push_back(range[1]); + } + + femur.remeshPercent(0.25, 1.0); + + auto remeshed = femur.getFieldNames(); + for (int i = 0; i < fields.size(); i++) { + ASSERT_NE(std::find(remeshed.begin(), remeshed.end(), fields[i]), remeshed.end()); + // a value for every new vertex, not just the ones that happen to line up with an old one + for (int p = 0; p < femur.numPoints(); p++) { + double value = femur.getFieldValue(fields[i], p); + ASSERT_GE(value, minimums[i]); + ASSERT_LE(value, maximums[i]); + } + } +} + +TEST(MeshTests, remeshInterpolatesFieldsTest) { + Mesh ellipsoid(std::string(TEST_DATA_DIR) + "/ellipsoid_01.vtk"); + + // a field that follows the geometry, so the values carried onto the new vertices can be checked + auto height = vtkSmartPointer::New(); + height->SetName("height"); + height->SetNumberOfValues(ellipsoid.numPoints()); + for (int i = 0; i < ellipsoid.numPoints(); i++) { + height->SetValue(i, ellipsoid.getPoint(i)[2]); + } + ellipsoid.setField("height", height, Mesh::Point); + + ellipsoid.remesh(300, 1.0); + + for (int i = 0; i < ellipsoid.numPoints(); i++) { + ASSERT_NEAR(ellipsoid.getFieldValue("height", i), ellipsoid.getPoint(i)[2], 1.0); + } +} + TEST(MeshTests, smoothTest1) { Mesh femur(std::string(TEST_DATA_DIR) + "/femur.vtk"); femur.smooth(10, 0.01); diff --git a/Testing/OptimizeTests/OptimizeTests.cpp b/Testing/OptimizeTests/OptimizeTests.cpp index 724c2004007..783f779bb6f 100644 --- a/Testing/OptimizeTests/OptimizeTests.cpp +++ b/Testing/OptimizeTests/OptimizeTests.cpp @@ -6,6 +6,10 @@ #include #include +#include + +#include +#include #include #include "../Testing.h" @@ -443,6 +447,167 @@ TEST(OptimizeTests, mesh_use_normals_test) { ASSERT_LT(values[values.size() - 2], 10); } +//--------------------------------------------------------------------------- +//! Give every mesh a scalar field and optimize with it as an attribute +static ProjectHandle prep_mesh_scalar_project() { + ProjectHandle project = std::make_shared(); + if (!project->load("optimize.swproj")) { + return nullptr; + } + + for (auto& subject : project->get_subjects()) { + std::vector filenames; + for (const auto& filename : subject->get_groomed_filenames()) { + Mesh mesh = MeshUtils::threadSafeReadMesh(filename); + + // deliberately a float field: that is how scalars usually arrive on a mesh + auto height = vtkSmartPointer::New(); + height->SetName("height"); + height->SetNumberOfValues(mesh.numPoints()); + for (int i = 0; i < mesh.numPoints(); i++) { + height->SetValue(i, mesh.getPoint(i)[2]); + } + mesh.setField("height", height, Mesh::Point); + + // .ply cannot carry fields, so keep the copy with the field in a format that can + auto name = StringUtils::getBaseFilenameWithoutExtension(filename) + "_scalars.vtk"; + mesh.write(name); + filenames.push_back(name); + } + subject->set_original_filenames(filenames); + subject->set_groomed_filenames(filenames); + } + project->update_subjects(); + + return project; +} + +//--------------------------------------------------------------------------- +TEST(OptimizeTests, mesh_scalars_test) { + prep_temp("/optimize/mesh_use_normals", "mesh_scalars"); + + auto project = prep_mesh_scalar_project(); + ASSERT_TRUE(project != nullptr); + + OptimizeParameters params(project); + params.set_field_attributes({"height"}); + params.set_field_attribute_weights({1.0}); + params.set_number_of_particles({32}); + params.set_optimization_iterations(20); + + Optimize app; + ASSERT_TRUE(params.set_up_optimize(&app)); + + // a scalar attribute is matched through the mesh-based correspondence path + ASSERT_TRUE(app.GetUseMeshBasedAttributes()); + ASSERT_EQ(app.GetAttributesPerDomain()[0], 1); + + ASSERT_TRUE(app.Run()); + + auto points = app.GetLocalPoints(); + ASSERT_EQ(points.size(), 4); + for (const auto& shape : points) { + ASSERT_EQ(shape.size(), 32); + } +} + +//--------------------------------------------------------------------------- +TEST(OptimizeTests, mesh_scalars_missing_field_test) { + prep_temp("/optimize/mesh_use_normals", "mesh_scalars_missing_field"); + + auto project = prep_mesh_scalar_project(); + ASSERT_TRUE(project != nullptr); + + OptimizeParameters params(project); + params.set_field_attributes({"not_a_field"}); + params.set_field_attribute_weights({1.0}); + params.set_number_of_particles({32}); + + // a field the meshes don't carry has to be reported, not interpolated as garbage + Optimize app; + ASSERT_THROW(params.set_up_optimize(&app), std::invalid_argument); +} + +//--------------------------------------------------------------------------- +//! Optimize spheres that carry a patch field at a different place on each shape. Returns the spread +//! across the shapes of the field under each particle, averaged over the particles, or -1 on failure. +static double run_mesh_patch_optimization(const std::string& name, bool use_field) { + prep_temp("/optimize/mesh_use_normals", name); + + ProjectHandle project = std::make_shared(); + if (!project->load("optimize.swproj")) { + return -1.0; + } + + const double degrees = std::acos(-1.0) / 180.0; + const double width = 25.0 * degrees; + + std::vector meshes; + for (auto& subject : project->get_subjects()) { + Mesh mesh = MeshUtils::threadSafeReadMesh(subject->get_groomed_filenames()[0]); + + // the spheres are centered on the origin: move the patch around them from shape to shape + const double angle = (-30.0 + 20.0 * meshes.size()) * degrees; + const Eigen::Vector3d patch_center(std::sin(angle), 0.0, std::cos(angle)); + + auto patch = vtkSmartPointer::New(); + patch->SetName("patch"); + patch->SetNumberOfValues(mesh.numPoints()); + for (int i = 0; i < mesh.numPoints(); i++) { + auto point = mesh.getPoint(i); + const Eigen::Vector3d direction = Eigen::Vector3d(point[0], point[1], point[2]).normalized(); + const double separation = std::acos(std::clamp(direction.dot(patch_center), -1.0, 1.0)); + patch->SetValue(i, std::exp(-0.5 * (separation / width) * (separation / width))); + } + mesh.setField("patch", patch, Mesh::Point); + + std::string filename = "sphere_patch_" + std::to_string(meshes.size()) + ".vtk"; + mesh.write(filename); + subject->set_original_filenames({filename}); + subject->set_groomed_filenames({filename}); + meshes.push_back(mesh); + } + project->update_subjects(); + + OptimizeParameters params(project); + if (use_field) { + params.set_field_attributes({"patch"}); + params.set_field_attribute_weights({100.0}); + } + params.set_use_normals({false}); + params.set_number_of_particles({32}); + + Optimize app; + if (!params.set_up_optimize(&app) || !app.Run()) { + return -1.0; + } + + auto points = app.GetLocalPoints(); + const size_t num_particles = points[0].size(); + double total = 0.0; + for (size_t j = 0; j < num_particles; j++) { + Eigen::VectorXd values(points.size()); + for (size_t shape = 0; shape < points.size(); shape++) { + values[shape] = meshes[shape].getFieldValue("patch", meshes[shape].closestPointId(points[shape][j])); + } + total += std::sqrt((values.array() - values.mean()).square().mean()); + } + return total / num_particles; +} + +//--------------------------------------------------------------------------- +TEST(OptimizeTests, mesh_scalars_follow_field_test) { + // a sphere says nothing about where the patch is, so only the field can line the particles up on it + const double without_field = run_mesh_patch_optimization("mesh_scalars_patch_off", false); + const double with_field = run_mesh_patch_optimization("mesh_scalars_patch_on", true); + std::cerr << "Spread of the field under a particle: " << without_field << " without the attribute, " + << with_field << " with it\n"; + + ASSERT_GT(without_field, 0.0); + ASSERT_GE(with_field, 0.0); + ASSERT_LT(with_field, 0.5 * without_field); +} + //--------------------------------------------------------------------------- TEST(OptimizeTests, embedded_python_test) { prep_temp("/simple", "embedded_python"); diff --git a/docs/studio/images/studio_mesh_scalars_analysis.png b/docs/studio/images/studio_mesh_scalars_analysis.png new file mode 100644 index 00000000000..e7d565bbcd5 Binary files /dev/null and b/docs/studio/images/studio_mesh_scalars_analysis.png differ diff --git a/docs/studio/images/studio_mesh_scalars_data.png b/docs/studio/images/studio_mesh_scalars_data.png new file mode 100644 index 00000000000..c019f392f67 Binary files /dev/null and b/docs/studio/images/studio_mesh_scalars_data.png differ diff --git a/docs/studio/images/studio_mesh_scalars_optimize.png b/docs/studio/images/studio_mesh_scalars_optimize.png new file mode 100644 index 00000000000..ac320507ba9 Binary files /dev/null and b/docs/studio/images/studio_mesh_scalars_optimize.png differ diff --git a/docs/studio/studio-groom.md b/docs/studio/studio-groom.md index 4b8d03dbd3e..f2b22663ab8 100644 --- a/docs/studio/studio-groom.md +++ b/docs/studio/studio-groom.md @@ -30,7 +30,7 @@ Before the mesh grooming pipeline runs, each mesh is automatically repaired. Thi | Smooth | Perform either Laplacian or Windowed Sinc smoothing | | Laplacian Smoothing | Laplacian smoothing option with specified iterations and relaxation factor. In general, it is recommended to use smaller relaxation factors and more iterations rather than larger relaxation and fewer iterations | | Windowed Sinc Smoothing | Windowed Sinc smoothing with specified iterations and passband (typically between 0 and 2). Lower passpand values produce more smoothing. | -| Remesh | Enabled remeshing using ACVD library | +| Remesh | Enabled remeshing using ACVD library. Scalar fields carried by the mesh are interpolated onto the new vertices | | Remesh Percent | Specify target vertices as a percentage of existing vertices | | Remesh Vertices | Specify target vertices directly | | Remesh Adaptivity | Curvature adaptivity of remeshing (0 = uniform, 2.0 most adaptive). This allocates more triangles/vertices to areas of higher curvature | diff --git a/docs/studio/studio-mesh-scalars.md b/docs/studio/studio-mesh-scalars.md new file mode 100644 index 00000000000..363d8d62266 --- /dev/null +++ b/docs/studio/studio-mesh-scalars.md @@ -0,0 +1,42 @@ +# Mesh Scalars as Correspondence Attributes in Studio + +Meshes often carry a per-vertex scalar field: thickness, curvature, a parametric coordinate, a measurement of your own. ShapeWorks Studio can use such a field as a correspondence attribute, so that particles line up on the field as well as on the geometry. This helps when the shape alone does not say where a feature is. See also [Mesh Scalar Attributes](../workflow/optimize.md#mesh-scalar-attributes). + +## Example Data + +The example data for this tutorial is provided in the ``Examples/Studio/MeshScalars`` directory. + +To open the project, start ShapeWorks Studio, and open the project file ``Examples/Studio/MeshScalars/mesh_scalars.swproj``. + +The data is ten ellipsoids of nearly the same shape. Each carries a field named `scalar_value`: a patch near the top of the ellipsoid whose position along the long axis differs from subject to subject. Nothing in the geometry marks where the patch is. The script `make_example.py` in the same directory regenerates the data. + +Choose `scalar_value` as the Feature Map below the viewer to see the patch on each subject. + +![Mesh Scalars Example in Studio](images/studio_mesh_scalars_data.png){: width="600" } + +## Grooming + +The meshes are already clean and aligned, so the grooming steps are turned off. Run Groom to pass them through. When grooming steps such as remeshing are used, scalar fields are carried onto the groomed meshes, which is where optimization reads them. + +## Optimization + +The Optimize panel has a Mesh Scalars section with a row for each field found on the meshes. In this project Mesh Scalars is checked, and `scalar_value` under it is checked with a Weight of 100. The weight scales the field relative to XYZ: the field here ranges from 0 to 1 while the ellipsoids are tens of units across, so it needs a large weight to count. + +![Mesh Scalars Optimization Options in Studio](images/studio_mesh_scalars_optimize.png){: width="600" } + +Run Optimize. To see what the field contributes, uncheck `scalar_value`, run Optimize again, and compare. + +## Analysis + +The first PCA mode, from -2 to +2 standard deviations, with the field shown on the surface. The particles move with the patch. + +![Mesh Scalars PCA Mode in Studio](images/studio_mesh_scalars_analysis.png){: width="800" } + +Compared with a model optimized without the field: + +| | Without the field | With the field | +| --- | --- | --- | +| First PCA mode | the small differences in size | the patch moving along the ellipsoid, 97% of the variance | +| Particles in the Samples view, colored by the feature map | a given particle's color changes from subject to subject | each particle has the same color in every subject | + +With the field in use, each particle sits at the same place relative to the patch in every subject, and the first mode of variation is the movement of the patch, which a model built from geometry alone cannot see. diff --git a/docs/studio/studio-optimize.md b/docs/studio/studio-optimize.md index 228ccf98ac0..fe7c259b0c2 100644 --- a/docs/studio/studio-optimize.md +++ b/docs/studio/studio-optimize.md @@ -22,6 +22,8 @@ Optimization Parameters | Normals Strength | Amount to scale surface normals feature to give it enough weight relative to XYZ | | Geodesic from Landmarks | Compute geodesic distance fields from landmarks and use as a correspondence attribute | | Geodesic Landmarks Weight | Weight for the geodesic-from-landmarks correspondence term (default: 1.0) | +| Mesh Scalars | Scalar fields carried by the meshes (thickness, curvature, and the like) that can be used as correspondence features. A row appears for each field found on the meshes; check the ones to use. Mesh inputs only | +| Mesh Scalar Weight | Amount to scale a mesh scalar field to give it enough weight relative to XYZ (default: 1.0) | | Multiscale Mode | Enable multiscale optimization where each particle split level after the multiscale start number runs in both initialization and optimization modes | | Multiscale Start | Number of particles to begin multiscale mode | | Shared Boundary | Enable shared boundary correspondence for multi-domain models with shared surfaces | diff --git a/docs/workflow/optimize.md b/docs/workflow/optimize.md index e8b4e1869cc..0fa0e93095b 100644 --- a/docs/workflow/optimize.md +++ b/docs/workflow/optimize.md @@ -214,6 +214,24 @@ When geodesic distances are enabled on mesh domains, `geodesic_remesh_percent` ( Reducing it trades geodesic accuracy for speed on dense meshes. Note that before 6.8 this value was misinterpreted, which inflated the mesh instead of decimating it and silently fell back to Euclidean distances; if you carried a value over from an older project, re-check it. +### Mesh Scalar Attributes + +A scalar field carried by the meshes -- thickness, curvature, a per-vertex measurement of your own -- can be used as a correspondence feature alongside particle position. The value is interpolated from the surface at each particle, so particles line up on the field as well as on the geometry. + +| Parameter | Default | Description | +| --- | --- | --- | +| `field_attributes` | *(empty)* | Names of the point data arrays to use, separated by spaces (write a space in a name as `%20`). | +| `field_attribute_weights` | *(empty)* | One weight per attribute, scaling it relative to XYZ. There must be exactly as many weights as attributes. | + +In Studio these appear as a **Mesh Scalars** row per field found on the meshes, in the Optimize panel. + +Two things to know: + +- Mesh domains only. Image and contour domains have no field to sample, and a project that mixes them is rejected. +- The field has to be on the **groomed** meshes, which is what optimization reads. Grooming carries fields through its steps, including remeshing, but a mesh built from a segmentation starts without any. + +See [Mesh Scalars in Studio](../studio/studio-mesh-scalars.md) for a worked example. + ## Optimizing Correspondences You can use either ShapeWorks Studio or `shapeworks optimize ` or `shapeworks optimize ` command to optimize your shape model. Both use a set of algorithmic parameters to control the optimization process. diff --git a/mkdocs.yml b/mkdocs.yml index 195bfa5931b..6d00688dfbc 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -52,6 +52,7 @@ nav: - 'Multiple Domains SSM': 'studio/multiple-domains.md' - 'Multi-Domain Reference Frames': 'studio/multi-domain-analysis-reference-frames.md' - 'Shared Boundaries': 'studio/studio-shared-boundary.md' + - 'Mesh Scalars': 'studio/studio-mesh-scalars.md' - 'Segmentation Tool': 'studio/segmentation-tool.md' - 'AI Assisted Segmentation': 'studio/ai-assisted-segmentation.md' - ShapeWorks Cloud: